svc_auth_unix.c revision 194498
1285SN/A/*
2487SN/A * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3285SN/A * unrestricted use provided that this legend is included on all tape
4285SN/A * media and as a part of the software program in whole or part.  Users
5285SN/A * may copy or modify Sun RPC without charge, but are not authorized
6285SN/A * to license or distribute it to anyone else except as part of a product or
7285SN/A * program developed by the user.
8285SN/A *
9285SN/A * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
10285SN/A * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
11285SN/A * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
12285SN/A *
13285SN/A * Sun RPC is provided with no support and without any obligation on the
14285SN/A * part of Sun Microsystems, Inc. to assist in its use, correction,
15285SN/A * modification or enhancement.
16285SN/A *
17285SN/A * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
18285SN/A * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
19285SN/A * OR ANY PART THEREOF.
20285SN/A *
21285SN/A * In no event will Sun Microsystems, Inc. be liable for any lost revenue
22285SN/A * or profits or other special, indirect and consequential damages, even if
23285SN/A * Sun has been advised of the possibility of such damages.
24285SN/A *
25285SN/A * Sun Microsystems, Inc.
26285SN/A * 2550 Garcia Avenue
27285SN/A * Mountain View, California  94043
28285SN/A */
29285SN/A
30285SN/A#if defined(LIBC_SCCS) && !defined(lint)
31285SN/Astatic char *sccsid2 = "@(#)svc_auth_unix.c 1.28 88/02/08 Copyr 1984 Sun Micro";
32285SN/Astatic char *sccsid = "@(#)svc_auth_unix.c	2.3 88/08/01 4.0 RPCSRC";
33285SN/A#endif
34285SN/A#include <sys/cdefs.h>
35285SN/A__FBSDID("$FreeBSD: head/sys/rpc/svc_auth_unix.c 194498 2009-06-19 17:10:35Z brooks $");
36285SN/A
37285SN/A/*
38285SN/A * svc_auth_unix.c
39285SN/A * Handles UNIX flavor authentication parameters on the service side of rpc.
40285SN/A * There are two svc auth implementations here: AUTH_UNIX and AUTH_SHORT.
41285SN/A * _svcauth_unix does full blown unix style uid,gid+gids auth,
42285SN/A * _svcauth_short uses a shorthand auth to index into a cache of longhand auths.
43285SN/A * Note: the shorthand has been gutted for efficiency.
44285SN/A *
45285SN/A * Copyright (C) 1984, Sun Microsystems, Inc.
46285SN/A */
47285SN/A
48285SN/A#include <sys/param.h>
49285SN/A#include <sys/lock.h>
50285SN/A#include <sys/mutex.h>
51285SN/A#include <sys/systm.h>
52285SN/A#include <sys/ucred.h>
53285SN/A
54285SN/A#include <rpc/rpc.h>
55285SN/A
56285SN/A#include <rpc/rpc_com.h>
57285SN/A
58285SN/A#define MAX_MACHINE_NAME	255
59285SN/A#define NGRPS			16
60285SN/A
61285SN/A/*
62285SN/A * Unix longhand authenticator
63285SN/A */
64285SN/Aenum auth_stat
65285SN/A_svcauth_unix(struct svc_req *rqst, struct rpc_msg *msg)
66285SN/A{
67487SN/A	enum auth_stat stat;
68487SN/A	XDR xdrs;
69487SN/A	int32_t *buf;
70487SN/A	uint32_t time;
71487SN/A	struct xucred *xcr;
72487SN/A	u_int auth_len;
73285SN/A	size_t str_len, gid_len;
74285SN/A	u_int i;
75285SN/A
76285SN/A	xcr = rqst->rq_clntcred;
77285SN/A	auth_len = (u_int)msg->rm_call.cb_cred.oa_length;
78285SN/A	xdrmem_create(&xdrs, msg->rm_call.cb_cred.oa_base, auth_len,
79285SN/A	    XDR_DECODE);
80285SN/A	buf = XDR_INLINE(&xdrs, auth_len);
81285SN/A	if (buf != NULL) {
82285SN/A		time = IXDR_GET_UINT32(buf);
83285SN/A		str_len = (size_t)IXDR_GET_UINT32(buf);
84285SN/A		if (str_len > MAX_MACHINE_NAME) {
85285SN/A			stat = AUTH_BADCRED;
86285SN/A			goto done;
87285SN/A		}
88285SN/A		str_len = RNDUP(str_len);
89367SN/A		buf += str_len / sizeof (int32_t);
90285SN/A		xcr->cr_uid = IXDR_GET_UINT32(buf);
91367SN/A		xcr->cr_groups[0] = IXDR_GET_UINT32(buf);
92285SN/A		gid_len = (size_t)IXDR_GET_UINT32(buf);
93285SN/A		if (gid_len > NGRPS) {
94487SN/A			stat = AUTH_BADCRED;
95285SN/A			goto done;
96285SN/A		}
97285SN/A		for (i = 0; i < gid_len; i++) {
98285SN/A			if (i + 1 < XU_NGROUPS)
99285SN/A				xcr->cr_groups[i + 1] = IXDR_GET_INT32(buf);
100285SN/A			else
101285SN/A				buf++;
102285SN/A		}
103285SN/A		if (gid_len + 1 > XU_NGROUPS)
104285SN/A			xcr->cr_ngroups = XU_NGROUPS;
105285SN/A		else
106285SN/A			xcr->cr_ngroups = gid_len + 1;
107285SN/A
108285SN/A		/*
109285SN/A		 * five is the smallest unix credentials structure -
110285SN/A		 * timestamp, hostname len (0), uid, gid, and gids len (0).
111367SN/A		 */
112285SN/A		if ((5 + gid_len) * BYTES_PER_XDR_UNIT + str_len > auth_len) {
113285SN/A			(void) printf("bad auth_len gid %ld str %ld auth %u\n",
114487SN/A			    (long)gid_len, (long)str_len, auth_len);
115285SN/A			stat = AUTH_BADCRED;
116285SN/A			goto done;
117285SN/A		}
118285SN/A	} else if (! xdr_authunix_parms(&xdrs, &time, xcr)) {
119285SN/A		stat = AUTH_BADCRED;
120285SN/A		goto done;
121285SN/A	}
122285SN/A
123285SN/A	rqst->rq_verf = _null_auth;
124285SN/A	stat = AUTH_OK;
125285SN/Adone:
126285SN/A	XDR_DESTROY(&xdrs);
127285SN/A
128285SN/A	return (stat);
129285SN/A}
130285SN/A
131285SN/A
132285SN/A/*
133285SN/A * Shorthand unix authenticator
134285SN/A * Looks up longhand in a cache.
135285SN/A */
136285SN/A/*ARGSUSED*/
137285SN/Aenum auth_stat
138285SN/A_svcauth_short(rqst, msg)
139285SN/A	struct svc_req *rqst;
140285SN/A	struct rpc_msg *msg;
141285SN/A{
142285SN/A	return (AUTH_REJECTEDCRED);
143285SN/A}
144285SN/A