cldap: let ads_cldap_netlogon() return all possible cldap replies.
authorGünther Deschner <gd@samba.org>
Wed, 7 May 2008 13:49:09 +0000 (15:49 +0200)
committerGünther Deschner <gd@samba.org>
Fri, 9 May 2008 12:59:18 +0000 (14:59 +0200)
Guenther

source/libads/cldap.c
source/libads/ldap.c
source/libsmb/dsgetdcname.c
source/utils/net_ads.c

index 8b23ff90229e04cc178abafa8b0b761572e8b812..e4fa965a0f0e0bf14fd0cc50bf1217e14ee10ce7 100644 (file)
@@ -3,6 +3,7 @@
    net ads cldap functions 
    Copyright (C) 2001 Andrew Tridgell (tridge@samba.org)
    Copyright (C) 2003 Jim McDonough (jmcd@us.ibm.com)
+   Copyright (C) 2008 Guenther Deschner (gd@samba.org)
 
    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
@@ -118,7 +119,8 @@ static void gotalarm_sig(void)
 */
 static int recv_cldap_netlogon(TALLOC_CTX *mem_ctx,
                               int sock,
-                              struct nbt_cldap_netlogon_5 *reply)
+                              uint32_t *nt_version,
+                              union nbt_cldap_netlogon **reply)
 {
        int ret;
        ASN1_DATA data;
@@ -129,8 +131,7 @@ static int recv_cldap_netlogon(TALLOC_CTX *mem_ctx,
        int i1;
        /* half the time of a regular ldap timeout, not less than 3 seconds. */
        unsigned int al_secs = MAX(3,lp_ldap_timeout()/2);
-       union nbt_cldap_netlogon p;
-       enum ndr_err_code ndr_err;
+       union nbt_cldap_netlogon *r = NULL;
 
        blob = data_blob(NULL, 8192);
        if (blob.data == NULL) {
@@ -184,16 +185,23 @@ static int recv_cldap_netlogon(TALLOC_CTX *mem_ctx,
                return -1;
        }
 
-       ndr_err = ndr_pull_union_blob_all(&os3, mem_ctx, &p, 5,
-                      (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon);
-       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+       r = TALLOC_ZERO_P(mem_ctx, union nbt_cldap_netlogon);
+       if (!r) {
+               errno = ENOMEM;
+               data_blob_free(&os1);
+               data_blob_free(&os2);
+               data_blob_free(&os3);
+               data_blob_free(&blob);
                return -1;
        }
 
-       *reply = p.logon5;
-
-       if (DEBUGLEVEL >= 10) {
-               NDR_PRINT_UNION_DEBUG(nbt_cldap_netlogon, 5, &p);
+       if (!pull_mailslot_cldap_reply(mem_ctx, &os3, r, nt_version)) {
+               data_blob_free(&os1);
+               data_blob_free(&os2);
+               data_blob_free(&os3);
+               data_blob_free(&blob);
+               TALLOC_FREE(r);
+               return -1;
        }
 
        data_blob_free(&os1);
@@ -203,6 +211,12 @@ static int recv_cldap_netlogon(TALLOC_CTX *mem_ctx,
        
        asn1_free(&data);
 
+       if (reply) {
+               *reply = r;
+       } else {
+               TALLOC_FREE(r);
+       }
+
        return 0;
 }
 
@@ -213,11 +227,11 @@ static int recv_cldap_netlogon(TALLOC_CTX *mem_ctx,
 bool ads_cldap_netlogon(TALLOC_CTX *mem_ctx,
                        const char *server,
                        const char *realm,
-                       struct nbt_cldap_netlogon_5 *reply)
+                       uint32_t *nt_version,
+                       union nbt_cldap_netlogon **reply)
 {
        int sock;
        int ret;
-       uint32_t nt_version = NETLOGON_VERSION_5 | NETLOGON_VERSION_5EX;
 
        sock = open_udp_socket(server, LDAP_PORT );
        if (sock == -1) {
@@ -226,12 +240,12 @@ bool ads_cldap_netlogon(TALLOC_CTX *mem_ctx,
                return False;
        }
 
-       ret = send_cldap_netlogon(sock, realm, global_myname(), nt_version);
+       ret = send_cldap_netlogon(sock, realm, global_myname(), *nt_version);
        if (ret != 0) {
                close(sock);
                return False;
        }
-       ret = recv_cldap_netlogon(mem_ctx, sock, reply);
+       ret = recv_cldap_netlogon(mem_ctx, sock, nt_version, reply);
        close(sock);
 
        if (ret == -1) {
@@ -240,3 +254,30 @@ bool ads_cldap_netlogon(TALLOC_CTX *mem_ctx,
 
        return True;
 }
+
+/*******************************************************************
+  do a cldap netlogon query.  Always 389/udp
+*******************************************************************/
+
+bool ads_cldap_netlogon_5(TALLOC_CTX *mem_ctx,
+                         const char *server,
+                         const char *realm,
+                         struct nbt_cldap_netlogon_5 *reply5)
+{
+       uint32_t nt_version = NETLOGON_VERSION_5 | NETLOGON_VERSION_5EX;
+       union nbt_cldap_netlogon *reply = NULL;
+       bool ret;
+
+       ret = ads_cldap_netlogon(mem_ctx, server, realm, &nt_version, &reply);
+       if (!ret) {
+               return false;
+       }
+
+       if (nt_version != (NETLOGON_VERSION_5 | NETLOGON_VERSION_5EX)) {
+               return false;
+       }
+
+       *reply5 = reply->logon5;
+
+       return true;
+}
index 93213021516d13ff75e612f16b9bea642d55cf20..24eb114f51d37f36272ae49251e8fcb0701dc136 100644 (file)
@@ -199,7 +199,7 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server )
 
        ZERO_STRUCT( cldap_reply );
 
-       if ( !ads_cldap_netlogon(mem_ctx, srv, ads->server.realm, &cldap_reply ) ) {
+       if ( !ads_cldap_netlogon_5(mem_ctx, srv, ads->server.realm, &cldap_reply ) ) {
                DEBUG(3,("ads_try_connect: CLDAP request %s failed.\n", srv));
                ret = false;
                goto out;
index 98c9997575d83a14b2c9bf92d2adf355cc9b7ea0..1fd42120ee36ead8cee282a08a2fbb662d8e97ce 100644 (file)
@@ -196,15 +196,13 @@ static NTSTATUS dsgetdcname_cache_refresh(TALLOC_CTX *mem_ctx,
                                          const char *site_name,
                                          struct netr_DsRGetDCNameInfo *info)
 {
-       struct nbt_cldap_netlogon_5 r;
+       uint32_t nt_version = NETLOGON_VERSION_1;
 
        /* check if matching entry is older then 15 minutes, if yes, send
         * CLDAP/MAILSLOT ping again and store the cached data */
 
-       ZERO_STRUCT(r);
-
        if (ads_cldap_netlogon(mem_ctx, info->dc_unc,
-                              info->domain_name, &r)) {
+                              info->domain_name, &nt_version, NULL)) {
 
                dsgetdcname_cache_delete(mem_ctx, domain_name);
 
index 3df9e2cff036da5e1fddd87cabfae5e5b6f967c9..bf348801776e6a63770a717fbb13f6aba00af285 100644 (file)
@@ -84,7 +84,7 @@ static int net_ads_cldap_netlogon(ADS_STRUCT *ads)
        struct nbt_cldap_netlogon_5 reply;
 
        print_sockaddr(addr, sizeof(addr), &ads->ldap.ss);
-       if ( !ads_cldap_netlogon(talloc_tos(), addr, ads->server.realm, &reply ) ) {
+       if ( !ads_cldap_netlogon_5(talloc_tos(), addr, ads->server.realm, &reply ) ) {
                d_fprintf(stderr, "CLDAP query failed!\n");
                return -1;
        }
@@ -389,7 +389,7 @@ static int net_ads_workgroup(int argc, const char **argv)
        }
 
        print_sockaddr(addr, sizeof(addr), &ads->ldap.ss);
-       if ( !ads_cldap_netlogon(talloc_tos(), addr, ads->server.realm, &reply ) ) {
+       if ( !ads_cldap_netlogon_5(talloc_tos(), addr, ads->server.realm, &reply ) ) {
                d_fprintf(stderr, "CLDAP query failed!\n");
                return -1;
        }