r24739: With resolve_ads() allow to query for PDCs as well.
authorGünther Deschner <gd@samba.org>
Tue, 28 Aug 2007 14:27:48 +0000 (14:27 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:30:16 +0000 (12:30 -0500)
Also add dns query functions to find GCs and DCs by GUID.

Guenther
(This used to be commit cc469157f6684ec507bf1c3a659fc36a53d304a1)

source3/libads/dns.c
source3/libsmb/namequery.c

index 96cd54af06e231cda30ec41e6678ec9d8c033ae4..02baec78fb7e11e7b1efd09a3d274bf75c2a69f9 100644 (file)
@@ -740,21 +740,23 @@ BOOL stored_sitename_changed(const char *realm, const char *sitename)
  Query with optional sitename.
 ********************************************************************/
 
-NTSTATUS ads_dns_query_internal(TALLOC_CTX *ctx,
-                               const char *servicename,
-                               const char *realm,
-                               const char *sitename,
-                               struct dns_rr_srv **dclist,
-                               int *numdcs )
+static NTSTATUS ads_dns_query_internal(TALLOC_CTX *ctx,
+                                      const char *servicename,
+                                      const char *dc_pdc_gc_domains,
+                                      const char *realm,
+                                      const char *sitename,
+                                      struct dns_rr_srv **dclist,
+                                      int *numdcs )
 {
        char *name;
        if (sitename) {
-               name = talloc_asprintf(ctx, "%s._tcp.%s._sites.dc._msdcs.%s",
-                               servicename, sitename, realm );
-       } else {
-               name = talloc_asprintf(ctx, "%s._tcp.dc._msdcs.%s",
-                               servicename, realm );
-       }
+               name = talloc_asprintf(ctx, "%s._tcp.%s._sites.%s._msdcs.%s",
+                                      servicename, sitename,
+                                      dc_pdc_gc_domains, realm);
+       } else {
+               name = talloc_asprintf(ctx, "%s._tcp.%s._msdcs.%s",
+                               servicename, dc_pdc_gc_domains, realm);
+       }
        if (!name) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -766,14 +768,14 @@ NTSTATUS ads_dns_query_internal(TALLOC_CTX *ctx,
 ********************************************************************/
 
 NTSTATUS ads_dns_query_dcs(TALLOC_CTX *ctx,
-                       const char *realm,
-                       const char *sitename,
-                       struct dns_rr_srv **dclist,
-                       int *numdcs )
+                          const char *realm,
+                          const char *sitename,
+                          struct dns_rr_srv **dclist,
+                          int *numdcs )
 {
        NTSTATUS status;
 
-       status = ads_dns_query_internal(ctx, "_ldap", realm, sitename,
+       status = ads_dns_query_internal(ctx, "_ldap", "dc", realm, sitename,
                                        dclist, numdcs);
 
        if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
@@ -781,10 +783,42 @@ NTSTATUS ads_dns_query_dcs(TALLOC_CTX *ctx,
                return status;
        }
 
-       if (sitename && !NT_STATUS_IS_OK(status)) {
+       if (sitename &&
+           ((!NT_STATUS_IS_OK(status)) ||
+            (NT_STATUS_IS_OK(status) && (numdcs == 0)))) {
                /* Sitename DNS query may have failed. Try without. */
-               status = ads_dns_query_internal(ctx, "_ldap", realm, NULL,
-                                               dclist, numdcs);
+               status = ads_dns_query_internal(ctx, "_ldap", "dc", realm,
+                                               NULL, dclist, numdcs);
+       }
+       return status;
+}
+
+/********************************************************************
+ Query for AD GC's.
+********************************************************************/
+
+NTSTATUS ads_dns_query_gcs(TALLOC_CTX *ctx,
+                          const char *realm,
+                          const char *sitename,
+                          struct dns_rr_srv **dclist,
+                          int *numdcs )
+{
+       NTSTATUS status;
+
+       status = ads_dns_query_internal(ctx, "_ldap", "gc", realm, sitename,
+                                       dclist, numdcs);
+
+       if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
+           NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_REFUSED)) {
+               return status;
+       }
+
+       if (sitename &&
+           ((!NT_STATUS_IS_OK(status)) ||
+            (NT_STATUS_IS_OK(status) && (numdcs == 0)))) {
+               /* Sitename DNS query may have failed. Try without. */
+               status = ads_dns_query_internal(ctx, "_ldap", "gc", realm,
+                                               NULL, dclist, numdcs);
        }
        return status;
 }
@@ -796,25 +830,72 @@ NTSTATUS ads_dns_query_dcs(TALLOC_CTX *ctx,
 ********************************************************************/
 
 NTSTATUS ads_dns_query_kdcs(TALLOC_CTX *ctx,
-                       const char *realm,
-                       const char *sitename,
-                       struct dns_rr_srv **dclist,
-                       int *numdcs )
+                           const char *dns_forest_name,
+                           const char *sitename,
+                           struct dns_rr_srv **dclist,
+                           int *numdcs )
 {
        NTSTATUS status;
 
-       status = ads_dns_query_internal(ctx, "_kerberos", realm, sitename,
-                                       dclist, numdcs);
+       status = ads_dns_query_internal(ctx, "_kerberos", "dc",
+                                       dns_forest_name, sitename, dclist,
+                                       numdcs);
 
        if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
            NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_REFUSED)) {
                return status;
        }
 
