r24748: Remove all dependencies to samba internals and convert the krb5 locator plugin
authorGünther Deschner <gd@samba.org>
Tue, 28 Aug 2007 15:26:59 +0000 (15:26 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:30:17 +0000 (12:30 -0500)
into a tiny winbindd DsGetDcName client. This still does not solve the case of
using the locator from within winbindd itself but at least gencache.tdb and
others are no longer corrupted.

Guenther
(This used to be commit 908e7963b8b2dd9b149f526a53dbb5dc7662bbef)

source3/Makefile.in
source3/libads/smb_krb5_locator.c

index da5d2c0e0409da5fd871019b81b1f82c67aeeba2..471e63010bc752de090e11dc38880ef0c9e76146 100644 (file)
@@ -921,8 +921,7 @@ LDBDEL_OBJ = $(LDB_CMDLINE_OBJ) lib/ldb/tools/ldbdel.o
 LDBMODIFY_OBJ = $(LDB_CMDLINE_OBJ) lib/ldb/tools/ldbmodify.o
 
 SMB_KRB5_LOCATOR_OBJ1 = libads/smb_krb5_locator.o
-SMB_KRB5_LOCATOR_OBJ = $(SMB_KRB5_LOCATOR_OBJ1) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
-                      $(LIBNMB_OBJ) $(RPC_PARSE_OBJ1) $(SECRETS_OBJ) $(LIBSAMBA_OBJ) $(DOSERR_OBJ)
+SMB_KRB5_LOCATOR_OBJ = $(SMB_KRB5_LOCATOR_OBJ1) $(WBCOMMON_OBJ) $(LIBREPLACE_OBJ) $(SOCKET_WRAPPER_OBJ)
 
 POPT_OBJ=popt/findme.o popt/popt.o popt/poptconfig.o \
           popt/popthelp.o popt/poptparse.o
index 6a906772624d13814c457cb49a9e0591a9605a9a..91ea24b30f4bdd84e1d16a64808a758e91fc8ed5 100644 (file)
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#include "includes.h"
+#include "nsswitch/winbind_client.h"
+
+#ifndef DEBUG_KRB5
+#undef DEBUG_KRB5
+#endif
 
 #if defined(HAVE_KRB5) && defined(HAVE_KRB5_LOCATE_PLUGIN_H)
+BOOL winbind_env_set( void );
 
 #include <krb5/locate_plugin.h>
 
@@ -42,6 +47,7 @@ static const char *get_service_from_locate_service_type(enum locate_service_type
 
 }
 
+#ifdef DEBUG_KRB5
 static const char *locate_service_type_name(enum locate_service_type svc)
 {
        switch (svc) {
@@ -88,6 +94,7 @@ static const char *family_name(int family)
        }
        return "unknown";
 }
+#endif
 
 /**
  * Check input parameters, return KRB5_PLUGIN_NO_HANDLE for unsupported ones
@@ -185,8 +192,12 @@ static krb5_error_code smb_krb5_locator_call_cbfunc(const char *name,
                        continue;
                }
 
-               DEBUG(10,("smb_krb5_locator_lookup: got ret: %s (%d)\n",
-                       gai_strerror(ret), ret));
+#ifdef DEBUG_KRB5
+               fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: "
+                       "getaddrinfo failed: %s (%d)\n",
+                       (unsigned int)getpid(), gai_strerror(ret), ret);
+#endif
+
 #ifdef KRB5_PLUGIN_NO_HANDLE
                return KRB5_PLUGIN_NO_HANDLE;
 #else
@@ -195,11 +206,13 @@ static krb5_error_code smb_krb5_locator_call_cbfunc(const char *name,
        }
 
        ret = cbfunc(cbdata, out->ai_socktype, out->ai_addr);
+#ifdef DEBUG_KRB5
        if (ret) {
-               DEBUG(10,("smb_krb5_locator_lookup: "
+               fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: "
                        "failed to call callback: %s (%d)\n",
-                       error_message(ret), ret));
+                       (unsigned int)getpid(), error_message(ret), ret);
        }
+#endif
 
        freeaddrinfo(out);
 
@@ -218,12 +231,6 @@ static krb5_error_code smb_krb5_locator_call_cbfunc(const char *name,
 krb5_error_code smb_krb5_locator_init(krb5_context context,
                                      void **private_data)
 {
-       setup_logging("smb_krb5_locator", True);
-       load_case_tables();
-       lp_load(dyn_CONFIGFILE,True,False,False,True);
-
-       DEBUG(10,("smb_krb5_locator_init: called\n"));
-
        return 0;
 }
 
@@ -237,9 +244,44 @@ krb5_error_code smb_krb5_locator_init(krb5_context context,
 
 void smb_krb5_locator_close(void *private_data)
 {
-       DEBUG(10,("smb_krb5_locator_close: called\n"));
+       return;
+}
+
 
-       /* gfree_all(); */
+static int 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;
 }
 
 /**
@@ -264,111 +306,65 @@ krb5_error_code smb_krb5_locator_lookup(void *private_data,
                                        int (*cbfunc)(void *, int, struct sockaddr *),
                                        void *cbdata)
 {
-       NTSTATUS status;
        krb5_error_code ret;
-       char *sitename = NULL;
-       struct ip_service *ip_list;
-       int count = 0;
        struct addrinfo aihints;
-       char *saf_name = NULL;
+       char *kdc_name = NULL;
        const char *service = get_service_from_locate_service_type(svc);
-       int i;
 
-       DEBUG(10,("smb_krb5_locator_lookup: called for\n"));
-       DEBUGADD(10,("\tsvc: %s (%d), realm: %s\n",
-               locate_service_type_name(svc), svc, realm));
-       DEBUGADD(10,("\tsocktype: %s (%d), family: %s (%d)\n",
-               socktype_name(socktype), socktype,
-               family_name(family), family));
+       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) {
-               DEBUG(10,("smb_krb5_locator_lookup: returning ret: %s (%d)\n",
-                       error_message(ret), ret));
-               return ret;
-       }
-
-       /* first try to fetch from SAF cache */
-
-       saf_name = saf_fetch(realm);
-       if (!saf_name || strlen(saf_name) == 0) {
-               DEBUG(10,("smb_krb5_locator_lookup: "
-                       "no SAF name stored for %s\n",
-                       realm));
-               goto find_kdc;
-       }
-
-       DEBUG(10,("smb_krb5_locator_lookup: got %s for %s from SAF cache\n",
-               saf_name, realm));
-
-       ZERO_STRUCT(aihints);
-
-       aihints.ai_family = family;
-       aihints.ai_socktype = socktype;
-
-       ret = smb_krb5_locator_call_cbfunc(saf_name,
-                                         service,
-                                         &aihints,
-                                         cbfunc, cbdata);
-       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;
        }
 
