X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Facls.c;h=7551d70d7eb1ab65fa52c2151ef2bb90e1a6919b;hb=7c659dda6359a0971112b3e16b38bca3c14ae896;hp=e37c6262bf4264e9766eaa1550efa2073f67f805;hpb=fbd6b007f0121c117e86d02efa0a88e1e5ff6676;p=netatalk.git diff --git a/etc/afpd/acls.c b/etc/afpd/acls.c index e37c6262..7551d70d 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); @@ -629,6 +654,7 @@ EC_CLEANUP: EC_EXIT; } +#if 0 /*! * Add entries of one acl to another acl * @@ -651,6 +677,7 @@ static int acl_add_acl(acl_t *aclp, const acl_t acl) EC_CLEANUP: EC_EXIT; } +#endif /*! * Map Darwin ACE rights to POSIX 1e perm @@ -991,7 +1018,7 @@ static int get_and_map_acl(char *name, char *rbuf, size_t *rbuflen) EC_INIT; int mapped_aces = 0; int dirflag; - uint32_t *darwin_ace_count = (uint32_t *)rbuf; + char *darwin_ace_count = rbuf; #ifdef HAVE_SOLARIS_ACLS int ace_count = 0; ace_t *aces = NULL; @@ -1040,8 +1067,9 @@ static int get_and_map_acl(char *name, char *rbuf, size_t *rbuflen) LOG(log_debug, logtype_afpd, "get_and_map_acl: mapped %d ACEs", mapped_aces); - *darwin_ace_count = htonl(mapped_aces); *rbuflen += sizeof(darwin_acl_header_t) + (mapped_aces * sizeof(darwin_ace_t)); + mapped_aces = htonl(mapped_aces); + memcpy(darwin_ace_count, &mapped_aces, sizeof(uint32_t)); EC_STATUS(0); @@ -1154,28 +1182,31 @@ static int set_acl(const struct vol *vol, } LOG(log_debug7, logtype_afpd, "set_acl: copied %d trivial ACEs", trivial_ace_count); - /* Ressourcefork first. - Note: for dirs we set the same ACL on the .AppleDouble/.Parent _file_. This - might be strange for ACE_DELETE_CHILD and for inheritance flags. */ + /* Ressourcefork first */ if ((ret = (vol->vfs->vfs_acl(vol, name, ACE_SETACL, new_aces_count, new_aces))) != 0) { - LOG(log_error, logtype_afpd, "set_acl: error setting acl: %s", strerror(errno)); - if (errno == (EACCES | EPERM)) - EC_STATUS(AFPERR_ACCESS); - else if (errno == ENOENT) - EC_STATUS(AFPERR_NOITEM); - else - EC_STATUS(AFPERR_MISC); - goto EC_CLEANUP; + LOG(log_debug, logtype_afpd, "set_acl: error setting acl: %s", strerror(errno)); + switch (errno) { + case ENOENT: + break; + case EACCES: + case EPERM: + EC_EXIT_STATUS(AFPERR_ACCESS); + default: + EC_EXIT_STATUS(AFPERR_MISC); + } } + if ((ret = (acl(name, ACE_SETACL, new_aces_count, new_aces))) != 0) { LOG(log_error, logtype_afpd, "set_acl: error setting acl: %s", strerror(errno)); - if (errno == (EACCES | EPERM)) - EC_STATUS(AFPERR_ACCESS); - else if (errno == ENOENT) - EC_STATUS(AFPERR_NOITEM); - else - EC_STATUS(AFPERR_MISC); - goto EC_CLEANUP; + switch (errno) { + case EACCES: + case EPERM: + EC_EXIT_STATUS(AFPERR_ACCESS); + case ENOENT: + EC_EXIT_STATUS(AFPERR_NOITEM); + default: + EC_EXIT_STATUS(AFPERR_MISC); + } } EC_STATUS(AFP_OK); @@ -1260,7 +1291,6 @@ static int set_acl(const struct vol *vol, acl_entry_t entry; acl_tag_t tag; int entry_id = ACL_FIRST_ENTRY; - int has_def_acl = 0; /* flags to indicate if the object has a minimal default acl and/or an extended * default acl. */ @@ -1354,7 +1384,6 @@ static int check_acl_access(const AFPObj *obj, int ret; uint32_t allowed_rights = 0; char *username = NULL; - uuidtype_t uuidtype; struct stat st; bstring parent = NULL; int is_dir; @@ -1362,6 +1391,8 @@ static int check_acl_access(const AFPObj *obj, LOG(log_maxdebug, logtype_afpd, "check_acl_access(dir: \"%s\", path: \"%s\", curdir: \"%s\", 0x%08x)", cfrombstr(dir->d_fullpath), path, getcwdpath(), requested_rights); + AFP_ASSERT(vol); + /* This check is not used anymore, as OS X Server seems to be ignoring too */ #if 0 /* Get uid or gid from UUID */ @@ -1379,7 +1410,7 @@ static int check_acl_access(const AFPObj *obj, } #endif - EC_ZERO_LOG_ERR(lstat(path, &st), AFPERR_PARAM); + EC_ZERO_LOG_ERR(ostat(path, &st, vol_syml_opt(vol)), AFPERR_PARAM); is_dir = !strcmp(path, "."); @@ -1389,7 +1420,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)); @@ -1422,7 +1453,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)); @@ -1576,10 +1607,10 @@ int afp_getacl(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size LOG(log_debug, logtype_afpd, "afp_getacl: client requested files owner user UUID"); if (NULL == (pw = getpwuid(s_path->st.st_uid))) { LOG(log_debug, logtype_afpd, "afp_getacl: local uid: %u", s_path->st.st_uid); - localuuid_from_id(rbuf, UUID_USER, s_path->st.st_uid); + localuuid_from_id((unsigned char *)rbuf, UUID_USER, s_path->st.st_uid); } else { LOG(log_debug, logtype_afpd, "afp_getacl: got uid: %d, name: %s", s_path->st.st_uid, pw->pw_name); - if ((ret = getuuidfromname(pw->pw_name, UUID_USER, rbuf)) != 0) + if ((ret = getuuidfromname(pw->pw_name, UUID_USER, (unsigned char *)rbuf)) != 0) return AFPERR_MISC; } rbuf += UUID_BINSIZE; @@ -1591,10 +1622,10 @@ int afp_getacl(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size LOG(log_debug, logtype_afpd, "afp_getacl: client requested files owner group UUID"); if (NULL == (gr = getgrgid(s_path->st.st_gid))) { LOG(log_debug, logtype_afpd, "afp_getacl: local gid: %u", s_path->st.st_gid); - localuuid_from_id(rbuf, UUID_GROUP, s_path->st.st_gid); + localuuid_from_id((unsigned char *)rbuf, UUID_GROUP, s_path->st.st_gid); } else { LOG(log_debug, logtype_afpd, "afp_getacl: got gid: %d, name: %s", s_path->st.st_gid, gr->gr_name); - if ((ret = getuuidfromname(gr->gr_name, UUID_GROUP, rbuf)) != 0) + if ((ret = getuuidfromname(gr->gr_name, UUID_GROUP, (unsigned char *)rbuf)) != 0) return AFPERR_MISC; } rbuf += UUID_BINSIZE; @@ -1726,9 +1757,8 @@ int afp_setacl(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size int acltoownermode(const AFPObj *obj, const struct vol *vol, char *path, struct stat *st, struct maccess *ma) { EC_INIT; - uint32_t rights = 0; - if ( ! (obj->options.flags & OPTION_ACL2MACCESS) + if ( ! (obj->options.flags & (OPTION_ACL2MACCESS | OPTION_ACL2MODE)) || ! (vol->v_flags & AFPVOL_ACLS)) return 0; @@ -1736,16 +1766,7 @@ int acltoownermode(const AFPObj *obj, const struct vol *vol, char *path, struct getcwdpath(), path, ma->ma_user); #ifdef HAVE_SOLARIS_ACLS - 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