2 * Copyright (c) 2003 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * 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.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #include "gssapi_locl.h"
38 OM_uint32
gss_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
)
51 OM_uint32 ret
, lifetime
;
52 gss_cred_id_t cred
, handle
;
55 cred
= input_cred_handle
;
57 if (gss_oid_equal(desired_mech
, GSS_KRB5_MECHANISM
) == 0) {
59 return GSS_S_BAD_MECH
;
62 if (cred
== GSS_C_NO_CREDENTIAL
&& output_cred_handle
== NULL
) {
67 /* check if requested output usage is compatible with output usage */
68 if (output_cred_handle
!= NULL
) {
69 HEIMDAL_MUTEX_lock(&cred
->cred_id_mutex
);
70 if (cred
->usage
!= cred_usage
&& cred
->usage
!= GSS_C_BOTH
) {
71 HEIMDAL_MUTEX_unlock(&cred
->cred_id_mutex
);
72 *minor_status
= GSS_KRB5_S_G_BAD_USAGE
;
73 return(GSS_S_FAILURE
);
77 /* check that we have the same name */
78 if (desired_name
!= GSS_C_NO_NAME
&&
79 krb5_principal_compare(gssapi_krb5_context
, desired_name
,
80 cred
->principal
) != FALSE
) {
81 if (output_cred_handle
)
82 HEIMDAL_MUTEX_unlock(&cred
->cred_id_mutex
);
84 return GSS_S_BAD_NAME
;
88 if (output_cred_handle
) {
90 handle
= (gss_cred_id_t
)malloc(sizeof(*handle
));
91 if (handle
== GSS_C_NO_CREDENTIAL
) {
92 HEIMDAL_MUTEX_unlock(&cred
->cred_id_mutex
);
93 *minor_status
= ENOMEM
;
94 return (GSS_S_FAILURE
);
97 memset(handle
, 0, sizeof (*handle
));
99 handle
->usage
= cred_usage
;
100 handle
->lifetime
= cred
->lifetime
;
101 handle
->principal
= NULL
;
102 handle
->keytab
= NULL
;
103 handle
->ccache
= NULL
;
104 handle
->mechanisms
= NULL
;
105 HEIMDAL_MUTEX_init(&handle
->cred_id_mutex
);
109 ret
= gss_duplicate_name(minor_status
, cred
->principal
,
112 HEIMDAL_MUTEX_unlock(&cred
->cred_id_mutex
);
114 *minor_status
= ENOMEM
;
115 return GSS_S_FAILURE
;
119 krb5_error_code kret
;
120 char name
[KRB5_KT_PREFIX_MAX_LEN
+ MAXPATHLEN
];
125 kret
= krb5_kt_get_type(gssapi_krb5_context
, cred
->keytab
,
126 name
, KRB5_KT_PREFIX_MAX_LEN
);
128 *minor_status
= kret
;
134 kret
= krb5_kt_get_name(gssapi_krb5_context
, cred
->keytab
,
138 *minor_status
= kret
;
142 kret
= krb5_kt_resolve(gssapi_krb5_context
, name
,
145 *minor_status
= kret
;
151 krb5_error_code kret
;
152 const char *type
, *name
;
157 type
= krb5_cc_get_type(gssapi_krb5_context
, cred
->ccache
);
159 *minor_status
= ENOMEM
;
163 if (strcmp(type
, "MEMORY") == 0) {
164 ret
= krb5_cc_gen_new(gssapi_krb5_context
, &krb5_mcc_ops
,
171 ret
= krb5_cc_copy_cache(gssapi_krb5_context
, cred
->ccache
,
179 name
= krb5_cc_get_name(gssapi_krb5_context
, cred
->ccache
);
181 *minor_status
= ENOMEM
;
185 asprintf(&type_name
, "%s:%s", type
, name
);
186 if (type_name
== NULL
) {
187 *minor_status
= ENOMEM
;
191 kret
= krb5_cc_resolve(gssapi_krb5_context
, type_name
,
195 *minor_status
= kret
;
200 ret
= gss_create_empty_oid_set(minor_status
, &handle
->mechanisms
);
204 ret
= gss_add_oid_set_member(minor_status
, GSS_KRB5_MECHANISM
,
205 &handle
->mechanisms
);
210 ret
= gss_inquire_cred(minor_status
, cred
, NULL
, &lifetime
,
215 if (initiator_time_rec
)
216 *initiator_time_rec
= lifetime
;
217 if (acceptor_time_rec
)
218 *acceptor_time_rec
= lifetime
;
220 if (output_cred_handle
) {
221 *output_cred_handle
= handle
;
222 HEIMDAL_MUTEX_unlock(&cred
->cred_id_mutex
);
231 if (handle
->principal
)
232 gss_release_name(NULL
, &handle
->principal
);
234 krb5_kt_close(gssapi_krb5_context
, handle
->keytab
);
236 krb5_cc_destroy(gssapi_krb5_context
, handle
->ccache
);
237 if (handle
->mechanisms
)
238 gss_release_oid_set(NULL
, &handle
->mechanisms
);
241 if (output_cred_handle
)
242 HEIMDAL_MUTEX_unlock(&cred
->cred_id_mutex
);