static int select_krb5_ccache(const struct dirent *d);
static int gssd_find_existing_krb5_ccache(uid_t uid, char *dirname,
- struct dirent **d);
+ const char **cctype, struct dirent **d);
static int gssd_get_single_krb5_cred(krb5_context context,
krb5_keytab kt, struct gssd_k5_kt_princ *ple, int nocache);
static int query_krb5_ccache(const char* cred_cache, char **ret_princname,
* code otherwise.
*/
static int
-gssd_find_existing_krb5_ccache(uid_t uid, char *dirname, struct dirent **d)
+gssd_find_existing_krb5_ccache(uid_t uid, char *dirname,
+ const char **cctype, struct dirent **d)
{
struct dirent **namelist;
int n;
int score, best_match_score = 0, err = -EACCES;
memset(&best_match_stat, 0, sizeof(best_match_stat));
+ *cctype = NULL;
*d = NULL;
n = scandir(dirname, &namelist, select_krb5_ccache, 0);
if (n < 0) {
for (i = 0; i < n; i++) {
snprintf(statname, sizeof(statname),
"%s/%s", dirname, namelist[i]->d_name);
- printerr(3, "CC file '%s' being considered, "
+ printerr(3, "CC '%s' being considered, "
"with preferred realm '%s'\n",
statname, preferred_realm ?
preferred_realm : "<none selected>");
- snprintf(buf, sizeof(buf), "FILE:%s/%s", dirname,
- namelist[i]->d_name);
if (lstat(statname, &tmp_stat)) {
- printerr(0, "Error doing stat on file '%s'\n",
+ printerr(0, "Error doing stat on '%s'\n",
statname);
free(namelist[i]);
continue;
}
/* Only pick caches owned by the user (uid) */
if (tmp_stat.st_uid != uid) {
- printerr(3, "CC file '%s' owned by %u, not %u\n",
+ printerr(3, "CC '%s' owned by %u, not %u\n",
statname, tmp_stat.st_uid, uid);
free(namelist[i]);
continue;
}
- if (!S_ISREG(tmp_stat.st_mode)) {
- printerr(3, "CC file '%s' is not a regular file\n",
+ if (!S_ISREG(tmp_stat.st_mode) &&
+ !S_ISDIR(tmp_stat.st_mode)) {
+ printerr(3, "CC '%s' is not a regular "
+ "file or directory\n",
statname);
free(namelist[i]);
continue;
}
if (uid == 0 && !root_uses_machine_creds &&
strstr(namelist[i]->d_name, "_machine_")) {
- printerr(3, "CC file '%s' not available to root\n",
+ printerr(3, "CC '%s' not available to root\n",
statname);
free(namelist[i]);
continue;
}
+ if (S_ISDIR(tmp_stat.st_mode)) {
+ *cctype = "DIR";
+ } else
+ if (S_ISREG(tmp_stat.st_mode)) {
+ *cctype = "FILE";
+ } else {
+ continue;
+ }
+ snprintf(buf, sizeof(buf), "%s:%s/%s", *cctype,
+ dirname, namelist[i]->d_name);
if (!query_krb5_ccache(buf, &princname, &realm)) {
- printerr(3, "CC file '%s' is expired or corrupt\n",
- statname);
+ printerr(3, "CC '%s' is expired or corrupt\n",
+ buf);
free(namelist[i]);
err = -EKEYEXPIRED;
continue;
strcmp(realm, preferred_realm) == 0)
score++;
- printerr(3, "CC file '%s'(%s@%s) passed all checks and"
+ printerr(3, "CC '%s'(%s@%s) passed all checks and"
" has mtime of %u\n",
- statname, princname, realm,
+ buf, princname, realm,
tmp_stat.st_mtime);
/*
* if more than one match is found, return the most
else {
free(namelist[i]);
}
- printerr(3, "CC file '%s/%s' is our "
+ printerr(3, "CC '%s:%s/%s' is our "
"current best match "
"with mtime of %u\n",
- dirname, best_match_dir->d_name,
+ cctype, dirname,
+ best_match_dir->d_name,
best_match_stat.st_mtime);
}
free(princname);
gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername, char *dirname)
{
char buf[MAX_NETOBJ_SZ];
+ const char *cctype;
struct dirent *d;
int err;
printerr(2, "getting credentials for client with uid %u for "
"server %s\n", uid, servername);
memset(buf, 0, sizeof(buf));
- err = gssd_find_existing_krb5_ccache(uid, dirname, &d);
+ err = gssd_find_existing_krb5_ccache(uid, dirname, &cctype, &d);
if (err)
return err;
- snprintf(buf, sizeof(buf), "FILE:%s/%s", dirname, d->d_name);
+ snprintf(buf, sizeof(buf), "%s:%s/%s", cctype, dirname, d->d_name);
free(d);
printerr(2, "using %s as credentials cache for client with "