summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--utils/gssd/gssd.c14
-rw-r--r--utils/gssd/gssd.h1
-rw-r--r--utils/gssd/gssd.man26
-rw-r--r--utils/gssd/gssd_proc.c82
4 files changed, 69 insertions, 54 deletions
diff --git a/utils/gssd/gssd.c b/utils/gssd/gssd.c
index 9988fe4..319dca4 100644
--- a/utils/gssd/gssd.c
+++ b/utils/gssd/gssd.c
@@ -57,12 +57,14 @@ char pipefsdir[PATH_MAX] = GSSD_PIPEFS_DIR;
char keytabfile[PATH_MAX] = GSSD_DEFAULT_KEYTAB_FILE;
char ccachedir[PATH_MAX] = GSSD_DEFAULT_CRED_DIR;
int use_memcache = 0;
+int root_uses_machine_creds = 1;
void
sig_die(int signal)
{
/* destroy krb5 machine creds */
- gssd_destroy_krb5_machine_creds();
+ if (root_uses_machine_creds)
+ gssd_destroy_krb5_machine_creds();
printerr(1, "exiting on signal %d\n", signal);
exit(1);
}
@@ -78,7 +80,7 @@ sig_hup(int signal)
static void
usage(char *progname)
{
- fprintf(stderr, "usage: %s [-f] [-v] [-r] [-p pipefsdir] [-k keytab] [-d ccachedir]\n",
+ fprintf(stderr, "usage: %s [-f] [-n] [-v] [-r] [-p pipefsdir] [-k keytab] [-d ccachedir]\n",
progname);
exit(1);
}
@@ -93,7 +95,7 @@ main(int argc, char *argv[])
extern char *optarg;
char *progname;
- while ((opt = getopt(argc, argv, "fvrmMp:k:d:")) != -1) {
+ while ((opt = getopt(argc, argv, "fvrmnMp:k:d:")) != -1) {
switch (opt) {
case 'f':
fg = 1;
@@ -104,6 +106,9 @@ main(int argc, char *argv[])
case 'M':
use_memcache = 1;
break;
+ case 'n':
+ root_uses_machine_creds = 0;
+ break;
case 'v':
verbosity++;
break;
@@ -160,7 +165,8 @@ main(int argc, char *argv[])
signal(SIGHUP, sig_hup);
/* Process keytab file and get machine credentials */
- gssd_refresh_krb5_machine_creds();
+ if (root_uses_machine_creds)
+ gssd_refresh_krb5_machine_creds();
gssd_run();
printerr(0, "gssd_run returned!\n");
diff --git a/utils/gssd/gssd.h b/utils/gssd/gssd.h
index ec91e89..3622b48 100644
--- a/utils/gssd/gssd.h
+++ b/utils/gssd/gssd.h
@@ -62,6 +62,7 @@ extern char pipefsdir[PATH_MAX];
extern char keytabfile[PATH_MAX];
extern char ccachedir[PATH_MAX];
extern int use_memcache;
+extern int root_uses_machine_creds;
TAILQ_HEAD(clnt_list_head, clnt_info) clnt_list;
diff --git a/utils/gssd/gssd.man b/utils/gssd/gssd.man
index 250d26f..1a30d69 100644
--- a/utils/gssd/gssd.man
+++ b/utils/gssd/gssd.man
@@ -2,11 +2,11 @@
.\" rpc.gssd(8)
.\"
.\" Copyright (C) 2003 J. Bruce Fields <bfields@umich.edu>
-.TH rpc.gssd 8 "17 Mar 2003"
+.TH rpc.gssd 8 "14 Mar 2007"
.SH NAME
rpc.gssd \- rpcsec_gss daemon
.SH SYNOPSIS
-.B "rpc.gssd [-f] [-k keytab] [-p pipefsdir] [-v] [-r] [-d ccachedir]"
+.B "rpc.gssd [-f] [-n] [-k keytab] [-p pipefsdir] [-v] [-r] [-d ccachedir]"
.SH DESCRIPTION
The rpcsec_gss protocol gives a means of using the gss-api generic security
api to provide security for protocols using rpc (in particular, nfs). Before
@@ -25,6 +25,19 @@ Runs
.B rpc.gssd
in the foreground and sends output to stderr (as opposed to syslogd)
.TP
+.B -n
+By default,
+.B rpc.gssd
+treats accesses by the user with UID 0 specially, and uses
+"machine credentials" for all accesses by that user which
+require Kerberos authentication.
+With the \-n option, "machine credentials" will not be used
+for accesses by UID 0. Instead, credentials must be obtained
+manually like all other users. Use of this option means that
+"root" must manually obtain Kerberos credentials before
+attemtpting to mount an nfs filesystem requiring Kerberos
+authentication.
+.TP
.B -k keytab
Tells
.B rpc.gssd
@@ -32,15 +45,6 @@ to use the keys for principals nfs/hostname in
.I keytab
to obtain machine credentials.
The default value is "/etc/krb5.keytab".
-.\".TP
-.\".B -m
-.\"Ordinarily,
-.\".B rpc.gssd
-.\"looks for a cached ticket for user $UID in /tmp/krb5cc_$UID.
-.\"With the -m option, the user with uid 0 will be treated specially, and will
-.\"be mapped instead to the credentials for the principal nfs/hostname found in
-.\"the keytab file.
-.\"(This option is now the default and is ignored if specified.)
.TP
.B -p path
Tells
diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c
index 68d645d..04de4e6 100644
--- a/utils/gssd/gssd_proc.c
+++ b/utils/gssd/gssd_proc.c
@@ -675,6 +675,7 @@ handle_krb5_upcall(struct clnt_info *clp)
gss_buffer_desc token;
char **credlist = NULL;
char **ccname;
+ int create_resp = -1;
printerr(1, "handling krb5 upcall\n");
@@ -688,49 +689,52 @@ handle_krb5_upcall(struct clnt_info *clp)
goto out;
}
- if (uid == 0) {
- int success = 0;
-
- /*
- * Get a list of credential cache names and try each
- * of them until one works or we've tried them all
- */
- if (gssd_get_krb5_machine_cred_list(&credlist)) {
- printerr(0, "WARNING: Failed to obtain machine "
- "credentials for connection to "
- "server %s\n", clp->servername);
- goto out_return_error;
- }
- for (ccname = credlist; ccname && *ccname; ccname++) {
- gssd_setup_krb5_machine_gss_ccache(*ccname);
- if ((create_auth_rpc_client(clp, &rpc_clnt, &auth, uid,
- AUTHTYPE_KRB5)) == 0) {
- /* Success! */
- success++;
- break;
- }
- printerr(2, "WARNING: Failed to create krb5 context "
- "for user with uid %d with credentials "
- "cache %s for server %s\n",
- uid, *ccname, clp->servername);
- }
- gssd_free_krb5_machine_cred_list(credlist);
- if (!success) {
- printerr(0, "WARNING: Failed to create krb5 context "
- "for user with uid %d with any "
- "credentials cache for server %s\n",
- uid, clp->servername);
- goto out_return_error;
- }
- }
- else {
+ 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);
- if ((create_auth_rpc_client(clp, &rpc_clnt, &auth, uid,
- AUTHTYPE_KRB5)) != 0) {
+ create_resp = create_auth_rpc_client(clp, &rpc_clnt, &auth, uid,
+ AUTHTYPE_KRB5);
+ }
+ if (create_resp != 0) {
+ if (uid == 0 && root_uses_machine_creds == 1) {
+ int success = 0;
+
+ /*
+ * Get a list of credential cache names and try each
+ * of them until one works or we've tried them all
+ */
+ if (gssd_get_krb5_machine_cred_list(&credlist)) {
+ printerr(0, "WARNING: Failed to obtain machine "
+ "credentials for connection to "
+ "server %s\n", clp->servername);
+ goto out_return_error;
+ }
+ for (ccname = credlist; ccname && *ccname; ccname++) {
+ gssd_setup_krb5_machine_gss_ccache(*ccname);
+ if ((create_auth_rpc_client(clp, &rpc_clnt,
+ &auth, uid,
+ AUTHTYPE_KRB5)) == 0) {
+ /* Success! */
+ success++;
+ break;
+ }
+ printerr(2, "WARNING: Failed to create krb5 context "
+ "for user with uid %d with credentials "
+ "cache %s for server %s\n",
+ uid, *ccname, clp->servername);
+ }
+ gssd_free_krb5_machine_cred_list(credlist);
+ if (!success) {
+ printerr(0, "WARNING: Failed to create krb5 context "
+ "for user with uid %d with any "
+ "credentials cache for server %s\n",
+ uid, clp->servername);
+ goto out_return_error;
+ }
+ } else {
printerr(0, "WARNING: Failed to create krb5 context "
- "for user with uid %d for server %s\n",
+ "for user with uid %d for server %s\n",
uid, clp->servername);
goto out_return_error;
}