1*ae771770SStanislav Sedov /*-
2*ae771770SStanislav Sedov * Copyright (c) 2005 Doug Rabson
3*ae771770SStanislav Sedov * All rights reserved.
4*ae771770SStanislav Sedov *
5*ae771770SStanislav Sedov * Redistribution and use in source and binary forms, with or without
6*ae771770SStanislav Sedov * modification, are permitted provided that the following conditions
7*ae771770SStanislav Sedov * are met:
8*ae771770SStanislav Sedov * 1. Redistributions of source code must retain the above copyright
9*ae771770SStanislav Sedov * notice, this list of conditions and the following disclaimer.
10*ae771770SStanislav Sedov * 2. Redistributions in binary form must reproduce the above copyright
11*ae771770SStanislav Sedov * notice, this list of conditions and the following disclaimer in the
12*ae771770SStanislav Sedov * documentation and/or other materials provided with the distribution.
13*ae771770SStanislav Sedov *
14*ae771770SStanislav Sedov * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15*ae771770SStanislav Sedov * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*ae771770SStanislav Sedov * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*ae771770SStanislav Sedov * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18*ae771770SStanislav Sedov * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*ae771770SStanislav Sedov * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*ae771770SStanislav Sedov * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*ae771770SStanislav Sedov * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*ae771770SStanislav Sedov * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*ae771770SStanislav Sedov * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*ae771770SStanislav Sedov * SUCH DAMAGE.
25*ae771770SStanislav Sedov *
26*ae771770SStanislav Sedov * $FreeBSD: src/lib/libgssapi/gss_add_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
27*ae771770SStanislav Sedov */
28*ae771770SStanislav Sedov
29*ae771770SStanislav Sedov #include "mech_locl.h"
30*ae771770SStanislav Sedov
31*ae771770SStanislav Sedov struct _gss_mechanism_cred *
_gss_copy_cred(struct _gss_mechanism_cred * mc)32*ae771770SStanislav Sedov _gss_copy_cred(struct _gss_mechanism_cred *mc)
33*ae771770SStanislav Sedov {
34*ae771770SStanislav Sedov struct _gss_mechanism_cred *new_mc;
35*ae771770SStanislav Sedov gssapi_mech_interface m = mc->gmc_mech;
36*ae771770SStanislav Sedov OM_uint32 major_status, minor_status;
37*ae771770SStanislav Sedov gss_name_t name;
38*ae771770SStanislav Sedov gss_cred_id_t cred;
39*ae771770SStanislav Sedov OM_uint32 initiator_lifetime, acceptor_lifetime;
40*ae771770SStanislav Sedov gss_cred_usage_t cred_usage;
41*ae771770SStanislav Sedov
42*ae771770SStanislav Sedov major_status = m->gm_inquire_cred_by_mech(&minor_status,
43*ae771770SStanislav Sedov mc->gmc_cred, mc->gmc_mech_oid,
44*ae771770SStanislav Sedov &name, &initiator_lifetime, &acceptor_lifetime, &cred_usage);
45*ae771770SStanislav Sedov if (major_status) {
46*ae771770SStanislav Sedov _gss_mg_error(m, major_status, minor_status);
47*ae771770SStanislav Sedov return (0);
48*ae771770SStanislav Sedov }
49*ae771770SStanislav Sedov
50*ae771770SStanislav Sedov major_status = m->gm_add_cred(&minor_status,
51*ae771770SStanislav Sedov GSS_C_NO_CREDENTIAL, name, mc->gmc_mech_oid,
52*ae771770SStanislav Sedov cred_usage, initiator_lifetime, acceptor_lifetime,
53*ae771770SStanislav Sedov &cred, 0, 0, 0);
54*ae771770SStanislav Sedov m->gm_release_name(&minor_status, &name);
55*ae771770SStanislav Sedov
56*ae771770SStanislav Sedov if (major_status) {
57*ae771770SStanislav Sedov _gss_mg_error(m, major_status, minor_status);
58*ae771770SStanislav Sedov return (0);
59*ae771770SStanislav Sedov }
60*ae771770SStanislav Sedov
61*ae771770SStanislav Sedov new_mc = malloc(sizeof(struct _gss_mechanism_cred));
62*ae771770SStanislav Sedov if (!new_mc) {
63*ae771770SStanislav Sedov m->gm_release_cred(&minor_status, &cred);
64*ae771770SStanislav Sedov return (0);
65*ae771770SStanislav Sedov }
66*ae771770SStanislav Sedov new_mc->gmc_mech = m;
67*ae771770SStanislav Sedov new_mc->gmc_mech_oid = &m->gm_mech_oid;
68*ae771770SStanislav Sedov new_mc->gmc_cred = cred;
69*ae771770SStanislav Sedov
70*ae771770SStanislav Sedov return (new_mc);
71*ae771770SStanislav Sedov }
72*ae771770SStanislav Sedov
73*ae771770SStanislav Sedov GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_add_cred(OM_uint32 * minor_status,const gss_cred_id_t input_cred_handle,const gss_name_t desired_name,const gss_OID desired_mech,gss_cred_usage_t cred_usage,OM_uint32 initiator_time_req,OM_uint32 acceptor_time_req,gss_cred_id_t * output_cred_handle,gss_OID_set * actual_mechs,OM_uint32 * initiator_time_rec,OM_uint32 * acceptor_time_rec)74*ae771770SStanislav Sedov gss_add_cred(OM_uint32 *minor_status,
75*ae771770SStanislav Sedov const gss_cred_id_t input_cred_handle,
76*ae771770SStanislav Sedov const gss_name_t desired_name,
77*ae771770SStanislav Sedov const gss_OID desired_mech,
78*ae771770SStanislav Sedov gss_cred_usage_t cred_usage,
79*ae771770SStanislav Sedov OM_uint32 initiator_time_req,
80*ae771770SStanislav Sedov OM_uint32 acceptor_time_req,
81*ae771770SStanislav Sedov gss_cred_id_t *output_cred_handle,
82*ae771770SStanislav Sedov gss_OID_set *actual_mechs,
83*ae771770SStanislav Sedov OM_uint32 *initiator_time_rec,
84*ae771770SStanislav Sedov OM_uint32 *acceptor_time_rec)
85*ae771770SStanislav Sedov {
86*ae771770SStanislav Sedov OM_uint32 major_status;
87*ae771770SStanislav Sedov gssapi_mech_interface m;
88*ae771770SStanislav Sedov struct _gss_cred *cred = (struct _gss_cred *) input_cred_handle;
89*ae771770SStanislav Sedov struct _gss_cred *new_cred;
90*ae771770SStanislav Sedov gss_cred_id_t release_cred;
91*ae771770SStanislav Sedov struct _gss_mechanism_cred *mc, *target_mc, *copy_mc;
92*ae771770SStanislav Sedov struct _gss_mechanism_name *mn;
93*ae771770SStanislav Sedov OM_uint32 junk;
94*ae771770SStanislav Sedov
95*ae771770SStanislav Sedov *minor_status = 0;
96*ae771770SStanislav Sedov *output_cred_handle = GSS_C_NO_CREDENTIAL;
97*ae771770SStanislav Sedov if (initiator_time_rec)
98*ae771770SStanislav Sedov *initiator_time_rec = 0;
99*ae771770SStanislav Sedov if (acceptor_time_rec)
100*ae771770SStanislav Sedov *acceptor_time_rec = 0;
101*ae771770SStanislav Sedov if (actual_mechs)
102*ae771770SStanislav Sedov *actual_mechs = GSS_C_NO_OID_SET;
103*ae771770SStanislav Sedov
104*ae771770SStanislav Sedov new_cred = malloc(sizeof(struct _gss_cred));
105*ae771770SStanislav Sedov if (!new_cred) {
106*ae771770SStanislav Sedov *minor_status = ENOMEM;
107*ae771770SStanislav Sedov return (GSS_S_FAILURE);
108*ae771770SStanislav Sedov }
109*ae771770SStanislav Sedov HEIM_SLIST_INIT(&new_cred->gc_mc);
110*ae771770SStanislav Sedov
111*ae771770SStanislav Sedov /*
112*ae771770SStanislav Sedov * We go through all the mc attached to the input_cred_handle
113*ae771770SStanislav Sedov * and check the mechanism. If it matches, we call
114*ae771770SStanislav Sedov * gss_add_cred for that mechanism, otherwise we copy the mc
115*ae771770SStanislav Sedov * to new_cred.
116*ae771770SStanislav Sedov */
117*ae771770SStanislav Sedov target_mc = 0;
118*ae771770SStanislav Sedov if (cred) {
119*ae771770SStanislav Sedov HEIM_SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
120*ae771770SStanislav Sedov if (gss_oid_equal(mc->gmc_mech_oid, desired_mech)) {
121*ae771770SStanislav Sedov target_mc = mc;
122*ae771770SStanislav Sedov }
123*ae771770SStanislav Sedov copy_mc = _gss_copy_cred(mc);
124*ae771770SStanislav Sedov if (!copy_mc) {
125*ae771770SStanislav Sedov release_cred = (gss_cred_id_t)new_cred;
126*ae771770SStanislav Sedov gss_release_cred(&junk, &release_cred);
127*ae771770SStanislav Sedov *minor_status = ENOMEM;
128*ae771770SStanislav Sedov return (GSS_S_FAILURE);
129*ae771770SStanislav Sedov }
130*ae771770SStanislav Sedov HEIM_SLIST_INSERT_HEAD(&new_cred->gc_mc, copy_mc, gmc_link);
131*ae771770SStanislav Sedov }
132*ae771770SStanislav Sedov }
133*ae771770SStanislav Sedov
134*ae771770SStanislav Sedov /*
135*ae771770SStanislav Sedov * Figure out a suitable mn, if any.
136*ae771770SStanislav Sedov */
137*ae771770SStanislav Sedov if (desired_name) {
138*ae771770SStanislav Sedov major_status = _gss_find_mn(minor_status,
139*ae771770SStanislav Sedov (struct _gss_name *) desired_name,
140*ae771770SStanislav Sedov desired_mech,
141*ae771770SStanislav Sedov &mn);
142*ae771770SStanislav Sedov if (major_status != GSS_S_COMPLETE) {
143*ae771770SStanislav Sedov free(new_cred);
144*ae771770SStanislav Sedov return major_status;
145*ae771770SStanislav Sedov }
146*ae771770SStanislav Sedov } else {
147*ae771770SStanislav Sedov mn = 0;
148*ae771770SStanislav Sedov }
149*ae771770SStanislav Sedov
150*ae771770SStanislav Sedov m = __gss_get_mechanism(desired_mech);
151*ae771770SStanislav Sedov
152*ae771770SStanislav Sedov mc = malloc(sizeof(struct _gss_mechanism_cred));
153*ae771770SStanislav Sedov if (!mc) {
154*ae771770SStanislav Sedov release_cred = (gss_cred_id_t)new_cred;
155*ae771770SStanislav Sedov gss_release_cred(&junk, &release_cred);
156*ae771770SStanislav Sedov *minor_status = ENOMEM;
157*ae771770SStanislav Sedov return (GSS_S_FAILURE);
158*ae771770SStanislav Sedov }
159*ae771770SStanislav Sedov mc->gmc_mech = m;
160*ae771770SStanislav Sedov mc->gmc_mech_oid = &m->gm_mech_oid;
161*ae771770SStanislav Sedov
162*ae771770SStanislav Sedov major_status = m->gm_add_cred(minor_status,
163*ae771770SStanislav Sedov target_mc ? target_mc->gmc_cred : GSS_C_NO_CREDENTIAL,
164*ae771770SStanislav Sedov desired_name ? mn->gmn_name : GSS_C_NO_NAME,
165*ae771770SStanislav Sedov desired_mech,
166*ae771770SStanislav Sedov cred_usage,
167*ae771770SStanislav Sedov initiator_time_req,
168*ae771770SStanislav Sedov acceptor_time_req,
169*ae771770SStanislav Sedov &mc->gmc_cred,
170*ae771770SStanislav Sedov actual_mechs,
171*ae771770SStanislav Sedov initiator_time_rec,
172*ae771770SStanislav Sedov acceptor_time_rec);
173*ae771770SStanislav Sedov
174*ae771770SStanislav Sedov if (major_status) {
175*ae771770SStanislav Sedov _gss_mg_error(m, major_status, *minor_status);
176*ae771770SStanislav Sedov release_cred = (gss_cred_id_t)new_cred;
177*ae771770SStanislav Sedov gss_release_cred(&junk, &release_cred);
178*ae771770SStanislav Sedov free(mc);
179*ae771770SStanislav Sedov return (major_status);
180*ae771770SStanislav Sedov }
181*ae771770SStanislav Sedov HEIM_SLIST_INSERT_HEAD(&new_cred->gc_mc, mc, gmc_link);
182*ae771770SStanislav Sedov *output_cred_handle = (gss_cred_id_t) new_cred;
183*ae771770SStanislav Sedov
184*ae771770SStanislav Sedov return (GSS_S_COMPLETE);
185*ae771770SStanislav Sedov }
186*ae771770SStanislav Sedov
187