xfs
[Top] [All Lists]

Re: Anyone using XFS ACLs? (fwd)

To: linux-xfs@xxxxxxxxxxx
Subject: Re: Anyone using XFS ACLs? (fwd)
From: Steve Lord <lord@xxxxxxx>
Date: Fri, 20 Jul 2001 13:33:07 -0500
Sender: owner-linux-xfs@xxxxxxxxxxx
This was sent privately, Danny later said he meant to send to the list,
any message mangling is entirely the fault of my mail tool. I expect we
will get something based on this into the tree fairly soon (is anyone
in Australia listening? hint hint).

Steve


------- Forwarded Message

Date:    Fri, 20 Jul 2001 12:35:35 -0400
From:    Danny Cox <danscox@xxxxxxxxxxxxxx>
To:      Steve Lord <lord@xxxxxxx>
Subject: Re: Anyone using XFS ACLs?

This is a multi-part message in MIME format.
- --------------4E072E6D209773EBBDAD1589
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Steve,

Steve Lord wrote:
> The other option here is for someone to take the source of something
> like chown which has a -R option, and chacl which does not. Merge the
> two and send in a patch. This is the sort of project which would be
> fairly easy for someone to tackle, would solve a problem. We are
> very tight on resources here and cannot be relied upon for things
> like bells and whistle extensions to commands like this.

        Steve, here is a patch that adds an '-r' arg to chacl, and decends
(depth first) a directory tree changing ACLs as it goes.  It doesn't
attempt to list them recursively, as that is a little trickier (and
neither chown nor chmod attempt this).

        I did have a little problem.  The "Makefile" uses the
'-D_FILE_OFFSET_BITS=64' which comes from ../include/builddefs, which
comes from ../include/builddefs.in, and causes the readdir to not work
correctly.  The included file "<dirents.h>" gets the wrong size, which
doesn't agree with my libc (I'm using RedHat 6.2, and it's standard
glibc).  When I recompiled without that flag, it works like a champ.

        Short of defining 'struct dirent' myself (HACK!), I don't know how to
work around this other than how I did (remove the flag, which probably
breaks something else).

        Anyway, the patch is attached.

        Oh, by the way, I did take the liberty of adding spaces where I thought
they should be, providing a little more consistency.  Ignore them if you
wish.

- -- 
"Men occasionally stumble over the truth, but most of them pick 
themselves up and hurry off as if nothing had happened." 
   -- Winston Churchill 

Danny
- --------------4E072E6D209773EBBDAD1589
Content-Type: text/plain; charset=us-ascii;
 name="chacl.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="chacl.patch"

- --- cmd/acl/chacl/chacl.c.orig        Fri Jul 20 11:04:45 2001
+++ cmd/acl/chacl/chacl.c       Fri Jul 20 12:30:09 2001
@@ -36,6 +36,7 @@
  */
 
 #include <sys/types.h>
+#include <sys/stat.h>
 #include <acl.h>
 #include <stdlib.h>
 #include <string.h>
@@ -43,10 +44,17 @@
 #include <getopt.h>
 #include <stdio.h>
 #include <errno.h>
+#include <dirent.h>
 
 static int acl_delete_file (const char * path, acl_type_t type);
- -static int list_acl(char *file);
+static int list_acl (char *file);
+static int set_acl (acl_t acl, acl_t dacl, const char *fname);
+static int isdir (const char *fname);
+static int walk_dir (acl_t acl, acl_t dacl, const char *fname);
+static void *emalloc (int len);
+
 static char *program;
+static int Recurse = 0;
 
 static void
 usage (void)
@@ -59,6 +67,7 @@
        fprintf (stderr, "\t%s -D pathname ...\n", program);
        fprintf (stderr, "\t%s -B pathname ...\n", program);
        fprintf (stderr, "\t%s -l pathname ...\n", program);
+       fprintf (stderr, "\t%s -r pathname ...\n", program);
        exit (1);
 }
 
@@ -70,7 +79,7 @@
        int switch_flag = 0;            /* ensure only one switch is used */
        int args_required = 1;  
        int failed = 0;                 /* exit status */
- -     int c;                                  /* For use by getopt(3) */
+       int c;                          /* For use by getopt(3) */
        int dflag = 0;                  /* a Default ACL is desired */
        int bflag = 0;                  /* a both ACLs are desired */
        int Rflag = 0;                  /* set to true to remove an acl */
@@ -82,25 +91,26 @@
 
        /* create program name */
        p = strrchr (argv[0], '/');
- -     program = p != NULL ? p + 1 : argv[0];
+       program = (p != NULL) ? p + 1 : argv[0];
 
