2 * lib/krb5/ccache/ccbase.c
4 * Copyright 1990,2004 by the Massachusetts Institute of Technology.
7 * Export of this software from the United States of America may
8 * require a specific license from the United States Government.
9 * It is the responsibility of any person or organization contemplating
10 * export to obtain such a license before exporting.
12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13 * distribute this software and its documentation for any purpose and
14 * without fee is hereby granted, provided that the above copyright
15 * notice appear in all copies and that both that copyright notice and
16 * this permission notice appear in supporting documentation, and that
17 * the name of M.I.T. not be used in advertising or publicity pertaining
18 * to distribution of the software without specific, written prior
19 * permission. Furthermore if you modify this software you must label
20 * your software as modified software and not distribute it in such a
21 * fashion that it might be confused with the original M.I.T. software.
22 * M.I.T. makes no representations about the suitability of
23 * this software for any purpose. It is provided "as is" without express
24 * or implied warranty.
27 * Registration functions for ccache.
31 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
32 * Use is subject to license terms.
37 #include "k5-thread.h"
42 struct krb5_cc_typelist
{
43 const krb5_cc_ops
*ops
;
44 struct krb5_cc_typelist
*next
;
47 struct krb5_cc_typecursor
{
48 struct krb5_cc_typelist
*tptr
;
50 /* typedef krb5_cc_typecursor in k5-int.h */
52 extern const krb5_cc_ops krb5_mcc_ops
;
53 #ifdef USE_KEYRING_CCACHE
54 extern const krb5_cc_ops krb5_krcc_ops
;
58 extern const krb5_cc_ops krb5_lcc_ops
;
59 static struct krb5_cc_typelist cc_lcc_entry
= { &krb5_lcc_ops
, NULL
};
60 static struct krb5_cc_typelist cc_mcc_entry
= { &krb5_mcc_ops
, &cc_lcc_entry
};
64 extern const krb5_cc_ops krb5_cc_stdcc_ops
;
65 static struct krb5_cc_typelist cc_stdcc_entry
= { &krb5_cc_stdcc_ops
, NULL
};
66 static struct krb5_cc_typelist cc_mcc_entry
= { &krb5_mcc_ops
, &cc_stdcc_entry
};
69 static struct krb5_cc_typelist cc_mcc_entry
= { &krb5_mcc_ops
, NULL
};
70 #endif /* USE_CCAPI_V3 */
72 #ifdef USE_KEYRING_CCACHE
73 static struct krb5_cc_typelist cc_file_entry
= { &krb5_cc_file_ops
,
75 static struct krb5_cc_typelist cc_krcc_entry
= { &krb5_krcc_ops
,
77 #endif /* USE_KEYRING_CCACHE */
80 static struct krb5_cc_typelist cc_fcc_entry
= { &krb5_cc_file_ops
,
82 #ifdef USE_KEYRING_CCACHE
83 #define INITIAL_TYPEHEAD (&cc_krcc_entry)
85 #define INITIAL_TYPEHEAD (&cc_fcc_entry)
87 static struct krb5_cc_typelist
*cc_typehead
= INITIAL_TYPEHEAD
;
88 static k5_mutex_t cc_typelist_lock
= K5_MUTEX_PARTIAL_INITIALIZER
;
90 static krb5_error_code
91 krb5int_cc_getops(krb5_context
, const char *, const krb5_cc_ops
**);
94 krb5int_cc_initialize(void)
98 err
= k5_mutex_finish_init(&krb5int_mcc_mutex
);
101 err
= k5_mutex_finish_init(&cc_typelist_lock
);
104 err
= k5_mutex_finish_init(&krb5int_cc_file_mutex
);
107 #ifdef USE_KEYRING_CCACHE
108 err
= k5_mutex_finish_init(&krb5int_krcc_mutex
);
116 krb5int_cc_finalize(void)
118 struct krb5_cc_typelist
*t
, *t_next
;
119 k5_mutex_destroy(&cc_typelist_lock
);
120 k5_mutex_destroy(&krb5int_cc_file_mutex
);
121 k5_mutex_destroy(&krb5int_mcc_mutex
);
122 #ifdef USE_KEYRING_CCACHE
123 k5_mutex_destroy(&krb5int_krcc_mutex
);
125 for (t
= cc_typehead
; t
!= INITIAL_TYPEHEAD
; t
= t_next
) {
133 * Register a new credentials cache type
134 * If override is set, replace any existing ccache with that type tag
137 krb5_error_code KRB5_CALLCONV
138 krb5_cc_register(krb5_context context
, krb5_cc_ops
*ops
, krb5_boolean override
)
140 struct krb5_cc_typelist
*t
;
143 err
= k5_mutex_lock(&cc_typelist_lock
);
146 for (t
= cc_typehead
;t
&& strcmp(t
->ops
->prefix
,ops
->prefix
);t
= t
->next
)
151 k5_mutex_unlock(&cc_typelist_lock
);
154 k5_mutex_unlock(&cc_typelist_lock
);
155 return KRB5_CC_TYPE_EXISTS
;
158 if (!(t
= (struct krb5_cc_typelist
*) malloc(sizeof(*t
)))) {
159 k5_mutex_unlock(&cc_typelist_lock
);
162 t
->next
= cc_typehead
;
165 k5_mutex_unlock(&cc_typelist_lock
);
170 * Resolve a credential cache name into a cred. cache object.
172 * The name is currently constrained to be of the form "type:residual";
174 * The "type" portion corresponds to one of the predefined credential
175 * cache types, while the "residual" portion is specific to the
176 * particular cache type.
180 krb5_error_code KRB5_CALLCONV
181 krb5_cc_resolve (krb5_context context
, const char *name
, krb5_ccache
*cache
)
187 const krb5_cc_ops
*ops
;
189 /* Solaris Kerberos */
191 return KRB5_CC_BADNAME
;
194 cp
= strchr (name
, ':');
197 return (*krb5_cc_dfl_ops
->resolve
)(context
, cache
, name
);
199 return KRB5_CC_BADNAME
;
204 if ( pfxlen
== 1 && isalpha((unsigned char) name
[0]) ) {
205 /* We found a drive letter not a prefix - use FILE */
206 pfx
= strdup("FILE");
212 resid
= name
+ pfxlen
+ 1;
214 pfx
= malloc (pfxlen
+1);
218 memcpy (pfx
, name
, pfxlen
);
222 *cache
= (krb5_ccache
) 0;
224 err
= krb5int_cc_getops(context
, pfx
, &ops
);
229 return ops
->resolve(context
, cache
, resid
);
235 * Internal function to return the ops vector for a given ccache
238 static krb5_error_code
240 krb5_context context
,
242 const krb5_cc_ops
**ops
)
245 struct krb5_cc_typelist
*tlist
;
247 err
= k5_mutex_lock(&cc_typelist_lock
);
251 for (tlist
= cc_typehead
; tlist
; tlist
= tlist
->next
) {
252 if (strcmp (tlist
->ops
->prefix
, pfx
) == 0) {
254 k5_mutex_unlock(&cc_typelist_lock
);
258 k5_mutex_unlock(&cc_typelist_lock
);
259 if (krb5_cc_dfl_ops
&& !strcmp (pfx
, krb5_cc_dfl_ops
->prefix
)) {
260 *ops
= krb5_cc_dfl_ops
;
263 return KRB5_CC_UNKNOWN_TYPE
;
269 * Generate a new unique ccache, given a ccache type and a hint
270 * string. Ignores the hint string for now.
272 krb5_error_code KRB5_CALLCONV
274 krb5_context context
,
279 const krb5_cc_ops
*ops
;
284 err
= krb5int_cc_getops(context
, type
, &ops
);
288 return ops
->gen_new(context
, id
);
294 * Note: to avoid copying the typelist at cursor creation time, among
295 * other things, we assume that the only additions ever occur to the
299 krb5int_cc_typecursor_new(krb5_context context
, krb5_cc_typecursor
*t
)
301 krb5_error_code err
= 0;
302 krb5_cc_typecursor n
= NULL
;
305 n
= malloc(sizeof(*n
));
309 err
= k5_mutex_lock(&cc_typelist_lock
);
312 n
->tptr
= cc_typehead
;
313 err
= k5_mutex_unlock(&cc_typelist_lock
);
325 krb5int_cc_typecursor_next(
326 krb5_context context
,
327 krb5_cc_typecursor t
,
328 const krb5_cc_ops
**ops
)
330 krb5_error_code err
= 0;
336 err
= k5_mutex_lock(&cc_typelist_lock
);
340 t
->tptr
= t
->tptr
->next
;
341 err
= k5_mutex_unlock(&cc_typelist_lock
);
350 krb5int_cc_typecursor_free(krb5_context context
, krb5_cc_typecursor
*t
)