summaryrefslogtreecommitdiffstats
path: root/src/providers
diff options
context:
space:
mode:
authorLukas Slebodnik <lslebodn@redhat.com>2013-04-06 17:58:53 +0200
committerJakub Hrozek <jhrozek@redhat.com>2013-04-12 18:03:30 +0200
commit9d890186ec2b511aa30a9574543f29e1ef56e0e8 (patch)
tree95da12995ea93c9e8bafb7e49620053ac1b14680 /src/providers
parentc3662207db84b05ebce904f34409ea61ab776d89 (diff)
downloadsssd-9d890186ec2b511aa30a9574543f29e1ef56e0e8.tar.gz
sssd-9d890186ec2b511aa30a9574543f29e1ef56e0e8.tar.xz
sssd-9d890186ec2b511aa30a9574543f29e1ef56e0e8.zip
Fix krbcc dir creation issue with MIT krb5 1.11
In krb5-libs >= 1.11, function krb5_cc_resolve verify if credential cache dir exists. If it doesn't exist, than it will be created with process permissions and not user permissions. Function cc_residual_is_used has already checked for non existing directory, but it wasn't considered to be a failure and therefore next call of krb5_init_context will create directory with wrong permissions. Now if directory doesn't exist, it will be handled like there was not ccache attribute in sysdb cache. We also check if "primary" file in ccache directory has right permissions. But we ignore missing "primary" file. https://fedorahosted.org/sssd/ticket/1822
Diffstat (limited to 'src/providers')
-rw-r--r--src/providers/krb5/krb5_auth.c12
-rw-r--r--src/providers/krb5/krb5_utils.c60
2 files changed, 61 insertions, 11 deletions
diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c
index 00025bfc1..5baea0bc8 100644
--- a/src/providers/krb5/krb5_auth.c
+++ b/src/providers/krb5/krb5_auth.c
@@ -106,6 +106,11 @@ check_old_ccache(const char *old_ccache, struct krb5child_req *kr,
ret = old_cc_ops->check_existing(old_ccache, kr->uid, realm, kr->upn,
cc_template, active, valid);
+ if (ret == ENOENT) {
+ DEBUG(SSSDBG_TRACE_FUNC,
+ ("Saved ccache %s doesn't exist.\n", old_ccache));
+ return ret;
+ }
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
("Cannot check if saved ccache %s is active and valid\n",
@@ -617,7 +622,12 @@ struct tevent_req *krb5_auth_send(TALLOC_CTX *mem_ctx,
ret = check_old_ccache(ccache_file, kr, realm,
&kr->active_ccache,
&kr->valid_tgt);
- if (ret != EOK) {
+ if (ret == ENOENT) {
+ DEBUG(SSSDBG_FUNC_DATA,
+ ("Ignoring ccache attribute [%s], because it doesn't"
+ "exist.\n", ccache_file));
+ ccache_file = NULL;
+ } else if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE,
("check_if_ccache_file_is_used failed.\n"));
goto done;
diff --git a/src/providers/krb5/krb5_utils.c b/src/providers/krb5/krb5_utils.c
index ad77c7cc8..524568939 100644
--- a/src/providers/krb5/krb5_utils.c
+++ b/src/providers/krb5/krb5_utils.c
@@ -776,7 +776,7 @@ cc_residual_is_used(uid_t uid, const char *ccname,
DEBUG(SSSDBG_FUNC_DATA, ("Cache file [%s] does not exist, "
"it will be recreated\n", ccname));
*result = false;
- return EOK;
+ return ENOENT;
}
DEBUG(SSSDBG_OP_FAILURE,
@@ -869,10 +869,13 @@ cc_file_check_existing(const char *location, uid_t uid,
ret = cc_residual_is_used(uid, filename, SSS_KRB5_TYPE_FILE, &active);
if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, ("Could not check if ccache is active. "
- "Will create a new one.\n"));
+ if (ret != ENOENT) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ ("Could not check if ccache is active.\n"));
+ }
cc_check_template(cc_template);
active = false;
+ return ret;
}
kerr = krb5_init_context(&context);
@@ -998,6 +1001,7 @@ cc_dir_check_existing(const char *location, uid_t uid,
const char *cc_template, bool *_active, bool *_valid)
{
bool active = false;
+ bool active_primary = false;
bool valid = false;
krb5_ccache ccache = NULL;
krb5_context context = NULL;
@@ -1006,7 +1010,9 @@ cc_dir_check_existing(const char *location, uid_t uid,
const char *filename;
const char *dir;
char *tmp;
+ char *primary_file;
errno_t ret;
+ TALLOC_CTX *tmp_ctx;
type = sss_krb5_get_type(location);
if (type != SSS_KRB5_TYPE_DIR) {
@@ -1027,29 +1033,62 @@ cc_dir_check_existing(const char *location, uid_t uid,
return EINVAL;
}
- tmp = talloc_strdup(NULL, filename);
- if (!tmp) return ENOMEM;
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, ("talloc_new failed.\n"));
+ return ENOMEM;
+ }
+
+ tmp = talloc_strdup(tmp_ctx, filename);
+ if (!tmp) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_strdup failed.\n"));
+ ret = ENOMEM;
+ goto done;
+ }
dir = dirname(tmp);
if (!dir) {
DEBUG(SSSDBG_CRIT_FAILURE,
("Cannot base get directory of %s\n", location));
- return EINVAL;
+ ret = EINVAL;
+ goto done;
}
ret = cc_residual_is_used(uid, dir, SSS_KRB5_TYPE_DIR, &active);
- talloc_free(tmp);
if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, ("Could not check if ccache is active. "
- "Will create a new one.\n"));
+ if (ret != ENOENT) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ ("Could not check if ccache is active.\n"));
+ }
cc_check_template(cc_template);
active = false;
+ goto done;
+ }
+
+ /* If primary file isn't in ccache dir, we will ignore it.
+ * But if primary file has wrong permissions, we will fail.
+ */
+ primary_file = talloc_asprintf(tmp_ctx, "%s/primary", dir);
+ if (!primary_file) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_asprintf failed.\n"));
+ ret = ENOMEM;
+ goto done;
+ }
+ ret = cc_residual_is_used(uid, primary_file, SSS_KRB5_TYPE_FILE,
+ &active_primary);
+ if (ret != EOK && ret != ENOENT) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ ("Could not check if file 'primary' [%s] in dir ccache"
+ " is active.\n", primary_file));
+ active = false;
+ goto done;
}
krberr = krb5_init_context(&context);
if (krberr) {
DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to init kerberos context\n"));
- return EIO;
+ ret = EIO;
+ goto done;
}
krberr = krb5_cc_resolve(context, location, &ccache);
@@ -1081,6 +1120,7 @@ cc_dir_check_existing(const char *location, uid_t uid,
ret = EOK;
done:
+ talloc_free(tmp_ctx);
if (ccache) krb5_cc_close(context, ccache);
krb5_free_context(context);
*_active = active;