- -     acl_set_compat(ACL_COMPAT_IRIXGET);
+       acl_set_compat (ACL_COMPAT_IRIXGET);
 
        /* parse arguments */
- -     while ((c = getopt (argc, argv, "bdlRDB")) != -1)
+       while ((c = getopt (argc, argv, "bdlRDBr")) != -1)
        {
- -             if (switch_flag) usage();
- -             switch_flag=1;          
+               if (switch_flag) 
+                       usage();
+               switch_flag = 1;
 
                switch (c)
                {
                        case 'b':
                                bflag = 1;
- -                             args_required=3;
+                               args_required = 3;
                                break;
                        case 'd':
                                dflag = 1;
- -                             args_required=2;
+                               args_required = 2;
                                break;
                        case 'R':
                                Rflag = 1;
@@ -114,6 +124,9 @@
                        case 'l':
                                lflag = 1;
                                break;
+                       case 'r':
+                               Recurse = 1;
+                               break;
                        default:
                                usage ();
                                break;
@@ -121,16 +134,16 @@
        }
 
        /* if not enough arguments quit */
- -     if ((argc-optind) < args_required)
+       if ((argc - optind) < args_required)
                usage ();
 
         /* list the acls */
- -     if ( lflag ) 
+       if (lflag) 
         {
- -         for (;optind < argc;optind++)
+           for (; optind < argc; optind++)
            {   
                 char *file = argv[optind];
- -                if (!list_acl(file))
+                if (!list_acl (file))
                 {
                     failed++;
                 }
@@ -139,20 +152,20 @@
         }
 
        /* remove the acls */
- -     if ( Rflag || Dflag || Bflag )
+       if (Rflag || Dflag || Bflag)
        {
- -             for (;optind < argc;optind++)
+               for (; optind < argc; optind++)
                {       
                        if (!Dflag && acl_delete_file (argv[optind], ACL_TYPE_A
CCESS) == -1)   
                        {
- -                             fprintf (stderr,"%s: error removing access acl 
on \"%s\": %s\n", 
- -                                     program, argv[optind],strerror(errno));
+                               fprintf (stderr, "%s: error removing access acl
 on \"%s\": %s\n", 
+                                       program, argv[optind], strerror (errno)
);
                                failed++;
                        }
                        if (!Rflag && acl_delete_file (argv[optind], ACL_TYPE_D
EFAULT) == -1)  
                        {
- -                             fprintf (stderr,"%s: error removing default acl
 on \"%s\": %s\n", 
- -                                     program, argv[optind],strerror(errno));
+                               fprintf (stderr, "%s: error removing default ac
l on \"%s\": %s\n", 
+                                       program, argv[optind], strerror (errno)
);
                                failed++;
                        }
                }
@@ -163,7 +176,7 @@
        /* file access acl */
        if (! dflag) { 
                acl = acl_from_text (argv[optind]);
- -             if (acl == NULL || acl_valid(acl) == -1)
+               if (acl == NULL || acl_valid (acl) == -1)
                {
                        fprintf (stderr, inv_acl, program, argv[optind]);
                        return (1);
@@ -175,7 +188,7 @@
        /* directory default acl */
        if (bflag || dflag) {
                dacl = acl_from_text (argv[optind]);
- -             if (dacl == NULL || acl_valid(dacl) == -1)
+               if (dacl == NULL || acl_valid (dacl) == -1)
                {
                        fprintf (stderr, inv_acl, program, argv[optind]);
                        return (1);
@@ -185,24 +198,9 @@
 
 
        /* place acls on files */
- -     for (;optind < argc;optind++)
+       for (; optind < argc; optind++)
        {
- -             /* set regular acl */
- -             if (acl &&
- -                 acl_set_file (argv[optind], ACL_TYPE_ACCESS, acl) == -1)
- -             {
- -                     fprintf (stderr,"%s: error setting access acl on \"%s\"
: %s\n",
- -                              program, argv[optind],strerror(errno));
- -                     failed++;
- -             }
- -             /* set default acl */
- -             if (dacl &&
- -                 acl_set_file (argv[optind], ACL_TYPE_DEFAULT, dacl) == -1)
- -             {
- -                     fprintf (stderr,"%s: error setting default acl on \"%s\
": %s\n",
- -                              program, argv[optind],strerror(errno));
- -                     failed++;
- -             }
+               failed += set_acl (acl, dacl, argv[optind]);
        }
 
        if (acl)
@@ -220,11 +218,11 @@
 acl_delete_file (const char * path, acl_type_t type)
 {
        struct acl acl;
- -     int error=0;
+       int error = 0;
 
        acl.acl_cnt = ACL_NOT_PRESENT;
 
- -     error = acl_set_file( path,type,&acl) ;
+       error = acl_set_file (path, type, &acl) ;
 
        return(error);
 }
@@ -242,10 +240,10 @@
        char *buf_acl = NULL;
        char *buf_dacl = NULL;
 
- -     acl = acl_get_file(file, ACL_TYPE_ACCESS);
+       acl = acl_get_file (file, ACL_TYPE_ACCESS);
        if (acl == NULL) {
            fprintf (stderr, "%s: error getting ACL on \"%s\": %s\n",
- -                      program, file, strerror(errno));
+                        program, file, strerror (errno));
             return 0;
        }
         if (acl->acl_cnt != ACL_NOT_PRESENT) {
@@ -253,15 +251,15 @@
            if (buf_acl == NULL) {
                fprintf (stderr, "%s: error converting ACL to short text "
                                 "for file \"%s\": %s\n",
- -                          program, file, strerror(errno));
+                            program, file, strerror (errno));
                return 0;
            }
         }
          
- -     dacl = acl_get_file(file, ACL_TYPE_DEFAULT);
+       dacl = acl_get_file (file, ACL_TYPE_DEFAULT);
        if (dacl == NULL) {
            fprintf (stderr, "%s: error getting default ACL on \"%s\": %s\n",
- -                      program, file, strerror(errno));
+                        program, file, strerror (errno));
            return 0;
         }
         if (dacl->acl_cnt > 0) {
@@ -269,7 +267,7 @@
            if (buf_dacl == NULL) {
                fprintf (stderr, "%s: error converting default ACL to short tex
t "
                                 "for file \"%s\": %s\n",
- -                          program, file, strerror(errno));
+                            program, file, strerror (errno));
                return 0;
            }
         }
@@ -294,5 +292,101 @@
         if (buf_dacl)
            acl_free(buf_dacl);
       
- -        return(1);
+        return (1);
+}
+
+static int
+set_acl (acl_t acl, acl_t dacl, const char *fname)
+{
+       int failed = 0;
+
+       /* set regular acl */
+       if (acl && acl_set_file (fname, ACL_TYPE_ACCESS, acl) == -1)
+       {
+               fprintf (stderr,"%s: error setting access acl on \"%s\": %s\n",
+                        program, fname, strerror (errno));
+               failed++;
+       }
+       /* set default acl */
+       if (dacl && acl_set_file (fname, ACL_TYPE_DEFAULT, dacl) == -1)
+       {
+               fprintf (stderr,"%s: error setting default acl on \"%s\": %s\n"
,
+                        program, fname, strerror (errno));
+               failed++;
+       }
+
+       if (Recurse && isdir (fname))
+       {
+               failed += walk_dir (acl, dacl, fname);
+       }
+
+       return (failed);
+}
+
+/* is fname a directory? */
+
+static int
+isdir (const char *fname)
+{
+       struct stat st;
+
+       if (stat (fname, &st) == -1)
+       {
+               return (0);
+       }
+
+       return (S_ISDIR (st.st_mode));
+}
+
+/* step through entries in a directory */
+
+static int
+walk_dir (acl_t acl, acl_t dacl, const char *fname)
+{
+       int failed = 0;
+       DIR *dir;
+       struct dirent *d;
+
+       if ((dir = opendir (fname)) == NULL)
+       {
+               fprintf (stderr, "%s: error opening \"%s\": %s\n", program,
+                        fname, strerror (errno));
+               return (0);
+       }
+
+       while ((d = readdir (dir)) != NULL)
+       {
+               char *new;
+
+               /* skip "." and ".." entries */
+               if (strcmp (d->d_name, ".") == 0 || 
+                   strcmp (d->d_name, "..") == 0)
+                       continue;
+
+               new = emalloc (strlen (fname) + strlen (d->d_name) + 2);
+               sprintf (new, "%s/%s", fname, d->d_name);
+
+               failed += set_acl (acl, dacl, new);
+               free (new);
+       }
+
+       closedir (dir);
+
+       return (failed);
+}
+
+static void *
+emalloc (int len)
+{
+       void *p;
+
+       p = malloc (len);
+       if (p == NULL)
+       {
+               fprintf (stderr, "%s: malloc error: %s\n", program, 
+                        strerror (errno));
+               exit (255);
+       }
+
+       return (p);
 }

- --------------4E072E6D209773EBBDAD1589--

------- End of Forwarded Message




<Prev in Thread] Current Thread [Next in Thread>