From owner-p4-projects@FreeBSD.ORG Wed Jul 2 11:03:40 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id E77461065676; Wed, 2 Jul 2008 11:03:39 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A7D101065673 for ; Wed, 2 Jul 2008 11:03:39 +0000 (UTC) (envelope-from trasz@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 949148FC17 for ; Wed, 2 Jul 2008 11:03:39 +0000 (UTC) (envelope-from trasz@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m62B3dUI013868 for ; Wed, 2 Jul 2008 11:03:39 GMT (envelope-from trasz@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m62B3d0O013866 for perforce@freebsd.org; Wed, 2 Jul 2008 11:03:39 GMT (envelope-from trasz@freebsd.org) Date: Wed, 2 Jul 2008 11:03:39 GMT Message-Id: <200807021103.m62B3d0O013866@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to trasz@freebsd.org using -f From: Edward Tomasz Napierala To: Perforce Change Reviews Cc: Subject: PERFORCE change 144478 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 02 Jul 2008 11:03:40 -0000 http://perforce.freebsd.org/chv.cgi?CH=144478 Change 144478 by trasz@trasz_traszkan on 2008/07/02 11:02:45 NFSv4 ACLs, libc part. Affected files ... .. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/Makefile.inc#2 edit .. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/Symbol.map#2 edit .. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_branding.c#1 add .. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_calc_mask.c#2 edit .. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_copy.c#2 edit .. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_delete.c#2 edit .. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_delete_entry.c#2 edit .. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_entry.c#2 edit .. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_flags_nfs4.c#1 add .. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_flags_nfs4.h#1 add .. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_from_text.c#3 edit .. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_from_text_nfs4.c#1 add .. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_get.c#3 edit .. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_init.c#2 edit .. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_perm.c#2 edit .. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_set.c#3 edit .. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_strip.c#1 add .. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_support.c#2 edit .. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_support.h#2 edit .. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_to_text.c#2 edit .. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_to_text_nfs4.c#1 add .. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_valid.c#2 edit Differences ... ==== //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/Makefile.inc#2 (text+ko) ==== @@ -7,14 +7,20 @@ acl_delete.c \ acl_delete_entry.c \ acl_entry.c \ + acl_flags_nfs4.c \ acl_free.c \ acl_from_text.c \ + acl_from_text_nfs4.c \ acl_get.c \ acl_init.c \ acl_perm.c \ acl_set.c \ acl_support.c \ + acl_branding.c \ + acl_strip.c \ acl_to_text.c \ + acl_to_text_nfs4.c \ + acl_strip.c \ acl_valid.c \ extattr.c \ mac.c \ ==== //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/Symbol.map#2 (text) ==== @@ -13,12 +13,16 @@ acl_delete_link_np; acl_delete_fd_np; acl_delete_entry; + acl_delete_entry_at_position_np; acl_create_entry; + acl_create_entry_at_position_np; acl_get_entry; acl_free; acl_from_text; acl_get_file; acl_get_link_np; + acl_get_extended_np; + acl_get_flags_np; acl_get_fd; acl_get_fd_np; acl_get_perm_np; @@ -30,6 +34,8 @@ acl_add_perm; acl_clear_perms; acl_delete_perm; + acl_set_extended_np; + acl_set_flags_np; acl_set_file; acl_set_link_np; acl_set_fd; @@ -42,6 +48,8 @@ acl_valid_file_np; acl_valid_link_np; acl_valid_fd_np; + acl_is_trivial_np; + acl_strip_np; extattr_namespace_to_string; extattr_string_to_namespace; mac_reload; ==== //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_calc_mask.c#2 (text+ko) ==== @@ -35,6 +35,8 @@ #include #include +#include "acl_support.h" + /* * acl_calc_mask() (23.4.2): calculate and set the permissions * associated with the ACL_MASK ACL entry. If the ACL already @@ -48,6 +50,11 @@ acl_t acl_new; int i, mask_mode, mask_num; + if (!_acl_must_be_posix(*acl_p)) { + errno = EINVAL; + return (-1); + } + /* * (23.4.2.4) requires acl_p to point to a pointer to a valid ACL. * Since one of the primary reasons to use this function would be ==== //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_copy.c#2 (text+ko) ==== @@ -35,6 +35,8 @@ #include #include +#include "acl_support.h" + /* * acl_copy_entry() (23.4.4): copy the contents of ACL entry src_d to * ACL entry dest_d @@ -48,9 +50,25 @@ return (-1); } - dest_d->ae_tag = src_d->ae_tag; - dest_d->ae_id = src_d->ae_id; + if (_entry_is_posix(src_d)) { + if (!_entry_must_be_posix(dest_d)) { + errno = EINVAL; + return (-1); + } + } + + if (_entry_is_nfs4(src_d)) { + if (!_entry_must_be_nfs4(dest_d)) { + errno = EINVAL; + return (-1); + } + } + + dest_d->ae_tag = src_d->ae_tag; + dest_d->ae_id = src_d->ae_id; dest_d->ae_perm = src_d->ae_perm; + dest_d->ae_extended = src_d->ae_extended; + dest_d->ae_flags = src_d->ae_flags; return (0); } ==== //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_delete.c#2 (text+ko) ==== @@ -38,6 +38,8 @@ #include "un-namespace.h" #include +#include "acl_support.h" + int acl_delete_def_file(const char *path_p) { @@ -56,6 +58,8 @@ acl_delete_file_np(const char *path_p, acl_type_t type) { + type = _acl_type_unold(type); + return (__acl_delete_file(path_p, type)); } @@ -63,6 +67,8 @@ acl_delete_link_np(const char *path_p, acl_type_t type) { + type = _acl_type_unold(type); + return (__acl_delete_link(path_p, type)); } @@ -71,5 +77,7 @@ acl_delete_fd_np(int filedes, acl_type_t type) { + type = _acl_type_unold(type); + return (___acl_delete_fd(filedes, type)); } ==== //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_delete_entry.c#2 (text+ko) ==== @@ -33,6 +33,40 @@ #include "un-namespace.h" #include #include +#include + +#include "acl_support.h" + +static int +_entry_matches(const acl_entry_t a, const acl_entry_t b) +{ + /* + * There is a semantical difference here between NFSv4 and POSIX + * draft ACLs. In POSIX, there may be only one entry for the particular + * user or group. In NFSv4 ACL, there may be any number of them. We're + * trying to be more specific here in that case. + * + * XXX: The proper way would be to remove them by entry number. + */ + if (_entry_is_nfs4(a)) { + if (a->ae_tag != b->ae_tag || a->ae_extended != b->ae_extended) + return (0); + + /* If ae_ids matter, compare them as well. */ + if (a->ae_tag == ACL_USER || a->ae_tag == ACL_GROUP) { + if (a->ae_id != b->ae_id) + return (0); + } + + return (1); + + } else { + if ((a->ae_tag == b->ae_tag) && (a->ae_id == b->ae_id)) + return (1); + } + + return (0); +} /* * acl_delete_entry() (23.4.9): remove the ACL entry indicated by entry_d @@ -42,7 +76,7 @@ acl_delete_entry(acl_t acl, acl_entry_t entry_d) { struct acl *acl_int; - int i; + int i, found = 0; if (acl == NULL || entry_d == NULL) { errno = EINVAL; @@ -51,15 +85,18 @@ acl_int = &acl->ats_acl; + if (_entry_is_nfs4(entry_d) != _acl_is_nfs4(acl)) { + errno = EINVAL; + return (-1); + } + if ((acl->ats_acl.acl_cnt < 1) || (acl->ats_acl.acl_cnt > ACL_MAX_ENTRIES)) { errno = EINVAL; return (-1); } for (i = 0; i < acl->ats_acl.acl_cnt; i++) { - /* if this is our entry... */ - if ((acl->ats_acl.acl_entry[i].ae_tag == entry_d->ae_tag) && - (acl->ats_acl.acl_entry[i].ae_id == entry_d->ae_id)) { + if (_entry_matches(&(acl->ats_acl.acl_entry[i]), entry_d)) { /* ...shift the remaining entries... */ for (; i < acl->ats_acl.acl_cnt - 1; ++i) acl->ats_acl.acl_entry[i] = @@ -68,12 +105,57 @@ acl->ats_acl.acl_cnt--; bzero(&acl->ats_acl.acl_entry[i], sizeof(struct acl_entry)); + /* XXX: We need this because of the bzero above. */ + _acl_fixup_entry_pointers(acl); acl->ats_cur_entry = 0; - return (0); + + /* Continue with the loop to remove all maching entries. */ + found = 1; } } + if (found) + return (0); errno = EINVAL; return (-1); } + +int +acl_delete_entry_at_position_np(acl_t acl, int offset) +{ + struct acl *acl_int; + int i; + + if (acl == NULL) { + errno = EINVAL; + return (-1); + } + + acl_int = &acl->ats_acl; + + if (offset < 0 || offset >= acl_int->acl_cnt) { + errno = EINVAL; + return (-1); + } + + if ((acl->ats_acl.acl_cnt < 1) || + (acl->ats_acl.acl_cnt > ACL_MAX_ENTRIES)) { + errno = EINVAL; + return (-1); + } + + /* ...shift the remaining entries... */ + for (i = offset; i < acl->ats_acl.acl_cnt - 1; ++i) + acl->ats_acl.acl_entry[i] = + acl->ats_acl.acl_entry[i+1]; + /* ...drop the count and zero the unused entry... */ + acl->ats_acl.acl_cnt--; + bzero(&acl->ats_acl.acl_entry[i], + sizeof(struct acl_entry)); + /* XXX: We need this because of the bzero above. */ + _acl_fixup_entry_pointers(acl); + acl->ats_cur_entry = 0; + + return (0); +} ==== //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_entry.c#2 (text+ko) ==== @@ -51,7 +51,8 @@ acl_int = &(*acl_p)->ats_acl; - if ((acl_int->acl_cnt >= ACL_MAX_ENTRIES) || (acl_int->acl_cnt < 0)) { + /* XXX: There was a bug here. */ + if ((acl_int->acl_cnt + 1 >= ACL_MAX_ENTRIES) || (acl_int->acl_cnt < 0)) { errno = EINVAL; return (-1); } @@ -61,6 +62,50 @@ (**entry_p).ae_tag = ACL_UNDEFINED_TAG; (**entry_p).ae_id = ACL_UNDEFINED_ID; (**entry_p).ae_perm = ACL_PERM_NONE; + (**entry_p).ae_acl = acl_int; + (**entry_p).ae_flags= 0; + + (*acl_p)->ats_cur_entry = 0; + + return (0); +} + +int +acl_create_entry_at_position_np(acl_t *acl_p, acl_entry_t *entry_p, int offset) +{ + int i; + struct acl *acl_int; + + if (acl_p == NULL) { + errno = EINVAL; + return (-1); + } + + acl_int = &(*acl_p)->ats_acl; + + if ((acl_int->acl_cnt + 1 >= ACL_MAX_ENTRIES) || (acl_int->acl_cnt < 0)) { + errno = EINVAL; + return (-1); + } + + if (offset < 0 || offset >= acl_int->acl_cnt) { + errno = EINVAL; + return (-1); + } + + /* Make room for the new entry. */ + for (i = acl_int->acl_cnt; i > offset; i--) + acl_int->acl_entry[i] = acl_int->acl_entry[i - 1]; + + acl_int->acl_cnt++; + + *entry_p = &acl_int->acl_entry[offset]; + + (**entry_p).ae_tag = ACL_UNDEFINED_TAG; + (**entry_p).ae_id = ACL_UNDEFINED_ID; + (**entry_p).ae_perm = ACL_PERM_NONE; + (**entry_p).ae_acl = acl_int; + (**entry_p).ae_flags= 0; (*acl_p)->ats_cur_entry = 0; @@ -90,6 +135,7 @@ if (acl->ats_cur_entry >= acl->ats_acl.acl_cnt) return 0; *entry_p = &acl_int->acl_entry[acl->ats_cur_entry++]; + (*entry_p)->ae_acl = acl_int; return (1); } ==== //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_from_text.c#3 (text+ko) ==== @@ -40,46 +40,16 @@ #include #include #include +#include #include "acl_support.h" static int _posix1e_acl_name_to_id(acl_tag_t tag, char *name, uid_t *id); static acl_tag_t acl_string_to_tag(char *tag, char *qualifier); -static char *string_skip_whitespace(char *string); -static void string_trim_trailing_whitespace(char *string); -static char * -string_skip_whitespace(char *string) -{ - - while (*string && ((*string == ' ') || (*string == '\t'))) { - string++; - } - return (string); -} - -static void -string_trim_trailing_whitespace(char *string) -{ - char *end; +int _nfs4_acl_entry_from_text(acl_t aclp, char *entry); +int _text_could_be_nfs4_acl(const char *entry); - if (*string == '\0') - return; - - end = string + strlen(string) - 1; - - while (end != string) { - if ((*end == ' ') || (*end == '\t')) { - *end = '\0'; - end--; - } else { - return; - } - } - - return; -} - static acl_tag_t acl_string_to_tag(char *tag, char *qualifier) { @@ -118,6 +88,8 @@ uid_t id; int error; + assert(_acl_is_posix(aclp)); + /* Split into three ':' delimited fields. */ tag = strsep(&entry, ":"); if (tag == NULL) { @@ -194,6 +166,25 @@ return (0); } +static int +_text_is_nfs4_entry(const char *entry) +{ + int count = 0; + + assert(strlen(entry) > 0); + + while (*entry != '\0') { + if (*entry == ':' || *entry == '@') + count++; + entry++; + } + + if (count <= 2) + return (0); + + return (1); +} + /* * acl_from_text -- Convert a string into an ACL. * Postpone most validity checking until the end and call acl_valid() to do @@ -211,7 +202,7 @@ if (mybuf_p == NULL) return(NULL); - acl = acl_init(3); + acl = acl_init(3); /* XXX: WTF, 3? */ if (acl == NULL) { free(mybuf_p); return(NULL); @@ -226,7 +217,21 @@ /* Inner loop: delimit at ',' boundaries. */ while ((entry = strsep(¬comment, ","))) { - error = _posix1e_acl_entry_from_text(acl, entry); + + /* Skip empty lines. */ + if (strlen(string_skip_whitespace(entry)) == 0) + continue; + + if (_acl_is_unknown(acl) && _text_is_nfs4_entry(entry)) + _acl_must_be_nfs4(acl); + else + _acl_must_be_posix(acl); + + if (_acl_is_nfs4(acl)) + error = _nfs4_acl_entry_from_text(acl, entry); + else + error = _posix1e_acl_entry_from_text(acl, entry); + if (error) goto error_label; } ==== //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_get.c#3 (text+ko) ==== @@ -49,6 +49,9 @@ #include #include #include +#include + +#include "acl_support.h" acl_t acl_get_file(const char *path_p, acl_type_t type) @@ -60,12 +63,17 @@ if (aclp == NULL) return (NULL); + type = _acl_type_unold(type); + error = __acl_get_file(path_p, type, &aclp->ats_acl); if (error) { acl_free(aclp); return (NULL); } + _acl_fixup_entry_pointers(aclp); + _acl_brand_from_type(aclp, type); + return (aclp); } @@ -79,18 +87,26 @@ if (aclp == NULL) return (NULL); + type = _acl_type_unold(type); + error = __acl_get_link(path_p, type, &aclp->ats_acl); if (error) { acl_free(aclp); return (NULL); } + _acl_fixup_entry_pointers(aclp); + _acl_brand_from_type(aclp, type); + return (aclp); } acl_t acl_get_fd(int fd) { + if (fpathconf(fd, _PC_EXTENDED_SECURITY_NP)) + return (acl_get_fd_np(fd, ACL_TYPE_NFS4)); + return (acl_get_fd_np(fd, ACL_TYPE_ACCESS)); } @@ -104,15 +120,23 @@ if (aclp == NULL) return (NULL); + type = _acl_type_unold(type); + error = ___acl_get_fd(fd, type, &aclp->ats_acl); if (error) { acl_free(aclp); return (NULL); } + _acl_fixup_entry_pointers(aclp); + _acl_brand_from_type(aclp, type); + return (aclp); } +/* + * XXX: Possible binary compatibility problem; acl_perm_t definition changed. + */ int acl_get_perm_np(acl_permset_t permset_d, acl_perm_t perm) { @@ -200,3 +224,40 @@ return (0); } + +int +acl_get_extended_np(acl_entry_t entry_d, acl_extended_t *extended_p) +{ + if (entry_d == NULL || extended_p == NULL) { + errno = EINVAL; + return (-1); + } + + if (!_entry_is_nfs4(entry_d)) { + errno = EINVAL; + return (-1); + } + + *extended_p = entry_d->ae_extended; + + return (0); +} + +int +acl_get_flags_np(acl_entry_t entry_d, acl_flag_t *flags_p) +{ + if (entry_d == NULL || flags_p == NULL) { + errno = EINVAL; + return (-1); + } + + if (!_entry_is_nfs4(entry_d)) { + errno = EINVAL; + return (-1); + } + + *flags_p = entry_d->ae_flags; + + return (0); +} + ==== //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_init.c#2 (text+ko) ==== @@ -39,6 +39,8 @@ #include #include +#include "acl_support.h" + acl_t acl_init(int count) { @@ -57,6 +59,11 @@ if (acl != NULL) bzero(acl, sizeof(struct acl_t_struct)); + acl->ats_acl.acl_brand = ACL_BRAND_UNKNOWN; + acl->ats_acl.acl_magic = ACL_MAGIC; + + _acl_fixup_entry_pointers(acl); + return (acl); } @@ -72,5 +79,7 @@ acl_new->ats_cur_entry = 0; } + _acl_fixup_entry_pointers(acl_new); + return (acl_new); } ==== //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_perm.c#2 (text+ko) ==== @@ -39,6 +39,9 @@ * acl_add_perm() (23.4.1): add the permission contained in perm to the * permission set permset_d */ +/* + * XXX: Possible binary compatibility problem; acl_perm_t definition changed. + */ int acl_add_perm(acl_permset_t permset_d, acl_perm_t perm) { @@ -79,6 +82,9 @@ * acl_delete_perm() (23.4.10): remove the permission in perm from the * permission set permset_d */ +/* + * XXX: Possible binary compatibility problem; acl_perm_t definition changed. + */ int acl_delete_perm(acl_permset_t permset_d, acl_perm_t perm) { ==== //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_set.c#3 (text+ko) ==== @@ -40,6 +40,7 @@ #include #include #include +#include #include "acl_support.h" @@ -58,6 +59,15 @@ errno = EINVAL; return (-1); } + + /* This is for old binaries using new libc. */ + type = _acl_type_unold(type); + + if (_acl_type_not_valid_for_acl(acl, type)) { + errno = EINVAL; + return (-1); + } + if (_posix1e_acl(acl, type)) { error = _posix1e_acl_sort(acl); if (error) { @@ -80,6 +90,14 @@ errno = EINVAL; return (-1); } + + type = _acl_type_unold(type); + + if (_acl_type_not_valid_for_acl(acl, type)) { + errno = EINVAL; + return (-1); + } + if (_posix1e_acl(acl, type)) { error = _posix1e_acl_sort(acl); if (error) { @@ -96,6 +114,9 @@ int acl_set_fd(int fd, acl_t acl) { + if (fpathconf(fd, _PC_EXTENDED_SECURITY_NP)) + return (acl_set_fd_np(fd, acl, ACL_TYPE_NFS4)); + return (acl_set_fd_np(fd, acl, ACL_TYPE_ACCESS)); } @@ -104,6 +125,18 @@ { int error; + if (acl == NULL) { + errno = EINVAL; + return (-1); + } + + type = _acl_type_unold(type); + + if (_acl_type_not_valid_for_acl(acl, type)) { + errno = EINVAL; + return (-1); + } + if (_posix1e_acl(acl, type)) { error = _posix1e_acl_sort(acl); if (error) { @@ -130,6 +163,19 @@ return (-1); } + if ((*permset_d & ACL_POSIX1E_BITS) != *permset_d) { + + if ((*permset_d & ACL_NFS4_PERM_BITS) != *permset_d) { + errno = EINVAL; + return (-1); + } + + if (!_entry_must_be_nfs4(entry_d)) { + errno = EINVAL; + return (-1); + } + } + entry_d->ae_perm = *permset_d; return (0); @@ -173,6 +219,15 @@ return (-1); } + if ((tag_type == ACL_OTHER || tag_type == ACL_MASK) && + !_entry_must_be_posix(entry_d)) { + errno = EINVAL; + return (-1); + } else if (tag_type == ACL_EVERYONE && !_entry_must_be_nfs4(entry_d)) { + errno = EINVAL; + return (-1); + } + switch(tag_type) { case ACL_USER_OBJ: case ACL_USER: @@ -180,6 +235,7 @@ case ACL_GROUP: case ACL_MASK: case ACL_OTHER: + case ACL_EVERYONE: entry_d->ae_tag = tag_type; return (0); } @@ -187,3 +243,53 @@ errno = EINVAL; return (-1); } + +int +acl_set_extended_np(acl_entry_t entry_d, acl_extended_t extended) +{ + if (entry_d == NULL) { + errno = EINVAL; + return (-1); + } + + if (!_entry_must_be_nfs4(entry_d)) { + errno = EINVAL; + return (-1); + } + + switch (extended) { + case ACL_EXTENDED_ALLOW: + case ACL_EXTENDED_DENY: + case ACL_EXTENDED_AUDIT: + case ACL_EXTENDED_ALARM: + + entry_d->ae_extended = extended; + return (0); + } + + errno = EINVAL; + return (-1); +} + +int +acl_set_flags_np(acl_entry_t entry_d, acl_flag_t flags) +{ + if (entry_d == NULL) { + errno = EINVAL; + return (-1); + } + + if ((flags & ACL_FLAGS_BITS) != flags) { + errno = EINVAL; + return (-1); + } + + if (!_entry_must_be_nfs4(entry_d)) { + errno = EINVAL; + return (-1); + } + + entry_d->ae_flags = flags; + return (0); +} + ==== //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_support.c#2 (text+ko) ==== @@ -40,6 +40,8 @@ #include #include #include +#include +#include #include "acl_support.h" @@ -49,6 +51,51 @@ #define ACL_STRING_PERM_NONE '-' /* + * Convert "old" type - ACL_TYPE_{ACCESS,DEFAULT}_OLD - into its "new" + * counterpart. It's neccessary for the old (pre-NFS4 ACLs) binaries + * to work with new libc and kernel. Fixing "type" for old binaries with + * old libc and new kernel is being done by kern/vfs_acl.c:type_unold(). + */ +int +_acl_type_unold(acl_type_t type) +{ + if (type == ACL_TYPE_ACCESS_OLD) + return (ACL_TYPE_ACCESS); + + if (type == ACL_TYPE_DEFAULT_OLD) + return (ACL_TYPE_DEFAULT); + + return (type); +} + +/* + * Return 0, if both ACLs are identical. + */ +int +_acl_differs(const acl_t a, const acl_t b) +{ + int i; + struct acl_entry *entrya, *entryb; + + if (a->ats_acl.acl_cnt != b->ats_acl.acl_cnt) + return (1); + + for (i = 0; i < b->ats_acl.acl_cnt; i++) { + entrya = &(a->ats_acl.acl_entry[i]); + entryb = &(b->ats_acl.acl_entry[i]); + + if (entrya->ae_tag != entryb->ae_tag || + entrya->ae_id != entryb->ae_id || + entrya->ae_perm != entryb->ae_perm || + entrya->ae_extended != entryb->ae_extended || + entrya->ae_flags != entryb->ae_flags) + return (1); + } + + return (0); +} + +/* * _posix1e_acl_entry_compare -- compare two acl_entry structures to * determine the order they should appear in. Used by _posix1e_acl_sort to * sort ACL entries into the kernel-desired order -- i.e., the order useful @@ -59,6 +106,9 @@ static int _posix1e_acl_entry_compare(struct acl_entry *a, struct acl_entry *b) { + assert(_entry_is_posix(a)); + assert(_entry_is_posix(b)); + /* * First, sort between tags -- conveniently defined in the correct * order for verification. @@ -101,6 +151,9 @@ acl_int = &acl->ats_acl; + /* XXX: */ + assert(_entry_is_posix(&(acl->ats_acl.acl_entry[3]))); + qsort(&acl_int->acl_entry[0], acl_int->acl_cnt, sizeof(struct acl_entry), (compare) _posix1e_acl_entry_compare); @@ -115,6 +168,8 @@ int _posix1e_acl(acl_t acl, acl_type_t type) { + if (!_acl_is_posix(acl)) + return (0); return ((type == ACL_TYPE_ACCESS) || (type == ACL_TYPE_DEFAULT)); } @@ -382,3 +437,37 @@ return (0); } + +char * +string_skip_whitespace(char *string) +{ + + while (*string && ((*string == ' ') || (*string == '\t'))) { + string++; + } + return (string); +} + +void +string_trim_trailing_whitespace(char *string) +{ + char *end; + + if (*string == '\0') + return; + + end = string + strlen(string) - 1; + + while (end != string) { + if ((*end == ' ') || (*end == '\t')) { + *end = '\0'; + end--; + } else { + return; + } + } + + return; +} + + ==== //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_support.h#2 (text+ko) ==== >>> TRUNCATED FOR MAIL (1000 lines) <<<