krb5: consolidate cc_ops enumeration

Consolidate the enumeration of the cc_ops table by using cc_get_prefix_ops() (a
variant of krb5_cc_get_prefix_ops that also returns the residual).
This commit is contained in:
Luke Howard
2020-08-29 16:45:34 +10:00
parent cbcc50cd00
commit 351145309d

View File

@@ -100,6 +100,11 @@ main (int argc, char **argv)
* @endcode
*/
static const krb5_cc_ops *
cc_get_prefix_ops(krb5_context context,
const char *prefix,
const char **residual);
/**
* Add a new ccache type with operations `ops', overwriting any
* existing one if `override'.
@@ -235,21 +240,16 @@ krb5_cc_resolve(krb5_context context,
const char *name,
krb5_ccache *id)
{
int i;
const krb5_cc_ops *ops;
const char *residual = NULL;
*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);
ops = cc_get_prefix_ops(context, name, &residual);
if (ops == NULL)
ops = &krb5_fcc_ops; /* residual will point to name */
if(strncmp(context->cc_ops[i]->prefix, name, prefix_len) == 0
&& name[prefix_len] == ':') {
return allocate_ccache (context, context->cc_ops[i],
name + prefix_len + 1, NULL,
id);
}
}
return allocate_ccache(context, &krb5_fcc_ops, name, NULL, id);
return allocate_ccache(context, ops, residual, NULL, id);
}
#ifdef _WIN32
@@ -299,25 +299,17 @@ get_default_cc_type(krb5_context context, int simple)
const char *def_cccol =
krb5_config_get_string(context, NULL, "libdefaults",
"default_cc_collection", NULL);
size_t i;
const krb5_cc_ops *ops;
if (!simple && (def_ccname = krb5_cc_default_name(context))) {
for (i = 0; i < context->num_cc_ops && context->cc_ops[i]->prefix; i++) {
size_t prefix_len = strlen(context->cc_ops[i]->prefix);
if (!strncmp(context->cc_ops[i]->prefix, def_ccname, prefix_len) &&
def_ccname[prefix_len] == ':')
return context->cc_ops[i]->prefix;
}
ops = cc_get_prefix_ops(context, def_ccname, NULL);
if (ops)
return ops->prefix;
}
if (!def_cctype && def_cccol) {
for (i = 0; i < context->num_cc_ops && context->cc_ops[i]->prefix; i++) {
size_t prefix_len = strlen(context->cc_ops[i]->prefix);
if (!strncmp(context->cc_ops[i]->prefix, def_cccol, prefix_len) &&
def_cccol[prefix_len] == ':')
return context->cc_ops[i]->prefix;
}
ops = cc_get_prefix_ops(context, def_cccol, NULL);
if (ops)
return ops->prefix;
}
#ifdef _WIN32
if (def_cctype == NULL)
@@ -352,49 +344,24 @@ krb5_cc_resolve_sub(krb5_context context,
const char *subsidiary,
krb5_ccache *id)
{
size_t i;
const krb5_cc_ops *ops = NULL;
*id = NULL;
if (!cctype && collection) {
/* Get the cctype from the collection, maybe */
for (i = 0; i < context->num_cc_ops && context->cc_ops[i]->prefix; i++) {
size_t plen = strlen(context->cc_ops[i]->prefix);
/* Get the cctype from the collection, maybe */
if (cctype == NULL && collection)
ops = cc_get_prefix_ops(context, collection, &collection);
if ((strncmp(context->cc_ops[i]->prefix, collection, plen) ||
collection[plen] != ':'))
continue;
cctype = context->cc_ops[i]->prefix;
collection += plen + 1;
break;
}
if (ops == NULL)
ops = cc_get_prefix_ops(context, get_default_cc_type(context, 0), NULL);
if (ops == NULL) {
krb5_set_error_message(context, KRB5_CC_UNKNOWN_TYPE,
N_("unknown ccache type %s", ""), cctype);
return KRB5_CC_UNKNOWN_TYPE;
}
if (!cctype)
cctype = get_default_cc_type(context, 0);
/* If either `cctype' is not NULL or `collection' starts with TYPE: */
if (cctype || collection) {
for (i = 0; i < context->num_cc_ops && context->cc_ops[i]->prefix; i++) {
size_t plen = strlen(context->cc_ops[i]->prefix);
if (cctype && strcmp(context->cc_ops[i]->prefix, cctype))
continue;
if (!cctype &&
(strncmp(context->cc_ops[i]->prefix, collection, plen) ||
collection[plen] != ':'))
continue;
return allocate_ccache(context, context->cc_ops[i],
cctype ? collection : collection + plen + 1,
subsidiary, id);
}
}
krb5_set_error_message(context, KRB5_CC_UNKNOWN_TYPE,
N_("unknown ccache type %s", ""),
cctype ? cctype : collection);
return KRB5_CC_UNKNOWN_TYPE;
return allocate_ccache(context, ops, collection, subsidiary, id);
}
@@ -1402,9 +1369,35 @@ krb5_cc_clear_mcred(krb5_creds *mcred)
KRB5_LIB_FUNCTION const krb5_cc_ops * KRB5_LIB_CALL
krb5_cc_get_prefix_ops(krb5_context context, const char *prefix)
{
char *p, *p1;
return cc_get_prefix_ops(context, prefix, NULL);
}
/**
* 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. If prefix the argument is NULL, the default ccache
* implementation is returned.
*
* If residual is non-NULL, it is set to the residual component of
* prefix (if present) or the prefix itself.
*
* @return Returns NULL if ops not found.
*
* @ingroup krb5_ccache
*/
static const krb5_cc_ops *
cc_get_prefix_ops(krb5_context context,
const char *prefix,
const char **residual)
{
int i;
if (residual)
*residual = prefix;
if (prefix == NULL)
return KRB5_DEFAULT_CCTYPE;
@@ -1418,22 +1411,22 @@ krb5_cc_get_prefix_ops(krb5_context context, const char *prefix)
return &krb5_fcc_ops;
#endif
p = strdup(prefix);
if (p == NULL) {
krb5_enomem(context);
return NULL;
}
p1 = strchr(p, ':');
if (p1)
*p1 = '\0';
for(i = 0; i < context->num_cc_ops && context->cc_ops[i]->prefix; i++) {
if(strcmp(context->cc_ops[i]->prefix, p) == 0) {
free(p);
size_t prefix_len = strlen(context->cc_ops[i]->prefix);
if (strncmp(context->cc_ops[i]->prefix, prefix, prefix_len) == 0 &&
(prefix[prefix_len] == ':' || prefix[prefix_len] == '\0')) {
if (residual) {
if (prefix[prefix_len] == ':' && prefix[prefix_len + 1] != '\0')
*residual = &prefix[prefix_len + 1];
else
*residual = NULL;
}
return context->cc_ops[i];
}
}
free(p);
return NULL;
}