Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/lib/libc/rpc/auth_unix.c
39476 views
1
/* $NetBSD: auth_unix.c,v 1.18 2000/07/06 03:03:30 christos Exp $ */
2
3
/*-
4
* SPDX-License-Identifier: BSD-3-Clause
5
*
6
* Copyright (c) 2009, Sun Microsystems, Inc.
7
* All rights reserved.
8
*
9
* Redistribution and use in source and binary forms, with or without
10
* modification, are permitted provided that the following conditions are met:
11
* - Redistributions of source code must retain the above copyright notice,
12
* this list of conditions and the following disclaimer.
13
* - Redistributions in binary form must reproduce the above copyright notice,
14
* this list of conditions and the following disclaimer in the documentation
15
* and/or other materials provided with the distribution.
16
* - Neither the name of Sun Microsystems, Inc. nor the names of its
17
* contributors may be used to endorse or promote products derived
18
* from this software without specific prior written permission.
19
*
20
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
* POSSIBILITY OF SUCH DAMAGE.
31
*/
32
33
/*
34
* auth_unix.c, Implements UNIX style authentication parameters.
35
*
36
* Copyright (C) 1984, Sun Microsystems, Inc.
37
*
38
* The system is very weak. The client uses no encryption for it's
39
* credentials and only sends null verifiers. The server sends backs
40
* null verifiers or optionally a verifier that suggests a new short hand
41
* for the credentials.
42
*
43
*/
44
45
#include "namespace.h"
46
#include "reentrant.h"
47
#include <sys/param.h>
48
49
#include <assert.h>
50
#include <err.h>
51
#include <stdio.h>
52
#include <stdlib.h>
53
#include <unistd.h>
54
#include <string.h>
55
56
#include <rpc/types.h>
57
#include <rpc/xdr.h>
58
#include <rpc/auth.h>
59
#include <rpc/auth_unix.h>
60
#include "un-namespace.h"
61
#include "mt_misc.h"
62
63
/* auth_unix.c */
64
static void authunix_nextverf (AUTH *);
65
static bool_t authunix_marshal (AUTH *, XDR *);
66
static bool_t authunix_validate (AUTH *, struct opaque_auth *);
67
static bool_t authunix_refresh (AUTH *, void *);
68
static void authunix_destroy (AUTH *);
69
static void marshal_new_auth (AUTH *);
70
static struct auth_ops *authunix_ops (void);
71
72
/*
73
* This struct is pointed to by the ah_private field of an auth_handle.
74
*/
75
struct audata {
76
struct opaque_auth au_origcred; /* original credentials */
77
struct opaque_auth au_shcred; /* short hand cred */
78
u_long au_shfaults; /* short hand cache faults */
79
char au_marshed[MAX_AUTH_BYTES];
80
u_int au_mpos; /* xdr pos at end of marshed */
81
};
82
#define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private)
83
84
/*
85
* Create a unix style authenticator.
86
* Returns an auth handle with the given stuff in it.
87
*/
88
AUTH *
89
authunix_create(char *machname, u_int uid, u_int gid, int len, u_int *aup_gids)
90
{
91
struct authunix_parms aup;
92
char mymem[MAX_AUTH_BYTES];
93
struct timeval now;
94
XDR xdrs;
95
AUTH *auth;
96
struct audata *au;
97
98
/*
99
* Allocate and set up auth handle
100
*/
101
au = NULL;
102
auth = mem_alloc(sizeof(*auth));
103
#ifndef _KERNEL
104
if (auth == NULL) {
105
warnx("authunix_create: out of memory");
106
goto cleanup_authunix_create;
107
}
108
#endif
109
au = mem_alloc(sizeof(*au));
110
#ifndef _KERNEL
111
if (au == NULL) {
112
warnx("authunix_create: out of memory");
113
goto cleanup_authunix_create;
114
}
115
#endif
116
auth->ah_ops = authunix_ops();
117
auth->ah_private = (caddr_t)au;
118
auth->ah_verf = au->au_shcred = _null_auth;
119
au->au_shfaults = 0;
120
au->au_origcred.oa_base = NULL;
121
122
/*
123
* fill in param struct from the given params
124
*/
125
(void)gettimeofday(&now, NULL);
126
aup.aup_time = now.tv_sec;
127
aup.aup_machname = machname;
128
aup.aup_uid = uid;
129
aup.aup_gid = gid;
130
aup.aup_len = (u_int)len;
131
aup.aup_gids = aup_gids;
132
133
/*
134
* Serialize the parameters into origcred
135
*/
136
xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE);
137
if (! xdr_authunix_parms(&xdrs, &aup))
138
abort();
139
au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs);
140
au->au_origcred.oa_flavor = AUTH_UNIX;
141
#ifdef _KERNEL
142
au->au_origcred.oa_base = mem_alloc((u_int) len);
143
#else
144
if ((au->au_origcred.oa_base = mem_alloc((u_int) len)) == NULL) {
145
warnx("authunix_create: out of memory");
146
goto cleanup_authunix_create;
147
}
148
#endif
149
memmove(au->au_origcred.oa_base, mymem, (size_t)len);
150
151
/*
152
* set auth handle to reflect new cred.
153
*/
154
auth->ah_cred = au->au_origcred;
155
marshal_new_auth(auth);
156
return (auth);
157
#ifndef _KERNEL
158
cleanup_authunix_create:
159
if (auth)
160
mem_free(auth, sizeof(*auth));
161
if (au) {
162
if (au->au_origcred.oa_base)
163
mem_free(au->au_origcred.oa_base, (u_int)len);
164
mem_free(au, sizeof(*au));
165
}
166
return (NULL);
167
#endif
168
}
169
170
/*
171
* Returns an auth handle with parameters determined by doing lots of
172
* syscalls.
173
*/
174
AUTH *
175
authunix_create_default(void)
176
{
177
AUTH *auth;
178
int ngids;
179
long ngids_max;
180
char machname[MAXHOSTNAMELEN + 1];
181
uid_t uid;
182
gid_t gid;
183
gid_t *gids;
184
185
ngids_max = sysconf(_SC_NGROUPS_MAX) + 1;
186
gids = malloc(sizeof(gid_t) * ngids_max);
187
if (gids == NULL)
188
return (NULL);
189
190
if (gethostname(machname, sizeof machname) == -1)
191
abort();
192
machname[sizeof(machname) - 1] = 0;
193
uid = geteuid();
194
gid = getegid();
195
if ((ngids = getgroups(ngids_max, gids)) < 0)
196
abort();
197
if (ngids > NGRPS)
198
ngids = NGRPS;
199
/* XXX: interface problem; we should translate from uid_t and gid_t */
200
auth = authunix_create(machname, uid, gid, ngids, gids);
201
free(gids);
202
return (auth);
203
}
204
205
/*
206
* authunix operations
207
*/
208
209
/* ARGSUSED */
210
static void
211
authunix_nextverf(AUTH *auth)
212
{
213
/* no action necessary */
214
}
215
216
static bool_t
217
authunix_marshal(AUTH *auth, XDR *xdrs)
218
{
219
struct audata *au;
220
221
assert(auth != NULL);
222
assert(xdrs != NULL);
223
224
au = AUTH_PRIVATE(auth);
225
return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos));
226
}
227
228
static bool_t
229
authunix_validate(AUTH *auth, struct opaque_auth *verf)
230
{
231
struct audata *au;
232
XDR xdrs;
233
234
assert(auth != NULL);
235
assert(verf != NULL);
236
237
if (verf->oa_flavor == AUTH_SHORT) {
238
au = AUTH_PRIVATE(auth);
239
xdrmem_create(&xdrs, verf->oa_base, verf->oa_length,
240
XDR_DECODE);
241
242
if (au->au_shcred.oa_base != NULL) {
243
mem_free(au->au_shcred.oa_base,
244
au->au_shcred.oa_length);
245
au->au_shcred.oa_base = NULL;
246
}
247
if (xdr_opaque_auth(&xdrs, &au->au_shcred)) {
248
auth->ah_cred = au->au_shcred;
249
} else {
250
xdrs.x_op = XDR_FREE;
251
(void)xdr_opaque_auth(&xdrs, &au->au_shcred);
252
au->au_shcred.oa_base = NULL;
253
auth->ah_cred = au->au_origcred;
254
}
255
marshal_new_auth(auth);
256
}
257
return (TRUE);
258
}
259
260
static bool_t
261
authunix_refresh(AUTH *auth, void *dummy)
262
{
263
struct audata *au = AUTH_PRIVATE(auth);
264
struct authunix_parms aup;
265
struct timeval now;
266
XDR xdrs;
267
int stat;
268
269
assert(auth != NULL);
270
271
if (auth->ah_cred.oa_base == au->au_origcred.oa_base) {
272
/* there is no hope. Punt */
273
return (FALSE);
274
}
275
au->au_shfaults ++;
276
277
/* first deserialize the creds back into a struct authunix_parms */
278
aup.aup_machname = NULL;
279
aup.aup_gids = NULL;
280
xdrmem_create(&xdrs, au->au_origcred.oa_base,
281
au->au_origcred.oa_length, XDR_DECODE);
282
stat = xdr_authunix_parms(&xdrs, &aup);
283
if (! stat)
284
goto done;
285
286
/* update the time and serialize in place */
287
(void)gettimeofday(&now, NULL);
288
aup.aup_time = now.tv_sec;
289
xdrs.x_op = XDR_ENCODE;
290
XDR_SETPOS(&xdrs, 0);
291
stat = xdr_authunix_parms(&xdrs, &aup);
292
if (! stat)
293
goto done;
294
auth->ah_cred = au->au_origcred;
295
marshal_new_auth(auth);
296
done:
297
/* free the struct authunix_parms created by deserializing */
298
xdrs.x_op = XDR_FREE;
299
(void)xdr_authunix_parms(&xdrs, &aup);
300
XDR_DESTROY(&xdrs);
301
return (stat);
302
}
303
304
static void
305
authunix_destroy(AUTH *auth)
306
{
307
struct audata *au;
308
309
assert(auth != NULL);
310
311
au = AUTH_PRIVATE(auth);
312
mem_free(au->au_origcred.oa_base, au->au_origcred.oa_length);
313
314
if (au->au_shcred.oa_base != NULL)
315
mem_free(au->au_shcred.oa_base, au->au_shcred.oa_length);
316
317
mem_free(auth->ah_private, sizeof(struct audata));
318
319
if (auth->ah_verf.oa_base != NULL)
320
mem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length);
321
322
mem_free(auth, sizeof(*auth));
323
}
324
325
/*
326
* Marshals (pre-serializes) an auth struct.
327
* sets private data, au_marshed and au_mpos
328
*/
329
static void
330
marshal_new_auth(AUTH *auth)
331
{
332
XDR xdr_stream;
333
XDR *xdrs = &xdr_stream;
334
struct audata *au;
335
336
assert(auth != NULL);
337
338
au = AUTH_PRIVATE(auth);
339
xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE);
340
if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) ||
341
(! xdr_opaque_auth(xdrs, &(auth->ah_verf))))
342
warnx("auth_none.c - Fatal marshalling problem");
343
else
344
au->au_mpos = XDR_GETPOS(xdrs);
345
XDR_DESTROY(xdrs);
346
}
347
348
static struct auth_ops *
349
authunix_ops(void)
350
{
351
static struct auth_ops ops;
352
353
/* VARIABLES PROTECTED BY ops_lock: ops */
354
355
mutex_lock(&ops_lock);
356
if (ops.ah_nextverf == NULL) {
357
ops.ah_nextverf = authunix_nextverf;
358
ops.ah_marshal = authunix_marshal;
359
ops.ah_validate = authunix_validate;
360
ops.ah_refresh = authunix_refresh;
361
ops.ah_destroy = authunix_destroy;
362
}
363
mutex_unlock(&ops_lock);
364
return (&ops);
365
}
366
367