diff options
author | Olga Kornievskaia <aglo@citi.umich.edu> | 2009-11-16 09:44:03 -0500 |
---|---|---|
committer | Steve Dickson <steved@redhat.com> | 2009-11-16 09:44:03 -0500 |
commit | dd31301d485b4244b1b35049f6917df907997da9 (patch) | |
tree | 7d6dbc4ada3bb8f3e713d05a5981c0ee9522f729 /utils/gssd/krb5_util.c | |
parent | 421406ee159fa27cca1a150600cfc321bbbe33f5 (diff) | |
download | nfs-utils-dd31301d485b4244b1b35049f6917df907997da9.tar.gz nfs-utils-dd31301d485b4244b1b35049f6917df907997da9.tar.xz nfs-utils-dd31301d485b4244b1b35049f6917df907997da9.zip |
gssd: process service= attribute in new upcall
Add processing of the "service=" attribute in the new gssd upcall.
If "service" is specified, then the kernel is indicating that
we must use machine credentials for this request. (Regardless
of the uid value or the setting of root_uses_machine_creds.)
If the service value is "*", then any service name can be used.
Otherwise, it specifies the service name that should be used.
(For now, the values of service will only be "*" or "nfs".)
Restricting gssd to use "nfs" service name is needed for when
the NFS server is doing a callback to the NFS client. In this
case, the NFS server has to authenticate itself as "nfs" --
even if there are other service keys such as "host" or "root"
in the keytab.
Another case when the kernel may specify the service attribute
is when gssd is being asked to create the context for a
SETCLIENT_ID operation. In this case, machine credentials
must be used for the authentication. However, the service name
used for this case is not important.
Signed-off-by: Olga Kornievskaia <aglo@citi.umich.edu>
Signed-off-by: Kevin Coffman <kwc@citi.umich.edu>
Signed-off-by: Steve Dickson <steved@redhat.com>
Diffstat (limited to 'utils/gssd/krb5_util.c')
-rw-r--r-- | utils/gssd/krb5_util.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/utils/gssd/krb5_util.c b/utils/gssd/krb5_util.c index 78e9775..c3c131b 100644 --- a/utils/gssd/krb5_util.c +++ b/utils/gssd/krb5_util.c @@ -797,10 +797,9 @@ gssd_search_krb5_keytab(krb5_context context, krb5_keytab kt, */ static int find_keytab_entry(krb5_context context, krb5_keytab kt, const char *hostname, - krb5_keytab_entry *kte) + krb5_keytab_entry *kte, const char **svcnames) { krb5_error_code code; - const char *svcnames[] = { "root", "nfs", "host", NULL }; char **realmnames = NULL; char myhostname[NI_MAXHOST], targethostname[NI_MAXHOST]; int i, j, retval; @@ -1096,7 +1095,8 @@ gssd_get_krb5_machine_cred_list(char ***list) for (ple = gssd_k5_kt_princ_list; ple; ple = ple->next) { if (ple->ccname) { /* Make sure cred is up-to-date before returning it */ - retval = gssd_refresh_krb5_machine_credential(NULL, ple, 0); + retval = gssd_refresh_krb5_machine_credential(NULL, ple, + NULL); if (retval) continue; if (i + 1 > listsize) { @@ -1186,14 +1186,24 @@ gssd_destroy_krb5_machine_creds(void) */ int gssd_refresh_krb5_machine_credential(char *hostname, - struct gssd_k5_kt_princ *ple, int nocache) + struct gssd_k5_kt_princ *ple, + char *service) { krb5_error_code code = 0; krb5_context context; krb5_keytab kt = NULL;; int retval = 0; char *k5err = NULL; + const char *svcnames[4] = { "root", "nfs", "host", NULL }; + /* + * If a specific service name was specified, use it. + * Otherwise, use the default list. + */ + if (service != NULL && strcmp(service, "*") != 0) { + svcnames[0] = service; + svcnames[1] = NULL; + } if (hostname == NULL && ple == NULL) return EINVAL; @@ -1216,7 +1226,7 @@ gssd_refresh_krb5_machine_credential(char *hostname, if (ple == NULL) { krb5_keytab_entry kte; - code = find_keytab_entry(context, kt, hostname, &kte); + code = find_keytab_entry(context, kt, hostname, &kte, svcnames); if (code) { printerr(0, "ERROR: %s: no usable keytab entry found " "in keytab %s for connection with host %s\n", @@ -1241,7 +1251,7 @@ gssd_refresh_krb5_machine_credential(char *hostname, goto out; } } - retval = gssd_get_single_krb5_cred(context, kt, ple, nocache); + retval = gssd_get_single_krb5_cred(context, kt, ple, 0); out: if (kt) krb5_kt_close(context, kt); |