Gentoo Archives: gentoo-commits

From: Gilles Dartiguelongue <eva@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] dev/eva:master commit in: sys-apps/acl/files/, sys-apps/acl/
Date: Fri, 30 Dec 2011 20:42:24
Message-Id: b346fe530609793f33ebb3b86a9f6f537d08ea56.eva@gentoo
1 commit: b346fe530609793f33ebb3b86a9f6f537d08ea56
2 Author: Gilles Dartiguelongue <eva <AT> gentoo <DOT> org>
3 AuthorDate: Fri Dec 30 20:41:44 2011 +0000
4 Commit: Gilles Dartiguelongue <eva <AT> gentoo <DOT> org>
5 CommitDate: Fri Dec 30 20:41:44 2011 +0000
6 URL: http://git.overlays.gentoo.org/gitweb/?p=dev/eva.git;a=commit;h=b346fe53
7
8 sys-apps/acl: update nfsv4 acl patches
9
10 ---
11 sys-apps/acl/Manifest | 11 +
12 sys-apps/acl/acl-2.2.51-r1.ebuild | 75 +
13 .../0001-Add-nfsv4-posix-acl-translation.patch | 4292 ++++++++++++++++++++
14 ...-move-to-new-nfsv4-posix-mapping-clean-up.patch | 1740 ++++++++
15 ...v4-POSIX-mapping-clean-up-loop-interation.patch | 60 +
16 .../0004-acl_ptn4_get_mask-style-cleanup.patch | 63 +
17 sys-apps/acl/files/0005-fix-WRITE_MODE.patch | 43 +
18 ...0006-Remove-some-some-unused-header-cruft.patch | 33 +
19 ...NFSv4-POSIX-relax-inheritance-bit-mapping.patch | 42 +
20 ...SIX-factor-out-inheritance-splitting-code.patch | 94 +
21 ...NFSv4-POSIX-remove-a-redundant-NULL-check.patch | 29 +
22 sys-apps/acl/files/0010-Minor-header-cleanup.patch | 59 +
23 ...POSIX-NFSv4-relax-inheritance-bit-mapping.patch | 95 +
24 ...posix-mapping-don-t-add-unnecessary-masks.patch | 52 +
25 ...-return-zero-length-default-acl-when-appr.patch | 39 +
26 .../0014-nfsd4-remove-spurious-XATTR_REPLACE.patch | 32 +
27 sys-apps/acl/files/0015-fix-comment-typo.patch | 28 +
28 ...6-fix-nfs4-posix-mapping-state-allocation.patch | 30 +
29 .../files/0017-fix-calculation-of-group-bits.patch | 99 +
30 sys-apps/acl/files/acl-2.2.49-quote-strchr.patch | 25 +
31 sys-apps/acl/files/acl-2.2.51-config-shell.patch | 53 +
32 21 files changed, 6994 insertions(+), 0 deletions(-)
33
34 diff --git a/sys-apps/acl/Manifest b/sys-apps/acl/Manifest
35 new file mode 100644
36 index 0000000..d2975fb
37 --- /dev/null
38 +++ b/sys-apps/acl/Manifest
39 @@ -0,0 +1,11 @@
40 +-----BEGIN PGP SIGNED MESSAGE-----
41 +Hash: SHA1
42 +
43 +DIST acl-2.2.51.src.tar.gz 385378 RMD160 5171bfbf55b8bf4c204503a72da568d38423dcdf SHA1 60d0b055949c2ba6155187f05ed2b0f89cb895b9 SHA256 06854521cf5d396801af7e54b9636680edf8064355e51c07657ec7442a185225
44 +-----BEGIN PGP SIGNATURE-----
45 +Version: GnuPG v2.0.18 (GNU/Linux)
46 +
47 +iEYEARECAAYFAk7+IgcACgkQ1fmVwcYIWAYzrwCg4TT/cGQVX8TMhaPeex/yfpXd
48 +vnwAn0dO7OQLG0iROUZUZivjM+hZWz96
49 +=Kr3b
50 +-----END PGP SIGNATURE-----
51
52 diff --git a/sys-apps/acl/acl-2.2.51-r1.ebuild b/sys-apps/acl/acl-2.2.51-r1.ebuild
53 new file mode 100644
54 index 0000000..3a1e575
55 --- /dev/null
56 +++ b/sys-apps/acl/acl-2.2.51-r1.ebuild
57 @@ -0,0 +1,75 @@
58 +# Copyright 1999-2011 Gentoo Foundation
59 +# Distributed under the terms of the GNU General Public License v2
60 +# $Header: /var/cvsroot/gentoo-x86/sys-apps/acl/acl-2.2.51.ebuild,v 1.8 2011/09/03 16:54:10 armin76 Exp $
61 +
62 +EAPI="4"
63 +
64 +inherit eutils toolchain-funcs
65 +
66 +DESCRIPTION="access control list utilities, libraries and headers"
67 +HOMEPAGE="http://savannah.nongnu.org/projects/acl"
68 +SRC_URI="http://download.savannah.gnu.org/releases/${PN}/${P}.src.tar.gz"
69 +
70 +LICENSE="LGPL-2.1"
71 +SLOT="0"
72 +KEYWORDS="alpha amd64 arm hppa ia64 m68k ~mips ppc ~ppc64 s390 sh sparc x86 ~amd64-linux ~ia64-linux ~x86-linux"
73 +IUSE="nfs nls static-libs"
74 +
75 +RDEPEND=">=sys-apps/attr-2.4
76 + nfs? ( net-libs/libnfsidmap )"
77 +DEPEND="${RDEPEND}
78 + nls? ( sys-devel/gettext )"
79 +
80 +src_prepare() {
81 + if use nfs ; then
82 + epatch \
83 + "${FILESDIR}"/0001-Add-nfsv4-posix-acl-translation.patch \
84 + "${FILESDIR}"/0002-nfsd4-move-to-new-nfsv4-posix-mapping-clean-up.patch \
85 + "${FILESDIR}"/0003-NFSv4-POSIX-mapping-clean-up-loop-interation.patch \
86 + "${FILESDIR}"/0004-acl_ptn4_get_mask-style-cleanup.patch \
87 + "${FILESDIR}"/0005-fix-WRITE_MODE.patch \
88 + "${FILESDIR}"/0006-Remove-some-some-unused-header-cruft.patch \
89 + "${FILESDIR}"/0007-NFSv4-POSIX-relax-inheritance-bit-mapping.patch \
90 + "${FILESDIR}"/0008-NFSv4-POSIX-factor-out-inheritance-splitting-code.patch \
91 + "${FILESDIR}"/0009-NFSv4-POSIX-remove-a-redundant-NULL-check.patch \
92 + "${FILESDIR}"/0010-Minor-header-cleanup.patch \
93 + "${FILESDIR}"/0011-POSIX-NFSv4-relax-inheritance-bit-mapping.patch \
94 + "${FILESDIR}"/0012-nfsv4-posix-mapping-don-t-add-unnecessary-masks.patch \
95 + "${FILESDIR}"/0013-nfsv4-posix-return-zero-length-default-acl-when-appr.patch \
96 + "${FILESDIR}"/0014-nfsd4-remove-spurious-XATTR_REPLACE.patch \
97 + "${FILESDIR}"/0015-fix-comment-typo.patch \
98 + "${FILESDIR}"/0016-fix-nfs4-posix-mapping-state-allocation.patch \
99 + "${FILESDIR}"/0017-fix-calculation-of-group-bits.patch
100 + fi
101 + epatch "${FILESDIR}"/${PN}-2.2.49-quote-strchr.patch
102 + epatch "${FILESDIR}"/${PN}-2.2.51-config-shell.patch #365397
103 + sed -i \
104 + -e '/^as_dummy=/s:=":="$PATH$PATH_SEPARATOR:' \
105 + configure # hack PATH with AC_PATH_PROG
106 + sed -i \
107 + -e "/^PKG_DOC_DIR/s:@pkg_name@:${PF}:" \
108 + -e '/HAVE_ZIPPED_MANPAGES/s:=.*:=false:' \
109 + include/builddefs.in \
110 + || die "failed to update builddefs"
111 + strip-linguas po
112 +}
113 +
114 +src_configure() {
115 + unset PLATFORM #184564
116 + export OPTIMIZER=${CFLAGS}
117 + export DEBUG=-DNDEBUG
118 +
119 + econf \
120 + $(use_enable nls gettext) \
121 + --enable-shared $(use_enable static-libs static) \
122 + --libexecdir="${EPREFIX}"/usr/$(get_libdir) \
123 + --bindir="${EPREFIX}"/bin
124 +}
125 +
126 +src_install() {
127 + emake DIST_ROOT="${D}" install install-dev install-lib || die
128 + use static-libs || find "${D}" -name '*.la' -delete
129 +
130 + # move shared libs to /
131 + gen_usr_ldscript -a acl
132 +}
133
134 diff --git a/sys-apps/acl/files/0001-Add-nfsv4-posix-acl-translation.patch b/sys-apps/acl/files/0001-Add-nfsv4-posix-acl-translation.patch
135 new file mode 100644
136 index 0000000..5323e6e
137 --- /dev/null
138 +++ b/sys-apps/acl/files/0001-Add-nfsv4-posix-acl-translation.patch
139 @@ -0,0 +1,4292 @@
140 +From fb0b47fecc2ca9a36ce3a8e05ab501e2f338d81a Mon Sep 17 00:00:00 2001
141 +From: "J. Bruce Fields" <bfields@××××××××.org>
142 +Date: Fri, 1 Sep 2006 18:59:12 -0400
143 +Subject: [PATCH 01/17] Add nfsv4<->posix acl translation
144 +
145 +Add nfs4<->posix acl translation to libacl, so we can present a posix
146 +acl interface to nfs4 filesystems, which only understand v4 acls.
147 +
148 +Original implementation due to Nate Gallaher, based on implementation by
149 +Marius Eriksen and others, subsequently maintained by Bruce Fields.
150 +
151 +Changes:
152 + - update interface versions and library exports. (Not sure this
153 + is really right; do we really want to export allo thosesymbols??)
154 + - Rely on libnfsidmap's notion of a default domain instead of
155 + hardwiring "CITI.UMICH.EDU".
156 + - We check whether the filesystem we're on supports nfs4 acl's by
157 + trying to fe the system.nfs4_acl xattr before falling back on
158 + posix. Our check was sligh wrong--we should be checking for
159 + an EOPNOTSUPP as well as an ENOATTR.
160 + - Call nfs4_init_name_mapping() to read idmapd.conf and set
161 + defaults before mapping names. (XXX: We're calling it before
162 + every single mapping, when we should only have to call it once.)
163 + - Set to zero all bits in the bitmask that aren't assigned a meaning
164 + by the protocol.
165 + - Allow default acls of zero length. (We were returning an error
166 + when the default acl on a directory was length 0, which is actually
167 + a perfectly normal occurance.)
168 + - Ignore WRITE_OWNER bit and named attr bits
169 + - Set DELETE_CHILD on directories with write permissions. (Thanks
170 + to Simon Vallet <svallet@×××××××××××××.fr> for identifying the
171 + bug and suggesting this solution.
172 + - Remove some needless accessor functions.
173 + - support the acl_extended_file function, so "ls -l" can show that
174 + neat plus sign after the unix permissions if additional ACLs are
175 + set (from Christophe Saout <christophe@×××××.de>)
176 + - Remove all native-nfsv4 acl getting/setting code (and all nfsv4
177 + acl printing code, only used for that); we're doing the native
178 + NFSv4 ACL stuff in a separate package now.
179 + - Fix some style problems.
180 + - Fix handling of inherited aces: the calculated ACL mustn't
181 + completely replace the existing ACL: instead, setting the default
182 + ACL should only replace the iherited ACEs (leaving any effective
183 + permissions untouched), and setting the access ACL should only
184 + modify effective ACEs (leaving any inherited stuff alone).
185 +---
186 + exports | 50 +++
187 + include/builddefs.in | 2 +-
188 + include/libacl_nfs4.h | 134 ++++++++
189 + include/nfs4.h | 397 ++++++++++++++++++++++++
190 + libacl/Makefile | 31 ++-
191 + libacl/__acl_extended_file.c | 29 ++
192 + libacl/__posix_acl_from_nfs4_xattr.c | 60 ++++
193 + libacl/acl_get_fd.c | 50 +++-
194 + libacl/acl_get_file.c | 46 +++-
195 + libacl/acl_n4tp_ace_count.c | 57 ++++
196 + libacl/acl_n4tp_ace_trans.c | 76 +++++
197 + libacl/acl_n4tp_acl_trans.c | 164 ++++++++++
198 + libacl/acl_n4tp_get_whotype.c | 73 +++++
199 + libacl/acl_n4tp_set_mode.c | 98 ++++++
200 + libacl/acl_n4tp_set_who.c | 89 ++++++
201 + libacl/acl_nfs4_add_ace.c | 83 +++++
202 + libacl/acl_nfs4_add_pair.c | 60 ++++
203 + libacl/acl_nfs4_copy_acl.c | 85 +++++
204 + libacl/acl_nfs4_free.c | 61 ++++
205 + libacl/acl_nfs4_get_who.c | 103 ++++++
206 + libacl/acl_nfs4_get_whotype.c | 60 ++++
207 + libacl/acl_nfs4_new.c | 58 ++++
208 + libacl/acl_nfs4_remove_ace.c | 48 +++
209 + libacl/acl_nfs4_set_who.c | 92 ++++++
210 + libacl/acl_nfs4_utils.c | 566 ++++++++++++++++++++++++++++++++++
211 + libacl/acl_nfs4_xattr_load.c | 191 ++++++++++++
212 + libacl/acl_nfs4_xattr_pack.c | 148 +++++++++
213 + libacl/acl_nfs4_xattr_size.c | 91 ++++++
214 + libacl/acl_ptn4_acl_trans.c | 518 +++++++++++++++++++++++++++++++
215 + libacl/acl_ptn4_get_mask.c | 81 +++++
216 + libacl/acl_set_fd.c | 37 +++
217 + libacl/acl_set_file.c | 75 +++++-
218 + libacl/libacl_nfs4.h | 134 ++++++++
219 + 33 files changed, 3825 insertions(+), 22 deletions(-)
220 + create mode 100644 include/libacl_nfs4.h
221 + create mode 100644 include/nfs4.h
222 + create mode 100644 libacl/__posix_acl_from_nfs4_xattr.c
223 + create mode 100644 libacl/acl_n4tp_ace_count.c
224 + create mode 100644 libacl/acl_n4tp_ace_trans.c
225 + create mode 100644 libacl/acl_n4tp_acl_trans.c
226 + create mode 100644 libacl/acl_n4tp_get_whotype.c
227 + create mode 100644 libacl/acl_n4tp_set_mode.c
228 + create mode 100644 libacl/acl_n4tp_set_who.c
229 + create mode 100644 libacl/acl_nfs4_add_ace.c
230 + create mode 100644 libacl/acl_nfs4_add_pair.c
231 + create mode 100644 libacl/acl_nfs4_copy_acl.c
232 + create mode 100644 libacl/acl_nfs4_free.c
233 + create mode 100644 libacl/acl_nfs4_get_who.c
234 + create mode 100644 libacl/acl_nfs4_get_whotype.c
235 + create mode 100644 libacl/acl_nfs4_new.c
236 + create mode 100644 libacl/acl_nfs4_remove_ace.c
237 + create mode 100644 libacl/acl_nfs4_set_who.c
238 + create mode 100644 libacl/acl_nfs4_utils.c
239 + create mode 100644 libacl/acl_nfs4_xattr_load.c
240 + create mode 100644 libacl/acl_nfs4_xattr_pack.c
241 + create mode 100644 libacl/acl_nfs4_xattr_size.c
242 + create mode 100644 libacl/acl_ptn4_acl_trans.c
243 + create mode 100644 libacl/acl_ptn4_get_mask.c
244 + create mode 100644 libacl/libacl_nfs4.h
245 +
246 +diff --git a/exports b/exports
247 +index 7d8e69e..08bf390 100644
248 +--- a/exports
249 ++++ b/exports
250 +@@ -88,4 +88,54 @@ ACL_1.2 {
251 + global:
252 + # Linux specific extensions
253 + acl_extended_file_nofollow;
254 ++
255 ++ # NFSv4 specific extensions
256 ++ acl_nfs4_add_ace;
257 ++ acl_nfs4_add_pair;
258 ++ acl_nfs4_free;
259 ++ acl_nfs4_new;
260 ++ acl_nfs4_set_dir;
261 ++ acl_nfs4_set_who;
262 ++ acl_nfs4_copy_acl;
263 ++ acl_nfs4_xattr_load;
264 ++ acl_nfs4_xattr_pack;
265 ++ acl_nfs4_xattr_size;
266 ++ acl_nfs4_remove_ace;
267 ++
268 ++ acl_n4tp_acl_trans;
269 ++ acl_n4tp_set_mode;
270 ++ acl_n4tp_ace_count;
271 ++ acl_n4tp_ace_trans;
272 ++ acl_n4tp_set_who;
273 ++ acl_n4tp_get_whotype;
274 ++
275 ++ acl_ptn4_get_mask;
276 ++ acl_ptn4_acl_trans;
277 ++
278 ++ acl_nfs4_get_next_ace;
279 ++ acl_nfs4_get_first_ace;
280 ++ acl_nfs4_get_dir;
281 ++ acl_nfs4_get_whotype;
282 ++ acl_nfs4_get_who;
283 ++ acl_nfs4_entries;
284 ++
285 ++ local:
286 ++ __posix_acl_from_nfs4_xattr;
287 ++ complementary_ace_pair;
288 ++ same_who;
289 ++ nfs4_get_gid_from_who;
290 ++ nfs4_get_uid_from_who;
291 ++ nfs4_get_who_from_uid;
292 ++ nfs4_get_who_from_gid;
293 ++ __nfs4_get_local_uid_from_who;
294 ++ __nfs4_get_foreign_uid_from_who;
295 ++ __nfs4_get_local_gid_from_who;
296 ++ __nfs4_get_foreign_gid_from_who;
297 ++ is_who_local;
298 ++
299 ++ user_obj_from_v4;
300 ++ users_from_v4;
301 ++ group_obj_and_groups_from_v4;
302 ++ mask_from_v4;
303 ++ other_from_v4;
304 + } ACL_1.1;
305 +diff --git a/include/builddefs.in b/include/builddefs.in
306 +index d054a56..69d7d82 100644
307 +--- a/include/builddefs.in
308 ++++ b/include/builddefs.in
309 +@@ -81,7 +81,7 @@ endif
310 +
311 + GCFLAGS = $(OPTIMIZER) $(DEBUG) -funsigned-char -fno-strict-aliasing -Wall \
312 + -DVERSION=\"$(PKG_VERSION)\" -DLOCALEDIR=\"$(PKG_LOCALE_DIR)\" \
313 +- -DPACKAGE=\"$(PKG_NAME)\" -I$(TOPDIR)/include
314 ++ -DPACKAGE=\"$(PKG_NAME)\" -I$(TOPDIR)/include -DUSE_NFSV4_TRANS
315 +
316 + # Global, Platform, Local CFLAGS
317 + CFLAGS += $(GCFLAGS) $(PCFLAGS) $(LCFLAGS)
318 +diff --git a/include/libacl_nfs4.h b/include/libacl_nfs4.h
319 +new file mode 100644
320 +index 0000000..e6a466c
321 +--- /dev/null
322 ++++ b/include/libacl_nfs4.h
323 +@@ -0,0 +1,134 @@
324 ++#include <sys/types.h>
325 ++#include <pwd.h>
326 ++#include <grp.h>
327 ++#include <sys/acl.h>
328 ++#include <stdlib.h>
329 ++#include <sys/queue.h>
330 ++#include <nfs4.h>
331 ++#include <sys/errno.h>
332 ++#include <string.h>
333 ++
334 ++/* mode bit translations: */
335 ++#define NFS4_READ_MODE NFS4_ACE_READ_DATA
336 ++#define NFS4_WRITE_MODE (NFS4_ACE_WRITE_DATA \
337 ++ | NFS4_ACE_APPEND_DATA | NFS4_ACE_DELETE_CHILD)
338 ++#define NFS4_EXECUTE_MODE NFS4_ACE_EXECUTE
339 ++#define NFS4_ANYONE_MODE (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL | \
340 ++ NFS4_ACE_SYNCHRONIZE)
341 ++#define NFS4_OWNER_MODE (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL)
342 ++
343 ++/* flags used to simulate posix default ACLs */
344 ++#define NFS4_INHERITANCE_FLAGS (NFS4_ACE_FILE_INHERIT_ACE \
345 ++ | NFS4_ACE_DIRECTORY_INHERIT_ACE | NFS4_ACE_INHERIT_ONLY_ACE)
346 ++
347 ++#define NFS4_ACE_MASK_IGNORE (NFS4_ACE_DELETE | NFS4_ACE_WRITE_OWNER \
348 ++ | NFS4_ACE_READ_NAMED_ATTRS | NFS4_ACE_WRITE_NAMED_ATTRS)
349 ++/* XXX not sure about the following. Note that e.g. DELETE_CHILD is wrong in
350 ++ * general (should only be ignored on files). */
351 ++#define MASK_EQUAL(mask1, mask2) \
352 ++ (((mask1) & NFS4_ACE_MASK_ALL & ~NFS4_ACE_MASK_IGNORE & \
353 ++ ~NFS4_ACE_DELETE_CHILD) \
354 ++ == ((mask2) & NFS4_ACE_MASK_ALL & ~NFS4_ACE_MASK_IGNORE & \
355 ++ ~NFS4_ACE_DELETE_CHILD))
356 ++
357 ++/* Maximum length of the ace->who attribute */
358 ++#define NFS4_ACL_WHO_LENGTH_MAX 2048
359 ++#define NFS4_ACL_WHO_BUFFER_LEN_GUESS 255
360 ++
361 ++/* NFS4 acl xattr name */
362 ++#define ACL_NFS4_XATTR "system.nfs4_acl"
363 ++
364 ++/* Macro for finding empty tailqs */
365 ++#define TAILQ_IS_EMPTY(head) (head.tqh_first == NULL)
366 ++
367 ++/* Flags to pass certain properties around */
368 ++#define NFS4_ACL_NOFLAGS 0x00
369 ++#define NFS4_ACL_ISFILE 0x00
370 ++#define NFS4_ACL_ISDIR 0x01
371 ++#define NFS4_ACL_OWNER 0x02
372 ++#define NFS4_ACL_REQUEST_DEFAULT 0x04
373 ++#define NFS4_ACL_RAW 0x01
374 ++
375 ++#define NFS4_XDR_MOD 4
376 ++
377 ++typedef u_int32_t u32;
378 ++
379 ++enum { ACL_NFS4_NOT_USED = 0,
380 ++ ACL_NFS4_USED
381 ++};
382 ++
383 ++struct ace_container {
384 ++ struct nfs4_ace *ace;
385 ++ TAILQ_ENTRY(ace_container) l_ace;
386 ++};
387 ++
388 ++TAILQ_HEAD(ace_container_list_head, ace_container);
389 ++
390 ++/**** Public functions ****/
391 ++
392 ++/** Manipulation functions **/
393 ++extern int acl_nfs4_add_ace(struct nfs4_acl *, u32, u32, u32, int, char*);
394 ++extern int acl_nfs4_add_pair(struct nfs4_acl *, int, u32, int, char*);
395 ++extern void acl_nfs4_free(struct nfs4_acl *);
396 ++extern struct nfs4_acl *acl_nfs4_new(u32);
397 ++extern int acl_nfs4_set_who(struct nfs4_ace*, int, char*);
398 ++extern struct nfs4_acl *acl_nfs4_copy_acl(struct nfs4_acl *);
399 ++extern struct nfs4_acl *acl_nfs4_xattr_load(char *, int, u32);
400 ++extern int acl_nfs4_xattr_pack(struct nfs4_acl *, char**);
401 ++extern int acl_nfs4_xattr_size(struct nfs4_acl *);
402 ++extern void acl_nfs4_remove_ace(struct nfs4_acl * acl, struct nfs4_ace * ace);
403 ++
404 ++/** Conversion functions **/
405 ++
406 ++/* nfs4 -> posix */
407 ++extern acl_t acl_n4tp_acl_trans(struct nfs4_acl *, acl_type_t);
408 ++extern int acl_n4tp_set_mode(acl_entry_t pace, u32 nfs4_access_mask,
409 ++ int iflags);
410 ++extern int acl_n4tp_ace_count(struct nfs4_acl *n4acl);
411 ++extern int acl_n4tp_ace_trans(struct nfs4_ace *ace, acl_t *pacl,
412 ++ acl_tag_t tag, int iflags);
413 ++extern int acl_n4tp_set_who(acl_entry_t ace, char* who,
414 ++ acl_tag_t who_type);
415 ++extern acl_tag_t acl_n4tp_get_whotype(struct nfs4_ace *ace);
416 ++
417 ++/* posix -> nfs4 */
418 ++extern int acl_ptn4_get_mask(u32* mask, acl_permset_t perms,
419 ++ int iflags);
420 ++extern int acl_ptn4_acl_trans(acl_t, struct nfs4_acl *, acl_type_t, u32, char*);
421 ++
422 ++
423 ++/** Access Functions **/
424 ++extern inline struct nfs4_ace *
425 ++ acl_nfs4_get_next_ace(struct nfs4_ace **);
426 ++extern inline struct nfs4_ace *
427 ++ acl_nfs4_get_first_ace(struct nfs4_acl *);
428 ++extern inline int acl_nfs4_get_whotype(char*);
429 ++extern int acl_nfs4_get_who(struct nfs4_ace*, int*, char**);
430 ++
431 ++/**** Private(?) functions ****/
432 ++acl_t __posix_acl_from_nfs4_xattr(char*, int, acl_type_t, u32);
433 ++int complementary_ace_pair(struct nfs4_ace *allow, struct nfs4_ace *deny);
434 ++int same_who(struct nfs4_ace *a, struct nfs4_ace *b);
435 ++
436 ++/* These will change */
437 ++int nfs4_get_gid_from_who(gid_t* gid, const char * who);
438 ++int nfs4_get_uid_from_who(uid_t* uid, const char * who);
439 ++char * nfs4_get_who_from_uid(uid_t);
440 ++char * nfs4_get_who_from_gid(gid_t);
441 ++int __nfs4_get_local_uid_from_who(uid_t* uid, const char * who);
442 ++int __nfs4_get_foreign_uid_from_who(uid_t* uid, const char * who);
443 ++int __nfs4_get_local_gid_from_who(gid_t* gid, const char * who);
444 ++int __nfs4_get_foreign_gid_from_who(gid_t* gid, const char * who);
445 ++int is_who_local(const char * who);
446 ++/* End change */
447 ++
448 ++int user_obj_from_v4(struct nfs4_acl *n4acl, struct nfs4_ace **n4ace,
449 ++ acl_t *pacl, int iflags);
450 ++int users_from_v4(struct nfs4_acl *n4acl, struct nfs4_ace ** n4ace_p,
451 ++ struct nfs4_ace **mask_ace, acl_t *pacl, int iflags);
452 ++int group_obj_and_groups_from_v4(struct nfs4_acl *n4acl,
453 ++ struct nfs4_ace ** n4ace_p, struct nfs4_ace **mask_ace, acl_t *pacl, int iflags);
454 ++int mask_from_v4(struct nfs4_acl *n4acl, struct nfs4_ace ** n4ace_p,
455 ++ struct nfs4_ace **mask_ace, acl_t *pacl, int iflags);
456 ++int other_from_v4(struct nfs4_acl *n4acl, struct nfs4_ace ** n4ace_p,
457 ++ acl_t *pacl, int iflags);
458 +diff --git a/include/nfs4.h b/include/nfs4.h
459 +new file mode 100644
460 +index 0000000..43a6418
461 +--- /dev/null
462 ++++ b/include/nfs4.h
463 +@@ -0,0 +1,397 @@
464 ++/*
465 ++ * NFSv4 protocol definitions.
466 ++ *
467 ++ * Copyright (c) 2002 The Regents of the University of Michigan.
468 ++ * All rights reserved.
469 ++ *
470 ++ * Kendrick Smith <kmsmith@×××××.edu>
471 ++ * Andy Adamson <andros@×××××.edu>
472 ++ */
473 ++
474 ++#include<sys/types.h>
475 ++#include<sys/queue.h>
476 ++
477 ++#ifndef _LINUX_NFS4_H
478 ++#define _LINUX_NFS4_H
479 ++
480 ++#define NFS4_VERIFIER_SIZE 8
481 ++#define NFS4_FHSIZE 128
482 ++#define NFS4_MAXNAMLEN NAME_MAX
483 ++
484 ++#define NFS4_ACCESS_READ 0x0001
485 ++#define NFS4_ACCESS_LOOKUP 0x0002
486 ++#define NFS4_ACCESS_MODIFY 0x0004
487 ++#define NFS4_ACCESS_EXTEND 0x0008
488 ++#define NFS4_ACCESS_DELETE 0x0010
489 ++#define NFS4_ACCESS_EXECUTE 0x0020
490 ++
491 ++#define NFS4_FH_PERISTENT 0x0000
492 ++#define NFS4_FH_NOEXPIRE_WITH_OPEN 0x0001
493 ++#define NFS4_FH_VOLATILE_ANY 0x0002
494 ++#define NFS4_FH_VOL_MIGRATION 0x0004
495 ++#define NFS4_FH_VOL_RENAME 0x0008
496 ++
497 ++#define NFS4_OPEN_RESULT_CONFIRM 0x0002
498 ++
499 ++#define NFS4_SHARE_ACCESS_READ 0x0001
500 ++#define NFS4_SHARE_ACCESS_WRITE 0x0002
501 ++#define NFS4_SHARE_ACCESS_BOTH 0x0003
502 ++#define NFS4_SHARE_DENY_READ 0x0001
503 ++#define NFS4_SHARE_DENY_WRITE 0x0002
504 ++#define NFS4_SHARE_DENY_BOTH 0x0003
505 ++
506 ++#define NFS4_SET_TO_SERVER_TIME 0
507 ++#define NFS4_SET_TO_CLIENT_TIME 1
508 ++
509 ++#define NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE 0
510 ++#define NFS4_ACE_ACCESS_DENIED_ACE_TYPE 1
511 ++#define NFS4_ACE_SYSTEM_AUDIT_ACE_TYPE 2
512 ++#define NFS4_ACE_SYSTEM_ALARM_ACE_TYPE 3
513 ++
514 ++#define ACL4_SUPPORT_ALLOW_ACL 0x01
515 ++#define ACL4_SUPPORT_DENY_ACL 0x02
516 ++#define ACL4_SUPPORT_AUDIT_ACL 0x04
517 ++#define ACL4_SUPPORT_ALARM_ACL 0x08
518 ++
519 ++#define NFS4_ACE_FILE_INHERIT_ACE 0x00000001
520 ++#define NFS4_ACE_DIRECTORY_INHERIT_ACE 0x00000002
521 ++#define NFS4_ACE_NO_PROPAGATE_INHERIT_ACE 0x00000004
522 ++#define NFS4_ACE_INHERIT_ONLY_ACE 0x00000008
523 ++#define NFS4_ACE_SUCCESSFUL_ACCESS_ACE_FLAG 0x00000010
524 ++#define NFS4_ACE_FAILED_ACCESS_ACE_FLAG 0x00000020
525 ++#define NFS4_ACE_IDENTIFIER_GROUP 0x00000040
526 ++#define NFS4_ACE_OWNER 0x00000080
527 ++#define NFS4_ACE_GROUP 0x00000100
528 ++#define NFS4_ACE_EVERYONE 0x00000200
529 ++
530 ++#define NFS4_ACE_READ_DATA 0x00000001
531 ++#define NFS4_ACE_LIST_DIRECTORY 0x00000001
532 ++#define NFS4_ACE_WRITE_DATA 0x00000002
533 ++#define NFS4_ACE_ADD_FILE 0x00000002
534 ++#define NFS4_ACE_APPEND_DATA 0x00000004
535 ++#define NFS4_ACE_ADD_SUBDIRECTORY 0x00000004
536 ++#define NFS4_ACE_READ_NAMED_ATTRS 0x00000008
537 ++#define NFS4_ACE_WRITE_NAMED_ATTRS 0x00000010
538 ++#define NFS4_ACE_EXECUTE 0x00000020
539 ++#define NFS4_ACE_DELETE_CHILD 0x00000040
540 ++#define NFS4_ACE_READ_ATTRIBUTES 0x00000080
541 ++#define NFS4_ACE_WRITE_ATTRIBUTES 0x00000100
542 ++#define NFS4_ACE_DELETE 0x00010000
543 ++#define NFS4_ACE_READ_ACL 0x00020000
544 ++#define NFS4_ACE_WRITE_ACL 0x00040000
545 ++#define NFS4_ACE_WRITE_OWNER 0x00080000
546 ++#define NFS4_ACE_SYNCHRONIZE 0x00100000
547 ++#define NFS4_ACE_GENERIC_READ 0x00120081
548 ++#define NFS4_ACE_GENERIC_WRITE 0x00160106
549 ++#define NFS4_ACE_GENERIC_EXECUTE 0x001200A0
550 ++#define NFS4_ACE_MASK_ALL 0x001F01FF
551 ++
552 ++enum nfs4_acl_whotype {
553 ++ NFS4_ACL_WHO_NAMED = 0,
554 ++ NFS4_ACL_WHO_OWNER,
555 ++ NFS4_ACL_WHO_GROUP,
556 ++ NFS4_ACL_WHO_EVERYONE,
557 ++};
558 ++
559 ++#define NFS4_ACL_WHO_OWNER_STRING "OWNER@"
560 ++#define NFS4_ACL_WHO_GROUP_STRING "GROUP@"
561 ++#define NFS4_ACL_WHO_EVERYONE_STRING "EVERYONE@"
562 ++
563 ++struct nfs4_ace {
564 ++ u_int32_t type;
565 ++ u_int32_t flag;
566 ++ u_int32_t access_mask;
567 ++ char* who;
568 ++ TAILQ_ENTRY(nfs4_ace) l_ace;
569 ++};
570 ++
571 ++TAILQ_HEAD(ace_list_head, nfs4_ace);
572 ++
573 ++struct nfs4_acl {
574 ++ u_int32_t naces;
575 ++ u_int32_t is_directory;
576 ++ struct ace_list_head ace_head;
577 ++};
578 ++
579 ++typedef struct { char data[NFS4_VERIFIER_SIZE]; } nfs4_verifier;
580 ++typedef struct { char data[16]; } nfs4_stateid;
581 ++
582 ++enum nfs_opnum4 {
583 ++ OP_ACCESS = 3,
584 ++ OP_CLOSE = 4,
585 ++ OP_COMMIT = 5,
586 ++ OP_CREATE = 6,
587 ++ OP_DELEGPURGE = 7,
588 ++ OP_DELEGRETURN = 8,
589 ++ OP_GETATTR = 9,
590 ++ OP_GETFH = 10,
591 ++ OP_LINK = 11,
592 ++ OP_LOCK = 12,
593 ++ OP_LOCKT = 13,
594 ++ OP_LOCKU = 14,
595 ++ OP_LOOKUP = 15,
596 ++ OP_LOOKUPP = 16,
597 ++ OP_NVERIFY = 17,
598 ++ OP_OPEN = 18,
599 ++ OP_OPENATTR = 19,
600 ++ OP_OPEN_CONFIRM = 20,
601 ++ OP_OPEN_DOWNGRADE = 21,
602 ++ OP_PUTFH = 22,
603 ++ OP_PUTPUBFH = 23,
604 ++ OP_PUTROOTFH = 24,
605 ++ OP_READ = 25,
606 ++ OP_READDIR = 26,
607 ++ OP_READLINK = 27,
608 ++ OP_REMOVE = 28,
609 ++ OP_RENAME = 29,
610 ++ OP_RENEW = 30,
611 ++ OP_RESTOREFH = 31,
612 ++ OP_SAVEFH = 32,
613 ++ OP_SECINFO = 33,
614 ++ OP_SETATTR = 34,
615 ++ OP_SETCLIENTID = 35,
616 ++ OP_SETCLIENTID_CONFIRM = 36,
617 ++ OP_VERIFY = 37,
618 ++ OP_WRITE = 38,
619 ++ OP_RELEASE_LOCKOWNER = 39,
620 ++ OP_ILLEGAL = 10044,
621 ++};
622 ++
623 ++enum nfsstat4 {
624 ++ NFS4_OK = 0,
625 ++ NFS4ERR_PERM = 1,
626 ++ NFS4ERR_NOENT = 2,
627 ++ NFS4ERR_IO = 5,
628 ++ NFS4ERR_NXIO = 6,
629 ++ NFS4ERR_ACCESS = 13,
630 ++ NFS4ERR_EXIST = 17,
631 ++ NFS4ERR_XDEV = 18,
632 ++ /* Unused/reserved 19 */
633 ++ NFS4ERR_NOTDIR = 20,
634 ++ NFS4ERR_ISDIR = 21,
635 ++ NFS4ERR_INVAL = 22,
636 ++ NFS4ERR_FBIG = 27,
637 ++ NFS4ERR_NOSPC = 28,
638 ++ NFS4ERR_ROFS = 30,
639 ++ NFS4ERR_MLINK = 31,
640 ++ NFS4ERR_NAMETOOLONG = 63,
641 ++ NFS4ERR_NOTEMPTY = 66,
642 ++ NFS4ERR_DQUOT = 69,
643 ++ NFS4ERR_STALE = 70,
644 ++ NFS4ERR_BADHANDLE = 10001,
645 ++ NFS4ERR_BAD_COOKIE = 10003,
646 ++ NFS4ERR_NOTSUPP = 10004,
647 ++ NFS4ERR_TOOSMALL = 10005,
648 ++ NFS4ERR_SERVERFAULT = 10006,
649 ++ NFS4ERR_BADTYPE = 10007,
650 ++ NFS4ERR_DELAY = 10008,
651 ++ NFS4ERR_SAME = 10009,
652 ++ NFS4ERR_DENIED = 10010,
653 ++ NFS4ERR_EXPIRED = 10011,
654 ++ NFS4ERR_LOCKED = 10012,
655 ++ NFS4ERR_GRACE = 10013,
656 ++ NFS4ERR_FHEXPIRED = 10014,
657 ++ NFS4ERR_SHARE_DENIED = 10015,
658 ++ NFS4ERR_WRONGSEC = 10016,
659 ++ NFS4ERR_CLID_INUSE = 10017,
660 ++ NFS4ERR_RESOURCE = 10018,
661 ++ NFS4ERR_MOVED = 10019,
662 ++ NFS4ERR_NOFILEHANDLE = 10020,
663 ++ NFS4ERR_MINOR_VERS_MISMATCH = 10021,
664 ++ NFS4ERR_STALE_CLIENTID = 10022,
665 ++ NFS4ERR_STALE_STATEID = 10023,
666 ++ NFS4ERR_OLD_STATEID = 10024,
667 ++ NFS4ERR_BAD_STATEID = 10025,
668 ++ NFS4ERR_BAD_SEQID = 10026,
669 ++ NFS4ERR_NOT_SAME = 10027,
670 ++ NFS4ERR_LOCK_RANGE = 10028,
671 ++ NFS4ERR_SYMLINK = 10029,
672 ++ NFS4ERR_RESTOREFH = 10030,
673 ++ NFS4ERR_LEASE_MOVED = 10031,
674 ++ NFS4ERR_ATTRNOTSUPP = 10032,
675 ++ NFS4ERR_NO_GRACE = 10033,
676 ++ NFS4ERR_RECLAIM_BAD = 10034,
677 ++ NFS4ERR_RECLAIM_CONFLICT = 10035,
678 ++ NFS4ERR_BADXDR = 10036,
679 ++ NFS4ERR_LOCKS_HELD = 10037,
680 ++ NFS4ERR_OPENMODE = 10038,
681 ++ NFS4ERR_BADOWNER = 10039,
682 ++ NFS4ERR_BADCHAR = 10040,
683 ++ NFS4ERR_BADNAME = 10041,
684 ++ NFS4ERR_BAD_RANGE = 10042,
685 ++ NFS4ERR_LOCK_NOTSUPP = 10043,
686 ++ NFS4ERR_OP_ILLEGAL = 10044,
687 ++ NFS4ERR_DEADLOCK = 10045,
688 ++ NFS4ERR_FILE_OPEN = 10046,
689 ++ NFS4ERR_ADMIN_REVOKED = 10047,
690 ++ NFS4ERR_CB_PATH_DOWN = 10048
691 ++};
692 ++
693 ++/*
694 ++ * Note: NF4BAD is not actually part of the protocol; it is just used
695 ++ * internally by nfsd.
696 ++ */
697 ++enum nfs_ftype4 {
698 ++ NF4BAD = 0,
699 ++ NF4REG = 1, /* Regular File */
700 ++ NF4DIR = 2, /* Directory */
701 ++ NF4BLK = 3, /* Special File - block device */
702 ++ NF4CHR = 4, /* Special File - character device */
703 ++ NF4LNK = 5, /* Symbolic Link */
704 ++ NF4SOCK = 6, /* Special File - socket */
705 ++ NF4FIFO = 7, /* Special File - fifo */
706 ++ NF4ATTRDIR = 8, /* Attribute Directory */
707 ++ NF4NAMEDATTR = 9 /* Named Attribute */
708 ++};
709 ++
710 ++enum open_claim_type4 {
711 ++ NFS4_OPEN_CLAIM_NULL = 0,
712 ++ NFS4_OPEN_CLAIM_PREVIOUS = 1,
713 ++ NFS4_OPEN_CLAIM_DELEGATE_CUR = 2,
714 ++ NFS4_OPEN_CLAIM_DELEGATE_PREV = 3
715 ++};
716 ++
717 ++enum opentype4 {
718 ++ NFS4_OPEN_NOCREATE = 0,
719 ++ NFS4_OPEN_CREATE = 1
720 ++};
721 ++
722 ++enum createmode4 {
723 ++ NFS4_CREATE_UNCHECKED = 0,
724 ++ NFS4_CREATE_GUARDED = 1,
725 ++ NFS4_CREATE_EXCLUSIVE = 2
726 ++};
727 ++
728 ++enum limit_by4 {
729 ++ NFS4_LIMIT_SIZE = 1,
730 ++ NFS4_LIMIT_BLOCKS = 2
731 ++};
732 ++
733 ++enum open_delegation_type4 {
734 ++ NFS4_OPEN_DELEGATE_NONE = 0,
735 ++ NFS4_OPEN_DELEGATE_READ = 1,
736 ++ NFS4_OPEN_DELEGATE_WRITE = 2
737 ++};
738 ++
739 ++enum lock_type4 {
740 ++ NFS4_UNLOCK_LT = 0,
741 ++ NFS4_READ_LT = 1,
742 ++ NFS4_WRITE_LT = 2,
743 ++ NFS4_READW_LT = 3,
744 ++ NFS4_WRITEW_LT = 4
745 ++};
746 ++
747 ++
748 ++/* Mandatory Attributes */
749 ++#define FATTR4_WORD0_SUPPORTED_ATTRS (1UL << 0)
750 ++#define FATTR4_WORD0_TYPE (1UL << 1)
751 ++#define FATTR4_WORD0_FH_EXPIRE_TYPE (1UL << 2)
752 ++#define FATTR4_WORD0_CHANGE (1UL << 3)
753 ++#define FATTR4_WORD0_SIZE (1UL << 4)
754 ++#define FATTR4_WORD0_LINK_SUPPORT (1UL << 5)
755 ++#define FATTR4_WORD0_SYMLINK_SUPPORT (1UL << 6)
756 ++#define FATTR4_WORD0_NAMED_ATTR (1UL << 7)
757 ++#define FATTR4_WORD0_FSID (1UL << 8)
758 ++#define FATTR4_WORD0_UNIQUE_HANDLES (1UL << 9)
759 ++#define FATTR4_WORD0_LEASE_TIME (1UL << 10)
760 ++#define FATTR4_WORD0_RDATTR_ERROR (1UL << 11)
761 ++
762 ++/* Recommended Attributes */
763 ++#define FATTR4_WORD0_ACL (1UL << 12)
764 ++#define FATTR4_WORD0_ACLSUPPORT (1UL << 13)
765 ++#define FATTR4_WORD0_ARCHIVE (1UL << 14)
766 ++#define FATTR4_WORD0_CANSETTIME (1UL << 15)
767 ++#define FATTR4_WORD0_CASE_INSENSITIVE (1UL << 16)
768 ++#define FATTR4_WORD0_CASE_PRESERVING (1UL << 17)
769 ++#define FATTR4_WORD0_CHOWN_RESTRICTED (1UL << 18)
770 ++#define FATTR4_WORD0_FILEHANDLE (1UL << 19)
771 ++#define FATTR4_WORD0_FILEID (1UL << 20)
772 ++#define FATTR4_WORD0_FILES_AVAIL (1UL << 21)
773 ++#define FATTR4_WORD0_FILES_FREE (1UL << 22)
774 ++#define FATTR4_WORD0_FILES_TOTAL (1UL << 23)
775 ++#define FATTR4_WORD0_FS_LOCATIONS (1UL << 24)
776 ++#define FATTR4_WORD0_HIDDEN (1UL << 25)
777 ++#define FATTR4_WORD0_HOMOGENEOUS (1UL << 26)
778 ++#define FATTR4_WORD0_MAXFILESIZE (1UL << 27)
779 ++#define FATTR4_WORD0_MAXLINK (1UL << 28)
780 ++#define FATTR4_WORD0_MAXNAME (1UL << 29)
781 ++#define FATTR4_WORD0_MAXREAD (1UL << 30)
782 ++#define FATTR4_WORD0_MAXWRITE (1UL << 31)
783 ++#define FATTR4_WORD1_MIMETYPE (1UL << 0)
784 ++#define FATTR4_WORD1_MODE (1UL << 1)
785 ++#define FATTR4_WORD1_NO_TRUNC (1UL << 2)
786 ++#define FATTR4_WORD1_NUMLINKS (1UL << 3)
787 ++#define FATTR4_WORD1_OWNER (1UL << 4)
788 ++#define FATTR4_WORD1_OWNER_GROUP (1UL << 5)
789 ++#define FATTR4_WORD1_QUOTA_HARD (1UL << 6)
790 ++#define FATTR4_WORD1_QUOTA_SOFT (1UL << 7)
791 ++#define FATTR4_WORD1_QUOTA_USED (1UL << 8)
792 ++#define FATTR4_WORD1_RAWDEV (1UL << 9)
793 ++#define FATTR4_WORD1_SPACE_AVAIL (1UL << 10)
794 ++#define FATTR4_WORD1_SPACE_FREE (1UL << 11)
795 ++#define FATTR4_WORD1_SPACE_TOTAL (1UL << 12)
796 ++#define FATTR4_WORD1_SPACE_USED (1UL << 13)
797 ++#define FATTR4_WORD1_SYSTEM (1UL << 14)
798 ++#define FATTR4_WORD1_TIME_ACCESS (1UL << 15)
799 ++#define FATTR4_WORD1_TIME_ACCESS_SET (1UL << 16)
800 ++#define FATTR4_WORD1_TIME_BACKUP (1UL << 17)
801 ++#define FATTR4_WORD1_TIME_CREATE (1UL << 18)
802 ++#define FATTR4_WORD1_TIME_DELTA (1UL << 19)
803 ++#define FATTR4_WORD1_TIME_METADATA (1UL << 20)
804 ++#define FATTR4_WORD1_TIME_MODIFY (1UL << 21)
805 ++#define FATTR4_WORD1_TIME_MODIFY_SET (1UL << 22)
806 ++#define FATTR4_WORD1_MOUNTED_ON_FILEID (1UL << 23)
807 ++
808 ++#define NFSPROC4_NULL 0
809 ++#define NFSPROC4_COMPOUND 1
810 ++#define NFS4_MINOR_VERSION 0
811 ++#define NFS4_DEBUG 1
812 ++
813 ++#ifdef __KERNEL__
814 ++
815 ++/* Index of predefined Linux client operations */
816 ++
817 ++enum {
818 ++ NFSPROC4_CLNT_NULL = 0, /* Unused */
819 ++ NFSPROC4_CLNT_READ,
820 ++ NFSPROC4_CLNT_WRITE,
821 ++ NFSPROC4_CLNT_COMMIT,
822 ++ NFSPROC4_CLNT_OPEN,
823 ++ NFSPROC4_CLNT_OPEN_CONFIRM,
824 ++ NFSPROC4_CLNT_OPEN_RECLAIM,
825 ++ NFSPROC4_CLNT_OPEN_DOWNGRADE,
826 ++ NFSPROC4_CLNT_CLOSE,
827 ++ NFSPROC4_CLNT_SETATTR,
828 ++ NFSPROC4_CLNT_FSINFO,
829 ++ NFSPROC4_CLNT_RENEW,
830 ++ NFSPROC4_CLNT_SETCLIENTID,
831 ++ NFSPROC4_CLNT_SETCLIENTID_CONFIRM,
832 ++ NFSPROC4_CLNT_LOCK,
833 ++ NFSPROC4_CLNT_LOCKT,
834 ++ NFSPROC4_CLNT_LOCKU,
835 ++ NFSPROC4_CLNT_ACCESS,
836 ++ NFSPROC4_CLNT_GETATTR,
837 ++ NFSPROC4_CLNT_LOOKUP,
838 ++ NFSPROC4_CLNT_LOOKUP_ROOT,
839 ++ NFSPROC4_CLNT_REMOVE,
840 ++ NFSPROC4_CLNT_RENAME,
841 ++ NFSPROC4_CLNT_LINK,
842 ++ NFSPROC4_CLNT_CREATE,
843 ++ NFSPROC4_CLNT_PATHCONF,
844 ++ NFSPROC4_CLNT_STATFS,
845 ++ NFSPROC4_CLNT_READLINK,
846 ++ NFSPROC4_CLNT_READDIR,
847 ++ NFSPROC4_CLNT_SERVER_CAPS,
848 ++ NFSPROC4_CLNT_DELEGRETURN,
849 ++ NFSPROC4_CLNT_GETACL,
850 ++ NFSPROC4_CLNT_SETACL,
851 ++};
852 ++
853 ++#endif
854 ++#endif
855 ++
856 ++/*
857 ++ * Local variables:
858 ++ * c-basic-offset: 8
859 ++ * End:
860 ++ */
861 +diff --git a/libacl/Makefile b/libacl/Makefile
862 +index 6befcd4..8335170 100644
863 +--- a/libacl/Makefile
864 ++++ b/libacl/Makefile
865 +@@ -22,19 +22,38 @@ LTLDFLAGS += -Wl,--version-script,$(TOPDIR)/exports
866 + include $(TOPDIR)/include/builddefs
867 +
868 + LTLIBRARY = libacl.la
869 +-LTLIBS = -lattr $(LIBMISC)
870 ++LTLIBS = -lattr -lnfsidmap $(LIBMISC)
871 + LTDEPENDENCIES = $(LIBMISC)
872 +-LT_CURRENT = 2
873 ++LT_CURRENT = 3
874 + LT_REVISION = 0
875 +-LT_AGE = 1
876 ++LT_AGE = 2
877 ++
878 ++CFILES = $(POSIX_CFILES) $(LIBACL_CFILES) $(LIBACL_NFS4_CFILES) \
879 ++ $(INTERNAL_CFILES) perm_copy_fd.c perm_copy_file.c
880 +
881 +-CFILES = $(POSIX_CFILES) $(LIBACL_CFILES) $(INTERNAL_CFILES) \
882 +- perm_copy_fd.c perm_copy_file.c
883 + HFILES = libobj.h libacl.h byteorder.h __acl_from_xattr.h __acl_to_xattr.h \
884 +- perm_copy.h __acl_extended_file.h
885 ++ perm_copy.h __acl_extended_file.h $(LIBACL_NFS4_HFILES)
886 +
887 + LCFLAGS = -include perm_copy.h
888 +
889 ++LIBACL_NFS4_CFILES = \
890 ++ acl_n4tp_ace_count.c \
891 ++ acl_n4tp_ace_trans.c acl_nfs4_get_who.c \
892 ++ acl_n4tp_acl_trans.c acl_nfs4_get_whotype.c \
893 ++ acl_n4tp_get_whotype.c acl_nfs4_new.c \
894 ++ acl_n4tp_set_mode.c acl_n4tp_set_who.c \
895 ++ acl_nfs4_add_ace.c acl_nfs4_remove_ace.c \
896 ++ acl_nfs4_add_pair.c \
897 ++ acl_nfs4_copy_acl.c acl_nfs4_set_who.c \
898 ++ acl_nfs4_utils.c \
899 ++ acl_nfs4_free.c acl_nfs4_xattr_load.c \
900 ++ acl_nfs4_xattr_pack.c acl_nfs4_xattr_size.c \
901 ++ acl_ptn4_acl_trans.c \
902 ++ acl_ptn4_get_mask.c __posix_acl_from_nfs4_xattr.c \
903 ++
904 ++
905 ++LIBACL_NFS4_HFILES = ../include/libacl_nfs4.h ../include/nfs4.h
906 ++
907 + POSIX_CFILES = \
908 + acl_add_perm.c acl_calc_mask.c acl_clear_perms.c acl_copy_entry.c \
909 + acl_copy_ext.c acl_copy_int.c acl_create_entry.c acl_delete_def_file.c \
910 +diff --git a/libacl/__acl_extended_file.c b/libacl/__acl_extended_file.c
911 +index 3e45abd..b84f2a8 100644
912 +--- a/libacl/__acl_extended_file.c
913 ++++ b/libacl/__acl_extended_file.c
914 +@@ -22,6 +22,7 @@
915 + #include <unistd.h>
916 + #include <attr/xattr.h>
917 + #include "libacl.h"
918 ++#include "libacl_nfs4.h"
919 +
920 + #include "byteorder.h"
921 + #include "acl_ea.h"
922 +@@ -36,6 +37,34 @@ __acl_extended_file(const char *path_p,
923 + int base_size = sizeof(acl_ea_header) + 3 * sizeof(acl_ea_entry);
924 + int retval;
925 +
926 ++ /* XXX: Ugh: what's the easiest way to do this, taking
927 ++ * into account default acl's, and that length alone won't do this?
928 ++ * Also I'm a little uncomfortable with the amount of #ifdef
929 ++ * NFS4 stuff that's going on. We need a cleaner separation. */
930 ++#ifdef USE_NFSV4_TRANS
931 ++ retval = fun(path_p, ACL_NFS4_XATTR, NULL, 0);
932 ++ if (retval < 0 && errno != ENOATTR && errno != EOPNOTSUPP)
933 ++ return -1;
934 ++ if (retval >= 0) {
935 ++ struct nfs4_acl *nfsacl;
936 ++ char *ext_acl_p = alloca(retval);
937 ++ if (!ext_acl_p)
938 ++ return -1;
939 ++
940 ++ retval = fun(path_p, ACL_NFS4_XATTR, ext_acl_p, retval);
941 ++ if (retval == -1)
942 ++ return -1;
943 ++
944 ++ nfsacl = acl_nfs4_xattr_load(ext_acl_p, retval, NFS4_ACL_ISFILE);
945 ++ if (nfsacl) {
946 ++ int count = nfsacl->naces;
947 ++ acl_nfs4_free(nfsacl);
948 ++ return count > 6;
949 ++ }
950 ++ return 0;
951 ++ }
952 ++#endif
953 ++
954 + retval = fun(path_p, ACL_EA_ACCESS, NULL, 0);
955 + if (retval < 0 && errno != ENOATTR && errno != ENODATA)
956 + return -1;
957 +diff --git a/libacl/__posix_acl_from_nfs4_xattr.c b/libacl/__posix_acl_from_nfs4_xattr.c
958 +new file mode 100644
959 +index 0000000..8941024
960 +--- /dev/null
961 ++++ b/libacl/__posix_acl_from_nfs4_xattr.c
962 +@@ -0,0 +1,60 @@
963 ++/*
964 ++ * NFSv4 ACL Code
965 ++ * Convert NFSv4 xattr values to a posix ACL
966 ++ *
967 ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
968 ++ * All rights reserved.
969 ++ *
970 ++ * Nathaniel Gallaher <ngallahe@×××××.edu>
971 ++ *
972 ++ * Redistribution and use in source and binary forms, with or without
973 ++ * modification, are permitted provided that the following conditions
974 ++ * are met:
975 ++ *
976 ++ * 1. Redistributions of source code must retain the above copyright
977 ++ * notice, this list of conditions and the following disclaimer.
978 ++ * 2. Redistributions in binary form must reproduce the above copyright
979 ++ * notice, this list of conditions and the following disclaimer in the
980 ++ * documentation and/or other materials provided with the distribution.
981 ++ * 3. Neither the name of the University nor the names of its
982 ++ * contributors may be used to endorse or promote products derived
983 ++ * from this software without specific prior written permission.
984 ++ *
985 ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
986 ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
987 ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
988 ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
989 ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
990 ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
991 ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
992 ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
993 ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
994 ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
995 ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
996 ++ */
997 ++
998 ++#include <acl/libacl.h>
999 ++#include "libacl_nfs4.h"
1000 ++
1001 ++/* xattr_v is a char buffer filled with the nfsv4 xattr value.
1002 ++ * xattr_size should be the byte count of the length of the xattr_v
1003 ++ * data size. xattr_v may be larger than <xattr_size> bytes, but only
1004 ++ * the first <xattr_size> bytes will be read. <type> is the posix acl
1005 ++ * type requested. Currently either default, or access */
1006 ++
1007 ++acl_t __posix_acl_from_nfs4_xattr(char* xattr_v,
1008 ++ int xattr_size, acl_type_t ptype, u32 is_dir)
1009 ++{
1010 ++ struct nfs4_acl * nfsacl = NULL;
1011 ++ acl_t pacl;
1012 ++
1013 ++ nfsacl = acl_nfs4_xattr_load(xattr_v, xattr_size, is_dir);
1014 ++ if(nfsacl == NULL) {
1015 ++ return NULL;
1016 ++ }
1017 ++
1018 ++ pacl = acl_n4tp_acl_trans(nfsacl, ptype);
1019 ++
1020 ++ return pacl;
1021 ++}
1022 ++
1023 +diff --git a/libacl/acl_get_fd.c b/libacl/acl_get_fd.c
1024 +index f2525ef..eb678a8 100644
1025 +--- a/libacl/acl_get_fd.c
1026 ++++ b/libacl/acl_get_fd.c
1027 +@@ -28,6 +28,10 @@
1028 + #include "libacl.h"
1029 + #include "__acl_from_xattr.h"
1030 +
1031 ++#ifdef USE_NFSV4_TRANS
1032 ++ #include "libacl_nfs4.h"
1033 ++#endif
1034 ++
1035 + #include "byteorder.h"
1036 + #include "acl_ea.h"
1037 +
1038 +@@ -38,31 +42,59 @@ acl_get_fd(int fd)
1039 + {
1040 + const size_t size_guess = acl_ea_size(16);
1041 + char *ext_acl_p = alloca(size_guess);
1042 ++ char *name = ACL_EA_ACCESS;
1043 + int retval;
1044 ++ int nfsv4acls;
1045 +
1046 + if (!ext_acl_p)
1047 + return NULL;
1048 +- retval = fgetxattr(fd, ACL_EA_ACCESS, ext_acl_p, size_guess);
1049 ++
1050 ++#ifdef USE_NFSV4_TRANS
1051 ++ retval = fgetxattr(fd, ACL_NFS4_XATTR, ext_acl_p, size_guess);
1052 ++ if(retval == -1 && (errno == ENOATTR || errno == EOPNOTSUPP)) {
1053 ++ nfsv4acls = ACL_NFS4_NOT_USED;
1054 ++ retval = fgetxattr(fd, name, ext_acl_p, size_guess);
1055 ++ } else {
1056 ++ nfsv4acls = ACL_NFS4_USED;
1057 ++ name = ACL_NFS4_XATTR;
1058 ++ }
1059 ++#else
1060 ++ retval = fgetxattr(fd, name, ext_acl_p, size_guess);
1061 ++#endif
1062 ++
1063 + if (retval == -1 && errno == ERANGE) {
1064 +- retval = fgetxattr(fd, ACL_EA_ACCESS, NULL, 0);
1065 ++ retval = fgetxattr(fd, name, NULL, 0);
1066 + if (retval > 0) {
1067 + ext_acl_p = alloca(retval);
1068 + if (!ext_acl_p)
1069 + return NULL;
1070 +- retval = fgetxattr(fd, ACL_EA_ACCESS, ext_acl_p,retval);
1071 ++ retval = fgetxattr(fd, name, ext_acl_p, retval);
1072 + }
1073 + }
1074 + if (retval > 0) {
1075 +- acl_t acl = __acl_from_xattr(ext_acl_p, retval);
1076 +- return acl;
1077 ++#ifdef USE_NFSV4_TRANS
1078 ++ if(nfsv4acls == ACL_NFS4_USED) {
1079 ++ acl_t acl = __posix_acl_from_nfs4_xattr(ext_acl_p, retval,
1080 ++ ACL_TYPE_ACCESS, NFS4_ACL_ISFILE);
1081 ++
1082 ++ return acl;
1083 ++ }
1084 ++ else
1085 ++#endif
1086 ++ {
1087 ++ acl_t acl = __acl_from_xattr(ext_acl_p, retval);
1088 ++ return acl;
1089 ++ }
1090 + } else if (retval == 0 || errno == ENOATTR || errno == ENODATA) {
1091 + struct stat st;
1092 +
1093 +- if (fstat(fd, &st) == 0)
1094 +- return acl_from_mode(st.st_mode);
1095 +- else
1096 ++ if (fstat(fd, &st) != 0) {
1097 + return NULL;
1098 +- } else
1099 ++ }
1100 ++
1101 ++ return acl_from_mode(st.st_mode);
1102 ++ } else {
1103 + return NULL;
1104 ++ }
1105 + }
1106 +
1107 +diff --git a/libacl/acl_get_file.c b/libacl/acl_get_file.c
1108 +index 110ef2e..42ac536 100644
1109 +--- a/libacl/acl_get_file.c
1110 ++++ b/libacl/acl_get_file.c
1111 +@@ -28,6 +28,10 @@
1112 + #include "libacl.h"
1113 + #include "__acl_from_xattr.h"
1114 +
1115 ++#ifdef USE_NFSV4_TRANS
1116 ++ #include "libacl_nfs4.h"
1117 ++#endif
1118 ++
1119 + #include "byteorder.h"
1120 + #include "acl_ea.h"
1121 +
1122 +@@ -40,6 +44,8 @@ acl_get_file(const char *path_p, acl_type_t type)
1123 + char *ext_acl_p = alloca(size_guess);
1124 + const char *name;
1125 + int retval;
1126 ++ int nfsv4acls;
1127 ++ int iflags;
1128 +
1129 + switch(type) {
1130 + case ACL_TYPE_ACCESS:
1131 +@@ -55,8 +61,20 @@ acl_get_file(const char *path_p, acl_type_t type)
1132 +
1133 + if (!ext_acl_p)
1134 + return NULL;
1135 ++#ifdef USE_NFSV4_TRANS
1136 ++ retval = getxattr(path_p, ACL_NFS4_XATTR, ext_acl_p, size_guess);
1137 ++ if((retval == -1) && (errno == ENOATTR || errno == EOPNOTSUPP)) {
1138 ++ nfsv4acls = ACL_NFS4_NOT_USED;
1139 ++ retval = getxattr(path_p, name, ext_acl_p, size_guess);
1140 ++ } else {
1141 ++ nfsv4acls = ACL_NFS4_USED;
1142 ++ name = ACL_NFS4_XATTR;
1143 ++ }
1144 ++#else
1145 + retval = getxattr(path_p, name, ext_acl_p, size_guess);
1146 +- if (retval == -1 && errno == ERANGE) {
1147 ++#endif
1148 ++
1149 ++ if ((retval == -1) && (errno == ERANGE)) {
1150 + retval = getxattr(path_p, name, NULL, 0);
1151 + if (retval > 0) {
1152 + ext_acl_p = alloca(retval);
1153 +@@ -66,9 +84,29 @@ acl_get_file(const char *path_p, acl_type_t type)
1154 + }
1155 + }
1156 + if (retval > 0) {
1157 +- acl_t acl = __acl_from_xattr(ext_acl_p, retval);
1158 +- return acl;
1159 +- } else if (retval == 0 || errno == ENOATTR || errno == ENODATA) {
1160 ++#ifdef USE_NFSV4_TRANS
1161 ++ if(nfsv4acls == ACL_NFS4_USED) {
1162 ++ struct stat st;
1163 ++
1164 ++ iflags = NFS4_ACL_ISFILE;
1165 ++
1166 ++ if (stat(path_p, &st) != 0)
1167 ++ return NULL;
1168 ++
1169 ++ if (S_ISDIR(st.st_mode))
1170 ++ iflags = NFS4_ACL_ISDIR;
1171 ++
1172 ++ acl_t acl = __posix_acl_from_nfs4_xattr(ext_acl_p, retval, type,
1173 ++ iflags);
1174 ++ return acl;
1175 ++ }
1176 ++ else
1177 ++#endif
1178 ++ {
1179 ++ acl_t acl = __acl_from_xattr(ext_acl_p, retval);
1180 ++ return acl;
1181 ++ }
1182 ++ } else if ((retval == 0) || (errno == ENOATTR) || (errno == ENODATA)) {
1183 + struct stat st;
1184 +
1185 + if (stat(path_p, &st) != 0)
1186 +diff --git a/libacl/acl_n4tp_ace_count.c b/libacl/acl_n4tp_ace_count.c
1187 +new file mode 100644
1188 +index 0000000..ecce637
1189 +--- /dev/null
1190 ++++ b/libacl/acl_n4tp_ace_count.c
1191 +@@ -0,0 +1,57 @@
1192 ++/*
1193 ++ * NFSv4 ACL Code
1194 ++ * Calculate the POSIX ACE count based upon the assumption that
1195 ++ * POSIX<->NFSv4 ACL translation has been the standard on the
1196 ++ * server/client. This would break against other servers?
1197 ++ *
1198 ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
1199 ++ * All rights reserved.
1200 ++ *
1201 ++ * Nathaniel Gallaher <ngallahe@×××××.edu>
1202 ++ *
1203 ++ * Redistribution and use in source and binary forms, with or without
1204 ++ * modification, are permitted provided that the following conditions
1205 ++ * are met:
1206 ++ *
1207 ++ * 1. Redistributions of source code must retain the above copyright
1208 ++ * notice, this list of conditions and the following disclaimer.
1209 ++ * 2. Redistributions in binary form must reproduce the above copyright
1210 ++ * notice, this list of conditions and the following disclaimer in the
1211 ++ * documentation and/or other materials provided with the distribution.
1212 ++ * 3. Neither the name of the University nor the names of its
1213 ++ * contributors may be used to endorse or promote products derived
1214 ++ * from this software without specific prior written permission.
1215 ++ *
1216 ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1217 ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1218 ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1219 ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1220 ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1221 ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1222 ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
1223 ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
1224 ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1225 ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1226 ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1227 ++ */
1228 ++
1229 ++#include <acl/libacl.h>
1230 ++#include "libacl_nfs4.h"
1231 ++
1232 ++int acl_n4tp_ace_count(struct nfs4_acl *n4acl)
1233 ++{
1234 ++ if (n4acl->naces == 0)
1235 ++ return 0;
1236 ++ if (n4acl->naces == 6) /* owner, owner group, and other only */
1237 ++ return 3;
1238 ++ else { /* Otherwise there must be a mask entry. */
1239 ++ /* Also, the remaining entries are for named users and
1240 ++ * groups, and come in threes (mask, allow, deny): */
1241 ++ if (n4acl->naces < 7)
1242 ++ return -1;
1243 ++ if ((n4acl->naces - 7) % 3)
1244 ++ return -1;
1245 ++ return 4 + (n4acl->naces - 7)/3;
1246 ++ }
1247 ++}
1248 ++
1249 +diff --git a/libacl/acl_n4tp_ace_trans.c b/libacl/acl_n4tp_ace_trans.c
1250 +new file mode 100644
1251 +index 0000000..c5cc4da
1252 +--- /dev/null
1253 ++++ b/libacl/acl_n4tp_ace_trans.c
1254 +@@ -0,0 +1,76 @@
1255 ++/*
1256 ++ * NFSv4 ACL Code
1257 ++ * Translate an NFSv4 ace to a POSIX ace.
1258 ++ *
1259 ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
1260 ++ * All rights reserved.
1261 ++ *
1262 ++ * Nathaniel Gallaher <ngallahe@×××××.edu>
1263 ++ *
1264 ++ * Redistribution and use in source and binary forms, with or without
1265 ++ * modification, are permitted provided that the following conditions
1266 ++ * are met:
1267 ++ *
1268 ++ * 1. Redistributions of source code must retain the above copyright
1269 ++ * notice, this list of conditions and the following disclaimer.
1270 ++ * 2. Redistributions in binary form must reproduce the above copyright
1271 ++ * notice, this list of conditions and the following disclaimer in the
1272 ++ * documentation and/or other materials provided with the distribution.
1273 ++ * 3. Neither the name of the University nor the names of its
1274 ++ * contributors may be used to endorse or promote products derived
1275 ++ * from this software without specific prior written permission.
1276 ++ *
1277 ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1278 ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1279 ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1280 ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1281 ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1282 ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1283 ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
1284 ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
1285 ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1286 ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1287 ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1288 ++ */
1289 ++
1290 ++#include "libacl_nfs4.h"
1291 ++
1292 ++int acl_n4tp_ace_trans(struct nfs4_ace *ace, acl_t *pacl, acl_tag_t tag,
1293 ++ int iflags)
1294 ++{
1295 ++ int result;
1296 ++ acl_entry_t new_ace;
1297 ++
1298 ++
1299 ++ if(ace == NULL || pacl == NULL || *pacl == NULL) {
1300 ++ errno = EINVAL;
1301 ++ goto failed;
1302 ++ }
1303 ++
1304 ++ result = acl_create_entry(pacl, &new_ace);
1305 ++ if(result < 0)
1306 ++ goto failed;
1307 ++
1308 ++ result = acl_set_tag_type(new_ace, tag);
1309 ++ if(result < 0)
1310 ++ goto ace_failed;
1311 ++
1312 ++ result = acl_n4tp_set_mode(new_ace, ace->access_mask, iflags);
1313 ++ if(result < 0)
1314 ++ goto ace_failed;
1315 ++
1316 ++ if(tag == ACL_USER || tag == ACL_GROUP) {
1317 ++ result = acl_n4tp_set_who(new_ace, ace->who, tag);
1318 ++ if(result < 0)
1319 ++ goto ace_failed;
1320 ++ }
1321 ++
1322 ++ return 0;
1323 ++
1324 ++ace_failed:
1325 ++ acl_delete_entry(*pacl, new_ace);
1326 ++
1327 ++failed:
1328 ++ return -1;
1329 ++}
1330 ++
1331 +diff --git a/libacl/acl_n4tp_acl_trans.c b/libacl/acl_n4tp_acl_trans.c
1332 +new file mode 100644
1333 +index 0000000..f658242
1334 +--- /dev/null
1335 ++++ b/libacl/acl_n4tp_acl_trans.c
1336 +@@ -0,0 +1,164 @@
1337 ++/*
1338 ++ * NFSv4 ACL Code
1339 ++ * Convert NFSv4 ACL to a POSIX ACL
1340 ++ *
1341 ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
1342 ++ * All rights reserved.
1343 ++ *
1344 ++ * Nathaniel Gallaher <ngallahe@×××××.edu>
1345 ++ *
1346 ++ * Redistribution and use in source and binary forms, with or without
1347 ++ * modification, are permitted provided that the following conditions
1348 ++ * are met:
1349 ++ *
1350 ++ * 1. Redistributions of source code must retain the above copyright
1351 ++ * notice, this list of conditions and the following disclaimer.
1352 ++ * 2. Redistributions in binary form must reproduce the above copyright
1353 ++ * notice, this list of conditions and the following disclaimer in the
1354 ++ * documentation and/or other materials provided with the distribution.
1355 ++ * 3. Neither the name of the University nor the names of its
1356 ++ * contributors may be used to endorse or promote products derived
1357 ++ * from this software without specific prior written permission.
1358 ++ *
1359 ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1360 ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1361 ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1362 ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1363 ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1364 ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1365 ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
1366 ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
1367 ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1368 ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1369 ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1370 ++ */
1371 ++
1372 ++#include <acl/libacl.h>
1373 ++#include "libacl_nfs4.h"
1374 ++
1375 ++acl_t acl_n4tp_acl_trans(struct nfs4_acl * nacl_p, acl_type_t ptype)
1376 ++{
1377 ++
1378 ++ acl_t pacl_p = NULL;
1379 ++ acl_t * pacl_pp;
1380 ++ struct nfs4_acl * temp_acl;
1381 ++ int naces = -1;
1382 ++ int num_aces;
1383 ++ int ace_num;
1384 ++ struct nfs4_ace * cur_ace = NULL;
1385 ++ struct nfs4_ace * mask_ace = NULL;
1386 ++ struct nfs4_ace * temp_ace = NULL;
1387 ++ int result;
1388 ++ u32 flags;
1389 ++ u32 iflags = NFS4_ACL_NOFLAGS;
1390 ++
1391 ++ if (nacl_p == NULL) {
1392 ++ errno = EINVAL;
1393 ++ goto failed;
1394 ++ }
1395 ++
1396 ++ if (ptype == ACL_TYPE_DEFAULT) {
1397 ++ if (nacl_p->is_directory)
1398 ++ iflags |= NFS4_ACL_REQUEST_DEFAULT;
1399 ++ else {
1400 ++ errno = EINVAL;
1401 ++ goto failed;
1402 ++ }
1403 ++ }
1404 ++
1405 ++ /* Copy so we can delete bits without borking the original */
1406 ++ temp_acl = acl_nfs4_copy_acl(nacl_p);
1407 ++ if (temp_acl == NULL)
1408 ++ goto failed;
1409 ++
1410 ++ num_aces = temp_acl->naces;
1411 ++
1412 ++ /* Strip or keep inheritance aces depending upon the type of posix acl
1413 ++ * requested */
1414 ++ cur_ace = acl_nfs4_get_first_ace(temp_acl);
1415 ++ ace_num = 1;
1416 ++
1417 ++ while(1) {
1418 ++ if(cur_ace == NULL) {
1419 ++ if(ace_num > num_aces)
1420 ++ break;
1421 ++ else
1422 ++ goto free_failed;
1423 ++ }
1424 ++
1425 ++ /* get the next ace now because we may be freeing the current ace */
1426 ++ temp_ace = cur_ace;
1427 ++ acl_nfs4_get_next_ace(&cur_ace);
1428 ++
1429 ++ flags = temp_ace->flag;
1430 ++
1431 ++ if (iflags & NFS4_ACL_REQUEST_DEFAULT) {
1432 ++ if((flags & NFS4_INHERITANCE_FLAGS) != NFS4_INHERITANCE_FLAGS)
1433 ++ acl_nfs4_remove_ace(temp_acl, temp_ace);
1434 ++ } else {
1435 ++ if ((flags & NFS4_INHERITANCE_FLAGS) == NFS4_INHERITANCE_FLAGS) {
1436 ++ acl_nfs4_remove_ace(temp_acl, temp_ace);
1437 ++ }
1438 ++ }
1439 ++
1440 ++ ace_num++;
1441 ++ }
1442 ++
1443 ++
1444 ++ naces = acl_n4tp_ace_count(temp_acl);
1445 ++ if (naces < 0) {
1446 ++ errno = EINVAL;
1447 ++ goto free_failed;
1448 ++ }
1449 ++
1450 ++ if (naces == 0)
1451 ++ return acl_init(0);
1452 ++
1453 ++ pacl_p = acl_init(naces);
1454 ++
1455 ++ if(pacl_p == NULL)
1456 ++ goto free_failed;
1457 ++
1458 ++ pacl_pp = &pacl_p;
1459 ++
1460 ++ cur_ace = acl_nfs4_get_first_ace(temp_acl);
1461 ++
1462 ++ result = user_obj_from_v4(temp_acl, &cur_ace, pacl_pp, iflags);
1463 ++ if(result < 0)
1464 ++ goto acl_free_failed;
1465 ++
1466 ++ result = users_from_v4(temp_acl, &cur_ace, &mask_ace, pacl_pp, iflags);
1467 ++ if(result < 0)
1468 ++ goto acl_free_failed;
1469 ++
1470 ++ result = group_obj_and_groups_from_v4(temp_acl, &cur_ace,
1471 ++ &mask_ace, pacl_pp, iflags);
1472 ++ if(result < 0)
1473 ++ goto acl_free_failed;
1474 ++
1475 ++ result = mask_from_v4(temp_acl, &cur_ace, &mask_ace, pacl_pp, iflags);
1476 ++ if(result < 0)
1477 ++ goto acl_free_failed;
1478 ++
1479 ++ result = other_from_v4(temp_acl, &cur_ace, pacl_pp, iflags);
1480 ++ if(result < 0)
1481 ++ goto acl_free_failed;
1482 ++
1483 ++ result = acl_valid(*pacl_pp);
1484 ++ if(result < 0)
1485 ++ goto acl_free_failed;
1486 ++
1487 ++ acl_nfs4_free(temp_acl);
1488 ++
1489 ++ return *pacl_pp;
1490 ++
1491 ++acl_free_failed:
1492 ++ acl_free(*pacl_pp);
1493 ++
1494 ++free_failed:
1495 ++ acl_nfs4_free(temp_acl);
1496 ++
1497 ++failed:
1498 ++ return NULL;
1499 ++}
1500 ++
1501 +diff --git a/libacl/acl_n4tp_get_whotype.c b/libacl/acl_n4tp_get_whotype.c
1502 +new file mode 100644
1503 +index 0000000..fd553c6
1504 +--- /dev/null
1505 ++++ b/libacl/acl_n4tp_get_whotype.c
1506 +@@ -0,0 +1,73 @@
1507 ++/*
1508 ++ * NFSv4 ACL Code
1509 ++ * Convert NFSv4 ACE who to a POSIX ACE whotype
1510 ++ *
1511 ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
1512 ++ * All rights reserved.
1513 ++ *
1514 ++ * Nathaniel Gallaher <ngallahe@×××××.edu>
1515 ++ *
1516 ++ * Redistribution and use in source and binary forms, with or without
1517 ++ * modification, are permitted provided that the following conditions
1518 ++ * are met:
1519 ++ *
1520 ++ * 1. Redistributions of source code must retain the above copyright
1521 ++ * notice, this list of conditions and the following disclaimer.
1522 ++ * 2. Redistributions in binary form must reproduce the above copyright
1523 ++ * notice, this list of conditions and the following disclaimer in the
1524 ++ * documentation and/or other materials provided with the distribution.
1525 ++ * 3. Neither the name of the University nor the names of its
1526 ++ * contributors may be used to endorse or promote products derived
1527 ++ * from this software without specific prior written permission.
1528 ++ *
1529 ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1530 ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1531 ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1532 ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1533 ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1534 ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1535 ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
1536 ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
1537 ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1538 ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1539 ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1540 ++ */
1541 ++
1542 ++#include <acl/libacl.h>
1543 ++#include "libacl_nfs4.h"
1544 ++
1545 ++acl_tag_t acl_n4tp_get_whotype(struct nfs4_ace *ace)
1546 ++{
1547 ++ int nfs4type;
1548 ++ int result;
1549 ++
1550 ++ if(ace == NULL)
1551 ++ goto inval_failed;
1552 ++
1553 ++ if(ace->who == NULL || strlen(ace->who) <= 0)
1554 ++ goto inval_failed;
1555 ++
1556 ++ result = acl_nfs4_get_who(ace, &nfs4type, NULL);
1557 ++ if ( result < 0 )
1558 ++ goto failed;
1559 ++
1560 ++ switch (nfs4type) {
1561 ++ case NFS4_ACL_WHO_NAMED:
1562 ++ return (ace->flag & NFS4_ACE_IDENTIFIER_GROUP ?
1563 ++ ACL_GROUP : ACL_USER);
1564 ++ case NFS4_ACL_WHO_OWNER:
1565 ++ return ACL_USER_OBJ;
1566 ++ case NFS4_ACL_WHO_GROUP:
1567 ++ return ACL_GROUP_OBJ;
1568 ++ case NFS4_ACL_WHO_EVERYONE:
1569 ++ return ACL_OTHER;
1570 ++ }
1571 ++
1572 ++inval_failed:
1573 ++ errno = EINVAL;
1574 ++
1575 ++failed:
1576 ++ return -1;
1577 ++}
1578 ++
1579 ++
1580 +diff --git a/libacl/acl_n4tp_set_mode.c b/libacl/acl_n4tp_set_mode.c
1581 +new file mode 100644
1582 +index 0000000..bef5e23
1583 +--- /dev/null
1584 ++++ b/libacl/acl_n4tp_set_mode.c
1585 +@@ -0,0 +1,98 @@
1586 ++/*
1587 ++ * NFSv4 ACL Code
1588 ++ * Set posix ACL mode based on NFSv4 mask
1589 ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
1590 ++ * All rights reserved.
1591 ++ *
1592 ++ * Nathaniel Gallaher <ngallahe@×××××.edu>
1593 ++ *
1594 ++ * Redistribution and use in source and binary forms, with or without
1595 ++ * modification, are permitted provided that the following conditions
1596 ++ * are met:
1597 ++ *
1598 ++ * 1. Redistributions of source code must retain the above copyright
1599 ++ * notice, this list of conditions and the following disclaimer.
1600 ++ * 2. Redistributions in binary form must reproduce the above copyright
1601 ++ * notice, this list of conditions and the following disclaimer in the
1602 ++ * documentation and/or other materials provided with the distribution.
1603 ++ * 3. Neither the name of the University nor the names of its
1604 ++ * contributors may be used to endorse or promote products derived
1605 ++ * from this software without specific prior written permission.
1606 ++ *
1607 ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1608 ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1609 ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1610 ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1611 ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1612 ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1613 ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
1614 ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
1615 ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1616 ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1617 ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1618 ++ */
1619 ++
1620 ++#include <acl/libacl.h>
1621 ++#include "libacl_nfs4.h"
1622 ++
1623 ++int acl_n4tp_set_mode(acl_entry_t pace, u32 nfs4_access_mask, int iflags)
1624 ++{
1625 ++ /* XXX we might also want to ignore DELETE_CHILD on non-directories */
1626 ++ /* XXX also add special interpretation to EXECUTE on directories */
1627 ++ u32 ignore = NFS4_ACE_SYNCHRONIZE;
1628 ++ u32 new_mask;
1629 ++ acl_permset_t perms;
1630 ++ int result;
1631 ++
1632 ++ if((iflags & NFS4_ACL_ISDIR) != NFS4_ACL_ISDIR)
1633 ++ ignore |= NFS4_ACE_DELETE_CHILD;
1634 ++
1635 ++ nfs4_access_mask |= ignore;
1636 ++
1637 ++ result = acl_get_permset(pace, &perms);
1638 ++ if(result < 0)
1639 ++ goto failed;
1640 ++
1641 ++ result = acl_clear_perms(perms);
1642 ++ if(result < 0)
1643 ++ goto failed;
1644 ++
1645 ++ if ((nfs4_access_mask & NFS4_READ_MODE) == NFS4_READ_MODE) {
1646 ++ result = acl_add_perm(perms, ACL_READ);
1647 ++ if(result < 0)
1648 ++ goto failed;
1649 ++ }
1650 ++
1651 ++ if ((nfs4_access_mask & NFS4_WRITE_MODE) == NFS4_WRITE_MODE) {
1652 ++ result = acl_add_perm(perms, ACL_WRITE);
1653 ++ if(result < 0)
1654 ++ goto failed;
1655 ++ }
1656 ++
1657 ++ if ((nfs4_access_mask & NFS4_EXECUTE_MODE) == NFS4_EXECUTE_MODE) {
1658 ++ result = acl_add_perm(perms, ACL_EXECUTE);
1659 ++ if(result < 0)
1660 ++ goto failed;
1661 ++ }
1662 ++
1663 ++ result = acl_ptn4_get_mask(&new_mask, perms, iflags);
1664 ++ if(result < 0)
1665 ++ goto failed;
1666 ++
1667 ++ new_mask |= ignore;
1668 ++
1669 ++ if (!MASK_EQUAL(nfs4_access_mask, new_mask)) {
1670 ++ errno = EINVAL;
1671 ++ goto failed;
1672 ++ }
1673 ++
1674 ++ result = acl_set_permset(pace, perms);
1675 ++ if(result < 0)
1676 ++ goto failed;
1677 ++
1678 ++ return 0;
1679 ++
1680 ++failed:
1681 ++ return -1;
1682 ++}
1683 ++
1684 +diff --git a/libacl/acl_n4tp_set_who.c b/libacl/acl_n4tp_set_who.c
1685 +new file mode 100644
1686 +index 0000000..241ef71
1687 +--- /dev/null
1688 ++++ b/libacl/acl_n4tp_set_who.c
1689 +@@ -0,0 +1,89 @@
1690 ++/*
1691 ++ * NFSv4 ACL Code
1692 ++ * Set the POSIX ACE who based on the whotype and NFS who attr.
1693 ++ * Translation is done using the NFS4 mapping functions.
1694 ++ *
1695 ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
1696 ++ * All rights reserved.
1697 ++ *
1698 ++ * Nathaniel Gallaher <ngallahe@×××××.edu>
1699 ++ *
1700 ++ * Redistribution and use in source and binary forms, with or without
1701 ++ * modification, are permitted provided that the following conditions
1702 ++ * are met:
1703 ++ *
1704 ++ * 1. Redistributions of source code must retain the above copyright
1705 ++ * notice, this list of conditions and the following disclaimer.
1706 ++ * 2. Redistributions in binary form must reproduce the above copyright
1707 ++ * notice, this list of conditions and the following disclaimer in the
1708 ++ * documentation and/or other materials provided with the distribution.
1709 ++ * 3. Neither the name of the University nor the names of its
1710 ++ * contributors may be used to endorse or promote products derived
1711 ++ * from this software without specific prior written permission.
1712 ++ *
1713 ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1714 ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1715 ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1716 ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1717 ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1718 ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1719 ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
1720 ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
1721 ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1722 ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1723 ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1724 ++ */
1725 ++
1726 ++#include <acl/libacl.h>
1727 ++#include <nfsidmap.h>
1728 ++#include "libacl_nfs4.h"
1729 ++
1730 ++#define PATH_IDMAPDCONF "/etc/idmapd.conf"
1731 ++char *conf_path = PATH_IDMAPDCONF;
1732 ++
1733 ++int acl_n4tp_set_who(acl_entry_t ace, char* who, acl_tag_t who_type)
1734 ++{
1735 ++ int result;
1736 ++ uid_t uid;
1737 ++ gid_t gid;
1738 ++
1739 ++ if(ace == NULL || who == NULL) {
1740 ++ errno = EINVAL;
1741 ++ goto failed;
1742 ++ }
1743 ++
1744 ++ switch(who_type) {
1745 ++ case ACL_USER:
1746 ++ result = nfs4_init_name_mapping(NULL);
1747 ++ if (result < 0)
1748 ++ goto failed;
1749 ++ result = nfs4_name_to_uid(who, &uid);
1750 ++ if(result < 0)
1751 ++ goto failed;
1752 ++ result = acl_set_qualifier(ace, (void *) &uid);
1753 ++ if(result < 0)
1754 ++ goto failed;
1755 ++ break;
1756 ++ case ACL_GROUP:
1757 ++ result = nfs4_init_name_mapping(NULL);
1758 ++ if (result < 0)
1759 ++ goto failed;
1760 ++ result = nfs4_name_to_gid(who, &gid);
1761 ++ if(result < 0)
1762 ++ goto failed;
1763 ++ result = acl_set_qualifier(ace, (void *) &gid);
1764 ++ if(result < 0)
1765 ++ goto failed;
1766 ++ break;
1767 ++ default:
1768 ++ errno = EINVAL;
1769 ++ goto failed;
1770 ++ }
1771 ++
1772 ++ return 0;
1773 ++
1774 ++failed:
1775 ++ return -1;
1776 ++}
1777 ++
1778 ++
1779 +diff --git a/libacl/acl_nfs4_add_ace.c b/libacl/acl_nfs4_add_ace.c
1780 +new file mode 100644
1781 +index 0000000..4c1ff9a
1782 +--- /dev/null
1783 ++++ b/libacl/acl_nfs4_add_ace.c
1784 +@@ -0,0 +1,83 @@
1785 ++/*
1786 ++ * NFSv4 ACL Code
1787 ++ * Add an ace to the acl
1788 ++ *
1789 ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
1790 ++ * All rights reserved.
1791 ++ *
1792 ++ * Marius Aamodt Eriksen <marius@×××××.edu>
1793 ++ * J. Bruce Fields <bfields@×××××.edu>
1794 ++ * Nathaniel Gallaher <ngallahe@×××××.edu>
1795 ++ * Jeff Sedlak <jsedlak@×××××.edu>
1796 ++ *
1797 ++ * Redistribution and use in source and binary forms, with or without
1798 ++ * modification, are permitted provided that the following conditions
1799 ++ * are met:
1800 ++ *
1801 ++ * 1. Redistributions of source code must retain the above copyright
1802 ++ * notice, this list of conditions and the following disclaimer.
1803 ++ * 2. Redistributions in binary form must reproduce the above copyright
1804 ++ * notice, this list of conditions and the following disclaimer in the
1805 ++ * documentation and/or other materials provided with the distribution.
1806 ++ * 3. Neither the name of the University nor the names of its
1807 ++ * contributors may be used to endorse or promote products derived
1808 ++ * from this software without specific prior written permission.
1809 ++ *
1810 ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1811 ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1812 ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1813 ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1814 ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1815 ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1816 ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
1817 ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
1818 ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1819 ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1820 ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1821 ++ */
1822 ++
1823 ++#include "libacl_nfs4.h"
1824 ++
1825 ++int
1826 ++acl_nfs4_add_ace(struct nfs4_acl *acl, u32 type, u32 flag, u32 access_mask,
1827 ++ int whotype, char* who)
1828 ++{
1829 ++ struct nfs4_ace *ace;
1830 ++ int result;
1831 ++
1832 ++ if(acl == NULL)
1833 ++ {
1834 ++ errno = EINVAL;
1835 ++ return -1;
1836 ++ }
1837 ++
1838 ++ if ((ace = malloc(sizeof(*ace))) == NULL)
1839 ++ {
1840 ++ errno = ENOMEM;
1841 ++ return -1;
1842 ++ }
1843 ++
1844 ++ ace->type = type;
1845 ++ ace->flag = flag;
1846 ++
1847 ++ if( type == NFS4_ACE_ACCESS_DENIED_ACE_TYPE )
1848 ++ access_mask = access_mask & ~(NFS4_ACE_MASK_IGNORE);
1849 ++
1850 ++
1851 ++ /* Castrate delete_child if we aren't a directory */
1852 ++ if (!acl->is_directory)
1853 ++ access_mask &= ~NFS4_ACE_DELETE_CHILD;
1854 ++
1855 ++
1856 ++ ace->access_mask = access_mask & NFS4_ACE_MASK_ALL;
1857 ++
1858 ++ result = acl_nfs4_set_who(ace, whotype, who);
1859 ++ if(result < 0)
1860 ++ return -1;
1861 ++
1862 ++ TAILQ_INSERT_TAIL(&acl->ace_head, ace, l_ace);
1863 ++ acl->naces++;
1864 ++
1865 ++ return 0;
1866 ++}
1867 ++
1868 +diff --git a/libacl/acl_nfs4_add_pair.c b/libacl/acl_nfs4_add_pair.c
1869 +new file mode 100644
1870 +index 0000000..d849fb9
1871 +--- /dev/null
1872 ++++ b/libacl/acl_nfs4_add_pair.c
1873 +@@ -0,0 +1,60 @@
1874 ++/*
1875 ++ * Add a pair of aces to the acl. The ace masks are complements of each other
1876 ++ * This keeps us from walking off the end of the acl
1877 ++ *
1878 ++ * Copyright (c) 2004 The Regents of the University of Michigan.
1879 ++ * All rights reserved.
1880 ++ *
1881 ++ * Marius Aamodt Eriksen <marius@×××××.edu>
1882 ++ * J. Bruce Fields <bfields@×××××.edu>
1883 ++ * Nathaniel Gallaher <ngallahe@×××××.edu>
1884 ++ * Jeff Sedlak <jsedlak@×××××.edu>
1885 ++ *
1886 ++ * Redistribution and use in source and binary forms, with or without
1887 ++ * modification, are permitted provided that the following conditions
1888 ++ * are met:
1889 ++ *
1890 ++ * 1. Redistributions of source code must retain the above copyright
1891 ++ * notice, this list of conditions, the following disclaimer, and
1892 ++ * any and all other licensing or copyright notices included in
1893 ++ * any files in this distribution.
1894 ++ * 2. Redistributions in binary form must reproduce the above copyright
1895 ++ * notice, this list of conditions and the following disclaimer in the
1896 ++ * documentation and/or other materials provided with the distribution.
1897 ++ * 3. Neither the name of the University nor the names of its
1898 ++ * contributors may be used to endorse or promote products derived
1899 ++ * from this software without specific prior written permission.
1900 ++ *
1901 ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1902 ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1903 ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1904 ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1905 ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1906 ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1907 ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
1908 ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
1909 ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1910 ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1911 ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1912 ++ *
1913 ++ */
1914 ++
1915 ++
1916 ++#include "libacl_nfs4.h"
1917 ++
1918 ++int
1919 ++acl_nfs4_add_pair(struct nfs4_acl *acl, int eflag, u32 mask, int ownertype,
1920 ++ char* owner)
1921 ++{
1922 ++ int error;
1923 ++
1924 ++ error = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE,
1925 ++ eflag, mask, ownertype, owner);
1926 ++ if (error < 0)
1927 ++ return error;
1928 ++ error = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE,
1929 ++ eflag, ~mask, ownertype, owner);
1930 ++ return error;
1931 ++}
1932 ++
1933 ++
1934 +diff --git a/libacl/acl_nfs4_copy_acl.c b/libacl/acl_nfs4_copy_acl.c
1935 +new file mode 100644
1936 +index 0000000..94d8a83
1937 +--- /dev/null
1938 ++++ b/libacl/acl_nfs4_copy_acl.c
1939 +@@ -0,0 +1,85 @@
1940 ++/*
1941 ++ * NFSv4 ACL Code
1942 ++ * Deep copy an NFS4 ACL
1943 ++ *
1944 ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
1945 ++ * All rights reserved.
1946 ++ *
1947 ++ * Nathaniel Gallaher <ngallahe@×××××.edu>
1948 ++ *
1949 ++ * Redistribution and use in source and binary forms, with or without
1950 ++ * modification, are permitted provided that the following conditions
1951 ++ * are met:
1952 ++ *
1953 ++ * 1. Redistributions of source code must retain the above copyright
1954 ++ * notice, this list of conditions and the following disclaimer.
1955 ++ * 2. Redistributions in binary form must reproduce the above copyright
1956 ++ * notice, this list of conditions and the following disclaimer in the
1957 ++ * documentation and/or other materials provided with the distribution.
1958 ++ * 3. Neither the name of the University nor the names of its
1959 ++ * contributors may be used to endorse or promote products derived
1960 ++ * from this software without specific prior written permission.
1961 ++ *
1962 ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1963 ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1964 ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1965 ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1966 ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1967 ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1968 ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
1969 ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
1970 ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1971 ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1972 ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1973 ++ */
1974 ++
1975 ++#include "libacl_nfs4.h"
1976 ++
1977 ++struct nfs4_acl * acl_nfs4_copy_acl(struct nfs4_acl * nacl)
1978 ++{
1979 ++ struct nfs4_acl * new_acl;
1980 ++ struct nfs4_ace * ace;
1981 ++ u32 nace;
1982 ++ u32 num_aces;
1983 ++ int result;
1984 ++
1985 ++ if(nacl == NULL) {
1986 ++ errno = EINVAL;
1987 ++ goto failed;
1988 ++ }
1989 ++
1990 ++ num_aces = nacl->naces;
1991 ++
1992 ++ new_acl = acl_nfs4_new(nacl->is_directory);
1993 ++ if(new_acl == NULL)
1994 ++ goto failed;
1995 ++
1996 ++ ace = acl_nfs4_get_first_ace(nacl);
1997 ++ nace = 1;
1998 ++
1999 ++ while(1)
2000 ++ {
2001 ++ if(ace == NULL) {
2002 ++ if(nace > num_aces)
2003 ++ break;
2004 ++ else
2005 ++ goto free_failed;
2006 ++ }
2007 ++
2008 ++ result = acl_nfs4_add_ace(new_acl, ace->type, ace->flag,
2009 ++ ace->access_mask, acl_nfs4_get_whotype(ace->who), ace->who);
2010 ++ if(result < 0)
2011 ++ goto free_failed;
2012 ++
2013 ++ acl_nfs4_get_next_ace(&ace);
2014 ++ nace++;
2015 ++ }
2016 ++
2017 ++ return new_acl;
2018 ++
2019 ++free_failed:
2020 ++ acl_nfs4_free(new_acl);
2021 ++
2022 ++failed:
2023 ++ return NULL;
2024 ++}
2025 +diff --git a/libacl/acl_nfs4_free.c b/libacl/acl_nfs4_free.c
2026 +new file mode 100644
2027 +index 0000000..9cab808
2028 +--- /dev/null
2029 ++++ b/libacl/acl_nfs4_free.c
2030 +@@ -0,0 +1,61 @@
2031 ++/*
2032 ++ * Copyright (c) 2004 The Regents of the University of Michigan.
2033 ++ * All rights reserved.
2034 ++ *
2035 ++ * Marius Aamodt Eriksen <marius@×××××.edu>
2036 ++ * J. Bruce Fields <bfields@×××××.edu>
2037 ++ * Nathaniel Gallaher <ngallahe@×××××.edu>
2038 ++ * Jeff Sedlak <jsedlak@×××××.edu>
2039 ++ *
2040 ++ * Redistribution and use in source and binary forms, with or without
2041 ++ * modification, are permitted provided that the following conditions
2042 ++ * are met:
2043 ++ *
2044 ++ * 1. Redistributions of source code must retain the above copyright
2045 ++ * notice, this list of conditions, the following disclaimer, and
2046 ++ * any and all other licensing or copyright notices included in
2047 ++ * any files in this distribution.
2048 ++ * 2. Redistributions in binary form must reproduce the above copyright
2049 ++ * notice, this list of conditions and the following disclaimer in the
2050 ++ * documentation and/or other materials provided with the distribution.
2051 ++ * 3. Neither the name of the University nor the names of its
2052 ++ * contributors may be used to endorse or promote products derived
2053 ++ * from this software without specific prior written permission.
2054 ++ *
2055 ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
2056 ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2057 ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2058 ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2059 ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2060 ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2061 ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
2062 ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2063 ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2064 ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2065 ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2066 ++ *
2067 ++ */
2068 ++
2069 ++#include "libacl_nfs4.h"
2070 ++
2071 ++void
2072 ++acl_nfs4_free(struct nfs4_acl *acl)
2073 ++{
2074 ++ struct nfs4_ace *ace;
2075 ++
2076 ++ if (!acl)
2077 ++ return;
2078 ++
2079 ++ while (!TAILQ_IS_EMPTY(acl->ace_head)) {
2080 ++ ace = (acl)->ace_head.tqh_first;
2081 ++
2082 ++ TAILQ_REMOVE( &(acl->ace_head), ace, l_ace);
2083 ++ free(ace->who);
2084 ++ free(ace);
2085 ++ }
2086 ++
2087 ++ free(acl);
2088 ++
2089 ++ return;
2090 ++}
2091 ++
2092 +diff --git a/libacl/acl_nfs4_get_who.c b/libacl/acl_nfs4_get_who.c
2093 +new file mode 100644
2094 +index 0000000..8c21b16
2095 +--- /dev/null
2096 ++++ b/libacl/acl_nfs4_get_who.c
2097 +@@ -0,0 +1,103 @@
2098 ++/*
2099 ++ * NFSv4 ACL Code
2100 ++ * Read the who value from the ace and return its type and optionally
2101 ++ * its value.
2102 ++ *
2103 ++ * Ace is a reference to the ace to extract the who value from.
2104 ++ * Type is a reference where the value of the whotype will be stored.
2105 ++ * Who is a double reference that should either be passed as NULL
2106 ++ * (and thus no who string will be returned) or as a pointer to a
2107 ++ * char* where the who string will be allocated. This string must be
2108 ++ * freed by the caller.
2109 ++ *
2110 ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
2111 ++ * All rights reserved.
2112 ++ *
2113 ++ * Nathaniel Gallaher <ngallahe@×××××.edu>
2114 ++ *
2115 ++ * Redistribution and use in source and binary forms, with or without
2116 ++ * modification, are permitted provided that the following conditions
2117 ++ * are met:
2118 ++ *
2119 ++ * 1. Redistributions of source code must retain the above copyright
2120 ++ * notice, this list of conditions and the following disclaimer.
2121 ++ * 2. Redistributions in binary form must reproduce the above copyright
2122 ++ * notice, this list of conditions and the following disclaimer in the
2123 ++ * documentation and/or other materials provided with the distribution.
2124 ++ * 3. Neither the name of the University nor the names of its
2125 ++ * contributors may be used to endorse or promote products derived
2126 ++ * from this software without specific prior written permission.
2127 ++ *
2128 ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
2129 ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2130 ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2131 ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2132 ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2133 ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2134 ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
2135 ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2136 ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2137 ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2138 ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2139 ++ */
2140 ++
2141 ++#include "libacl_nfs4.h"
2142 ++
2143 ++int acl_nfs4_get_who(struct nfs4_ace* ace, int* type, char** who)
2144 ++{
2145 ++ int itype;
2146 ++ char* iwho = NULL;
2147 ++ int wholen;
2148 ++
2149 ++ if(ace == NULL || ace->who == NULL)
2150 ++ goto inval_failed;
2151 ++
2152 ++ itype = acl_nfs4_get_whotype(ace->who);
2153 ++
2154 ++ if(type != NULL) {
2155 ++ *type = itype;
2156 ++ }
2157 ++
2158 ++
2159 ++ if(who == NULL)
2160 ++ return 0;
2161 ++
2162 ++ switch(itype)
2163 ++ {
2164 ++ case NFS4_ACL_WHO_NAMED:
2165 ++ iwho = ace->who;
2166 ++ break;
2167 ++ case NFS4_ACL_WHO_OWNER:
2168 ++ iwho = NFS4_ACL_WHO_OWNER_STRING;
2169 ++ break;
2170 ++ case NFS4_ACL_WHO_GROUP:
2171 ++ iwho = NFS4_ACL_WHO_GROUP_STRING;
2172 ++ break;
2173 ++ case NFS4_ACL_WHO_EVERYONE:
2174 ++ iwho = NFS4_ACL_WHO_EVERYONE_STRING;
2175 ++ break;
2176 ++ default:
2177 ++ goto inval_failed;
2178 ++ }
2179 ++
2180 ++ wholen = strlen(iwho);
2181 ++ if(wholen < 0)
2182 ++ goto inval_failed;
2183 ++
2184 ++ (*who) = (char *) malloc(sizeof(char) * (wholen + 1));
2185 ++ if((*who) == NULL) {
2186 ++ errno = ENOMEM;
2187 ++ goto failed;
2188 ++ }
2189 ++
2190 ++ strcpy((*who), iwho);
2191 ++
2192 ++ return 0;
2193 ++
2194 ++inval_failed:
2195 ++ errno = EINVAL;
2196 ++
2197 ++failed:
2198 ++ return -1;
2199 ++}
2200 ++
2201 +diff --git a/libacl/acl_nfs4_get_whotype.c b/libacl/acl_nfs4_get_whotype.c
2202 +new file mode 100644
2203 +index 0000000..10574f8
2204 +--- /dev/null
2205 ++++ b/libacl/acl_nfs4_get_whotype.c
2206 +@@ -0,0 +1,60 @@
2207 ++/*
2208 ++ * NFSv4 ACL Code
2209 ++ * Get the whotype of the who string passed
2210 ++ *
2211 ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
2212 ++ * All rights reserved.
2213 ++ *
2214 ++ * Marius Aamodt Eriksen <marius@×××××.edu>
2215 ++ * J. Bruce Fields <bfields@×××××.edu>
2216 ++ * Nathaniel Gallaher <ngallahe@×××××.edu>
2217 ++ * Jeff Sedlak <jsedlak@×××××.edu>
2218 ++ *
2219 ++ * Redistribution and use in source and binary forms, with or without
2220 ++ * modification, are permitted provided that the following conditions
2221 ++ * are met:
2222 ++ *
2223 ++ * 1. Redistributions of source code must retain the above copyright
2224 ++ * notice, this list of conditions and the following disclaimer.
2225 ++ * 2. Redistributions in binary form must reproduce the above copyright
2226 ++ * notice, this list of conditions and the following disclaimer in the
2227 ++ * documentation and/or other materials provided with the distribution.
2228 ++ * 3. Neither the name of the University nor the names of its
2229 ++ * contributors may be used to endorse or promote products derived
2230 ++ * from this software without specific prior written permission.
2231 ++ *
2232 ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
2233 ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2234 ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2235 ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2236 ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2237 ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2238 ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
2239 ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2240 ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2241 ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2242 ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2243 ++ */
2244 ++
2245 ++#include "libacl_nfs4.h"
2246 ++
2247 ++inline int
2248 ++acl_nfs4_get_whotype(char *p)
2249 ++{
2250 ++ if(0 == strcmp(p, NFS4_ACL_WHO_OWNER_STRING) &&
2251 ++ strlen(p) == strlen(NFS4_ACL_WHO_OWNER_STRING)) {
2252 ++ return NFS4_ACL_WHO_OWNER;
2253 ++ }
2254 ++ if(0 == strcmp(p, NFS4_ACL_WHO_GROUP_STRING) &&
2255 ++ strlen(p) == strlen(NFS4_ACL_WHO_GROUP_STRING)) {
2256 ++ return NFS4_ACL_WHO_GROUP;
2257 ++ }
2258 ++ if(0 == strcmp(p, NFS4_ACL_WHO_EVERYONE_STRING) &&
2259 ++ strlen(p) == strlen(NFS4_ACL_WHO_EVERYONE_STRING)) {
2260 ++ return NFS4_ACL_WHO_EVERYONE;
2261 ++ }
2262 ++
2263 ++ return NFS4_ACL_WHO_NAMED;
2264 ++}
2265 ++
2266 ++
2267 +diff --git a/libacl/acl_nfs4_new.c b/libacl/acl_nfs4_new.c
2268 +new file mode 100644
2269 +index 0000000..658a282
2270 +--- /dev/null
2271 ++++ b/libacl/acl_nfs4_new.c
2272 +@@ -0,0 +1,58 @@
2273 ++/*
2274 ++ * Common NFSv4 ACL handling code.
2275 ++ * Create a new NFSv4 ACL
2276 ++ *
2277 ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
2278 ++ * All rights reserved.
2279 ++ *
2280 ++ * Marius Aamodt Eriksen <marius@×××××.edu>
2281 ++ * J. Bruce Fields <bfields@×××××.edu>
2282 ++ * Nathaniel Gallaher <ngallahe@×××××.edu>
2283 ++ * Jeff Sedlak <jsedlak@×××××.edu>
2284 ++ *
2285 ++ * Redistribution and use in source and binary forms, with or without
2286 ++ * modification, are permitted provided that the following conditions
2287 ++ * are met:
2288 ++ *
2289 ++ * 1. Redistributions of source code must retain the above copyright
2290 ++ * notice, this list of conditions and the following disclaimer.
2291 ++ * 2. Redistributions in binary form must reproduce the above copyright
2292 ++ * notice, this list of conditions and the following disclaimer in the
2293 ++ * documentation and/or other materials provided with the distribution.
2294 ++ * 3. Neither the name of the University nor the names of its
2295 ++ * contributors may be used to endorse or promote products derived
2296 ++ * from this software without specific prior written permission.
2297 ++ *
2298 ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
2299 ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2300 ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2301 ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2302 ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2303 ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2304 ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
2305 ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2306 ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2307 ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2308 ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2309 ++ */
2310 ++
2311 ++
2312 ++
2313 ++#include "libacl_nfs4.h"
2314 ++
2315 ++struct nfs4_acl *
2316 ++acl_nfs4_new(u32 is_dir)
2317 ++{
2318 ++ struct nfs4_acl *acl;
2319 ++
2320 ++ if ((acl = malloc(sizeof(*acl))) == NULL)
2321 ++ return NULL;
2322 ++
2323 ++ acl->naces = 0;
2324 ++ acl->is_directory = is_dir;
2325 ++
2326 ++ TAILQ_INIT(&acl->ace_head);
2327 ++
2328 ++ return acl;
2329 ++}
2330 ++
2331 +diff --git a/libacl/acl_nfs4_remove_ace.c b/libacl/acl_nfs4_remove_ace.c
2332 +new file mode 100644
2333 +index 0000000..f7dbba2
2334 +--- /dev/null
2335 ++++ b/libacl/acl_nfs4_remove_ace.c
2336 +@@ -0,0 +1,48 @@
2337 ++/*
2338 ++ * NFSv4 ACL Code
2339 ++ * Remove an ace from an NFS4 ACL
2340 ++ *
2341 ++ * Copyright (c) 2004 The Regents of the University of Michigan.
2342 ++ * All rights reserved.
2343 ++ *
2344 ++ * Nathaniel Gallaher <ngallahe@×××××.edu>
2345 ++ *
2346 ++ * Redistribution and use in source and binary forms, with or without
2347 ++ * modification, are permitted provided that the following conditions
2348 ++ * are met:
2349 ++ *
2350 ++ * 1. Redistributions of source code must retain the above copyright
2351 ++ * notice, this list of conditions, the following disclaimer, and
2352 ++ * any and all other licensing or copyright notices included in
2353 ++ * any files in this distribution.
2354 ++ * 2. Redistributions in binary form must reproduce the above copyright
2355 ++ * notice, this list of conditions and the following disclaimer in the
2356 ++ * documentation and/or other materials provided with the distribution.
2357 ++ * 3. Neither the name of the University nor the names of its
2358 ++ * contributors may be used to endorse or promote products derived
2359 ++ * from this software without specific prior written permission.
2360 ++ *
2361 ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
2362 ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2363 ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2364 ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2365 ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2366 ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2367 ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
2368 ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2369 ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2370 ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2371 ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2372 ++ *
2373 ++ */
2374 ++
2375 ++#include "libacl_nfs4.h"
2376 ++
2377 ++void acl_nfs4_remove_ace(struct nfs4_acl * acl, struct nfs4_ace * ace)
2378 ++{
2379 ++ TAILQ_REMOVE(&acl->ace_head, ace, l_ace);
2380 ++ free(ace->who);
2381 ++ free(ace);
2382 ++ acl->naces--;
2383 ++}
2384 ++
2385 +diff --git a/libacl/acl_nfs4_set_who.c b/libacl/acl_nfs4_set_who.c
2386 +new file mode 100644
2387 +index 0000000..c0ddfa7
2388 +--- /dev/null
2389 ++++ b/libacl/acl_nfs4_set_who.c
2390 +@@ -0,0 +1,92 @@
2391 ++/*
2392 ++ * NFSv4 ACL Code
2393 ++ * Write the who entry in the nfs4 ace. Who is a user supplied buffer
2394 ++ * containing a named who entry (null terminated string) if type is
2395 ++ * set to NFS4_ACL_WHO_NAMED. Otherwise, the who buffer is not used.
2396 ++ * The user supplied who buffer must be freed by the caller.
2397 ++ *
2398 ++ * This code allocates the who buffer used in the ace. This must be freed
2399 ++ * upon ace removal by the ace_remove or acl_free.
2400 ++ *
2401 ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
2402 ++ * All rights reserved.
2403 ++ *
2404 ++ * Nathaniel Gallaher <ngallahe@×××××.edu>
2405 ++ *
2406 ++ * Redistribution and use in source and binary forms, with or without
2407 ++ * modification, are permitted provided that the following conditions
2408 ++ * are met:
2409 ++ *
2410 ++ * 1. Redistributions of source code must retain the above copyright
2411 ++ * notice, this list of conditions and the following disclaimer.
2412 ++ * 2. Redistributions in binary form must reproduce the above copyright
2413 ++ * notice, this list of conditions and the following disclaimer in the
2414 ++ * documentation and/or other materials provided with the distribution.
2415 ++ * 3. Neither the name of the University nor the names of its
2416 ++ * contributors may be used to endorse or promote products derived
2417 ++ * from this software without specific prior written permission.
2418 ++ *
2419 ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
2420 ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2421 ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2422 ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2423 ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2424 ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2425 ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
2426 ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2427 ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2428 ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2429 ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2430 ++ */
2431 ++
2432 ++#include "libacl_nfs4.h"
2433 ++
2434 ++int acl_nfs4_set_who(struct nfs4_ace* ace, int type, char* who)
2435 ++{
2436 ++ char* iwho = NULL;
2437 ++ int wholen;
2438 ++
2439 ++ if(ace == NULL)
2440 ++ goto inval_failed;
2441 ++
2442 ++ switch(type)
2443 ++ {
2444 ++ case NFS4_ACL_WHO_NAMED:
2445 ++ if(who == NULL)
2446 ++ goto inval_failed;
2447 ++ iwho = who;
2448 ++ break;
2449 ++ case NFS4_ACL_WHO_OWNER:
2450 ++ iwho = NFS4_ACL_WHO_OWNER_STRING;
2451 ++ break;
2452 ++ case NFS4_ACL_WHO_GROUP:
2453 ++ iwho = NFS4_ACL_WHO_GROUP_STRING;
2454 ++ break;
2455 ++ case NFS4_ACL_WHO_EVERYONE:
2456 ++ iwho = NFS4_ACL_WHO_EVERYONE_STRING;
2457 ++ break;
2458 ++ default:
2459 ++ goto inval_failed;
2460 ++ }
2461 ++
2462 ++ wholen = strlen(iwho);
2463 ++ if(wholen < 1)
2464 ++ goto inval_failed;
2465 ++
2466 ++ ace->who = (char *) malloc(sizeof(char) * (wholen + 1));
2467 ++ if(ace->who == NULL) {
2468 ++ errno = ENOMEM;
2469 ++ goto failed;
2470 ++ }
2471 ++
2472 ++ strcpy(ace->who, iwho);
2473 ++
2474 ++ return 0;
2475 ++
2476 ++inval_failed:
2477 ++ errno = EINVAL;
2478 ++
2479 ++failed:
2480 ++ return -1;
2481 ++}
2482 ++
2483 +diff --git a/libacl/acl_nfs4_utils.c b/libacl/acl_nfs4_utils.c
2484 +new file mode 100644
2485 +index 0000000..49238ee
2486 +--- /dev/null
2487 ++++ b/libacl/acl_nfs4_utils.c
2488 +@@ -0,0 +1,566 @@
2489 ++#include <acl/libacl.h>
2490 ++#include "libacl_nfs4.h"
2491 ++
2492 ++int user_obj_from_v4(struct nfs4_acl *n4acl, struct nfs4_ace **n4ace,
2493 ++ acl_t *pacl, int iflags)
2494 ++{
2495 ++ struct nfs4_ace *ace = *n4ace;
2496 ++ struct nfs4_ace *ace2;
2497 ++
2498 ++ if (ace == NULL)
2499 ++ goto inval_out;
2500 ++
2501 ++ if (pacl == NULL || *pacl == NULL)
2502 ++ goto inval_out;
2503 ++
2504 ++ if (acl_n4tp_get_whotype(ace) != ACL_USER_OBJ)
2505 ++ goto inval_out;
2506 ++
2507 ++ if(acl_n4tp_ace_trans(ace, pacl, ACL_USER_OBJ, iflags|NFS4_ACL_OWNER) < 0)
2508 ++ goto out;
2509 ++
2510 ++ ace2 = acl_nfs4_get_next_ace(n4ace);
2511 ++ if (ace2 == NULL)
2512 ++ goto inval_out;
2513 ++
2514 ++ if (!complementary_ace_pair(ace, ace2))
2515 ++ goto inval_out;
2516 ++
2517 ++ ace2 = acl_nfs4_get_next_ace(n4ace);
2518 ++
2519 ++ return 0;
2520 ++
2521 ++inval_out:
2522 ++ errno = EINVAL;
2523 ++out:
2524 ++ return -1;
2525 ++}
2526 ++
2527 ++/* public */
2528 ++inline struct nfs4_ace * acl_nfs4_get_next_ace(struct nfs4_ace ** ace)
2529 ++{
2530 ++ if(ace == NULL || (*ace) == NULL)
2531 ++ return NULL;
2532 ++
2533 ++ (*ace) = (*ace)->l_ace.tqe_next;
2534 ++ return *ace;
2535 ++}
2536 ++
2537 ++/* public */
2538 ++inline struct nfs4_ace * acl_nfs4_get_first_ace(struct nfs4_acl * acl)
2539 ++{
2540 ++ if(acl == NULL)
2541 ++ return NULL;
2542 ++
2543 ++ return acl->ace_head.tqh_first;
2544 ++}
2545 ++
2546 ++
2547 ++
2548 ++
2549 ++int nfs4_get_gid_from_who(gid_t* gid, const char * who)
2550 ++{
2551 ++ int islocal;
2552 ++ int result;
2553 ++
2554 ++ if(who == NULL || gid == NULL) {
2555 ++ errno = EINVAL;
2556 ++ goto failed;
2557 ++ }
2558 ++
2559 ++ islocal = is_who_local(who);
2560 ++ if(islocal < 0)
2561 ++ goto failed;
2562 ++ else if (islocal == 1)
2563 ++ result = __nfs4_get_local_gid_from_who(gid, who);
2564 ++ else
2565 ++ result = __nfs4_get_foreign_gid_from_who(gid, who);
2566 ++
2567 ++ if(result < 0)
2568 ++ goto failed;
2569 ++
2570 ++ return 0;
2571 ++
2572 ++failed:
2573 ++ return -1;
2574 ++}
2575 ++
2576 ++int __nfs4_get_local_gid_from_who(gid_t* gid, const char * who)
2577 ++{
2578 ++ /* XXX Just trim things at the @. We need to pull the local domain
2579 ++ * name from the conf file for comparison, and handle foriegn names
2580 ++ * as well. Tie this in with idmapd and gssvcd */
2581 ++ /* Special whos? */
2582 ++
2583 ++ struct group * grent;
2584 ++ char * gname_buf = NULL;
2585 ++ int gname_buflen;
2586 ++ char * char_pos = NULL;
2587 ++ int char_posi;
2588 ++
2589 ++
2590 ++ if(who == NULL) {
2591 ++ errno = EINVAL;
2592 ++ goto failed;
2593 ++ }
2594 ++
2595 ++ gname_buflen = strlen(who);
2596 ++ if(gname_buflen <= 0) {
2597 ++ errno = EINVAL;
2598 ++ goto failed;
2599 ++ }
2600 ++
2601 ++ char_pos = strchr(who, '@');
2602 ++ char_posi = char_pos - who;
2603 ++
2604 ++ if((gname_buf = (char*) malloc(sizeof(char) * (char_posi + 1))) == NULL)
2605 ++ {
2606 ++ errno = ENOMEM;
2607 ++ goto failed;
2608 ++ }
2609 ++
2610 ++ strncpy(gname_buf, who, char_posi);
2611 ++ gname_buf[char_posi] = '\0';
2612 ++
2613 ++ grent = getgrnam(gname_buf);
2614 ++ free(gname_buf);
2615 ++
2616 ++ if(grent == NULL)
2617 ++ goto failed;
2618 ++
2619 ++ *gid = grent->gr_gid;
2620 ++
2621 ++ return 0;
2622 ++
2623 ++failed:
2624 ++ return -1;
2625 ++}
2626 ++
2627 ++int __nfs4_get_foreign_gid_from_who(gid_t* gid, const char * who)
2628 ++{
2629 ++ return -1;
2630 ++}
2631 ++
2632 ++
2633 ++int nfs4_get_uid_from_who(uid_t* uid, const char * who)
2634 ++{
2635 ++ int islocal;
2636 ++ int result;
2637 ++
2638 ++ if(who == NULL || uid == NULL) {
2639 ++ errno = EINVAL;
2640 ++ goto failed;
2641 ++ }
2642 ++
2643 ++ islocal = is_who_local(who);
2644 ++ if(islocal < 0)
2645 ++ goto failed;
2646 ++ else if (islocal == 1)
2647 ++ result = __nfs4_get_local_uid_from_who(uid, who);
2648 ++ else
2649 ++ result = __nfs4_get_foreign_uid_from_who(uid, who);
2650 ++
2651 ++ if(result < 0)
2652 ++ goto failed;
2653 ++
2654 ++ return 0;
2655 ++
2656 ++failed:
2657 ++ return -1;
2658 ++}
2659 ++
2660 ++int __nfs4_get_local_uid_from_who(uid_t* uid, const char * who)
2661 ++{
2662 ++ /* XXX Just trim things at the @. We need to pull the local domain
2663 ++ * name from the conf file for comparison, and handle foriegn names
2664 ++ * as well. Tie this in with idmapd and gssvcd */
2665 ++ /* Special whos? */
2666 ++
2667 ++ char* lname_buf;
2668 ++ char* char_pos;
2669 ++ int lname_buflen;
2670 ++ struct passwd *pwent;
2671 ++ int char_posi;
2672 ++
2673 ++ if(who == NULL) {
2674 ++ errno = EINVAL;
2675 ++ goto failed;
2676 ++ }
2677 ++
2678 ++ lname_buflen = strlen(who);
2679 ++ if(lname_buflen <= 0) {
2680 ++ errno = EINVAL;
2681 ++ goto failed;
2682 ++ }
2683 ++
2684 ++ char_pos = strchr(who, '@');
2685 ++ char_posi = char_pos - who;
2686 ++
2687 ++ if((lname_buf = (char*) malloc(sizeof(char) * (char_posi + 1))) == NULL)
2688 ++ {
2689 ++ errno = ENOMEM;
2690 ++ goto failed;
2691 ++ }
2692 ++
2693 ++ strncpy(lname_buf, who, char_posi);
2694 ++ lname_buf[char_posi] = '\0';
2695 ++
2696 ++ pwent = getpwnam(lname_buf);
2697 ++ free(lname_buf);
2698 ++
2699 ++ if(pwent == NULL)
2700 ++ goto failed;
2701 ++
2702 ++ *uid = pwent->pw_uid;
2703 ++
2704 ++ return 0;
2705 ++
2706 ++failed:
2707 ++ return -1;
2708 ++}
2709 ++
2710 ++
2711 ++
2712 ++int is_who_local(const char * who)
2713 ++{
2714 ++ /* -1 on error, 0 for no, 1 for yes */
2715 ++ /* TODO: Compare domain to local domain */
2716 ++ if(who == NULL){
2717 ++ errno = EINVAL;
2718 ++ return -1;
2719 ++ }
2720 ++
2721 ++ if(strchr(who, '@') == NULL) {
2722 ++ errno = EINVAL;
2723 ++ return -1;
2724 ++ }
2725 ++
2726 ++ return 1;
2727 ++}
2728 ++
2729 ++int __nfs4_get_foreign_uid_from_who(uid_t* uid, const char * who)
2730 ++{
2731 ++ /* TODO: Make this work */
2732 ++ return -1;
2733 ++}
2734 ++
2735 ++
2736 ++
2737 ++int users_from_v4(struct nfs4_acl *n4acl, struct nfs4_ace ** n4ace_p,
2738 ++ struct nfs4_ace **mask_ace, acl_t *pacl, int iflags)
2739 ++{
2740 ++ struct nfs4_ace *ace, *ace2;
2741 ++ int result;
2742 ++
2743 ++ ace = *n4ace_p;
2744 ++
2745 ++ if (ace == NULL) {
2746 ++ goto inval_failed;
2747 ++ }
2748 ++
2749 ++ while (ace != NULL && acl_n4tp_get_whotype(ace) == ACL_USER) {
2750 ++ if (ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE)
2751 ++ goto inval_failed;
2752 ++ if (*mask_ace &&
2753 ++ !MASK_EQUAL(ace->access_mask, (*mask_ace)->access_mask))
2754 ++ goto inval_failed;
2755 ++ *mask_ace = ace;
2756 ++
2757 ++ ace = acl_nfs4_get_next_ace(n4ace_p);
2758 ++ if (ace == NULL)
2759 ++ goto inval_failed;
2760 ++ if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE)
2761 ++ goto inval_failed;
2762 ++ result = acl_n4tp_ace_trans(ace, pacl, ACL_USER, iflags);
2763 ++ if (result < 0)
2764 ++ goto failed;
2765 ++
2766 ++ ace2 = acl_nfs4_get_next_ace(n4ace_p);
2767 ++ if (ace2 == NULL)
2768 ++ goto failed;
2769 ++ if (!complementary_ace_pair(ace, ace2))
2770 ++ goto failed;
2771 ++ if ((*mask_ace)->flag != ace2->flag ||
2772 ++ !same_who(*mask_ace, ace2))
2773 ++ goto failed;
2774 ++ ace = acl_nfs4_get_next_ace(n4ace_p);
2775 ++ }
2776 ++
2777 ++ return 0;
2778 ++
2779 ++inval_failed:
2780 ++ errno = EINVAL;
2781 ++
2782 ++failed:
2783 ++ return -1;
2784 ++}
2785 ++
2786 ++int complementary_ace_pair(struct nfs4_ace *allow, struct nfs4_ace *deny)
2787 ++{
2788 ++ return MASK_EQUAL(allow->access_mask, ~deny->access_mask) &&
2789 ++ allow->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE &&
2790 ++ deny->type == NFS4_ACE_ACCESS_DENIED_ACE_TYPE &&
2791 ++ allow->flag == deny->flag &&
2792 ++ same_who(allow, deny);
2793 ++}
2794 ++
2795 ++int same_who(struct nfs4_ace *a, struct nfs4_ace *b)
2796 ++{
2797 ++ if(!strcmp(a->who, b->who) && strlen(a->who) == strlen(b->who))
2798 ++ return 1;
2799 ++ return 0;
2800 ++}
2801 ++
2802 ++int group_obj_and_groups_from_v4(struct nfs4_acl *n4acl,
2803 ++ struct nfs4_ace ** n4ace_p, struct nfs4_ace **mask_ace,
2804 ++ acl_t *pacl, int iflags)
2805 ++{
2806 ++ struct nfs4_ace *ace, *ace2;
2807 ++ int num_aces;
2808 ++ struct ace_container_list_head ace_list;
2809 ++ struct ace_container *ace_c = NULL;
2810 ++ int result;
2811 ++
2812 ++ TAILQ_INIT(&ace_list);
2813 ++
2814 ++ ace = *n4ace_p;
2815 ++
2816 ++ num_aces = acl_n4tp_ace_count(n4acl);
2817 ++
2818 ++ if(num_aces < 0)
2819 ++ goto inval_failed;
2820 ++
2821 ++ /* group owner (mask and allow aces) */
2822 ++
2823 ++ if (num_aces != 3) {
2824 ++ /* then the group owner should be preceded by mask */
2825 ++ if (ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE)
2826 ++ goto inval_failed;
2827 ++
2828 ++ /* If we already got a mask, and it doesn't match this one... */
2829 ++ if (*mask_ace &&
2830 ++ !MASK_EQUAL(ace->access_mask, (*mask_ace)->access_mask))
2831 ++ goto inval_failed;
2832 ++ *mask_ace = ace;
2833 ++ ace = acl_nfs4_get_next_ace(n4ace_p);
2834 ++ if (ace == NULL)
2835 ++ goto inval_failed;
2836 ++
2837 ++ if ((*mask_ace)->flag != ace->flag || !same_who(*mask_ace, ace))
2838 ++ goto inval_failed;
2839 ++ }
2840 ++
2841 ++ if (acl_n4tp_get_whotype(ace) != ACL_GROUP_OBJ)
2842 ++ goto inval_failed;
2843 ++
2844 ++ if((ace_c = malloc(sizeof(struct ace_container))) == NULL) {
2845 ++ errno = ENOMEM;
2846 ++ goto failed;
2847 ++ }
2848 ++ ace_c->ace = ace;
2849 ++
2850 ++ TAILQ_INSERT_TAIL(&ace_list, ace_c, l_ace);
2851 ++
2852 ++ if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE)
2853 ++ goto inval_failed;
2854 ++
2855 ++ result = acl_n4tp_ace_trans(ace, pacl, ACL_GROUP_OBJ, iflags);
2856 ++ if (result < 0)
2857 ++ goto inval_failed;
2858 ++
2859 ++ ace = acl_nfs4_get_next_ace(n4ace_p);
2860 ++ if (ace == NULL)
2861 ++ goto inval_failed;
2862 ++
2863 ++ /* groups (mask and allow aces) */
2864 ++
2865 ++ while (acl_n4tp_get_whotype(ace) == ACL_GROUP) {
2866 ++ if (*mask_ace == NULL)
2867 ++ goto inval_failed;
2868 ++
2869 ++ if (ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE ||
2870 ++ !MASK_EQUAL(ace->access_mask, (*mask_ace)->access_mask))
2871 ++ goto inval_failed;
2872 ++ *mask_ace = ace;
2873 ++
2874 ++ ace = acl_nfs4_get_next_ace(n4ace_p);
2875 ++ if (ace == NULL)
2876 ++ goto inval_failed;
2877 ++
2878 ++ if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE ||
2879 ++ !same_who(ace, *mask_ace))
2880 ++ goto inval_failed;
2881 ++
2882 ++ if((ace_c = malloc(sizeof(struct ace_container))) == NULL) {
2883 ++ errno = ENOMEM;
2884 ++ goto failed;
2885 ++ }
2886 ++ ace_c->ace = ace;
2887 ++
2888 ++ TAILQ_INSERT_TAIL(&ace_list, ace_c, l_ace);
2889 ++
2890 ++ result = acl_n4tp_ace_trans(ace, pacl, ACL_GROUP, iflags);
2891 ++ if (result < 0)
2892 ++ goto inval_failed;
2893 ++
2894 ++ ace = acl_nfs4_get_next_ace(n4ace_p);
2895 ++ if (ace == NULL)
2896 ++ goto inval_failed;
2897 ++ }
2898 ++
2899 ++ /* group owner (deny ace) */
2900 ++
2901 ++ if (acl_n4tp_get_whotype(ace) != ACL_GROUP_OBJ)
2902 ++ goto inval_failed;
2903 ++
2904 ++ ace_c = ace_list.tqh_first;
2905 ++ ace2 = ace_c->ace;
2906 ++ if (!complementary_ace_pair(ace2, ace))
2907 ++ goto inval_failed;
2908 ++ TAILQ_REMOVE(&ace_list, ace_c, l_ace);
2909 ++ free(ace_c);
2910 ++
2911 ++ /* groups (deny aces) */
2912 ++
2913 ++ while (!TAILQ_IS_EMPTY(ace_list)) {
2914 ++ ace = acl_nfs4_get_next_ace(n4ace_p);
2915 ++ if (ace == NULL)
2916 ++ goto inval_failed;
2917 ++ if (acl_n4tp_get_whotype(ace) != ACL_GROUP)
2918 ++ goto inval_failed;
2919 ++ ace_c = ace_list.tqh_first;
2920 ++ ace2 = ace_c->ace;
2921 ++ if (!complementary_ace_pair(ace2, ace))
2922 ++ goto inval_failed;
2923 ++ TAILQ_REMOVE(&ace_list, ace_c, l_ace);
2924 ++ free(ace_c);
2925 ++ }
2926 ++
2927 ++ ace = acl_nfs4_get_next_ace(n4ace_p);
2928 ++ if (ace == NULL)
2929 ++ goto inval_failed;
2930 ++ if (acl_n4tp_get_whotype(ace) != ACL_OTHER)
2931 ++ goto inval_failed;
2932 ++
2933 ++ return 0;
2934 ++
2935 ++inval_failed:
2936 ++ errno = EINVAL;
2937 ++
2938 ++failed:
2939 ++ while (!TAILQ_IS_EMPTY(ace_list)) {
2940 ++ ace_c = ace_list.tqh_first;
2941 ++ TAILQ_REMOVE(&ace_list, ace_c, l_ace);
2942 ++ free(ace_c);
2943 ++ }
2944 ++ return -1;
2945 ++}
2946 ++
2947 ++int
2948 ++other_from_v4(struct nfs4_acl *n4acl,
2949 ++ struct nfs4_ace ** n4ace_p, acl_t *pacl, int iflags)
2950 ++{
2951 ++ int result;
2952 ++ struct nfs4_ace *ace, *ace2;
2953 ++
2954 ++ ace = *n4ace_p;
2955 ++ if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE)
2956 ++ goto inval_failed;
2957 ++
2958 ++ result = acl_n4tp_ace_trans(ace, pacl, ACL_OTHER, iflags);
2959 ++ if (result < 0)
2960 ++ goto failed;
2961 ++
2962 ++ ace2 = acl_nfs4_get_next_ace(n4ace_p);
2963 ++ if (ace2 == NULL)
2964 ++ goto inval_failed;
2965 ++
2966 ++ if (!complementary_ace_pair(ace, ace2))
2967 ++ goto inval_failed;
2968 ++
2969 ++ return 0;
2970 ++
2971 ++inval_failed:
2972 ++ errno = EINVAL;
2973 ++
2974 ++failed:
2975 ++ return -1;
2976 ++}
2977 ++
2978 ++int mask_from_v4(struct nfs4_acl *n4acl,
2979 ++ struct nfs4_ace ** n4ace_p, struct nfs4_ace **mask_ace,
2980 ++ acl_t *pacl, int iflags)
2981 ++{
2982 ++ int result;
2983 ++ struct nfs4_ace *ace;
2984 ++
2985 ++ ace = *n4ace_p;
2986 ++ if (acl_n4tp_ace_count(n4acl) != 3) {
2987 ++ if (*mask_ace == NULL)
2988 ++ goto inval_failed;
2989 ++ (*mask_ace)->access_mask = ~(*mask_ace)->access_mask;
2990 ++
2991 ++ result = acl_n4tp_ace_trans(*mask_ace, pacl, ACL_MASK, iflags);
2992 ++ if(result < 0)
2993 ++ goto failed;
2994 ++
2995 ++ //ace = acl_nfs4_get_next_ace(n4ace_p);
2996 ++ //if (ace == NULL)
2997 ++ // goto inval_failed;
2998 ++ }
2999 ++
3000 ++ return 0;
3001 ++
3002 ++inval_failed:
3003 ++ errno = EINVAL;
3004 ++
3005 ++failed:
3006 ++ return -1;
3007 ++}
3008 ++
3009 ++
3010 ++/*
3011 ++static inline int
3012 ++match_who(struct nfs4_ace *ace, uid_t owner, gid_t group, uid_t who)
3013 ++{
3014 ++ switch (ace->whotype) {
3015 ++ case NFS4_ACL_WHO_NAMED:
3016 ++ return who == ace->who;
3017 ++ case NFS4_ACL_WHO_OWNER:
3018 ++ return who == owner;
3019 ++ case NFS4_ACL_WHO_GROUP:
3020 ++ return who == group;
3021 ++ case NFS4_ACL_WHO_EVERYONE:
3022 ++ return 1;
3023 ++ default:
3024 ++ return 0;
3025 ++ }
3026 ++}
3027 ++*/
3028 ++/* 0 = granted, -EACCES = denied; mask is an nfsv4 mask, not mode bits */
3029 ++/*
3030 ++int
3031 ++nfs4_acl_permission(struct nfs4_acl *acl, uid_t owner, gid_t group,
3032 ++ uid_t who, u32 mask)
3033 ++{
3034 ++ struct nfs4_ace *ace;
3035 ++ u32 allowed = 0;
3036 ++
3037 ++ list_for_each_entry(ace, &acl->ace_head, l_ace) {
3038 ++ if (!match_who(ace, group, owner, who))
3039 ++ continue;
3040 ++ switch (ace->type) {
3041 ++ case NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE:
3042 ++ allowed |= ace->access_mask;
3043 ++ if ((allowed & mask) == mask)
3044 ++ return 0;
3045 ++ break;
3046 ++ case NFS4_ACE_ACCESS_DENIED_ACE_TYPE:
3047 ++ if (ace->access_mask & mask)
3048 ++ return -EACCES;
3049 ++ break;
3050 ++ }
3051 ++ }
3052 ++ return -EACCES;
3053 ++}
3054 ++*/
3055 +diff --git a/libacl/acl_nfs4_xattr_load.c b/libacl/acl_nfs4_xattr_load.c
3056 +new file mode 100644
3057 +index 0000000..e045cd2
3058 +--- /dev/null
3059 ++++ b/libacl/acl_nfs4_xattr_load.c
3060 +@@ -0,0 +1,191 @@
3061 ++/*
3062 ++ * NFSv4 ACL Code
3063 ++ * Convert NFSv4 xattr values to a posix ACL
3064 ++ *
3065 ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
3066 ++ * All rights reserved.
3067 ++ *
3068 ++ * Nathaniel Gallaher <ngallahe@×××××.edu>
3069 ++ *
3070 ++ * Redistribution and use in source and binary forms, with or without
3071 ++ * modification, are permitted provided that the following conditions
3072 ++ * are met:
3073 ++ *
3074 ++ * 1. Redistributions of source code must retain the above copyright
3075 ++ * notice, this list of conditions and the following disclaimer.
3076 ++ * 2. Redistributions in binary form must reproduce the above copyright
3077 ++ * notice, this list of conditions and the following disclaimer in the
3078 ++ * documentation and/or other materials provided with the distribution.
3079 ++ * 3. Neither the name of the University nor the names of its
3080 ++ * contributors may be used to endorse or promote products derived
3081 ++ * from this software without specific prior written permission.
3082 ++ *
3083 ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
3084 ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
3085 ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3086 ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
3087 ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
3088 ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
3089 ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
3090 ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
3091 ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3092 ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3093 ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3094 ++ */
3095 ++
3096 ++
3097 ++#include <acl/libacl.h>
3098 ++#include <netinet/in.h>
3099 ++#include "libacl_nfs4.h"
3100 ++
3101 ++
3102 ++struct nfs4_acl * acl_nfs4_xattr_load(
3103 ++ char * xattr_v,
3104 ++ int xattr_size,
3105 ++ u32 is_dir)
3106 ++{
3107 ++ struct nfs4_acl * nacl_p;
3108 ++ char* bufp = xattr_v;
3109 ++ int bufs = xattr_size;
3110 ++ u32 ace_n;
3111 ++ u32 wholen;
3112 ++ char* who;
3113 ++ int d_ptr;
3114 ++ u32 num_aces;
3115 ++
3116 ++ u32 type, flag, access_mask;
3117 ++
3118 ++ if(xattr_size < sizeof(u32)) {
3119 ++ errno = EINVAL;
3120 ++ return NULL;
3121 ++ }
3122 ++
3123 ++ if((nacl_p = acl_nfs4_new(is_dir)) == NULL) {
3124 ++ errno = ENOMEM;
3125 ++ return NULL;
3126 ++ }
3127 ++
3128 ++ /* Grab the number of aces in the acl */
3129 ++ num_aces = (u32)ntohl(*((u32*)(bufp)));
3130 ++
3131 ++#ifdef LIBACL_NFS4_DEBUG
3132 ++ printf(" Got number of aces: %d\n", nacl_p->naces);
3133 ++#endif
3134 ++
3135 ++
3136 ++ d_ptr = sizeof(u32);
3137 ++ bufp += d_ptr;
3138 ++ bufs -= d_ptr;
3139 ++
3140 ++ for(ace_n = 0; num_aces > ace_n ; ace_n++)
3141 ++ {
3142 ++#ifdef LIBACL_NFS4_DEBUG
3143 ++ printf(" Getting Ace #%d of %d\n", ace_n, num_aces);
3144 ++#endif
3145 ++ /* Get the acl type */
3146 ++ if(bufs <= 0) {
3147 ++ errno = EINVAL;
3148 ++ goto bad_xattr_val;
3149 ++ }
3150 ++
3151 ++ type = (u32)ntohl(*((u32*)bufp));
3152 ++#ifdef LIBACL_NFS4_DEBUG
3153 ++ printf(" Type: %x\n", type);
3154 ++#endif
3155 ++
3156 ++ d_ptr = sizeof(u32);
3157 ++ bufp += d_ptr;
3158 ++ bufs -= d_ptr;
3159 ++
3160 ++ /* Get the acl flag */
3161 ++ if(bufs <= 0) {
3162 ++ errno = EINVAL;
3163 ++ goto bad_xattr_val;
3164 ++ }
3165 ++
3166 ++ flag = (u32)ntohl(*((u32*)bufp));
3167 ++#ifdef LIBACL_NFS4_DEBUG
3168 ++ printf(" Flag: %x\n", flag);
3169 ++#endif
3170 ++
3171 ++ bufp += d_ptr;
3172 ++ bufs -= d_ptr;
3173 ++
3174 ++ /* Get the access mask */
3175 ++
3176 ++ if(bufs <= 0) {
3177 ++ errno = EINVAL;
3178 ++ goto bad_xattr_val;
3179 ++ }
3180 ++
3181 ++ access_mask = (u32)ntohl(*((u32*)bufp));
3182 ++#ifdef LIBACL_NFS4_DEBUG
3183 ++ printf(" Access Mask: %x\n", access_mask);
3184 ++#endif
3185 ++
3186 ++ bufp += d_ptr;
3187 ++ bufs -= d_ptr;
3188 ++
3189 ++ /* Get the who string length*/
3190 ++ if(bufs <= 0) {
3191 ++ errno = EINVAL;
3192 ++ goto bad_xattr_val;
3193 ++ }
3194 ++
3195 ++ wholen = (u32)ntohl(*((u32*)bufp));
3196 ++#ifdef LIBACL_NFS4_DEBUG
3197 ++ printf(" Wholen: %d\n", wholen);
3198 ++#endif
3199 ++
3200 ++ bufp += d_ptr;
3201 ++ bufs -= d_ptr;
3202 ++
3203 ++ /* Get the who string */
3204 ++ if(bufs <= 0) {
3205 ++ errno = EINVAL;
3206 ++ goto bad_xattr_val;
3207 ++ }
3208 ++
3209 ++ who = (char *) malloc((wholen+1) * sizeof(char));
3210 ++ if(who == NULL)
3211 ++ {
3212 ++ errno = ENOMEM;
3213 ++ goto bad_xattr_val;
3214 ++ }
3215 ++
3216 ++ memcpy(who, bufp, wholen);
3217 ++
3218 ++ who[wholen] = '\0';
3219 ++
3220 ++#ifdef LIBACL_NFS4_DEBUG
3221 ++ printf(" Who: %s\n", who);
3222 ++#endif
3223 ++
3224 ++ d_ptr = ((wholen / sizeof(u32))*sizeof(u32));
3225 ++ if(wholen % sizeof(u32) != 0)
3226 ++ d_ptr += sizeof(u32);
3227 ++
3228 ++ bufp += d_ptr;
3229 ++ bufs -= d_ptr;
3230 ++
3231 ++ /* Make sure we aren't outside our domain */
3232 ++ if(bufs < 0) {
3233 ++ free(who);
3234 ++ goto bad_xattr_val;
3235 ++ }
3236 ++
3237 ++ if(acl_nfs4_add_ace(nacl_p, type, flag, access_mask, acl_nfs4_get_whotype(who), who) < 0) {
3238 ++ free(who);
3239 ++ goto bad_xattr_val;
3240 ++ }
3241 ++
3242 ++ free(who);
3243 ++ }
3244 ++
3245 ++ return nacl_p;
3246 ++
3247 ++bad_xattr_val:
3248 ++ /* We bailed for some reason */
3249 ++ acl_nfs4_free(nacl_p);
3250 ++ return NULL;
3251 ++}
3252 +diff --git a/libacl/acl_nfs4_xattr_pack.c b/libacl/acl_nfs4_xattr_pack.c
3253 +new file mode 100644
3254 +index 0000000..be92ba4
3255 +--- /dev/null
3256 ++++ b/libacl/acl_nfs4_xattr_pack.c
3257 +@@ -0,0 +1,148 @@
3258 ++/*
3259 ++ * NFSv4 ACL Code
3260 ++ * Pack an NFS4 ACL into an XDR encoded buffer.
3261 ++ *
3262 ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
3263 ++ * All rights reserved.
3264 ++ *
3265 ++ * Nathaniel Gallaher <ngallahe@×××××.edu>
3266 ++ *
3267 ++ * Redistribution and use in source and binary forms, with or without
3268 ++ * modification, are permitted provided that the following conditions
3269 ++ * are met:
3270 ++ *
3271 ++ * 1. Redistributions of source code must retain the above copyright
3272 ++ * notice, this list of conditions and the following disclaimer.
3273 ++ * 2. Redistributions in binary form must reproduce the above copyright
3274 ++ * notice, this list of conditions and the following disclaimer in the
3275 ++ * documentation and/or other materials provided with the distribution.
3276 ++ * 3. Neither the name of the University nor the names of its
3277 ++ * contributors may be used to endorse or promote products derived
3278 ++ * from this software without specific prior written permission.
3279 ++ *
3280 ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
3281 ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
3282 ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3283 ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
3284 ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
3285 ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
3286 ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
3287 ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
3288 ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3289 ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3290 ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3291 ++ */
3292 ++
3293 ++#include <libacl_nfs4.h>
3294 ++#include <netinet/in.h>
3295 ++
3296 ++int acl_nfs4_xattr_pack(struct nfs4_acl * acl, char** bufp)
3297 ++{
3298 ++ struct nfs4_ace * ace;
3299 ++ int buflen;
3300 ++ int rbuflen;
3301 ++ int num_aces;
3302 ++ int ace_num;
3303 ++ int wholen;
3304 ++ int result;
3305 ++ char* p;
3306 ++ char* who;
3307 ++
3308 ++ if(acl == NULL || bufp == NULL)
3309 ++ {
3310 ++ errno = EINVAL;
3311 ++ goto failed;
3312 ++ }
3313 ++
3314 ++ buflen = acl_nfs4_xattr_size(acl);
3315 ++ if(buflen < 0)
3316 ++ {
3317 ++ goto failed;
3318 ++ }
3319 ++
3320 ++ *bufp = (char*) malloc(buflen);
3321 ++ if(*bufp == NULL) {
3322 ++ errno = ENOMEM;
3323 ++ goto failed;
3324 ++ }
3325 ++
3326 ++ p = *bufp;
3327 ++
3328 ++ num_aces = acl->naces;
3329 ++
3330 ++ *((u32*)p) = htonl(num_aces);
3331 ++
3332 ++ rbuflen = sizeof(u32);
3333 ++ p += sizeof(u32);
3334 ++
3335 ++ ace = acl_nfs4_get_first_ace(acl);
3336 ++ ace_num = 1;
3337 ++
3338 ++ while(1)
3339 ++ {
3340 ++ if(ace == NULL)
3341 ++ {
3342 ++ if(ace_num > num_aces) {
3343 ++ break;
3344 ++ } else {
3345 ++ errno = ENODATA;
3346 ++ goto failed;
3347 ++ }
3348 ++ }
3349 ++
3350 ++ *((u32*)p) = htonl(ace->type);
3351 ++ p += sizeof(u32);
3352 ++ rbuflen += sizeof(u32);
3353 ++
3354 ++ *((u32*)p) = htonl(ace->flag);
3355 ++ p += sizeof(u32);
3356 ++ rbuflen += sizeof(u32);
3357 ++
3358 ++ *((u32*)p) = htonl(ace->access_mask);
3359 ++ p += sizeof(u32);
3360 ++ rbuflen += sizeof(u32);
3361 ++
3362 ++ result = acl_nfs4_get_who(ace, NULL, &who);
3363 ++ if(result < 0) {
3364 ++ goto free_failed;
3365 ++ }
3366 ++
3367 ++ wholen = strlen(who);
3368 ++ *((u32*)p) = htonl(wholen);
3369 ++ rbuflen += sizeof(u32);
3370 ++
3371 ++ p += sizeof(u32);
3372 ++
3373 ++ memcpy(p, who, wholen);
3374 ++ free(who);
3375 ++
3376 ++ p += (wholen / NFS4_XDR_MOD) * NFS4_XDR_MOD;
3377 ++ if(wholen % NFS4_XDR_MOD) {
3378 ++ p += NFS4_XDR_MOD;
3379 ++ }
3380 ++
3381 ++ rbuflen += (wholen / NFS4_XDR_MOD) * NFS4_XDR_MOD;
3382 ++ if(wholen % NFS4_XDR_MOD) {
3383 ++ rbuflen += NFS4_XDR_MOD;
3384 ++ }
3385 ++
3386 ++ acl_nfs4_get_next_ace(&ace);
3387 ++ ace_num++;
3388 ++ }
3389 ++
3390 ++ if (buflen != rbuflen)
3391 ++ {
3392 ++ goto free_failed;
3393 ++ }
3394 ++ return buflen;
3395 ++
3396 ++free_failed:
3397 ++ free(*bufp);
3398 ++ *bufp = NULL;
3399 ++
3400 ++failed:
3401 ++ return -1;
3402 ++}
3403 ++
3404 ++
3405 ++
3406 +diff --git a/libacl/acl_nfs4_xattr_size.c b/libacl/acl_nfs4_xattr_size.c
3407 +new file mode 100644
3408 +index 0000000..3719535
3409 +--- /dev/null
3410 ++++ b/libacl/acl_nfs4_xattr_size.c
3411 +@@ -0,0 +1,91 @@
3412 ++/*
3413 ++ * NFSv4 ACL Code
3414 ++ * Return the expected xattr XDR encoded size of the nfs acl. Used for
3415 ++ * figuring the size of the xattr buffer.
3416 ++ *
3417 ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
3418 ++ * All rights reserved.
3419 ++ *
3420 ++ * Nathaniel Gallaher <ngallahe@×××××.edu>
3421 ++ *
3422 ++ * Redistribution and use in source and binary forms, with or without
3423 ++ * modification, are permitted provided that the following conditions
3424 ++ * are met:
3425 ++ *
3426 ++ * 1. Redistributions of source code must retain the above copyright
3427 ++ * notice, this list of conditions and the following disclaimer.
3428 ++ * 2. Redistributions in binary form must reproduce the above copyright
3429 ++ * notice, this list of conditions and the following disclaimer in the
3430 ++ * documentation and/or other materials provided with the distribution.
3431 ++ * 3. Neither the name of the University nor the names of its
3432 ++ * contributors may be used to endorse or promote products derived
3433 ++ * from this software without specific prior written permission.
3434 ++ *
3435 ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
3436 ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
3437 ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3438 ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
3439 ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
3440 ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
3441 ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
3442 ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
3443 ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3444 ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3445 ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3446 ++ */
3447 ++
3448 ++#include <libacl_nfs4.h>
3449 ++
3450 ++int acl_nfs4_xattr_size(struct nfs4_acl * acl)
3451 ++{
3452 ++ int size = 0;
3453 ++ struct nfs4_ace * ace;
3454 ++ int ace_num;
3455 ++ int num_aces;
3456 ++
3457 ++ if(acl == NULL) {
3458 ++ errno = EINVAL;
3459 ++ goto failed;
3460 ++ }
3461 ++
3462 ++ /* Space for number of aces */
3463 ++ size += sizeof(u32);
3464 ++
3465 ++ ace = acl_nfs4_get_first_ace(acl);
3466 ++ ace_num = 1;
3467 ++
3468 ++ num_aces = acl->naces;
3469 ++
3470 ++ while(1)
3471 ++ {
3472 ++ if(ace == NULL) {
3473 ++ if(ace_num > num_aces) {
3474 ++ break;
3475 ++ } else {
3476 ++ errno = ENODATA;
3477 ++ goto failed;
3478 ++ }
3479 ++ }
3480 ++
3481 ++ /* space for type, flag, and mask */
3482 ++ size += (3 * sizeof(u32));
3483 ++
3484 ++ /* space for strlen */
3485 ++ size += sizeof(u32);
3486 ++
3487 ++ /* space for the who string... xdr encoded */
3488 ++ size += (strlen(ace->who) / NFS4_XDR_MOD) * NFS4_XDR_MOD * sizeof(char);
3489 ++ if(strlen(ace->who) % NFS4_XDR_MOD) {
3490 ++ size += NFS4_XDR_MOD;
3491 ++ }
3492 ++
3493 ++ acl_nfs4_get_next_ace(&ace);
3494 ++ ace_num++;
3495 ++ }
3496 ++
3497 ++ return size;
3498 ++
3499 ++failed:
3500 ++ return -1;
3501 ++}
3502 ++
3503 +diff --git a/libacl/acl_ptn4_acl_trans.c b/libacl/acl_ptn4_acl_trans.c
3504 +new file mode 100644
3505 +index 0000000..2e5aa51
3506 +--- /dev/null
3507 ++++ b/libacl/acl_ptn4_acl_trans.c
3508 +@@ -0,0 +1,518 @@
3509 ++/*
3510 ++ * NFSv4 ACL Code
3511 ++ * Convert a posix ACL to an NFSv4 ACL
3512 ++ *
3513 ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
3514 ++ * All rights reserved.
3515 ++ *
3516 ++ * Nathaniel Gallaher <ngallahe@×××××.edu>
3517 ++ * J. Bruce Fields <bfields@×××××.edu>
3518 ++ *
3519 ++ * Redistribution and use in source and binary forms, with or without
3520 ++ * modification, are permitted provided that the following conditions
3521 ++ * are met:
3522 ++ *
3523 ++ * 1. Redistributions of source code must retain the above copyright
3524 ++ * notice, this list of conditions and the following disclaimer.
3525 ++ * 2. Redistributions in binary form must reproduce the above copyright
3526 ++ * notice, this list of conditions and the following disclaimer in the
3527 ++ * documentation and/or other materials provided with the distribution.
3528 ++ * 3. Neither the name of the University nor the names of its
3529 ++ * contributors may be used to endorse or promote products derived
3530 ++ * from this software without specific prior written permission.
3531 ++ *
3532 ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
3533 ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
3534 ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3535 ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
3536 ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
3537 ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
3538 ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
3539 ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
3540 ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3541 ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3542 ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3543 ++ */
3544 ++
3545 ++#include <acl/libacl.h>
3546 ++#include <nfsidmap.h>
3547 ++#include "libacl_nfs4.h"
3548 ++
3549 ++
3550 ++/* Plan:
3551 ++ * 1: if setting default, remove all purely inherited aces, and replace
3552 ++ * all dual-use aces by purely effective aces
3553 ++ * 2: if setting effective, remove all purely effective aces, and replace
3554 ++ * all dual-use aces by purely inherited ones
3555 ++ */
3556 ++
3557 ++int purge_aces(struct nfs4_acl *nacl, acl_type_t type)
3558 ++{
3559 ++ struct nfs4_ace *p, *next;
3560 ++
3561 ++ for (p = nacl->ace_head.tqh_first; p != NULL; p = next) {
3562 ++ next = p->l_ace.tqe_next;
3563 ++
3564 ++ switch (p->flag & NFS4_INHERITANCE_FLAGS) {
3565 ++ case 0:
3566 ++ /* purely effective */
3567 ++ if (type == ACL_TYPE_ACCESS)
3568 ++ acl_nfs4_remove_ace(nacl, p);
3569 ++ continue;
3570 ++ case NFS4_INHERITANCE_FLAGS:
3571 ++ /* purely inherited */
3572 ++ if (type == ACL_TYPE_DEFAULT)
3573 ++ acl_nfs4_remove_ace(nacl, p);
3574 ++ break;
3575 ++ case NFS4_INHERITANCE_FLAGS & ~NFS4_ACE_INHERIT_ONLY_ACE:
3576 ++ /* both effective and inherited */
3577 ++ if (type == ACL_TYPE_DEFAULT) {
3578 ++ /* Change to purely effective */
3579 ++ p->flag &= ~NFS4_INHERITANCE_FLAGS;
3580 ++ } else { /* ACL_TYPE_ACCESS */
3581 ++ /* Change to purely inherited */
3582 ++ p->flag |= NFS4_INHERITANCE_FLAGS;
3583 ++ }
3584 ++ break;
3585 ++ default:
3586 ++ errno = EINVAL;
3587 ++ return -1;
3588 ++ }
3589 ++
3590 ++ }
3591 ++ return 0;
3592 ++}
3593 ++
3594 ++int
3595 ++acl_ptn4_acl_trans(acl_t pacl, struct nfs4_acl *acl, acl_type_t type, u32 is_dir, char *nfs_domain)
3596 ++{
3597 ++ int eflag;
3598 ++ u32 mask, mask_mask = 0;
3599 ++ int num_aces;
3600 ++ int result, result2;
3601 ++ u32 iflags = NFS4_ACL_NOFLAGS;
3602 ++ int allocated = 0;
3603 ++
3604 ++ acl_entry_t pace_p;
3605 ++ acl_tag_t ace_type;
3606 ++ acl_permset_t perms;
3607 ++
3608 ++ char who_buf_static[NFS4_ACL_WHO_BUFFER_LEN_GUESS];
3609 ++ char *who_buf = NULL;
3610 ++ int who_buflen;
3611 ++ int who_buflen_static = NFS4_ACL_WHO_BUFFER_LEN_GUESS;
3612 ++ uid_t * uid_p;
3613 ++ gid_t * gid_p;
3614 ++
3615 ++ eflag = 0;
3616 ++
3617 ++ if (type == ACL_TYPE_DEFAULT) {
3618 ++ eflag = NFS4_INHERITANCE_FLAGS;
3619 ++ iflags |= NFS4_ACL_REQUEST_DEFAULT;
3620 ++ }
3621 ++
3622 ++ result = purge_aces(acl, type);
3623 ++ if (result)
3624 ++ return -1;
3625 ++
3626 ++ if (is_dir & NFS4_ACL_ISDIR)
3627 ++ iflags |= NFS4_ACL_ISDIR;
3628 ++
3629 ++
3630 ++ if (pacl == NULL || (acl_valid(pacl) < 0 || acl_entries(pacl) == 0)) {
3631 ++ errno = EINVAL;
3632 ++ goto out;
3633 ++ }
3634 ++
3635 ++ /* Start Conversion */
3636 ++
3637 ++ /* 3 aces minimum (mode bits) */
3638 ++ num_aces = acl_entries(pacl);
3639 ++ if (num_aces < 3) {
3640 ++ errno = EINVAL;
3641 ++ goto out;
3642 ++ }
3643 ++
3644 ++ /* Get the mask entry */
3645 ++
3646 ++ result = acl_get_entry(pacl, ACL_FIRST_ENTRY, &pace_p);
3647 ++ if (result < 0)
3648 ++ goto out;
3649 ++
3650 ++ while (result > 0 && mask_mask == 0) {
3651 ++ result = acl_get_tag_type(pace_p, &ace_type);
3652 ++ if (result < 0)
3653 ++ goto out;
3654 ++
3655 ++ if (ace_type == ACL_MASK) {
3656 ++ result = acl_get_permset(pace_p, &perms);
3657 ++ if(result < 0)
3658 ++ goto out;
3659 ++
3660 ++ result = acl_ptn4_get_mask(&mask_mask, perms, iflags);
3661 ++ if(result < 0)
3662 ++ goto out;
3663 ++
3664 ++ mask_mask = ~mask_mask;
3665 ++ }
3666 ++
3667 ++ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p);
3668 ++ if (result < 0)
3669 ++ goto out;
3670 ++ }
3671 ++
3672 ++ /* Get the file owner entry */
3673 ++ result = acl_get_entry(pacl, ACL_FIRST_ENTRY, &pace_p);
3674 ++ if (result < 0)
3675 ++ goto out;
3676 ++
3677 ++ result = acl_get_tag_type(pace_p, &ace_type);
3678 ++ if (result < 0)
3679 ++ goto out;
3680 ++
3681 ++ if (ace_type != ACL_USER_OBJ) {
3682 ++ errno = EINVAL;
3683 ++ goto out;
3684 ++ }
3685 ++
3686 ++ result = acl_get_permset(pace_p, &perms);
3687 ++ if (result < 0)
3688 ++ goto out;
3689 ++
3690 ++ result = acl_ptn4_get_mask(&mask, perms, iflags | NFS4_ACL_OWNER);
3691 ++ if (result < 0)
3692 ++ goto out;
3693 ++
3694 ++ result = acl_nfs4_add_pair(acl, eflag, mask, NFS4_ACL_WHO_OWNER, NULL);
3695 ++
3696 ++ if (result < 0)
3697 ++ goto out;
3698 ++
3699 ++ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p);
3700 ++ if (result < 0)
3701 ++ goto out;
3702 ++
3703 ++ result2 = acl_get_tag_type(pace_p, &ace_type);
3704 ++ if (result2 < 0)
3705 ++ goto out;
3706 ++
3707 ++ while (ace_type == ACL_USER && result > 0) {
3708 ++ result = acl_get_permset(pace_p, &perms);
3709 ++ if (result < 0)
3710 ++ goto out;
3711 ++
3712 ++ result = acl_ptn4_get_mask(&mask, perms, iflags);
3713 ++ if (result < 0)
3714 ++ goto out;
3715 ++
3716 ++ uid_p = acl_get_qualifier(pace_p);
3717 ++
3718 ++ who_buf = who_buf_static;
3719 ++ who_buflen = who_buflen_static;
3720 ++
3721 ++ result = nfs4_init_name_mapping(NULL);
3722 ++ result = nfs4_uid_to_name(*uid_p, nfs_domain, who_buf, who_buflen);
3723 ++
3724 ++
3725 ++ while (result == -ENOBUFS) {
3726 ++ if (who_buf != who_buf_static)
3727 ++ free(who_buf);
3728 ++
3729 ++ /* Increase the size by a full buflen unit */
3730 ++ who_buflen += who_buflen_static;
3731 ++ who_buf = malloc(who_buflen);
3732 ++
3733 ++ if (who_buf == NULL) {
3734 ++ result = -ENOMEM;
3735 ++ break;
3736 ++ }
3737 ++
3738 ++ result = nfs4_init_name_mapping(NULL);
3739 ++ result = nfs4_uid_to_name(*uid_p, nfs_domain, who_buf, who_buflen);
3740 ++
3741 ++ }
3742 ++ acl_free(uid_p);
3743 ++ if (result < 0) {
3744 ++ errno = -result;
3745 ++ goto out;
3746 ++ }
3747 ++
3748 ++ if (who_buf == NULL)
3749 ++ goto out;
3750 ++
3751 ++ result = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE,
3752 ++ eflag, mask_mask, NFS4_ACL_WHO_NAMED, who_buf);
3753 ++ if (result < 0) {
3754 ++ if(who_buf != who_buf_static)
3755 ++ free(who_buf);
3756 ++ goto out;
3757 ++ }
3758 ++
3759 ++ result = acl_nfs4_add_pair(acl, eflag, mask, NFS4_ACL_WHO_NAMED,
3760 ++ who_buf);
3761 ++ if (who_buf != who_buf_static)
3762 ++ free(who_buf);
3763 ++ if (result < 0)
3764 ++ goto out;
3765 ++
3766 ++ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p);
3767 ++ if (result <= 0)
3768 ++ goto out;
3769 ++
3770 ++ result2 = acl_get_tag_type(pace_p, &ace_type);
3771 ++ if (result2 < 0)
3772 ++ goto out;
3773 ++
3774 ++ }
3775 ++
3776 ++ /* In the case of groups, we apply allow ACEs first, then deny ACEs,
3777 ++ * since a user can be in more than one group. */
3778 ++
3779 ++ /* allow ACEs */
3780 ++
3781 ++ if (num_aces > 3) {
3782 ++ result2 = acl_get_tag_type(pace_p, &ace_type);
3783 ++ if (result2 < 0)
3784 ++ goto out;
3785 ++
3786 ++ if (ace_type != ACL_GROUP_OBJ) {
3787 ++ errno = EINVAL;
3788 ++ goto out;
3789 ++ }
3790 ++
3791 ++ result = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE,
3792 ++ NFS4_ACE_IDENTIFIER_GROUP | eflag, mask_mask,
3793 ++ NFS4_ACL_WHO_GROUP, NULL);
3794 ++
3795 ++ if (result < 0)
3796 ++ goto out;
3797 ++ }
3798 ++
3799 ++ result = acl_get_permset(pace_p, &perms);
3800 ++ if (result < 0)
3801 ++ goto out;
3802 ++
3803 ++ result = acl_ptn4_get_mask(&mask, perms, iflags);
3804 ++ if (result < 0)
3805 ++ goto out;
3806 ++
3807 ++ result = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE,
3808 ++ NFS4_ACE_IDENTIFIER_GROUP | eflag, mask, NFS4_ACL_WHO_GROUP, NULL);
3809 ++
3810 ++ if (result < 0)
3811 ++ goto out;
3812 ++
3813 ++ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p);
3814 ++ if (result <= 0)
3815 ++ goto out;
3816 ++
3817 ++ result2 = acl_get_tag_type(pace_p, &ace_type);
3818 ++ if (result2 < 0)
3819 ++ goto out;
3820 ++
3821 ++ while (ace_type == ACL_GROUP && result > 0) {
3822 ++ result = acl_get_permset(pace_p, &perms);
3823 ++ if (result < 0)
3824 ++ goto out;
3825 ++
3826 ++ result = acl_ptn4_get_mask(&mask, perms, iflags);
3827 ++ if (result < 0)
3828 ++ goto out;
3829 ++
3830 ++ gid_p = acl_get_qualifier(pace_p);
3831 ++
3832 ++ who_buf = who_buf_static;
3833 ++ who_buflen = who_buflen_static;
3834 ++
3835 ++ result = nfs4_gid_to_name(*gid_p, nfs_domain, who_buf, who_buflen);
3836 ++
3837 ++
3838 ++ while (result == -ENOBUFS) {
3839 ++ if (who_buf != who_buf_static)
3840 ++ free(who_buf);
3841 ++
3842 ++ /* Increase the size by a full buflen unit */
3843 ++ who_buflen += who_buflen_static;
3844 ++ who_buf = malloc(who_buflen);
3845 ++
3846 ++ if (who_buf == NULL) {
3847 ++ result = -ENOMEM;
3848 ++ break;
3849 ++ }
3850 ++
3851 ++ result = nfs4_gid_to_name(*gid_p, nfs_domain, who_buf, who_buflen);
3852 ++ }
3853 ++
3854 ++ acl_free(gid_p);
3855 ++
3856 ++ if (result < 0) {
3857 ++ errno = -result;
3858 ++ goto out;
3859 ++ }
3860 ++
3861 ++ if (who_buf == NULL)
3862 ++ goto out;
3863 ++
3864 ++ result = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE,
3865 ++ NFS4_ACE_IDENTIFIER_GROUP | eflag, mask_mask,
3866 ++ NFS4_ACL_WHO_NAMED, who_buf);
3867 ++ if (result < 0) {
3868 ++ if(who_buf != who_buf_static)
3869 ++ free(who_buf);
3870 ++ goto out;
3871 ++ }
3872 ++
3873 ++ result = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE,
3874 ++ NFS4_ACE_IDENTIFIER_GROUP | eflag, mask,
3875 ++ NFS4_ACL_WHO_NAMED, who_buf);
3876 ++
3877 ++ if (who_buf != who_buf_static)
3878 ++ free(who_buf);
3879 ++
3880 ++ if (result < 0)
3881 ++ goto out;
3882 ++ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p);
3883 ++ if (result <= 0)
3884 ++ goto out;
3885 ++
3886 ++ result2 = acl_get_tag_type(pace_p, &ace_type);
3887 ++ if (result2 < 0)
3888 ++ goto out;
3889 ++ }
3890 ++
3891 ++ /* deny ACEs */
3892 ++
3893 ++ result = acl_get_entry(pacl, ACL_FIRST_ENTRY, &pace_p);
3894 ++ if (result <= 0)
3895 ++ goto out;
3896 ++
3897 ++ result2 = acl_get_tag_type(pace_p, &ace_type);
3898 ++ if (result2 < 0)
3899 ++ goto out;
3900 ++
3901 ++ while (ace_type != ACL_GROUP_OBJ && result > 0) {
3902 ++ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p);
3903 ++ if(result <= 0)
3904 ++ goto out;
3905 ++
3906 ++ result2 = acl_get_tag_type(pace_p, &ace_type);
3907 ++ if(result2 < 0)
3908 ++ goto out;
3909 ++ }
3910 ++
3911 ++ result = acl_get_permset(pace_p, &perms);
3912 ++ if (result < 0)
3913 ++ goto out;
3914 ++
3915 ++ result = acl_ptn4_get_mask(&mask, perms, iflags);
3916 ++ if (result < 0)
3917 ++ goto out;
3918 ++
3919 ++ result = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE,
3920 ++ NFS4_ACE_IDENTIFIER_GROUP | eflag, ~mask, NFS4_ACL_WHO_GROUP,
3921 ++ NULL);
3922 ++
3923 ++ if (result < 0)
3924 ++ goto out;
3925 ++
3926 ++ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p);
3927 ++ if (result <= 0)
3928 ++ goto out;
3929 ++
3930 ++ result2 = acl_get_tag_type(pace_p, &ace_type);
3931 ++ if (result2 < 0)
3932 ++ goto out;
3933 ++
3934 ++ while (ace_type == ACL_GROUP && result > 0) {
3935 ++ result = acl_get_permset(pace_p, &perms);
3936 ++ if (result < 0)
3937 ++ goto out;
3938 ++
3939 ++ result = acl_ptn4_get_mask(&mask, perms, iflags);
3940 ++ if (result < 0)
3941 ++ goto out;
3942 ++
3943 ++ gid_p = acl_get_qualifier(pace_p);
3944 ++
3945 ++ who_buf = who_buf_static;
3946 ++ who_buflen = who_buflen_static;
3947 ++
3948 ++ result = nfs4_gid_to_name(*gid_p, nfs_domain, who_buf, who_buflen);
3949 ++
3950 ++
3951 ++ while (result == -ENOBUFS) {
3952 ++ if (who_buf != who_buf_static)
3953 ++ free(who_buf);
3954 ++
3955 ++ /* Increase the size by a full buflen unit */
3956 ++ who_buflen += who_buflen_static;
3957 ++ who_buf = malloc(who_buflen);
3958 ++
3959 ++ if (who_buf == NULL) {
3960 ++ result = -ENOMEM;
3961 ++ break;
3962 ++ }
3963 ++
3964 ++ result = nfs4_gid_to_name(*gid_p, nfs_domain, who_buf, who_buflen);
3965 ++ }
3966 ++
3967 ++ acl_free(gid_p);
3968 ++
3969 ++ if (result < 0) {
3970 ++ errno = -result;
3971 ++ goto out;
3972 ++ }
3973 ++
3974 ++ if (who_buf == NULL)
3975 ++ goto out;
3976 ++
3977 ++ result = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE,
3978 ++ NFS4_ACE_IDENTIFIER_GROUP | eflag, ~mask,
3979 ++ NFS4_ACL_WHO_NAMED, who_buf);
3980 ++ if (who_buf != who_buf_static)
3981 ++ free(who_buf);
3982 ++ if (result < 0)
3983 ++ goto out;
3984 ++
3985 ++ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p);
3986 ++ if (result <= 0)
3987 ++ goto out;
3988 ++
3989 ++ result2 = acl_get_tag_type(pace_p, &ace_type);
3990 ++ if (result2 < 0)
3991 ++ goto out;
3992 ++ }
3993 ++
3994 ++ if (ace_type == ACL_MASK) {
3995 ++ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p);
3996 ++ if (result <= 0)
3997 ++ goto out;
3998 ++
3999 ++ result2 = acl_get_tag_type(pace_p, &ace_type);
4000 ++ if (result2 < 0)
4001 ++ goto out;
4002 ++ }
4003 ++
4004 ++ if (ace_type != ACL_OTHER) {
4005 ++ errno = EINVAL;
4006 ++ goto out;
4007 ++ }
4008 ++
4009 ++ result = acl_get_permset(pace_p, &perms);
4010 ++ if (result < 0)
4011 ++ goto out;
4012 ++
4013 ++ result = acl_ptn4_get_mask(&mask, perms, iflags);
4014 ++ if (result < 0)
4015 ++ goto out;
4016 ++
4017 ++ result = acl_nfs4_add_pair(acl, eflag, mask, NFS4_ACL_WHO_EVERYONE, NULL);
4018 ++
4019 ++ return result;
4020 ++out:
4021 ++ if (allocated)
4022 ++ acl_nfs4_free(acl);
4023 ++ return -1;
4024 ++}
4025 ++
4026 ++
4027 +diff --git a/libacl/acl_ptn4_get_mask.c b/libacl/acl_ptn4_get_mask.c
4028 +new file mode 100644
4029 +index 0000000..bee0a97
4030 +--- /dev/null
4031 ++++ b/libacl/acl_ptn4_get_mask.c
4032 +@@ -0,0 +1,81 @@
4033 ++/*
4034 ++ * NFSv4 ACL Code
4035 ++ * Translate POSIX permissions to an NFSv4 mask
4036 ++ *
4037 ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
4038 ++ * All rights reserved.
4039 ++ *
4040 ++ * Nathaniel Gallaher <ngallahe@×××××.edu>
4041 ++ *
4042 ++ * Redistribution and use in source and binary forms, with or without
4043 ++ * modification, are permitted provided that the following conditions
4044 ++ * are met:
4045 ++ *
4046 ++ * 1. Redistributions of source code must retain the above copyright
4047 ++ * notice, this list of conditions and the following disclaimer.
4048 ++ * 2. Redistributions in binary form must reproduce the above copyright
4049 ++ * notice, this list of conditions and the following disclaimer in the
4050 ++ * documentation and/or other materials provided with the distribution.
4051 ++ * 3. Neither the name of the University nor the names of its
4052 ++ * contributors may be used to endorse or promote products derived
4053 ++ * from this software without specific prior written permission.
4054 ++ *
4055 ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
4056 ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
4057 ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
4058 ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
4059 ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
4060 ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
4061 ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
4062 ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
4063 ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4064 ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4065 ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4066 ++ */
4067 ++
4068 ++#include <acl/libacl.h>
4069 ++#include <libacl_nfs4.h>
4070 ++
4071 ++int acl_ptn4_get_mask(u32* mask, acl_permset_t perms, int iflags)
4072 ++{
4073 ++ int result;
4074 ++
4075 ++ *mask = NFS4_ANYONE_MODE;
4076 ++
4077 ++ if(perms == NULL) {
4078 ++ errno = EINVAL;
4079 ++ goto failed;
4080 ++ }
4081 ++
4082 ++ if (iflags & NFS4_ACL_OWNER)
4083 ++ *mask |= NFS4_OWNER_MODE;
4084 ++
4085 ++ result = acl_get_perm(perms, ACL_READ);
4086 ++ if(result < 0)
4087 ++ goto failed;
4088 ++ else if(result == 1)
4089 ++ *mask |= NFS4_READ_MODE;
4090 ++
4091 ++ result = acl_get_perm(perms, ACL_WRITE);
4092 ++ if(result < 0)
4093 ++ goto failed;
4094 ++ else if(result == 1) {
4095 ++ *mask |= NFS4_WRITE_MODE;
4096 ++ if(iflags & NFS4_ACL_ISDIR)
4097 ++ *mask |= NFS4_ACE_DELETE_CHILD;
4098 ++ }
4099 ++
4100 ++ result = acl_get_perm(perms, ACL_EXECUTE);
4101 ++ if(result < 0)
4102 ++ goto failed;
4103 ++ else if(result == 1)
4104 ++ *mask |= NFS4_EXECUTE_MODE;
4105 ++
4106 ++ return 0;
4107 ++
4108 ++failed:
4109 ++ return -1;
4110 ++}
4111 ++
4112 ++
4113 ++
4114 +diff --git a/libacl/acl_set_fd.c b/libacl/acl_set_fd.c
4115 +index e6413ad..93536a8 100644
4116 +--- a/libacl/acl_set_fd.c
4117 ++++ b/libacl/acl_set_fd.c
4118 +@@ -24,6 +24,11 @@
4119 + #include "libacl.h"
4120 + #include "__acl_to_xattr.h"
4121 +
4122 ++#ifdef USE_NFSV4_TRANS
4123 ++ #include "libacl_nfs4.h"
4124 ++ #include <nfsidmap.h>
4125 ++#endif
4126 ++
4127 + #include "byteorder.h"
4128 + #include "acl_ea.h"
4129 +
4130 +@@ -37,10 +42,42 @@ acl_set_fd(int fd, acl_t acl)
4131 + const char *name = ACL_EA_ACCESS;
4132 + size_t size;
4133 + int error;
4134 ++#ifdef USE_NFSV4_TRANS
4135 ++ int retval;
4136 ++ struct nfs4_acl * nacl;
4137 ++#endif
4138 +
4139 + if (!acl_obj_p)
4140 + return -1;
4141 ++
4142 ++#ifdef USE_NFSV4_TRANS
4143 ++ retval = fgetxattr(fd, ACL_NFS4_XATTR, NULL, 0);
4144 ++
4145 ++ if(retval == -1 && (errno == ENOATTR || errno == EOPNOTSUPP)) {
4146 ++ ext_acl_p = __acl_to_xattr(acl_obj_p, &size);
4147 ++ } else {
4148 ++ char domain[NFS4_MAX_DOMAIN_LEN];
4149 ++ nfs4_init_name_mapping(NULL);
4150 ++ error = nfs4_get_default_domain(NULL, domain, sizeof(domain));
4151 ++ if (error)
4152 ++ return -1;
4153 ++ nacl = acl_nfs4_new(0);
4154 ++ if (acl == NULL) {
4155 ++ errno = ENOMEM;
4156 ++ return -1;
4157 ++ }
4158 ++ error = acl_ptn4_acl_trans(acl, nacl, ACL_TYPE_ACCESS, 0, domain);
4159 ++ if (error)
4160 ++ return -1;
4161 ++
4162 ++ size = acl_nfs4_xattr_pack(nacl, &ext_acl_p);
4163 ++ name = ACL_NFS4_XATTR;
4164 ++ acl_nfs4_free(nacl);
4165 ++ }
4166 ++#else
4167 + ext_acl_p = __acl_to_xattr(acl_obj_p, &size);
4168 ++#endif
4169 ++
4170 + if (!ext_acl_p)
4171 + return -1;
4172 + error = fsetxattr(fd, name, (char *)ext_acl_p, size, 0);
4173 +diff --git a/libacl/acl_set_file.c b/libacl/acl_set_file.c
4174 +index 6821851..303e39c 100644
4175 +--- a/libacl/acl_set_file.c
4176 ++++ b/libacl/acl_set_file.c
4177 +@@ -26,9 +26,38 @@
4178 + #include "libacl.h"
4179 + #include "__acl_to_xattr.h"
4180 +
4181 ++#ifdef USE_NFSV4_TRANS
4182 ++ #include "libacl_nfs4.h"
4183 ++ #include <nfsidmap.h>
4184 ++#endif
4185 ++
4186 + #include "byteorder.h"
4187 + #include "acl_ea.h"
4188 +
4189 ++#ifdef USE_NFSV4_TRANS
4190 ++static struct nfs4_acl *get_nfs4_acl(const char *path_p, int is_dir)
4191 ++{
4192 ++ struct nfs4_acl * acl = NULL;
4193 ++ ssize_t ret;
4194 ++ char *buf;
4195 ++
4196 ++ ret = getxattr(path_p, ACL_NFS4_XATTR, NULL, 0);
4197 ++ if (ret < 0)
4198 ++ return NULL;
4199 ++ buf = malloc(ret);
4200 ++ if (buf == NULL)
4201 ++ return NULL;
4202 ++ ret = getxattr(path_p, ACL_NFS4_XATTR, buf, ret);
4203 ++ if (ret < 0)
4204 ++ goto out_free;
4205 ++ acl = acl_nfs4_xattr_load(buf, ret, is_dir);
4206 ++
4207 ++out_free:
4208 ++ free(buf);
4209 ++ return acl;
4210 ++}
4211 ++
4212 ++#endif
4213 +
4214 + /* 23.4.22 */
4215 + int
4216 +@@ -39,9 +68,15 @@ acl_set_file(const char *path_p, acl_type_t type, acl_t acl)
4217 + const char *name;
4218 + size_t size;
4219 + int error;
4220 ++ struct stat st;
4221 ++#ifdef USE_NFSV4_TRANS
4222 ++ struct nfs4_acl * nacl;
4223 ++ int is_dir = NFS4_ACL_ISFILE;
4224 ++#endif
4225 +
4226 + if (!acl_obj_p)
4227 + return -1;
4228 ++
4229 + switch (type) {
4230 + case ACL_TYPE_ACCESS:
4231 + name = ACL_EA_ACCESS;
4232 +@@ -54,8 +89,41 @@ acl_set_file(const char *path_p, acl_type_t type, acl_t acl)
4233 + return -1;
4234 + }
4235 +
4236 ++
4237 ++#ifdef USE_NFSV4_TRANS
4238 ++ if (stat(path_p, &st) != 0)
4239 ++ return -1;
4240 ++ if (S_ISDIR(st.st_mode))
4241 ++ is_dir = NFS4_ACL_ISDIR;
4242 ++ if (type == ACL_TYPE_DEFAULT && !is_dir) {
4243 ++ errno = EACCES;
4244 ++ return -1;
4245 ++ }
4246 ++ nacl = get_nfs4_acl(path_p, is_dir);
4247 ++ if (nacl == NULL && (errno == ENOATTR || errno == EOPNOTSUPP))
4248 ++ ext_acl_p = __acl_to_xattr(acl_obj_p, &size);
4249 ++ else {
4250 ++ char domain[NFS4_MAX_DOMAIN_LEN];
4251 ++
4252 ++ nfs4_init_name_mapping(NULL);
4253 ++ error = nfs4_get_default_domain(NULL, domain, sizeof(domain));
4254 ++ if (error) {
4255 ++ acl_nfs4_free(nacl);
4256 ++ return -1;
4257 ++ }
4258 ++ error = acl_ptn4_acl_trans(acl, nacl, type, is_dir, domain);
4259 ++ if (error) {
4260 ++ acl_nfs4_free(nacl);
4261 ++ return -1;
4262 ++ }
4263 ++
4264 ++ size = acl_nfs4_xattr_pack(nacl, &ext_acl_p);
4265 ++ name = ACL_NFS4_XATTR;
4266 ++ acl_nfs4_free(nacl);
4267 ++ }
4268 ++#else
4269 ++
4270 + if (type == ACL_TYPE_DEFAULT) {
4271 +- struct stat st;
4272 +
4273 + if (stat(path_p, &st) != 0)
4274 + return -1;
4275 +@@ -68,9 +136,12 @@ acl_set_file(const char *path_p, acl_type_t type, acl_t acl)
4276 + }
4277 +
4278 + ext_acl_p = __acl_to_xattr(acl_obj_p, &size);
4279 ++#endif
4280 ++
4281 + if (!ext_acl_p)
4282 + return -1;
4283 +- error = setxattr(path_p, name, (char *)ext_acl_p, size, 0);
4284 ++
4285 ++ error = setxattr(path_p, name, (char *)ext_acl_p, size, XATTR_REPLACE);
4286 + free(ext_acl_p);
4287 + return error;
4288 + }
4289 +diff --git a/libacl/libacl_nfs4.h b/libacl/libacl_nfs4.h
4290 +new file mode 100644
4291 +index 0000000..e6a466c
4292 +--- /dev/null
4293 ++++ b/libacl/libacl_nfs4.h
4294 +@@ -0,0 +1,134 @@
4295 ++#include <sys/types.h>
4296 ++#include <pwd.h>
4297 ++#include <grp.h>
4298 ++#include <sys/acl.h>
4299 ++#include <stdlib.h>
4300 ++#include <sys/queue.h>
4301 ++#include <nfs4.h>
4302 ++#include <sys/errno.h>
4303 ++#include <string.h>
4304 ++
4305 ++/* mode bit translations: */
4306 ++#define NFS4_READ_MODE NFS4_ACE_READ_DATA
4307 ++#define NFS4_WRITE_MODE (NFS4_ACE_WRITE_DATA \
4308 ++ | NFS4_ACE_APPEND_DATA | NFS4_ACE_DELETE_CHILD)
4309 ++#define NFS4_EXECUTE_MODE NFS4_ACE_EXECUTE
4310 ++#define NFS4_ANYONE_MODE (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL | \
4311 ++ NFS4_ACE_SYNCHRONIZE)
4312 ++#define NFS4_OWNER_MODE (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL)
4313 ++
4314 ++/* flags used to simulate posix default ACLs */
4315 ++#define NFS4_INHERITANCE_FLAGS (NFS4_ACE_FILE_INHERIT_ACE \
4316 ++ | NFS4_ACE_DIRECTORY_INHERIT_ACE | NFS4_ACE_INHERIT_ONLY_ACE)
4317 ++
4318 ++#define NFS4_ACE_MASK_IGNORE (NFS4_ACE_DELETE | NFS4_ACE_WRITE_OWNER \
4319 ++ | NFS4_ACE_READ_NAMED_ATTRS | NFS4_ACE_WRITE_NAMED_ATTRS)
4320 ++/* XXX not sure about the following. Note that e.g. DELETE_CHILD is wrong in
4321 ++ * general (should only be ignored on files). */
4322 ++#define MASK_EQUAL(mask1, mask2) \
4323 ++ (((mask1) & NFS4_ACE_MASK_ALL & ~NFS4_ACE_MASK_IGNORE & \
4324 ++ ~NFS4_ACE_DELETE_CHILD) \
4325 ++ == ((mask2) & NFS4_ACE_MASK_ALL & ~NFS4_ACE_MASK_IGNORE & \
4326 ++ ~NFS4_ACE_DELETE_CHILD))
4327 ++
4328 ++/* Maximum length of the ace->who attribute */
4329 ++#define NFS4_ACL_WHO_LENGTH_MAX 2048
4330 ++#define NFS4_ACL_WHO_BUFFER_LEN_GUESS 255
4331 ++
4332 ++/* NFS4 acl xattr name */
4333 ++#define ACL_NFS4_XATTR "system.nfs4_acl"
4334 ++
4335 ++/* Macro for finding empty tailqs */
4336 ++#define TAILQ_IS_EMPTY(head) (head.tqh_first == NULL)
4337 ++
4338 ++/* Flags to pass certain properties around */
4339 ++#define NFS4_ACL_NOFLAGS 0x00
4340 ++#define NFS4_ACL_ISFILE 0x00
4341 ++#define NFS4_ACL_ISDIR 0x01
4342 ++#define NFS4_ACL_OWNER 0x02
4343 ++#define NFS4_ACL_REQUEST_DEFAULT 0x04
4344 ++#define NFS4_ACL_RAW 0x01
4345 ++
4346 ++#define NFS4_XDR_MOD 4
4347 ++
4348 ++typedef u_int32_t u32;
4349 ++
4350 ++enum { ACL_NFS4_NOT_USED = 0,
4351 ++ ACL_NFS4_USED
4352 ++};
4353 ++
4354 ++struct ace_container {
4355 ++ struct nfs4_ace *ace;
4356 ++ TAILQ_ENTRY(ace_container) l_ace;
4357 ++};
4358 ++
4359 ++TAILQ_HEAD(ace_container_list_head, ace_container);
4360 ++
4361 ++/**** Public functions ****/
4362 ++
4363 ++/** Manipulation functions **/
4364 ++extern int acl_nfs4_add_ace(struct nfs4_acl *, u32, u32, u32, int, char*);
4365 ++extern int acl_nfs4_add_pair(struct nfs4_acl *, int, u32, int, char*);
4366 ++extern void acl_nfs4_free(struct nfs4_acl *);
4367 ++extern struct nfs4_acl *acl_nfs4_new(u32);
4368 ++extern int acl_nfs4_set_who(struct nfs4_ace*, int, char*);
4369 ++extern struct nfs4_acl *acl_nfs4_copy_acl(struct nfs4_acl *);
4370 ++extern struct nfs4_acl *acl_nfs4_xattr_load(char *, int, u32);
4371 ++extern int acl_nfs4_xattr_pack(struct nfs4_acl *, char**);
4372 ++extern int acl_nfs4_xattr_size(struct nfs4_acl *);
4373 ++extern void acl_nfs4_remove_ace(struct nfs4_acl * acl, struct nfs4_ace * ace);
4374 ++
4375 ++/** Conversion functions **/
4376 ++
4377 ++/* nfs4 -> posix */
4378 ++extern acl_t acl_n4tp_acl_trans(struct nfs4_acl *, acl_type_t);
4379 ++extern int acl_n4tp_set_mode(acl_entry_t pace, u32 nfs4_access_mask,
4380 ++ int iflags);
4381 ++extern int acl_n4tp_ace_count(struct nfs4_acl *n4acl);
4382 ++extern int acl_n4tp_ace_trans(struct nfs4_ace *ace, acl_t *pacl,
4383 ++ acl_tag_t tag, int iflags);
4384 ++extern int acl_n4tp_set_who(acl_entry_t ace, char* who,
4385 ++ acl_tag_t who_type);
4386 ++extern acl_tag_t acl_n4tp_get_whotype(struct nfs4_ace *ace);
4387 ++
4388 ++/* posix -> nfs4 */
4389 ++extern int acl_ptn4_get_mask(u32* mask, acl_permset_t perms,
4390 ++ int iflags);
4391 ++extern int acl_ptn4_acl_trans(acl_t, struct nfs4_acl *, acl_type_t, u32, char*);
4392 ++
4393 ++
4394 ++/** Access Functions **/
4395 ++extern inline struct nfs4_ace *
4396 ++ acl_nfs4_get_next_ace(struct nfs4_ace **);
4397 ++extern inline struct nfs4_ace *
4398 ++ acl_nfs4_get_first_ace(struct nfs4_acl *);
4399 ++extern inline int acl_nfs4_get_whotype(char*);
4400 ++extern int acl_nfs4_get_who(struct nfs4_ace*, int*, char**);
4401 ++
4402 ++/**** Private(?) functions ****/
4403 ++acl_t __posix_acl_from_nfs4_xattr(char*, int, acl_type_t, u32);
4404 ++int complementary_ace_pair(struct nfs4_ace *allow, struct nfs4_ace *deny);
4405 ++int same_who(struct nfs4_ace *a, struct nfs4_ace *b);
4406 ++
4407 ++/* These will change */
4408 ++int nfs4_get_gid_from_who(gid_t* gid, const char * who);
4409 ++int nfs4_get_uid_from_who(uid_t* uid, const char * who);
4410 ++char * nfs4_get_who_from_uid(uid_t);
4411 ++char * nfs4_get_who_from_gid(gid_t);
4412 ++int __nfs4_get_local_uid_from_who(uid_t* uid, const char * who);
4413 ++int __nfs4_get_foreign_uid_from_who(uid_t* uid, const char * who);
4414 ++int __nfs4_get_local_gid_from_who(gid_t* gid, const char * who);
4415 ++int __nfs4_get_foreign_gid_from_who(gid_t* gid, const char * who);
4416 ++int is_who_local(const char * who);
4417 ++/* End change */
4418 ++
4419 ++int user_obj_from_v4(struct nfs4_acl *n4acl, struct nfs4_ace **n4ace,
4420 ++ acl_t *pacl, int iflags);
4421 ++int users_from_v4(struct nfs4_acl *n4acl, struct nfs4_ace ** n4ace_p,
4422 ++ struct nfs4_ace **mask_ace, acl_t *pacl, int iflags);
4423 ++int group_obj_and_groups_from_v4(struct nfs4_acl *n4acl,
4424 ++ struct nfs4_ace ** n4ace_p, struct nfs4_ace **mask_ace, acl_t *pacl, int iflags);
4425 ++int mask_from_v4(struct nfs4_acl *n4acl, struct nfs4_ace ** n4ace_p,
4426 ++ struct nfs4_ace **mask_ace, acl_t *pacl, int iflags);
4427 ++int other_from_v4(struct nfs4_acl *n4acl, struct nfs4_ace ** n4ace_p,
4428 ++ acl_t *pacl, int iflags);
4429 +--
4430 +1.7.8.1
4431 +
4432
4433 diff --git a/sys-apps/acl/files/0002-nfsd4-move-to-new-nfsv4-posix-mapping-clean-up.patch b/sys-apps/acl/files/0002-nfsd4-move-to-new-nfsv4-posix-mapping-clean-up.patch
4434 new file mode 100644
4435 index 0000000..f6c134d
4436 --- /dev/null
4437 +++ b/sys-apps/acl/files/0002-nfsd4-move-to-new-nfsv4-posix-mapping-clean-up.patch
4438 @@ -0,0 +1,1740 @@
4439 +From 7b6f7353fe4d05c18fcc5a932282b16c4cfe55b4 Mon Sep 17 00:00:00 2001
4440 +From: "J. Bruce Fields" <bfields@×××××××××××××××××.edu>
4441 +Date: Mon, 11 Dec 2006 18:38:01 -0500
4442 +Subject: [PATCH 02/17] nfsd4: move to new nfsv4->posix mapping; clean up
4443 +
4444 +Move to the new nfsv4->posix mapping which accepts any nfsv4 acl and converts
4445 +it to the closest posix acl, erring on the side of permissiveness.
4446 +
4447 +Also delete some cruft.
4448 +
4449 +Signed-off-by: "J. Bruce Fields" <bfields@××××××××××.edu>
4450 +---
4451 + exports | 22 --
4452 + include/libacl_nfs4.h | 21 --
4453 + libacl/Makefile | 7 +-
4454 + libacl/acl_n4tp_ace_count.c | 57 ----
4455 + libacl/acl_n4tp_ace_trans.c | 76 ------
4456 + libacl/acl_n4tp_acl_trans.c | 400 +++++++++++++++++++++++++-----
4457 + libacl/acl_n4tp_get_whotype.c | 73 ------
4458 + libacl/acl_n4tp_set_mode.c | 98 -------
4459 + libacl/acl_n4tp_set_who.c | 89 -------
4460 + libacl/acl_nfs4_copy_acl.c | 4 +-
4461 + libacl/acl_nfs4_utils.c | 566 -----------------------------------------
4462 + libacl/acl_nfs4_xattr_pack.c | 4 +-
4463 + libacl/acl_nfs4_xattr_size.c | 4 +-
4464 + libacl/libacl_nfs4.h | 32 ---
4465 + 14 files changed, 348 insertions(+), 1105 deletions(-)
4466 + delete mode 100644 libacl/acl_n4tp_ace_count.c
4467 + delete mode 100644 libacl/acl_n4tp_ace_trans.c
4468 + delete mode 100644 libacl/acl_n4tp_get_whotype.c
4469 + delete mode 100644 libacl/acl_n4tp_set_mode.c
4470 + delete mode 100644 libacl/acl_n4tp_set_who.c
4471 + delete mode 100644 libacl/acl_nfs4_utils.c
4472 +
4473 +diff --git a/exports b/exports
4474 +index 08bf390..31f3e00 100644
4475 +--- a/exports
4476 ++++ b/exports
4477 +@@ -103,39 +103,17 @@ ACL_1.2 {
4478 + acl_nfs4_remove_ace;
4479 +
4480 + acl_n4tp_acl_trans;
4481 +- acl_n4tp_set_mode;
4482 +- acl_n4tp_ace_count;
4483 +- acl_n4tp_ace_trans;
4484 +- acl_n4tp_set_who;
4485 +- acl_n4tp_get_whotype;
4486 +
4487 + acl_ptn4_get_mask;
4488 + acl_ptn4_acl_trans;
4489 +
4490 +- acl_nfs4_get_next_ace;
4491 +- acl_nfs4_get_first_ace;
4492 +- acl_nfs4_get_dir;
4493 + acl_nfs4_get_whotype;
4494 + acl_nfs4_get_who;
4495 + acl_nfs4_entries;
4496 +
4497 + local:
4498 + __posix_acl_from_nfs4_xattr;
4499 +- complementary_ace_pair;
4500 +- same_who;
4501 +- nfs4_get_gid_from_who;
4502 +- nfs4_get_uid_from_who;
4503 + nfs4_get_who_from_uid;
4504 + nfs4_get_who_from_gid;
4505 +- __nfs4_get_local_uid_from_who;
4506 +- __nfs4_get_foreign_uid_from_who;
4507 +- __nfs4_get_local_gid_from_who;
4508 +- __nfs4_get_foreign_gid_from_who;
4509 +- is_who_local;
4510 +
4511 +- user_obj_from_v4;
4512 +- users_from_v4;
4513 +- group_obj_and_groups_from_v4;
4514 +- mask_from_v4;
4515 +- other_from_v4;
4516 + } ACL_1.1;
4517 +diff --git a/include/libacl_nfs4.h b/include/libacl_nfs4.h
4518 +index e6a466c..9103424 100644
4519 +--- a/include/libacl_nfs4.h
4520 ++++ b/include/libacl_nfs4.h
4521 +@@ -82,14 +82,6 @@ extern void acl_nfs4_remove_ace(struct nfs4_acl * acl, struct nfs4_ace * ace)
4522 +
4523 + /* nfs4 -> posix */
4524 + extern acl_t acl_n4tp_acl_trans(struct nfs4_acl *, acl_type_t);
4525 +-extern int acl_n4tp_set_mode(acl_entry_t pace, u32 nfs4_access_mask,
4526 +- int iflags);
4527 +-extern int acl_n4tp_ace_count(struct nfs4_acl *n4acl);
4528 +-extern int acl_n4tp_ace_trans(struct nfs4_ace *ace, acl_t *pacl,
4529 +- acl_tag_t tag, int iflags);
4530 +-extern int acl_n4tp_set_who(acl_entry_t ace, char* who,
4531 +- acl_tag_t who_type);
4532 +-extern acl_tag_t acl_n4tp_get_whotype(struct nfs4_ace *ace);
4533 +
4534 + /* posix -> nfs4 */
4535 + extern int acl_ptn4_get_mask(u32* mask, acl_permset_t perms,
4536 +@@ -98,28 +90,15 @@ extern int acl_ptn4_acl_trans(acl_t, struct nfs4_acl *, acl_type_t, u32, char*);
4537 +
4538 +
4539 + /** Access Functions **/
4540 +-extern inline struct nfs4_ace *
4541 +- acl_nfs4_get_next_ace(struct nfs4_ace **);
4542 +-extern inline struct nfs4_ace *
4543 +- acl_nfs4_get_first_ace(struct nfs4_acl *);
4544 + extern inline int acl_nfs4_get_whotype(char*);
4545 + extern int acl_nfs4_get_who(struct nfs4_ace*, int*, char**);
4546 +
4547 + /**** Private(?) functions ****/
4548 + acl_t __posix_acl_from_nfs4_xattr(char*, int, acl_type_t, u32);
4549 +-int complementary_ace_pair(struct nfs4_ace *allow, struct nfs4_ace *deny);
4550 +-int same_who(struct nfs4_ace *a, struct nfs4_ace *b);
4551 +
4552 + /* These will change */
4553 +-int nfs4_get_gid_from_who(gid_t* gid, const char * who);
4554 +-int nfs4_get_uid_from_who(uid_t* uid, const char * who);
4555 + char * nfs4_get_who_from_uid(uid_t);
4556 + char * nfs4_get_who_from_gid(gid_t);
4557 +-int __nfs4_get_local_uid_from_who(uid_t* uid, const char * who);
4558 +-int __nfs4_get_foreign_uid_from_who(uid_t* uid, const char * who);
4559 +-int __nfs4_get_local_gid_from_who(gid_t* gid, const char * who);
4560 +-int __nfs4_get_foreign_gid_from_who(gid_t* gid, const char * who);
4561 +-int is_who_local(const char * who);
4562 + /* End change */
4563 +
4564 + int user_obj_from_v4(struct nfs4_acl *n4acl, struct nfs4_ace **n4ace,
4565 +diff --git a/libacl/Makefile b/libacl/Makefile
4566 +index 8335170..feee9a5 100644
4567 +--- a/libacl/Makefile
4568 ++++ b/libacl/Makefile
4569 +@@ -37,15 +37,12 @@ HFILES = libobj.h libacl.h byteorder.h __acl_from_xattr.h __acl_to_xattr.h \
4570 + LCFLAGS = -include perm_copy.h
4571 +
4572 + LIBACL_NFS4_CFILES = \
4573 +- acl_n4tp_ace_count.c \
4574 +- acl_n4tp_ace_trans.c acl_nfs4_get_who.c \
4575 ++ acl_nfs4_get_who.c \
4576 + acl_n4tp_acl_trans.c acl_nfs4_get_whotype.c \
4577 +- acl_n4tp_get_whotype.c acl_nfs4_new.c \
4578 +- acl_n4tp_set_mode.c acl_n4tp_set_who.c \
4579 ++ acl_nfs4_new.c \
4580 + acl_nfs4_add_ace.c acl_nfs4_remove_ace.c \
4581 + acl_nfs4_add_pair.c \
4582 + acl_nfs4_copy_acl.c acl_nfs4_set_who.c \
4583 +- acl_nfs4_utils.c \
4584 + acl_nfs4_free.c acl_nfs4_xattr_load.c \
4585 + acl_nfs4_xattr_pack.c acl_nfs4_xattr_size.c \
4586 + acl_ptn4_acl_trans.c \
4587 +diff --git a/libacl/acl_n4tp_ace_count.c b/libacl/acl_n4tp_ace_count.c
4588 +deleted file mode 100644
4589 +index ecce637..0000000
4590 +--- a/libacl/acl_n4tp_ace_count.c
4591 ++++ /dev/null
4592 +@@ -1,57 +0,0 @@
4593 +-/*
4594 +- * NFSv4 ACL Code
4595 +- * Calculate the POSIX ACE count based upon the assumption that
4596 +- * POSIX<->NFSv4 ACL translation has been the standard on the
4597 +- * server/client. This would break against other servers?
4598 +- *
4599 +- * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
4600 +- * All rights reserved.
4601 +- *
4602 +- * Nathaniel Gallaher <ngallahe@×××××.edu>
4603 +- *
4604 +- * Redistribution and use in source and binary forms, with or without
4605 +- * modification, are permitted provided that the following conditions
4606 +- * are met:
4607 +- *
4608 +- * 1. Redistributions of source code must retain the above copyright
4609 +- * notice, this list of conditions and the following disclaimer.
4610 +- * 2. Redistributions in binary form must reproduce the above copyright
4611 +- * notice, this list of conditions and the following disclaimer in the
4612 +- * documentation and/or other materials provided with the distribution.
4613 +- * 3. Neither the name of the University nor the names of its
4614 +- * contributors may be used to endorse or promote products derived
4615 +- * from this software without specific prior written permission.
4616 +- *
4617 +- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
4618 +- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
4619 +- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
4620 +- * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
4621 +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
4622 +- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
4623 +- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
4624 +- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
4625 +- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4626 +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4627 +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4628 +- */
4629 +-
4630 +-#include <acl/libacl.h>
4631 +-#include "libacl_nfs4.h"
4632 +-
4633 +-int acl_n4tp_ace_count(struct nfs4_acl *n4acl)
4634 +-{
4635 +- if (n4acl->naces == 0)
4636 +- return 0;
4637 +- if (n4acl->naces == 6) /* owner, owner group, and other only */
4638 +- return 3;
4639 +- else { /* Otherwise there must be a mask entry. */
4640 +- /* Also, the remaining entries are for named users and
4641 +- * groups, and come in threes (mask, allow, deny): */
4642 +- if (n4acl->naces < 7)
4643 +- return -1;
4644 +- if ((n4acl->naces - 7) % 3)
4645 +- return -1;
4646 +- return 4 + (n4acl->naces - 7)/3;
4647 +- }
4648 +-}
4649 +-
4650 +diff --git a/libacl/acl_n4tp_ace_trans.c b/libacl/acl_n4tp_ace_trans.c
4651 +deleted file mode 100644
4652 +index c5cc4da..0000000
4653 +--- a/libacl/acl_n4tp_ace_trans.c
4654 ++++ /dev/null
4655 +@@ -1,76 +0,0 @@
4656 +-/*
4657 +- * NFSv4 ACL Code
4658 +- * Translate an NFSv4 ace to a POSIX ace.
4659 +- *
4660 +- * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
4661 +- * All rights reserved.
4662 +- *
4663 +- * Nathaniel Gallaher <ngallahe@×××××.edu>
4664 +- *
4665 +- * Redistribution and use in source and binary forms, with or without
4666 +- * modification, are permitted provided that the following conditions
4667 +- * are met:
4668 +- *
4669 +- * 1. Redistributions of source code must retain the above copyright
4670 +- * notice, this list of conditions and the following disclaimer.
4671 +- * 2. Redistributions in binary form must reproduce the above copyright
4672 +- * notice, this list of conditions and the following disclaimer in the
4673 +- * documentation and/or other materials provided with the distribution.
4674 +- * 3. Neither the name of the University nor the names of its
4675 +- * contributors may be used to endorse or promote products derived
4676 +- * from this software without specific prior written permission.
4677 +- *
4678 +- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
4679 +- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
4680 +- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
4681 +- * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
4682 +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
4683 +- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
4684 +- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
4685 +- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
4686 +- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4687 +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4688 +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4689 +- */
4690 +-
4691 +-#include "libacl_nfs4.h"
4692 +-
4693 +-int acl_n4tp_ace_trans(struct nfs4_ace *ace, acl_t *pacl, acl_tag_t tag,
4694 +- int iflags)
4695 +-{
4696 +- int result;
4697 +- acl_entry_t new_ace;
4698 +-
4699 +-
4700 +- if(ace == NULL || pacl == NULL || *pacl == NULL) {
4701 +- errno = EINVAL;
4702 +- goto failed;
4703 +- }
4704 +-
4705 +- result = acl_create_entry(pacl, &new_ace);
4706 +- if(result < 0)
4707 +- goto failed;
4708 +-
4709 +- result = acl_set_tag_type(new_ace, tag);
4710 +- if(result < 0)
4711 +- goto ace_failed;
4712 +-
4713 +- result = acl_n4tp_set_mode(new_ace, ace->access_mask, iflags);
4714 +- if(result < 0)
4715 +- goto ace_failed;
4716 +-
4717 +- if(tag == ACL_USER || tag == ACL_GROUP) {
4718 +- result = acl_n4tp_set_who(new_ace, ace->who, tag);
4719 +- if(result < 0)
4720 +- goto ace_failed;
4721 +- }
4722 +-
4723 +- return 0;
4724 +-
4725 +-ace_failed:
4726 +- acl_delete_entry(*pacl, new_ace);
4727 +-
4728 +-failed:
4729 +- return -1;
4730 +-}
4731 +-
4732 +diff --git a/libacl/acl_n4tp_acl_trans.c b/libacl/acl_n4tp_acl_trans.c
4733 +index f658242..7fcb992 100644
4734 +--- a/libacl/acl_n4tp_acl_trans.c
4735 ++++ b/libacl/acl_n4tp_acl_trans.c
4736 +@@ -34,27 +34,335 @@
4737 + */
4738 +
4739 + #include <acl/libacl.h>
4740 ++#include <nfsidmap.h>
4741 + #include "libacl_nfs4.h"
4742 +
4743 +-acl_t acl_n4tp_acl_trans(struct nfs4_acl * nacl_p, acl_type_t ptype)
4744 ++
4745 ++/*
4746 ++ * While processing the NFSv4 ACE, this maintains bitmasks representing
4747 ++ * which permission bits have been allowed and which denied to a given
4748 ++ * entity: */
4749 ++struct posix_ace_state {
4750 ++ u_int32_t allow;
4751 ++ u_int32_t deny;
4752 ++};
4753 ++
4754 ++struct posix_user_ace_state {
4755 ++ uid_t uid;
4756 ++ struct posix_ace_state perms;
4757 ++};
4758 ++
4759 ++struct posix_ace_state_array {
4760 ++ int n;
4761 ++ struct posix_user_ace_state aces[];
4762 ++};
4763 ++
4764 ++/*
4765 ++ * While processing the NFSv4 ACE, this maintains the partial permissions
4766 ++ * calculated so far: */
4767 ++
4768 ++struct posix_acl_state {
4769 ++ struct posix_ace_state owner;
4770 ++ struct posix_ace_state group;
4771 ++ struct posix_ace_state other;
4772 ++ struct posix_ace_state everyone;
4773 ++ struct posix_ace_state mask; /* Deny unused in this case */
4774 ++ struct posix_ace_state_array *users;
4775 ++ struct posix_ace_state_array *groups;
4776 ++};
4777 ++
4778 ++static int
4779 ++init_state(struct posix_acl_state *state, int cnt)
4780 ++{
4781 ++ int alloc;
4782 ++
4783 ++ memset(state, 0, sizeof(struct posix_acl_state));
4784 ++ /*
4785 ++ * In the worst case, each individual acl could be for a distinct
4786 ++ * named user or group, but we don't no which, so we allocate
4787 ++ * enough space for either:
4788 ++ */
4789 ++ alloc = sizeof(struct posix_ace_state_array)
4790 ++ + cnt*sizeof(struct posix_ace_state);
4791 ++ state->users = calloc(1, alloc);
4792 ++ if (!state->users)
4793 ++ return -ENOMEM;
4794 ++ state->groups = calloc(1, alloc);
4795 ++ if (!state->groups) {
4796 ++ free(state->users);
4797 ++ return -ENOMEM;
4798 ++ }
4799 ++ return 0;
4800 ++}
4801 ++
4802 ++static void
4803 ++free_state(struct posix_acl_state *state) {
4804 ++ free(state->users);
4805 ++ free(state->groups);
4806 ++}
4807 ++
4808 ++static inline void add_to_mask(struct posix_acl_state *state, struct posix_ace_state *astate)
4809 ++{
4810 ++ state->mask.allow |= astate->allow;
4811 ++}
4812 ++
4813 ++/*
4814 ++ * We only map from NFSv4 to POSIX ACLs when getting ACLs, when we err on the
4815 ++ * side of permissiveness (so as not to make the file appear more secure than
4816 ++ * it really is), so the mode bit mapping below is optimistic.
4817 ++ */
4818 ++static void
4819 ++set_mode_from_nfs4(acl_entry_t pace, u_int32_t perm, int is_dir)
4820 ++{
4821 ++ u32 write_mode = NFS4_WRITE_MODE;
4822 ++ acl_permset_t perms;
4823 ++
4824 ++ acl_get_permset(pace, &perms);
4825 ++ acl_clear_perms(perms);
4826 ++ if (is_dir)
4827 ++ write_mode |= NFS4_ACE_DELETE_CHILD;
4828 ++ if (perm & NFS4_READ_MODE)
4829 ++ acl_add_perm(perms, ACL_READ);
4830 ++ if (perm & write_mode)
4831 ++ acl_add_perm(perms, ACL_WRITE);
4832 ++ if (perm & NFS4_EXECUTE_MODE)
4833 ++ acl_add_perm(perms, ACL_EXECUTE);
4834 ++ acl_set_permset(pace, perms);
4835 ++}
4836 ++
4837 ++/* XXX: add a "check allow" that can warn on e.g. allows of WRITE_ACL
4838 ++ * to non-owner? */
4839 ++
4840 ++/* XXX: replace error returns by errno sets all over. Ugh. */
4841 ++
4842 ++static acl_t
4843 ++posix_state_to_acl(struct posix_acl_state *state, int is_dir)
4844 ++{
4845 ++ acl_entry_t pace;
4846 ++ acl_t pacl;
4847 ++ int nace;
4848 ++ int i, error = 0;
4849 ++
4850 ++ nace = 4 + state->users->n + state->groups->n;
4851 ++ pacl = acl_init(nace);
4852 ++ if (!pacl)
4853 ++ return NULL;
4854 ++
4855 ++ error = acl_create_entry(&pacl, &pace);
4856 ++ if (error)
4857 ++ goto out_err;
4858 ++ acl_set_tag_type(pace, ACL_USER_OBJ);
4859 ++ set_mode_from_nfs4(pace, state->owner.allow, is_dir);
4860 ++
4861 ++ for (i=0; i < state->users->n; i++) {
4862 ++ error = acl_create_entry(&pacl, &pace);
4863 ++ if (error)
4864 ++ goto out_err;
4865 ++ acl_set_tag_type(pace, ACL_USER);
4866 ++ set_mode_from_nfs4(pace, state->users->aces[i].perms.allow,
4867 ++ is_dir);
4868 ++ acl_set_qualifier(pace, &state->users->aces[i].uid);
4869 ++ add_to_mask(state, &state->users->aces[i].perms);
4870 ++ }
4871 ++
4872 ++ error = acl_create_entry(&pacl, &pace);
4873 ++ if (error)
4874 ++ goto out_err;
4875 ++ acl_set_tag_type(pace, ACL_GROUP_OBJ);
4876 ++ set_mode_from_nfs4(pace, state->group.allow, is_dir);
4877 ++ add_to_mask(state, &state->group);
4878 ++
4879 ++ for (i=0; i < state->groups->n; i++) {
4880 ++ error = acl_create_entry(&pacl, &pace);
4881 ++ if (error)
4882 ++ goto out_err;
4883 ++ acl_set_tag_type(pace, ACL_GROUP);
4884 ++ set_mode_from_nfs4(pace, state->groups->aces[i].perms.allow,
4885 ++ is_dir);
4886 ++ acl_set_qualifier(pace, &state->groups->aces[i].uid);
4887 ++ add_to_mask(state, &state->groups->aces[i].perms);
4888 ++ }
4889 ++
4890 ++ error = acl_create_entry(&pacl, &pace);
4891 ++ if (error)
4892 ++ goto out_err;
4893 ++ acl_set_tag_type(pace, ACL_MASK);
4894 ++ set_mode_from_nfs4(pace, state->mask.allow, is_dir);
4895 ++
4896 ++ error = acl_create_entry(&pacl, &pace);
4897 ++ if (error)
4898 ++ goto out_err;
4899 ++ acl_set_tag_type(pace, ACL_OTHER);
4900 ++ set_mode_from_nfs4(pace, state->other.allow, is_dir);
4901 ++
4902 ++ return pacl;
4903 ++out_err:
4904 ++ acl_free(pacl);
4905 ++ return NULL;
4906 ++}
4907 ++
4908 ++static inline void allow_bits(struct posix_ace_state *astate, u32 mask)
4909 ++{
4910 ++ /* Allow all bits in the mask not already denied: */
4911 ++ astate->allow |= mask & ~astate->deny;
4912 ++}
4913 ++
4914 ++static inline void deny_bits(struct posix_ace_state *astate, u32 mask)
4915 ++{
4916 ++ /* Deny all bits in the mask not already allowed: */
4917 ++ astate->deny |= mask & ~astate->allow;
4918 ++}
4919 ++
4920 ++static int find_uid(struct posix_acl_state *state, struct posix_ace_state_array *a, uid_t uid)
4921 ++{
4922 ++ int i;
4923 ++
4924 ++ for (i = 0; i < a->n; i++)
4925 ++ if (a->aces[i].uid == uid)
4926 ++ return i;
4927 ++ /* Not found: */
4928 ++ a->n++;
4929 ++ a->aces[i].uid = uid;
4930 ++ a->aces[i].perms.allow = state->everyone.allow;
4931 ++ a->aces[i].perms.deny = state->everyone.deny;
4932 ++
4933 ++ return i;
4934 ++}
4935 ++
4936 ++static void deny_bits_array(struct posix_ace_state_array *a, u32 mask)
4937 ++{
4938 ++ int i;
4939 ++
4940 ++ for (i=0; i < a->n; i++)
4941 ++ deny_bits(&a->aces[i].perms, mask);
4942 ++}
4943 ++
4944 ++static void allow_bits_array(struct posix_ace_state_array *a, u32 mask)
4945 ++{
4946 ++ int i;
4947 ++
4948 ++ for (i=0; i < a->n; i++)
4949 ++ allow_bits(&a->aces[i].perms, mask);
4950 ++}
4951 ++
4952 ++static acl_tag_t acl_n4tp_get_whotype(struct nfs4_ace *ace)
4953 + {
4954 ++ int nfs4type;
4955 ++ int result;
4956 ++
4957 ++ result = acl_nfs4_get_who(ace, &nfs4type, NULL);
4958 ++ if (result < 0)
4959 ++ return -1;
4960 ++
4961 ++ switch (nfs4type) {
4962 ++ case NFS4_ACL_WHO_NAMED:
4963 ++ return (ace->flag & NFS4_ACE_IDENTIFIER_GROUP ?
4964 ++ ACL_GROUP : ACL_USER);
4965 ++ case NFS4_ACL_WHO_OWNER:
4966 ++ return ACL_USER_OBJ;
4967 ++ case NFS4_ACL_WHO_GROUP:
4968 ++ return ACL_GROUP_OBJ;
4969 ++ case NFS4_ACL_WHO_EVERYONE:
4970 ++ return ACL_OTHER;
4971 ++ }
4972 ++ errno = EINVAL;
4973 ++ return -1;
4974 ++}
4975 ++
4976 ++static int process_one_v4_ace(struct posix_acl_state *state,
4977 ++ struct nfs4_ace *ace)
4978 ++{
4979 ++ u32 mask = ace->access_mask;
4980 ++ uid_t id;
4981 ++ int i;
4982 ++
4983 ++ if (nfs4_init_name_mapping(NULL))
4984 ++ return -1;
4985 ++
4986 ++ switch (acl_n4tp_get_whotype(ace)) {
4987 ++ case ACL_USER_OBJ:
4988 ++ if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
4989 ++ allow_bits(&state->owner, mask);
4990 ++ } else {
4991 ++ deny_bits(&state->owner, mask);
4992 ++ }
4993 ++ break;
4994 ++ case ACL_USER:
4995 ++ if (nfs4_name_to_uid(ace->who, &id))
4996 ++ return -1;
4997 ++ i = find_uid(state, state->users, id);
4998 ++ if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
4999 ++ allow_bits(&state->users->aces[i].perms, mask);
5000 ++ mask = state->users->aces[i].perms.allow;
5001 ++ allow_bits(&state->owner, mask);
5002 ++ } else {
5003 ++ deny_bits(&state->users->aces[i].perms, mask);
5004 ++ }
5005 ++ break;
5006 ++ case ACL_GROUP_OBJ:
5007 ++ if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
5008 ++ allow_bits(&state->group, mask);
5009 ++ mask = state->group.allow;
5010 ++ allow_bits(&state->owner, mask);
5011 ++ allow_bits(&state->everyone, mask);
5012 ++ allow_bits_array(state->users, mask);
5013 ++ allow_bits_array(state->groups, mask);
5014 ++ } else {
5015 ++ deny_bits(&state->group, mask);
5016 ++ }
5017 ++ break;
5018 ++ case ACL_GROUP:
5019 ++ if (nfs4_name_to_gid(ace->who, &id))
5020 ++ return -1;
5021 ++ i = find_uid(state, state->groups, id);
5022 ++ if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
5023 ++ allow_bits(&state->groups->aces[i].perms, mask);
5024 ++ mask = state->groups->aces[i].perms.allow;
5025 ++ allow_bits(&state->owner, mask);
5026 ++ allow_bits(&state->group, mask);
5027 ++ allow_bits(&state->everyone, mask);
5028 ++ allow_bits_array(state->users, mask);
5029 ++ allow_bits_array(state->groups, mask);
5030 ++ } else {
5031 ++ deny_bits(&state->groups->aces[i].perms, mask);
5032 ++ }
5033 ++ break;
5034 ++ case ACL_OTHER:
5035 ++ if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
5036 ++ allow_bits(&state->owner, mask);
5037 ++ allow_bits(&state->group, mask);
5038 ++ allow_bits(&state->other, mask);
5039 ++ allow_bits(&state->everyone, mask);
5040 ++ allow_bits_array(state->users, mask);
5041 ++ allow_bits_array(state->groups, mask);
5042 ++ } else {
5043 ++ deny_bits(&state->owner, mask);
5044 ++ deny_bits(&state->group, mask);
5045 ++ deny_bits(&state->other, mask);
5046 ++ deny_bits(&state->everyone, mask);
5047 ++ deny_bits_array(state->users, mask);
5048 ++ deny_bits_array(state->groups, mask);
5049 ++ }
5050 ++ }
5051 ++ return 0;
5052 ++}
5053 +
5054 +- acl_t pacl_p = NULL;
5055 +- acl_t * pacl_pp;
5056 ++acl_t acl_n4tp_acl_trans(struct nfs4_acl * nacl_p, acl_type_t ptype)
5057 ++{
5058 ++ struct posix_acl_state state;
5059 ++ acl_t pacl;
5060 + struct nfs4_acl * temp_acl;
5061 +- int naces = -1;
5062 + int num_aces;
5063 + int ace_num;
5064 + struct nfs4_ace * cur_ace = NULL;
5065 +- struct nfs4_ace * mask_ace = NULL;
5066 + struct nfs4_ace * temp_ace = NULL;
5067 +- int result;
5068 ++ int ret;
5069 + u32 flags;
5070 + u32 iflags = NFS4_ACL_NOFLAGS;
5071 +
5072 + if (nacl_p == NULL) {
5073 + errno = EINVAL;
5074 +- goto failed;
5075 ++ return NULL;
5076 + }
5077 +
5078 + if (ptype == ACL_TYPE_DEFAULT) {
5079 +@@ -62,25 +370,25 @@ acl_t acl_n4tp_acl_trans(struct nfs4_acl * nacl_p, acl_type_t ptype)
5080 + iflags |= NFS4_ACL_REQUEST_DEFAULT;
5081 + else {
5082 + errno = EINVAL;
5083 +- goto failed;
5084 ++ return NULL;
5085 + }
5086 + }
5087 +
5088 + /* Copy so we can delete bits without borking the original */
5089 + temp_acl = acl_nfs4_copy_acl(nacl_p);
5090 + if (temp_acl == NULL)
5091 +- goto failed;
5092 ++ return NULL;
5093 +
5094 + num_aces = temp_acl->naces;
5095 +
5096 + /* Strip or keep inheritance aces depending upon the type of posix acl
5097 + * requested */
5098 +- cur_ace = acl_nfs4_get_first_ace(temp_acl);
5099 ++ cur_ace = temp_acl->ace_head.tqh_first;
5100 + ace_num = 1;
5101 +
5102 +- while(1) {
5103 +- if(cur_ace == NULL) {
5104 +- if(ace_num > num_aces)
5105 ++ while (1) {
5106 ++ if (cur_ace == NULL) {
5107 ++ if (ace_num > num_aces)
5108 + break;
5109 + else
5110 + goto free_failed;
5111 +@@ -88,10 +396,11 @@ acl_t acl_n4tp_acl_trans(struct nfs4_acl * nacl_p, acl_type_t ptype)
5112 +
5113 + /* get the next ace now because we may be freeing the current ace */
5114 + temp_ace = cur_ace;
5115 +- acl_nfs4_get_next_ace(&cur_ace);
5116 ++ cur_ace = cur_ace->l_ace.tqe_next;
5117 +
5118 + flags = temp_ace->flag;
5119 +
5120 ++ /* XXX: bring in sync with current kernel: */
5121 + if (iflags & NFS4_ACL_REQUEST_DEFAULT) {
5122 + if((flags & NFS4_INHERITANCE_FLAGS) != NFS4_INHERITANCE_FLAGS)
5123 + acl_nfs4_remove_ace(temp_acl, temp_ace);
5124 +@@ -104,61 +413,32 @@ acl_t acl_n4tp_acl_trans(struct nfs4_acl * nacl_p, acl_type_t ptype)
5125 + ace_num++;
5126 + }
5127 +
5128 +-
5129 +- naces = acl_n4tp_ace_count(temp_acl);
5130 +- if (naces < 0) {
5131 +- errno = EINVAL;
5132 ++ ret = init_state(&state, temp_acl->naces);
5133 ++ if (ret)
5134 + goto free_failed;
5135 +- }
5136 +-
5137 +- if (naces == 0)
5138 +- return acl_init(0);
5139 +-
5140 +- pacl_p = acl_init(naces);
5141 +-
5142 +- if(pacl_p == NULL)
5143 +- goto free_failed;
5144 +-
5145 +- pacl_pp = &pacl_p;
5146 +
5147 +- cur_ace = acl_nfs4_get_first_ace(temp_acl);
5148 +-
5149 +- result = user_obj_from_v4(temp_acl, &cur_ace, pacl_pp, iflags);
5150 +- if(result < 0)
5151 +- goto acl_free_failed;
5152 +-
5153 +- result = users_from_v4(temp_acl, &cur_ace, &mask_ace, pacl_pp, iflags);
5154 +- if(result < 0)
5155 +- goto acl_free_failed;
5156 +-
5157 +- result = group_obj_and_groups_from_v4(temp_acl, &cur_ace,
5158 +- &mask_ace, pacl_pp, iflags);
5159 +- if(result < 0)
5160 +- goto acl_free_failed;
5161 +-
5162 +- result = mask_from_v4(temp_acl, &cur_ace, &mask_ace, pacl_pp, iflags);
5163 +- if(result < 0)
5164 +- goto acl_free_failed;
5165 ++ cur_ace = temp_acl->ace_head.tqh_first;
5166 ++ while (cur_ace) {
5167 ++ if (process_one_v4_ace(&state, cur_ace)) {
5168 ++ free_state(&state);
5169 ++ goto free_failed;
5170 ++ }
5171 ++ cur_ace = cur_ace->l_ace.tqe_next;
5172 ++ }
5173 +
5174 +- result = other_from_v4(temp_acl, &cur_ace, pacl_pp, iflags);
5175 +- if(result < 0)
5176 +- goto acl_free_failed;
5177 ++ acl_nfs4_free(temp_acl);
5178 +
5179 +- result = acl_valid(*pacl_pp);
5180 +- if(result < 0)
5181 +- goto acl_free_failed;
5182 ++ pacl = posix_state_to_acl(&state, nacl_p->is_directory);
5183 +
5184 +- acl_nfs4_free(temp_acl);
5185 ++ free_state(&state);
5186 +
5187 +- return *pacl_pp;
5188 ++ ret = acl_valid(pacl);
5189 ++ if (ret < 0)
5190 ++ goto free_failed;
5191 +
5192 +-acl_free_failed:
5193 +- acl_free(*pacl_pp);
5194 ++ return pacl;
5195 +
5196 + free_failed:
5197 + acl_nfs4_free(temp_acl);
5198 +-
5199 +-failed:
5200 + return NULL;
5201 + }
5202 +-
5203 +diff --git a/libacl/acl_n4tp_get_whotype.c b/libacl/acl_n4tp_get_whotype.c
5204 +deleted file mode 100644
5205 +index fd553c6..0000000
5206 +--- a/libacl/acl_n4tp_get_whotype.c
5207 ++++ /dev/null
5208 +@@ -1,73 +0,0 @@
5209 +-/*
5210 +- * NFSv4 ACL Code
5211 +- * Convert NFSv4 ACE who to a POSIX ACE whotype
5212 +- *
5213 +- * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
5214 +- * All rights reserved.
5215 +- *
5216 +- * Nathaniel Gallaher <ngallahe@×××××.edu>
5217 +- *
5218 +- * Redistribution and use in source and binary forms, with or without
5219 +- * modification, are permitted provided that the following conditions
5220 +- * are met:
5221 +- *
5222 +- * 1. Redistributions of source code must retain the above copyright
5223 +- * notice, this list of conditions and the following disclaimer.
5224 +- * 2. Redistributions in binary form must reproduce the above copyright
5225 +- * notice, this list of conditions and the following disclaimer in the
5226 +- * documentation and/or other materials provided with the distribution.
5227 +- * 3. Neither the name of the University nor the names of its
5228 +- * contributors may be used to endorse or promote products derived
5229 +- * from this software without specific prior written permission.
5230 +- *
5231 +- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
5232 +- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
5233 +- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
5234 +- * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
5235 +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
5236 +- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
5237 +- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
5238 +- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
5239 +- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
5240 +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5241 +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5242 +- */
5243 +-
5244 +-#include <acl/libacl.h>
5245 +-#include "libacl_nfs4.h"
5246 +-
5247 +-acl_tag_t acl_n4tp_get_whotype(struct nfs4_ace *ace)
5248 +-{
5249 +- int nfs4type;
5250 +- int result;
5251 +-
5252 +- if(ace == NULL)
5253 +- goto inval_failed;
5254 +-
5255 +- if(ace->who == NULL || strlen(ace->who) <= 0)
5256 +- goto inval_failed;
5257 +-
5258 +- result = acl_nfs4_get_who(ace, &nfs4type, NULL);
5259 +- if ( result < 0 )
5260 +- goto failed;
5261 +-
5262 +- switch (nfs4type) {
5263 +- case NFS4_ACL_WHO_NAMED:
5264 +- return (ace->flag & NFS4_ACE_IDENTIFIER_GROUP ?
5265 +- ACL_GROUP : ACL_USER);
5266 +- case NFS4_ACL_WHO_OWNER:
5267 +- return ACL_USER_OBJ;
5268 +- case NFS4_ACL_WHO_GROUP:
5269 +- return ACL_GROUP_OBJ;
5270 +- case NFS4_ACL_WHO_EVERYONE:
5271 +- return ACL_OTHER;
5272 +- }
5273 +-
5274 +-inval_failed:
5275 +- errno = EINVAL;
5276 +-
5277 +-failed:
5278 +- return -1;
5279 +-}
5280 +-
5281 +-
5282 +diff --git a/libacl/acl_n4tp_set_mode.c b/libacl/acl_n4tp_set_mode.c
5283 +deleted file mode 100644
5284 +index bef5e23..0000000
5285 +--- a/libacl/acl_n4tp_set_mode.c
5286 ++++ /dev/null
5287 +@@ -1,98 +0,0 @@
5288 +-/*
5289 +- * NFSv4 ACL Code
5290 +- * Set posix ACL mode based on NFSv4 mask
5291 +- * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
5292 +- * All rights reserved.
5293 +- *
5294 +- * Nathaniel Gallaher <ngallahe@×××××.edu>
5295 +- *
5296 +- * Redistribution and use in source and binary forms, with or without
5297 +- * modification, are permitted provided that the following conditions
5298 +- * are met:
5299 +- *
5300 +- * 1. Redistributions of source code must retain the above copyright
5301 +- * notice, this list of conditions and the following disclaimer.
5302 +- * 2. Redistributions in binary form must reproduce the above copyright
5303 +- * notice, this list of conditions and the following disclaimer in the
5304 +- * documentation and/or other materials provided with the distribution.
5305 +- * 3. Neither the name of the University nor the names of its
5306 +- * contributors may be used to endorse or promote products derived
5307 +- * from this software without specific prior written permission.
5308 +- *
5309 +- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
5310 +- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
5311 +- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
5312 +- * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
5313 +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
5314 +- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
5315 +- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
5316 +- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
5317 +- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
5318 +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5319 +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5320 +- */
5321 +-
5322 +-#include <acl/libacl.h>
5323 +-#include "libacl_nfs4.h"
5324 +-
5325 +-int acl_n4tp_set_mode(acl_entry_t pace, u32 nfs4_access_mask, int iflags)
5326 +-{
5327 +- /* XXX we might also want to ignore DELETE_CHILD on non-directories */
5328 +- /* XXX also add special interpretation to EXECUTE on directories */
5329 +- u32 ignore = NFS4_ACE_SYNCHRONIZE;
5330 +- u32 new_mask;
5331 +- acl_permset_t perms;
5332 +- int result;
5333 +-
5334 +- if((iflags & NFS4_ACL_ISDIR) != NFS4_ACL_ISDIR)
5335 +- ignore |= NFS4_ACE_DELETE_CHILD;
5336 +-
5337 +- nfs4_access_mask |= ignore;
5338 +-
5339 +- result = acl_get_permset(pace, &perms);
5340 +- if(result < 0)
5341 +- goto failed;
5342 +-
5343 +- result = acl_clear_perms(perms);
5344 +- if(result < 0)
5345 +- goto failed;
5346 +-
5347 +- if ((nfs4_access_mask & NFS4_READ_MODE) == NFS4_READ_MODE) {
5348 +- result = acl_add_perm(perms, ACL_READ);
5349 +- if(result < 0)
5350 +- goto failed;
5351 +- }
5352 +-
5353 +- if ((nfs4_access_mask & NFS4_WRITE_MODE) == NFS4_WRITE_MODE) {
5354 +- result = acl_add_perm(perms, ACL_WRITE);
5355 +- if(result < 0)
5356 +- goto failed;
5357 +- }
5358 +-
5359 +- if ((nfs4_access_mask & NFS4_EXECUTE_MODE) == NFS4_EXECUTE_MODE) {
5360 +- result = acl_add_perm(perms, ACL_EXECUTE);
5361 +- if(result < 0)
5362 +- goto failed;
5363 +- }
5364 +-
5365 +- result = acl_ptn4_get_mask(&new_mask, perms, iflags);
5366 +- if(result < 0)
5367 +- goto failed;
5368 +-
5369 +- new_mask |= ignore;
5370 +-
5371 +- if (!MASK_EQUAL(nfs4_access_mask, new_mask)) {
5372 +- errno = EINVAL;
5373 +- goto failed;
5374 +- }
5375 +-
5376 +- result = acl_set_permset(pace, perms);
5377 +- if(result < 0)
5378 +- goto failed;
5379 +-
5380 +- return 0;
5381 +-
5382 +-failed:
5383 +- return -1;
5384 +-}
5385 +-
5386 +diff --git a/libacl/acl_n4tp_set_who.c b/libacl/acl_n4tp_set_who.c
5387 +deleted file mode 100644
5388 +index 241ef71..0000000
5389 +--- a/libacl/acl_n4tp_set_who.c
5390 ++++ /dev/null
5391 +@@ -1,89 +0,0 @@
5392 +-/*
5393 +- * NFSv4 ACL Code
5394 +- * Set the POSIX ACE who based on the whotype and NFS who attr.
5395 +- * Translation is done using the NFS4 mapping functions.
5396 +- *
5397 +- * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
5398 +- * All rights reserved.
5399 +- *
5400 +- * Nathaniel Gallaher <ngallahe@×××××.edu>
5401 +- *
5402 +- * Redistribution and use in source and binary forms, with or without
5403 +- * modification, are permitted provided that the following conditions
5404 +- * are met:
5405 +- *
5406 +- * 1. Redistributions of source code must retain the above copyright
5407 +- * notice, this list of conditions and the following disclaimer.
5408 +- * 2. Redistributions in binary form must reproduce the above copyright
5409 +- * notice, this list of conditions and the following disclaimer in the
5410 +- * documentation and/or other materials provided with the distribution.
5411 +- * 3. Neither the name of the University nor the names of its
5412 +- * contributors may be used to endorse or promote products derived
5413 +- * from this software without specific prior written permission.
5414 +- *
5415 +- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
5416 +- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
5417 +- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
5418 +- * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
5419 +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
5420 +- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
5421 +- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
5422 +- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
5423 +- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
5424 +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5425 +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5426 +- */
5427 +-
5428 +-#include <acl/libacl.h>
5429 +-#include <nfsidmap.h>
5430 +-#include "libacl_nfs4.h"
5431 +-
5432 +-#define PATH_IDMAPDCONF "/etc/idmapd.conf"
5433 +-char *conf_path = PATH_IDMAPDCONF;
5434 +-
5435 +-int acl_n4tp_set_who(acl_entry_t ace, char* who, acl_tag_t who_type)
5436 +-{
5437 +- int result;
5438 +- uid_t uid;
5439 +- gid_t gid;
5440 +-
5441 +- if(ace == NULL || who == NULL) {
5442 +- errno = EINVAL;
5443 +- goto failed;
5444 +- }
5445 +-
5446 +- switch(who_type) {
5447 +- case ACL_USER:
5448 +- result = nfs4_init_name_mapping(NULL);
5449 +- if (result < 0)
5450 +- goto failed;
5451 +- result = nfs4_name_to_uid(who, &uid);
5452 +- if(result < 0)
5453 +- goto failed;
5454 +- result = acl_set_qualifier(ace, (void *) &uid);
5455 +- if(result < 0)
5456 +- goto failed;
5457 +- break;
5458 +- case ACL_GROUP:
5459 +- result = nfs4_init_name_mapping(NULL);
5460 +- if (result < 0)
5461 +- goto failed;
5462 +- result = nfs4_name_to_gid(who, &gid);
5463 +- if(result < 0)
5464 +- goto failed;
5465 +- result = acl_set_qualifier(ace, (void *) &gid);
5466 +- if(result < 0)
5467 +- goto failed;
5468 +- break;
5469 +- default:
5470 +- errno = EINVAL;
5471 +- goto failed;
5472 +- }
5473 +-
5474 +- return 0;
5475 +-
5476 +-failed:
5477 +- return -1;
5478 +-}
5479 +-
5480 +-
5481 +diff --git a/libacl/acl_nfs4_copy_acl.c b/libacl/acl_nfs4_copy_acl.c
5482 +index 94d8a83..4ce63f7 100644
5483 +--- a/libacl/acl_nfs4_copy_acl.c
5484 ++++ b/libacl/acl_nfs4_copy_acl.c
5485 +@@ -54,7 +54,7 @@ struct nfs4_acl * acl_nfs4_copy_acl(struct nfs4_acl * nacl)
5486 + if(new_acl == NULL)
5487 + goto failed;
5488 +
5489 +- ace = acl_nfs4_get_first_ace(nacl);
5490 ++ ace = nacl->ace_head.tqh_first;
5491 + nace = 1;
5492 +
5493 + while(1)
5494 +@@ -71,7 +71,7 @@ struct nfs4_acl * acl_nfs4_copy_acl(struct nfs4_acl * nacl)
5495 + if(result < 0)
5496 + goto free_failed;
5497 +
5498 +- acl_nfs4_get_next_ace(&ace);
5499 ++ ace = ace->l_ace.tqe_next;
5500 + nace++;
5501 + }
5502 +
5503 +diff --git a/libacl/acl_nfs4_utils.c b/libacl/acl_nfs4_utils.c
5504 +deleted file mode 100644
5505 +index 49238ee..0000000
5506 +--- a/libacl/acl_nfs4_utils.c
5507 ++++ /dev/null
5508 +@@ -1,566 +0,0 @@
5509 +-#include <acl/libacl.h>
5510 +-#include "libacl_nfs4.h"
5511 +-
5512 +-int user_obj_from_v4(struct nfs4_acl *n4acl, struct nfs4_ace **n4ace,
5513 +- acl_t *pacl, int iflags)
5514 +-{
5515 +- struct nfs4_ace *ace = *n4ace;
5516 +- struct nfs4_ace *ace2;
5517 +-
5518 +- if (ace == NULL)
5519 +- goto inval_out;
5520 +-
5521 +- if (pacl == NULL || *pacl == NULL)
5522 +- goto inval_out;
5523 +-
5524 +- if (acl_n4tp_get_whotype(ace) != ACL_USER_OBJ)
5525 +- goto inval_out;
5526 +-
5527 +- if(acl_n4tp_ace_trans(ace, pacl, ACL_USER_OBJ, iflags|NFS4_ACL_OWNER) < 0)
5528 +- goto out;
5529 +-
5530 +- ace2 = acl_nfs4_get_next_ace(n4ace);
5531 +- if (ace2 == NULL)
5532 +- goto inval_out;
5533 +-
5534 +- if (!complementary_ace_pair(ace, ace2))
5535 +- goto inval_out;
5536 +-
5537 +- ace2 = acl_nfs4_get_next_ace(n4ace);
5538 +-
5539 +- return 0;
5540 +-
5541 +-inval_out:
5542 +- errno = EINVAL;
5543 +-out:
5544 +- return -1;
5545 +-}
5546 +-
5547 +-/* public */
5548 +-inline struct nfs4_ace * acl_nfs4_get_next_ace(struct nfs4_ace ** ace)
5549 +-{
5550 +- if(ace == NULL || (*ace) == NULL)
5551 +- return NULL;
5552 +-
5553 +- (*ace) = (*ace)->l_ace.tqe_next;
5554 +- return *ace;
5555 +-}
5556 +-
5557 +-/* public */
5558 +-inline struct nfs4_ace * acl_nfs4_get_first_ace(struct nfs4_acl * acl)
5559 +-{
5560 +- if(acl == NULL)
5561 +- return NULL;
5562 +-
5563 +- return acl->ace_head.tqh_first;
5564 +-}
5565 +-
5566 +-
5567 +-
5568 +-
5569 +-int nfs4_get_gid_from_who(gid_t* gid, const char * who)
5570 +-{
5571 +- int islocal;
5572 +- int result;
5573 +-
5574 +- if(who == NULL || gid == NULL) {
5575 +- errno = EINVAL;
5576 +- goto failed;
5577 +- }
5578 +-
5579 +- islocal = is_who_local(who);
5580 +- if(islocal < 0)
5581 +- goto failed;
5582 +- else if (islocal == 1)
5583 +- result = __nfs4_get_local_gid_from_who(gid, who);
5584 +- else
5585 +- result = __nfs4_get_foreign_gid_from_who(gid, who);
5586 +-
5587 +- if(result < 0)
5588 +- goto failed;
5589 +-
5590 +- return 0;
5591 +-
5592 +-failed:
5593 +- return -1;
5594 +-}
5595 +-
5596 +-int __nfs4_get_local_gid_from_who(gid_t* gid, const char * who)
5597 +-{
5598 +- /* XXX Just trim things at the @. We need to pull the local domain
5599 +- * name from the conf file for comparison, and handle foriegn names
5600 +- * as well. Tie this in with idmapd and gssvcd */
5601 +- /* Special whos? */
5602 +-
5603 +- struct group * grent;
5604 +- char * gname_buf = NULL;
5605 +- int gname_buflen;
5606 +- char * char_pos = NULL;
5607 +- int char_posi;
5608 +-
5609 +-
5610 +- if(who == NULL) {
5611 +- errno = EINVAL;
5612 +- goto failed;
5613 +- }
5614 +-
5615 +- gname_buflen = strlen(who);
5616 +- if(gname_buflen <= 0) {
5617 +- errno = EINVAL;
5618 +- goto failed;
5619 +- }
5620 +-
5621 +- char_pos = strchr(who, '@');
5622 +- char_posi = char_pos - who;
5623 +-
5624 +- if((gname_buf = (char*) malloc(sizeof(char) * (char_posi + 1))) == NULL)
5625 +- {
5626 +- errno = ENOMEM;
5627 +- goto failed;
5628 +- }
5629 +-
5630 +- strncpy(gname_buf, who, char_posi);
5631 +- gname_buf[char_posi] = '\0';
5632 +-
5633 +- grent = getgrnam(gname_buf);
5634 +- free(gname_buf);
5635 +-
5636 +- if(grent == NULL)
5637 +- goto failed;
5638 +-
5639 +- *gid = grent->gr_gid;
5640 +-
5641 +- return 0;
5642 +-
5643 +-failed:
5644 +- return -1;
5645 +-}
5646 +-
5647 +-int __nfs4_get_foreign_gid_from_who(gid_t* gid, const char * who)
5648 +-{
5649 +- return -1;
5650 +-}
5651 +-
5652 +-
5653 +-int nfs4_get_uid_from_who(uid_t* uid, const char * who)
5654 +-{
5655 +- int islocal;
5656 +- int result;
5657 +-
5658 +- if(who == NULL || uid == NULL) {
5659 +- errno = EINVAL;
5660 +- goto failed;
5661 +- }
5662 +-
5663 +- islocal = is_who_local(who);
5664 +- if(islocal < 0)
5665 +- goto failed;
5666 +- else if (islocal == 1)
5667 +- result = __nfs4_get_local_uid_from_who(uid, who);
5668 +- else
5669 +- result = __nfs4_get_foreign_uid_from_who(uid, who);
5670 +-
5671 +- if(result < 0)
5672 +- goto failed;
5673 +-
5674 +- return 0;
5675 +-
5676 +-failed:
5677 +- return -1;
5678 +-}
5679 +-
5680 +-int __nfs4_get_local_uid_from_who(uid_t* uid, const char * who)
5681 +-{
5682 +- /* XXX Just trim things at the @. We need to pull the local domain
5683 +- * name from the conf file for comparison, and handle foriegn names
5684 +- * as well. Tie this in with idmapd and gssvcd */
5685 +- /* Special whos? */
5686 +-
5687 +- char* lname_buf;
5688 +- char* char_pos;
5689 +- int lname_buflen;
5690 +- struct passwd *pwent;
5691 +- int char_posi;
5692 +-
5693 +- if(who == NULL) {
5694 +- errno = EINVAL;
5695 +- goto failed;
5696 +- }
5697 +-
5698 +- lname_buflen = strlen(who);
5699 +- if(lname_buflen <= 0) {
5700 +- errno = EINVAL;
5701 +- goto failed;
5702 +- }
5703 +-
5704 +- char_pos = strchr(who, '@');
5705 +- char_posi = char_pos - who;
5706 +-
5707 +- if((lname_buf = (char*) malloc(sizeof(char) * (char_posi + 1))) == NULL)
5708 +- {
5709 +- errno = ENOMEM;
5710 +- goto failed;
5711 +- }
5712 +-
5713 +- strncpy(lname_buf, who, char_posi);
5714 +- lname_buf[char_posi] = '\0';
5715 +-
5716 +- pwent = getpwnam(lname_buf);
5717 +- free(lname_buf);
5718 +-
5719 +- if(pwent == NULL)
5720 +- goto failed;
5721 +-
5722 +- *uid = pwent->pw_uid;
5723 +-
5724 +- return 0;
5725 +-
5726 +-failed:
5727 +- return -1;
5728 +-}
5729 +-
5730 +-
5731 +-
5732 +-int is_who_local(const char * who)
5733 +-{
5734 +- /* -1 on error, 0 for no, 1 for yes */
5735 +- /* TODO: Compare domain to local domain */
5736 +- if(who == NULL){
5737 +- errno = EINVAL;
5738 +- return -1;
5739 +- }
5740 +-
5741 +- if(strchr(who, '@') == NULL) {
5742 +- errno = EINVAL;
5743 +- return -1;
5744 +- }
5745 +-
5746 +- return 1;
5747 +-}
5748 +-
5749 +-int __nfs4_get_foreign_uid_from_who(uid_t* uid, const char * who)
5750 +-{
5751 +- /* TODO: Make this work */
5752 +- return -1;
5753 +-}
5754 +-
5755 +-
5756 +-
5757 +-int users_from_v4(struct nfs4_acl *n4acl, struct nfs4_ace ** n4ace_p,
5758 +- struct nfs4_ace **mask_ace, acl_t *pacl, int iflags)
5759 +-{
5760 +- struct nfs4_ace *ace, *ace2;
5761 +- int result;
5762 +-
5763 +- ace = *n4ace_p;
5764 +-
5765 +- if (ace == NULL) {
5766 +- goto inval_failed;
5767 +- }
5768 +-
5769 +- while (ace != NULL && acl_n4tp_get_whotype(ace) == ACL_USER) {
5770 +- if (ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE)
5771 +- goto inval_failed;
5772 +- if (*mask_ace &&
5773 +- !MASK_EQUAL(ace->access_mask, (*mask_ace)->access_mask))
5774 +- goto inval_failed;
5775 +- *mask_ace = ace;
5776 +-
5777 +- ace = acl_nfs4_get_next_ace(n4ace_p);
5778 +- if (ace == NULL)
5779 +- goto inval_failed;
5780 +- if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE)
5781 +- goto inval_failed;
5782 +- result = acl_n4tp_ace_trans(ace, pacl, ACL_USER, iflags);
5783 +- if (result < 0)
5784 +- goto failed;
5785 +-
5786 +- ace2 = acl_nfs4_get_next_ace(n4ace_p);
5787 +- if (ace2 == NULL)
5788 +- goto failed;
5789 +- if (!complementary_ace_pair(ace, ace2))
5790 +- goto failed;
5791 +- if ((*mask_ace)->flag != ace2->flag ||
5792 +- !same_who(*mask_ace, ace2))
5793 +- goto failed;
5794 +- ace = acl_nfs4_get_next_ace(n4ace_p);
5795 +- }
5796 +-
5797 +- return 0;
5798 +-
5799 +-inval_failed:
5800 +- errno = EINVAL;
5801 +-
5802 +-failed:
5803 +- return -1;
5804 +-}
5805 +-
5806 +-int complementary_ace_pair(struct nfs4_ace *allow, struct nfs4_ace *deny)
5807 +-{
5808 +- return MASK_EQUAL(allow->access_mask, ~deny->access_mask) &&
5809 +- allow->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE &&
5810 +- deny->type == NFS4_ACE_ACCESS_DENIED_ACE_TYPE &&
5811 +- allow->flag == deny->flag &&
5812 +- same_who(allow, deny);
5813 +-}
5814 +-
5815 +-int same_who(struct nfs4_ace *a, struct nfs4_ace *b)
5816 +-{
5817 +- if(!strcmp(a->who, b->who) && strlen(a->who) == strlen(b->who))
5818 +- return 1;
5819 +- return 0;
5820 +-}
5821 +-
5822 +-int group_obj_and_groups_from_v4(struct nfs4_acl *n4acl,
5823 +- struct nfs4_ace ** n4ace_p, struct nfs4_ace **mask_ace,
5824 +- acl_t *pacl, int iflags)
5825 +-{
5826 +- struct nfs4_ace *ace, *ace2;
5827 +- int num_aces;
5828 +- struct ace_container_list_head ace_list;
5829 +- struct ace_container *ace_c = NULL;
5830 +- int result;
5831 +-
5832 +- TAILQ_INIT(&ace_list);
5833 +-
5834 +- ace = *n4ace_p;
5835 +-
5836 +- num_aces = acl_n4tp_ace_count(n4acl);
5837 +-
5838 +- if(num_aces < 0)
5839 +- goto inval_failed;
5840 +-
5841 +- /* group owner (mask and allow aces) */
5842 +-
5843 +- if (num_aces != 3) {
5844 +- /* then the group owner should be preceded by mask */
5845 +- if (ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE)
5846 +- goto inval_failed;
5847 +-
5848 +- /* If we already got a mask, and it doesn't match this one... */
5849 +- if (*mask_ace &&
5850 +- !MASK_EQUAL(ace->access_mask, (*mask_ace)->access_mask))
5851 +- goto inval_failed;
5852 +- *mask_ace = ace;
5853 +- ace = acl_nfs4_get_next_ace(n4ace_p);
5854 +- if (ace == NULL)
5855 +- goto inval_failed;
5856 +-
5857 +- if ((*mask_ace)->flag != ace->flag || !same_who(*mask_ace, ace))
5858 +- goto inval_failed;
5859 +- }
5860 +-
5861 +- if (acl_n4tp_get_whotype(ace) != ACL_GROUP_OBJ)
5862 +- goto inval_failed;
5863 +-
5864 +- if((ace_c = malloc(sizeof(struct ace_container))) == NULL) {
5865 +- errno = ENOMEM;
5866 +- goto failed;
5867 +- }
5868 +- ace_c->ace = ace;
5869 +-
5870 +- TAILQ_INSERT_TAIL(&ace_list, ace_c, l_ace);
5871 +-
5872 +- if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE)
5873 +- goto inval_failed;
5874 +-
5875 +- result = acl_n4tp_ace_trans(ace, pacl, ACL_GROUP_OBJ, iflags);
5876 +- if (result < 0)
5877 +- goto inval_failed;
5878 +-
5879 +- ace = acl_nfs4_get_next_ace(n4ace_p);
5880 +- if (ace == NULL)
5881 +- goto inval_failed;
5882 +-
5883 +- /* groups (mask and allow aces) */
5884 +-
5885 +- while (acl_n4tp_get_whotype(ace) == ACL_GROUP) {
5886 +- if (*mask_ace == NULL)
5887 +- goto inval_failed;
5888 +-
5889 +- if (ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE ||
5890 +- !MASK_EQUAL(ace->access_mask, (*mask_ace)->access_mask))
5891 +- goto inval_failed;
5892 +- *mask_ace = ace;
5893 +-
5894 +- ace = acl_nfs4_get_next_ace(n4ace_p);
5895 +- if (ace == NULL)
5896 +- goto inval_failed;
5897 +-
5898 +- if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE ||
5899 +- !same_who(ace, *mask_ace))
5900 +- goto inval_failed;
5901 +-
5902 +- if((ace_c = malloc(sizeof(struct ace_container))) == NULL) {
5903 +- errno = ENOMEM;
5904 +- goto failed;
5905 +- }
5906 +- ace_c->ace = ace;
5907 +-
5908 +- TAILQ_INSERT_TAIL(&ace_list, ace_c, l_ace);
5909 +-
5910 +- result = acl_n4tp_ace_trans(ace, pacl, ACL_GROUP, iflags);
5911 +- if (result < 0)
5912 +- goto inval_failed;
5913 +-
5914 +- ace = acl_nfs4_get_next_ace(n4ace_p);
5915 +- if (ace == NULL)
5916 +- goto inval_failed;
5917 +- }
5918 +-
5919 +- /* group owner (deny ace) */
5920 +-
5921 +- if (acl_n4tp_get_whotype(ace) != ACL_GROUP_OBJ)
5922 +- goto inval_failed;
5923 +-
5924 +- ace_c = ace_list.tqh_first;
5925 +- ace2 = ace_c->ace;
5926 +- if (!complementary_ace_pair(ace2, ace))
5927 +- goto inval_failed;
5928 +- TAILQ_REMOVE(&ace_list, ace_c, l_ace);
5929 +- free(ace_c);
5930 +-
5931 +- /* groups (deny aces) */
5932 +-
5933 +- while (!TAILQ_IS_EMPTY(ace_list)) {
5934 +- ace = acl_nfs4_get_next_ace(n4ace_p);
5935 +- if (ace == NULL)
5936 +- goto inval_failed;
5937 +- if (acl_n4tp_get_whotype(ace) != ACL_GROUP)
5938 +- goto inval_failed;
5939 +- ace_c = ace_list.tqh_first;
5940 +- ace2 = ace_c->ace;
5941 +- if (!complementary_ace_pair(ace2, ace))
5942 +- goto inval_failed;
5943 +- TAILQ_REMOVE(&ace_list, ace_c, l_ace);
5944 +- free(ace_c);
5945 +- }
5946 +-
5947 +- ace = acl_nfs4_get_next_ace(n4ace_p);
5948 +- if (ace == NULL)
5949 +- goto inval_failed;
5950 +- if (acl_n4tp_get_whotype(ace) != ACL_OTHER)
5951 +- goto inval_failed;
5952 +-
5953 +- return 0;
5954 +-
5955 +-inval_failed:
5956 +- errno = EINVAL;
5957 +-
5958 +-failed:
5959 +- while (!TAILQ_IS_EMPTY(ace_list)) {
5960 +- ace_c = ace_list.tqh_first;
5961 +- TAILQ_REMOVE(&ace_list, ace_c, l_ace);
5962 +- free(ace_c);
5963 +- }
5964 +- return -1;
5965 +-}
5966 +-
5967 +-int
5968 +-other_from_v4(struct nfs4_acl *n4acl,
5969 +- struct nfs4_ace ** n4ace_p, acl_t *pacl, int iflags)
5970 +-{
5971 +- int result;
5972 +- struct nfs4_ace *ace, *ace2;
5973 +-
5974 +- ace = *n4ace_p;
5975 +- if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE)
5976 +- goto inval_failed;
5977 +-
5978 +- result = acl_n4tp_ace_trans(ace, pacl, ACL_OTHER, iflags);
5979 +- if (result < 0)
5980 +- goto failed;
5981 +-
5982 +- ace2 = acl_nfs4_get_next_ace(n4ace_p);
5983 +- if (ace2 == NULL)
5984 +- goto inval_failed;
5985 +-
5986 +- if (!complementary_ace_pair(ace, ace2))
5987 +- goto inval_failed;
5988 +-
5989 +- return 0;
5990 +-
5991 +-inval_failed:
5992 +- errno = EINVAL;
5993 +-
5994 +-failed:
5995 +- return -1;
5996 +-}
5997 +-
5998 +-int mask_from_v4(struct nfs4_acl *n4acl,
5999 +- struct nfs4_ace ** n4ace_p, struct nfs4_ace **mask_ace,
6000 +- acl_t *pacl, int iflags)
6001 +-{
6002 +- int result;
6003 +- struct nfs4_ace *ace;
6004 +-
6005 +- ace = *n4ace_p;
6006 +- if (acl_n4tp_ace_count(n4acl) != 3) {
6007 +- if (*mask_ace == NULL)
6008 +- goto inval_failed;
6009 +- (*mask_ace)->access_mask = ~(*mask_ace)->access_mask;
6010 +-
6011 +- result = acl_n4tp_ace_trans(*mask_ace, pacl, ACL_MASK, iflags);
6012 +- if(result < 0)
6013 +- goto failed;
6014 +-
6015 +- //ace = acl_nfs4_get_next_ace(n4ace_p);
6016 +- //if (ace == NULL)
6017 +- // goto inval_failed;
6018 +- }
6019 +-
6020 +- return 0;
6021 +-
6022 +-inval_failed:
6023 +- errno = EINVAL;
6024 +-
6025 +-failed:
6026 +- return -1;
6027 +-}
6028 +-
6029 +-
6030 +-/*
6031 +-static inline int
6032 +-match_who(struct nfs4_ace *ace, uid_t owner, gid_t group, uid_t who)
6033 +-{
6034 +- switch (ace->whotype) {
6035 +- case NFS4_ACL_WHO_NAMED:
6036 +- return who == ace->who;
6037 +- case NFS4_ACL_WHO_OWNER:
6038 +- return who == owner;
6039 +- case NFS4_ACL_WHO_GROUP:
6040 +- return who == group;
6041 +- case NFS4_ACL_WHO_EVERYONE:
6042 +- return 1;
6043 +- default:
6044 +- return 0;
6045 +- }
6046 +-}
6047 +-*/
6048 +-/* 0 = granted, -EACCES = denied; mask is an nfsv4 mask, not mode bits */
6049 +-/*
6050 +-int
6051 +-nfs4_acl_permission(struct nfs4_acl *acl, uid_t owner, gid_t group,
6052 +- uid_t who, u32 mask)
6053 +-{
6054 +- struct nfs4_ace *ace;
6055 +- u32 allowed = 0;
6056 +-
6057 +- list_for_each_entry(ace, &acl->ace_head, l_ace) {
6058 +- if (!match_who(ace, group, owner, who))
6059 +- continue;
6060 +- switch (ace->type) {
6061 +- case NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE:
6062 +- allowed |= ace->access_mask;
6063 +- if ((allowed & mask) == mask)
6064 +- return 0;
6065 +- break;
6066 +- case NFS4_ACE_ACCESS_DENIED_ACE_TYPE:
6067 +- if (ace->access_mask & mask)
6068 +- return -EACCES;
6069 +- break;
6070 +- }
6071 +- }
6072 +- return -EACCES;
6073 +-}
6074 +-*/
6075 +diff --git a/libacl/acl_nfs4_xattr_pack.c b/libacl/acl_nfs4_xattr_pack.c
6076 +index be92ba4..6274f48 100644
6077 +--- a/libacl/acl_nfs4_xattr_pack.c
6078 ++++ b/libacl/acl_nfs4_xattr_pack.c
6079 +@@ -75,7 +75,7 @@ int acl_nfs4_xattr_pack(struct nfs4_acl * acl, char** bufp)
6080 + rbuflen = sizeof(u32);
6081 + p += sizeof(u32);
6082 +
6083 +- ace = acl_nfs4_get_first_ace(acl);
6084 ++ ace = acl->ace_head.tqh_first;
6085 + ace_num = 1;
6086 +
6087 + while(1)
6088 +@@ -126,7 +126,7 @@ int acl_nfs4_xattr_pack(struct nfs4_acl * acl, char** bufp)
6089 + rbuflen += NFS4_XDR_MOD;
6090 + }
6091 +
6092 +- acl_nfs4_get_next_ace(&ace);
6093 ++ ace = ace->l_ace.tqe_next;
6094 + ace_num++;
6095 + }
6096 +
6097 +diff --git a/libacl/acl_nfs4_xattr_size.c b/libacl/acl_nfs4_xattr_size.c
6098 +index 3719535..a20b5d6 100644
6099 +--- a/libacl/acl_nfs4_xattr_size.c
6100 ++++ b/libacl/acl_nfs4_xattr_size.c
6101 +@@ -51,7 +51,7 @@ int acl_nfs4_xattr_size(struct nfs4_acl * acl)
6102 + /* Space for number of aces */
6103 + size += sizeof(u32);
6104 +
6105 +- ace = acl_nfs4_get_first_ace(acl);
6106 ++ ace = acl->ace_head.tqh_first;
6107 + ace_num = 1;
6108 +
6109 + num_aces = acl->naces;
6110 +@@ -79,7 +79,7 @@ int acl_nfs4_xattr_size(struct nfs4_acl * acl)
6111 + size += NFS4_XDR_MOD;
6112 + }
6113 +
6114 +- acl_nfs4_get_next_ace(&ace);
6115 ++ ace = ace->l_ace.tqe_next;
6116 + ace_num++;
6117 + }
6118 +
6119 +diff --git a/libacl/libacl_nfs4.h b/libacl/libacl_nfs4.h
6120 +index e6a466c..1402f92 100644
6121 +--- a/libacl/libacl_nfs4.h
6122 ++++ b/libacl/libacl_nfs4.h
6123 +@@ -82,14 +82,6 @@ extern void acl_nfs4_remove_ace(struct nfs4_acl * acl, struct nfs4_ace * ace)
6124 +
6125 + /* nfs4 -> posix */
6126 + extern acl_t acl_n4tp_acl_trans(struct nfs4_acl *, acl_type_t);
6127 +-extern int acl_n4tp_set_mode(acl_entry_t pace, u32 nfs4_access_mask,
6128 +- int iflags);
6129 +-extern int acl_n4tp_ace_count(struct nfs4_acl *n4acl);
6130 +-extern int acl_n4tp_ace_trans(struct nfs4_ace *ace, acl_t *pacl,
6131 +- acl_tag_t tag, int iflags);
6132 +-extern int acl_n4tp_set_who(acl_entry_t ace, char* who,
6133 +- acl_tag_t who_type);
6134 +-extern acl_tag_t acl_n4tp_get_whotype(struct nfs4_ace *ace);
6135 +
6136 + /* posix -> nfs4 */
6137 + extern int acl_ptn4_get_mask(u32* mask, acl_permset_t perms,
6138 +@@ -98,37 +90,13 @@ extern int acl_ptn4_acl_trans(acl_t, struct nfs4_acl *, acl_type_t, u32, char*);
6139 +
6140 +
6141 + /** Access Functions **/
6142 +-extern inline struct nfs4_ace *
6143 +- acl_nfs4_get_next_ace(struct nfs4_ace **);
6144 +-extern inline struct nfs4_ace *
6145 +- acl_nfs4_get_first_ace(struct nfs4_acl *);
6146 + extern inline int acl_nfs4_get_whotype(char*);
6147 + extern int acl_nfs4_get_who(struct nfs4_ace*, int*, char**);
6148 +
6149 + /**** Private(?) functions ****/
6150 + acl_t __posix_acl_from_nfs4_xattr(char*, int, acl_type_t, u32);
6151 +-int complementary_ace_pair(struct nfs4_ace *allow, struct nfs4_ace *deny);
6152 +-int same_who(struct nfs4_ace *a, struct nfs4_ace *b);
6153 +
6154 + /* These will change */
6155 +-int nfs4_get_gid_from_who(gid_t* gid, const char * who);
6156 +-int nfs4_get_uid_from_who(uid_t* uid, const char * who);
6157 + char * nfs4_get_who_from_uid(uid_t);
6158 + char * nfs4_get_who_from_gid(gid_t);
6159 +-int __nfs4_get_local_uid_from_who(uid_t* uid, const char * who);
6160 +-int __nfs4_get_foreign_uid_from_who(uid_t* uid, const char * who);
6161 +-int __nfs4_get_local_gid_from_who(gid_t* gid, const char * who);
6162 +-int __nfs4_get_foreign_gid_from_who(gid_t* gid, const char * who);
6163 +-int is_who_local(const char * who);
6164 + /* End change */
6165 +-
6166 +-int user_obj_from_v4(struct nfs4_acl *n4acl, struct nfs4_ace **n4ace,
6167 +- acl_t *pacl, int iflags);
6168 +-int users_from_v4(struct nfs4_acl *n4acl, struct nfs4_ace ** n4ace_p,
6169 +- struct nfs4_ace **mask_ace, acl_t *pacl, int iflags);
6170 +-int group_obj_and_groups_from_v4(struct nfs4_acl *n4acl,
6171 +- struct nfs4_ace ** n4ace_p, struct nfs4_ace **mask_ace, acl_t *pacl, int iflags);
6172 +-int mask_from_v4(struct nfs4_acl *n4acl, struct nfs4_ace ** n4ace_p,
6173 +- struct nfs4_ace **mask_ace, acl_t *pacl, int iflags);
6174 +-int other_from_v4(struct nfs4_acl *n4acl, struct nfs4_ace ** n4ace_p,
6175 +- acl_t *pacl, int iflags);
6176 +--
6177 +1.7.8.1
6178 +
6179
6180 diff --git a/sys-apps/acl/files/0003-NFSv4-POSIX-mapping-clean-up-loop-interation.patch b/sys-apps/acl/files/0003-NFSv4-POSIX-mapping-clean-up-loop-interation.patch
6181 new file mode 100644
6182 index 0000000..34e6ce2
6183 --- /dev/null
6184 +++ b/sys-apps/acl/files/0003-NFSv4-POSIX-mapping-clean-up-loop-interation.patch
6185 @@ -0,0 +1,60 @@
6186 +From 2710403cf7742fd6f919977df4da4797625c4407 Mon Sep 17 00:00:00 2001
6187 +From: "J. Bruce Fields" <bfields@×××××××××××××××××.edu>
6188 +Date: Tue, 12 Dec 2006 16:41:12 -0500
6189 +Subject: [PATCH 03/17] NFSv4->POSIX mapping: clean up loop interation
6190 +
6191 +Clean up slightly over-complicated iteration here.
6192 +---
6193 + libacl/acl_n4tp_acl_trans.c | 16 ++--------------
6194 + 1 files changed, 2 insertions(+), 14 deletions(-)
6195 +
6196 +diff --git a/libacl/acl_n4tp_acl_trans.c b/libacl/acl_n4tp_acl_trans.c
6197 +index 7fcb992..0e505c4 100644
6198 +--- a/libacl/acl_n4tp_acl_trans.c
6199 ++++ b/libacl/acl_n4tp_acl_trans.c
6200 +@@ -353,7 +353,6 @@ acl_t acl_n4tp_acl_trans(struct nfs4_acl * nacl_p, acl_type_t ptype)
6201 + acl_t pacl;
6202 + struct nfs4_acl * temp_acl;
6203 + int num_aces;
6204 +- int ace_num;
6205 + struct nfs4_ace * cur_ace = NULL;
6206 + struct nfs4_ace * temp_ace = NULL;
6207 + int ret;
6208 +@@ -384,23 +383,14 @@ acl_t acl_n4tp_acl_trans(struct nfs4_acl * nacl_p, acl_type_t ptype)
6209 + /* Strip or keep inheritance aces depending upon the type of posix acl
6210 + * requested */
6211 + cur_ace = temp_acl->ace_head.tqh_first;
6212 +- ace_num = 1;
6213 +-
6214 +- while (1) {
6215 +- if (cur_ace == NULL) {
6216 +- if (ace_num > num_aces)
6217 +- break;
6218 +- else
6219 +- goto free_failed;
6220 +- }
6221 +
6222 +- /* get the next ace now because we may be freeing the current ace */
6223 ++ while (cur_ace) {
6224 ++ /* get the next ace now in case we free the current ace */
6225 + temp_ace = cur_ace;
6226 + cur_ace = cur_ace->l_ace.tqe_next;
6227 +
6228 + flags = temp_ace->flag;
6229 +
6230 +- /* XXX: bring in sync with current kernel: */
6231 + if (iflags & NFS4_ACL_REQUEST_DEFAULT) {
6232 + if((flags & NFS4_INHERITANCE_FLAGS) != NFS4_INHERITANCE_FLAGS)
6233 + acl_nfs4_remove_ace(temp_acl, temp_ace);
6234 +@@ -409,8 +399,6 @@ acl_t acl_n4tp_acl_trans(struct nfs4_acl * nacl_p, acl_type_t ptype)
6235 + acl_nfs4_remove_ace(temp_acl, temp_ace);
6236 + }
6237 + }
6238 +-
6239 +- ace_num++;
6240 + }
6241 +
6242 + ret = init_state(&state, temp_acl->naces);
6243 +--
6244 +1.7.8.1
6245 +
6246
6247 diff --git a/sys-apps/acl/files/0004-acl_ptn4_get_mask-style-cleanup.patch b/sys-apps/acl/files/0004-acl_ptn4_get_mask-style-cleanup.patch
6248 new file mode 100644
6249 index 0000000..cab4856
6250 --- /dev/null
6251 +++ b/sys-apps/acl/files/0004-acl_ptn4_get_mask-style-cleanup.patch
6252 @@ -0,0 +1,63 @@
6253 +From 4e2a9689bca5bd260e151e0f5bf877a0720c8b53 Mon Sep 17 00:00:00 2001
6254 +From: "J. Bruce Fields" <bfields@×××××××××××××××××.edu>
6255 +Date: Tue, 12 Dec 2006 16:44:39 -0500
6256 +Subject: [PATCH 04/17] acl_ptn4_get_mask: style cleanup
6257 +
6258 +Minor style cleanup; indentation, if()->if ()
6259 +---
6260 + libacl/acl_ptn4_get_mask.c | 20 ++++++++++----------
6261 + 1 files changed, 10 insertions(+), 10 deletions(-)
6262 +
6263 +diff --git a/libacl/acl_ptn4_get_mask.c b/libacl/acl_ptn4_get_mask.c
6264 +index bee0a97..a6b117b 100644
6265 +--- a/libacl/acl_ptn4_get_mask.c
6266 ++++ b/libacl/acl_ptn4_get_mask.c
6267 +@@ -40,35 +40,35 @@ int acl_ptn4_get_mask(u32* mask, acl_permset_t perms, int iflags)
6268 + {
6269 + int result;
6270 +
6271 +- *mask = NFS4_ANYONE_MODE;
6272 ++ *mask = NFS4_ANYONE_MODE;
6273 +
6274 +- if(perms == NULL) {
6275 ++ if (perms == NULL) {
6276 + errno = EINVAL;
6277 + goto failed;
6278 + }
6279 +
6280 +- if (iflags & NFS4_ACL_OWNER)
6281 +- *mask |= NFS4_OWNER_MODE;
6282 ++ if (iflags & NFS4_ACL_OWNER)
6283 ++ *mask |= NFS4_OWNER_MODE;
6284 +
6285 + result = acl_get_perm(perms, ACL_READ);
6286 +- if(result < 0)
6287 ++ if (result < 0)
6288 + goto failed;
6289 + else if(result == 1)
6290 + *mask |= NFS4_READ_MODE;
6291 +
6292 + result = acl_get_perm(perms, ACL_WRITE);
6293 +- if(result < 0)
6294 ++ if (result < 0)
6295 + goto failed;
6296 +- else if(result == 1) {
6297 ++ else if (result == 1) {
6298 + *mask |= NFS4_WRITE_MODE;
6299 +- if(iflags & NFS4_ACL_ISDIR)
6300 ++ if (iflags & NFS4_ACL_ISDIR)
6301 + *mask |= NFS4_ACE_DELETE_CHILD;
6302 + }
6303 +
6304 + result = acl_get_perm(perms, ACL_EXECUTE);
6305 +- if(result < 0)
6306 ++ if (result < 0)
6307 + goto failed;
6308 +- else if(result == 1)
6309 ++ else if (result == 1)
6310 + *mask |= NFS4_EXECUTE_MODE;
6311 +
6312 + return 0;
6313 +--
6314 +1.7.8.1
6315 +
6316
6317 diff --git a/sys-apps/acl/files/0005-fix-WRITE_MODE.patch b/sys-apps/acl/files/0005-fix-WRITE_MODE.patch
6318 new file mode 100644
6319 index 0000000..07146a2
6320 --- /dev/null
6321 +++ b/sys-apps/acl/files/0005-fix-WRITE_MODE.patch
6322 @@ -0,0 +1,43 @@
6323 +From 2f7a5c64d7e873ee7afc47e420a124b2f5aa26e5 Mon Sep 17 00:00:00 2001
6324 +From: "J. Bruce Fields" <bfields@×××××××××××××××××.edu>
6325 +Date: Tue, 12 Dec 2006 16:46:54 -0500
6326 +Subject: [PATCH 05/17] fix WRITE_MODE
6327 +
6328 +Note only two uses of WRITE_MODE both assume that DELETE_CHILD is not or'd in
6329 +to it.
6330 +---
6331 + include/libacl_nfs4.h | 3 +--
6332 + libacl/libacl_nfs4.h | 3 +--
6333 + 2 files changed, 2 insertions(+), 4 deletions(-)
6334 +
6335 +diff --git a/include/libacl_nfs4.h b/include/libacl_nfs4.h
6336 +index 9103424..ab16450 100644
6337 +--- a/include/libacl_nfs4.h
6338 ++++ b/include/libacl_nfs4.h
6339 +@@ -10,8 +10,7 @@
6340 +
6341 + /* mode bit translations: */
6342 + #define NFS4_READ_MODE NFS4_ACE_READ_DATA
6343 +-#define NFS4_WRITE_MODE (NFS4_ACE_WRITE_DATA \
6344 +- | NFS4_ACE_APPEND_DATA | NFS4_ACE_DELETE_CHILD)
6345 ++#define NFS4_WRITE_MODE (NFS4_ACE_WRITE_DATA | NFS4_ACE_APPEND_DATA)
6346 + #define NFS4_EXECUTE_MODE NFS4_ACE_EXECUTE
6347 + #define NFS4_ANYONE_MODE (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL | \
6348 + NFS4_ACE_SYNCHRONIZE)
6349 +diff --git a/libacl/libacl_nfs4.h b/libacl/libacl_nfs4.h
6350 +index 1402f92..c3d7ef3 100644
6351 +--- a/libacl/libacl_nfs4.h
6352 ++++ b/libacl/libacl_nfs4.h
6353 +@@ -10,8 +10,7 @@
6354 +
6355 + /* mode bit translations: */
6356 + #define NFS4_READ_MODE NFS4_ACE_READ_DATA
6357 +-#define NFS4_WRITE_MODE (NFS4_ACE_WRITE_DATA \
6358 +- | NFS4_ACE_APPEND_DATA | NFS4_ACE_DELETE_CHILD)
6359 ++#define NFS4_WRITE_MODE (NFS4_ACE_WRITE_DATA | NFS4_ACE_APPEND_DATA)
6360 + #define NFS4_EXECUTE_MODE NFS4_ACE_EXECUTE
6361 + #define NFS4_ANYONE_MODE (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL | \
6362 + NFS4_ACE_SYNCHRONIZE)
6363 +--
6364 +1.7.8.1
6365 +
6366
6367 diff --git a/sys-apps/acl/files/0006-Remove-some-some-unused-header-cruft.patch b/sys-apps/acl/files/0006-Remove-some-some-unused-header-cruft.patch
6368 new file mode 100644
6369 index 0000000..68fc2ac
6370 --- /dev/null
6371 +++ b/sys-apps/acl/files/0006-Remove-some-some-unused-header-cruft.patch
6372 @@ -0,0 +1,33 @@
6373 +From 443f30f29aa4a5520d2daf2748444e0cd0196749 Mon Sep 17 00:00:00 2001
6374 +From: "J. Bruce Fields" <bfields@×××××××××××××××××.edu>
6375 +Date: Tue, 12 Dec 2006 16:47:57 -0500
6376 +Subject: [PATCH 06/17] Remove some some unused header cruft
6377 +
6378 +These functions were deleted a while ago; forgot to delete them from both
6379 +copies of header file. (*Why* do we have two copies of this file?)
6380 +---
6381 + include/libacl_nfs4.h | 11 -----------
6382 + 1 files changed, 0 insertions(+), 11 deletions(-)
6383 +
6384 +diff --git a/include/libacl_nfs4.h b/include/libacl_nfs4.h
6385 +index ab16450..c3d7ef3 100644
6386 +--- a/include/libacl_nfs4.h
6387 ++++ b/include/libacl_nfs4.h
6388 +@@ -99,14 +99,3 @@ acl_t __posix_acl_from_nfs4_xattr(char*, int, acl_type_t, u32);
6389 + char * nfs4_get_who_from_uid(uid_t);
6390 + char * nfs4_get_who_from_gid(gid_t);
6391 + /* End change */
6392 +-
6393 +-int user_obj_from_v4(struct nfs4_acl *n4acl, struct nfs4_ace **n4ace,
6394 +- acl_t *pacl, int iflags);
6395 +-int users_from_v4(struct nfs4_acl *n4acl, struct nfs4_ace ** n4ace_p,
6396 +- struct nfs4_ace **mask_ace, acl_t *pacl, int iflags);
6397 +-int group_obj_and_groups_from_v4(struct nfs4_acl *n4acl,
6398 +- struct nfs4_ace ** n4ace_p, struct nfs4_ace **mask_ace, acl_t *pacl, int iflags);
6399 +-int mask_from_v4(struct nfs4_acl *n4acl, struct nfs4_ace ** n4ace_p,
6400 +- struct nfs4_ace **mask_ace, acl_t *pacl, int iflags);
6401 +-int other_from_v4(struct nfs4_acl *n4acl, struct nfs4_ace ** n4ace_p,
6402 +- acl_t *pacl, int iflags);
6403 +--
6404 +1.7.8.1
6405 +
6406
6407 diff --git a/sys-apps/acl/files/0007-NFSv4-POSIX-relax-inheritance-bit-mapping.patch b/sys-apps/acl/files/0007-NFSv4-POSIX-relax-inheritance-bit-mapping.patch
6408 new file mode 100644
6409 index 0000000..48d2bd6
6410 --- /dev/null
6411 +++ b/sys-apps/acl/files/0007-NFSv4-POSIX-relax-inheritance-bit-mapping.patch
6412 @@ -0,0 +1,42 @@
6413 +From ac166c83ea05339fe197b56ea906bed558481eec Mon Sep 17 00:00:00 2001
6414 +From: "J. Bruce Fields" <bfields@×××××××××××××××××.edu>
6415 +Date: Tue, 12 Dec 2006 17:06:17 -0500
6416 +Subject: [PATCH 07/17] NFSv4->POSIX: relax inheritance bit mapping
6417 +
6418 +Relax the inheritance bit mapping, and make it a little more accurate.
6419 +---
6420 + libacl/acl_n4tp_acl_trans.c | 8 +++++---
6421 + 1 files changed, 5 insertions(+), 3 deletions(-)
6422 +
6423 +diff --git a/libacl/acl_n4tp_acl_trans.c b/libacl/acl_n4tp_acl_trans.c
6424 +index 0e505c4..f0f802d 100644
6425 +--- a/libacl/acl_n4tp_acl_trans.c
6426 ++++ b/libacl/acl_n4tp_acl_trans.c
6427 +@@ -384,6 +384,9 @@ acl_t acl_n4tp_acl_trans(struct nfs4_acl * nacl_p, acl_type_t ptype)
6428 + * requested */
6429 + cur_ace = temp_acl->ace_head.tqh_first;
6430 +
6431 ++#define FILE_OR_DIR_INHERIT (NFS4_ACE_FILE_INHERIT_ACE \
6432 ++ | NFS4_ACE_DIRECTORY_INHERIT_ACE)
6433 ++
6434 + while (cur_ace) {
6435 + /* get the next ace now in case we free the current ace */
6436 + temp_ace = cur_ace;
6437 +@@ -392,12 +395,11 @@ acl_t acl_n4tp_acl_trans(struct nfs4_acl * nacl_p, acl_type_t ptype)
6438 + flags = temp_ace->flag;
6439 +
6440 + if (iflags & NFS4_ACL_REQUEST_DEFAULT) {
6441 +- if((flags & NFS4_INHERITANCE_FLAGS) != NFS4_INHERITANCE_FLAGS)
6442 ++ if (!(temp_ace->flag & FILE_OR_DIR_INHERIT))
6443 + acl_nfs4_remove_ace(temp_acl, temp_ace);
6444 + } else {
6445 +- if ((flags & NFS4_INHERITANCE_FLAGS) == NFS4_INHERITANCE_FLAGS) {
6446 ++ if (temp_ace->flag & NFS4_ACE_INHERIT_ONLY_ACE)
6447 + acl_nfs4_remove_ace(temp_acl, temp_ace);
6448 +- }
6449 + }
6450 + }
6451 +
6452 +--
6453 +1.7.8.1
6454 +
6455
6456 diff --git a/sys-apps/acl/files/0008-NFSv4-POSIX-factor-out-inheritance-splitting-code.patch b/sys-apps/acl/files/0008-NFSv4-POSIX-factor-out-inheritance-splitting-code.patch
6457 new file mode 100644
6458 index 0000000..8991891
6459 --- /dev/null
6460 +++ b/sys-apps/acl/files/0008-NFSv4-POSIX-factor-out-inheritance-splitting-code.patch
6461 @@ -0,0 +1,94 @@
6462 +From d55de6fa0c8d2448e55d51ce7b6c9b48fa5632cb Mon Sep 17 00:00:00 2001
6463 +From: "J. Bruce Fields" <bfields@×××××××××××××××××.edu>
6464 +Date: Tue, 12 Dec 2006 17:15:14 -0500
6465 +Subject: [PATCH 08/17] NFSv4->POSIX: factor out inheritance splitting code
6466 +
6467 +Factor out the code that splits out ACEs that are irrelevant (because of
6468 +inheritance bits) into a separate function, do a little more cleanup.
6469 +---
6470 + libacl/acl_n4tp_acl_trans.c | 56 +++++++++++++++++++++---------------------
6471 + 1 files changed, 28 insertions(+), 28 deletions(-)
6472 +
6473 +diff --git a/libacl/acl_n4tp_acl_trans.c b/libacl/acl_n4tp_acl_trans.c
6474 +index f0f802d..b0d2b54 100644
6475 +--- a/libacl/acl_n4tp_acl_trans.c
6476 ++++ b/libacl/acl_n4tp_acl_trans.c
6477 +@@ -347,16 +347,39 @@ static int process_one_v4_ace(struct posix_acl_state *state,
6478 + return 0;
6479 + }
6480 +
6481 ++#define FILE_OR_DIR_INHERIT (NFS4_ACE_FILE_INHERIT_ACE \
6482 ++ | NFS4_ACE_DIRECTORY_INHERIT_ACE)
6483 ++
6484 ++/* Strip or keep inheritance aces depending on type of posix acl requested */
6485 ++static void acl_nfs4_check_inheritance(struct nfs4_acl *acl, u32 iflags)
6486 ++{
6487 ++ struct nfs4_ace * cur_ace;
6488 ++ struct nfs4_ace * temp_ace;
6489 ++
6490 ++ cur_ace = acl->ace_head.tqh_first;
6491 ++
6492 ++ while (cur_ace) {
6493 ++ /* get the next ace now in case we free the current ace */
6494 ++ temp_ace = cur_ace;
6495 ++ cur_ace = cur_ace->l_ace.tqe_next;
6496 ++
6497 ++ if (iflags & NFS4_ACL_REQUEST_DEFAULT) {
6498 ++ if (!(temp_ace->flag & FILE_OR_DIR_INHERIT))
6499 ++ acl_nfs4_remove_ace(acl, temp_ace);
6500 ++ } else {
6501 ++ if (temp_ace->flag & NFS4_ACE_INHERIT_ONLY_ACE)
6502 ++ acl_nfs4_remove_ace(acl, temp_ace);
6503 ++ }
6504 ++ }
6505 ++}
6506 ++
6507 + acl_t acl_n4tp_acl_trans(struct nfs4_acl * nacl_p, acl_type_t ptype)
6508 + {
6509 + struct posix_acl_state state;
6510 + acl_t pacl;
6511 + struct nfs4_acl * temp_acl;
6512 +- int num_aces;
6513 +- struct nfs4_ace * cur_ace = NULL;
6514 +- struct nfs4_ace * temp_ace = NULL;
6515 ++ struct nfs4_ace * cur_ace;
6516 + int ret;
6517 +- u32 flags;
6518 + u32 iflags = NFS4_ACL_NOFLAGS;
6519 +
6520 + if (nacl_p == NULL) {
6521 +@@ -378,30 +401,7 @@ acl_t acl_n4tp_acl_trans(struct nfs4_acl * nacl_p, acl_type_t ptype)
6522 + if (temp_acl == NULL)
6523 + return NULL;
6524 +
6525 +- num_aces = temp_acl->naces;
6526 +-
6527 +- /* Strip or keep inheritance aces depending upon the type of posix acl
6528 +- * requested */
6529 +- cur_ace = temp_acl->ace_head.tqh_first;
6530 +-
6531 +-#define FILE_OR_DIR_INHERIT (NFS4_ACE_FILE_INHERIT_ACE \
6532 +- | NFS4_ACE_DIRECTORY_INHERIT_ACE)
6533 +-
6534 +- while (cur_ace) {
6535 +- /* get the next ace now in case we free the current ace */
6536 +- temp_ace = cur_ace;
6537 +- cur_ace = cur_ace->l_ace.tqe_next;
6538 +-
6539 +- flags = temp_ace->flag;
6540 +-
6541 +- if (iflags & NFS4_ACL_REQUEST_DEFAULT) {
6542 +- if (!(temp_ace->flag & FILE_OR_DIR_INHERIT))
6543 +- acl_nfs4_remove_ace(temp_acl, temp_ace);
6544 +- } else {
6545 +- if (temp_ace->flag & NFS4_ACE_INHERIT_ONLY_ACE)
6546 +- acl_nfs4_remove_ace(temp_acl, temp_ace);
6547 +- }
6548 +- }
6549 ++ acl_nfs4_check_inheritance(temp_acl, iflags);
6550 +
6551 + ret = init_state(&state, temp_acl->naces);
6552 + if (ret)
6553 +--
6554 +1.7.8.1
6555 +
6556
6557 diff --git a/sys-apps/acl/files/0009-NFSv4-POSIX-remove-a-redundant-NULL-check.patch b/sys-apps/acl/files/0009-NFSv4-POSIX-remove-a-redundant-NULL-check.patch
6558 new file mode 100644
6559 index 0000000..515ec9c
6560 --- /dev/null
6561 +++ b/sys-apps/acl/files/0009-NFSv4-POSIX-remove-a-redundant-NULL-check.patch
6562 @@ -0,0 +1,29 @@
6563 +From 0989e9ad282ae0806ec9601d4a1038f4103dc0e6 Mon Sep 17 00:00:00 2001
6564 +From: "J. Bruce Fields" <bfields@×××××××××××××××××.edu>
6565 +Date: Tue, 12 Dec 2006 17:15:54 -0500
6566 +Subject: [PATCH 09/17] NFSv4->POSIX: remove a redundant NULL check
6567 +
6568 +The caller already checks this.
6569 +---
6570 + libacl/acl_n4tp_acl_trans.c | 5 -----
6571 + 1 files changed, 0 insertions(+), 5 deletions(-)
6572 +
6573 +diff --git a/libacl/acl_n4tp_acl_trans.c b/libacl/acl_n4tp_acl_trans.c
6574 +index b0d2b54..a81a06d 100644
6575 +--- a/libacl/acl_n4tp_acl_trans.c
6576 ++++ b/libacl/acl_n4tp_acl_trans.c
6577 +@@ -382,11 +382,6 @@ acl_t acl_n4tp_acl_trans(struct nfs4_acl * nacl_p, acl_type_t ptype)
6578 + int ret;
6579 + u32 iflags = NFS4_ACL_NOFLAGS;
6580 +
6581 +- if (nacl_p == NULL) {
6582 +- errno = EINVAL;
6583 +- return NULL;
6584 +- }
6585 +-
6586 + if (ptype == ACL_TYPE_DEFAULT) {
6587 + if (nacl_p->is_directory)
6588 + iflags |= NFS4_ACL_REQUEST_DEFAULT;
6589 +--
6590 +1.7.8.1
6591 +
6592
6593 diff --git a/sys-apps/acl/files/0010-Minor-header-cleanup.patch b/sys-apps/acl/files/0010-Minor-header-cleanup.patch
6594 new file mode 100644
6595 index 0000000..e6270bf
6596 --- /dev/null
6597 +++ b/sys-apps/acl/files/0010-Minor-header-cleanup.patch
6598 @@ -0,0 +1,59 @@
6599 +From c96b248f388587ebcff23d3a2625054899badcff Mon Sep 17 00:00:00 2001
6600 +From: "J. Bruce Fields" <bfields@×××××××××××××××××.edu>
6601 +Date: Tue, 12 Dec 2006 17:25:43 -0500
6602 +Subject: [PATCH 10/17] Minor header cleanup
6603 +
6604 +Move a define out of common header to where it's actually used.
6605 +---
6606 + include/libacl_nfs4.h | 4 ----
6607 + libacl/acl_ptn4_acl_trans.c | 3 +++
6608 + libacl/libacl_nfs4.h | 4 ----
6609 + 3 files changed, 3 insertions(+), 8 deletions(-)
6610 +
6611 +diff --git a/include/libacl_nfs4.h b/include/libacl_nfs4.h
6612 +index c3d7ef3..b29b802 100644
6613 +--- a/include/libacl_nfs4.h
6614 ++++ b/include/libacl_nfs4.h
6615 +@@ -16,10 +16,6 @@
6616 + NFS4_ACE_SYNCHRONIZE)
6617 + #define NFS4_OWNER_MODE (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL)
6618 +
6619 +-/* flags used to simulate posix default ACLs */
6620 +-#define NFS4_INHERITANCE_FLAGS (NFS4_ACE_FILE_INHERIT_ACE \
6621 +- | NFS4_ACE_DIRECTORY_INHERIT_ACE | NFS4_ACE_INHERIT_ONLY_ACE)
6622 +-
6623 + #define NFS4_ACE_MASK_IGNORE (NFS4_ACE_DELETE | NFS4_ACE_WRITE_OWNER \
6624 + | NFS4_ACE_READ_NAMED_ATTRS | NFS4_ACE_WRITE_NAMED_ATTRS)
6625 + /* XXX not sure about the following. Note that e.g. DELETE_CHILD is wrong in
6626 +diff --git a/libacl/acl_ptn4_acl_trans.c b/libacl/acl_ptn4_acl_trans.c
6627 +index 2e5aa51..3c23f01 100644
6628 +--- a/libacl/acl_ptn4_acl_trans.c
6629 ++++ b/libacl/acl_ptn4_acl_trans.c
6630 +@@ -38,6 +38,9 @@
6631 + #include <nfsidmap.h>
6632 + #include "libacl_nfs4.h"
6633 +
6634 ++/* flags used to simulate posix default ACLs */
6635 ++#define NFS4_INHERITANCE_FLAGS (NFS4_ACE_FILE_INHERIT_ACE \
6636 ++ | NFS4_ACE_DIRECTORY_INHERIT_ACE | NFS4_ACE_INHERIT_ONLY_ACE)
6637 +
6638 + /* Plan:
6639 + * 1: if setting default, remove all purely inherited aces, and replace
6640 +diff --git a/libacl/libacl_nfs4.h b/libacl/libacl_nfs4.h
6641 +index c3d7ef3..b29b802 100644
6642 +--- a/libacl/libacl_nfs4.h
6643 ++++ b/libacl/libacl_nfs4.h
6644 +@@ -16,10 +16,6 @@
6645 + NFS4_ACE_SYNCHRONIZE)
6646 + #define NFS4_OWNER_MODE (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL)
6647 +
6648 +-/* flags used to simulate posix default ACLs */
6649 +-#define NFS4_INHERITANCE_FLAGS (NFS4_ACE_FILE_INHERIT_ACE \
6650 +- | NFS4_ACE_DIRECTORY_INHERIT_ACE | NFS4_ACE_INHERIT_ONLY_ACE)
6651 +-
6652 + #define NFS4_ACE_MASK_IGNORE (NFS4_ACE_DELETE | NFS4_ACE_WRITE_OWNER \
6653 + | NFS4_ACE_READ_NAMED_ATTRS | NFS4_ACE_WRITE_NAMED_ATTRS)
6654 + /* XXX not sure about the following. Note that e.g. DELETE_CHILD is wrong in
6655 +--
6656 +1.7.8.1
6657 +
6658
6659 diff --git a/sys-apps/acl/files/0011-POSIX-NFSv4-relax-inheritance-bit-mapping.patch b/sys-apps/acl/files/0011-POSIX-NFSv4-relax-inheritance-bit-mapping.patch
6660 new file mode 100644
6661 index 0000000..3d97eea
6662 --- /dev/null
6663 +++ b/sys-apps/acl/files/0011-POSIX-NFSv4-relax-inheritance-bit-mapping.patch
6664 @@ -0,0 +1,95 @@
6665 +From cd582e0230f502a8e9710b03ec6375699d2e484e Mon Sep 17 00:00:00 2001
6666 +From: "J. Bruce Fields" <bfields@×××××××××××××××××.edu>
6667 +Date: Tue, 12 Dec 2006 17:37:22 -0500
6668 +Subject: [PATCH 11/17] POSIX->NFSv4: relax inheritance bit mapping
6669 +
6670 +Accept wider range of inheritance bits by e.g. treating file inherit and
6671 +directory inherit as if both were always on if one is.
6672 +---
6673 + libacl/acl_ptn4_acl_trans.c | 30 +++++++++---------------------
6674 + 1 files changed, 9 insertions(+), 21 deletions(-)
6675 +
6676 +diff --git a/libacl/acl_ptn4_acl_trans.c b/libacl/acl_ptn4_acl_trans.c
6677 +index 3c23f01..4dbd4c5 100644
6678 +--- a/libacl/acl_ptn4_acl_trans.c
6679 ++++ b/libacl/acl_ptn4_acl_trans.c
6680 +@@ -38,9 +38,10 @@
6681 + #include <nfsidmap.h>
6682 + #include "libacl_nfs4.h"
6683 +
6684 +-/* flags used to simulate posix default ACLs */
6685 +-#define NFS4_INHERITANCE_FLAGS (NFS4_ACE_FILE_INHERIT_ACE \
6686 +- | NFS4_ACE_DIRECTORY_INHERIT_ACE | NFS4_ACE_INHERIT_ONLY_ACE)
6687 ++
6688 ++#define FILE_OR_DIR_INHERIT (NFS4_ACE_FILE_INHERIT_ACE \
6689 ++ | NFS4_ACE_DIRECTORY_INHERIT_ACE)
6690 ++#define NFS4_INHERITANCE_FLAGS (FILE_OR_DIR_INHERIT | NFS4_ACE_INHERIT_ONLY_ACE)
6691 +
6692 + /* Plan:
6693 + * 1: if setting default, remove all purely inherited aces, and replace
6694 +@@ -48,26 +49,22 @@
6695 + * 2: if setting effective, remove all purely effective aces, and replace
6696 + * all dual-use aces by purely inherited ones
6697 + */
6698 +-
6699 +-int purge_aces(struct nfs4_acl *nacl, acl_type_t type)
6700 ++static void purge_aces(struct nfs4_acl *nacl, acl_type_t type)
6701 + {
6702 + struct nfs4_ace *p, *next;
6703 +
6704 + for (p = nacl->ace_head.tqh_first; p != NULL; p = next) {
6705 + next = p->l_ace.tqe_next;
6706 +
6707 +- switch (p->flag & NFS4_INHERITANCE_FLAGS) {
6708 +- case 0:
6709 ++ if (!(p->flag & FILE_OR_DIR_INHERIT)) {
6710 + /* purely effective */
6711 + if (type == ACL_TYPE_ACCESS)
6712 + acl_nfs4_remove_ace(nacl, p);
6713 +- continue;
6714 +- case NFS4_INHERITANCE_FLAGS:
6715 ++ } else if (p->flag & NFS4_ACE_INHERIT_ONLY_ACE) {
6716 + /* purely inherited */
6717 + if (type == ACL_TYPE_DEFAULT)
6718 + acl_nfs4_remove_ace(nacl, p);
6719 +- break;
6720 +- case NFS4_INHERITANCE_FLAGS & ~NFS4_ACE_INHERIT_ONLY_ACE:
6721 ++ } else {
6722 + /* both effective and inherited */
6723 + if (type == ACL_TYPE_DEFAULT) {
6724 + /* Change to purely effective */
6725 +@@ -76,14 +73,9 @@ int purge_aces(struct nfs4_acl *nacl, acl_type_t type)
6726 + /* Change to purely inherited */
6727 + p->flag |= NFS4_INHERITANCE_FLAGS;
6728 + }
6729 +- break;
6730 +- default:
6731 +- errno = EINVAL;
6732 +- return -1;
6733 + }
6734 +
6735 + }
6736 +- return 0;
6737 + }
6738 +
6739 + int
6740 +@@ -114,9 +106,7 @@ acl_ptn4_acl_trans(acl_t pacl, struct nfs4_acl *acl, acl_type_t type, u32 is_dir
6741 + iflags |= NFS4_ACL_REQUEST_DEFAULT;
6742 + }
6743 +
6744 +- result = purge_aces(acl, type);
6745 +- if (result)
6746 +- return -1;
6747 ++ purge_aces(acl, type);
6748 +
6749 + if (is_dir & NFS4_ACL_ISDIR)
6750 + iflags |= NFS4_ACL_ISDIR;
6751 +@@ -517,5 +507,3 @@ out:
6752 + acl_nfs4_free(acl);
6753 + return -1;
6754 + }
6755 +-
6756 +-
6757 +--
6758 +1.7.8.1
6759 +
6760
6761 diff --git a/sys-apps/acl/files/0012-nfsv4-posix-mapping-don-t-add-unnecessary-masks.patch b/sys-apps/acl/files/0012-nfsv4-posix-mapping-don-t-add-unnecessary-masks.patch
6762 new file mode 100644
6763 index 0000000..47e9177
6764 --- /dev/null
6765 +++ b/sys-apps/acl/files/0012-nfsv4-posix-mapping-don-t-add-unnecessary-masks.patch
6766 @@ -0,0 +1,52 @@
6767 +From 106227f0a4f89724b099114dfb2584b4eb249130 Mon Sep 17 00:00:00 2001
6768 +From: "J. Bruce Fields" <bfields@××××××××××.edu>
6769 +Date: Tue, 30 Jan 2007 18:45:55 -0500
6770 +Subject: [PATCH 12/17] nfsv4->posix mapping: don't add unnecessary masks
6771 +
6772 +Don't add masks to 3-element ACLs unnecessarily; otherwise we never
6773 +translate to a posix ACL exactly equivalent to a mode, which seems a
6774 +little rude.
6775 +
6776 +Signed-off-by: "J. Bruce Fields" <bfields@××××××××××.edu>
6777 +---
6778 + libacl/acl_n4tp_acl_trans.c | 17 +++++++++++------
6779 + 1 files changed, 11 insertions(+), 6 deletions(-)
6780 +
6781 +diff --git a/libacl/acl_n4tp_acl_trans.c b/libacl/acl_n4tp_acl_trans.c
6782 +index a81a06d..eca94ff 100644
6783 +--- a/libacl/acl_n4tp_acl_trans.c
6784 ++++ b/libacl/acl_n4tp_acl_trans.c
6785 +@@ -143,7 +143,10 @@ posix_state_to_acl(struct posix_acl_state *state, int is_dir)
6786 + int nace;
6787 + int i, error = 0;
6788 +
6789 +- nace = 4 + state->users->n + state->groups->n;
6790 ++ if (state->users->n || state->groups->n)
6791 ++ nace = 4 + state->users->n + state->groups->n;
6792 ++ else
6793 ++ nace = 3;
6794 + pacl = acl_init(nace);
6795 + if (!pacl)
6796 + return NULL;
6797 +@@ -183,11 +186,13 @@ posix_state_to_acl(struct posix_acl_state *state, int is_dir)
6798 + add_to_mask(state, &state->groups->aces[i].perms);
6799 + }
6800 +
6801 +- error = acl_create_entry(&pacl, &pace);
6802 +- if (error)
6803 +- goto out_err;
6804 +- acl_set_tag_type(pace, ACL_MASK);
6805 +- set_mode_from_nfs4(pace, state->mask.allow, is_dir);
6806 ++ if (nace > 3) {
6807 ++ error = acl_create_entry(&pacl, &pace);
6808 ++ if (error)
6809 ++ goto out_err;
6810 ++ acl_set_tag_type(pace, ACL_MASK);
6811 ++ set_mode_from_nfs4(pace, state->mask.allow, is_dir);
6812 ++ }
6813 +
6814 + error = acl_create_entry(&pacl, &pace);
6815 + if (error)
6816 +--
6817 +1.7.8.1
6818 +
6819
6820 diff --git a/sys-apps/acl/files/0013-nfsv4-posix-return-zero-length-default-acl-when-appr.patch b/sys-apps/acl/files/0013-nfsv4-posix-return-zero-length-default-acl-when-appr.patch
6821 new file mode 100644
6822 index 0000000..6c16356
6823 --- /dev/null
6824 +++ b/sys-apps/acl/files/0013-nfsv4-posix-return-zero-length-default-acl-when-appr.patch
6825 @@ -0,0 +1,39 @@
6826 +From aaa123a30a393fce1b5c998ef24c236d030fe8e2 Mon Sep 17 00:00:00 2001
6827 +From: "J. Bruce Fields" <bfields@××××××××××.edu>
6828 +Date: Wed, 31 Jan 2007 12:47:27 -0500
6829 +Subject: [PATCH 13/17] nfsv4->posix: return zero-length default acl when
6830 + appropriate
6831 +
6832 +A normal posix acl isn't zero-length: having "no" posix acl is
6833 +equivalent to having a 3-ace posix acl determined by the mode.
6834 +
6835 +Default acls, however, may be zero-length. We should be returning a
6836 +zero-length posix acl when given an nfsv4 acl with no inheritable aces.
6837 +
6838 +Fixes a problem that caused all directories to appear to have a default
6839 +acl that grants no permissions.
6840 +
6841 +Signed-off-by: "J. Bruce Fields" <bfields@××××××××××.edu>
6842 +---
6843 + libacl/acl_n4tp_acl_trans.c | 5 +++++
6844 + 1 files changed, 5 insertions(+), 0 deletions(-)
6845 +
6846 +diff --git a/libacl/acl_n4tp_acl_trans.c b/libacl/acl_n4tp_acl_trans.c
6847 +index eca94ff..62ac81a 100644
6848 +--- a/libacl/acl_n4tp_acl_trans.c
6849 ++++ b/libacl/acl_n4tp_acl_trans.c
6850 +@@ -403,6 +403,11 @@ acl_t acl_n4tp_acl_trans(struct nfs4_acl * nacl_p, acl_type_t ptype)
6851 +
6852 + acl_nfs4_check_inheritance(temp_acl, iflags);
6853 +
6854 ++ if (ptype == ACL_TYPE_DEFAULT && temp_acl->naces == 0) {
6855 ++ acl_nfs4_free(temp_acl);
6856 ++ return acl_init(0);
6857 ++ }
6858 ++
6859 + ret = init_state(&state, temp_acl->naces);
6860 + if (ret)
6861 + goto free_failed;
6862 +--
6863 +1.7.8.1
6864 +
6865
6866 diff --git a/sys-apps/acl/files/0014-nfsd4-remove-spurious-XATTR_REPLACE.patch b/sys-apps/acl/files/0014-nfsd4-remove-spurious-XATTR_REPLACE.patch
6867 new file mode 100644
6868 index 0000000..f2f8402
6869 --- /dev/null
6870 +++ b/sys-apps/acl/files/0014-nfsd4-remove-spurious-XATTR_REPLACE.patch
6871 @@ -0,0 +1,32 @@
6872 +From 6542fbd970376cc7f7cbdfa1a6dfc7efc5149d62 Mon Sep 17 00:00:00 2001
6873 +From: "J. Bruce Fields" <bfields@××××××××××.edu>
6874 +Date: Wed, 9 May 2007 14:20:34 -0400
6875 +Subject: [PATCH 14/17] nfsd4: remove spurious XATTR_REPLACE
6876 +
6877 +For some reason we're calling acl_set_file with XATTR_REPLACE. I have
6878 +no idea why, and it can make it impossible to set an acl on a filesystem
6879 +that didn't previously have one (on those filesystems that don't just
6880 +fake up an acl on their on in this case).
6881 +
6882 +Signed-off-by: "J. Bruce Fields" <bfields@××××××××××.edu>
6883 +---
6884 + libacl/acl_set_file.c | 3 +--
6885 + 1 files changed, 1 insertions(+), 2 deletions(-)
6886 +
6887 +diff --git a/libacl/acl_set_file.c b/libacl/acl_set_file.c
6888 +index 303e39c..ba84999 100644
6889 +--- a/libacl/acl_set_file.c
6890 ++++ b/libacl/acl_set_file.c
6891 +@@ -140,8 +140,7 @@ acl_set_file(const char *path_p, acl_type_t type, acl_t acl)
6892 +
6893 + if (!ext_acl_p)
6894 + return -1;
6895 +-
6896 +- error = setxattr(path_p, name, (char *)ext_acl_p, size, XATTR_REPLACE);
6897 ++ error = setxattr(path_p, name, (char *)ext_acl_p, size, 0);
6898 + free(ext_acl_p);
6899 + return error;
6900 + }
6901 +--
6902 +1.7.8.1
6903 +
6904
6905 diff --git a/sys-apps/acl/files/0015-fix-comment-typo.patch b/sys-apps/acl/files/0015-fix-comment-typo.patch
6906 new file mode 100644
6907 index 0000000..7a01c79
6908 --- /dev/null
6909 +++ b/sys-apps/acl/files/0015-fix-comment-typo.patch
6910 @@ -0,0 +1,28 @@
6911 +From 8d66a2ef07b205b701aa5b3805136ca9320dddd2 Mon Sep 17 00:00:00 2001
6912 +From: "J. Bruce Fields" <bfields@××××××××××.edu>
6913 +Date: Wed, 15 Aug 2007 14:32:36 -0400
6914 +Subject: [PATCH 15/17] fix comment typo
6915 +
6916 +Fix a comment typo
6917 +
6918 +Signed-off-by: J. Bruce Fields <bfields@××××××××××.edu>
6919 +---
6920 + libacl/acl_n4tp_acl_trans.c | 2 +-
6921 + 1 files changed, 1 insertions(+), 1 deletions(-)
6922 +
6923 +diff --git a/libacl/acl_n4tp_acl_trans.c b/libacl/acl_n4tp_acl_trans.c
6924 +index 62ac81a..7708248 100644
6925 +--- a/libacl/acl_n4tp_acl_trans.c
6926 ++++ b/libacl/acl_n4tp_acl_trans.c
6927 +@@ -79,7 +79,7 @@ init_state(struct posix_acl_state *state, int cnt)
6928 + memset(state, 0, sizeof(struct posix_acl_state));
6929 + /*
6930 + * In the worst case, each individual acl could be for a distinct
6931 +- * named user or group, but we don't no which, so we allocate
6932 ++ * named user or group, but we don't know which, so we allocate
6933 + * enough space for either:
6934 + */
6935 + alloc = sizeof(struct posix_ace_state_array)
6936 +--
6937 +1.7.8.1
6938 +
6939
6940 diff --git a/sys-apps/acl/files/0016-fix-nfs4-posix-mapping-state-allocation.patch b/sys-apps/acl/files/0016-fix-nfs4-posix-mapping-state-allocation.patch
6941 new file mode 100644
6942 index 0000000..10c0f9a
6943 --- /dev/null
6944 +++ b/sys-apps/acl/files/0016-fix-nfs4-posix-mapping-state-allocation.patch
6945 @@ -0,0 +1,30 @@
6946 +From 7cb0e09ded7c5c0138fb5e4621f0ce54df1f381e Mon Sep 17 00:00:00 2001
6947 +From: "J. Bruce Fields" <bfields@××××××××××.edu>
6948 +Date: Wed, 15 Aug 2007 16:43:26 -0400
6949 +Subject: [PATCH 16/17] fix nfs4->posix mapping state allocation
6950 +
6951 +Fix allocation of a couple arrays used in the nfs4->posix mapping;
6952 +without this we could get heap corruption when translating acls with
6953 +more than a few users or groups.
6954 +
6955 +Signed-off-by: J. Bruce Fields <bfields@××××××××××.edu>
6956 +---
6957 + libacl/acl_n4tp_acl_trans.c | 2 +-
6958 + 1 files changed, 1 insertions(+), 1 deletions(-)
6959 +
6960 +diff --git a/libacl/acl_n4tp_acl_trans.c b/libacl/acl_n4tp_acl_trans.c
6961 +index 7708248..52972c7 100644
6962 +--- a/libacl/acl_n4tp_acl_trans.c
6963 ++++ b/libacl/acl_n4tp_acl_trans.c
6964 +@@ -83,7 +83,7 @@ init_state(struct posix_acl_state *state, int cnt)
6965 + * enough space for either:
6966 + */
6967 + alloc = sizeof(struct posix_ace_state_array)
6968 +- + cnt*sizeof(struct posix_ace_state);
6969 ++ + cnt*sizeof(struct posix_user_ace_state);
6970 + state->users = calloc(1, alloc);
6971 + if (!state->users)
6972 + return -ENOMEM;
6973 +--
6974 +1.7.8.1
6975 +
6976
6977 diff --git a/sys-apps/acl/files/0017-fix-calculation-of-group-bits.patch b/sys-apps/acl/files/0017-fix-calculation-of-group-bits.patch
6978 new file mode 100644
6979 index 0000000..69cfb07
6980 --- /dev/null
6981 +++ b/sys-apps/acl/files/0017-fix-calculation-of-group-bits.patch
6982 @@ -0,0 +1,99 @@
6983 +From 6dfe0d58bd27ee1b3668831b59a14218a441c3bd Mon Sep 17 00:00:00 2001
6984 +From: "J. Bruce Fields" <bfields@××××××××××.edu>
6985 +Date: Tue, 18 Sep 2007 15:28:34 -0400
6986 +Subject: [PATCH 17/17] fix calculation of group bits
6987 +
6988 +With the current code allowing bits to a group can result in those bits
6989 +also being allowed to other groups. This is unnecessary, as posix group
6990 +permissions already accumulate in most cases.
6991 +
6992 +Signed-off-by: "J. Bruce Fields" <bfields@××××××××××.edu>
6993 +---
6994 + libacl/acl_n4tp_acl_trans.c | 39 +++++++++++++++++++++++++++------------
6995 + 1 files changed, 27 insertions(+), 12 deletions(-)
6996 +
6997 +diff --git a/libacl/acl_n4tp_acl_trans.c b/libacl/acl_n4tp_acl_trans.c
6998 +index 52972c7..3b0563f 100644
6999 +--- a/libacl/acl_n4tp_acl_trans.c
7000 ++++ b/libacl/acl_n4tp_acl_trans.c
7001 +@@ -218,18 +218,36 @@ static inline void deny_bits(struct posix_ace_state *astate, u32 mask)
7002 + astate->deny |= mask & ~astate->allow;
7003 + }
7004 +
7005 +-static int find_uid(struct posix_acl_state *state, struct posix_ace_state_array *a, uid_t uid)
7006 ++static int find_uid(struct posix_acl_state *state, uid_t uid)
7007 + {
7008 + int i;
7009 ++ struct posix_ace_state_array *users = state->users;
7010 +
7011 +- for (i = 0; i < a->n; i++)
7012 +- if (a->aces[i].uid == uid)
7013 ++ for (i = 0; i < users->n; i++)
7014 ++ if (users->aces[i].uid == uid)
7015 + return i;
7016 + /* Not found: */
7017 +- a->n++;
7018 +- a->aces[i].uid = uid;
7019 +- a->aces[i].perms.allow = state->everyone.allow;
7020 +- a->aces[i].perms.deny = state->everyone.deny;
7021 ++ users->n++;
7022 ++ users->aces[i].uid = uid;
7023 ++ users->aces[i].perms.allow = state->everyone.allow;
7024 ++ users->aces[i].perms.deny = state->everyone.deny;
7025 ++
7026 ++ return i;
7027 ++}
7028 ++
7029 ++static int find_gid(struct posix_acl_state *state, uid_t uid)
7030 ++{
7031 ++ int i;
7032 ++ struct posix_ace_state_array *groups = state->groups;
7033 ++
7034 ++ for (i = 0; i < groups->n; i++)
7035 ++ if (groups->aces[i].uid == uid)
7036 ++ return i;
7037 ++ /* Not found: */
7038 ++ groups->n++;
7039 ++ groups->aces[i].uid = uid;
7040 ++ groups->aces[i].perms.allow = state->other.allow;
7041 ++ groups->aces[i].perms.deny = state->other.deny;
7042 +
7043 + return i;
7044 + }
7045 +@@ -295,7 +313,7 @@ static int process_one_v4_ace(struct posix_acl_state *state,
7046 + case ACL_USER:
7047 + if (nfs4_name_to_uid(ace->who, &id))
7048 + return -1;
7049 +- i = find_uid(state, state->users, id);
7050 ++ i = find_uid(state, id);
7051 + if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
7052 + allow_bits(&state->users->aces[i].perms, mask);
7053 + mask = state->users->aces[i].perms.allow;
7054 +@@ -311,7 +329,6 @@ static int process_one_v4_ace(struct posix_acl_state *state,
7055 + allow_bits(&state->owner, mask);
7056 + allow_bits(&state->everyone, mask);
7057 + allow_bits_array(state->users, mask);
7058 +- allow_bits_array(state->groups, mask);
7059 + } else {
7060 + deny_bits(&state->group, mask);
7061 + }
7062 +@@ -319,15 +336,13 @@ static int process_one_v4_ace(struct posix_acl_state *state,
7063 + case ACL_GROUP:
7064 + if (nfs4_name_to_gid(ace->who, &id))
7065 + return -1;
7066 +- i = find_uid(state, state->groups, id);
7067 ++ i = find_gid(state, id);
7068 + if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
7069 + allow_bits(&state->groups->aces[i].perms, mask);
7070 + mask = state->groups->aces[i].perms.allow;
7071 + allow_bits(&state->owner, mask);
7072 +- allow_bits(&state->group, mask);
7073 + allow_bits(&state->everyone, mask);
7074 + allow_bits_array(state->users, mask);
7075 +- allow_bits_array(state->groups, mask);
7076 + } else {
7077 + deny_bits(&state->groups->aces[i].perms, mask);
7078 + }
7079 +--
7080 +1.7.8.1
7081 +
7082
7083 diff --git a/sys-apps/acl/files/acl-2.2.49-quote-strchr.patch b/sys-apps/acl/files/acl-2.2.49-quote-strchr.patch
7084 new file mode 100644
7085 index 0000000..d2510da
7086 --- /dev/null
7087 +++ b/sys-apps/acl/files/acl-2.2.49-quote-strchr.patch
7088 @@ -0,0 +1,25 @@
7089 +From 7565e4fcb9209782ed02f3caff246cf5ea816674 Mon Sep 17 00:00:00 2001
7090 +From: Mike Frysinger <vapier@g.o>
7091 +Date: Fri, 8 Jan 2010 21:28:31 -0500
7092 +Subject: [PATCH] quote: pull in string.h for strchr prototype
7093 +
7094 +Signed-off-by: Mike Frysinger <vapier@g.o>
7095 +---
7096 + libmisc/quote.c | 1 +
7097 + 1 files changed, 1 insertions(+), 0 deletions(-)
7098 +
7099 +diff --git a/libmisc/quote.c b/libmisc/quote.c
7100 +index f98c887..bf8f9eb 100644
7101 +--- a/libmisc/quote.c
7102 ++++ b/libmisc/quote.c
7103 +@@ -20,6 +20,7 @@
7104 + #include <stdio.h>
7105 + #include <stdlib.h>
7106 + #include <ctype.h>
7107 ++#include <string.h>
7108 + #include "misc.h"
7109 +
7110 + const char *quote(const char *str, const char *quote_chars)
7111 +--
7112 +1.6.6
7113 +
7114
7115 diff --git a/sys-apps/acl/files/acl-2.2.51-config-shell.patch b/sys-apps/acl/files/acl-2.2.51-config-shell.patch
7116 new file mode 100644
7117 index 0000000..78b3f0f
7118 --- /dev/null
7119 +++ b/sys-apps/acl/files/acl-2.2.51-config-shell.patch
7120 @@ -0,0 +1,53 @@
7121 +https://bugs.gentoo.org/365397
7122 +
7123 +From 10bfb16245ec4b55c1f5b6dc5554913bc9b13c9c Mon Sep 17 00:00:00 2001
7124 +From: Mike Frysinger <vapier@g.o>
7125 +Date: Mon, 16 May 2011 01:59:52 -0400
7126 +Subject: [PATCH] use SHELL from configure
7127 +
7128 +If /bin/sh is not a functional enough shell, configure will select a
7129 +SHELL of /bin/bash or better. But the current build helpers always
7130 +hardcode /bin/sh, so if libtool itself configures itself for /bin/bash,
7131 +things will fail when it attempts to do:
7132 + SHELL = /bin/sh
7133 + LIBTOOL = $(SHELL) .../libtool
7134 + ...
7135 + eval: 1: base_compile+= -pipe: not found
7136 + ...
7137 +
7138 +So rather than hardcoding SHELL to /bin/sh, set it to @SHELL@ and let
7139 +configure find a good value for us.
7140 +
7141 +Signed-off-by: Mike Frysinger <vapier@g.o>
7142 +---
7143 + include/builddefs.in | 1 +
7144 + include/buildmacros | 1 -
7145 + 2 files changed, 1 insertions(+), 1 deletions(-)
7146 +
7147 +diff --git a/include/builddefs.in b/include/builddefs.in
7148 +index d054a56..434ce95 100644
7149 +--- a/include/builddefs.in
7150 ++++ b/include/builddefs.in
7151 +@@ -46,6 +46,7 @@ MAKE = @make@
7152 + ECHO = @echo@
7153 + SORT = @sort@
7154 + LN_S = @LN_S@
7155 ++SHELL = @SHELL@
7156 + LIBTOOL = @LIBTOOL@
7157 + MAKEDEPEND = @makedepend@
7158 +
7159 +diff --git a/include/buildmacros b/include/buildmacros
7160 +index ab89182..8efb32e 100644
7161 +--- a/include/buildmacros
7162 ++++ b/include/buildmacros
7163 +@@ -42,7 +42,6 @@ OBJECTS = $(ASFILES:.s=.o) \
7164 +
7165 + INSTALL = $(TOPDIR)/include/install-sh -o $(PKG_USER) -g $(PKG_GROUP)
7166 +
7167 +-SHELL = /bin/sh
7168 + IMAGES_DIR = $(TOPDIR)/all-images
7169 + DIST_DIR = $(TOPDIR)/dist
7170 +
7171 +--
7172 +1.7.5.rc3
7173 +