summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib/krb5/cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/heimdal/lib/krb5/cache.c')
-rw-r--r--source4/heimdal/lib/krb5/cache.c330
1 files changed, 253 insertions, 77 deletions
diff --git a/source4/heimdal/lib/krb5/cache.c b/source4/heimdal/lib/krb5/cache.c
index 59aae40d28..5db6d2b2cf 100644
--- a/source4/heimdal/lib/krb5/cache.c
+++ b/source4/heimdal/lib/krb5/cache.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -33,12 +33,20 @@
#include "krb5_locl.h"
-RCSID("$Id: cache.c 21498 2007-07-11 09:41:43Z lha $");
+RCSID("$Id: cache.c 22127 2007-12-04 00:54:37Z lha $");
-/*
+/**
* Add a new ccache type with operations `ops', overwriting any
* existing one if `override'.
- * Return an error code or 0.
+ *
+ * @param context a Keberos context
+ * @param ops type of plugin symbol
+ * @param override flag to select if the registration is to overide
+ * an existing ops with the same name.
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_ccache
*/
krb5_error_code KRB5_LIB_FUNCTION
@@ -101,8 +109,7 @@ _krb5_cc_allocate(krb5_context context,
/*
* Allocate memory for a new ccache in `id' with operations `ops'
- * and name `residual'.
- * Return 0 or an error code.
+ * and name `residual'. Return 0 or an error code.
*/
static krb5_error_code
@@ -122,12 +129,21 @@ allocate_ccache (krb5_context context,
return ret;
}
-/*
+/**
* Find and allocate a ccache in `id' from the specification in `residual'.
* If the ccache name doesn't contain any colon, interpret it as a file name.
- * Return 0 or an error code.
+ *
+ * @param context a Keberos context.
+ * @param name string name of a credential cache.
+ * @param id return pointer to a found credential cache.
+ *
+ * @return Return 0 or an error code. In case of an error, id is set
+ * to NULL.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_resolve(krb5_context context,
const char *name,
@@ -135,6 +151,8 @@ krb5_cc_resolve(krb5_context context,
{
int i;
+ *id = NULL;
+
for(i = 0; i < context->num_cc_ops && context->cc_ops[i].prefix; i++) {
size_t prefix_len = strlen(context->cc_ops[i].prefix);
@@ -153,57 +171,64 @@ krb5_cc_resolve(krb5_context context,
}
}
-/*
+/**
* Generate a new ccache of type `ops' in `id'.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_gen_new(krb5_context context,
const krb5_cc_ops *ops,
krb5_ccache *id)
{
- krb5_error_code ret;
-
- ret = _krb5_cc_allocate(context, ops, id);
- if (ret)
- return ret;
- return (*id)->ops->gen_new(context, id);
+ return krb5_cc_new_unique(context, ops->prefix, NULL, id);
}
-/*
+/**
* Generates a new unique ccache of `type` in `id'. If `type' is NULL,
* the library chooses the default credential cache type. The supplied
* `hint' (that can be NULL) is a string that the credential cache
* type can use to base the name of the credential on, this is to make
- * its easier for the user to differentiate the credentials.
+ * it easier for the user to differentiate the credentials.
+ *
+ * @return Returns 0 or an error code.
*
- * Returns 0 or an error code.
+ * @ingroup krb5_ccache
*/
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_new_unique(krb5_context context, const char *type,
const char *hint, krb5_ccache *id)
{
- const krb5_cc_ops *ops;
-
- if (type == NULL)
- type = KRB5_DEFAULT_CCNAME;
+ const krb5_cc_ops *ops = KRB5_DEFAULT_CCTYPE;
+ krb5_error_code ret;
- ops = krb5_cc_get_prefix_ops(context, type);
- if (ops == NULL) {
- krb5_set_error_string(context, "Credential cache type %s is unknown",
- type);
- return KRB5_CC_UNKNOWN_TYPE;
+ if (type) {
+ ops = krb5_cc_get_prefix_ops(context, type);
+ if (ops == NULL) {
+ krb5_set_error_string(context,
+ "Credential cache type %s is unknown", type);
+ return KRB5_CC_UNKNOWN_TYPE;
+ }
}
- return krb5_cc_gen_new(context, ops, id);
+ ret = _krb5_cc_allocate(context, ops, id);
+ if (ret)
+ return ret;
+ return (*id)->ops->gen_new(context, id);
}
-/*
+/**
* Return the name of the ccache `id'
+ *
+ * @ingroup krb5_ccache
*/
+
const char* KRB5_LIB_FUNCTION
krb5_cc_get_name(krb5_context context,
krb5_ccache id)
@@ -211,10 +236,13 @@ krb5_cc_get_name(krb5_context context,
return id->ops->get_name(context, id);
}
-/*
+/**
* Return the type of the ccache `id'.
+ *
+ * @ingroup krb5_ccache
*/
+
const char* KRB5_LIB_FUNCTION
krb5_cc_get_type(krb5_context context,
krb5_ccache id)
@@ -222,12 +250,15 @@ krb5_cc_get_type(krb5_context context,
return id->ops->prefix;
}
-/*
+/**
* Return the complete resolvable name the ccache `id' in `str´.
* `str` should be freed with free(3).
* Returns 0 or an error (and then *str is set to NULL).
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_get_full_name(krb5_context context,
krb5_ccache id,
@@ -257,10 +288,13 @@ krb5_cc_get_full_name(krb5_context context,
return 0;
}
-/*
+/**
* Return krb5_cc_ops of a the ccache `id'.
+ *
+ * @ingroup krb5_ccache
*/
+
const krb5_cc_ops *
krb5_cc_get_ops(krb5_context context, krb5_ccache id)
{
@@ -348,6 +382,10 @@ environment_changed(krb5_context context)
{
const char *e;
+ /* if the cc name was set, don't change it */
+ if (context->default_cc_name_set)
+ return 0;
+
if(issuid())
return 0;
@@ -367,10 +405,13 @@ environment_changed(krb5_context context)
return 0;
}
-/*
+/**
* Set the default cc name for `context' to `name'.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_set_default_name(krb5_context context, const char *name)
{
@@ -392,14 +433,23 @@ krb5_cc_set_default_name(krb5_context context, const char *name)
if (e == NULL) {
e = krb5_config_get_string(context, NULL, "libdefaults",
"default_cc_name", NULL);
- if (e == NULL)
- e = KRB5_DEFAULT_CCNAME;
- ret = _krb5_expand_default_cc_name(context, e, &p);
- if (ret)
- return ret;
+ if (e) {
+ ret = _krb5_expand_default_cc_name(context, e, &p);
+ if (ret)
+ return ret;
+ }
+ if (e == NULL) {
+ const krb5_cc_ops *ops = KRB5_DEFAULT_CCTYPE;
+ ret = (*ops->default_name)(context, &p);
+ if (ret)
+ return ret;
+ }
}
- } else
+ context->default_cc_name_set = 0;
+ } else {
p = strdup(name);
+ context->default_cc_name_set = 1;
+ }
if (p == NULL) {
krb5_set_error_string(context, "malloc - out of memory");
@@ -414,11 +464,16 @@ krb5_cc_set_default_name(krb5_context context, const char *name)
return ret;
}
-/*
+/**
* Return a pointer to a context static string containing the default
* ccache name.
+ *
+ * @return String to the default credential cache name.
+ *
+ * @ingroup krb5_ccache
*/
+
const char* KRB5_LIB_FUNCTION
krb5_cc_default_name(krb5_context context)
{
@@ -428,11 +483,15 @@ krb5_cc_default_name(krb5_context context)
return context->default_cc_name;
}
-/*
+/**
* Open the default ccache in `id'.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_default(krb5_context context,
krb5_ccache *id)
@@ -446,11 +505,15 @@ krb5_cc_default(krb5_context context,
return krb5_cc_resolve(context, p, id);
}
-/*
+/**
* Create a new ccache in `id' for `primary_principal'.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_initialize(krb5_context context,
krb5_ccache id,
@@ -460,11 +523,15 @@ krb5_cc_initialize(krb5_context context,
}
-/*
+/**
* Remove the ccache `id'.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_destroy(krb5_context context,
krb5_ccache id)
@@ -476,11 +543,15 @@ krb5_cc_destroy(krb5_context context,
return ret;
}
-/*
+/**
* Stop using the ccache `id' and free the related resources.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_close(krb5_context context,
krb5_ccache id)
@@ -491,11 +562,15 @@ krb5_cc_close(krb5_context context,
return ret;
}
-/*
+/**
* Store `creds' in the ccache `id'.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_store_cred(krb5_context context,
krb5_ccache id,
@@ -504,13 +579,17 @@ krb5_cc_store_cred(krb5_context context,
return (*id->ops->store)(context, id, creds);
}
-/*
+/**
* Retrieve the credential identified by `mcreds' (and `whichfields')
* from `id' in `creds'. 'creds' must be free by the caller using
* krb5_free_cred_contents.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_retrieve_cred(krb5_context context,
krb5_ccache id,
@@ -526,7 +605,9 @@ krb5_cc_retrieve_cred(krb5_context context,
mcreds, creds);
}
- krb5_cc_start_seq_get(context, id, &cursor);
+ ret = krb5_cc_start_seq_get(context, id, &cursor);
+ if (ret)
+ return ret;
while((ret = krb5_cc_next_cred(context, id, &cursor, creds)) == 0){
if(krb5_compare_creds(context, whichfields, mcreds, creds)){
ret = 0;
@@ -538,11 +619,15 @@ krb5_cc_retrieve_cred(krb5_context context,
return ret;
}
-/*
+/**
* Return the principal of `id' in `principal'.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_get_principal(krb5_context context,
krb5_ccache id,
@@ -551,12 +636,16 @@ krb5_cc_get_principal(krb5_context context,
return (*id->ops->get_princ)(context, id, principal);
}
-/*
+/**
* Start iterating over `id', `cursor' is initialized to the
* beginning.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_start_seq_get (krb5_context context,
const krb5_ccache id,
@@ -565,12 +654,16 @@ krb5_cc_start_seq_get (krb5_context context,
return (*id->ops->get_first)(context, id, cursor);
}
-/*
+/**
* Retrieve the next cred pointed to by (`id', `cursor') in `creds'
* and advance `cursor'.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_next_cred (krb5_context context,
const krb5_ccache id,
@@ -580,7 +673,12 @@ krb5_cc_next_cred (krb5_context context,
return (*id->ops->get_next)(context, id, cursor, creds);
}
-/* like krb5_cc_next_cred, but allow for selective retrieval */
+/**
+ * Like krb5_cc_next_cred, but allow for selective retrieval
+ *
+ * @ingroup krb5_ccache
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_next_cred_match(krb5_context context,
@@ -601,10 +699,13 @@ krb5_cc_next_cred_match(krb5_context context,
}
}
-/*
+/**
* Destroy the cursor `cursor'.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_end_seq_get (krb5_context context,
const krb5_ccache id,
@@ -613,10 +714,13 @@ krb5_cc_end_seq_get (krb5_context context,
return (*id->ops->end_get)(context, id, cursor);
}
-/*
+/**
* Remove the credential identified by `cred', `which' from `id'.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_remove_cred(krb5_context context,
krb5_ccache id,
@@ -632,10 +736,13 @@ krb5_cc_remove_cred(krb5_context context,
return (*id->ops->remove_cred)(context, id, which, cred);
}
-/*
+/**
* Set the flags of `id' to `flags'.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_set_flags(krb5_context context,
krb5_ccache id,
@@ -644,10 +751,13 @@ krb5_cc_set_flags(krb5_context context,
return (*id->ops->set_flags)(context, id, flags);
}
-/*
+/**
* Copy the contents of `from' to `to'.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_copy_cache_match(krb5_context context,
const krb5_ccache from,
@@ -689,6 +799,13 @@ krb5_cc_copy_cache_match(krb5_context context,
return ret;
}
+/**
+ * Just like krb5_cc_copy_cache_match, but copy everything.
+ *
+ * @ingroup krb5_ccache
+ */
+
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_copy_cache(krb5_context context,
const krb5_ccache from,
@@ -697,10 +814,13 @@ krb5_cc_copy_cache(krb5_context context,
return krb5_cc_copy_cache_match(context, from, to, 0, NULL, NULL);
}
-/*
+/**
* Return the version of `id'.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_get_version(krb5_context context,
const krb5_ccache id)
@@ -711,23 +831,30 @@ krb5_cc_get_version(krb5_context context,
return 0;
}
-/*
+/**
* Clear `mcreds' so it can be used with krb5_cc_retrieve_cred
+ *
+ * @ingroup krb5_ccache
*/
+
void KRB5_LIB_FUNCTION
krb5_cc_clear_mcred(krb5_creds *mcred)
{
memset(mcred, 0, sizeof(*mcred));
}
-/*
+/**
* Get the cc ops that is registered in `context' to handle the
* `prefix'. `prefix' can be a complete credential cache name or a
* prefix, the function will only use part up to the first colon (:)
- * if there is one. Returns NULL if ops not found.
+ * if there is one.
+ * Returns NULL if ops not found.
+ *
+ * @ingroup krb5_ccache
*/
+
const krb5_cc_ops *
krb5_cc_get_prefix_ops(krb5_context context, const char *prefix)
{
@@ -761,12 +888,16 @@ struct krb5_cc_cache_cursor_data {
krb5_cc_cursor cursor;
};
-/*
+/**
* Start iterating over all caches of `type'. If `type' is NULL, the
* default type is * used. `cursor' is initialized to the beginning.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_cache_get_first (krb5_context context,
const char *type,
@@ -807,12 +938,16 @@ krb5_cc_cache_get_first (krb5_context context,
return ret;
}
-/*
+/**
* Retrieve the next cache pointed to by (`cursor') in `id'
* and advance `cursor'.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_cache_next (krb5_context context,
krb5_cc_cache_cursor cursor,
@@ -821,10 +956,15 @@ krb5_cc_cache_next (krb5_context context,
return cursor->ops->get_cache_next(context, cursor->cursor, id);
}
-/*
+/**
* Destroy the cursor `cursor'.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_cache_end_seq_get (krb5_context context,
krb5_cc_cache_cursor cursor)
@@ -836,14 +976,18 @@ krb5_cc_cache_end_seq_get (krb5_context context,
return ret;
}
-/*
+/**
* Search for a matching credential cache of type `type' that have the
* `principal' as the default principal. If NULL is used for `type',
* the default type is used. On success, `id' needs to be freed with
- * krb5_cc_close or krb5_cc_destroy. On failure, error code is
- * returned and `id' is set to NULL.
+ * krb5_cc_close or krb5_cc_destroy.
+ *
+ * @return On failure, error code is returned and `id' is set to NULL.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_cache_match (krb5_context context,
krb5_principal client,
@@ -895,3 +1039,35 @@ krb5_cc_cache_match (krb5_context context,
return 0;
}
+/**
+ * Move the content from one credential cache to another. The
+ * operation is an atomic switch.
+ *
+ * @param context a Keberos context
+ * @param from the credential cache to move the content from
+ * @param to the credential cache to move the content to
+
+ * @return On sucess, from is freed. On failure, error code is
+ * returned and from and to are both still allocated.
+ *
+ * @ingroup krb5_ccache
+ */
+
+krb5_error_code
+krb5_cc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
+{
+ krb5_error_code ret;
+
+ if (strcmp(from->ops->prefix, to->ops->prefix) != 0) {
+ krb5_set_error_string(context, "Moving credentials between diffrent "
+ "types not yet supported");
+ return KRB5_CC_NOSUPP;
+ }
+
+ ret = (*to->ops->move)(context, from, to);
+ if (ret == 0) {
+ memset(from, 0, sizeof(*from));
+ free(from);
+ }
+ return ret;
+}