-       return 0;
-
- find_kdc:
-
-       /* now try to find via site-aware DNS SRV query */
-
-       sitename = sitename_fetch(realm);
-       status = get_kdc_list(realm, sitename, &ip_list, &count);
-
-       /* if we didn't found any KDCs on our site go to the main list */
-
-       if (NT_STATUS_IS_OK(status) && sitename && (count == 0)) {
-               SAFE_FREE(ip_list);
-               SAFE_FREE(sitename);
-               status = get_kdc_list(realm, NULL, &ip_list, &count);
-       }
-
-       SAFE_FREE(sitename);
+       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
 
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(10,("smb_krb5_locator_lookup: got %s (%s)\n",
-                       nt_errstr(status),
-                       error_message(nt_status_to_krb5(status))));
 #ifdef KRB5_PLUGIN_NO_HANDLE
-               return KRB5_PLUGIN_NO_HANDLE;
+                       return KRB5_PLUGIN_NO_HANDLE;
 #else
-               return KRB5_KDC_UNREACH; /* Heimdal */
+                       return KRB5_KDC_UNREACH; /* Heimdal */
 #endif
-       }
-
-       for (i=0; i<count; i++) {
-
-               const char *host = NULL;
-               const char *port = NULL;
-
-               ZERO_STRUCT(aihints);
-
-               aihints.ai_family = family;
-               aihints.ai_socktype = socktype;
-
-               host = inet_ntoa(ip_list[i].ip);
-               port = get_service_from_locate_service_type(svc);
-
-               ret = smb_krb5_locator_call_cbfunc(host,
-                                                 port,
-                                                 &aihints,
-                                                 cbfunc, cbdata);
-               if (ret) {
-                       /* got error */
-                       break;
                }
+       } else {
+               /* FIXME: here comes code for locator being called from within
+                * winbind */
        }
+#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;
 
-       SAFE_FREE(ip_list);
+       ret = smb_krb5_locator_call_cbfunc(kdc_name,
+                                          service,
+                                          &aihints,
+                                          cbfunc, cbdata);
+       SAFE_FREE(kdc_name);
 
        return ret;
 }