From 09e752274e1c94dab228223761209fc1df14a0e5 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Tue, 30 Jul 2013 15:37:04 -0600 Subject: [PATCH] Strip off leading FILE: or WRFILE: prefix before trying to copy the user's credential cache. --- plugins/sudoers/ldap.c | 85 ++++++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 33 deletions(-) diff --git a/plugins/sudoers/ldap.c b/plugins/sudoers/ldap.c index 880078985..672f8af2a 100644 --- a/plugins/sudoers/ldap.c +++ b/plugins/sudoers/ldap.c @@ -1438,11 +1438,10 @@ sudo_ldap_parse_keyword(const char *keyword, const char *value, } #ifdef HAVE_LDAP_SASL_INTERACTIVE_BIND_S -static bool -sudo_check_krb5_ccname(const char *ccname) +static const char * +sudo_krb5_ccname_path(const char *ccname) { - int fd = -1; - debug_decl(sudo_check_krb5_ccname, SUDO_DEBUG_LDAP) + debug_decl(sudo_krb5_ccname_path, SUDO_DEBUG_LDAP) /* Strip off leading FILE: or WRFILE: prefix. */ switch (ccname[0]) { @@ -1458,17 +1457,34 @@ sudo_check_krb5_ccname(const char *ccname) break; } + /* Credential cache must be a fully-qualified path name. */ + debug_return_str(*ccname == '/' ? ccname : NULL); +} + +static bool +sudo_check_krb5_ccname(const char *ccname) +{ + int fd = -1; + const char *ccname_path; + debug_decl(sudo_check_krb5_ccname, SUDO_DEBUG_LDAP) + + /* Strip off prefix to get path name. */ + ccname_path = sudo_krb5_ccname_path(ccname); + if (ccname_path == NULL) { + sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO, + "unsupported krb5 credential cache path: %s", ccname); + debug_return_bool(false); + } /* Make sure credential cache is fully-qualified and exists. */ - if (ccname[0] == '/') - fd = open(ccname, O_RDONLY|O_NONBLOCK, 0); + fd = open(ccname_path, O_RDONLY|O_NONBLOCK, 0); if (fd == -1) { sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO, - "unable to open krb5 credential cache: %s", ccname); + "unable to open krb5 credential cache: %s", ccname_path); debug_return_bool(false); } close(fd); sudo_debug_printf(SUDO_DEBUG_INFO, - "using krb5 credential cache: %s", ccname); + "using krb5 credential cache: %s", ccname_path); debug_return_bool(true); } #endif /* HAVE_LDAP_SASL_INTERACTIVE_BIND_S */ @@ -2050,35 +2066,38 @@ sudo_krb5_copy_cc_file(const char *old_ccname) char buf[10240], *ret = NULL; debug_decl(sudo_krb5_copy_cc_file, SUDO_DEBUG_LDAP) - /* Open credential cache as user to prevent stolen creds. */ - set_perms(PERM_USER); - ofd = open(old_ccname, O_RDONLY|O_NONBLOCK); - restore_perms(); - - if (ofd != -1) { - (void) fcntl(ofd, F_SETFL, 0); - if (lock_file(ofd, SUDO_LOCK)) { - snprintf(new_ccname, sizeof(new_ccname), "%s%s", - _PATH_TMP, "sudocc_XXXXXXXX"); - nfd = mkstemp(new_ccname); - if (nfd != -1) { - while ((nread = read(ofd, buf, sizeof(buf))) > 0) { - off = 0; - while ((nwritten = write(nfd, buf + off, nread - off)) != -1) { - off += nwritten; + old_ccname = sudo_krb5_ccname_path(old_ccname); + if (old_ccname != NULL) { + /* Open credential cache as user to prevent stolen creds. */ + set_perms(PERM_USER); + ofd = open(old_ccname, O_RDONLY|O_NONBLOCK); + restore_perms(); + + if (ofd != -1) { + (void) fcntl(ofd, F_SETFL, 0); + if (lock_file(ofd, SUDO_LOCK)) { + snprintf(new_ccname, sizeof(new_ccname), "%s%s", + _PATH_TMP, "sudocc_XXXXXXXX"); + nfd = mkstemp(new_ccname); + if (nfd != -1) { + while ((nread = read(ofd, buf, sizeof(buf))) > 0) { + off = 0; + while ((nwritten = write(nfd, buf + off, nread - off)) != -1) { + off += nwritten; + } + if (nwritten == -1) + break; + } + close(nfd); + if (nread != -1 && nwritten != -1) { + ret = new_ccname; /* success! */ + } else { + unlink(new_ccname); /* failed */ } - if (nwritten == -1) - break; - } - close(nfd); - if (nread != -1 && nwritten != -1) { - ret = new_ccname; /* success! */ - } else { - unlink(new_ccname); /* failed */ } } + close(ofd); } - close(ofd); } debug_return_str(ret); } -- 2.50.0