[PATCH 3/3] cifs.upcall: try and guess the domain name on unqualified names

Jeff Layton jlayton at samba.org
Sun Nov 13 18:17:28 MST 2011


Resolve the unqualified hostname and set AI_CANONNAME to make sure that
field is populated. Scan forward to the first '.' in ai_canonname, and
append that value onto the unqualified hostname to get a FQDN. Then
prepend that value with "cifs/" and try to get a service ticket for
that principal. If that fails prepend with "host/" and try again.

Signed-off-by: Jeff Layton <jlayton at samba.org>
---
 cifs.upcall.c |   50 ++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 44 insertions(+), 6 deletions(-)

diff --git a/cifs.upcall.c b/cifs.upcall.c
index 57ed0ba..ab3f87f 100644
--- a/cifs.upcall.c
+++ b/cifs.upcall.c
@@ -945,20 +945,58 @@ retry_new_hostname:
 			if (!rc)
 				break;
 		} else {
+			struct addrinfo hints;
+			struct addrinfo *ai;
+			char *domainname;
+
 			/* shortname: try AD-style first */
 			set_ad_principal(princ, host);
 			rc = handle_krb5_mech(oid, princ, &secblob, &sess_key, ccname);
 			if (!rc)
 				break;
 
+			/* Try to guess the DNS domain name for the host. We must */
+
 			/*
-			 * FIXME: try to guess the DNS domain name for the host. We
-			 * must require that the kernel sends the IP addr in the upcall.
-			 *
-			 * Use getaddrinfo() to resolve the hostname of the server and
-			 * set ai_canonname. Then use the domainname in ai canonname
-			 * to turn the unqualified hostname into a FQDN.
+			 * use getaddrinfo() to resolve the hostname of the server
+			 * and set ai_canonname.
 			 */
+			memset(&hints, 0, sizeof(hints));
+			hints.ai_family = AF_UNSPEC;
+			hints.ai_flags = AI_CANONNAME;
+			rc = getaddrinfo(host, NULL, &hints, &ai);
+			if (rc) {
+				syslog(LOG_ERR, "Unable to resolve host address: %s [%s]",
+				       host, gai_strerror(rc));
+				break;
+			}
+
+			/* scan forward to first '.' in ai_canonnname */
+			domainname = strchr(ai->ai_canonname, '.');
+			if (!domainname) {
+				rc = -EINVAL;
+				freeaddrinfo(ai);
+				break;
+			}
+
+			rc = snprintf(princ, sizeof(princ), "cifs/%s%s",
+					host, domainname);
+			freeaddrinfo(ai);
+			if (rc < 0 || (size_t)rc >= sizeof(princ)) {
+				syslog(LOG_ERR, "Problem setting hostname in string: %ld", rc);
+				rc = -EINVAL;
+				break;
+			}
+
+			rc = handle_krb5_mech(oid, princ, &secblob, &sess_key, ccname);
+			if (!rc)
+				break;
+
+			/* now try "host/" */
+			memcpy(princ, "host", 4);
+			rc = handle_krb5_mech(oid, princ, &secblob, &sess_key, ccname);
+			if (!rc)
+				break;
 		}
 
 		if (!try_dns || !(have & DKD_HAVE_IP))
-- 
1.7.6.4



More information about the samba-technical mailing list