Newer versions of systemd create a /run/user/${UID} directory
instead of the /run/user/${USER} directory, so switch to
scanning for that. To make the per-user directory bit a little
less magical, change the default to incorporate a "%U", which
gets dynamically expanded to the user's UID when needed.
Signed-off-by: Steve Dickson <steved@redhat.com>
#define DNOTIFY_SIGNAL (SIGRTMIN + 3)
#define GSSD_DEFAULT_CRED_DIR "/tmp"
#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"
#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
.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
stored in files, then the first directory on this list is where the
machine credentials are stored.
.TP
-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
/*
* 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;
gss_buffer_desc token;
char **credlist = NULL;
char **ccname;
- char **dirname, *dir, *userdir;
int create_resp = -1;
int err, downcall_err = -EACCES;
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++) {
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)
if (err == -EKEYEXPIRED)
downcall_err = -EKEYEXPIRED;
else if (!err)
* Returns 0 if a ccache was found, and a non-zero error code otherwise.
*/
int
* 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;
const char *cctype;
struct dirent *d;
printerr(2, "getting credentials for client with uid %u for "
"server %s\n", uid, servername);
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;
err = gssd_find_existing_krb5_ccache(uid, dirname, &cctype, &d);
if (err)
return err;