Skip to content

Commit

Permalink
krb5: Improve SCC new unique (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
nicowilliams committed May 30, 2023
1 parent 2508b72 commit f05facf
Show file tree
Hide file tree
Showing 15 changed files with 408 additions and 335 deletions.
4 changes: 4 additions & 0 deletions kcm/glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,10 @@ static const krb5_cc_ops krb5_kcmss_ops = {
NULL,
kcmss_get_name_2,
kcmss_resolve_2,
NULL,
0,
'\0',
':'
};

krb5_error_code
Expand Down
8 changes: 8 additions & 0 deletions kuser/kinit.1
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,14 @@ in the KEYRING collection named
.Bl -tag -width Ds
.It Ev KRB5CCNAME
Specifies the default credentials cache.
.It Ev KRB5CCTYPE
Specifies the default credentials cache type.
This is only used when a specific credentials cache is not named with
.Ev KRB5CCNAME
or with an appropriate command-line option such as
.Fl c
for
.Nm .
.It Ev KRB5_CONFIG
The file name of
.Pa krb5.conf ,
Expand Down
2 changes: 1 addition & 1 deletion lib/gssapi/krb5/store_cred.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ _gsskrb5_store_cred_into2(OM_uint32 *minor_status,
HEIMDAL_MUTEX_lock(&input_cred->cred_id_mutex);

if (cs_ccache_name && strchr(cs_ccache_name, '%')) {
ret = _krb5_expand_default_cc_name(context, cs_ccache_name,
ret = _krb5_expand_default_cc_name(context, NULL, cs_ccache_name,
&ccache_name);
if (ret) {
HEIMDAL_MUTEX_unlock(&input_cred->cred_id_mutex);
Expand Down
7 changes: 4 additions & 3 deletions lib/krb5/acache.c
Original file line number Diff line number Diff line change
Expand Up @@ -579,8 +579,9 @@ acc_resolve_2(krb5_context context, krb5_ccache *id, const char *res, const char
}

static krb5_error_code KRB5_CALLCONV
acc_gen_new(krb5_context context, krb5_ccache *id)
acc_gen_new_2(krb5_context context, const char *name, krb5_ccache *id)
{
(void) name;
return acc_alloc(context, id);
}

Expand Down Expand Up @@ -1098,7 +1099,7 @@ KRB5_LIB_VARIABLE const krb5_cc_ops krb5_acc_ops = {
"API",
NULL,
NULL,
acc_gen_new,
NULL,
acc_initialize,
acc_destroy,
acc_close,
Expand All @@ -1122,7 +1123,7 @@ KRB5_LIB_VARIABLE const krb5_cc_ops krb5_acc_ops = {
NULL,
acc_get_name_2,
acc_resolve_2,
NULL,
acc_gen_new_2,
0,
':',
'\0',
Expand Down
41 changes: 32 additions & 9 deletions lib/krb5/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,9 @@ krb5_cc_new_unique(krb5_context context, const char *type,
} else {
ops = cc_get_prefix_ops(context, type, &res);
if (res == NULL && hint == NULL &&
strcmp(ops->prefix, def_type) != 0) {
!context->default_cc_name_defaulted &&
strcmp(ops->prefix, def_type) != 0 &&
strncmp(type, "MEMORY", sizeof("MEMORY")) != 0) {
krb5_set_error_message(context, KRB5_CC_NOSUPP,
"Refusing to create a new unique cache in "
"the default collection for cache type %s "
Expand Down Expand Up @@ -482,7 +484,7 @@ krb5_cc_new_unique(krb5_context context, const char *type,
if (ret)
return ret;
if ((*id)->ops->gen_new_2)
ret = (*id)->ops->gen_new_2(context, type, hint ? hint : res, id);
ret = (*id)->ops->gen_new_2(context, hint ? hint : res, id);
else
ret = (*id)->ops->gen_new(context, id);
if (ret) {
Expand Down Expand Up @@ -626,17 +628,38 @@ krb5_cc_get_ops(krb5_context context, krb5_ccache id)
*/

KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
_krb5_expand_default_cc_name(krb5_context context, const char *str, char **res)
_krb5_expand_default_cc_name(krb5_context context, const krb5_cc_ops *ops, const char *str, char **res)
{
int filepath;

filepath = (strncmp("FILE:", str, 5) == 0
|| strncmp("DIR:", str, 4) == 0
|| strncmp("SCC:", str, 4) == 0);
int filepath = 0;

if (ops == NULL)
ops = cc_get_prefix_ops(context, str, NULL);
if (ops == NULL)
filepath = ops->filepath;
return _krb5_expand_path_tokens(context, str, filepath, res);
}

KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
_krb5_default_cc_name(krb5_context context,
const krb5_cc_ops *ops,
const char *type,
const char *hardcoded_default,
char **res)
{
const char *s;

if (ops == NULL)
ops = cc_get_prefix_ops(context, type, NULL);
if (ops == NULL)
return _krb5_expand_path_tokens(context, hardcoded_default, 0, res);

s = krb5_config_get_string(context, NULL, "libdefaults",
"default_ccache_name_by_type", type, NULL);
if (s)
return _krb5_expand_path_tokens(context, s, 0, res);
return _krb5_expand_path_tokens(context, hardcoded_default, 0, res);
}

/*
* Return non-zero if envirnoment that will determine default krb5cc
* name has changed.
Expand Down Expand Up @@ -830,7 +853,7 @@ krb5_cc_configured_default_name(krb5_context context)
cfg = krb5_config_get_string(context, NULL, "libdefaults",
"default_ccache_name", NULL);
if (cfg) {
ret = _krb5_expand_default_cc_name(context, cfg, &expanded);
ret = _krb5_expand_default_cc_name(context, NULL, cfg, &expanded);
if (ret) {
krb5_set_error_message(context, ret,
"token expansion failed for %s", cfg);
Expand Down
36 changes: 16 additions & 20 deletions lib/krb5/dcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -488,26 +488,29 @@ dcc_resolve_2(krb5_context context,
}

static krb5_error_code KRB5_CALLCONV
dcc_gen_new(krb5_context context, krb5_ccache *id)
dcc_gen_new_2(krb5_context context, const char *name, krb5_ccache *id)
{
krb5_error_code ret;
krb5_error_code ret = 0;
char *def_dir = NULL;
char *name = NULL;
char *ccname = NULL;
int fd = -1;

ret = get_default_dir(context, &def_dir);
if (name == NULL) {
ret = get_default_dir(context, &def_dir);
name = def_dir;
}
if (ret == 0)
ret = verify_directory(context, def_dir);
ret = verify_directory(context, name);
if (ret == 0 &&
(asprintf(&name, "DIR::%s/tktXXXXXX", def_dir) == -1 || name == NULL))
(asprintf(&ccname, "DIR::%s/tktXXXXXX", name) == -1 || name == NULL))
ret = krb5_enomem(context);
if (ret == 0 && (fd = mkstemp(name + sizeof("DIR::") - 1)) == -1)
if (ret == 0 && (fd = mkstemp(ccname + sizeof("DIR::") - 1)) == -1)
ret = errno;
if (ret == 0)
ret = dcc_resolve_2(context, id, name + sizeof("DIR:") - 1, NULL);
ret = dcc_resolve_2(context, id, ccname + sizeof("DIR:") - 1, NULL);

free(def_dir);
free(name);
free(ccname);
if (fd != -1)
close(fd);
return ret;
Expand Down Expand Up @@ -773,15 +776,8 @@ dcc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
static krb5_error_code KRB5_CALLCONV
dcc_get_default_name(krb5_context context, char **str)
{
const char *def_cc_colname =
krb5_config_get_string_default(context, NULL, KRB5_DEFAULT_CCNAME_DIR,
"libdefaults", "default_cc_collection",
NULL);

/* [libdefaults] default_cc_collection is for testing */
if (strncmp(def_cc_colname, "DIR:", sizeof("DIR:") - 1) != 0)
def_cc_colname = KRB5_DEFAULT_CCNAME_DIR;
return _krb5_expand_default_cc_name(context, def_cc_colname, str);
return _krb5_default_cc_name(context, &krb5_dcc_ops, NULL,
KRB5_DEFAULT_CCNAME_DIR, str);
}

static krb5_error_code KRB5_CALLCONV
Expand Down Expand Up @@ -827,7 +823,7 @@ KRB5_LIB_VARIABLE const krb5_cc_ops krb5_dcc_ops = {
"DIR",
NULL,
NULL,
dcc_gen_new,
NULL,
dcc_initialize,
dcc_destroy,
dcc_close,
Expand All @@ -851,7 +847,7 @@ KRB5_LIB_VARIABLE const krb5_cc_ops krb5_dcc_ops = {
dcc_get_kdc_offset,
dcc_get_name_2,
dcc_resolve_2,
NULL,
dcc_gen_new_2,
1,
'\0',
':',
Expand Down
22 changes: 13 additions & 9 deletions lib/krb5/fcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -371,13 +371,17 @@ _krb5_erase_file(krb5_context context, const char *filename)
}

static krb5_error_code KRB5_CALLCONV
fcc_gen_new(krb5_context context, krb5_ccache *id)
fcc_gen_new_2(krb5_context context, const char *name, krb5_ccache *id)
{
char *file = NULL, *exp_file = NULL;
krb5_error_code ret;
krb5_fcache *f;
int fd;

if (name == NULL)
/* TODO use the first in [libdefaults] default_file_cache_collections */
name = KRB5_DEFAULT_CCFILE_ROOT;

f = calloc(1, sizeof(*f));
if(f == NULL) {
krb5_set_error_message(context, KRB5_CC_NOMEM,
Expand All @@ -390,7 +394,7 @@ fcc_gen_new(krb5_context context, krb5_ccache *id)
* instead so that new unique FILE ccaches can be found in the user's
* default collection.
* */
ret = asprintf(&file, "%sXXXXXX", KRB5_DEFAULT_CCFILE_ROOT);
ret = asprintf(&file, "%sXXXXXX", name);
if(ret < 0 || file == NULL) {
free(f);
krb5_set_error_message(context, KRB5_CC_NOMEM,
Expand Down Expand Up @@ -1281,7 +1285,7 @@ is_default_collection(krb5_context context, const char *name,
const char * const *def_locs, int *res)
{
krb5_error_code ret;
const char *def_loc[2] = { KRB5_DEFAULT_CCNAME_FILE, NULL };
const char *def_loc[2] = { KRB5_DEFAULT_CCNAME_FILE, NULL }; /* XXX */
const char *sep;
size_t namelen;
size_t i;
Expand All @@ -1300,7 +1304,8 @@ is_default_collection(krb5_context context, const char *name,
for (i = 0; !(*res) && def_locs[i]; i++) {
char *e = NULL;

if ((ret = _krb5_expand_default_cc_name(context, def_locs[i], &e)))
if ((ret = _krb5_expand_default_cc_name(context, &krb5_fcc_ops,
def_locs[i], &e)))
return ret;
*res = strncmp(e, name, namelen) == 0 &&
(sep == NULL || e[namelen] == FILESUBSEPCHR || e[namelen] == '\0');
Expand Down Expand Up @@ -1579,9 +1584,8 @@ fcc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
static krb5_error_code KRB5_CALLCONV
fcc_get_default_name(krb5_context context, char **str)
{
return _krb5_expand_default_cc_name(context,
KRB5_DEFAULT_CCNAME_FILE,
str);
return _krb5_default_cc_name(context, &krb5_fcc_ops, NULL,
KRB5_DEFAULT_CCNAME_FILE, str);
}

static krb5_error_code KRB5_CALLCONV
Expand Down Expand Up @@ -1666,7 +1670,7 @@ KRB5_LIB_VARIABLE const krb5_cc_ops krb5_fcc_ops = {
"FILE",
NULL,
NULL,
fcc_gen_new,
NULL,
fcc_initialize,
fcc_destroy,
fcc_close,
Expand All @@ -1690,7 +1694,7 @@ KRB5_LIB_VARIABLE const krb5_cc_ops krb5_fcc_ops = {
fcc_get_kdc_offset,
fcc_get_name_2,
fcc_resolve_2,
NULL,
fcc_gen_new_2,
1,
'+',
'\0',
Expand Down

0 comments on commit f05facf

Please sign in to comment.