From patchwork Wed Dec 22 19:22:27 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Gunthorpe X-Patchwork-Id: 428371 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id oBMJKLD3019373 for ; Wed, 22 Dec 2010 19:22:30 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750869Ab0LVTWa (ORCPT ); Wed, 22 Dec 2010 14:22:30 -0500 Received: from quartz.orcorp.ca ([139.142.54.143]:41747 "EHLO quartz.orcorp.ca" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750835Ab0LVTW3 (ORCPT ); Wed, 22 Dec 2010 14:22:29 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=obsidianresearch.com; s=rsa1; h=Content-Type:MIME-Version:Message-ID:Subject:To:From:Date; bh=11u3+lESMn/i5xE9RzwZEtKHmuw+A6BJJAJ9B1d/PNo=; b=t3iSoLLnmwZyIOt8bff7G6RoebQF/+6aFb1rYC0zn5aLiyuyEUQnsB6HJBSwskPlkREXrw5eE5YMdZnYhGHU0wJi6eLuTRBljWZotW1O0BwKhCn/xniR6BNzEdNPGD9W09OV4CwraPaZLyodJNef83OEmSuTpDYq0Vgxh3cfZBY=; Received: from [10.0.0.11] (helo=jggl.edm.orcorp.ca) by quartz.orcorp.ca with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.72) (envelope-from ) id 1PVUGa-0005W0-3r for linux-nfs@vger.kernel.org; Wed, 22 Dec 2010 12:22:28 -0700 Received: from jgg by jggl.edm.orcorp.ca with local (Exim 4.72) (envelope-from ) id 1PVUGZ-0008Bn-PD for linux-nfs@vger.kernel.org; Wed, 22 Dec 2010 12:22:27 -0700 Date: Wed, 22 Dec 2010 12:22:27 -0700 From: Jason Gunthorpe To: linux-nfs@vger.kernel.org Subject: [PATCH] Support AD style kerberos automatically in rpc.gss Message-ID: <20101222192227.GA31112@obsidianresearch.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) X-Broken-Reverse-DNS: no host name found for IP address 10.0.0.11 Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Wed, 22 Dec 2010 19:22:30 +0000 (UTC) diff --git a/utils/gssd/gssd.man b/utils/gssd/gssd.man index 0a23cd6..073379d 100644 --- a/utils/gssd/gssd.man +++ b/utils/gssd/gssd.man @@ -53,6 +53,8 @@ To be more consistent with other implementations, we now look for specific keytab entries. The search order for keytabs to be used for "machine credentials" is now: .br + $@ +.br root/@ .br nfs/@ @@ -64,6 +66,9 @@ for "machine credentials" is now: nfs/@ .br host/@ +.IP +If this search order does not use the correct key then provide a +keytab file that contains only correct keys. .TP .B -p path Tells diff --git a/utils/gssd/krb5_util.c b/utils/gssd/krb5_util.c index f071600..4b13fa1 100644 --- a/utils/gssd/krb5_util.c +++ b/utils/gssd/krb5_util.c @@ -768,6 +768,7 @@ find_keytab_entry(krb5_context context, krb5_keytab kt, const char *hostname, krb5_error_code code; char **realmnames = NULL; char myhostname[NI_MAXHOST], targethostname[NI_MAXHOST]; + char myhostad[NI_MAXHOST+1]; int i, j, retval; char *default_realm = NULL; char *realm; @@ -789,6 +790,14 @@ find_keytab_entry(krb5_context context, krb5_keytab kt, const char *hostname, printerr(1, "%s while getting local hostname\n", k5err); goto out; } + + /* Compute the active directory machine name HOST$ */ + strcpy(myhostad, myhostname); + for (i = 0; myhostad[i] != 0; ++i) + myhostad[i] = toupper(myhostad[i]); + myhostad[i] = '$'; + myhostad[i+1] = 0; + retval = get_full_hostname(myhostname, myhostname, sizeof(myhostname)); if (retval) goto out; @@ -833,32 +842,47 @@ find_keytab_entry(krb5_context context, krb5_keytab kt, const char *hostname, if (strcmp(realm, default_realm) == 0) tried_default = 1; for (j = 0; svcnames[j] != NULL; j++) { - code = krb5_build_principal_ext(context, &princ, - strlen(realm), - realm, - strlen(svcnames[j]), - svcnames[j], - strlen(myhostname), - myhostname, - NULL); + char spn[300]; + + /* + * The special svcname "$" means 'try the active + * directory machine account' + */ + if (strcmp(svcnames[j],"$") == 0) { + snprintf(spn, sizeof(spn), "%s@%s", myhostad, realm); + code = krb5_build_principal_ext(context, &princ, + strlen(realm), + realm, + strlen(myhostad), + myhostad, + NULL); + } else { + snprintf(spn, sizeof(spn), "%s/%s@%s", + svcnames[j], myhostname, realm); + code = krb5_build_principal_ext(context, &princ, + strlen(realm), + realm, + strlen(svcnames[j]), + svcnames[j], + strlen(myhostname), + myhostname, + NULL); + } + if (code) { k5err = gssd_k5_err_msg(context, code); - printerr(1, "%s while building principal for " - "'%s/%s@%s'\n", k5err, svcnames[j], - myhostname, realm); + printerr(1, "%s while building principal for '%s'\n", + k5err, spn); continue; } code = krb5_kt_get_entry(context, kt, princ, 0, 0, kte); krb5_free_principal(context, princ); if (code) { k5err = gssd_k5_err_msg(context, code); - printerr(3, "%s while getting keytab entry for " - "'%s/%s@%s'\n", k5err, svcnames[j], - myhostname, realm); + printerr(3, "%s while getting keytab entry for '%s'\n", + k5err, spn); } else { - printerr(3, "Success getting keytab entry for " - "'%s/%s@%s'\n", - svcnames[j], myhostname, realm); + printerr(3, "Success getting keytab entry for '%s'\n",spn); retval = 0; goto out; } @@ -870,6 +894,8 @@ find_keytab_entry(krb5_context context, krb5_keytab kt, const char *hostname, */ for (j = 0; svcnames[j] != NULL; j++) { int found = 0; + if (strcmp(svcnames[j],"$") == 0) + continue; code = gssd_search_krb5_keytab(context, kt, realm, svcnames[j], &found, kte); if (!code && found) { @@ -1160,7 +1186,7 @@ gssd_refresh_krb5_machine_credential(char *hostname, krb5_keytab kt = NULL;; int retval = 0; char *k5err = NULL; - const char *svcnames[4] = { "root", "nfs", "host", NULL }; + const char *svcnames[5] = { "$", "root", "nfs", "host", NULL }; /* * If a specific service name was specified, use it.