Common NFSv4 ACL definitions. fs/Kconfig | 4 fs/Makefile | 1 fs/nfs/Makefile | 2 fs/nfs/idmap_syms.c | 48 ++ fs/nfs4acl/Makefile | 3 fs/nfs4acl/acl.c | 936 +++++++++++++++++++++++++++++++++++++++++++++++ fs/nfs4acl/acl_map.c | 123 ++++++ fs/nfs4acl/acl_map.h | 53 ++ fs/nfs4acl/acl_syms.c | 52 ++ fs/nfsd/Makefile | 3 fs/nfsd/nfs4idmap_syms.c | 45 ++ include/linux/nfs4.h | 59 ++ include/linux/nfs4_acl.h | 58 ++ 13 files changed, 1381 insertions(+), 6 deletions(-) diff -puN include/linux/nfs4.h~acl_common include/linux/nfs4.h --- current/include/linux/nfs4.h~acl_common Thu May 22 05:10:21 2003 +++ current-marius/include/linux/nfs4.h Thu May 22 05:10:21 2003 @@ -39,10 +39,61 @@ #define NFS4_SET_TO_SERVER_TIME 0 #define NFS4_SET_TO_CLIENT_TIME 1 -#define NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE 0 -#define NFS4_ACE_ACCESS_DENIED_ACE_TYPE 1 -#define NFS4_ACE_SYSTEM_AUDIT_ACE_TYPE 2 -#define NFS4_ACE_SYSTEM_ALARM_ACE_TYPE 3 +#define ACL4_SUPPORT_ALLOW_ACL 0x00000001 +#define ACL4_SUPPORT_DENY_ACL 0x00000002 +#define ACL4_SUPPORT_AUDIT_ACL 0x00000004 +#define ACL4_SUPPORT_ALARM_ACL 0x00000008 + +#define NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE 0x00000000 +#define NFS4_ACE_ACCESS_DENIED_ACE_TYPE 0x00000001 +#define NFS4_ACE_SYSTEM_AUDIT_ACE_TYPE 0x00000002 +#define NFS4_ACE_SYSTEM_ALARM_ACE_TYPE 0x00000003 + +#define NFS4_ACE_FILE_INHERIT_ACE 0x00000001 +#define NFS4_ACE_DIRECTORY_INHERIT_ACE 0x00000002 +#define NFS4_ACE_NO_PROPAGATE_INHERIT_ACE 0x00000004 +#define NFS4_ACE_INHERIT_ONLY_ACE 0x00000008 +#define NFS4_ACE_SUCCESSFUL_ACCESS_ACE_FLAG 0x00000010 +#define NFS4_ACE_FAILED_ACCESS_ACE_FLAG 0x00000020 +#define NFS4_ACE_IDENTIFIER_GROUP 0x00000040 +#define NFS4_ACE_OWNER 0x00000080 +#define NFS4_ACE_GROUP 0x00000100 +#define NFS4_ACE_EVERYONE 0x00000200 + +#define NFS4_ACE_READ_DATA 0x00000001 +#define NFS4_ACE_LIST_DIRECTORY 0x00000001 +#define NFS4_ACE_WRITE_DATA 0x00000002 +#define NFS4_ACE_ADD_FILE 0x00000002 +#define NFS4_ACE_APPEND_DATA 0x00000004 +#define NFS4_ACE_ADD_SUBDIRECTORY 0x00000004 +#define NFS4_ACE_READ_NAMED_ATTRS 0x00000008 +#define NFS4_ACE_WRITE_NAMED_ATTRS 0x00000010 +#define NFS4_ACE_EXECUTE 0x00000020 +#define NFS4_ACE_DELETE_CHILD 0x00000040 +#define NFS4_ACE_READ_ATTRIBUTES 0x00000080 +#define NFS4_ACE_WRITE_ATTRIBUTES 0x00000100 +#define NFS4_ACE_DELETE 0x00010000 +#define NFS4_ACE_READ_ACL 0x00020000 +#define NFS4_ACE_WRITE_ACL 0x00040000 +#define NFS4_ACE_WRITE_OWNER 0x00080000 +#define NFS4_ACE_SYNCHRONIZE 0x00100000 +#define NFS4_ACE_GENERIC_READ 0x00120081 +#define NFS4_ACE_GENERIC_WRITE 0x00160106 +#define NFS4_ACE_GENERIC_EXECUTE 0x001200A0 + +struct nfs4_ace { + u32 type; + u32 flag; + u32 access_mask; + char *who; + u32 wholen; + struct list_head l_ace; +}; + +struct nfs4_acl { + u32 naces; + struct list_head ace_head; +}; typedef char nfs4_verifier[NFS4_VERIFIER_SIZE]; typedef char nfs4_stateid[16]; diff -puN /dev/null fs/nfs4acl/Makefile --- /dev/null Thu Aug 30 16:30:55 2001 +++ current-marius/fs/nfs4acl/Makefile Thu May 22 05:10:21 2003 @@ -0,0 +1,3 @@ +obj-$(CONFIG_NFS_V4_ACL) += nfs4acl.o + +nfs4acl-objs := acl.o acl_syms.o acl_map.o diff -puN fs/Kconfig~acl_common fs/Kconfig --- current/fs/Kconfig~acl_common Thu May 22 05:10:21 2003 +++ current-marius/fs/Kconfig Thu May 22 05:10:21 2003 @@ -1353,6 +1353,10 @@ config LOCKD_V4 depends on NFSD_V3 || NFS_V3 default y +config NFS_V4_ACL + tristate "Provide NFSv4 ACL support" + depends on NFSD_V4 || NFS_V4 + config EXPORTFS tristate default NFSD diff -puN fs/Makefile~acl_common fs/Makefile --- current/fs/Makefile~acl_common Thu May 22 05:10:21 2003 +++ current-marius/fs/Makefile Thu May 22 05:10:21 2003 @@ -69,6 +69,7 @@ obj-$(CONFIG_NFS_FS) += nfs/ obj-$(CONFIG_EXPORTFS) += exportfs/ obj-$(CONFIG_NFSD) += nfsd/ obj-$(CONFIG_LOCKD) += lockd/ +obj-$(CONFIG_NFS_V4_ACL) += nfs4acl/ obj-$(CONFIG_NLS) += nls/ obj-$(CONFIG_SYSV_FS) += sysv/ obj-$(CONFIG_SMB_FS) += smbfs/ diff -puN /dev/null fs/nfs4acl/acl.c --- /dev/null Thu Aug 30 16:30:55 2001 +++ current-marius/fs/nfs4acl/acl.c Mon Jun 2 18:00:56 2003 @@ -0,0 +1,936 @@ +/* + * fs/nfs4acl/acl.c + * + * Common NFSv4 ACL handling code. + * + * Copyright (c) 2002, 2003 The Regents of the University of Michigan. + * All rights reserved. + * + * Marius Aamodt Eriksen + * Jeff Sedlak + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "acl_map.h" + +#define ACETYPE_OWNER 0x01 +#define ACETYPE_GROUP 0x02 +#define ACETYPE_EVERYONE 0x04 +#define ACETYPE_OGROUP 0x08 +#define ACETYPE_OUSER 0x10 +#define ACETYPE_OGROUP1 0x20 +#define ACETYPE_OGROUP2 0x40 +#define ACETYPE_OGROUP3 0x80 + +/* #define ACL_DEBUG */ + +#ifdef ACL_DEBUG +#define DPRINTK(fmt, arg...) printk(fmt, ##arg) +#define ON_DEBUG(x) x +#else +#define DPRINTK(...) +#define ON_DEBUG +#endif /* ACL_DEBUG */ + +#define SET_MASK_FROM_POSIX(perm, mask) do { \ + mask = 0; \ + if (perm & ACL_READ) \ + mask |= NFS4_ACE_GENERIC_READ; \ + if (perm & ACL_WRITE) \ + mask |= NFS4_ACE_GENERIC_WRITE; \ + if (perm & ACL_EXECUTE) \ + mask |= NFS4_ACE_GENERIC_EXECUTE; \ +} while (0) + +#define SET_MODE_FROM_NFS4(perm, mode) do { \ + mode = 0; \ + if ((perm & NFS4_ACE_GENERIC_READ) == NFS4_ACE_GENERIC_READ) \ + mode |= ACL_READ; \ + if ((perm & NFS4_ACE_GENERIC_WRITE) == NFS4_ACE_GENERIC_WRITE) \ + mode |= ACL_WRITE; \ + if ((perm & NFS4_ACE_GENERIC_EXECUTE) == NFS4_ACE_GENERIC_EXECUTE) \ + mode |= ACL_EXECUTE; \ +} while (0) + +struct ace_container { + struct nfs4_ace *ace; + struct list_head ace_l; +}; + +static void nfs4_acl_print_ace(struct nfs4_ace *); +static void nfs4_posix_acl_print(struct posix_acl *); +static int ace2type(struct nfs4_ace *); +static int _posix_to_nfsv4_one(struct inode *, struct posix_acl *, + struct nfs4_acl *, int); +static struct posix_acl *_nfsv4_to_posix_one(struct inode *, + struct nfs4_acl *); + +struct nfs4_acl * +nfs4_acl_posix_to_nfsv4(struct inode *inode, struct posix_acl *pacl, + struct posix_acl *dpacl) +{ + struct nfs4_acl *acl; + int error = -EINVAL; + + if ((pacl != NULL && + (posix_acl_valid(pacl) < 0 || pacl->a_count == 0)) || + (dpacl != NULL && + (posix_acl_valid(dpacl) < 0 || dpacl->a_count == 0))) + goto out_err; + + acl = nfs4_acl_new(); + if (acl == NULL) { + error = -ENOMEM; + goto out_err; + } + + if (pacl != NULL) { + error = _posix_to_nfsv4_one(inode, pacl, acl, 0); + if (error < 0) + goto out_acl; + } + + if (dpacl != NULL) { + error = _posix_to_nfsv4_one(inode, dpacl, acl, + NFS4_ACE_FILE_INHERIT_ACE | + NFS4_ACE_DIRECTORY_INHERIT_ACE | + NFS4_ACE_INHERIT_ONLY_ACE); + if (error < 0) + goto out_acl; + } + + DPRINTK("NFS%s encoded ACL:\n", inode == NULL ? "d" : ""); + ON_DEBUG(nfs4_acl_print(acl)); + + return (acl); + + out_acl: + nfs4_acl_free(acl); + out_err: + acl = ERR_PTR(error); + + return (acl); +} + +#define ADD_MASK_ACL(acl, mask, owner, ownerlen, flag, error, out) do { \ + error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, \ + flag, mask_mask, owner, ownerlen); \ + if (error < 0) \ + goto out; \ +} while (0) + +static int +_posix_to_nfsv4_one(struct inode *inode, struct posix_acl *pacl, + struct nfs4_acl *acl, int eflag) +{ + struct posix_acl_entry *pa, *pe, *user_owner_entry = NULL, + *group_owner_entry = NULL, *mask_entry = NULL; + int error = -EINVAL; + u32 mask, mask_mask; + char xname[NFS4_ACL_MAP_MAXNAMELEN]; + int xnamelen; + + FOREACH_ACL_ENTRY(pa, pacl, pe) + switch (pa->e_tag) { + case ACL_USER_OBJ: + user_owner_entry = pa; + break; + case ACL_GROUP_OBJ: + group_owner_entry = pa; + break; + case ACL_MASK: + mask_entry = pa; + break; + default: + break; + } + + if (mask_entry != NULL) { + SET_MASK_FROM_POSIX(mask_entry->e_perm, mask_mask); + mask_mask = ~mask_mask; + } else + mask_mask = 0; + + if (user_owner_entry != NULL) { + SET_MASK_FROM_POSIX(user_owner_entry->e_perm, mask); + error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE, + eflag, mask, "OWNER@", sizeof("OWNER@") - 1); + if (error < 0) + goto out; + + error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, + eflag, ~mask, "OWNER@", sizeof("OWNER@") - 1); + if (error < 0) + goto out; + } + + /* First all user ACEs */ + FOREACH_ACL_ENTRY(pa, pacl, pe) { + if (pa->e_tag != ACL_USER) + continue; + + SET_MASK_FROM_POSIX(pa->e_perm, mask); + xnamelen = sizeof(xname); + error = nfs4_acl_map_id2name(inode, NFS4_ACL_MAP_USER, + xname, &xnamelen, pa->e_id); + if (error < 0) + goto out; + + ADD_MASK_ACL(acl, mask_mask, + xname, xnamelen, eflag, error, out); + + error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE, + eflag, mask, xname, xnamelen); + if (error < 0) + goto out; + + error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, + eflag, ~mask, xname, xnamelen); + if (error < 0) + goto out; + } + + /* + * Here, we apply positive ACEs first, then negative ACEs, + * since a user can be in more than one group. + */ + + /* + * Positive ACEs + */ + + if (group_owner_entry != NULL) { + SET_MASK_FROM_POSIX(group_owner_entry->e_perm, mask); + error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE, + eflag, mask, + "GROUP@", sizeof("GROUP@") - 1); + if (error < 0) + goto out; + } + + FOREACH_ACL_ENTRY(pa, pacl, pe) { + if (pa->e_tag != ACL_GROUP) + continue; + + SET_MASK_FROM_POSIX(pa->e_perm, mask); + xnamelen = sizeof(xname); + error = nfs4_acl_map_id2name(inode, NFS4_ACL_MAP_GROUP, + xname, &xnamelen, pa->e_id); + if (error < 0) + goto out; + + ADD_MASK_ACL(acl, mask_mask, + xname, xnamelen, NFS4_ACE_IDENTIFIER_GROUP | eflag, + error, out); + + error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE, + NFS4_ACE_IDENTIFIER_GROUP | eflag, mask, xname, xnamelen); + if (error < 0) + goto out; + } + + /* + * Negative ACEs + */ + + if (group_owner_entry != NULL) { + SET_MASK_FROM_POSIX(group_owner_entry->e_perm, mask); + error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, + eflag, ~mask, "GROUP@", sizeof("GROUP@") - 1); + if (error < 0) + goto out; + } + + FOREACH_ACL_ENTRY(pa, pacl, pe) { + if (pa->e_tag != ACL_GROUP) + continue; + + SET_MASK_FROM_POSIX(pa->e_perm, mask); + xnamelen = sizeof(xname); + error = nfs4_acl_map_id2name(inode, NFS4_ACL_MAP_GROUP, + xname, &xnamelen, pa->e_id); + if (error < 0) + goto out; + + error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, + NFS4_ACE_IDENTIFIER_GROUP | eflag, ~mask, xname, xnamelen); + if (error < 0) + goto out; + } + + /* EVERYONE@ ace*/ + FOREACH_ACL_ENTRY(pa, pacl, pe) + if (pa->e_tag == ACL_OTHER) + break; + + if (pa < pe) { + SET_MASK_FROM_POSIX(pa->e_perm, mask); + error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE, + eflag, mask, "EVERYONE@", sizeof("EVERYONE@") - 1); + if (error < 0) + goto out; + error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, + eflag, ~mask, "EVERYONE@", sizeof("EVERYONE@") - 1); + } + + out: + return (error); +} + +#define ASSIGN_ACE(ace, pace, mask, tag, error, out, inode) do { \ + int mode, map = NFS4_ACL_MAP_USER; \ + \ + if (tag == ACL_GROUP_OBJ || tag == ACL_GROUP) \ + map = NFS4_ACL_MAP_GROUP; \ + \ + SET_MODE_FROM_NFS4((ace)->access_mask, mode); \ + (pace)->e_tag = tag; \ + (pace)->e_perm = mode; \ + (mask) |= mode; \ + if (tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ || tag == ACL_OTHER) \ + break; \ + (error) = nfs4_acl_map_name2id((inode), map, \ + (ace)->who, (ace)->wholen, &(pace)->e_id); \ + if ((error) < 0) \ + goto out; \ +} while (0) + +#define NEXT_ACE(p, ace, head, error, out) do { \ + p = p->next; prefetch(p->next); \ + if (p == head) { \ + error = -EINVAL; \ + goto out; \ + } \ + ace = list_entry(p, struct nfs4_ace, l_ace); \ +} while (0) + +int +nfs4_acl_nfsv4_to_posix(struct inode *inode, struct nfs4_acl *acl, + struct posix_acl **pacl, struct posix_acl **dpacl) +{ + struct nfs4_acl *dacl; + int error = -ENOMEM; + + dacl = nfs4_acl_new(); + if (dacl == NULL) + goto out; + + error = nfs4_acl_split(acl, dacl); + if (error < 0) + goto out_acl; + + if (pacl != NULL) { + if (acl->naces == 0) { + error = -ENODATA; + *pacl = NULL; + goto try_dpacl; + } + + *pacl = _nfsv4_to_posix_one(inode, acl); + if (IS_ERR(*pacl)) { + error = PTR_ERR(*pacl); + goto out_acl; + } + } + + try_dpacl: + if (dpacl != NULL) { + if (dacl->naces == 0) { + if (pacl == NULL || (pacl != NULL && *pacl == NULL)) + error = -ENODATA; + *dpacl = NULL; + goto out_acl; + } + + error = 0; + *dpacl = _nfsv4_to_posix_one(inode, dacl); + if (IS_ERR(*dpacl)) { + error = PTR_ERR(*dpacl); + goto out_acl; + } + } + + out_acl: + nfs4_acl_free(dacl); + out: + return (error); +} + +static struct posix_acl * +_nfsv4_to_posix_one(struct inode *inode, struct nfs4_acl *n4acl) +{ + struct posix_acl *acl; + int error = -EINVAL, nace = 0, i, nmask = 0, mask_wholen, deny_wholen; + struct list_head *p, group_l; + struct nfs4_ace *ace, *_ace, *user_owner_ace, *group_owner_ace, *mask_ace; + u32 mask = 0, mode; + struct posix_acl_entry *pace; + struct ace_container *ac; + int state = ACETYPE_OWNER, type, access_mask, flag, mask_flag; + char *mask_who, *deny_who; + + user_owner_ace = group_owner_ace = mask_ace = NULL; + + nace = n4acl->naces; + + list_for_each(p, &n4acl->ace_head) { + ace = list_entry(p, struct nfs4_ace, l_ace); + + type = ace2type(ace); + switch (type) { + case ACETYPE_OUSER: + case ACETYPE_OGROUP: + nmask++; + break; + default: + break; + } + } + + if (nmask % 3 != 0) + goto out_err; + + nmask /= 3; + nace -= nmask; + + if (nace % 2 != 0) + goto out_err; + + nace /= 2; + nace++; /* ACL_MASK */ + + if ((acl = posix_acl_alloc(nace, GFP_KERNEL)) == NULL) { + error = -ENOMEM; + goto out_err; + } + + i = 0; + INIT_LIST_HEAD(&group_l); + list_for_each(p, &n4acl->ace_head) { + ace = list_entry(p, struct nfs4_ace, l_ace); + pace = &acl->a_entries[i++]; + error = -EINVAL; + + DPRINTK("MARIUS: mapping entry %d\n", i - 1); + ON_DEBUG(nfs4_acl_print_ace(ace)); + + type = ace2type(ace); + switch (type) { + case ACETYPE_OWNER: + if (state != ACETYPE_OWNER) { + DPRINTK("MARIUS: state != ACETYPE_OWNER\n"); + goto out_acl; + } + + if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) + goto out_acl; + + /* obviously, also make sure this is an allowed type. */ + + access_mask = ace->access_mask; + flag = ace->flag; + deny_who = ace->who; + deny_wholen = ace->wholen; + ASSIGN_ACE(ace, pace, mask, ACL_USER_OBJ, + error, out_acl, inode); + NEXT_ACE(p, ace, &n4acl->ace_head, error, out_acl); + + if (ace->access_mask != ~access_mask || + ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE || + ace->flag != flag || + ace->wholen != deny_wholen || + memcmp(ace->who, deny_who, deny_wholen) != 0) + goto out_acl; + state = ACETYPE_OUSER; + break; + case ACETYPE_OUSER: + if (state != ACETYPE_OUSER) { + DPRINTK("MARIUS: state != ACETYPE_OUSER\n"); + goto out_acl; + } + + if (mask_ace == NULL) + mask_ace = ace; + + if (ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE || + ace->access_mask != mask_ace->access_mask) + goto out_acl; + + mask_who = ace->who; + mask_wholen = ace->wholen; + mask_flag = ace->flag; + NEXT_ACE(p, ace, &n4acl->ace_head, error, out_acl); + + if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) + goto out_acl; + + access_mask = ace->access_mask; + flag = ace->flag; + deny_who = ace->who; + deny_wholen = ace->wholen; + ASSIGN_ACE(ace, pace, mask, ACL_USER, + error, out_acl, inode); + NEXT_ACE(p, ace, &n4acl->ace_head, error, out_acl); + if (ace->access_mask != ~access_mask || + ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE || + ace->flag != flag || + mask_flag != flag || + ace->wholen != deny_wholen || + memcmp(ace->who, deny_who, deny_wholen) != 0 || + ace->wholen != mask_wholen || + memcmp(ace->who, mask_who, mask_wholen) != 0) + goto out_acl; + break; + case ACETYPE_GROUP: + if (state == ACETYPE_OGROUP) + state = ACETYPE_OGROUP3; + + if (state == ACETYPE_OUSER) { + ac = kmalloc(sizeof(*ac), GFP_KERNEL); + if (ac == NULL) { + error = -ENOMEM; + goto out_acl; + } + ac->ace = ace; + list_add_tail(&ac->ace_l, &group_l); + + if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) + goto out_acl; + + ASSIGN_ACE(ace, pace, mask, ACL_GROUP_OBJ, + error, out_acl, inode); + + state = ACETYPE_OGROUP; + } else if (state == ACETYPE_OGROUP1 || + state == ACETYPE_OGROUP3) { + ac = list_entry(group_l.next, + struct ace_container, ace_l); + _ace = ac->ace; + + DPRINTK("MARIUS: processing _ACE: \n"); + ON_DEBUG(nfs4_acl_print_ace(_ace)); + + if (ace->access_mask != ~_ace->access_mask || + ace->type != + NFS4_ACE_ACCESS_DENIED_ACE_TYPE || + ace->flag != _ace->flag || + ace->wholen != _ace->wholen || + memcmp(ace->who, + _ace->who, _ace->wholen) != 0) + goto out_acl; + + list_del(group_l.next); + kfree(ac); + + if (state == ACETYPE_OGROUP3 && + !list_empty(&group_l)) + goto out_acl; + + state = list_empty(&group_l) ? + ACETYPE_EVERYONE : ACETYPE_OGROUP2; + i--; + } else { + DPRINTK("MARIUS: bad state in ACETYPE_GROUP " + "(%d)\n", state); + goto out_acl; + } + break; + case ACETYPE_OGROUP: + if (state == ACETYPE_OGROUP || + state == ACETYPE_OGROUP1) { + if (mask_ace == NULL) + mask_ace = ace; + + mask_who = ace->who; + mask_wholen = ace->wholen; + + if (ace->type != + NFS4_ACE_ACCESS_DENIED_ACE_TYPE || + ace->access_mask != mask_ace->access_mask) + goto out_acl; + + NEXT_ACE(p, ace, &n4acl->ace_head, error, + out_acl); + + ac = kmalloc(sizeof(*ac), GFP_KERNEL); + if (ac == NULL) { + error = -ENOMEM; + goto out_acl; + } + + if (ace->type != + NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE || + ace->wholen != mask_wholen || + memcmp(ace->who, + mask_who, mask_wholen) != 0) + goto out_acl; + + ac->ace = ace; + list_add_tail(&ac->ace_l, &group_l); + + ASSIGN_ACE(ace, pace, mask, ACL_GROUP, + error, out_acl, inode); + + state = ACETYPE_OGROUP1; + } else if (state == ACETYPE_OGROUP2) { + ac = list_entry(group_l.next, + struct ace_container, ace_l); + _ace = ac->ace; + + if (ace->access_mask != ~_ace->access_mask || + ace->type != + NFS4_ACE_ACCESS_DENIED_ACE_TYPE || + ace->flag != _ace->flag || + ace->wholen != _ace->wholen || + memcmp(ace->who, + _ace->who, _ace->wholen) != 0) + goto out_acl; + + list_del(group_l.next); + kfree(ac); + + if (list_empty(&group_l)) + state = ACETYPE_EVERYONE; + i--; + } else { + DPRINTK("MARIUS: bad state in " + "ACETYPE_OGROUP (%d)\n", state); + goto out_acl; + } + + break; + case ACETYPE_EVERYONE: + /* XXX jump over OGROUP */ + if (state != ACETYPE_EVERYONE && + state != ACETYPE_OGROUP) { + DPRINTK("MARIUS: bad state in " + "ACETYPE_EVERYONE (%d)\n", state); + goto out_acl; + } + + /* First, the ACL_MASK */ + pace->e_tag = ACL_MASK; + if (mask_ace != NULL) + SET_MODE_FROM_NFS4(~mask_ace->access_mask, + pace->e_perm); + else + SET_MODE_FROM_NFS4(0xFFFFFFFF, pace->e_perm); + pace = &acl->a_entries[i++]; + + if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) + goto out_acl; + + access_mask = ace->access_mask; + flag = ace->flag; + deny_who = ace->who; + deny_wholen = ace->wholen; + + SET_MODE_FROM_NFS4(ace->access_mask, mode); + ASSIGN_ACE(ace, pace, mask, ACL_OTHER, + error, out_acl, inode); + + NEXT_ACE(p, ace, &n4acl->ace_head, error, out_acl); + + if (ace->access_mask != ~access_mask || + ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE || + ace->flag != flag || + ace->wholen != deny_wholen || + memcmp(ace->who, deny_who, deny_wholen) != 0) + goto out_acl; + + state = 0; + + DPRINTK("MARIUS: (ACL#) %d == (nace) %d\n", i, nace); + } + } + + if (!list_empty(&group_l) || state != 0) { + error = -EINVAL; + goto out_acl; + } + + DPRINTK("MARIUS: SUCCESSFUL mapping\n"); + ON_DEBUG(nfs4_posix_acl_print(acl)); + + return (acl); + + out_acl: + while (!list_empty(&group_l)) { + ac = list_entry(group_l.next, struct ace_container, ace_l); + list_del(group_l.next); + kfree(ac); + } + + + DPRINTK("FAILED mapping\n"); + ON_DEBUG(nfs4_posix_acl_print(acl)); + + posix_acl_release(acl); + out_err: + acl = ERR_PTR(error); + + return (acl); +} + + +struct nfs4_acl * +nfs4_acl_new(void) +{ + struct nfs4_acl *acl; + + if ((acl = kmalloc(sizeof(*acl), GFP_KERNEL)) == NULL) + return (NULL); + + acl->naces = 0; + INIT_LIST_HEAD(&acl->ace_head); + + return (acl); +} + +struct nfs4_acl * +nfs4_acl_free(struct nfs4_acl *acl) +{ + struct list_head *h; + struct nfs4_ace *ace; + + while (!list_empty(&acl->ace_head)) { + h = acl->ace_head.next; + list_del(h); + ace = list_entry(h, struct nfs4_ace, l_ace); + if (ace->who != NULL) + kfree(ace->who); + kfree(ace); + } + + kfree(acl); + + return (NULL); +} + +int +nfs4_acl_add_ace(struct nfs4_acl *acl, u32 type, u32 flag, u32 access_mask, + char *who, u32 wholen) +{ + struct nfs4_ace *ace; + + if ((ace = kmalloc(sizeof(*ace), GFP_KERNEL)) == NULL) + return (-1); + + ace->type = type; + ace->flag = flag; + ace->access_mask = access_mask; + if (wholen > 0) { + if ((ace->who = kmalloc(wholen, GFP_KERNEL)) == NULL) + goto fail; + memcpy(ace->who, who, wholen); + } + ace->wholen = wholen; + + list_add_tail(&ace->l_ace, &acl->ace_head); + + return (++acl->naces); + + fail: + kfree(ace); + return (-1); +} + + +int +nfs4_acl_merge(struct nfs4_acl *fromacl, struct nfs4_acl *withacl) +{ + struct nfs4_ace *ace; + struct list_head *h; + + if (fromacl == NULL || withacl == NULL) + return (0); + + while (!list_empty(&fromacl->ace_head)) { + h = fromacl->ace_head.next; + list_del(h); + ace = list_entry(h, struct nfs4_ace, l_ace); + /* XXX */ + ace->flag |= NFS4_ACE_FILE_INHERIT_ACE | + NFS4_ACE_DIRECTORY_INHERIT_ACE | NFS4_ACE_INHERIT_ONLY_ACE; + list_add_tail(&ace->l_ace, &withacl->ace_head); + withacl->naces++; + } + + return (0); +} + +int +nfs4_acl_split(struct nfs4_acl *acl, struct nfs4_acl *dacl) +{ + struct list_head *h, *n; + struct nfs4_ace *ace; + int error = 0; + + list_for_each_safe(h, n, &acl->ace_head) { + ace = list_entry(h, struct nfs4_ace, l_ace); + + if (!(ace->flag & NFS4_ACE_DIRECTORY_INHERIT_ACE && + ace->flag & NFS4_ACE_FILE_INHERIT_ACE && + ace->flag & NFS4_ACE_INHERIT_ONLY_ACE)) + continue; + + error = nfs4_acl_add_ace(dacl, ace->type, ace->flag, + ace->access_mask, ace->who, ace->wholen) == -1; + if (error < 0) + goto out; + + list_del(h); + if (ace->who != NULL) + kfree(ace->who); + kfree(ace); + acl->naces--; + } + + out: + return (error); +} + +void +nfs4_acl_print(struct nfs4_acl *acl) +{ +#ifdef ACL_DEBUG + struct list_head *h; + struct nfs4_ace *ace; + + printk(KERN_INFO "** ACL [%i]:\n", acl->naces); + + list_for_each(h, &acl->ace_head) { + ace = list_entry(h, struct nfs4_ace, l_ace); + nfs4_acl_print_ace(ace); + } +#endif /* ACL_DEBUG */ +} + +static void +nfs4_acl_print_ace(struct nfs4_ace *ace) +{ +#ifdef ACL_DEBUG + char mask[4]; + + mask[3] = '\0'; + + mask[0] = (ace->access_mask & + NFS4_ACE_GENERIC_READ) == NFS4_ACE_GENERIC_READ ? 'r' : '-'; + mask[1] = (ace->access_mask & + NFS4_ACE_GENERIC_WRITE) == NFS4_ACE_GENERIC_WRITE ? 'w' : '-'; + mask[2] = (ace->access_mask & + NFS4_ACE_GENERIC_EXECUTE) == NFS4_ACE_GENERIC_EXECUTE ? 'x' : '-'; + + if (ace->wholen == 0) + return; + + printk(KERN_INFO "**\twho: %.*s\n", ace->wholen, ace->who); + printk(KERN_INFO "**\ttype: %x flag: %x mask: %s\n", + ace->type, ace->flag, mask); +#endif /* ACL_DEBUG */ +} + +static void +nfs4_posix_acl_print(struct posix_acl *acl) +{ +#ifdef ACL_DEBUG + struct posix_acl_entry *pa, *pe; + + FOREACH_ACL_ENTRY(pa, acl, pe) + switch(pa->e_tag) { + case ACL_USER_OBJ: + printk("++\tOWNER: p: 0x%x\n", pa->e_perm); + break; + case ACL_USER: + printk("++\t%d p: 0x%x\n", pa->e_id, pa->e_perm); + break; + case ACL_GROUP_OBJ: + printk("++\tGROUP: p: 0x%x\n", pa->e_perm); + break; + case ACL_GROUP: + printk("++\t%d p: 0x%x\n", pa->e_id, pa->e_perm); + break; + case ACL_MASK: + printk("++\tMASK: p: 0x%x\n", pa->e_perm); + break; + case ACL_OTHER: + printk("++\tOTHER: p: 0x%x\n", pa->e_perm); + break; + default: + break; + } +#endif ACL_DEBUG +} + +static struct { + char *string; + int stringlen; + int type; +} s2t_map[] = { + { + .string = "OWNER@", + .stringlen = sizeof("OWNER@") - 1, + .type = ACETYPE_OWNER + }, + { + .string = "GROUP@", + .stringlen = sizeof("GROUP@") - 1, + .type = ACETYPE_GROUP + }, + { + .string = "EVERYONE@", + .stringlen = sizeof("EVERYONE@") - 1, + .type = ACETYPE_EVERYONE + }, +}; + +static int +ace2type(struct nfs4_ace *ace) +{ + int i; + + if (ace->who == NULL || ace->wholen <= 0) + return (0); + + for (i = 0; i < sizeof(s2t_map) / sizeof(*s2t_map); i++) + if (s2t_map[i].stringlen == ace->wholen && + strncmp(s2t_map[i].string, ace->who, ace->wholen) == 0) + return (s2t_map[i].type); + + return (ace->flag & NFS4_ACE_IDENTIFIER_GROUP ? ACETYPE_OGROUP : + ACETYPE_OUSER); +} diff -puN /dev/null include/linux/nfs4_acl.h --- /dev/null Thu Aug 30 16:30:55 2001 +++ current-marius/include/linux/nfs4_acl.h Thu May 22 05:10:21 2003 @@ -0,0 +1,58 @@ +/* + * include/linux/nfs4_acl.c + * + * Common NFSv4 ACL handling definitions. + * + * Copyright (c) 2002 The Regents of the University of Michigan. + * All rights reserved. + * + * Marius Aamodt Eriksen + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LINUX_NFS4_ACL_H +#define LINUX_NFS4_ACL_H + +#include + +#define NFS4_ACL_TYPE_ACCESS 0 +#define NFS4_ACL_TYPE_DEFAULT 1 + +struct nfs4_acl *nfs4_acl_new(void); +struct nfs4_acl *nfs4_acl_free(struct nfs4_acl *); +int nfs4_acl_merge(struct nfs4_acl *, struct nfs4_acl *); +int nfs4_acl_split(struct nfs4_acl *, struct nfs4_acl *); +int nfs4_acl_add_ace(struct nfs4_acl *, u32, u32, + u32, char *, u32); +void nfs4_acl_print(struct nfs4_acl *); +struct nfs4_acl *nfs4_acl_posix_to_nfsv4(struct inode *inode, + struct posix_acl *, struct posix_acl *); +int nfs4_acl_nfsv4_to_posix(struct inode *inode, + struct nfs4_acl *, struct posix_acl **, + struct posix_acl **); + +#endif /* LINUX_NFS4_ACL_H */ diff -puN /dev/null fs/nfs4acl/acl_syms.c --- /dev/null Thu Aug 30 16:30:55 2001 +++ current-marius/fs/nfs4acl/acl_syms.c Thu May 22 05:10:21 2003 @@ -0,0 +1,52 @@ +/* + * fs/nfs4acl/acl_syms.c + * + * Common NFSv4 ACL handling symbol exports. + * + * Copyright (c) 2002 The Regents of the University of Michigan. + * All rights reserved. + * + * Marius Aamodt Eriksen + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include +#include + +#include +#include +#include +#include +#include + +EXPORT_SYMBOL(nfs4_acl_new); +EXPORT_SYMBOL(nfs4_acl_free); +EXPORT_SYMBOL(nfs4_acl_merge); +EXPORT_SYMBOL(nfs4_acl_split); +EXPORT_SYMBOL(nfs4_acl_add_ace); +EXPORT_SYMBOL(nfs4_acl_print); diff -puN /dev/null fs/nfs4acl/acl_map.c --- /dev/null Thu Aug 30 16:30:55 2001 +++ current-marius/fs/nfs4acl/acl_map.c Thu May 22 05:10:21 2003 @@ -0,0 +1,123 @@ +/* + * fs/nfs4acl/acl_map.c + * + * Name mapping multiplexing for the NFSv4 ACL handling code. + * + * Copyright (c) 2003 The Regents of the University of Michigan. + * All rights reserved. + * + * Marius Aamodt Eriksen + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This is to mediate the two interfaces. *HOPEFULLY* these will be + * coalesced at some point, and we can get rid of this. + */ + +#include + +#include +#include +#include +#include +#include + +#include "acl_map.h" + +int +nfs4_acl_map_name2id(struct inode *inode, short flag, + char *name, u32 namelen, uid_t *id) +{ + u8 type; + int error = -EINVAL; + int i = 0; + + type = flag & NFS4_ACL_MAP_USER ? IDMAP_TYPE_USER : IDMAP_TYPE_GROUP; + + /* check inode != NULL for client ... */ + + if (inode != NULL) { +#ifdef CONFIG_NFS_V4 + error = nfs_idmap_id(NFS_SERVER(inode), type, name, + namelen, id); +#else + error = -EOPNOTSUPP; +#endif /* CONFIG_NFS_V4 */ + } else { +#ifdef CONFIG_NFSD_V4 + char *xname; + /* XXX */ + i+= 2; + + if ((xname = kmalloc(namelen + 1, GFP_KERNEL)) == NULL) + return (-ENOMEM); + + memcpy(xname, name, namelen); + xname[namelen] = '\0'; + + error = nfsd_idmap(IDMAP_TRANS_NAMETOID, type, id, xname); + + kfree(xname); +#else + error = -EOPNOTSUPP; +#endif /* CONFIG_NFSD_V4 */ + } + + return (error); +} + +int +nfs4_acl_map_id2name(struct inode *inode, short flag, + char *name, u32 *namelen, uid_t id) +{ + u8 type; + int error = -EINVAL; + + if (*namelen < IDMAP_NAMESZ) + return (-EINVAL); + + type = flag & NFS4_ACL_MAP_USER ? IDMAP_TYPE_USER : IDMAP_TYPE_GROUP; + + if (inode != NULL) { +#ifdef CONFIG_NFS_V4 + error = nfs_idmap_name(NFS_SERVER(inode), type, id, name, namelen); +#else + error = -EOPNOTSUPP; +#endif /* CONFIG_NFS_V4 */ + } else { +#ifdef CONFIG_NFSD_V4 + error = nfsd_idmap(IDMAP_TRANS_IDTONAME, type, &id, name); + + *namelen = strlen(name); +#else + error = -EOPNOTSUPP; +#endif /* CONFIG_NFSD_V4 */ + } + + return (error); +} diff -puN /dev/null fs/nfs4acl/acl_map.h --- /dev/null Thu Aug 30 16:30:55 2001 +++ current-marius/fs/nfs4acl/acl_map.h Thu May 22 05:10:21 2003 @@ -0,0 +1,53 @@ +/* + * fs/nfs4acl/acl_map.h + * + * Name mapping multiplexing for the NFSv4 ACL handling code. + * + * Copyright (c) 2003 The Regents of the University of Michigan. + * All rights reserved. + * + * Marius Aamodt Eriksen + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This is to mediate the two interfaces. *HOPEFULLY* these will be + * coalesced at some point, and we can get rid of this. + */ + +#ifndef FS_NFS4MAP_ACL_MAP_H +#define FS_NFS4MAP_ACL_MAP_H + +#define NFS4_ACL_MAP_USER 0x01 +#define NFS4_ACL_MAP_GROUP 0x02 + +#define NFS4_ACL_MAP_MAXNAMELEN 128 + +int nfs4_acl_map_name2id(struct inode *, short, char *, u32, uid_t *); +int nfs4_acl_map_id2name(struct inode *, short, char *, u32 *, uid_t); + +#endif /* FS_NFS4MAP_ACL_MAP_H */ diff -puN /dev/null fs/nfs/idmap_syms.c --- /dev/null Thu Aug 30 16:30:55 2001 +++ current-marius/fs/nfs/idmap_syms.c Thu May 22 05:10:21 2003 @@ -0,0 +1,48 @@ +/* + * fs/nfs/idmap_syms.c + * + * NFSv4 client IDmap symbol exports. + * + * Copyright (c) 2003 The Regents of the University of Michigan. + * All rights reserved. + * + * Marius Aamodt Eriksen + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include +#include + +#include +#include +#include + +EXPORT_SYMBOL(nfs_idmap_new); +EXPORT_SYMBOL(nfs_idmap_delete); +EXPORT_SYMBOL(nfs_idmap_id); +EXPORT_SYMBOL(nfs_idmap_name); diff -puN /dev/null fs/nfsd/nfs4idmap_syms.c --- /dev/null Thu Aug 30 16:30:55 2001 +++ current-marius/fs/nfsd/nfs4idmap_syms.c Thu May 22 05:10:21 2003 @@ -0,0 +1,45 @@ +/* + * fs/nfsd/nfs4idmap_syms.c + * + * NFSv4 server IDmap symbol exports. + * + * Copyright (c) 2003 The Regents of the University of Michigan. + * All rights reserved. + * + * Marius Aamodt Eriksen + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#include +#include + +EXPORT_SYMBOL(nfsd_idmap_init); +EXPORT_SYMBOL(nfsd_idmap_shutdown); +EXPORT_SYMBOL(nfsd_idmap); diff -puN fs/nfsd/Makefile~acl_common fs/nfsd/Makefile --- current/fs/nfsd/Makefile~acl_common Thu May 22 05:10:21 2003 +++ current-marius/fs/nfsd/Makefile Thu May 22 05:10:21 2003 @@ -7,5 +7,6 @@ obj-$(CONFIG_NFSD) += nfsd.o nfsd-y := nfssvc.o nfsctl.o nfsproc.o nfsfh.o vfs.o \ export.o auth.o lockd.o nfscache.o nfsxdr.o stats.o nfsd-$(CONFIG_NFSD_V3) += nfs3proc.o nfs3xdr.o -nfsd-$(CONFIG_NFSD_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4idmap.o +nfsd-$(CONFIG_NFSD_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4idmap.o \ + nfs4idmap_syms.o nfsd-objs := $(nfsd-y) diff -puN fs/nfs/Makefile~acl_common fs/nfs/Makefile --- current/fs/nfs/Makefile~acl_common Thu May 22 05:10:21 2003 +++ current-marius/fs/nfs/Makefile Thu May 22 05:10:21 2003 @@ -9,6 +9,6 @@ nfs-y := dir.o file.o inode.o nfs2xdr nfs-$(CONFIG_ROOT_NFS) += nfsroot.o mount_clnt.o nfs-$(CONFIG_NFS_V3) += nfs3proc.o nfs3xdr.o nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \ - idmap.o + idmap.o idmap_syms.o nfs-$(CONFIG_NFS_DIRECTIO) += direct.o nfs-objs := $(nfs-y) _