diff options
-rw-r--r-- | source3/libads/dns.c | 137 | ||||
-rw-r--r-- | source3/libsmb/namequery.c | 26 |
2 files changed, 129 insertions, 34 deletions
diff --git a/source3/libads/dns.c b/source3/libads/dns.c index 96cd54af06..02baec78fb 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -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); +} diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 77d259cfa6..49e3375f50 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -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 |