PERFORCE change 144481 for review
Edward Tomasz Napierala
trasz at FreeBSD.org
Wed Jul 2 11:16:54 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=144481
Change 144481 by trasz at trasz_traszkan on 2008/07/02 11:16:14
Add support for the new ACLs to setfacl(1).
Affected files ...
.. //depot/projects/soc2008/trasz_nfs4acl/bin/setfacl/merge.c#2 edit
.. //depot/projects/soc2008/trasz_nfs4acl/bin/setfacl/remove.c#2 edit
.. //depot/projects/soc2008/trasz_nfs4acl/bin/setfacl/setfacl.c#3 edit
Differences ...
==== //depot/projects/soc2008/trasz_nfs4acl/bin/setfacl/merge.c#2 (text+ko) ====
@@ -42,6 +42,8 @@
merge_user_group(acl_entry_t *entry, acl_entry_t *entry_new)
{
acl_permset_t permset;
+ acl_extended_t extended;
+ acl_flag_t flags;
int have_entry;
uid_t *id, *id_new;
@@ -59,6 +61,18 @@
err(1, "acl_get_permset() failed");
if (acl_set_permset(*entry_new, permset) == -1)
err(1, "acl_set_permset() failed");
+
+ if (acl_type == ACL_TYPE_NFS4) {
+ if (acl_get_extended_np(*entry, &extended))
+ err(1, "acl_get_extended_np() failed");
+ if (acl_set_extended_np(*entry_new, extended))
+ err(1, "acl_set_extended_np() failed");
+ if (acl_get_flags_np(*entry, &flags))
+ err(1, "acl_get_flags_np() failed");
+ if (acl_set_flags_np(*entry_new, flags))
+ err(1, "acl_set_flags_np() failed");
+ }
+
have_entry = 1;
}
acl_free(id);
@@ -77,9 +91,11 @@
acl_permset_t permset;
acl_t acl_new;
acl_tag_t tag, tag_new;
+ acl_extended_t extended, extended_new;
+ acl_flag_t flags;
int entry_id, entry_id_new, have_entry;
- if (acl_type == ACL_TYPE_ACCESS)
+ if (acl_type == ACL_TYPE_ACCESS || acl_type == ACL_TYPE_NFS4)
acl_new = acl_dup(prev_acl[ACCESS_ACL]);
else
acl_new = acl_dup(prev_acl[DEFAULT_ACL]);
@@ -111,6 +127,19 @@
if (tag != tag_new)
continue;
+ /*
+ * For NFS4, in addition to "tag" and "id" we also
+ * compare "extended".
+ */
+ if (acl_type == ACL_TYPE_NFS4) {
+ if (acl_get_extended_np(entry, &extended))
+ err(1, "acl_get_extended_np() failed");
+ if (acl_get_extended_np(entry_new, &extended_new))
+ err(1, "acl_get_extended_np() failed");
+ if (extended != extended_new)
+ continue;
+ }
+
switch(tag) {
case ACL_USER:
case ACL_GROUP:
@@ -123,10 +152,22 @@
case ACL_GROUP_OBJ:
case ACL_OTHER:
case ACL_MASK:
+ case ACL_EVERYONE:
if (acl_get_permset(entry, &permset) == -1)
err(1, "acl_get_permset() failed");
if (acl_set_permset(entry_new, permset) == -1)
err(1, "acl_set_permset() failed");
+
+ if (acl_type == ACL_TYPE_NFS4) {
+ if (acl_get_extended_np(entry, &extended))
+ err(1, "acl_get_extended_np() failed");
+ if (acl_set_extended_np(entry_new, extended))
+ err(1, "acl_set_extended_np() failed");
+ if (acl_get_flags_np(entry, &flags))
+ err(1, "acl_get_flags_np() failed");
+ if (acl_set_flags_np(entry_new, flags))
+ err(1, "acl_set_flags_np() failed");
+ }
have_entry = 1;
break;
default:
@@ -138,16 +179,29 @@
/* if this entry has not been found, it must be new */
if (have_entry == 0) {
- if (acl_create_entry(&acl_new, &entry_new) == -1) {
- acl_free(acl_new);
- return (-1);
+
+ /*
+ * NFS4 ACL entries must be prepended to the ACL.
+ * Appending them at the end makes no sense, since
+ * in most cases they wouldn't even get evaluated.
+ */
+ if (acl_type == ACL_TYPE_NFS4) {
+ if (acl_create_entry_at_position_np(&acl_new, &entry_new, 0) == -1) {
+ acl_free(acl_new);
+ return (-1);
+ }
+ } else {
+ if (acl_create_entry(&acl_new, &entry_new) == -1) {
+ acl_free(acl_new);
+ return (-1);
+ }
}
if (acl_copy_entry(entry_new, entry) == -1)
err(1, "acl_copy_entry() failed");
}
}
- if (acl_type == ACL_TYPE_ACCESS) {
+ if (acl_type == ACL_TYPE_ACCESS || acl_type == ACL_TYPE_NFS4) {
acl_free(prev_acl[ACCESS_ACL]);
prev_acl[ACCESS_ACL] = acl_new;
} else {
==== //depot/projects/soc2008/trasz_nfs4acl/bin/setfacl/remove.c#2 (text+ko) ====
@@ -50,7 +50,7 @@
carried_error = 0;
- if (acl_type == ACL_TYPE_ACCESS)
+ if (acl_type == ACL_TYPE_ACCESS || acl_type == ACL_TYPE_NFS4)
acl_new = acl_dup(prev_acl[ACCESS_ACL]);
else
acl_new = acl_dup(prev_acl[DEFAULT_ACL]);
@@ -73,7 +73,7 @@
}
}
- if (acl_type == ACL_TYPE_ACCESS) {
+ if (acl_type == ACL_TYPE_ACCESS || acl_type == ACL_TYPE_NFS4) {
acl_free(prev_acl[ACCESS_ACL]);
prev_acl[ACCESS_ACL] = acl_new;
} else {
@@ -113,64 +113,17 @@
remove_ext(acl_t *prev_acl)
{
acl_t acl_new, acl_old;
- acl_entry_t entry, entry_new;
- acl_permset_t perm;
- acl_tag_t tag;
- int entry_id, have_mask_entry;
- if (acl_type == ACL_TYPE_ACCESS)
- acl_old = acl_dup(prev_acl[ACCESS_ACL]);
+ if (acl_type == ACL_TYPE_ACCESS || acl_type == ACL_TYPE_NFS4)
+ acl_old = prev_acl[ACCESS_ACL];
else
- acl_old = acl_dup(prev_acl[DEFAULT_ACL]);
- if (acl_old == NULL)
- err(1, "acl_dup() failed");
+ acl_old = prev_acl[DEFAULT_ACL];
- have_mask_entry = 0;
- acl_new = acl_init(ACL_MAX_ENTRIES);
+ acl_new = acl_strip_np(acl_old, !n_flag);
if (acl_new == NULL)
- err(1, "acl_init() failed");
- tag = ACL_UNDEFINED_TAG;
+ err(1, "acl_strip_np() failed");
- /* only save the default user/group/other entries */
- entry_id = ACL_FIRST_ENTRY;
- while (acl_get_entry(acl_old, entry_id, &entry) == 1) {
- entry_id = ACL_NEXT_ENTRY;
-
- if (acl_get_tag_type(entry, &tag) == -1)
- err(1, "acl_get_tag_type() failed");
-
- switch(tag) {
- case ACL_USER_OBJ:
- case ACL_GROUP_OBJ:
- case ACL_OTHER:
- if (acl_get_tag_type(entry, &tag) == -1)
- err(1, "acl_get_tag_type() failed");
- if (acl_get_permset(entry, &perm) == -1)
- err(1, "acl_get_permset() failed");
- if (acl_create_entry(&acl_new, &entry_new) == -1)
- err(1, "acl_create_entry() failed");
- if (acl_set_tag_type(entry_new, tag) == -1)
- err(1, "acl_set_tag_type() failed");
- if (acl_set_permset(entry_new, perm) == -1)
- err(1, "acl_get_permset() failed");
- if (acl_copy_entry(entry_new, entry) == -1)
- err(1, "acl_copy_entry() failed");
- break;
- case ACL_MASK:
- have_mask_entry = 1;
- break;
- default:
- break;
- }
- }
- if (have_mask_entry && n_flag == 0) {
- if (acl_calc_mask(&acl_new) == -1)
- err(1, "acl_calc_mask() failed");
- } else {
- have_mask = 1;
- }
-
- if (acl_type == ACL_TYPE_ACCESS) {
+ if (acl_type == ACL_TYPE_ACCESS || acl_type == ACL_TYPE_NFS4) {
acl_free(prev_acl[ACCESS_ACL]);
prev_acl[ACCESS_ACL] = acl_new;
} else {
==== //depot/projects/soc2008/trasz_nfs4acl/bin/setfacl/setfacl.c#3 (text+ko) ====
@@ -64,20 +64,26 @@
{
acl_t *acl;
struct stat sb;
+ int type;
if (stat(filename, &sb) == -1) {
warn("stat() of %s failed", filename);
return (NULL);
}
+ if (pathconf(filename, _PC_EXTENDED_SECURITY_NP))
+ type = ACL_TYPE_NFS4;
+ else
+ type = ACL_TYPE_ACCESS;
+
acl = zmalloc(sizeof(acl_t) * 2);
if (h_flag)
- acl[ACCESS_ACL] = acl_get_link_np(filename, ACL_TYPE_ACCESS);
+ acl[ACCESS_ACL] = acl_get_link_np(filename, type);
else
- acl[ACCESS_ACL] = acl_get_file(filename, ACL_TYPE_ACCESS);
+ acl[ACCESS_ACL] = acl_get_file(filename, type);
if (acl[ACCESS_ACL] == NULL)
err(1, "acl_get_file() failed");
- if (S_ISDIR(sb.st_mode)) {
+ if (S_ISDIR(sb.st_mode) && type != ACL_TYPE_NFS4) {
if (h_flag)
acl[DEFAULT_ACL] = acl_get_link_np(filename,
ACL_TYPE_DEFAULT);
@@ -210,6 +216,11 @@
local_error = 0;
+ if (acl_type != ACL_TYPE_DEFAULT && pathconf(file->filename, _PC_EXTENDED_SECURITY_NP))
+ acl_type = ACL_TYPE_NFS4;
+ else
+ acl_type = ACL_TYPE_ACCESS;
+
/* cycle through each option */
TAILQ_FOREACH(entry, &entrylist, next) {
if (local_error)
@@ -245,11 +256,14 @@
continue;
}
- if (acl_type == ACL_TYPE_ACCESS)
+ if (acl_type == ACL_TYPE_ACCESS || acl_type == ACL_TYPE_NFS4)
final_acl = acl[ACCESS_ACL];
else
final_acl = acl[DEFAULT_ACL];
+ if (acl_type == ACL_TYPE_NFS4)
+ need_mask = 0;
+
if (need_mask && (set_acl_mask(&final_acl) == -1)) {
warnx("failed to set ACL mask on %s", file->filename);
carried_error++;
More information about the p4-projects
mailing list