From 6b441e9e74b11bee4b661eaa17682d6351c264ff Mon Sep 17 00:00:00 2001 From: Guenther Deschner Date: Thu, 11 Oct 2007 15:12:12 +0200 Subject: Rename krb5 locator plugin to "winbind_krb5_locator". Guenther (This used to be commit 6ae4066bbb59536852036394ffdb89121198a39f) --- source3/nsswitch/smb_krb5_locator.c | 394 -------------------------------- source3/nsswitch/winbind_krb5_locator.c | 394 ++++++++++++++++++++++++++++++++ 2 files changed, 394 insertions(+), 394 deletions(-) delete mode 100644 source3/nsswitch/smb_krb5_locator.c create mode 100644 source3/nsswitch/winbind_krb5_locator.c (limited to 'source3/nsswitch') diff --git a/source3/nsswitch/smb_krb5_locator.c b/source3/nsswitch/smb_krb5_locator.c deleted file mode 100644 index 18a9fe3429..0000000000 --- a/source3/nsswitch/smb_krb5_locator.c +++ /dev/null @@ -1,394 +0,0 @@ -/* - Unix SMB/CIFS implementation. - kerberos locator plugin - Copyright (C) Guenther Deschner 2007 - - 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 - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "nsswitch/winbind_client.h" - -#ifndef DEBUG_KRB5 -#undef DEBUG_KRB5 -#endif - -#if defined(HAVE_KRB5) && defined(HAVE_KRB5_LOCATE_PLUGIN_H) - -#include - -#ifndef KRB5_PLUGIN_NO_HANDLE -#define KRB5_PLUGIN_NO_HANDLE KRB5_KDC_UNREACH /* Heimdal */ -#endif - -static const char *get_service_from_locate_service_type(enum locate_service_type svc) -{ - switch (svc) { - case locate_service_kdc: - case locate_service_master_kdc: - return "88"; - case locate_service_kadmin: - case locate_service_krb524: - /* not supported */ - return NULL; - case locate_service_kpasswd: - return "464"; - default: - break; - } - return NULL; - -} - -#ifdef DEBUG_KRB5 -static const char *locate_service_type_name(enum locate_service_type svc) -{ - switch (svc) { - case locate_service_kdc: - return "locate_service_kdc"; - case locate_service_master_kdc: - return "locate_service_master_kdc"; - case locate_service_kadmin: - return "locate_service_kadmin"; - case locate_service_krb524: - return "locate_service_krb524"; - case locate_service_kpasswd: - return "locate_service_kpasswd"; - default: - break; - } - return NULL; -} - -static const char *socktype_name(int socktype) -{ - switch (socktype) { - case SOCK_STREAM: - return "SOCK_STREAM"; - case SOCK_DGRAM: - return "SOCK_DGRAM"; - default: - break; - } - return "unknown"; -} - -static const char *family_name(int family) -{ - switch (family) { - case AF_UNSPEC: - return "AF_UNSPEC"; - case AF_INET: - return "AF_INET"; - case AF_INET6: - return "AF_INET6"; - default: - break; - } - return "unknown"; -} -#endif - -/** - * Check input parameters, return KRB5_PLUGIN_NO_HANDLE for unsupported ones - * - * @param svc - * @param realm string - * @param socktype integer - * @param family integer - * - * @return integer. - */ - -static int smb_krb5_locator_lookup_sanity_check(enum locate_service_type svc, - const char *realm, - int socktype, - int family) -{ - if (!realm || strlen(realm) == 0) { - return EINVAL; - } - - switch (svc) { - case locate_service_kdc: - case locate_service_master_kdc: - case locate_service_kpasswd: - break; - case locate_service_kadmin: - case locate_service_krb524: - return KRB5_PLUGIN_NO_HANDLE; - default: - return EINVAL; - } - - switch (family) { - case AF_UNSPEC: - case AF_INET: - break; - case AF_INET6: /* not yet */ - return KRB5_PLUGIN_NO_HANDLE; - default: - return EINVAL; - } - - switch (socktype) { - case SOCK_STREAM: - case SOCK_DGRAM: - case 0: /* Heimdal uses that */ - break; - default: - return EINVAL; - } - - return 0; -} - -/** - * Try to get addrinfo for a given host and call the krb5 callback - * - * @param name string - * @param service string - * @param in struct addrinfo hint - * @param cbfunc krb5 callback function - * @param cbdata void pointer cbdata - * - * @return krb5_error_code. - */ - -static krb5_error_code smb_krb5_locator_call_cbfunc(const char *name, - const char *service, - struct addrinfo *in, - int (*cbfunc)(void *, int, struct sockaddr *), - void *cbdata) -{ - struct addrinfo *out; - int ret; - int count = 3; - - while (count) { - - ret = getaddrinfo(name, service, in, &out); - if (ret == 0) { - break; - } - - if (ret == EAI_AGAIN) { - count--; - continue; - } - -#ifdef DEBUG_KRB5 - fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: " - "getaddrinfo failed: %s (%d)\n", - (unsigned int)getpid(), gai_strerror(ret), ret); -#endif - - return KRB5_PLUGIN_NO_HANDLE; - } - - ret = cbfunc(cbdata, out->ai_socktype, out->ai_addr); -#ifdef DEBUG_KRB5 - if (ret) { - fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: " - "failed to call callback: %s (%d)\n", - (unsigned int)getpid(), error_message(ret), ret); - } -#endif - - freeaddrinfo(out); - - return ret; -} - -/** - * PUBLIC INTERFACE: locate init - * - * @param context krb5_context - * @param privata_data pointer to private data pointer - * - * @return krb5_error_code. - */ - -krb5_error_code smb_krb5_locator_init(krb5_context context, - void **private_data) -{ - return 0; -} - -/** - * PUBLIC INTERFACE: close locate - * - * @param private_data pointer to private data - * - * @return void. - */ - -void smb_krb5_locator_close(void *private_data) -{ - return; -} - - -static bool ask_winbind(const char *realm, char **dcname) -{ - NSS_STATUS status; - struct winbindd_request request; - struct winbindd_response response; - - ZERO_STRUCT(request); - ZERO_STRUCT(response); - - request.flags = 0x40020600; - /* DS_KDC_REQUIRED | - DS_IS_DNS_NAME | - DS_RETURN_DNS_NAME | - DS_IP_REQUIRED */ - - strncpy(request.domain_name, realm, - sizeof(request.domain_name)-1); - - status = winbindd_request_response(WINBINDD_DSGETDCNAME, - &request, &response); - if (status != NSS_STATUS_SUCCESS) { -#ifdef DEBUG_KRB5 - fprintf(stderr,"[%5u]: smb_krb5_locator_lookup: failed with: %s\n", - (unsigned int)getpid(), nss_err_str(status)); -#endif - return false; - } - - *dcname = strdup(response.data.dc_name); - if (!*dcname) { - return false; - } - - return true; -} - -/** - * PUBLIC INTERFACE: locate lookup - * - * @param private_data pointer to private data - * @param svc enum locate_service_type. - * @param realm string - * @param socktype integer - * @param family integer - * @param cbfunc callback function to send back entries - * @param cbdata void pointer to cbdata - * - * @return krb5_error_code. - */ - -krb5_error_code smb_krb5_locator_lookup(void *private_data, - enum locate_service_type svc, - const char *realm, - int socktype, - int family, - int (*cbfunc)(void *, int, struct sockaddr *), - void *cbdata) -{ - krb5_error_code ret; - struct addrinfo aihints; - char *kdc_name = NULL; - const char *service = get_service_from_locate_service_type(svc); - - ZERO_STRUCT(aihints); - -#ifdef DEBUG_KRB5 - fprintf(stderr,"[%5u]: smb_krb5_locator_lookup: called for '%s' " - "svc: '%s' (%d) " - "socktype: '%s' (%d), family: '%s' (%d)\n", - (unsigned int)getpid(), realm, - locate_service_type_name(svc), svc, - socktype_name(socktype), socktype, - family_name(family), family); -#endif - ret = smb_krb5_locator_lookup_sanity_check(svc, realm, socktype, - family); - if (ret) { -#ifdef DEBUG_KRB5 - fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: " - "returning ret: %s (%d)\n", - (unsigned int)getpid(), error_message(ret), ret); -#endif - return ret; - } - - if (!winbind_env_set()) { - if (!ask_winbind(realm, &kdc_name)) { -#ifdef DEBUG_KRB5 - fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: " - "failed to query winbindd\n", - (unsigned int)getpid()); -#endif - goto failed; - } - } else { - const char *env = NULL; - char *var = NULL; - if (asprintf(&var, "%s_%s", - WINBINDD_LOCATOR_KDC_ADDRESS, realm) == -1) { - goto failed; - } - env = getenv(var); - if (!env) { -#ifdef DEBUG_KRB5 - fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: " - "failed to get kdc from env %s\n", - (unsigned int)getpid(), var); -#endif - free(var); - goto failed; - } - free(var); - - kdc_name = strdup(env); - if (!kdc_name) { - goto failed; - } - } -#ifdef DEBUG_KRB5 - fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: " - "got '%s' for '%s' from winbindd\n", (unsigned int)getpid(), - kdc_name, realm); -#endif - - aihints.ai_family = family; - aihints.ai_socktype = socktype; - - ret = smb_krb5_locator_call_cbfunc(kdc_name, - service, - &aihints, - cbfunc, cbdata); - SAFE_FREE(kdc_name); - - return ret; - - failed: - return KRB5_PLUGIN_NO_HANDLE; -} - -#ifdef HEIMDAL_KRB5_LOCATE_PLUGIN_H -#define SMB_KRB5_LOCATOR_SYMBOL_NAME resolve /* Heimdal */ -#else -#define SMB_KRB5_LOCATOR_SYMBOL_NAME service_locator /* MIT */ -#endif - -const krb5plugin_service_locate_ftable SMB_KRB5_LOCATOR_SYMBOL_NAME = { - 0, /* version */ - smb_krb5_locator_init, - smb_krb5_locator_close, - smb_krb5_locator_lookup, -}; - -#endif diff --git a/source3/nsswitch/winbind_krb5_locator.c b/source3/nsswitch/winbind_krb5_locator.c new file mode 100644 index 0000000000..18a9fe3429 --- /dev/null +++ b/source3/nsswitch/winbind_krb5_locator.c @@ -0,0 +1,394 @@ +/* + Unix SMB/CIFS implementation. + kerberos locator plugin + Copyright (C) Guenther Deschner 2007 + + 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 + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "nsswitch/winbind_client.h" + +#ifndef DEBUG_KRB5 +#undef DEBUG_KRB5 +#endif + +#if defined(HAVE_KRB5) && defined(HAVE_KRB5_LOCATE_PLUGIN_H) + +#include + +#ifndef KRB5_PLUGIN_NO_HANDLE +#define KRB5_PLUGIN_NO_HANDLE KRB5_KDC_UNREACH /* Heimdal */ +#endif + +static const char *get_service_from_locate_service_type(enum locate_service_type svc) +{ + switch (svc) { + case locate_service_kdc: + case locate_service_master_kdc: + return "88"; + case locate_service_kadmin: + case locate_service_krb524: + /* not supported */ + return NULL; + case locate_service_kpasswd: + return "464"; + default: + break; + } + return NULL; + +} + +#ifdef DEBUG_KRB5 +static const char *locate_service_type_name(enum locate_service_type svc) +{ + switch (svc) { + case locate_service_kdc: + return "locate_service_kdc"; + case locate_service_master_kdc: + return "locate_service_master_kdc"; + case locate_service_kadmin: + return "locate_service_kadmin"; + case locate_service_krb524: + return "locate_service_krb524"; + case locate_service_kpasswd: + return "locate_service_kpasswd"; + default: + break; + } + return NULL; +} + +static const char *socktype_name(int socktype) +{ + switch (socktype) { + case SOCK_STREAM: + return "SOCK_STREAM"; + case SOCK_DGRAM: + return "SOCK_DGRAM"; + default: + break; + } + return "unknown"; +} + +static const char *family_name(int family) +{ + switch (family) { + case AF_UNSPEC: + return "AF_UNSPEC"; + case AF_INET: + return "AF_INET"; + case AF_INET6: + return "AF_INET6"; + default: + break; + } + return "unknown"; +} +#endif + +/** + * Check input parameters, return KRB5_PLUGIN_NO_HANDLE for unsupported ones + * + * @param svc + * @param realm string + * @param socktype integer + * @param family integer + * + * @return integer. + */ + +static int smb_krb5_locator_lookup_sanity_check(enum locate_service_type svc, + const char *realm, + int socktype, + int family) +{ + if (!realm || strlen(realm) == 0) { + return EINVAL; + } + + switch (svc) { + case locate_service_kdc: + case locate_service_master_kdc: + case locate_service_kpasswd: + break; + case locate_service_kadmin: + case locate_service_krb524: + return KRB5_PLUGIN_NO_HANDLE; + default: + return EINVAL; + } + + switch (family) { + case AF_UNSPEC: + case AF_INET: + break; + case AF_INET6: /* not yet */ + return KRB5_PLUGIN_NO_HANDLE; + default: + return EINVAL; + } + + switch (socktype) { + case SOCK_STREAM: + case SOCK_DGRAM: + case 0: /* Heimdal uses that */ + break; + default: + return EINVAL; + } + + return 0; +} + +/** + * Try to get addrinfo for a given host and call the krb5 callback + * + * @param name string + * @param service string + * @param in struct addrinfo hint + * @param cbfunc krb5 callback function + * @param cbdata void pointer cbdata + * + * @return krb5_error_code. + */ + +static krb5_error_code smb_krb5_locator_call_cbfunc(const char *name, + const char *service, + struct addrinfo *in, + int (*cbfunc)(void *, int, struct sockaddr *), + void *cbdata) +{ + struct addrinfo *out; + int ret; + int count = 3; + + while (count) { + + ret = getaddrinfo(name, service, in, &out); + if (ret == 0) { + break; + } + + if (ret == EAI_AGAIN) { + count--; + continue; + } + +#ifdef DEBUG_KRB5 + fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: " + "getaddrinfo failed: %s (%d)\n", + (unsigned int)getpid(), gai_strerror(ret), ret); +#endif + + return KRB5_PLUGIN_NO_HANDLE; + } + + ret = cbfunc(cbdata, out->ai_socktype, out->ai_addr); +#ifdef DEBUG_KRB5 + if (ret) { + fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: " + "failed to call callback: %s (%d)\n", + (unsigned int)getpid(), error_message(ret), ret); + } +#endif + + freeaddrinfo(out); + + return ret; +} + +/** + * PUBLIC INTERFACE: locate init + * + * @param context krb5_context + * @param privata_data pointer to private data pointer + * + * @return krb5_error_code. + */ + +krb5_error_code smb_krb5_locator_init(krb5_context context, + void **private_data) +{ + return 0; +} + +/** + * PUBLIC INTERFACE: close locate + * + * @param private_data pointer to private data + * + * @return void. + */ + +void smb_krb5_locator_close(void *private_data) +{ + return; +} + + +static bool ask_winbind(const char *realm, char **dcname) +{ + NSS_STATUS status; + struct winbindd_request request; + struct winbindd_response response; + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + request.flags = 0x40020600; + /* DS_KDC_REQUIRED | + DS_IS_DNS_NAME | + DS_RETURN_DNS_NAME | + DS_IP_REQUIRED */ + + strncpy(request.domain_name, realm, + sizeof(request.domain_name)-1); + + status = winbindd_request_response(WINBINDD_DSGETDCNAME, + &request, &response); + if (status != NSS_STATUS_SUCCESS) { +#ifdef DEBUG_KRB5 + fprintf(stderr,"[%5u]: smb_krb5_locator_lookup: failed with: %s\n", + (unsigned int)getpid(), nss_err_str(status)); +#endif + return false; + } + + *dcname = strdup(response.data.dc_name); + if (!*dcname) { + return false; + } + + return true; +} + +/** + * PUBLIC INTERFACE: locate lookup + * + * @param private_data pointer to private data + * @param svc enum locate_service_type. + * @param realm string + * @param socktype integer + * @param family integer + * @param cbfunc callback function to send back entries + * @param cbdata void pointer to cbdata + * + * @return krb5_error_code. + */ + +krb5_error_code smb_krb5_locator_lookup(void *private_data, + enum locate_service_type svc, + const char *realm, + int socktype, + int family, + int (*cbfunc)(void *, int, struct sockaddr *), + void *cbdata) +{ + krb5_error_code ret; + struct addrinfo aihints; + char *kdc_name = NULL; + const char *service = get_service_from_locate_service_type(svc); + + ZERO_STRUCT(aihints); + +#ifdef DEBUG_KRB5 + fprintf(stderr,"[%5u]: smb_krb5_locator_lookup: called for '%s' " + "svc: '%s' (%d) " + "socktype: '%s' (%d), family: '%s' (%d)\n", + (unsigned int)getpid(), realm, + locate_service_type_name(svc), svc, + socktype_name(socktype), socktype, + family_name(family), family); +#endif + ret = smb_krb5_locator_lookup_sanity_check(svc, realm, socktype, + family); + if (ret) { +#ifdef DEBUG_KRB5 + fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: " + "returning ret: %s (%d)\n", + (unsigned int)getpid(), error_message(ret), ret); +#endif + return ret; + } + + if (!winbind_env_set()) { + if (!ask_winbind(realm, &kdc_name)) { +#ifdef DEBUG_KRB5 + fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: " + "failed to query winbindd\n", + (unsigned int)getpid()); +#endif + goto failed; + } + } else { + const char *env = NULL; + char *var = NULL; + if (asprintf(&var, "%s_%s", + WINBINDD_LOCATOR_KDC_ADDRESS, realm) == -1) { + goto failed; + } + env = getenv(var); + if (!env) { +#ifdef DEBUG_KRB5 + fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: " + "failed to get kdc from env %s\n", + (unsigned int)getpid(), var); +#endif + free(var); + goto failed; + } + free(var); + + kdc_name = strdup(env); + if (!kdc_name) { + goto failed; + } + } +#ifdef DEBUG_KRB5 + fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: " + "got '%s' for '%s' from winbindd\n", (unsigned int)getpid(), + kdc_name, realm); +#endif + + aihints.ai_family = family; + aihints.ai_socktype = socktype; + + ret = smb_krb5_locator_call_cbfunc(kdc_name, + service, + &aihints, + cbfunc, cbdata); + SAFE_FREE(kdc_name); + + return ret; + + failed: + return KRB5_PLUGIN_NO_HANDLE; +} + +#ifdef HEIMDAL_KRB5_LOCATE_PLUGIN_H +#define SMB_KRB5_LOCATOR_SYMBOL_NAME resolve /* Heimdal */ +#else +#define SMB_KRB5_LOCATOR_SYMBOL_NAME service_locator /* MIT */ +#endif + +const krb5plugin_service_locate_ftable SMB_KRB5_LOCATOR_SYMBOL_NAME = { + 0, /* version */ + smb_krb5_locator_init, + smb_krb5_locator_close, + smb_krb5_locator_lookup, +}; + +#endif -- cgit