1c0b9f4feSDoug Rabson /*-
2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
35e53a4f9SPedro F. Giffuni *
4c0b9f4feSDoug Rabson * Copyright (c) 2005 Doug Rabson
5c0b9f4feSDoug Rabson * All rights reserved.
6c0b9f4feSDoug Rabson *
7c0b9f4feSDoug Rabson * Redistribution and use in source and binary forms, with or without
8c0b9f4feSDoug Rabson * modification, are permitted provided that the following conditions
9c0b9f4feSDoug Rabson * are met:
10c0b9f4feSDoug Rabson * 1. Redistributions of source code must retain the above copyright
11c0b9f4feSDoug Rabson * notice, this list of conditions and the following disclaimer.
12c0b9f4feSDoug Rabson * 2. Redistributions in binary form must reproduce the above copyright
13c0b9f4feSDoug Rabson * notice, this list of conditions and the following disclaimer in the
14c0b9f4feSDoug Rabson * documentation and/or other materials provided with the distribution.
15c0b9f4feSDoug Rabson *
16c0b9f4feSDoug Rabson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17c0b9f4feSDoug Rabson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18c0b9f4feSDoug Rabson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19c0b9f4feSDoug Rabson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20c0b9f4feSDoug Rabson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21c0b9f4feSDoug Rabson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22c0b9f4feSDoug Rabson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23c0b9f4feSDoug Rabson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24c0b9f4feSDoug Rabson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25c0b9f4feSDoug Rabson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26c0b9f4feSDoug Rabson * SUCH DAMAGE.
27c0b9f4feSDoug Rabson */
28c0b9f4feSDoug Rabson
29c0b9f4feSDoug Rabson #include <gssapi/gssapi.h>
30c0b9f4feSDoug Rabson #include <stdlib.h>
313aebdb89SAlexander Kabaev #include <string.h>
32c0b9f4feSDoug Rabson #include <errno.h>
33c0b9f4feSDoug Rabson
34c0b9f4feSDoug Rabson #include "mech_switch.h"
35c0b9f4feSDoug Rabson #include "name.h"
36c0b9f4feSDoug Rabson #include "cred.h"
37c0b9f4feSDoug Rabson
3833f12199SDoug Rabson #define AUSAGE 1
3933f12199SDoug Rabson #define IUSAGE 2
4033f12199SDoug Rabson
4133f12199SDoug Rabson static void
updateusage(gss_cred_usage_t usage,int * usagemask)4233f12199SDoug Rabson updateusage(gss_cred_usage_t usage, int *usagemask)
4333f12199SDoug Rabson {
4433f12199SDoug Rabson if (usage == GSS_C_BOTH)
4533f12199SDoug Rabson *usagemask |= AUSAGE | IUSAGE;
4633f12199SDoug Rabson else if (usage == GSS_C_ACCEPT)
4733f12199SDoug Rabson *usagemask |= AUSAGE;
4833f12199SDoug Rabson else if (usage == GSS_C_INITIATE)
4933f12199SDoug Rabson *usagemask |= IUSAGE;
5033f12199SDoug Rabson }
5133f12199SDoug Rabson
52c0b9f4feSDoug Rabson OM_uint32
gss_inquire_cred(OM_uint32 * minor_status,const gss_cred_id_t cred_handle,gss_name_t * name_ret,OM_uint32 * lifetime,gss_cred_usage_t * cred_usage,gss_OID_set * mechanisms)53c0b9f4feSDoug Rabson gss_inquire_cred(OM_uint32 *minor_status,
54c0b9f4feSDoug Rabson const gss_cred_id_t cred_handle,
55c0b9f4feSDoug Rabson gss_name_t *name_ret,
56c0b9f4feSDoug Rabson OM_uint32 *lifetime,
57c0b9f4feSDoug Rabson gss_cred_usage_t *cred_usage,
58c0b9f4feSDoug Rabson gss_OID_set *mechanisms)
59c0b9f4feSDoug Rabson {
60c0b9f4feSDoug Rabson OM_uint32 major_status;
61c0b9f4feSDoug Rabson struct _gss_mech_switch *m;
62c0b9f4feSDoug Rabson struct _gss_cred *cred = (struct _gss_cred *) cred_handle;
63c0b9f4feSDoug Rabson struct _gss_name *name;
64c0b9f4feSDoug Rabson struct _gss_mechanism_name *mn;
65c0b9f4feSDoug Rabson OM_uint32 min_lifetime;
6633f12199SDoug Rabson int found = 0;
6733f12199SDoug Rabson int usagemask = 0;
6833f12199SDoug Rabson gss_cred_usage_t usage;
6933f12199SDoug Rabson
7033f12199SDoug Rabson _gss_load_mech();
71c0b9f4feSDoug Rabson
72c0b9f4feSDoug Rabson *minor_status = 0;
73c0b9f4feSDoug Rabson if (name_ret)
7433f12199SDoug Rabson *name_ret = GSS_C_NO_NAME;
75c0b9f4feSDoug Rabson if (lifetime)
76c0b9f4feSDoug Rabson *lifetime = 0;
77c0b9f4feSDoug Rabson if (cred_usage)
78c0b9f4feSDoug Rabson *cred_usage = 0;
7933f12199SDoug Rabson if (mechanisms)
8033f12199SDoug Rabson *mechanisms = GSS_C_NO_OID_SET;
81c0b9f4feSDoug Rabson
82c0b9f4feSDoug Rabson if (name_ret) {
83c0b9f4feSDoug Rabson name = malloc(sizeof(struct _gss_name));
8433f12199SDoug Rabson if (name == NULL) {
85c0b9f4feSDoug Rabson *minor_status = ENOMEM;
86c0b9f4feSDoug Rabson return (GSS_S_FAILURE);
87c0b9f4feSDoug Rabson }
88c0b9f4feSDoug Rabson memset(name, 0, sizeof(struct _gss_name));
89c0b9f4feSDoug Rabson SLIST_INIT(&name->gn_mn);
90c0b9f4feSDoug Rabson } else {
9133f12199SDoug Rabson name = NULL;
92c0b9f4feSDoug Rabson }
93c0b9f4feSDoug Rabson
94c0b9f4feSDoug Rabson if (mechanisms) {
95c0b9f4feSDoug Rabson major_status = gss_create_empty_oid_set(minor_status,
96c0b9f4feSDoug Rabson mechanisms);
97c0b9f4feSDoug Rabson if (major_status) {
98c0b9f4feSDoug Rabson if (name) free(name);
99c0b9f4feSDoug Rabson return (major_status);
100c0b9f4feSDoug Rabson }
101c0b9f4feSDoug Rabson }
102c0b9f4feSDoug Rabson
103c0b9f4feSDoug Rabson min_lifetime = GSS_C_INDEFINITE;
104c0b9f4feSDoug Rabson if (cred) {
10533f12199SDoug Rabson struct _gss_mechanism_cred *mc;
10633f12199SDoug Rabson
107c0b9f4feSDoug Rabson SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
108c0b9f4feSDoug Rabson gss_name_t mc_name;
109c0b9f4feSDoug Rabson OM_uint32 mc_lifetime;
110c0b9f4feSDoug Rabson
111c0b9f4feSDoug Rabson major_status = mc->gmc_mech->gm_inquire_cred(minor_status,
11233f12199SDoug Rabson mc->gmc_cred, &mc_name, &mc_lifetime, &usage, NULL);
113c0b9f4feSDoug Rabson if (major_status)
114c0b9f4feSDoug Rabson continue;
115c0b9f4feSDoug Rabson
11633f12199SDoug Rabson updateusage(usage, &usagemask);
11733f12199SDoug Rabson if (name && mc_name) {
118c0b9f4feSDoug Rabson mn = malloc(sizeof(struct _gss_mechanism_name));
119c0b9f4feSDoug Rabson if (!mn) {
120c0b9f4feSDoug Rabson mc->gmc_mech->gm_release_name(minor_status,
121c0b9f4feSDoug Rabson &mc_name);
122c0b9f4feSDoug Rabson continue;
123c0b9f4feSDoug Rabson }
124c0b9f4feSDoug Rabson mn->gmn_mech = mc->gmc_mech;
125c0b9f4feSDoug Rabson mn->gmn_mech_oid = mc->gmc_mech_oid;
126c0b9f4feSDoug Rabson mn->gmn_name = mc_name;
127c0b9f4feSDoug Rabson SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link);
128c0b9f4feSDoug Rabson } else if (mc_name) {
129c0b9f4feSDoug Rabson mc->gmc_mech->gm_release_name(minor_status,
130c0b9f4feSDoug Rabson &mc_name);
131c0b9f4feSDoug Rabson }
132c0b9f4feSDoug Rabson
133c0b9f4feSDoug Rabson if (mc_lifetime < min_lifetime)
134c0b9f4feSDoug Rabson min_lifetime = mc_lifetime;
135c0b9f4feSDoug Rabson
136c0b9f4feSDoug Rabson if (mechanisms)
137c0b9f4feSDoug Rabson gss_add_oid_set_member(minor_status,
13833f12199SDoug Rabson mc->gmc_mech_oid, mechanisms);
13933f12199SDoug Rabson found++;
14033f12199SDoug Rabson }
14133f12199SDoug Rabson } else {
14233f12199SDoug Rabson SLIST_FOREACH(m, &_gss_mechs, gm_link) {
14333f12199SDoug Rabson gss_name_t mc_name;
14433f12199SDoug Rabson OM_uint32 mc_lifetime;
14533f12199SDoug Rabson
14633f12199SDoug Rabson major_status = m->gm_inquire_cred(minor_status,
14733f12199SDoug Rabson GSS_C_NO_CREDENTIAL, &mc_name, &mc_lifetime,
14833f12199SDoug Rabson &usage, NULL);
14933f12199SDoug Rabson if (major_status)
15033f12199SDoug Rabson continue;
15133f12199SDoug Rabson
15233f12199SDoug Rabson updateusage(usage, &usagemask);
15333f12199SDoug Rabson if (name && mc_name) {
15433f12199SDoug Rabson mn = malloc(
15533f12199SDoug Rabson sizeof(struct _gss_mechanism_name));
15633f12199SDoug Rabson if (!mn) {
15733f12199SDoug Rabson m->gm_release_name(
15833f12199SDoug Rabson minor_status, &mc_name);
15933f12199SDoug Rabson continue;
16033f12199SDoug Rabson }
16133f12199SDoug Rabson mn->gmn_mech = m;
16233f12199SDoug Rabson mn->gmn_mech_oid = &m->gm_mech_oid;
16333f12199SDoug Rabson mn->gmn_name = mc_name;
16433f12199SDoug Rabson SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link);
16533f12199SDoug Rabson } else if (mc_name) {
16633f12199SDoug Rabson m->gm_release_name(minor_status,
16733f12199SDoug Rabson &mc_name);
168c0b9f4feSDoug Rabson }
169c0b9f4feSDoug Rabson
17033f12199SDoug Rabson if (mc_lifetime < min_lifetime)
17133f12199SDoug Rabson min_lifetime = mc_lifetime;
17233f12199SDoug Rabson
17333f12199SDoug Rabson if (mechanisms)
17433f12199SDoug Rabson gss_add_oid_set_member(minor_status,
17533f12199SDoug Rabson &m->gm_mech_oid, mechanisms);
17633f12199SDoug Rabson found++;
17733f12199SDoug Rabson }
17833f12199SDoug Rabson }
17933f12199SDoug Rabson
18033f12199SDoug Rabson if (found == 0) {
18133f12199SDoug Rabson gss_name_t n = (gss_name_t)name;
18233f12199SDoug Rabson if (n)
18333f12199SDoug Rabson gss_release_name(minor_status, &n);
184c0b9f4feSDoug Rabson gss_release_oid_set(minor_status, mechanisms);
185c0b9f4feSDoug Rabson *minor_status = 0;
186c0b9f4feSDoug Rabson return (GSS_S_NO_CRED);
187c0b9f4feSDoug Rabson }
188c0b9f4feSDoug Rabson
189c0b9f4feSDoug Rabson *minor_status = 0;
190c0b9f4feSDoug Rabson if (name_ret)
191c0b9f4feSDoug Rabson *name_ret = (gss_name_t) name;
192c0b9f4feSDoug Rabson if (lifetime)
193c0b9f4feSDoug Rabson *lifetime = min_lifetime;
19433f12199SDoug Rabson if (cred_usage) {
19533f12199SDoug Rabson if ((usagemask & (AUSAGE|IUSAGE)) == (AUSAGE|IUSAGE))
19633f12199SDoug Rabson *cred_usage = GSS_C_BOTH;
19733f12199SDoug Rabson else if (usagemask & IUSAGE)
19833f12199SDoug Rabson *cred_usage = GSS_C_INITIATE;
19933f12199SDoug Rabson else if (usagemask & AUSAGE)
20033f12199SDoug Rabson *cred_usage = GSS_C_ACCEPT;
20133f12199SDoug Rabson }
202c0b9f4feSDoug Rabson return (GSS_S_COMPLETE);
203c0b9f4feSDoug Rabson }
204