~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/net/sunrpc/svcauth.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * linux/net/sunrpc/svcauth.c
  3  *
  4  * The generic interface for RPC authentication on the server side.
  5  * 
  6  * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
  7  *
  8  * CHANGES
  9  * 19-Apr-2000 Chris Evans      - Security fix
 10  */
 11 
 12 #include <linux/types.h>
 13 #include <linux/sched.h>
 14 #include <linux/sunrpc/types.h>
 15 #include <linux/sunrpc/xdr.h>
 16 #include <linux/sunrpc/svcauth.h>
 17 #include <linux/sunrpc/svcsock.h>
 18 
 19 #define RPCDBG_FACILITY RPCDBG_AUTH
 20 
 21 /*
 22  * Type of authenticator function
 23  */
 24 typedef void    (*auth_fn_t)(struct svc_rqst *rqstp, u32 *statp, u32 *authp);
 25 
 26 /*
 27  * Builtin auth flavors
 28  */
 29 static void     svcauth_null(struct svc_rqst *rqstp, u32 *statp, u32 *authp);
 30 static void     svcauth_unix(struct svc_rqst *rqstp, u32 *statp, u32 *authp);
 31 
 32 /*
 33  * Max number of authentication flavors we support
 34  */
 35 #define RPC_SVCAUTH_MAX 8
 36 
 37 /*
 38  * Table of authenticators
 39  */
 40 static auth_fn_t        authtab[RPC_SVCAUTH_MAX] = {
 41         svcauth_null,
 42         svcauth_unix,
 43         NULL,
 44 };
 45 
 46 void
 47 svc_authenticate(struct svc_rqst *rqstp, u32 *statp, u32 *authp)
 48 {
 49         u32             flavor;
 50         auth_fn_t       func;
 51 
 52         *statp = rpc_success;
 53         *authp = rpc_auth_ok;
 54 
 55         svc_getlong(&rqstp->rq_argbuf, flavor);
 56         flavor = ntohl(flavor);
 57 
 58         dprintk("svc: svc_authenticate (%d)\n", flavor);
 59         if (flavor >= RPC_SVCAUTH_MAX || !(func = authtab[flavor])) {
 60                 *authp = rpc_autherr_badcred;
 61                 return;
 62         }
 63 
 64         rqstp->rq_cred.cr_flavor = flavor;
 65         func(rqstp, statp, authp);
 66 }
 67 
 68 int
 69 svc_auth_register(u32 flavor, auth_fn_t func)
 70 {
 71         if (flavor >= RPC_SVCAUTH_MAX || authtab[flavor])
 72                 return -EINVAL;
 73         authtab[flavor] = func;
 74         return 0;
 75 }
 76 
 77 void
 78 svc_auth_unregister(u32 flavor)
 79 {
 80         if (flavor < RPC_SVCAUTH_MAX)
 81                 authtab[flavor] = NULL;
 82 }
 83 
 84 static void
 85 svcauth_null(struct svc_rqst *rqstp, u32 *statp, u32 *authp)
 86 {
 87         struct svc_buf  *argp = &rqstp->rq_argbuf;
 88         struct svc_buf  *resp = &rqstp->rq_resbuf;
 89 
 90         if ((argp->len -= 3) < 0) {
 91                 *statp = rpc_garbage_args;
 92                 return;
 93         }
 94         if (*(argp->buf)++ != 0) {      /* we already skipped the flavor */
 95                 dprintk("svc: bad null cred\n");
 96                 *authp = rpc_autherr_badcred;
 97                 return;
 98         }
 99         if (*(argp->buf)++ != RPC_AUTH_NULL || *(argp->buf)++ != 0) {
100                 dprintk("svc: bad null verf\n");
101                 *authp = rpc_autherr_badverf;
102                 return;
103         }
104 
105         /* Signal that mapping to nobody uid/gid is required */
106         rqstp->rq_cred.cr_uid = (uid_t) -1;
107         rqstp->rq_cred.cr_gid = (gid_t) -1;
108         rqstp->rq_cred.cr_groups[0] = NOGROUP;
109 
110         /* Put NULL verifier */
111         rqstp->rq_verfed = 1;
112         svc_putlong(resp, RPC_AUTH_NULL);
113         svc_putlong(resp, 0);
114 }
115 
116 static void
117 svcauth_unix(struct svc_rqst *rqstp, u32 *statp, u32 *authp)
118 {
119         struct svc_buf  *argp = &rqstp->rq_argbuf;
120         struct svc_buf  *resp = &rqstp->rq_resbuf;
121         struct svc_cred *cred = &rqstp->rq_cred;
122         u32             *bufp = argp->buf, slen, i;
123         int             len   = argp->len;
124 
125         if ((len -= 3) < 0) {
126                 *statp = rpc_garbage_args;
127                 return;
128         }
129 
130         bufp++;                                 /* length */
131         bufp++;                                 /* time stamp */
132         slen = (ntohl(*bufp++) + 3) >> 2;       /* machname length */
133         if (slen > 64 || (len -= slen + 3) < 0)
134                 goto badcred;
135         bufp += slen;                           /* skip machname */
136 
137         cred->cr_uid = ntohl(*bufp++);          /* uid */
138         cred->cr_gid = ntohl(*bufp++);          /* gid */
139 
140         slen = ntohl(*bufp++);                  /* gids length */
141         if (slen > 16 || (len -= slen + 2) < 0)
142                 goto badcred;
143         for (i = 0; i < NGROUPS && i < slen; i++)
144                 cred->cr_groups[i] = ntohl(*bufp++);
145         if (i < NGROUPS)
146                 cred->cr_groups[i] = NOGROUP;
147         bufp += (slen - i);
148 
149         if (*bufp++ != RPC_AUTH_NULL || *bufp++ != 0) {
150                 *authp = rpc_autherr_badverf;
151                 return;
152         }
153 
154         argp->buf = bufp;
155         argp->len = len;
156 
157         /* Put NULL verifier */
158         rqstp->rq_verfed = 1;
159         svc_putlong(resp, RPC_AUTH_NULL);
160         svc_putlong(resp, 0);
161 
162         return;
163 
164 badcred:
165         *authp = rpc_autherr_badcred;
166 }
167 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.