Commit c85705ed authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] kNFSd: IDmap support for the NFSv4 server.

From: NeilBrown <neilb@cse.unsw.edu.au>

Updated version which uses ascii-encoding of messages, from
http://www.citi.umich.edu/u/marius/linux-2.5.70-idmap-server-new.diff as of
October 14, 2003.
parent dacfae9e
......@@ -7,5 +7,5 @@ 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
nfsd-$(CONFIG_NFSD_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4idmap.o
nfsd-objs := $(nfsd-y)
This diff is collapsed.
......@@ -568,7 +568,8 @@ nfsd4_verify(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_ver
status = nfsd4_encode_fattr(current_fh, current_fh->fh_export,
current_fh->fh_dentry, buf,
&count, verify->ve_bmval);
&count, verify->ve_bmval,
rqstp);
/* this means that nfsd4_encode_fattr() ran out of space */
if (status == nfserr_resource && count == 0)
......
......@@ -51,10 +51,10 @@
#include <linux/sunrpc/xdr.h>
#include <linux/sunrpc/svc.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/name_lookup.h>
#include <linux/nfsd/nfsd.h>
#include <linux/nfsd/state.h>
#include <linux/nfsd/xdr4.h>
#include <linux/nfsd_idmap.h>
#define NFSDDBG_FACILITY NFSDDBG_XDR
......@@ -373,7 +373,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia
READMEM(buf, dummy32);
if (check_utf8(buf, dummy32))
return nfserr_inval;
if ((status = name_get_uid(buf, dummy32, &iattr->ia_uid)))
if ((status = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &iattr->ia_uid)))
goto out_nfserr;
iattr->ia_valid |= ATTR_UID;
}
......@@ -386,7 +386,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia
READMEM(buf, dummy32);
if (check_utf8(buf, dummy32))
return nfserr_inval;
if ((status = name_get_gid(buf, dummy32, &iattr->ia_gid)))
if ((status = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &iattr->ia_gid)))
goto out_nfserr;
iattr->ia_valid |= ATTR_GID;
}
......@@ -1239,13 +1239,16 @@ static u32 nfs4_ftypes[16] = {
*/
int
nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
struct dentry *dentry, u32 *buffer, int *countp, u32 *bmval)
struct dentry *dentry, u32 *buffer, int *countp, u32 *bmval,
struct svc_rqst *rqstp)
{
u32 bmval0 = bmval[0];
u32 bmval1 = bmval[1];
struct kstat stat;
struct name_ent *owner = NULL;
struct name_ent *group = NULL;
char owner[IDMAP_NAMESZ];
u32 ownerlen = 0;
char group[IDMAP_NAMESZ];
u32 grouplen = 0;
struct svc_fh tempfh;
struct kstatfs statfs;
int buflen = *countp << 2;
......@@ -1277,14 +1280,20 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
fhp = &tempfh;
}
if (bmval1 & FATTR4_WORD1_OWNER) {
status = name_get_user(stat.uid, &owner);
if (status)
int temp = nfsd_map_uid_to_name(rqstp, stat.uid, owner);
if (temp < 0) {
status = temp;
goto out_nfserr;
}
ownerlen = (unsigned) temp;
}
if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
status = name_get_group(stat.gid, &group);
if (status)
int temp = nfsd_map_gid_to_name(rqstp, stat.gid, group);
if (temp < 0) {
status = temp;
goto out_nfserr;
}
grouplen = (unsigned) temp;
}
if ((buflen -= 16) < 0)
......@@ -1485,20 +1494,18 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
WRITE32(stat.nlink);
}
if (bmval1 & FATTR4_WORD1_OWNER) {
int namelen = strlen(owner->name);
buflen -= (XDR_QUADLEN(namelen) << 2) + 4;
buflen -= (XDR_QUADLEN(ownerlen) << 2) + 4;
if (buflen < 0)
goto out_resource;
WRITE32(namelen);
WRITEMEM(owner->name, namelen);
WRITE32(ownerlen);
WRITEMEM(owner, ownerlen);
}
if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
int namelen = strlen(group->name);
buflen -= (XDR_QUADLEN(namelen) << 2) + 4;
buflen -= (XDR_QUADLEN(grouplen) << 2) + 4;
if (buflen < 0)
goto out_resource;
WRITE32(namelen);
WRITEMEM(group->name, namelen);
WRITE32(grouplen);
WRITEMEM(group, grouplen);
}
if (bmval1 & FATTR4_WORD1_RAWDEV) {
if ((buflen -= 8) < 0)
......@@ -1566,10 +1573,6 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
out:
if (fhp == &tempfh)
fh_put(&tempfh);
if (owner)
name_put(owner);
if (group)
name_put(group);
return status;
out_nfserr:
status = nfserrno(status);
......@@ -1648,7 +1651,8 @@ nfsd4_encode_dirent(struct readdir_cd *ccd, const char *name, int namlen,
}
nfserr = nfsd4_encode_fattr(NULL, exp,
dentry, p, &buflen, cd->rd_bmval);
dentry, p, &buflen, cd->rd_bmval,
cd->rd_rqstp);
if (!nfserr) {
p += buflen;
goto out;
......@@ -1771,7 +1775,8 @@ nfsd4_encode_getattr(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_ge
buflen = resp->end - resp->p - (COMPOUND_ERR_SLACK_SPACE >> 2);
nfserr = nfsd4_encode_fattr(fhp, fhp->fh_export, fhp->fh_dentry,
resp->p, &buflen, getattr->ga_bmval);
resp->p, &buflen, getattr->ga_bmval,
resp->rqstp);
if (!nfserr)
resp->p += buflen;
......@@ -2381,6 +2386,7 @@ nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, u32 *p, struct nfsd4_compoun
args->tmpp = NULL;
args->to_free = NULL;
args->ops = args->iops;
args->rqstp = rqstp;
status = nfsd4_decode_compound(args);
if (status) {
......
......@@ -25,6 +25,7 @@
#include <linux/init.h>
#include <linux/nfs.h>
#include <linux/nfsd_idmap.h>
#include <linux/sunrpc/svc.h>
#include <linux/nfsd/nfsd.h>
#include <linux/nfsd/cache.h>
......@@ -437,6 +438,9 @@ static int __init init_nfsd(void)
nfsd_cache_init(); /* RPC reply cache */
nfsd_export_init(); /* Exports table */
nfsd_lockd_init(); /* lockd->nfsd callbacks */
#ifdef CONFIG_NFSD_V4
nfsd_idmap_init(); /* Name to ID mapping */
#endif /* CONFIG_NFSD_V4 */
if (proc_mkdir("fs/nfs", 0)) {
struct proc_dir_entry *entry;
entry = create_proc_entry("fs/nfs/exports", 0, NULL);
......@@ -463,6 +467,9 @@ static void __exit exit_nfsd(void)
remove_proc_entry("fs/nfs", NULL);
nfsd_stat_shutdown();
nfsd_lockd_shutdown();
#ifdef CONFIG_NFSD_V4
nfsd_idmap_shutdown();
#endif /* CONFIG_NFSD_V4 */
unregister_filesystem(&nfsd_fs_type);
}
......
......@@ -585,6 +585,7 @@ nfserrno (int errno)
{ nfserr_dquot, -EDQUOT },
#endif
{ nfserr_stale, -ESTALE },
{ nfserr_jukebox, -ETIMEDOUT },
{ nfserr_dropit, -EAGAIN },
{ nfserr_dropit, -ENOMEM },
{ -1, -EIO }
......
......@@ -375,7 +375,9 @@ struct nfsd4_compoundargs {
struct tmpbuf *next;
void *buf;
} *to_free;
struct svc_rqst *rqstp;
u32 taglen;
char * tag;
u32 minorversion;
......@@ -419,7 +421,7 @@ void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *);
void nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op);
int nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
struct dentry *dentry, u32 *buffer, int *countp,
u32 *bmval);
u32 *bmval, struct svc_rqst *);
extern int nfsd4_setclientid(struct svc_rqst *rqstp,
struct nfsd4_setclientid *setclid);
extern int nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
......
/*
* include/linux/nfsd_idmap.h
*
* Mapping of UID to name and vice versa.
*
* Copyright (c) 2002, 2003 The Regents of the University of
* Michigan. All rights reserved.
> *
* Marius Aamodt Eriksen <marius@umich.edu>
*
* 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_NFSD_IDMAP_H
#define LINUX_NFSD_IDMAP_H
#include <linux/in.h>
#include <linux/sunrpc/svc.h>
/* XXX from linux/nfs_idmap.h */
#define IDMAP_NAMESZ 128
void nfsd_idmap_init(void);
void nfsd_idmap_shutdown(void);
int nfsd_map_name_to_uid(struct svc_rqst *, const char *, size_t, __u32 *);
int nfsd_map_name_to_gid(struct svc_rqst *, const char *, size_t, __u32 *);
int nfsd_map_uid_to_name(struct svc_rqst *, __u32, char *);
int nfsd_map_gid_to_name(struct svc_rqst *, __u32, char *);
#endif /* LINUX_NFSD_IDMAP_H */
......@@ -43,7 +43,6 @@
#include <linux/sunrpc/sched.h>
#include <linux/sunrpc/gss_api.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/name_lookup.h>
#ifdef RPC_DEBUG
# define RPCDBG_FACILITY RPCDBG_AUTH
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment