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