patch-2.1.32 linux/net/sunrpc/svcauth.c

Next file: linux/net/sunrpc/svcauth_des.c
Previous file: linux/net/sunrpc/svc.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.31/linux/net/sunrpc/svcauth.c linux/net/sunrpc/svcauth.c
@@ -0,0 +1,163 @@
+/*
+ * linux/net/sunrpc/svcauth.c
+ *
+ * The generic interface for RPC authentication on the server side.
+ * 
+ * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/sunrpc/types.h>
+#include <linux/sunrpc/xdr.h>
+#include <linux/sunrpc/svcauth.h>
+#include <linux/sunrpc/svcsock.h>
+
+#define RPCDBG_FACILITY	RPCDBG_AUTH
+
+/*
+ * Type of authenticator function
+ */
+typedef void	(*auth_fn_t)(struct svc_rqst *rqstp, u32 *statp, u32 *authp);
+
+/*
+ * Builtin auth flavors
+ */
+static void	svcauth_null(struct svc_rqst *rqstp, u32 *statp, u32 *authp);
+static void	svcauth_unix(struct svc_rqst *rqstp, u32 *statp, u32 *authp);
+
+/*
+ * Max number of authentication flavors we support
+ */
+#define RPC_SVCAUTH_MAX	8
+
+/*
+ * Table of authenticators
+ */
+static auth_fn_t	authtab[RPC_SVCAUTH_MAX] = {
+	svcauth_null,
+	svcauth_unix,
+	NULL,
+};
+
+void
+svc_authenticate(struct svc_rqst *rqstp, u32 *statp, u32 *authp)
+{
+	u32		flavor;
+	auth_fn_t	func;
+
+	*statp = rpc_success;
+	*authp = rpc_auth_ok;
+
+	svc_getlong(&rqstp->rq_argbuf, flavor);
+	flavor = ntohl(flavor);
+
+	dprintk("svc: svc_authenticate (%d)\n", flavor);
+	if (flavor >= RPC_SVCAUTH_MAX || !(func = authtab[flavor])) {
+		*authp = rpc_autherr_badcred;
+		return;
+	}
+
+	rqstp->rq_cred.cr_flavor = flavor;
+	func(rqstp, statp, authp);
+}
+
+int
+svc_auth_register(u32 flavor, auth_fn_t func)
+{
+	if (flavor >= RPC_SVCAUTH_MAX || authtab[flavor])
+		return -EINVAL;
+	authtab[flavor] = func;
+	return 0;
+}
+
+void
+svc_auth_unregister(u32 flavor)
+{
+	if (flavor < RPC_SVCAUTH_MAX)
+		authtab[flavor] = NULL;
+}
+
+static void
+svcauth_null(struct svc_rqst *rqstp, u32 *statp, u32 *authp)
+{
+	struct svc_buf	*argp = &rqstp->rq_argbuf;
+	struct svc_buf	*resp = &rqstp->rq_resbuf;
+
+	if ((argp->len -= 3) < 0) {
+		*statp = rpc_garbage_args;
+		return;
+	}
+	if (*(argp->buf)++ != 0) {	/* we already skipped the flavor */
+		dprintk("svc: bad null cred\n");
+		*authp = rpc_autherr_badcred;
+		return;
+	}
+	if (*(argp->buf)++ != RPC_AUTH_NULL || *(argp->buf)++ != 0) {
+		dprintk("svc: bad null verf\n");
+		*authp = rpc_autherr_badverf;
+		return;
+	}
+
+	/* Signal that mapping to nobody uid/gid is required */
+	rqstp->rq_cred.cr_uid = (uid_t) -1;
+	rqstp->rq_cred.cr_gid = (gid_t) -1;
+	rqstp->rq_cred.cr_groups[0] = NOGROUP;
+
+	/* Put NULL verifier */
+	rqstp->rq_verfed = 1;
+	svc_putlong(resp, RPC_AUTH_NULL);
+	svc_putlong(resp, 0);
+}
+
+static void
+svcauth_unix(struct svc_rqst *rqstp, u32 *statp, u32 *authp)
+{
+	struct svc_buf	*argp = &rqstp->rq_argbuf;
+	struct svc_buf	*resp = &rqstp->rq_resbuf;
+	struct svc_cred	*cred = &rqstp->rq_cred;
+	u32		*bufp = argp->buf;
+	int		len   = argp->len, slen, i;
+
+	if ((len -= 3) < 0) {
+		*statp = rpc_garbage_args;
+		return;
+	}
+
+	bufp++;					/* length */
+	bufp++;					/* time stamp */
+	slen = (ntohl(*bufp++) + 3) >> 2;	/* machname length */
+	if (slen > 64 || (len -= slen) < 0)
+		goto badcred;
+	bufp += slen;				/* skip machname */
+
+	cred->cr_uid = ntohl(*bufp++);		/* uid */
+	cred->cr_gid = ntohl(*bufp++);		/* gid */
+
+	slen = ntohl(*bufp++);			/* gids length */
+	if (slen > 16 || (len -= slen + 2) < 0)
+		goto badcred;
+	for (i = 0; i < NGROUPS && i < slen; i++)
+		cred->cr_groups[i] = ntohl(*bufp++);
+	if (i < NGROUPS)
+		cred->cr_groups[i] = NOGROUP;
+	bufp += (slen - i);
+
+	if (*bufp++ != RPC_AUTH_NULL || *bufp++ != 0) {
+		*authp = rpc_autherr_badverf;
+		return;
+	}
+
+	argp->buf = bufp;
+	argp->len = len;
+
+	/* Put NULL verifier */
+	rqstp->rq_verfed = 1;
+	svc_putlong(resp, RPC_AUTH_NULL);
+	svc_putlong(resp, 0);
+
+	return;
+
+badcred:
+	*authp = rpc_autherr_badcred;
+}

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov