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 * @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 * Add a new ccache type with operations `ops', overwriting any
* existing one if `override'. * existing one if `override'.
@@ -235,21 +240,16 @@ krb5_cc_resolve(krb5_context context,
const char *name, const char *name,
krb5_ccache *id) krb5_ccache *id)
{ {
int i; const krb5_cc_ops *ops;
const char *residual = NULL;
*id = NULL; *id = NULL;
for(i = 0; i < context->num_cc_ops && context->cc_ops[i]->prefix; i++) { ops = cc_get_prefix_ops(context, name, &residual);
size_t prefix_len = strlen(context->cc_ops[i]->prefix); if (ops == NULL)
ops = &krb5_fcc_ops; /* residual will point to name */
if(strncmp(context->cc_ops[i]->prefix, name, prefix_len) == 0 return allocate_ccache(context, ops, residual, NULL, id);
&& 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);
} }
#ifdef _WIN32 #ifdef _WIN32
@@ -299,25 +299,17 @@ get_default_cc_type(krb5_context context, int simple)
const char *def_cccol = const char *def_cccol =
krb5_config_get_string(context, NULL, "libdefaults", krb5_config_get_string(context, NULL, "libdefaults",
"default_cc_collection", NULL); "default_cc_collection", NULL);
size_t i; const krb5_cc_ops *ops;
if (!simple && (def_ccname = krb5_cc_default_name(context))) { if (!simple && (def_ccname = krb5_cc_default_name(context))) {
for (i = 0; i < context->num_cc_ops && context->cc_ops[i]->prefix; i++) { ops = cc_get_prefix_ops(context, def_ccname, NULL);
size_t prefix_len = strlen(context->cc_ops[i]->prefix); if (ops)
return ops->prefix;
if (!strncmp(context->cc_ops[i]->prefix, def_ccname, prefix_len) &&
def_ccname[prefix_len] == ':')
return context->cc_ops[i]->prefix;
}
} }
if (!def_cctype && def_cccol) { if (!def_cctype && def_cccol) {
for (i = 0; i < context->num_cc_ops && context->cc_ops[i]->prefix; i++) { ops = cc_get_prefix_ops(context, def_cccol, NULL);
size_t prefix_len = strlen(context->cc_ops[i]->prefix); if (ops)
return ops->prefix;
if (!strncmp(context->cc_ops[i]->prefix, def_cccol, prefix_len) &&
def_cccol[prefix_len] == ':')
return context->cc_ops[i]->prefix;
}
} }
#ifdef _WIN32 #ifdef _WIN32
if (def_cctype == NULL) if (def_cctype == NULL)
@@ -352,49 +344,24 @@ krb5_cc_resolve_sub(krb5_context context,
const char *subsidiary, const char *subsidiary,
krb5_ccache *id) krb5_ccache *id)
{ {
size_t i; const krb5_cc_ops *ops = NULL;
*id = NULL; *id = NULL;
if (!cctype && collection) {
/* Get the cctype from the collection, maybe */ /* Get the cctype from the collection, maybe */
for (i = 0; i < context->num_cc_ops && context->cc_ops[i]->prefix; i++) { if (cctype == NULL && collection)
size_t plen = strlen(context->cc_ops[i]->prefix); ops = cc_get_prefix_ops(context, collection, &collection);
if ((strncmp(context->cc_ops[i]->prefix, collection, plen) || if (ops == NULL)
collection[plen] != ':')) ops = cc_get_prefix_ops(context, get_default_cc_type(context, 0), NULL);
continue;
cctype = context->cc_ops[i]->prefix;
collection += plen + 1;
break;
}
}
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);
}
}
if (ops == NULL) {
krb5_set_error_message(context, KRB5_CC_UNKNOWN_TYPE, krb5_set_error_message(context, KRB5_CC_UNKNOWN_TYPE,
N_("unknown ccache type %s", ""), N_("unknown ccache type %s", ""), cctype);
cctype ? cctype : collection);
return KRB5_CC_UNKNOWN_TYPE; 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_LIB_FUNCTION const krb5_cc_ops * KRB5_LIB_CALL
krb5_cc_get_prefix_ops(krb5_context context, const char *prefix) 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; int i;
if (residual)
*residual = prefix;
if (prefix == NULL) if (prefix == NULL)
return KRB5_DEFAULT_CCTYPE; return KRB5_DEFAULT_CCTYPE;
@@ -1418,22 +1411,22 @@ krb5_cc_get_prefix_ops(krb5_context context, const char *prefix)
return &krb5_fcc_ops; return &krb5_fcc_ops;
#endif #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++) { for(i = 0; i < context->num_cc_ops && context->cc_ops[i]->prefix; i++) {
if(strcmp(context->cc_ops[i]->prefix, p) == 0) { size_t prefix_len = strlen(context->cc_ops[i]->prefix);
free(p);
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]; return context->cc_ops[i];
} }
} }
free(p);
return NULL; return NULL;
} }