[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