#define DNOTIFY_SIGNAL (SIGRTMIN + 3)
#define GSSD_DEFAULT_CRED_DIR "/tmp"
-#define GSSD_USER_CRED_DIR "/run/user"
+#define GSSD_USER_CRED_DIR "/run/user/%U"
#define GSSD_DEFAULT_CRED_PREFIX "krb5cc"
#define GSSD_DEFAULT_MACHINE_CRED_SUFFIX "machine"
#define GSSD_DEFAULT_KEYTAB_FILE "/etc/krb5.keytab"
.B -d directory
Tells
.B rpc.gssd
-where to look for Kerberos credential files. The default value is "/tmp".
-This can also be a colon separated list of directories to be searched
-for Kerberos credential files. Note that if machine credentials are being
+where to look for Kerberos credential files. The default value is
+"/tmp:/run/user/%U".
+This can also be a colon separated list of directories to be searched for
+Kerberos credential files. The sequence "%U", if used, is replaced with
+the UID of the user for whom credentials are being searched.
+Note that if machine credentials are being
stored in files, then the first directory on this list is where the
machine credentials are stored.
.TP
goto out;
}
-static char *
-user_cachedir(char *dirname, uid_t uid)
-{
- struct passwd *pw;
- char *ptr;
-
- if ((pw = getpwuid(uid)) == NULL) {
- printerr(0, "user_cachedir: Failed to find '%d' uid"
- " for cache directory\n");
- return NULL;
- }
- ptr = malloc(strlen(dirname)+strlen(pw->pw_name)+2);
- if (ptr)
- sprintf(ptr, "%s/%s", dirname, pw->pw_name);
-
- return ptr;
-}
/*
* this code uses the userland rpcsec gss library to create a krb5
* context on behalf of the kernel
gss_buffer_desc token;
char **credlist = NULL;
char **ccname;
- char **dirname, *dir, *userdir;
+ char **dirname;
int create_resp = -1;
int err, downcall_err = -EACCES;
service == NULL)) {
/* Tell krb5 gss which credentials cache to use */
for (dirname = ccachesearch; *dirname != NULL; dirname++) {
- /* See if the user name is needed */
- if (strncmp(*dirname, GSSD_USER_CRED_DIR,
- strlen(GSSD_USER_CRED_DIR)) == 0) {
- userdir = user_cachedir(*dirname, uid);
- if (userdir == NULL)
- continue;
- dir = userdir;
- } else
- dir = *dirname;
-
- err = gssd_setup_krb5_user_gss_ccache(uid, clp->servername, dir);
-
- if (userdir) {
- free(userdir);
- userdir = NULL;
- }
+ err = gssd_setup_krb5_user_gss_ccache(uid, clp->servername, *dirname);
if (err == -EKEYEXPIRED)
downcall_err = -EKEYEXPIRED;
else if (!err)
* Returns 0 if a ccache was found, and a non-zero error code otherwise.
*/
int
-gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername, char *dirname)
+gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername, char *dirpattern)
{
- char buf[MAX_NETOBJ_SZ];
+ char buf[MAX_NETOBJ_SZ], dirname[PATH_MAX];
const char *cctype;
struct dirent *d;
- int err;
+ int err, i, j;
printerr(2, "getting credentials for client with uid %u for "
"server %s\n", uid, servername);
- memset(buf, 0, sizeof(buf));
+
+ for (i = 0, j = 0; dirpattern[i] != '\0'; i++) {
+ switch (dirpattern[i]) {
+ case '%':
+ switch (dirpattern[i + 1]) {
+ case '%':
+ dirname[j++] = dirpattern[i];
+ i++;
+ break;
+ case 'U':
+ j += sprintf(dirname + j, "%lu",
+ (unsigned long) uid);
+ i++;
+ break;
+ }
+ break;
+ default:
+ dirname[j++] = dirpattern[i];
+ break;
+ }
+ }
+ dirname[j] = '\0';
+
err = gssd_find_existing_krb5_ccache(uid, dirname, &cctype, &d);
if (err)
return err;