--- old/usr/src/lib/libadutils/common/addisc.c	Mon Aug  5 17:16:10 2019
+++ new/usr/src/lib/libadutils/common/addisc.c	Mon Aug  5 17:16:10 2019
@@ -21,7 +21,7 @@
 
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright 2019 Nexenta Systems, Inc.  All rights reserved.
  */
 
 /*
@@ -1222,8 +1222,10 @@
 		return (&ctx->domain_controller);
 
 	domain_name_item = validate_DomainName(ctx);
-	if (domain_name_item == NULL)
+	if (domain_name_item == NULL) {
+		DEBUG1STATUS(ctx, "(no domain name)");
 		return (NULL);
+	}
 	domain_name = (char *)domain_name_item->value;
 
 	/* Get (optional) preferred DC. */
@@ -1236,29 +1238,41 @@
 	else {
 		if (is_fixed(&ctx->site_name))
 			validate_site = B_TRUE;
-		else if (req == AD_DISC_PREFER_SITE)
+		if (req == AD_DISC_PREFER_SITE)
 			validate_global = B_TRUE;
 	}
 
-	if (validate_global) {
-		if (!is_valid(&ctx->domain_controller) ||
-		    is_changed(&ctx->domain_controller, PARAM1,
-		    domain_name_item)) {
+	/*
+	 * If we're trying both site-specific and global,
+	 * try the site-specific first, then fall-back.
+	 */
+	if (validate_site) {
+		site_name_item = &ctx->site_name;
+		site_name = (char *)site_name_item->value;
 
+		if (!is_valid(&ctx->site_domain_controller) ||
+		    is_changed(&ctx->site_domain_controller, PARAM1,
+		    domain_name_item) ||
+		    is_changed(&ctx->site_domain_controller, PARAM2,
+		    site_name_item)) {
+			char rr_name[DNS_MAX_NAME];
+
 			/*
 			 * Lookup DNS SRV RR named
-			 * _ldap._tcp.dc._msdcs.<DomainName>
+			 * _ldap._tcp.<SiteName>._sites.dc._msdcs.<DomainName>
 			 */
-			DEBUG1STATUS(ctx, "DNS SRV query, dom=%s",
-			    domain_name);
+			DEBUG1STATUS(ctx, "DNS SRV query, dom=%s, site=%s",
+			    domain_name, site_name);
+			(void) snprintf(rr_name, sizeof (rr_name),
+			    LDAP_SRV_HEAD SITE_SRV_MIDDLE DC_SRV_TAIL,
+			    site_name);
 			DO_RES_NINIT(ctx);
-			cdc = srv_query(&ctx->res_state,
-			    LDAP_SRV_HEAD DC_SRV_TAIL,
+			cdc = srv_query(&ctx->res_state, rr_name,
 			    domain_name, prefer_dc);
 
 			if (cdc == NULL) {
 				DEBUG1STATUS(ctx, "(no DNS response)");
-				return (NULL);
+				goto try_global;
 			}
 			log_cds(ctx, cdc);
 
@@ -1276,40 +1290,36 @@
 
 			if (dc == NULL) {
 				DEBUG1STATUS(ctx, "(no LDAP response)");
-				return (NULL);
+				goto try_global;
 			}
 			log_ds(ctx, dc);
 
-			update_item(&ctx->domain_controller, dc,
+			update_item(&ctx->site_domain_controller, dc,
 			    AD_STATE_AUTO, dc->ttl);
-			update_version(&ctx->domain_controller, PARAM1,
+			update_version(&ctx->site_domain_controller, PARAM1,
 			    domain_name_item);
+			update_version(&ctx->site_domain_controller, PARAM2,
+			    site_name_item);
 		}
-		return (&ctx->domain_controller);
+		return (&ctx->site_domain_controller);
 	}
 
-	if (validate_site) {
-		site_name_item = &ctx->site_name;
-		site_name = (char *)site_name_item->value;
+try_global:
 
-		if (!is_valid(&ctx->site_domain_controller) ||
-		    is_changed(&ctx->site_domain_controller, PARAM1,
-		    domain_name_item) ||
-		    is_changed(&ctx->site_domain_controller, PARAM2,
-		    site_name_item)) {
-			char rr_name[DNS_MAX_NAME];
+	if (validate_global) {
+		if (!is_valid(&ctx->domain_controller) ||
+		    is_changed(&ctx->domain_controller, PARAM1,
+		    domain_name_item)) {
 
 			/*
 			 * Lookup DNS SRV RR named
-			 * _ldap._tcp.<SiteName>._sites.dc._msdcs.<DomainName>
+			 * _ldap._tcp.dc._msdcs.<DomainName>
 			 */
-			DEBUG1STATUS(ctx, "DNS SRV query, dom=%s, site=%s",
-			    domain_name, site_name);
-			(void) snprintf(rr_name, sizeof (rr_name),
-			    LDAP_SRV_HEAD SITE_SRV_MIDDLE DC_SRV_TAIL,
-			    site_name);
+			DEBUG1STATUS(ctx, "DNS SRV query, dom=%s",
+			    domain_name);
 			DO_RES_NINIT(ctx);
-			cdc = srv_query(&ctx->res_state, rr_name,
+			cdc = srv_query(&ctx->res_state,
+			    LDAP_SRV_HEAD DC_SRV_TAIL,
 			    domain_name, prefer_dc);
 
 			if (cdc == NULL) {
@@ -1336,15 +1346,14 @@
 			}
 			log_ds(ctx, dc);
 
-			update_item(&ctx->site_domain_controller, dc,
+			update_item(&ctx->domain_controller, dc,
 			    AD_STATE_AUTO, dc->ttl);
-			update_version(&ctx->site_domain_controller, PARAM1,
+			update_version(&ctx->domain_controller, PARAM1,
 			    domain_name_item);
-			update_version(&ctx->site_domain_controller, PARAM2,
-			    site_name_item);
 		}
-		return (&ctx->site_domain_controller);
+		return (&ctx->domain_controller);
 	}
+
 	return (NULL);
 }
 
@@ -1516,8 +1525,10 @@
 		return (&ctx->global_catalog);
 
 	forest_name_item = validate_ForestName(ctx);
-	if (forest_name_item == NULL)
+	if (forest_name_item == NULL) {
+		DEBUG1STATUS(ctx, "(no forrest name)");
 		return (NULL);
+	}
 	forest_name = (char *)forest_name_item->value;
 
 	if (req == AD_DISC_GLOBAL)
@@ -1525,15 +1536,25 @@
 	else {
 		if (is_fixed(&ctx->site_name))
 			validate_site = B_TRUE;
-		else if (req == AD_DISC_PREFER_SITE)
+		if (req == AD_DISC_PREFER_SITE)
 			validate_global = B_TRUE;
 	}
 
-	if (validate_global) {
-		if (!is_valid(&ctx->global_catalog) ||
-		    is_changed(&ctx->global_catalog, PARAM1,
-		    forest_name_item)) {
+	/*
+	 * If we're trying both site-specific and global,
+	 * try the site-specific first, then fall-back.
+	 */
+	if (validate_site) {
+		site_name_item = &ctx->site_name;
+		site_name = (char *)site_name_item->value;
 
+		if (!is_valid(&ctx->site_global_catalog) ||
+		    is_changed(&ctx->site_global_catalog, PARAM1,
+		    forest_name_item) ||
+		    is_changed(&ctx->site_global_catalog, PARAM2,
+		    site_name_item)) {
+			char rr_name[DNS_MAX_NAME];
+
 			/*
 			 * See if our DC is also a GC.
 			 */
@@ -1542,12 +1563,12 @@
 				ad_disc_ds_t *ds = dc_item->value;
 				if ((ds->flags & DS_GC_FLAG) != 0) {
 					DEBUG1STATUS(ctx,
-					    "DC is also a GC for %s",
-					    forest_name);
+					    "DC is also a GC for %s in %s",
+					    forest_name, site_name);
 					gc = ds_dup(ds);
 					if (gc != NULL) {
 						gc->port = GC_PORT;
-						goto update_global;
+						goto update_site;
 					}
 				}
 			}
@@ -1554,18 +1575,21 @@
 
 			/*
 			 * Lookup DNS SRV RR named:
-			 * _ldap._tcp.gc._msdcs.<ForestName>
+			 * _ldap._tcp.<siteName>._sites.gc.
+			 *	_msdcs.<ForestName>
 			 */
-			DEBUG1STATUS(ctx, "DNS SRV query, forest=%s",
-			    forest_name);
+			DEBUG1STATUS(ctx, "DNS SRV query, forest=%s, site=%s",
+			    forest_name, site_name);
+			(void) snprintf(rr_name, sizeof (rr_name),
+			    LDAP_SRV_HEAD SITE_SRV_MIDDLE GC_SRV_TAIL,
+			    site_name);
 			DO_RES_NINIT(ctx);
-			cgc = srv_query(&ctx->res_state,
-			    LDAP_SRV_HEAD GC_SRV_TAIL,
+			cgc = srv_query(&ctx->res_state, rr_name,
 			    forest_name, NULL);
 
 			if (cgc == NULL) {
 				DEBUG1STATUS(ctx, "(no DNS response)");
-				return (NULL);
+				goto try_global;
 			}
 			log_cds(ctx, cgc);
 
@@ -1583,29 +1607,27 @@
 
 			if (gc == NULL) {
 				DEBUG1STATUS(ctx, "(no LDAP response)");
-				return (NULL);
+				goto try_global;
 			}
 			log_ds(ctx, gc);
 
-		update_global:
-			update_item(&ctx->global_catalog, gc,
+		update_site:
+			update_item(&ctx->site_global_catalog, gc,
 			    AD_STATE_AUTO, gc->ttl);
-			update_version(&ctx->global_catalog, PARAM1,
+			update_version(&ctx->site_global_catalog, PARAM1,
 			    forest_name_item);
+			update_version(&ctx->site_global_catalog, PARAM2,
+			    site_name_item);
 		}
-		return (&ctx->global_catalog);
+		return (&ctx->site_global_catalog);
 	}
 
-	if (validate_site) {
-		site_name_item = &ctx->site_name;
-		site_name = (char *)site_name_item->value;
+try_global:
 
-		if (!is_valid(&ctx->site_global_catalog) ||
-		    is_changed(&ctx->site_global_catalog, PARAM1,
-		    forest_name_item) ||
-		    is_changed(&ctx->site_global_catalog, PARAM2,
-		    site_name_item)) {
-			char rr_name[DNS_MAX_NAME];
+	if (validate_global) {
+		if (!is_valid(&ctx->global_catalog) ||
+		    is_changed(&ctx->global_catalog, PARAM1,
+		    forest_name_item)) {
 
 			/*
 			 * See if our DC is also a GC.
@@ -1615,12 +1637,12 @@
 				ad_disc_ds_t *ds = dc_item->value;
 				if ((ds->flags & DS_GC_FLAG) != 0) {
 					DEBUG1STATUS(ctx,
-					    "DC is also a GC for %s in %s",
-					    forest_name, site_name);
+					    "DC is also a GC for %s",
+					    forest_name);
 					gc = ds_dup(ds);
 					if (gc != NULL) {
 						gc->port = GC_PORT;
-						goto update_site;
+						goto update_global;
 					}
 				}
 			}
@@ -1627,16 +1649,13 @@
 
 			/*
 			 * Lookup DNS SRV RR named:
-			 * _ldap._tcp.<siteName>._sites.gc.
-			 *	_msdcs.<ForestName>
+			 * _ldap._tcp.gc._msdcs.<ForestName>
 			 */
-			DEBUG1STATUS(ctx, "DNS SRV query, forest=%s, site=%s",
-			    forest_name, site_name);
-			(void) snprintf(rr_name, sizeof (rr_name),
-			    LDAP_SRV_HEAD SITE_SRV_MIDDLE GC_SRV_TAIL,
-			    site_name);
+			DEBUG1STATUS(ctx, "DNS SRV query, forest=%s",
+			    forest_name);
 			DO_RES_NINIT(ctx);
-			cgc = srv_query(&ctx->res_state, rr_name,
+			cgc = srv_query(&ctx->res_state,
+			    LDAP_SRV_HEAD GC_SRV_TAIL,
 			    forest_name, NULL);
 
 			if (cgc == NULL) {
@@ -1663,15 +1682,13 @@
 			}
 			log_ds(ctx, gc);
 
-		update_site:
-			update_item(&ctx->site_global_catalog, gc,
+		update_global:
+			update_item(&ctx->global_catalog, gc,
 			    AD_STATE_AUTO, gc->ttl);
-			update_version(&ctx->site_global_catalog, PARAM1,
+			update_version(&ctx->global_catalog, PARAM1,
 			    forest_name_item);
-			update_version(&ctx->site_global_catalog, PARAM2,
-			    site_name_item);
 		}
-		return (&ctx->site_global_catalog);
+		return (&ctx->global_catalog);
 	}
 	return (NULL);
 }
