2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2005 Doug Rabson
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 #include <gssapi/gssapi.h>
35 #include "mech_switch.h"
40 static struct _gss_mechanism_cred *
41 _gss_copy_cred(struct _gss_mechanism_cred *mc)
43 struct _gss_mechanism_cred *new_mc;
44 struct _gss_mech_switch *m = mc->gmc_mech;
45 OM_uint32 major_status, minor_status;
48 OM_uint32 initiator_lifetime, acceptor_lifetime;
49 gss_cred_usage_t cred_usage;
51 major_status = m->gm_inquire_cred_by_mech(&minor_status,
52 mc->gmc_cred, mc->gmc_mech_oid,
53 &name, &initiator_lifetime, &acceptor_lifetime, &cred_usage);
55 _gss_mg_error(m, major_status, minor_status);
59 major_status = m->gm_add_cred(&minor_status,
60 GSS_C_NO_CREDENTIAL, name, mc->gmc_mech_oid,
61 cred_usage, initiator_lifetime, acceptor_lifetime,
63 m->gm_release_name(&minor_status, &name);
66 _gss_mg_error(m, major_status, minor_status);
70 new_mc = malloc(sizeof(struct _gss_mechanism_cred));
72 m->gm_release_cred(&minor_status, &cred);
76 new_mc->gmc_mech_oid = &m->gm_mech_oid;
77 new_mc->gmc_cred = cred;
83 gss_add_cred(OM_uint32 *minor_status,
84 const gss_cred_id_t input_cred_handle,
85 const gss_name_t desired_name,
86 const gss_OID desired_mech,
87 gss_cred_usage_t cred_usage,
88 OM_uint32 initiator_time_req,
89 OM_uint32 acceptor_time_req,
90 gss_cred_id_t *output_cred_handle,
91 gss_OID_set *actual_mechs,
92 OM_uint32 *initiator_time_rec,
93 OM_uint32 *acceptor_time_rec)
95 OM_uint32 major_status;
96 struct _gss_mech_switch *m;
97 struct _gss_cred *cred = (struct _gss_cred *) input_cred_handle;
98 struct _gss_cred *new_cred;
99 gss_cred_id_t release_cred;
100 struct _gss_mechanism_cred *mc, *target_mc, *copy_mc;
101 struct _gss_mechanism_name *mn;
105 *output_cred_handle = GSS_C_NO_CREDENTIAL;
106 if (initiator_time_rec)
107 *initiator_time_rec = 0;
108 if (acceptor_time_rec)
109 *acceptor_time_rec = 0;
111 *actual_mechs = GSS_C_NO_OID_SET;
113 new_cred = malloc(sizeof(struct _gss_cred));
115 *minor_status = ENOMEM;
116 return (GSS_S_FAILURE);
118 SLIST_INIT(&new_cred->gc_mc);
121 * We go through all the mc attached to the input_cred_handle
122 * and check the mechanism. If it matches, we call
123 * gss_add_cred for that mechanism, otherwise we copy the mc
128 SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
129 if (gss_oid_equal(mc->gmc_mech_oid, desired_mech)) {
132 copy_mc = _gss_copy_cred(mc);
134 release_cred = (gss_cred_id_t) new_cred;
135 gss_release_cred(&junk, &release_cred);
136 *minor_status = ENOMEM;
137 return (GSS_S_FAILURE);
139 SLIST_INSERT_HEAD(&new_cred->gc_mc, copy_mc, gmc_link);
144 * Figure out a suitable mn, if any.
147 major_status = _gss_find_mn(minor_status,
148 (struct _gss_name *) desired_name,
151 if (major_status != GSS_S_COMPLETE) {
153 return (major_status);
159 m = _gss_find_mech_switch(desired_mech);
161 mc = malloc(sizeof(struct _gss_mechanism_cred));
163 release_cred = (gss_cred_id_t) new_cred;
164 gss_release_cred(&junk, &release_cred);
165 *minor_status = ENOMEM;
166 return (GSS_S_FAILURE);
169 mc->gmc_mech_oid = &m->gm_mech_oid;
171 major_status = m->gm_add_cred(minor_status,
172 target_mc ? target_mc->gmc_cred : GSS_C_NO_CREDENTIAL,
173 desired_name ? mn->gmn_name : GSS_C_NO_NAME,
184 _gss_mg_error(m, major_status, *minor_status);
185 release_cred = (gss_cred_id_t) new_cred;
186 gss_release_cred(&junk, &release_cred);
188 return (major_status);
190 SLIST_INSERT_HEAD(&new_cred->gc_mc, mc, gmc_link);
191 *output_cred_handle = (gss_cred_id_t) new_cred;
193 return (GSS_S_COMPLETE);