only perform dir separator normalization for file paths

Commit ad7e54d698 introduced the use
of _krb5_expand_path_tokens() to expand tokens (and on Windows convert
path delimiters) within credential cache names.  This is safe to do
for the path based credential cache types FILE, DIR and SCC but on
Windows is unsafe for the non-path types.

For example on Windows, the API credential cache names are often based
on the principal name and the principal name is parsed from the ccname.
This practice was introduced with the version v2 ccapi when there was
no method of enumerating the caches from the krb5 library.

This change adds a "filepath" boolean parameter to _krb5_expand_path_tokens()
which is set to TRUE (non-zero) when the input is a file path and FALSE
(zero) when the input is not a file path.  _krb5_expand_path_tokens() will
only perform directory separator normalization on Windows when the
"filepath" parameter is TRUE.

This change is not the preferred solution because it requires that the
library be aware of all credential cache types that use path based
residuals.  The preferred solution would require that the credential cache
implementation indicate whether or not it uses a path based residual.

This change has been implemented using a prefix test and not a change to
struct krb5_cc_ops because existing ccache plugins will not know how to
advertise their use of path based residuals and that path expansion is
safe.

Change-Id: I8135991e8ce69fc5273d381ea9c2078bc2bcd19a
This commit is contained in:
Jeffrey Altman
2014-10-19 13:49:24 -04:00
parent b3f29170a3
commit ef8e4da010
8 changed files with 32 additions and 12 deletions

View File

@@ -125,7 +125,7 @@ init_ccapi(krb5_context context)
#ifdef KRB5_USE_PATH_TOKENS
{
char * explib = NULL;
if (_krb5_expand_path_tokens(context, lib, &explib) == 0) {
if (_krb5_expand_path_tokens(context, lib, 0, &explib) == 0) {
cc_handle = dlopen(explib, RTLD_LAZY|RTLD_LOCAL);
free(explib);
}

View File

@@ -188,8 +188,13 @@ allocate_ccache (krb5_context context,
krb5_error_code ret;
#ifdef KRB5_USE_PATH_TOKENS
char * exp_residual = NULL;
int filepath;
ret = _krb5_expand_path_tokens(context, residual, &exp_residual);
filepath = (strcmp("FILE", ops->prefix) == 0
|| strcmp("DIR", ops->prefix) == 0
|| strcmp("SCC", ops->prefix) == 0);
ret = _krb5_expand_path_tokens(context, residual, filepath, &exp_residual);
if (ret)
return ret;
@@ -409,7 +414,13 @@ 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)
{
return _krb5_expand_path_tokens(context, str, res);
int filepath;
filepath = (strncmp("FILE:", str, 5) == 0
|| strncmp("DIR:", str, 4) == 0
|| strncmp("SCC:", str, 4) == 0);
return _krb5_expand_path_tokens(context, str, filepath, res);
}
/*
@@ -501,6 +512,7 @@ krb5_cc_set_default_name(krb5_context context, const char *name)
{
krb5_error_code ret = 0;
char *p = NULL, *exp_p = NULL;
int filepath;
if (name == NULL) {
const char *e = NULL;
@@ -556,15 +568,20 @@ krb5_cc_set_default_name(krb5_context context, const char *name)
if (p == NULL)
return krb5_enomem(context);
ret = _krb5_expand_path_tokens(context, p, &exp_p);
filepath = (strncmp("FILE:", p, 5) == 0
|| strncmp("DIR:", p, 4) == 0
|| strncmp("SCC:", p, 4) == 0);
ret = _krb5_expand_path_tokens(context, p, filepath, &exp_p);
free(p);
p = exp_p;
if (ret)
return ret;
if (context->default_cc_name)
free(context->default_cc_name);
context->default_cc_name = exp_p;
context->default_cc_name = p;
return 0;
}

View File

@@ -478,7 +478,7 @@ krb5_config_parse_file_multi (krb5_context context,
#ifdef KRB5_USE_PATH_TOKENS
char * exp_fname = NULL;
ret = _krb5_expand_path_tokens(context, fname, &exp_fname);
ret = _krb5_expand_path_tokens(context, fname, 1, &exp_fname);
if (ret) {
if (newfname)
free(newfname);

View File

@@ -424,9 +424,10 @@ _expand_token(krb5_context context,
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
_krb5_expand_path_tokens(krb5_context context,
const char *path_in,
int filepath,
char **ppath_out)
{
return _krb5_expand_path_tokensv(context, path_in, ppath_out, NULL);
return _krb5_expand_path_tokensv(context, path_in, filepath, ppath_out, NULL);
}
static void
@@ -458,6 +459,7 @@ free_extra_tokens(char **extra_tokens)
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
_krb5_expand_path_tokensv(krb5_context context,
const char *path_in,
int filepath,
char **ppath_out, ...)
{
char *tok_begin, *tok_end, *append;
@@ -587,8 +589,9 @@ _krb5_expand_path_tokensv(krb5_context context,
#ifdef _WIN32
/* Also deal with slashes */
if (*ppath_out) {
if (filepath && *ppath_out) {
char * c;
for (c = *ppath_out; *c; c++)
if (*c == '/')
*c = '\\';

View File

@@ -334,7 +334,7 @@ fcc_gen_new(krb5_context context, krb5_ccache *id)
N_("malloc: out of memory", ""));
return KRB5_CC_NOMEM;
}
ret = _krb5_expand_path_tokens(context, file, &exp_file);
ret = _krb5_expand_path_tokens(context, file, 1, &exp_file);
free(file);
if (ret) {
free(f);

View File

@@ -639,7 +639,7 @@ kuserok_user_k5login_plug_f(void *plug_ctx, krb5_context context,
if (asprintf(&path, "%s/.k5login.d", profile_dir) == -1)
return krb5_enomem(context);
ret = _krb5_expand_path_tokensv(context, path, &path_exp,
ret = _krb5_expand_path_tokensv(context, path, 1, &path_exp,
"luser", luser, NULL);
free(path);
if (ret)

View File

@@ -2207,7 +2207,7 @@ _krb5_parse_moduli(krb5_context context, const char *file,
{
char * exp_file;
if (_krb5_expand_path_tokens(context, file, &exp_file) == 0) {
if (_krb5_expand_path_tokens(context, file, 1, &exp_file) == 0) {
f = fopen(exp_file, "r");
krb5_xfree(exp_file);
} else {

View File

@@ -80,7 +80,7 @@ main(int argc, char **argv)
if (ret)
errx (1, "krb5_init_context failed: %d", ret);
ret = _krb5_expand_path_tokensv(context, "/tmp/%{foo}/%{bar}%{baz}/x",
ret = _krb5_expand_path_tokensv(context, "/tmp/%{foo}/%{bar}%{baz}/x", 0,
&expanded,
"foo", "abc",
"bar", "dce",