]> git.ipfire.org Git - people/arne_f/ipfire-3.x.git/blame - acl/patches/acl-2.2.47-nfs4.patch
autoconf: updated to 2.69.
[people/arne_f/ipfire-3.x.git] / acl / patches / acl-2.2.47-nfs4.patch
CommitLineData
a8e75dea
MT
1--- /dev/null 2007-08-22 11:21:03.626521839 -0400
2+++ acl-2.2.39/libacl/acl_nfs4_get_who.c 2007-08-22 12:02:13.000000000 -0400
3@@ -0,0 +1,103 @@
4+/*
5+ * NFSv4 ACL Code
6+ * Read the who value from the ace and return its type and optionally
7+ * its value.
8+ *
9+ * Ace is a reference to the ace to extract the who value from.
10+ * Type is a reference where the value of the whotype will be stored.
11+ * Who is a double reference that should either be passed as NULL
12+ * (and thus no who string will be returned) or as a pointer to a
13+ * char* where the who string will be allocated. This string must be
14+ * freed by the caller.
15+ *
16+ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
17+ * All rights reserved.
18+ *
19+ * Nathaniel Gallaher <ngallahe@umich.edu>
20+ *
21+ * Redistribution and use in source and binary forms, with or without
22+ * modification, are permitted provided that the following conditions
23+ * are met:
24+ *
25+ * 1. Redistributions of source code must retain the above copyright
26+ * notice, this list of conditions and the following disclaimer.
27+ * 2. Redistributions in binary form must reproduce the above copyright
28+ * notice, this list of conditions and the following disclaimer in the
29+ * documentation and/or other materials provided with the distribution.
30+ * 3. Neither the name of the University nor the names of its
31+ * contributors may be used to endorse or promote products derived
32+ * from this software without specific prior written permission.
33+ *
34+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
35+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
36+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
38+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
39+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
40+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
41+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
42+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
43+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
44+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45+ */
46+
47+#include "libacl_nfs4.h"
48+
49+int acl_nfs4_get_who(struct nfs4_ace* ace, int* type, char** who)
50+{
51+ int itype;
52+ char* iwho = NULL;
53+ int wholen;
54+
55+ if(ace == NULL || ace->who == NULL)
56+ goto inval_failed;
57+
58+ itype = acl_nfs4_get_whotype(ace->who);
59+
60+ if(type != NULL) {
61+ *type = itype;
62+ }
63+
64+
65+ if(who == NULL)
66+ return 0;
67+
68+ switch(itype)
69+ {
70+ case NFS4_ACL_WHO_NAMED:
71+ iwho = ace->who;
72+ break;
73+ case NFS4_ACL_WHO_OWNER:
74+ iwho = NFS4_ACL_WHO_OWNER_STRING;
75+ break;
76+ case NFS4_ACL_WHO_GROUP:
77+ iwho = NFS4_ACL_WHO_GROUP_STRING;
78+ break;
79+ case NFS4_ACL_WHO_EVERYONE:
80+ iwho = NFS4_ACL_WHO_EVERYONE_STRING;
81+ break;
82+ default:
83+ goto inval_failed;
84+ }
85+
86+ wholen = strlen(iwho);
87+ if(wholen < 0)
88+ goto inval_failed;
89+
90+ (*who) = (char *) malloc(sizeof(char) * (wholen + 1));
91+ if((*who) == NULL) {
92+ errno = ENOMEM;
93+ goto failed;
94+ }
95+
96+ strcpy((*who), iwho);
97+
98+ return 0;
99+
100+inval_failed:
101+ errno = EINVAL;
102+
103+failed:
104+ return -1;
105+}
106+
107--- /dev/null 2007-08-22 11:21:03.626521839 -0400
108+++ acl-2.2.39/libacl/acl_nfs4_add_ace.c 2007-08-22 12:02:13.000000000 -0400
109@@ -0,0 +1,83 @@
110+/*
111+ * NFSv4 ACL Code
112+ * Add an ace to the acl
113+ *
114+ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
115+ * All rights reserved.
116+ *
117+ * Marius Aamodt Eriksen <marius@umich.edu>
118+ * J. Bruce Fields <bfields@umich.edu>
119+ * Nathaniel Gallaher <ngallahe@umich.edu>
120+ * Jeff Sedlak <jsedlak@umich.edu>
121+ *
122+ * Redistribution and use in source and binary forms, with or without
123+ * modification, are permitted provided that the following conditions
124+ * are met:
125+ *
126+ * 1. Redistributions of source code must retain the above copyright
127+ * notice, this list of conditions and the following disclaimer.
128+ * 2. Redistributions in binary form must reproduce the above copyright
129+ * notice, this list of conditions and the following disclaimer in the
130+ * documentation and/or other materials provided with the distribution.
131+ * 3. Neither the name of the University nor the names of its
132+ * contributors may be used to endorse or promote products derived
133+ * from this software without specific prior written permission.
134+ *
135+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
136+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
137+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
138+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
139+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
140+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
141+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
142+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
143+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
144+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
145+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
146+ */
147+
148+#include "libacl_nfs4.h"
149+
150+int
151+acl_nfs4_add_ace(struct nfs4_acl *acl, u32 type, u32 flag, u32 access_mask,
152+ int whotype, char* who)
153+{
154+ struct nfs4_ace *ace;
155+ int result;
156+
157+ if(acl == NULL)
158+ {
159+ errno = EINVAL;
160+ return -1;
161+ }
162+
163+ if ((ace = malloc(sizeof(*ace))) == NULL)
164+ {
165+ errno = ENOMEM;
166+ return -1;
167+ }
168+
169+ ace->type = type;
170+ ace->flag = flag;
171+
172+ if( type == NFS4_ACE_ACCESS_DENIED_ACE_TYPE )
173+ access_mask = access_mask & ~(NFS4_ACE_MASK_IGNORE);
174+
175+
176+ /* Castrate delete_child if we aren't a directory */
177+ if (!acl->is_directory)
178+ access_mask &= ~NFS4_ACE_DELETE_CHILD;
179+
180+
181+ ace->access_mask = access_mask & NFS4_ACE_MASK_ALL;
182+
183+ result = acl_nfs4_set_who(ace, whotype, who);
184+ if(result < 0)
185+ return -1;
186+
187+ TAILQ_INSERT_TAIL(&acl->ace_head, ace, l_ace);
188+ acl->naces++;
189+
190+ return 0;
191+}
192+
193--- /dev/null 2007-08-22 11:21:03.626521839 -0400
194+++ acl-2.2.39/libacl/acl_nfs4_get_whotype.c 2007-08-22 12:02:13.000000000 -0400
195@@ -0,0 +1,60 @@
196+/*
197+ * NFSv4 ACL Code
198+ * Get the whotype of the who string passed
199+ *
200+ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
201+ * All rights reserved.
202+ *
203+ * Marius Aamodt Eriksen <marius@umich.edu>
204+ * J. Bruce Fields <bfields@umich.edu>
205+ * Nathaniel Gallaher <ngallahe@umich.edu>
206+ * Jeff Sedlak <jsedlak@umich.edu>
207+ *
208+ * Redistribution and use in source and binary forms, with or without
209+ * modification, are permitted provided that the following conditions
210+ * are met:
211+ *
212+ * 1. Redistributions of source code must retain the above copyright
213+ * notice, this list of conditions and the following disclaimer.
214+ * 2. Redistributions in binary form must reproduce the above copyright
215+ * notice, this list of conditions and the following disclaimer in the
216+ * documentation and/or other materials provided with the distribution.
217+ * 3. Neither the name of the University nor the names of its
218+ * contributors may be used to endorse or promote products derived
219+ * from this software without specific prior written permission.
220+ *
221+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
222+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
223+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
224+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
225+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
226+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
227+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
228+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
229+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
230+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
231+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
232+ */
233+
234+#include "libacl_nfs4.h"
235+
236+inline int
237+acl_nfs4_get_whotype(char *p)
238+{
239+ if(0 == strcmp(p, NFS4_ACL_WHO_OWNER_STRING) &&
240+ strlen(p) == strlen(NFS4_ACL_WHO_OWNER_STRING)) {
241+ return NFS4_ACL_WHO_OWNER;
242+ }
243+ if(0 == strcmp(p, NFS4_ACL_WHO_GROUP_STRING) &&
244+ strlen(p) == strlen(NFS4_ACL_WHO_GROUP_STRING)) {
245+ return NFS4_ACL_WHO_GROUP;
246+ }
247+ if(0 == strcmp(p, NFS4_ACL_WHO_EVERYONE_STRING) &&
248+ strlen(p) == strlen(NFS4_ACL_WHO_EVERYONE_STRING)) {
249+ return NFS4_ACL_WHO_EVERYONE;
250+ }
251+
252+ return NFS4_ACL_WHO_NAMED;
253+}
254+
255+
256--- /dev/null 2007-08-22 11:21:03.626521839 -0400
257+++ acl-2.2.39/libacl/acl_nfs4_free.c 2007-08-22 12:02:13.000000000 -0400
258@@ -0,0 +1,61 @@
259+/*
260+ * Copyright (c) 2004 The Regents of the University of Michigan.
261+ * All rights reserved.
262+ *
263+ * Marius Aamodt Eriksen <marius@umich.edu>
264+ * J. Bruce Fields <bfields@umich.edu>
265+ * Nathaniel Gallaher <ngallahe@umich.edu>
266+ * Jeff Sedlak <jsedlak@umich.edu>
267+ *
268+ * Redistribution and use in source and binary forms, with or without
269+ * modification, are permitted provided that the following conditions
270+ * are met:
271+ *
272+ * 1. Redistributions of source code must retain the above copyright
273+ * notice, this list of conditions, the following disclaimer, and
274+ * any and all other licensing or copyright notices included in
275+ * any files in this distribution.
276+ * 2. Redistributions in binary form must reproduce the above copyright
277+ * notice, this list of conditions and the following disclaimer in the
278+ * documentation and/or other materials provided with the distribution.
279+ * 3. Neither the name of the University nor the names of its
280+ * contributors may be used to endorse or promote products derived
281+ * from this software without specific prior written permission.
282+ *
283+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
284+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
285+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
286+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
287+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
288+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
289+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
290+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
291+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
292+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
293+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
294+ *
295+ */
296+
297+#include "libacl_nfs4.h"
298+
299+void
300+acl_nfs4_free(struct nfs4_acl *acl)
301+{
302+ struct nfs4_ace *ace;
303+
304+ if (!acl)
305+ return;
306+
307+ while (!TAILQ_IS_EMPTY(acl->ace_head)) {
308+ ace = (acl)->ace_head.tqh_first;
309+
310+ TAILQ_REMOVE( &(acl->ace_head), ace, l_ace);
311+ free(ace->who);
312+ free(ace);
313+ }
314+
315+ free(acl);
316+
317+ return;
318+}
319+
320--- /dev/null 2007-08-22 11:21:03.626521839 -0400
321+++ acl-2.2.39/libacl/acl_n4tp_acl_trans.c 2007-08-22 12:02:13.000000000 -0400
322@@ -0,0 +1,439 @@
323+/*
324+ * NFSv4 ACL Code
325+ * Convert NFSv4 ACL to a POSIX ACL
326+ *
327+ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
328+ * All rights reserved.
329+ *
330+ * Nathaniel Gallaher <ngallahe@umich.edu>
331+ *
332+ * Redistribution and use in source and binary forms, with or without
333+ * modification, are permitted provided that the following conditions
334+ * are met:
335+ *
336+ * 1. Redistributions of source code must retain the above copyright
337+ * notice, this list of conditions and the following disclaimer.
338+ * 2. Redistributions in binary form must reproduce the above copyright
339+ * notice, this list of conditions and the following disclaimer in the
340+ * documentation and/or other materials provided with the distribution.
341+ * 3. Neither the name of the University nor the names of its
342+ * contributors may be used to endorse or promote products derived
343+ * from this software without specific prior written permission.
344+ *
345+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
346+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
347+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
348+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
349+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
350+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
351+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
352+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
353+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
354+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
355+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
356+ */
357+
358+#include <acl/libacl.h>
359+#include <nfsidmap.h>
360+#include "libacl_nfs4.h"
361+
362+
363+/*
364+ * While processing the NFSv4 ACE, this maintains bitmasks representing
365+ * which permission bits have been allowed and which denied to a given
366+ * entity: */
367+struct posix_ace_state {
368+ u_int32_t allow;
369+ u_int32_t deny;
370+};
371+
372+struct posix_user_ace_state {
373+ uid_t uid;
374+ struct posix_ace_state perms;
375+};
376+
377+struct posix_ace_state_array {
378+ int n;
379+ struct posix_user_ace_state aces[];
380+};
381+
382+/*
383+ * While processing the NFSv4 ACE, this maintains the partial permissions
384+ * calculated so far: */
385+
386+struct posix_acl_state {
387+ struct posix_ace_state owner;
388+ struct posix_ace_state group;
389+ struct posix_ace_state other;
390+ struct posix_ace_state everyone;
391+ struct posix_ace_state mask; /* Deny unused in this case */
392+ struct posix_ace_state_array *users;
393+ struct posix_ace_state_array *groups;
394+};
395+
396+static int
397+init_state(struct posix_acl_state *state, int cnt)
398+{
399+ int alloc;
400+
401+ memset(state, 0, sizeof(struct posix_acl_state));
402+ /*
403+ * In the worst case, each individual acl could be for a distinct
404+ * named user or group, but we don't know which, so we allocate
405+ * enough space for either:
406+ */
407+ alloc = sizeof(struct posix_ace_state_array)
408+ + cnt*sizeof(struct posix_user_ace_state);
409+ state->users = calloc(1, alloc);
410+ if (!state->users)
411+ return -ENOMEM;
412+ state->groups = calloc(1, alloc);
413+ if (!state->groups) {
414+ free(state->users);
415+ return -ENOMEM;
416+ }
417+ return 0;
418+}
419+
420+static void
421+free_state(struct posix_acl_state *state) {
422+ free(state->users);
423+ free(state->groups);
424+}
425+
426+static inline void add_to_mask(struct posix_acl_state *state, struct posix_ace_state *astate)
427+{
428+ state->mask.allow |= astate->allow;
429+}
430+
431+/*
432+ * We only map from NFSv4 to POSIX ACLs when getting ACLs, when we err on the
433+ * side of permissiveness (so as not to make the file appear more secure than
434+ * it really is), so the mode bit mapping below is optimistic.
435+ */
436+static void
437+set_mode_from_nfs4(acl_entry_t pace, u_int32_t perm, int is_dir)
438+{
439+ u32 write_mode = NFS4_WRITE_MODE;
440+ acl_permset_t perms;
441+
442+ acl_get_permset(pace, &perms);
443+ acl_clear_perms(perms);
444+ if (is_dir)
445+ write_mode |= NFS4_ACE_DELETE_CHILD;
446+ if (perm & NFS4_READ_MODE)
447+ acl_add_perm(perms, ACL_READ);
448+ if (perm & write_mode)
449+ acl_add_perm(perms, ACL_WRITE);
450+ if (perm & NFS4_EXECUTE_MODE)
451+ acl_add_perm(perms, ACL_EXECUTE);
452+ acl_set_permset(pace, perms);
453+}
454+
455+/* XXX: add a "check allow" that can warn on e.g. allows of WRITE_ACL
456+ * to non-owner? */
457+
458+/* XXX: replace error returns by errno sets all over. Ugh. */
459+
460+static acl_t
461+posix_state_to_acl(struct posix_acl_state *state, int is_dir)
462+{
463+ acl_entry_t pace;
464+ acl_t pacl;
465+ int nace;
466+ int i, error = 0;
467+
468+ if (state->users->n || state->groups->n)
469+ nace = 4 + state->users->n + state->groups->n;
470+ else
471+ nace = 3;
472+ pacl = acl_init(nace);
473+ if (!pacl)
474+ return NULL;
475+
476+ error = acl_create_entry(&pacl, &pace);
477+ if (error)
478+ goto out_err;
479+ acl_set_tag_type(pace, ACL_USER_OBJ);
480+ set_mode_from_nfs4(pace, state->owner.allow, is_dir);
481+
482+ for (i=0; i < state->users->n; i++) {
483+ error = acl_create_entry(&pacl, &pace);
484+ if (error)
485+ goto out_err;
486+ acl_set_tag_type(pace, ACL_USER);
487+ set_mode_from_nfs4(pace, state->users->aces[i].perms.allow,
488+ is_dir);
489+ acl_set_qualifier(pace, &state->users->aces[i].uid);
490+ add_to_mask(state, &state->users->aces[i].perms);
491+ }
492+
493+ error = acl_create_entry(&pacl, &pace);
494+ if (error)
495+ goto out_err;
496+ acl_set_tag_type(pace, ACL_GROUP_OBJ);
497+ set_mode_from_nfs4(pace, state->group.allow, is_dir);
498+ add_to_mask(state, &state->group);
499+
500+ for (i=0; i < state->groups->n; i++) {
501+ error = acl_create_entry(&pacl, &pace);
502+ if (error)
503+ goto out_err;
504+ acl_set_tag_type(pace, ACL_GROUP);
505+ set_mode_from_nfs4(pace, state->groups->aces[i].perms.allow,
506+ is_dir);
507+ acl_set_qualifier(pace, &state->groups->aces[i].uid);
508+ add_to_mask(state, &state->groups->aces[i].perms);
509+ }
510+
511+ if (nace > 3) {
512+ error = acl_create_entry(&pacl, &pace);
513+ if (error)
514+ goto out_err;
515+ acl_set_tag_type(pace, ACL_MASK);
516+ set_mode_from_nfs4(pace, state->mask.allow, is_dir);
517+ }
518+
519+ error = acl_create_entry(&pacl, &pace);
520+ if (error)
521+ goto out_err;
522+ acl_set_tag_type(pace, ACL_OTHER);
523+ set_mode_from_nfs4(pace, state->other.allow, is_dir);
524+
525+ return pacl;
526+out_err:
527+ acl_free(pacl);
528+ return NULL;
529+}
530+
531+static inline void allow_bits(struct posix_ace_state *astate, u32 mask)
532+{
533+ /* Allow all bits in the mask not already denied: */
534+ astate->allow |= mask & ~astate->deny;
535+}
536+
537+static inline void deny_bits(struct posix_ace_state *astate, u32 mask)
538+{
539+ /* Deny all bits in the mask not already allowed: */
540+ astate->deny |= mask & ~astate->allow;
541+}
542+
543+static int find_uid(struct posix_acl_state *state, struct posix_ace_state_array *a, uid_t uid)
544+{
545+ int i;
546+
547+ for (i = 0; i < a->n; i++)
548+ if (a->aces[i].uid == uid)
549+ return i;
550+ /* Not found: */
551+ a->n++;
552+ a->aces[i].uid = uid;
553+ a->aces[i].perms.allow = state->everyone.allow;
554+ a->aces[i].perms.deny = state->everyone.deny;
555+
556+ return i;
557+}
558+
559+static void deny_bits_array(struct posix_ace_state_array *a, u32 mask)
560+{
561+ int i;
562+
563+ for (i=0; i < a->n; i++)
564+ deny_bits(&a->aces[i].perms, mask);
565+}
566+
567+static void allow_bits_array(struct posix_ace_state_array *a, u32 mask)
568+{
569+ int i;
570+
571+ for (i=0; i < a->n; i++)
572+ allow_bits(&a->aces[i].perms, mask);
573+}
574+
575+static acl_tag_t acl_n4tp_get_whotype(struct nfs4_ace *ace)
576+{
577+ int nfs4type;
578+ int result;
579+
580+ result = acl_nfs4_get_who(ace, &nfs4type, NULL);
581+ if (result < 0)
582+ return -1;
583+
584+ switch (nfs4type) {
585+ case NFS4_ACL_WHO_NAMED:
586+ return (ace->flag & NFS4_ACE_IDENTIFIER_GROUP ?
587+ ACL_GROUP : ACL_USER);
588+ case NFS4_ACL_WHO_OWNER:
589+ return ACL_USER_OBJ;
590+ case NFS4_ACL_WHO_GROUP:
591+ return ACL_GROUP_OBJ;
592+ case NFS4_ACL_WHO_EVERYONE:
593+ return ACL_OTHER;
594+ }
595+ errno = EINVAL;
596+ return -1;
597+}
598+
599+static int process_one_v4_ace(struct posix_acl_state *state,
600+ struct nfs4_ace *ace)
601+{
602+ u32 mask = ace->access_mask;
603+ uid_t id;
604+ int i;
605+
606+ if (nfs4_init_name_mapping(NULL))
607+ return -1;
608+
609+ switch (acl_n4tp_get_whotype(ace)) {
610+ case ACL_USER_OBJ:
611+ if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
612+ allow_bits(&state->owner, mask);
613+ } else {
614+ deny_bits(&state->owner, mask);
615+ }
616+ break;
617+ case ACL_USER:
618+ if (nfs4_name_to_uid(ace->who, &id))
619+ return -1;
620+ i = find_uid(state, state->users, id);
621+ if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
622+ allow_bits(&state->users->aces[i].perms, mask);
623+ mask = state->users->aces[i].perms.allow;
624+ allow_bits(&state->owner, mask);
625+ } else {
626+ deny_bits(&state->users->aces[i].perms, mask);
627+ }
628+ break;
629+ case ACL_GROUP_OBJ:
630+ if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
631+ allow_bits(&state->group, mask);
632+ mask = state->group.allow;
633+ allow_bits(&state->owner, mask);
634+ allow_bits(&state->everyone, mask);
635+ allow_bits_array(state->users, mask);
636+ allow_bits_array(state->groups, mask);
637+ } else {
638+ deny_bits(&state->group, mask);
639+ }
640+ break;
641+ case ACL_GROUP:
642+ if (nfs4_name_to_gid(ace->who, &id))
643+ return -1;
644+ i = find_uid(state, state->groups, id);
645+ if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
646+ allow_bits(&state->groups->aces[i].perms, mask);
647+ mask = state->groups->aces[i].perms.allow;
648+ allow_bits(&state->owner, mask);
649+ allow_bits(&state->group, mask);
650+ allow_bits(&state->everyone, mask);
651+ allow_bits_array(state->users, mask);
652+ allow_bits_array(state->groups, mask);
653+ } else {
654+ deny_bits(&state->groups->aces[i].perms, mask);
655+ }
656+ break;
657+ case ACL_OTHER:
658+ if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
659+ allow_bits(&state->owner, mask);
660+ allow_bits(&state->group, mask);
661+ allow_bits(&state->other, mask);
662+ allow_bits(&state->everyone, mask);
663+ allow_bits_array(state->users, mask);
664+ allow_bits_array(state->groups, mask);
665+ } else {
666+ deny_bits(&state->owner, mask);
667+ deny_bits(&state->group, mask);
668+ deny_bits(&state->other, mask);
669+ deny_bits(&state->everyone, mask);
670+ deny_bits_array(state->users, mask);
671+ deny_bits_array(state->groups, mask);
672+ }
673+ }
674+ return 0;
675+}
676+
677+#define FILE_OR_DIR_INHERIT (NFS4_ACE_FILE_INHERIT_ACE \
678+ | NFS4_ACE_DIRECTORY_INHERIT_ACE)
679+
680+/* Strip or keep inheritance aces depending on type of posix acl requested */
681+static void acl_nfs4_check_inheritance(struct nfs4_acl *acl, u32 iflags)
682+{
683+ struct nfs4_ace * cur_ace;
684+ struct nfs4_ace * temp_ace;
685+
686+ cur_ace = acl->ace_head.tqh_first;
687+
688+ while (cur_ace) {
689+ /* get the next ace now in case we free the current ace */
690+ temp_ace = cur_ace;
691+ cur_ace = cur_ace->l_ace.tqe_next;
692+
693+ if (iflags & NFS4_ACL_REQUEST_DEFAULT) {
694+ if (!(temp_ace->flag & FILE_OR_DIR_INHERIT))
695+ acl_nfs4_remove_ace(acl, temp_ace);
696+ } else {
697+ if (temp_ace->flag & NFS4_ACE_INHERIT_ONLY_ACE)
698+ acl_nfs4_remove_ace(acl, temp_ace);
699+ }
700+ }
701+}
702+
703+acl_t acl_n4tp_acl_trans(struct nfs4_acl * nacl_p, acl_type_t ptype)
704+{
705+ struct posix_acl_state state;
706+ acl_t pacl;
707+ struct nfs4_acl * temp_acl;
708+ struct nfs4_ace * cur_ace;
709+ int ret;
710+ u32 iflags = NFS4_ACL_NOFLAGS;
711+
712+ if (ptype == ACL_TYPE_DEFAULT) {
713+ if (nacl_p->is_directory)
714+ iflags |= NFS4_ACL_REQUEST_DEFAULT;
715+ else {
716+ errno = EINVAL;
717+ return NULL;
718+ }
719+ }
720+
721+ /* Copy so we can delete bits without borking the original */
722+ temp_acl = acl_nfs4_copy_acl(nacl_p);
723+ if (temp_acl == NULL)
724+ return NULL;
725+
726+ acl_nfs4_check_inheritance(temp_acl, iflags);
727+
728+ if (ptype == ACL_TYPE_DEFAULT && temp_acl->naces == 0) {
729+ acl_nfs4_free(temp_acl);
730+ return acl_init(0);
731+ }
732+
733+ ret = init_state(&state, temp_acl->naces);
734+ if (ret)
735+ goto free_failed;
736+
737+ cur_ace = temp_acl->ace_head.tqh_first;
738+ while (cur_ace) {
739+ if (process_one_v4_ace(&state, cur_ace)) {
740+ free_state(&state);
741+ goto free_failed;
742+ }
743+ cur_ace = cur_ace->l_ace.tqe_next;
744+ }
745+
746+ acl_nfs4_free(temp_acl);
747+
748+ pacl = posix_state_to_acl(&state, nacl_p->is_directory);
749+
750+ free_state(&state);
751+
752+ ret = acl_valid(pacl);
753+ if (ret < 0)
754+ goto free_failed;
755+
756+ return pacl;
757+
758+free_failed:
759+ acl_nfs4_free(temp_acl);
760+ return NULL;
761+}
762--- acl-2.2.39/libacl/acl_set_fd.c.orig 2006-06-20 02:51:25.000000000 -0400
763+++ acl-2.2.39/libacl/acl_set_fd.c 2007-08-22 12:02:13.000000000 -0400
764@@ -24,6 +24,11 @@
765 #include "libacl.h"
766 #include "__acl_to_xattr.h"
767
768+#ifdef USE_NFSV4_TRANS
769+ #include "libacl_nfs4.h"
770+ #include <nfsidmap.h>
771+#endif
772+
773 #include "byteorder.h"
774 #include "acl_ea.h"
775
776@@ -37,10 +42,42 @@ acl_set_fd(int fd, acl_t acl)
777 const char *name = ACL_EA_ACCESS;
778 size_t size;
779 int error;
780+#ifdef USE_NFSV4_TRANS
781+ int retval;
782+ struct nfs4_acl * nacl;
783+#endif
784
785 if (!acl_obj_p)
786 return -1;
787+
788+#ifdef USE_NFSV4_TRANS
789+ retval = fgetxattr(fd, ACL_NFS4_XATTR, NULL, 0);
790+
791+ if(retval == -1 && (errno == ENOATTR || errno == EOPNOTSUPP)) {
792+ ext_acl_p = __acl_to_xattr(acl_obj_p, &size);
793+ } else {
794+ char domain[NFS4_MAX_DOMAIN_LEN];
795+ nfs4_init_name_mapping(NULL);
796+ error = nfs4_get_default_domain(NULL, domain, sizeof(domain));
797+ if (error)
798+ return -1;
799+ nacl = acl_nfs4_new(0);
800+ if (acl == NULL) {
801+ errno = ENOMEM;
802+ return -1;
803+ }
804+ error = acl_ptn4_acl_trans(acl, nacl, ACL_TYPE_ACCESS, 0, domain);
805+ if (error)
806+ return -1;
807+
808+ size = acl_nfs4_xattr_pack(nacl, &ext_acl_p);
809+ name = ACL_NFS4_XATTR;
810+ acl_nfs4_free(nacl);
811+ }
812+#else
813 ext_acl_p = __acl_to_xattr(acl_obj_p, &size);
814+#endif
815+
816 if (!ext_acl_p)
817 return -1;
818 error = fsetxattr(fd, name, (char *)ext_acl_p, size, 0);
819--- acl-2.2.39/libacl/Makefile.orig 2006-06-20 02:51:25.000000000 -0400
820+++ acl-2.2.39/libacl/Makefile 2007-08-22 12:02:13.000000000 -0400
821@@ -8,19 +8,35 @@ LTLDFLAGS += -Wl,--version-script,$(TOPD
822 include $(TOPDIR)/include/builddefs
823
824 LTLIBRARY = libacl.la
825-LTLIBS = -lattr $(LIBMISC)
826+LTLIBS = -lattr -lnfsidmap $(LIBMISC)
827 LTDEPENDENCIES = $(LIBMISC)
828-LT_CURRENT = 2
829+LT_CURRENT = 3
830 LT_REVISION = 0
831-LT_AGE = 1
832+LT_AGE = 2
833+
834+CFILES = $(POSIX_CFILES) $(LIBACL_CFILES) $(LIBACL_NFS4_CFILES) \
835+ $(INTERNAL_CFILES) perm_copy_fd.c perm_copy_file.c
836
837-CFILES = $(POSIX_CFILES) $(LIBACL_CFILES) $(INTERNAL_CFILES) \
838- perm_copy_fd.c perm_copy_file.c
839 HFILES = libobj.h libacl.h byteorder.h __acl_from_xattr.h __acl_to_xattr.h \
840- perm_copy.h
841+ perm_copy.h $(LIBACL_NFS4_HFILES)
842
843 LCFLAGS = -include perm_copy.h
844
845+LIBACL_NFS4_CFILES = \
846+ acl_nfs4_get_who.c \
847+ acl_n4tp_acl_trans.c acl_nfs4_get_whotype.c \
848+ acl_nfs4_new.c \
849+ acl_nfs4_add_ace.c acl_nfs4_remove_ace.c \
850+ acl_nfs4_add_pair.c \
851+ acl_nfs4_copy_acl.c acl_nfs4_set_who.c \
852+ acl_nfs4_free.c acl_nfs4_xattr_load.c \
853+ acl_nfs4_xattr_pack.c acl_nfs4_xattr_size.c \
854+ acl_ptn4_acl_trans.c \
855+ acl_ptn4_get_mask.c __posix_acl_from_nfs4_xattr.c \
856+
857+
858+LIBACL_NFS4_HFILES = ../include/libacl_nfs4.h ../include/nfs4.h
859+
860 POSIX_CFILES = \
861 acl_add_perm.c acl_calc_mask.c acl_clear_perms.c acl_copy_entry.c \
862 acl_copy_ext.c acl_copy_int.c acl_create_entry.c acl_delete_def_file.c \
863--- /dev/null 2007-08-22 11:21:03.626521839 -0400
864+++ acl-2.2.39/libacl/acl_nfs4_remove_ace.c 2007-08-22 12:02:13.000000000 -0400
865@@ -0,0 +1,48 @@
866+/*
867+ * NFSv4 ACL Code
868+ * Remove an ace from an NFS4 ACL
869+ *
870+ * Copyright (c) 2004 The Regents of the University of Michigan.
871+ * All rights reserved.
872+ *
873+ * Nathaniel Gallaher <ngallahe@umich.edu>
874+ *
875+ * Redistribution and use in source and binary forms, with or without
876+ * modification, are permitted provided that the following conditions
877+ * are met:
878+ *
879+ * 1. Redistributions of source code must retain the above copyright
880+ * notice, this list of conditions, the following disclaimer, and
881+ * any and all other licensing or copyright notices included in
882+ * any files in this distribution.
883+ * 2. Redistributions in binary form must reproduce the above copyright
884+ * notice, this list of conditions and the following disclaimer in the
885+ * documentation and/or other materials provided with the distribution.
886+ * 3. Neither the name of the University nor the names of its
887+ * contributors may be used to endorse or promote products derived
888+ * from this software without specific prior written permission.
889+ *
890+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
891+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
892+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
893+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
894+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
895+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
896+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
897+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
898+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
899+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
900+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
901+ *
902+ */
903+
904+#include "libacl_nfs4.h"
905+
906+void acl_nfs4_remove_ace(struct nfs4_acl * acl, struct nfs4_ace * ace)
907+{
908+ TAILQ_REMOVE(&acl->ace_head, ace, l_ace);
909+ free(ace->who);
910+ free(ace);
911+ acl->naces--;
912+}
913+
914--- /dev/null 2007-08-22 11:21:03.626521839 -0400
915+++ acl-2.2.39/libacl/acl_nfs4_set_who.c 2007-08-22 12:02:13.000000000 -0400
916@@ -0,0 +1,92 @@
917+/*
918+ * NFSv4 ACL Code
919+ * Write the who entry in the nfs4 ace. Who is a user supplied buffer
920+ * containing a named who entry (null terminated string) if type is
921+ * set to NFS4_ACL_WHO_NAMED. Otherwise, the who buffer is not used.
922+ * The user supplied who buffer must be freed by the caller.
923+ *
924+ * This code allocates the who buffer used in the ace. This must be freed
925+ * upon ace removal by the ace_remove or acl_free.
926+ *
927+ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
928+ * All rights reserved.
929+ *
930+ * Nathaniel Gallaher <ngallahe@umich.edu>
931+ *
932+ * Redistribution and use in source and binary forms, with or without
933+ * modification, are permitted provided that the following conditions
934+ * are met:
935+ *
936+ * 1. Redistributions of source code must retain the above copyright
937+ * notice, this list of conditions and the following disclaimer.
938+ * 2. Redistributions in binary form must reproduce the above copyright
939+ * notice, this list of conditions and the following disclaimer in the
940+ * documentation and/or other materials provided with the distribution.
941+ * 3. Neither the name of the University nor the names of its
942+ * contributors may be used to endorse or promote products derived
943+ * from this software without specific prior written permission.
944+ *
945+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
946+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
947+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
948+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
949+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
950+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
951+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
952+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
953+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
954+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
955+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
956+ */
957+
958+#include "libacl_nfs4.h"
959+
960+int acl_nfs4_set_who(struct nfs4_ace* ace, int type, char* who)
961+{
962+ char* iwho = NULL;
963+ int wholen;
964+
965+ if(ace == NULL)
966+ goto inval_failed;
967+
968+ switch(type)
969+ {
970+ case NFS4_ACL_WHO_NAMED:
971+ if(who == NULL)
972+ goto inval_failed;
973+ iwho = who;
974+ break;
975+ case NFS4_ACL_WHO_OWNER:
976+ iwho = NFS4_ACL_WHO_OWNER_STRING;
977+ break;
978+ case NFS4_ACL_WHO_GROUP:
979+ iwho = NFS4_ACL_WHO_GROUP_STRING;
980+ break;
981+ case NFS4_ACL_WHO_EVERYONE:
982+ iwho = NFS4_ACL_WHO_EVERYONE_STRING;
983+ break;
984+ default:
985+ goto inval_failed;
986+ }
987+
988+ wholen = strlen(iwho);
989+ if(wholen < 1)
990+ goto inval_failed;
991+
992+ ace->who = (char *) malloc(sizeof(char) * (wholen + 1));
993+ if(ace->who == NULL) {
994+ errno = ENOMEM;
995+ goto failed;
996+ }
997+
998+ strcpy(ace->who, iwho);
999+
1000+ return 0;
1001+
1002+inval_failed:
1003+ errno = EINVAL;
1004+
1005+failed:
1006+ return -1;
1007+}
1008+
1009--- acl-2.2.39/libacl/acl_set_file.c.orig 2006-06-20 02:51:25.000000000 -0400
1010+++ acl-2.2.39/libacl/acl_set_file.c 2007-08-22 12:02:13.000000000 -0400
1011@@ -26,9 +26,38 @@
1012 #include "libacl.h"
1013 #include "__acl_to_xattr.h"
1014
1015+#ifdef USE_NFSV4_TRANS
1016+ #include "libacl_nfs4.h"
1017+ #include <nfsidmap.h>
1018+#endif
1019+
1020 #include "byteorder.h"
1021 #include "acl_ea.h"
1022
1023+#ifdef USE_NFSV4_TRANS
1024+static struct nfs4_acl *get_nfs4_acl(const char *path_p, int is_dir)
1025+{
1026+ struct nfs4_acl * acl = NULL;
1027+ ssize_t ret;
1028+ char *buf;
1029+
1030+ ret = getxattr(path_p, ACL_NFS4_XATTR, NULL, 0);
1031+ if (ret < 0)
1032+ return NULL;
1033+ buf = malloc(ret);
1034+ if (buf == NULL)
1035+ return NULL;
1036+ ret = getxattr(path_p, ACL_NFS4_XATTR, buf, ret);
1037+ if (ret < 0)
1038+ goto out_free;
1039+ acl = acl_nfs4_xattr_load(buf, ret, is_dir);
1040+
1041+out_free:
1042+ free(buf);
1043+ return acl;
1044+}
1045+
1046+#endif
1047
1048 /* 23.4.22 */
1049 int
1050@@ -39,9 +68,15 @@ acl_set_file(const char *path_p, acl_typ
1051 const char *name;
1052 size_t size;
1053 int error;
1054+ struct stat st;
1055+#ifdef USE_NFSV4_TRANS
1056+ struct nfs4_acl * nacl;
1057+ int is_dir = NFS4_ACL_ISFILE;
1058+#endif
1059
1060 if (!acl_obj_p)
1061 return -1;
1062+
1063 switch (type) {
1064 case ACL_TYPE_ACCESS:
1065 name = ACL_EA_ACCESS;
1066@@ -54,8 +89,41 @@ acl_set_file(const char *path_p, acl_typ
1067 return -1;
1068 }
1069
1070+
1071+#ifdef USE_NFSV4_TRANS
1072+ if (stat(path_p, &st) != 0)
1073+ return -1;
1074+ if (S_ISDIR(st.st_mode))
1075+ is_dir = NFS4_ACL_ISDIR;
1076+ if (type == ACL_TYPE_DEFAULT && !is_dir) {
1077+ errno = EACCES;
1078+ return -1;
1079+ }
1080+ nacl = get_nfs4_acl(path_p, is_dir);
1081+ if (nacl == NULL && (errno == ENOATTR || errno == EOPNOTSUPP))
1082+ ext_acl_p = __acl_to_xattr(acl_obj_p, &size);
1083+ else {
1084+ char domain[NFS4_MAX_DOMAIN_LEN];
1085+
1086+ nfs4_init_name_mapping(NULL);
1087+ error = nfs4_get_default_domain(NULL, domain, sizeof(domain));
1088+ if (error) {
1089+ acl_nfs4_free(nacl);
1090+ return -1;
1091+ }
1092+ error = acl_ptn4_acl_trans(acl, nacl, type, is_dir, domain);
1093+ if (error) {
1094+ acl_nfs4_free(nacl);
1095+ return -1;
1096+ }
1097+
1098+ size = acl_nfs4_xattr_pack(nacl, &ext_acl_p);
1099+ name = ACL_NFS4_XATTR;
1100+ acl_nfs4_free(nacl);
1101+ }
1102+#else
1103+
1104 if (type == ACL_TYPE_DEFAULT) {
1105- struct stat st;
1106
1107 if (stat(path_p, &st) != 0)
1108 return -1;
1109@@ -68,6 +136,8 @@ acl_set_file(const char *path_p, acl_typ
1110 }
1111
1112 ext_acl_p = __acl_to_xattr(acl_obj_p, &size);
1113+#endif
1114+
1115 if (!ext_acl_p)
1116 return -1;
1117 error = setxattr(path_p, name, (char *)ext_acl_p, size, 0);
1118--- /dev/null 2007-08-22 11:21:03.626521839 -0400
1119+++ acl-2.2.39/libacl/__posix_acl_from_nfs4_xattr.c 2007-08-22 12:02:13.000000000 -0400
1120@@ -0,0 +1,60 @@
1121+/*
1122+ * NFSv4 ACL Code
1123+ * Convert NFSv4 xattr values to a posix ACL
1124+ *
1125+ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
1126+ * All rights reserved.
1127+ *
1128+ * Nathaniel Gallaher <ngallahe@umich.edu>
1129+ *
1130+ * Redistribution and use in source and binary forms, with or without
1131+ * modification, are permitted provided that the following conditions
1132+ * are met:
1133+ *
1134+ * 1. Redistributions of source code must retain the above copyright
1135+ * notice, this list of conditions and the following disclaimer.
1136+ * 2. Redistributions in binary form must reproduce the above copyright
1137+ * notice, this list of conditions and the following disclaimer in the
1138+ * documentation and/or other materials provided with the distribution.
1139+ * 3. Neither the name of the University nor the names of its
1140+ * contributors may be used to endorse or promote products derived
1141+ * from this software without specific prior written permission.
1142+ *
1143+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1144+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1145+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1146+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1147+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1148+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1149+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
1150+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
1151+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1152+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1153+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1154+ */
1155+
1156+#include <acl/libacl.h>
1157+#include "libacl_nfs4.h"
1158+
1159+/* xattr_v is a char buffer filled with the nfsv4 xattr value.
1160+ * xattr_size should be the byte count of the length of the xattr_v
1161+ * data size. xattr_v may be larger than <xattr_size> bytes, but only
1162+ * the first <xattr_size> bytes will be read. <type> is the posix acl
1163+ * type requested. Currently either default, or access */
1164+
1165+acl_t __posix_acl_from_nfs4_xattr(char* xattr_v,
1166+ int xattr_size, acl_type_t ptype, u32 is_dir)
1167+{
1168+ struct nfs4_acl * nfsacl = NULL;
1169+ acl_t pacl;
1170+
1171+ nfsacl = acl_nfs4_xattr_load(xattr_v, xattr_size, is_dir);
1172+ if(nfsacl == NULL) {
1173+ return NULL;
1174+ }
1175+
1176+ pacl = acl_n4tp_acl_trans(nfsacl, ptype);
1177+
1178+ return pacl;
1179+}
1180+
1181--- /dev/null 2007-08-22 11:21:03.626521839 -0400
1182+++ acl-2.2.39/libacl/acl_nfs4_xattr_load.c 2007-08-22 12:02:13.000000000 -0400
1183@@ -0,0 +1,191 @@
1184+/*
1185+ * NFSv4 ACL Code
1186+ * Convert NFSv4 xattr values to a posix ACL
1187+ *
1188+ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
1189+ * All rights reserved.
1190+ *
1191+ * Nathaniel Gallaher <ngallahe@umich.edu>
1192+ *
1193+ * Redistribution and use in source and binary forms, with or without
1194+ * modification, are permitted provided that the following conditions
1195+ * are met:
1196+ *
1197+ * 1. Redistributions of source code must retain the above copyright
1198+ * notice, this list of conditions and the following disclaimer.
1199+ * 2. Redistributions in binary form must reproduce the above copyright
1200+ * notice, this list of conditions and the following disclaimer in the
1201+ * documentation and/or other materials provided with the distribution.
1202+ * 3. Neither the name of the University nor the names of its
1203+ * contributors may be used to endorse or promote products derived
1204+ * from this software without specific prior written permission.
1205+ *
1206+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1207+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1208+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1209+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1210+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1211+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1212+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
1213+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
1214+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1215+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1216+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1217+ */
1218+
1219+
1220+#include <acl/libacl.h>
1221+#include <netinet/in.h>
1222+#include "libacl_nfs4.h"
1223+
1224+
1225+struct nfs4_acl * acl_nfs4_xattr_load(
1226+ char * xattr_v,
1227+ int xattr_size,
1228+ u32 is_dir)
1229+{
1230+ struct nfs4_acl * nacl_p;
1231+ char* bufp = xattr_v;
1232+ int bufs = xattr_size;
1233+ u32 ace_n;
1234+ u32 wholen;
1235+ char* who;
1236+ int d_ptr;
1237+ u32 num_aces;
1238+
1239+ u32 type, flag, access_mask;
1240+
1241+ if(xattr_size < sizeof(u32)) {
1242+ errno = EINVAL;
1243+ return NULL;
1244+ }
1245+
1246+ if((nacl_p = acl_nfs4_new(is_dir)) == NULL) {
1247+ errno = ENOMEM;
1248+ return NULL;
1249+ }
1250+
1251+ /* Grab the number of aces in the acl */
1252+ num_aces = (u32)ntohl(*((u32*)(bufp)));
1253+
1254+#ifdef LIBACL_NFS4_DEBUG
1255+ printf(" Got number of aces: %d\n", nacl_p->naces);
1256+#endif
1257+
1258+
1259+ d_ptr = sizeof(u32);
1260+ bufp += d_ptr;
1261+ bufs -= d_ptr;
1262+
1263+ for(ace_n = 0; num_aces > ace_n ; ace_n++)
1264+ {
1265+#ifdef LIBACL_NFS4_DEBUG
1266+ printf(" Getting Ace #%d of %d\n", ace_n, num_aces);
1267+#endif
1268+ /* Get the acl type */
1269+ if(bufs <= 0) {
1270+ errno = EINVAL;
1271+ goto bad_xattr_val;
1272+ }
1273+
1274+ type = (u32)ntohl(*((u32*)bufp));
1275+#ifdef LIBACL_NFS4_DEBUG
1276+ printf(" Type: %x\n", type);
1277+#endif
1278+
1279+ d_ptr = sizeof(u32);
1280+ bufp += d_ptr;
1281+ bufs -= d_ptr;
1282+
1283+ /* Get the acl flag */
1284+ if(bufs <= 0) {
1285+ errno = EINVAL;
1286+ goto bad_xattr_val;
1287+ }
1288+
1289+ flag = (u32)ntohl(*((u32*)bufp));
1290+#ifdef LIBACL_NFS4_DEBUG
1291+ printf(" Flag: %x\n", flag);
1292+#endif
1293+
1294+ bufp += d_ptr;
1295+ bufs -= d_ptr;
1296+
1297+ /* Get the access mask */
1298+
1299+ if(bufs <= 0) {
1300+ errno = EINVAL;
1301+ goto bad_xattr_val;
1302+ }
1303+
1304+ access_mask = (u32)ntohl(*((u32*)bufp));
1305+#ifdef LIBACL_NFS4_DEBUG
1306+ printf(" Access Mask: %x\n", access_mask);
1307+#endif
1308+
1309+ bufp += d_ptr;
1310+ bufs -= d_ptr;
1311+
1312+ /* Get the who string length*/
1313+ if(bufs <= 0) {
1314+ errno = EINVAL;
1315+ goto bad_xattr_val;
1316+ }
1317+
1318+ wholen = (u32)ntohl(*((u32*)bufp));
1319+#ifdef LIBACL_NFS4_DEBUG
1320+ printf(" Wholen: %d\n", wholen);
1321+#endif
1322+
1323+ bufp += d_ptr;
1324+ bufs -= d_ptr;
1325+
1326+ /* Get the who string */
1327+ if(bufs <= 0) {
1328+ errno = EINVAL;
1329+ goto bad_xattr_val;
1330+ }
1331+
1332+ who = (char *) malloc((wholen+1) * sizeof(char));
1333+ if(who == NULL)
1334+ {
1335+ errno = ENOMEM;
1336+ goto bad_xattr_val;
1337+ }
1338+
1339+ memcpy(who, bufp, wholen);
1340+
1341+ who[wholen] = '\0';
1342+
1343+#ifdef LIBACL_NFS4_DEBUG
1344+ printf(" Who: %s\n", who);
1345+#endif
1346+
1347+ d_ptr = ((wholen / sizeof(u32))*sizeof(u32));
1348+ if(wholen % sizeof(u32) != 0)
1349+ d_ptr += sizeof(u32);
1350+
1351+ bufp += d_ptr;
1352+ bufs -= d_ptr;
1353+
1354+ /* Make sure we aren't outside our domain */
1355+ if(bufs < 0) {
1356+ free(who);
1357+ goto bad_xattr_val;
1358+ }
1359+
1360+ if(acl_nfs4_add_ace(nacl_p, type, flag, access_mask, acl_nfs4_get_whotype(who), who) < 0) {
1361+ free(who);
1362+ goto bad_xattr_val;
1363+ }
1364+
1365+ free(who);
1366+ }
1367+
1368+ return nacl_p;
1369+
1370+bad_xattr_val:
1371+ /* We bailed for some reason */
1372+ acl_nfs4_free(nacl_p);
1373+ return NULL;
1374+}
1375--- /dev/null 2007-08-22 11:21:03.626521839 -0400
1376+++ acl-2.2.39/libacl/acl_nfs4_xattr_pack.c 2007-08-22 12:02:13.000000000 -0400
1377@@ -0,0 +1,148 @@
1378+/*
1379+ * NFSv4 ACL Code
1380+ * Pack an NFS4 ACL into an XDR encoded buffer.
1381+ *
1382+ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
1383+ * All rights reserved.
1384+ *
1385+ * Nathaniel Gallaher <ngallahe@umich.edu>
1386+ *
1387+ * Redistribution and use in source and binary forms, with or without
1388+ * modification, are permitted provided that the following conditions
1389+ * are met:
1390+ *
1391+ * 1. Redistributions of source code must retain the above copyright
1392+ * notice, this list of conditions and the following disclaimer.
1393+ * 2. Redistributions in binary form must reproduce the above copyright
1394+ * notice, this list of conditions and the following disclaimer in the
1395+ * documentation and/or other materials provided with the distribution.
1396+ * 3. Neither the name of the University nor the names of its
1397+ * contributors may be used to endorse or promote products derived
1398+ * from this software without specific prior written permission.
1399+ *
1400+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1401+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1402+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1403+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1404+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1405+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1406+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
1407+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
1408+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1409+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1410+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1411+ */
1412+
1413+#include <libacl_nfs4.h>
1414+#include <netinet/in.h>
1415+
1416+int acl_nfs4_xattr_pack(struct nfs4_acl * acl, char** bufp)
1417+{
1418+ struct nfs4_ace * ace;
1419+ int buflen;
1420+ int rbuflen;
1421+ int num_aces;
1422+ int ace_num;
1423+ int wholen;
1424+ int result;
1425+ char* p;
1426+ char* who;
1427+
1428+ if(acl == NULL || bufp == NULL)
1429+ {
1430+ errno = EINVAL;
1431+ goto failed;
1432+ }
1433+
1434+ buflen = acl_nfs4_xattr_size(acl);
1435+ if(buflen < 0)
1436+ {
1437+ goto failed;
1438+ }
1439+
1440+ *bufp = (char*) malloc(buflen);
1441+ if(*bufp == NULL) {
1442+ errno = ENOMEM;
1443+ goto failed;
1444+ }
1445+
1446+ p = *bufp;
1447+
1448+ num_aces = acl->naces;
1449+
1450+ *((u32*)p) = htonl(num_aces);
1451+
1452+ rbuflen = sizeof(u32);
1453+ p += sizeof(u32);
1454+
1455+ ace = acl->ace_head.tqh_first;
1456+ ace_num = 1;
1457+
1458+ while(1)
1459+ {
1460+ if(ace == NULL)
1461+ {
1462+ if(ace_num > num_aces) {
1463+ break;
1464+ } else {
1465+ errno = ENODATA;
1466+ goto failed;
1467+ }
1468+ }
1469+
1470+ *((u32*)p) = htonl(ace->type);
1471+ p += sizeof(u32);
1472+ rbuflen += sizeof(u32);
1473+
1474+ *((u32*)p) = htonl(ace->flag);
1475+ p += sizeof(u32);
1476+ rbuflen += sizeof(u32);
1477+
1478+ *((u32*)p) = htonl(ace->access_mask);
1479+ p += sizeof(u32);
1480+ rbuflen += sizeof(u32);
1481+
1482+ result = acl_nfs4_get_who(ace, NULL, &who);
1483+ if(result < 0) {
1484+ goto free_failed;
1485+ }
1486+
1487+ wholen = strlen(who);
1488+ *((u32*)p) = htonl(wholen);
1489+ rbuflen += sizeof(u32);
1490+
1491+ p += sizeof(u32);
1492+
1493+ memcpy(p, who, wholen);
1494+ free(who);
1495+
1496+ p += (wholen / NFS4_XDR_MOD) * NFS4_XDR_MOD;
1497+ if(wholen % NFS4_XDR_MOD) {
1498+ p += NFS4_XDR_MOD;
1499+ }
1500+
1501+ rbuflen += (wholen / NFS4_XDR_MOD) * NFS4_XDR_MOD;
1502+ if(wholen % NFS4_XDR_MOD) {
1503+ rbuflen += NFS4_XDR_MOD;
1504+ }
1505+
1506+ ace = ace->l_ace.tqe_next;
1507+ ace_num++;
1508+ }
1509+
1510+ if (buflen != rbuflen)
1511+ {
1512+ goto free_failed;
1513+ }
1514+ return buflen;
1515+
1516+free_failed:
1517+ free(*bufp);
1518+ *bufp = NULL;
1519+
1520+failed:
1521+ return -1;
1522+}
1523+
1524+
1525+
1526--- acl-2.2.39/libacl/acl_extended_file.c.orig 2006-06-20 02:51:25.000000000 -0400
1527+++ acl-2.2.39/libacl/acl_extended_file.c 2007-08-22 12:02:13.000000000 -0400
1528@@ -22,6 +22,7 @@
1529 #include <unistd.h>
1530 #include <attr/xattr.h>
1531 #include "libacl.h"
1532+#include "libacl_nfs4.h"
1533
1534 #include "byteorder.h"
1535 #include "acl_ea.h"
1536@@ -33,6 +34,34 @@ acl_extended_file(const char *path_p)
1537 int base_size = sizeof(acl_ea_header) + 3 * sizeof(acl_ea_entry);
1538 int retval;
1539
1540+ /* XXX: Ugh: what's the easiest way to do this, taking
1541+ * into account default acl's, and that length alone won't do this?
1542+ * Also I'm a little uncomfortable with the amount of #ifdef
1543+ * NFS4 stuff that's going on. We need a cleaner separation. */
1544+#ifdef USE_NFSV4_TRANS
1545+ retval = getxattr(path_p, ACL_NFS4_XATTR, NULL, 0);
1546+ if (retval < 0 && errno != ENOATTR && errno != EOPNOTSUPP)
1547+ return -1;
1548+ if (retval >= 0) {
1549+ struct nfs4_acl *nfsacl;
1550+ char *ext_acl_p = alloca(retval);
1551+ if (!ext_acl_p)
1552+ return -1;
1553+
1554+ retval = getxattr(path_p, ACL_NFS4_XATTR, ext_acl_p, retval);
1555+ if (retval == -1)
1556+ return -1;
1557+
1558+ nfsacl = acl_nfs4_xattr_load(ext_acl_p, retval, NFS4_ACL_ISFILE);
1559+ if (nfsacl) {
1560+ int count = nfsacl->naces;
1561+ acl_nfs4_free(nfsacl);
1562+ return count > 6;
1563+ }
1564+ return 0;
1565+ }
1566+#endif
1567+
1568 retval = getxattr(path_p, ACL_EA_ACCESS, NULL, 0);
1569 if (retval < 0 && errno != ENOATTR && errno != ENODATA)
1570 return -1;
1571--- /dev/null 2007-08-22 11:21:03.626521839 -0400
1572+++ acl-2.2.39/libacl/acl_ptn4_acl_trans.c 2007-08-22 12:02:13.000000000 -0400
1573@@ -0,0 +1,509 @@
1574+/*
1575+ * NFSv4 ACL Code
1576+ * Convert a posix ACL to an NFSv4 ACL
1577+ *
1578+ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
1579+ * All rights reserved.
1580+ *
1581+ * Nathaniel Gallaher <ngallahe@umich.edu>
1582+ * J. Bruce Fields <bfields@umich.edu>
1583+ *
1584+ * Redistribution and use in source and binary forms, with or without
1585+ * modification, are permitted provided that the following conditions
1586+ * are met:
1587+ *
1588+ * 1. Redistributions of source code must retain the above copyright
1589+ * notice, this list of conditions and the following disclaimer.
1590+ * 2. Redistributions in binary form must reproduce the above copyright
1591+ * notice, this list of conditions and the following disclaimer in the
1592+ * documentation and/or other materials provided with the distribution.
1593+ * 3. Neither the name of the University nor the names of its
1594+ * contributors may be used to endorse or promote products derived
1595+ * from this software without specific prior written permission.
1596+ *
1597+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1598+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1599+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1600+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1601+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1602+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1603+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
1604+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
1605+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1606+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1607+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1608+ */
1609+
1610+#include <acl/libacl.h>
1611+#include <nfsidmap.h>
1612+#include "libacl_nfs4.h"
1613+
1614+
1615+#define FILE_OR_DIR_INHERIT (NFS4_ACE_FILE_INHERIT_ACE \
1616+ | NFS4_ACE_DIRECTORY_INHERIT_ACE)
1617+#define NFS4_INHERITANCE_FLAGS (FILE_OR_DIR_INHERIT | NFS4_ACE_INHERIT_ONLY_ACE)
1618+
1619+/* Plan:
1620+ * 1: if setting default, remove all purely inherited aces, and replace
1621+ * all dual-use aces by purely effective aces
1622+ * 2: if setting effective, remove all purely effective aces, and replace
1623+ * all dual-use aces by purely inherited ones
1624+ */
1625+static void purge_aces(struct nfs4_acl *nacl, acl_type_t type)
1626+{
1627+ struct nfs4_ace *p, *next;
1628+
1629+ for (p = nacl->ace_head.tqh_first; p != NULL; p = next) {
1630+ next = p->l_ace.tqe_next;
1631+
1632+ if (!(p->flag & FILE_OR_DIR_INHERIT)) {
1633+ /* purely effective */
1634+ if (type == ACL_TYPE_ACCESS)
1635+ acl_nfs4_remove_ace(nacl, p);
1636+ } else if (p->flag & NFS4_ACE_INHERIT_ONLY_ACE) {
1637+ /* purely inherited */
1638+ if (type == ACL_TYPE_DEFAULT)
1639+ acl_nfs4_remove_ace(nacl, p);
1640+ } else {
1641+ /* both effective and inherited */
1642+ if (type == ACL_TYPE_DEFAULT) {
1643+ /* Change to purely effective */
1644+ p->flag &= ~NFS4_INHERITANCE_FLAGS;
1645+ } else { /* ACL_TYPE_ACCESS */
1646+ /* Change to purely inherited */
1647+ p->flag |= NFS4_INHERITANCE_FLAGS;
1648+ }
1649+ }
1650+
1651+ }
1652+}
1653+
1654+int
1655+acl_ptn4_acl_trans(acl_t pacl, struct nfs4_acl *acl, acl_type_t type, u32 is_dir, char *nfs_domain)
1656+{
1657+ int eflag;
1658+ u32 mask, mask_mask = 0;
1659+ int num_aces;
1660+ int result, result2;
1661+ u32 iflags = NFS4_ACL_NOFLAGS;
1662+ int allocated = 0;
1663+
1664+ acl_entry_t pace_p;
1665+ acl_tag_t ace_type;
1666+ acl_permset_t perms;
1667+
1668+ char who_buf_static[NFS4_ACL_WHO_BUFFER_LEN_GUESS];
1669+ char *who_buf = NULL;
1670+ int who_buflen;
1671+ int who_buflen_static = NFS4_ACL_WHO_BUFFER_LEN_GUESS;
1672+ uid_t * uid_p;
1673+ gid_t * gid_p;
1674+
1675+ eflag = 0;
1676+
1677+ if (type == ACL_TYPE_DEFAULT) {
1678+ eflag = NFS4_INHERITANCE_FLAGS;
1679+ iflags |= NFS4_ACL_REQUEST_DEFAULT;
1680+ }
1681+
1682+ purge_aces(acl, type);
1683+
1684+ if (is_dir & NFS4_ACL_ISDIR)
1685+ iflags |= NFS4_ACL_ISDIR;
1686+
1687+
1688+ if (pacl == NULL || (acl_valid(pacl) < 0 || acl_entries(pacl) == 0)) {
1689+ errno = EINVAL;
1690+ goto out;
1691+ }
1692+
1693+ /* Start Conversion */
1694+
1695+ /* 3 aces minimum (mode bits) */
1696+ num_aces = acl_entries(pacl);
1697+ if (num_aces < 3) {
1698+ errno = EINVAL;
1699+ goto out;
1700+ }
1701+
1702+ /* Get the mask entry */
1703+
1704+ result = acl_get_entry(pacl, ACL_FIRST_ENTRY, &pace_p);
1705+ if (result < 0)
1706+ goto out;
1707+
1708+ while (result > 0 && mask_mask == 0) {
1709+ result = acl_get_tag_type(pace_p, &ace_type);
1710+ if (result < 0)
1711+ goto out;
1712+
1713+ if (ace_type == ACL_MASK) {
1714+ result = acl_get_permset(pace_p, &perms);
1715+ if(result < 0)
1716+ goto out;
1717+
1718+ result = acl_ptn4_get_mask(&mask_mask, perms, iflags);
1719+ if(result < 0)
1720+ goto out;
1721+
1722+ mask_mask = ~mask_mask;
1723+ }
1724+
1725+ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p);
1726+ if (result < 0)
1727+ goto out;
1728+ }
1729+
1730+ /* Get the file owner entry */
1731+ result = acl_get_entry(pacl, ACL_FIRST_ENTRY, &pace_p);
1732+ if (result < 0)
1733+ goto out;
1734+
1735+ result = acl_get_tag_type(pace_p, &ace_type);
1736+ if (result < 0)
1737+ goto out;
1738+
1739+ if (ace_type != ACL_USER_OBJ) {
1740+ errno = EINVAL;
1741+ goto out;
1742+ }
1743+
1744+ result = acl_get_permset(pace_p, &perms);
1745+ if (result < 0)
1746+ goto out;
1747+
1748+ result = acl_ptn4_get_mask(&mask, perms, iflags | NFS4_ACL_OWNER);
1749+ if (result < 0)
1750+ goto out;
1751+
1752+ result = acl_nfs4_add_pair(acl, eflag, mask, NFS4_ACL_WHO_OWNER, NULL);
1753+
1754+ if (result < 0)
1755+ goto out;
1756+
1757+ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p);
1758+ if (result < 0)
1759+ goto out;
1760+
1761+ result2 = acl_get_tag_type(pace_p, &ace_type);
1762+ if (result2 < 0)
1763+ goto out;
1764+
1765+ while (ace_type == ACL_USER && result > 0) {
1766+ result = acl_get_permset(pace_p, &perms);
1767+ if (result < 0)
1768+ goto out;
1769+
1770+ result = acl_ptn4_get_mask(&mask, perms, iflags);
1771+ if (result < 0)
1772+ goto out;
1773+
1774+ uid_p = acl_get_qualifier(pace_p);
1775+
1776+ who_buf = who_buf_static;
1777+ who_buflen = who_buflen_static;
1778+
1779+ result = nfs4_init_name_mapping(NULL);
1780+ result = nfs4_uid_to_name(*uid_p, nfs_domain, who_buf, who_buflen);
1781+
1782+
1783+ while (result == -ENOBUFS) {
1784+ if (who_buf != who_buf_static)
1785+ free(who_buf);
1786+
1787+ /* Increase the size by a full buflen unit */
1788+ who_buflen += who_buflen_static;
1789+ who_buf = malloc(who_buflen);
1790+
1791+ if (who_buf == NULL) {
1792+ result = -ENOMEM;
1793+ break;
1794+ }
1795+
1796+ result = nfs4_init_name_mapping(NULL);
1797+ result = nfs4_uid_to_name(*uid_p, nfs_domain, who_buf, who_buflen);
1798+
1799+ }
1800+ acl_free(uid_p);
1801+ if (result < 0) {
1802+ errno = -result;
1803+ goto out;
1804+ }
1805+
1806+ if (who_buf == NULL)
1807+ goto out;
1808+
1809+ result = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE,
1810+ eflag, mask_mask, NFS4_ACL_WHO_NAMED, who_buf);
1811+ if (result < 0) {
1812+ if(who_buf != who_buf_static)
1813+ free(who_buf);
1814+ goto out;
1815+ }
1816+
1817+ result = acl_nfs4_add_pair(acl, eflag, mask, NFS4_ACL_WHO_NAMED,
1818+ who_buf);
1819+ if (who_buf != who_buf_static)
1820+ free(who_buf);
1821+ if (result < 0)
1822+ goto out;
1823+
1824+ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p);
1825+ if (result <= 0)
1826+ goto out;
1827+
1828+ result2 = acl_get_tag_type(pace_p, &ace_type);
1829+ if (result2 < 0)
1830+ goto out;
1831+
1832+ }
1833+
1834+ /* In the case of groups, we apply allow ACEs first, then deny ACEs,
1835+ * since a user can be in more than one group. */
1836+
1837+ /* allow ACEs */
1838+
1839+ if (num_aces > 3) {
1840+ result2 = acl_get_tag_type(pace_p, &ace_type);
1841+ if (result2 < 0)
1842+ goto out;
1843+
1844+ if (ace_type != ACL_GROUP_OBJ) {
1845+ errno = EINVAL;
1846+ goto out;
1847+ }
1848+
1849+ result = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE,
1850+ NFS4_ACE_IDENTIFIER_GROUP | eflag, mask_mask,
1851+ NFS4_ACL_WHO_GROUP, NULL);
1852+
1853+ if (result < 0)
1854+ goto out;
1855+ }
1856+
1857+ result = acl_get_permset(pace_p, &perms);
1858+ if (result < 0)
1859+ goto out;
1860+
1861+ result = acl_ptn4_get_mask(&mask, perms, iflags);
1862+ if (result < 0)
1863+ goto out;
1864+
1865+ result = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE,
1866+ NFS4_ACE_IDENTIFIER_GROUP | eflag, mask, NFS4_ACL_WHO_GROUP, NULL);
1867+
1868+ if (result < 0)
1869+ goto out;
1870+
1871+ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p);
1872+ if (result <= 0)
1873+ goto out;
1874+
1875+ result2 = acl_get_tag_type(pace_p, &ace_type);
1876+ if (result2 < 0)
1877+ goto out;
1878+
1879+ while (ace_type == ACL_GROUP && result > 0) {
1880+ result = acl_get_permset(pace_p, &perms);
1881+ if (result < 0)
1882+ goto out;
1883+
1884+ result = acl_ptn4_get_mask(&mask, perms, iflags);
1885+ if (result < 0)
1886+ goto out;
1887+
1888+ gid_p = acl_get_qualifier(pace_p);
1889+
1890+ who_buf = who_buf_static;
1891+ who_buflen = who_buflen_static;
1892+
1893+ result = nfs4_gid_to_name(*gid_p, nfs_domain, who_buf, who_buflen);
1894+
1895+
1896+ while (result == -ENOBUFS) {
1897+ if (who_buf != who_buf_static)
1898+ free(who_buf);
1899+
1900+ /* Increase the size by a full buflen unit */
1901+ who_buflen += who_buflen_static;
1902+ who_buf = malloc(who_buflen);
1903+
1904+ if (who_buf == NULL) {
1905+ result = -ENOMEM;
1906+ break;
1907+ }
1908+
1909+ result = nfs4_gid_to_name(*gid_p, nfs_domain, who_buf, who_buflen);
1910+ }
1911+
1912+ acl_free(gid_p);
1913+
1914+ if (result < 0) {
1915+ errno = -result;
1916+ goto out;
1917+ }
1918+
1919+ if (who_buf == NULL)
1920+ goto out;
1921+
1922+ result = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE,
1923+ NFS4_ACE_IDENTIFIER_GROUP | eflag, mask_mask,
1924+ NFS4_ACL_WHO_NAMED, who_buf);
1925+ if (result < 0) {
1926+ if(who_buf != who_buf_static)
1927+ free(who_buf);
1928+ goto out;
1929+ }
1930+
1931+ result = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE,
1932+ NFS4_ACE_IDENTIFIER_GROUP | eflag, mask,
1933+ NFS4_ACL_WHO_NAMED, who_buf);
1934+
1935+ if (who_buf != who_buf_static)
1936+ free(who_buf);
1937+
1938+ if (result < 0)
1939+ goto out;
1940+ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p);
1941+ if (result <= 0)
1942+ goto out;
1943+
1944+ result2 = acl_get_tag_type(pace_p, &ace_type);
1945+ if (result2 < 0)
1946+ goto out;
1947+ }
1948+
1949+ /* deny ACEs */
1950+
1951+ result = acl_get_entry(pacl, ACL_FIRST_ENTRY, &pace_p);
1952+ if (result <= 0)
1953+ goto out;
1954+
1955+ result2 = acl_get_tag_type(pace_p, &ace_type);
1956+ if (result2 < 0)
1957+ goto out;
1958+
1959+ while (ace_type != ACL_GROUP_OBJ && result > 0) {
1960+ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p);
1961+ if(result <= 0)
1962+ goto out;
1963+
1964+ result2 = acl_get_tag_type(pace_p, &ace_type);
1965+ if(result2 < 0)
1966+ goto out;
1967+ }
1968+
1969+ result = acl_get_permset(pace_p, &perms);
1970+ if (result < 0)
1971+ goto out;
1972+
1973+ result = acl_ptn4_get_mask(&mask, perms, iflags);
1974+ if (result < 0)
1975+ goto out;
1976+
1977+ result = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE,
1978+ NFS4_ACE_IDENTIFIER_GROUP | eflag, ~mask, NFS4_ACL_WHO_GROUP,
1979+ NULL);
1980+
1981+ if (result < 0)
1982+ goto out;
1983+
1984+ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p);
1985+ if (result <= 0)
1986+ goto out;
1987+
1988+ result2 = acl_get_tag_type(pace_p, &ace_type);
1989+ if (result2 < 0)
1990+ goto out;
1991+
1992+ while (ace_type == ACL_GROUP && result > 0) {
1993+ result = acl_get_permset(pace_p, &perms);
1994+ if (result < 0)
1995+ goto out;
1996+
1997+ result = acl_ptn4_get_mask(&mask, perms, iflags);
1998+ if (result < 0)
1999+ goto out;
2000+
2001+ gid_p = acl_get_qualifier(pace_p);
2002+
2003+ who_buf = who_buf_static;
2004+ who_buflen = who_buflen_static;
2005+
2006+ result = nfs4_gid_to_name(*gid_p, nfs_domain, who_buf, who_buflen);
2007+
2008+
2009+ while (result == -ENOBUFS) {
2010+ if (who_buf != who_buf_static)
2011+ free(who_buf);
2012+
2013+ /* Increase the size by a full buflen unit */
2014+ who_buflen += who_buflen_static;
2015+ who_buf = malloc(who_buflen);
2016+
2017+ if (who_buf == NULL) {
2018+ result = -ENOMEM;
2019+ break;
2020+ }
2021+
2022+ result = nfs4_gid_to_name(*gid_p, nfs_domain, who_buf, who_buflen);
2023+ }
2024+
2025+ acl_free(gid_p);
2026+
2027+ if (result < 0) {
2028+ errno = -result;
2029+ goto out;
2030+ }
2031+
2032+ if (who_buf == NULL)
2033+ goto out;
2034+
2035+ result = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE,
2036+ NFS4_ACE_IDENTIFIER_GROUP | eflag, ~mask,
2037+ NFS4_ACL_WHO_NAMED, who_buf);
2038+ if (who_buf != who_buf_static)
2039+ free(who_buf);
2040+ if (result < 0)
2041+ goto out;
2042+
2043+ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p);
2044+ if (result <= 0)
2045+ goto out;
2046+
2047+ result2 = acl_get_tag_type(pace_p, &ace_type);
2048+ if (result2 < 0)
2049+ goto out;
2050+ }
2051+
2052+ if (ace_type == ACL_MASK) {
2053+ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p);
2054+ if (result <= 0)
2055+ goto out;
2056+
2057+ result2 = acl_get_tag_type(pace_p, &ace_type);
2058+ if (result2 < 0)
2059+ goto out;
2060+ }
2061+
2062+ if (ace_type != ACL_OTHER) {
2063+ errno = EINVAL;
2064+ goto out;
2065+ }
2066+
2067+ result = acl_get_permset(pace_p, &perms);
2068+ if (result < 0)
2069+ goto out;
2070+
2071+ result = acl_ptn4_get_mask(&mask, perms, iflags);
2072+ if (result < 0)
2073+ goto out;
2074+
2075+ result = acl_nfs4_add_pair(acl, eflag, mask, NFS4_ACL_WHO_EVERYONE, NULL);
2076+
2077+ return result;
2078+out:
2079+ if (allocated)
2080+ acl_nfs4_free(acl);
2081+ return -1;
2082+}
2083--- acl-2.2.39/libacl/acl_get_fd.c.orig 2006-06-20 02:51:25.000000000 -0400
2084+++ acl-2.2.39/libacl/acl_get_fd.c 2007-08-22 12:02:13.000000000 -0400
2085@@ -28,6 +28,10 @@
2086 #include "libacl.h"
2087 #include "__acl_from_xattr.h"
2088
2089+#ifdef USE_NFSV4_TRANS
2090+ #include "libacl_nfs4.h"
2091+#endif
2092+
2093 #include "byteorder.h"
2094 #include "acl_ea.h"
2095
2096@@ -38,31 +42,59 @@ acl_get_fd(int fd)
2097 {
2098 const size_t size_guess = acl_ea_size(16);
2099 char *ext_acl_p = alloca(size_guess);
2100+ char *name = ACL_EA_ACCESS;
2101 int retval;
2102+ int nfsv4acls;
2103
2104 if (!ext_acl_p)
2105 return NULL;
2106- retval = fgetxattr(fd, ACL_EA_ACCESS, ext_acl_p, size_guess);
2107+
2108+#ifdef USE_NFSV4_TRANS
2109+ retval = fgetxattr(fd, ACL_NFS4_XATTR, ext_acl_p, size_guess);
2110+ if(retval == -1 && (errno == ENOATTR || errno == EOPNOTSUPP)) {
2111+ nfsv4acls = ACL_NFS4_NOT_USED;
2112+ retval = fgetxattr(fd, name, ext_acl_p, size_guess);
2113+ } else {
2114+ nfsv4acls = ACL_NFS4_USED;
2115+ name = ACL_NFS4_XATTR;
2116+ }
2117+#else
2118+ retval = fgetxattr(fd, name, ext_acl_p, size_guess);
2119+#endif
2120+
2121 if (retval == -1 && errno == ERANGE) {
2122- retval = fgetxattr(fd, ACL_EA_ACCESS, NULL, 0);
2123+ retval = fgetxattr(fd, name, NULL, 0);
2124 if (retval > 0) {
2125 ext_acl_p = alloca(retval);
2126 if (!ext_acl_p)
2127 return NULL;
2128- retval = fgetxattr(fd, ACL_EA_ACCESS, ext_acl_p,retval);
2129+ retval = fgetxattr(fd, name, ext_acl_p, retval);
2130 }
2131 }
2132 if (retval > 0) {
2133- acl_t acl = __acl_from_xattr(ext_acl_p, retval);
2134- return acl;
2135+#ifdef USE_NFSV4_TRANS
2136+ if(nfsv4acls == ACL_NFS4_USED) {
2137+ acl_t acl = __posix_acl_from_nfs4_xattr(ext_acl_p, retval,
2138+ ACL_TYPE_ACCESS, NFS4_ACL_ISFILE);
2139+
2140+ return acl;
2141+ }
2142+ else
2143+#endif
2144+ {
2145+ acl_t acl = __acl_from_xattr(ext_acl_p, retval);
2146+ return acl;
2147+ }
2148 } else if (retval == 0 || errno == ENOATTR || errno == ENODATA) {
2149 struct stat st;
2150
2151- if (fstat(fd, &st) == 0)
2152- return acl_from_mode(st.st_mode);
2153- else
2154+ if (fstat(fd, &st) != 0) {
2155 return NULL;
2156- } else
2157+ }
2158+
2159+ return acl_from_mode(st.st_mode);
2160+ } else {
2161 return NULL;
2162+ }
2163 }
2164
2165--- /dev/null 2007-08-22 11:21:03.626521839 -0400
2166+++ acl-2.2.39/libacl/acl_nfs4_xattr_size.c 2007-08-22 12:02:13.000000000 -0400
2167@@ -0,0 +1,91 @@
2168+/*
2169+ * NFSv4 ACL Code
2170+ * Return the expected xattr XDR encoded size of the nfs acl. Used for
2171+ * figuring the size of the xattr buffer.
2172+ *
2173+ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
2174+ * All rights reserved.
2175+ *
2176+ * Nathaniel Gallaher <ngallahe@umich.edu>
2177+ *
2178+ * Redistribution and use in source and binary forms, with or without
2179+ * modification, are permitted provided that the following conditions
2180+ * are met:
2181+ *
2182+ * 1. Redistributions of source code must retain the above copyright
2183+ * notice, this list of conditions and the following disclaimer.
2184+ * 2. Redistributions in binary form must reproduce the above copyright
2185+ * notice, this list of conditions and the following disclaimer in the
2186+ * documentation and/or other materials provided with the distribution.
2187+ * 3. Neither the name of the University nor the names of its
2188+ * contributors may be used to endorse or promote products derived
2189+ * from this software without specific prior written permission.
2190+ *
2191+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
2192+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2193+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2194+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2195+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2196+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2197+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
2198+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2199+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2200+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2201+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2202+ */
2203+
2204+#include <libacl_nfs4.h>
2205+
2206+int acl_nfs4_xattr_size(struct nfs4_acl * acl)
2207+{
2208+ int size = 0;
2209+ struct nfs4_ace * ace;
2210+ int ace_num;
2211+ int num_aces;
2212+
2213+ if(acl == NULL) {
2214+ errno = EINVAL;
2215+ goto failed;
2216+ }
2217+
2218+ /* Space for number of aces */
2219+ size += sizeof(u32);
2220+
2221+ ace = acl->ace_head.tqh_first;
2222+ ace_num = 1;
2223+
2224+ num_aces = acl->naces;
2225+
2226+ while(1)
2227+ {
2228+ if(ace == NULL) {
2229+ if(ace_num > num_aces) {
2230+ break;
2231+ } else {
2232+ errno = ENODATA;
2233+ goto failed;
2234+ }
2235+ }
2236+
2237+ /* space for type, flag, and mask */
2238+ size += (3 * sizeof(u32));
2239+
2240+ /* space for strlen */
2241+ size += sizeof(u32);
2242+
2243+ /* space for the who string... xdr encoded */
2244+ size += (strlen(ace->who) / NFS4_XDR_MOD) * NFS4_XDR_MOD * sizeof(char);
2245+ if(strlen(ace->who) % NFS4_XDR_MOD) {
2246+ size += NFS4_XDR_MOD;
2247+ }
2248+
2249+ ace = ace->l_ace.tqe_next;
2250+ ace_num++;
2251+ }
2252+
2253+ return size;
2254+
2255+failed:
2256+ return -1;
2257+}
2258+
2259--- /dev/null 2007-08-22 11:21:03.626521839 -0400
2260+++ acl-2.2.39/libacl/acl_ptn4_get_mask.c 2007-08-22 12:02:13.000000000 -0400
2261@@ -0,0 +1,81 @@
2262+/*
2263+ * NFSv4 ACL Code
2264+ * Translate POSIX permissions to an NFSv4 mask
2265+ *
2266+ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
2267+ * All rights reserved.
2268+ *
2269+ * Nathaniel Gallaher <ngallahe@umich.edu>
2270+ *
2271+ * Redistribution and use in source and binary forms, with or without
2272+ * modification, are permitted provided that the following conditions
2273+ * are met:
2274+ *
2275+ * 1. Redistributions of source code must retain the above copyright
2276+ * notice, this list of conditions and the following disclaimer.
2277+ * 2. Redistributions in binary form must reproduce the above copyright
2278+ * notice, this list of conditions and the following disclaimer in the
2279+ * documentation and/or other materials provided with the distribution.
2280+ * 3. Neither the name of the University nor the names of its
2281+ * contributors may be used to endorse or promote products derived
2282+ * from this software without specific prior written permission.
2283+ *
2284+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
2285+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2286+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2287+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2288+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2289+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2290+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
2291+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2292+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2293+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2294+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2295+ */
2296+
2297+#include <acl/libacl.h>
2298+#include <libacl_nfs4.h>
2299+
2300+int acl_ptn4_get_mask(u32* mask, acl_permset_t perms, int iflags)
2301+{
2302+ int result;
2303+
2304+ *mask = NFS4_ANYONE_MODE;
2305+
2306+ if (perms == NULL) {
2307+ errno = EINVAL;
2308+ goto failed;
2309+ }
2310+
2311+ if (iflags & NFS4_ACL_OWNER)
2312+ *mask |= NFS4_OWNER_MODE;
2313+
2314+ result = acl_get_perm(perms, ACL_READ);
2315+ if (result < 0)
2316+ goto failed;
2317+ else if(result == 1)
2318+ *mask |= NFS4_READ_MODE;
2319+
2320+ result = acl_get_perm(perms, ACL_WRITE);
2321+ if (result < 0)
2322+ goto failed;
2323+ else if (result == 1) {
2324+ *mask |= NFS4_WRITE_MODE;
2325+ if (iflags & NFS4_ACL_ISDIR)
2326+ *mask |= NFS4_ACE_DELETE_CHILD;
2327+ }
2328+
2329+ result = acl_get_perm(perms, ACL_EXECUTE);
2330+ if (result < 0)
2331+ goto failed;
2332+ else if (result == 1)
2333+ *mask |= NFS4_EXECUTE_MODE;
2334+
2335+ return 0;
2336+
2337+failed:
2338+ return -1;
2339+}
2340+
2341+
2342+
2343--- acl-2.2.39/libacl/acl_get_file.c.orig 2006-06-20 02:51:25.000000000 -0400
2344+++ acl-2.2.39/libacl/acl_get_file.c 2007-08-22 12:02:13.000000000 -0400
2345@@ -28,6 +28,10 @@
2346 #include "libacl.h"
2347 #include "__acl_from_xattr.h"
2348
2349+#ifdef USE_NFSV4_TRANS
2350+ #include "libacl_nfs4.h"
2351+#endif
2352+
2353 #include "byteorder.h"
2354 #include "acl_ea.h"
2355
2356@@ -40,6 +44,8 @@ acl_get_file(const char *path_p, acl_typ
2357 char *ext_acl_p = alloca(size_guess);
2358 const char *name;
2359 int retval;
2360+ int nfsv4acls;
2361+ int iflags;
2362
2363 switch(type) {
2364 case ACL_TYPE_ACCESS:
2365@@ -55,8 +61,20 @@ acl_get_file(const char *path_p, acl_typ
2366
2367 if (!ext_acl_p)
2368 return NULL;
2369+#ifdef USE_NFSV4_TRANS
2370+ retval = getxattr(path_p, ACL_NFS4_XATTR, ext_acl_p, size_guess);
2371+ if((retval == -1) && (errno == ENOATTR || errno == EOPNOTSUPP)) {
2372+ nfsv4acls = ACL_NFS4_NOT_USED;
2373+ retval = getxattr(path_p, name, ext_acl_p, size_guess);
2374+ } else {
2375+ nfsv4acls = ACL_NFS4_USED;
2376+ name = ACL_NFS4_XATTR;
2377+ }
2378+#else
2379 retval = getxattr(path_p, name, ext_acl_p, size_guess);
2380- if (retval == -1 && errno == ERANGE) {
2381+#endif
2382+
2383+ if ((retval == -1) && (errno == ERANGE)) {
2384 retval = getxattr(path_p, name, NULL, 0);
2385 if (retval > 0) {
2386 ext_acl_p = alloca(retval);
2387@@ -66,9 +84,29 @@ acl_get_file(const char *path_p, acl_typ
2388 }
2389 }
2390 if (retval > 0) {
2391- acl_t acl = __acl_from_xattr(ext_acl_p, retval);
2392- return acl;
2393- } else if (retval == 0 || errno == ENOATTR || errno == ENODATA) {
2394+#ifdef USE_NFSV4_TRANS
2395+ if(nfsv4acls == ACL_NFS4_USED) {
2396+ struct stat st;
2397+
2398+ iflags = NFS4_ACL_ISFILE;
2399+
2400+ if (stat(path_p, &st) != 0)
2401+ return NULL;
2402+
2403+ if (S_ISDIR(st.st_mode))
2404+ iflags = NFS4_ACL_ISDIR;
2405+
2406+ acl_t acl = __posix_acl_from_nfs4_xattr(ext_acl_p, retval, type,
2407+ iflags);
2408+ return acl;
2409+ }
2410+ else
2411+#endif
2412+ {
2413+ acl_t acl = __acl_from_xattr(ext_acl_p, retval);
2414+ return acl;
2415+ }
2416+ } else if ((retval == 0) || (errno == ENOATTR) || (errno == ENODATA)) {
2417 struct stat st;
2418
2419 if (stat(path_p, &st) != 0)
2420--- /dev/null 2007-08-22 11:21:03.626521839 -0400
2421+++ acl-2.2.39/libacl/libacl_nfs4.h 2007-08-22 12:02:13.000000000 -0400
2422@@ -0,0 +1,97 @@
2423+#include <sys/types.h>
2424+#include <pwd.h>
2425+#include <grp.h>
2426+#include <sys/acl.h>
2427+#include <stdlib.h>
2428+#include <sys/queue.h>
2429+#include <nfs4.h>
2430+#include <sys/errno.h>
2431+#include <string.h>
2432+
2433+/* mode bit translations: */
2434+#define NFS4_READ_MODE NFS4_ACE_READ_DATA
2435+#define NFS4_WRITE_MODE (NFS4_ACE_WRITE_DATA | NFS4_ACE_APPEND_DATA)
2436+#define NFS4_EXECUTE_MODE NFS4_ACE_EXECUTE
2437+#define NFS4_ANYONE_MODE (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL | \
2438+ NFS4_ACE_SYNCHRONIZE)
2439+#define NFS4_OWNER_MODE (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL)
2440+
2441+#define NFS4_ACE_MASK_IGNORE (NFS4_ACE_DELETE | NFS4_ACE_WRITE_OWNER \
2442+ | NFS4_ACE_READ_NAMED_ATTRS | NFS4_ACE_WRITE_NAMED_ATTRS)
2443+/* XXX not sure about the following. Note that e.g. DELETE_CHILD is wrong in
2444+ * general (should only be ignored on files). */
2445+#define MASK_EQUAL(mask1, mask2) \
2446+ (((mask1) & NFS4_ACE_MASK_ALL & ~NFS4_ACE_MASK_IGNORE & \
2447+ ~NFS4_ACE_DELETE_CHILD) \
2448+ == ((mask2) & NFS4_ACE_MASK_ALL & ~NFS4_ACE_MASK_IGNORE & \
2449+ ~NFS4_ACE_DELETE_CHILD))
2450+
2451+/* Maximum length of the ace->who attribute */
2452+#define NFS4_ACL_WHO_LENGTH_MAX 2048
2453+#define NFS4_ACL_WHO_BUFFER_LEN_GUESS 255
2454+
2455+/* NFS4 acl xattr name */
2456+#define ACL_NFS4_XATTR "system.nfs4_acl"
2457+
2458+/* Macro for finding empty tailqs */
2459+#define TAILQ_IS_EMPTY(head) (head.tqh_first == NULL)
2460+
2461+/* Flags to pass certain properties around */
2462+#define NFS4_ACL_NOFLAGS 0x00
2463+#define NFS4_ACL_ISFILE 0x00
2464+#define NFS4_ACL_ISDIR 0x01
2465+#define NFS4_ACL_OWNER 0x02
2466+#define NFS4_ACL_REQUEST_DEFAULT 0x04
2467+#define NFS4_ACL_RAW 0x01
2468+
2469+#define NFS4_XDR_MOD 4
2470+
2471+typedef u_int32_t u32;
2472+
2473+enum { ACL_NFS4_NOT_USED = 0,
2474+ ACL_NFS4_USED
2475+};
2476+
2477+struct ace_container {
2478+ struct nfs4_ace *ace;
2479+ TAILQ_ENTRY(ace_container) l_ace;
2480+};
2481+
2482+TAILQ_HEAD(ace_container_list_head, ace_container);
2483+
2484+/**** Public functions ****/
2485+
2486+/** Manipulation functions **/
2487+extern int acl_nfs4_add_ace(struct nfs4_acl *, u32, u32, u32, int, char*);
2488+extern int acl_nfs4_add_pair(struct nfs4_acl *, int, u32, int, char*);
2489+extern void acl_nfs4_free(struct nfs4_acl *);
2490+extern struct nfs4_acl *acl_nfs4_new(u32);
2491+extern int acl_nfs4_set_who(struct nfs4_ace*, int, char*);
2492+extern struct nfs4_acl *acl_nfs4_copy_acl(struct nfs4_acl *);
2493+extern struct nfs4_acl *acl_nfs4_xattr_load(char *, int, u32);
2494+extern int acl_nfs4_xattr_pack(struct nfs4_acl *, char**);
2495+extern int acl_nfs4_xattr_size(struct nfs4_acl *);
2496+extern void acl_nfs4_remove_ace(struct nfs4_acl * acl, struct nfs4_ace * ace);
2497+
2498+/** Conversion functions **/
2499+
2500+/* nfs4 -> posix */
2501+extern acl_t acl_n4tp_acl_trans(struct nfs4_acl *, acl_type_t);
2502+
2503+/* posix -> nfs4 */
2504+extern int acl_ptn4_get_mask(u32* mask, acl_permset_t perms,
2505+ int iflags);
2506+extern int acl_ptn4_acl_trans(acl_t, struct nfs4_acl *, acl_type_t, u32, char*);
2507+
2508+
2509+/** Access Functions **/
2510+extern inline int acl_nfs4_get_whotype(char*);
2511+extern int acl_nfs4_get_who(struct nfs4_ace*, int*, char**);
2512+
2513+/**** Private(?) functions ****/
2514+acl_t __posix_acl_from_nfs4_xattr(char*, int, acl_type_t, u32);
2515+
2516+/* These will change */
2517+char * nfs4_get_who_from_uid(uid_t);
2518+char * nfs4_get_who_from_gid(gid_t);
2519+/* End change */
2520--- /dev/null 2007-08-22 11:21:03.626521839 -0400
2521+++ acl-2.2.39/libacl/acl_nfs4_new.c 2007-08-22 12:02:13.000000000 -0400
2522@@ -0,0 +1,58 @@
2523+/*
2524+ * Common NFSv4 ACL handling code.
2525+ * Create a new NFSv4 ACL
2526+ *
2527+ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
2528+ * All rights reserved.
2529+ *
2530+ * Marius Aamodt Eriksen <marius@umich.edu>
2531+ * J. Bruce Fields <bfields@umich.edu>
2532+ * Nathaniel Gallaher <ngallahe@umich.edu>
2533+ * Jeff Sedlak <jsedlak@umich.edu>
2534+ *
2535+ * Redistribution and use in source and binary forms, with or without
2536+ * modification, are permitted provided that the following conditions
2537+ * are met:
2538+ *
2539+ * 1. Redistributions of source code must retain the above copyright
2540+ * notice, this list of conditions and the following disclaimer.
2541+ * 2. Redistributions in binary form must reproduce the above copyright
2542+ * notice, this list of conditions and the following disclaimer in the
2543+ * documentation and/or other materials provided with the distribution.
2544+ * 3. Neither the name of the University nor the names of its
2545+ * contributors may be used to endorse or promote products derived
2546+ * from this software without specific prior written permission.
2547+ *
2548+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
2549+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2550+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2551+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2552+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2553+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2554+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
2555+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2556+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2557+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2558+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2559+ */
2560+
2561+
2562+
2563+#include "libacl_nfs4.h"
2564+
2565+struct nfs4_acl *
2566+acl_nfs4_new(u32 is_dir)
2567+{
2568+ struct nfs4_acl *acl;
2569+
2570+ if ((acl = malloc(sizeof(*acl))) == NULL)
2571+ return NULL;
2572+
2573+ acl->naces = 0;
2574+ acl->is_directory = is_dir;
2575+
2576+ TAILQ_INIT(&acl->ace_head);
2577+
2578+ return acl;
2579+}
2580+
2581--- /dev/null 2007-08-22 11:21:03.626521839 -0400
2582+++ acl-2.2.39/libacl/acl_nfs4_copy_acl.c 2007-08-22 12:02:13.000000000 -0400
2583@@ -0,0 +1,85 @@
2584+/*
2585+ * NFSv4 ACL Code
2586+ * Deep copy an NFS4 ACL
2587+ *
2588+ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
2589+ * All rights reserved.
2590+ *
2591+ * Nathaniel Gallaher <ngallahe@umich.edu>
2592+ *
2593+ * Redistribution and use in source and binary forms, with or without
2594+ * modification, are permitted provided that the following conditions
2595+ * are met:
2596+ *
2597+ * 1. Redistributions of source code must retain the above copyright
2598+ * notice, this list of conditions and the following disclaimer.
2599+ * 2. Redistributions in binary form must reproduce the above copyright
2600+ * notice, this list of conditions and the following disclaimer in the
2601+ * documentation and/or other materials provided with the distribution.
2602+ * 3. Neither the name of the University nor the names of its
2603+ * contributors may be used to endorse or promote products derived
2604+ * from this software without specific prior written permission.
2605+ *
2606+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
2607+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2608+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2609+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2610+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2611+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2612+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
2613+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2614+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2615+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2616+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2617+ */
2618+
2619+#include "libacl_nfs4.h"
2620+
2621+struct nfs4_acl * acl_nfs4_copy_acl(struct nfs4_acl * nacl)
2622+{
2623+ struct nfs4_acl * new_acl;
2624+ struct nfs4_ace * ace;
2625+ u32 nace;
2626+ u32 num_aces;
2627+ int result;
2628+
2629+ if(nacl == NULL) {
2630+ errno = EINVAL;
2631+ goto failed;
2632+ }
2633+
2634+ num_aces = nacl->naces;
2635+
2636+ new_acl = acl_nfs4_new(nacl->is_directory);
2637+ if(new_acl == NULL)
2638+ goto failed;
2639+
2640+ ace = nacl->ace_head.tqh_first;
2641+ nace = 1;
2642+
2643+ while(1)
2644+ {
2645+ if(ace == NULL) {
2646+ if(nace > num_aces)
2647+ break;
2648+ else
2649+ goto free_failed;
2650+ }
2651+
2652+ result = acl_nfs4_add_ace(new_acl, ace->type, ace->flag,
2653+ ace->access_mask, acl_nfs4_get_whotype(ace->who), ace->who);
2654+ if(result < 0)
2655+ goto free_failed;
2656+
2657+ ace = ace->l_ace.tqe_next;
2658+ nace++;
2659+ }
2660+
2661+ return new_acl;
2662+
2663+free_failed:
2664+ acl_nfs4_free(new_acl);
2665+
2666+failed:
2667+ return NULL;
2668+}
2669--- /dev/null 2007-08-22 11:21:03.626521839 -0400
2670+++ acl-2.2.39/libacl/acl_nfs4_add_pair.c 2007-08-22 12:02:13.000000000 -0400
2671@@ -0,0 +1,60 @@
2672+/*
2673+ * Add a pair of aces to the acl. The ace masks are complements of each other
2674+ * This keeps us from walking off the end of the acl
2675+ *
2676+ * Copyright (c) 2004 The Regents of the University of Michigan.
2677+ * All rights reserved.
2678+ *
2679+ * Marius Aamodt Eriksen <marius@umich.edu>
2680+ * J. Bruce Fields <bfields@umich.edu>
2681+ * Nathaniel Gallaher <ngallahe@umich.edu>
2682+ * Jeff Sedlak <jsedlak@umich.edu>
2683+ *
2684+ * Redistribution and use in source and binary forms, with or without
2685+ * modification, are permitted provided that the following conditions
2686+ * are met:
2687+ *
2688+ * 1. Redistributions of source code must retain the above copyright
2689+ * notice, this list of conditions, the following disclaimer, and
2690+ * any and all other licensing or copyright notices included in
2691+ * any files in this distribution.
2692+ * 2. Redistributions in binary form must reproduce the above copyright
2693+ * notice, this list of conditions and the following disclaimer in the
2694+ * documentation and/or other materials provided with the distribution.
2695+ * 3. Neither the name of the University nor the names of its
2696+ * contributors may be used to endorse or promote products derived
2697+ * from this software without specific prior written permission.
2698+ *
2699+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
2700+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2701+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2702+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2703+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2704+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2705+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
2706+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2707+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2708+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2709+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2710+ *
2711+ */
2712+
2713+
2714+#include "libacl_nfs4.h"
2715+
2716+int
2717+acl_nfs4_add_pair(struct nfs4_acl *acl, int eflag, u32 mask, int ownertype,
2718+ char* owner)
2719+{
2720+ int error;
2721+
2722+ error = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE,
2723+ eflag, mask, ownertype, owner);
2724+ if (error < 0)
2725+ return error;
2726+ error = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE,
2727+ eflag, ~mask, ownertype, owner);
2728+ return error;
2729+}
2730+
2731+
2732--- acl-2.2.39/exports.orig 2006-06-20 02:51:25.000000000 -0400
2733+++ acl-2.2.39/exports 2007-08-22 12:02:13.000000000 -0400
2734@@ -67,3 +67,33 @@ ACL_1.1 {
2735 perm_copy_fd;
2736 perm_copy_file;
2737 } ACL_1.0;
2738+
2739+ACL_1.2 {
2740+ global:
2741+ acl_nfs4_add_ace;
2742+ acl_nfs4_add_pair;
2743+ acl_nfs4_free;
2744+ acl_nfs4_new;
2745+ acl_nfs4_set_dir;
2746+ acl_nfs4_set_who;
2747+ acl_nfs4_copy_acl;
2748+ acl_nfs4_xattr_load;
2749+ acl_nfs4_xattr_pack;
2750+ acl_nfs4_xattr_size;
2751+ acl_nfs4_remove_ace;
2752+
2753+ acl_n4tp_acl_trans;
2754+
2755+ acl_ptn4_get_mask;
2756+ acl_ptn4_acl_trans;
2757+
2758+ acl_nfs4_get_whotype;
2759+ acl_nfs4_get_who;
2760+ acl_nfs4_entries;
2761+
2762+ local:
2763+ __posix_acl_from_nfs4_xattr;
2764+ nfs4_get_who_from_uid;
2765+ nfs4_get_who_from_gid;
2766+
2767+} ACL_1.1;
2768--- acl-2.2.39/include/builddefs.in.orig 2007-08-22 11:59:37.000000000 -0400
2769+++ acl-2.2.39/include/builddefs.in 2007-08-22 12:02:13.000000000 -0400
2770@@ -65,7 +65,7 @@ endif
2771
2772 GCFLAGS = $(OPTIMIZER) $(DEBUG) -funsigned-char -fno-strict-aliasing -Wall \
2773 -DVERSION=\"$(PKG_VERSION)\" -DLOCALEDIR=\"$(PKG_LOCALE_DIR)\" \
2774- -DPACKAGE=\"$(PKG_NAME)\" -I$(TOPDIR)/include
2775+ -DPACKAGE=\"$(PKG_NAME)\" -I$(TOPDIR)/include -DUSE_NFSV4_TRANS
2776
2777 # Global, Platform, Local CFLAGS
2778 CFLAGS += $(GCFLAGS) $(PCFLAGS) $(LCFLAGS)
2779--- /dev/null 2007-08-22 11:21:03.626521839 -0400
2780+++ acl-2.2.39/include/nfs4.h 2007-08-22 12:02:13.000000000 -0400
2781@@ -0,0 +1,397 @@
2782+/*
2783+ * NFSv4 protocol definitions.
2784+ *
2785+ * Copyright (c) 2002 The Regents of the University of Michigan.
2786+ * All rights reserved.
2787+ *
2788+ * Kendrick Smith <kmsmith@umich.edu>
2789+ * Andy Adamson <andros@umich.edu>
2790+ */
2791+
2792+#include<sys/types.h>
2793+#include<sys/queue.h>
2794+
2795+#ifndef _LINUX_NFS4_H
2796+#define _LINUX_NFS4_H
2797+
2798+#define NFS4_VERIFIER_SIZE 8
2799+#define NFS4_FHSIZE 128
2800+#define NFS4_MAXNAMLEN NAME_MAX
2801+
2802+#define NFS4_ACCESS_READ 0x0001
2803+#define NFS4_ACCESS_LOOKUP 0x0002
2804+#define NFS4_ACCESS_MODIFY 0x0004
2805+#define NFS4_ACCESS_EXTEND 0x0008
2806+#define NFS4_ACCESS_DELETE 0x0010
2807+#define NFS4_ACCESS_EXECUTE 0x0020
2808+
2809+#define NFS4_FH_PERISTENT 0x0000
2810+#define NFS4_FH_NOEXPIRE_WITH_OPEN 0x0001
2811+#define NFS4_FH_VOLATILE_ANY 0x0002
2812+#define NFS4_FH_VOL_MIGRATION 0x0004
2813+#define NFS4_FH_VOL_RENAME 0x0008
2814+
2815+#define NFS4_OPEN_RESULT_CONFIRM 0x0002
2816+
2817+#define NFS4_SHARE_ACCESS_READ 0x0001
2818+#define NFS4_SHARE_ACCESS_WRITE 0x0002
2819+#define NFS4_SHARE_ACCESS_BOTH 0x0003
2820+#define NFS4_SHARE_DENY_READ 0x0001
2821+#define NFS4_SHARE_DENY_WRITE 0x0002
2822+#define NFS4_SHARE_DENY_BOTH 0x0003
2823+
2824+#define NFS4_SET_TO_SERVER_TIME 0
2825+#define NFS4_SET_TO_CLIENT_TIME 1
2826+
2827+#define NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE 0
2828+#define NFS4_ACE_ACCESS_DENIED_ACE_TYPE 1
2829+#define NFS4_ACE_SYSTEM_AUDIT_ACE_TYPE 2
2830+#define NFS4_ACE_SYSTEM_ALARM_ACE_TYPE 3
2831+
2832+#define ACL4_SUPPORT_ALLOW_ACL 0x01
2833+#define ACL4_SUPPORT_DENY_ACL 0x02
2834+#define ACL4_SUPPORT_AUDIT_ACL 0x04
2835+#define ACL4_SUPPORT_ALARM_ACL 0x08
2836+
2837+#define NFS4_ACE_FILE_INHERIT_ACE 0x00000001
2838+#define NFS4_ACE_DIRECTORY_INHERIT_ACE 0x00000002
2839+#define NFS4_ACE_NO_PROPAGATE_INHERIT_ACE 0x00000004
2840+#define NFS4_ACE_INHERIT_ONLY_ACE 0x00000008
2841+#define NFS4_ACE_SUCCESSFUL_ACCESS_ACE_FLAG 0x00000010
2842+#define NFS4_ACE_FAILED_ACCESS_ACE_FLAG 0x00000020
2843+#define NFS4_ACE_IDENTIFIER_GROUP 0x00000040
2844+#define NFS4_ACE_OWNER 0x00000080
2845+#define NFS4_ACE_GROUP 0x00000100
2846+#define NFS4_ACE_EVERYONE 0x00000200
2847+
2848+#define NFS4_ACE_READ_DATA 0x00000001
2849+#define NFS4_ACE_LIST_DIRECTORY 0x00000001
2850+#define NFS4_ACE_WRITE_DATA 0x00000002
2851+#define NFS4_ACE_ADD_FILE 0x00000002
2852+#define NFS4_ACE_APPEND_DATA 0x00000004
2853+#define NFS4_ACE_ADD_SUBDIRECTORY 0x00000004
2854+#define NFS4_ACE_READ_NAMED_ATTRS 0x00000008
2855+#define NFS4_ACE_WRITE_NAMED_ATTRS 0x00000010
2856+#define NFS4_ACE_EXECUTE 0x00000020
2857+#define NFS4_ACE_DELETE_CHILD 0x00000040
2858+#define NFS4_ACE_READ_ATTRIBUTES 0x00000080
2859+#define NFS4_ACE_WRITE_ATTRIBUTES 0x00000100
2860+#define NFS4_ACE_DELETE 0x00010000
2861+#define NFS4_ACE_READ_ACL 0x00020000
2862+#define NFS4_ACE_WRITE_ACL 0x00040000
2863+#define NFS4_ACE_WRITE_OWNER 0x00080000
2864+#define NFS4_ACE_SYNCHRONIZE 0x00100000
2865+#define NFS4_ACE_GENERIC_READ 0x00120081
2866+#define NFS4_ACE_GENERIC_WRITE 0x00160106
2867+#define NFS4_ACE_GENERIC_EXECUTE 0x001200A0
2868+#define NFS4_ACE_MASK_ALL 0x001F01FF
2869+
2870+enum nfs4_acl_whotype {
2871+ NFS4_ACL_WHO_NAMED = 0,
2872+ NFS4_ACL_WHO_OWNER,
2873+ NFS4_ACL_WHO_GROUP,
2874+ NFS4_ACL_WHO_EVERYONE,
2875+};
2876+
2877+#define NFS4_ACL_WHO_OWNER_STRING "OWNER@"
2878+#define NFS4_ACL_WHO_GROUP_STRING "GROUP@"
2879+#define NFS4_ACL_WHO_EVERYONE_STRING "EVERYONE@"
2880+
2881+struct nfs4_ace {
2882+ u_int32_t type;
2883+ u_int32_t flag;
2884+ u_int32_t access_mask;
2885+ char* who;
2886+ TAILQ_ENTRY(nfs4_ace) l_ace;
2887+};
2888+
2889+TAILQ_HEAD(ace_list_head, nfs4_ace);
2890+
2891+struct nfs4_acl {
2892+ u_int32_t naces;
2893+ u_int32_t is_directory;
2894+ struct ace_list_head ace_head;
2895+};
2896+
2897+typedef struct { char data[NFS4_VERIFIER_SIZE]; } nfs4_verifier;
2898+typedef struct { char data[16]; } nfs4_stateid;
2899+
2900+enum nfs_opnum4 {
2901+ OP_ACCESS = 3,
2902+ OP_CLOSE = 4,
2903+ OP_COMMIT = 5,
2904+ OP_CREATE = 6,
2905+ OP_DELEGPURGE = 7,
2906+ OP_DELEGRETURN = 8,
2907+ OP_GETATTR = 9,
2908+ OP_GETFH = 10,
2909+ OP_LINK = 11,
2910+ OP_LOCK = 12,
2911+ OP_LOCKT = 13,
2912+ OP_LOCKU = 14,
2913+ OP_LOOKUP = 15,
2914+ OP_LOOKUPP = 16,
2915+ OP_NVERIFY = 17,
2916+ OP_OPEN = 18,
2917+ OP_OPENATTR = 19,
2918+ OP_OPEN_CONFIRM = 20,
2919+ OP_OPEN_DOWNGRADE = 21,
2920+ OP_PUTFH = 22,
2921+ OP_PUTPUBFH = 23,
2922+ OP_PUTROOTFH = 24,
2923+ OP_READ = 25,
2924+ OP_READDIR = 26,
2925+ OP_READLINK = 27,
2926+ OP_REMOVE = 28,
2927+ OP_RENAME = 29,
2928+ OP_RENEW = 30,
2929+ OP_RESTOREFH = 31,
2930+ OP_SAVEFH = 32,
2931+ OP_SECINFO = 33,
2932+ OP_SETATTR = 34,
2933+ OP_SETCLIENTID = 35,
2934+ OP_SETCLIENTID_CONFIRM = 36,
2935+ OP_VERIFY = 37,
2936+ OP_WRITE = 38,
2937+ OP_RELEASE_LOCKOWNER = 39,
2938+ OP_ILLEGAL = 10044,
2939+};
2940+
2941+enum nfsstat4 {
2942+ NFS4_OK = 0,
2943+ NFS4ERR_PERM = 1,
2944+ NFS4ERR_NOENT = 2,
2945+ NFS4ERR_IO = 5,
2946+ NFS4ERR_NXIO = 6,
2947+ NFS4ERR_ACCESS = 13,
2948+ NFS4ERR_EXIST = 17,
2949+ NFS4ERR_XDEV = 18,
2950+ /* Unused/reserved 19 */
2951+ NFS4ERR_NOTDIR = 20,
2952+ NFS4ERR_ISDIR = 21,
2953+ NFS4ERR_INVAL = 22,
2954+ NFS4ERR_FBIG = 27,
2955+ NFS4ERR_NOSPC = 28,
2956+ NFS4ERR_ROFS = 30,
2957+ NFS4ERR_MLINK = 31,
2958+ NFS4ERR_NAMETOOLONG = 63,
2959+ NFS4ERR_NOTEMPTY = 66,
2960+ NFS4ERR_DQUOT = 69,
2961+ NFS4ERR_STALE = 70,
2962+ NFS4ERR_BADHANDLE = 10001,
2963+ NFS4ERR_BAD_COOKIE = 10003,
2964+ NFS4ERR_NOTSUPP = 10004,
2965+ NFS4ERR_TOOSMALL = 10005,
2966+ NFS4ERR_SERVERFAULT = 10006,
2967+ NFS4ERR_BADTYPE = 10007,
2968+ NFS4ERR_DELAY = 10008,
2969+ NFS4ERR_SAME = 10009,
2970+ NFS4ERR_DENIED = 10010,
2971+ NFS4ERR_EXPIRED = 10011,
2972+ NFS4ERR_LOCKED = 10012,
2973+ NFS4ERR_GRACE = 10013,
2974+ NFS4ERR_FHEXPIRED = 10014,
2975+ NFS4ERR_SHARE_DENIED = 10015,
2976+ NFS4ERR_WRONGSEC = 10016,
2977+ NFS4ERR_CLID_INUSE = 10017,
2978+ NFS4ERR_RESOURCE = 10018,
2979+ NFS4ERR_MOVED = 10019,
2980+ NFS4ERR_NOFILEHANDLE = 10020,
2981+ NFS4ERR_MINOR_VERS_MISMATCH = 10021,
2982+ NFS4ERR_STALE_CLIENTID = 10022,
2983+ NFS4ERR_STALE_STATEID = 10023,
2984+ NFS4ERR_OLD_STATEID = 10024,
2985+ NFS4ERR_BAD_STATEID = 10025,
2986+ NFS4ERR_BAD_SEQID = 10026,
2987+ NFS4ERR_NOT_SAME = 10027,
2988+ NFS4ERR_LOCK_RANGE = 10028,
2989+ NFS4ERR_SYMLINK = 10029,
2990+ NFS4ERR_RESTOREFH = 10030,
2991+ NFS4ERR_LEASE_MOVED = 10031,
2992+ NFS4ERR_ATTRNOTSUPP = 10032,
2993+ NFS4ERR_NO_GRACE = 10033,
2994+ NFS4ERR_RECLAIM_BAD = 10034,
2995+ NFS4ERR_RECLAIM_CONFLICT = 10035,
2996+ NFS4ERR_BADXDR = 10036,
2997+ NFS4ERR_LOCKS_HELD = 10037,
2998+ NFS4ERR_OPENMODE = 10038,
2999+ NFS4ERR_BADOWNER = 10039,
3000+ NFS4ERR_BADCHAR = 10040,
3001+ NFS4ERR_BADNAME = 10041,
3002+ NFS4ERR_BAD_RANGE = 10042,
3003+ NFS4ERR_LOCK_NOTSUPP = 10043,
3004+ NFS4ERR_OP_ILLEGAL = 10044,
3005+ NFS4ERR_DEADLOCK = 10045,
3006+ NFS4ERR_FILE_OPEN = 10046,
3007+ NFS4ERR_ADMIN_REVOKED = 10047,
3008+ NFS4ERR_CB_PATH_DOWN = 10048
3009+};
3010+
3011+/*
3012+ * Note: NF4BAD is not actually part of the protocol; it is just used
3013+ * internally by nfsd.
3014+ */
3015+enum nfs_ftype4 {
3016+ NF4BAD = 0,
3017+ NF4REG = 1, /* Regular File */
3018+ NF4DIR = 2, /* Directory */
3019+ NF4BLK = 3, /* Special File - block device */
3020+ NF4CHR = 4, /* Special File - character device */
3021+ NF4LNK = 5, /* Symbolic Link */
3022+ NF4SOCK = 6, /* Special File - socket */
3023+ NF4FIFO = 7, /* Special File - fifo */
3024+ NF4ATTRDIR = 8, /* Attribute Directory */
3025+ NF4NAMEDATTR = 9 /* Named Attribute */
3026+};
3027+
3028+enum open_claim_type4 {
3029+ NFS4_OPEN_CLAIM_NULL = 0,
3030+ NFS4_OPEN_CLAIM_PREVIOUS = 1,
3031+ NFS4_OPEN_CLAIM_DELEGATE_CUR = 2,
3032+ NFS4_OPEN_CLAIM_DELEGATE_PREV = 3
3033+};
3034+
3035+enum opentype4 {
3036+ NFS4_OPEN_NOCREATE = 0,
3037+ NFS4_OPEN_CREATE = 1
3038+};
3039+
3040+enum createmode4 {
3041+ NFS4_CREATE_UNCHECKED = 0,
3042+ NFS4_CREATE_GUARDED = 1,
3043+ NFS4_CREATE_EXCLUSIVE = 2
3044+};
3045+
3046+enum limit_by4 {
3047+ NFS4_LIMIT_SIZE = 1,
3048+ NFS4_LIMIT_BLOCKS = 2
3049+};
3050+
3051+enum open_delegation_type4 {
3052+ NFS4_OPEN_DELEGATE_NONE = 0,
3053+ NFS4_OPEN_DELEGATE_READ = 1,
3054+ NFS4_OPEN_DELEGATE_WRITE = 2
3055+};
3056+
3057+enum lock_type4 {
3058+ NFS4_UNLOCK_LT = 0,
3059+ NFS4_READ_LT = 1,
3060+ NFS4_WRITE_LT = 2,
3061+ NFS4_READW_LT = 3,
3062+ NFS4_WRITEW_LT = 4
3063+};
3064+
3065+
3066+/* Mandatory Attributes */
3067+#define FATTR4_WORD0_SUPPORTED_ATTRS (1UL << 0)
3068+#define FATTR4_WORD0_TYPE (1UL << 1)
3069+#define FATTR4_WORD0_FH_EXPIRE_TYPE (1UL << 2)
3070+#define FATTR4_WORD0_CHANGE (1UL << 3)
3071+#define FATTR4_WORD0_SIZE (1UL << 4)
3072+#define FATTR4_WORD0_LINK_SUPPORT (1UL << 5)
3073+#define FATTR4_WORD0_SYMLINK_SUPPORT (1UL << 6)
3074+#define FATTR4_WORD0_NAMED_ATTR (1UL << 7)
3075+#define FATTR4_WORD0_FSID (1UL << 8)
3076+#define FATTR4_WORD0_UNIQUE_HANDLES (1UL << 9)
3077+#define FATTR4_WORD0_LEASE_TIME (1UL << 10)
3078+#define FATTR4_WORD0_RDATTR_ERROR (1UL << 11)
3079+
3080+/* Recommended Attributes */
3081+#define FATTR4_WORD0_ACL (1UL << 12)
3082+#define FATTR4_WORD0_ACLSUPPORT (1UL << 13)
3083+#define FATTR4_WORD0_ARCHIVE (1UL << 14)
3084+#define FATTR4_WORD0_CANSETTIME (1UL << 15)
3085+#define FATTR4_WORD0_CASE_INSENSITIVE (1UL << 16)
3086+#define FATTR4_WORD0_CASE_PRESERVING (1UL << 17)
3087+#define FATTR4_WORD0_CHOWN_RESTRICTED (1UL << 18)
3088+#define FATTR4_WORD0_FILEHANDLE (1UL << 19)
3089+#define FATTR4_WORD0_FILEID (1UL << 20)
3090+#define FATTR4_WORD0_FILES_AVAIL (1UL << 21)
3091+#define FATTR4_WORD0_FILES_FREE (1UL << 22)
3092+#define FATTR4_WORD0_FILES_TOTAL (1UL << 23)
3093+#define FATTR4_WORD0_FS_LOCATIONS (1UL << 24)
3094+#define FATTR4_WORD0_HIDDEN (1UL << 25)
3095+#define FATTR4_WORD0_HOMOGENEOUS (1UL << 26)
3096+#define FATTR4_WORD0_MAXFILESIZE (1UL << 27)
3097+#define FATTR4_WORD0_MAXLINK (1UL << 28)
3098+#define FATTR4_WORD0_MAXNAME (1UL << 29)
3099+#define FATTR4_WORD0_MAXREAD (1UL << 30)
3100+#define FATTR4_WORD0_MAXWRITE (1UL << 31)
3101+#define FATTR4_WORD1_MIMETYPE (1UL << 0)
3102+#define FATTR4_WORD1_MODE (1UL << 1)
3103+#define FATTR4_WORD1_NO_TRUNC (1UL << 2)
3104+#define FATTR4_WORD1_NUMLINKS (1UL << 3)
3105+#define FATTR4_WORD1_OWNER (1UL << 4)
3106+#define FATTR4_WORD1_OWNER_GROUP (1UL << 5)
3107+#define FATTR4_WORD1_QUOTA_HARD (1UL << 6)
3108+#define FATTR4_WORD1_QUOTA_SOFT (1UL << 7)
3109+#define FATTR4_WORD1_QUOTA_USED (1UL << 8)
3110+#define FATTR4_WORD1_RAWDEV (1UL << 9)
3111+#define FATTR4_WORD1_SPACE_AVAIL (1UL << 10)
3112+#define FATTR4_WORD1_SPACE_FREE (1UL << 11)
3113+#define FATTR4_WORD1_SPACE_TOTAL (1UL << 12)
3114+#define FATTR4_WORD1_SPACE_USED (1UL << 13)
3115+#define FATTR4_WORD1_SYSTEM (1UL << 14)
3116+#define FATTR4_WORD1_TIME_ACCESS (1UL << 15)
3117+#define FATTR4_WORD1_TIME_ACCESS_SET (1UL << 16)
3118+#define FATTR4_WORD1_TIME_BACKUP (1UL << 17)
3119+#define FATTR4_WORD1_TIME_CREATE (1UL << 18)
3120+#define FATTR4_WORD1_TIME_DELTA (1UL << 19)
3121+#define FATTR4_WORD1_TIME_METADATA (1UL << 20)
3122+#define FATTR4_WORD1_TIME_MODIFY (1UL << 21)
3123+#define FATTR4_WORD1_TIME_MODIFY_SET (1UL << 22)
3124+#define FATTR4_WORD1_MOUNTED_ON_FILEID (1UL << 23)
3125+
3126+#define NFSPROC4_NULL 0
3127+#define NFSPROC4_COMPOUND 1
3128+#define NFS4_MINOR_VERSION 0
3129+#define NFS4_DEBUG 1
3130+
3131+#ifdef __KERNEL__
3132+
3133+/* Index of predefined Linux client operations */
3134+
3135+enum {
3136+ NFSPROC4_CLNT_NULL = 0, /* Unused */
3137+ NFSPROC4_CLNT_READ,
3138+ NFSPROC4_CLNT_WRITE,
3139+ NFSPROC4_CLNT_COMMIT,
3140+ NFSPROC4_CLNT_OPEN,
3141+ NFSPROC4_CLNT_OPEN_CONFIRM,
3142+ NFSPROC4_CLNT_OPEN_RECLAIM,
3143+ NFSPROC4_CLNT_OPEN_DOWNGRADE,
3144+ NFSPROC4_CLNT_CLOSE,
3145+ NFSPROC4_CLNT_SETATTR,
3146+ NFSPROC4_CLNT_FSINFO,
3147+ NFSPROC4_CLNT_RENEW,
3148+ NFSPROC4_CLNT_SETCLIENTID,
3149+ NFSPROC4_CLNT_SETCLIENTID_CONFIRM,
3150+ NFSPROC4_CLNT_LOCK,
3151+ NFSPROC4_CLNT_LOCKT,
3152+ NFSPROC4_CLNT_LOCKU,
3153+ NFSPROC4_CLNT_ACCESS,
3154+ NFSPROC4_CLNT_GETATTR,
3155+ NFSPROC4_CLNT_LOOKUP,
3156+ NFSPROC4_CLNT_LOOKUP_ROOT,
3157+ NFSPROC4_CLNT_REMOVE,
3158+ NFSPROC4_CLNT_RENAME,
3159+ NFSPROC4_CLNT_LINK,
3160+ NFSPROC4_CLNT_CREATE,
3161+ NFSPROC4_CLNT_PATHCONF,
3162+ NFSPROC4_CLNT_STATFS,
3163+ NFSPROC4_CLNT_READLINK,
3164+ NFSPROC4_CLNT_READDIR,
3165+ NFSPROC4_CLNT_SERVER_CAPS,
3166+ NFSPROC4_CLNT_DELEGRETURN,
3167+ NFSPROC4_CLNT_GETACL,
3168+ NFSPROC4_CLNT_SETACL,
3169+};
3170+
3171+#endif
3172+#endif
3173+
3174+/*
3175+ * Local variables:
3176+ * c-basic-offset: 8
3177+ * End:
3178+ */
3179--- /dev/null 2007-08-22 11:21:03.626521839 -0400
3180+++ acl-2.2.39/include/libacl_nfs4.h 2007-08-22 12:02:13.000000000 -0400
3181@@ -0,0 +1,97 @@
3182+#include <sys/types.h>
3183+#include <pwd.h>
3184+#include <grp.h>
3185+#include <sys/acl.h>
3186+#include <stdlib.h>
3187+#include <sys/queue.h>
3188+#include <nfs4.h>
3189+#include <sys/errno.h>
3190+#include <string.h>
3191+
3192+/* mode bit translations: */
3193+#define NFS4_READ_MODE NFS4_ACE_READ_DATA
3194+#define NFS4_WRITE_MODE (NFS4_ACE_WRITE_DATA | NFS4_ACE_APPEND_DATA)
3195+#define NFS4_EXECUTE_MODE NFS4_ACE_EXECUTE
3196+#define NFS4_ANYONE_MODE (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL | \
3197+ NFS4_ACE_SYNCHRONIZE)
3198+#define NFS4_OWNER_MODE (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL)
3199+
3200+#define NFS4_ACE_MASK_IGNORE (NFS4_ACE_DELETE | NFS4_ACE_WRITE_OWNER \
3201+ | NFS4_ACE_READ_NAMED_ATTRS | NFS4_ACE_WRITE_NAMED_ATTRS)
3202+/* XXX not sure about the following. Note that e.g. DELETE_CHILD is wrong in
3203+ * general (should only be ignored on files). */
3204+#define MASK_EQUAL(mask1, mask2) \
3205+ (((mask1) & NFS4_ACE_MASK_ALL & ~NFS4_ACE_MASK_IGNORE & \
3206+ ~NFS4_ACE_DELETE_CHILD) \
3207+ == ((mask2) & NFS4_ACE_MASK_ALL & ~NFS4_ACE_MASK_IGNORE & \
3208+ ~NFS4_ACE_DELETE_CHILD))
3209+
3210+/* Maximum length of the ace->who attribute */
3211+#define NFS4_ACL_WHO_LENGTH_MAX 2048
3212+#define NFS4_ACL_WHO_BUFFER_LEN_GUESS 255
3213+
3214+/* NFS4 acl xattr name */
3215+#define ACL_NFS4_XATTR "system.nfs4_acl"
3216+
3217+/* Macro for finding empty tailqs */
3218+#define TAILQ_IS_EMPTY(head) (head.tqh_first == NULL)
3219+
3220+/* Flags to pass certain properties around */
3221+#define NFS4_ACL_NOFLAGS 0x00
3222+#define NFS4_ACL_ISFILE 0x00
3223+#define NFS4_ACL_ISDIR 0x01
3224+#define NFS4_ACL_OWNER 0x02
3225+#define NFS4_ACL_REQUEST_DEFAULT 0x04
3226+#define NFS4_ACL_RAW 0x01
3227+
3228+#define NFS4_XDR_MOD 4
3229+
3230+typedef u_int32_t u32;
3231+
3232+enum { ACL_NFS4_NOT_USED = 0,
3233+ ACL_NFS4_USED
3234+};
3235+
3236+struct ace_container {
3237+ struct nfs4_ace *ace;
3238+ TAILQ_ENTRY(ace_container) l_ace;
3239+};
3240+
3241+TAILQ_HEAD(ace_container_list_head, ace_container);
3242+
3243+/**** Public functions ****/
3244+
3245+/** Manipulation functions **/
3246+extern int acl_nfs4_add_ace(struct nfs4_acl *, u32, u32, u32, int, char*);
3247+extern int acl_nfs4_add_pair(struct nfs4_acl *, int, u32, int, char*);
3248+extern void acl_nfs4_free(struct nfs4_acl *);
3249+extern struct nfs4_acl *acl_nfs4_new(u32);
3250+extern int acl_nfs4_set_who(struct nfs4_ace*, int, char*);
3251+extern struct nfs4_acl *acl_nfs4_copy_acl(struct nfs4_acl *);
3252+extern struct nfs4_acl *acl_nfs4_xattr_load(char *, int, u32);
3253+extern int acl_nfs4_xattr_pack(struct nfs4_acl *, char**);
3254+extern int acl_nfs4_xattr_size(struct nfs4_acl *);
3255+extern void acl_nfs4_remove_ace(struct nfs4_acl * acl, struct nfs4_ace * ace);
3256+
3257+/** Conversion functions **/
3258+
3259+/* nfs4 -> posix */
3260+extern acl_t acl_n4tp_acl_trans(struct nfs4_acl *, acl_type_t);
3261+
3262+/* posix -> nfs4 */
3263+extern int acl_ptn4_get_mask(u32* mask, acl_permset_t perms,
3264+ int iflags);
3265+extern int acl_ptn4_acl_trans(acl_t, struct nfs4_acl *, acl_type_t, u32, char*);
3266+
3267+
3268+/** Access Functions **/
3269+extern inline int acl_nfs4_get_whotype(char*);
3270+extern int acl_nfs4_get_who(struct nfs4_ace*, int*, char**);
3271+
3272+/**** Private(?) functions ****/
3273+acl_t __posix_acl_from_nfs4_xattr(char*, int, acl_type_t, u32);
3274+
3275+/* These will change */
3276+char * nfs4_get_who_from_uid(uid_t);
3277+char * nfs4_get_who_from_gid(gid_t);
3278+/* End change */