From: Frank Lahm Date: Thu, 28 Feb 2013 07:02:48 +0000 (+0100) Subject: Enhance ACL mapping X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=commitdiff_plain;h=4c691d7ebf0d54b3ee69d54955bcaf2283e98abc Enhance ACL mapping Change globald ACL option 'map acl' to take the following options: "none", "rights", "mode". The default is "rights". none = no mapping, this resembles the previous false/no setting rights = map ACLs to Finder UARights, this resembles the previous true/yes setting. This is the default. mode = map ACLs to Finder UARights and UNIX mode From FR #73. --- diff --git a/NEWS b/NEWS index 65c6c1e0..a1c3cedf 100644 --- a/NEWS +++ b/NEWS @@ -7,7 +7,14 @@ Changes in 3.0.4 lead to a failure setting the size of a files ressource fork. This affected application like Adobe Photoshop where saving files may fail. Fixes bug #511. - +* UPD: Enhance ACL mapping, change global ACL option 'map acl' to take + the following options: "none", "rights" (default), "mode". + none = no mapping, this resembles the previous false/no setting + rights = map ACLs to Finder UARights, this resembles the previous + true/yes setting. This is the default. + mode = map ACLs to Finder UARights and UNIX mode + From FR #73. + Changes in 3.0.3 ================ * UPD: afpd: Increase default DSI server quantum to 1 MB diff --git a/etc/afpd/acls.c b/etc/afpd/acls.c index 6f2abdf3..d162b994 100644 --- a/etc/afpd/acls.c +++ b/etc/afpd/acls.c @@ -87,15 +87,17 @@ * * @param obj (r) handle * @param path (r) path to filesystem object - * @param sb (r) struct stat of path - * @param result (w) resulting Darwin allow ACE + * @param sb (rw) struct stat of path + * @param ma (rw) UARights struct + * @param rights_out (w) mapped Darwin ACL rights * * @returns 0 or -1 on error */ static int solaris_acl_rights(const AFPObj *obj, const char *path, - const struct stat *sb, - uint32_t *result) + struct stat *sb, + struct maccess *ma, + uint32_t *rights_out) { EC_INIT; int i, ace_count, checkgroup; @@ -168,7 +170,28 @@ static int solaris_acl_rights(const AFPObj *obj, darwin_rights |= nfsv4_to_darwin_rights[i].to; } - *result |= darwin_rights; + LOG(log_maxdebug, logtype_afpd, "rights: 0x%08x", darwin_rights); + + if (rights_out) + *rights_out = darwin_rights; + + if (ma && obj->options.flags & OPTION_ACL2MACCESS) { + if (darwin_rights & DARWIN_ACE_READ_DATA) + ma->ma_user |= AR_UREAD; + if (darwin_rights & DARWIN_ACE_WRITE_DATA) + ma->ma_user |= AR_UWRITE; + if (darwin_rights & (DARWIN_ACE_EXECUTE | DARWIN_ACE_SEARCH)) + ma->ma_user |= AR_USEARCH; + } + + if (sb && obj->options.flags & OPTION_ACL2MODE) { + if (darwin_rights & DARWIN_ACE_READ_DATA) + sb->st_mode |= S_IRUSR; + if (darwin_rights & DARWIN_ACE_WRITE_DATA) + sb->st_mode |= S_IWUSR; + if (darwin_rights & (DARWIN_ACE_EXECUTE | DARWIN_ACE_SEARCH)) + sb->st_mode |= S_IXUSR; + } EC_CLEANUP: if (aces) free(aces); @@ -607,21 +630,23 @@ static int posix_acls_to_uaperms(const AFPObj *obj, const char *path, struct sta break; } } - /* apply the mask and adjust user and group permissions */ - ma->ma_user |= (acl_rights & mask); - ma->ma_group = (group_rights & mask); - /* update st_mode to properly reflect group permissions */ - sb->st_mode &= ~S_IRWXG; - - if (ma->ma_group & AR_USEARCH) - sb->st_mode |= S_IXGRP; - - if (ma->ma_group & AR_UWRITE) - sb->st_mode |= S_IWGRP; + if (obj->options.flags & OPTION_ACL2MACCESS) { + /* apply the mask and adjust user and group permissions */ + ma->ma_user |= (acl_rights & mask); + ma->ma_group = (group_rights & mask); + } - if (ma->ma_group & AR_UREAD) - sb->st_mode |= S_IRGRP; + if (obj->options.flags & OPTION_ACL2MODE) { + /* update st_mode to properly reflect group permissions */ + sb->st_mode &= ~S_IRWXG; + if (ma->ma_group & AR_USEARCH) + sb->st_mode |= S_IXGRP; + if (ma->ma_group & AR_UWRITE) + sb->st_mode |= S_IWGRP; + if (ma->ma_group & AR_UREAD) + sb->st_mode |= S_IRGRP; + } EC_CLEANUP: if (acl) acl_free(acl); @@ -1396,7 +1421,7 @@ static int check_acl_access(const AFPObj *obj, LOG(log_debug, logtype_afpd, "check_access: allowed rights from dircache: 0x%08x", allowed_rights); } else { #ifdef HAVE_SOLARIS_ACLS - EC_ZERO_LOG(solaris_acl_rights(obj, path, &st, &allowed_rights)); + EC_ZERO_LOG(solaris_acl_rights(obj, path, &st, NULL, &allowed_rights)); #endif #ifdef HAVE_POSIX_ACLS EC_ZERO_LOG(posix_acl_rights(obj, path, &st, &allowed_rights)); @@ -1429,7 +1454,7 @@ static int check_acl_access(const AFPObj *obj, EC_ZERO_LOG_ERR(lstat(cfrombstr(parent), &st), AFPERR_MISC); #ifdef HAVE_SOLARIS_ACLS - EC_ZERO_LOG(solaris_acl_rights(obj, cfrombstr(parent), &st, &parent_rights)); + EC_ZERO_LOG(solaris_acl_rights(obj, cfrombstr(parent), &st, NULL, &parent_rights)); #endif #ifdef HAVE_POSIX_ACLS EC_ZERO_LOG(posix_acl_rights(obj, path, &st, &parent_rights)); @@ -1734,7 +1759,7 @@ int acltoownermode(const AFPObj *obj, const struct vol *vol, char *path, struct { EC_INIT; - if ( ! (obj->options.flags & OPTION_ACL2MACCESS) + if ( ! (obj->options.flags & (OPTION_ACL2MACCESS | OPTION_ACL2MODE)) || ! (vol->v_flags & AFPVOL_ACLS)) return 0; @@ -1742,17 +1767,7 @@ int acltoownermode(const AFPObj *obj, const struct vol *vol, char *path, struct getcwdpath(), path, ma->ma_user); #ifdef HAVE_SOLARIS_ACLS - uint32_t rights = 0; - EC_ZERO_LOG(solaris_acl_rights(obj, path, st, &rights)); - - LOG(log_maxdebug, logtype_afpd, "rights: 0x%08x", rights); - - if (rights & DARWIN_ACE_READ_DATA) - ma->ma_user |= AR_UREAD; - if (rights & DARWIN_ACE_WRITE_DATA) - ma->ma_user |= AR_UWRITE; - if (rights & (DARWIN_ACE_EXECUTE | DARWIN_ACE_SEARCH)) - ma->ma_user |= AR_USEARCH; + EC_ZERO_LOG(solaris_acl_rights(obj, path, st, ma, NULL)); #endif #ifdef HAVE_POSIX_ACLS diff --git a/include/atalk/globals.h b/include/atalk/globals.h index 96f062a0..a095b103 100644 --- a/include/atalk/globals.h +++ b/include/atalk/globals.h @@ -54,6 +54,7 @@ #define OPTION_UUID (1 << 7) #define OPTION_ACL2MACCESS (1 << 8) #define OPTION_NOZEROCONF (1 << 9) +#define OPTION_ACL2MODE (1 << 10) #define OPTION_SHARE_RESERV (1 << 11) /* whether to use Solaris fcntl F_SHARE locks */ #define OPTION_DBUS_AFPSTATS (1 << 12) /* whether to run dbus thread for afpstats */ diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index 6445d3fe..fdb0bfc9 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -1711,8 +1711,6 @@ int afp_config_parse(AFPObj *AFPObj, char *processname) options->flags |= OPTION_NOZEROCONF; if (iniparser_getboolean(config, INISEC_GLOBAL, "advertise ssh", 0)) options->flags |= OPTION_ANNOUNCESSH; - if (iniparser_getboolean(config, INISEC_GLOBAL, "map acls", 1)) - options->flags |= OPTION_ACL2MACCESS; if (iniparser_getboolean(config, INISEC_GLOBAL, "close vol", 0)) options->flags |= OPTION_CLOSEVOL; if (!iniparser_getboolean(config, INISEC_GLOBAL, "client polling", 0)) @@ -1761,6 +1759,18 @@ int afp_config_parse(AFPObj *AFPObj, char *processname) options->sleep = iniparser_getint (config, INISEC_GLOBAL, "sleep time", 10); options->disconnected = iniparser_getint (config, INISEC_GLOBAL, "disconnect time",24); + p = iniparser_getstring(config, INISEC_GLOBAL, "map acls", "rights"); + if (STRCMP(p, ==, "rights")) + options->flags |= OPTION_ACL2MACCESS; + else if (STRCMP(p, ==, "mode")) + options->flags |= OPTION_ACL2MODE | OPTION_ACL2MACCESS; + else { + if (STRCMP(p, !=, "none")) { + LOG(log_error, logtype_afpd, "bad ACL mapping option: %s, defaulting to 'rights'", p); + options->flags |= OPTION_ACL2MACCESS; + } + } + if ((p = iniparser_getstring(config, INISEC_GLOBAL, "hostname", NULL))) { EC_NULL_LOG( options->hostname = strdup(p) ); } else {