xref: /titanic_44/usr/src/cmd/gss/gssd/gssd_proc.c (revision 77b65ce69d04f1ba0eceb747081964672b718796)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5004388ebScasper  * Common Development and Distribution License (the "License").
6004388ebScasper  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
21*77b65ce6SAlex Wilson /*
22*77b65ce6SAlex Wilson  * Copyright 2017 Joyent Inc
23*77b65ce6SAlex Wilson  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
24*77b65ce6SAlex Wilson  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate /*
277c478bd9Sstevel@tonic-gate  *  RPC server procedures for the gssapi usermode daemon gssd.
287c478bd9Sstevel@tonic-gate  */
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate #include <stdio.h>
31004388ebScasper #include <stdio_ext.h>
327c478bd9Sstevel@tonic-gate #include <unistd.h>
337c478bd9Sstevel@tonic-gate #include <pwd.h>
347c478bd9Sstevel@tonic-gate #include <grp.h>
357c478bd9Sstevel@tonic-gate #include <strings.h>
367c478bd9Sstevel@tonic-gate #include <limits.h>
377c478bd9Sstevel@tonic-gate #include <sys/param.h>
387c478bd9Sstevel@tonic-gate #include <mechglueP.h>
397c478bd9Sstevel@tonic-gate #include "gssd.h"
407c478bd9Sstevel@tonic-gate #include <gssapi/gssapi.h>
417c478bd9Sstevel@tonic-gate #include <rpc/rpc.h>
427c478bd9Sstevel@tonic-gate #include <stdlib.h>
437c478bd9Sstevel@tonic-gate #include <syslog.h>
447c478bd9Sstevel@tonic-gate #include <sys/resource.h>
45*77b65ce6SAlex Wilson #include <sys/debug.h>
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate #define	SRVTAB	""
487c478bd9Sstevel@tonic-gate #define	FDCACHE_PERCENTAGE	.75	/* Percentage of total FD limit */
497c478bd9Sstevel@tonic-gate #define	FDCACHE_DEFAULT		16	/* Default LRU cache size */
507c478bd9Sstevel@tonic-gate #define	GSSD_FD_LIMIT		255	/* Increase number of fds allowed */
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate extern int gssd_debug;			/* declared in gssd.c */
537c478bd9Sstevel@tonic-gate static OM_uint32 gssd_time_verf;	/* verifies same gssd */
547c478bd9Sstevel@tonic-gate static OM_uint32 context_verf;		/* context sequence numbers */
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate struct gssd_ctx_slot {
577c478bd9Sstevel@tonic-gate 	struct gssd_ctx_slot *lru_next;
587c478bd9Sstevel@tonic-gate 	struct gssd_ctx_slot *lru_prev;
597c478bd9Sstevel@tonic-gate 	bool_t		inuse;
607c478bd9Sstevel@tonic-gate 	OM_uint32	create_time;
617c478bd9Sstevel@tonic-gate 	OM_uint32	verf;
627c478bd9Sstevel@tonic-gate 	gss_ctx_id_t	ctx;
637c478bd9Sstevel@tonic-gate 	gss_ctx_id_t	rpcctx;
647c478bd9Sstevel@tonic-gate };
657c478bd9Sstevel@tonic-gate 
667c478bd9Sstevel@tonic-gate struct gssd_ctx_slot *gssd_ctx_slot_tbl;
677c478bd9Sstevel@tonic-gate struct gssd_ctx_slot *gssd_lru_head;
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate static int max_contexts;
707c478bd9Sstevel@tonic-gate 
717c478bd9Sstevel@tonic-gate static int checkfrom(struct svc_req *, uid_t *);
727c478bd9Sstevel@tonic-gate extern void set_gssd_uid(uid_t);
737c478bd9Sstevel@tonic-gate extern int __rpc_get_local_uid(SVCXPRT *, uid_t *);
747c478bd9Sstevel@tonic-gate 
755e01956fSGlenn Barry /*
765e01956fSGlenn Barry  * Syslog (and output to stderr if debug set) the GSSAPI major
775e01956fSGlenn Barry  * and minor numbers.
785e01956fSGlenn Barry  */
795e01956fSGlenn Barry static void
syslog_gss_error(OM_uint32 maj_stat,OM_uint32 min_stat,char * errstr)805e01956fSGlenn Barry syslog_gss_error(OM_uint32 maj_stat, OM_uint32 min_stat, char *errstr)
815e01956fSGlenn Barry {
825e01956fSGlenn Barry 	OM_uint32 gmaj_stat, gmin_stat;
835e01956fSGlenn Barry 	gss_buffer_desc msg;
845e01956fSGlenn Barry 	OM_uint32 msg_ctx = 0;
855e01956fSGlenn Barry 
865e01956fSGlenn Barry 
875e01956fSGlenn Barry 	if (gssd_debug)
885e01956fSGlenn Barry 		fprintf(stderr,
895e01956fSGlenn Barry 		    "gssd: syslog_gss_err: called from %s: maj=%d min=%d\n",
905e01956fSGlenn Barry 		    errstr ? errstr : "<null>", maj_stat, min_stat);
915e01956fSGlenn Barry 
925e01956fSGlenn Barry 	/* Print the major status error from the mech. */
935e01956fSGlenn Barry 	/* msg_ctx - skip the check for it as is probably unnecesary */
945e01956fSGlenn Barry 	gmaj_stat = gss_display_status(&gmin_stat, maj_stat,
955e01956fSGlenn Barry 	    GSS_C_GSS_CODE,
965e01956fSGlenn Barry 	    GSS_C_NULL_OID, &msg_ctx, &msg);
975e01956fSGlenn Barry 	if ((gmaj_stat == GSS_S_COMPLETE)||
985e01956fSGlenn Barry 	    (gmaj_stat == GSS_S_CONTINUE_NEEDED)) {
995e01956fSGlenn Barry 		syslog(LOG_DAEMON|LOG_NOTICE,
1005e01956fSGlenn Barry 		    "GSSAPI error major: %s", (char *)msg.value);
1015e01956fSGlenn Barry 		if (gssd_debug)
1025e01956fSGlenn Barry 			(void) fprintf(stderr,
1035e01956fSGlenn Barry 			    "gssd: GSSAPI error major: %s\n",
1045e01956fSGlenn Barry 			    (char *)msg.value);
1055e01956fSGlenn Barry 
1065e01956fSGlenn Barry 		(void) gss_release_buffer(&gmin_stat, &msg);
1075e01956fSGlenn Barry 	}
1085e01956fSGlenn Barry 
1095e01956fSGlenn Barry 	/* Print the minor status error from the mech. */
1105e01956fSGlenn Barry 	msg_ctx = 0;
1115e01956fSGlenn Barry 	/* msg_ctx - skip the check for it as is probably unnecesary */
1125e01956fSGlenn Barry 	gmaj_stat = gss_display_status(&gmin_stat, min_stat,
1135e01956fSGlenn Barry 	    GSS_C_MECH_CODE,
1145e01956fSGlenn Barry 	    GSS_C_NULL_OID,
1155e01956fSGlenn Barry 	    &msg_ctx, &msg);
1165e01956fSGlenn Barry 	if ((gmaj_stat == GSS_S_COMPLETE)||
1175e01956fSGlenn Barry 	    (gmaj_stat == GSS_S_CONTINUE_NEEDED)) {
1185e01956fSGlenn Barry 		syslog(LOG_DAEMON|LOG_NOTICE,
1195e01956fSGlenn Barry 		    "GSSAPI error minor: %s",
1205e01956fSGlenn Barry 		    (char *)msg.value);
1215e01956fSGlenn Barry 		if (gssd_debug)
1225e01956fSGlenn Barry 			(void) fprintf(stderr,
1235e01956fSGlenn Barry 			    "gssd: GSSAPI error minor: %s\n",
1245e01956fSGlenn Barry 			    (char *)msg.value);
1255e01956fSGlenn Barry 		(void) gss_release_buffer(&gmin_stat, &msg);
1265e01956fSGlenn Barry 	}
1275e01956fSGlenn Barry }
1285e01956fSGlenn Barry 
1297c478bd9Sstevel@tonic-gate void
gssd_setup(char * arg)1307c478bd9Sstevel@tonic-gate gssd_setup(char *arg)
1317c478bd9Sstevel@tonic-gate {
1327c478bd9Sstevel@tonic-gate 	int i;
1337c478bd9Sstevel@tonic-gate 	struct rlimit rl;
1347c478bd9Sstevel@tonic-gate 	hrtime_t high_res_time;
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate 	gssd_time_verf = (OM_uint32)time(NULL);
1377c478bd9Sstevel@tonic-gate 	max_contexts = FDCACHE_DEFAULT;
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate 	/*
1407c478bd9Sstevel@tonic-gate 	 * Use low order bits of high resolution time to get a reasonably
1417c478bd9Sstevel@tonic-gate 	 * random number to start the context sequencing.  This alternative
1427c478bd9Sstevel@tonic-gate 	 * to using a time value avoid clock resets via NTP or ntpdate.
1437c478bd9Sstevel@tonic-gate 	 */
1447c478bd9Sstevel@tonic-gate 	high_res_time = gethrtime();
1457c478bd9Sstevel@tonic-gate 	context_verf = (OM_uint32)high_res_time;
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate 	/*
1487c478bd9Sstevel@tonic-gate 	 * Increase resource limit of FDs in case we get alot accept/init_
1497c478bd9Sstevel@tonic-gate 	 * sec_context calls before we're able to export them.  This can
1507c478bd9Sstevel@tonic-gate 	 * happen in very heavily load environments where gssd doesn't get
1517c478bd9Sstevel@tonic-gate 	 * much time to work on its backlog.
1527c478bd9Sstevel@tonic-gate 	 */
1537c478bd9Sstevel@tonic-gate 	if ((getrlimit(RLIMIT_NOFILE, &rl)) == 0) {
1547c478bd9Sstevel@tonic-gate 		rl.rlim_cur = (rl.rlim_max >= GSSD_FD_LIMIT) ?
1557c478bd9Sstevel@tonic-gate 				GSSD_FD_LIMIT : rl.rlim_max;
1567c478bd9Sstevel@tonic-gate 		if ((setrlimit(RLIMIT_NOFILE, &rl)) == 0)
1577c478bd9Sstevel@tonic-gate 			max_contexts = rl.rlim_cur * FDCACHE_PERCENTAGE;
158004388ebScasper 		(void) enable_extended_FILE_stdio(-1, -1);
1597c478bd9Sstevel@tonic-gate 	}
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate 	gssd_ctx_slot_tbl = (struct gssd_ctx_slot *)
1627c478bd9Sstevel@tonic-gate 		malloc(sizeof (struct gssd_ctx_slot) * max_contexts);
1637c478bd9Sstevel@tonic-gate 
1647c478bd9Sstevel@tonic-gate 	if (gssd_ctx_slot_tbl == NULL) {
1657c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
1667c478bd9Sstevel@tonic-gate 			gettext("[%s] could not allocate %d byte context table"
1677c478bd9Sstevel@tonic-gate 			"\n"), arg,
1687c478bd9Sstevel@tonic-gate 			(sizeof (struct gssd_ctx_slot) * max_contexts));
1697c478bd9Sstevel@tonic-gate 		exit(1);
1707c478bd9Sstevel@tonic-gate 	}
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate 	for (i = 1; i < max_contexts; i++) {
1737c478bd9Sstevel@tonic-gate 		gssd_ctx_slot_tbl[i-1].lru_next = &gssd_ctx_slot_tbl[i];
1747c478bd9Sstevel@tonic-gate 		gssd_ctx_slot_tbl[i].lru_prev = &gssd_ctx_slot_tbl[i-1];
1757c478bd9Sstevel@tonic-gate 		gssd_ctx_slot_tbl[i].inuse = FALSE;
1767c478bd9Sstevel@tonic-gate 		gssd_ctx_slot_tbl[i].verf = 0;
1777c478bd9Sstevel@tonic-gate 		gssd_ctx_slot_tbl[i].create_time = 0;
1787c478bd9Sstevel@tonic-gate 		gssd_ctx_slot_tbl[i].rpcctx = (gss_ctx_id_t)(i + 1);
1797c478bd9Sstevel@tonic-gate 	}
1807c478bd9Sstevel@tonic-gate 
1817c478bd9Sstevel@tonic-gate 	gssd_ctx_slot_tbl[max_contexts - 1].lru_next = &gssd_ctx_slot_tbl[0];
1827c478bd9Sstevel@tonic-gate 	gssd_ctx_slot_tbl[0].lru_prev = &gssd_ctx_slot_tbl[max_contexts - 1];
1837c478bd9Sstevel@tonic-gate 	gssd_ctx_slot_tbl[0].inuse = FALSE;
1847c478bd9Sstevel@tonic-gate 	gssd_ctx_slot_tbl[0].verf = 0;
1857c478bd9Sstevel@tonic-gate 	gssd_ctx_slot_tbl[0].create_time = 0;
1867c478bd9Sstevel@tonic-gate 	gssd_ctx_slot_tbl[0].rpcctx = (gss_ctx_id_t)1;
1877c478bd9Sstevel@tonic-gate 
1887c478bd9Sstevel@tonic-gate 	gssd_lru_head = &gssd_ctx_slot_tbl[0];
1897c478bd9Sstevel@tonic-gate }
1907c478bd9Sstevel@tonic-gate 
1917c478bd9Sstevel@tonic-gate static OM_uint32 syslog_interval = 60;
1927c478bd9Sstevel@tonic-gate 
1937c478bd9Sstevel@tonic-gate static struct gssd_ctx_slot *
gssd_alloc_slot(gss_ctx_id_t ctx)1947c478bd9Sstevel@tonic-gate gssd_alloc_slot(gss_ctx_id_t ctx)
1957c478bd9Sstevel@tonic-gate {
1967c478bd9Sstevel@tonic-gate 	struct gssd_ctx_slot *lru;
1977c478bd9Sstevel@tonic-gate 	OM_uint32 current_time;
1987c478bd9Sstevel@tonic-gate 	static OM_uint32 last_syslog = 0;
1997c478bd9Sstevel@tonic-gate 	static bool_t first_take = TRUE;
2007c478bd9Sstevel@tonic-gate 	static int tooks;
2017c478bd9Sstevel@tonic-gate 	OM_uint32 minor_status;
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate 	lru = gssd_lru_head;
2047c478bd9Sstevel@tonic-gate 	gssd_lru_head = lru->lru_next;
2057c478bd9Sstevel@tonic-gate 
2067c478bd9Sstevel@tonic-gate 	current_time = (OM_uint32) time(NULL);
2077c478bd9Sstevel@tonic-gate 
2087c478bd9Sstevel@tonic-gate 	if (last_syslog == 0)
2097c478bd9Sstevel@tonic-gate 		last_syslog = current_time;	/* Save 1st alloc time */
2107c478bd9Sstevel@tonic-gate 
2117c478bd9Sstevel@tonic-gate 	if (lru->inuse) {
2127c478bd9Sstevel@tonic-gate 		if (lru->ctx != GSS_C_NO_CONTEXT)
2137c478bd9Sstevel@tonic-gate 			(void) gss_delete_sec_context(&minor_status,
2147c478bd9Sstevel@tonic-gate 				&lru->ctx, NULL);
2157c478bd9Sstevel@tonic-gate 		tooks++;
2167c478bd9Sstevel@tonic-gate 
2177c478bd9Sstevel@tonic-gate 		if (((current_time - last_syslog) > syslog_interval) ||
2187c478bd9Sstevel@tonic-gate 			first_take) {
2197c478bd9Sstevel@tonic-gate 			syslog(LOG_WARNING, gettext("re-used an existing "
2207c478bd9Sstevel@tonic-gate 				"context slot of age %u seconds (%d slots re-"
2217c478bd9Sstevel@tonic-gate 				"used during last %u seconds)"),
2227c478bd9Sstevel@tonic-gate 				current_time - lru->create_time, tooks,
2237c478bd9Sstevel@tonic-gate 				current_time - last_syslog);
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate 			last_syslog = current_time;
2267c478bd9Sstevel@tonic-gate 			tooks = 0;
2277c478bd9Sstevel@tonic-gate 			first_take = FALSE;
2287c478bd9Sstevel@tonic-gate 		}
2297c478bd9Sstevel@tonic-gate 	}
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate 	/*
2327c478bd9Sstevel@tonic-gate 	 * Assign the next context verifier to the context (avoiding zero).
2337c478bd9Sstevel@tonic-gate 	 */
2347c478bd9Sstevel@tonic-gate 	context_verf++;
2357c478bd9Sstevel@tonic-gate 	if (context_verf == 0)
2367c478bd9Sstevel@tonic-gate 		context_verf = 1;
2377c478bd9Sstevel@tonic-gate 	lru->verf = context_verf;
2387c478bd9Sstevel@tonic-gate 
2397c478bd9Sstevel@tonic-gate 	lru->create_time = current_time;
2407c478bd9Sstevel@tonic-gate 	lru->ctx = ctx;
2417c478bd9Sstevel@tonic-gate 	lru->inuse = TRUE;
2427c478bd9Sstevel@tonic-gate 	return (lru);
2437c478bd9Sstevel@tonic-gate }
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate /*
2467c478bd9Sstevel@tonic-gate  * We always add 1 because we don't want slot 0 to be confused
2477c478bd9Sstevel@tonic-gate  * with GSS_C_NO_CONTEXT.
2487c478bd9Sstevel@tonic-gate  */
2497c478bd9Sstevel@tonic-gate 
2507c478bd9Sstevel@tonic-gate static struct gssd_ctx_slot *
gssd_handle_to_slot(GSS_CTX_ID_T * h)2517c478bd9Sstevel@tonic-gate gssd_handle_to_slot(GSS_CTX_ID_T *h)
2527c478bd9Sstevel@tonic-gate {
2537c478bd9Sstevel@tonic-gate 	intptr_t i;
2547c478bd9Sstevel@tonic-gate 
2557c478bd9Sstevel@tonic-gate 	if (h->GSS_CTX_ID_T_len == 0) {
2567c478bd9Sstevel@tonic-gate 		return (NULL);
2577c478bd9Sstevel@tonic-gate 	}
2587c478bd9Sstevel@tonic-gate 	if (h->GSS_CTX_ID_T_len != sizeof (i))
2597c478bd9Sstevel@tonic-gate 		return (NULL);
2607c478bd9Sstevel@tonic-gate 
2617c478bd9Sstevel@tonic-gate 	i = (*(intptr_t *)(h->GSS_CTX_ID_T_val)) - 1;
2627c478bd9Sstevel@tonic-gate 
2637c478bd9Sstevel@tonic-gate 	if (i < 0 || i >= max_contexts)
2647c478bd9Sstevel@tonic-gate 		return (NULL);
2657c478bd9Sstevel@tonic-gate 
2667c478bd9Sstevel@tonic-gate 	return (&gssd_ctx_slot_tbl[i]);
2677c478bd9Sstevel@tonic-gate }
2687c478bd9Sstevel@tonic-gate 
2697c478bd9Sstevel@tonic-gate static void
gssd_rel_slot(struct gssd_ctx_slot * lru)2707c478bd9Sstevel@tonic-gate gssd_rel_slot(struct gssd_ctx_slot *lru)
2717c478bd9Sstevel@tonic-gate {
2727c478bd9Sstevel@tonic-gate 	struct gssd_ctx_slot *prev, *next;
2737c478bd9Sstevel@tonic-gate 
2747c478bd9Sstevel@tonic-gate 	if (lru == NULL)
2757c478bd9Sstevel@tonic-gate 		return;
2767c478bd9Sstevel@tonic-gate 
2777c478bd9Sstevel@tonic-gate 	lru->inuse = FALSE;
2787c478bd9Sstevel@tonic-gate 
2797c478bd9Sstevel@tonic-gate 	/*
2807c478bd9Sstevel@tonic-gate 	 * Remove entry from its current location in list
2817c478bd9Sstevel@tonic-gate 	 */
2827c478bd9Sstevel@tonic-gate 	prev = lru->lru_prev;
2837c478bd9Sstevel@tonic-gate 	next = lru->lru_next;
2847c478bd9Sstevel@tonic-gate 	prev->lru_next = next;
2857c478bd9Sstevel@tonic-gate 	next->lru_prev = prev;
2867c478bd9Sstevel@tonic-gate 
2877c478bd9Sstevel@tonic-gate 	/*
2887c478bd9Sstevel@tonic-gate 	 * Since it is no longer in use, it is the least recently
2897c478bd9Sstevel@tonic-gate 	 * used.
2907c478bd9Sstevel@tonic-gate 	 */
2917c478bd9Sstevel@tonic-gate 	prev = gssd_lru_head->lru_prev;
2927c478bd9Sstevel@tonic-gate 	next = gssd_lru_head;
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate 	prev->lru_next = lru;
2957c478bd9Sstevel@tonic-gate 	lru->lru_prev = prev;
2967c478bd9Sstevel@tonic-gate 
2977c478bd9Sstevel@tonic-gate 	next->lru_prev = lru;
2987c478bd9Sstevel@tonic-gate 	lru->lru_next = next;
2997c478bd9Sstevel@tonic-gate 
3007c478bd9Sstevel@tonic-gate 	gssd_lru_head = lru;
3017c478bd9Sstevel@tonic-gate }
3027c478bd9Sstevel@tonic-gate 
3037c478bd9Sstevel@tonic-gate static void
gssd_convert_context_handle(GSS_CTX_ID_T * h,gss_ctx_id_t * context_handle,OM_uint32 verf,bool_t * context_verf_ok,struct gssd_ctx_slot ** slotp)3047c478bd9Sstevel@tonic-gate gssd_convert_context_handle(GSS_CTX_ID_T *h,
3057c478bd9Sstevel@tonic-gate 	gss_ctx_id_t *context_handle,
3067c478bd9Sstevel@tonic-gate 	OM_uint32 verf,
3077c478bd9Sstevel@tonic-gate 	bool_t *context_verf_ok,
3087c478bd9Sstevel@tonic-gate 	struct gssd_ctx_slot **slotp)
3097c478bd9Sstevel@tonic-gate {
3107c478bd9Sstevel@tonic-gate 	struct gssd_ctx_slot *slot;
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate 	*context_verf_ok = FALSE;
3137c478bd9Sstevel@tonic-gate 	*context_handle = (gss_ctx_id_t)1;
3147c478bd9Sstevel@tonic-gate 	if (slotp != NULL)
3157c478bd9Sstevel@tonic-gate 		*slotp = NULL;
3167c478bd9Sstevel@tonic-gate 
3177c478bd9Sstevel@tonic-gate 	if (h->GSS_CTX_ID_T_len == 0) {
3187c478bd9Sstevel@tonic-gate 		*context_handle = GSS_C_NO_CONTEXT;
3197c478bd9Sstevel@tonic-gate 		*context_verf_ok = TRUE;
3207c478bd9Sstevel@tonic-gate 		return;
3217c478bd9Sstevel@tonic-gate 	}
3227c478bd9Sstevel@tonic-gate 
3237c478bd9Sstevel@tonic-gate 	slot = gssd_handle_to_slot(h);
3247c478bd9Sstevel@tonic-gate 
3257c478bd9Sstevel@tonic-gate 	if (slot == NULL)
3267c478bd9Sstevel@tonic-gate 		return;
3277c478bd9Sstevel@tonic-gate 
3287c478bd9Sstevel@tonic-gate 	if (verf != slot->verf)
3297c478bd9Sstevel@tonic-gate 		return;
3307c478bd9Sstevel@tonic-gate 
3317c478bd9Sstevel@tonic-gate 	*context_verf_ok = TRUE;
3327c478bd9Sstevel@tonic-gate 	*context_handle = slot->ctx;
3337c478bd9Sstevel@tonic-gate 	if (slotp != NULL)
3347c478bd9Sstevel@tonic-gate 		*slotp = slot;
3357c478bd9Sstevel@tonic-gate }
3367c478bd9Sstevel@tonic-gate 
3377c478bd9Sstevel@tonic-gate bool_t
gss_acquire_cred_1_svc(argp,res,rqstp)3387c478bd9Sstevel@tonic-gate gss_acquire_cred_1_svc(argp, res, rqstp)
3397c478bd9Sstevel@tonic-gate 	gss_acquire_cred_arg *argp;
3407c478bd9Sstevel@tonic-gate 	gss_acquire_cred_res *res;
3417c478bd9Sstevel@tonic-gate 	struct svc_req *rqstp;
3427c478bd9Sstevel@tonic-gate {
3437c478bd9Sstevel@tonic-gate 	OM_uint32 		minor_status;
3447c478bd9Sstevel@tonic-gate 	gss_name_t		desired_name;
3457c478bd9Sstevel@tonic-gate 	gss_OID_desc		name_type_desc;
3467c478bd9Sstevel@tonic-gate 	gss_OID			name_type = &name_type_desc;
3477c478bd9Sstevel@tonic-gate 	OM_uint32		time_req;
3487c478bd9Sstevel@tonic-gate 	gss_OID_set_desc	desired_mechs_desc;
3497c478bd9Sstevel@tonic-gate 	gss_OID_set		desired_mechs;
3507c478bd9Sstevel@tonic-gate 	int			cred_usage;
3517c478bd9Sstevel@tonic-gate 	gss_cred_id_t 		output_cred_handle;
3527c478bd9Sstevel@tonic-gate 	gss_OID_set 		actual_mechs;
3537c478bd9Sstevel@tonic-gate 	gss_buffer_desc		external_name;
3547c478bd9Sstevel@tonic-gate 	uid_t			uid;
3557c478bd9Sstevel@tonic-gate 	int			i, j;
3567c478bd9Sstevel@tonic-gate 
3577c478bd9Sstevel@tonic-gate 	if (gssd_debug)
3587c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("gss_acquire_cred\n"));
3597c478bd9Sstevel@tonic-gate 
3607c478bd9Sstevel@tonic-gate 	memset(res, 0, sizeof (*res));
3617c478bd9Sstevel@tonic-gate 
3627c478bd9Sstevel@tonic-gate 	/*
3637c478bd9Sstevel@tonic-gate 	 * if the request isn't from root, null out the result pointer
3647c478bd9Sstevel@tonic-gate 	 * entries, so the next time through xdr_free won't try to
3657c478bd9Sstevel@tonic-gate 	 * free unmalloc'd memory and then return NULL
3667c478bd9Sstevel@tonic-gate 	 */
3677c478bd9Sstevel@tonic-gate 
3687c478bd9Sstevel@tonic-gate 	if (checkfrom(rqstp, &uid) == 0) {
3697c478bd9Sstevel@tonic-gate 		res->output_cred_handle.GSS_CRED_ID_T_val = NULL;
3707c478bd9Sstevel@tonic-gate 		res->actual_mechs.GSS_OID_SET_val = NULL;
3717c478bd9Sstevel@tonic-gate 		return (FALSE);
3727c478bd9Sstevel@tonic-gate 	}
3737c478bd9Sstevel@tonic-gate 
3747c478bd9Sstevel@tonic-gate /* set the uid sent as the RPC argument */
3757c478bd9Sstevel@tonic-gate 
3767c478bd9Sstevel@tonic-gate 	uid = argp->uid;
3777c478bd9Sstevel@tonic-gate 	set_gssd_uid(uid);
3787c478bd9Sstevel@tonic-gate 
3797c478bd9Sstevel@tonic-gate /* convert the desired name from external to internal format */
3807c478bd9Sstevel@tonic-gate 
3817c478bd9Sstevel@tonic-gate 	external_name.length = argp->desired_name.GSS_BUFFER_T_len;
3827c478bd9Sstevel@tonic-gate 	external_name.value = (void *)malloc(external_name.length);
3837c478bd9Sstevel@tonic-gate 	if (!external_name.value)
3847c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
3857c478bd9Sstevel@tonic-gate 	memcpy(external_name.value, argp->desired_name.GSS_BUFFER_T_val,
3867c478bd9Sstevel@tonic-gate 		external_name.length);
3877c478bd9Sstevel@tonic-gate 
3887c478bd9Sstevel@tonic-gate 	if (argp->name_type.GSS_OID_len == 0) {
3897c478bd9Sstevel@tonic-gate 		name_type = GSS_C_NULL_OID;
3907c478bd9Sstevel@tonic-gate 	} else {
3917c478bd9Sstevel@tonic-gate 		name_type->length = argp->name_type.GSS_OID_len;
3927c478bd9Sstevel@tonic-gate 		name_type->elements = (void *)malloc(name_type->length);
3937c478bd9Sstevel@tonic-gate 		if (!name_type->elements) {
3947c478bd9Sstevel@tonic-gate 			free(external_name.value);
3957c478bd9Sstevel@tonic-gate 			return (GSS_S_FAILURE);
3967c478bd9Sstevel@tonic-gate 		}
3977c478bd9Sstevel@tonic-gate 		memcpy(name_type->elements, argp->name_type.GSS_OID_val,
3987c478bd9Sstevel@tonic-gate 			name_type->length);
3997c478bd9Sstevel@tonic-gate 	}
4007c478bd9Sstevel@tonic-gate 
4017c478bd9Sstevel@tonic-gate 	if (gss_import_name(&minor_status, &external_name, name_type,
4027c478bd9Sstevel@tonic-gate 			    &desired_name) != GSS_S_COMPLETE) {
4037c478bd9Sstevel@tonic-gate 
4047c478bd9Sstevel@tonic-gate 		res->status = (OM_uint32) GSS_S_FAILURE;
4057c478bd9Sstevel@tonic-gate 		res->minor_status = minor_status;
4067c478bd9Sstevel@tonic-gate 
4077c478bd9Sstevel@tonic-gate 		free(external_name.value);
4087c478bd9Sstevel@tonic-gate 		if (name_type != GSS_C_NULL_OID)
4097c478bd9Sstevel@tonic-gate 			free(name_type->elements);
4107c478bd9Sstevel@tonic-gate 
4117c478bd9Sstevel@tonic-gate 		return (TRUE);
4127c478bd9Sstevel@tonic-gate 	}
4137c478bd9Sstevel@tonic-gate 
4147c478bd9Sstevel@tonic-gate /*
4157c478bd9Sstevel@tonic-gate  * copy the XDR structured arguments into their corresponding local GSSAPI
4167c478bd9Sstevel@tonic-gate  * variables.
4177c478bd9Sstevel@tonic-gate  */
4187c478bd9Sstevel@tonic-gate 
4197c478bd9Sstevel@tonic-gate 	cred_usage = argp->cred_usage;
4207c478bd9Sstevel@tonic-gate 	time_req = argp->time_req;
4217c478bd9Sstevel@tonic-gate 
4227c478bd9Sstevel@tonic-gate 	if (argp->desired_mechs.GSS_OID_SET_len != 0) {
4237c478bd9Sstevel@tonic-gate 		desired_mechs = &desired_mechs_desc;
4247c478bd9Sstevel@tonic-gate 		desired_mechs->count =
4257c478bd9Sstevel@tonic-gate 			(int)argp->desired_mechs.GSS_OID_SET_len;
4267c478bd9Sstevel@tonic-gate 		desired_mechs->elements = (gss_OID)
4277c478bd9Sstevel@tonic-gate 			malloc(sizeof (gss_OID_desc) * desired_mechs->count);
4287c478bd9Sstevel@tonic-gate 		if (!desired_mechs->elements) {
4297c478bd9Sstevel@tonic-gate 			free(external_name.value);
4307c478bd9Sstevel@tonic-gate 			free(name_type->elements);
4317c478bd9Sstevel@tonic-gate 			return (GSS_S_FAILURE);
4327c478bd9Sstevel@tonic-gate 		}
4337c478bd9Sstevel@tonic-gate 		for (i = 0; i < desired_mechs->count; i++) {
4347c478bd9Sstevel@tonic-gate 			desired_mechs->elements[i].length =
4357c478bd9Sstevel@tonic-gate 				(OM_uint32)argp->desired_mechs.
4367c478bd9Sstevel@tonic-gate 				GSS_OID_SET_val[i].GSS_OID_len;
4377c478bd9Sstevel@tonic-gate 			desired_mechs->elements[i].elements =
4387c478bd9Sstevel@tonic-gate 				(void *)malloc(desired_mechs->elements[i].
4397c478bd9Sstevel@tonic-gate 						length);
4407c478bd9Sstevel@tonic-gate 			if (!desired_mechs->elements[i].elements) {
4417c478bd9Sstevel@tonic-gate 				free(external_name.value);
4427c478bd9Sstevel@tonic-gate 				free(name_type->elements);
4437c478bd9Sstevel@tonic-gate 				for (j = 0; j < (i -1); j++) {
4447c478bd9Sstevel@tonic-gate 					free
4457c478bd9Sstevel@tonic-gate 					(desired_mechs->elements[j].elements);
4467c478bd9Sstevel@tonic-gate 				}
4477c478bd9Sstevel@tonic-gate 				free(desired_mechs->elements);
4487c478bd9Sstevel@tonic-gate 				return (GSS_S_FAILURE);
4497c478bd9Sstevel@tonic-gate 			}
4507c478bd9Sstevel@tonic-gate 			memcpy(desired_mechs->elements[i].elements,
4517c478bd9Sstevel@tonic-gate 				argp->desired_mechs.GSS_OID_SET_val[i].
4527c478bd9Sstevel@tonic-gate 				GSS_OID_val,
4537c478bd9Sstevel@tonic-gate 				desired_mechs->elements[i].length);
4547c478bd9Sstevel@tonic-gate 		}
4557c478bd9Sstevel@tonic-gate 	} else
4567c478bd9Sstevel@tonic-gate 		desired_mechs = GSS_C_NULL_OID_SET;
4577c478bd9Sstevel@tonic-gate 
4587c478bd9Sstevel@tonic-gate 	/* call the gssapi routine */
4597c478bd9Sstevel@tonic-gate 
4607c478bd9Sstevel@tonic-gate 	res->status = (OM_uint32)gss_acquire_cred(&res->minor_status,
4617c478bd9Sstevel@tonic-gate 				desired_name,
4627c478bd9Sstevel@tonic-gate 				time_req,
4637c478bd9Sstevel@tonic-gate 				desired_mechs,
4647c478bd9Sstevel@tonic-gate 				cred_usage,
4657c478bd9Sstevel@tonic-gate 				&output_cred_handle,
4667c478bd9Sstevel@tonic-gate 				&actual_mechs,
4677c478bd9Sstevel@tonic-gate 				&res->time_rec);
4687c478bd9Sstevel@tonic-gate 
4697c478bd9Sstevel@tonic-gate 	/*
4707c478bd9Sstevel@tonic-gate 	 * convert the output args from the parameter given in the call to the
4717c478bd9Sstevel@tonic-gate 	 * variable in the XDR result
4727c478bd9Sstevel@tonic-gate 	 */
4737c478bd9Sstevel@tonic-gate 
4747c478bd9Sstevel@tonic-gate 	res->output_cred_handle.GSS_CRED_ID_T_len = sizeof (gss_cred_id_t);
4757c478bd9Sstevel@tonic-gate 	res->output_cred_handle.GSS_CRED_ID_T_val =
4767c478bd9Sstevel@tonic-gate 		(void *)malloc(sizeof (gss_cred_id_t));
4777c478bd9Sstevel@tonic-gate 	if (!res->output_cred_handle.GSS_CRED_ID_T_val) {
4787c478bd9Sstevel@tonic-gate 		free(external_name.value);
4797c478bd9Sstevel@tonic-gate 		free(name_type->elements);
4807c478bd9Sstevel@tonic-gate 		for (i = 0; i < desired_mechs->count; i++) {
4817c478bd9Sstevel@tonic-gate 			free(desired_mechs->elements[i].elements);
4827c478bd9Sstevel@tonic-gate 			}
4837c478bd9Sstevel@tonic-gate 		free(desired_mechs->elements);
4847c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
4857c478bd9Sstevel@tonic-gate 	}
4867c478bd9Sstevel@tonic-gate 	memcpy(res->output_cred_handle.GSS_CRED_ID_T_val, &output_cred_handle,
4877c478bd9Sstevel@tonic-gate 		sizeof (gss_cred_id_t));
4887c478bd9Sstevel@tonic-gate 
4897c478bd9Sstevel@tonic-gate 	if (actual_mechs != GSS_C_NULL_OID_SET) {
4907c478bd9Sstevel@tonic-gate 		res->actual_mechs.GSS_OID_SET_len =
4917c478bd9Sstevel@tonic-gate 			(uint_t)actual_mechs->count;
4927c478bd9Sstevel@tonic-gate 		res->actual_mechs.GSS_OID_SET_val = (GSS_OID *)
4937c478bd9Sstevel@tonic-gate 			malloc(sizeof (GSS_OID) * actual_mechs->count);
4947c478bd9Sstevel@tonic-gate 		if (!res->actual_mechs.GSS_OID_SET_val) {
4957c478bd9Sstevel@tonic-gate 			free(external_name.value);
4967c478bd9Sstevel@tonic-gate 			free(name_type->elements);
4977c478bd9Sstevel@tonic-gate 			for (i = 0; i < desired_mechs->count; i++) {
4987c478bd9Sstevel@tonic-gate 				free(desired_mechs->elements[i].elements);
4997c478bd9Sstevel@tonic-gate 			}
5007c478bd9Sstevel@tonic-gate 			free(desired_mechs->elements);
5017c478bd9Sstevel@tonic-gate 			free(res->output_cred_handle.GSS_CRED_ID_T_val);
5027c478bd9Sstevel@tonic-gate 			return (GSS_S_FAILURE);
5037c478bd9Sstevel@tonic-gate 		}
5047c478bd9Sstevel@tonic-gate 		for (i = 0; i < actual_mechs->count; i++) {
5057c478bd9Sstevel@tonic-gate 			res->actual_mechs.GSS_OID_SET_val[i].GSS_OID_len =
5067c478bd9Sstevel@tonic-gate 				(uint_t)actual_mechs->elements[i].length;
5077c478bd9Sstevel@tonic-gate 			res->actual_mechs.GSS_OID_SET_val[i].GSS_OID_val =
5087c478bd9Sstevel@tonic-gate 				(char *)malloc(actual_mechs->elements[i].
5097c478bd9Sstevel@tonic-gate 						length);
5107c478bd9Sstevel@tonic-gate 			if (!res->actual_mechs.GSS_OID_SET_val[i].GSS_OID_val) {
5117c478bd9Sstevel@tonic-gate 				free(external_name.value);
5127c478bd9Sstevel@tonic-gate 				free(name_type->elements);
5137c478bd9Sstevel@tonic-gate 				free(desired_mechs->elements);
5147c478bd9Sstevel@tonic-gate 				for (j = 0; j < desired_mechs->count; j++) {
5157c478bd9Sstevel@tonic-gate 					free
5167c478bd9Sstevel@tonic-gate 					(desired_mechs->elements[i].elements);
5177c478bd9Sstevel@tonic-gate 				}
5187c478bd9Sstevel@tonic-gate 				free(res->actual_mechs.GSS_OID_SET_val);
5197c478bd9Sstevel@tonic-gate 				for (j = 0; j < (i - 1); j++) {
5207c478bd9Sstevel@tonic-gate 					free
5217c478bd9Sstevel@tonic-gate 					(res->actual_mechs.
5227c478bd9Sstevel@tonic-gate 						GSS_OID_SET_val[j].GSS_OID_val);
5237c478bd9Sstevel@tonic-gate 				}
5247c478bd9Sstevel@tonic-gate 				return (GSS_S_FAILURE);
5257c478bd9Sstevel@tonic-gate 			}
5267c478bd9Sstevel@tonic-gate 			memcpy(res->actual_mechs.GSS_OID_SET_val[i].GSS_OID_val,
5277c478bd9Sstevel@tonic-gate 				actual_mechs->elements[i].elements,
5287c478bd9Sstevel@tonic-gate 				actual_mechs->elements[i].length);
5297c478bd9Sstevel@tonic-gate 		}
5307c478bd9Sstevel@tonic-gate 	} else
5317c478bd9Sstevel@tonic-gate 		res->actual_mechs.GSS_OID_SET_len = 0;
5327c478bd9Sstevel@tonic-gate 
5337c478bd9Sstevel@tonic-gate 	/*
5347c478bd9Sstevel@tonic-gate 	 * set the time verifier for credential handle.  To ensure that the
5357c478bd9Sstevel@tonic-gate 	 * timestamp is not the same as previous gssd process, verify that
5367c478bd9Sstevel@tonic-gate 	 * time is not the same as set earlier at start of process.  If it
5377c478bd9Sstevel@tonic-gate 	 * is, sleep one second and reset. (due to one second granularity)
5387c478bd9Sstevel@tonic-gate 	 */
5397c478bd9Sstevel@tonic-gate 
5407c478bd9Sstevel@tonic-gate 	if (res->status == GSS_S_COMPLETE) {
5417c478bd9Sstevel@tonic-gate 		res->gssd_cred_verifier = (OM_uint32)time(NULL);
5427c478bd9Sstevel@tonic-gate 		if (res->gssd_cred_verifier == gssd_time_verf) {
5437c478bd9Sstevel@tonic-gate 			sleep(1);
5447c478bd9Sstevel@tonic-gate 			gssd_time_verf = (OM_uint32)time(NULL);
5457c478bd9Sstevel@tonic-gate 		}
5467c478bd9Sstevel@tonic-gate 		res->gssd_cred_verifier = gssd_time_verf;
5475e01956fSGlenn Barry 	} else
5485e01956fSGlenn Barry 		syslog_gss_error(res->status, res->minor_status,
5495e01956fSGlenn Barry 		    "acquire_cred");
5507c478bd9Sstevel@tonic-gate 
5517c478bd9Sstevel@tonic-gate 	/*
5527c478bd9Sstevel@tonic-gate 	 * now release the space allocated by the underlying gssapi mechanism
5537c478bd9Sstevel@tonic-gate 	 * library for actual_mechs as well as by this routine for
5547c478bd9Sstevel@tonic-gate 	 * external_name, name_type and desired_name
5557c478bd9Sstevel@tonic-gate 	 */
5567c478bd9Sstevel@tonic-gate 
5577c478bd9Sstevel@tonic-gate 	free(external_name.value);
5587c478bd9Sstevel@tonic-gate 	if (name_type != GSS_C_NULL_OID)
5597c478bd9Sstevel@tonic-gate 		free(name_type->elements);
5607c478bd9Sstevel@tonic-gate 	gss_release_name(&minor_status, &desired_name);
5617c478bd9Sstevel@tonic-gate 
5627c478bd9Sstevel@tonic-gate 	if (actual_mechs != GSS_C_NULL_OID_SET) {
5637c478bd9Sstevel@tonic-gate 		for (i = 0; i < actual_mechs->count; i++)
5647c478bd9Sstevel@tonic-gate 			free(actual_mechs->elements[i].elements);
5657c478bd9Sstevel@tonic-gate 		free(actual_mechs->elements);
5667c478bd9Sstevel@tonic-gate 		free(actual_mechs);
5677c478bd9Sstevel@tonic-gate 	}
5687c478bd9Sstevel@tonic-gate 
5697c478bd9Sstevel@tonic-gate 	if (desired_mechs != GSS_C_NULL_OID_SET) {
5707c478bd9Sstevel@tonic-gate 		for (i = 0; i < desired_mechs->count; i++)
5717c478bd9Sstevel@tonic-gate 			free(desired_mechs->elements[i].elements);
5727c478bd9Sstevel@tonic-gate 		free(desired_mechs->elements);
5737c478bd9Sstevel@tonic-gate 
5747c478bd9Sstevel@tonic-gate 	}
5757c478bd9Sstevel@tonic-gate 
5767c478bd9Sstevel@tonic-gate /* return to caller */
5777c478bd9Sstevel@tonic-gate 
5787c478bd9Sstevel@tonic-gate 	return (TRUE);
5797c478bd9Sstevel@tonic-gate }
5807c478bd9Sstevel@tonic-gate 
5817c478bd9Sstevel@tonic-gate bool_t
gss_add_cred_1_svc(argp,res,rqstp)5827c478bd9Sstevel@tonic-gate gss_add_cred_1_svc(argp, res, rqstp)
5837c478bd9Sstevel@tonic-gate 	gss_add_cred_arg *argp;
5847c478bd9Sstevel@tonic-gate 	gss_add_cred_res *res;
5857c478bd9Sstevel@tonic-gate 	struct svc_req *rqstp;
5867c478bd9Sstevel@tonic-gate {
5877c478bd9Sstevel@tonic-gate 
5887c478bd9Sstevel@tonic-gate 	OM_uint32 		minor_status;
5897c478bd9Sstevel@tonic-gate 	gss_name_t		desired_name;
5907c478bd9Sstevel@tonic-gate 	gss_OID_desc		name_type_desc;
5917c478bd9Sstevel@tonic-gate 	gss_OID			name_type = &name_type_desc;
5927c478bd9Sstevel@tonic-gate 	gss_OID_desc		desired_mech_type_desc;
5937c478bd9Sstevel@tonic-gate 	gss_OID			desired_mech_type = &desired_mech_type_desc;
5947c478bd9Sstevel@tonic-gate 	int			cred_usage;
5957c478bd9Sstevel@tonic-gate 	gss_cred_id_t 		input_cred_handle;
5967c478bd9Sstevel@tonic-gate 	gss_OID_set 		actual_mechs;
5977c478bd9Sstevel@tonic-gate 	gss_buffer_desc		external_name;
5987c478bd9Sstevel@tonic-gate 	uid_t			uid;
5997c478bd9Sstevel@tonic-gate 	int			i, j;
6007c478bd9Sstevel@tonic-gate 
6017c478bd9Sstevel@tonic-gate 	if (gssd_debug)
6027c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("gss_add_cred\n"));
6037c478bd9Sstevel@tonic-gate 
6047c478bd9Sstevel@tonic-gate 	if (argp->gssd_cred_verifier != gssd_time_verf) {
6057c478bd9Sstevel@tonic-gate 		res->status = (OM_uint32)GSS_S_DEFECTIVE_CREDENTIAL;
6067c478bd9Sstevel@tonic-gate 		res->minor_status = 0;
6077c478bd9Sstevel@tonic-gate 		res->actual_mechs.GSS_OID_SET_len = 0;
6087c478bd9Sstevel@tonic-gate 		res->actual_mechs.GSS_OID_SET_val = NULL;
6097c478bd9Sstevel@tonic-gate 		res->initiator_time_rec = 0;
6107c478bd9Sstevel@tonic-gate 		res->acceptor_time_rec = 0;
6117c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("gss_add_cred defective cred\n"));
6127c478bd9Sstevel@tonic-gate 		return (TRUE);
6137c478bd9Sstevel@tonic-gate 	}
6147c478bd9Sstevel@tonic-gate 	memset(res, 0, sizeof (*res));
6157c478bd9Sstevel@tonic-gate 
6167c478bd9Sstevel@tonic-gate 	/*
6177c478bd9Sstevel@tonic-gate 	 * if the request isn't from root, null out the result pointer
6187c478bd9Sstevel@tonic-gate 	 * entries, so the next time through xdr_free won't try to
6197c478bd9Sstevel@tonic-gate 	 * free unmalloc'd memory and then return NULL
6207c478bd9Sstevel@tonic-gate 	 */
6217c478bd9Sstevel@tonic-gate 
6227c478bd9Sstevel@tonic-gate 	if (checkfrom(rqstp, &uid) == 0) {
6237c478bd9Sstevel@tonic-gate 		return (FALSE);
6247c478bd9Sstevel@tonic-gate 	}
6257c478bd9Sstevel@tonic-gate 
6267c478bd9Sstevel@tonic-gate /* set the uid sent as the RPC argument */
6277c478bd9Sstevel@tonic-gate 
6287c478bd9Sstevel@tonic-gate 	uid = argp->uid;
6297c478bd9Sstevel@tonic-gate 	set_gssd_uid(uid);
6307c478bd9Sstevel@tonic-gate 
6317c478bd9Sstevel@tonic-gate /* convert the desired name from external to internal format */
6327c478bd9Sstevel@tonic-gate 
6337c478bd9Sstevel@tonic-gate 	external_name.length = argp->desired_name.GSS_BUFFER_T_len;
6347c478bd9Sstevel@tonic-gate 	external_name.value = (void *)argp->desired_name.GSS_BUFFER_T_val;
6357c478bd9Sstevel@tonic-gate 	name_type->length = argp->name_type.GSS_OID_len;
6367c478bd9Sstevel@tonic-gate 	name_type->elements = (void *)argp->name_type.GSS_OID_val;
6377c478bd9Sstevel@tonic-gate 
6387c478bd9Sstevel@tonic-gate 	if (gss_import_name(&minor_status, &external_name, name_type,
6397c478bd9Sstevel@tonic-gate 			    &desired_name) != GSS_S_COMPLETE) {
6407c478bd9Sstevel@tonic-gate 
6417c478bd9Sstevel@tonic-gate 		if (gssd_debug)
6427c478bd9Sstevel@tonic-gate 			fprintf(stderr,
6437c478bd9Sstevel@tonic-gate 				gettext("gss_add_cred:import name"),
6447c478bd9Sstevel@tonic-gate 				gettext(" failed status %d \n"),
6457c478bd9Sstevel@tonic-gate 				res->status);
6467c478bd9Sstevel@tonic-gate 		res->status = (OM_uint32)GSS_S_FAILURE;
6477c478bd9Sstevel@tonic-gate 		res->minor_status = minor_status;
6487c478bd9Sstevel@tonic-gate 		return (TRUE);
6497c478bd9Sstevel@tonic-gate 	}
6507c478bd9Sstevel@tonic-gate 
6517c478bd9Sstevel@tonic-gate /*
6527c478bd9Sstevel@tonic-gate  * copy the XDR structured arguments into their corresponding local GSSAPI
6537c478bd9Sstevel@tonic-gate  * variables.
6547c478bd9Sstevel@tonic-gate  */
6557c478bd9Sstevel@tonic-gate 
6567c478bd9Sstevel@tonic-gate 	cred_usage = argp->cred_usage;
6577c478bd9Sstevel@tonic-gate 	if (argp->desired_mech_type.GSS_OID_len == 0)
6587c478bd9Sstevel@tonic-gate 		desired_mech_type = GSS_C_NULL_OID;
6597c478bd9Sstevel@tonic-gate 	else {
6607c478bd9Sstevel@tonic-gate 		desired_mech_type->length =
6617c478bd9Sstevel@tonic-gate 			(OM_uint32)argp->desired_mech_type.GSS_OID_len;
6627c478bd9Sstevel@tonic-gate 		desired_mech_type->elements =
6637c478bd9Sstevel@tonic-gate 			(void *)malloc(desired_mech_type->length);
6647c478bd9Sstevel@tonic-gate 		if (!desired_mech_type->elements) {
6657c478bd9Sstevel@tonic-gate 			return (GSS_S_FAILURE);
6667c478bd9Sstevel@tonic-gate 		}
6677c478bd9Sstevel@tonic-gate 		memcpy(desired_mech_type->elements,
6687c478bd9Sstevel@tonic-gate 			argp->desired_mech_type.GSS_OID_val,
6697c478bd9Sstevel@tonic-gate 			desired_mech_type->length);
6707c478bd9Sstevel@tonic-gate 	}
6717c478bd9Sstevel@tonic-gate 	input_cred_handle =
6727c478bd9Sstevel@tonic-gate 		(argp->input_cred_handle.GSS_CRED_ID_T_len == 0 ?
6737c478bd9Sstevel@tonic-gate 			GSS_C_NO_CREDENTIAL :
6747c478bd9Sstevel@tonic-gate 			/*LINTED*/
6757c478bd9Sstevel@tonic-gate 			*((gss_cred_id_t *)argp->input_cred_handle.
6767c478bd9Sstevel@tonic-gate 				GSS_CRED_ID_T_val));
6777c478bd9Sstevel@tonic-gate 
6787c478bd9Sstevel@tonic-gate 	if (input_cred_handle != GSS_C_NO_CREDENTIAL)
6797c478bd9Sstevel@tonic-gate 	/* verify the input_cred_handle */
6807c478bd9Sstevel@tonic-gate 		if (argp->gssd_cred_verifier != gssd_time_verf) {
6817c478bd9Sstevel@tonic-gate 			res->status = (OM_uint32)GSS_S_DEFECTIVE_CREDENTIAL;
6827c478bd9Sstevel@tonic-gate 			res->minor_status = 0;
6837c478bd9Sstevel@tonic-gate 			return (TRUE);
6847c478bd9Sstevel@tonic-gate 		}
6857c478bd9Sstevel@tonic-gate 
6867c478bd9Sstevel@tonic-gate 	/* call the gssapi routine */
6877c478bd9Sstevel@tonic-gate 
6887c478bd9Sstevel@tonic-gate 	res->status = (OM_uint32)gss_add_cred(&res->minor_status,
6897c478bd9Sstevel@tonic-gate 				input_cred_handle,
6907c478bd9Sstevel@tonic-gate 				desired_name,
6917c478bd9Sstevel@tonic-gate 				desired_mech_type,
6927c478bd9Sstevel@tonic-gate 				cred_usage,
6937c478bd9Sstevel@tonic-gate 				argp->initiator_time_req,
6947c478bd9Sstevel@tonic-gate 				argp->acceptor_time_req,
6957c478bd9Sstevel@tonic-gate 				NULL,
6967c478bd9Sstevel@tonic-gate 				&actual_mechs,
6977c478bd9Sstevel@tonic-gate 				&res->initiator_time_rec,
6987c478bd9Sstevel@tonic-gate 				&res->acceptor_time_rec);
6997c478bd9Sstevel@tonic-gate 
7007c478bd9Sstevel@tonic-gate 	if ((res->status != GSS_S_COMPLETE) &&
7015e01956fSGlenn Barry 		(res->status != GSS_S_DUPLICATE_ELEMENT))
7025e01956fSGlenn Barry 		syslog_gss_error(res->status, res->minor_status, "add_cred");
7035e01956fSGlenn Barry 
7047c478bd9Sstevel@tonic-gate 	/*
7057c478bd9Sstevel@tonic-gate 	 * convert the output args from the parameter given in the call to the
7067c478bd9Sstevel@tonic-gate 	 * variable in the XDR result
7077c478bd9Sstevel@tonic-gate 	 */
7087c478bd9Sstevel@tonic-gate 	if (actual_mechs != GSS_C_NULL_OID_SET) {
7097c478bd9Sstevel@tonic-gate 		res->actual_mechs.GSS_OID_SET_len =
7107c478bd9Sstevel@tonic-gate 			(uint_t)actual_mechs->count;
7117c478bd9Sstevel@tonic-gate 		res->actual_mechs.GSS_OID_SET_val = (GSS_OID *)
7127c478bd9Sstevel@tonic-gate 			malloc(sizeof (GSS_OID) * actual_mechs->count);
7137c478bd9Sstevel@tonic-gate 		if (!res->actual_mechs.GSS_OID_SET_val) {
7147c478bd9Sstevel@tonic-gate 			free(desired_mech_type->elements);
7157c478bd9Sstevel@tonic-gate 			free(desired_mech_type);
7167c478bd9Sstevel@tonic-gate 			return (GSS_S_FAILURE);
7177c478bd9Sstevel@tonic-gate 		}
7187c478bd9Sstevel@tonic-gate 		for (i = 0; i < actual_mechs->count; i++) {
7197c478bd9Sstevel@tonic-gate 			res->actual_mechs.GSS_OID_SET_val[i].GSS_OID_len =
7207c478bd9Sstevel@tonic-gate 				(uint_t)actual_mechs->elements[i].length;
7217c478bd9Sstevel@tonic-gate 			res->actual_mechs.GSS_OID_SET_val[i].GSS_OID_val =
7227c478bd9Sstevel@tonic-gate 				(char *)malloc(actual_mechs->elements[i].
7237c478bd9Sstevel@tonic-gate 						length);
7247c478bd9Sstevel@tonic-gate 			if (!res->actual_mechs.GSS_OID_SET_val[i].GSS_OID_val) {
7257c478bd9Sstevel@tonic-gate 				free(desired_mech_type->elements);
7267c478bd9Sstevel@tonic-gate 				free(desired_mech_type);
7277c478bd9Sstevel@tonic-gate 				free(res->actual_mechs.GSS_OID_SET_val);
7287c478bd9Sstevel@tonic-gate 				for (j = 0; j < (i - 1); j++) {
7297c478bd9Sstevel@tonic-gate 					free
7307c478bd9Sstevel@tonic-gate 					(res->actual_mechs.
7317c478bd9Sstevel@tonic-gate 						GSS_OID_SET_val[j].GSS_OID_val);
7327c478bd9Sstevel@tonic-gate 				}
7337c478bd9Sstevel@tonic-gate 				return (GSS_S_FAILURE);
7347c478bd9Sstevel@tonic-gate 			}
7357c478bd9Sstevel@tonic-gate 			memcpy(res->actual_mechs.GSS_OID_SET_val[i].GSS_OID_val,
7367c478bd9Sstevel@tonic-gate 				actual_mechs->elements[i].elements,
7377c478bd9Sstevel@tonic-gate 				actual_mechs->elements[i].length);
7387c478bd9Sstevel@tonic-gate 		}
7397c478bd9Sstevel@tonic-gate 	} else
7407c478bd9Sstevel@tonic-gate 		res->actual_mechs.GSS_OID_SET_len = 0;
7417c478bd9Sstevel@tonic-gate 
7427c478bd9Sstevel@tonic-gate 	/*
7437c478bd9Sstevel@tonic-gate 	 * now release the space allocated for
7447c478bd9Sstevel@tonic-gate 	 * desired_name  and desired_mech_type
7457c478bd9Sstevel@tonic-gate 	 */
7467c478bd9Sstevel@tonic-gate 
7477c478bd9Sstevel@tonic-gate 	gss_release_name(&minor_status, &desired_name);
7487c478bd9Sstevel@tonic-gate 	free(desired_mech_type->elements);
7497c478bd9Sstevel@tonic-gate 	gss_release_oid_set(&minor_status, &actual_mechs);
7507c478bd9Sstevel@tonic-gate 	/*
7517c478bd9Sstevel@tonic-gate 	 * if (actual_mechs != GSS_C_NULL_OID_SET) {
7527c478bd9Sstevel@tonic-gate 	 * 	for (i = 0; i < actual_mechs->count; i++)
7537c478bd9Sstevel@tonic-gate 	 * 		free(actual_mechs->elements[i].elements);
7547c478bd9Sstevel@tonic-gate 	 * 	free(actual_mechs->elements);
7557c478bd9Sstevel@tonic-gate 	 * 	free(actual_mechs);
7567c478bd9Sstevel@tonic-gate 	 * }
7577c478bd9Sstevel@tonic-gate 	 */
7587c478bd9Sstevel@tonic-gate 
7597c478bd9Sstevel@tonic-gate 
7607c478bd9Sstevel@tonic-gate /* return to caller */
7617c478bd9Sstevel@tonic-gate 
7627c478bd9Sstevel@tonic-gate 	return (TRUE);
7637c478bd9Sstevel@tonic-gate }
7647c478bd9Sstevel@tonic-gate 
7657c478bd9Sstevel@tonic-gate bool_t
gss_release_cred_1_svc(argp,res,rqstp)7667c478bd9Sstevel@tonic-gate gss_release_cred_1_svc(argp, res, rqstp)
7677c478bd9Sstevel@tonic-gate gss_release_cred_arg *argp;
7687c478bd9Sstevel@tonic-gate gss_release_cred_res *res;
7697c478bd9Sstevel@tonic-gate struct svc_req *rqstp;
7707c478bd9Sstevel@tonic-gate {
7717c478bd9Sstevel@tonic-gate 
7727c478bd9Sstevel@tonic-gate 	uid_t uid;
7737c478bd9Sstevel@tonic-gate 	gss_cred_id_t cred_handle;
7747c478bd9Sstevel@tonic-gate 
7757c478bd9Sstevel@tonic-gate 	memset(res, 0, sizeof (*res));
7767c478bd9Sstevel@tonic-gate 
7777c478bd9Sstevel@tonic-gate 	if (gssd_debug)
7787c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("gss_release_cred\n"));
7797c478bd9Sstevel@tonic-gate 
7807c478bd9Sstevel@tonic-gate 	if (checkfrom(rqstp, &uid) == 0)
7817c478bd9Sstevel@tonic-gate 		return (FALSE);
7827c478bd9Sstevel@tonic-gate 
7837c478bd9Sstevel@tonic-gate 	/* set the uid sent as the RPC argument */
7847c478bd9Sstevel@tonic-gate 
7857c478bd9Sstevel@tonic-gate 	uid = argp->uid;
7867c478bd9Sstevel@tonic-gate 	set_gssd_uid(uid);
7877c478bd9Sstevel@tonic-gate 
7887c478bd9Sstevel@tonic-gate 	/*
7897c478bd9Sstevel@tonic-gate 	 * if the cred_handle verifier is not correct,
7907c478bd9Sstevel@tonic-gate 	 * set status to GSS_S_DEFECTIVE_CREDENTIAL and return
7917c478bd9Sstevel@tonic-gate 	 */
7927c478bd9Sstevel@tonic-gate 
7937c478bd9Sstevel@tonic-gate 	if (argp->gssd_cred_verifier != gssd_time_verf) {
7947c478bd9Sstevel@tonic-gate 		res->status = (OM_uint32)GSS_S_DEFECTIVE_CREDENTIAL;
7957c478bd9Sstevel@tonic-gate 		return (TRUE);
7967c478bd9Sstevel@tonic-gate 	}
7977c478bd9Sstevel@tonic-gate 
7987c478bd9Sstevel@tonic-gate 	/*
7997c478bd9Sstevel@tonic-gate 	 * if the cred_handle length is 0
8007c478bd9Sstevel@tonic-gate 	 * set cred_handle argument to GSS_S_NO_CREDENTIAL
8017c478bd9Sstevel@tonic-gate 	 */
8027c478bd9Sstevel@tonic-gate 
8037c478bd9Sstevel@tonic-gate 	if (argp->cred_handle.GSS_CRED_ID_T_len == 0)
8047c478bd9Sstevel@tonic-gate 		cred_handle = GSS_C_NO_CREDENTIAL;
8057c478bd9Sstevel@tonic-gate 	else
8067c478bd9Sstevel@tonic-gate 		cred_handle =
8077c478bd9Sstevel@tonic-gate 		(gss_cred_id_t)argp->cred_handle.GSS_CRED_ID_T_val;
8087c478bd9Sstevel@tonic-gate 
8097c478bd9Sstevel@tonic-gate 	/* call the gssapi routine */
8107c478bd9Sstevel@tonic-gate 
8117c478bd9Sstevel@tonic-gate 	res->status = (OM_uint32)gss_release_cred(&res->minor_status,
8127c478bd9Sstevel@tonic-gate 					&cred_handle);
8137c478bd9Sstevel@tonic-gate 
8147c478bd9Sstevel@tonic-gate 	/* return to caller */
8157c478bd9Sstevel@tonic-gate 
8167c478bd9Sstevel@tonic-gate 	return (TRUE);
8177c478bd9Sstevel@tonic-gate }
8187c478bd9Sstevel@tonic-gate 
8197c478bd9Sstevel@tonic-gate bool_t
gss_init_sec_context_1_svc(argp,res,rqstp)8207c478bd9Sstevel@tonic-gate gss_init_sec_context_1_svc(argp, res, rqstp)
8217c478bd9Sstevel@tonic-gate gss_init_sec_context_arg *argp;
8227c478bd9Sstevel@tonic-gate gss_init_sec_context_res *res;
8237c478bd9Sstevel@tonic-gate struct svc_req *rqstp;
8247c478bd9Sstevel@tonic-gate {
8257c478bd9Sstevel@tonic-gate 
8267c478bd9Sstevel@tonic-gate 	OM_uint32 	minor_status;
8277c478bd9Sstevel@tonic-gate 	gss_ctx_id_t	context_handle;
8287c478bd9Sstevel@tonic-gate 	bool_t context_verf_ok;
8297c478bd9Sstevel@tonic-gate 	gss_cred_id_t	claimant_cred_handle;
8307c478bd9Sstevel@tonic-gate 	gss_buffer_desc	external_name;
8317c478bd9Sstevel@tonic-gate 	gss_OID_desc	name_type_desc;
8327c478bd9Sstevel@tonic-gate 	gss_OID		name_type = &name_type_desc;
8337c478bd9Sstevel@tonic-gate 	gss_name_t	internal_name;
8347c478bd9Sstevel@tonic-gate 
8357c478bd9Sstevel@tonic-gate 	gss_OID_desc	mech_type_desc;
8367c478bd9Sstevel@tonic-gate 	gss_OID		mech_type = &mech_type_desc;
8377c478bd9Sstevel@tonic-gate 	struct gss_channel_bindings_struct
8387c478bd9Sstevel@tonic-gate 			input_chan_bindings;
8397c478bd9Sstevel@tonic-gate 	gss_channel_bindings_t input_chan_bindings_ptr;
8407c478bd9Sstevel@tonic-gate 	gss_buffer_desc input_token;
8417c478bd9Sstevel@tonic-gate 	gss_buffer_desc output_token;
8427c478bd9Sstevel@tonic-gate 	gss_buffer_t input_token_ptr;
8437c478bd9Sstevel@tonic-gate 	gss_OID actual_mech_type;
8447c478bd9Sstevel@tonic-gate 	struct gssd_ctx_slot *slot = NULL;
8457c478bd9Sstevel@tonic-gate 
8467c478bd9Sstevel@tonic-gate 	uid_t uid;
8477c478bd9Sstevel@tonic-gate 
8487c478bd9Sstevel@tonic-gate 	memset(res, 0, sizeof (*res));
8497c478bd9Sstevel@tonic-gate 
8507c478bd9Sstevel@tonic-gate 	if (gssd_debug)
8517c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("gss_init_sec_context\n"));
8527c478bd9Sstevel@tonic-gate 
8537c478bd9Sstevel@tonic-gate 	/*
8547c478bd9Sstevel@tonic-gate 	 * if the request isn't from root, null out the result pointer
8557c478bd9Sstevel@tonic-gate 	 * entries, so the next time through xdr_free won't try to
8567c478bd9Sstevel@tonic-gate 	 * free unmalloc'd memory and then return NULL
8577c478bd9Sstevel@tonic-gate 	 */
8587c478bd9Sstevel@tonic-gate 
8597c478bd9Sstevel@tonic-gate 	if (checkfrom(rqstp, &uid) == 0) {
8607c478bd9Sstevel@tonic-gate 		res->context_handle.GSS_CTX_ID_T_val =  NULL;
8617c478bd9Sstevel@tonic-gate 		res->actual_mech_type.GSS_OID_val = NULL;
8627c478bd9Sstevel@tonic-gate 		res->output_token.GSS_BUFFER_T_val = NULL;
8637c478bd9Sstevel@tonic-gate 		return (FALSE);
8647c478bd9Sstevel@tonic-gate 	}
8657c478bd9Sstevel@tonic-gate 
8667c478bd9Sstevel@tonic-gate /* set the uid sent as the RPC argument */
8677c478bd9Sstevel@tonic-gate 
8687c478bd9Sstevel@tonic-gate 	uid = argp->uid;
8697c478bd9Sstevel@tonic-gate 	set_gssd_uid(uid);
8707c478bd9Sstevel@tonic-gate 
8717c478bd9Sstevel@tonic-gate /*
8727c478bd9Sstevel@tonic-gate  * copy the supplied context handle into the local context handle, so it
8737c478bd9Sstevel@tonic-gate  * can be supplied to the gss_init_sec_context call
8747c478bd9Sstevel@tonic-gate  */
8757c478bd9Sstevel@tonic-gate 
8767c478bd9Sstevel@tonic-gate 	gssd_convert_context_handle(&argp->context_handle, &context_handle,
8777c478bd9Sstevel@tonic-gate 		argp->gssd_context_verifier, &context_verf_ok, &slot);
8787c478bd9Sstevel@tonic-gate 
8797c478bd9Sstevel@tonic-gate 	claimant_cred_handle =
8807c478bd9Sstevel@tonic-gate 		(argp->claimant_cred_handle.GSS_CRED_ID_T_len == 0 ?
8817c478bd9Sstevel@tonic-gate 		GSS_C_NO_CREDENTIAL :
8827c478bd9Sstevel@tonic-gate 		/*LINTED*/
8837c478bd9Sstevel@tonic-gate 		*((gss_cred_id_t *)argp->claimant_cred_handle.
8847c478bd9Sstevel@tonic-gate 			GSS_CRED_ID_T_val));
8857c478bd9Sstevel@tonic-gate 
8867c478bd9Sstevel@tonic-gate 	if (claimant_cred_handle != GSS_C_NO_CREDENTIAL) {
8877c478bd9Sstevel@tonic-gate 		/* verify the verifier_cred_handle */
8887c478bd9Sstevel@tonic-gate 		if (argp->gssd_cred_verifier != gssd_time_verf) {
8897c478bd9Sstevel@tonic-gate 			res->context_handle.GSS_CTX_ID_T_val = NULL;
8907c478bd9Sstevel@tonic-gate 			res->output_token.GSS_BUFFER_T_val = NULL;
8917c478bd9Sstevel@tonic-gate 			res->actual_mech_type.GSS_OID_val = NULL;
8927c478bd9Sstevel@tonic-gate 			res->context_handle.GSS_CTX_ID_T_len = 0;
8937c478bd9Sstevel@tonic-gate 			res->output_token.GSS_BUFFER_T_len = 0;
8947c478bd9Sstevel@tonic-gate 			res->actual_mech_type.GSS_OID_len = 0;
8957c478bd9Sstevel@tonic-gate 			res->status = (OM_uint32)GSS_S_DEFECTIVE_CREDENTIAL;
8967c478bd9Sstevel@tonic-gate 			res->minor_status = 0;
8977c478bd9Sstevel@tonic-gate 			return (TRUE);
8987c478bd9Sstevel@tonic-gate 		}
8997c478bd9Sstevel@tonic-gate 	}
9007c478bd9Sstevel@tonic-gate 
9017c478bd9Sstevel@tonic-gate 	if (context_handle != GSS_C_NO_CONTEXT) {
9027c478bd9Sstevel@tonic-gate 		/* verify the verifier_context_handle */
9037c478bd9Sstevel@tonic-gate 
9047c478bd9Sstevel@tonic-gate 		if (!context_verf_ok) {
9057c478bd9Sstevel@tonic-gate 			res->context_handle.GSS_CTX_ID_T_val = NULL;
9067c478bd9Sstevel@tonic-gate 			res->output_token.GSS_BUFFER_T_val = NULL;
9077c478bd9Sstevel@tonic-gate 			res->actual_mech_type.GSS_OID_val = NULL;
9087c478bd9Sstevel@tonic-gate 			res->context_handle.GSS_CTX_ID_T_len = 0;
9097c478bd9Sstevel@tonic-gate 			res->output_token.GSS_BUFFER_T_len = 0;
9107c478bd9Sstevel@tonic-gate 			res->actual_mech_type.GSS_OID_len = 0;
9117c478bd9Sstevel@tonic-gate 			res->status = (OM_uint32)GSS_S_NO_CONTEXT;
9127c478bd9Sstevel@tonic-gate 			res->minor_status = 0;
9137c478bd9Sstevel@tonic-gate 			return (TRUE);
9147c478bd9Sstevel@tonic-gate 		}
9157c478bd9Sstevel@tonic-gate 	}
9167c478bd9Sstevel@tonic-gate 
9177c478bd9Sstevel@tonic-gate 	/* convert the target name from external to internal format */
9187c478bd9Sstevel@tonic-gate 
9197c478bd9Sstevel@tonic-gate 	external_name.length = argp->target_name.GSS_BUFFER_T_len;
9207c478bd9Sstevel@tonic-gate 	external_name.value = (void *)argp->target_name.GSS_BUFFER_T_val;
9217c478bd9Sstevel@tonic-gate 
9227c478bd9Sstevel@tonic-gate 	if (argp->name_type.GSS_OID_len == 0) {
9237c478bd9Sstevel@tonic-gate 		name_type = GSS_C_NULL_OID;
9247c478bd9Sstevel@tonic-gate 	} else {
9257c478bd9Sstevel@tonic-gate 		name_type->length = argp->name_type.GSS_OID_len;
9267c478bd9Sstevel@tonic-gate 		name_type->elements = (void *)malloc(name_type->length);
9277c478bd9Sstevel@tonic-gate 		if (!name_type->elements)
9287c478bd9Sstevel@tonic-gate 			return (GSS_S_FAILURE);
9297c478bd9Sstevel@tonic-gate 		memcpy(name_type->elements, argp->name_type.GSS_OID_val,
9307c478bd9Sstevel@tonic-gate 			name_type->length);
9317c478bd9Sstevel@tonic-gate 	}
9327c478bd9Sstevel@tonic-gate 
9337c478bd9Sstevel@tonic-gate 	if (argp->mech_type.GSS_OID_len == 0)
9347c478bd9Sstevel@tonic-gate 		mech_type = GSS_C_NULL_OID;
9357c478bd9Sstevel@tonic-gate 	else {
9367c478bd9Sstevel@tonic-gate 		mech_type->length = (OM_uint32)argp->mech_type.GSS_OID_len;
9377c478bd9Sstevel@tonic-gate 		mech_type->elements = (void *)argp->mech_type.GSS_OID_val;
9387c478bd9Sstevel@tonic-gate 	}
9397c478bd9Sstevel@tonic-gate 
9407c478bd9Sstevel@tonic-gate 	if (gss_import_name(&minor_status, &external_name, name_type,
9417c478bd9Sstevel@tonic-gate 			    &internal_name) != GSS_S_COMPLETE) {
9427c478bd9Sstevel@tonic-gate 
9437c478bd9Sstevel@tonic-gate 		if (name_type != GSS_C_NULL_OID)
9447c478bd9Sstevel@tonic-gate 			free(name_type->elements);
9457c478bd9Sstevel@tonic-gate 		res->status = (OM_uint32)GSS_S_FAILURE;
9467c478bd9Sstevel@tonic-gate 		res->minor_status = minor_status;
9477c478bd9Sstevel@tonic-gate 
9487c478bd9Sstevel@tonic-gate 		return (TRUE);
9497c478bd9Sstevel@tonic-gate 	}
9507c478bd9Sstevel@tonic-gate /*
9517c478bd9Sstevel@tonic-gate  * copy the XDR structured arguments into their corresponding local GSSAPI
9527c478bd9Sstevel@tonic-gate  * variables.
9537c478bd9Sstevel@tonic-gate  */
9547c478bd9Sstevel@tonic-gate 
9557c478bd9Sstevel@tonic-gate 	if (argp->input_chan_bindings.present == YES) {
9567c478bd9Sstevel@tonic-gate 		input_chan_bindings_ptr = &input_chan_bindings;
9577c478bd9Sstevel@tonic-gate 		input_chan_bindings.initiator_addrtype =
9587c478bd9Sstevel@tonic-gate 			(OM_uint32)argp->input_chan_bindings.
9597c478bd9Sstevel@tonic-gate 			initiator_addrtype;
9607c478bd9Sstevel@tonic-gate 		input_chan_bindings.initiator_address.length =
9617c478bd9Sstevel@tonic-gate 			(uint_t)argp->input_chan_bindings.initiator_address.
9627c478bd9Sstevel@tonic-gate 			GSS_BUFFER_T_len;
9637c478bd9Sstevel@tonic-gate 		input_chan_bindings.initiator_address.value =
9647c478bd9Sstevel@tonic-gate 			(void *)argp->input_chan_bindings.initiator_address.
9657c478bd9Sstevel@tonic-gate 			GSS_BUFFER_T_val;
9667c478bd9Sstevel@tonic-gate 		input_chan_bindings.acceptor_addrtype =
9677c478bd9Sstevel@tonic-gate 			(OM_uint32)argp->input_chan_bindings.acceptor_addrtype;
9687c478bd9Sstevel@tonic-gate 		input_chan_bindings.acceptor_address.length =
9697c478bd9Sstevel@tonic-gate 			(uint_t)argp->input_chan_bindings.acceptor_address.
9707c478bd9Sstevel@tonic-gate 			GSS_BUFFER_T_len;
9717c478bd9Sstevel@tonic-gate 		input_chan_bindings.acceptor_address.value =
9727c478bd9Sstevel@tonic-gate 			(void *)argp->input_chan_bindings.acceptor_address.
9737c478bd9Sstevel@tonic-gate 			GSS_BUFFER_T_val;
9747c478bd9Sstevel@tonic-gate 		input_chan_bindings.application_data.length =
9757c478bd9Sstevel@tonic-gate 			(uint_t)argp->input_chan_bindings.application_data.
9767c478bd9Sstevel@tonic-gate 			GSS_BUFFER_T_len;
9777c478bd9Sstevel@tonic-gate 		input_chan_bindings.application_data.value =
9787c478bd9Sstevel@tonic-gate 			(void *)argp->input_chan_bindings.application_data.
9797c478bd9Sstevel@tonic-gate 			GSS_BUFFER_T_val;
9807c478bd9Sstevel@tonic-gate 	} else {
9817c478bd9Sstevel@tonic-gate 		input_chan_bindings_ptr = GSS_C_NO_CHANNEL_BINDINGS;
9827c478bd9Sstevel@tonic-gate 		input_chan_bindings.initiator_addrtype = 0;
9837c478bd9Sstevel@tonic-gate 		input_chan_bindings.initiator_address.length = 0;
9847c478bd9Sstevel@tonic-gate 		input_chan_bindings.initiator_address.value = 0;
9857c478bd9Sstevel@tonic-gate 		input_chan_bindings.acceptor_addrtype = 0;
9867c478bd9Sstevel@tonic-gate 		input_chan_bindings.acceptor_address.length = 0;
9877c478bd9Sstevel@tonic-gate 		input_chan_bindings.acceptor_address.value = 0;
9887c478bd9Sstevel@tonic-gate 		input_chan_bindings.application_data.length = 0;
9897c478bd9Sstevel@tonic-gate 		input_chan_bindings.application_data.value = 0;
9907c478bd9Sstevel@tonic-gate 	}
9917c478bd9Sstevel@tonic-gate 
9927c478bd9Sstevel@tonic-gate 	if (argp->input_token.GSS_BUFFER_T_len == 0) {
9937c478bd9Sstevel@tonic-gate 		input_token_ptr = GSS_C_NO_BUFFER;
9947c478bd9Sstevel@tonic-gate 	} else {
9957c478bd9Sstevel@tonic-gate 		input_token_ptr = &input_token;
9967c478bd9Sstevel@tonic-gate 		input_token.length = (size_t)
9977c478bd9Sstevel@tonic-gate 				argp->input_token.GSS_BUFFER_T_len;
9987c478bd9Sstevel@tonic-gate 		input_token.value = (void *)argp->input_token.GSS_BUFFER_T_val;
9997c478bd9Sstevel@tonic-gate 	}
10007c478bd9Sstevel@tonic-gate 
10017c478bd9Sstevel@tonic-gate /* call the gssapi routine */
10027c478bd9Sstevel@tonic-gate 
10037c478bd9Sstevel@tonic-gate 	res->status = (OM_uint32)gss_init_sec_context(&res->minor_status,
10047c478bd9Sstevel@tonic-gate 			(gss_cred_id_t)argp->claimant_cred_handle.
10057c478bd9Sstevel@tonic-gate 						GSS_CRED_ID_T_val,
10067c478bd9Sstevel@tonic-gate 					&context_handle,
10077c478bd9Sstevel@tonic-gate 					internal_name,
10087c478bd9Sstevel@tonic-gate 					mech_type,
10097c478bd9Sstevel@tonic-gate 					argp->req_flags,
10107c478bd9Sstevel@tonic-gate 					argp->time_req,
10117c478bd9Sstevel@tonic-gate 					input_chan_bindings_ptr,
10127c478bd9Sstevel@tonic-gate 					input_token_ptr,
10137c478bd9Sstevel@tonic-gate 					&actual_mech_type,
10147c478bd9Sstevel@tonic-gate 					&output_token,
10157c478bd9Sstevel@tonic-gate 					&res->ret_flags,
10167c478bd9Sstevel@tonic-gate 					&res->time_rec);
10177c478bd9Sstevel@tonic-gate 
10187c478bd9Sstevel@tonic-gate 	/*
10197c478bd9Sstevel@tonic-gate 	 * convert the output args from the parameter given in the call to the
10207c478bd9Sstevel@tonic-gate 	 * variable in the XDR result
10217c478bd9Sstevel@tonic-gate 	 */
10227c478bd9Sstevel@tonic-gate 
10237c478bd9Sstevel@tonic-gate 	if (res->status == (OM_uint32)GSS_S_COMPLETE ||
10247c478bd9Sstevel@tonic-gate 		res->status == (OM_uint32)GSS_S_CONTINUE_NEEDED) {
10257c478bd9Sstevel@tonic-gate 
10267c478bd9Sstevel@tonic-gate 		if (slot == NULL || slot->ctx != context_handle) {
10277c478bd9Sstevel@tonic-gate 			/*
10287c478bd9Sstevel@tonic-gate 			 * Note that gssd_alloc_slot() will delete ctx's as long
10297c478bd9Sstevel@tonic-gate 			 * as we don't call gssd_rel_slot().
10307c478bd9Sstevel@tonic-gate 			 */
10317c478bd9Sstevel@tonic-gate 			slot = gssd_alloc_slot(context_handle);
10327c478bd9Sstevel@tonic-gate 		}
10337c478bd9Sstevel@tonic-gate 
10347c478bd9Sstevel@tonic-gate 		res->gssd_context_verifier = slot->verf;
10357c478bd9Sstevel@tonic-gate 
10367c478bd9Sstevel@tonic-gate 		res->context_handle.GSS_CTX_ID_T_len = sizeof (gss_ctx_id_t);
10377c478bd9Sstevel@tonic-gate 		res->context_handle.GSS_CTX_ID_T_val =
10387c478bd9Sstevel@tonic-gate 			(void *)malloc(sizeof (gss_ctx_id_t));
10397c478bd9Sstevel@tonic-gate 		if (!res->context_handle.GSS_CTX_ID_T_val) {
10407c478bd9Sstevel@tonic-gate 			free(name_type->elements);
10417c478bd9Sstevel@tonic-gate 			return (GSS_S_FAILURE);
10427c478bd9Sstevel@tonic-gate 		}
10437c478bd9Sstevel@tonic-gate 
10447c478bd9Sstevel@tonic-gate 		memcpy(res->context_handle.GSS_CTX_ID_T_val, &slot->rpcctx,
10457c478bd9Sstevel@tonic-gate 			sizeof (gss_ctx_id_t));
10467c478bd9Sstevel@tonic-gate 
10477c478bd9Sstevel@tonic-gate 		res->output_token.GSS_BUFFER_T_len =
10487c478bd9Sstevel@tonic-gate 			(uint_t)output_token.length;
10497c478bd9Sstevel@tonic-gate 		res->output_token.GSS_BUFFER_T_val =
10507c478bd9Sstevel@tonic-gate 			(char *)output_token.value;
10517c478bd9Sstevel@tonic-gate 
10527c478bd9Sstevel@tonic-gate 		/*
10537c478bd9Sstevel@tonic-gate 		 * the actual mech type parameter
10547c478bd9Sstevel@tonic-gate 		 * is ready only upon GSS_S_COMPLETE
10557c478bd9Sstevel@tonic-gate 		 */
10567c478bd9Sstevel@tonic-gate 		if (res->status == GSS_S_COMPLETE) {
10577c478bd9Sstevel@tonic-gate 			res->actual_mech_type.GSS_OID_len =
10587c478bd9Sstevel@tonic-gate 				(uint_t)actual_mech_type->length;
10597c478bd9Sstevel@tonic-gate 			res->actual_mech_type.GSS_OID_val =
10607c478bd9Sstevel@tonic-gate 				(void *)malloc(actual_mech_type->length);
10617c478bd9Sstevel@tonic-gate 			if (!res->actual_mech_type.GSS_OID_val) {
10627c478bd9Sstevel@tonic-gate 				free(name_type->elements);
10637c478bd9Sstevel@tonic-gate 				free(res->context_handle.GSS_CTX_ID_T_val);
10647c478bd9Sstevel@tonic-gate 				return (GSS_S_FAILURE);
10657c478bd9Sstevel@tonic-gate 			}
10667c478bd9Sstevel@tonic-gate 			memcpy(res->actual_mech_type.GSS_OID_val,
10677c478bd9Sstevel@tonic-gate 				(char *)actual_mech_type->elements,
10687c478bd9Sstevel@tonic-gate 				actual_mech_type->length);
10697c478bd9Sstevel@tonic-gate 		} else
10707c478bd9Sstevel@tonic-gate 			res->actual_mech_type.GSS_OID_len = 0;
10717c478bd9Sstevel@tonic-gate 	} else {
10725e01956fSGlenn Barry 		syslog_gss_error(res->status, res->minor_status,
10735e01956fSGlenn Barry 			    "init_sec_context");
10747c478bd9Sstevel@tonic-gate 		if (context_handle != GSS_C_NO_CONTEXT) {
10757c478bd9Sstevel@tonic-gate 			(void) gss_delete_sec_context(&minor_status,
10767c478bd9Sstevel@tonic-gate 				&context_handle, NULL);
10777c478bd9Sstevel@tonic-gate 		}
10787c478bd9Sstevel@tonic-gate 		res->context_handle.GSS_CTX_ID_T_len = 0;
10797c478bd9Sstevel@tonic-gate 		res->actual_mech_type.GSS_OID_len = 0;
10807c478bd9Sstevel@tonic-gate 		res->output_token.GSS_BUFFER_T_len = 0;
10817c478bd9Sstevel@tonic-gate 	}
10827c478bd9Sstevel@tonic-gate 
10837c478bd9Sstevel@tonic-gate 	/*
10847c478bd9Sstevel@tonic-gate 	 * now release the space allocated by the underlying gssapi mechanism
10857c478bd9Sstevel@tonic-gate 	 * library for internal_name and for the name_type.
10867c478bd9Sstevel@tonic-gate 	 */
10877c478bd9Sstevel@tonic-gate 
10887c478bd9Sstevel@tonic-gate 	gss_release_name(&minor_status, &internal_name);
10897c478bd9Sstevel@tonic-gate 	if (name_type != GSS_C_NULL_OID)
10907c478bd9Sstevel@tonic-gate 		free(name_type->elements);
10917c478bd9Sstevel@tonic-gate 
10927c478bd9Sstevel@tonic-gate 
10937c478bd9Sstevel@tonic-gate 	/* return to caller */
10947c478bd9Sstevel@tonic-gate 	return (TRUE);
10957c478bd9Sstevel@tonic-gate }
10967c478bd9Sstevel@tonic-gate 
10977c478bd9Sstevel@tonic-gate bool_t
gss_accept_sec_context_1_svc(argp,res,rqstp)10987c478bd9Sstevel@tonic-gate gss_accept_sec_context_1_svc(argp, res, rqstp)
10997c478bd9Sstevel@tonic-gate gss_accept_sec_context_arg *argp;
11007c478bd9Sstevel@tonic-gate gss_accept_sec_context_res *res;
11017c478bd9Sstevel@tonic-gate struct svc_req *rqstp;
11027c478bd9Sstevel@tonic-gate {
11037c478bd9Sstevel@tonic-gate 	uid_t uid;
11047c478bd9Sstevel@tonic-gate 	OM_uint32 minor_status;
11057c478bd9Sstevel@tonic-gate 	gss_ctx_id_t context_handle = NULL;
11067c478bd9Sstevel@tonic-gate 	gss_cred_id_t verifier_cred_handle;
11077c478bd9Sstevel@tonic-gate 	gss_buffer_desc external_name;
11087c478bd9Sstevel@tonic-gate 	gss_name_t internal_name = NULL;
11097c478bd9Sstevel@tonic-gate 
11107c478bd9Sstevel@tonic-gate 	gss_buffer_desc input_token_buffer;
11117c478bd9Sstevel@tonic-gate 	gss_buffer_t input_token_buffer_ptr;
11127c478bd9Sstevel@tonic-gate 	struct gss_channel_bindings_struct
11137c478bd9Sstevel@tonic-gate 			input_chan_bindings;
11147c478bd9Sstevel@tonic-gate 	gss_channel_bindings_t input_chan_bindings_ptr;
11157c478bd9Sstevel@tonic-gate 	gss_OID mech_type;
11167c478bd9Sstevel@tonic-gate 	gss_buffer_desc output_token;
11177c478bd9Sstevel@tonic-gate 	gss_cred_id_t delegated_cred_handle;
11187c478bd9Sstevel@tonic-gate 	bool_t context_verf_ok;
11197c478bd9Sstevel@tonic-gate 	struct gssd_ctx_slot *slot = NULL;
11207c478bd9Sstevel@tonic-gate 
11217c478bd9Sstevel@tonic-gate 	memset(res, 0, sizeof (*res));
11227c478bd9Sstevel@tonic-gate 
11237c478bd9Sstevel@tonic-gate 	if (gssd_debug)
11247c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("gss_accept_sec_context\n"));
11257c478bd9Sstevel@tonic-gate 
11267c478bd9Sstevel@tonic-gate 	/*
11277c478bd9Sstevel@tonic-gate 	 * if the request isn't from root, null out the result pointer
11287c478bd9Sstevel@tonic-gate 	 * entries, so the next time through xdr_free won't try to
11297c478bd9Sstevel@tonic-gate 	 * free unmalloc'd memory and then return NULL
11307c478bd9Sstevel@tonic-gate 	 */
11317c478bd9Sstevel@tonic-gate 
11327c478bd9Sstevel@tonic-gate 	if (checkfrom(rqstp, &uid) == 0) {
11337c478bd9Sstevel@tonic-gate 		res->context_handle.GSS_CTX_ID_T_val = NULL;
11347c478bd9Sstevel@tonic-gate 		res->src_name.GSS_BUFFER_T_val = NULL;
11357c478bd9Sstevel@tonic-gate 		res->mech_type.GSS_OID_val = NULL;
11367c478bd9Sstevel@tonic-gate 		res->output_token.GSS_BUFFER_T_val = NULL;
11377c478bd9Sstevel@tonic-gate 		res->delegated_cred_handle.GSS_CRED_ID_T_val = NULL;
11387c478bd9Sstevel@tonic-gate 		return (FALSE);
11397c478bd9Sstevel@tonic-gate 	}
11407c478bd9Sstevel@tonic-gate 
11417c478bd9Sstevel@tonic-gate 	/* set the uid sent as the RPC argument */
11427c478bd9Sstevel@tonic-gate 
11437c478bd9Sstevel@tonic-gate 	uid = argp->uid;
11447c478bd9Sstevel@tonic-gate 	set_gssd_uid(uid);
11457c478bd9Sstevel@tonic-gate 
11467c478bd9Sstevel@tonic-gate 	/*
11477c478bd9Sstevel@tonic-gate 	 * copy the supplied context handle into the local context handle, so
11487c478bd9Sstevel@tonic-gate 	 * it can be supplied to the gss_accept_sec_context call
11497c478bd9Sstevel@tonic-gate 	 */
11507c478bd9Sstevel@tonic-gate 
11517c478bd9Sstevel@tonic-gate 	gssd_convert_context_handle(&argp->context_handle, &context_handle,
11527c478bd9Sstevel@tonic-gate 		argp->gssd_context_verifier, &context_verf_ok, &slot);
11537c478bd9Sstevel@tonic-gate 
11547c478bd9Sstevel@tonic-gate 	if (context_handle != GSS_C_NO_CONTEXT)
11557c478bd9Sstevel@tonic-gate 		/* verify the context_handle */
11567c478bd9Sstevel@tonic-gate 		if (!context_verf_ok) {
11577c478bd9Sstevel@tonic-gate 			res->context_handle.GSS_CTX_ID_T_val = NULL;
11587c478bd9Sstevel@tonic-gate 			res->src_name.GSS_BUFFER_T_val = NULL;
11597c478bd9Sstevel@tonic-gate 			res->mech_type.GSS_OID_val = NULL;
11607c478bd9Sstevel@tonic-gate 			res->output_token.GSS_BUFFER_T_val = NULL;
11617c478bd9Sstevel@tonic-gate 			res->delegated_cred_handle.GSS_CRED_ID_T_val = NULL;
11627c478bd9Sstevel@tonic-gate 			res->src_name.GSS_BUFFER_T_len = 0;
11637c478bd9Sstevel@tonic-gate 			res->context_handle.GSS_CTX_ID_T_len = 0;
11647c478bd9Sstevel@tonic-gate 			res->delegated_cred_handle.GSS_CRED_ID_T_len = 0;
11657c478bd9Sstevel@tonic-gate 			res->output_token.GSS_BUFFER_T_len = 0;
11667c478bd9Sstevel@tonic-gate 			res->mech_type.GSS_OID_len = 0;
11677c478bd9Sstevel@tonic-gate 			res->status = (OM_uint32)GSS_S_NO_CONTEXT;
11687c478bd9Sstevel@tonic-gate 			res->minor_status = 0;
11697c478bd9Sstevel@tonic-gate 			return (TRUE);
11707c478bd9Sstevel@tonic-gate 		}
11717c478bd9Sstevel@tonic-gate 
11727c478bd9Sstevel@tonic-gate 	/*
11737c478bd9Sstevel@tonic-gate 	 * copy the XDR structured arguments into their corresponding local
11747c478bd9Sstevel@tonic-gate 	 * GSSAPI variable equivalents.
11757c478bd9Sstevel@tonic-gate 	 */
11767c478bd9Sstevel@tonic-gate 
11777c478bd9Sstevel@tonic-gate 
11787c478bd9Sstevel@tonic-gate 	verifier_cred_handle =
11797c478bd9Sstevel@tonic-gate 		(argp->verifier_cred_handle.GSS_CRED_ID_T_len == 0 ?
11807c478bd9Sstevel@tonic-gate 			GSS_C_NO_CREDENTIAL :
11817c478bd9Sstevel@tonic-gate 			/*LINTED*/
11827c478bd9Sstevel@tonic-gate 			*((gss_cred_id_t *)argp->verifier_cred_handle.
11837c478bd9Sstevel@tonic-gate 				GSS_CRED_ID_T_val));
11847c478bd9Sstevel@tonic-gate 
11857c478bd9Sstevel@tonic-gate 	if (verifier_cred_handle != GSS_C_NO_CREDENTIAL)
11867c478bd9Sstevel@tonic-gate 	/* verify the verifier_cred_handle */
11877c478bd9Sstevel@tonic-gate 		if (argp->gssd_cred_verifier != gssd_time_verf) {
11887c478bd9Sstevel@tonic-gate 			res->context_handle.GSS_CTX_ID_T_val = NULL;
11897c478bd9Sstevel@tonic-gate 			res->src_name.GSS_BUFFER_T_val = NULL;
11907c478bd9Sstevel@tonic-gate 			res->mech_type.GSS_OID_val = NULL;
11917c478bd9Sstevel@tonic-gate 			res->output_token.GSS_BUFFER_T_val = NULL;
11927c478bd9Sstevel@tonic-gate 			res->delegated_cred_handle.GSS_CRED_ID_T_val = NULL;
11937c478bd9Sstevel@tonic-gate 			res->src_name.GSS_BUFFER_T_len = 0;
11947c478bd9Sstevel@tonic-gate 			res->context_handle.GSS_CTX_ID_T_len = 0;
11957c478bd9Sstevel@tonic-gate 			res->delegated_cred_handle.GSS_CRED_ID_T_len = 0;
11967c478bd9Sstevel@tonic-gate 			res->output_token.GSS_BUFFER_T_len = 0;
11977c478bd9Sstevel@tonic-gate 			res->mech_type.GSS_OID_len = 0;
11987c478bd9Sstevel@tonic-gate 			res->status = (OM_uint32)GSS_S_DEFECTIVE_CREDENTIAL;
11997c478bd9Sstevel@tonic-gate 			res->minor_status = 0;
12007c478bd9Sstevel@tonic-gate 			return (TRUE);
12017c478bd9Sstevel@tonic-gate 		}
12027c478bd9Sstevel@tonic-gate 
12037c478bd9Sstevel@tonic-gate 	input_token_buffer_ptr = &input_token_buffer;
12047c478bd9Sstevel@tonic-gate 	input_token_buffer.length = (size_t)argp->input_token_buffer.
12057c478bd9Sstevel@tonic-gate 		GSS_BUFFER_T_len;
12067c478bd9Sstevel@tonic-gate 	input_token_buffer.value = (void *)argp->input_token_buffer.
12077c478bd9Sstevel@tonic-gate 		GSS_BUFFER_T_val;
12087c478bd9Sstevel@tonic-gate 
12097c478bd9Sstevel@tonic-gate 	if (argp->input_chan_bindings.present == YES) {
12107c478bd9Sstevel@tonic-gate 		input_chan_bindings_ptr = &input_chan_bindings;
12117c478bd9Sstevel@tonic-gate 		input_chan_bindings.initiator_addrtype =
12127c478bd9Sstevel@tonic-gate 			(OM_uint32)argp->input_chan_bindings.
12137c478bd9Sstevel@tonic-gate 					initiator_addrtype;
12147c478bd9Sstevel@tonic-gate 		input_chan_bindings.initiator_address.length =
12157c478bd9Sstevel@tonic-gate 			(uint_t)argp->input_chan_bindings.initiator_address.
12167c478bd9Sstevel@tonic-gate 					GSS_BUFFER_T_len;
12177c478bd9Sstevel@tonic-gate 		input_chan_bindings.initiator_address.value =
12187c478bd9Sstevel@tonic-gate 			(void *)argp->input_chan_bindings.initiator_address.
12197c478bd9Sstevel@tonic-gate 					GSS_BUFFER_T_val;
12207c478bd9Sstevel@tonic-gate 		input_chan_bindings.acceptor_addrtype =
12217c478bd9Sstevel@tonic-gate 			(OM_uint32)argp->input_chan_bindings.
12227c478bd9Sstevel@tonic-gate 					acceptor_addrtype;
12237c478bd9Sstevel@tonic-gate 		input_chan_bindings.acceptor_address.length =
12247c478bd9Sstevel@tonic-gate 			(uint_t)argp->input_chan_bindings.acceptor_address.
12257c478bd9Sstevel@tonic-gate 					GSS_BUFFER_T_len;
12267c478bd9Sstevel@tonic-gate 		input_chan_bindings.acceptor_address.value =
12277c478bd9Sstevel@tonic-gate 			(void *)argp->input_chan_bindings.acceptor_address.
12287c478bd9Sstevel@tonic-gate 					GSS_BUFFER_T_val;
12297c478bd9Sstevel@tonic-gate 		input_chan_bindings.application_data.length =
12307c478bd9Sstevel@tonic-gate 			(uint_t)argp->input_chan_bindings.application_data.
12317c478bd9Sstevel@tonic-gate 					GSS_BUFFER_T_len;
12327c478bd9Sstevel@tonic-gate 		input_chan_bindings.application_data.value =
12337c478bd9Sstevel@tonic-gate 			(void *)argp->input_chan_bindings.application_data.
12347c478bd9Sstevel@tonic-gate 					GSS_BUFFER_T_val;
12357c478bd9Sstevel@tonic-gate 	} else {
12367c478bd9Sstevel@tonic-gate 		input_chan_bindings_ptr = GSS_C_NO_CHANNEL_BINDINGS;
12377c478bd9Sstevel@tonic-gate 		input_chan_bindings.initiator_addrtype = 0;
12387c478bd9Sstevel@tonic-gate 		input_chan_bindings.initiator_address.length = 0;
12397c478bd9Sstevel@tonic-gate 		input_chan_bindings.initiator_address.value = 0;
12407c478bd9Sstevel@tonic-gate 		input_chan_bindings.acceptor_addrtype = 0;
12417c478bd9Sstevel@tonic-gate 		input_chan_bindings.acceptor_address.length = 0;
12427c478bd9Sstevel@tonic-gate 		input_chan_bindings.acceptor_address.value = 0;
12437c478bd9Sstevel@tonic-gate 		input_chan_bindings.application_data.length = 0;
12447c478bd9Sstevel@tonic-gate 		input_chan_bindings.application_data.value = 0;
12457c478bd9Sstevel@tonic-gate 	}
12467c478bd9Sstevel@tonic-gate 
12477c478bd9Sstevel@tonic-gate 
12487c478bd9Sstevel@tonic-gate 	/* call the gssapi routine */
12497c478bd9Sstevel@tonic-gate 
12507c478bd9Sstevel@tonic-gate 	res->status = (OM_uint32)gss_accept_sec_context(&res->minor_status,
12517c478bd9Sstevel@tonic-gate 						&context_handle,
12527c478bd9Sstevel@tonic-gate 						verifier_cred_handle,
12537c478bd9Sstevel@tonic-gate 						input_token_buffer_ptr,
12547c478bd9Sstevel@tonic-gate 						input_chan_bindings_ptr,
12557c478bd9Sstevel@tonic-gate 						&internal_name,
12567c478bd9Sstevel@tonic-gate 						&mech_type,
12577c478bd9Sstevel@tonic-gate 						&output_token,
12587c478bd9Sstevel@tonic-gate 						&res->ret_flags,
12597c478bd9Sstevel@tonic-gate 						&res->time_rec,
12607c478bd9Sstevel@tonic-gate 						&delegated_cred_handle);
12617c478bd9Sstevel@tonic-gate 
12627c478bd9Sstevel@tonic-gate 	/* convert the src name from internal to external format */
12637c478bd9Sstevel@tonic-gate 
12647c478bd9Sstevel@tonic-gate 	if (res->status == (OM_uint32)GSS_S_COMPLETE ||
12657c478bd9Sstevel@tonic-gate 		res->status == (OM_uint32)GSS_S_CONTINUE_NEEDED) {
12667c478bd9Sstevel@tonic-gate 
12677c478bd9Sstevel@tonic-gate 		/*
12687c478bd9Sstevel@tonic-gate 		 * upon GSS_S_CONTINUE_NEEDED only the following
12697c478bd9Sstevel@tonic-gate 		 * parameters are ready: minor, ctxt, and output token
12707c478bd9Sstevel@tonic-gate 		 */
12717c478bd9Sstevel@tonic-gate 		res->context_handle.GSS_CTX_ID_T_len = sizeof (gss_ctx_id_t);
12727c478bd9Sstevel@tonic-gate 		res->context_handle.GSS_CTX_ID_T_val =
12737c478bd9Sstevel@tonic-gate 			(void *)malloc(sizeof (gss_ctx_id_t));
12747c478bd9Sstevel@tonic-gate 		if (!res->context_handle.GSS_CTX_ID_T_val) {
12757c478bd9Sstevel@tonic-gate 			res->status = (OM_uint32)GSS_S_FAILURE;
12767c478bd9Sstevel@tonic-gate 			res->minor_status = 0;
12777c478bd9Sstevel@tonic-gate 			return (TRUE);
12787c478bd9Sstevel@tonic-gate 		}
12797c478bd9Sstevel@tonic-gate 
12807c478bd9Sstevel@tonic-gate 		if (slot == NULL || slot->ctx != context_handle) {
12817c478bd9Sstevel@tonic-gate 			/*
12827c478bd9Sstevel@tonic-gate 			 * Note that gssd_alloc_slot() will delete ctx's as long
12837c478bd9Sstevel@tonic-gate 			 * as we don't call gssd_rel_slot().
12847c478bd9Sstevel@tonic-gate 			 */
12857c478bd9Sstevel@tonic-gate 			slot = gssd_alloc_slot(context_handle);
12867c478bd9Sstevel@tonic-gate 		}
12877c478bd9Sstevel@tonic-gate 
12887c478bd9Sstevel@tonic-gate 		memcpy(res->context_handle.GSS_CTX_ID_T_val, &slot->rpcctx,
12897c478bd9Sstevel@tonic-gate 			sizeof (gss_ctx_id_t));
12907c478bd9Sstevel@tonic-gate 		res->gssd_context_verifier = slot->verf;
12917c478bd9Sstevel@tonic-gate 
12927c478bd9Sstevel@tonic-gate 		res->output_token.GSS_BUFFER_T_len =
12937c478bd9Sstevel@tonic-gate 				(uint_t)output_token.length;
12947c478bd9Sstevel@tonic-gate 		res->output_token.GSS_BUFFER_T_val =
12957c478bd9Sstevel@tonic-gate 				(char *)output_token.value;
12967c478bd9Sstevel@tonic-gate 
12977c478bd9Sstevel@tonic-gate 		if (res->status == GSS_S_COMPLETE) {
12987c478bd9Sstevel@tonic-gate 			if (gss_export_name(&minor_status, internal_name,
12997c478bd9Sstevel@tonic-gate 					&external_name)
13007c478bd9Sstevel@tonic-gate 				!= GSS_S_COMPLETE) {
13017c478bd9Sstevel@tonic-gate 
13027c478bd9Sstevel@tonic-gate 				res->status = (OM_uint32)GSS_S_FAILURE;
13037c478bd9Sstevel@tonic-gate 				res->minor_status = minor_status;
13047c478bd9Sstevel@tonic-gate 				gss_release_name(&minor_status, &internal_name);
13057c478bd9Sstevel@tonic-gate 				gss_delete_sec_context(&minor_status,
13067c478bd9Sstevel@tonic-gate 						&context_handle, NULL);
13077c478bd9Sstevel@tonic-gate 				free(res->context_handle.GSS_CTX_ID_T_val);
13087c478bd9Sstevel@tonic-gate 				res->context_handle.GSS_CTX_ID_T_val = NULL;
13097c478bd9Sstevel@tonic-gate 				res->context_handle.GSS_CTX_ID_T_len = 0;
13107c478bd9Sstevel@tonic-gate 				gss_release_buffer(&minor_status,
13117c478bd9Sstevel@tonic-gate 						&output_token);
13127c478bd9Sstevel@tonic-gate 				res->output_token.GSS_BUFFER_T_len = 0;
13137c478bd9Sstevel@tonic-gate 				res->output_token.GSS_BUFFER_T_val = NULL;
13147c478bd9Sstevel@tonic-gate 				return (TRUE);
13157c478bd9Sstevel@tonic-gate 			}
13167c478bd9Sstevel@tonic-gate 			res->src_name.GSS_BUFFER_T_len =
13177c478bd9Sstevel@tonic-gate 				(uint_t)external_name.length;
13187c478bd9Sstevel@tonic-gate 			res->src_name.GSS_BUFFER_T_val =
13197c478bd9Sstevel@tonic-gate 				(void *)external_name.value;
13207c478bd9Sstevel@tonic-gate 
13217c478bd9Sstevel@tonic-gate 			res->delegated_cred_handle.GSS_CRED_ID_T_len =
13227c478bd9Sstevel@tonic-gate 				sizeof (gss_cred_id_t);
13237c478bd9Sstevel@tonic-gate 			res->delegated_cred_handle.GSS_CRED_ID_T_val =
13247c478bd9Sstevel@tonic-gate 				(void *)malloc(sizeof (gss_cred_id_t));
13257c478bd9Sstevel@tonic-gate 			if (!res->delegated_cred_handle.GSS_CRED_ID_T_val) {
13267c478bd9Sstevel@tonic-gate 				free(res->context_handle.GSS_CTX_ID_T_val);
13277c478bd9Sstevel@tonic-gate 				gss_release_name(&minor_status, &internal_name);
13287c478bd9Sstevel@tonic-gate 				gss_delete_sec_context(&minor_status,
13297c478bd9Sstevel@tonic-gate 						&context_handle, NULL);
13307c478bd9Sstevel@tonic-gate 				gss_release_buffer(&minor_status,
13317c478bd9Sstevel@tonic-gate 						&external_name);
13327c478bd9Sstevel@tonic-gate 				res->status = (OM_uint32)GSS_S_FAILURE;
13337c478bd9Sstevel@tonic-gate 				res->minor_status = 0;
13347c478bd9Sstevel@tonic-gate 				return (TRUE);
13357c478bd9Sstevel@tonic-gate 			}
13367c478bd9Sstevel@tonic-gate 			memcpy(res->delegated_cred_handle.GSS_CRED_ID_T_val,
13377c478bd9Sstevel@tonic-gate 				&delegated_cred_handle,
13387c478bd9Sstevel@tonic-gate 				sizeof (gss_cred_id_t));
13397c478bd9Sstevel@tonic-gate 
13407c478bd9Sstevel@tonic-gate 			res->mech_type.GSS_OID_len = (uint_t)mech_type->length;
13417c478bd9Sstevel@tonic-gate 			res->mech_type.GSS_OID_val =
13427c478bd9Sstevel@tonic-gate 				(void *)malloc(mech_type->length);
13437c478bd9Sstevel@tonic-gate 			if (!res->mech_type.GSS_OID_val) {
13447c478bd9Sstevel@tonic-gate 			    free(res->context_handle.GSS_CTX_ID_T_val);
13457c478bd9Sstevel@tonic-gate 			    free(res->delegated_cred_handle.GSS_CRED_ID_T_val);
13467c478bd9Sstevel@tonic-gate 			    gss_release_name(&minor_status, &internal_name);
13477c478bd9Sstevel@tonic-gate 			    gss_delete_sec_context(&minor_status,
13487c478bd9Sstevel@tonic-gate 						&context_handle, NULL);
13497c478bd9Sstevel@tonic-gate 			    gss_release_buffer(&minor_status, &external_name);
13507c478bd9Sstevel@tonic-gate 			    res->status = (OM_uint32)GSS_S_FAILURE;
13517c478bd9Sstevel@tonic-gate 			    res->minor_status = 0;
13527c478bd9Sstevel@tonic-gate 			    return (TRUE);
13537c478bd9Sstevel@tonic-gate 			}
13547c478bd9Sstevel@tonic-gate 			memcpy(res->mech_type.GSS_OID_val, mech_type->elements,
13557c478bd9Sstevel@tonic-gate 				mech_type->length);
13567c478bd9Sstevel@tonic-gate 
13577c478bd9Sstevel@tonic-gate 			/* release the space allocated for internal_name */
13587c478bd9Sstevel@tonic-gate 			gss_release_name(&minor_status, &internal_name);
13597c478bd9Sstevel@tonic-gate 
13607c478bd9Sstevel@tonic-gate 		} else {    /* GSS_S_CONTINUE_NEEDED */
13617c478bd9Sstevel@tonic-gate 			res->src_name.GSS_BUFFER_T_len = 0;
13627c478bd9Sstevel@tonic-gate 			res->delegated_cred_handle.GSS_CRED_ID_T_len = 0;
13637c478bd9Sstevel@tonic-gate 			res->mech_type.GSS_OID_len = 0;
13647c478bd9Sstevel@tonic-gate 		}
13657c478bd9Sstevel@tonic-gate 	} else {
13665e01956fSGlenn Barry 		syslog_gss_error(res->status, res->minor_status,
13675e01956fSGlenn Barry 			    "accept_sec_context");
13685e01956fSGlenn Barry 
13697c478bd9Sstevel@tonic-gate 		if (context_handle != GSS_C_NO_CONTEXT) {
13707c478bd9Sstevel@tonic-gate 			(void) gss_delete_sec_context(&minor_status,
13717c478bd9Sstevel@tonic-gate 				&context_handle, NULL);
13727c478bd9Sstevel@tonic-gate 		}
13737c478bd9Sstevel@tonic-gate 		res->src_name.GSS_BUFFER_T_len = 0;
13747c478bd9Sstevel@tonic-gate 		res->context_handle.GSS_CTX_ID_T_len = 0;
13757c478bd9Sstevel@tonic-gate                 res->delegated_cred_handle.GSS_CRED_ID_T_len = 0;
1376ba7b222eSGlenn Barry                 res->output_token.GSS_BUFFER_T_len =
1377ba7b222eSGlenn Barry 			(uint_t)output_token.length;
1378ba7b222eSGlenn Barry                 res->output_token.GSS_BUFFER_T_val =
1379ba7b222eSGlenn Barry 			(char *)output_token.value;
1380ba7b222eSGlenn Barry 
13817c478bd9Sstevel@tonic-gate                 res->mech_type.GSS_OID_len = 0;
13827c478bd9Sstevel@tonic-gate 	}
13837c478bd9Sstevel@tonic-gate 
13847c478bd9Sstevel@tonic-gate /* return to caller */
13857c478bd9Sstevel@tonic-gate 
13867c478bd9Sstevel@tonic-gate 	return (TRUE);
13877c478bd9Sstevel@tonic-gate }
13887c478bd9Sstevel@tonic-gate 
13897c478bd9Sstevel@tonic-gate bool_t
gss_process_context_token_1_svc(argp,res,rqstp)13907c478bd9Sstevel@tonic-gate gss_process_context_token_1_svc(argp, res, rqstp)
13917c478bd9Sstevel@tonic-gate gss_process_context_token_arg *argp;
13927c478bd9Sstevel@tonic-gate gss_process_context_token_res *res;
13937c478bd9Sstevel@tonic-gate struct svc_req *rqstp;
13947c478bd9Sstevel@tonic-gate {
13957c478bd9Sstevel@tonic-gate 
13967c478bd9Sstevel@tonic-gate 	uid_t uid;
13977c478bd9Sstevel@tonic-gate 	gss_buffer_desc token_buffer;
13987c478bd9Sstevel@tonic-gate 	gss_ctx_id_t context_handle;
13997c478bd9Sstevel@tonic-gate 	bool_t context_verf_ok;
14007c478bd9Sstevel@tonic-gate 
14017c478bd9Sstevel@tonic-gate 	memset(res, 0, sizeof (*res));
14027c478bd9Sstevel@tonic-gate 
14037c478bd9Sstevel@tonic-gate 	if (gssd_debug)
14047c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("gss_process_context_token\n"));
14057c478bd9Sstevel@tonic-gate 
14067c478bd9Sstevel@tonic-gate 	if (checkfrom(rqstp, &uid) == 0)
14077c478bd9Sstevel@tonic-gate 		return (FALSE);
14087c478bd9Sstevel@tonic-gate 
14097c478bd9Sstevel@tonic-gate 	gssd_convert_context_handle(&argp->context_handle, &context_handle,
14107c478bd9Sstevel@tonic-gate 		argp->gssd_context_verifier, &context_verf_ok, NULL);
14117c478bd9Sstevel@tonic-gate 
14127c478bd9Sstevel@tonic-gate 	/* verify the context_handle */
14137c478bd9Sstevel@tonic-gate 
14147c478bd9Sstevel@tonic-gate 	if (!context_verf_ok) {
14157c478bd9Sstevel@tonic-gate 		res->status = (OM_uint32) GSS_S_NO_CONTEXT;
14167c478bd9Sstevel@tonic-gate 		res->minor_status = 0;
14177c478bd9Sstevel@tonic-gate 		return (TRUE);
14187c478bd9Sstevel@tonic-gate 	}
14197c478bd9Sstevel@tonic-gate 
14207c478bd9Sstevel@tonic-gate 	/* set the uid sent as the RPC argument */
14217c478bd9Sstevel@tonic-gate 
14227c478bd9Sstevel@tonic-gate 	uid = argp->uid;
14237c478bd9Sstevel@tonic-gate 	set_gssd_uid(uid);
14247c478bd9Sstevel@tonic-gate 
14257c478bd9Sstevel@tonic-gate 	/*
14267c478bd9Sstevel@tonic-gate 	 * copy the XDR structured arguments into their corresponding local
14277c478bd9Sstevel@tonic-gate 	 * GSSAPI variable equivalents.
14287c478bd9Sstevel@tonic-gate 	 */
14297c478bd9Sstevel@tonic-gate 
14307c478bd9Sstevel@tonic-gate 	token_buffer.length = (size_t)argp->token_buffer.GSS_BUFFER_T_len;
14317c478bd9Sstevel@tonic-gate 	token_buffer.value = (void *)argp->token_buffer.GSS_BUFFER_T_val;
14327c478bd9Sstevel@tonic-gate 
14337c478bd9Sstevel@tonic-gate 
14347c478bd9Sstevel@tonic-gate 	/* call the gssapi routine */
14357c478bd9Sstevel@tonic-gate 
14367c478bd9Sstevel@tonic-gate 	res->status = (OM_uint32)gss_process_context_token(&res->minor_status,
14377c478bd9Sstevel@tonic-gate 				context_handle,
14387c478bd9Sstevel@tonic-gate 				&token_buffer);
14397c478bd9Sstevel@tonic-gate 
14405e01956fSGlenn Barry 	if (GSS_ERROR(res->status))
14415e01956fSGlenn Barry 		syslog_gss_error(res->status, res->minor_status,
14425e01956fSGlenn Barry 			    "process_context_token");
14437c478bd9Sstevel@tonic-gate 
14447c478bd9Sstevel@tonic-gate 	/* return to caller */
14457c478bd9Sstevel@tonic-gate 
14467c478bd9Sstevel@tonic-gate 	return (TRUE);
14477c478bd9Sstevel@tonic-gate }
14487c478bd9Sstevel@tonic-gate 
14497c478bd9Sstevel@tonic-gate bool_t
gss_delete_sec_context_1_svc(argp,res,rqstp)14507c478bd9Sstevel@tonic-gate gss_delete_sec_context_1_svc(argp, res, rqstp)
14517c478bd9Sstevel@tonic-gate gss_delete_sec_context_arg *argp;
14527c478bd9Sstevel@tonic-gate gss_delete_sec_context_res *res;
14537c478bd9Sstevel@tonic-gate struct svc_req *rqstp;
14547c478bd9Sstevel@tonic-gate {
14557c478bd9Sstevel@tonic-gate 	uid_t uid;
14567c478bd9Sstevel@tonic-gate 	gss_ctx_id_t  context_handle;
14577c478bd9Sstevel@tonic-gate 	gss_buffer_desc output_token;
14587c478bd9Sstevel@tonic-gate 	bool_t context_verf_ok;
14597c478bd9Sstevel@tonic-gate 	struct gssd_ctx_slot *slot = NULL;
14607c478bd9Sstevel@tonic-gate 
14617c478bd9Sstevel@tonic-gate 	memset(res, 0, sizeof (*res));
14627c478bd9Sstevel@tonic-gate 
14637c478bd9Sstevel@tonic-gate 	if (gssd_debug)
14647c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("gss_delete_sec_context\n"));
14657c478bd9Sstevel@tonic-gate 
14667c478bd9Sstevel@tonic-gate 
14677c478bd9Sstevel@tonic-gate 	/*
14687c478bd9Sstevel@tonic-gate 	 * copy the supplied context handle into the local context handle, so it
14697c478bd9Sstevel@tonic-gate 	 * can be supplied to the gss_delete_sec_context call
14707c478bd9Sstevel@tonic-gate 	 */
14717c478bd9Sstevel@tonic-gate 	gssd_convert_context_handle(&argp->context_handle, &context_handle,
14727c478bd9Sstevel@tonic-gate 		argp->gssd_context_verifier, &context_verf_ok, &slot);
14737c478bd9Sstevel@tonic-gate 
14747c478bd9Sstevel@tonic-gate 	/* verify the context_handle */
14757c478bd9Sstevel@tonic-gate 	if (!context_verf_ok) {
14767c478bd9Sstevel@tonic-gate 		res->context_handle.GSS_CTX_ID_T_val = NULL;
14777c478bd9Sstevel@tonic-gate 		res->context_handle.GSS_CTX_ID_T_len = 0;
14787c478bd9Sstevel@tonic-gate 		res->output_token.GSS_BUFFER_T_val = NULL;
14797c478bd9Sstevel@tonic-gate 		res->output_token.GSS_BUFFER_T_len = 0;
14807c478bd9Sstevel@tonic-gate 		res->status = (OM_uint32)GSS_S_NO_CONTEXT;
14817c478bd9Sstevel@tonic-gate 		res->minor_status = 0;
14827c478bd9Sstevel@tonic-gate 		return (TRUE);
14837c478bd9Sstevel@tonic-gate 	}
14847c478bd9Sstevel@tonic-gate 
14857c478bd9Sstevel@tonic-gate 	/*
14867c478bd9Sstevel@tonic-gate 	 * if the request isn't from root, null out the result pointer
14877c478bd9Sstevel@tonic-gate 	 * entries, so the next time through xdr_free won't try to
14887c478bd9Sstevel@tonic-gate 	 * free unmalloc'd memory and then return NULL
14897c478bd9Sstevel@tonic-gate 	 */
14907c478bd9Sstevel@tonic-gate 
14917c478bd9Sstevel@tonic-gate 	if (checkfrom(rqstp, &uid) == 0) {
14927c478bd9Sstevel@tonic-gate 		res->context_handle.GSS_CTX_ID_T_val = NULL;
14937c478bd9Sstevel@tonic-gate 		res->output_token.GSS_BUFFER_T_val = NULL;
14947c478bd9Sstevel@tonic-gate 		return (FALSE);
14957c478bd9Sstevel@tonic-gate 	}
14967c478bd9Sstevel@tonic-gate 
14977c478bd9Sstevel@tonic-gate 	/* call the gssapi routine */
14987c478bd9Sstevel@tonic-gate 
14997c478bd9Sstevel@tonic-gate 	res->status = (OM_uint32)gss_delete_sec_context(&res->minor_status,
15007c478bd9Sstevel@tonic-gate 						&context_handle,
15017c478bd9Sstevel@tonic-gate 						&output_token);
15027c478bd9Sstevel@tonic-gate 
15037c478bd9Sstevel@tonic-gate 	/*
15047c478bd9Sstevel@tonic-gate 	 * convert the output args from the parameter given in the call to the
15057c478bd9Sstevel@tonic-gate 	 * variable in the XDR result. If the delete succeeded, return a zero
15067c478bd9Sstevel@tonic-gate 	 * context handle.
15077c478bd9Sstevel@tonic-gate 	 */
15087c478bd9Sstevel@tonic-gate 
15097c478bd9Sstevel@tonic-gate 	if (res->status == GSS_S_COMPLETE) {
15107c478bd9Sstevel@tonic-gate 		if (context_handle != GSS_C_NO_CONTEXT)
15117c478bd9Sstevel@tonic-gate 			return (GSS_S_FAILURE);
15127c478bd9Sstevel@tonic-gate 		res->context_handle.GSS_CTX_ID_T_len = 0;
15137c478bd9Sstevel@tonic-gate 		res->context_handle.GSS_CTX_ID_T_val = NULL;
15147c478bd9Sstevel@tonic-gate 		res->output_token.GSS_BUFFER_T_len =
15157c478bd9Sstevel@tonic-gate 			(uint_t)output_token.length;
15167c478bd9Sstevel@tonic-gate 		res->output_token.GSS_BUFFER_T_val =
15177c478bd9Sstevel@tonic-gate 			(char *)output_token.value;
15187c478bd9Sstevel@tonic-gate 
15197c478bd9Sstevel@tonic-gate 		if (slot != NULL) {
15207c478bd9Sstevel@tonic-gate 			/*
15217c478bd9Sstevel@tonic-gate 			 * gss_delete_sec_context deletes the context if it
15227c478bd9Sstevel@tonic-gate 			 * succeeds so clear slot->ctx to avoid a dangling
15237c478bd9Sstevel@tonic-gate 			 * reference.
15247c478bd9Sstevel@tonic-gate 			 */
15257c478bd9Sstevel@tonic-gate 			slot->ctx = GSS_C_NO_CONTEXT;
15267c478bd9Sstevel@tonic-gate 			gssd_rel_slot(slot);
15277c478bd9Sstevel@tonic-gate 		}
15287c478bd9Sstevel@tonic-gate 	} else {
15297c478bd9Sstevel@tonic-gate 		res->context_handle.GSS_CTX_ID_T_len = sizeof (gss_ctx_id_t);
15307c478bd9Sstevel@tonic-gate 		res->context_handle.GSS_CTX_ID_T_val =
15317c478bd9Sstevel@tonic-gate 			(void *)malloc(sizeof (gss_ctx_id_t));
15327c478bd9Sstevel@tonic-gate 		if (!res->context_handle.GSS_CTX_ID_T_val) {
15337c478bd9Sstevel@tonic-gate 			return (GSS_S_FAILURE);
15347c478bd9Sstevel@tonic-gate 		}
15357c478bd9Sstevel@tonic-gate 
15367c478bd9Sstevel@tonic-gate 		if (slot == NULL || slot->ctx != context_handle) {
15377c478bd9Sstevel@tonic-gate 			/*
15387c478bd9Sstevel@tonic-gate 			 * Note that gssd_alloc_slot() will delete ctx's as long
15397c478bd9Sstevel@tonic-gate 			 * as we don't call gssd_rel_slot().
15407c478bd9Sstevel@tonic-gate 			 */
15417c478bd9Sstevel@tonic-gate 			slot = gssd_alloc_slot(context_handle);
15427c478bd9Sstevel@tonic-gate 			/*
15437c478bd9Sstevel@tonic-gate 			 * Note that no verifier is returned in the .x
15447c478bd9Sstevel@tonic-gate 			 * protocol. So if the context changes, we won't
15457c478bd9Sstevel@tonic-gate 			 * be able to release it now. So it will have to
15467c478bd9Sstevel@tonic-gate 			 * be LRUed out.
15477c478bd9Sstevel@tonic-gate 			 */
15487c478bd9Sstevel@tonic-gate 		}
15497c478bd9Sstevel@tonic-gate 
15507c478bd9Sstevel@tonic-gate 		memcpy(res->context_handle.GSS_CTX_ID_T_val, &slot->rpcctx,
15517c478bd9Sstevel@tonic-gate 			sizeof (gss_ctx_id_t));
15527c478bd9Sstevel@tonic-gate 
15537c478bd9Sstevel@tonic-gate 		res->output_token.GSS_BUFFER_T_len = 0;
15547c478bd9Sstevel@tonic-gate 		res->output_token.GSS_BUFFER_T_val = NULL;
15557c478bd9Sstevel@tonic-gate 	}
15567c478bd9Sstevel@tonic-gate 
15577c478bd9Sstevel@tonic-gate 	/* return to caller */
15587c478bd9Sstevel@tonic-gate 
1559ba7b222eSGlenn Barry 
15607c478bd9Sstevel@tonic-gate 	return (TRUE);
15617c478bd9Sstevel@tonic-gate }
15627c478bd9Sstevel@tonic-gate 
15637c478bd9Sstevel@tonic-gate 
15647c478bd9Sstevel@tonic-gate bool_t
gss_export_sec_context_1_svc(argp,res,rqstp)15657c478bd9Sstevel@tonic-gate gss_export_sec_context_1_svc(argp, res, rqstp)
15667c478bd9Sstevel@tonic-gate 	gss_export_sec_context_arg *argp;
15677c478bd9Sstevel@tonic-gate 	gss_export_sec_context_res *res;
15687c478bd9Sstevel@tonic-gate 	struct svc_req *rqstp;
15697c478bd9Sstevel@tonic-gate {
15707c478bd9Sstevel@tonic-gate 
15717c478bd9Sstevel@tonic-gate 	uid_t		uid;
15727c478bd9Sstevel@tonic-gate 	gss_ctx_id_t	context_handle;
15737c478bd9Sstevel@tonic-gate 	gss_buffer_desc	output_token;
15747c478bd9Sstevel@tonic-gate 	bool_t		context_verf_ok;
15757c478bd9Sstevel@tonic-gate 	struct gssd_ctx_slot *slot = NULL;
15767c478bd9Sstevel@tonic-gate 
15777c478bd9Sstevel@tonic-gate 	memset(res, 0, sizeof (*res));
15787c478bd9Sstevel@tonic-gate 
15797c478bd9Sstevel@tonic-gate 	if (gssd_debug)
15807c478bd9Sstevel@tonic-gate 		fprintf(stderr, "gss_export_sec_context\n");
15817c478bd9Sstevel@tonic-gate 
15827c478bd9Sstevel@tonic-gate 	/*
15837c478bd9Sstevel@tonic-gate 	 * if the request isn't from root, null out the result pointer
15847c478bd9Sstevel@tonic-gate 	 * entries, so the next time through xdr_free won't try to
15857c478bd9Sstevel@tonic-gate 	 * free unmalloc'd memory and then return NULL
15867c478bd9Sstevel@tonic-gate 	 */
15877c478bd9Sstevel@tonic-gate 
15887c478bd9Sstevel@tonic-gate 	if (checkfrom(rqstp, &uid) == 0) {
15897c478bd9Sstevel@tonic-gate 		res->context_handle.GSS_CTX_ID_T_val = NULL;
15907c478bd9Sstevel@tonic-gate 		res->output_token.GSS_BUFFER_T_val = NULL;
15917c478bd9Sstevel@tonic-gate 		return (FALSE);
15927c478bd9Sstevel@tonic-gate 	}
15937c478bd9Sstevel@tonic-gate 
15947c478bd9Sstevel@tonic-gate /*
15957c478bd9Sstevel@tonic-gate  * copy the supplied context handle into the local context handle, so it
15967c478bd9Sstevel@tonic-gate  * can be supplied to the gss_export_sec_context call
15977c478bd9Sstevel@tonic-gate  */
15987c478bd9Sstevel@tonic-gate 
15997c478bd9Sstevel@tonic-gate 	gssd_convert_context_handle(&argp->context_handle, &context_handle,
16007c478bd9Sstevel@tonic-gate 		argp->gssd_context_verifier, &context_verf_ok, &slot);
16017c478bd9Sstevel@tonic-gate 
16027c478bd9Sstevel@tonic-gate 	/* verify the context_handle */
16037c478bd9Sstevel@tonic-gate 
16047c478bd9Sstevel@tonic-gate 	if (!context_verf_ok) {
16057c478bd9Sstevel@tonic-gate 		res->status = (OM_uint32)GSS_S_NO_CONTEXT;
16067c478bd9Sstevel@tonic-gate 		/* the rest of "res" was cleared by a previous memset() */
16077c478bd9Sstevel@tonic-gate 		return (TRUE);
16087c478bd9Sstevel@tonic-gate 	}
16097c478bd9Sstevel@tonic-gate 
16107c478bd9Sstevel@tonic-gate 	/* call the gssapi routine */
16117c478bd9Sstevel@tonic-gate 
16127c478bd9Sstevel@tonic-gate 	res->status = (OM_uint32)gss_export_sec_context(&res->minor_status,
16137c478bd9Sstevel@tonic-gate 					&context_handle,
16147c478bd9Sstevel@tonic-gate 					&output_token);
16157c478bd9Sstevel@tonic-gate 
16167c478bd9Sstevel@tonic-gate /*
16177c478bd9Sstevel@tonic-gate  * convert the output args from the parameter given in the call to the
16187c478bd9Sstevel@tonic-gate  * variable in the XDR result. If the delete succeeded, return a zero context
16197c478bd9Sstevel@tonic-gate  * handle.
16207c478bd9Sstevel@tonic-gate  */
16217c478bd9Sstevel@tonic-gate 	if (res->status == GSS_S_COMPLETE) {
16227c478bd9Sstevel@tonic-gate 		if (context_handle != GSS_C_NO_CONTEXT)
16237c478bd9Sstevel@tonic-gate 			return (GSS_S_FAILURE);
16247c478bd9Sstevel@tonic-gate 		res->context_handle.GSS_CTX_ID_T_len = 0;
16257c478bd9Sstevel@tonic-gate 		res->context_handle.GSS_CTX_ID_T_val = NULL;
16267c478bd9Sstevel@tonic-gate 		res->output_token.GSS_BUFFER_T_len =
16277c478bd9Sstevel@tonic-gate 						(uint_t)output_token.length;
16287c478bd9Sstevel@tonic-gate 		res->output_token.GSS_BUFFER_T_val =
16297c478bd9Sstevel@tonic-gate 						(char *)output_token.value;
16307c478bd9Sstevel@tonic-gate 
16317c478bd9Sstevel@tonic-gate 		if (slot != NULL) {
16327c478bd9Sstevel@tonic-gate 			/*
16337c478bd9Sstevel@tonic-gate 			 * gss_export_sec_context deletes the context if it
16347c478bd9Sstevel@tonic-gate 			 * succeeds so set slot->ctx to avoid a dangling
16357c478bd9Sstevel@tonic-gate 			 * reference.
16367c478bd9Sstevel@tonic-gate 			 */
16377c478bd9Sstevel@tonic-gate 			slot->ctx = GSS_C_NO_CONTEXT;
16387c478bd9Sstevel@tonic-gate 			gssd_rel_slot(slot);
16397c478bd9Sstevel@tonic-gate 		}
16407c478bd9Sstevel@tonic-gate 	} else {
16417c478bd9Sstevel@tonic-gate 		res->context_handle.GSS_CTX_ID_T_len = sizeof (gss_ctx_id_t);
16427c478bd9Sstevel@tonic-gate 		res->context_handle.GSS_CTX_ID_T_val =
16437c478bd9Sstevel@tonic-gate 					(void *)malloc(sizeof (gss_ctx_id_t));
16447c478bd9Sstevel@tonic-gate 
16457c478bd9Sstevel@tonic-gate 		if (slot == NULL || slot->ctx != context_handle) {
16467c478bd9Sstevel@tonic-gate 			/*
16477c478bd9Sstevel@tonic-gate 			 * Note that gssd_alloc_slot() will delete ctx's as long
16487c478bd9Sstevel@tonic-gate 			 * as we don't call gssd_rel_slot().
16497c478bd9Sstevel@tonic-gate 			 */
16507c478bd9Sstevel@tonic-gate 			slot = gssd_alloc_slot(context_handle);
16517c478bd9Sstevel@tonic-gate 			/*
16527c478bd9Sstevel@tonic-gate 			 * Note that no verifier is returned in the .x
16537c478bd9Sstevel@tonic-gate 			 * protocol. So if the context changes, we won't
16547c478bd9Sstevel@tonic-gate 			 * be able to release it now. So it will have to
16557c478bd9Sstevel@tonic-gate 			 * be LRUed out.
16567c478bd9Sstevel@tonic-gate 			 */
16577c478bd9Sstevel@tonic-gate 		}
16587c478bd9Sstevel@tonic-gate 
16597c478bd9Sstevel@tonic-gate 		memcpy(res->context_handle.GSS_CTX_ID_T_val, &slot->rpcctx,
16607c478bd9Sstevel@tonic-gate 			sizeof (gss_ctx_id_t));
16617c478bd9Sstevel@tonic-gate 		res->output_token.GSS_BUFFER_T_len = 0;
16627c478bd9Sstevel@tonic-gate 		res->output_token.GSS_BUFFER_T_val = NULL;
16637c478bd9Sstevel@tonic-gate 	}
16647c478bd9Sstevel@tonic-gate 
16657c478bd9Sstevel@tonic-gate 
16667c478bd9Sstevel@tonic-gate 	/* return to caller */
16677c478bd9Sstevel@tonic-gate 
16687c478bd9Sstevel@tonic-gate 	return (TRUE);
16697c478bd9Sstevel@tonic-gate }
16707c478bd9Sstevel@tonic-gate 
16717c478bd9Sstevel@tonic-gate /*
16727c478bd9Sstevel@tonic-gate  * This routine doesn't appear to ever be called.
16737c478bd9Sstevel@tonic-gate  */
16747c478bd9Sstevel@tonic-gate bool_t
gss_import_sec_context_1_svc(argp,res,rqstp)16757c478bd9Sstevel@tonic-gate gss_import_sec_context_1_svc(argp, res, rqstp)
16767c478bd9Sstevel@tonic-gate 	gss_import_sec_context_arg *argp;
16777c478bd9Sstevel@tonic-gate 	gss_import_sec_context_res *res;
16787c478bd9Sstevel@tonic-gate 	struct svc_req *rqstp;
16797c478bd9Sstevel@tonic-gate {
16807c478bd9Sstevel@tonic-gate 
16817c478bd9Sstevel@tonic-gate 	uid_t		uid;
16827c478bd9Sstevel@tonic-gate 	gss_ctx_id_t	context_handle;
16837c478bd9Sstevel@tonic-gate 	gss_buffer_desc	input_token;
16847c478bd9Sstevel@tonic-gate 	gss_buffer_t input_token_ptr;
16857c478bd9Sstevel@tonic-gate 
16867c478bd9Sstevel@tonic-gate 	memset(res, 0, sizeof (*res));
16877c478bd9Sstevel@tonic-gate 
16887c478bd9Sstevel@tonic-gate 	if (gssd_debug)
16897c478bd9Sstevel@tonic-gate 		fprintf(stderr, "gss_export_sec_context\n");
16907c478bd9Sstevel@tonic-gate 
16917c478bd9Sstevel@tonic-gate 	/*
16927c478bd9Sstevel@tonic-gate 	 * if the request isn't from root, null out the result pointer
16937c478bd9Sstevel@tonic-gate 	 * entries, so the next time through xdr_free won't try to
16947c478bd9Sstevel@tonic-gate 	 * free unmalloc'd memory and then return NULL
16957c478bd9Sstevel@tonic-gate 	 */
16967c478bd9Sstevel@tonic-gate 
16977c478bd9Sstevel@tonic-gate 	if (checkfrom(rqstp, &uid) == 0) {
16987c478bd9Sstevel@tonic-gate 		res->context_handle.GSS_CTX_ID_T_val = NULL;
16997c478bd9Sstevel@tonic-gate 		return (FALSE);
17007c478bd9Sstevel@tonic-gate 	}
17017c478bd9Sstevel@tonic-gate 
17027c478bd9Sstevel@tonic-gate 
17037c478bd9Sstevel@tonic-gate 	if (argp->input_token.GSS_BUFFER_T_len == 0) {
17047c478bd9Sstevel@tonic-gate 		input_token_ptr = GSS_C_NO_BUFFER;
17057c478bd9Sstevel@tonic-gate 	} else {
17067c478bd9Sstevel@tonic-gate 		input_token_ptr = &input_token;
17077c478bd9Sstevel@tonic-gate 		input_token.length = (size_t)
17087c478bd9Sstevel@tonic-gate 				argp->input_token.GSS_BUFFER_T_len;
17097c478bd9Sstevel@tonic-gate 		input_token.value = (void *) argp->input_token.GSS_BUFFER_T_val;
17107c478bd9Sstevel@tonic-gate 	}
17117c478bd9Sstevel@tonic-gate 
17127c478bd9Sstevel@tonic-gate 
17137c478bd9Sstevel@tonic-gate /* call the gssapi routine */
17147c478bd9Sstevel@tonic-gate 
17157c478bd9Sstevel@tonic-gate 	res->status = (OM_uint32) gss_import_sec_context(&res->minor_status,
17167c478bd9Sstevel@tonic-gate 					input_token_ptr,
17177c478bd9Sstevel@tonic-gate 					&context_handle);
17187c478bd9Sstevel@tonic-gate 
17197c478bd9Sstevel@tonic-gate /*
17207c478bd9Sstevel@tonic-gate  * convert the output args from the parameter given in the call to the
17217c478bd9Sstevel@tonic-gate  * variable in the XDR result. If the delete succeeded, return a zero context
17227c478bd9Sstevel@tonic-gate  * handle.
17237c478bd9Sstevel@tonic-gate  */
17247c478bd9Sstevel@tonic-gate 	if (res->status == GSS_S_COMPLETE) {
17257c478bd9Sstevel@tonic-gate 		res->context_handle.GSS_CTX_ID_T_len = sizeof (gss_ctx_id_t);
17267c478bd9Sstevel@tonic-gate 		res->context_handle.GSS_CTX_ID_T_val =
17277c478bd9Sstevel@tonic-gate 					(void *) malloc(sizeof (gss_ctx_id_t));
17287c478bd9Sstevel@tonic-gate 		memcpy(res->context_handle.GSS_CTX_ID_T_val, &context_handle,
17297c478bd9Sstevel@tonic-gate 			sizeof (gss_ctx_id_t));
17307c478bd9Sstevel@tonic-gate 	} else {
17317c478bd9Sstevel@tonic-gate 		res->context_handle.GSS_CTX_ID_T_len = 0;
17327c478bd9Sstevel@tonic-gate 		res->context_handle.GSS_CTX_ID_T_val = NULL;
17337c478bd9Sstevel@tonic-gate 	}
17347c478bd9Sstevel@tonic-gate 
17357c478bd9Sstevel@tonic-gate 
17367c478bd9Sstevel@tonic-gate 	/* return to caller */
17377c478bd9Sstevel@tonic-gate 
17387c478bd9Sstevel@tonic-gate 	return (TRUE);
17397c478bd9Sstevel@tonic-gate }
17407c478bd9Sstevel@tonic-gate 
17417c478bd9Sstevel@tonic-gate bool_t
gss_context_time_1_svc(argp,res,rqstp)17427c478bd9Sstevel@tonic-gate gss_context_time_1_svc(argp, res, rqstp)
17437c478bd9Sstevel@tonic-gate gss_context_time_arg *argp;
17447c478bd9Sstevel@tonic-gate gss_context_time_res *res;
17457c478bd9Sstevel@tonic-gate struct svc_req *rqstp;
17467c478bd9Sstevel@tonic-gate {
17477c478bd9Sstevel@tonic-gate 	uid_t uid;
17487c478bd9Sstevel@tonic-gate 
17497c478bd9Sstevel@tonic-gate 	memset(res, 0, sizeof (*res));
17507c478bd9Sstevel@tonic-gate 
17517c478bd9Sstevel@tonic-gate 	if (gssd_debug)
17527c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("gss_context_time\n"));
17537c478bd9Sstevel@tonic-gate 
17547c478bd9Sstevel@tonic-gate 	/*
17557c478bd9Sstevel@tonic-gate 	 * if the request isn't from root, null out the result pointer
17567c478bd9Sstevel@tonic-gate 	 * entries, so the next time through xdr_free won't try to
17577c478bd9Sstevel@tonic-gate 	 * free unmalloc'd memory and then return NULL
17587c478bd9Sstevel@tonic-gate 	 */
17597c478bd9Sstevel@tonic-gate 
17607c478bd9Sstevel@tonic-gate 	if (checkfrom(rqstp, &uid) == 0)
17617c478bd9Sstevel@tonic-gate 		return (FALSE);
17627c478bd9Sstevel@tonic-gate 
17637c478bd9Sstevel@tonic-gate 	/* set the uid sent as the RPC argument */
17647c478bd9Sstevel@tonic-gate 
17657c478bd9Sstevel@tonic-gate 	uid = argp->uid;
17667c478bd9Sstevel@tonic-gate 	set_gssd_uid(uid);
17677c478bd9Sstevel@tonic-gate 
17687c478bd9Sstevel@tonic-gate 	/* Semantics go here */
17697c478bd9Sstevel@tonic-gate 
17707c478bd9Sstevel@tonic-gate 	return (TRUE);
17717c478bd9Sstevel@tonic-gate }
17727c478bd9Sstevel@tonic-gate 
17737c478bd9Sstevel@tonic-gate bool_t
gss_sign_1_svc(argp,res,rqstp)17747c478bd9Sstevel@tonic-gate gss_sign_1_svc(argp, res, rqstp)
17757c478bd9Sstevel@tonic-gate gss_sign_arg *argp;
17767c478bd9Sstevel@tonic-gate gss_sign_res *res;
17777c478bd9Sstevel@tonic-gate struct svc_req *rqstp;
17787c478bd9Sstevel@tonic-gate {
17797c478bd9Sstevel@tonic-gate 
17807c478bd9Sstevel@tonic-gate 	uid_t uid;
17817c478bd9Sstevel@tonic-gate 
17827c478bd9Sstevel@tonic-gate 	gss_buffer_desc message_buffer;
17837c478bd9Sstevel@tonic-gate 	gss_buffer_desc msg_token;
17847c478bd9Sstevel@tonic-gate 	gss_ctx_id_t	context_handle;
17857c478bd9Sstevel@tonic-gate 	bool_t context_verf_ok;
17867c478bd9Sstevel@tonic-gate 
17877c478bd9Sstevel@tonic-gate 	memset(res, 0, sizeof (*res));
17887c478bd9Sstevel@tonic-gate 
17897c478bd9Sstevel@tonic-gate 	if (gssd_debug)
17907c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("gss_sign\n"));
17917c478bd9Sstevel@tonic-gate 
17927c478bd9Sstevel@tonic-gate 	gssd_convert_context_handle(&argp->context_handle, &context_handle,
17937c478bd9Sstevel@tonic-gate 		argp->gssd_context_verifier, &context_verf_ok, NULL);
17947c478bd9Sstevel@tonic-gate 
17957c478bd9Sstevel@tonic-gate 	/* verify the context_handle */
17967c478bd9Sstevel@tonic-gate 	if (!context_verf_ok) {
17977c478bd9Sstevel@tonic-gate 		res->msg_token.GSS_BUFFER_T_val = NULL;
17987c478bd9Sstevel@tonic-gate 		res->msg_token.GSS_BUFFER_T_len = 0;
17997c478bd9Sstevel@tonic-gate 		res->status = (OM_uint32) GSS_S_NO_CONTEXT;
18007c478bd9Sstevel@tonic-gate 		res->minor_status = 0;
18017c478bd9Sstevel@tonic-gate 		return (TRUE);
18027c478bd9Sstevel@tonic-gate 	}
18037c478bd9Sstevel@tonic-gate 
18047c478bd9Sstevel@tonic-gate 
18057c478bd9Sstevel@tonic-gate 	/*
18067c478bd9Sstevel@tonic-gate 	 * if the request isn't from root, null out the result pointer
18077c478bd9Sstevel@tonic-gate 	 * entries, so the next time through xdr_free won't try to
18087c478bd9Sstevel@tonic-gate 	 * free unmalloc'd memory and then return NULL
18097c478bd9Sstevel@tonic-gate 	 */
18107c478bd9Sstevel@tonic-gate 
18117c478bd9Sstevel@tonic-gate 	if (checkfrom(rqstp, &uid) == 0) {
18127c478bd9Sstevel@tonic-gate 		res->msg_token.GSS_BUFFER_T_val = NULL;
18137c478bd9Sstevel@tonic-gate 		return (FALSE);
18147c478bd9Sstevel@tonic-gate 	}
18157c478bd9Sstevel@tonic-gate 
18167c478bd9Sstevel@tonic-gate 	/*
18177c478bd9Sstevel@tonic-gate 	 * copy the XDR structured arguments into their corresponding local
18187c478bd9Sstevel@tonic-gate 	 * GSSAPI variable equivalents.
18197c478bd9Sstevel@tonic-gate 	 */
18207c478bd9Sstevel@tonic-gate 
18217c478bd9Sstevel@tonic-gate 	message_buffer.length = (size_t)argp->message_buffer.GSS_BUFFER_T_len;
18227c478bd9Sstevel@tonic-gate 	message_buffer.value = (void *)argp->message_buffer.GSS_BUFFER_T_val;
18237c478bd9Sstevel@tonic-gate 
18247c478bd9Sstevel@tonic-gate 	/* call the gssapi routine */
18257c478bd9Sstevel@tonic-gate 
18267c478bd9Sstevel@tonic-gate 	res->status = (OM_uint32)gss_sign(&res->minor_status,
18277c478bd9Sstevel@tonic-gate 					context_handle,
18287c478bd9Sstevel@tonic-gate 					argp->qop_req,
18297c478bd9Sstevel@tonic-gate 					(gss_buffer_t)&message_buffer,
18307c478bd9Sstevel@tonic-gate 					(gss_buffer_t)&msg_token);
18317c478bd9Sstevel@tonic-gate 	/*
18327c478bd9Sstevel@tonic-gate 	 * convert the output args from the parameter given in the call to
18337c478bd9Sstevel@tonic-gate 	 * the variable in the XDR result
18347c478bd9Sstevel@tonic-gate 	 */
18357c478bd9Sstevel@tonic-gate 
18367c478bd9Sstevel@tonic-gate 	if (res->status == GSS_S_COMPLETE) {
18377c478bd9Sstevel@tonic-gate 		res->msg_token.GSS_BUFFER_T_len = (uint_t)msg_token.length;
18387c478bd9Sstevel@tonic-gate 		res->msg_token.GSS_BUFFER_T_val = (char *)msg_token.value;
18395e01956fSGlenn Barry 	} else
18405e01956fSGlenn Barry 		syslog_gss_error(res->status, res->minor_status, "sign");
18417c478bd9Sstevel@tonic-gate 
18427c478bd9Sstevel@tonic-gate 	/* return to caller */
18437c478bd9Sstevel@tonic-gate 
18447c478bd9Sstevel@tonic-gate 	return (TRUE);
18457c478bd9Sstevel@tonic-gate }
18467c478bd9Sstevel@tonic-gate 
18477c478bd9Sstevel@tonic-gate bool_t
gss_verify_1_svc(argp,res,rqstp)18487c478bd9Sstevel@tonic-gate gss_verify_1_svc(argp, res, rqstp)
18497c478bd9Sstevel@tonic-gate gss_verify_arg *argp;
18507c478bd9Sstevel@tonic-gate gss_verify_res *res;
18517c478bd9Sstevel@tonic-gate struct svc_req *rqstp;
18527c478bd9Sstevel@tonic-gate {
18537c478bd9Sstevel@tonic-gate 
18547c478bd9Sstevel@tonic-gate 	uid_t uid;
18557c478bd9Sstevel@tonic-gate 
18567c478bd9Sstevel@tonic-gate 	gss_buffer_desc message_buffer;
18577c478bd9Sstevel@tonic-gate 	gss_buffer_desc token_buffer;
18587c478bd9Sstevel@tonic-gate 	gss_ctx_id_t context_handle;
18597c478bd9Sstevel@tonic-gate 	bool_t context_verf_ok;
18607c478bd9Sstevel@tonic-gate 
18617c478bd9Sstevel@tonic-gate 	memset(res, 0, sizeof (*res));
18627c478bd9Sstevel@tonic-gate 
18637c478bd9Sstevel@tonic-gate 	if (gssd_debug)
18647c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("gss_verify\n"));
18657c478bd9Sstevel@tonic-gate 
18667c478bd9Sstevel@tonic-gate 	gssd_convert_context_handle(&argp->context_handle, &context_handle,
18677c478bd9Sstevel@tonic-gate 		argp->gssd_context_verifier, &context_verf_ok, NULL);
18687c478bd9Sstevel@tonic-gate 
18697c478bd9Sstevel@tonic-gate 	/* verify the context_handle */
18707c478bd9Sstevel@tonic-gate 	if (!context_verf_ok) {
18717c478bd9Sstevel@tonic-gate 		res->status = (OM_uint32) GSS_S_NO_CONTEXT;
18727c478bd9Sstevel@tonic-gate 		res->minor_status = 0;
18737c478bd9Sstevel@tonic-gate 		return (TRUE);
18747c478bd9Sstevel@tonic-gate 	}
18757c478bd9Sstevel@tonic-gate 
18767c478bd9Sstevel@tonic-gate 	/*
18777c478bd9Sstevel@tonic-gate 	 * if the request isn't from root, null out the result pointer
18787c478bd9Sstevel@tonic-gate 	 * entries, so the next time through xdr_free won't try to
18797c478bd9Sstevel@tonic-gate 	 * free unmalloc'd memory and then return NULL
18807c478bd9Sstevel@tonic-gate 	 */
18817c478bd9Sstevel@tonic-gate 
18827c478bd9Sstevel@tonic-gate 	if (checkfrom(rqstp, &uid) == 0)
18837c478bd9Sstevel@tonic-gate 		return (FALSE);
18847c478bd9Sstevel@tonic-gate 
18857c478bd9Sstevel@tonic-gate 	/*
18867c478bd9Sstevel@tonic-gate 	 * copy the XDR structured arguments into their corresponding local
18877c478bd9Sstevel@tonic-gate 	 * GSSAPI variable equivalents.
18887c478bd9Sstevel@tonic-gate 	 */
18897c478bd9Sstevel@tonic-gate 
18907c478bd9Sstevel@tonic-gate 	message_buffer.length = (size_t)argp->message_buffer.GSS_BUFFER_T_len;
18917c478bd9Sstevel@tonic-gate 	message_buffer.value = (void *)argp->message_buffer.GSS_BUFFER_T_val;
18927c478bd9Sstevel@tonic-gate 
18937c478bd9Sstevel@tonic-gate 	token_buffer.length = (size_t)argp->token_buffer.GSS_BUFFER_T_len;
18947c478bd9Sstevel@tonic-gate 	token_buffer.value = (void *)argp->token_buffer.GSS_BUFFER_T_val;
18957c478bd9Sstevel@tonic-gate 
18967c478bd9Sstevel@tonic-gate 	/* call the gssapi routine */
18977c478bd9Sstevel@tonic-gate 
18987c478bd9Sstevel@tonic-gate 	res->status = (OM_uint32)gss_verify(&res->minor_status,
18997c478bd9Sstevel@tonic-gate 				context_handle,
19007c478bd9Sstevel@tonic-gate 				&message_buffer,
19017c478bd9Sstevel@tonic-gate 				&token_buffer,
19027c478bd9Sstevel@tonic-gate 				&res->qop_state);
19037c478bd9Sstevel@tonic-gate 
19045e01956fSGlenn Barry 	if (GSS_ERROR(res->status))
19055e01956fSGlenn Barry 		syslog_gss_error(res->status, res->minor_status, "verify");
19067c478bd9Sstevel@tonic-gate 
19075e01956fSGlenn Barry 	/* return to caller */
19087c478bd9Sstevel@tonic-gate 	return (TRUE);
19097c478bd9Sstevel@tonic-gate }
19107c478bd9Sstevel@tonic-gate 
19117c478bd9Sstevel@tonic-gate bool_t
gss_seal_1_svc(argp,res,rqstp)19127c478bd9Sstevel@tonic-gate gss_seal_1_svc(argp, res, rqstp)
19137c478bd9Sstevel@tonic-gate gss_seal_arg *argp;
19147c478bd9Sstevel@tonic-gate gss_seal_res *res;
19157c478bd9Sstevel@tonic-gate struct svc_req *rqstp;
19167c478bd9Sstevel@tonic-gate {
19177c478bd9Sstevel@tonic-gate 	uid_t uid;
19187c478bd9Sstevel@tonic-gate 
19197c478bd9Sstevel@tonic-gate 	gss_buffer_desc input_message_buffer;
19207c478bd9Sstevel@tonic-gate 	gss_buffer_desc output_message_buffer;
19217c478bd9Sstevel@tonic-gate 	gss_ctx_id_t context_handle;
19227c478bd9Sstevel@tonic-gate 	bool_t context_verf_ok;
19237c478bd9Sstevel@tonic-gate 
19247c478bd9Sstevel@tonic-gate 	memset(res, 0, sizeof (*res));
19257c478bd9Sstevel@tonic-gate 
19267c478bd9Sstevel@tonic-gate 	if (gssd_debug)
19277c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("gss_seal\n"));
19287c478bd9Sstevel@tonic-gate 
19297c478bd9Sstevel@tonic-gate 	gssd_convert_context_handle(&argp->context_handle, &context_handle,
19307c478bd9Sstevel@tonic-gate 		argp->gssd_context_verifier, &context_verf_ok, NULL);
19317c478bd9Sstevel@tonic-gate 
19327c478bd9Sstevel@tonic-gate 	/* verify the context_handle */
19337c478bd9Sstevel@tonic-gate 
19347c478bd9Sstevel@tonic-gate 	if (!context_verf_ok) {
19357c478bd9Sstevel@tonic-gate 		res->output_message_buffer.GSS_BUFFER_T_val = NULL;
19367c478bd9Sstevel@tonic-gate 		res->output_message_buffer.GSS_BUFFER_T_len = 0;
19377c478bd9Sstevel@tonic-gate 		res->status = (OM_uint32) GSS_S_NO_CONTEXT;
19387c478bd9Sstevel@tonic-gate 		res->minor_status = 0;
19397c478bd9Sstevel@tonic-gate 		return (TRUE);
19407c478bd9Sstevel@tonic-gate 	}
19417c478bd9Sstevel@tonic-gate 
19427c478bd9Sstevel@tonic-gate 	/*
19437c478bd9Sstevel@tonic-gate 	 * if the request isn't from root, null out the result pointer
19447c478bd9Sstevel@tonic-gate 	 * entries, so the next time through xdr_free won't try to
19457c478bd9Sstevel@tonic-gate 	 * free unmalloc'd memory and then return NULL
19467c478bd9Sstevel@tonic-gate 	 */
19477c478bd9Sstevel@tonic-gate 
19487c478bd9Sstevel@tonic-gate 	if (checkfrom(rqstp, &uid) == 0) {
19497c478bd9Sstevel@tonic-gate 		res->output_message_buffer.GSS_BUFFER_T_val = NULL;
19507c478bd9Sstevel@tonic-gate 		return (FALSE);
19517c478bd9Sstevel@tonic-gate 
19527c478bd9Sstevel@tonic-gate 	}
19537c478bd9Sstevel@tonic-gate 
19547c478bd9Sstevel@tonic-gate 
19557c478bd9Sstevel@tonic-gate 	/*
19567c478bd9Sstevel@tonic-gate 	 * copy the XDR structured arguments into their corresponding local
19577c478bd9Sstevel@tonic-gate 	 * GSSAPI variable equivalents.
19587c478bd9Sstevel@tonic-gate 	 */
19597c478bd9Sstevel@tonic-gate 
19607c478bd9Sstevel@tonic-gate 	input_message_buffer.length = (size_t)argp->input_message_buffer.
19617c478bd9Sstevel@tonic-gate 					GSS_BUFFER_T_len;
19627c478bd9Sstevel@tonic-gate 	input_message_buffer.value = (void *)argp->input_message_buffer.
19637c478bd9Sstevel@tonic-gate 					GSS_BUFFER_T_val;
19647c478bd9Sstevel@tonic-gate 
19657c478bd9Sstevel@tonic-gate 
19667c478bd9Sstevel@tonic-gate 	/* call the gssapi routine */
19677c478bd9Sstevel@tonic-gate 
19687c478bd9Sstevel@tonic-gate 	res->status = (OM_uint32)gss_seal(&res->minor_status,
19697c478bd9Sstevel@tonic-gate 				context_handle,
19707c478bd9Sstevel@tonic-gate 				argp->conf_req_flag,
19717c478bd9Sstevel@tonic-gate 				argp->qop_req,
19727c478bd9Sstevel@tonic-gate 				&input_message_buffer,
19737c478bd9Sstevel@tonic-gate 				&res->conf_state,
19747c478bd9Sstevel@tonic-gate 				&output_message_buffer);
19757c478bd9Sstevel@tonic-gate 	/*
19767c478bd9Sstevel@tonic-gate 	 * convert the output args from the parameter given in the call to the
19777c478bd9Sstevel@tonic-gate 	 * variable in the XDR result
19787c478bd9Sstevel@tonic-gate 	 */
19797c478bd9Sstevel@tonic-gate 
19807c478bd9Sstevel@tonic-gate 	if (res->status == GSS_S_COMPLETE) {
19817c478bd9Sstevel@tonic-gate 		res->output_message_buffer.GSS_BUFFER_T_len =
19827c478bd9Sstevel@tonic-gate 				(uint_t)output_message_buffer.length;
19837c478bd9Sstevel@tonic-gate 		res->output_message_buffer.GSS_BUFFER_T_val =
19847c478bd9Sstevel@tonic-gate 				(char *)output_message_buffer.value;
19855e01956fSGlenn Barry 	} else
19865e01956fSGlenn Barry 		syslog_gss_error(res->status, res->minor_status, "seal");
19877c478bd9Sstevel@tonic-gate 
19887c478bd9Sstevel@tonic-gate /* return to caller */
19897c478bd9Sstevel@tonic-gate 
19907c478bd9Sstevel@tonic-gate 	return (TRUE);
19917c478bd9Sstevel@tonic-gate }
19927c478bd9Sstevel@tonic-gate 
19937c478bd9Sstevel@tonic-gate bool_t
gss_unseal_1_svc(argp,res,rqstp)19947c478bd9Sstevel@tonic-gate gss_unseal_1_svc(argp, res, rqstp)
19957c478bd9Sstevel@tonic-gate gss_unseal_arg *argp;
19967c478bd9Sstevel@tonic-gate gss_unseal_res *res;
19977c478bd9Sstevel@tonic-gate struct svc_req *rqstp;
19987c478bd9Sstevel@tonic-gate {
19997c478bd9Sstevel@tonic-gate 
20007c478bd9Sstevel@tonic-gate 	uid_t uid;
20017c478bd9Sstevel@tonic-gate 
20027c478bd9Sstevel@tonic-gate 	gss_buffer_desc input_message_buffer;
20037c478bd9Sstevel@tonic-gate 	gss_buffer_desc output_message_buffer;
20047c478bd9Sstevel@tonic-gate 	gss_ctx_id_t context_handle;
20057c478bd9Sstevel@tonic-gate 	bool_t context_verf_ok;
20067c478bd9Sstevel@tonic-gate 
20077c478bd9Sstevel@tonic-gate 	memset(res, 0, sizeof (*res));
20087c478bd9Sstevel@tonic-gate 
20097c478bd9Sstevel@tonic-gate 	if (gssd_debug)
20107c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("gss_unseal\n"));
20117c478bd9Sstevel@tonic-gate 
20127c478bd9Sstevel@tonic-gate 	/* verify the context_handle */
20137c478bd9Sstevel@tonic-gate 	gssd_convert_context_handle(&argp->context_handle, &context_handle,
20147c478bd9Sstevel@tonic-gate 		argp->gssd_context_verifier, &context_verf_ok, NULL);
20157c478bd9Sstevel@tonic-gate 
20167c478bd9Sstevel@tonic-gate 	/* verify the context_handle */
20177c478bd9Sstevel@tonic-gate 	if (!context_verf_ok) {
20187c478bd9Sstevel@tonic-gate 		res->output_message_buffer.GSS_BUFFER_T_val = NULL;
20197c478bd9Sstevel@tonic-gate 		res->output_message_buffer.GSS_BUFFER_T_len = 0;
20207c478bd9Sstevel@tonic-gate 		res->status = (OM_uint32)GSS_S_NO_CONTEXT;
20217c478bd9Sstevel@tonic-gate 		res->minor_status = 0;
20227c478bd9Sstevel@tonic-gate 		return (TRUE);
20237c478bd9Sstevel@tonic-gate 	}
20247c478bd9Sstevel@tonic-gate 
20257c478bd9Sstevel@tonic-gate 	/*
20267c478bd9Sstevel@tonic-gate 	 * if the request isn't from root, null out the result pointer
20277c478bd9Sstevel@tonic-gate 	 * entries, so the next time through xdr_free won't try to
20287c478bd9Sstevel@tonic-gate 	 * free unmalloc'd memory and then return NULL
20297c478bd9Sstevel@tonic-gate 	 */
20307c478bd9Sstevel@tonic-gate 
20317c478bd9Sstevel@tonic-gate 	if (checkfrom(rqstp, &uid) == 0) {
20327c478bd9Sstevel@tonic-gate 		res->output_message_buffer.GSS_BUFFER_T_val = NULL;
20337c478bd9Sstevel@tonic-gate 		return (FALSE);
20347c478bd9Sstevel@tonic-gate 	}
20357c478bd9Sstevel@tonic-gate 
20367c478bd9Sstevel@tonic-gate 
20377c478bd9Sstevel@tonic-gate 	/*
20387c478bd9Sstevel@tonic-gate 	 * copy the XDR structured arguments into their corresponding local
20397c478bd9Sstevel@tonic-gate 	 * GSSAPI variable equivalents.
20407c478bd9Sstevel@tonic-gate 	 */
20417c478bd9Sstevel@tonic-gate 
20427c478bd9Sstevel@tonic-gate 	input_message_buffer.length = (size_t)argp->input_message_buffer.
20437c478bd9Sstevel@tonic-gate 					GSS_BUFFER_T_len;
20447c478bd9Sstevel@tonic-gate 	input_message_buffer.value = (void *)argp->input_message_buffer.
20457c478bd9Sstevel@tonic-gate 					GSS_BUFFER_T_val;
20467c478bd9Sstevel@tonic-gate 
20477c478bd9Sstevel@tonic-gate 	/* call the gssapi routine */
20487c478bd9Sstevel@tonic-gate 
20497c478bd9Sstevel@tonic-gate 	res->status = (OM_uint32)gss_unseal(&res->minor_status,
20507c478bd9Sstevel@tonic-gate 				context_handle,
20517c478bd9Sstevel@tonic-gate 				&input_message_buffer,
20527c478bd9Sstevel@tonic-gate 				&output_message_buffer,
20537c478bd9Sstevel@tonic-gate 				&res->conf_state,
20547c478bd9Sstevel@tonic-gate 				&res->qop_state);
20557c478bd9Sstevel@tonic-gate 
20567c478bd9Sstevel@tonic-gate 	/*
20577c478bd9Sstevel@tonic-gate 	 * convert the output args from the parameter given in the call to the
20587c478bd9Sstevel@tonic-gate 	 * variable in the XDR result
20597c478bd9Sstevel@tonic-gate 	 */
20607c478bd9Sstevel@tonic-gate 
20617c478bd9Sstevel@tonic-gate 	if (res->status == GSS_S_COMPLETE) {
20627c478bd9Sstevel@tonic-gate 		res->output_message_buffer.GSS_BUFFER_T_len =
20637c478bd9Sstevel@tonic-gate 				(uint_t)output_message_buffer.length;
20647c478bd9Sstevel@tonic-gate 		res->output_message_buffer.GSS_BUFFER_T_val =
20657c478bd9Sstevel@tonic-gate 				(char *)output_message_buffer.value;
20665e01956fSGlenn Barry 	} else
20675e01956fSGlenn Barry 		syslog_gss_error(res->status, res->minor_status, "unseal");
20687c478bd9Sstevel@tonic-gate 
20697c478bd9Sstevel@tonic-gate 
20707c478bd9Sstevel@tonic-gate 	/* return to caller */
20717c478bd9Sstevel@tonic-gate 
20727c478bd9Sstevel@tonic-gate 	return (TRUE);
20737c478bd9Sstevel@tonic-gate }
20747c478bd9Sstevel@tonic-gate 
20757c478bd9Sstevel@tonic-gate bool_t
gss_display_status_1_svc(argp,res,rqstp)20767c478bd9Sstevel@tonic-gate gss_display_status_1_svc(argp, res, rqstp)
20777c478bd9Sstevel@tonic-gate gss_display_status_arg *argp;
20787c478bd9Sstevel@tonic-gate gss_display_status_res *res;
20797c478bd9Sstevel@tonic-gate struct svc_req *rqstp;
20807c478bd9Sstevel@tonic-gate {
20817c478bd9Sstevel@tonic-gate 	uid_t uid;
20827c478bd9Sstevel@tonic-gate 	gss_OID mech_type;
20837c478bd9Sstevel@tonic-gate 	gss_OID_desc mech_type_desc;
20847c478bd9Sstevel@tonic-gate 	gss_buffer_desc status_string;
20857c478bd9Sstevel@tonic-gate 
20867c478bd9Sstevel@tonic-gate 	memset(res, 0, sizeof (*res));
20877c478bd9Sstevel@tonic-gate 
20887c478bd9Sstevel@tonic-gate 	if (gssd_debug)
20897c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("gss_display_status\n"));
20907c478bd9Sstevel@tonic-gate 
20917c478bd9Sstevel@tonic-gate 	/*
20927c478bd9Sstevel@tonic-gate 	 * if the request isn't from root, null out the result pointer
20937c478bd9Sstevel@tonic-gate 	 * entries, so the next time through xdr_free won't try to
20947c478bd9Sstevel@tonic-gate 	 * free unmalloc'd memory and then return NULL
20957c478bd9Sstevel@tonic-gate 	 */
20967c478bd9Sstevel@tonic-gate 
20977c478bd9Sstevel@tonic-gate 	if (checkfrom(rqstp, &uid) == 0) {
20987c478bd9Sstevel@tonic-gate 		res->status_string.GSS_BUFFER_T_val = NULL;
20997c478bd9Sstevel@tonic-gate 		return (FALSE);
21007c478bd9Sstevel@tonic-gate 	}
21017c478bd9Sstevel@tonic-gate 
21027c478bd9Sstevel@tonic-gate 	/* set the uid sent as the RPC argument */
21037c478bd9Sstevel@tonic-gate 
21047c478bd9Sstevel@tonic-gate 	uid = argp->uid;
21057c478bd9Sstevel@tonic-gate 	set_gssd_uid(uid);
21067c478bd9Sstevel@tonic-gate 
21077c478bd9Sstevel@tonic-gate 	/*
21087c478bd9Sstevel@tonic-gate 	 * copy the XDR structured arguments into their corresponding local
21097c478bd9Sstevel@tonic-gate 	 * GSSAPI variables.
21107c478bd9Sstevel@tonic-gate 	 */
21117c478bd9Sstevel@tonic-gate 
21127c478bd9Sstevel@tonic-gate 	if (argp->mech_type.GSS_OID_len == 0)
21137c478bd9Sstevel@tonic-gate 		mech_type = GSS_C_NULL_OID;
21147c478bd9Sstevel@tonic-gate 	else {
21157c478bd9Sstevel@tonic-gate 		mech_type = &mech_type_desc;
21167c478bd9Sstevel@tonic-gate 		mech_type_desc.length = (OM_uint32) argp->mech_type.GSS_OID_len;
21177c478bd9Sstevel@tonic-gate 		mech_type_desc.elements = (void *) argp->mech_type.GSS_OID_val;
21187c478bd9Sstevel@tonic-gate 	}
21197c478bd9Sstevel@tonic-gate 
21207c478bd9Sstevel@tonic-gate 
21217c478bd9Sstevel@tonic-gate 	/* call the gssapi routine */
21227c478bd9Sstevel@tonic-gate 
21237c478bd9Sstevel@tonic-gate 	res->status = (OM_uint32) gss_display_status(&res->minor_status,
21247c478bd9Sstevel@tonic-gate 					argp->status_value,
21257c478bd9Sstevel@tonic-gate 					argp->status_type,
21267c478bd9Sstevel@tonic-gate 					mech_type,
21277c478bd9Sstevel@tonic-gate 					(OM_uint32 *)&res->message_context,
21287c478bd9Sstevel@tonic-gate 					&status_string);
21297c478bd9Sstevel@tonic-gate 
21307c478bd9Sstevel@tonic-gate 	/*
21317c478bd9Sstevel@tonic-gate 	 * convert the output args from the parameter given in the call to the
21327c478bd9Sstevel@tonic-gate 	 * variable in the XDR result
21337c478bd9Sstevel@tonic-gate 	 */
21347c478bd9Sstevel@tonic-gate 
21357c478bd9Sstevel@tonic-gate 	if (res->status == GSS_S_COMPLETE) {
21367c478bd9Sstevel@tonic-gate 		res->status_string.GSS_BUFFER_T_len =
21377c478bd9Sstevel@tonic-gate 			(uint_t)status_string.length;
21387c478bd9Sstevel@tonic-gate 		res->status_string.GSS_BUFFER_T_val =
21397c478bd9Sstevel@tonic-gate 			(char *)status_string.value;
21407c478bd9Sstevel@tonic-gate 	}
21417c478bd9Sstevel@tonic-gate 
21427c478bd9Sstevel@tonic-gate 	return (TRUE);
21437c478bd9Sstevel@tonic-gate 
21447c478bd9Sstevel@tonic-gate }
21457c478bd9Sstevel@tonic-gate 
21467c478bd9Sstevel@tonic-gate /*ARGSUSED*/
21477c478bd9Sstevel@tonic-gate bool_t
gss_indicate_mechs_1_svc(argp,res,rqstp)21487c478bd9Sstevel@tonic-gate gss_indicate_mechs_1_svc(argp, res, rqstp)
21497c478bd9Sstevel@tonic-gate 	void *argp;
21507c478bd9Sstevel@tonic-gate 	gss_indicate_mechs_res *res;
21517c478bd9Sstevel@tonic-gate 	struct svc_req *rqstp;
21527c478bd9Sstevel@tonic-gate {
21537c478bd9Sstevel@tonic-gate 	gss_OID_set oid_set;
21547c478bd9Sstevel@tonic-gate 	uid_t uid;
21557c478bd9Sstevel@tonic-gate 
21567c478bd9Sstevel@tonic-gate 	memset(res, 0, sizeof (*res));
21577c478bd9Sstevel@tonic-gate 
21587c478bd9Sstevel@tonic-gate 	if (gssd_debug)
21597c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("gss_indicate_mechs\n"));
21607c478bd9Sstevel@tonic-gate 
21617c478bd9Sstevel@tonic-gate 	res->mech_set.GSS_OID_SET_val = NULL;
21627c478bd9Sstevel@tonic-gate 
21637c478bd9Sstevel@tonic-gate 	/*
21647c478bd9Sstevel@tonic-gate 	 * if the request isn't from root, null out the result pointer
21657c478bd9Sstevel@tonic-gate 	 * entries, so the next time through xdr_free won't try to
21667c478bd9Sstevel@tonic-gate 	 * free unmalloc'd memory and then return NULL
21677c478bd9Sstevel@tonic-gate 	 */
21687c478bd9Sstevel@tonic-gate 
21697c478bd9Sstevel@tonic-gate 	if (checkfrom(rqstp, &uid) == 0) {
21707c478bd9Sstevel@tonic-gate 		return (FALSE);
21717c478bd9Sstevel@tonic-gate 	}
21727c478bd9Sstevel@tonic-gate 
21737c478bd9Sstevel@tonic-gate 	res->status = gss_indicate_mechs(&res->minor_status, &oid_set);
21747c478bd9Sstevel@tonic-gate 
21757c478bd9Sstevel@tonic-gate 	if (res->status == GSS_S_COMPLETE) {
21767c478bd9Sstevel@tonic-gate 		int i, j;
21777c478bd9Sstevel@tonic-gate 
21787c478bd9Sstevel@tonic-gate 		res->mech_set.GSS_OID_SET_len = oid_set->count;
21797c478bd9Sstevel@tonic-gate 		res->mech_set.GSS_OID_SET_val = (void *)
21807c478bd9Sstevel@tonic-gate 				malloc(oid_set->count * sizeof (GSS_OID));
21817c478bd9Sstevel@tonic-gate 		if (!res->mech_set.GSS_OID_SET_val) {
21827c478bd9Sstevel@tonic-gate 			return (GSS_S_FAILURE);
21837c478bd9Sstevel@tonic-gate 		}
21847c478bd9Sstevel@tonic-gate 		for (i = 0; i < oid_set->count; i++) {
21857c478bd9Sstevel@tonic-gate 			res->mech_set.GSS_OID_SET_val[i].GSS_OID_len =
21867c478bd9Sstevel@tonic-gate 				oid_set->elements[i].length;
21877c478bd9Sstevel@tonic-gate 			res->mech_set.GSS_OID_SET_val[i].GSS_OID_val =
21887c478bd9Sstevel@tonic-gate 				(char *)malloc(oid_set->elements[i].length);
21897c478bd9Sstevel@tonic-gate 			if (!res->mech_set.GSS_OID_SET_val[i].GSS_OID_val) {
21907c478bd9Sstevel@tonic-gate 				for (j = 0; j < (i -1); j++) {
21917c478bd9Sstevel@tonic-gate 				free
21927c478bd9Sstevel@tonic-gate 				(res->mech_set.GSS_OID_SET_val[i].GSS_OID_val);
21937c478bd9Sstevel@tonic-gate 				}
21947c478bd9Sstevel@tonic-gate 				free(res->mech_set.GSS_OID_SET_val);
21957c478bd9Sstevel@tonic-gate 				return (GSS_S_FAILURE);
21967c478bd9Sstevel@tonic-gate 			}
21977c478bd9Sstevel@tonic-gate 			memcpy(res->mech_set.GSS_OID_SET_val[i].GSS_OID_val,
21987c478bd9Sstevel@tonic-gate 				oid_set->elements[i].elements,
21997c478bd9Sstevel@tonic-gate 				oid_set->elements[i].length);
22007c478bd9Sstevel@tonic-gate 		}
22017c478bd9Sstevel@tonic-gate 	}
22027c478bd9Sstevel@tonic-gate 
22037c478bd9Sstevel@tonic-gate 	return (TRUE);
22047c478bd9Sstevel@tonic-gate }
22057c478bd9Sstevel@tonic-gate 
22067c478bd9Sstevel@tonic-gate bool_t
gss_inquire_cred_1_svc(argp,res,rqstp)22077c478bd9Sstevel@tonic-gate gss_inquire_cred_1_svc(argp, res, rqstp)
22087c478bd9Sstevel@tonic-gate gss_inquire_cred_arg *argp;
22097c478bd9Sstevel@tonic-gate gss_inquire_cred_res *res;
22107c478bd9Sstevel@tonic-gate struct svc_req *rqstp;
22117c478bd9Sstevel@tonic-gate {
22127c478bd9Sstevel@tonic-gate 
22137c478bd9Sstevel@tonic-gate 	uid_t uid;
22147c478bd9Sstevel@tonic-gate 
22157c478bd9Sstevel@tonic-gate 	OM_uint32 minor_status;
22167c478bd9Sstevel@tonic-gate 	gss_cred_id_t cred_handle;
22177c478bd9Sstevel@tonic-gate 	gss_buffer_desc external_name;
22187c478bd9Sstevel@tonic-gate 	gss_OID name_type;
22197c478bd9Sstevel@tonic-gate 	gss_name_t internal_name;
22207c478bd9Sstevel@tonic-gate 	gss_OID_set mechanisms;
22217c478bd9Sstevel@tonic-gate 	int i, j;
22227c478bd9Sstevel@tonic-gate 
22237c478bd9Sstevel@tonic-gate 	memset(res, 0, sizeof (*res));
22247c478bd9Sstevel@tonic-gate 
22257c478bd9Sstevel@tonic-gate 	if (gssd_debug)
22267c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("gss_inquire_cred\n"));
22277c478bd9Sstevel@tonic-gate 
22287c478bd9Sstevel@tonic-gate 	/* verify the verifier_cred_handle */
22297c478bd9Sstevel@tonic-gate 
22307c478bd9Sstevel@tonic-gate 	if (argp->gssd_cred_verifier != gssd_time_verf) {
22317c478bd9Sstevel@tonic-gate 		res->name.GSS_BUFFER_T_val = NULL;
22327c478bd9Sstevel@tonic-gate 		res->name_type.GSS_OID_val = NULL;
22337c478bd9Sstevel@tonic-gate 		res->mechanisms.GSS_OID_SET_val = NULL;
22347c478bd9Sstevel@tonic-gate 		res->status = (OM_uint32) GSS_S_DEFECTIVE_CREDENTIAL;
22357c478bd9Sstevel@tonic-gate 		res->minor_status = 0;
22367c478bd9Sstevel@tonic-gate 		return (TRUE);
22377c478bd9Sstevel@tonic-gate 	}
22387c478bd9Sstevel@tonic-gate 
22397c478bd9Sstevel@tonic-gate 	/*
22407c478bd9Sstevel@tonic-gate 	 * if the request isn't from root, null out the result pointer
22417c478bd9Sstevel@tonic-gate 	 * entries, so the next time through xdr_free won't try to
22427c478bd9Sstevel@tonic-gate 	 * free unmalloc'd memory and then return NULL
22437c478bd9Sstevel@tonic-gate 	 */
22447c478bd9Sstevel@tonic-gate 
22457c478bd9Sstevel@tonic-gate 	if (checkfrom(rqstp, &uid) == 0) {
22467c478bd9Sstevel@tonic-gate 		res->name.GSS_BUFFER_T_val = NULL;
22477c478bd9Sstevel@tonic-gate 		res->name_type.GSS_OID_val = NULL;
22487c478bd9Sstevel@tonic-gate 		res->mechanisms.GSS_OID_SET_val = NULL;
22497c478bd9Sstevel@tonic-gate 		return (FALSE);
22507c478bd9Sstevel@tonic-gate 	}
22517c478bd9Sstevel@tonic-gate 
22527c478bd9Sstevel@tonic-gate 	/* set the uid sent as the RPC argument */
22537c478bd9Sstevel@tonic-gate 
22547c478bd9Sstevel@tonic-gate 	uid = argp->uid;
22557c478bd9Sstevel@tonic-gate 	set_gssd_uid(uid);
22567c478bd9Sstevel@tonic-gate 
22577c478bd9Sstevel@tonic-gate 	cred_handle = (argp->cred_handle.GSS_CRED_ID_T_len == 0 ?
22587c478bd9Sstevel@tonic-gate 			GSS_C_NO_CREDENTIAL :
22597c478bd9Sstevel@tonic-gate 			/*LINTED*/
22607c478bd9Sstevel@tonic-gate 			*((gss_cred_id_t *)argp->cred_handle.
22617c478bd9Sstevel@tonic-gate 				GSS_CRED_ID_T_val));
22627c478bd9Sstevel@tonic-gate 
22637c478bd9Sstevel@tonic-gate 	/* call the gssapi routine */
22647c478bd9Sstevel@tonic-gate 
22657c478bd9Sstevel@tonic-gate 	res->status = (OM_uint32)gss_inquire_cred(&res->minor_status,
22667c478bd9Sstevel@tonic-gate 					cred_handle,
22677c478bd9Sstevel@tonic-gate 					&internal_name,
22687c478bd9Sstevel@tonic-gate 					&res->lifetime,
22697c478bd9Sstevel@tonic-gate 					&res->cred_usage,
22707c478bd9Sstevel@tonic-gate 					&mechanisms);
22717c478bd9Sstevel@tonic-gate 
22725e01956fSGlenn Barry 	if (res->status != GSS_S_COMPLETE) {
22735e01956fSGlenn Barry 		syslog_gss_error(res->status, res->minor_status,
22745e01956fSGlenn Barry 				"inquire_cred");
22757c478bd9Sstevel@tonic-gate 		return (TRUE);
22765e01956fSGlenn Barry 	}
22777c478bd9Sstevel@tonic-gate 
22787c478bd9Sstevel@tonic-gate 	/* convert the returned name from internal to external format */
22797c478bd9Sstevel@tonic-gate 
22807c478bd9Sstevel@tonic-gate 	if (gss_display_name(&minor_status, internal_name,
22817c478bd9Sstevel@tonic-gate 				&external_name, &name_type)
22827c478bd9Sstevel@tonic-gate 			!= GSS_S_COMPLETE) {
22837c478bd9Sstevel@tonic-gate 
22847c478bd9Sstevel@tonic-gate 		res->status = (OM_uint32)GSS_S_FAILURE;
22857c478bd9Sstevel@tonic-gate 		res->minor_status = minor_status;
22867c478bd9Sstevel@tonic-gate 
22877c478bd9Sstevel@tonic-gate 		gss_release_name(&minor_status, &internal_name);
22887c478bd9Sstevel@tonic-gate 
22897c478bd9Sstevel@tonic-gate 		if (mechanisms != GSS_C_NULL_OID_SET) {
22907c478bd9Sstevel@tonic-gate 			for (i = 0; i < mechanisms->count; i++)
22917c478bd9Sstevel@tonic-gate 				free(mechanisms->elements[i].elements);
22927c478bd9Sstevel@tonic-gate 			free(mechanisms->elements);
22937c478bd9Sstevel@tonic-gate 			free(mechanisms);
22947c478bd9Sstevel@tonic-gate 		}
22957c478bd9Sstevel@tonic-gate 
22967c478bd9Sstevel@tonic-gate 		return (TRUE);
22977c478bd9Sstevel@tonic-gate 	}
22987c478bd9Sstevel@tonic-gate 
22997c478bd9Sstevel@tonic-gate 	/*
23007c478bd9Sstevel@tonic-gate 	 * convert the output args from the parameter given in the call to the
23017c478bd9Sstevel@tonic-gate 	 * variable in the XDR result
23027c478bd9Sstevel@tonic-gate 	 */
23037c478bd9Sstevel@tonic-gate 
23047c478bd9Sstevel@tonic-gate 
23057c478bd9Sstevel@tonic-gate 	res->name.GSS_BUFFER_T_len = (uint_t)external_name.length;
23067c478bd9Sstevel@tonic-gate 	res->name.GSS_BUFFER_T_val = (void *)external_name.value;
23077c478bd9Sstevel@tonic-gate 
23087c478bd9Sstevel@tonic-gate 	/*
23097c478bd9Sstevel@tonic-gate 	 * we have to allocate storage for name_type here, since the value
23107c478bd9Sstevel@tonic-gate 	 * returned from gss_display_name points to the underlying mechanism
23117c478bd9Sstevel@tonic-gate 	 * static storage. If we didn't allocate storage, the next time
23127c478bd9Sstevel@tonic-gate 	 * through this routine, the xdr_free() call at the beginning would
23137c478bd9Sstevel@tonic-gate 	 * try to free up that static storage.
23147c478bd9Sstevel@tonic-gate 	 */
23157c478bd9Sstevel@tonic-gate 
23167c478bd9Sstevel@tonic-gate 	res->name_type.GSS_OID_len = (uint_t)name_type->length;
23177c478bd9Sstevel@tonic-gate 	res->name_type.GSS_OID_val = (void *)malloc(name_type->length);
23187c478bd9Sstevel@tonic-gate 	if (!res->name_type.GSS_OID_val) {
23197c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
23207c478bd9Sstevel@tonic-gate 	}
23217c478bd9Sstevel@tonic-gate 	memcpy(res->name_type.GSS_OID_val, name_type->elements,
23227c478bd9Sstevel@tonic-gate 		name_type->length);
23237c478bd9Sstevel@tonic-gate 
23247c478bd9Sstevel@tonic-gate 	if (mechanisms != GSS_C_NULL_OID_SET) {
23257c478bd9Sstevel@tonic-gate 		res->mechanisms.GSS_OID_SET_len =
23267c478bd9Sstevel@tonic-gate 			(uint_t)mechanisms->count;
23277c478bd9Sstevel@tonic-gate 		res->mechanisms.GSS_OID_SET_val = (GSS_OID *)
23287c478bd9Sstevel@tonic-gate 				malloc(sizeof (GSS_OID) * mechanisms->count);
23297c478bd9Sstevel@tonic-gate 		if (!res->mechanisms.GSS_OID_SET_val) {
23307c478bd9Sstevel@tonic-gate 			free(res->name_type.GSS_OID_val);
23317c478bd9Sstevel@tonic-gate 			return (GSS_S_FAILURE);
23327c478bd9Sstevel@tonic-gate 		}
23337c478bd9Sstevel@tonic-gate 		for (i = 0; i < mechanisms->count; i++) {
23347c478bd9Sstevel@tonic-gate 			res->mechanisms.GSS_OID_SET_val[i].GSS_OID_len =
23357c478bd9Sstevel@tonic-gate 				(uint_t)mechanisms->elements[i].length;
23367c478bd9Sstevel@tonic-gate 			res->mechanisms.GSS_OID_SET_val[i].GSS_OID_val =
23377c478bd9Sstevel@tonic-gate 				(char *)malloc(mechanisms->elements[i].
23387c478bd9Sstevel@tonic-gate 						length);
23397c478bd9Sstevel@tonic-gate 			if (!res->mechanisms.GSS_OID_SET_val[i].GSS_OID_val) {
23407c478bd9Sstevel@tonic-gate 				free(res->name_type.GSS_OID_val);
23417c478bd9Sstevel@tonic-gate 				for (j = 0; j < i; j++) {
23427c478bd9Sstevel@tonic-gate 				free(res->mechanisms.
23437c478bd9Sstevel@tonic-gate 					GSS_OID_SET_val[i].GSS_OID_val);
23447c478bd9Sstevel@tonic-gate 				}
23457c478bd9Sstevel@tonic-gate 				free(res->mechanisms.GSS_OID_SET_val);
23467c478bd9Sstevel@tonic-gate 				return (GSS_S_FAILURE);
23477c478bd9Sstevel@tonic-gate 			}
23487c478bd9Sstevel@tonic-gate 			memcpy(res->mechanisms.GSS_OID_SET_val[i].GSS_OID_val,
23497c478bd9Sstevel@tonic-gate 				mechanisms->elements[i].elements,
23507c478bd9Sstevel@tonic-gate 				mechanisms->elements[i].length);
23517c478bd9Sstevel@tonic-gate 		}
23527c478bd9Sstevel@tonic-gate 	} else
23537c478bd9Sstevel@tonic-gate 		res->mechanisms.GSS_OID_SET_len = 0;
23547c478bd9Sstevel@tonic-gate 
23557c478bd9Sstevel@tonic-gate 	/* release the space allocated for internal_name and mechanisms */
23567c478bd9Sstevel@tonic-gate 	gss_release_name(&minor_status, &internal_name);
23577c478bd9Sstevel@tonic-gate 
23587c478bd9Sstevel@tonic-gate 	if (mechanisms != GSS_C_NULL_OID_SET) {
23597c478bd9Sstevel@tonic-gate 		for (i = 0; i < mechanisms->count; i++)
23607c478bd9Sstevel@tonic-gate 			free(mechanisms->elements[i].elements);
23617c478bd9Sstevel@tonic-gate 		free(mechanisms->elements);
23627c478bd9Sstevel@tonic-gate 		free(mechanisms);
23637c478bd9Sstevel@tonic-gate 	}
23647c478bd9Sstevel@tonic-gate 
23657c478bd9Sstevel@tonic-gate 	/* return to caller */
23667c478bd9Sstevel@tonic-gate 	return (TRUE);
23677c478bd9Sstevel@tonic-gate }
23687c478bd9Sstevel@tonic-gate 
23697c478bd9Sstevel@tonic-gate 
23707c478bd9Sstevel@tonic-gate bool_t
gss_inquire_cred_by_mech_1_svc(argp,res,rqstp)23717c478bd9Sstevel@tonic-gate gss_inquire_cred_by_mech_1_svc(argp, res, rqstp)
23727c478bd9Sstevel@tonic-gate gss_inquire_cred_by_mech_arg *argp;
23737c478bd9Sstevel@tonic-gate gss_inquire_cred_by_mech_res *res;
23747c478bd9Sstevel@tonic-gate struct svc_req *rqstp;
23757c478bd9Sstevel@tonic-gate {
23767c478bd9Sstevel@tonic-gate 
23777c478bd9Sstevel@tonic-gate 	uid_t uid;
23787c478bd9Sstevel@tonic-gate 
23797c478bd9Sstevel@tonic-gate 	gss_cred_id_t cred_handle;
23807c478bd9Sstevel@tonic-gate 	gss_OID_desc		mech_type_desc;
23817c478bd9Sstevel@tonic-gate 	gss_OID 		mech_type = &mech_type_desc;
23827c478bd9Sstevel@tonic-gate 
23837c478bd9Sstevel@tonic-gate 	memset(res, 0, sizeof (*res));
23847c478bd9Sstevel@tonic-gate 
23857c478bd9Sstevel@tonic-gate 	if (gssd_debug)
23867c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("gss_inquire_cred\n"));
23877c478bd9Sstevel@tonic-gate 
23887c478bd9Sstevel@tonic-gate 	/* verify the verifier_cred_handle */
23897c478bd9Sstevel@tonic-gate 
23907c478bd9Sstevel@tonic-gate 	if (argp->gssd_cred_verifier != gssd_time_verf) {
23917c478bd9Sstevel@tonic-gate 		res->status = (OM_uint32) GSS_S_DEFECTIVE_CREDENTIAL;
23927c478bd9Sstevel@tonic-gate 		res->minor_status = 0;
23937c478bd9Sstevel@tonic-gate 		return (TRUE);
23947c478bd9Sstevel@tonic-gate 	}
23957c478bd9Sstevel@tonic-gate 
23967c478bd9Sstevel@tonic-gate 	/*
23977c478bd9Sstevel@tonic-gate 	 * if the request isn't from root, null out the result pointer
23987c478bd9Sstevel@tonic-gate 	 * entries, so the next time through xdr_free won't try to
23997c478bd9Sstevel@tonic-gate 	 * free unmalloc'd memory and then return NULL
24007c478bd9Sstevel@tonic-gate 	 */
24017c478bd9Sstevel@tonic-gate 
24027c478bd9Sstevel@tonic-gate 	if (checkfrom(rqstp, &uid) == 0) {
24037c478bd9Sstevel@tonic-gate 		return (FALSE);
24047c478bd9Sstevel@tonic-gate 	}
24057c478bd9Sstevel@tonic-gate 
24067c478bd9Sstevel@tonic-gate 	/* set the uid sent as the RPC argument */
24077c478bd9Sstevel@tonic-gate 
24087c478bd9Sstevel@tonic-gate 	uid = argp->uid;
24097c478bd9Sstevel@tonic-gate 	set_gssd_uid(uid);
24107c478bd9Sstevel@tonic-gate 
24117c478bd9Sstevel@tonic-gate 	cred_handle = (argp->cred_handle.GSS_CRED_ID_T_len == 0 ?
24127c478bd9Sstevel@tonic-gate 			GSS_C_NO_CREDENTIAL :
24137c478bd9Sstevel@tonic-gate 			/*LINTED*/
24147c478bd9Sstevel@tonic-gate 			*((gss_cred_id_t *)argp->cred_handle.
24157c478bd9Sstevel@tonic-gate 				GSS_CRED_ID_T_val));
24167c478bd9Sstevel@tonic-gate 
24177c478bd9Sstevel@tonic-gate 	/* call the gssapi routine */
24187c478bd9Sstevel@tonic-gate 
24197c478bd9Sstevel@tonic-gate 	if (argp->mech_type.GSS_OID_len == 0)
24207c478bd9Sstevel@tonic-gate 		mech_type = GSS_C_NULL_OID;
24217c478bd9Sstevel@tonic-gate 	else {
24227c478bd9Sstevel@tonic-gate 		mech_type->length =
24237c478bd9Sstevel@tonic-gate 			(OM_uint32)argp->mech_type.GSS_OID_len;
24247c478bd9Sstevel@tonic-gate 		mech_type->elements =
24257c478bd9Sstevel@tonic-gate 			(void *)malloc(mech_type->length);
24267c478bd9Sstevel@tonic-gate 		if (!mech_type->elements) {
24277c478bd9Sstevel@tonic-gate 			return (GSS_S_FAILURE);
24287c478bd9Sstevel@tonic-gate 		}
24297c478bd9Sstevel@tonic-gate 		memcpy(mech_type->elements,
24307c478bd9Sstevel@tonic-gate 			argp->mech_type.GSS_OID_val,
24317c478bd9Sstevel@tonic-gate 			mech_type->length);
24327c478bd9Sstevel@tonic-gate 	}
24337c478bd9Sstevel@tonic-gate 	res->status = (OM_uint32)gss_inquire_cred_by_mech(
24347c478bd9Sstevel@tonic-gate 					&res->minor_status, cred_handle,
24357c478bd9Sstevel@tonic-gate 					mech_type, NULL, NULL,
24367c478bd9Sstevel@tonic-gate 					NULL, NULL);
24377c478bd9Sstevel@tonic-gate 
24387c478bd9Sstevel@tonic-gate 	/* return to caller */
24397c478bd9Sstevel@tonic-gate 	return (TRUE);
24407c478bd9Sstevel@tonic-gate }
24417c478bd9Sstevel@tonic-gate 
24427c478bd9Sstevel@tonic-gate 
24437c478bd9Sstevel@tonic-gate bool_t
gsscred_name_to_unix_cred_1_svc(argsp,res,rqstp)24447c478bd9Sstevel@tonic-gate gsscred_name_to_unix_cred_1_svc(argsp, res, rqstp)
24457c478bd9Sstevel@tonic-gate gsscred_name_to_unix_cred_arg *argsp;
24467c478bd9Sstevel@tonic-gate gsscred_name_to_unix_cred_res *res;
24477c478bd9Sstevel@tonic-gate struct svc_req *rqstp;
24487c478bd9Sstevel@tonic-gate {
24497c478bd9Sstevel@tonic-gate 	uid_t uid;
24507c478bd9Sstevel@tonic-gate 	gss_OID_desc oid;
24517c478bd9Sstevel@tonic-gate 	gss_name_t gssName;
24527c478bd9Sstevel@tonic-gate 	gss_buffer_desc gssBuf = GSS_C_EMPTY_BUFFER;
24537c478bd9Sstevel@tonic-gate 	OM_uint32 minor;
24547c478bd9Sstevel@tonic-gate 	int gidsLen;
24557c478bd9Sstevel@tonic-gate 	gid_t *gids, gidOut;
24567c478bd9Sstevel@tonic-gate 
24577c478bd9Sstevel@tonic-gate 	if (gssd_debug)
24587c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("gsscred_name_to_unix_cred\n"));
24597c478bd9Sstevel@tonic-gate 
24607c478bd9Sstevel@tonic-gate 	memset(res, 0, sizeof (*res));
24617c478bd9Sstevel@tonic-gate 
24627c478bd9Sstevel@tonic-gate 	/*
24637c478bd9Sstevel@tonic-gate 	 * check the request originator
24647c478bd9Sstevel@tonic-gate 	 */
24657c478bd9Sstevel@tonic-gate 	if (checkfrom(rqstp, &uid) == 0)
24667c478bd9Sstevel@tonic-gate 		return (FALSE);
24677c478bd9Sstevel@tonic-gate 
24687c478bd9Sstevel@tonic-gate 	/* set the uid from the rpc request */
24697c478bd9Sstevel@tonic-gate 	uid = argsp->uid;
24707c478bd9Sstevel@tonic-gate 	set_gssd_uid(uid);
24717c478bd9Sstevel@tonic-gate 
24727c478bd9Sstevel@tonic-gate 	/*
24737c478bd9Sstevel@tonic-gate 	 * convert the principal name to gss internal format
24747c478bd9Sstevel@tonic-gate 	 * need not malloc the input parameters
24757c478bd9Sstevel@tonic-gate 	 */
24767c478bd9Sstevel@tonic-gate 	gssBuf.length = argsp->pname.GSS_BUFFER_T_len;
24777c478bd9Sstevel@tonic-gate 	gssBuf.value = (void*)argsp->pname.GSS_BUFFER_T_val;
24787c478bd9Sstevel@tonic-gate 	oid.length = argsp->name_type.GSS_OID_len;
24797c478bd9Sstevel@tonic-gate 	oid.elements = (void*)argsp->name_type.GSS_OID_val;
24807c478bd9Sstevel@tonic-gate 
24817c478bd9Sstevel@tonic-gate 	res->major = gss_import_name(&minor, &gssBuf, &oid, &gssName);
24827c478bd9Sstevel@tonic-gate 	if (res->major != GSS_S_COMPLETE)
24837c478bd9Sstevel@tonic-gate 		return (TRUE);
24847c478bd9Sstevel@tonic-gate 
24857c478bd9Sstevel@tonic-gate 	/* retrieve the mechanism type from the arguments */
24867c478bd9Sstevel@tonic-gate 	oid.length = argsp->mech_type.GSS_OID_len;
24877c478bd9Sstevel@tonic-gate 	oid.elements = (void*)argsp->mech_type.GSS_OID_val;
24887c478bd9Sstevel@tonic-gate 
24897c478bd9Sstevel@tonic-gate 	/* call the gss extensions to map the principal name to unix creds */
24907c478bd9Sstevel@tonic-gate 	res->major = gsscred_name_to_unix_cred(gssName, &oid, &uid, &gidOut,
24917c478bd9Sstevel@tonic-gate 					&gids, &gidsLen);
24927c478bd9Sstevel@tonic-gate 	gss_release_name(&minor, &gssName);
24937c478bd9Sstevel@tonic-gate 
24947c478bd9Sstevel@tonic-gate 	if (res->major == GSS_S_COMPLETE) {
24957c478bd9Sstevel@tonic-gate 		res->uid = uid;
24967c478bd9Sstevel@tonic-gate 		res->gid = gidOut;
24977c478bd9Sstevel@tonic-gate 		res->gids.GSSCRED_GIDS_val = gids;
24987c478bd9Sstevel@tonic-gate 		res->gids.GSSCRED_GIDS_len = gidsLen;
24997c478bd9Sstevel@tonic-gate 	}
25007c478bd9Sstevel@tonic-gate 
25017c478bd9Sstevel@tonic-gate 	return (TRUE);
25027c478bd9Sstevel@tonic-gate } /* gsscred_name_to_unix_cred_svc_1 */
25037c478bd9Sstevel@tonic-gate 
25047c478bd9Sstevel@tonic-gate bool_t
gsscred_expname_to_unix_cred_1_svc(argsp,res,rqstp)25057c478bd9Sstevel@tonic-gate gsscred_expname_to_unix_cred_1_svc(argsp, res, rqstp)
25067c478bd9Sstevel@tonic-gate gsscred_expname_to_unix_cred_arg *argsp;
25077c478bd9Sstevel@tonic-gate gsscred_expname_to_unix_cred_res *res;
25087c478bd9Sstevel@tonic-gate struct svc_req *rqstp;
25097c478bd9Sstevel@tonic-gate {
25107c478bd9Sstevel@tonic-gate 	uid_t uid;
25117c478bd9Sstevel@tonic-gate 	gss_buffer_desc expName = GSS_C_EMPTY_BUFFER;
25127c478bd9Sstevel@tonic-gate 	int gidsLen;
25137c478bd9Sstevel@tonic-gate 	gid_t *gids, gidOut;
25147c478bd9Sstevel@tonic-gate 
25157c478bd9Sstevel@tonic-gate 	if (gssd_debug)
25167c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("gsscred_expname_to_unix_cred\n"));
25177c478bd9Sstevel@tonic-gate 
25187c478bd9Sstevel@tonic-gate 	memset(res, 0, sizeof (*res));
25197c478bd9Sstevel@tonic-gate 
25207c478bd9Sstevel@tonic-gate 	/*
25217c478bd9Sstevel@tonic-gate 	 * check the request originator
25227c478bd9Sstevel@tonic-gate 	 */
25237c478bd9Sstevel@tonic-gate 	if (checkfrom(rqstp, &uid) == 0)
25247c478bd9Sstevel@tonic-gate 		return (FALSE);
25257c478bd9Sstevel@tonic-gate 
25267c478bd9Sstevel@tonic-gate 	/* set the uid from the rpc request */
25277c478bd9Sstevel@tonic-gate 	uid = argsp->uid;
25287c478bd9Sstevel@tonic-gate 	set_gssd_uid(uid);
25297c478bd9Sstevel@tonic-gate 
25307c478bd9Sstevel@tonic-gate 	/*
25317c478bd9Sstevel@tonic-gate 	 * extract the export name from arguments
25327c478bd9Sstevel@tonic-gate 	 * need not malloc the input parameters
25337c478bd9Sstevel@tonic-gate 	 */
25347c478bd9Sstevel@tonic-gate 	expName.length = argsp->expname.GSS_BUFFER_T_len;
25357c478bd9Sstevel@tonic-gate 	expName.value = (void*)argsp->expname.GSS_BUFFER_T_val;
25367c478bd9Sstevel@tonic-gate 
25377c478bd9Sstevel@tonic-gate 	res->major = gsscred_expname_to_unix_cred(&expName, &uid,
25387c478bd9Sstevel@tonic-gate 					&gidOut, &gids, &gidsLen);
25397c478bd9Sstevel@tonic-gate 
25407c478bd9Sstevel@tonic-gate 	if (res->major == GSS_S_COMPLETE) {
25417c478bd9Sstevel@tonic-gate 		res->uid = uid;
25427c478bd9Sstevel@tonic-gate 		res->gid = gidOut;
25437c478bd9Sstevel@tonic-gate 		res->gids.GSSCRED_GIDS_val = gids;
25447c478bd9Sstevel@tonic-gate 		res->gids.GSSCRED_GIDS_len = gidsLen;
25457c478bd9Sstevel@tonic-gate 	}
25467c478bd9Sstevel@tonic-gate 
25477c478bd9Sstevel@tonic-gate 	return (TRUE);
25487c478bd9Sstevel@tonic-gate } /* gsscred_expname_to_unix_cred_1_svc */
25497c478bd9Sstevel@tonic-gate 
25507c478bd9Sstevel@tonic-gate bool_t
gss_get_group_info_1_svc(argsp,res,rqstp)25517c478bd9Sstevel@tonic-gate gss_get_group_info_1_svc(argsp, res, rqstp)
25527c478bd9Sstevel@tonic-gate gss_get_group_info_arg *argsp;
25537c478bd9Sstevel@tonic-gate gss_get_group_info_res *res;
25547c478bd9Sstevel@tonic-gate struct svc_req *rqstp;
25557c478bd9Sstevel@tonic-gate {
25567c478bd9Sstevel@tonic-gate 	uid_t uid;
25577c478bd9Sstevel@tonic-gate 	int gidsLen;
25587c478bd9Sstevel@tonic-gate 	gid_t *gids, gidOut;
25597c478bd9Sstevel@tonic-gate 
25607c478bd9Sstevel@tonic-gate 	if (gssd_debug)
25617c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("gss_get_group_info\n"));
25627c478bd9Sstevel@tonic-gate 
25637c478bd9Sstevel@tonic-gate 	memset(res, 0, sizeof (*res));
25647c478bd9Sstevel@tonic-gate 
25657c478bd9Sstevel@tonic-gate 	/*
25667c478bd9Sstevel@tonic-gate 	 * check the request originator
25677c478bd9Sstevel@tonic-gate 	 */
25687c478bd9Sstevel@tonic-gate 	if (checkfrom(rqstp, &uid) == 0)
25697c478bd9Sstevel@tonic-gate 		return (FALSE);
25707c478bd9Sstevel@tonic-gate 
25717c478bd9Sstevel@tonic-gate 	/* set the uid from the rpc request */
25727c478bd9Sstevel@tonic-gate 	uid = argsp->uid;
25737c478bd9Sstevel@tonic-gate 	set_gssd_uid(uid);
25747c478bd9Sstevel@tonic-gate 
25757c478bd9Sstevel@tonic-gate 	/*
25767c478bd9Sstevel@tonic-gate 	 * extract the uid from the arguments
25777c478bd9Sstevel@tonic-gate 	 */
25787c478bd9Sstevel@tonic-gate 	uid = argsp->puid;
25797c478bd9Sstevel@tonic-gate 	res->major = gss_get_group_info(uid, &gidOut, &gids, &gidsLen);
25807c478bd9Sstevel@tonic-gate 	if (res->major == GSS_S_COMPLETE) {
25817c478bd9Sstevel@tonic-gate 		res->gid = gidOut;
25827c478bd9Sstevel@tonic-gate 		res->gids.GSSCRED_GIDS_val = gids;
25837c478bd9Sstevel@tonic-gate 		res->gids.GSSCRED_GIDS_len = gidsLen;
25847c478bd9Sstevel@tonic-gate 	}
25857c478bd9Sstevel@tonic-gate 
25867c478bd9Sstevel@tonic-gate 	return (TRUE);
25877c478bd9Sstevel@tonic-gate } /* gss_get_group_info_1_svc */
25887c478bd9Sstevel@tonic-gate 
25897c478bd9Sstevel@tonic-gate /*ARGSUSED*/
25907c478bd9Sstevel@tonic-gate bool_t
gss_get_kmod_1_svc(argsp,res,rqstp)25917c478bd9Sstevel@tonic-gate gss_get_kmod_1_svc(argsp, res, rqstp)
25927c478bd9Sstevel@tonic-gate 	gss_get_kmod_arg *argsp;
25937c478bd9Sstevel@tonic-gate 	gss_get_kmod_res *res;
25947c478bd9Sstevel@tonic-gate 	struct svc_req *rqstp;
25957c478bd9Sstevel@tonic-gate {
25967c478bd9Sstevel@tonic-gate 	gss_OID_desc oid;
25977c478bd9Sstevel@tonic-gate 	char *kmodName;
25987c478bd9Sstevel@tonic-gate 
25997c478bd9Sstevel@tonic-gate 	if (gssd_debug)
26007c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("gss_get_kmod\n"));
26017c478bd9Sstevel@tonic-gate 
26027c478bd9Sstevel@tonic-gate 	res->module_follow = FALSE;
26037c478bd9Sstevel@tonic-gate 	oid.length = argsp->mech_oid.GSS_OID_len;
26047c478bd9Sstevel@tonic-gate 	oid.elements = (void *)argsp->mech_oid.GSS_OID_val;
26057c478bd9Sstevel@tonic-gate 	kmodName = __gss_get_kmodName(&oid);
26067c478bd9Sstevel@tonic-gate 
26077c478bd9Sstevel@tonic-gate 	if (kmodName != NULL) {
26087c478bd9Sstevel@tonic-gate 		res->module_follow = TRUE;
26097c478bd9Sstevel@tonic-gate 		res->gss_get_kmod_res_u.modname = kmodName;
26107c478bd9Sstevel@tonic-gate 	}
26117c478bd9Sstevel@tonic-gate 
26127c478bd9Sstevel@tonic-gate 	return (TRUE);
26137c478bd9Sstevel@tonic-gate }
26147c478bd9Sstevel@tonic-gate 
26157c478bd9Sstevel@tonic-gate /*
26167c478bd9Sstevel@tonic-gate  *  Returns 1 if caller is ok, else 0.
26177c478bd9Sstevel@tonic-gate  *  If caller ok, the uid is returned in uidp.
26187c478bd9Sstevel@tonic-gate  */
26197c478bd9Sstevel@tonic-gate static int
checkfrom(rqstp,uidp)26207c478bd9Sstevel@tonic-gate checkfrom(rqstp, uidp)
26217c478bd9Sstevel@tonic-gate struct svc_req *rqstp;
26227c478bd9Sstevel@tonic-gate uid_t *uidp;
26237c478bd9Sstevel@tonic-gate {
26247c478bd9Sstevel@tonic-gate 	SVCXPRT *xprt = rqstp->rq_xprt;
26257c478bd9Sstevel@tonic-gate 	struct authunix_parms *aup;
26267c478bd9Sstevel@tonic-gate 	uid_t uid;
26277c478bd9Sstevel@tonic-gate 
26287c478bd9Sstevel@tonic-gate 	/* check client agent uid to ensure it is privileged */
26297c478bd9Sstevel@tonic-gate 	if (__rpc_get_local_uid(xprt, &uid) < 0) {
26307c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR, gettext("__rpc_get_local_uid failed %s %s"),
26317c478bd9Sstevel@tonic-gate 			xprt->xp_netid, xprt->xp_tp);
26327c478bd9Sstevel@tonic-gate 		goto weakauth;
26337c478bd9Sstevel@tonic-gate 	}
26347c478bd9Sstevel@tonic-gate 	if (gssd_debug)
26357c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("checkfrom: local_uid  %d\n"), uid);
26367c478bd9Sstevel@tonic-gate 	if (uid != 0) {
26377c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR,
26387c478bd9Sstevel@tonic-gate 			gettext("checkfrom: caller (uid %d) not privileged"),
26397c478bd9Sstevel@tonic-gate 			uid);
26407c478bd9Sstevel@tonic-gate 		goto weakauth;
26417c478bd9Sstevel@tonic-gate 	}
26427c478bd9Sstevel@tonic-gate 
26437c478bd9Sstevel@tonic-gate 	/*
26447c478bd9Sstevel@tonic-gate 	 *  Request came from local privileged process.
26457c478bd9Sstevel@tonic-gate 	 *  Proceed to get uid of client if needed by caller.
26467c478bd9Sstevel@tonic-gate 	 */
26477c478bd9Sstevel@tonic-gate 	if (uidp) {
26487c478bd9Sstevel@tonic-gate 		if (rqstp->rq_cred.oa_flavor != AUTH_SYS) {
26497c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR, gettext("checkfrom: not UNIX credentials"));
26507c478bd9Sstevel@tonic-gate 			goto weakauth;
26517c478bd9Sstevel@tonic-gate 		}
2652*77b65ce6SAlex Wilson 		CTASSERT(sizeof (struct authunix_parms) <= RQCRED_SIZE);
26537c478bd9Sstevel@tonic-gate 		/*LINTED*/
26547c478bd9Sstevel@tonic-gate 		aup = (struct authunix_parms *)rqstp->rq_clntcred;
26557c478bd9Sstevel@tonic-gate 		*uidp = aup->aup_uid;
26567c478bd9Sstevel@tonic-gate 		if (gssd_debug) {
26577c478bd9Sstevel@tonic-gate 			fprintf(stderr,
26587c478bd9Sstevel@tonic-gate 				gettext("checkfrom: caller's uid %d\n"), *uidp);
26597c478bd9Sstevel@tonic-gate 		}
26607c478bd9Sstevel@tonic-gate 	}
26617c478bd9Sstevel@tonic-gate 	return (1);
26627c478bd9Sstevel@tonic-gate 
26637c478bd9Sstevel@tonic-gate 	weakauth:
26647c478bd9Sstevel@tonic-gate 	svcerr_weakauth(xprt);
26657c478bd9Sstevel@tonic-gate 	return (0);
26667c478bd9Sstevel@tonic-gate }
2667