1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /*
27 * GSSAPI library stub module for gssd.
28 */
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <mechglueP.h>
33 #include "gssd.h"
34 #include <rpc/rpc.h>
35
36 #ifdef _KERNEL
37 #define MALLOC(n) kmem_alloc((n), KM_SLEEP)
38 #define FREE(x, n) kmem_free((x), (n))
39 #define memcpy(dst, src, n) bcopy((src), (dst), (n))
40 #define clnt_pcreateerror(srv) printf("Cannot connect to server on %s\n", srv)
41
42 #ifdef DEBUG
43 #ifndef _SYS_CMN_ERR_H
44 #define _SYS_CMN_ERR_H
45 #define CE_NOTE 1
46 #endif
47 #include <sys/types.h>
48 #include <sys/devops.h>
49 #include <sys/open.h>
50 #include <sys/stat.h>
51 #include <sys/conf.h>
52 #include <sys/ddi.h>
53 #include <sys/sunddi.h>
54 #include <sys/uio.h>
55 #endif /* DEBUG */
56
57 #else /* !_KERNEL */
58 #define MALLOC(n) malloc(n)
59 #define FREE(x, n) free(x)
60 #endif /* _KERNEL */
61 #define DEFAULT_MINOR_STAT ((OM_uint32) ~0)
62
63 CLIENT *clnt, *getgssd_handle();
64 char *server = "localhost";
65
66 OM_uint32
kgss_acquire_cred_wrapped(minor_status,desired_name,time_req,desired_mechs,cred_usage,output_cred_handle,actual_mechs,time_rec,uid,gssd_cred_verifier)67 kgss_acquire_cred_wrapped(minor_status,
68 desired_name,
69 time_req,
70 desired_mechs,
71 cred_usage,
72 output_cred_handle,
73 actual_mechs,
74 time_rec,
75 uid,
76 gssd_cred_verifier)
77 OM_uint32 *minor_status;
78 gss_name_t desired_name;
79 OM_uint32 time_req;
80 gss_OID_set desired_mechs;
81 int cred_usage;
82 gssd_cred_id_t *output_cred_handle;
83 gss_OID_set *actual_mechs;
84 OM_uint32 *time_rec;
85 uid_t uid;
86 OM_uint32 *gssd_cred_verifier;
87 {
88 OM_uint32 minor_status_temp;
89 gss_buffer_desc external_name;
90 gss_OID name_type;
91 int i;
92
93 gss_acquire_cred_arg arg;
94 gss_acquire_cred_res res;
95
96 /* get the client handle to GSSD */
97
98 if ((clnt = getgssd_handle()) == NULL) {
99 clnt_pcreateerror(server);
100 return (GSS_S_FAILURE);
101 }
102
103 /* convert the desired name from internal to external format */
104
105 if (gss_display_name(&minor_status_temp, desired_name, &external_name,
106 &name_type) != GSS_S_COMPLETE) {
107
108 *minor_status = (OM_uint32) minor_status_temp;
109 gss_release_buffer(&minor_status_temp, &external_name);
110 return ((OM_uint32) GSS_S_FAILURE);
111 }
112
113
114 /* copy the procedure arguments into the rpc arg parameter */
115
116 arg.uid = (OM_uint32)uid;
117
118 arg.desired_name.GSS_BUFFER_T_len = (uint_t)external_name.length;
119 arg.desired_name.GSS_BUFFER_T_val = (char *)external_name.value;
120
121 arg.name_type.GSS_OID_len =
122 name_type == GSS_C_NULL_OID ?
123 0 : (uint_t)name_type->length;
124
125 arg.name_type.GSS_OID_val =
126 name_type == GSS_C_NULL_OID ?
127 (char *)NULL : (char *)name_type->elements;
128
129 arg.time_req = time_req;
130
131 if (desired_mechs != GSS_C_NULL_OID_SET) {
132 arg.desired_mechs.GSS_OID_SET_len =
133 (uint_t)desired_mechs->count;
134 arg.desired_mechs.GSS_OID_SET_val = (GSS_OID *)
135 MALLOC(sizeof (GSS_OID) * desired_mechs->count);
136
137 for (i = 0; i < desired_mechs->count; i++) {
138 arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_len =
139 (uint_t)desired_mechs->elements[i].length;
140 arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_val =
141 (char *)
142 MALLOC(desired_mechs->elements[i].length);
143 memcpy(arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_val,
144 desired_mechs->elements[i].elements,
145 desired_mechs->elements[i].length);
146 }
147 } else
148 arg.desired_mechs.GSS_OID_SET_len = 0;
149
150 arg.cred_usage = cred_usage;
151
152 /* call the remote procedure */
153
154 memset(&res, 0, sizeof (res));
155 if (gss_acquire_cred_1(&arg, &res, clnt) != RPC_SUCCESS) {
156
157 /*
158 * if the RPC call times out, null out all return arguments,
159 * set minor_status to its maximum value, and return GSS_S_FAILURE
160 */
161
162 if (minor_status != NULL)
163 *minor_status = DEFAULT_MINOR_STAT;
164 if (output_cred_handle != NULL)
165 *output_cred_handle = 0;
166 if (actual_mechs != NULL)
167 *actual_mechs = NULL;
168 if (time_rec != NULL)
169 *time_rec = 0;
170
171 return (GSS_S_FAILURE);
172 }
173
174 /* free the allocated memory for the flattened name and desire_mechs */
175
176 gss_release_buffer(&minor_status_temp, &external_name);
177 for (i = 0; i < desired_mechs->count; i++)
178 FREE(arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_val,
179 arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_len);
180 FREE(arg.desired_mechs.GSS_OID_SET_val,
181 arg.desired_mechs.GSS_OID_SET_len * sizeof (GSS_OID));
182
183 /* copy the rpc results into the return arguments */
184
185 if (minor_status != NULL)
186 *minor_status = res.minor_status;
187
188 if (output_cred_handle != NULL) {
189 *output_cred_handle =
190 /*LINTED*/
191 *((gssd_cred_id_t *)res.output_cred_handle.GSS_CRED_ID_T_val);
192 *gssd_cred_verifier = res.gssd_cred_verifier;
193 }
194
195 if (res.status == GSS_S_COMPLETE &&
196 res.actual_mechs.GSS_OID_SET_len != 0 &&
197 actual_mechs != NULL) {
198 *actual_mechs = (gss_OID_set) MALLOC(sizeof (gss_OID_set_desc));
199 (*actual_mechs)->count =
200 (int)res.actual_mechs.GSS_OID_SET_len;
201 (*actual_mechs)->elements = (gss_OID)
202 MALLOC(sizeof (gss_OID_desc) * (*actual_mechs)->count);
203
204 for (i = 0; i < (*actual_mechs)->count; i++) {
205 (*actual_mechs)->elements[i].length = (OM_uint32)
206 res.actual_mechs.GSS_OID_SET_val[i].GSS_OID_len;
207 (*actual_mechs)->elements[i].elements =
208 (void *) MALLOC((*actual_mechs)->elements[i].length);
209 memcpy((*actual_mechs)->elements[i].elements,
210 res.actual_mechs.GSS_OID_SET_val[i].GSS_OID_val,
211 (*actual_mechs)->elements[i].length);
212 }
213 } else {
214 if (res.status == GSS_S_COMPLETE && actual_mechs != NULL)
215 (*actual_mechs)->count = 0;
216 }
217
218 if (time_rec != NULL)
219 *time_rec = res.time_rec;
220
221 /*
222 * free the memory allocated for the results and return with the status
223 * received in the rpc call
224 */
225
226 clnt_freeres(clnt, xdr_gss_acquire_cred_res, (caddr_t)&res);
227 return (res.status);
228 }
229
230 OM_uint32
kgss_acquire_cred(minor_status,desired_name,time_req,desired_mechs,cred_usage,output_cred_handle,actual_mechs,time_rec,uid)231 kgss_acquire_cred(minor_status,
232 desired_name,
233 time_req,
234 desired_mechs,
235 cred_usage,
236 output_cred_handle,
237 actual_mechs,
238 time_rec,
239 uid)
240 OM_uint32 *minor_status;
241 gss_name_t desired_name;
242 OM_uint32 time_req;
243 gss_OID_set desired_mechs;
244 int cred_usage;
245 gss_cred_id_t *output_cred_handle;
246 gss_OID_set *actual_mechs;
247 OM_uint32 *time_rec;
248 uid_t uid;
249 {
250
251 OM_uint32 err;
252 struct kgss_cred *kcred;
253
254 kcred = KGSS_CRED_ALLOC();
255 *output_cred_handle = (gss_cred_id_t)kcred;
256 err = kgss_acquire_cred_wrapped(minor_status,
257 desired_name, time_req,
258 desired_mechs, cred_usage,
259 &kcred->gssd_cred, actual_mechs,
260 time_rec, uid,
261 &kcred->gssd_cred_verifier);
262 if (GSS_ERROR(err)) {
263 KGSS_CRED_FREE(kcred);
264 *output_cred_handle = GSS_C_NO_CREDENTIAL;
265 }
266 return (err);
267 }
268
269 OM_uint32
kgss_add_cred_wrapped(minor_status,input_cred_handle,gssd_cred_verifier,desired_name,desired_mech_type,cred_usage,initiator_time_req,acceptor_time_req,actual_mechs,initiator_time_rec,acceptor_time_rec,uid)270 kgss_add_cred_wrapped(minor_status,
271 input_cred_handle,
272 gssd_cred_verifier,
273 desired_name,
274 desired_mech_type,
275 cred_usage,
276 initiator_time_req,
277 acceptor_time_req,
278 actual_mechs,
279 initiator_time_rec,
280 acceptor_time_rec,
281 uid)
282 OM_uint32 *minor_status;
283 gssd_cred_id_t input_cred_handle;
284 OM_uint32 gssd_cred_verifier;
285 gss_name_t desired_name;
286 gss_OID desired_mech_type;
287 int cred_usage;
288 int initiator_time_req;
289 int acceptor_time_req;
290 gss_OID_set *actual_mechs;
291 OM_uint32 *initiator_time_rec;
292 OM_uint32 *acceptor_time_rec;
293 uid_t uid;
294 {
295 CLIENT *clnt;
296
297 OM_uint32 minor_status_temp;
298 gss_buffer_desc external_name;
299 gss_OID name_type;
300 int i;
301
302 gss_add_cred_arg arg;
303 gss_add_cred_res res;
304
305 /* get the client handle to GSSD */
306
307 if ((clnt = getgssd_handle()) == NULL) {
308 clnt_pcreateerror(server);
309 return (GSS_S_FAILURE);
310 }
311
312
313 /* convert the desired name from internal to external format */
314
315 if (gss_display_name(&minor_status_temp, desired_name, &external_name,
316 &name_type) != GSS_S_COMPLETE) {
317
318 *minor_status = (OM_uint32) minor_status_temp;
319 (void) gss_release_buffer(&minor_status_temp, &external_name);
320 clnt_pcreateerror(server);
321 return ((OM_uint32) GSS_S_FAILURE);
322 }
323
324
325 /* copy the procedure arguments into the rpc arg parameter */
326
327 arg.uid = (OM_uint32) uid;
328 arg.input_cred_handle.GSS_CRED_ID_T_len =
329 input_cred_handle == GSSD_NO_CREDENTIAL ?
330 0 : (uint_t)sizeof (gssd_cred_id_t);
331 arg.input_cred_handle.GSS_CRED_ID_T_val =
332 (char *)&input_cred_handle;
333 arg.gssd_cred_verifier = gssd_cred_verifier;
334 arg.desired_name.GSS_BUFFER_T_len = (uint_t)external_name.length;
335 arg.desired_name.GSS_BUFFER_T_val = (char *)external_name.value;
336 arg.name_type.GSS_OID_len =
337 name_type == GSS_C_NULL_OID ?
338 0 : (uint_t)name_type->length;
339 arg.name_type.GSS_OID_val =
340 name_type == GSS_C_NULL_OID ?
341 (char *)NULL : (char *)name_type->elements;
342
343 arg.desired_mech_type.GSS_OID_len =
344 (uint_t)(desired_mech_type != GSS_C_NULL_OID ?
345 desired_mech_type->length : 0);
346 arg.desired_mech_type.GSS_OID_val =
347 (char *)(desired_mech_type != GSS_C_NULL_OID ?
348 desired_mech_type->elements : 0);
349 arg.cred_usage = cred_usage;
350 arg.initiator_time_req = initiator_time_req;
351 arg.acceptor_time_req = acceptor_time_req;
352
353 /* call the remote procedure */
354
355 bzero((caddr_t)&res, sizeof (res));
356 if (gss_add_cred_1(&arg, &res, clnt) != RPC_SUCCESS) {
357
358 /*
359 * if the RPC call times out, null out all return arguments,
360 * set minor_status to its maximum value, and return
361 * GSS_S_FAILURE
362 */
363
364 if (minor_status != NULL)
365 *minor_status = DEFAULT_MINOR_STAT;
366 if (actual_mechs != NULL)
367 *actual_mechs = NULL;
368 if (initiator_time_rec != NULL)
369 *initiator_time_rec = 0;
370 if (acceptor_time_rec != NULL)
371 *acceptor_time_rec = 0;
372 return (GSS_S_FAILURE);
373 }
374
375 /* free the allocated memory for the flattened name */
376
377 (void) gss_release_buffer(&minor_status_temp, &external_name);
378
379 /* copy the rpc results into the return arguments */
380
381 if (minor_status != NULL)
382 *minor_status = res.minor_status;
383
384 if (res.status == GSS_S_COMPLETE &&
385 res.actual_mechs.GSS_OID_SET_len != 0 &&
386 actual_mechs != NULL) {
387 *actual_mechs = (gss_OID_set) MALLOC(sizeof (gss_OID_set_desc));
388 (*actual_mechs)->count =
389 (int)res.actual_mechs.GSS_OID_SET_len;
390 (*actual_mechs)->elements = (gss_OID)
391 MALLOC(sizeof (gss_OID_desc) * (*actual_mechs)->count);
392
393 for (i = 0; i < (*actual_mechs)->count; i++) {
394 (*actual_mechs)->elements[i].length = (OM_uint32)
395 res.actual_mechs.GSS_OID_SET_val[i].GSS_OID_len;
396 (*actual_mechs)->elements[i].elements =
397 (void *) MALLOC((*actual_mechs)->elements[i].length);
398 memcpy((*actual_mechs)->elements[i].elements,
399 res.actual_mechs.GSS_OID_SET_val[i].GSS_OID_val,
400 (*actual_mechs)->elements[i].length);
401 }
402 } else {
403 if (res.status == GSS_S_COMPLETE &&
404 actual_mechs != NULL)
405 (*actual_mechs)->count = 0;
406 }
407 if (initiator_time_rec != NULL)
408 *initiator_time_rec = res.initiator_time_rec;
409 if (acceptor_time_rec != NULL)
410 *acceptor_time_rec = res.acceptor_time_rec;
411
412 /*
413 * free the memory allocated for the results and return with the status
414 * received in the rpc call
415 */
416
417 clnt_freeres(clnt, xdr_gss_add_cred_res, (caddr_t)&res);
418 return (res.status);
419
420 }
421
422 OM_uint32
kgss_add_cred(minor_status,input_cred_handle,desired_name,desired_mech_type,cred_usage,initiator_time_req,acceptor_time_req,actual_mechs,initiator_time_rec,acceptor_time_rec,uid)423 kgss_add_cred(minor_status,
424 input_cred_handle,
425 desired_name,
426 desired_mech_type,
427 cred_usage,
428 initiator_time_req,
429 acceptor_time_req,
430 actual_mechs,
431 initiator_time_rec,
432 acceptor_time_rec,
433 uid)
434 OM_uint32 *minor_status;
435 gss_cred_id_t input_cred_handle;
436 gss_name_t desired_name;
437 gss_OID desired_mech_type;
438 int cred_usage;
439 int initiator_time_req;
440 int acceptor_time_req;
441 gss_OID_set *actual_mechs;
442 OM_uint32 *initiator_time_rec;
443 OM_uint32 *acceptor_time_rec;
444 uid_t uid;
445 {
446
447 OM_uint32 err;
448 OM_uint32 gssd_cred_verifier;
449 gssd_cred_id_t gssd_input_cred_handle;
450
451
452 if (input_cred_handle != GSS_C_NO_CREDENTIAL) {
453 gssd_cred_verifier = KCRED_TO_CREDV(input_cred_handle);
454 gssd_input_cred_handle = KCRED_TO_CRED(input_cred_handle);
455 } else
456 gssd_input_cred_handle = GSSD_NO_CREDENTIAL;
457
458 err = kgss_add_cred_wrapped(minor_status, gssd_input_cred_handle,
459 gssd_cred_verifier, desired_name, desired_mech_type,
460 cred_usage, initiator_time_req, acceptor_time_req,
461 actual_mechs, initiator_time_rec,
462 acceptor_time_rec, uid);
463 return (err);
464 }
465
466 OM_uint32
kgss_release_cred_wrapped(minor_status,cred_handle,uid,gssd_cred_verifier)467 kgss_release_cred_wrapped(minor_status,
468 cred_handle,
469 uid,
470 gssd_cred_verifier)
471 OM_uint32 *minor_status;
472 gssd_cred_id_t *cred_handle;
473 uid_t uid;
474 OM_uint32 gssd_cred_verifier;
475 {
476
477 gss_release_cred_arg arg;
478 gss_release_cred_res res;
479
480
481 /* get the client handle to GSSD */
482 if ((clnt = getgssd_handle()) == NULL) {
483 clnt_pcreateerror(server);
484 return (GSS_S_FAILURE);
485 }
486
487 /* copy the procedure arguments into the rpc arg parameter */
488
489 arg.uid = (OM_uint32) uid;
490 arg.gssd_cred_verifier = gssd_cred_verifier;
491
492 if (cred_handle != NULL) {
493 arg.cred_handle.GSS_CRED_ID_T_len =
494 (uint_t)sizeof (gssd_cred_id_t);
495 arg.cred_handle.GSS_CRED_ID_T_val = (char *)cred_handle;
496 } else
497 arg.cred_handle.GSS_CRED_ID_T_len = 0;
498
499 /* call the remote procedure */
500
501 memset(&res, 0, sizeof (res));
502 if (gss_release_cred_1(&arg, &res, clnt) != RPC_SUCCESS) {
503
504 /*
505 * if the RPC call times out, null out all return arguments,
506 * set minor_status to its max value, and return GSS_S_FAILURE
507 */
508
509 if (minor_status != NULL)
510 *minor_status = DEFAULT_MINOR_STAT;
511 if (cred_handle != NULL)
512 *cred_handle = 0;
513
514 return (GSS_S_FAILURE);
515 }
516
517 /* if the release succeeded, null out the cred_handle */
518 if (res.status == GSS_S_COMPLETE && cred_handle != NULL)
519 *cred_handle = 0;
520
521 /* copy the rpc results into the return arguments */
522 if (minor_status != NULL)
523 *minor_status = res.minor_status;
524
525 /* return with status returned in rpc call */
526 return (res.status);
527 }
528
529 OM_uint32
kgss_release_cred(minor_status,cred_handle,uid)530 kgss_release_cred(minor_status,
531 cred_handle,
532 uid)
533 OM_uint32 *minor_status;
534 gss_cred_id_t *cred_handle;
535 uid_t uid;
536
537 {
538
539 OM_uint32 err;
540 struct kgss_cred *kcred;
541
542 if (*cred_handle == GSS_C_NO_CREDENTIAL)
543 return (GSS_S_COMPLETE);
544 else
545 kcred = KCRED_TO_KGSS_CRED(*cred_handle);
546
547 err = kgss_release_cred_wrapped(minor_status, &kcred->gssd_cred,
548 uid, kcred->gssd_cred_verifier);
549 KGSS_CRED_FREE(kcred);
550 *cred_handle = GSS_C_NO_CREDENTIAL;
551 return (err);
552 }
553
554 OM_uint32
kgss_init_sec_context_wrapped(minor_status,claimant_cred_handle,gssd_cred_verifier,context_handle,gssd_context_verifier,target_name,mech_type,req_flags,time_req,input_chan_bindings,input_token,actual_mech_type,output_token,ret_flags,time_rec,uid)555 kgss_init_sec_context_wrapped(minor_status,
556 claimant_cred_handle,
557 gssd_cred_verifier,
558 context_handle,
559 gssd_context_verifier,
560 target_name,
561 mech_type,
562 req_flags,
563 time_req,
564 input_chan_bindings,
565 input_token,
566 actual_mech_type,
567 output_token,
568 ret_flags,
569 time_rec,
570 uid)
571 OM_uint32 *minor_status;
572 gssd_cred_id_t claimant_cred_handle;
573 OM_uint32 gssd_cred_verifier;
574 OM_uint32 *context_handle;
575 OM_uint32 *gssd_context_verifier;
576 gss_name_t target_name;
577 gss_OID mech_type;
578 int req_flags;
579 OM_uint32 time_req;
580 gss_channel_bindings_t input_chan_bindings;
581 gss_buffer_t input_token;
582 gss_OID *actual_mech_type;
583 gss_buffer_t output_token;
584 int *ret_flags;
585 OM_uint32 *time_rec;
586 uid_t uid;
587 {
588 OM_uint32 minor_status_temp;
589 gss_buffer_desc external_name;
590 gss_OID name_type;
591 gss_init_sec_context_arg arg;
592 gss_init_sec_context_res res;
593
594 /* get the client handle to GSSD */
595
596 if ((clnt = getgssd_handle()) == NULL) {
597 clnt_pcreateerror(server);
598 return (GSS_S_FAILURE);
599 }
600
601 /* convert the target name from internal to external format */
602
603 if (gss_display_name(&minor_status_temp, target_name,
604 &external_name, &name_type) != GSS_S_COMPLETE) {
605
606 *minor_status = (OM_uint32) minor_status_temp;
607 return ((OM_uint32) GSS_S_FAILURE);
608 }
609
610
611 /* copy the procedure arguments into the rpc arg parameter */
612
613 arg.uid = (OM_uint32) uid;
614
615 arg.context_handle.GSS_CTX_ID_T_len =
616 *context_handle == (OM_uint32) GSS_C_NO_CONTEXT ? 0 :
617 (uint_t)sizeof (OM_uint32);
618 arg.context_handle.GSS_CTX_ID_T_val = (char *)context_handle;
619 arg.gssd_context_verifier = *gssd_context_verifier;
620
621 arg.claimant_cred_handle.GSS_CRED_ID_T_len =
622 claimant_cred_handle == GSSD_NO_CREDENTIAL ?
623 0 : (uint_t)sizeof (gssd_cred_id_t);
624 arg.claimant_cred_handle.GSS_CRED_ID_T_val =
625 (char *)&claimant_cred_handle;
626 arg.gssd_cred_verifier = gssd_cred_verifier;
627
628 arg.target_name.GSS_BUFFER_T_len = (uint_t)external_name.length;
629 arg.target_name.GSS_BUFFER_T_val = (char *)external_name.value;
630
631 arg.name_type.GSS_OID_len =
632 name_type == GSS_C_NULL_OID ?
633 0 : (uint_t)name_type->length;
634
635 arg.name_type.GSS_OID_val =
636 name_type == GSS_C_NULL_OID ?
637 (char *)NULL : (char *)name_type->elements;
638
639 arg.mech_type.GSS_OID_len = (uint_t)(mech_type != GSS_C_NULL_OID ?
640 mech_type->length : 0);
641 arg.mech_type.GSS_OID_val = (char *)(mech_type != GSS_C_NULL_OID ?
642 mech_type->elements : 0);
643
644 arg.req_flags = req_flags;
645
646 arg.time_req = time_req;
647
648 if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS) {
649 arg.input_chan_bindings.present = YES;
650 arg.input_chan_bindings.initiator_addrtype =
651 input_chan_bindings->initiator_addrtype;
652 arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_len =
653 (uint_t)input_chan_bindings->initiator_address.length;
654 arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_val =
655 (void *) input_chan_bindings->initiator_address.value;
656 arg.input_chan_bindings.acceptor_addrtype =
657 input_chan_bindings->acceptor_addrtype;
658 arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_len =
659 (uint_t)input_chan_bindings->acceptor_address.length;
660 arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_val =
661 (void *) input_chan_bindings->acceptor_address.value;
662 arg.input_chan_bindings.application_data.GSS_BUFFER_T_len =
663 (uint_t)input_chan_bindings->application_data.length;
664 arg.input_chan_bindings.application_data.GSS_BUFFER_T_val =
665 (void *) input_chan_bindings->application_data.value;
666 } else {
667 arg.input_chan_bindings.present = NO;
668 arg.input_chan_bindings.initiator_addrtype = 0;
669 arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_len = 0;
670 arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_val = 0;
671 arg.input_chan_bindings.acceptor_addrtype = 0;
672 arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_len = 0;
673 arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_val = 0;
674 arg.input_chan_bindings.application_data.GSS_BUFFER_T_len = 0;
675 arg.input_chan_bindings.application_data.GSS_BUFFER_T_val = 0;
676 }
677
678 arg.input_token.GSS_BUFFER_T_len = (uint_t)
679 (input_token != GSS_C_NO_BUFFER ? input_token->length : 0);
680 arg.input_token.GSS_BUFFER_T_val = (char *)
681 (input_token != GSS_C_NO_BUFFER ? input_token->value : 0);
682
683 /* initialize the output parameters to empty values */
684 if (minor_status != NULL)
685 *minor_status = DEFAULT_MINOR_STAT;
686 if (actual_mech_type != NULL)
687 *actual_mech_type = NULL;
688 if (output_token != NULL)
689 output_token->length = 0;
690 if (ret_flags != NULL)
691 *ret_flags = 0;
692 if (time_rec != NULL)
693 *time_rec = 0;
694
695 /* call the remote procedure */
696 memset(&res, 0, sizeof (res));
697 if (gss_init_sec_context_1(&arg, &res, clnt) != RPC_SUCCESS) {
698
699 /* free the allocated memory for the flattened name */
700 gss_release_buffer(&minor_status_temp, &external_name);
701
702 return (GSS_S_FAILURE);
703 }
704
705 /*
706 * We could return from a GSS error here and need to return both the
707 * minor_status and output_token, back to the caller if applicable.
708 */
709 if (minor_status != NULL)
710 *minor_status = res.minor_status;
711
712 if (output_token != NULL && res.output_token.GSS_BUFFER_T_val != NULL) {
713 output_token->length =
714 (size_t)res.output_token.GSS_BUFFER_T_len;
715 output_token->value =
716 (void *)res.output_token.GSS_BUFFER_T_val;
717 res.output_token.GSS_BUFFER_T_val = NULL;
718 res.output_token.GSS_BUFFER_T_len = 0;
719 }
720
721 /* free the allocated memory for the flattened name */
722 gss_release_buffer(&minor_status_temp, &external_name);
723
724 /* if the call was successful, copy out the results */
725 if (res.status == (OM_uint32) GSS_S_COMPLETE ||
726 res.status == (OM_uint32) GSS_S_CONTINUE_NEEDED) {
727 /*
728 * copy the rpc results into the return argument
729 * on CONTINUE_NEEDED only ctx handle is ready.
730 */
731 /*LINTED*/
732 *context_handle = *((OM_uint32 *)
733 res.context_handle.GSS_CTX_ID_T_val);
734
735 *gssd_context_verifier = res.gssd_context_verifier;
736
737 /* the rest of the parameters is only ready on COMPLETE */
738 if (res.status == GSS_S_COMPLETE) {
739 if (actual_mech_type != NULL) {
740 *actual_mech_type = (gss_OID)
741 MALLOC(sizeof (gss_OID_desc));
742 (*actual_mech_type)->length = (OM_UINT32)
743 res.actual_mech_type.GSS_OID_len;
744 (*actual_mech_type)->elements = (void *)
745 MALLOC((*actual_mech_type)->length);
746 memcpy((*actual_mech_type)->elements, (void *)
747 res.actual_mech_type.GSS_OID_val,
748 (*actual_mech_type)->length);
749 }
750
751
752 if (ret_flags != NULL)
753 *ret_flags = res.ret_flags;
754
755 if (time_rec != NULL)
756 *time_rec = res.time_rec;
757 }
758 }
759
760
761 /*
762 * free the memory allocated for the results and return with the
763 * status received in the rpc call.
764 */
765
766 clnt_freeres(clnt, xdr_gss_init_sec_context_res, (caddr_t)&res);
767 return (res.status);
768 }
769 OM_uint32
kgss_init_sec_context(OM_uint32 * minor_status,gss_cred_id_t claimant_cred_handle,gss_ctx_id_t * context_handle,gss_name_t target_name,gss_OID mech_type,int req_flags,OM_uint32 time_req,gss_channel_bindings_t input_chan_bindings,gss_buffer_t input_token,gss_OID * actual_mech_type,gss_buffer_t output_token,int * ret_flags,OM_uint32 * time_rec,uid_t uid)770 kgss_init_sec_context(
771 OM_uint32 *minor_status,
772 gss_cred_id_t claimant_cred_handle,
773 gss_ctx_id_t *context_handle,
774 gss_name_t target_name,
775 gss_OID mech_type,
776 int req_flags,
777 OM_uint32 time_req,
778 gss_channel_bindings_t input_chan_bindings,
779 gss_buffer_t input_token,
780 gss_OID *actual_mech_type,
781 gss_buffer_t output_token,
782 int *ret_flags,
783 OM_uint32 *time_rec,
784 uid_t uid)
785 {
786 OM_uint32 err;
787 struct kgss_ctx *kctx;
788 OM_uint32 gssd_cred_verifier;
789 gssd_cred_id_t gssd_cl_cred_handle;
790
791 /*
792 * If this is an initial call, we'll need to create the
793 * wrapper struct that contains kernel state information, and
794 * a reference to the handle from gssd.
795 */
796 if (*context_handle == GSS_C_NO_CONTEXT) {
797 kctx = KGSS_ALLOC();
798 *context_handle = (gss_ctx_id_t)kctx;
799 kctx->gssd_ctx = (OM_uint32) GSS_C_NO_CONTEXT;
800 } else
801 kctx = (struct kgss_ctx *)*context_handle;
802
803 if (claimant_cred_handle != GSS_C_NO_CREDENTIAL) {
804 gssd_cred_verifier =
805 KCRED_TO_CREDV(claimant_cred_handle);
806 gssd_cl_cred_handle =
807 KCRED_TO_CRED(claimant_cred_handle);
808 } else {
809 gssd_cl_cred_handle = GSSD_NO_CREDENTIAL;
810 }
811
812 err = kgss_init_sec_context_wrapped(minor_status,
813 gssd_cl_cred_handle,
814 gssd_cred_verifier, &kctx->gssd_ctx,
815 &kctx->gssd_ctx_verifier,
816 target_name, mech_type, req_flags, time_req,
817 input_chan_bindings, input_token, actual_mech_type,
818 output_token, ret_flags, time_rec, uid);
819
820 if (GSS_ERROR(err)) {
821 KGSS_FREE(kctx);
822 *context_handle = GSS_C_NO_CONTEXT;
823 }
824 return (err);
825 }
826 OM_uint32
kgss_accept_sec_context_wrapped(minor_status,context_handle,gssd_context_verifier,verifier_cred_handle,gssd_cred_verifier,input_token,input_chan_bindings,src_name,mech_type,output_token,ret_flags,time_rec,delegated_cred_handle,uid)827 kgss_accept_sec_context_wrapped(minor_status,
828 context_handle,
829 gssd_context_verifier,
830 verifier_cred_handle,
831 gssd_cred_verifier,
832 input_token,
833 input_chan_bindings,
834 src_name,
835 mech_type,
836 output_token,
837 ret_flags,
838 time_rec,
839 delegated_cred_handle,
840 uid)
841 OM_uint32 *minor_status;
842 gssd_ctx_id_t *context_handle;
843 OM_uint32 *gssd_context_verifier;
844 gssd_cred_id_t verifier_cred_handle;
845 OM_uint32 gssd_cred_verifier;
846 gss_buffer_t input_token;
847 gss_channel_bindings_t input_chan_bindings;
848 gss_buffer_t src_name;
849 gss_OID *mech_type;
850 gss_buffer_t output_token;
851 int *ret_flags;
852 OM_uint32 *time_rec;
853 gss_cred_id_t *delegated_cred_handle;
854 uid_t uid;
855 {
856 gss_accept_sec_context_arg arg;
857 gss_accept_sec_context_res res;
858 struct kgss_cred *kcred;
859
860 /* get the client handle to GSSD */
861 if ((clnt = getgssd_handle()) == NULL) {
862 clnt_pcreateerror(server);
863 return (GSS_S_FAILURE);
864 }
865
866 /* copy the procedure arguments into the rpc arg parameter */
867 arg.uid = (OM_uint32) uid;
868
869 arg.context_handle.GSS_CTX_ID_T_len =
870 *context_handle == GSSD_NO_CONTEXT ?
871 0 : (uint_t)sizeof (gssd_ctx_id_t);
872 arg.context_handle.GSS_CTX_ID_T_val = (char *)context_handle;
873 arg.gssd_context_verifier =
874 *context_handle == (OM_uint32) GSS_C_NO_CONTEXT ?
875 0 : *gssd_context_verifier;
876
877 arg.verifier_cred_handle.GSS_CRED_ID_T_len =
878 verifier_cred_handle == GSSD_NO_CREDENTIAL ?
879 0 : (uint_t)sizeof (gssd_cred_id_t);
880 arg.verifier_cred_handle.GSS_CRED_ID_T_val =
881 (char *)&verifier_cred_handle;
882 arg.gssd_cred_verifier = gssd_cred_verifier;
883
884 arg.input_token_buffer.GSS_BUFFER_T_len =
885 (uint_t)(input_token != GSS_C_NO_BUFFER ?
886 input_token->length : 0);
887 arg.input_token_buffer.GSS_BUFFER_T_val =
888 (char *)(input_token != GSS_C_NO_BUFFER ?
889 input_token->value : 0);
890
891 if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS) {
892 arg.input_chan_bindings.present = YES;
893 arg.input_chan_bindings.initiator_addrtype =
894 input_chan_bindings->initiator_addrtype;
895 arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_len =
896 (uint_t)input_chan_bindings->initiator_address.length;
897 arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_val =
898 (void *) input_chan_bindings->initiator_address.value;
899 arg.input_chan_bindings.acceptor_addrtype =
900 input_chan_bindings->acceptor_addrtype;
901 arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_len =
902 (uint_t)input_chan_bindings->acceptor_address.length;
903 arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_val =
904 (void *) input_chan_bindings->acceptor_address.value;
905 arg.input_chan_bindings.application_data.GSS_BUFFER_T_len =
906 (uint_t)input_chan_bindings->application_data.length;
907 arg.input_chan_bindings.application_data.GSS_BUFFER_T_val =
908 (void *) input_chan_bindings->application_data.value;
909 } else {
910 arg.input_chan_bindings.present = NO;
911 arg.input_chan_bindings.initiator_addrtype = 0;
912 arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_len = 0;
913 arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_val = 0;
914 arg.input_chan_bindings.acceptor_addrtype = 0;
915 arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_len = 0;
916 arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_val = 0;
917 arg.input_chan_bindings.application_data.GSS_BUFFER_T_len = 0;
918 arg.input_chan_bindings.application_data.GSS_BUFFER_T_val = 0;
919 }
920
921 /* set the output parameters to empty values.... */
922 if (minor_status != NULL)
923 *minor_status = DEFAULT_MINOR_STAT;
924 if (src_name != NULL) {
925 src_name->length = 0;
926 src_name->value = NULL;
927 }
928 if (mech_type != NULL)
929 *mech_type = NULL;
930 if (output_token != NULL)
931 output_token->length = 0;
932 if (ret_flags != NULL)
933 *ret_flags = 0;
934 if (time_rec != NULL)
935 *time_rec = 0;
936 if (delegated_cred_handle != NULL)
937 *delegated_cred_handle = NULL;
938
939 /* call the remote procedure */
940 memset(&res, 0, sizeof (res));
941 if (gss_accept_sec_context_1(&arg, &res, clnt) != RPC_SUCCESS) {
942 return (GSS_S_FAILURE);
943 }
944
945 /*
946 * We could return from a GSS error here and need to return both the
947 * minor_status and output_token, back to the caller if applicable.
948 */
949 if (minor_status != NULL)
950 *minor_status = res.minor_status;
951
952 if (output_token != NULL && res.output_token.GSS_BUFFER_T_val != NULL) {
953 output_token->length =
954 res.output_token.GSS_BUFFER_T_len;
955 output_token->value =
956 (void *) res.output_token.GSS_BUFFER_T_val;
957 res.output_token.GSS_BUFFER_T_val = 0;
958 res.output_token.GSS_BUFFER_T_len = 0;
959 }
960
961 if (res.status == (OM_uint32) GSS_S_COMPLETE ||
962 res.status == (OM_uint32) GSS_S_CONTINUE_NEEDED) {
963 /*
964 * when gss returns CONTINUE_NEEDED we can only
965 * use the context parameter.
966 */
967 /*LINTED*/
968 *context_handle = *((gssd_ctx_id_t *)
969 res.context_handle.GSS_CTX_ID_T_val);
970 *gssd_context_verifier = res.gssd_context_verifier;
971
972 /* the other parameters are ready on for COMPLETE */
973 if (res.status == GSS_S_COMPLETE)
974 {
975
976 /*
977 * The src_name is in external format.
978 */
979 if (src_name != NULL) {
980 src_name->length = res.src_name.GSS_BUFFER_T_len;
981 src_name->value = res.src_name.GSS_BUFFER_T_val;
982 res.src_name.GSS_BUFFER_T_val = NULL;
983 res.src_name.GSS_BUFFER_T_len = 0;
984 }
985 /*
986 * move mech type returned to mech_type
987 * for gss_import_name_for_mech()
988 */
989 if (mech_type != NULL) {
990 *mech_type =
991 (gss_OID) MALLOC(sizeof (gss_OID_desc));
992 (*mech_type)->length =
993 (OM_UINT32) res.mech_type.GSS_OID_len;
994 (*mech_type)->elements =
995 (void *) MALLOC((*mech_type)->length);
996 memcpy((*mech_type)->elements,
997 res.mech_type.GSS_OID_val,
998 (*mech_type)->length);
999 }
1000
1001 if (ret_flags != NULL)
1002 *ret_flags = res.ret_flags;
1003
1004 if (time_rec != NULL)
1005 *time_rec = res.time_rec;
1006
1007 if ((delegated_cred_handle != NULL) &&
1008 (res.delegated_cred_handle.GSS_CRED_ID_T_len
1009 != 0)) {
1010 kcred = KGSS_CRED_ALLOC();
1011 /*LINTED*/
1012 kcred->gssd_cred = *((gssd_cred_id_t *)
1013 res.delegated_cred_handle.GSS_CRED_ID_T_val);
1014 kcred->gssd_cred_verifier =
1015 res.gssd_context_verifier;
1016 *delegated_cred_handle = (gss_cred_id_t)kcred;
1017 }
1018 } /* res.status == GSS_S_COMPLETE */
1019 } /* res.status == GSS_S_COMPLETE or GSS_CONTINUE_NEEDED */
1020
1021
1022 /*
1023 * free the memory allocated for the results and return with the status
1024 * received in the rpc call
1025 */
1026
1027 clnt_freeres(clnt, xdr_gss_accept_sec_context_res, (caddr_t)&res);
1028 return (res.status);
1029 }
1030
1031 OM_uint32
kgss_accept_sec_context(OM_uint32 * minor_status,gss_ctx_id_t * context_handle,gss_cred_id_t verifier_cred_handle,gss_buffer_t input_token,gss_channel_bindings_t input_chan_bindings,gss_buffer_t src_name,gss_OID * mech_type,gss_buffer_t output_token,int * ret_flags,OM_uint32 * time_rec,gss_cred_id_t * delegated_cred_handle,uid_t uid)1032 kgss_accept_sec_context(
1033 OM_uint32 *minor_status,
1034 gss_ctx_id_t *context_handle,
1035 gss_cred_id_t verifier_cred_handle,
1036 gss_buffer_t input_token,
1037 gss_channel_bindings_t input_chan_bindings,
1038 gss_buffer_t src_name,
1039 gss_OID *mech_type,
1040 gss_buffer_t output_token,
1041 int *ret_flags,
1042 OM_uint32 *time_rec,
1043 gss_cred_id_t *delegated_cred_handle,
1044 uid_t uid)
1045 {
1046 OM_uint32 err;
1047 struct kgss_ctx *kctx;
1048 OM_uint32 gssd_cred_verifier;
1049 gssd_cred_id_t gssd_ver_cred_handle;
1050
1051
1052 if (*context_handle == GSS_C_NO_CONTEXT) {
1053 kctx = KGSS_ALLOC();
1054 *context_handle = (gss_ctx_id_t)kctx;
1055 kctx->gssd_ctx = GSSD_NO_CONTEXT;
1056 } else
1057 kctx = (struct kgss_ctx *)*context_handle;
1058
1059 if (verifier_cred_handle != GSS_C_NO_CREDENTIAL) {
1060 gssd_cred_verifier =
1061 KCRED_TO_CREDV(verifier_cred_handle);
1062 gssd_ver_cred_handle =
1063 KCRED_TO_CRED(verifier_cred_handle);
1064 } else
1065 gssd_ver_cred_handle = GSSD_NO_CREDENTIAL;
1066
1067 err = kgss_accept_sec_context_wrapped(minor_status, &kctx->gssd_ctx,
1068 &kctx->gssd_ctx_verifier, gssd_ver_cred_handle,
1069 gssd_cred_verifier, input_token, input_chan_bindings,
1070 src_name, mech_type, output_token, ret_flags,
1071 time_rec, delegated_cred_handle, uid);
1072
1073 if (GSS_ERROR(err)) {
1074 KGSS_FREE(kctx);
1075 *context_handle = GSS_C_NO_CONTEXT;
1076
1077 }
1078
1079 return (err);
1080 }
1081
1082 OM_uint32
kgss_process_context_token(minor_status,context_handle,token_buffer,uid)1083 kgss_process_context_token(minor_status,
1084 context_handle,
1085 token_buffer,
1086 uid)
1087 OM_uint32 *minor_status;
1088 gss_ctx_id_t context_handle;
1089 gss_buffer_t token_buffer;
1090 uid_t uid;
1091 {
1092 OM_uint32 gssd_context_verifier;
1093
1094 gss_process_context_token_arg arg;
1095 gss_process_context_token_res res;
1096
1097 gssd_context_verifier = KGSS_CTX_TO_GSSD_CTXV(context_handle);
1098
1099 /* get the client handle to GSSD */
1100
1101 if ((clnt = getgssd_handle()) == NULL) {
1102 clnt_pcreateerror(server);
1103 return (GSS_S_FAILURE);
1104 }
1105
1106 /* copy the procedure arguments into the rpc arg parameter */
1107 arg.uid = (OM_uint32) uid;
1108
1109 arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gss_ctx_id_t);
1110 arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
1111 arg.gssd_context_verifier = gssd_context_verifier;
1112 arg.token_buffer.GSS_BUFFER_T_len = (uint_t)token_buffer;
1113 arg.token_buffer.GSS_BUFFER_T_val = (char *)token_buffer->value;
1114
1115 /* call the remote procedure */
1116
1117 memset(&res, 0, sizeof (res));
1118 if (gss_process_context_token_1(&arg, &res, clnt) != RPC_SUCCESS) {
1119
1120 /*
1121 * if the RPC call times out, null out all return arguments,
1122 * set minor_status to its maximum value, and return GSS_S_FAILURE
1123 */
1124
1125 if (minor_status != NULL)
1126 *minor_status = DEFAULT_MINOR_STAT;
1127
1128 return (GSS_S_FAILURE);
1129 }
1130
1131 /* copy the rpc results into the return arguments */
1132
1133 if (minor_status != NULL)
1134 *minor_status = res.minor_status;
1135
1136 /* return with status returned in rpc call */
1137
1138 return (res.status);
1139 }
1140
1141 OM_uint32
kgss_delete_sec_context_wrapped(minor_status,context_handle,gssd_context_verifier,output_token)1142 kgss_delete_sec_context_wrapped(minor_status,
1143 context_handle,
1144 gssd_context_verifier,
1145 output_token)
1146 OM_uint32 *minor_status;
1147 gssd_ctx_id_t *context_handle;
1148 OM_uint32 gssd_context_verifier;
1149 gss_buffer_t output_token;
1150 {
1151 gss_delete_sec_context_arg arg;
1152 gss_delete_sec_context_res res;
1153
1154
1155 /* get the client handle to GSSD */
1156 if ((clnt = getgssd_handle()) == NULL) {
1157 clnt_pcreateerror(server);
1158 return (GSS_S_FAILURE);
1159 }
1160
1161 /* copy the procedure arguments into the rpc arg parameter */
1162
1163 arg.context_handle.GSS_CTX_ID_T_len =
1164 *context_handle == (OM_uint32) GSS_C_NO_CONTEXT ? 0 :
1165 (uint_t)sizeof (OM_uint32);
1166 arg.context_handle.GSS_CTX_ID_T_val = (char *)context_handle;
1167
1168 arg.gssd_context_verifier = gssd_context_verifier;
1169
1170 /* call the remote procedure */
1171
1172 memset(&res, 0, sizeof (res));
1173 if (gss_delete_sec_context_1(&arg, &res, clnt) != RPC_SUCCESS) {
1174
1175 /*
1176 * if the RPC call times out, null out all return arguments,
1177 * set minor_status to its max value, and return GSS_S_FAILURE
1178 */
1179
1180 if (minor_status != NULL)
1181 *minor_status = DEFAULT_MINOR_STAT;
1182 if (context_handle != NULL)
1183 *context_handle = 0;
1184 if (output_token != NULL)
1185 output_token->length = 0;
1186
1187 return (GSS_S_FAILURE);
1188 }
1189
1190 /* copy the rpc results into the return arguments */
1191
1192 if (minor_status != NULL)
1193 *minor_status = res.minor_status;
1194
1195 if (res.context_handle.GSS_CTX_ID_T_len == 0)
1196 *context_handle = 0;
1197 else
1198 /*LINTED*/
1199 *context_handle = *((gssd_ctx_id_t *)
1200 res.context_handle.GSS_CTX_ID_T_val);
1201
1202 if (output_token != NULL && res.output_token.GSS_BUFFER_T_val != NULL) {
1203 output_token->length = res.output_token.GSS_BUFFER_T_len;
1204 output_token->value = res.output_token.GSS_BUFFER_T_val;
1205 res.output_token.GSS_BUFFER_T_len = 0;
1206 res.output_token.GSS_BUFFER_T_val = NULL;
1207 }
1208
1209 /*
1210 * free the memory allocated for the results and return with the status
1211 * received in the rpc call
1212 */
1213
1214 clnt_freeres(clnt, xdr_gss_delete_sec_context_res, (caddr_t)&res);
1215 return (res.status);
1216 }
1217
1218 /*ARGSUSED*/
1219 OM_uint32
kgss_delete_sec_context(OM_uint32 * minor_status,gss_ctx_id_t * context_handle,gss_buffer_t output_token)1220 kgss_delete_sec_context(
1221 OM_uint32 *minor_status,
1222 gss_ctx_id_t *context_handle,
1223 gss_buffer_t output_token)
1224 {
1225 OM_uint32 err;
1226 struct kgss_ctx *kctx;
1227
1228 if (*context_handle == GSS_C_NO_CONTEXT) {
1229 return (GSS_S_NO_CONTEXT);
1230 } else
1231 kctx = KCTX_TO_KGSS_CTX(*context_handle);
1232
1233 err = kgss_delete_sec_context_wrapped(minor_status,
1234 &kctx->gssd_ctx, kctx->gssd_ctx_verifier,
1235 output_token);
1236
1237 if (kctx->gssd_ctx != GSSD_NO_CONTEXT)
1238 err = GSS_S_FAILURE;
1239 else
1240 err = GSS_S_COMPLETE;
1241
1242 KGSS_FREE(kctx);
1243 *context_handle = GSS_C_NO_CONTEXT;
1244 return (err);
1245 }
1246
1247 /*ARGSUSED*/
1248 OM_uint32
kgss_context_time(minor_status,context_handle,time_rec,uid)1249 kgss_context_time(minor_status,
1250 context_handle,
1251 time_rec,
1252 uid)
1253 OM_uint32 *minor_status;
1254 gss_ctx_id_t context_handle;
1255 OM_uint32 *time_rec;
1256 uid_t uid;
1257 {
1258 return (GSS_S_FAILURE);
1259 }
1260
1261 OM_uint32
kgss_sign_wrapped(minor_status,context_handle,qop_req,message_buffer,msg_token,gssd_context_verifier)1262 kgss_sign_wrapped(minor_status,
1263 context_handle,
1264 qop_req,
1265 message_buffer,
1266 msg_token,
1267 gssd_context_verifier)
1268 OM_uint32 *minor_status;
1269 gssd_ctx_id_t context_handle;
1270 OM_uint32 gssd_context_verifier;
1271 int qop_req;
1272 gss_buffer_t message_buffer;
1273 gss_buffer_t msg_token;
1274 {
1275
1276 gss_sign_arg arg;
1277 gss_sign_res res;
1278
1279 /* get the client handle to GSSD */
1280
1281 if ((clnt = getgssd_handle()) == NULL) {
1282 clnt_pcreateerror(server);
1283 return (GSS_S_FAILURE);
1284 }
1285
1286 /* copy the procedure arguments into the rpc arg parameter */
1287
1288
1289 arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t);
1290 arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
1291 arg.gssd_context_verifier = gssd_context_verifier;
1292
1293 arg.qop_req = qop_req;
1294 arg.message_buffer.GSS_BUFFER_T_len = (uint_t)message_buffer->length;
1295 arg.message_buffer.GSS_BUFFER_T_val = (char *)message_buffer->value;
1296
1297 /* call the remote procedure */
1298
1299 memset(&res, 0, sizeof (res));
1300 if (gss_sign_1(&arg, &res, clnt) != RPC_SUCCESS) {
1301
1302 /*
1303 * if the RPC call times out, null out all return arguments,
1304 * set minor_status to its maximum value, and return GSS_S_FAILURE
1305 */
1306
1307 if (minor_status != NULL)
1308 *minor_status = DEFAULT_MINOR_STAT;
1309 if (msg_token != NULL)
1310 msg_token->length = 0;
1311
1312 return (GSS_S_FAILURE);
1313 }
1314
1315 /* copy the rpc results into the return arguments */
1316
1317 if (minor_status != NULL)
1318 *minor_status = res.minor_status;
1319
1320 if (msg_token != NULL) {
1321 msg_token->length = res.msg_token.GSS_BUFFER_T_len;
1322 msg_token->value = (void *) MALLOC(msg_token->length);
1323 memcpy(msg_token->value, res.msg_token.GSS_BUFFER_T_val,
1324 msg_token->length);
1325 }
1326
1327 /*
1328 * free the memory allocated for the results and return with the status
1329 * received in the rpc call
1330 */
1331
1332 clnt_freeres(clnt, xdr_gss_sign_res, (caddr_t)&res);
1333 return (res.status);
1334 }
1335
1336 OM_uint32
kgss_sign(OM_uint32 * minor_status,gss_ctx_id_t context_handle,int qop_req,gss_buffer_t message_buffer,gss_buffer_t msg_token)1337 kgss_sign(
1338 OM_uint32 *minor_status,
1339 gss_ctx_id_t context_handle,
1340 int qop_req,
1341 gss_buffer_t message_buffer,
1342 gss_buffer_t msg_token)
1343 {
1344 if (context_handle == GSS_C_NO_CONTEXT)
1345 return (GSS_S_FAILURE);
1346
1347 return (KGSS_SIGN(minor_status,
1348 context_handle, qop_req, message_buffer,
1349 msg_token));
1350 }
1351
1352 OM_uint32
kgss_verify_wrapped(minor_status,context_handle,message_buffer,token_buffer,qop_state,gssd_context_verifier)1353 kgss_verify_wrapped(
1354 minor_status,
1355 context_handle,
1356 message_buffer,
1357 token_buffer,
1358 qop_state,
1359 gssd_context_verifier)
1360 OM_uint32 *minor_status;
1361 gssd_ctx_id_t context_handle;
1362 OM_uint32 gssd_context_verifier;
1363 gss_buffer_t message_buffer;
1364 gss_buffer_t token_buffer;
1365 int *qop_state;
1366 {
1367 gss_verify_arg arg;
1368 gss_verify_res res;
1369
1370 /* get the client handle to GSSD */
1371
1372 if ((clnt = getgssd_handle()) == NULL) {
1373 clnt_pcreateerror(server);
1374 return (GSS_S_FAILURE);
1375 }
1376
1377 /* copy the procedure arguments into the rpc arg parameter */
1378
1379 arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t);
1380 arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
1381
1382 arg.gssd_context_verifier = gssd_context_verifier;
1383
1384 arg.message_buffer.GSS_BUFFER_T_len = (uint_t)message_buffer->length;
1385 arg.message_buffer.GSS_BUFFER_T_val = (char *)message_buffer->value;
1386
1387 arg.token_buffer.GSS_BUFFER_T_len = (uint_t)token_buffer->length;
1388 arg.token_buffer.GSS_BUFFER_T_val = (char *)token_buffer->value;
1389
1390 /* call the remote procedure */
1391
1392 memset(&res, 0, sizeof (res));
1393 if (gss_verify_1(&arg, &res, clnt) != RPC_SUCCESS) {
1394
1395 /*
1396 * if the RPC call times out, null out all return arguments,
1397 * set minor_status to its maximum value, and return GSS_S_FAILURE
1398 */
1399
1400 if (minor_status != NULL)
1401 *minor_status = DEFAULT_MINOR_STAT;
1402 if (qop_state != NULL)
1403 *qop_state = 0;
1404
1405 return (GSS_S_FAILURE);
1406 }
1407
1408 /* copy the rpc results into the return arguments */
1409
1410 if (minor_status != NULL)
1411 *minor_status = res.minor_status;
1412
1413 if (qop_state != NULL)
1414 *qop_state = res.qop_state;
1415
1416 /* return with status returned in rpc call */
1417
1418 return (res.status);
1419 }
1420
1421 OM_uint32
kgss_verify(OM_uint32 * minor_status,gss_ctx_id_t context_handle,gss_buffer_t message_buffer,gss_buffer_t token_buffer,int * qop_state)1422 kgss_verify(OM_uint32 *minor_status,
1423 gss_ctx_id_t context_handle,
1424 gss_buffer_t message_buffer,
1425 gss_buffer_t token_buffer,
1426 int *qop_state)
1427 {
1428 if (context_handle == GSS_C_NO_CONTEXT)
1429 return (GSS_S_FAILURE);
1430
1431 return (KGSS_VERIFY(minor_status, context_handle,
1432 message_buffer, token_buffer, qop_state));
1433 }
1434
1435
1436 OM_uint32
kgss_seal_wrapped(minor_status,context_handle,conf_req_flag,qop_req,input_message_buffer,conf_state,output_message_buffer,gssd_context_verifier)1437 kgss_seal_wrapped(
1438 minor_status,
1439 context_handle,
1440 conf_req_flag,
1441 qop_req,
1442 input_message_buffer,
1443 conf_state,
1444 output_message_buffer,
1445 gssd_context_verifier)
1446
1447 OM_uint32 *minor_status;
1448 gssd_ctx_id_t context_handle;
1449 OM_uint32 gssd_context_verifier;
1450 int conf_req_flag;
1451 int qop_req;
1452 gss_buffer_t input_message_buffer;
1453 int *conf_state;
1454 gss_buffer_t output_message_buffer;
1455 {
1456 gss_seal_arg arg;
1457 gss_seal_res res;
1458
1459 /* get the client handle to GSSD */
1460
1461 if ((clnt = getgssd_handle()) == NULL) {
1462 clnt_pcreateerror(server);
1463 return (GSS_S_FAILURE);
1464 }
1465
1466 /* copy the procedure arguments into the rpc arg parameter */
1467
1468
1469 arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t);
1470 arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
1471 arg.gssd_context_verifier = gssd_context_verifier;
1472
1473 arg.conf_req_flag = conf_req_flag;
1474
1475 arg.qop_req = qop_req;
1476
1477 arg.input_message_buffer.GSS_BUFFER_T_len =
1478 (uint_t)input_message_buffer->length;
1479
1480 arg.input_message_buffer.GSS_BUFFER_T_val =
1481 (char *)input_message_buffer->value;
1482
1483 /* call the remote procedure */
1484
1485 memset(&res, 0, sizeof (res));
1486 if (gss_seal_1(&arg, &res, clnt) != RPC_SUCCESS) {
1487
1488 /*
1489 * if the RPC call times out, null out all return arguments,
1490 * set minor_status to its maximum value, and return GSS_S_FAILURE
1491 */
1492
1493 if (minor_status != NULL)
1494 *minor_status = DEFAULT_MINOR_STAT;
1495 if (conf_state != NULL)
1496 *conf_state = 0;
1497 if (output_message_buffer != NULL)
1498 output_message_buffer->length = 0;
1499
1500 return (GSS_S_FAILURE);
1501 }
1502
1503 /* copy the rpc results into the return arguments */
1504
1505 if (minor_status != NULL)
1506 *minor_status = res.minor_status;
1507
1508 if (conf_state != NULL)
1509 *conf_state = res.conf_state;
1510
1511 if (output_message_buffer != NULL) {
1512 output_message_buffer->length =
1513 res.output_message_buffer.GSS_BUFFER_T_len;
1514
1515 output_message_buffer->value =
1516 (void *) MALLOC(output_message_buffer->length);
1517 memcpy(output_message_buffer->value,
1518 res.output_message_buffer.GSS_BUFFER_T_val,
1519 output_message_buffer->length);
1520 }
1521
1522 /*
1523 * free the memory allocated for the results and return with the status
1524 * received in the rpc call
1525 */
1526
1527 clnt_freeres(clnt, xdr_gss_seal_res, (caddr_t)&res);
1528 return (res.status);
1529 }
1530
1531 OM_uint32
kgss_seal(OM_uint32 * minor_status,gss_ctx_id_t context_handle,int conf_req_flag,int qop_req,gss_buffer_t input_message_buffer,int * conf_state,gss_buffer_t output_message_buffer)1532 kgss_seal(OM_uint32 *minor_status,
1533 gss_ctx_id_t context_handle,
1534 int conf_req_flag,
1535 int qop_req,
1536 gss_buffer_t input_message_buffer,
1537 int *conf_state,
1538 gss_buffer_t output_message_buffer)
1539
1540 {
1541 if (context_handle == GSS_C_NO_CONTEXT)
1542 return (GSS_S_FAILURE);
1543
1544 return (KGSS_SEAL(minor_status, context_handle,
1545 conf_req_flag, qop_req,
1546 input_message_buffer,
1547 conf_state, output_message_buffer));
1548 }
1549
1550 OM_uint32
kgss_unseal_wrapped(minor_status,context_handle,input_message_buffer,output_message_buffer,conf_state,qop_state,gssd_context_verifier)1551 kgss_unseal_wrapped(minor_status,
1552 context_handle,
1553 input_message_buffer,
1554 output_message_buffer,
1555 conf_state,
1556 qop_state,
1557 gssd_context_verifier)
1558 OM_uint32 *minor_status;
1559 gssd_ctx_id_t context_handle;
1560 OM_uint32 gssd_context_verifier;
1561 gss_buffer_t input_message_buffer;
1562 gss_buffer_t output_message_buffer;
1563 int *conf_state;
1564 int *qop_state;
1565 {
1566 gss_unseal_arg arg;
1567 gss_unseal_res res;
1568
1569 /* get the client handle to GSSD */
1570
1571 if ((clnt = getgssd_handle()) == NULL) {
1572 clnt_pcreateerror(server);
1573 return (GSS_S_FAILURE);
1574 }
1575
1576 /* copy the procedure arguments into the rpc arg parameter */
1577
1578
1579 arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t);
1580 arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
1581 arg.gssd_context_verifier = gssd_context_verifier;
1582
1583 arg.input_message_buffer.GSS_BUFFER_T_len =
1584 (uint_t)input_message_buffer->length;
1585
1586 arg.input_message_buffer.GSS_BUFFER_T_val =
1587 (char *)input_message_buffer->value;
1588
1589 /* call the remote procedure */
1590
1591 memset(&res, 0, sizeof (res));
1592 if (gss_unseal_1(&arg, &res, clnt) != RPC_SUCCESS) {
1593
1594 /*
1595 * if the RPC call times out, null out all return arguments,
1596 * set minor_status to its maximum value, and return GSS_S_FAILURE
1597 */
1598
1599 if (minor_status != NULL)
1600 *minor_status = DEFAULT_MINOR_STAT;
1601 if (output_message_buffer != NULL)
1602 output_message_buffer->length = 0;
1603 if (conf_state != NULL)
1604 *conf_state = 0;
1605 if (qop_state != NULL)
1606 *qop_state = 0;
1607
1608 return (GSS_S_FAILURE);
1609 }
1610
1611 /* copy the rpc results into the return arguments */
1612
1613 if (minor_status != NULL)
1614 *minor_status = res.minor_status;
1615
1616 if (output_message_buffer != NULL) {
1617 output_message_buffer->length =
1618 res.output_message_buffer.GSS_BUFFER_T_len;
1619
1620 output_message_buffer->value =
1621 (void *) MALLOC(output_message_buffer->length);
1622 memcpy(output_message_buffer->value,
1623 res.output_message_buffer.GSS_BUFFER_T_val,
1624 output_message_buffer->length);
1625 }
1626
1627 if (conf_state != NULL)
1628 *conf_state = res.conf_state;
1629
1630 if (qop_state != NULL)
1631 *qop_state = res.qop_state;
1632
1633 /*
1634 * free the memory allocated for the results and return with the status
1635 * received in the rpc call
1636 */
1637
1638 clnt_freeres(clnt, xdr_gss_unseal_res, (caddr_t)&res);
1639 return (res.status);
1640 }
1641
1642 OM_uint32
kgss_unseal(OM_uint32 * minor_status,gss_ctx_id_t context_handle,gss_buffer_t input_message_buffer,gss_buffer_t output_message_buffer,int * conf_state,int * qop_state)1643 kgss_unseal(OM_uint32 *minor_status,
1644 gss_ctx_id_t context_handle,
1645 gss_buffer_t input_message_buffer,
1646 gss_buffer_t output_message_buffer,
1647 int *conf_state,
1648 int *qop_state)
1649 {
1650 if (context_handle == GSS_C_NO_CONTEXT)
1651 return (GSS_S_FAILURE);
1652
1653 return (KGSS_UNSEAL(minor_status, context_handle,
1654 input_message_buffer, output_message_buffer,
1655 conf_state, qop_state));
1656 }
1657
1658 OM_uint32
kgss_display_status(minor_status,status_value,status_type,mech_type,message_context,status_string,uid)1659 kgss_display_status(minor_status,
1660 status_value,
1661 status_type,
1662 mech_type,
1663 message_context,
1664 status_string,
1665 uid)
1666 OM_uint32 *minor_status;
1667 OM_uint32 status_value;
1668 int status_type;
1669 gss_OID mech_type;
1670 int *message_context;
1671 gss_buffer_t status_string;
1672 uid_t uid;
1673 {
1674 gss_display_status_arg arg;
1675 gss_display_status_res res;
1676
1677 /* get the client handle to GSSD */
1678
1679 if ((clnt = getgssd_handle()) == NULL) {
1680 clnt_pcreateerror(server);
1681 return (GSS_S_FAILURE);
1682 }
1683
1684 /* copy the procedure arguments into the rpc arg parameter */
1685
1686 arg.uid = (OM_uint32) uid;
1687
1688 arg.status_value = status_value;
1689 arg.status_type = status_type;
1690
1691 arg.mech_type.GSS_OID_len = (uint_t)(mech_type != GSS_C_NULL_OID ?
1692 mech_type->length : 0);
1693 arg.mech_type.GSS_OID_val = (char *)(mech_type != GSS_C_NULL_OID ?
1694 mech_type->elements : 0);
1695
1696 arg.message_context = *message_context;
1697
1698 /* call the remote procedure */
1699
1700 if (message_context != NULL)
1701 *message_context = 0;
1702 if (status_string != NULL) {
1703 status_string->length = 0;
1704 status_string->value = NULL;
1705 }
1706
1707 memset(&res, 0, sizeof (res));
1708 if (gss_display_status_1(&arg, &res, clnt) != RPC_SUCCESS) {
1709
1710 /*
1711 * if the RPC call times out, null out all return arguments,
1712 * set minor_status to its maximum value, and return GSS_S_FAILURE
1713 */
1714
1715 if (minor_status != NULL)
1716 *minor_status = DEFAULT_MINOR_STAT;
1717
1718 return (GSS_S_FAILURE);
1719 }
1720
1721 if (minor_status != NULL)
1722 *minor_status = res.minor_status;
1723
1724 /* now process the results and pass them back to the caller */
1725
1726 if (res.status == GSS_S_COMPLETE) {
1727 if (message_context != NULL)
1728 *message_context = res.message_context;
1729 if (status_string != NULL) {
1730 status_string->length =
1731 (size_t)res.status_string.GSS_BUFFER_T_len;
1732 status_string->value =
1733 (void *)MALLOC(status_string->length);
1734 memcpy(status_string->value,
1735 res.status_string.GSS_BUFFER_T_val,
1736 status_string->length);
1737 }
1738 }
1739
1740 clnt_freeres(clnt, xdr_gss_display_status_res, (caddr_t)&res);
1741 return (res.status);
1742 }
1743
1744 /*ARGSUSED*/
1745 OM_uint32
kgss_indicate_mechs(minor_status,mech_set,uid)1746 kgss_indicate_mechs(minor_status,
1747 mech_set,
1748 uid)
1749 OM_uint32 *minor_status;
1750 gss_OID_set *mech_set;
1751 uid_t uid;
1752 {
1753 void *arg;
1754 gss_indicate_mechs_res res;
1755 int i;
1756
1757 /* get the client handle to GSSD */
1758
1759 if ((clnt = getgssd_handle()) == NULL) {
1760 clnt_pcreateerror(server);
1761 return (GSS_S_FAILURE);
1762 }
1763
1764 memset(&res, 0, sizeof (res));
1765 if (gss_indicate_mechs_1(&arg, &res, clnt) != RPC_SUCCESS) {
1766
1767 /*
1768 * if the RPC call times out, null out all return arguments,
1769 * set minor_status to its maximum value, and return GSS_S_FAILURE
1770 */
1771
1772 if (minor_status != NULL)
1773 *minor_status = DEFAULT_MINOR_STAT;
1774 if (mech_set != NULL)
1775 *mech_set = NULL;
1776
1777 return (GSS_S_FAILURE);
1778 }
1779
1780 /* copy the rpc results into the return arguments */
1781
1782 if (minor_status != NULL)
1783 *minor_status = res.minor_status;
1784
1785 if (mech_set != NULL) {
1786 *mech_set = (gss_OID_set) MALLOC(sizeof (gss_OID_set_desc));
1787 (*mech_set)->count = res.mech_set.GSS_OID_SET_len;
1788 (*mech_set)->elements = (void *)
1789 MALLOC ((*mech_set)->count * sizeof (gss_OID_desc));
1790 for (i = 0; i < (*mech_set)->count; i++) {
1791 (*mech_set)->elements[i].length =
1792 res.mech_set.GSS_OID_SET_val[i].GSS_OID_len;
1793 (*mech_set)->elements[i].elements = (void *)
1794 MALLOC ((*mech_set)->elements[i].length);
1795 memcpy ((*mech_set)->elements[i].elements,
1796 res.mech_set.GSS_OID_SET_val[i].GSS_OID_val,
1797 (*mech_set)->elements[i].length);
1798 }
1799 }
1800
1801 /*
1802 * free the memory allocated for the results and return with the status
1803 * received in the rpc call
1804 */
1805
1806 clnt_freeres(clnt, xdr_gss_indicate_mechs_res, (caddr_t)&res);
1807 return (res.status);
1808 }
1809
1810
1811 OM_uint32
kgss_inquire_cred_wrapped(minor_status,cred_handle,gssd_cred_verifier,name,lifetime,cred_usage,mechanisms,uid)1812 kgss_inquire_cred_wrapped(minor_status,
1813 cred_handle,
1814 gssd_cred_verifier,
1815 name,
1816 lifetime,
1817 cred_usage,
1818 mechanisms,
1819 uid)
1820 OM_uint32 *minor_status;
1821 gssd_cred_id_t cred_handle;
1822 OM_uint32 gssd_cred_verifier;
1823 gss_name_t *name;
1824 OM_uint32 *lifetime;
1825 int *cred_usage;
1826 gss_OID_set *mechanisms;
1827 uid_t uid;
1828 {
1829 OM_uint32 minor_status_temp;
1830 gss_buffer_desc external_name;
1831 gss_OID name_type;
1832 int i;
1833
1834 gss_inquire_cred_arg arg;
1835 gss_inquire_cred_res res;
1836
1837 /* get the client handle to GSSD */
1838
1839 if ((clnt = getgssd_handle()) == NULL) {
1840 clnt_pcreateerror(server);
1841 return (GSS_S_FAILURE);
1842 }
1843
1844
1845 /* copy the procedure arguments into the rpc arg parameter */
1846
1847 arg.uid = (OM_uint32) uid;
1848
1849 arg.cred_handle.GSS_CRED_ID_T_len =
1850 cred_handle == GSSD_NO_CREDENTIAL ?
1851 0 : (uint_t)sizeof (gssd_cred_id_t);
1852 arg.cred_handle.GSS_CRED_ID_T_val = (char *)&cred_handle;
1853 arg.gssd_cred_verifier = gssd_cred_verifier;
1854
1855 /* call the remote procedure */
1856
1857 memset(&res, 0, sizeof (res));
1858 if (gss_inquire_cred_1(&arg, &res, clnt) != RPC_SUCCESS) {
1859
1860 /*
1861 * if the RPC call times out, null out all return arguments,
1862 * set minor_status to its maximum value, and return GSS_S_FAILURE
1863 */
1864
1865 if (minor_status != NULL)
1866 *minor_status = DEFAULT_MINOR_STAT;
1867 if (name != NULL)
1868 *name = NULL;
1869 if (lifetime != NULL)
1870 *lifetime = 0;
1871 if (cred_usage != NULL)
1872 *cred_usage = 0;
1873 if (mechanisms != NULL)
1874 *mechanisms = NULL;
1875
1876 return (GSS_S_FAILURE);
1877 }
1878
1879 /* copy the rpc results into the return arguments */
1880
1881 if (minor_status != NULL)
1882 *minor_status = res.minor_status;
1883
1884 /* convert name from external to internal format */
1885
1886 if (name != NULL) {
1887 external_name.length = res.name.GSS_BUFFER_T_len;
1888 external_name.value = res.name.GSS_BUFFER_T_val;
1889
1890 /*
1891 * we have to allocate a name_type descriptor and
1892 * elements storage, since gss_import_name() only
1893 * stores a pointer to the name_type info in the
1894 * union_name struct
1895 */
1896
1897 name_type = (gss_OID) MALLOC(sizeof (gss_OID_desc));
1898
1899 name_type->length = res.name_type.GSS_OID_len;
1900 name_type->elements = (void *) MALLOC(name_type->length);
1901 memcpy(name_type->elements, res.name_type.GSS_OID_val,
1902 name_type->length);
1903
1904 if (gss_import_name(&minor_status_temp, &external_name,
1905 name_type, name) != GSS_S_COMPLETE) {
1906
1907 *minor_status = (OM_uint32) minor_status_temp;
1908 gss_release_buffer(&minor_status_temp, &external_name);
1909
1910 clnt_freeres(clnt, xdr_gss_inquire_cred_res,
1911 (caddr_t)&res);
1912 return ((OM_uint32) GSS_S_FAILURE);
1913 }
1914 }
1915
1916 if (lifetime != NULL)
1917 *lifetime = res.lifetime;
1918
1919 if (cred_usage != NULL)
1920 *cred_usage = res.cred_usage;
1921
1922 if (mechanisms != NULL) {
1923 *mechanisms =
1924 (gss_OID_set) MALLOC(sizeof (gss_OID_set_desc));
1925 if (res.mechanisms.GSS_OID_SET_len != 0) {
1926 (*mechanisms)->count =
1927 (int)res.mechanisms.GSS_OID_SET_len;
1928 (*mechanisms)->elements = (gss_OID)
1929 MALLOC(sizeof (gss_OID) * (*mechanisms)->count);
1930
1931 for (i = 0; i < (*mechanisms)->count; i++) {
1932 (*mechanisms)->elements[i].length = (OM_uint32)
1933 res.mechanisms.GSS_OID_SET_val[i].GSS_OID_len;
1934 (*mechanisms)->elements[i].elements = (void *)
1935 MALLOC((*mechanisms)->elements[i].length);
1936 memcpy((*mechanisms)->elements[i].elements,
1937 res.mechanisms.GSS_OID_SET_val[i].GSS_OID_val,
1938 (*mechanisms)->elements[i].length);
1939 }
1940 } else
1941 (*mechanisms)->count = 0;
1942 }
1943
1944 /*
1945 * free the memory allocated for the results and return with the status
1946 * received in the rpc call
1947 */
1948
1949 clnt_freeres(clnt, xdr_gss_inquire_cred_res, (caddr_t)&res);
1950 return (res.status);
1951 }
1952
1953
1954 OM_uint32
kgss_inquire_cred(minor_status,cred_handle,name,lifetime,cred_usage,mechanisms,uid)1955 kgss_inquire_cred(minor_status,
1956 cred_handle,
1957 name,
1958 lifetime,
1959 cred_usage,
1960 mechanisms,
1961 uid)
1962 OM_uint32 *minor_status;
1963 gss_cred_id_t cred_handle;
1964 gss_name_t *name;
1965 OM_uint32 *lifetime;
1966 int *cred_usage;
1967 gss_OID_set * mechanisms;
1968 uid_t uid;
1969 {
1970
1971 OM_uint32 gssd_cred_verifier;
1972 gssd_cred_id_t gssd_cred_handle;
1973
1974 gssd_cred_verifier = KCRED_TO_CREDV(cred_handle);
1975 gssd_cred_handle = KCRED_TO_CRED(cred_handle);
1976
1977 return (kgss_inquire_cred_wrapped(minor_status,
1978 gssd_cred_handle, gssd_cred_verifier,
1979 name, lifetime, cred_usage, mechanisms, uid));
1980 }
1981
1982
1983 OM_uint32
kgss_inquire_cred_by_mech_wrapped(minor_status,cred_handle,gssd_cred_verifier,mech_type,uid)1984 kgss_inquire_cred_by_mech_wrapped(minor_status,
1985 cred_handle,
1986 gssd_cred_verifier,
1987 mech_type,
1988 uid)
1989 OM_uint32 *minor_status;
1990 gssd_cred_id_t cred_handle;
1991 OM_uint32 gssd_cred_verifier;
1992 gss_OID mech_type;
1993 uid_t uid;
1994 {
1995 OM_uint32 minor_status_temp;
1996
1997 gss_inquire_cred_by_mech_arg arg;
1998 gss_inquire_cred_by_mech_res res;
1999
2000 /* get the client handle to GSSD */
2001
2002 if ((clnt = getgssd_handle()) == NULL) {
2003 clnt_pcreateerror(server);
2004 return (GSS_S_FAILURE);
2005 }
2006
2007
2008 /* copy the procedure arguments into the rpc arg parameter */
2009
2010 arg.uid = (OM_uint32) uid;
2011
2012 arg.cred_handle.GSS_CRED_ID_T_len =
2013 cred_handle == GSSD_NO_CREDENTIAL ?
2014 0 : (uint_t)sizeof (gssd_cred_id_t);
2015 arg.cred_handle.GSS_CRED_ID_T_val = (char *)&cred_handle;
2016 arg.gssd_cred_verifier = gssd_cred_verifier;
2017
2018 arg.mech_type.GSS_OID_len =
2019 (uint_t)(mech_type != GSS_C_NULL_OID ?
2020 mech_type->length : 0);
2021 arg.mech_type.GSS_OID_val =
2022 (char *)(mech_type != GSS_C_NULL_OID ?
2023 mech_type->elements : 0);
2024 /* call the remote procedure */
2025
2026 memset(&res, 0, sizeof (res));
2027 if (gss_inquire_cred_by_mech_1(&arg, &res, clnt) != RPC_SUCCESS) {
2028
2029 /*
2030 * if the RPC call times out, null out all return arguments,
2031 * set minor_status to its maximum value, and return GSS_S_FAILURE
2032 */
2033
2034 if (minor_status != NULL)
2035 *minor_status = DEFAULT_MINOR_STAT;
2036 return (GSS_S_FAILURE);
2037 }
2038
2039 /* copy the rpc results into the return arguments */
2040
2041 if (minor_status != NULL)
2042 *minor_status = res.minor_status;
2043
2044 /* convert name from external to internal format */
2045
2046 /*
2047 * free the memory allocated for the results and return with the status
2048 * received in the rpc call
2049 */
2050
2051 clnt_freeres(clnt, xdr_gss_inquire_cred_by_mech_res, (caddr_t)&res);
2052 return (res.status);
2053 }
2054
2055
2056 OM_uint32
kgss_inquire_cred_by_mech(minor_status,cred_handle,mech_type,uid)2057 kgss_inquire_cred_by_mech(minor_status,
2058 cred_handle,
2059 mech_type,
2060 uid)
2061 OM_uint32 *minor_status;
2062 gss_cred_id_t cred_handle;
2063 gss_OID mech_type;
2064 uid_t uid;
2065 {
2066
2067 OM_uint32 gssd_cred_verifier;
2068 gssd_cred_id_t gssd_cred_handle;
2069
2070 gssd_cred_verifier = KCRED_TO_CREDV(cred_handle);
2071 gssd_cred_handle = KCRED_TO_CRED(cred_handle);
2072
2073 return (kgss_inquire_cred_by_mech_wrapped(minor_status,
2074 gssd_cred_handle, gssd_cred_verifier,
2075 mech_type, uid));
2076 }
2077
2078 OM_uint32
kgsscred_expname_to_unix_cred(expName,uidOut,gidOut,gids,gidsLen,uid)2079 kgsscred_expname_to_unix_cred(expName, uidOut, gidOut, gids, gidsLen, uid)
2080 const gss_buffer_t expName;
2081 uid_t *uidOut;
2082 gid_t *gidOut;
2083 gid_t *gids[];
2084 int *gidsLen;
2085 uid_t uid;
2086 {
2087 gsscred_expname_to_unix_cred_arg args;
2088 gsscred_expname_to_unix_cred_res res;
2089
2090 /* check input/output parameters */
2091 if (expName == NULL || expName->value == NULL)
2092 return (GSS_S_CALL_INACCESSIBLE_READ);
2093
2094 if (uidOut == NULL)
2095 return (GSS_S_CALL_INACCESSIBLE_WRITE);
2096
2097 /* NULL out output parameters */
2098 *uidOut = 0;
2099 if (gidsLen)
2100 *gidsLen = 0;
2101
2102 if (gids)
2103 *gids = NULL;
2104
2105 /* get the client handle to gssd */
2106 if ((clnt = getgssd_handle()) == NULL)
2107 {
2108 clnt_pcreateerror(server);
2109 return (GSS_S_FAILURE);
2110 }
2111
2112 /* copy the procedure arguments */
2113 args.uid = uid;
2114 args.expname.GSS_BUFFER_T_val = expName->value;
2115 args.expname.GSS_BUFFER_T_len = expName->length;
2116
2117 /* null out the return buffer and call the remote proc */
2118 memset(&res, 0, sizeof (res));
2119
2120 if (gsscred_expname_to_unix_cred_1(&args, &res, clnt) != RPC_SUCCESS)
2121 {
2122 return (GSS_S_FAILURE);
2123 }
2124
2125 /* copy the results into the result parameters */
2126 if (res.major == GSS_S_COMPLETE)
2127 {
2128 *uidOut = res.uid;
2129 if (gidOut)
2130 *gidOut = res.gid;
2131 if (gids && gidsLen)
2132 {
2133 *gids = res.gids.GSSCRED_GIDS_val;
2134 *gidsLen = res.gids.GSSCRED_GIDS_len;
2135 res.gids.GSSCRED_GIDS_val = NULL;
2136 res.gids.GSSCRED_GIDS_len = 0;
2137 }
2138 }
2139
2140 /* free RPC results */
2141 clnt_freeres(clnt, xdr_gsscred_expname_to_unix_cred_res, (caddr_t)&res);
2142
2143 return (res.major);
2144 } /* kgsscred_expname_to_unix_cred */
2145
2146 OM_uint32
kgsscred_name_to_unix_cred(intName,mechType,uidOut,gidOut,gids,gidsLen,uid)2147 kgsscred_name_to_unix_cred(intName, mechType, uidOut, gidOut, gids,
2148 gidsLen, uid)
2149 const gss_name_t intName;
2150 const gss_OID mechType;
2151 uid_t *uidOut;
2152 gid_t *gidOut;
2153 gid_t *gids[];
2154 int *gidsLen;
2155 uid_t uid;
2156 {
2157 gsscred_name_to_unix_cred_arg args;
2158 gsscred_name_to_unix_cred_res res;
2159 OM_uint32 major, minor;
2160 gss_OID nameOid;
2161 gss_buffer_desc flatName = GSS_C_EMPTY_BUFFER;
2162
2163
2164 /* check the input/output parameters */
2165 if (intName == NULL || mechType == NULL)
2166 return (GSS_S_CALL_INACCESSIBLE_READ);
2167
2168 if (uidOut == NULL)
2169 return (GSS_S_CALL_INACCESSIBLE_WRITE);
2170
2171 /* NULL out the output parameters */
2172 *uidOut = 0;
2173 if (gids)
2174 *gids = NULL;
2175
2176 if (gidsLen)
2177 *gidsLen = 0;
2178
2179 /* get the client handle to gssd */
2180 if ((clnt = getgssd_handle()) == NULL)
2181 {
2182 clnt_pcreateerror(server);
2183 return (GSS_S_FAILURE);
2184 }
2185
2186 /* convert the name to flat representation */
2187 if ((major = gss_display_name(&minor, intName, &flatName, &nameOid))
2188 != GSS_S_COMPLETE)
2189 {
2190 return (major);
2191 }
2192
2193 /* set the rpc parameters */
2194 args.uid = uid;
2195 args.pname.GSS_BUFFER_T_len = flatName.length;
2196 args.pname.GSS_BUFFER_T_val = flatName.value;
2197 args.name_type.GSS_OID_len = nameOid->length;
2198 args.name_type.GSS_OID_val = nameOid->elements;
2199 args.mech_type.GSS_OID_len = mechType->length;
2200 args.mech_type.GSS_OID_val = mechType->elements;
2201
2202 /* call the remote procedure */
2203 memset(&res, 0, sizeof (res));
2204 if (gsscred_name_to_unix_cred_1(&args, &res, clnt) != RPC_SUCCESS)
2205 {
2206 gss_release_buffer(&minor, &flatName);
2207 return (GSS_S_FAILURE);
2208 }
2209
2210 gss_release_buffer(&minor, &flatName);
2211 /* copy the output parameters on output */
2212 if (res.major == GSS_S_COMPLETE)
2213 {
2214 *uidOut = res.uid;
2215 if (gidOut)
2216 *gidOut = res.gid;
2217 if (gids && gidsLen)
2218 {
2219 *gids = res.gids.GSSCRED_GIDS_val;
2220 *gidsLen = res.gids.GSSCRED_GIDS_len;
2221 res.gids.GSSCRED_GIDS_val = NULL;
2222 res.gids.GSSCRED_GIDS_len = 0;
2223 }
2224 }
2225
2226 /* delete RPC allocated memory */
2227 clnt_freeres(clnt, xdr_gsscred_name_to_unix_cred_res, (caddr_t)&res);
2228
2229 return (res.major);
2230 } /* kgsscred_name_to_unix_cred */
2231
2232 OM_uint32
kgss_get_group_info(puid,gidOut,gids,gidsLen,uid)2233 kgss_get_group_info(puid, gidOut, gids, gidsLen, uid)
2234 const uid_t puid;
2235 gid_t *gidOut;
2236 gid_t *gids[];
2237 int *gidsLen;
2238 uid_t uid;
2239 {
2240 gss_get_group_info_arg args;
2241 gss_get_group_info_res res;
2242
2243
2244 /* check the output parameters */
2245 if (gidOut == NULL || gids == NULL || gidsLen == NULL)
2246 return (GSS_S_CALL_INACCESSIBLE_WRITE);
2247
2248 /* get the client GSSD handle */
2249 if ((clnt = getgssd_handle()) == NULL)
2250 {
2251 clnt_pcreateerror(server);
2252 return (GSS_S_FAILURE);
2253 }
2254
2255 /* set the input parameters */
2256 args.uid = uid;
2257 args.puid = puid;
2258
2259
2260 /* call the remote procedure */
2261 memset(&res, 0, sizeof (res));
2262 if (gss_get_group_info_1(&args, &res, clnt) != RPC_SUCCESS)
2263 {
2264 return (GSS_S_FAILURE);
2265 }
2266
2267 /* copy the results */
2268 if (res.major == GSS_S_COMPLETE)
2269 {
2270 *gidOut = res.gid;
2271 *gids = res.gids.GSSCRED_GIDS_val;
2272 *gidsLen = res.gids.GSSCRED_GIDS_len;
2273 res.gids.GSSCRED_GIDS_val = NULL;
2274 res.gids.GSSCRED_GIDS_len = 0;
2275 }
2276
2277 /* nothing to free */
2278
2279 return (res.major);
2280 } /* kgss_get_group_info */
2281
2282 OM_uint32
kgss_export_sec_context_wrapped(minor_status,context_handle,output_token,gssd_context_verifier)2283 kgss_export_sec_context_wrapped(minor_status,
2284 context_handle,
2285 output_token,
2286 gssd_context_verifier)
2287 OM_uint32 *minor_status;
2288 gssd_ctx_id_t *context_handle;
2289 gss_buffer_t output_token;
2290 OM_uint32 gssd_context_verifier;
2291 {
2292 CLIENT *clnt;
2293 gss_export_sec_context_arg arg;
2294 gss_export_sec_context_res res;
2295
2296
2297 /* get the client handle to GSSD */
2298
2299 if ((clnt = getgssd_handle()) == NULL) {
2300 clnt_pcreateerror(server);
2301 return (GSS_S_FAILURE);
2302 }
2303
2304 /* copy the procedure arguments into the rpc arg parameter */
2305
2306 arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t);
2307 arg.context_handle.GSS_CTX_ID_T_val = (char *)context_handle;
2308 arg.gssd_context_verifier = gssd_context_verifier;
2309
2310 /* call the remote procedure */
2311
2312 memset(&res, 0, sizeof (res));
2313 if (gss_export_sec_context_1(&arg, &res, clnt) != RPC_SUCCESS) {
2314
2315 /*
2316 * if the RPC call times out, null out all return arguments, set minor_status
2317 * to its maximum value, and return GSS_S_FAILURE
2318 */
2319
2320 if (minor_status != NULL)
2321 *minor_status = DEFAULT_MINOR_STAT;
2322 if (context_handle != NULL)
2323 *context_handle = 0;
2324 if (output_token != NULL)
2325 output_token->length = 0;
2326
2327 return (GSS_S_FAILURE);
2328 }
2329
2330 /* copy the rpc results into the return arguments */
2331
2332 if (minor_status != NULL)
2333 *minor_status = res.minor_status;
2334
2335 if (res.context_handle.GSS_CTX_ID_T_len == 0)
2336 *context_handle = 0;
2337 else
2338 *context_handle =
2339 *((gssd_ctx_id_t *)res.context_handle.GSS_CTX_ID_T_val);
2340
2341 if (output_token != NULL && res.output_token.GSS_BUFFER_T_val != NULL) {
2342 output_token->length = res.output_token.GSS_BUFFER_T_len;
2343 output_token->value =
2344 (void *) MALLOC(output_token->length);
2345 memcpy(output_token->value,
2346 res.output_token.GSS_BUFFER_T_val,
2347 output_token->length);
2348 }
2349
2350 /*
2351 * free the memory allocated for the results and return with the status
2352 * received in the rpc call
2353 */
2354
2355 clnt_freeres(clnt, xdr_gss_export_sec_context_res, (caddr_t)&res);
2356 return (res.status);
2357
2358 }
2359
2360 OM_uint32
kgss_export_sec_context(minor_status,context_handle,output_token)2361 kgss_export_sec_context(minor_status,
2362 context_handle,
2363 output_token)
2364 OM_uint32 *minor_status;
2365 gss_ctx_id_t *context_handle;
2366 gss_buffer_t output_token;
2367 {
2368 OM_uint32 err;
2369 struct kgss_ctx *kctx;
2370
2371 if (*context_handle == GSS_C_NO_CONTEXT) {
2372 return (GSS_S_NO_CONTEXT);
2373 } else
2374 kctx = KCTX_TO_KGSS_CTX(*context_handle);
2375
2376 err = kgss_export_sec_context_wrapped(minor_status,
2377 &kctx->gssd_ctx, output_token,
2378 kctx->gssd_ctx_verifier);
2379
2380 if (GSS_ERROR(err))
2381 return (err);
2382 else {
2383 KGSS_FREE(kctx);
2384 *context_handle = GSS_C_NO_CONTEXT;
2385 return (err);
2386 }
2387
2388 }
2389
2390 OM_uint32
kgss_import_sec_context_wrapped(minor_status,input_token,context_handle,gssd_context_verifier)2391 kgss_import_sec_context_wrapped(minor_status,
2392 input_token,
2393 context_handle,
2394 gssd_context_verifier)
2395 OM_uint32 *minor_status;
2396 gss_buffer_t input_token;
2397 gss_ctx_id_t *context_handle;
2398 OM_uint32 gssd_context_verifier;
2399 {
2400 CLIENT *clnt;
2401 gss_import_sec_context_arg arg;
2402 gss_import_sec_context_res res;
2403
2404
2405 /* get the client handle to GSSD */
2406
2407 if ((clnt = getgssd_handle()) == NULL) {
2408 clnt_pcreateerror(server);
2409 return (GSS_S_FAILURE);
2410 }
2411
2412 /* copy the procedure arguments into the rpc arg parameter */
2413 arg.input_token.GSS_BUFFER_T_len = (uint_t)
2414 (input_token != GSS_C_NO_BUFFER ? input_token->length : 0);
2415 arg.input_token.GSS_BUFFER_T_val = (char *)
2416 (input_token != GSS_C_NO_BUFFER ? input_token->value : 0);
2417 arg.gssd_context_verifier = gssd_context_verifier;
2418
2419
2420 /* call the remote procedure */
2421
2422 memset(&res, 0, sizeof (res));
2423 if (gss_import_sec_context_1(&arg, &res, clnt) != RPC_SUCCESS) {
2424
2425 /*
2426 * if the RPC call times out, null out all return arguments, set minor_status
2427 * to its maximum value, and return GSS_S_FAILURE
2428 */
2429
2430 if (minor_status != NULL)
2431 *minor_status = DEFAULT_MINOR_STAT;
2432 if (context_handle != NULL)
2433 *context_handle = NULL;
2434
2435 return (GSS_S_FAILURE);
2436 }
2437
2438 /* copy the rpc results into the return arguments */
2439
2440 if (minor_status != NULL)
2441 *minor_status = res.minor_status;
2442
2443 if (res.context_handle.GSS_CTX_ID_T_len == 0)
2444 *context_handle = NULL;
2445 else
2446 *context_handle =
2447 *((gss_ctx_id_t *)res.context_handle.GSS_CTX_ID_T_val);
2448
2449
2450 /*
2451 * free the memory allocated for the results and return with the status
2452 * received in the rpc call
2453 */
2454
2455 clnt_freeres(clnt, xdr_gss_import_sec_context_res, (caddr_t)&res);
2456 return (res.status);
2457 }
2458
2459 OM_uint32
kgss_import_sec_context(minor_status,input_token,context_handle)2460 kgss_import_sec_context(minor_status,
2461 input_token,
2462 context_handle)
2463 OM_uint32 *minor_status;
2464 gss_buffer_t input_token;
2465 gss_ctx_id_t *context_handle;
2466 {
2467 struct kgss_ctx *kctx;
2468
2469 if (*context_handle == GSS_C_NO_CONTEXT) {
2470 kctx = KGSS_ALLOC();
2471 *context_handle = (gss_ctx_id_t)kctx;
2472 kctx->gssd_ctx = (OM_uint32) GSS_C_NO_CONTEXT;
2473 } else
2474 kctx = (struct kgss_ctx *)*context_handle;
2475 return (kgss_import_sec_context_wrapped(minor_status,
2476 input_token, &kctx->gssd_ctx,
2477 KCTX_TO_CTXV(context_handle)));
2478 }
2479
2480 #ifdef _KERNEL
2481 #include <sys/modctl.h>
2482
2483 static void *gss_clnt = NULL;
2484
2485 #ifdef DEBUG
2486 typedef struct {
2487 char *name; /* just put something here */
2488 } gssd_devstate_t;
2489
2490
2491 static void *gssd_state;
2492
gssd_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)2493 static int gssd_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
2494 {
2495 /* cmn_err(CE_NOTE, "In gssd_attach"); */
2496 switch (cmd) {
2497 case DDI_ATTACH:
2498 if (ddi_create_minor_node(dip, "gssd", S_IFCHR, 0, "gssd", 0)
2499 == DDI_FAILURE) {
2500 ddi_remove_minor_node(dip, NULL);
2501 return (DDI_FAILURE);
2502 }
2503 return (DDI_SUCCESS);
2504
2505 default:
2506 return (DDI_FAILURE);
2507 }
2508 }
2509
gssd_getinfo(dev_info_t * dip,ddi_info_cmd_t infocmd,void * arg,void ** result)2510 static int gssd_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd,
2511 void *arg, void **result)
2512 {
2513 dev_t dev;
2514 int error;
2515
2516 /* cmn_err(CE_NOTE, "In gssd_getinfo"); */
2517
2518 switch (infocmd) {
2519 case DDI_INFO_DEVT2INSTANCE:
2520 dev = (dev_t)arg;
2521 *result = (void *) getminor(dev);
2522 error = DDI_SUCCESS;
2523 break;
2524
2525 case DDI_INFO_DEVT2DEVINFO:
2526 /* cmn_err(CE_NOTE, "getinfo wants devinfo"); */
2527 default:
2528 error = DDI_FAILURE;
2529 break;
2530 }
2531 return (error);
2532 }
2533
gssd_identify(dev_info_t * dip)2534 static int gssd_identify(dev_info_t *dip)
2535 {
2536 /* cmn_err(CE_NOTE, "in gssd_identify"); */
2537 if (strcmp(ddi_get_name(dip), "gssd") == 0)
2538 return (DDI_IDENTIFIED);
2539 else
2540 return (DDI_NOT_IDENTIFIED);
2541 }
2542
gssd_probe(dev_info_t * dip)2543 static int gssd_probe(dev_info_t *dip)
2544 {
2545 /* cmn_err(CE_NOTE, "In gssd_probe"); */
2546
2547 return (DDI_PROBE_SUCCESS);
2548 }
2549
gssd_open(dev_t * devp,int flag,int otyp,cred_t * credp)2550 static int gssd_open(dev_t *devp, int flag, int otyp, cred_t *credp)
2551 {
2552 /* cmn_err (CE_NOTE, "In gssd_open"); */
2553 if (otyp != OTYP_CHR)
2554 return (EINVAL);
2555
2556 gss_clnt = getgssd_handle();
2557 return (0);
2558 }
2559
gssd_close(dev_t dev,int flag,int otyp,cred_t * credp)2560 static int gssd_close(dev_t dev, int flag, int otyp, cred_t *credp)
2561 {
2562 /* cmn_err(CE_NOTE, "In gssd_close"); */
2563 killgssd_handle(gss_clnt);
2564 return (0);
2565 }
2566
gssd_write(dev_t dev,struct uio * uiop,cred_t * credp)2567 static int gssd_write(dev_t dev, struct uio *uiop, cred_t *credp)
2568 {
2569 char buffer[1024];
2570 int len;
2571
2572 /* cmn_err(CE_NOTE, "In gssd_write"); */
2573 bzero(buffer, 1024);
2574
2575 uiomove(buffer, 1024, UIO_WRITE, uiop);
2576 len = strlen(buffer);
2577
2578 if (buffer[len-1] == '\n')
2579 buffer[--len] = '\0';
2580
2581 cmn_err(CE_NOTE, "Got command: (%d) \"%s\"", len, buffer);
2582 do_gssdtest(buffer);
2583 return (0);
2584 }
2585
2586 static struct cb_ops gssd_cb_ops = {
2587 gssd_open, /* cb_open */
2588 gssd_close, /* cb_close */
2589 nodev, /* cb_strategy */
2590 nodev, /* cb_print */
2591 nodev, /* cb_dump */
2592 nulldev, /* cb_read */
2593 gssd_write, /* cb_write */
2594 nodev, /* cb_ioctl */
2595 nodev, /* cb_devmap */
2596 nodev, /* cb_mmap */
2597 nodev, /* cb_segmap */
2598 nochpoll, /* cb_chpoll */
2599 ddi_prop_op, /* cb_prop_op */
2600 NULL, /* cb_stream */
2601 (int)(D_NEW|D_MP) /* cb_flag */
2602 };
2603
2604 static struct dev_ops gssd_ops = {
2605 DEVO_REV, /* devo_rev */
2606 0, /* devo_refcnt */
2607 gssd_getinfo, /* devo_getinfo */
2608 gssd_identify, /* devo_identify */
2609 nulldev, /* devo_probe */
2610 gssd_attach, /* devo_attach */
2611 nulldev, /* devo_detach */
2612 nodev, /* devo_reset */
2613 &gssd_cb_ops, /* devo_cb_ops */
2614 (struct bus_ops *)NULL /* devo_bus_ops */
2615 };
2616
2617 extern struct mod_ops mod_driverops;
2618
2619 static struct modldrv modlmisc = {
2620 &mod_driverops,
2621 "GSSD DRV Client Module",
2622 &gssd_ops
2623
2624 #else /* !DEBUG */
2625
2626 static struct modlmisc modlmisc = {
2627 &mod_miscops,
2628 "GSSD Client Module"
2629 #endif /* DEBUG */
2630 };
2631
2632 static struct modlinkage modlinkage = {
2633 MODREV_1,
2634 (void *)&modlmisc,
2635 NULL
2636 };
2637
2638 char _depends_on[] = "strmod/rpcmod misc/tlimod";
2639
_init(void)2640 _init(void)
2641 {
2642 int status;
2643
2644 if ((status = ddi_soft_state_init(&gssd_state,
2645 sizeof (gssd_devstate_t), 1)) != 0)
2646 return (status);
2647
2648 if ((status = mod_install((struct modlinkage *)&modlinkage)) != 0)
2649 ddi_soft_state_fini(&gssd_state);
2650
2651 cmn_err(CE_NOTE, "gssd: I'm in the kernel: %d.", status);
2652 return (status);
2653 }
2654
_fini()2655 _fini()
2656 {
2657 int status;
2658
2659 killgssd_handle(gss_clnt);
2660 cmn_err(CE_NOTE, "gssd: Handle destroyed.. leaving module.");
2661
2662 if ((status = mod_remove(&modlinkage)) != 0)
2663 return (status);
2664
2665 ddi_soft_state_fini(&gssd_state);
2666 return (status);
2667 }
2668
2669 _info(modinfop)
2670 struct modinfo *modinfop;
2671 {
2672 return (mod_info(&modlinkage, modinfop));
2673 }
2674
2675 #endif
2676