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;
}
********************************************************************/
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) ||
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;
}
********************************************************************/
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);
+}
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;
}
}
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));
/* 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