summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libc/sys/nfssvc.2152
-rw-r--r--sbin/nfsd/nfsd.c21
-rw-r--r--sys/nfs/nfs_syscalls.c275
3 files changed, 56 insertions, 392 deletions
diff --git a/lib/libc/sys/nfssvc.2 b/lib/libc/sys/nfssvc.2
index 1dcb3473696..acd7e80a506 100644
--- a/lib/libc/sys/nfssvc.2
+++ b/lib/libc/sys/nfssvc.2
@@ -1,4 +1,4 @@
-.\" $OpenBSD: nfssvc.2,v 1.17 2003/10/22 04:45:54 jmc Exp $
+.\" $OpenBSD: nfssvc.2,v 1.18 2007/05/27 21:14:41 thib Exp $
.\" $NetBSD: nfssvc.2,v 1.6 1995/02/27 12:35:08 cgd Exp $
.\"
.\" Copyright (c) 1989, 1991, 1993
@@ -44,94 +44,19 @@
.Sh DESCRIPTION
The
.Fn nfssvc
-function is used by the NFS daemons to pass information into and out
-of the kernel and also to enter the kernel as a server daemon.
+function is used by the NFS daemons to pass information into the kernel
+and also to enter the kernel as a server daemon.
The
.Fa flags
argument consists of several bits that show what action is to be taken
once in the kernel and the
.Fa argstructp
-points to one of three structures depending on which bits are set in
+points to one of two structures depending on which bits are set in
flags.
.Pp
-On the client side, there is no longer a need to call
-.Fn nfssvc
-with the
-.Fa flags
-argument set to
-.Dv NFSSVC_BIOD
-since this functionality has been replaced by a
-.Nm nfsiod
-implementation using kernel threads.
-See
+To enter an
.Xr nfsd 8
-and
-.Xr sysctl 8
-for further discussion.
-For
-.Nm NQNFS ,
-.Xr mount_nfs 8
-calls
-.Fn nfssvc
-with the
-.Dv NFSSVC_MNTD
-flag, optionally or'd with the flags
-.Dv NFSSVC_GOTAUTH
-and
-.Dv NFSSVC_AUTHINFAIL
-along with a pointer to a
-.Bd -literal
-struct nfsd_cargs {
- char *ncd_dirp; /* Mount dir path */
- uid_t ncd_authuid; /* Effective uid */
- int ncd_authtype; /* Type of authenticator */
- u_int ncd_authlen; /* Length of authenticator string */
- u_char *ncd_authstr; /* Authenticator string */
- u_int ncd_verflen; /* and the verifier */
- u_char *ncd_verfstr;
- NFSKERBKEY_T ncd_key; /* Session key */
-};
-.Ed
-.Pp
-structure.
-The initial call has only the
-.Dv NFSSVC_MNTD
-flag set to specify service for the mount point.
-If the mount point is using Kerberos, then the
-.Xr mount_nfs 8
-daemon will return from
-.Fn nfssvc
-with
-.Va errno
-set to
-.Er ENEEDAUTH
-whenever the client side requires an
-.Dq rcmd
-authentication ticket for the user.
-.Xr mount_nfs 8
-will attempt to get the Kerberos ticket, and if successful will call
-.Fn nfssvc
-with the flags
-.Dv NFSSVC_MNTD
-and
-.Dv NFSSVC_GOTAUTH
-after filling the ticket into the
-ncd_authstr field
-and
-setting the ncd_authlen and ncd_authtype
-fields of the nfsd_cargs structure.
-If
-.Xr mount_nfs 8
-failed to get the ticket,
-.Fn nfssvc
-will be called with the flags
-.Dv NFSSVC_MNTD ,
-.Dv NFSSVC_GOTAUTH
-and
-.Dv NFSSVC_AUTHINFAIL
-to denote a failed authentication attempt.
-.Pp
-On the server side,
+daemon into the kernel
.Fn nfssvc
is called with the flag
.Dv NFSSVC_NFSD
@@ -151,51 +76,13 @@ struct nfsd_srvargs {
NFSKERBKEY_T nsd_key; /* Session key */
};
.Ed
+structure.
.Pp
-to enter the kernel as an
-.Xr nfsd 8
-daemon.
-Whenever an
+To add further sockets for processing by the
.Xr nfsd 8
-daemon receives a Kerberos authentication ticket, it will return from
-.Fn nfssvc
-with
-.Va errno
-set to
-.Er ENEEDAUTH .
-The
-.Xr nfsd 8
-will attempt to authenticate the ticket and generate a set of credentials
-on the server for the user ID specified in the field nsd_uid.
-This is done by first authenticating the Kerberos ticket and then mapping
-the Kerberos principal to a local name and getting a set of credentials for
-that user via
-.Xr getpwnam 3
-and
-.Xr getgrouplist 3 .
-If successful, the
-.Xr nfsd 8
-will call
-.Fn nfssvc
-with the
-.Dv NFSSVC_NFSD
-and
-.Dv NFSSVC_AUTHIN
-flags set to pass the credential mapping in nsd_cr into the
-kernel to be cached on the server socket for that client.
-If the authentication failed,
-.Xr nfsd 8
-calls
-.Fn nfssvc
-with the flags
-.Dv NFSSVC_NFSD
-and
-.Dv NFSSVC_AUTHINFAIL
-to denote an authentication failure.
-.Pp
-The master
+server daemons the master
.Xr nfsd 8
-server daemon calls
+daemon calls
.Fn nfssvc
with the flag
.Dv NFSSVC_ADDSOCK
@@ -207,12 +94,8 @@ struct nfsd_args {
int namelen; /* Length of name */
};
.Ed
+structure.
.Pp
-to pass a server side
-.Tn NFS
-socket into the kernel for servicing by the
-.Xr nfsd 8
-daemons.
.Sh RETURN VALUES
Normally
.Nm nfssvc
@@ -223,12 +106,11 @@ Otherwise, \-1 is returned and the global variable
is set to specify the error.
.Sh ERRORS
.Bl -tag -width Er
-.It Bq Er ENEEDAUTH
-This special error value
-is really used for authentication support, particularly Kerberos,
-as explained above.
.It Bq Er EPERM
The caller is not the superuser.
+.It Bq Er EINVAL
+The flag argument consisted of incompatible or otherwise
+unsupported bits.
.El
.Sh SEE ALSO
.Xr mount_nfs 8 ,
@@ -245,11 +127,7 @@ The
system call is designed specifically for the
.Tn NFS
support daemons and as such is specific to their requirements.
-It should really return values to indicate the need for authentication
-support, since
-.Er ENEEDAUTH
-is not really an error.
Several fields of the argument structures are assumed to be valid and
sometimes to be unchanged from a previous call, such that
-.Nm nfssvc
+.Fn nfssvc
must be used with extreme care.
diff --git a/sbin/nfsd/nfsd.c b/sbin/nfsd/nfsd.c
index b963f55dbbb..14286e1159b 100644
--- a/sbin/nfsd/nfsd.c
+++ b/sbin/nfsd/nfsd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nfsd.c,v 1.26 2005/12/02 01:08:01 deraadt Exp $ */
+/* $OpenBSD: nfsd.c,v 1.27 2007/05/27 21:14:41 thib Exp $ */
/* $NetBSD: nfsd.c,v 1.19 1996/02/18 23:18:56 mycroft Exp $ */
/*
@@ -43,7 +43,7 @@ static const char copyright[] =
#if 0
static const char sccsid[] = "@(#)nfsd.c 8.9 (Berkeley) 3/29/95";
#else
-static const char rcsid[] = "$OpenBSD: nfsd.c,v 1.26 2005/12/02 01:08:01 deraadt Exp $";
+static const char rcsid[] = "$OpenBSD: nfsd.c,v 1.27 2007/05/27 21:14:41 thib Exp $";
#endif
#endif /* not lint */
@@ -120,7 +120,7 @@ main(int argc, char *argv[])
fd_set *ready, *sockbits;
size_t fd_size;
int ch, connect_type_cnt, i, maxsock = 0, msgsock;
- int nfsdcnt = DEFNFSDCNT, nfssvc_flag, on, reregister = 0, sock;
+ int nfsdcnt = DEFNFSDCNT, on, reregister = 0, sock;
int udpflag = 0, tcpflag = 0, tcpsock;
const char *errstr = NULL;
socklen_t len;
@@ -199,14 +199,10 @@ main(int argc, char *argv[])
}
setproctitle("server");
- nfssvc_flag = NFSSVC_NFSD;
nsd.nsd_nfsd = NULL;
- while (nfssvc(nfssvc_flag, &nsd) < 0) {
- if (errno != ENEEDAUTH) {
- syslog(LOG_ERR, "nfssvc: %m");
- return (1);
- }
- nfssvc_flag = NFSSVC_NFSD | NFSSVC_AUTHINFAIL;
+ if (nfssvc(NFSSVC_NFSD, &nsd) < 0) {
+ syslog(LOG_ERR, "nfssvc: %m");
+ return (1);
}
return (0);
}
@@ -323,7 +319,10 @@ main(int argc, char *argv[])
nfsdargs.sock = msgsock;
nfsdargs.name = (caddr_t)&inetpeer;
nfsdargs.namelen = sizeof(inetpeer);
- nfssvc(NFSSVC_ADDSOCK, &nfsdargs);
+ if (nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) {
+ syslog(LOG_ERR, "can't Add TCP socket");
+ return (1);
+ }
(void)close(msgsock);
}
}
diff --git a/sys/nfs/nfs_syscalls.c b/sys/nfs/nfs_syscalls.c
index 25e956d0f8c..a6da0887e1e 100644
--- a/sys/nfs/nfs_syscalls.c
+++ b/sys/nfs/nfs_syscalls.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nfs_syscalls.c,v 1.50 2006/11/29 12:24:18 miod Exp $ */
+/* $OpenBSD: nfs_syscalls.c,v 1.51 2007/05/27 21:14:41 thib Exp $ */
/* $NetBSD: nfs_syscalls.c,v 1.19 1996/02/18 11:53:52 fvdl Exp $ */
/*
@@ -109,187 +109,57 @@ int nfs_niothreads = -1;
static void nfsd_rt(int, struct nfsrv_descript *, int);
#endif
-int nfs_clientd(struct nfsmount *nmp, struct ucred *cred,
- struct nfsd_cargs *ncd, int flag, caddr_t argp, struct proc *p);
-
/*
- * Nfs client helper daemon.
- * It also get authorization strings for "kerb" mounts.
- * It must start at the beginning of the list again after any potential
- * "sleep" since nfs_reclaim() called from vclean() can pull a node off
- * the list asynchronously.
- */
-int
-nfs_clientd(struct nfsmount *nmp, struct ucred *cred, struct nfsd_cargs *ncd,
- int flag, caddr_t argp, struct proc *p)
-{
- struct nfsuid *nuidp, *nnuidp;
- int error = 0;
-
- /*
- * First initialize some variables
- */
-
- /*
- * If an authorization string is being passed in, get it.
- */
- if ((flag & NFSSVC_GOTAUTH) &&
- (nmp->nm_flag & (NFSMNT_WAITAUTH | NFSMNT_DISMNT)) == 0) {
- if (nmp->nm_flag & NFSMNT_HASAUTH)
- panic("cld kerb");
- if ((flag & NFSSVC_AUTHINFAIL) == 0) {
- if (ncd->ncd_authlen <= nmp->nm_authlen &&
- ncd->ncd_verflen <= nmp->nm_verflen &&
- !copyin(ncd->ncd_authstr,nmp->nm_authstr,ncd->ncd_authlen)&&
- !copyin(ncd->ncd_verfstr,nmp->nm_verfstr,ncd->ncd_verflen)){
- nmp->nm_authtype = ncd->ncd_authtype;
- nmp->nm_authlen = ncd->ncd_authlen;
- nmp->nm_verflen = ncd->ncd_verflen;
- } else
- nmp->nm_flag |= NFSMNT_AUTHERR;
- } else
- nmp->nm_flag |= NFSMNT_AUTHERR;
- nmp->nm_flag |= NFSMNT_HASAUTH;
- wakeup((caddr_t)&nmp->nm_authlen);
- } else
- nmp->nm_flag |= NFSMNT_WAITAUTH;
-
- /*
- * Loop every second updating queue until there is a termination sig.
- */
- while ((nmp->nm_flag & NFSMNT_DISMNT) == 0) {
- /*
- * Get an authorization string, if required.
- */
- if ((nmp->nm_flag & (NFSMNT_WAITAUTH | NFSMNT_DISMNT | NFSMNT_HASAUTH)) == 0) {
- ncd->ncd_authuid = nmp->nm_authuid;
- if (copyout((caddr_t)ncd, argp, sizeof (struct nfsd_cargs)))
- nmp->nm_flag |= NFSMNT_WAITAUTH;
- else
- return (ENEEDAUTH);
- }
-
- /*
- * Wait a bit (no pun) and do it again.
- */
- if ((nmp->nm_flag & NFSMNT_DISMNT) == 0 &&
- (nmp->nm_flag & (NFSMNT_WAITAUTH | NFSMNT_HASAUTH))) {
- error = tsleep((caddr_t)&nmp->nm_authstr, PSOCK | PCATCH,
- "nqnfstimr", hz / 3);
- if (error == EINTR || error == ERESTART) {
- if (vfs_busy(nmp->nm_mountp, VB_WRITE|VB_WAIT) == 0)
- dounmount(nmp->nm_mountp, MNT_FORCE, p, NULL);
- }
- }
- }
-
- /*
- * Finally, we can free up the mount structure.
- */
- for (nuidp = TAILQ_FIRST(&nmp->nm_uidlruhead); nuidp != NULL;
- nuidp = nnuidp) {
- nnuidp = TAILQ_NEXT(nuidp, nu_lru);
- LIST_REMOVE(nuidp, nu_hash);
- TAILQ_REMOVE(&nmp->nm_uidlruhead, nuidp, nu_lru);
- free((caddr_t)nuidp, M_NFSUID);
- }
- free((caddr_t)nmp, M_NFSMNT);
- if (error == EWOULDBLOCK)
- error = 0;
- return (error);
-}
-
-
-/*
- * NFS server system calls
- */
-
-/*
- * Nfs server pseudo system call for the nfsd's
+ * NFS server pseudo system call for the nfsd's
* Based on the flag value it either:
* - adds a socket to the selection list
* - remains in the kernel as an nfsd
- * - remains in the kernel as an nfsiod
*/
int
-sys_nfssvc(p, v, retval)
- struct proc *p;
- void *v;
- register_t *retval;
+sys_nfssvc(struct proc *p, void *v, register_t *retval)
{
struct sys_nfssvc_args /* {
syscallarg(int) flag;
syscallarg(caddr_t) argp;
} */ *uap = v;
-#ifdef NFSCLIENT
- struct nameidata nd;
- struct nfsmount *nmp;
- struct nfsd_cargs ncd;
-#endif
- int error;
+ int flags = SCARG(uap, flag);
+ int error = 0;
#ifdef NFSSERVER
struct file *fp;
struct mbuf *nam;
struct nfsd_args nfsdarg;
struct nfsd_srvargs nfsd_srvargs, *nsd = &nfsd_srvargs;
- struct nfsd *nfsd;
- struct nfssvc_sock *slp;
- struct nfsuid *nuidp;
#endif
- /*
- * Must be super user
- */
+ /* Must be super user */
error = suser(p, 0);
- if(error)
+ if (error)
return (error);
- while (nfssvc_sockhead_flag & SLP_INIT) {
- nfssvc_sockhead_flag |= SLP_WANTINIT;
- (void) tsleep((caddr_t)&nfssvc_sockhead, PSOCK, "nfsd init", 0);
- }
- if (SCARG(uap, flag) & NFSSVC_BIOD) {
- error = ENOSYS;
- } else if (SCARG(uap, flag) & NFSSVC_MNTD) {
-#ifndef NFSCLIENT
- error = ENOSYS;
-#else
- error = copyin(SCARG(uap, argp), (caddr_t)&ncd, sizeof (ncd));
- if (error)
- return (error);
- NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
- ncd.ncd_dirp, p);
- error = namei(&nd);
- if (error)
- return (error);
- if ((nd.ni_vp->v_flag & VROOT) == 0)
- error = EINVAL;
- nmp = VFSTONFS(nd.ni_vp->v_mount);
- vput(nd.ni_vp);
- if (error)
- return (error);
- if ((nmp->nm_flag & NFSMNT_MNTD) &&
- (SCARG(uap, flag) & NFSSVC_GOTAUTH) == 0)
- return (0);
- nmp->nm_flag |= NFSMNT_MNTD;
- error = nfs_clientd(nmp, p->p_ucred, &ncd, SCARG(uap, flag),
- SCARG(uap, argp), p);
-#endif /* NFSCLIENT */
- } else if (SCARG(uap, flag) & NFSSVC_ADDSOCK) {
+
#ifndef NFSSERVER
- error = ENOSYS;
+ error = ENOSYS;
#else
- error = copyin(SCARG(uap, argp), (caddr_t)&nfsdarg,
- sizeof(nfsdarg));
+
+ while (nfssvc_sockhead_flag & SLP_INIT) {
+ nfssvc_sockhead_flag |= SLP_WANTINIT;
+ tsleep(&nfssvc_sockhead, PSOCK, "nfsd init", 0);
+ }
+
+ switch (flags) {
+ case NFSSVC_ADDSOCK:
+ error = copyin(SCARG(uap, argp), &nfsdarg, sizeof(nfsdarg));
if (error)
return (error);
+
error = getsock(p->p_fd, nfsdarg.sock, &fp);
if (error)
return (error);
+
/*
* Get the client address for connected sockets.
*/
if (nfsdarg.name == NULL || nfsdarg.namelen == 0)
- nam = (struct mbuf *)0;
+ nam = NULL;
else {
error = sockargs(&nam, nfsdarg.name, nfsdarg.namelen,
MT_SONAME);
@@ -300,106 +170,23 @@ sys_nfssvc(p, v, retval)
}
error = nfssvc_addsock(fp, nam);
FRELE(fp);
-#endif /* !NFSSERVER */
- } else {
-#ifndef NFSSERVER
- error = ENOSYS;
-#else
- error = copyin(SCARG(uap, argp), (caddr_t)nsd, sizeof (*nsd));
+ break;
+ case NFSSVC_NFSD:
+ error = copyin(SCARG(uap, argp), nsd, sizeof(*nsd));
if (error)
return (error);
- if ((SCARG(uap, flag) & NFSSVC_AUTHIN) &&
- ((nfsd = nsd->nsd_nfsd)) != NULL &&
- (nfsd->nfsd_slp->ns_flag & SLP_VALID)) {
- slp = nfsd->nfsd_slp;
-
- /*
- * First check to see if another nfsd has already
- * added this credential.
- */
- LIST_FOREACH(nuidp, NUIDHASH(slp,nsd->nsd_cr.cr_uid),
- nu_hash) {
- if (nuidp->nu_cr.cr_uid == nsd->nsd_cr.cr_uid &&
- (!nfsd->nfsd_nd->nd_nam2 ||
- netaddr_match(NU_NETFAM(nuidp),
- &nuidp->nu_haddr, nfsd->nfsd_nd->nd_nam2)))
- break;
- }
- if (nuidp) {
- nfsrv_setcred(&nuidp->nu_cr,&nfsd->nfsd_nd->nd_cr);
- nfsd->nfsd_nd->nd_flag |= ND_KERBFULL;
- } else {
- /*
- * Nope, so we will.
- */
- if (slp->ns_numuids < nuidhash_max) {
- slp->ns_numuids++;
- nuidp = (struct nfsuid *)
- malloc(sizeof (struct nfsuid), M_NFSUID,
- M_WAITOK);
- } else
- nuidp = (struct nfsuid *)0;
- if ((slp->ns_flag & SLP_VALID) == 0) {
- if (nuidp)
- free((caddr_t)nuidp, M_NFSUID);
- } else {
- if (nuidp == (struct nfsuid *)0) {
- nuidp = TAILQ_FIRST(&slp->ns_uidlruhead);
- LIST_REMOVE(nuidp, nu_hash);
- TAILQ_REMOVE(&slp->ns_uidlruhead, nuidp,
- nu_lru);
- if (nuidp->nu_flag & NU_NAM)
- m_freem(nuidp->nu_nam);
- }
- nuidp->nu_flag = 0;
- nuidp->nu_cr = nsd->nsd_cr;
- if (nuidp->nu_cr.cr_ngroups > NGROUPS)
- nuidp->nu_cr.cr_ngroups = NGROUPS;
- nuidp->nu_cr.cr_ref = 1;
- nuidp->nu_timestamp = nsd->nsd_timestamp;
- nuidp->nu_expire = time_second + nsd->nsd_ttl;
- /*
- * and save the session key in nu_key.
- */
- bcopy(nsd->nsd_key, nuidp->nu_key,
- sizeof (nsd->nsd_key));
- if (nfsd->nfsd_nd->nd_nam2) {
- struct sockaddr_in *saddr;
- saddr = mtod(nfsd->nfsd_nd->nd_nam2,
- struct sockaddr_in *);
- switch (saddr->sin_family) {
- case AF_INET:
- nuidp->nu_flag |= NU_INETADDR;
- nuidp->nu_inetaddr =
- saddr->sin_addr.s_addr;
- break;
- default:
- nuidp->nu_flag |= NU_NAM;
- nuidp->nu_nam = m_copym(
- nfsd->nfsd_nd->nd_nam2, 0,
- M_COPYALL, M_WAIT);
- break;
- };
- }
- TAILQ_INSERT_TAIL(&slp->ns_uidlruhead, nuidp,
- nu_lru);
- LIST_INSERT_HEAD(NUIDHASH(slp, nsd->nsd_uid),
- nuidp, nu_hash);
- nfsrv_setcred(&nuidp->nu_cr,
- &nfsd->nfsd_nd->nd_cr);
- nfsd->nfsd_nd->nd_flag |= ND_KERBFULL;
- }
- }
- }
- if ((SCARG(uap, flag) & NFSSVC_AUTHINFAIL) &&
- (nfsd = nsd->nsd_nfsd))
- nfsd->nfsd_flag |= NFSD_AUTHFAIL;
error = nfssvc_nfsd(nsd, SCARG(uap, argp), p);
-#endif /* !NFSSERVER */
+ break;
+ default:
+ error = EINVAL;
+ break;
}
+
if (error == EINTR || error == ERESTART)
error = 0;
+#endif /* !NFSSERVER */
+
return (error);
}