possible to search several directories for valid credentials when
making NFS requests.
Original patch from Vince Busam <vbusam@google.com>
Signed-off-by: Kevin Coffman <kwc@citi.umich.edu>.
Signed-off-by: Steve Dickson <steved@redhat.com>
char pipefs_nfsdir[PATH_MAX] = GSSD_PIPEFS_DIR;
char keytabfile[PATH_MAX] = GSSD_DEFAULT_KEYTAB_FILE;
char ccachedir[PATH_MAX] = GSSD_DEFAULT_CRED_DIR;
char pipefs_nfsdir[PATH_MAX] = GSSD_PIPEFS_DIR;
char keytabfile[PATH_MAX] = GSSD_DEFAULT_KEYTAB_FILE;
char ccachedir[PATH_MAX] = GSSD_DEFAULT_CRED_DIR;
+char *ccachesearch[GSSD_MAX_CCACHE_SEARCH + 1];
int use_memcache = 0;
int root_uses_machine_creds = 1;
int use_memcache = 0;
int root_uses_machine_creds = 1;
int verbosity = 0;
int rpc_verbosity = 0;
int opt;
int verbosity = 0;
int rpc_verbosity = 0;
int opt;
extern char *optarg;
char *progname;
extern char *optarg;
char *progname;
+ memset(ccachesearch, 0, sizeof(ccachesearch));
while ((opt = getopt(argc, argv, "fvrmnMp:k:d:")) != -1) {
switch (opt) {
case 'f':
while ((opt = getopt(argc, argv, "fvrmnMp:k:d:")) != -1) {
switch (opt) {
case 'f':
+
+ i = 0;
+ ccachesearch[i++] = strtok(ccachedir, ":");
+ do {
+ ccachesearch[i++] = strtok(NULL, ":");
+ } while (ccachesearch[i-1] != NULL && i < GSSD_MAX_CCACHE_SEARCH);
+
snprintf(pipefs_nfsdir, sizeof(pipefs_nfsdir), "%s/%s",
pipefs_dir, GSSD_SERVICE_NAME);
if (pipefs_nfsdir[sizeof(pipefs_nfsdir)-1] != '\0')
snprintf(pipefs_nfsdir, sizeof(pipefs_nfsdir), "%s/%s",
pipefs_dir, GSSD_SERVICE_NAME);
if (pipefs_nfsdir[sizeof(pipefs_nfsdir)-1] != '\0')
#define GSSD_DEFAULT_KEYTAB_FILE "/etc/krb5.keytab"
#define GSSD_SERVICE_NAME "nfs"
#define GSSD_SERVICE_NAME_LEN 3
#define GSSD_DEFAULT_KEYTAB_FILE "/etc/krb5.keytab"
#define GSSD_SERVICE_NAME "nfs"
#define GSSD_SERVICE_NAME_LEN 3
+#define GSSD_MAX_CCACHE_SEARCH 16
/*
* The gss mechanisms that we can handle
/*
* The gss mechanisms that we can handle
extern char pipefs_dir[PATH_MAX];
extern char pipefs_nfsdir[PATH_MAX];
extern char keytabfile[PATH_MAX];
extern char pipefs_dir[PATH_MAX];
extern char pipefs_nfsdir[PATH_MAX];
extern char keytabfile[PATH_MAX];
-extern char ccachedir[PATH_MAX];
+extern char *ccachesearch[];
extern int use_memcache;
extern int root_uses_machine_creds;
extern int use_memcache;
extern int root_uses_machine_creds;
.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".
+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
+stored in files, then the first directory on this list is where the
+machine credentials are stored.
.TP
.B -v
Increases the verbosity of the output (can be specified multiple times).
.TP
.B -v
Increases the verbosity of the output (can be specified multiple times).
gss_buffer_desc token;
char **credlist = NULL;
char **ccname;
gss_buffer_desc token;
char **credlist = NULL;
char **ccname;
int create_resp = -1;
printerr(1, "handling krb5 upcall\n");
int create_resp = -1;
printerr(1, "handling krb5 upcall\n");
if (uid != 0 || (uid == 0 && root_uses_machine_creds == 0)) {
/* Tell krb5 gss which credentials cache to use */
if (uid != 0 || (uid == 0 && root_uses_machine_creds == 0)) {
/* Tell krb5 gss which credentials cache to use */
- gssd_setup_krb5_user_gss_ccache(uid, clp->servername);
+ for (dirname = ccachesearch; *dirname != NULL; dirname++) {
+ gssd_setup_krb5_user_gss_ccache(uid, clp->servername, *dirname);
- create_resp = create_auth_rpc_client(clp, &rpc_clnt, &auth, uid,
- AUTHTYPE_KRB5);
+ create_resp = create_auth_rpc_client(clp, &rpc_clnt, &auth, uid,
+ AUTHTYPE_KRB5);
+ if (create_resp == 0)
+ break;
+ }
}
if (create_resp != 0) {
if (uid == 0 && root_uses_machine_creds == 1) {
}
if (create_resp != 0) {
if (uid == 0 && root_uses_machine_creds == 1) {
/*==========================*/
static int select_krb5_ccache(const struct dirent *d);
/*==========================*/
static int select_krb5_ccache(const struct dirent *d);
-static int gssd_find_existing_krb5_ccache(uid_t uid, struct dirent **d);
+static int gssd_find_existing_krb5_ccache(uid_t uid, char *dirname,
+ struct dirent **d);
static int gssd_get_single_krb5_cred(krb5_context context,
krb5_keytab kt, struct gssd_k5_kt_princ *ple);
static int gssd_get_single_krb5_cred(krb5_context context,
krb5_keytab kt, struct gssd_k5_kt_princ *ple);
- * Look in the ccachedir for files that look like they
+ * Look in directory "dirname" for files that look like they
* are Kerberos Credential Cache files for a given UID. Return
* non-zero and the dirent pointer for the entry most likely to be
* what we want. Otherwise, return zero and no dirent pointer.
* are Kerberos Credential Cache files for a given UID. Return
* non-zero and the dirent pointer for the entry most likely to be
* what we want. Otherwise, return zero and no dirent pointer.
* 1 => found an existing entry
*/
static int
* 1 => found an existing entry
*/
static int
-gssd_find_existing_krb5_ccache(uid_t uid, struct dirent **d)
+gssd_find_existing_krb5_ccache(uid_t uid, char *dirname, struct dirent **d)
{
struct dirent **namelist;
int n;
{
struct dirent **namelist;
int n;
memset(&best_match_stat, 0, sizeof(best_match_stat));
*d = NULL;
memset(&best_match_stat, 0, sizeof(best_match_stat));
*d = NULL;
- n = scandir(ccachedir, &namelist, select_krb5_ccache, 0);
+ n = scandir(dirname, &namelist, select_krb5_ccache, 0);
- perror("scandir looking for krb5 credentials caches");
+ printerr(1, "Error doing scandir on directory '%s': %s\n",
+ dirname, strerror(errno));
}
else if (n > 0) {
char statname[1024];
}
else if (n > 0) {
char statname[1024];
printerr(3, "CC file '%s' being considered\n",
namelist[i]->d_name);
snprintf(statname, sizeof(statname),
printerr(3, "CC file '%s' being considered\n",
namelist[i]->d_name);
snprintf(statname, sizeof(statname),
- "%s/%s", ccachedir, namelist[i]->d_name);
+ "%s/%s", dirname, namelist[i]->d_name);
if (lstat(statname, &tmp_stat)) {
printerr(0, "Error doing stat on file '%s'\n",
statname);
if (lstat(statname, &tmp_stat)) {
printerr(0, "Error doing stat on file '%s'\n",
statname);
&credh, NULL, NULL);
if (maj_stat != GSS_S_COMPLETE) {
&credh, NULL, NULL);
if (maj_stat != GSS_S_COMPLETE) {
- pgsserr("gss_acquire_cred",
- maj_stat, min_stat, &krb5oid);
+ if (get_verbosity() > 0)
+ pgsserr("gss_acquire_cred",
+ maj_stat, min_stat, &krb5oid);
cache_type = "FILE";
snprintf(cc_name, sizeof(cc_name), "%s:%s/%s%s_%s",
cache_type,
cache_type = "FILE";
snprintf(cc_name, sizeof(cc_name), "%s:%s/%s%s_%s",
cache_type,
- ccachedir, GSSD_DEFAULT_CRED_PREFIX,
+ ccachesearch[0], GSSD_DEFAULT_CRED_PREFIX,
GSSD_DEFAULT_MACHINE_CRED_SUFFIX, ple->realm);
ple->endtime = my_creds.times.endtime;
if (ple->ccname != NULL)
GSSD_DEFAULT_MACHINE_CRED_SUFFIX, ple->realm);
ple->endtime = my_creds.times.endtime;
if (ple->ccname != NULL)
-gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername)
+gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername, char *dirname)
{
char buf[MAX_NETOBJ_SZ];
struct dirent *d;
{
char buf[MAX_NETOBJ_SZ];
struct dirent *d;
printerr(2, "getting credentials for client with uid %u for "
"server %s\n", uid, servername);
memset(buf, 0, sizeof(buf));
printerr(2, "getting credentials for client with uid %u for "
"server %s\n", uid, servername);
memset(buf, 0, sizeof(buf));
- if (gssd_find_existing_krb5_ccache(uid, &d)) {
- snprintf(buf, sizeof(buf), "FILE:%s/%s",
- ccachedir, d->d_name);
+ if (gssd_find_existing_krb5_ccache(uid, dirname, &d)) {
+ snprintf(buf, sizeof(buf), "FILE:%s/%s", dirname, d->d_name);
free(d);
}
else
snprintf(buf, sizeof(buf), "FILE:%s/%s%u",
free(d);
}
else
snprintf(buf, sizeof(buf), "FILE:%s/%s%u",
- ccachedir, GSSD_DEFAULT_CRED_PREFIX, uid);
+ dirname, GSSD_DEFAULT_CRED_PREFIX, uid);
printerr(2, "using %s as credentials cache for client with "
"uid %u for server %s\n", buf, uid, servername);
gssd_set_krb5_ccache_name(buf);
printerr(2, "using %s as credentials cache for client with "
"uid %u for server %s\n", buf, uid, servername);
gssd_set_krb5_ccache_name(buf);
-void gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername);
+void gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername,
+ char *dirname);
int gssd_get_krb5_machine_cred_list(char ***list);
void gssd_free_krb5_machine_cred_list(char **list);
void gssd_setup_krb5_machine_gss_ccache(char *servername);
int gssd_get_krb5_machine_cred_list(char ***list);
void gssd_free_krb5_machine_cred_list(char **list);
void gssd_setup_krb5_machine_gss_ccache(char *servername);