From 3f5a64015c34e525c73ccda17d5e300c58ee7505 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sun, 8 Jun 2008 20:33:08 +0200 Subject: [PATCH] Add support for AIX ACLs. --- ChangeLog | 9 +++++++++ lib/acl-internal.h | 10 ++++++++++ lib/copy-acl.c | 32 ++++++++++++++++++++++++++++++++ lib/file-has-acl.c | 46 +++++++++++++++++++++++++++++++++++++++++++--- lib/set-mode-acl.c | 25 +++++++++++++++++++++++++ 5 files changed, 119 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 90eca9494..8f3db0f71 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,14 @@ 2008-06-08 Bruno Haible + 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. + +2008-06-08 Bruno Haible + Add support for HP-UX ACLs. * lib/acl-internal.h (acl_nontrivial): New declaration. * lib/file-has-acl.c (acl_nontrivial): New function. diff --git a/lib/acl-internal.h b/lib/acl-internal.h index af7396e92..74d67aeb8 100644 --- a/lib/acl-internal.h +++ b/lib/acl-internal.h @@ -185,6 +185,16 @@ extern int acl_ace_nontrivial (int count, ace_t *entries); 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 diff --git a/lib/copy-acl.c b/lib/copy-acl.c index 73f370c9a..780865cef 100644 --- a/lib/copy-acl.c +++ b/lib/copy-acl.c @@ -470,6 +470,38 @@ qcopy_acl (const char *src_name, int source_desc, const char *dst_name, } 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); diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c index 50e60d515..37a0ee1cd 100644 --- a/lib/file-has-acl.c +++ b/lib/file-has-acl.c @@ -195,6 +195,36 @@ acl_nontrivial (int count, struct acl_entry *entries, struct stat *sb) 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,12 +460,22 @@ file_has_acl (char const *name, struct stat const *sb) 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 - /* FIXME: Add support for AIX. Please see Samba's - source/lib/sysacls.c file for fix-related ideas. */ - return 0; } diff --git a/lib/set-mode-acl.c b/lib/set-mode-acl.c index c25c5fe3d..7ef39cfa2 100644 --- a/lib/set-mode-acl.c +++ b/lib/set-mode-acl.c @@ -357,6 +357,31 @@ qset_acl (char const *name, int desc, mode_t mode) } 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 -- 2.11.0