bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

acl: add support for AIX


From: Bruno Haible
Subject: acl: add support for AIX
Date: Sun, 8 Jun 2008 20:33:23 +0200
User-agent: KMail/1.5.4

The acl tests still fail on AIX 5.1:
  file_has_acl("tmpfile0") returned no, expected yes
  FAIL: test-file-has-acl.sh
  PASS: test-set-mode-acl.sh
  files tmpfile0 and tmpfile2 have different access modes: 200500600 and 500600
  FAIL: test-copy-acl.sh

There are two ACL APIs: one in AIX >= 5.3, one already present in AIX 4.
Since I don't have access to an AIX >= 5.3 machine, I can only add support for
the older API. Two things are particular about this API:
  - The ACL is stored in a block of memory which is traversed like a linked
    list. 4096 bytes of room must be allocated for it.
  - The ACL contains also the mode bits other than 0777 (in a special field).


2008-06-08  Bruno Haible  <address@hidden>

        Add support for AIX ACLs.
        * lib/acl-internal.h (acl_nontrivial): New declaration.
        * lib/file-has-acl.c (acl_nontrivial): New function.
        (file_has_acl): Add implementation using AIX 4 ACL API.
        * lib/set-mode-acl.c (qset_acl): Likewise.
        * lib/copy-acl.c (qcopy_acl): Likewise.

*** lib/acl-internal.h.orig     2008-06-08 19:51:19.000000000 +0200
--- lib/acl-internal.h  2008-06-08 19:18:56.000000000 +0200
***************
*** 185,190 ****
--- 185,200 ----
     Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
  extern int acl_nontrivial (int count, struct acl_entry *entries, struct stat 
*sb);
  
+ # elif HAVE_ACLX_GET && 0 /* AIX */
+ 
+ /* TODO */
+ 
+ # elif HAVE_STATACL /* older AIX */
+ 
+ /* Return 1 if the given ACL is non-trivial.
+    Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
+ extern int acl_nontrivial (struct acl *a);
+ 
  # endif
  
  #endif
*** lib/file-has-acl.c.orig     2008-06-08 19:51:19.000000000 +0200
--- lib/file-has-acl.c  2008-06-08 19:21:40.000000000 +0200
***************
*** 195,200 ****
--- 195,230 ----
    return 0;
  }
  
+ #elif USE_ACL && HAVE_ACLX_GET && 0 /* AIX */
+ 
+ /* TODO */
+ 
+ #elif USE_ACL && HAVE_STATACL /* older AIX */
+ 
+ /* Return 1 if the given ACL is non-trivial.
+    Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
+ int
+ acl_nontrivial (struct acl *a)
+ {
+   /* The normal way to iterate through an ACL is like this:
+        struct acl_entry *ace;
+        for (ace = a->acl_ext; ace != acl_last (a); ace = acl_nxt (ace))
+          {
+            struct ace_id *aei;
+            switch (ace->ace_type)
+              {
+              case ACC_PERMIT:
+              case ACC_DENY:
+              case ACC_SPECIFY:
+                ...;
+              }
+            for (aei = ace->ace_id; aei != id_last (ace); aei = id_nxt (aei))
+              ...
+          }
+    */
+   return (acl_last (a) != a->acl_ext ? 1 : 0);
+ }
+ 
  #endif
  
  
***************
*** 430,441 ****
             Repeat.  */
        }
  
  # endif
      }
  #endif
  
-   /* FIXME: Add support for AIX.  Please see Samba's
-      source/lib/sysacls.c file for fix-related ideas.  */
- 
    return 0;
  }
--- 460,481 ----
             Repeat.  */
        }
  
+ # elif HAVE_ACLX_GET && 0 /* AIX */
+ 
+       /* TODO: use aclx_get(), and then?  */
+ 
+ # elif HAVE_STATACL /* older AIX */
+ 
+       union { struct acl a; char room[4096]; } u;
+ 
+       if (statacl (name, STX_NORMAL, &u.a, sizeof (u)) < 0)
+       return -1;
+ 
+       return acl_nontrivial (&u.a);
+ 
  # endif
      }
  #endif
  
    return 0;
  }
*** lib/set-mode-acl.c.orig     2008-06-08 19:51:19.000000000 +0200
--- lib/set-mode-acl.c  2008-06-08 19:22:40.000000000 +0200
***************
*** 357,362 ****
--- 357,387 ----
      }
    return 0;
  
+ # elif HAVE_ACLX_GET && 0 /* AIX */
+ 
+   /* TODO: use aclx_fput or aclx_put, respectively */
+ 
+ # elif HAVE_STATACL /* older AIX */
+ 
+   union { struct acl a; char room[128]; } u;
+   int ret;
+ 
+   u.a.acl_len = (char *) &u.a.acl_ext[0] - (char *) &u.a; /* no entries */
+   u.a.acl_mode = mode & ~(S_IXACL | 0777);
+   u.a.u_access = (mode >> 6) & 7;
+   u.a.g_access = (mode >> 3) & 7;
+   u.a.o_access = mode & 7;
+ 
+   if (desc != -1)
+     ret = fchacl (desc, &u.a, u.a.acl_len);
+   else
+     ret = chacl (name, &u.a, u.a.acl_len);
+ 
+   if (ret < 0 && errno == ENOSYS)
+     return chmod_or_fchmod (name, desc, mode);
+ 
+   return ret;
+ 
  # else /* Unknown flavor of ACLs */
    return chmod_or_fchmod (name, desc, mode);
  # endif
*** lib/copy-acl.c.orig 2008-06-08 19:51:19.000000000 +0200
--- lib/copy-acl.c      2008-06-08 19:51:08.000000000 +0200
***************
*** 470,475 ****
--- 470,507 ----
      }
    return 0;
  
+ #elif USE_ACL && HAVE_ACLX_GET && 0 /* AIX */
+ 
+   /* TODO */
+ 
+ #elif USE_ACL && HAVE_STATACL /* older AIX */
+ 
+   union { struct acl a; char room[4096]; } u;
+   int ret;
+ 
+   if ((source_desc != -1
+        ? fstatacl (source_desc, STX_NORMAL, &u.a, sizeof (u))
+        : statacl (src_name, STX_NORMAL, &u.a, sizeof (u)))
+       < 0)
+     return -2;
+ 
+   ret = (dest_desc != -1
+        ? fchacl (dest_desc, &u.a, u.a.acl_len)
+        : chacl (dst_name, &u.a, u.a.acl_len));
+   if (ret < 0)
+     {
+       int saved_errno = errno;
+ 
+       chmod_or_fchmod (dst_name, dest_desc, mode);
+       errno = saved_errno;
+       return -1;
+     }
+ 
+   /* No need to call chmod_or_fchmod at this point, since the mode bits
+      S_ISUID, S_ISGID, S_ISVTX are also stored in the ACL.  */
+ 
+   return 0;
+ 
  #else
  
    return qset_acl (dst_name, dest_desc, mode);





reply via email to

[Prev in Thread] Current Thread [Next in Thread]