-       if (sitename && !NT_STATUS_IS_OK(status)) {
+       if (sitename &&
+           ((!NT_STATUS_IS_OK(status)) ||
+            (NT_STATUS_IS_OK(status) && (numdcs == 0)))) {
                /* Sitename DNS query may have failed. Try without. */
-               status = ads_dns_query_internal(ctx, "_kerberos", realm, NULL,
+               status = ads_dns_query_internal(ctx, "_kerberos", "dc",
+                                               dns_forest_name, NULL,
                                                dclist, numdcs);
        }
        return status;
 }
+
+/********************************************************************
+ Query for AD PDC. Sitename is obsolete here.
+********************************************************************/
+
+NTSTATUS ads_dns_query_pdc(TALLOC_CTX *ctx,
+                          const char *dns_domain_name,
+                          struct dns_rr_srv **dclist,
+                          int *numdcs )
+{
+       return ads_dns_query_internal(ctx, "_ldap", "pdc", dns_domain_name,
+                                     NULL, dclist, numdcs);
+}
+
+/********************************************************************
+ Query for AD DC by guid. Sitename is obsolete here.
+********************************************************************/
+
+NTSTATUS ads_dns_query_dcs_guid(TALLOC_CTX *ctx,
+                               const char *dns_forest_name,
+                               const struct GUID *domain_guid,
+                               struct dns_rr_srv **dclist,
+                               int *numdcs )
+{
+       /*_ldap._tcp.DomainGuid.domains._msdcs.DnsForestName */
+
+       const char *domains;
+       const char *guid_string;
+
+       guid_string = GUID_string(ctx, domain_guid);
+       if (!guid_string) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       /* little hack */
+       domains = talloc_asprintf(ctx, "%s.domains", guid_string);
+       if (!domains) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       return ads_dns_query_internal(ctx, "_ldap", domains, dns_forest_name,
+                                     NULL, dclist, numdcs);
+}
index 77d259cfa687abc1d53d778d6d98376719e61302..49e3375f508d2cc4423efc47489e491071ec9705 100644 (file)
@@ -1059,7 +1059,8 @@ NTSTATUS resolve_ads(const char *name, int name_type,
        int                     numdcs = 0;
        int                     numaddrs = 0;
 
-       if ((name_type != 0x1c) && (name_type != KDC_NAME_TYPE)) {
+       if ((name_type != 0x1c) && (name_type != KDC_NAME_TYPE) &&
+           (name_type != 0x1b)) {
                return NT_STATUS_INVALID_PARAMETER;
        }
 
@@ -1069,6 +1070,12 @@ NTSTATUS resolve_ads(const char *name, int name_type,
        }
 
        switch (name_type) {
+               case 0x1b:
+                       DEBUG(5,("resolve_ads: Attempting to resolve "
+                                "PDC for %s using DNS\n", name));
+                       status = ads_dns_query_pdc(ctx, name, &dcs, &numdcs);
+                       break;
+
                case 0x1c:
                        DEBUG(5,("resolve_ads: Attempting to resolve "
                                 "DCs for %s using DNS\n", name));
@@ -1419,11 +1426,18 @@ BOOL get_pdc_ip(const char *domain, struct in_addr *ip)
 
        /* Look up #1B name */
 
-       status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
-                                      &count,
-                                      lp_name_resolve_order());
-       if (!NT_STATUS_IS_OK(status)) {
-               return False;
+       if (lp_security() == SEC_ADS) {
+               status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
+                                              &count, "ads");
+       }
+
+       if (!NT_STATUS_IS_OK(status) || count == 0) {
+               status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
+                                              &count,
+                                              lp_name_resolve_order());
+               if (!NT_STATUS_IS_OK(status)) {
+                       return False;
+               }
        }
 
        /* if we get more than 1 IP back we have to assume it is a