From 9f86b4982988f486901b5b9f1d96a45a9698606d Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Tue, 28 Sep 2010 18:31:47 +0200 Subject: [PATCH] I've set my first POSIX 1e ACL, now nice --- NEWS | 2 +- etc/afpd/acls.c | 42 ++++++++++++++++++++++++++++++------------ include/atalk/errchk.h | 10 ++++++++-- 3 files changed, 39 insertions(+), 15 deletions(-) diff --git a/NEWS b/NEWS index 9b57c5a4..658cfd01 100644 --- a/NEWS +++ b/NEWS @@ -4,7 +4,7 @@ Changes in 2.2 * UPD: AppleTalk ist disabled by default at configuration time. If needed use --enable-ddp. * NEW: afpd: dynamic directoy and CNID cache -* NEW: afpd: read-only POSIX 1e ACL support +* NEW: afpd: POSIX 1e ACL support * NEW: afpd: automagic Zeroconf registration with avahi, registering both the service _afpovertcp._tcp and TimeMachine volumes with _adisk._tcp. diff --git a/etc/afpd/acls.c b/etc/afpd/acls.c index d8fd133a..dd7aead1 100644 --- a/etc/afpd/acls.c +++ b/etc/afpd/acls.c @@ -436,11 +436,11 @@ static int map_acl_darwin_to_posix(const darwin_ace_t *darwin_aces, EC_ZERO_LOG(getnamefromuuid(darwin_aces->darwin_ace_uuid, &name, &uuidtype)); if (uuidtype == UUID_USER) { EC_NULL_LOG(pwd = getpwnam(name)); - tag = ACL_USER_OBJ; + tag = ACL_USER; id = pwd->pw_uid; } else { /* hopefully UUID_GROUP*/ EC_NULL_LOG(getgrnam(name)); - tag = ACL_GROUP_OBJ; + tag = ACL_GROUP; id = (uid_t)(grp->gr_gid); } free(name); @@ -453,8 +453,6 @@ static int map_acl_darwin_to_posix(const darwin_ace_t *darwin_aces, darwin_aces++; } - EC_ZERO_LOG(acl_valid(*aclp)); - EC_CLEANUP: if (name) free(name); @@ -851,10 +849,12 @@ EC_CLEANUP: #endif /* HAVE_SOLARIS_ACLS */ #ifdef HAVE_POSIX_ACLS -static int set_acl(const struct vol *vol, char *name, int inherit, char *ibuf) +static int set_acl(const struct vol *vol, const char *name, int inherit, char *ibuf) { EC_INIT; int is_dir = 0; + acl_t acl = NULL; + acl_t mode_acl = NULL; LOG(log_maxdebug, logtype_afpd, "set_acl: BEGIN"); @@ -862,11 +862,11 @@ static int set_acl(const struct vol *vol, char *name, int inherit, char *ibuf) uint32_t ace_count = htonl(*((uint32_t *)ibuf)); ibuf += 8; /* skip ACL flags (see acls.h) */ - acl_t acl = NULL; + struct stat st; + EC_ZERO_LOG_ERR(stat(name, &st), AFPERR_NOOBJ); + if (inherit) { /* get default ACEs */ - struct stat st; - EC_ZERO_LOG_ERR(stat(name, &st), AFPERR_NOOBJ); if (S_ISDIR(st.st_mode)) { is_dir = 1; EC_NULL_LOG_ERR(acl = acl_get_file(name, ACL_TYPE_DEFAULT), AFPERR_MISC); @@ -875,13 +875,31 @@ static int set_acl(const struct vol *vol, char *name, int inherit, char *ibuf) EC_NULL_LOG_ERR(acl = acl_init(0), AFPERR_MISC); } - EC_ZERO_LOG(map_acl_darwin_to_posix((darwin_ace_t *)ibuf, &acl, is_dir, ace_count)); + /* Now combine acl with aces from mode */ + EC_NULL_LOG_ERR(mode_acl = acl_from_mode(st.st_mode), AFPERR_MISC); + int entry_id = ACL_FIRST_ENTRY; + acl_entry_t se, de; + while (acl_get_entry(mode_acl, entry_id, &se) == 1) { + EC_ZERO_LOG_ERR(acl_create_entry(&acl, &de), AFPERR_MISC); + EC_ZERO_LOG_ERR(acl_copy_entry(de, se), AFPERR_MISC); + entry_id = ACL_NEXT_ENTRY; + } - EC_STATUS(AFP_OK); + /* map_acl_darwin_to_posix adds the clients aces */ + EC_ZERO_ERR(map_acl_darwin_to_posix((darwin_ace_t *)ibuf, &acl, is_dir, ace_count), AFPERR_MISC); + + /* calcuate ACL mask */ + EC_ZERO_LOG_ERR(acl_calc_mask(&acl), AFPERR_MISC); + + /* is it ok? */ + EC_ZERO_LOG_ERR(acl_valid(acl), AFPERR_MISC); + + /* set it */ + EC_ZERO_LOG_ERR(acl_set_file(name, ACL_TYPE_ACCESS, acl), AFPERR_MISC); EC_CLEANUP: - if (acl) - acl_free(acl); + if (acl) acl_free(acl); + if (mode_acl) acl_free(mode_acl); LOG(log_maxdebug, logtype_afpd, "set_acl: END: %u", ret); EC_EXIT; } diff --git a/include/atalk/errchk.h b/include/atalk/errchk.h index 00ae8b64..f0d8ca4e 100644 --- a/include/atalk/errchk.h +++ b/include/atalk/errchk.h @@ -62,7 +62,6 @@ } \ } while (0) -/* check for return val 0 which is ok, every other is an error */ #define EC_ZERO(a) \ do { \ if ((a) != 0) { \ @@ -71,7 +70,14 @@ } \ } while (0) -/* check for return val 0 which is ok, every other is an error */ +#define EC_ZERO_ERR(a,b ) \ + do { \ + if ((a) != 0) { \ + ret = b; \ + goto cleanup; \ + } \ + } while (0) + #define EC_ZERO_CUSTOM(a) \ (ret = (a)) != 0 -- 2.39.2