[linux-cifs-client] Unable to mount CIFS with kerberos security

Suresh Jayaraman sjayaraman at suse.de
Thu Jan 29 13:34:16 GMT 2009


Jeff Layton wrote:
> On Tue, 27 Jan 2009 18:29:00 +0530

>> (using IP)
>> #kinit Administrator
>> #mount -t cifs -o //164.99.99.182/Winshare /mnt/cifs -o
>> user=Administrator,sec=krb5i
>>
>> fails.
>>
>> I enabled CifsFYI o/p and the only difference I see is:
>>
>> (with hostname)
>> fs/cifs/cifs_spnego.c: key description =
>> ver=0x2;host=myserver;ip4=164.99.99.182;sec=mskrb5;uid=0x0;user=Administrator
>> (with IP)
>> fs/cifs/cifs_spnego.c: key description =
>> ver=0x2;host=164.99.99.182;ip4=164.99.99.182;sec=mskrb5;uid=0x0;user=Administrator
>>
>> * note "host=" parameter ^^^ it contains value of IP, when we use IP to
>> mount. May be this is the problem, passing down ip as "host=" down to
>> request_key() ?
>>
>> In CIFS_SessSetup
>> 	spnego_key = cifs_get_spnego_key(ses);
>>
>> fails and returns error -126
> 
> The upcall program needs some way to know what cifs or host principal to look
> for. When it just has an IP address to go on, then it often doesn't have a
> way to know. To fix this, we'll need to fix cifs.upcall to be able to make
> better guesses as to the hostname when we try to get the SPNEGO key.
> 
> Patches welcome.
> 

Something like this..
(quick hack just to ensure I get your hint correct - 
untested as my setup is goofed up)



Index: source/client/cifs.upcall.c
===================================================================
--- source/client/cifs.upcall.c.orig
+++ source/client/cifs.upcall.c
@@ -27,6 +27,7 @@ create dns_resolver * * /usr/local/sbin/
 #include "includes.h"
 #include <keyutils.h>
 
+
 #include "cifs_spnego.h"
 
 const char *CIFSSPNEGO_VERSION = "1.2";
@@ -113,6 +114,59 @@ decode_key_description(const char *desc,
 			*hostname = SMB_XMALLOC_ARRAY(char, len);
 			strlcpy(*hostname, tkn + 5, len);
 			retval |= DKD_HAVE_HOSTNAME;
+			/* May be it's an IP address?
+			 * request_key() might fail if we pass it down,
+			 * so attempt to lookup the hostname.
+			 */
+			if (is_ipaddress(*hostname)) {
+				struct sockaddr_storage ss;
+				struct sockaddr *addr;
+				socklen_t length;
+				char *hp = *hostname;
+				char host[MAX_DNS_NAME_LENGTH];
+
+				addr = (struct sockaddr *)&ss;
+
+				/* IPv4 */
+				if (is_ipaddress_v4(*hostname)) {
+					struct sockaddr_in addr4;
+					length = sizeof(addr4);
+
+					if (inet_pton(AF_INET, hp, &addr4.sin_addr) <= 0) {
+						syslog(LOG_WARNING, "cifs.upcall: error converting hostname to IP address");
+						return -1;
+					}
+					addr4.sin_family = AF_INET;
+					addr4.sin_port = 0;
+					if (!getnameinfo((struct sockaddr *)&addr4,
+							length, host,
+							sizeof(host), NULL, 0, 0))
+						syslog(LOG_WARNING, "hostname is %s", host);
+					else
+						syslog(LOG_WARNING, "getnameinfo() failed");
+				} else { /* IPv6 */
+					struct sockaddr_in6 addr6;
+					length = sizeof(addr6);
+
+					if (inet_pton(AF_INET6, hp, &addr6.sin6_addr) <= 0) {
+						syslog(LOG_WARNING, "cifs.upcall: error converting hostname to IP address");
+						return -1;
+					}
+					addr6.sin6_family = AF_INET6;
+					addr6.sin6_port = 0;
+					if (!getnameinfo((struct sockaddr *)&addr6,
+							length, host,
+							sizeof(host), NULL, 0, 0))
+						syslog(LOG_WARNING, "hostname is %s", host);
+					else
+						syslog(LOG_WARNING, "getnameinfo() failed");
+				}
+
+			} else
+			syslog(LOG_WARNING, "cifs.upcall: is_ipaddress() block skipped");
+
+			/* BB: do we need to err if we don't get hostname if IP
+			 * address and krb5 if used? */
 		} else if (strncmp(tkn, "ipv4=", 5) == 0) {
 			/* BB: do we need it if we have hostname already? */
 		} else if (strncmp(tkn, "ipv6=", 5) == 0) {


-- 
Suresh Jayaraman


More information about the linux-cifs-client mailing list