summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2013-08-31 14:21:22 -0400
committerSimo Sorce <simo@redhat.com>2013-09-09 15:11:46 -0400
commit14050f35224360883e20ebd810d3eb40f39267cf (patch)
treec31be7accf7d69007010ef67f832076ceffe9a7a
parent0dbcc64a5cee58d5fffaaef923302d9c7a951a7d (diff)
downloadsssd-14050f35224360883e20ebd810d3eb40f39267cf.tar.gz
sssd-14050f35224360883e20ebd810d3eb40f39267cf.tar.xz
sssd-14050f35224360883e20ebd810d3eb40f39267cf.zip
krb5: Add file/dir path precheck
Add a precheck on the actual existence at all of the file/dir ccname targeted (for FILE/DIR types), and bail early if nothing is available. While testing I found out that without this check, the krb5_cc_resolve() function we call as user to check old paths would try to create the directory if it didn't exist. With a ccname of DIR:/tmp/ccdir_1000 saved in the user entry this would cause two undesirable side effects: First it would actually create a directory with the old name, when it should not. Second, because for some reason the umask is set to 0127 in sssd_be, it would create the directory with permission 600 (missing the 'x' traverse bit on the directory. If the new ccache has the same name it would cause the krb5_child process to fal to store the credential cache in it. Related: https://fedorahosted.org/sssd/ticket/2061
-rw-r--r--src/providers/krb5/krb5_auth.c1
-rw-r--r--src/providers/krb5/krb5_utils.c34
2 files changed, 35 insertions, 0 deletions
diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c
index 1585f709..7cfa3e94 100644
--- a/src/providers/krb5/krb5_auth.c
+++ b/src/providers/krb5/krb5_auth.c
@@ -69,6 +69,7 @@ check_old_ccache(const char *old_ccache, struct krb5child_req *kr,
realm, kr->upn);
switch (ret) {
case ERR_NOT_FOUND:
+ case ENOENT:
DEBUG(SSSDBG_TRACE_FUNC,
("Saved ccache %s doesn't exist.\n", old_ccache));
return ENOENT;
diff --git a/src/providers/krb5/krb5_utils.c b/src/providers/krb5/krb5_utils.c
index d0ccd2d7..bb933d7f 100644
--- a/src/providers/krb5/krb5_utils.c
+++ b/src/providers/krb5/krb5_utils.c
@@ -967,6 +967,30 @@ done:
return ret;
}
+static errno_t sss_low_level_path_check(const char *ccname)
+{
+ const char *filename;
+ struct stat buf;
+ int ret;
+
+ if (ccname[0] == '/') {
+ filename = ccname;
+ } else if (strncmp(ccname, "FILE:", 5) == 0) {
+ filename = ccname + 5;
+ } else if (strncmp(ccname, "DIR:", 4) == 0) {
+ filename = ccname + 4;
+ if (filename[0] == ':') filename += 1;
+ } else {
+ /* only FILE and DIR types need file checks so far, we ignore any
+ * other type */
+ return EOK;
+ }
+
+ ret = stat(filename, &buf);
+ if (ret == -1) return errno;
+ return EOK;
+}
+
errno_t sss_krb5_cc_verify_ccache(const char *ccname, uid_t uid, gid_t gid,
const char *realm, const char *principal)
{
@@ -980,6 +1004,16 @@ errno_t sss_krb5_cc_verify_ccache(const char *ccname, uid_t uid, gid_t gid,
krb5_error_code kerr;
errno_t ret;
+ /* first of all verify if the old ccache file/dir exists as we may be
+ * trying to verify if an old ccache exists at all. If no file/dir
+ * exists bail out immediately otherwise a following krb5_cc_resolve()
+ * call may actually create paths and files we do not want to have
+ * around */
+ ret = sss_low_level_path_check(ccname);
+ if (ret) {
+ return ret;
+ }
+
tmp_ctx = talloc_new(NULL);
if (tmp_ctx == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new failed.\n"));