10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
56855Sjohnlev * Common Development and Distribution License (the "License").
66855Sjohnlev * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*10598SGlenn.Barry@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
230Sstevel@tonic-gate * Use is subject to license terms.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate /*
270Sstevel@tonic-gate * GSSAPI library stub module for gssd.
280Sstevel@tonic-gate */
290Sstevel@tonic-gate
300Sstevel@tonic-gate #include <mechglueP.h>
310Sstevel@tonic-gate #include "gssd_prot.h"
320Sstevel@tonic-gate #include <rpc/rpc.h>
330Sstevel@tonic-gate
340Sstevel@tonic-gate #include <sys/systm.h>
350Sstevel@tonic-gate #include <sys/types.h>
360Sstevel@tonic-gate #include <sys/cmn_err.h>
370Sstevel@tonic-gate #include <sys/kmem.h>
380Sstevel@tonic-gate #include <gssapi/kgssapi_defs.h>
390Sstevel@tonic-gate #include <sys/debug.h>
400Sstevel@tonic-gate
410Sstevel@tonic-gate #ifdef GSSDEBUG
420Sstevel@tonic-gate /*
430Sstevel@tonic-gate * Kernel kgssd module debugging aid. The global variable "gss_log"
440Sstevel@tonic-gate * is a bit mask which allows various types of debugging messages
450Sstevel@tonic-gate * to be printed out.
460Sstevel@tonic-gate *
470Sstevel@tonic-gate * gss_log & 1 will cause actual failures to be printed.
480Sstevel@tonic-gate * gss_log & 2 will cause informational messages to be
490Sstevel@tonic-gate * printed on the client side of kgssd.
500Sstevel@tonic-gate * gss_log & 4 will cause informational messages to be
510Sstevel@tonic-gate * printed on the server side of kgssd.
520Sstevel@tonic-gate * gss_log & 8 will cause informational messages to be
530Sstevel@tonic-gate * printed on both client and server side of kgssd.
540Sstevel@tonic-gate */
550Sstevel@tonic-gate
560Sstevel@tonic-gate uint_t gss_log = 1;
570Sstevel@tonic-gate
580Sstevel@tonic-gate #endif /* GSSDEBUG */
590Sstevel@tonic-gate
600Sstevel@tonic-gate #ifdef DEBUG
610Sstevel@tonic-gate extern void prom_printf();
620Sstevel@tonic-gate #endif
630Sstevel@tonic-gate
640Sstevel@tonic-gate char *server = "localhost";
650Sstevel@tonic-gate
660Sstevel@tonic-gate static OM_uint32 kgss_sign_wrapped(void *, OM_uint32 *, gss_ctx_id_t, int,
670Sstevel@tonic-gate gss_buffer_t, gss_buffer_t, OM_uint32);
680Sstevel@tonic-gate
690Sstevel@tonic-gate static OM_uint32 kgss_verify_wrapped(void *, OM_uint32 *, gss_ctx_id_t,
700Sstevel@tonic-gate gss_buffer_t, gss_buffer_t, int *qop_state, OM_uint32);
710Sstevel@tonic-gate
720Sstevel@tonic-gate /* EXPORT DELETE START */
730Sstevel@tonic-gate static OM_uint32 kgss_seal_wrapped(void *, OM_uint32 *, gss_ctx_id_t,
740Sstevel@tonic-gate int, int, gss_buffer_t, int *, gss_buffer_t, OM_uint32);
750Sstevel@tonic-gate
760Sstevel@tonic-gate static OM_uint32 kgss_unseal_wrapped(void *, OM_uint32 *, gss_ctx_id_t,
770Sstevel@tonic-gate gss_buffer_t, gss_buffer_t, int *conf_state, int *qop_state,
780Sstevel@tonic-gate OM_uint32);
790Sstevel@tonic-gate /* EXPORT DELETE END */
800Sstevel@tonic-gate
810Sstevel@tonic-gate static OM_uint32 kgss_delete_sec_context_wrapped(void *, OM_uint32 *,
820Sstevel@tonic-gate gssd_ctx_id_t *, gss_buffer_t, OM_uint32);
830Sstevel@tonic-gate
840Sstevel@tonic-gate static void __kgss_reset_mech(gss_mechanism *, gss_OID);
850Sstevel@tonic-gate
860Sstevel@tonic-gate #define DEFAULT_MINOR_STAT ((OM_uint32) ~0)
870Sstevel@tonic-gate
880Sstevel@tonic-gate 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)890Sstevel@tonic-gate kgss_acquire_cred_wrapped(minor_status,
900Sstevel@tonic-gate desired_name,
910Sstevel@tonic-gate time_req,
920Sstevel@tonic-gate desired_mechs,
930Sstevel@tonic-gate cred_usage,
940Sstevel@tonic-gate output_cred_handle,
950Sstevel@tonic-gate actual_mechs,
960Sstevel@tonic-gate time_rec,
970Sstevel@tonic-gate uid,
980Sstevel@tonic-gate gssd_cred_verifier)
990Sstevel@tonic-gate OM_uint32 *minor_status;
1000Sstevel@tonic-gate const gss_name_t desired_name;
1010Sstevel@tonic-gate OM_uint32 time_req;
1020Sstevel@tonic-gate const gss_OID_set desired_mechs;
1030Sstevel@tonic-gate int cred_usage;
1040Sstevel@tonic-gate gssd_cred_id_t *output_cred_handle;
1050Sstevel@tonic-gate gss_OID_set *actual_mechs;
1060Sstevel@tonic-gate OM_uint32 *time_rec;
1070Sstevel@tonic-gate uid_t uid;
1080Sstevel@tonic-gate OM_uint32 *gssd_cred_verifier;
1090Sstevel@tonic-gate {
1100Sstevel@tonic-gate CLIENT *clnt;
1110Sstevel@tonic-gate
1120Sstevel@tonic-gate OM_uint32 minor_status_temp;
1130Sstevel@tonic-gate gss_buffer_desc external_name;
1140Sstevel@tonic-gate gss_OID name_type;
1150Sstevel@tonic-gate enum clnt_stat client_stat;
1160Sstevel@tonic-gate int i;
1170Sstevel@tonic-gate
1180Sstevel@tonic-gate gss_acquire_cred_arg arg;
1190Sstevel@tonic-gate gss_acquire_cred_res res;
1200Sstevel@tonic-gate
1210Sstevel@tonic-gate /* get the client handle to GSSD */
1220Sstevel@tonic-gate
1230Sstevel@tonic-gate if ((clnt = getgssd_handle()) == NULL) {
1240Sstevel@tonic-gate GSSLOG(1, "kgss_acquire_cred: can't connect to server on %s\n",
1250Sstevel@tonic-gate server);
1260Sstevel@tonic-gate return (GSS_S_FAILURE);
1270Sstevel@tonic-gate }
1280Sstevel@tonic-gate
1290Sstevel@tonic-gate /* convert the desired name from internal to external format */
1300Sstevel@tonic-gate
1310Sstevel@tonic-gate if (gss_display_name(&minor_status_temp, desired_name, &external_name,
1320Sstevel@tonic-gate &name_type) != GSS_S_COMPLETE) {
1330Sstevel@tonic-gate
1340Sstevel@tonic-gate *minor_status = (OM_uint32) minor_status_temp;
1350Sstevel@tonic-gate killgssd_handle(clnt);
1360Sstevel@tonic-gate GSSLOG0(1, "kgss_acquire_cred: display name failed\n");
1370Sstevel@tonic-gate return ((OM_uint32) GSS_S_FAILURE);
1380Sstevel@tonic-gate }
1390Sstevel@tonic-gate
1400Sstevel@tonic-gate
1410Sstevel@tonic-gate /* copy the procedure arguments into the rpc arg parameter */
1420Sstevel@tonic-gate
1430Sstevel@tonic-gate arg.uid = (OM_uint32) uid;
1440Sstevel@tonic-gate
1450Sstevel@tonic-gate arg.desired_name.GSS_BUFFER_T_len = (uint_t)external_name.length;
1460Sstevel@tonic-gate arg.desired_name.GSS_BUFFER_T_val = (char *)external_name.value;
1470Sstevel@tonic-gate
1480Sstevel@tonic-gate arg.name_type.GSS_OID_len =
1490Sstevel@tonic-gate name_type == GSS_C_NULL_OID ?
1500Sstevel@tonic-gate 0 : (uint_t)name_type->length;
1510Sstevel@tonic-gate
1520Sstevel@tonic-gate arg.name_type.GSS_OID_val =
1530Sstevel@tonic-gate name_type == GSS_C_NULL_OID ?
1540Sstevel@tonic-gate (char *)NULL : (char *)name_type->elements;
1550Sstevel@tonic-gate
1560Sstevel@tonic-gate arg.time_req = time_req;
1570Sstevel@tonic-gate
1580Sstevel@tonic-gate if (desired_mechs != GSS_C_NULL_OID_SET) {
1590Sstevel@tonic-gate arg.desired_mechs.GSS_OID_SET_len =
1600Sstevel@tonic-gate (uint_t)desired_mechs->count;
1610Sstevel@tonic-gate arg.desired_mechs.GSS_OID_SET_val = (GSS_OID *)
1620Sstevel@tonic-gate MALLOC(sizeof (GSS_OID) * desired_mechs->count);
1630Sstevel@tonic-gate
1640Sstevel@tonic-gate for (i = 0; i < desired_mechs->count; i++) {
1650Sstevel@tonic-gate arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_len =
1660Sstevel@tonic-gate (uint_t)desired_mechs->elements[i].length;
1670Sstevel@tonic-gate arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_val =
1680Sstevel@tonic-gate (char *)MALLOC(desired_mechs->elements[i].length);
1690Sstevel@tonic-gate (void) memcpy(
1700Sstevel@tonic-gate arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_val,
1710Sstevel@tonic-gate desired_mechs->elements[i].elements,
1720Sstevel@tonic-gate desired_mechs->elements[i].length);
1730Sstevel@tonic-gate }
1740Sstevel@tonic-gate } else
1750Sstevel@tonic-gate arg.desired_mechs.GSS_OID_SET_len = 0;
1760Sstevel@tonic-gate
1770Sstevel@tonic-gate arg.cred_usage = cred_usage;
1780Sstevel@tonic-gate
1790Sstevel@tonic-gate /* call the remote procedure */
1800Sstevel@tonic-gate
1810Sstevel@tonic-gate bzero((caddr_t)&res, sizeof (res));
1820Sstevel@tonic-gate client_stat = gss_acquire_cred_1(&arg, &res, clnt);
1830Sstevel@tonic-gate
1840Sstevel@tonic-gate (void) gss_release_buffer(&minor_status_temp, &external_name);
1850Sstevel@tonic-gate if (desired_mechs != GSS_C_NULL_OID_SET) {
1860Sstevel@tonic-gate for (i = 0; i < desired_mechs->count; i++)
1870Sstevel@tonic-gate FREE(arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_val,
1880Sstevel@tonic-gate arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_len);
1890Sstevel@tonic-gate FREE(arg.desired_mechs.GSS_OID_SET_val,
1900Sstevel@tonic-gate arg.desired_mechs.GSS_OID_SET_len * sizeof (GSS_OID));
1910Sstevel@tonic-gate }
1920Sstevel@tonic-gate
1930Sstevel@tonic-gate if (client_stat != RPC_SUCCESS) {
1940Sstevel@tonic-gate
1950Sstevel@tonic-gate /*
1960Sstevel@tonic-gate * if the RPC call times out, null out all return arguments,
1970Sstevel@tonic-gate * set minor_status to its maximum value, and return
1980Sstevel@tonic-gate * GSS_S_FAILURE
1990Sstevel@tonic-gate */
2000Sstevel@tonic-gate
2010Sstevel@tonic-gate if (minor_status != NULL)
2020Sstevel@tonic-gate *minor_status = DEFAULT_MINOR_STAT;
2030Sstevel@tonic-gate if (output_cred_handle != NULL)
2040Sstevel@tonic-gate *output_cred_handle = NULL;
2050Sstevel@tonic-gate if (actual_mechs != NULL)
2060Sstevel@tonic-gate *actual_mechs = NULL;
2070Sstevel@tonic-gate if (time_rec != NULL)
2080Sstevel@tonic-gate *time_rec = 0;
2090Sstevel@tonic-gate
2100Sstevel@tonic-gate killgssd_handle(clnt);
2110Sstevel@tonic-gate GSSLOG0(1, "kgss_acquire_cred: RPC call times out\n");
2120Sstevel@tonic-gate return (GSS_S_FAILURE);
2130Sstevel@tonic-gate }
2140Sstevel@tonic-gate
2150Sstevel@tonic-gate /* copy the rpc results into the return arguments */
2160Sstevel@tonic-gate
2170Sstevel@tonic-gate if (minor_status != NULL)
2180Sstevel@tonic-gate *minor_status = res.minor_status;
2190Sstevel@tonic-gate
2200Sstevel@tonic-gate if (output_cred_handle != NULL &&
2210Sstevel@tonic-gate (res.status == GSS_S_COMPLETE)) {
2220Sstevel@tonic-gate *output_cred_handle =
2230Sstevel@tonic-gate *((gssd_cred_id_t *)res.output_cred_handle.GSS_CRED_ID_T_val);
2240Sstevel@tonic-gate *gssd_cred_verifier = res.gssd_cred_verifier;
2250Sstevel@tonic-gate }
2260Sstevel@tonic-gate
2270Sstevel@tonic-gate if (res.status == GSS_S_COMPLETE &&
2280Sstevel@tonic-gate res.actual_mechs.GSS_OID_SET_len != 0 &&
2290Sstevel@tonic-gate actual_mechs != NULL) {
2300Sstevel@tonic-gate *actual_mechs = (gss_OID_set) MALLOC(sizeof (gss_OID_set_desc));
2310Sstevel@tonic-gate (*actual_mechs)->count =
2320Sstevel@tonic-gate (int)res.actual_mechs.GSS_OID_SET_len;
2330Sstevel@tonic-gate (*actual_mechs)->elements = (gss_OID)
2340Sstevel@tonic-gate MALLOC(sizeof (gss_OID_desc) * (*actual_mechs)->count);
2350Sstevel@tonic-gate
2360Sstevel@tonic-gate for (i = 0; i < (*actual_mechs)->count; i++) {
2370Sstevel@tonic-gate (*actual_mechs)->elements[i].length = (OM_uint32)
2380Sstevel@tonic-gate res.actual_mechs.GSS_OID_SET_val[i].GSS_OID_len;
2390Sstevel@tonic-gate (*actual_mechs)->elements[i].elements =
2400Sstevel@tonic-gate (void *) MALLOC((*actual_mechs)->elements[i].length);
2410Sstevel@tonic-gate (void) memcpy((*actual_mechs)->elements[i].elements,
2420Sstevel@tonic-gate res.actual_mechs.GSS_OID_SET_val[i].GSS_OID_val,
2430Sstevel@tonic-gate (*actual_mechs)->elements[i].length);
2440Sstevel@tonic-gate }
2450Sstevel@tonic-gate } else {
2460Sstevel@tonic-gate if (res.status == GSS_S_COMPLETE &&
2470Sstevel@tonic-gate actual_mechs != NULL)
2480Sstevel@tonic-gate (*actual_mechs) = NULL;
2490Sstevel@tonic-gate }
2500Sstevel@tonic-gate
2510Sstevel@tonic-gate if (time_rec != NULL)
2520Sstevel@tonic-gate *time_rec = res.time_rec;
2530Sstevel@tonic-gate
2540Sstevel@tonic-gate /*
2550Sstevel@tonic-gate * free the memory allocated for the results and return with the status
2560Sstevel@tonic-gate * received in the rpc call
2570Sstevel@tonic-gate */
2580Sstevel@tonic-gate
2590Sstevel@tonic-gate clnt_freeres(clnt, xdr_gss_acquire_cred_res, (caddr_t)&res);
2600Sstevel@tonic-gate killgssd_handle(clnt);
2610Sstevel@tonic-gate return (res.status);
2620Sstevel@tonic-gate
2630Sstevel@tonic-gate }
2640Sstevel@tonic-gate
2650Sstevel@tonic-gate OM_uint32
kgss_acquire_cred(minor_status,desired_name,time_req,desired_mechs,cred_usage,output_cred_handle,actual_mechs,time_rec,uid)2660Sstevel@tonic-gate kgss_acquire_cred(minor_status,
2670Sstevel@tonic-gate desired_name,
2680Sstevel@tonic-gate time_req,
2690Sstevel@tonic-gate desired_mechs,
2700Sstevel@tonic-gate cred_usage,
2710Sstevel@tonic-gate output_cred_handle,
2720Sstevel@tonic-gate actual_mechs,
2730Sstevel@tonic-gate time_rec,
2740Sstevel@tonic-gate uid)
2750Sstevel@tonic-gate OM_uint32 *minor_status;
2760Sstevel@tonic-gate const gss_name_t desired_name;
2770Sstevel@tonic-gate OM_uint32 time_req;
2780Sstevel@tonic-gate const gss_OID_set desired_mechs;
2790Sstevel@tonic-gate int cred_usage;
2800Sstevel@tonic-gate gss_cred_id_t *output_cred_handle;
2810Sstevel@tonic-gate gss_OID_set *actual_mechs;
2820Sstevel@tonic-gate OM_uint32 *time_rec;
2830Sstevel@tonic-gate uid_t uid;
2840Sstevel@tonic-gate {
2850Sstevel@tonic-gate
2860Sstevel@tonic-gate OM_uint32 err;
2870Sstevel@tonic-gate struct kgss_cred *kcred;
2880Sstevel@tonic-gate
2890Sstevel@tonic-gate kcred = KGSS_CRED_ALLOC();
2900Sstevel@tonic-gate *output_cred_handle = (gss_cred_id_t)kcred;
2910Sstevel@tonic-gate err = kgss_acquire_cred_wrapped(minor_status, desired_name, time_req,
2920Sstevel@tonic-gate desired_mechs, cred_usage, &kcred->gssd_cred, actual_mechs,
2930Sstevel@tonic-gate time_rec, uid, &kcred->gssd_cred_verifier);
2940Sstevel@tonic-gate if (GSS_ERROR(err)) {
2950Sstevel@tonic-gate KGSS_CRED_FREE(kcred);
2960Sstevel@tonic-gate *output_cred_handle = GSS_C_NO_CREDENTIAL;
2970Sstevel@tonic-gate }
2980Sstevel@tonic-gate return (err);
2990Sstevel@tonic-gate }
3000Sstevel@tonic-gate
3010Sstevel@tonic-gate 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)3020Sstevel@tonic-gate kgss_add_cred_wrapped(minor_status,
3030Sstevel@tonic-gate input_cred_handle,
3040Sstevel@tonic-gate gssd_cred_verifier,
3050Sstevel@tonic-gate desired_name,
3060Sstevel@tonic-gate desired_mech_type,
3070Sstevel@tonic-gate cred_usage,
3080Sstevel@tonic-gate initiator_time_req,
3090Sstevel@tonic-gate acceptor_time_req,
3100Sstevel@tonic-gate actual_mechs,
3110Sstevel@tonic-gate initiator_time_rec,
3120Sstevel@tonic-gate acceptor_time_rec,
3130Sstevel@tonic-gate uid)
3140Sstevel@tonic-gate OM_uint32 *minor_status;
3150Sstevel@tonic-gate gssd_cred_id_t input_cred_handle;
3160Sstevel@tonic-gate OM_uint32 gssd_cred_verifier;
3170Sstevel@tonic-gate gss_name_t desired_name;
3180Sstevel@tonic-gate gss_OID desired_mech_type;
3190Sstevel@tonic-gate int cred_usage;
3200Sstevel@tonic-gate int initiator_time_req;
3210Sstevel@tonic-gate int acceptor_time_req;
3220Sstevel@tonic-gate gss_OID_set *actual_mechs;
3230Sstevel@tonic-gate OM_uint32 *initiator_time_rec;
3240Sstevel@tonic-gate OM_uint32 *acceptor_time_rec;
3250Sstevel@tonic-gate uid_t uid;
3260Sstevel@tonic-gate {
3270Sstevel@tonic-gate CLIENT *clnt;
3280Sstevel@tonic-gate
3290Sstevel@tonic-gate OM_uint32 minor_status_temp;
3300Sstevel@tonic-gate gss_buffer_desc external_name;
3310Sstevel@tonic-gate gss_OID name_type;
3320Sstevel@tonic-gate int i;
3330Sstevel@tonic-gate
3340Sstevel@tonic-gate gss_add_cred_arg arg;
3350Sstevel@tonic-gate gss_add_cred_res res;
3360Sstevel@tonic-gate
3370Sstevel@tonic-gate
3380Sstevel@tonic-gate /*
3390Sstevel@tonic-gate * NULL the params here once
3400Sstevel@tonic-gate * If there are errors then we won't
3410Sstevel@tonic-gate * have to do it for every error
3420Sstevel@tonic-gate * case
3430Sstevel@tonic-gate */
3440Sstevel@tonic-gate
3450Sstevel@tonic-gate if (minor_status != NULL)
3460Sstevel@tonic-gate *minor_status = DEFAULT_MINOR_STAT;
3470Sstevel@tonic-gate if (actual_mechs != NULL)
3480Sstevel@tonic-gate *actual_mechs = NULL;
3490Sstevel@tonic-gate if (initiator_time_rec != NULL)
3500Sstevel@tonic-gate *initiator_time_rec = 0;
3510Sstevel@tonic-gate if (acceptor_time_rec != NULL)
3520Sstevel@tonic-gate *acceptor_time_rec = 0;
3530Sstevel@tonic-gate /* get the client handle to GSSD */
3540Sstevel@tonic-gate
3550Sstevel@tonic-gate if ((clnt = getgssd_handle()) == NULL) {
3560Sstevel@tonic-gate GSSLOG(1, "kgss_add_cred: can't connect to server on %s\n",
3570Sstevel@tonic-gate server);
3580Sstevel@tonic-gate return (GSS_S_FAILURE);
3590Sstevel@tonic-gate }
3600Sstevel@tonic-gate
3610Sstevel@tonic-gate
3620Sstevel@tonic-gate /* convert the desired name from internal to external format */
3630Sstevel@tonic-gate
3640Sstevel@tonic-gate if (gss_display_name(&minor_status_temp, desired_name, &external_name,
3650Sstevel@tonic-gate &name_type) != GSS_S_COMPLETE) {
3660Sstevel@tonic-gate
3670Sstevel@tonic-gate *minor_status = (OM_uint32) minor_status_temp;
3680Sstevel@tonic-gate killgssd_handle(clnt);
3690Sstevel@tonic-gate GSSLOG0(1, "kgss_acquire_cred: display name failed\n");
3700Sstevel@tonic-gate return ((OM_uint32) GSS_S_FAILURE);
3710Sstevel@tonic-gate }
3720Sstevel@tonic-gate
3730Sstevel@tonic-gate
3740Sstevel@tonic-gate /* copy the procedure arguments into the rpc arg parameter */
3750Sstevel@tonic-gate
3760Sstevel@tonic-gate arg.uid = (OM_uint32)uid;
3770Sstevel@tonic-gate arg.input_cred_handle.GSS_CRED_ID_T_len =
3780Sstevel@tonic-gate input_cred_handle ==
3790Sstevel@tonic-gate (gssd_cred_id_t)GSS_C_NO_CREDENTIAL ?
3800Sstevel@tonic-gate 0 : (uint_t)sizeof (gssd_cred_id_t);
3810Sstevel@tonic-gate arg.input_cred_handle.GSS_CRED_ID_T_val = (char *)&input_cred_handle;
3820Sstevel@tonic-gate arg.gssd_cred_verifier = gssd_cred_verifier;
3830Sstevel@tonic-gate arg.desired_name.GSS_BUFFER_T_len = (uint_t)external_name.length;
3840Sstevel@tonic-gate arg.desired_name.GSS_BUFFER_T_val = (char *)external_name.value;
3850Sstevel@tonic-gate arg.name_type.GSS_OID_len =
3860Sstevel@tonic-gate name_type == GSS_C_NULL_OID ?
3870Sstevel@tonic-gate 0 : (uint_t)name_type->length;
3880Sstevel@tonic-gate arg.name_type.GSS_OID_val =
3890Sstevel@tonic-gate name_type == GSS_C_NULL_OID ?
3900Sstevel@tonic-gate (char *)NULL : (char *)name_type->elements;
3910Sstevel@tonic-gate
3920Sstevel@tonic-gate arg.desired_mech_type.GSS_OID_len =
3930Sstevel@tonic-gate (uint_t)(desired_mech_type != GSS_C_NULL_OID ?
3940Sstevel@tonic-gate desired_mech_type->length : 0);
3950Sstevel@tonic-gate arg.desired_mech_type.GSS_OID_val =
3960Sstevel@tonic-gate (char *)(desired_mech_type != GSS_C_NULL_OID ?
3970Sstevel@tonic-gate desired_mech_type->elements : 0);
3980Sstevel@tonic-gate arg.cred_usage = cred_usage;
3990Sstevel@tonic-gate arg.initiator_time_req = initiator_time_req;
4000Sstevel@tonic-gate arg.acceptor_time_req = acceptor_time_req;
4010Sstevel@tonic-gate
4020Sstevel@tonic-gate /* call the remote procedure */
4030Sstevel@tonic-gate
4040Sstevel@tonic-gate bzero((caddr_t)&res, sizeof (res));
4050Sstevel@tonic-gate if (gss_add_cred_1(&arg, &res, clnt) != RPC_SUCCESS) {
4060Sstevel@tonic-gate
4070Sstevel@tonic-gate /*
4080Sstevel@tonic-gate * if the RPC call times out, null out all return arguments,
4090Sstevel@tonic-gate * set minor_status to its maximum value, and return
4100Sstevel@tonic-gate * GSS_S_FAILURE
4110Sstevel@tonic-gate */
4120Sstevel@tonic-gate
4130Sstevel@tonic-gate killgssd_handle(clnt);
4140Sstevel@tonic-gate (void) gss_release_buffer(&minor_status_temp, &external_name);
4150Sstevel@tonic-gate GSSLOG0(1, "kgss_add_cred: RPC call times out\n");
4160Sstevel@tonic-gate return (GSS_S_FAILURE);
4170Sstevel@tonic-gate }
4180Sstevel@tonic-gate
4190Sstevel@tonic-gate /* free the allocated memory for the flattened name */
4200Sstevel@tonic-gate
4210Sstevel@tonic-gate (void) gss_release_buffer(&minor_status_temp, &external_name);
4220Sstevel@tonic-gate
4230Sstevel@tonic-gate /* copy the rpc results into the return arguments */
4240Sstevel@tonic-gate
4250Sstevel@tonic-gate if (minor_status != NULL)
4260Sstevel@tonic-gate *minor_status = res.minor_status;
4270Sstevel@tonic-gate
4280Sstevel@tonic-gate if (res.status == GSS_S_COMPLETE &&
4290Sstevel@tonic-gate res.actual_mechs.GSS_OID_SET_len != 0 &&
4300Sstevel@tonic-gate actual_mechs != NULL) {
4310Sstevel@tonic-gate *actual_mechs = (gss_OID_set) MALLOC(sizeof (gss_OID_set_desc));
4320Sstevel@tonic-gate (*actual_mechs)->count =
4330Sstevel@tonic-gate (int)res.actual_mechs.GSS_OID_SET_len;
4340Sstevel@tonic-gate (*actual_mechs)->elements = (gss_OID)
4350Sstevel@tonic-gate MALLOC(sizeof (gss_OID_desc) * (*actual_mechs)->count);
4360Sstevel@tonic-gate
4370Sstevel@tonic-gate for (i = 0; i < (*actual_mechs)->count; i++) {
4380Sstevel@tonic-gate (*actual_mechs)->elements[i].length = (OM_uint32)
4390Sstevel@tonic-gate res.actual_mechs.GSS_OID_SET_val[i].GSS_OID_len;
4400Sstevel@tonic-gate (*actual_mechs)->elements[i].elements =
4410Sstevel@tonic-gate (void *) MALLOC((*actual_mechs)->elements[i].length);
4420Sstevel@tonic-gate (void) memcpy((*actual_mechs)->elements[i].elements,
4430Sstevel@tonic-gate res.actual_mechs.GSS_OID_SET_val[i].GSS_OID_val,
4440Sstevel@tonic-gate (*actual_mechs)->elements[i].length);
4450Sstevel@tonic-gate }
4460Sstevel@tonic-gate } else {
4470Sstevel@tonic-gate if (res.status == GSS_S_COMPLETE && actual_mechs != NULL)
4480Sstevel@tonic-gate (*actual_mechs) = NULL;
4490Sstevel@tonic-gate }
4500Sstevel@tonic-gate if (initiator_time_rec != NULL)
4510Sstevel@tonic-gate *initiator_time_rec = res.acceptor_time_rec;
4520Sstevel@tonic-gate if (acceptor_time_rec != NULL)
4530Sstevel@tonic-gate *acceptor_time_rec = res.acceptor_time_rec;
4540Sstevel@tonic-gate
4550Sstevel@tonic-gate /*
4560Sstevel@tonic-gate * free the memory allocated for the results and return with the status
4570Sstevel@tonic-gate * received in the rpc call
4580Sstevel@tonic-gate */
4590Sstevel@tonic-gate
4600Sstevel@tonic-gate clnt_freeres(clnt, xdr_gss_add_cred_res, (caddr_t)&res);
4610Sstevel@tonic-gate killgssd_handle(clnt);
4620Sstevel@tonic-gate return (res.status);
4630Sstevel@tonic-gate
4640Sstevel@tonic-gate }
4650Sstevel@tonic-gate
4660Sstevel@tonic-gate 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)4670Sstevel@tonic-gate kgss_add_cred(minor_status,
4680Sstevel@tonic-gate input_cred_handle,
4690Sstevel@tonic-gate desired_name,
4700Sstevel@tonic-gate desired_mech_type,
4710Sstevel@tonic-gate cred_usage,
4720Sstevel@tonic-gate initiator_time_req,
4730Sstevel@tonic-gate acceptor_time_req,
4740Sstevel@tonic-gate actual_mechs,
4750Sstevel@tonic-gate initiator_time_rec,
4760Sstevel@tonic-gate acceptor_time_rec,
4770Sstevel@tonic-gate uid)
4780Sstevel@tonic-gate OM_uint32 *minor_status;
4790Sstevel@tonic-gate gss_cred_id_t input_cred_handle;
4800Sstevel@tonic-gate gss_name_t desired_name;
4810Sstevel@tonic-gate gss_OID desired_mech_type;
4820Sstevel@tonic-gate int cred_usage;
4830Sstevel@tonic-gate int initiator_time_req;
4840Sstevel@tonic-gate int acceptor_time_req;
4850Sstevel@tonic-gate gss_OID_set *actual_mechs;
4860Sstevel@tonic-gate OM_uint32 *initiator_time_rec;
4870Sstevel@tonic-gate OM_uint32 *acceptor_time_rec;
4880Sstevel@tonic-gate uid_t uid;
4890Sstevel@tonic-gate {
4900Sstevel@tonic-gate
4910Sstevel@tonic-gate OM_uint32 err;
4920Sstevel@tonic-gate OM_uint32 gssd_cred_verifier;
4930Sstevel@tonic-gate gssd_cred_id_t gssd_input_cred_handle;
4940Sstevel@tonic-gate
4950Sstevel@tonic-gate if (input_cred_handle != GSS_C_NO_CREDENTIAL) {
4960Sstevel@tonic-gate gssd_cred_verifier = KCRED_TO_CREDV(input_cred_handle);
4970Sstevel@tonic-gate gssd_input_cred_handle = KCRED_TO_CRED(input_cred_handle);
4980Sstevel@tonic-gate } else
4990Sstevel@tonic-gate gssd_input_cred_handle = (gssd_cred_id_t)GSS_C_NO_CREDENTIAL;
5000Sstevel@tonic-gate
5010Sstevel@tonic-gate err = kgss_add_cred_wrapped(minor_status, gssd_input_cred_handle,
5020Sstevel@tonic-gate gssd_cred_verifier, desired_name, desired_mech_type,
5030Sstevel@tonic-gate cred_usage, initiator_time_req, acceptor_time_req,
5040Sstevel@tonic-gate actual_mechs, initiator_time_rec,
5050Sstevel@tonic-gate acceptor_time_rec, uid);
5060Sstevel@tonic-gate return (err);
5070Sstevel@tonic-gate }
5080Sstevel@tonic-gate
5090Sstevel@tonic-gate
5100Sstevel@tonic-gate OM_uint32
kgss_release_cred_wrapped(minor_status,cred_handle,uid,gssd_cred_verifier)5110Sstevel@tonic-gate kgss_release_cred_wrapped(minor_status,
5120Sstevel@tonic-gate cred_handle,
5130Sstevel@tonic-gate uid,
5140Sstevel@tonic-gate gssd_cred_verifier)
5150Sstevel@tonic-gate OM_uint32 *minor_status;
5160Sstevel@tonic-gate gssd_cred_id_t *cred_handle;
5170Sstevel@tonic-gate uid_t uid;
5180Sstevel@tonic-gate OM_uint32 gssd_cred_verifier;
5190Sstevel@tonic-gate {
5200Sstevel@tonic-gate CLIENT *clnt;
5210Sstevel@tonic-gate
5220Sstevel@tonic-gate gss_release_cred_arg arg;
5230Sstevel@tonic-gate gss_release_cred_res res;
5240Sstevel@tonic-gate
5250Sstevel@tonic-gate
5260Sstevel@tonic-gate /* get the client handle to GSSD */
5270Sstevel@tonic-gate
5280Sstevel@tonic-gate if ((clnt = getgssd_handle()) == NULL) {
5290Sstevel@tonic-gate GSSLOG(1, "kgss_release_cred: can't connect to server on %s\n",
5300Sstevel@tonic-gate server);
5310Sstevel@tonic-gate return (GSS_S_FAILURE);
5320Sstevel@tonic-gate }
5330Sstevel@tonic-gate
5340Sstevel@tonic-gate /* copy the procedure arguments into the rpc arg parameter */
5350Sstevel@tonic-gate
5360Sstevel@tonic-gate arg.uid = (OM_uint32)uid;
5370Sstevel@tonic-gate arg.gssd_cred_verifier = gssd_cred_verifier;
5380Sstevel@tonic-gate
5390Sstevel@tonic-gate if (cred_handle != NULL) {
5400Sstevel@tonic-gate arg.cred_handle.GSS_CRED_ID_T_len =
5410Sstevel@tonic-gate (uint_t)sizeof (gssd_cred_id_t);
5420Sstevel@tonic-gate arg.cred_handle.GSS_CRED_ID_T_val = (char *)cred_handle;
5430Sstevel@tonic-gate } else
5440Sstevel@tonic-gate arg.cred_handle.GSS_CRED_ID_T_len = 0;
5450Sstevel@tonic-gate
5460Sstevel@tonic-gate /* call the remote procedure */
5470Sstevel@tonic-gate
5480Sstevel@tonic-gate bzero((caddr_t)&res, sizeof (res));
5490Sstevel@tonic-gate if (gss_release_cred_1(&arg, &res, clnt) != RPC_SUCCESS) {
5500Sstevel@tonic-gate
5510Sstevel@tonic-gate /*
5520Sstevel@tonic-gate * if the RPC call times out, null out all return arguments, set
5530Sstevel@tonic-gate * minor_status to its maximum value, and return GSS_S_FAILURE
5540Sstevel@tonic-gate */
5550Sstevel@tonic-gate
5560Sstevel@tonic-gate if (minor_status != NULL)
5570Sstevel@tonic-gate *minor_status = DEFAULT_MINOR_STAT;
5580Sstevel@tonic-gate if (cred_handle != NULL)
5590Sstevel@tonic-gate *cred_handle = NULL;
5600Sstevel@tonic-gate
5610Sstevel@tonic-gate killgssd_handle(clnt);
5620Sstevel@tonic-gate GSSLOG0(1, "kgss_release_cred: RPC call times out\n");
5630Sstevel@tonic-gate return (GSS_S_FAILURE);
5640Sstevel@tonic-gate }
5650Sstevel@tonic-gate
5660Sstevel@tonic-gate /* if the release succeeded, null out the cred_handle */
5670Sstevel@tonic-gate
5680Sstevel@tonic-gate if (res.status == GSS_S_COMPLETE && cred_handle != NULL)
5690Sstevel@tonic-gate *cred_handle = NULL;
5700Sstevel@tonic-gate
5710Sstevel@tonic-gate /* copy the rpc results into the return arguments */
5720Sstevel@tonic-gate
5730Sstevel@tonic-gate if (minor_status != NULL)
5740Sstevel@tonic-gate *minor_status = res.minor_status;
5750Sstevel@tonic-gate
5760Sstevel@tonic-gate /* return with status returned in rpc call */
5770Sstevel@tonic-gate
5780Sstevel@tonic-gate killgssd_handle(clnt);
5790Sstevel@tonic-gate
5800Sstevel@tonic-gate return (res.status);
5810Sstevel@tonic-gate
5820Sstevel@tonic-gate }
5830Sstevel@tonic-gate
5840Sstevel@tonic-gate OM_uint32
kgss_release_cred(minor_status,cred_handle,uid)5850Sstevel@tonic-gate kgss_release_cred(minor_status,
5860Sstevel@tonic-gate cred_handle,
5870Sstevel@tonic-gate uid)
5880Sstevel@tonic-gate OM_uint32 *minor_status;
5890Sstevel@tonic-gate gss_cred_id_t *cred_handle;
5900Sstevel@tonic-gate uid_t uid;
5910Sstevel@tonic-gate
5920Sstevel@tonic-gate {
5930Sstevel@tonic-gate
5940Sstevel@tonic-gate OM_uint32 err;
5950Sstevel@tonic-gate struct kgss_cred *kcred;
5960Sstevel@tonic-gate
5970Sstevel@tonic-gate if (*cred_handle == GSS_C_NO_CREDENTIAL)
5980Sstevel@tonic-gate return (GSS_S_COMPLETE);
5990Sstevel@tonic-gate else
6000Sstevel@tonic-gate kcred = KCRED_TO_KGSS_CRED(*cred_handle);
6010Sstevel@tonic-gate
6020Sstevel@tonic-gate err = kgss_release_cred_wrapped(minor_status, &kcred->gssd_cred,
6030Sstevel@tonic-gate uid, kcred->gssd_cred_verifier);
6040Sstevel@tonic-gate KGSS_CRED_FREE(kcred);
6050Sstevel@tonic-gate *cred_handle = GSS_C_NO_CREDENTIAL;
6060Sstevel@tonic-gate return (err);
6070Sstevel@tonic-gate }
6080Sstevel@tonic-gate
6090Sstevel@tonic-gate static OM_uint32
kgss_init_sec_context_wrapped(OM_uint32 * minor_status,const gssd_cred_id_t claimant_cred_handle,OM_uint32 gssd_cred_verifier,gssd_ctx_id_t * context_handle,OM_uint32 * gssd_context_verifier,const gss_name_t target_name,const gss_OID mech_type,int req_flags,OM_uint32 time_req,const gss_channel_bindings_t input_chan_bindings,const 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)6100Sstevel@tonic-gate kgss_init_sec_context_wrapped(
6110Sstevel@tonic-gate OM_uint32 *minor_status,
6120Sstevel@tonic-gate const gssd_cred_id_t claimant_cred_handle,
6130Sstevel@tonic-gate OM_uint32 gssd_cred_verifier,
6140Sstevel@tonic-gate gssd_ctx_id_t *context_handle,
6150Sstevel@tonic-gate OM_uint32 *gssd_context_verifier,
6160Sstevel@tonic-gate const gss_name_t target_name,
6170Sstevel@tonic-gate const gss_OID mech_type,
6180Sstevel@tonic-gate int req_flags,
6190Sstevel@tonic-gate OM_uint32 time_req,
6200Sstevel@tonic-gate const gss_channel_bindings_t input_chan_bindings,
6210Sstevel@tonic-gate const gss_buffer_t input_token,
6220Sstevel@tonic-gate gss_OID *actual_mech_type,
6230Sstevel@tonic-gate gss_buffer_t output_token,
6240Sstevel@tonic-gate int *ret_flags,
6250Sstevel@tonic-gate OM_uint32 *time_rec,
6260Sstevel@tonic-gate uid_t uid)
6270Sstevel@tonic-gate {
6280Sstevel@tonic-gate CLIENT *clnt;
6290Sstevel@tonic-gate
6300Sstevel@tonic-gate OM_uint32 minor_status_temp;
6310Sstevel@tonic-gate gss_buffer_desc external_name;
6320Sstevel@tonic-gate gss_OID name_type;
6330Sstevel@tonic-gate
6340Sstevel@tonic-gate gss_init_sec_context_arg arg;
6350Sstevel@tonic-gate gss_init_sec_context_res res;
6360Sstevel@tonic-gate
6370Sstevel@tonic-gate /* get the client handle to GSSD */
6380Sstevel@tonic-gate
6390Sstevel@tonic-gate if ((clnt = getgssd_handle()) == NULL) {
6400Sstevel@tonic-gate GSSLOG(1,
6410Sstevel@tonic-gate "kgss_init_sec_context: can't connect to server on %s\n",
6420Sstevel@tonic-gate server);
6430Sstevel@tonic-gate return (GSS_S_FAILURE);
6440Sstevel@tonic-gate }
6450Sstevel@tonic-gate
6460Sstevel@tonic-gate /* convert the target name from internal to external format */
6470Sstevel@tonic-gate
6480Sstevel@tonic-gate if (gss_display_name(&minor_status_temp, target_name,
6490Sstevel@tonic-gate &external_name, &name_type) != GSS_S_COMPLETE) {
6500Sstevel@tonic-gate
6510Sstevel@tonic-gate *minor_status = (OM_uint32) minor_status_temp;
6520Sstevel@tonic-gate killgssd_handle(clnt);
6530Sstevel@tonic-gate GSSLOG0(1, "kgss_init_sec_context: can't display name\n");
6540Sstevel@tonic-gate return ((OM_uint32) GSS_S_FAILURE);
6550Sstevel@tonic-gate }
6560Sstevel@tonic-gate
6570Sstevel@tonic-gate
6580Sstevel@tonic-gate /* copy the procedure arguments into the rpc arg parameter */
6590Sstevel@tonic-gate
6600Sstevel@tonic-gate arg.uid = (OM_uint32)uid;
6610Sstevel@tonic-gate
6620Sstevel@tonic-gate arg.context_handle.GSS_CTX_ID_T_len =
6630Sstevel@tonic-gate *context_handle == (gssd_ctx_id_t)GSS_C_NO_CONTEXT ?
6640Sstevel@tonic-gate 0 : (uint_t)sizeof (gssd_ctx_id_t);
6650Sstevel@tonic-gate arg.context_handle.GSS_CTX_ID_T_val = (char *)context_handle;
6660Sstevel@tonic-gate
6670Sstevel@tonic-gate arg.gssd_context_verifier = *gssd_context_verifier;
6680Sstevel@tonic-gate
6690Sstevel@tonic-gate arg.claimant_cred_handle.GSS_CRED_ID_T_len =
6700Sstevel@tonic-gate claimant_cred_handle == (gssd_cred_id_t)GSS_C_NO_CREDENTIAL ?
6710Sstevel@tonic-gate 0 : (uint_t)sizeof (gssd_cred_id_t);
6720Sstevel@tonic-gate arg.claimant_cred_handle.GSS_CRED_ID_T_val =
6730Sstevel@tonic-gate (char *)&claimant_cred_handle;
6740Sstevel@tonic-gate arg.gssd_cred_verifier = gssd_cred_verifier;
6750Sstevel@tonic-gate
6760Sstevel@tonic-gate arg.target_name.GSS_BUFFER_T_len = (uint_t)external_name.length;
6770Sstevel@tonic-gate arg.target_name.GSS_BUFFER_T_val = (char *)external_name.value;
6780Sstevel@tonic-gate
6790Sstevel@tonic-gate arg.name_type.GSS_OID_len =
6800Sstevel@tonic-gate name_type == GSS_C_NULL_OID ?
6810Sstevel@tonic-gate 0 : (uint_t)name_type->length;
6820Sstevel@tonic-gate
6830Sstevel@tonic-gate arg.name_type.GSS_OID_val =
6840Sstevel@tonic-gate name_type == GSS_C_NULL_OID ?
6850Sstevel@tonic-gate (char *)NULL : (char *)name_type->elements;
6860Sstevel@tonic-gate
6870Sstevel@tonic-gate arg.mech_type.GSS_OID_len = (uint_t)(mech_type != GSS_C_NULL_OID ?
6880Sstevel@tonic-gate mech_type->length : 0);
6890Sstevel@tonic-gate arg.mech_type.GSS_OID_val = (char *)(mech_type != GSS_C_NULL_OID ?
6900Sstevel@tonic-gate mech_type->elements : 0);
6910Sstevel@tonic-gate
6920Sstevel@tonic-gate arg.req_flags = req_flags;
6930Sstevel@tonic-gate
6940Sstevel@tonic-gate arg.time_req = time_req;
6950Sstevel@tonic-gate
6960Sstevel@tonic-gate if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS) {
6970Sstevel@tonic-gate arg.input_chan_bindings.present = YES;
6980Sstevel@tonic-gate arg.input_chan_bindings.initiator_addrtype =
6990Sstevel@tonic-gate input_chan_bindings->initiator_addrtype;
7000Sstevel@tonic-gate arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_len =
7010Sstevel@tonic-gate (uint_t)input_chan_bindings->initiator_address.length;
7020Sstevel@tonic-gate arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_val =
7030Sstevel@tonic-gate (void *)input_chan_bindings->initiator_address.value;
7040Sstevel@tonic-gate arg.input_chan_bindings.acceptor_addrtype =
7050Sstevel@tonic-gate input_chan_bindings->acceptor_addrtype;
7060Sstevel@tonic-gate arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_len =
7070Sstevel@tonic-gate (uint_t)input_chan_bindings->acceptor_address.length;
7080Sstevel@tonic-gate arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_val =
7090Sstevel@tonic-gate (void *)input_chan_bindings->acceptor_address.value;
7100Sstevel@tonic-gate arg.input_chan_bindings.application_data.GSS_BUFFER_T_len =
7110Sstevel@tonic-gate (uint_t)input_chan_bindings->application_data.length;
7120Sstevel@tonic-gate arg.input_chan_bindings.application_data.GSS_BUFFER_T_val =
7130Sstevel@tonic-gate (void *)input_chan_bindings->application_data.value;
7140Sstevel@tonic-gate } else {
7150Sstevel@tonic-gate arg.input_chan_bindings.present = NO;
7160Sstevel@tonic-gate arg.input_chan_bindings.initiator_addrtype = 0;
7170Sstevel@tonic-gate arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_len = 0;
7180Sstevel@tonic-gate arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_val = 0;
7190Sstevel@tonic-gate arg.input_chan_bindings.acceptor_addrtype = 0;
7200Sstevel@tonic-gate arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_len = 0;
7210Sstevel@tonic-gate arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_val = 0;
7220Sstevel@tonic-gate arg.input_chan_bindings.application_data.GSS_BUFFER_T_len = 0;
7230Sstevel@tonic-gate arg.input_chan_bindings.application_data.GSS_BUFFER_T_val = 0;
7240Sstevel@tonic-gate }
7250Sstevel@tonic-gate
7260Sstevel@tonic-gate arg.input_token.GSS_BUFFER_T_len =
7270Sstevel@tonic-gate (uint_t)(input_token != GSS_C_NO_BUFFER ?
7280Sstevel@tonic-gate input_token->length : 0);
7290Sstevel@tonic-gate arg.input_token.GSS_BUFFER_T_val =
7300Sstevel@tonic-gate (char *)(input_token != GSS_C_NO_BUFFER ?
7310Sstevel@tonic-gate input_token->value : 0);
7320Sstevel@tonic-gate
7330Sstevel@tonic-gate /* call the remote procedure */
7340Sstevel@tonic-gate
7350Sstevel@tonic-gate bzero((caddr_t)&res, sizeof (res));
7360Sstevel@tonic-gate if (gss_init_sec_context_1(&arg, &res, clnt) != RPC_SUCCESS) {
7370Sstevel@tonic-gate
7380Sstevel@tonic-gate /*
7390Sstevel@tonic-gate * if the RPC call times out, null out all return arguments, set
7400Sstevel@tonic-gate * minor_status to its maximum value, and return GSS_S_FAILURE
7410Sstevel@tonic-gate */
7420Sstevel@tonic-gate
7430Sstevel@tonic-gate if (minor_status != NULL)
7440Sstevel@tonic-gate *minor_status = DEFAULT_MINOR_STAT;
7450Sstevel@tonic-gate if (actual_mech_type != NULL)
7460Sstevel@tonic-gate *actual_mech_type = NULL;
7470Sstevel@tonic-gate if (output_token != NULL)
7480Sstevel@tonic-gate output_token->length = 0;
7490Sstevel@tonic-gate if (ret_flags != NULL)
7500Sstevel@tonic-gate *ret_flags = 0;
7510Sstevel@tonic-gate if (time_rec != NULL)
7520Sstevel@tonic-gate *time_rec = 0;
7530Sstevel@tonic-gate
7540Sstevel@tonic-gate killgssd_handle(clnt);
7550Sstevel@tonic-gate (void) gss_release_buffer(&minor_status_temp, &external_name);
7560Sstevel@tonic-gate GSSLOG0(1, "kgss_init_sec_context: RPC call times out\n");
7570Sstevel@tonic-gate return (GSS_S_FAILURE);
7580Sstevel@tonic-gate }
7590Sstevel@tonic-gate
7600Sstevel@tonic-gate /* free the allocated memory for the flattened name */
7610Sstevel@tonic-gate
7620Sstevel@tonic-gate (void) gss_release_buffer(&minor_status_temp, &external_name);
7630Sstevel@tonic-gate
7640Sstevel@tonic-gate if (minor_status != NULL)
7650Sstevel@tonic-gate *minor_status = res.minor_status;
7660Sstevel@tonic-gate
767*10598SGlenn.Barry@Sun.COM if (output_token != NULL && res.output_token.GSS_BUFFER_T_val != NULL) {
768*10598SGlenn.Barry@Sun.COM output_token->length =
769*10598SGlenn.Barry@Sun.COM (size_t)res.output_token.GSS_BUFFER_T_len;
770*10598SGlenn.Barry@Sun.COM output_token->value =
771*10598SGlenn.Barry@Sun.COM (void *)MALLOC(output_token->length);
772*10598SGlenn.Barry@Sun.COM (void) memcpy(output_token->value,
773*10598SGlenn.Barry@Sun.COM res.output_token.GSS_BUFFER_T_val,
774*10598SGlenn.Barry@Sun.COM output_token->length);
775*10598SGlenn.Barry@Sun.COM }
776*10598SGlenn.Barry@Sun.COM
7770Sstevel@tonic-gate /* if the call was successful, copy out the results */
7780Sstevel@tonic-gate if (res.status == (OM_uint32) GSS_S_COMPLETE ||
7790Sstevel@tonic-gate res.status == (OM_uint32) GSS_S_CONTINUE_NEEDED) {
7800Sstevel@tonic-gate /*
7810Sstevel@tonic-gate * if the return code is GSS_S_CONTINUE_NEEDED
7820Sstevel@tonic-gate * ignore all return parameters except for
7830Sstevel@tonic-gate * status codes, output token and context handle.
7840Sstevel@tonic-gate */
7850Sstevel@tonic-gate *context_handle =
7860Sstevel@tonic-gate *((gssd_ctx_id_t *)
7870Sstevel@tonic-gate res.context_handle.GSS_CTX_ID_T_val);
7880Sstevel@tonic-gate *gssd_context_verifier = res.gssd_context_verifier;
7890Sstevel@tonic-gate
7900Sstevel@tonic-gate if (res.status == GSS_S_COMPLETE) {
7910Sstevel@tonic-gate if (actual_mech_type != NULL) {
7920Sstevel@tonic-gate *actual_mech_type =
7930Sstevel@tonic-gate (gss_OID) MALLOC(sizeof (gss_OID_desc));
7940Sstevel@tonic-gate (*actual_mech_type)->length =
7950Sstevel@tonic-gate (OM_UINT32)
7960Sstevel@tonic-gate res.actual_mech_type.GSS_OID_len;
7970Sstevel@tonic-gate (*actual_mech_type)->elements =
7980Sstevel@tonic-gate (void *)
7990Sstevel@tonic-gate MALLOC((*actual_mech_type)->length);
8000Sstevel@tonic-gate (void) memcpy((*actual_mech_type)->elements,
8010Sstevel@tonic-gate (void *)
8020Sstevel@tonic-gate res.actual_mech_type.GSS_OID_val,
8030Sstevel@tonic-gate (*actual_mech_type)->length);
8040Sstevel@tonic-gate }
8050Sstevel@tonic-gate
8060Sstevel@tonic-gate
8070Sstevel@tonic-gate if (ret_flags != NULL)
8080Sstevel@tonic-gate *ret_flags = res.ret_flags;
8090Sstevel@tonic-gate
8100Sstevel@tonic-gate if (time_rec != NULL)
8110Sstevel@tonic-gate *time_rec = res.time_rec;
8120Sstevel@tonic-gate }
8130Sstevel@tonic-gate }
8140Sstevel@tonic-gate
8150Sstevel@tonic-gate /*
8160Sstevel@tonic-gate * free the memory allocated for the results and return with the status
8170Sstevel@tonic-gate * received in the rpc call
8180Sstevel@tonic-gate */
8190Sstevel@tonic-gate
8200Sstevel@tonic-gate clnt_freeres(clnt, xdr_gss_init_sec_context_res, (caddr_t)&res);
8210Sstevel@tonic-gate killgssd_handle(clnt);
8220Sstevel@tonic-gate return (res.status);
8230Sstevel@tonic-gate
8240Sstevel@tonic-gate }
8250Sstevel@tonic-gate
8260Sstevel@tonic-gate static struct gss_config default_gc = {
8270Sstevel@tonic-gate { 0, NULL},
8280Sstevel@tonic-gate NULL,
8290Sstevel@tonic-gate NULL,
8300Sstevel@tonic-gate 0,
8310Sstevel@tonic-gate /* EXPORT DELETE START */ /* CRYPT DELETE START */
8320Sstevel@tonic-gate kgss_unseal_wrapped,
8330Sstevel@tonic-gate /* EXPORT DELETE END */ /* CRYPT DELETE END */
8340Sstevel@tonic-gate NULL, /* kgss_delete_sec_context_wrapped */
8350Sstevel@tonic-gate /* EXPORT DELETE START */ /* CRYPT DELETE START */
8360Sstevel@tonic-gate kgss_seal_wrapped,
8370Sstevel@tonic-gate /* EXPORT DELETE END */ /* CRYPT DELETE END */
8380Sstevel@tonic-gate NULL, /* kgss_import_sec_context */
8390Sstevel@tonic-gate /* EXPORT DELETE START */
8400Sstevel@tonic-gate /* CRYPT DELETE START */
8410Sstevel@tonic-gate #if 0
8420Sstevel@tonic-gate /* CRYPT DELETE END */
8430Sstevel@tonic-gate kgss_seal_wrapped,
8440Sstevel@tonic-gate kgss_unseal_wrapped,
8450Sstevel@tonic-gate /* CRYPT DELETE START */
8460Sstevel@tonic-gate #endif
8470Sstevel@tonic-gate /* CRYPT DELETE END */
8480Sstevel@tonic-gate /* EXPORT DELETE END */
8490Sstevel@tonic-gate kgss_sign_wrapped,
8500Sstevel@tonic-gate kgss_verify_wrapped
8510Sstevel@tonic-gate };
8520Sstevel@tonic-gate
8530Sstevel@tonic-gate void
kgss_free_oid(gss_OID oid)8540Sstevel@tonic-gate kgss_free_oid(gss_OID oid)
8550Sstevel@tonic-gate {
8560Sstevel@tonic-gate FREE(oid->elements, oid->length);
8570Sstevel@tonic-gate FREE(oid, sizeof (gss_OID_desc));
8580Sstevel@tonic-gate }
8590Sstevel@tonic-gate
8600Sstevel@tonic-gate OM_uint32
kgss_init_sec_context(OM_uint32 * minor_status,const gss_cred_id_t claimant_cred_handle,gss_ctx_id_t * context_handle,const gss_name_t target_name,const gss_OID mech_type,int req_flags,OM_uint32 time_req,const gss_channel_bindings_t input_chan_bindings,const 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)8610Sstevel@tonic-gate kgss_init_sec_context(
8620Sstevel@tonic-gate OM_uint32 *minor_status,
8630Sstevel@tonic-gate const gss_cred_id_t claimant_cred_handle,
8640Sstevel@tonic-gate gss_ctx_id_t *context_handle,
8650Sstevel@tonic-gate const gss_name_t target_name,
8660Sstevel@tonic-gate const gss_OID mech_type,
8670Sstevel@tonic-gate int req_flags,
8680Sstevel@tonic-gate OM_uint32 time_req,
8690Sstevel@tonic-gate const gss_channel_bindings_t input_chan_bindings,
8700Sstevel@tonic-gate const gss_buffer_t input_token,
8710Sstevel@tonic-gate gss_OID *actual_mech_type,
8720Sstevel@tonic-gate gss_buffer_t output_token,
8730Sstevel@tonic-gate int *ret_flags,
8740Sstevel@tonic-gate OM_uint32 *time_rec,
8750Sstevel@tonic-gate uid_t uid)
8760Sstevel@tonic-gate {
8770Sstevel@tonic-gate OM_uint32 err;
8780Sstevel@tonic-gate struct kgss_ctx *kctx;
8790Sstevel@tonic-gate gss_OID amt;
8800Sstevel@tonic-gate gssd_cred_id_t gssd_cl_cred_handle;
8810Sstevel@tonic-gate OM_uint32 gssd_cred_verifier;
8820Sstevel@tonic-gate
8830Sstevel@tonic-gate /*
8840Sstevel@tonic-gate * If this is an initial call, we'll need to create the
8850Sstevel@tonic-gate * wrapper struct that contains kernel state information, and
8860Sstevel@tonic-gate * a reference to the handle from gssd.
8870Sstevel@tonic-gate */
8880Sstevel@tonic-gate if (*context_handle == GSS_C_NO_CONTEXT) {
8890Sstevel@tonic-gate kctx = KGSS_ALLOC();
8900Sstevel@tonic-gate /*
8910Sstevel@tonic-gate * The default gss-mechanism struct as pointers to
8920Sstevel@tonic-gate * the sign/seal/verify/unseal routines that make
8930Sstevel@tonic-gate * upcalls to gssd.
8940Sstevel@tonic-gate */
8950Sstevel@tonic-gate kctx->mech = &default_gc;
8960Sstevel@tonic-gate kctx->gssd_ctx = (gssd_ctx_id_t)GSS_C_NO_CONTEXT;
8970Sstevel@tonic-gate *context_handle = (gss_ctx_id_t)kctx;
8980Sstevel@tonic-gate } else
8990Sstevel@tonic-gate kctx = (struct kgss_ctx *)*context_handle;
9000Sstevel@tonic-gate
9010Sstevel@tonic-gate if (claimant_cred_handle != GSS_C_NO_CREDENTIAL) {
9020Sstevel@tonic-gate gssd_cred_verifier = KCRED_TO_CREDV(claimant_cred_handle);
9030Sstevel@tonic-gate gssd_cl_cred_handle = KCRED_TO_CRED(claimant_cred_handle);
9040Sstevel@tonic-gate } else
9050Sstevel@tonic-gate gssd_cl_cred_handle = (gssd_cred_id_t)GSS_C_NO_CREDENTIAL;
9060Sstevel@tonic-gate
9070Sstevel@tonic-gate /*
9080Sstevel@tonic-gate * We need to know the resulting mechanism oid, so allocate
9090Sstevel@tonic-gate * it if the caller won't.
9100Sstevel@tonic-gate */
9110Sstevel@tonic-gate if (actual_mech_type == NULL)
9120Sstevel@tonic-gate actual_mech_type = &amt;
9130Sstevel@tonic-gate
9140Sstevel@tonic-gate err = kgss_init_sec_context_wrapped(minor_status, gssd_cl_cred_handle,
9150Sstevel@tonic-gate gssd_cred_verifier, &kctx->gssd_ctx, &kctx->gssd_ctx_verifier,
9160Sstevel@tonic-gate target_name, mech_type, req_flags, time_req,
9170Sstevel@tonic-gate input_chan_bindings, input_token, actual_mech_type,
9180Sstevel@tonic-gate output_token, ret_flags, time_rec, uid);
9190Sstevel@tonic-gate
9200Sstevel@tonic-gate if (GSS_ERROR(err)) {
9210Sstevel@tonic-gate KGSS_FREE(kctx);
9220Sstevel@tonic-gate *context_handle = GSS_C_NO_CONTEXT;
9230Sstevel@tonic-gate } else if (err == GSS_S_COMPLETE) {
9240Sstevel@tonic-gate /*
9250Sstevel@tonic-gate * Now check if there is a kernel module for this
9260Sstevel@tonic-gate * mechanism OID. If so, set the gss_mechanism structure
9270Sstevel@tonic-gate * in the wrapper context to point to the kernel mech.
9280Sstevel@tonic-gate */
9290Sstevel@tonic-gate __kgss_reset_mech(&kctx->mech, *actual_mech_type);
9300Sstevel@tonic-gate
9310Sstevel@tonic-gate /*
9320Sstevel@tonic-gate * If the mech oid was allocated for us, free it.
9330Sstevel@tonic-gate */
9340Sstevel@tonic-gate if (&amt == actual_mech_type) {
9350Sstevel@tonic-gate kgss_free_oid(amt);
9360Sstevel@tonic-gate }
9370Sstevel@tonic-gate }
9380Sstevel@tonic-gate return (err);
9390Sstevel@tonic-gate }
9400Sstevel@tonic-gate
9410Sstevel@tonic-gate static OM_uint32
kgss_accept_sec_context_wrapped(OM_uint32 * minor_status,gssd_ctx_id_t * context_handle,OM_uint32 * gssd_context_verifier,const gssd_cred_id_t verifier_cred_handle,OM_uint32 gssd_cred_verifier,const gss_buffer_t input_token,const 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)9420Sstevel@tonic-gate kgss_accept_sec_context_wrapped(
9430Sstevel@tonic-gate OM_uint32 *minor_status,
9440Sstevel@tonic-gate gssd_ctx_id_t *context_handle,
9450Sstevel@tonic-gate OM_uint32 *gssd_context_verifier,
9460Sstevel@tonic-gate const gssd_cred_id_t verifier_cred_handle,
9470Sstevel@tonic-gate OM_uint32 gssd_cred_verifier,
9480Sstevel@tonic-gate const gss_buffer_t input_token,
9490Sstevel@tonic-gate const gss_channel_bindings_t input_chan_bindings,
9500Sstevel@tonic-gate gss_buffer_t src_name,
9510Sstevel@tonic-gate gss_OID *mech_type,
9520Sstevel@tonic-gate gss_buffer_t output_token,
9530Sstevel@tonic-gate int *ret_flags,
9540Sstevel@tonic-gate OM_uint32 *time_rec,
9550Sstevel@tonic-gate gss_cred_id_t *delegated_cred_handle,
9560Sstevel@tonic-gate uid_t uid)
9570Sstevel@tonic-gate {
9580Sstevel@tonic-gate CLIENT *clnt;
9590Sstevel@tonic-gate
9600Sstevel@tonic-gate gss_accept_sec_context_arg arg;
9610Sstevel@tonic-gate gss_accept_sec_context_res res;
9620Sstevel@tonic-gate struct kgss_cred *kcred;
9630Sstevel@tonic-gate
9640Sstevel@tonic-gate /* get the client handle to GSSD */
9650Sstevel@tonic-gate
9660Sstevel@tonic-gate if ((clnt = getgssd_handle()) == NULL) {
9670Sstevel@tonic-gate GSSLOG(1,
9680Sstevel@tonic-gate "kgss_accept_sec_context: can't connect to server on %s\n",
9690Sstevel@tonic-gate server);
9700Sstevel@tonic-gate return (GSS_S_FAILURE);
9710Sstevel@tonic-gate }
9720Sstevel@tonic-gate
9730Sstevel@tonic-gate /* copy the procedure arguments into the rpc arg parameter */
9740Sstevel@tonic-gate
9750Sstevel@tonic-gate arg.uid = (OM_uint32)uid;
9760Sstevel@tonic-gate
9770Sstevel@tonic-gate arg.context_handle.GSS_CTX_ID_T_len =
9780Sstevel@tonic-gate *context_handle == (gssd_ctx_id_t)GSS_C_NO_CONTEXT ?
9790Sstevel@tonic-gate 0 : (uint_t)sizeof (gssd_ctx_id_t);
9800Sstevel@tonic-gate arg.context_handle.GSS_CTX_ID_T_val = (char *)context_handle;
9810Sstevel@tonic-gate arg.gssd_context_verifier = *gssd_context_verifier;
9820Sstevel@tonic-gate
9830Sstevel@tonic-gate arg.verifier_cred_handle.GSS_CRED_ID_T_len =
9840Sstevel@tonic-gate verifier_cred_handle ==
9850Sstevel@tonic-gate (gssd_cred_id_t)GSS_C_NO_CREDENTIAL ?
9860Sstevel@tonic-gate 0 : (uint_t)sizeof (gssd_cred_id_t);
9870Sstevel@tonic-gate arg.verifier_cred_handle.GSS_CRED_ID_T_val =
9880Sstevel@tonic-gate (char *)&verifier_cred_handle;
9890Sstevel@tonic-gate arg.gssd_cred_verifier = gssd_cred_verifier;
9900Sstevel@tonic-gate
9910Sstevel@tonic-gate arg.input_token_buffer.GSS_BUFFER_T_len =
9920Sstevel@tonic-gate (uint_t)(input_token != GSS_C_NO_BUFFER ?
9930Sstevel@tonic-gate input_token->length : 0);
9940Sstevel@tonic-gate arg.input_token_buffer.GSS_BUFFER_T_val =
9950Sstevel@tonic-gate (char *)(input_token != GSS_C_NO_BUFFER ?
9960Sstevel@tonic-gate input_token->value : 0);
9970Sstevel@tonic-gate
9980Sstevel@tonic-gate if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS) {
9990Sstevel@tonic-gate arg.input_chan_bindings.present = YES;
10000Sstevel@tonic-gate arg.input_chan_bindings.initiator_addrtype =
10010Sstevel@tonic-gate input_chan_bindings->initiator_addrtype;
10020Sstevel@tonic-gate arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_len =
10030Sstevel@tonic-gate (uint_t)input_chan_bindings->initiator_address.length;
10040Sstevel@tonic-gate arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_val =
10050Sstevel@tonic-gate (void *)input_chan_bindings->initiator_address.value;
10060Sstevel@tonic-gate arg.input_chan_bindings.acceptor_addrtype =
10070Sstevel@tonic-gate input_chan_bindings->acceptor_addrtype;
10080Sstevel@tonic-gate arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_len =
10090Sstevel@tonic-gate (uint_t)input_chan_bindings->acceptor_address.length;
10100Sstevel@tonic-gate arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_val =
10110Sstevel@tonic-gate (void *)input_chan_bindings->acceptor_address.value;
10120Sstevel@tonic-gate arg.input_chan_bindings.application_data.GSS_BUFFER_T_len =
10130Sstevel@tonic-gate (uint_t)input_chan_bindings->application_data.length;
10140Sstevel@tonic-gate arg.input_chan_bindings.application_data.GSS_BUFFER_T_val =
10150Sstevel@tonic-gate (void *)input_chan_bindings->application_data.value;
10160Sstevel@tonic-gate } else {
10170Sstevel@tonic-gate
10180Sstevel@tonic-gate arg.input_chan_bindings.present = NO;
10190Sstevel@tonic-gate arg.input_chan_bindings.initiator_addrtype = 0;
10200Sstevel@tonic-gate arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_len = 0;
10210Sstevel@tonic-gate arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_val = 0;
10220Sstevel@tonic-gate arg.input_chan_bindings.acceptor_addrtype = 0;
10230Sstevel@tonic-gate arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_len = 0;
10240Sstevel@tonic-gate arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_val = 0;
10250Sstevel@tonic-gate arg.input_chan_bindings.application_data.GSS_BUFFER_T_len = 0;
10260Sstevel@tonic-gate arg.input_chan_bindings.application_data.GSS_BUFFER_T_val = 0;
10270Sstevel@tonic-gate }
10280Sstevel@tonic-gate
10290Sstevel@tonic-gate /* set the return parameters in case of errors.... */
10300Sstevel@tonic-gate if (minor_status != NULL)
10310Sstevel@tonic-gate *minor_status = DEFAULT_MINOR_STAT;
10320Sstevel@tonic-gate if (src_name != NULL) {
10330Sstevel@tonic-gate src_name->length = 0;
10340Sstevel@tonic-gate src_name->value = NULL;
10350Sstevel@tonic-gate }
10360Sstevel@tonic-gate if (mech_type != NULL)
10370Sstevel@tonic-gate *mech_type = NULL;
10380Sstevel@tonic-gate if (output_token != NULL)
10390Sstevel@tonic-gate output_token->length = 0;
10400Sstevel@tonic-gate if (ret_flags != NULL)
10410Sstevel@tonic-gate *ret_flags = 0;
10420Sstevel@tonic-gate if (time_rec != NULL)
10430Sstevel@tonic-gate *time_rec = 0;
10440Sstevel@tonic-gate if (delegated_cred_handle != NULL)
10450Sstevel@tonic-gate *delegated_cred_handle = NULL;
10460Sstevel@tonic-gate
10470Sstevel@tonic-gate /* call the remote procedure */
10480Sstevel@tonic-gate
10490Sstevel@tonic-gate bzero((caddr_t)&res, sizeof (res));
10500Sstevel@tonic-gate if (gss_accept_sec_context_1(&arg, &res, clnt) != RPC_SUCCESS) {
10510Sstevel@tonic-gate killgssd_handle(clnt);
10520Sstevel@tonic-gate GSSLOG0(1, "kgss_accept_sec_context: RPC call times out\n");
10530Sstevel@tonic-gate return (GSS_S_FAILURE);
10540Sstevel@tonic-gate }
10550Sstevel@tonic-gate
1056*10598SGlenn.Barry@Sun.COM if (minor_status != NULL)
1057*10598SGlenn.Barry@Sun.COM *minor_status = res.minor_status;
1058*10598SGlenn.Barry@Sun.COM
1059*10598SGlenn.Barry@Sun.COM if (output_token != NULL && res.output_token.GSS_BUFFER_T_val != NULL) {
1060*10598SGlenn.Barry@Sun.COM output_token->length =
1061*10598SGlenn.Barry@Sun.COM res.output_token.GSS_BUFFER_T_len;
1062*10598SGlenn.Barry@Sun.COM output_token->value =
1063*10598SGlenn.Barry@Sun.COM (void *) MALLOC(output_token->length);
1064*10598SGlenn.Barry@Sun.COM (void) memcpy(output_token->value,
1065*10598SGlenn.Barry@Sun.COM res.output_token.GSS_BUFFER_T_val,
1066*10598SGlenn.Barry@Sun.COM output_token->length);
1067*10598SGlenn.Barry@Sun.COM }
1068*10598SGlenn.Barry@Sun.COM
10690Sstevel@tonic-gate /* if the call was successful, copy out the results */
10700Sstevel@tonic-gate
10710Sstevel@tonic-gate if (res.status == (OM_uint32) GSS_S_COMPLETE ||
10720Sstevel@tonic-gate res.status == (OM_uint32) GSS_S_CONTINUE_NEEDED) {
10730Sstevel@tonic-gate
10740Sstevel@tonic-gate /*
10750Sstevel@tonic-gate * the only parameters that are ready when we
10760Sstevel@tonic-gate * get GSS_S_CONTINUE_NEEDED are: minor, ctxt_handle,
10770Sstevel@tonic-gate * and the output token to send to the peer.
10780Sstevel@tonic-gate */
10790Sstevel@tonic-gate
10800Sstevel@tonic-gate *context_handle = *((gssd_ctx_id_t *)
10810Sstevel@tonic-gate res.context_handle.GSS_CTX_ID_T_val);
10820Sstevel@tonic-gate *gssd_context_verifier = res.gssd_context_verifier;
10830Sstevel@tonic-gate
10840Sstevel@tonic-gate /* these other parameters are only ready upon GSS_S_COMPLETE */
10850Sstevel@tonic-gate if (res.status == (OM_uint32) GSS_S_COMPLETE) {
10860Sstevel@tonic-gate
10870Sstevel@tonic-gate if (src_name != NULL) {
10880Sstevel@tonic-gate src_name->length = res.src_name.GSS_BUFFER_T_len;
10890Sstevel@tonic-gate src_name->value = res.src_name.GSS_BUFFER_T_val;
10900Sstevel@tonic-gate res.src_name.GSS_BUFFER_T_val = NULL;
10910Sstevel@tonic-gate res.src_name.GSS_BUFFER_T_len = 0;
10920Sstevel@tonic-gate }
10930Sstevel@tonic-gate
10940Sstevel@tonic-gate /*
10950Sstevel@tonic-gate * move mech type returned to mech_type
10960Sstevel@tonic-gate * for gss_import_name_for_mech()
10970Sstevel@tonic-gate */
10980Sstevel@tonic-gate if (mech_type != NULL) {
10990Sstevel@tonic-gate *mech_type = (gss_OID)
11000Sstevel@tonic-gate MALLOC(sizeof (gss_OID_desc));
11010Sstevel@tonic-gate (*mech_type)->length =
11020Sstevel@tonic-gate (OM_UINT32) res.mech_type.GSS_OID_len;
11030Sstevel@tonic-gate (*mech_type)->elements =
11040Sstevel@tonic-gate (void *) MALLOC((*mech_type)->length);
11050Sstevel@tonic-gate (void) memcpy((*mech_type)->elements,
11060Sstevel@tonic-gate res.mech_type.GSS_OID_val,
11070Sstevel@tonic-gate (*mech_type)->length);
11080Sstevel@tonic-gate }
11090Sstevel@tonic-gate
11100Sstevel@tonic-gate if (ret_flags != NULL)
11110Sstevel@tonic-gate *ret_flags = res.ret_flags;
11120Sstevel@tonic-gate
11130Sstevel@tonic-gate if (time_rec != NULL)
11140Sstevel@tonic-gate *time_rec = res.time_rec;
11150Sstevel@tonic-gate
11160Sstevel@tonic-gate if ((delegated_cred_handle != NULL) &&
11170Sstevel@tonic-gate (res.delegated_cred_handle.GSS_CRED_ID_T_len
11180Sstevel@tonic-gate != 0)) {
11190Sstevel@tonic-gate kcred = KGSS_CRED_ALLOC();
11200Sstevel@tonic-gate kcred->gssd_cred =
11210Sstevel@tonic-gate *((gssd_cred_id_t *)
11220Sstevel@tonic-gate res.delegated_cred_handle.GSS_CRED_ID_T_val);
11230Sstevel@tonic-gate kcred->gssd_cred_verifier =
11240Sstevel@tonic-gate res.gssd_context_verifier;
11250Sstevel@tonic-gate *delegated_cred_handle = (gss_cred_id_t)kcred;
11260Sstevel@tonic-gate }
11270Sstevel@tonic-gate
11280Sstevel@tonic-gate }
11290Sstevel@tonic-gate }
11300Sstevel@tonic-gate
11310Sstevel@tonic-gate
11320Sstevel@tonic-gate /*
11330Sstevel@tonic-gate * free the memory allocated for the results and return with the status
11340Sstevel@tonic-gate * received in the rpc call
11350Sstevel@tonic-gate */
11360Sstevel@tonic-gate
11370Sstevel@tonic-gate clnt_freeres(clnt, xdr_gss_accept_sec_context_res, (caddr_t)&res);
11380Sstevel@tonic-gate killgssd_handle(clnt);
11390Sstevel@tonic-gate return (res.status);
11400Sstevel@tonic-gate
11410Sstevel@tonic-gate }
11420Sstevel@tonic-gate
11430Sstevel@tonic-gate OM_uint32
kgss_accept_sec_context(OM_uint32 * minor_status,gss_ctx_id_t * context_handle,const gss_cred_id_t verifier_cred_handle,const gss_buffer_t input_token,const 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)11440Sstevel@tonic-gate kgss_accept_sec_context(
11450Sstevel@tonic-gate OM_uint32 *minor_status,
11460Sstevel@tonic-gate gss_ctx_id_t *context_handle,
11470Sstevel@tonic-gate const gss_cred_id_t verifier_cred_handle,
11480Sstevel@tonic-gate const gss_buffer_t input_token,
11490Sstevel@tonic-gate const gss_channel_bindings_t input_chan_bindings,
11500Sstevel@tonic-gate gss_buffer_t src_name,
11510Sstevel@tonic-gate gss_OID *mech_type,
11520Sstevel@tonic-gate gss_buffer_t output_token,
11530Sstevel@tonic-gate int *ret_flags,
11540Sstevel@tonic-gate OM_uint32 *time_rec,
11550Sstevel@tonic-gate gss_cred_id_t *delegated_cred_handle,
11560Sstevel@tonic-gate uid_t uid)
11570Sstevel@tonic-gate {
11580Sstevel@tonic-gate OM_uint32 err;
11590Sstevel@tonic-gate struct kgss_ctx *kctx;
11600Sstevel@tonic-gate gss_OID mt;
11610Sstevel@tonic-gate OM_uint32 gssd_cred_verifier;
11620Sstevel@tonic-gate gssd_cred_id_t gssd_ver_cred_handle;
11630Sstevel@tonic-gate
11640Sstevel@tonic-gate
11650Sstevel@tonic-gate /*
11660Sstevel@tonic-gate * See kgss_init_sec_context() to get an idea of what is going
11670Sstevel@tonic-gate * on here.
11680Sstevel@tonic-gate */
11690Sstevel@tonic-gate if (mech_type == NULL)
11700Sstevel@tonic-gate mech_type = &mt;
11710Sstevel@tonic-gate
11720Sstevel@tonic-gate if (*context_handle == GSS_C_NO_CONTEXT) {
11730Sstevel@tonic-gate kctx = KGSS_ALLOC();
11740Sstevel@tonic-gate kctx->mech = &default_gc;
11750Sstevel@tonic-gate kctx->gssd_ctx = (gssd_ctx_id_t)GSS_C_NO_CONTEXT;
11760Sstevel@tonic-gate *context_handle = (gss_ctx_id_t)kctx;
11770Sstevel@tonic-gate } else
11780Sstevel@tonic-gate kctx = (struct kgss_ctx *)*context_handle;
11790Sstevel@tonic-gate
11800Sstevel@tonic-gate if (verifier_cred_handle != GSS_C_NO_CREDENTIAL) {
11810Sstevel@tonic-gate gssd_cred_verifier = KCRED_TO_CREDV(verifier_cred_handle);
11820Sstevel@tonic-gate gssd_ver_cred_handle = KCRED_TO_CRED(verifier_cred_handle);
11830Sstevel@tonic-gate } else
11840Sstevel@tonic-gate gssd_ver_cred_handle = (gssd_cred_id_t)GSS_C_NO_CREDENTIAL;
11850Sstevel@tonic-gate
11860Sstevel@tonic-gate err = kgss_accept_sec_context_wrapped(minor_status,
11870Sstevel@tonic-gate &kctx->gssd_ctx, &kctx->gssd_ctx_verifier,
11880Sstevel@tonic-gate gssd_ver_cred_handle, gssd_cred_verifier,
11890Sstevel@tonic-gate input_token, input_chan_bindings, src_name,
11900Sstevel@tonic-gate mech_type, output_token, ret_flags,
11910Sstevel@tonic-gate time_rec, delegated_cred_handle, uid);
11920Sstevel@tonic-gate
11930Sstevel@tonic-gate if (GSS_ERROR(err)) {
11940Sstevel@tonic-gate KGSS_FREE(kctx);
11950Sstevel@tonic-gate *context_handle = GSS_C_NO_CONTEXT;
11960Sstevel@tonic-gate
11970Sstevel@tonic-gate } else if (err == GSS_S_COMPLETE) {
11980Sstevel@tonic-gate __kgss_reset_mech(&kctx->mech, *mech_type);
11990Sstevel@tonic-gate
12000Sstevel@tonic-gate /*
12010Sstevel@tonic-gate * If the mech oid was allocated for us, free it.
12020Sstevel@tonic-gate */
12030Sstevel@tonic-gate if (&mt == mech_type) {
12040Sstevel@tonic-gate kgss_free_oid(mt);
12050Sstevel@tonic-gate }
12060Sstevel@tonic-gate }
12070Sstevel@tonic-gate
12080Sstevel@tonic-gate return (err);
12090Sstevel@tonic-gate }
12100Sstevel@tonic-gate
12110Sstevel@tonic-gate OM_uint32
kgss_process_context_token(minor_status,context_handle,token_buffer,uid)12120Sstevel@tonic-gate kgss_process_context_token(minor_status,
12130Sstevel@tonic-gate context_handle,
12140Sstevel@tonic-gate token_buffer,
12150Sstevel@tonic-gate uid)
12160Sstevel@tonic-gate OM_uint32 *minor_status;
12170Sstevel@tonic-gate const gss_ctx_id_t context_handle;
12180Sstevel@tonic-gate gss_buffer_t token_buffer;
12190Sstevel@tonic-gate uid_t uid;
12200Sstevel@tonic-gate {
12210Sstevel@tonic-gate CLIENT *clnt;
12220Sstevel@tonic-gate OM_uint32 gssd_context_verifier;
12230Sstevel@tonic-gate gssd_ctx_id_t gssd_ctx_handle;
12240Sstevel@tonic-gate gss_process_context_token_arg arg;
12250Sstevel@tonic-gate gss_process_context_token_res res;
12260Sstevel@tonic-gate
12270Sstevel@tonic-gate gssd_context_verifier = KGSS_CTX_TO_GSSD_CTXV(context_handle);
12280Sstevel@tonic-gate gssd_ctx_handle = (gssd_ctx_id_t)KGSS_CTX_TO_GSSD_CTX(context_handle);
12290Sstevel@tonic-gate
12300Sstevel@tonic-gate /* get the client handle to GSSD */
12310Sstevel@tonic-gate
12320Sstevel@tonic-gate if ((clnt = getgssd_handle()) == NULL) {
12330Sstevel@tonic-gate GSSLOG(1,
12340Sstevel@tonic-gate "kgss_process_context_token: can't connect to server on %s\n",
12350Sstevel@tonic-gate server);
12360Sstevel@tonic-gate return (GSS_S_FAILURE);
12370Sstevel@tonic-gate }
12380Sstevel@tonic-gate
12390Sstevel@tonic-gate /* copy the procedure arguments into the rpc arg parameter */
12400Sstevel@tonic-gate
12410Sstevel@tonic-gate arg.uid = (OM_uint32) uid;
12420Sstevel@tonic-gate
12430Sstevel@tonic-gate arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t);
12440Sstevel@tonic-gate arg.context_handle.GSS_CTX_ID_T_val = (char *)&gssd_ctx_handle;
12450Sstevel@tonic-gate arg.gssd_context_verifier = gssd_context_verifier;
12460Sstevel@tonic-gate arg.token_buffer.GSS_BUFFER_T_len = (uint_t)token_buffer->length;
12470Sstevel@tonic-gate arg.token_buffer.GSS_BUFFER_T_val = (char *)token_buffer->value;
12480Sstevel@tonic-gate
12490Sstevel@tonic-gate /* call the remote procedure */
12500Sstevel@tonic-gate
12510Sstevel@tonic-gate bzero(&res, sizeof (res));
12520Sstevel@tonic-gate
12530Sstevel@tonic-gate if (gss_process_context_token_1(&arg, &res, clnt) != RPC_SUCCESS) {
12540Sstevel@tonic-gate
12550Sstevel@tonic-gate /*
12560Sstevel@tonic-gate * if the RPC call times out, null out all return arguments, set
12570Sstevel@tonic-gate * minor_status to its maximum value, and return GSS_S_FAILURE
12580Sstevel@tonic-gate */
12590Sstevel@tonic-gate
12600Sstevel@tonic-gate if (minor_status != NULL)
12610Sstevel@tonic-gate *minor_status = DEFAULT_MINOR_STAT;
12620Sstevel@tonic-gate GSSLOG0(1, "kgss_process_context_token: RPC call times out\n");
12630Sstevel@tonic-gate killgssd_handle(clnt);
12640Sstevel@tonic-gate return (GSS_S_FAILURE);
12650Sstevel@tonic-gate }
12660Sstevel@tonic-gate
12670Sstevel@tonic-gate /* copy the rpc results into the return arguments */
12680Sstevel@tonic-gate
12690Sstevel@tonic-gate if (minor_status != NULL)
12700Sstevel@tonic-gate *minor_status = res.minor_status;
12710Sstevel@tonic-gate
12720Sstevel@tonic-gate /* return with status returned in rpc call */
12730Sstevel@tonic-gate
12740Sstevel@tonic-gate killgssd_handle(clnt);
12750Sstevel@tonic-gate return (res.status);
12760Sstevel@tonic-gate
12770Sstevel@tonic-gate }
12780Sstevel@tonic-gate
12790Sstevel@tonic-gate /*ARGSUSED*/
12800Sstevel@tonic-gate static OM_uint32
kgss_delete_sec_context_wrapped(void * private,OM_uint32 * minor_status,gssd_ctx_id_t * context_handle,gss_buffer_t output_token,OM_uint32 gssd_context_verifier)12810Sstevel@tonic-gate kgss_delete_sec_context_wrapped(void *private,
12820Sstevel@tonic-gate OM_uint32 *minor_status,
12830Sstevel@tonic-gate gssd_ctx_id_t *context_handle,
12840Sstevel@tonic-gate gss_buffer_t output_token,
12850Sstevel@tonic-gate OM_uint32 gssd_context_verifier)
12860Sstevel@tonic-gate
12870Sstevel@tonic-gate
12880Sstevel@tonic-gate {
12890Sstevel@tonic-gate CLIENT *clnt;
12900Sstevel@tonic-gate
12910Sstevel@tonic-gate gss_delete_sec_context_arg arg;
12920Sstevel@tonic-gate gss_delete_sec_context_res res;
12930Sstevel@tonic-gate
12940Sstevel@tonic-gate
12950Sstevel@tonic-gate /* get the client handle to GSSD */
12960Sstevel@tonic-gate
12970Sstevel@tonic-gate if ((clnt = getgssd_handle()) == NULL) {
12980Sstevel@tonic-gate GSSLOG(1,
12990Sstevel@tonic-gate "kgss_delete_sec_context: can't connect to server on %s\n",
13000Sstevel@tonic-gate server);
13010Sstevel@tonic-gate return (GSS_S_FAILURE);
13020Sstevel@tonic-gate }
13030Sstevel@tonic-gate
13040Sstevel@tonic-gate /* copy the procedure arguments into the rpc arg parameter */
13050Sstevel@tonic-gate
13060Sstevel@tonic-gate arg.context_handle.GSS_CTX_ID_T_len =
13070Sstevel@tonic-gate *context_handle == (gssd_ctx_id_t)GSS_C_NO_CONTEXT ?
13080Sstevel@tonic-gate 0 : (uint_t)sizeof (gssd_ctx_id_t);
13090Sstevel@tonic-gate arg.context_handle.GSS_CTX_ID_T_val = (char *)context_handle;
13100Sstevel@tonic-gate
13110Sstevel@tonic-gate arg.gssd_context_verifier = gssd_context_verifier;
13120Sstevel@tonic-gate
13130Sstevel@tonic-gate /* call the remote procedure */
13140Sstevel@tonic-gate
13150Sstevel@tonic-gate bzero((caddr_t)&res, sizeof (res));
13160Sstevel@tonic-gate if (gss_delete_sec_context_1(&arg, &res, clnt) != RPC_SUCCESS) {
13170Sstevel@tonic-gate
13180Sstevel@tonic-gate /*
13190Sstevel@tonic-gate * if the RPC call times out, null out all return arguments, set
13200Sstevel@tonic-gate * minor_status to its maximum value, and return GSS_S_FAILURE
13210Sstevel@tonic-gate */
13220Sstevel@tonic-gate
13230Sstevel@tonic-gate if (minor_status != NULL)
13240Sstevel@tonic-gate *minor_status = DEFAULT_MINOR_STAT;
13250Sstevel@tonic-gate if (context_handle != NULL)
13260Sstevel@tonic-gate *context_handle = NULL;
13270Sstevel@tonic-gate if (output_token != NULL)
13280Sstevel@tonic-gate output_token->length = 0;
13290Sstevel@tonic-gate
13300Sstevel@tonic-gate killgssd_handle(clnt);
13310Sstevel@tonic-gate GSSLOG0(1, "kgssd_delete_sec_context: RPC call times out\n");
13320Sstevel@tonic-gate return (GSS_S_FAILURE);
13330Sstevel@tonic-gate }
13340Sstevel@tonic-gate
13350Sstevel@tonic-gate /* copy the rpc results into the return arguments */
13360Sstevel@tonic-gate
13370Sstevel@tonic-gate if (minor_status != NULL)
13380Sstevel@tonic-gate *minor_status = res.minor_status;
13390Sstevel@tonic-gate
13400Sstevel@tonic-gate if (res.context_handle.GSS_CTX_ID_T_len == 0)
13410Sstevel@tonic-gate *context_handle = NULL;
13420Sstevel@tonic-gate else
13430Sstevel@tonic-gate *context_handle =
13440Sstevel@tonic-gate *((gssd_ctx_id_t *)res.context_handle.GSS_CTX_ID_T_val);
13450Sstevel@tonic-gate
13460Sstevel@tonic-gate if (output_token != NULL) {
13470Sstevel@tonic-gate output_token->length = res.output_token.GSS_BUFFER_T_len;
13480Sstevel@tonic-gate output_token->value = res.output_token.GSS_BUFFER_T_val;
13490Sstevel@tonic-gate res.output_token.GSS_BUFFER_T_len = 0;
13500Sstevel@tonic-gate res.output_token.GSS_BUFFER_T_val = NULL;
13510Sstevel@tonic-gate }
13520Sstevel@tonic-gate
13530Sstevel@tonic-gate /*
13540Sstevel@tonic-gate * free the memory allocated for the results and return with the status
13550Sstevel@tonic-gate * received in the rpc call
13560Sstevel@tonic-gate */
13570Sstevel@tonic-gate
13580Sstevel@tonic-gate clnt_freeres(clnt, xdr_gss_delete_sec_context_res, (caddr_t)&res);
13590Sstevel@tonic-gate killgssd_handle(clnt);
13600Sstevel@tonic-gate return (res.status);
13610Sstevel@tonic-gate
13620Sstevel@tonic-gate }
13630Sstevel@tonic-gate
13640Sstevel@tonic-gate OM_uint32
kgss_delete_sec_context(OM_uint32 * minor_status,gss_ctx_id_t * context_handle,gss_buffer_t output_token)13650Sstevel@tonic-gate kgss_delete_sec_context(
13660Sstevel@tonic-gate OM_uint32 *minor_status,
13670Sstevel@tonic-gate gss_ctx_id_t *context_handle,
13680Sstevel@tonic-gate gss_buffer_t output_token)
13690Sstevel@tonic-gate {
13700Sstevel@tonic-gate OM_uint32 err;
13710Sstevel@tonic-gate struct kgss_ctx *kctx;
13720Sstevel@tonic-gate
13730Sstevel@tonic-gate if (*context_handle == GSS_C_NO_CONTEXT) {
13740Sstevel@tonic-gate GSSLOG0(8, "kgss_delete_sec_context: Null context handle \n");
13750Sstevel@tonic-gate return (GSS_S_COMPLETE);
13760Sstevel@tonic-gate } else
13770Sstevel@tonic-gate kctx = (struct kgss_ctx *)*context_handle;
13780Sstevel@tonic-gate
13790Sstevel@tonic-gate if (kctx->ctx_imported == FALSE) {
13800Sstevel@tonic-gate if (kctx->gssd_ctx == (gssd_ctx_id_t)GSS_C_NO_CONTEXT) {
13810Sstevel@tonic-gate KGSS_FREE(kctx);
13820Sstevel@tonic-gate *context_handle = GSS_C_NO_CONTEXT;
13830Sstevel@tonic-gate return (GSS_S_COMPLETE);
13840Sstevel@tonic-gate }
13850Sstevel@tonic-gate err = kgss_delete_sec_context_wrapped(
13860Sstevel@tonic-gate KCTX_TO_PRIVATE(*context_handle),
13870Sstevel@tonic-gate minor_status,
13880Sstevel@tonic-gate &kctx->gssd_ctx,
13890Sstevel@tonic-gate output_token,
13900Sstevel@tonic-gate kctx->gssd_ctx_verifier);
13910Sstevel@tonic-gate } else {
13920Sstevel@tonic-gate if (kctx->gssd_i_ctx == (gss_ctx_id_t)GSS_C_NO_CONTEXT) {
13930Sstevel@tonic-gate KGSS_FREE(kctx);
13940Sstevel@tonic-gate *context_handle = GSS_C_NO_CONTEXT;
13950Sstevel@tonic-gate return (GSS_S_COMPLETE);
13960Sstevel@tonic-gate }
13970Sstevel@tonic-gate err = KGSS_DELETE_SEC_CONTEXT(minor_status, kctx,
13980Sstevel@tonic-gate &kctx->gssd_i_ctx, output_token);
13990Sstevel@tonic-gate }
14000Sstevel@tonic-gate KGSS_FREE(kctx);
14010Sstevel@tonic-gate *context_handle = GSS_C_NO_CONTEXT;
14020Sstevel@tonic-gate return (err);
14030Sstevel@tonic-gate
14040Sstevel@tonic-gate }
14050Sstevel@tonic-gate
14060Sstevel@tonic-gate
14070Sstevel@tonic-gate OM_uint32
kgss_export_sec_context_wrapped(minor_status,context_handle,output_token,gssd_context_verifier)14080Sstevel@tonic-gate kgss_export_sec_context_wrapped(minor_status,
14090Sstevel@tonic-gate context_handle,
14100Sstevel@tonic-gate output_token,
14110Sstevel@tonic-gate gssd_context_verifier)
14120Sstevel@tonic-gate OM_uint32 *minor_status;
14130Sstevel@tonic-gate gssd_ctx_id_t *context_handle;
14140Sstevel@tonic-gate gss_buffer_t output_token;
14150Sstevel@tonic-gate OM_uint32 gssd_context_verifier;
14160Sstevel@tonic-gate {
14170Sstevel@tonic-gate CLIENT *clnt;
14180Sstevel@tonic-gate gss_export_sec_context_arg arg;
14190Sstevel@tonic-gate gss_export_sec_context_res res;
14200Sstevel@tonic-gate
14210Sstevel@tonic-gate
14220Sstevel@tonic-gate /* get the client handle to GSSD */
14230Sstevel@tonic-gate
14240Sstevel@tonic-gate if ((clnt = getgssd_handle()) == NULL) {
14250Sstevel@tonic-gate GSSLOG(1, "kgss_export_sec_context_wrapped :"
14260Sstevel@tonic-gate " can't connect to server on %s\n", server);
14270Sstevel@tonic-gate return (GSS_S_FAILURE);
14280Sstevel@tonic-gate }
14290Sstevel@tonic-gate
14300Sstevel@tonic-gate /* copy the procedure arguments into the rpc arg parameter */
14310Sstevel@tonic-gate
14320Sstevel@tonic-gate arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t);
14330Sstevel@tonic-gate arg.context_handle.GSS_CTX_ID_T_val = (char *)context_handle;
14340Sstevel@tonic-gate arg.gssd_context_verifier = gssd_context_verifier;
14350Sstevel@tonic-gate
14360Sstevel@tonic-gate /* call the remote procedure */
14370Sstevel@tonic-gate
14380Sstevel@tonic-gate (void) memset(&res, 0, sizeof (res));
14390Sstevel@tonic-gate if (gss_export_sec_context_1(&arg, &res, clnt) != RPC_SUCCESS) {
14400Sstevel@tonic-gate
14410Sstevel@tonic-gate /*
14420Sstevel@tonic-gate * if the RPC call times out, null out all return arguments,
14430Sstevel@tonic-gate * set minor_status to its maximum value, and return
14440Sstevel@tonic-gate * GSS_S_FAILURE
14450Sstevel@tonic-gate */
14460Sstevel@tonic-gate
14470Sstevel@tonic-gate if (minor_status != NULL)
14480Sstevel@tonic-gate *minor_status = DEFAULT_MINOR_STAT;
14490Sstevel@tonic-gate if (context_handle != NULL)
14500Sstevel@tonic-gate *context_handle = NULL;
14510Sstevel@tonic-gate if (output_token != NULL)
14520Sstevel@tonic-gate output_token->length = 0;
14530Sstevel@tonic-gate killgssd_handle(clnt);
14540Sstevel@tonic-gate GSSLOG0(1,
14550Sstevel@tonic-gate "kgss_export_sec_context_wrapped: RPC call times out\n");
14560Sstevel@tonic-gate return (GSS_S_FAILURE);
14570Sstevel@tonic-gate }
14580Sstevel@tonic-gate
14590Sstevel@tonic-gate /* copy the rpc results into the return arguments */
14600Sstevel@tonic-gate
14610Sstevel@tonic-gate if (minor_status != NULL)
14620Sstevel@tonic-gate *minor_status = res.minor_status;
14630Sstevel@tonic-gate
14640Sstevel@tonic-gate if (res.context_handle.GSS_CTX_ID_T_len == 0)
14650Sstevel@tonic-gate *context_handle = NULL;
14660Sstevel@tonic-gate else
14670Sstevel@tonic-gate *context_handle =
14680Sstevel@tonic-gate *((gssd_ctx_id_t *)res.context_handle.GSS_CTX_ID_T_val);
14690Sstevel@tonic-gate
14700Sstevel@tonic-gate if (output_token != NULL) {
14710Sstevel@tonic-gate output_token->length = res.output_token.GSS_BUFFER_T_len;
14720Sstevel@tonic-gate output_token->value =
14730Sstevel@tonic-gate (void *) MALLOC(output_token->length);
14740Sstevel@tonic-gate (void) memcpy(output_token->value,
14750Sstevel@tonic-gate res.output_token.GSS_BUFFER_T_val,
14760Sstevel@tonic-gate output_token->length);
14770Sstevel@tonic-gate }
14780Sstevel@tonic-gate
14790Sstevel@tonic-gate /*
14800Sstevel@tonic-gate * free the memory allocated for the results and return with the status
14810Sstevel@tonic-gate * received in the rpc call
14820Sstevel@tonic-gate */
14830Sstevel@tonic-gate
14840Sstevel@tonic-gate clnt_freeres(clnt, xdr_gss_export_sec_context_res, (caddr_t)&res);
14850Sstevel@tonic-gate killgssd_handle(clnt);
14860Sstevel@tonic-gate return (res.status);
14870Sstevel@tonic-gate
14880Sstevel@tonic-gate }
14890Sstevel@tonic-gate
14900Sstevel@tonic-gate OM_uint32
kgss_export_sec_context(minor_status,context_handle,output_token)14910Sstevel@tonic-gate kgss_export_sec_context(minor_status,
14920Sstevel@tonic-gate context_handle,
14930Sstevel@tonic-gate output_token)
14940Sstevel@tonic-gate OM_uint32 *minor_status;
14950Sstevel@tonic-gate gss_ctx_id_t context_handle;
14960Sstevel@tonic-gate gss_buffer_t output_token;
14970Sstevel@tonic-gate {
14980Sstevel@tonic-gate struct kgss_ctx *kctx;
14990Sstevel@tonic-gate
15000Sstevel@tonic-gate if (context_handle == GSS_C_NO_CONTEXT)
15010Sstevel@tonic-gate return (GSS_S_FAILURE);
15020Sstevel@tonic-gate else
15030Sstevel@tonic-gate kctx = (struct kgss_ctx *)context_handle;
15040Sstevel@tonic-gate
15050Sstevel@tonic-gate
15060Sstevel@tonic-gate
15070Sstevel@tonic-gate /*
15080Sstevel@tonic-gate * If there is a kernel module then import_sec context must be
15090Sstevel@tonic-gate * supported and we make an upcall to export_sec_context.
15100Sstevel@tonic-gate * If there is no kernel module then we return an error
15110Sstevel@tonic-gate */
15120Sstevel@tonic-gate
15130Sstevel@tonic-gate *minor_status = 0;
15140Sstevel@tonic-gate
15150Sstevel@tonic-gate if (kctx->mech->gss_import_sec_context) {
15160Sstevel@tonic-gate GSSLOG0(8, "kgss_export_sec_context: Kernel mod available \n");
15170Sstevel@tonic-gate return (kgss_export_sec_context_wrapped(minor_status,
15180Sstevel@tonic-gate &kctx->gssd_ctx,
15190Sstevel@tonic-gate output_token,
15200Sstevel@tonic-gate kctx->gssd_ctx_verifier));
15210Sstevel@tonic-gate
15220Sstevel@tonic-gate } else {
15230Sstevel@tonic-gate
15240Sstevel@tonic-gate /*
15250Sstevel@tonic-gate * This is not the right error value; instead of
15260Sstevel@tonic-gate * inventing new error we return GSS_S_NAME_NOT_MN
15270Sstevel@tonic-gate * This error is not returned by the export routine
15280Sstevel@tonic-gate */
15290Sstevel@tonic-gate
15300Sstevel@tonic-gate GSSLOG0(8, "kgss_export_sec_context: Kernel mod "
15310Sstevel@tonic-gate "unavailable \n");
15320Sstevel@tonic-gate return (GSS_S_NAME_NOT_MN);
15330Sstevel@tonic-gate }
15340Sstevel@tonic-gate
15350Sstevel@tonic-gate }
15360Sstevel@tonic-gate
15370Sstevel@tonic-gate OM_uint32
kgss_import_sec_context(minor_status,interprocess_token,context_handle)15380Sstevel@tonic-gate kgss_import_sec_context(minor_status,
15390Sstevel@tonic-gate interprocess_token,
15400Sstevel@tonic-gate context_handle)
15410Sstevel@tonic-gate
15420Sstevel@tonic-gate OM_uint32 * minor_status;
15430Sstevel@tonic-gate const gss_buffer_t interprocess_token;
15440Sstevel@tonic-gate gss_ctx_id_t context_handle;
15450Sstevel@tonic-gate
15460Sstevel@tonic-gate {
15470Sstevel@tonic-gate OM_uint32 status;
15480Sstevel@tonic-gate struct kgss_ctx *kctx;
15490Sstevel@tonic-gate
15500Sstevel@tonic-gate size_t length;
15510Sstevel@tonic-gate char *p;
15520Sstevel@tonic-gate gss_buffer_desc token;
15530Sstevel@tonic-gate gss_ctx_id_t internal_ctx_id;
15540Sstevel@tonic-gate kctx = (struct kgss_ctx *)context_handle;
15550Sstevel@tonic-gate
15560Sstevel@tonic-gate if (kctx->gssd_ctx != (gssd_ctx_id_t)GSS_C_NO_CONTEXT) {
15570Sstevel@tonic-gate return (GSS_S_FAILURE);
15580Sstevel@tonic-gate }
15590Sstevel@tonic-gate
15600Sstevel@tonic-gate if (!(KCTX_TO_MECH(context_handle)->gss_import_sec_context)) {
15610Sstevel@tonic-gate
15620Sstevel@tonic-gate /*
15630Sstevel@tonic-gate * This should never happen
15640Sstevel@tonic-gate * If Kernel import sec context does not exist the export
15650Sstevel@tonic-gate * sec context should have caught this and returned an error
15660Sstevel@tonic-gate * and the caller should not have called this routine
15670Sstevel@tonic-gate */
15680Sstevel@tonic-gate GSSLOG0(1, "import_sec_context called improperly\n");
15690Sstevel@tonic-gate return (GSS_S_FAILURE);
15700Sstevel@tonic-gate }
15710Sstevel@tonic-gate *minor_status = 0;
15720Sstevel@tonic-gate
15730Sstevel@tonic-gate if (interprocess_token->length == 0 || interprocess_token->value == 0)
15740Sstevel@tonic-gate return (GSS_S_DEFECTIVE_TOKEN);
15750Sstevel@tonic-gate
15760Sstevel@tonic-gate status = GSS_S_FAILURE;
15770Sstevel@tonic-gate
15780Sstevel@tonic-gate p = interprocess_token->value;
15790Sstevel@tonic-gate length = *p++;
15800Sstevel@tonic-gate length = (length << 8) + *p++;
15810Sstevel@tonic-gate length = (length << 8) + *p++;
15820Sstevel@tonic-gate length = (length << 8) + *p++;
15830Sstevel@tonic-gate
15840Sstevel@tonic-gate p += length;
15850Sstevel@tonic-gate
15860Sstevel@tonic-gate token.length = interprocess_token->length - 4 - length;
15870Sstevel@tonic-gate token.value = p;
15880Sstevel@tonic-gate
15890Sstevel@tonic-gate /*
15900Sstevel@tonic-gate * select the approprate underlying mechanism routine and
15910Sstevel@tonic-gate * call it.
15920Sstevel@tonic-gate */
15930Sstevel@tonic-gate
15940Sstevel@tonic-gate status = KGSS_IMPORT_SEC_CONTEXT(minor_status, &token, kctx,
15950Sstevel@tonic-gate &internal_ctx_id);
15960Sstevel@tonic-gate
15970Sstevel@tonic-gate if (status == GSS_S_COMPLETE) {
15980Sstevel@tonic-gate KCTX_TO_I_CTX(kctx) = internal_ctx_id;
15990Sstevel@tonic-gate kctx->ctx_imported = TRUE;
16000Sstevel@tonic-gate return (GSS_S_COMPLETE);
16010Sstevel@tonic-gate } else
16020Sstevel@tonic-gate return (status);
16030Sstevel@tonic-gate }
16040Sstevel@tonic-gate
16050Sstevel@tonic-gate /*ARGSUSED*/
16060Sstevel@tonic-gate OM_uint32
kgss_context_time(minor_status,context_handle,time_rec,uid)16070Sstevel@tonic-gate kgss_context_time(minor_status,
16080Sstevel@tonic-gate context_handle,
16090Sstevel@tonic-gate time_rec,
16100Sstevel@tonic-gate uid)
16110Sstevel@tonic-gate OM_uint32 *minor_status;
16120Sstevel@tonic-gate const gss_ctx_id_t context_handle;
16130Sstevel@tonic-gate OM_uint32 *time_rec;
16140Sstevel@tonic-gate uid_t uid;
16150Sstevel@tonic-gate {
16160Sstevel@tonic-gate return (GSS_S_FAILURE);
16170Sstevel@tonic-gate }
16180Sstevel@tonic-gate
16190Sstevel@tonic-gate /*ARGSUSED*/
16200Sstevel@tonic-gate static OM_uint32
kgss_sign_wrapped(void * private,OM_uint32 * minor_status,const gss_ctx_id_t ctx_handle,int qop_req,const gss_buffer_t message_buffer,gss_buffer_t msg_token,OM_uint32 gssd_context_verifier)16210Sstevel@tonic-gate kgss_sign_wrapped(void *private,
16220Sstevel@tonic-gate OM_uint32 *minor_status,
16230Sstevel@tonic-gate const gss_ctx_id_t ctx_handle,
16240Sstevel@tonic-gate int qop_req,
16250Sstevel@tonic-gate const gss_buffer_t message_buffer,
16260Sstevel@tonic-gate gss_buffer_t msg_token,
16270Sstevel@tonic-gate OM_uint32 gssd_context_verifier)
16280Sstevel@tonic-gate {
16290Sstevel@tonic-gate CLIENT *clnt;
16300Sstevel@tonic-gate gssd_ctx_id_t context_handle;
16310Sstevel@tonic-gate
16320Sstevel@tonic-gate gss_sign_arg arg;
16330Sstevel@tonic-gate gss_sign_res res;
16340Sstevel@tonic-gate context_handle = (gssd_ctx_id_t)KCTX_TO_GSSD_CTX(ctx_handle);
16350Sstevel@tonic-gate /* get the client handle to GSSD */
16360Sstevel@tonic-gate
16370Sstevel@tonic-gate if ((clnt = getgssd_handle()) == NULL) {
16380Sstevel@tonic-gate GSSLOG(1, "kgss_sign: can't connect to server on %s\n", server);
16390Sstevel@tonic-gate return (GSS_S_FAILURE);
16400Sstevel@tonic-gate }
16410Sstevel@tonic-gate
16420Sstevel@tonic-gate /* copy the procedure arguments into the rpc arg parameter */
16430Sstevel@tonic-gate
16440Sstevel@tonic-gate arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t);
16450Sstevel@tonic-gate arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
16460Sstevel@tonic-gate
16470Sstevel@tonic-gate arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t);
16480Sstevel@tonic-gate arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
16490Sstevel@tonic-gate arg.gssd_context_verifier = gssd_context_verifier;
16500Sstevel@tonic-gate
16510Sstevel@tonic-gate arg.qop_req = qop_req;
16520Sstevel@tonic-gate
16530Sstevel@tonic-gate arg.message_buffer.GSS_BUFFER_T_len = (uint_t)message_buffer->length;
16540Sstevel@tonic-gate arg.message_buffer.GSS_BUFFER_T_val = (char *)message_buffer->value;
16550Sstevel@tonic-gate
16560Sstevel@tonic-gate /* call the remote procedure */
16570Sstevel@tonic-gate
16580Sstevel@tonic-gate bzero((caddr_t)&res, sizeof (res));
16590Sstevel@tonic-gate if (gss_sign_1(&arg, &res, clnt) != RPC_SUCCESS) {
16600Sstevel@tonic-gate
16610Sstevel@tonic-gate /*
16620Sstevel@tonic-gate * if the RPC call times out, null out all return arguments, set
16630Sstevel@tonic-gate * minor_status to its maximum value, and return GSS_S_FAILURE
16640Sstevel@tonic-gate */
16650Sstevel@tonic-gate
16660Sstevel@tonic-gate if (minor_status != NULL)
16670Sstevel@tonic-gate *minor_status = DEFAULT_MINOR_STAT;
16680Sstevel@tonic-gate if (msg_token != NULL)
16690Sstevel@tonic-gate msg_token->length = 0;
16700Sstevel@tonic-gate
16710Sstevel@tonic-gate killgssd_handle(clnt);
16720Sstevel@tonic-gate GSSLOG0(1, "kgss_sign: RPC call times out\n");
16730Sstevel@tonic-gate return (GSS_S_FAILURE);
16740Sstevel@tonic-gate }
16750Sstevel@tonic-gate
16760Sstevel@tonic-gate /* copy the rpc results into the return arguments */
16770Sstevel@tonic-gate
16780Sstevel@tonic-gate if (minor_status != NULL)
16790Sstevel@tonic-gate *minor_status = res.minor_status;
16800Sstevel@tonic-gate
16810Sstevel@tonic-gate if (msg_token != NULL) {
16820Sstevel@tonic-gate msg_token->length = res.msg_token.GSS_BUFFER_T_len;
16830Sstevel@tonic-gate msg_token->value = (void *) MALLOC(msg_token->length);
16840Sstevel@tonic-gate (void) memcpy(msg_token->value, res.msg_token.GSS_BUFFER_T_val,
16850Sstevel@tonic-gate msg_token->length);
16860Sstevel@tonic-gate }
16870Sstevel@tonic-gate
16880Sstevel@tonic-gate /*
16890Sstevel@tonic-gate * free the memory allocated for the results and return with the status
16900Sstevel@tonic-gate * received in the rpc call
16910Sstevel@tonic-gate */
16920Sstevel@tonic-gate
16930Sstevel@tonic-gate clnt_freeres(clnt, xdr_gss_sign_res, (caddr_t)&res);
16940Sstevel@tonic-gate killgssd_handle(clnt);
16950Sstevel@tonic-gate return (res.status);
16960Sstevel@tonic-gate
16970Sstevel@tonic-gate }
16980Sstevel@tonic-gate
16990Sstevel@tonic-gate OM_uint32
kgss_sign(OM_uint32 * minor_status,const gss_ctx_id_t context_handle,int qop_req,const gss_buffer_t message_buffer,gss_buffer_t msg_token)17000Sstevel@tonic-gate kgss_sign(
17010Sstevel@tonic-gate OM_uint32 *minor_status,
17020Sstevel@tonic-gate const gss_ctx_id_t context_handle,
17030Sstevel@tonic-gate int qop_req,
17040Sstevel@tonic-gate const gss_buffer_t message_buffer,
17050Sstevel@tonic-gate gss_buffer_t msg_token)
17060Sstevel@tonic-gate {
17070Sstevel@tonic-gate if (context_handle == GSS_C_NO_CONTEXT)
17080Sstevel@tonic-gate return (GSS_S_FAILURE);
17090Sstevel@tonic-gate return (KGSS_SIGN(minor_status, context_handle, qop_req,
17100Sstevel@tonic-gate message_buffer, msg_token));
17110Sstevel@tonic-gate }
17120Sstevel@tonic-gate
17130Sstevel@tonic-gate /*ARGSUSED*/
17140Sstevel@tonic-gate static OM_uint32
kgss_verify_wrapped(void * private,OM_uint32 * minor_status,const gss_ctx_id_t ctx_handle,const gss_buffer_t message_buffer,const gss_buffer_t token_buffer,int * qop_state,OM_uint32 gssd_context_verifier)17150Sstevel@tonic-gate kgss_verify_wrapped(void *private,
17160Sstevel@tonic-gate OM_uint32 *minor_status,
17170Sstevel@tonic-gate const gss_ctx_id_t ctx_handle,
17180Sstevel@tonic-gate const gss_buffer_t message_buffer,
17190Sstevel@tonic-gate const gss_buffer_t token_buffer,
17200Sstevel@tonic-gate int *qop_state,
17210Sstevel@tonic-gate OM_uint32 gssd_context_verifier)
17220Sstevel@tonic-gate {
17230Sstevel@tonic-gate CLIENT *clnt;
17240Sstevel@tonic-gate
17250Sstevel@tonic-gate gssd_ctx_id_t context_handle;
17260Sstevel@tonic-gate gss_verify_arg arg;
17270Sstevel@tonic-gate gss_verify_res res;
17280Sstevel@tonic-gate
17290Sstevel@tonic-gate context_handle = (gssd_ctx_id_t)KCTX_TO_GSSD_CTX(ctx_handle);
17300Sstevel@tonic-gate
17310Sstevel@tonic-gate /* get the client handle to GSSD */
17320Sstevel@tonic-gate
17330Sstevel@tonic-gate if ((clnt = getgssd_handle()) == NULL) {
17340Sstevel@tonic-gate GSSLOG(1, "kgss_verify: can't connect to server on %s\n",
17350Sstevel@tonic-gate server);
17360Sstevel@tonic-gate return (GSS_S_FAILURE);
17370Sstevel@tonic-gate }
17380Sstevel@tonic-gate
17390Sstevel@tonic-gate /* copy the procedure arguments into the rpc arg parameter */
17400Sstevel@tonic-gate
17410Sstevel@tonic-gate arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gss_ctx_id_t);
17420Sstevel@tonic-gate arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
17430Sstevel@tonic-gate
17440Sstevel@tonic-gate arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t);
17450Sstevel@tonic-gate arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
17460Sstevel@tonic-gate arg.gssd_context_verifier = gssd_context_verifier;
17470Sstevel@tonic-gate
17480Sstevel@tonic-gate arg.message_buffer.GSS_BUFFER_T_len = (uint_t)message_buffer->length;
17490Sstevel@tonic-gate arg.message_buffer.GSS_BUFFER_T_val = (char *)message_buffer->value;
17500Sstevel@tonic-gate
17510Sstevel@tonic-gate arg.token_buffer.GSS_BUFFER_T_len = (uint_t)token_buffer->length;
17520Sstevel@tonic-gate arg.token_buffer.GSS_BUFFER_T_val = (char *)token_buffer->value;
17530Sstevel@tonic-gate
17540Sstevel@tonic-gate /* call the remote procedure */
17550Sstevel@tonic-gate
17560Sstevel@tonic-gate bzero((caddr_t)&res, sizeof (res));
17570Sstevel@tonic-gate if (gss_verify_1(&arg, &res, clnt) != RPC_SUCCESS) {
17580Sstevel@tonic-gate
17590Sstevel@tonic-gate /*
17600Sstevel@tonic-gate * if the RPC call times out, null out all return arguments, set
17610Sstevel@tonic-gate * minor_status to its maximum value, and return GSS_S_FAILURE
17620Sstevel@tonic-gate */
17630Sstevel@tonic-gate
17640Sstevel@tonic-gate if (minor_status != NULL)
17650Sstevel@tonic-gate *minor_status = DEFAULT_MINOR_STAT;
17660Sstevel@tonic-gate if (qop_state != NULL)
17670Sstevel@tonic-gate *qop_state = 0;
17680Sstevel@tonic-gate
17690Sstevel@tonic-gate killgssd_handle(clnt);
17700Sstevel@tonic-gate GSSLOG0(1, "kgss_verify: RPC call times out\n");
17710Sstevel@tonic-gate return (GSS_S_FAILURE);
17720Sstevel@tonic-gate }
17730Sstevel@tonic-gate
17740Sstevel@tonic-gate /* copy the rpc results into the return arguments */
17750Sstevel@tonic-gate
17760Sstevel@tonic-gate if (minor_status != NULL)
17770Sstevel@tonic-gate *minor_status = res.minor_status;
17780Sstevel@tonic-gate
17790Sstevel@tonic-gate if (qop_state != NULL)
17800Sstevel@tonic-gate *qop_state = res.qop_state;
17810Sstevel@tonic-gate
17820Sstevel@tonic-gate /* return with status returned in rpc call */
17830Sstevel@tonic-gate
17840Sstevel@tonic-gate killgssd_handle(clnt);
17850Sstevel@tonic-gate return (res.status);
17860Sstevel@tonic-gate
17870Sstevel@tonic-gate }
17880Sstevel@tonic-gate
17890Sstevel@tonic-gate OM_uint32
kgss_verify(OM_uint32 * minor_status,const gss_ctx_id_t context_handle,const gss_buffer_t message_buffer,const gss_buffer_t token_buffer,int * qop_state)17900Sstevel@tonic-gate kgss_verify(OM_uint32 *minor_status,
17910Sstevel@tonic-gate const gss_ctx_id_t context_handle,
17920Sstevel@tonic-gate const gss_buffer_t message_buffer,
17930Sstevel@tonic-gate const gss_buffer_t token_buffer,
17940Sstevel@tonic-gate int *qop_state)
17950Sstevel@tonic-gate {
17960Sstevel@tonic-gate if (context_handle == GSS_C_NO_CONTEXT)
17970Sstevel@tonic-gate return (GSS_S_FAILURE);
17980Sstevel@tonic-gate return (KGSS_VERIFY(minor_status, context_handle,
17990Sstevel@tonic-gate message_buffer,
18000Sstevel@tonic-gate token_buffer,
18010Sstevel@tonic-gate qop_state));
18020Sstevel@tonic-gate }
18030Sstevel@tonic-gate
18040Sstevel@tonic-gate /* EXPORT DELETE START */
18050Sstevel@tonic-gate
18060Sstevel@tonic-gate /*ARGSUSED*/
18070Sstevel@tonic-gate static OM_uint32
kgss_seal_wrapped(void * private,OM_uint32 * minor_status,const gss_ctx_id_t ctx_handle,int conf_req_flag,int qop_req,const gss_buffer_t input_message_buffer,int * conf_state,gss_buffer_t output_message_buffer,OM_uint32 gssd_context_verifier)18080Sstevel@tonic-gate kgss_seal_wrapped(void *private,
18090Sstevel@tonic-gate OM_uint32 *minor_status,
18100Sstevel@tonic-gate const gss_ctx_id_t ctx_handle,
18110Sstevel@tonic-gate int conf_req_flag,
18120Sstevel@tonic-gate int qop_req,
18130Sstevel@tonic-gate const gss_buffer_t input_message_buffer,
18140Sstevel@tonic-gate int *conf_state,
18150Sstevel@tonic-gate gss_buffer_t output_message_buffer,
18160Sstevel@tonic-gate OM_uint32 gssd_context_verifier)
18170Sstevel@tonic-gate {
18180Sstevel@tonic-gate CLIENT *clnt;
18190Sstevel@tonic-gate gssd_ctx_id_t context_handle;
18200Sstevel@tonic-gate
18210Sstevel@tonic-gate gss_seal_arg arg;
18220Sstevel@tonic-gate gss_seal_res res;
18230Sstevel@tonic-gate
18240Sstevel@tonic-gate context_handle = (gssd_ctx_id_t)KCTX_TO_GSSD_CTX(ctx_handle);
18250Sstevel@tonic-gate
18260Sstevel@tonic-gate /* get the client handle to GSSD */
18270Sstevel@tonic-gate
18280Sstevel@tonic-gate if ((clnt = getgssd_handle()) == NULL) {
18290Sstevel@tonic-gate GSSLOG(1, "kgss_seal: can't connect to server on %s\n", server);
18300Sstevel@tonic-gate return (GSS_S_FAILURE);
18310Sstevel@tonic-gate }
18320Sstevel@tonic-gate
18330Sstevel@tonic-gate /* copy the procedure arguments into the rpc arg parameter */
18340Sstevel@tonic-gate
18350Sstevel@tonic-gate arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gss_ctx_id_t);
18360Sstevel@tonic-gate arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
18370Sstevel@tonic-gate
18380Sstevel@tonic-gate arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (OM_uint32);
18390Sstevel@tonic-gate arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
18400Sstevel@tonic-gate arg.gssd_context_verifier = gssd_context_verifier;
18410Sstevel@tonic-gate
18420Sstevel@tonic-gate arg.conf_req_flag = conf_req_flag;
18430Sstevel@tonic-gate
18440Sstevel@tonic-gate arg.qop_req = qop_req;
18450Sstevel@tonic-gate
18460Sstevel@tonic-gate arg.input_message_buffer.GSS_BUFFER_T_len =
18470Sstevel@tonic-gate (uint_t)input_message_buffer->length;
18480Sstevel@tonic-gate
18490Sstevel@tonic-gate arg.input_message_buffer.GSS_BUFFER_T_val =
18500Sstevel@tonic-gate (char *)input_message_buffer->value;
18510Sstevel@tonic-gate
18520Sstevel@tonic-gate /* call the remote procedure */
18530Sstevel@tonic-gate
18540Sstevel@tonic-gate bzero((caddr_t)&res, sizeof (res));
18550Sstevel@tonic-gate if (gss_seal_1(&arg, &res, clnt) != RPC_SUCCESS) {
18560Sstevel@tonic-gate
18570Sstevel@tonic-gate /*
18580Sstevel@tonic-gate * if the RPC call times out, null out all return arguments, set
18590Sstevel@tonic-gate * minor_status to its maximum value, and return GSS_S_FAILURE
18600Sstevel@tonic-gate */
18610Sstevel@tonic-gate
18620Sstevel@tonic-gate if (minor_status != NULL)
18630Sstevel@tonic-gate *minor_status = DEFAULT_MINOR_STAT;
18640Sstevel@tonic-gate if (conf_state != NULL)
18650Sstevel@tonic-gate *conf_state = 0;
18660Sstevel@tonic-gate if (output_message_buffer != NULL)
18670Sstevel@tonic-gate output_message_buffer->length = 0;
18680Sstevel@tonic-gate
18690Sstevel@tonic-gate killgssd_handle(clnt);
18700Sstevel@tonic-gate GSSLOG0(1, "kgss_seal: RPC call times out\n");
18710Sstevel@tonic-gate return (GSS_S_FAILURE);
18720Sstevel@tonic-gate }
18730Sstevel@tonic-gate
18740Sstevel@tonic-gate /* copy the rpc results into the return arguments */
18750Sstevel@tonic-gate
18760Sstevel@tonic-gate if (minor_status != NULL)
18770Sstevel@tonic-gate *minor_status = res.minor_status;
18780Sstevel@tonic-gate
18790Sstevel@tonic-gate if (conf_state != NULL)
18800Sstevel@tonic-gate *conf_state = res.conf_state;
18810Sstevel@tonic-gate
18820Sstevel@tonic-gate if (output_message_buffer != NULL) {
18830Sstevel@tonic-gate output_message_buffer->length =
18840Sstevel@tonic-gate res.output_message_buffer.GSS_BUFFER_T_len;
18850Sstevel@tonic-gate
18860Sstevel@tonic-gate output_message_buffer->value =
18870Sstevel@tonic-gate (void *) MALLOC(output_message_buffer->length);
18880Sstevel@tonic-gate (void) memcpy(output_message_buffer->value,
18890Sstevel@tonic-gate res.output_message_buffer.GSS_BUFFER_T_val,
18900Sstevel@tonic-gate output_message_buffer->length);
18910Sstevel@tonic-gate }
18920Sstevel@tonic-gate
18930Sstevel@tonic-gate /*
18940Sstevel@tonic-gate * free the memory allocated for the results and return with the status
18950Sstevel@tonic-gate * received in the rpc call
18960Sstevel@tonic-gate */
18970Sstevel@tonic-gate
18980Sstevel@tonic-gate clnt_freeres(clnt, xdr_gss_seal_res, (caddr_t)&res);
18990Sstevel@tonic-gate killgssd_handle(clnt);
19000Sstevel@tonic-gate return (res.status);
19010Sstevel@tonic-gate }
19020Sstevel@tonic-gate
19030Sstevel@tonic-gate /*ARGSUSED*/
19040Sstevel@tonic-gate OM_uint32
kgss_seal(OM_uint32 * minor_status,const gss_ctx_id_t context_handle,int conf_req_flag,int qop_req,const gss_buffer_t input_message_buffer,int * conf_state,gss_buffer_t output_message_buffer)19050Sstevel@tonic-gate kgss_seal(OM_uint32 *minor_status,
19060Sstevel@tonic-gate const gss_ctx_id_t context_handle,
19070Sstevel@tonic-gate int conf_req_flag,
19080Sstevel@tonic-gate int qop_req,
19090Sstevel@tonic-gate const gss_buffer_t input_message_buffer,
19100Sstevel@tonic-gate int *conf_state,
19110Sstevel@tonic-gate gss_buffer_t output_message_buffer)
19120Sstevel@tonic-gate
19130Sstevel@tonic-gate {
19140Sstevel@tonic-gate if (context_handle == GSS_C_NO_CONTEXT)
19150Sstevel@tonic-gate return (GSS_S_FAILURE);
19160Sstevel@tonic-gate return (KGSS_SEAL(minor_status, context_handle,
19170Sstevel@tonic-gate conf_req_flag, qop_req,
19180Sstevel@tonic-gate input_message_buffer, conf_state,
19190Sstevel@tonic-gate output_message_buffer));
19200Sstevel@tonic-gate }
19210Sstevel@tonic-gate
19220Sstevel@tonic-gate /*ARGSUSED*/
19230Sstevel@tonic-gate static OM_uint32
kgss_unseal_wrapped(void * private,OM_uint32 * minor_status,const gss_ctx_id_t ctx_handle,const gss_buffer_t input_message_buffer,gss_buffer_t output_message_buffer,int * conf_state,int * qop_state,OM_uint32 gssd_context_verifier)19240Sstevel@tonic-gate kgss_unseal_wrapped(void *private,
19250Sstevel@tonic-gate OM_uint32 *minor_status,
19260Sstevel@tonic-gate const gss_ctx_id_t ctx_handle,
19270Sstevel@tonic-gate const gss_buffer_t input_message_buffer,
19280Sstevel@tonic-gate gss_buffer_t output_message_buffer,
19290Sstevel@tonic-gate int *conf_state,
19300Sstevel@tonic-gate int *qop_state,
19310Sstevel@tonic-gate OM_uint32 gssd_context_verifier)
19320Sstevel@tonic-gate {
19330Sstevel@tonic-gate CLIENT *clnt;
19340Sstevel@tonic-gate
19350Sstevel@tonic-gate gss_unseal_arg arg;
19360Sstevel@tonic-gate gss_unseal_res res;
19370Sstevel@tonic-gate gssd_ctx_id_t context_handle;
19380Sstevel@tonic-gate
19390Sstevel@tonic-gate context_handle = (gssd_ctx_id_t)KCTX_TO_GSSD_CTX(ctx_handle);
19400Sstevel@tonic-gate
19410Sstevel@tonic-gate /* get the client handle to GSSD */
19420Sstevel@tonic-gate
19430Sstevel@tonic-gate if ((clnt = getgssd_handle()) == NULL) {
19440Sstevel@tonic-gate GSSLOG(1, "kgss_unseal: can't connect to server on %s\n",
19450Sstevel@tonic-gate server);
19460Sstevel@tonic-gate return (GSS_S_FAILURE);
19470Sstevel@tonic-gate }
19480Sstevel@tonic-gate
19490Sstevel@tonic-gate /* copy the procedure arguments into the rpc arg parameter */
19500Sstevel@tonic-gate
19510Sstevel@tonic-gate arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gss_ctx_id_t);
19520Sstevel@tonic-gate arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
19530Sstevel@tonic-gate
19540Sstevel@tonic-gate arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t);
19550Sstevel@tonic-gate arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
19560Sstevel@tonic-gate arg.gssd_context_verifier = gssd_context_verifier;
19570Sstevel@tonic-gate
19580Sstevel@tonic-gate arg.input_message_buffer.GSS_BUFFER_T_len =
19590Sstevel@tonic-gate (uint_t)input_message_buffer->length;
19600Sstevel@tonic-gate
19610Sstevel@tonic-gate arg.input_message_buffer.GSS_BUFFER_T_val =
19620Sstevel@tonic-gate (char *)input_message_buffer->value;
19630Sstevel@tonic-gate
19640Sstevel@tonic-gate /* call the remote procedure */
19650Sstevel@tonic-gate
19660Sstevel@tonic-gate bzero((caddr_t)&res, sizeof (res));
19670Sstevel@tonic-gate if (gss_unseal_1(&arg, &res, clnt) != RPC_SUCCESS) {
19680Sstevel@tonic-gate
19690Sstevel@tonic-gate /*
19700Sstevel@tonic-gate * if the RPC call times out, null out all return arguments, set
19710Sstevel@tonic-gate * minor_status to its maximum value, and return GSS_S_FAILURE
19720Sstevel@tonic-gate */
19730Sstevel@tonic-gate
19740Sstevel@tonic-gate if (minor_status != NULL)
19750Sstevel@tonic-gate *minor_status = DEFAULT_MINOR_STAT;
19760Sstevel@tonic-gate if (output_message_buffer != NULL)
19770Sstevel@tonic-gate output_message_buffer->length = 0;
19780Sstevel@tonic-gate if (conf_state != NULL)
19790Sstevel@tonic-gate *conf_state = 0;
19800Sstevel@tonic-gate if (qop_state != NULL)
19810Sstevel@tonic-gate *qop_state = 0;
19820Sstevel@tonic-gate
19830Sstevel@tonic-gate killgssd_handle(clnt);
19840Sstevel@tonic-gate GSSLOG0(1, "kgss_unseal: RPC call times out\n");
19850Sstevel@tonic-gate return (GSS_S_FAILURE);
19860Sstevel@tonic-gate }
19870Sstevel@tonic-gate
19880Sstevel@tonic-gate /* copy the rpc results into the return arguments */
19890Sstevel@tonic-gate
19900Sstevel@tonic-gate if (minor_status != NULL)
19910Sstevel@tonic-gate *minor_status = res.minor_status;
19920Sstevel@tonic-gate
19930Sstevel@tonic-gate if (output_message_buffer != NULL) {
19940Sstevel@tonic-gate output_message_buffer->length =
19950Sstevel@tonic-gate res.output_message_buffer.GSS_BUFFER_T_len;
19960Sstevel@tonic-gate
19970Sstevel@tonic-gate output_message_buffer->value =
19980Sstevel@tonic-gate (void *) MALLOC(output_message_buffer->length);
19990Sstevel@tonic-gate (void) memcpy(output_message_buffer->value,
20000Sstevel@tonic-gate res.output_message_buffer.GSS_BUFFER_T_val,
20010Sstevel@tonic-gate output_message_buffer->length);
20020Sstevel@tonic-gate }
20030Sstevel@tonic-gate
20040Sstevel@tonic-gate if (conf_state != NULL)
20050Sstevel@tonic-gate *conf_state = res.conf_state;
20060Sstevel@tonic-gate
20070Sstevel@tonic-gate if (qop_state != NULL)
20080Sstevel@tonic-gate *qop_state = res.qop_state;
20090Sstevel@tonic-gate
20100Sstevel@tonic-gate /*
20110Sstevel@tonic-gate * free the memory allocated for the results and return with the
20120Sstevel@tonic-gate * status received in the rpc call
20130Sstevel@tonic-gate */
20140Sstevel@tonic-gate
20150Sstevel@tonic-gate clnt_freeres(clnt, xdr_gss_unseal_res, (caddr_t)&res);
20160Sstevel@tonic-gate killgssd_handle(clnt);
20170Sstevel@tonic-gate return (res.status);
20180Sstevel@tonic-gate }
20190Sstevel@tonic-gate
20200Sstevel@tonic-gate OM_uint32
kgss_unseal(OM_uint32 * minor_status,const gss_ctx_id_t context_handle,const gss_buffer_t input_message_buffer,const gss_buffer_t output_message_buffer,int * conf_state,int * qop_state)20210Sstevel@tonic-gate kgss_unseal(OM_uint32 *minor_status,
20220Sstevel@tonic-gate const gss_ctx_id_t context_handle,
20230Sstevel@tonic-gate const gss_buffer_t input_message_buffer,
20240Sstevel@tonic-gate const gss_buffer_t output_message_buffer,
20250Sstevel@tonic-gate int *conf_state,
20260Sstevel@tonic-gate int *qop_state)
20270Sstevel@tonic-gate {
20280Sstevel@tonic-gate
20290Sstevel@tonic-gate if (context_handle == GSS_C_NO_CONTEXT)
20300Sstevel@tonic-gate return (GSS_S_FAILURE);
20310Sstevel@tonic-gate
20320Sstevel@tonic-gate return (KGSS_UNSEAL(minor_status, context_handle, input_message_buffer,
20330Sstevel@tonic-gate output_message_buffer, conf_state, qop_state));
20340Sstevel@tonic-gate }
20350Sstevel@tonic-gate
20360Sstevel@tonic-gate /* EXPORT DELETE END */
20370Sstevel@tonic-gate
20380Sstevel@tonic-gate OM_uint32
kgss_display_status(minor_status,status_value,status_type,mech_type,message_context,status_string,uid)20390Sstevel@tonic-gate kgss_display_status(minor_status,
20400Sstevel@tonic-gate status_value,
20410Sstevel@tonic-gate status_type,
20420Sstevel@tonic-gate mech_type,
20430Sstevel@tonic-gate message_context,
20440Sstevel@tonic-gate status_string,
20450Sstevel@tonic-gate uid)
20460Sstevel@tonic-gate OM_uint32 *minor_status;
20470Sstevel@tonic-gate OM_uint32 status_value;
20480Sstevel@tonic-gate int status_type;
20490Sstevel@tonic-gate const gss_OID mech_type;
20500Sstevel@tonic-gate int *message_context;
20510Sstevel@tonic-gate gss_buffer_t status_string;
20520Sstevel@tonic-gate uid_t uid;
20530Sstevel@tonic-gate {
20540Sstevel@tonic-gate CLIENT *clnt;
20550Sstevel@tonic-gate
20560Sstevel@tonic-gate gss_display_status_arg arg;
20570Sstevel@tonic-gate gss_display_status_res res;
20580Sstevel@tonic-gate
20590Sstevel@tonic-gate /* get the client handle to GSSD */
20600Sstevel@tonic-gate
20610Sstevel@tonic-gate if ((clnt = getgssd_handle()) == NULL) {
20620Sstevel@tonic-gate GSSLOG(1, "kgss_display_status: can't connect to server on %s\n",
20630Sstevel@tonic-gate server);
20640Sstevel@tonic-gate return (GSS_S_FAILURE);
20650Sstevel@tonic-gate }
20660Sstevel@tonic-gate
20670Sstevel@tonic-gate /* copy the procedure arguments into the rpc arg parameter */
20680Sstevel@tonic-gate
20690Sstevel@tonic-gate arg.uid = (OM_uint32) uid;
20700Sstevel@tonic-gate
20710Sstevel@tonic-gate arg.status_value = status_value;
20720Sstevel@tonic-gate arg.status_type = status_type;
20730Sstevel@tonic-gate
20740Sstevel@tonic-gate arg.mech_type.GSS_OID_len = (uint_t)(mech_type != GSS_C_NULL_OID ?
20750Sstevel@tonic-gate mech_type->length : 0);
20760Sstevel@tonic-gate arg.mech_type.GSS_OID_val = (char *)(mech_type != GSS_C_NULL_OID ?
20770Sstevel@tonic-gate mech_type->elements : 0);
20780Sstevel@tonic-gate
20790Sstevel@tonic-gate arg.message_context = *message_context;
20800Sstevel@tonic-gate
20810Sstevel@tonic-gate /* call the remote procedure */
20820Sstevel@tonic-gate
20830Sstevel@tonic-gate if (message_context != NULL)
20840Sstevel@tonic-gate *message_context = 0;
20850Sstevel@tonic-gate if (status_string != NULL) {
20860Sstevel@tonic-gate status_string->length = 0;
20870Sstevel@tonic-gate status_string->value = NULL;
20880Sstevel@tonic-gate }
20890Sstevel@tonic-gate
20900Sstevel@tonic-gate bzero((caddr_t)&res, sizeof (res));
20910Sstevel@tonic-gate if (gss_display_status_1(&arg, &res, clnt) != RPC_SUCCESS) {
20920Sstevel@tonic-gate
20930Sstevel@tonic-gate /*
20940Sstevel@tonic-gate * if the RPC call times out, null out all return arguments, set
20950Sstevel@tonic-gate * minor_status to its maximum value, and return GSS_S_FAILURE
20960Sstevel@tonic-gate */
20970Sstevel@tonic-gate
20980Sstevel@tonic-gate if (minor_status != NULL)
20990Sstevel@tonic-gate *minor_status = DEFAULT_MINOR_STAT;
21000Sstevel@tonic-gate
21010Sstevel@tonic-gate killgssd_handle(clnt);
21020Sstevel@tonic-gate GSSLOG0(1, "kgss_display_status: RPC call time out\n");
21030Sstevel@tonic-gate return (GSS_S_FAILURE);
21040Sstevel@tonic-gate }
21050Sstevel@tonic-gate
21060Sstevel@tonic-gate
21070Sstevel@tonic-gate /* now process the results and pass them back to the caller */
21080Sstevel@tonic-gate
21090Sstevel@tonic-gate if (res.status == GSS_S_COMPLETE) {
21100Sstevel@tonic-gate if (minor_status != NULL)
21110Sstevel@tonic-gate *minor_status = res.minor_status;
21120Sstevel@tonic-gate if (message_context != NULL)
21130Sstevel@tonic-gate *message_context = res.message_context;
21140Sstevel@tonic-gate if (status_string != NULL) {
21150Sstevel@tonic-gate status_string->length =
21160Sstevel@tonic-gate (size_t)res.status_string.GSS_BUFFER_T_len;
21170Sstevel@tonic-gate status_string->value =
21180Sstevel@tonic-gate (void *) MALLOC(status_string->length);
21190Sstevel@tonic-gate (void) memcpy(status_string->value,
21200Sstevel@tonic-gate res.status_string.GSS_BUFFER_T_val,
21210Sstevel@tonic-gate status_string->length);
21220Sstevel@tonic-gate }
21230Sstevel@tonic-gate }
21240Sstevel@tonic-gate
21250Sstevel@tonic-gate clnt_freeres(clnt, xdr_gss_display_status_res, (caddr_t)&res);
21260Sstevel@tonic-gate killgssd_handle(clnt);
21270Sstevel@tonic-gate return (res.status);
21280Sstevel@tonic-gate }
21290Sstevel@tonic-gate
21300Sstevel@tonic-gate /*ARGSUSED*/
21310Sstevel@tonic-gate OM_uint32
kgss_indicate_mechs(minor_status,mech_set,uid)21320Sstevel@tonic-gate kgss_indicate_mechs(minor_status,
21330Sstevel@tonic-gate mech_set,
21340Sstevel@tonic-gate uid)
21350Sstevel@tonic-gate OM_uint32 *minor_status;
21360Sstevel@tonic-gate gss_OID_set *mech_set;
21370Sstevel@tonic-gate uid_t uid;
21380Sstevel@tonic-gate {
21390Sstevel@tonic-gate CLIENT *clnt;
21400Sstevel@tonic-gate void *arg;
21410Sstevel@tonic-gate gss_indicate_mechs_res res;
21420Sstevel@tonic-gate int i;
21430Sstevel@tonic-gate
21440Sstevel@tonic-gate /* get the client handle to GSSD */
21450Sstevel@tonic-gate
21460Sstevel@tonic-gate if ((clnt = getgssd_handle()) == NULL) {
21470Sstevel@tonic-gate GSSLOG(1, "kgss_indicate_mechs: can't connect to server on %s\n",
21480Sstevel@tonic-gate server);
21490Sstevel@tonic-gate return (GSS_S_FAILURE);
21500Sstevel@tonic-gate }
21510Sstevel@tonic-gate
21520Sstevel@tonic-gate bzero((caddr_t)&res, sizeof (res));
21530Sstevel@tonic-gate if (gss_indicate_mechs_1(&arg, &res, clnt) != RPC_SUCCESS) {
21540Sstevel@tonic-gate
21550Sstevel@tonic-gate /*
21560Sstevel@tonic-gate * if the RPC call times out, null out all return arguments, set
21570Sstevel@tonic-gate * minor_status to its maximum value, and return GSS_S_FAILURE
21580Sstevel@tonic-gate */
21590Sstevel@tonic-gate
21600Sstevel@tonic-gate if (minor_status != NULL)
21610Sstevel@tonic-gate *minor_status = DEFAULT_MINOR_STAT;
21620Sstevel@tonic-gate if (mech_set != NULL)
21630Sstevel@tonic-gate *mech_set = NULL;
21640Sstevel@tonic-gate
21650Sstevel@tonic-gate killgssd_handle(clnt);
21660Sstevel@tonic-gate GSSLOG0(1, "kgss_indicate_mechs: RPC call times out\n");
21670Sstevel@tonic-gate return (GSS_S_FAILURE);
21680Sstevel@tonic-gate }
21690Sstevel@tonic-gate
21700Sstevel@tonic-gate /* copy the rpc results into the return arguments */
21710Sstevel@tonic-gate
21720Sstevel@tonic-gate if (minor_status != NULL)
21730Sstevel@tonic-gate *minor_status = res.minor_status;
21740Sstevel@tonic-gate
21750Sstevel@tonic-gate if (mech_set != NULL) {
21760Sstevel@tonic-gate *mech_set = (gss_OID_set) MALLOC(sizeof (gss_OID_set_desc));
21770Sstevel@tonic-gate (*mech_set)->count = res.mech_set.GSS_OID_SET_len;
21780Sstevel@tonic-gate (*mech_set)->elements = (void *)
21790Sstevel@tonic-gate MALLOC ((*mech_set)->count * sizeof (gss_OID_desc));
21800Sstevel@tonic-gate for (i = 0; i < (*mech_set)->count; i++) {
21810Sstevel@tonic-gate (*mech_set)->elements[i].length =
21820Sstevel@tonic-gate res.mech_set.GSS_OID_SET_val[i].GSS_OID_len;
21830Sstevel@tonic-gate (*mech_set)->elements[i].elements = (void *)
21840Sstevel@tonic-gate MALLOC ((*mech_set)->elements[i].length);
21850Sstevel@tonic-gate (void) memcpy((*mech_set)->elements[i].elements,
21860Sstevel@tonic-gate res.mech_set.GSS_OID_SET_val[i].GSS_OID_val,
21870Sstevel@tonic-gate (*mech_set)->elements[i].length);
21880Sstevel@tonic-gate }
21890Sstevel@tonic-gate }
21900Sstevel@tonic-gate
21910Sstevel@tonic-gate /*
21920Sstevel@tonic-gate * free the memory allocated for the results and return with the status
21930Sstevel@tonic-gate * received in the rpc call
21940Sstevel@tonic-gate */
21950Sstevel@tonic-gate
21960Sstevel@tonic-gate clnt_freeres(clnt, xdr_gss_indicate_mechs_res, (caddr_t)&res);
21970Sstevel@tonic-gate killgssd_handle(clnt);
21980Sstevel@tonic-gate return (res.status);
21990Sstevel@tonic-gate }
22000Sstevel@tonic-gate
22010Sstevel@tonic-gate
22020Sstevel@tonic-gate OM_uint32
kgss_inquire_cred_wrapped(minor_status,cred_handle,gssd_cred_verifier,name,lifetime,cred_usage,mechanisms,uid)22030Sstevel@tonic-gate kgss_inquire_cred_wrapped(minor_status,
22040Sstevel@tonic-gate cred_handle,
22050Sstevel@tonic-gate gssd_cred_verifier,
22060Sstevel@tonic-gate name,
22070Sstevel@tonic-gate lifetime,
22080Sstevel@tonic-gate cred_usage,
22090Sstevel@tonic-gate mechanisms,
22100Sstevel@tonic-gate uid)
22110Sstevel@tonic-gate OM_uint32 *minor_status;
22120Sstevel@tonic-gate const gssd_cred_id_t cred_handle;
22130Sstevel@tonic-gate OM_uint32 gssd_cred_verifier;
22140Sstevel@tonic-gate gss_name_t *name;
22150Sstevel@tonic-gate OM_uint32 *lifetime;
22160Sstevel@tonic-gate int *cred_usage;
22170Sstevel@tonic-gate gss_OID_set *mechanisms;
22180Sstevel@tonic-gate uid_t uid;
22190Sstevel@tonic-gate {
22200Sstevel@tonic-gate CLIENT *clnt;
22210Sstevel@tonic-gate
22220Sstevel@tonic-gate OM_uint32 minor_status_temp;
22230Sstevel@tonic-gate gss_buffer_desc external_name;
22240Sstevel@tonic-gate gss_OID_desc name_type;
22250Sstevel@tonic-gate int i;
22260Sstevel@tonic-gate
22270Sstevel@tonic-gate gss_inquire_cred_arg arg;
22280Sstevel@tonic-gate gss_inquire_cred_res res;
22290Sstevel@tonic-gate
22300Sstevel@tonic-gate /*
22310Sstevel@tonic-gate * NULL the params here once
22320Sstevel@tonic-gate * If there are errors then we won't
22330Sstevel@tonic-gate * have to do it for every error
22340Sstevel@tonic-gate * case
22350Sstevel@tonic-gate */
22360Sstevel@tonic-gate if (minor_status != NULL)
22370Sstevel@tonic-gate *minor_status = DEFAULT_MINOR_STAT;
22380Sstevel@tonic-gate if (name != NULL)
22390Sstevel@tonic-gate *name = NULL;
22400Sstevel@tonic-gate if (lifetime != NULL)
22410Sstevel@tonic-gate *lifetime = 0;
22420Sstevel@tonic-gate if (cred_usage != NULL)
22430Sstevel@tonic-gate *cred_usage = 0;
22440Sstevel@tonic-gate if (mechanisms != NULL)
22450Sstevel@tonic-gate *mechanisms = NULL;
22460Sstevel@tonic-gate
22470Sstevel@tonic-gate /* get the client handle to GSSD */
22480Sstevel@tonic-gate
22490Sstevel@tonic-gate if ((clnt = getgssd_handle()) == NULL) {
22500Sstevel@tonic-gate GSSLOG(1, "kgss_inquire_cred: can't connect to server on %s\n",
22510Sstevel@tonic-gate server);
22520Sstevel@tonic-gate return (GSS_S_FAILURE);
22530Sstevel@tonic-gate }
22540Sstevel@tonic-gate
22550Sstevel@tonic-gate
22560Sstevel@tonic-gate /* copy the procedure arguments into the rpc arg parameter */
22570Sstevel@tonic-gate
22580Sstevel@tonic-gate arg.uid = (OM_uint32) uid;
22590Sstevel@tonic-gate
22600Sstevel@tonic-gate arg.cred_handle.GSS_CRED_ID_T_len =
22610Sstevel@tonic-gate cred_handle == (gssd_cred_id_t)GSS_C_NO_CREDENTIAL ?
22620Sstevel@tonic-gate 0 : (uint_t)sizeof (gssd_cred_id_t);
22630Sstevel@tonic-gate arg.cred_handle.GSS_CRED_ID_T_val = (char *)&cred_handle;
22640Sstevel@tonic-gate arg.gssd_cred_verifier = gssd_cred_verifier;
22650Sstevel@tonic-gate
22660Sstevel@tonic-gate /* call the remote procedure */
22670Sstevel@tonic-gate
22680Sstevel@tonic-gate bzero((caddr_t)&res, sizeof (res));
22690Sstevel@tonic-gate if (gss_inquire_cred_1(&arg, &res, clnt) != RPC_SUCCESS) {
22700Sstevel@tonic-gate
22710Sstevel@tonic-gate /*
22720Sstevel@tonic-gate * if the RPC call times out
22730Sstevel@tonic-gate * kill the handle and return GSS_S_FAILURE
22740Sstevel@tonic-gate * the parameters have been set to NULL already
22750Sstevel@tonic-gate */
22760Sstevel@tonic-gate
22770Sstevel@tonic-gate killgssd_handle(clnt);
22780Sstevel@tonic-gate GSSLOG0(1, "kgss_inquire_cred: RPC call times out\n");
22790Sstevel@tonic-gate return (GSS_S_FAILURE);
22800Sstevel@tonic-gate }
22810Sstevel@tonic-gate
22820Sstevel@tonic-gate /* copy the rpc results into the return arguments */
22830Sstevel@tonic-gate
22840Sstevel@tonic-gate if (minor_status != NULL)
22850Sstevel@tonic-gate *minor_status = res.minor_status;
22860Sstevel@tonic-gate
22870Sstevel@tonic-gate /* convert name from external to internal format */
22880Sstevel@tonic-gate
22890Sstevel@tonic-gate if (name != NULL) {
22900Sstevel@tonic-gate external_name.length = res.name.GSS_BUFFER_T_len;
22910Sstevel@tonic-gate external_name.value = res.name.GSS_BUFFER_T_val;
22920Sstevel@tonic-gate
22930Sstevel@tonic-gate /*
22940Sstevel@tonic-gate * we can pass a pointer to res structure
22950Sstevel@tonic-gate * since gss_import_name treats the name_type
22960Sstevel@tonic-gate * parameter as read only and performs a copy
22970Sstevel@tonic-gate */
22980Sstevel@tonic-gate
22990Sstevel@tonic-gate name_type.length = res.name_type.GSS_OID_len;
23000Sstevel@tonic-gate name_type.elements = (void *)res.name_type.GSS_OID_val;
23010Sstevel@tonic-gate
23020Sstevel@tonic-gate if (gss_import_name(&minor_status_temp, &external_name,
23030Sstevel@tonic-gate &name_type, name) != GSS_S_COMPLETE) {
23040Sstevel@tonic-gate
23050Sstevel@tonic-gate *minor_status = (OM_uint32) minor_status_temp;
23060Sstevel@tonic-gate clnt_freeres(clnt, xdr_gss_inquire_cred_res,
23070Sstevel@tonic-gate (caddr_t)&res);
23080Sstevel@tonic-gate killgssd_handle(clnt);
23090Sstevel@tonic-gate GSSLOG0(1, "kgss_inquire_cred: import name fails\n");
23100Sstevel@tonic-gate return ((OM_uint32) GSS_S_FAILURE);
23110Sstevel@tonic-gate }
23120Sstevel@tonic-gate }
23130Sstevel@tonic-gate
23140Sstevel@tonic-gate if (lifetime != NULL)
23150Sstevel@tonic-gate *lifetime = res.lifetime;
23160Sstevel@tonic-gate
23170Sstevel@tonic-gate if (cred_usage != NULL)
23180Sstevel@tonic-gate *cred_usage = res.cred_usage;
23190Sstevel@tonic-gate
23200Sstevel@tonic-gate if (res.status == GSS_S_COMPLETE &&
23210Sstevel@tonic-gate res.mechanisms.GSS_OID_SET_len != 0 &&
23220Sstevel@tonic-gate mechanisms != NULL) {
23230Sstevel@tonic-gate *mechanisms = (gss_OID_set) MALLOC(sizeof (gss_OID_set_desc));
23240Sstevel@tonic-gate (*mechanisms)->count =
23250Sstevel@tonic-gate (int)res.mechanisms.GSS_OID_SET_len;
23260Sstevel@tonic-gate (*mechanisms)->elements = (gss_OID)
23270Sstevel@tonic-gate MALLOC(sizeof (gss_OID_desc) * (*mechanisms)->count);
23280Sstevel@tonic-gate
23290Sstevel@tonic-gate for (i = 0; i < (*mechanisms)->count; i++) {
23300Sstevel@tonic-gate (*mechanisms)->elements[i].length = (OM_uint32)
23310Sstevel@tonic-gate res.mechanisms.GSS_OID_SET_val[i].GSS_OID_len;
23320Sstevel@tonic-gate (*mechanisms)->elements[i].elements =
23330Sstevel@tonic-gate (void *) MALLOC((*mechanisms)->elements[i].length);
23340Sstevel@tonic-gate (void) memcpy((*mechanisms)->elements[i].elements,
23350Sstevel@tonic-gate res.mechanisms.GSS_OID_SET_val[i].GSS_OID_val,
23360Sstevel@tonic-gate (*mechanisms)->elements[i].length);
23370Sstevel@tonic-gate }
23380Sstevel@tonic-gate } else {
23390Sstevel@tonic-gate if (res.status == GSS_S_COMPLETE &&
23400Sstevel@tonic-gate mechanisms != NULL)
23410Sstevel@tonic-gate (*mechanisms) = NULL;
23420Sstevel@tonic-gate }
23430Sstevel@tonic-gate /*
23440Sstevel@tonic-gate * free the memory allocated for the results and return with the status
23450Sstevel@tonic-gate * received in the rpc call
23460Sstevel@tonic-gate */
23470Sstevel@tonic-gate
23480Sstevel@tonic-gate clnt_freeres(clnt, xdr_gss_inquire_cred_res, (caddr_t)&res);
23490Sstevel@tonic-gate killgssd_handle(clnt);
23500Sstevel@tonic-gate return (res.status);
23510Sstevel@tonic-gate
23520Sstevel@tonic-gate }
23530Sstevel@tonic-gate
23540Sstevel@tonic-gate OM_uint32
kgss_inquire_cred(minor_status,cred_handle,name,lifetime,cred_usage,mechanisms,uid)23550Sstevel@tonic-gate kgss_inquire_cred(minor_status,
23560Sstevel@tonic-gate cred_handle,
23570Sstevel@tonic-gate name,
23580Sstevel@tonic-gate lifetime,
23590Sstevel@tonic-gate cred_usage,
23600Sstevel@tonic-gate mechanisms,
23610Sstevel@tonic-gate uid)
23620Sstevel@tonic-gate OM_uint32 *minor_status;
23630Sstevel@tonic-gate const gss_cred_id_t cred_handle;
23640Sstevel@tonic-gate gss_name_t *name;
23650Sstevel@tonic-gate OM_uint32 *lifetime;
23660Sstevel@tonic-gate int *cred_usage;
23670Sstevel@tonic-gate gss_OID_set * mechanisms;
23680Sstevel@tonic-gate uid_t uid;
23690Sstevel@tonic-gate {
23700Sstevel@tonic-gate
23710Sstevel@tonic-gate OM_uint32 gssd_cred_verifier;
23720Sstevel@tonic-gate OM_uint32 gssd_cred_handle;
23730Sstevel@tonic-gate
23740Sstevel@tonic-gate gssd_cred_verifier = KCRED_TO_CREDV(cred_handle);
23750Sstevel@tonic-gate gssd_cred_handle = KCRED_TO_CRED(cred_handle);
23760Sstevel@tonic-gate
23770Sstevel@tonic-gate return (kgss_inquire_cred_wrapped(minor_status,
23780Sstevel@tonic-gate gssd_cred_handle, gssd_cred_verifier,
23790Sstevel@tonic-gate name, lifetime, cred_usage, mechanisms, uid));
23800Sstevel@tonic-gate }
23810Sstevel@tonic-gate
23820Sstevel@tonic-gate OM_uint32
kgss_inquire_cred_by_mech_wrapped(minor_status,cred_handle,gssd_cred_verifier,mech_type,uid)23830Sstevel@tonic-gate kgss_inquire_cred_by_mech_wrapped(minor_status,
23840Sstevel@tonic-gate cred_handle,
23850Sstevel@tonic-gate gssd_cred_verifier,
23860Sstevel@tonic-gate mech_type,
23870Sstevel@tonic-gate uid)
23880Sstevel@tonic-gate OM_uint32 *minor_status;
23890Sstevel@tonic-gate gssd_cred_id_t cred_handle;
23900Sstevel@tonic-gate OM_uint32 gssd_cred_verifier;
23910Sstevel@tonic-gate gss_OID mech_type;
23920Sstevel@tonic-gate uid_t uid;
23930Sstevel@tonic-gate {
23940Sstevel@tonic-gate CLIENT *clnt;
23950Sstevel@tonic-gate
23960Sstevel@tonic-gate gss_inquire_cred_by_mech_arg arg;
23970Sstevel@tonic-gate gss_inquire_cred_by_mech_res res;
23980Sstevel@tonic-gate
23990Sstevel@tonic-gate /* get the client handle to GSSD */
24000Sstevel@tonic-gate
24010Sstevel@tonic-gate if ((clnt = getgssd_handle()) == NULL) {
24020Sstevel@tonic-gate GSSLOG(1, "kgss_inquire_cred: can't connect to server on %s\n",
24030Sstevel@tonic-gate server);
24040Sstevel@tonic-gate return (GSS_S_FAILURE);
24050Sstevel@tonic-gate }
24060Sstevel@tonic-gate
24070Sstevel@tonic-gate
24080Sstevel@tonic-gate /* copy the procedure arguments into the rpc arg parameter */
24090Sstevel@tonic-gate
24100Sstevel@tonic-gate arg.uid = (OM_uint32) uid;
24110Sstevel@tonic-gate
24120Sstevel@tonic-gate arg.cred_handle.GSS_CRED_ID_T_len =
24130Sstevel@tonic-gate cred_handle == (gssd_cred_id_t)GSS_C_NO_CREDENTIAL ?
24140Sstevel@tonic-gate 0 : (uint_t)sizeof (gssd_cred_id_t);
24150Sstevel@tonic-gate arg.cred_handle.GSS_CRED_ID_T_val = (char *)&cred_handle;
24160Sstevel@tonic-gate arg.gssd_cred_verifier = gssd_cred_verifier;
24170Sstevel@tonic-gate
24180Sstevel@tonic-gate arg.mech_type.GSS_OID_len =
24190Sstevel@tonic-gate (uint_t)(mech_type != GSS_C_NULL_OID ?
24200Sstevel@tonic-gate mech_type->length : 0);
24210Sstevel@tonic-gate arg.mech_type.GSS_OID_val =
24220Sstevel@tonic-gate (char *)(mech_type != GSS_C_NULL_OID ?
24230Sstevel@tonic-gate mech_type->elements : 0);
24240Sstevel@tonic-gate /* call the remote procedure */
24250Sstevel@tonic-gate
24260Sstevel@tonic-gate bzero((caddr_t)&res, sizeof (res));
24270Sstevel@tonic-gate if (gss_inquire_cred_by_mech_1(&arg, &res, clnt) != RPC_SUCCESS) {
24280Sstevel@tonic-gate
24290Sstevel@tonic-gate /*
24300Sstevel@tonic-gate * if the RPC call times out, null out all return arguments, set
24310Sstevel@tonic-gate * minor_status to its maximum value, and return GSS_S_FAILURE
24320Sstevel@tonic-gate */
24330Sstevel@tonic-gate
24340Sstevel@tonic-gate if (minor_status != NULL)
24350Sstevel@tonic-gate *minor_status = DEFAULT_MINOR_STAT;
24360Sstevel@tonic-gate killgssd_handle(clnt);
24370Sstevel@tonic-gate GSSLOG0(1, "kgss_inquire_cred: RPC call times out\n");
24380Sstevel@tonic-gate return (GSS_S_FAILURE);
24390Sstevel@tonic-gate }
24400Sstevel@tonic-gate
24410Sstevel@tonic-gate /* copy the rpc results into the return arguments */
24420Sstevel@tonic-gate
24430Sstevel@tonic-gate if (minor_status != NULL)
24440Sstevel@tonic-gate *minor_status = res.minor_status;
24450Sstevel@tonic-gate
24460Sstevel@tonic-gate clnt_freeres(clnt, xdr_gss_inquire_cred_by_mech_res, (caddr_t)&res);
24470Sstevel@tonic-gate killgssd_handle(clnt);
24480Sstevel@tonic-gate return (res.status);
24490Sstevel@tonic-gate
24500Sstevel@tonic-gate }
24510Sstevel@tonic-gate
24520Sstevel@tonic-gate OM_uint32
kgss_inquire_cred_by_mech(minor_status,cred_handle,mech_type,uid)24530Sstevel@tonic-gate kgss_inquire_cred_by_mech(minor_status,
24540Sstevel@tonic-gate cred_handle,
24550Sstevel@tonic-gate mech_type,
24560Sstevel@tonic-gate uid)
24570Sstevel@tonic-gate OM_uint32 *minor_status;
24580Sstevel@tonic-gate gss_cred_id_t cred_handle;
24590Sstevel@tonic-gate gss_OID mech_type;
24600Sstevel@tonic-gate uid_t uid;
24610Sstevel@tonic-gate {
24620Sstevel@tonic-gate
24630Sstevel@tonic-gate OM_uint32 gssd_cred_verifier;
24640Sstevel@tonic-gate OM_uint32 gssd_cred_handle;
24650Sstevel@tonic-gate
24660Sstevel@tonic-gate gssd_cred_verifier = KCRED_TO_CREDV(cred_handle);
24670Sstevel@tonic-gate gssd_cred_handle = KCRED_TO_CRED(cred_handle);
24680Sstevel@tonic-gate
24690Sstevel@tonic-gate return (kgss_inquire_cred_by_mech_wrapped(minor_status,
24700Sstevel@tonic-gate gssd_cred_handle, gssd_cred_verifier,
24710Sstevel@tonic-gate mech_type, uid));
24720Sstevel@tonic-gate }
24730Sstevel@tonic-gate
24740Sstevel@tonic-gate OM_uint32
kgsscred_expname_to_unix_cred(expName,uidOut,gidOut,gids,gidsLen,uid)24750Sstevel@tonic-gate kgsscred_expname_to_unix_cred(expName, uidOut, gidOut, gids, gidsLen, uid)
24760Sstevel@tonic-gate const gss_buffer_t expName;
24770Sstevel@tonic-gate uid_t *uidOut;
24780Sstevel@tonic-gate gid_t *gidOut;
24790Sstevel@tonic-gate gid_t *gids[];
24800Sstevel@tonic-gate int *gidsLen;
24810Sstevel@tonic-gate uid_t uid;
24820Sstevel@tonic-gate {
24830Sstevel@tonic-gate CLIENT *clnt;
24840Sstevel@tonic-gate gsscred_expname_to_unix_cred_arg args;
24850Sstevel@tonic-gate gsscred_expname_to_unix_cred_res res;
24860Sstevel@tonic-gate
24870Sstevel@tonic-gate /* check input/output parameters */
24880Sstevel@tonic-gate if (expName == NULL || expName->value == NULL)
24890Sstevel@tonic-gate return (GSS_S_CALL_INACCESSIBLE_READ);
24900Sstevel@tonic-gate
24910Sstevel@tonic-gate if (uidOut == NULL)
24920Sstevel@tonic-gate return (GSS_S_CALL_INACCESSIBLE_WRITE);
24930Sstevel@tonic-gate
24940Sstevel@tonic-gate /* NULL out output parameters */
24950Sstevel@tonic-gate *uidOut = UID_NOBODY;
24960Sstevel@tonic-gate if (gidsLen)
24970Sstevel@tonic-gate *gidsLen = 0;
24980Sstevel@tonic-gate
24990Sstevel@tonic-gate if (gids)
25000Sstevel@tonic-gate *gids = NULL;
25010Sstevel@tonic-gate
25020Sstevel@tonic-gate /* get the client handle to gssd */
25030Sstevel@tonic-gate if ((clnt = getgssd_handle()) == NULL)
25040Sstevel@tonic-gate {
25050Sstevel@tonic-gate GSSLOG(1, "kgsscred_expname_to_unix_cred:"
25060Sstevel@tonic-gate " can't connect to server on %s\n", server);
25070Sstevel@tonic-gate return (GSS_S_FAILURE);
25080Sstevel@tonic-gate }
25090Sstevel@tonic-gate
25100Sstevel@tonic-gate /* copy the procedure arguments */
25110Sstevel@tonic-gate args.uid = uid;
25120Sstevel@tonic-gate args.expname.GSS_BUFFER_T_val = expName->value;
25130Sstevel@tonic-gate args.expname.GSS_BUFFER_T_len = expName->length;
25140Sstevel@tonic-gate
25150Sstevel@tonic-gate /* null out the return buffer and call the remote proc */
25160Sstevel@tonic-gate bzero(&res, sizeof (res));
25170Sstevel@tonic-gate
25180Sstevel@tonic-gate if (gsscred_expname_to_unix_cred_1(&args, &res, clnt) != RPC_SUCCESS)
25190Sstevel@tonic-gate {
25200Sstevel@tonic-gate killgssd_handle(clnt);
25210Sstevel@tonic-gate GSSLOG0(1,
25220Sstevel@tonic-gate "kgsscred_expname_to_unix_cred: RPC call times out\n");
25230Sstevel@tonic-gate return (GSS_S_FAILURE);
25240Sstevel@tonic-gate }
25250Sstevel@tonic-gate
25260Sstevel@tonic-gate /* copy the results into the result parameters */
25270Sstevel@tonic-gate if (res.major == GSS_S_COMPLETE)
25280Sstevel@tonic-gate {
25290Sstevel@tonic-gate *uidOut = res.uid;
25300Sstevel@tonic-gate if (gidOut)
25310Sstevel@tonic-gate *gidOut = res.gid;
25320Sstevel@tonic-gate if (gids && gidsLen)
25330Sstevel@tonic-gate {
25340Sstevel@tonic-gate *gids = res.gids.GSSCRED_GIDS_val;
25350Sstevel@tonic-gate *gidsLen = res.gids.GSSCRED_GIDS_len;
25360Sstevel@tonic-gate res.gids.GSSCRED_GIDS_val = NULL;
25370Sstevel@tonic-gate res.gids.GSSCRED_GIDS_len = 0;
25380Sstevel@tonic-gate }
25390Sstevel@tonic-gate }
25400Sstevel@tonic-gate
25410Sstevel@tonic-gate /* free RPC results */
25420Sstevel@tonic-gate clnt_freeres(clnt, xdr_gsscred_expname_to_unix_cred_res, (caddr_t)&res);
25430Sstevel@tonic-gate killgssd_handle(clnt);
25440Sstevel@tonic-gate
25450Sstevel@tonic-gate return (res.major);
25460Sstevel@tonic-gate } /* kgsscred_expname_to_unix_cred */
25470Sstevel@tonic-gate
25480Sstevel@tonic-gate OM_uint32
kgsscred_name_to_unix_cred(intName,mechType,uidOut,gidOut,gids,gidsLen,uid)25490Sstevel@tonic-gate kgsscred_name_to_unix_cred(intName, mechType, uidOut, gidOut, gids,
25500Sstevel@tonic-gate gidsLen, uid)
25510Sstevel@tonic-gate const gss_name_t intName;
25520Sstevel@tonic-gate const gss_OID mechType;
25530Sstevel@tonic-gate uid_t *uidOut;
25540Sstevel@tonic-gate gid_t *gidOut;
25550Sstevel@tonic-gate gid_t *gids[];
25560Sstevel@tonic-gate int *gidsLen;
25570Sstevel@tonic-gate uid_t uid;
25580Sstevel@tonic-gate {
25590Sstevel@tonic-gate CLIENT *clnt;
25600Sstevel@tonic-gate gsscred_name_to_unix_cred_arg args;
25610Sstevel@tonic-gate gsscred_name_to_unix_cred_res res;
25620Sstevel@tonic-gate OM_uint32 major, minor;
25630Sstevel@tonic-gate gss_OID nameOid;
25640Sstevel@tonic-gate gss_buffer_desc flatName = GSS_C_EMPTY_BUFFER;
25650Sstevel@tonic-gate
25660Sstevel@tonic-gate /* check the input/output parameters */
25670Sstevel@tonic-gate if (intName == NULL || mechType == NULL)
25680Sstevel@tonic-gate return (GSS_S_CALL_INACCESSIBLE_READ);
25690Sstevel@tonic-gate
25700Sstevel@tonic-gate if (uidOut == NULL)
25710Sstevel@tonic-gate return (GSS_S_CALL_INACCESSIBLE_WRITE);
25720Sstevel@tonic-gate
25730Sstevel@tonic-gate /* NULL out the output parameters */
25740Sstevel@tonic-gate *uidOut = UID_NOBODY;
25750Sstevel@tonic-gate if (gids)
25760Sstevel@tonic-gate *gids = NULL;
25770Sstevel@tonic-gate
25780Sstevel@tonic-gate if (gidsLen)
25790Sstevel@tonic-gate *gidsLen = 0;
25800Sstevel@tonic-gate
25810Sstevel@tonic-gate /* get the client handle to gssd */
25820Sstevel@tonic-gate if ((clnt = getgssd_handle()) == NULL)
25830Sstevel@tonic-gate {
25840Sstevel@tonic-gate GSSLOG(1,
25850Sstevel@tonic-gate "kgsscred_name_to_unix_cred: can't connect to server %s\n",
25860Sstevel@tonic-gate server);
25870Sstevel@tonic-gate return (GSS_S_FAILURE);
25880Sstevel@tonic-gate }
25890Sstevel@tonic-gate
25900Sstevel@tonic-gate /* convert the name to flat representation */
25910Sstevel@tonic-gate if ((major = gss_display_name(&minor, intName, &flatName, &nameOid))
25920Sstevel@tonic-gate != GSS_S_COMPLETE)
25930Sstevel@tonic-gate {
25940Sstevel@tonic-gate killgssd_handle(clnt);
25950Sstevel@tonic-gate GSSLOG0(1, "kgsscred_name_to_unix_cred: display name failed\n");
25960Sstevel@tonic-gate return (major);
25970Sstevel@tonic-gate }
25980Sstevel@tonic-gate
25990Sstevel@tonic-gate /* set the rpc parameters */
26000Sstevel@tonic-gate args.uid = uid;
26010Sstevel@tonic-gate args.pname.GSS_BUFFER_T_len = flatName.length;
26020Sstevel@tonic-gate args.pname.GSS_BUFFER_T_val = flatName.value;
26030Sstevel@tonic-gate args.name_type.GSS_OID_len = nameOid->length;
26040Sstevel@tonic-gate args.name_type.GSS_OID_val = nameOid->elements;
26050Sstevel@tonic-gate args.mech_type.GSS_OID_len = mechType->length;
26060Sstevel@tonic-gate args.mech_type.GSS_OID_val = mechType->elements;
26070Sstevel@tonic-gate
26080Sstevel@tonic-gate /* call the remote procedure */
26090Sstevel@tonic-gate bzero(&res, sizeof (res));
26100Sstevel@tonic-gate if (gsscred_name_to_unix_cred_1(&args, &res, clnt) != RPC_SUCCESS) {
26110Sstevel@tonic-gate killgssd_handle(clnt);
26120Sstevel@tonic-gate (void) gss_release_buffer(&minor, &flatName);
26130Sstevel@tonic-gate GSSLOG0(1, "kgsscred_name_to_unix_cred: RPC call times out\n");
26140Sstevel@tonic-gate return (GSS_S_FAILURE);
26150Sstevel@tonic-gate }
26160Sstevel@tonic-gate
26170Sstevel@tonic-gate /* delete the flat name buffer */
26180Sstevel@tonic-gate (void) gss_release_buffer(&minor, &flatName);
26190Sstevel@tonic-gate
26200Sstevel@tonic-gate /* copy the output parameters on output */
26210Sstevel@tonic-gate if (res.major == GSS_S_COMPLETE) {
26220Sstevel@tonic-gate *uidOut = res.uid;
26230Sstevel@tonic-gate
26240Sstevel@tonic-gate if (gidOut)
26250Sstevel@tonic-gate *gidOut = res.gid;
26260Sstevel@tonic-gate if (gids && gidsLen) {
26270Sstevel@tonic-gate *gids = res.gids.GSSCRED_GIDS_val;
26280Sstevel@tonic-gate *gidsLen = res.gids.GSSCRED_GIDS_len;
26290Sstevel@tonic-gate res.gids.GSSCRED_GIDS_val = NULL;
26300Sstevel@tonic-gate res.gids.GSSCRED_GIDS_len = 0;
26310Sstevel@tonic-gate }
26320Sstevel@tonic-gate }
26330Sstevel@tonic-gate
26340Sstevel@tonic-gate /* delete RPC allocated memory */
26350Sstevel@tonic-gate clnt_freeres(clnt, xdr_gsscred_name_to_unix_cred_res, (caddr_t)&res);
26360Sstevel@tonic-gate killgssd_handle(clnt);
26370Sstevel@tonic-gate
26380Sstevel@tonic-gate return (res.major);
26390Sstevel@tonic-gate } /* kgsscred_name_to_unix_cred */
26400Sstevel@tonic-gate
26410Sstevel@tonic-gate OM_uint32
kgss_get_group_info(puid,gidOut,gids,gidsLen,uid)26420Sstevel@tonic-gate kgss_get_group_info(puid, gidOut, gids, gidsLen, uid)
26430Sstevel@tonic-gate const uid_t puid;
26440Sstevel@tonic-gate gid_t *gidOut;
26450Sstevel@tonic-gate gid_t *gids[];
26460Sstevel@tonic-gate int *gidsLen;
26470Sstevel@tonic-gate uid_t uid;
26480Sstevel@tonic-gate {
26490Sstevel@tonic-gate CLIENT *clnt;
26500Sstevel@tonic-gate gss_get_group_info_arg args;
26510Sstevel@tonic-gate gss_get_group_info_res res;
26520Sstevel@tonic-gate
26530Sstevel@tonic-gate
26540Sstevel@tonic-gate /* check the output parameters */
26550Sstevel@tonic-gate if (gidOut == NULL || gids == NULL || gidsLen == NULL)
26560Sstevel@tonic-gate return (GSS_S_CALL_INACCESSIBLE_WRITE);
26570Sstevel@tonic-gate
26580Sstevel@tonic-gate /* get the client GSSD handle */
26590Sstevel@tonic-gate if ((clnt = getgssd_handle()) == NULL) {
26600Sstevel@tonic-gate GSSLOG(1,
26610Sstevel@tonic-gate "kgss_get_group_info: can't connect to server on %s\n",
26620Sstevel@tonic-gate server);
26630Sstevel@tonic-gate return (GSS_S_FAILURE);
26640Sstevel@tonic-gate }
26650Sstevel@tonic-gate
26660Sstevel@tonic-gate /* set the input parameters */
26670Sstevel@tonic-gate args.uid = uid;
26680Sstevel@tonic-gate args.puid = puid;
26690Sstevel@tonic-gate
26700Sstevel@tonic-gate /* call the remote procedure */
26710Sstevel@tonic-gate bzero(&res, sizeof (res));
26720Sstevel@tonic-gate if (gss_get_group_info_1(&args, &res, clnt) != RPC_SUCCESS) {
26730Sstevel@tonic-gate killgssd_handle(clnt);
26740Sstevel@tonic-gate GSSLOG0(1, "kgss_get_group_info: RPC call times out\n");
26750Sstevel@tonic-gate return (GSS_S_FAILURE);
26760Sstevel@tonic-gate }
26770Sstevel@tonic-gate
26780Sstevel@tonic-gate /* copy the results */
26790Sstevel@tonic-gate if (res.major == GSS_S_COMPLETE) {
26800Sstevel@tonic-gate *gidOut = res.gid;
26810Sstevel@tonic-gate *gids = res.gids.GSSCRED_GIDS_val;
26820Sstevel@tonic-gate *gidsLen = res.gids.GSSCRED_GIDS_len;
26830Sstevel@tonic-gate res.gids.GSSCRED_GIDS_val = NULL;
26840Sstevel@tonic-gate res.gids.GSSCRED_GIDS_len = 0;
26850Sstevel@tonic-gate }
26860Sstevel@tonic-gate
26870Sstevel@tonic-gate /* no results to free */
26880Sstevel@tonic-gate killgssd_handle(clnt);
26890Sstevel@tonic-gate
26900Sstevel@tonic-gate return (res.major);
26910Sstevel@tonic-gate } /* kgss_get_group_info */
26920Sstevel@tonic-gate
26930Sstevel@tonic-gate static char *
kgss_get_kmod(gss_OID mech_oid)26940Sstevel@tonic-gate kgss_get_kmod(gss_OID mech_oid)
26950Sstevel@tonic-gate {
26960Sstevel@tonic-gate CLIENT *clnt;
26970Sstevel@tonic-gate gss_get_kmod_arg args;
26980Sstevel@tonic-gate gss_get_kmod_res res;
26990Sstevel@tonic-gate
27000Sstevel@tonic-gate
27010Sstevel@tonic-gate /* get the client GSSD handle */
27020Sstevel@tonic-gate if ((clnt = getgssd_handle()) == NULL) {
27030Sstevel@tonic-gate GSSLOG(1, "kgss_get_kmod: can't connect to server on %s\n",
27040Sstevel@tonic-gate server);
27050Sstevel@tonic-gate return (NULL);
27060Sstevel@tonic-gate }
27070Sstevel@tonic-gate
27080Sstevel@tonic-gate /* set the input parameters */
27090Sstevel@tonic-gate args.mech_oid.GSS_OID_len = mech_oid->length;
27100Sstevel@tonic-gate args.mech_oid.GSS_OID_val = mech_oid->elements;
27110Sstevel@tonic-gate
27120Sstevel@tonic-gate /* call the remote procedure */
27130Sstevel@tonic-gate bzero(&res, sizeof (res));
27140Sstevel@tonic-gate if (gss_get_kmod_1(&args, &res, clnt) != RPC_SUCCESS) {
27150Sstevel@tonic-gate killgssd_handle(clnt);
27160Sstevel@tonic-gate GSSLOG0(1, "gss_get_kmod_1: RPC call times out\n");
27170Sstevel@tonic-gate return (NULL);
27180Sstevel@tonic-gate }
27190Sstevel@tonic-gate /* no results to free */
27200Sstevel@tonic-gate killgssd_handle(clnt);
27210Sstevel@tonic-gate
27220Sstevel@tonic-gate if (res.module_follow == TRUE) {
27230Sstevel@tonic-gate return (res.gss_get_kmod_res_u.modname);
27240Sstevel@tonic-gate } else
27250Sstevel@tonic-gate return (NULL);
27260Sstevel@tonic-gate } /* kgss_get_kmod */
27270Sstevel@tonic-gate
27280Sstevel@tonic-gate static gss_mechanism kgss_mech_head;
27290Sstevel@tonic-gate static gss_mechanism kgss_mech_tail;
27300Sstevel@tonic-gate kmutex_t __kgss_mech_lock;
27310Sstevel@tonic-gate
27320Sstevel@tonic-gate /*
27330Sstevel@tonic-gate * See if there is kernel mechanism module, and if so, attempt to
27340Sstevel@tonic-gate * load it and reset the pointer (gss_mechanism) to the sign/seal/etc.
27350Sstevel@tonic-gate * entry points to that of the kernel module.
27360Sstevel@tonic-gate */
27370Sstevel@tonic-gate static void
__kgss_reset_mech(gss_mechanism * mechp,gss_OID mech_oid)27380Sstevel@tonic-gate __kgss_reset_mech(gss_mechanism *mechp, gss_OID mech_oid)
27390Sstevel@tonic-gate {
27400Sstevel@tonic-gate gss_mechanism mech;
27410Sstevel@tonic-gate char *kmod;
27420Sstevel@tonic-gate
27430Sstevel@tonic-gate /*
27440Sstevel@tonic-gate * We can search the list without a mutex, becuase the list never
27450Sstevel@tonic-gate * shrinks and we always add to the end.
27460Sstevel@tonic-gate */
27470Sstevel@tonic-gate mech = __kgss_get_mechanism(mech_oid);
27480Sstevel@tonic-gate if (mech) {
27490Sstevel@tonic-gate *mechp = mech;
27500Sstevel@tonic-gate return;
27510Sstevel@tonic-gate }
27520Sstevel@tonic-gate
27530Sstevel@tonic-gate /*
27540Sstevel@tonic-gate * Get the module name from the kernel.
27550Sstevel@tonic-gate */
27560Sstevel@tonic-gate kmod = kgss_get_kmod(mech_oid);
27570Sstevel@tonic-gate
27580Sstevel@tonic-gate if (kmod) {
27596855Sjohnlev extern int modload(const char *, const char *);
27600Sstevel@tonic-gate if (modload("misc/kgss", kmod) < 0) {
27610Sstevel@tonic-gate /*
27620Sstevel@tonic-gate * Modload of 'kmod' failed, so log an
27630Sstevel@tonic-gate * appropriate comment
27640Sstevel@tonic-gate */
27650Sstevel@tonic-gate cmn_err(CE_NOTE, "kgss_reset_mech: Algorithm modload "
27660Sstevel@tonic-gate "(%s) failed. Userland gssd will now handle "
27670Sstevel@tonic-gate "all GSSAPI calls, which may result in "
27680Sstevel@tonic-gate "reduced performance.\n", kmod);
27690Sstevel@tonic-gate };
27700Sstevel@tonic-gate
27710Sstevel@tonic-gate /*
27720Sstevel@tonic-gate * Allocated in the XDR routine called by gss_get_kmod_1().
27730Sstevel@tonic-gate */
27740Sstevel@tonic-gate FREE(kmod, strlen(kmod)+1);
27750Sstevel@tonic-gate
27760Sstevel@tonic-gate mech = __kgss_get_mechanism(mech_oid);
27770Sstevel@tonic-gate if (mech) {
27780Sstevel@tonic-gate *mechp = mech;
27790Sstevel@tonic-gate }
27800Sstevel@tonic-gate
27810Sstevel@tonic-gate /*
27820Sstevel@tonic-gate * If for some reason the module load didn't take,
27830Sstevel@tonic-gate * we return anyway and hope that the next context
27840Sstevel@tonic-gate * creation succeeds.
27850Sstevel@tonic-gate */
27860Sstevel@tonic-gate return;
27870Sstevel@tonic-gate }
27880Sstevel@tonic-gate
27890Sstevel@tonic-gate
27900Sstevel@tonic-gate /*
27910Sstevel@tonic-gate * No kernel module, so enter this mech oid into the list
27920Sstevel@tonic-gate * using the default sign/seal/etc. operations that upcall to
27930Sstevel@tonic-gate * gssd.
27940Sstevel@tonic-gate */
27950Sstevel@tonic-gate mutex_enter(&__kgss_mech_lock);
27960Sstevel@tonic-gate mech = __kgss_get_mechanism(mech_oid);
27970Sstevel@tonic-gate if (mech) {
27980Sstevel@tonic-gate mutex_exit(&__kgss_mech_lock);
27990Sstevel@tonic-gate *mechp = mech;
28000Sstevel@tonic-gate return;
28010Sstevel@tonic-gate }
28020Sstevel@tonic-gate
28030Sstevel@tonic-gate /*
28040Sstevel@tonic-gate * Allocate space for the mechanism entry.
28050Sstevel@tonic-gate */
28060Sstevel@tonic-gate mech = kmem_zalloc(sizeof (struct gss_config), KM_SLEEP);
28070Sstevel@tonic-gate
28080Sstevel@tonic-gate /*
28090Sstevel@tonic-gate * Copy basic information from default mechanism struct.
28100Sstevel@tonic-gate */
28110Sstevel@tonic-gate *mech = default_gc;
28120Sstevel@tonic-gate
28130Sstevel@tonic-gate /*
28140Sstevel@tonic-gate * Record the real mech OID.
28150Sstevel@tonic-gate */
28160Sstevel@tonic-gate mech->mech_type.length = mech_oid->length;
28170Sstevel@tonic-gate mech->mech_type.elements = MALLOC(mech_oid->length);
28180Sstevel@tonic-gate bcopy(mech_oid->elements, mech->mech_type.elements, mech_oid->length);
28190Sstevel@tonic-gate
28200Sstevel@tonic-gate /*
28210Sstevel@tonic-gate * Add it to the table.
28220Sstevel@tonic-gate */
28230Sstevel@tonic-gate __kgss_add_mechanism(mech);
28240Sstevel@tonic-gate mutex_exit(&__kgss_mech_lock);
28250Sstevel@tonic-gate *mechp = mech;
28260Sstevel@tonic-gate }
28270Sstevel@tonic-gate
28280Sstevel@tonic-gate /*
28290Sstevel@tonic-gate * Called with __kgss_mech_lock held.
28300Sstevel@tonic-gate */
28310Sstevel@tonic-gate void
__kgss_add_mechanism(gss_mechanism mech)28320Sstevel@tonic-gate __kgss_add_mechanism(gss_mechanism mech)
28330Sstevel@tonic-gate {
28340Sstevel@tonic-gate gss_mechanism tmp;
28350Sstevel@tonic-gate
28360Sstevel@tonic-gate tmp = kgss_mech_tail;
28370Sstevel@tonic-gate kgss_mech_tail = mech;
28380Sstevel@tonic-gate
28390Sstevel@tonic-gate if (tmp != NULL)
28400Sstevel@tonic-gate tmp->next = mech;
28410Sstevel@tonic-gate
28420Sstevel@tonic-gate if (kgss_mech_head == NULL)
28430Sstevel@tonic-gate kgss_mech_head = mech;
28440Sstevel@tonic-gate }
28450Sstevel@tonic-gate
28460Sstevel@tonic-gate /*
28470Sstevel@tonic-gate * given the mechs_array and a mechanism OID, return the
28480Sstevel@tonic-gate * pointer to the mechanism, or NULL if that mechanism is
28490Sstevel@tonic-gate * not supported.
28500Sstevel@tonic-gate */
28510Sstevel@tonic-gate gss_mechanism
__kgss_get_mechanism(gss_OID type)28520Sstevel@tonic-gate __kgss_get_mechanism(gss_OID type)
28530Sstevel@tonic-gate {
28540Sstevel@tonic-gate gss_mechanism mech;
28550Sstevel@tonic-gate
28560Sstevel@tonic-gate mech = kgss_mech_head;
28570Sstevel@tonic-gate
28580Sstevel@tonic-gate /*
28590Sstevel@tonic-gate * Note that a reader can scan this list without the mutex held.
28600Sstevel@tonic-gate * This is safe because we always append, and never shrink the list.
28610Sstevel@tonic-gate * Moreover, the entry is fully initialized before it is ever
28620Sstevel@tonic-gate * added to the list.
28630Sstevel@tonic-gate */
28640Sstevel@tonic-gate while (mech != NULL) {
28650Sstevel@tonic-gate if ((mech->mech_type.length == type->length) &&
28660Sstevel@tonic-gate (bcmp(mech->mech_type.elements, type->elements,
28670Sstevel@tonic-gate type->length) == 0))
28680Sstevel@tonic-gate return (mech);
28690Sstevel@tonic-gate
28700Sstevel@tonic-gate mech = mech->next;
28710Sstevel@tonic-gate }
28720Sstevel@tonic-gate return (NULL);
28730Sstevel@tonic-gate }
2874