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