On Tue, 21 Aug 2012 18:56:48 -0400 Nalin Dahyabhai <nalin@xxxxxxxxxx> wrote: > When scanning for credential caches, check the user's directory under > /run/user first, then fall back to /tmp as we have previously. Because > we now call find_krb5_cc() twice (once for each directory), we move its > state to be outside of the function. We also add a substitution > mechanism to make the process of resolving the location of the user's > home directory before searching it a bit more explicable. > --- > cifs.upcall.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++----------- > 1 file changed, 51 insertions(+), 11 deletions(-) > > diff --git a/cifs.upcall.c b/cifs.upcall.c > index 6f95c1c..598a999 100644 > --- a/cifs.upcall.c > +++ b/cifs.upcall.c > @@ -53,7 +53,8 @@ > #include "cifs_spnego.h" > > #define CIFS_DEFAULT_KRB5_DIR "/tmp" > -#define CIFS_DEFAULT_KRB5_PREFIX "krb5cc_" > +#define CIFS_DEFAULT_KRB5_USER_DIR "/run/user/%U" > +#define CIFS_DEFAULT_KRB5_PREFIX "krb5cc" > #define CIFS_DEFAULT_KRB5_KEYTAB "/etc/krb5.keytab" > > #define MAX_CCNAME_LEN PATH_MAX + 5 > @@ -258,14 +259,47 @@ icfk_cleanup: > return ccname; > } > > +/* resolve a pattern to an actual directory path */ > +static char *resolve_krb5_dir(const char *pattern, uid_t uid) > +{ > + char name[MAX_CCNAME_LEN]; > + int i; > + size_t j; > + for (i = 0, j = 0; (pattern[i] != '\0') && (j < sizeof(name)); i++) { > + switch (pattern[i]) { > + case '%': > + switch (pattern[i + 1]) { > + case '%': > + name[j++] = pattern[i]; > + i++; > + break; > + case 'U': > + j += snprintf(name + j, sizeof(name) - j, > + "%lu", (unsigned long) uid); > + i++; > + break; > + } > + break; > + default: > + name[j++] = pattern[i]; > + break; > + } > + } > + if ((j > 0) && (j < sizeof(name))) > + return strndup(name, MAX_CCNAME_LEN); > + else > + return NULL; > +} > + > /* search for a credcache that looks like a likely candidate */ > -static char *find_krb5_cc(const char *dirname, uid_t uid) > +static char *find_krb5_cc(const char *dirname, uid_t uid, > + char **best_cache, time_t *best_time) > { > struct dirent **namelist; > struct stat sbuf; > - char ccname[MAX_CCNAME_LEN], *credpath, *best_cache = NULL; > + char ccname[MAX_CCNAME_LEN], *credpath; > int i, n; > - time_t cred_time, best_time = 0; > + time_t cred_time; > > n = scandir(dirname, &namelist, krb5cc_filter, NULL); > if (n < 0) { > @@ -310,7 +344,7 @@ static char *find_krb5_cc(const char *dirname, uid_t uid) > continue; > } > > - if (cred_time <= best_time) { > + if (cred_time <= *best_time) { > syslog(LOG_DEBUG, "%s: %s expires sooner than current " > "best.", __func__, ccname); > free(namelist[i]); > @@ -318,14 +352,14 @@ static char *find_krb5_cc(const char *dirname, uid_t uid) > } > > syslog(LOG_DEBUG, "%s: %s is valid ccache", __func__, ccname); > - free(best_cache); > - best_cache = strndup(ccname, MAX_CCNAME_LEN); > - best_time = cred_time; > + free(*best_cache); > + *best_cache = strndup(ccname, MAX_CCNAME_LEN); > + *best_time = cred_time; > free(namelist[i]); > } > free(namelist); > > - return best_cache; > + return *best_cache; > } > > static int > @@ -793,12 +827,13 @@ int main(const int argc, char *const argv[]) > unsigned int have; > long rc = 1; > int c, try_dns = 0, legacy_uid = 0; > - char *buf, *ccname = NULL; > + char *buf, *ccdir = NULL, *ccname = NULL, *best_cache = NULL; > char hostbuf[NI_MAXHOST], *host; > struct decoded_args arg; > const char *oid; > uid_t uid; > char *keytab_name = CIFS_DEFAULT_KRB5_KEYTAB; > + time_t best_time = 0; > > hostbuf[0] = '\0'; > memset(&arg, 0, sizeof(arg)); > @@ -901,7 +936,12 @@ int main(const int argc, char *const argv[]) > syslog(LOG_ERR, "setuid: %s", strerror(errno)); > goto out; > } > - ccname = find_krb5_cc(CIFS_DEFAULT_KRB5_DIR, uid); > + ccdir = resolve_krb5_dir(CIFS_DEFAULT_KRB5_USER_DIR, uid); > + if (ccdir != NULL) > + find_krb5_cc(ccdir, uid, &best_cache, &best_time); > + ccname = find_krb5_cc(CIFS_DEFAULT_KRB5_DIR, uid, &best_cache, > + &best_time); > + SAFE_FREE(ccdir); > > /* Couldn't find credcache? Try to use keytab */ > if (ccname == NULL && arg.username != NULL) Committed... -- Jeff Layton <jlayton@xxxxxxxxx> -- To unsubscribe from this list: send the line "unsubscribe linux-cifs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html