diff options
author | Igor Mammedov <niallain@gmail.com> | 2007-12-19 17:48:43 +0300 |
---|---|---|
committer | Simo Sorce <idra@samba.org> | 2008-01-16 09:51:06 -0500 |
commit | 94fdd59f1c2a41b8e737aa8ca8939e9bf2b59a77 (patch) | |
tree | 44ce4d9643b033cd702d910b922a6403aa34dd88 /source3 | |
parent | be9b7a6414cda06b400d654f73f17327a1a6f69c (diff) | |
download | samba-94fdd59f1c2a41b8e737aa8ca8939e9bf2b59a77.tar.gz samba-94fdd59f1c2a41b8e737aa8ca8939e9bf2b59a77.tar.bz2 samba-94fdd59f1c2a41b8e737aa8ca8939e9bf2b59a77.zip |
Adds support for cifs.resolver upcall.
Here is a patch for userspace cifs.spnego handler that adds support for cifs.resolver
upcall used in DFS code.
Any comments are appreciated.
#############################
Cifs upcall with key type cifs.resolver is used for resolving
server names in handling DFS refferals.
Signed-off-by: Igor Mammedov <niallain@gmail.com>
(This used to be commit dfc80b4f1c00c131ba8077432bfe79f22f63ccd1)
Diffstat (limited to 'source3')
-rw-r--r-- | source3/client/cifs.spnego.c | 63 |
1 files changed, 61 insertions, 2 deletions
diff --git a/source3/client/cifs.spnego.c b/source3/client/cifs.spnego.c index caa22276c4..d10d19da96 100644 --- a/source3/client/cifs.spnego.c +++ b/source3/client/cifs.spnego.c @@ -3,11 +3,13 @@ * Copyright (C) Igor Mammedov (niallain@gmail.com) 2007 * * Used by /sbin/request-key for handling -* cifs upcall for kerberos authorization of access to share. +* cifs upcall for kerberos authorization of access to share and +* cifs upcall for DFS srver name resolving (IPv4/IPv6 aware). * You should have keyutils installed and add following line to * /etc/request-key.conf file create cifs.spnego * * /usr/local/sbin/cifs.spnego [-v][-c] %k +create cifs.resolver * * /usr/local/sbin/cifs.spnego [-v] %k * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,7 +29,7 @@ create cifs.spnego * * /usr/local/sbin/cifs.spnego [-v][-c] %k #include "cifs_spnego.h" -const char* CIFSSPNEGO_VERSION="1.0"; +const char *CIFSSPNEGO_VERSION = "1.1"; static const char *prog = "cifs.spnego"; typedef enum _secType { KRB5, @@ -146,6 +148,58 @@ int decode_key_description(const char *desc, int *ver, secType_t * sec, return retval; } +int cifs_resolver(const key_serial_t key, const char *key_descr) +{ + int c; + struct addrinfo *addr; + char ip[INET6_ADDRSTRLEN]; + void *p; + const char *keyend = key_descr; + /* skip next 4 ';' delimiters to get to description */ + for (c = 1; c <= 4; c++) { + keyend = index(keyend+1, ';'); + if (!keyend) { + syslog(LOG_WARNING, "invalid key description: %s", + key_descr); + return 1; + } + } + keyend++; + + /* resolve name to ip */ + c = getaddrinfo(keyend, NULL, NULL, &addr); + if (c) { + syslog(LOG_WARNING, "unable to resolve hostname: %s [%s]", + keyend, gai_strerror(c)); + return 1; + } + + /* conver ip to string form */ + if (addr->ai_family == AF_INET) { + p = &(((struct sockaddr_in *)addr->ai_addr)->sin_addr); + } else { + p = &(((struct sockaddr_in6 *)addr->ai_addr)->sin6_addr); + } + if (!inet_ntop(addr->ai_family, p, ip, sizeof(ip))) { + syslog(LOG_WARNING, "%s: inet_ntop: %s", + __FUNCTION__, strerror(errno)); + freeaddrinfo(addr); + return 1; + } + + /* setup key */ + c = keyctl_instantiate(key, ip, strlen(ip)+1, 0); + if (c == -1) { + syslog(LOG_WARNING, "%s: keyctl_instantiate: %s", + __FUNCTION__, strerror(errno)); + freeaddrinfo(addr); + return 1; + } + + freeaddrinfo(addr); + return 0; +} + int main(const int argc, char *const argv[]) { struct cifs_spnego_msg *keydata = NULL; @@ -199,6 +253,11 @@ int main(const int argc, char *const argv[]) goto out; } + if (strncmp(buf, "cifs.resolver", sizeof("cifs.resolver")-1) == 0) { + rc = cifs_resolver(key, buf); + goto out; + } + rc = decode_key_description(buf, &kernel_upcall_version, §ype, &hostname, &uid); if ((rc & DKD_MUSTHAVE_SET) != DKD_MUSTHAVE_SET) { |