1 /* $NetBSD: add_cred.c,v 1.1.1.2 2014/04/24 12:45:29 pettai Exp $ */
4 * Copyright (c) 2003 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 #include "gsskrb5_locl.h"
38 OM_uint32 GSSAPI_CALLCONV
_gsskrb5_add_cred (
39 OM_uint32
*minor_status
,
40 const gss_cred_id_t input_cred_handle
,
41 const gss_name_t desired_name
,
42 const gss_OID desired_mech
,
43 gss_cred_usage_t cred_usage
,
44 OM_uint32 initiator_time_req
,
45 OM_uint32 acceptor_time_req
,
46 gss_cred_id_t
*output_cred_handle
,
47 gss_OID_set
*actual_mechs
,
48 OM_uint32
*initiator_time_rec
,
49 OM_uint32
*acceptor_time_rec
)
52 OM_uint32 ret
, lifetime
;
53 gsskrb5_cred cred
, handle
;
54 krb5_const_principal dname
;
57 cred
= (gsskrb5_cred
)input_cred_handle
;
58 dname
= (krb5_const_principal
)desired_name
;
60 GSSAPI_KRB5_INIT (&context
);
62 if (gss_oid_equal(desired_mech
, GSS_KRB5_MECHANISM
) == 0) {
64 return GSS_S_BAD_MECH
;
67 if (cred
== NULL
&& output_cred_handle
== NULL
) {
72 if (cred
== NULL
) { /* XXX standard conformance failure */
77 /* check if requested output usage is compatible with output usage */
78 if (output_cred_handle
!= NULL
) {
79 HEIMDAL_MUTEX_lock(&cred
->cred_id_mutex
);
80 if (cred
->usage
!= cred_usage
&& cred
->usage
!= GSS_C_BOTH
) {
81 HEIMDAL_MUTEX_unlock(&cred
->cred_id_mutex
);
82 *minor_status
= GSS_KRB5_S_G_BAD_USAGE
;
83 return(GSS_S_FAILURE
);
87 /* check that we have the same name */
89 krb5_principal_compare(context
, dname
,
90 cred
->principal
) != FALSE
) {
91 if (output_cred_handle
)
92 HEIMDAL_MUTEX_unlock(&cred
->cred_id_mutex
);
94 return GSS_S_BAD_NAME
;
98 if (output_cred_handle
) {
101 handle
= calloc(1, sizeof(*handle
));
102 if (handle
== NULL
) {
103 HEIMDAL_MUTEX_unlock(&cred
->cred_id_mutex
);
104 *minor_status
= ENOMEM
;
105 return (GSS_S_FAILURE
);
108 handle
->usage
= cred_usage
;
109 handle
->lifetime
= cred
->lifetime
;
110 handle
->principal
= NULL
;
111 handle
->keytab
= NULL
;
112 handle
->ccache
= NULL
;
113 handle
->mechanisms
= NULL
;
114 HEIMDAL_MUTEX_init(&handle
->cred_id_mutex
);
118 kret
= krb5_copy_principal(context
, cred
->principal
,
121 HEIMDAL_MUTEX_unlock(&cred
->cred_id_mutex
);
123 *minor_status
= kret
;
124 return GSS_S_FAILURE
;
132 kret
= krb5_kt_get_full_name(context
, cred
->keytab
, &name
);
134 *minor_status
= kret
;
138 kret
= krb5_kt_resolve(context
, name
,
142 *minor_status
= kret
;
148 const char *type
, *name
;
149 char *type_name
= NULL
;
153 type
= krb5_cc_get_type(context
, cred
->ccache
);
155 *minor_status
= ENOMEM
;
159 if (strcmp(type
, "MEMORY") == 0) {
160 ret
= krb5_cc_new_unique(context
, type
,
161 NULL
, &handle
->ccache
);
167 ret
= krb5_cc_copy_cache(context
, cred
->ccache
,
175 name
= krb5_cc_get_name(context
, cred
->ccache
);
177 *minor_status
= ENOMEM
;
181 kret
= asprintf(&type_name
, "%s:%s", type
, name
);
182 if (kret
< 0 || type_name
== NULL
) {
183 *minor_status
= ENOMEM
;
187 kret
= krb5_cc_resolve(context
, type_name
,
191 *minor_status
= kret
;
196 ret
= gss_create_empty_oid_set(minor_status
, &handle
->mechanisms
);
200 ret
= gss_add_oid_set_member(minor_status
, GSS_KRB5_MECHANISM
,
201 &handle
->mechanisms
);
206 HEIMDAL_MUTEX_unlock(&cred
->cred_id_mutex
);
208 ret
= _gsskrb5_inquire_cred(minor_status
, (gss_cred_id_t
)cred
,
209 NULL
, &lifetime
, NULL
, actual_mechs
);
213 if (initiator_time_rec
)
214 *initiator_time_rec
= lifetime
;
215 if (acceptor_time_rec
)
216 *acceptor_time_rec
= lifetime
;
218 if (output_cred_handle
) {
219 *output_cred_handle
= (gss_cred_id_t
)handle
;
228 if (handle
->principal
)
229 krb5_free_principal(context
, handle
->principal
);
231 krb5_kt_close(context
, handle
->keytab
);
233 krb5_cc_destroy(context
, handle
->ccache
);
234 if (handle
->mechanisms
)
235 gss_release_oid_set(NULL
, &handle
->mechanisms
);
238 if (output_cred_handle
)
239 HEIMDAL_MUTEX_unlock(&cred
->cred_id_mutex
);