1 | #include <machine/rtems-bsd-user-space.h> |
---|
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 | * Copyright (c) 1988 by Sun Microsystems, Inc. |
---|
34 | */ |
---|
35 | /* |
---|
36 | * auth_des.c, client-side implementation of DES authentication |
---|
37 | */ |
---|
38 | |
---|
39 | #include "namespace.h" |
---|
40 | #include "reentrant.h" |
---|
41 | #include <err.h> |
---|
42 | #include <errno.h> |
---|
43 | #include <string.h> |
---|
44 | #include <stdlib.h> |
---|
45 | #include <unistd.h> |
---|
46 | #include <sys/cdefs.h> |
---|
47 | #include <rpc/des_crypt.h> |
---|
48 | #include <syslog.h> |
---|
49 | #include <rpc/types.h> |
---|
50 | #include <rpc/auth.h> |
---|
51 | #include <rpc/auth_des.h> |
---|
52 | #include <rpc/clnt.h> |
---|
53 | #include <rpc/xdr.h> |
---|
54 | #include <sys/socket.h> |
---|
55 | #undef NIS |
---|
56 | #include <rpcsvc/nis.h> |
---|
57 | #include "un-namespace.h" |
---|
58 | #include "mt_misc.h" |
---|
59 | |
---|
60 | #if defined(LIBC_SCCS) && !defined(lint) |
---|
61 | static char sccsid[] = "@(#)auth_des.c 2.2 88/07/29 4.0 RPCSRC; from 1.9 88/02/08 SMI"; |
---|
62 | #endif |
---|
63 | #include <sys/cdefs.h> |
---|
64 | __FBSDID("$FreeBSD$"); |
---|
65 | |
---|
66 | #define USEC_PER_SEC 1000000 |
---|
67 | #define RTIME_TIMEOUT 5 /* seconds to wait for sync */ |
---|
68 | |
---|
69 | #define AUTH_PRIVATE(auth) (struct ad_private *) auth->ah_private |
---|
70 | #define ALLOC(object_type) (object_type *) mem_alloc(sizeof(object_type)) |
---|
71 | #define FREE(ptr, size) mem_free((char *)(ptr), (int) size) |
---|
72 | #define ATTEMPT(xdr_op) if (!(xdr_op)) return (FALSE) |
---|
73 | |
---|
74 | extern bool_t xdr_authdes_cred( XDR *, struct authdes_cred *); |
---|
75 | extern bool_t xdr_authdes_verf( XDR *, struct authdes_verf *); |
---|
76 | extern int key_encryptsession_pk(char *, netobj *, des_block *); |
---|
77 | |
---|
78 | extern bool_t __rpc_get_time_offset(struct timeval *, nis_server *, char *, |
---|
79 | char **, char **); |
---|
80 | |
---|
81 | /* |
---|
82 | * DES authenticator operations vector |
---|
83 | */ |
---|
84 | static void authdes_nextverf(AUTH *); |
---|
85 | static bool_t authdes_marshal(AUTH *, XDR *); |
---|
86 | static bool_t authdes_validate(AUTH *, struct opaque_auth *); |
---|
87 | static bool_t authdes_refresh(AUTH *, void *); |
---|
88 | static void authdes_destroy(AUTH *); |
---|
89 | |
---|
90 | static struct auth_ops *authdes_ops(void); |
---|
91 | |
---|
92 | /* |
---|
93 | * This struct is pointed to by the ah_private field of an "AUTH *" |
---|
94 | */ |
---|
95 | struct ad_private { |
---|
96 | char *ad_fullname; /* client's full name */ |
---|
97 | u_int ad_fullnamelen; /* length of name, rounded up */ |
---|
98 | char *ad_servername; /* server's full name */ |
---|
99 | u_int ad_servernamelen; /* length of name, rounded up */ |
---|
100 | u_int ad_window; /* client specified window */ |
---|
101 | bool_t ad_dosync; /* synchronize? */ |
---|
102 | struct netbuf ad_syncaddr; /* remote host to synch with */ |
---|
103 | char *ad_timehost; /* remote host to synch with */ |
---|
104 | struct timeval ad_timediff; /* server's time - client's time */ |
---|
105 | u_int ad_nickname; /* server's nickname for client */ |
---|
106 | struct authdes_cred ad_cred; /* storage for credential */ |
---|
107 | struct authdes_verf ad_verf; /* storage for verifier */ |
---|
108 | struct timeval ad_timestamp; /* timestamp sent */ |
---|
109 | des_block ad_xkey; /* encrypted conversation key */ |
---|
110 | u_char ad_pkey[1024]; /* Server's actual public key */ |
---|
111 | char *ad_netid; /* Timehost netid */ |
---|
112 | char *ad_uaddr; /* Timehost uaddr */ |
---|
113 | nis_server *ad_nis_srvr; /* NIS+ server struct */ |
---|
114 | }; |
---|
115 | |
---|
116 | AUTH *authdes_pk_seccreate(const char *, netobj *, u_int, const char *, |
---|
117 | const des_block *, nis_server *); |
---|
118 | |
---|
119 | /* |
---|
120 | * documented version of authdes_seccreate |
---|
121 | */ |
---|
122 | /* |
---|
123 | servername: network name of server |
---|
124 | win: time to live |
---|
125 | timehost: optional hostname to sync with |
---|
126 | ckey: optional conversation key to use |
---|
127 | */ |
---|
128 | |
---|
129 | AUTH * |
---|
130 | authdes_seccreate(const char *servername, const u_int win, |
---|
131 | const char *timehost, const des_block *ckey) |
---|
132 | { |
---|
133 | u_char pkey_data[1024]; |
---|
134 | netobj pkey; |
---|
135 | AUTH *dummy; |
---|
136 | |
---|
137 | if (! getpublickey(servername, (char *) pkey_data)) { |
---|
138 | syslog(LOG_ERR, |
---|
139 | "authdes_seccreate: no public key found for %s", |
---|
140 | servername); |
---|
141 | return (NULL); |
---|
142 | } |
---|
143 | |
---|
144 | pkey.n_bytes = (char *) pkey_data; |
---|
145 | pkey.n_len = (u_int)strlen((char *)pkey_data) + 1; |
---|
146 | dummy = authdes_pk_seccreate(servername, &pkey, win, timehost, |
---|
147 | ckey, NULL); |
---|
148 | return (dummy); |
---|
149 | } |
---|
150 | |
---|
151 | /* |
---|
152 | * Slightly modified version of authdessec_create which takes the public key |
---|
153 | * of the server principal as an argument. This spares us a call to |
---|
154 | * getpublickey() which in the nameserver context can cause a deadlock. |
---|
155 | */ |
---|
156 | AUTH * |
---|
157 | authdes_pk_seccreate(const char *servername, netobj *pkey, u_int window, |
---|
158 | const char *timehost, const des_block *ckey, nis_server *srvr) |
---|
159 | { |
---|
160 | AUTH *auth; |
---|
161 | struct ad_private *ad; |
---|
162 | char namebuf[MAXNETNAMELEN+1]; |
---|
163 | |
---|
164 | /* |
---|
165 | * Allocate everything now |
---|
166 | */ |
---|
167 | auth = ALLOC(AUTH); |
---|
168 | if (auth == NULL) { |
---|
169 | syslog(LOG_ERR, "authdes_pk_seccreate: out of memory"); |
---|
170 | return (NULL); |
---|
171 | } |
---|
172 | ad = ALLOC(struct ad_private); |
---|
173 | if (ad == NULL) { |
---|
174 | syslog(LOG_ERR, "authdes_pk_seccreate: out of memory"); |
---|
175 | goto failed; |
---|
176 | } |
---|
177 | ad->ad_fullname = ad->ad_servername = NULL; /* Sanity reasons */ |
---|
178 | ad->ad_timehost = NULL; |
---|
179 | ad->ad_netid = NULL; |
---|
180 | ad->ad_uaddr = NULL; |
---|
181 | ad->ad_nis_srvr = NULL; |
---|
182 | ad->ad_timediff.tv_sec = 0; |
---|
183 | ad->ad_timediff.tv_usec = 0; |
---|
184 | memcpy(ad->ad_pkey, pkey->n_bytes, pkey->n_len); |
---|
185 | if (!getnetname(namebuf)) |
---|
186 | goto failed; |
---|
187 | ad->ad_fullnamelen = RNDUP((u_int) strlen(namebuf)); |
---|
188 | ad->ad_fullname = (char *)mem_alloc(ad->ad_fullnamelen + 1); |
---|
189 | ad->ad_servernamelen = strlen(servername); |
---|
190 | ad->ad_servername = (char *)mem_alloc(ad->ad_servernamelen + 1); |
---|
191 | |
---|
192 | if (ad->ad_fullname == NULL || ad->ad_servername == NULL) { |
---|
193 | syslog(LOG_ERR, "authdes_seccreate: out of memory"); |
---|
194 | goto failed; |
---|
195 | } |
---|
196 | if (timehost != NULL) { |
---|
197 | ad->ad_timehost = (char *)mem_alloc(strlen(timehost) + 1); |
---|
198 | if (ad->ad_timehost == NULL) { |
---|
199 | syslog(LOG_ERR, "authdes_seccreate: out of memory"); |
---|
200 | goto failed; |
---|
201 | } |
---|
202 | memcpy(ad->ad_timehost, timehost, strlen(timehost) + 1); |
---|
203 | ad->ad_dosync = TRUE; |
---|
204 | } else if (srvr != NULL) { |
---|
205 | ad->ad_nis_srvr = srvr; /* transient */ |
---|
206 | ad->ad_dosync = TRUE; |
---|
207 | } else { |
---|
208 | ad->ad_dosync = FALSE; |
---|
209 | } |
---|
210 | memcpy(ad->ad_fullname, namebuf, ad->ad_fullnamelen + 1); |
---|
211 | memcpy(ad->ad_servername, servername, ad->ad_servernamelen + 1); |
---|
212 | ad->ad_window = window; |
---|
213 | if (ckey == NULL) { |
---|
214 | if (key_gendes(&auth->ah_key) < 0) { |
---|
215 | syslog(LOG_ERR, |
---|
216 | "authdes_seccreate: keyserv(1m) is unable to generate session key"); |
---|
217 | goto failed; |
---|
218 | } |
---|
219 | } else { |
---|
220 | auth->ah_key = *ckey; |
---|
221 | } |
---|
222 | |
---|
223 | /* |
---|
224 | * Set up auth handle |
---|
225 | */ |
---|
226 | auth->ah_cred.oa_flavor = AUTH_DES; |
---|
227 | auth->ah_verf.oa_flavor = AUTH_DES; |
---|
228 | auth->ah_ops = authdes_ops(); |
---|
229 | auth->ah_private = (caddr_t)ad; |
---|
230 | |
---|
231 | if (!authdes_refresh(auth, NULL)) { |
---|
232 | goto failed; |
---|
233 | } |
---|
234 | ad->ad_nis_srvr = NULL; /* not needed any longer */ |
---|
235 | return (auth); |
---|
236 | |
---|
237 | failed: |
---|
238 | if (auth) |
---|
239 | FREE(auth, sizeof (AUTH)); |
---|
240 | if (ad) { |
---|
241 | if (ad->ad_fullname) |
---|
242 | FREE(ad->ad_fullname, ad->ad_fullnamelen + 1); |
---|
243 | if (ad->ad_servername) |
---|
244 | FREE(ad->ad_servername, ad->ad_servernamelen + 1); |
---|
245 | if (ad->ad_timehost) |
---|
246 | FREE(ad->ad_timehost, strlen(ad->ad_timehost) + 1); |
---|
247 | if (ad->ad_netid) |
---|
248 | FREE(ad->ad_netid, strlen(ad->ad_netid) + 1); |
---|
249 | if (ad->ad_uaddr) |
---|
250 | FREE(ad->ad_uaddr, strlen(ad->ad_uaddr) + 1); |
---|
251 | FREE(ad, sizeof (struct ad_private)); |
---|
252 | } |
---|
253 | return (NULL); |
---|
254 | } |
---|
255 | |
---|
256 | /* |
---|
257 | * Implement the five authentication operations |
---|
258 | */ |
---|
259 | |
---|
260 | |
---|
261 | /* |
---|
262 | * 1. Next Verifier |
---|
263 | */ |
---|
264 | /*ARGSUSED*/ |
---|
265 | static void |
---|
266 | authdes_nextverf(AUTH *auth __unused) |
---|
267 | { |
---|
268 | /* what the heck am I supposed to do??? */ |
---|
269 | } |
---|
270 | |
---|
271 | |
---|
272 | /* |
---|
273 | * 2. Marshal |
---|
274 | */ |
---|
275 | static bool_t |
---|
276 | authdes_marshal(AUTH *auth, XDR *xdrs) |
---|
277 | { |
---|
278 | /* LINTED pointer alignment */ |
---|
279 | struct ad_private *ad = AUTH_PRIVATE(auth); |
---|
280 | struct authdes_cred *cred = &ad->ad_cred; |
---|
281 | struct authdes_verf *verf = &ad->ad_verf; |
---|
282 | des_block cryptbuf[2]; |
---|
283 | des_block ivec; |
---|
284 | int status; |
---|
285 | int len; |
---|
286 | rpc_inline_t *ixdr; |
---|
287 | |
---|
288 | /* |
---|
289 | * Figure out the "time", accounting for any time difference |
---|
290 | * with the server if necessary. |
---|
291 | */ |
---|
292 | (void)gettimeofday(&ad->ad_timestamp, NULL); |
---|
293 | ad->ad_timestamp.tv_sec += ad->ad_timediff.tv_sec; |
---|
294 | ad->ad_timestamp.tv_usec += ad->ad_timediff.tv_usec; |
---|
295 | while (ad->ad_timestamp.tv_usec >= USEC_PER_SEC) { |
---|
296 | ad->ad_timestamp.tv_usec -= USEC_PER_SEC; |
---|
297 | ad->ad_timestamp.tv_sec++; |
---|
298 | } |
---|
299 | |
---|
300 | /* |
---|
301 | * XDR the timestamp and possibly some other things, then |
---|
302 | * encrypt them. |
---|
303 | */ |
---|
304 | ixdr = (rpc_inline_t *)cryptbuf; |
---|
305 | IXDR_PUT_INT32(ixdr, ad->ad_timestamp.tv_sec); |
---|
306 | IXDR_PUT_INT32(ixdr, ad->ad_timestamp.tv_usec); |
---|
307 | if (ad->ad_cred.adc_namekind == ADN_FULLNAME) { |
---|
308 | IXDR_PUT_U_INT32(ixdr, ad->ad_window); |
---|
309 | IXDR_PUT_U_INT32(ixdr, ad->ad_window - 1); |
---|
310 | ivec.key.high = ivec.key.low = 0; |
---|
311 | status = cbc_crypt((char *)&auth->ah_key, (char *)cryptbuf, |
---|
312 | (u_int) 2 * sizeof (des_block), |
---|
313 | DES_ENCRYPT | DES_HW, (char *)&ivec); |
---|
314 | } else { |
---|
315 | status = ecb_crypt((char *)&auth->ah_key, (char *)cryptbuf, |
---|
316 | (u_int) sizeof (des_block), |
---|
317 | DES_ENCRYPT | DES_HW); |
---|
318 | } |
---|
319 | if (DES_FAILED(status)) { |
---|
320 | syslog(LOG_ERR, "authdes_marshal: DES encryption failure"); |
---|
321 | return (FALSE); |
---|
322 | } |
---|
323 | ad->ad_verf.adv_xtimestamp = cryptbuf[0]; |
---|
324 | if (ad->ad_cred.adc_namekind == ADN_FULLNAME) { |
---|
325 | ad->ad_cred.adc_fullname.window = cryptbuf[1].key.high; |
---|
326 | ad->ad_verf.adv_winverf = cryptbuf[1].key.low; |
---|
327 | } else { |
---|
328 | ad->ad_cred.adc_nickname = ad->ad_nickname; |
---|
329 | ad->ad_verf.adv_winverf = 0; |
---|
330 | } |
---|
331 | |
---|
332 | /* |
---|
333 | * Serialize the credential and verifier into opaque |
---|
334 | * authentication data. |
---|
335 | */ |
---|
336 | if (ad->ad_cred.adc_namekind == ADN_FULLNAME) { |
---|
337 | len = ((1 + 1 + 2 + 1)*BYTES_PER_XDR_UNIT + ad->ad_fullnamelen); |
---|
338 | } else { |
---|
339 | len = (1 + 1)*BYTES_PER_XDR_UNIT; |
---|
340 | } |
---|
341 | |
---|
342 | if ((ixdr = xdr_inline(xdrs, 2*BYTES_PER_XDR_UNIT))) { |
---|
343 | IXDR_PUT_INT32(ixdr, AUTH_DES); |
---|
344 | IXDR_PUT_INT32(ixdr, len); |
---|
345 | } else { |
---|
346 | ATTEMPT(xdr_putint32(xdrs, (int *)&auth->ah_cred.oa_flavor)); |
---|
347 | ATTEMPT(xdr_putint32(xdrs, &len)); |
---|
348 | } |
---|
349 | ATTEMPT(xdr_authdes_cred(xdrs, cred)); |
---|
350 | |
---|
351 | len = (2 + 1)*BYTES_PER_XDR_UNIT; |
---|
352 | if ((ixdr = xdr_inline(xdrs, 2*BYTES_PER_XDR_UNIT))) { |
---|
353 | IXDR_PUT_INT32(ixdr, AUTH_DES); |
---|
354 | IXDR_PUT_INT32(ixdr, len); |
---|
355 | } else { |
---|
356 | ATTEMPT(xdr_putint32(xdrs, (int *)&auth->ah_verf.oa_flavor)); |
---|
357 | ATTEMPT(xdr_putint32(xdrs, &len)); |
---|
358 | } |
---|
359 | ATTEMPT(xdr_authdes_verf(xdrs, verf)); |
---|
360 | return (TRUE); |
---|
361 | } |
---|
362 | |
---|
363 | |
---|
364 | /* |
---|
365 | * 3. Validate |
---|
366 | */ |
---|
367 | static bool_t |
---|
368 | authdes_validate(AUTH *auth, struct opaque_auth *rverf) |
---|
369 | { |
---|
370 | /* LINTED pointer alignment */ |
---|
371 | struct ad_private *ad = AUTH_PRIVATE(auth); |
---|
372 | struct authdes_verf verf; |
---|
373 | int status; |
---|
374 | uint32_t *ixdr; |
---|
375 | des_block buf; |
---|
376 | |
---|
377 | if (rverf->oa_length != (2 + 1) * BYTES_PER_XDR_UNIT) { |
---|
378 | return (FALSE); |
---|
379 | } |
---|
380 | /* LINTED pointer alignment */ |
---|
381 | ixdr = (uint32_t *)rverf->oa_base; |
---|
382 | buf.key.high = (uint32_t)*ixdr++; |
---|
383 | buf.key.low = (uint32_t)*ixdr++; |
---|
384 | verf.adv_int_u = (uint32_t)*ixdr++; |
---|
385 | |
---|
386 | /* |
---|
387 | * Decrypt the timestamp |
---|
388 | */ |
---|
389 | status = ecb_crypt((char *)&auth->ah_key, (char *)&buf, |
---|
390 | (u_int)sizeof (des_block), DES_DECRYPT | DES_HW); |
---|
391 | |
---|
392 | if (DES_FAILED(status)) { |
---|
393 | syslog(LOG_ERR, "authdes_validate: DES decryption failure"); |
---|
394 | return (FALSE); |
---|
395 | } |
---|
396 | |
---|
397 | /* |
---|
398 | * xdr the decrypted timestamp |
---|
399 | */ |
---|
400 | /* LINTED pointer alignment */ |
---|
401 | ixdr = (uint32_t *)buf.c; |
---|
402 | verf.adv_timestamp.tv_sec = IXDR_GET_INT32(ixdr) + 1; |
---|
403 | verf.adv_timestamp.tv_usec = IXDR_GET_INT32(ixdr); |
---|
404 | |
---|
405 | /* |
---|
406 | * validate |
---|
407 | */ |
---|
408 | if (bcmp((char *)&ad->ad_timestamp, (char *)&verf.adv_timestamp, |
---|
409 | sizeof(struct timeval)) != 0) { |
---|
410 | syslog(LOG_DEBUG, "authdes_validate: verifier mismatch"); |
---|
411 | return (FALSE); |
---|
412 | } |
---|
413 | |
---|
414 | /* |
---|
415 | * We have a nickname now, let's use it |
---|
416 | */ |
---|
417 | ad->ad_nickname = verf.adv_nickname; |
---|
418 | ad->ad_cred.adc_namekind = ADN_NICKNAME; |
---|
419 | return (TRUE); |
---|
420 | } |
---|
421 | |
---|
422 | /* |
---|
423 | * 4. Refresh |
---|
424 | */ |
---|
425 | /*ARGSUSED*/ |
---|
426 | static bool_t |
---|
427 | authdes_refresh(AUTH *auth, void *dummy __unused) |
---|
428 | { |
---|
429 | /* LINTED pointer alignment */ |
---|
430 | struct ad_private *ad = AUTH_PRIVATE(auth); |
---|
431 | struct authdes_cred *cred = &ad->ad_cred; |
---|
432 | int ok; |
---|
433 | netobj pkey; |
---|
434 | |
---|
435 | if (ad->ad_dosync) { |
---|
436 | ok = __rpc_get_time_offset(&ad->ad_timediff, ad->ad_nis_srvr, |
---|
437 | ad->ad_timehost, &(ad->ad_uaddr), |
---|
438 | &(ad->ad_netid)); |
---|
439 | if (! ok) { |
---|
440 | /* |
---|
441 | * Hope the clocks are synced! |
---|
442 | */ |
---|
443 | ad->ad_dosync = 0; |
---|
444 | syslog(LOG_DEBUG, |
---|
445 | "authdes_refresh: unable to synchronize clock"); |
---|
446 | } |
---|
447 | } |
---|
448 | ad->ad_xkey = auth->ah_key; |
---|
449 | pkey.n_bytes = (char *)(ad->ad_pkey); |
---|
450 | pkey.n_len = (u_int)strlen((char *)ad->ad_pkey) + 1; |
---|
451 | if (key_encryptsession_pk(ad->ad_servername, &pkey, &ad->ad_xkey) < 0) { |
---|
452 | syslog(LOG_INFO, |
---|
453 | "authdes_refresh: keyserv(1m) is unable to encrypt session key"); |
---|
454 | return (FALSE); |
---|
455 | } |
---|
456 | cred->adc_fullname.key = ad->ad_xkey; |
---|
457 | cred->adc_namekind = ADN_FULLNAME; |
---|
458 | cred->adc_fullname.name = ad->ad_fullname; |
---|
459 | return (TRUE); |
---|
460 | } |
---|
461 | |
---|
462 | |
---|
463 | /* |
---|
464 | * 5. Destroy |
---|
465 | */ |
---|
466 | static void |
---|
467 | authdes_destroy(AUTH *auth) |
---|
468 | { |
---|
469 | /* LINTED pointer alignment */ |
---|
470 | struct ad_private *ad = AUTH_PRIVATE(auth); |
---|
471 | |
---|
472 | FREE(ad->ad_fullname, ad->ad_fullnamelen + 1); |
---|
473 | FREE(ad->ad_servername, ad->ad_servernamelen + 1); |
---|
474 | if (ad->ad_timehost) |
---|
475 | FREE(ad->ad_timehost, strlen(ad->ad_timehost) + 1); |
---|
476 | if (ad->ad_netid) |
---|
477 | FREE(ad->ad_netid, strlen(ad->ad_netid) + 1); |
---|
478 | if (ad->ad_uaddr) |
---|
479 | FREE(ad->ad_uaddr, strlen(ad->ad_uaddr) + 1); |
---|
480 | FREE(ad, sizeof (struct ad_private)); |
---|
481 | FREE(auth, sizeof(AUTH)); |
---|
482 | } |
---|
483 | |
---|
484 | static struct auth_ops * |
---|
485 | authdes_ops(void) |
---|
486 | { |
---|
487 | static struct auth_ops ops; |
---|
488 | |
---|
489 | /* VARIABLES PROTECTED BY ops_lock: ops */ |
---|
490 | |
---|
491 | mutex_lock(&authdes_ops_lock); |
---|
492 | if (ops.ah_nextverf == NULL) { |
---|
493 | ops.ah_nextverf = authdes_nextverf; |
---|
494 | ops.ah_marshal = authdes_marshal; |
---|
495 | ops.ah_validate = authdes_validate; |
---|
496 | ops.ah_refresh = authdes_refresh; |
---|
497 | ops.ah_destroy = authdes_destroy; |
---|
498 | } |
---|
499 | mutex_unlock(&authdes_ops_lock); |
---|
500 | return (&ops); |
---|
501 | } |
---|