Print this page
NEX-20555 idmap fall-back to DC discovery is broken
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-3155 idmap in a loop spamming its svc log
Reviewed by: Bayard Bell <bayard.bell@nexenta.com>
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Tony Nguyen <tony.nguyen@nexenta.com>
NEX-2892 NexentaStor losing connectivity to multihomed AD servers
Reviewed by: Bayard Bell <bayard.bell@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
NEX-2225 Unable to join NexentaStor to 2008 AD
NEX-1638 Updated DC Locator
 Includes work by: matt.barden@nexenta.com, kevin.crowe@nexenta.com

@@ -19,11 +19,11 @@
  * CDDL HEADER END
  */
 
 /*
  * 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.
  */
 
 /*
  * Active Directory Auto-Discovery.
  *

@@ -1220,12 +1220,14 @@
         /* If the values is fixed there will not be a site specific version */
         if (is_fixed(&ctx->domain_controller))
                 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. */
         prefer_dc_item = validate_PreferredDC(ctx);
         if (prefer_dc_item != NULL)

@@ -1234,33 +1236,45 @@
         if (req == AD_DISC_GLOBAL)
                 validate_global = B_TRUE;
         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);
 
                         /*
                          * Filter out unresponsive servers, and

@@ -1274,44 +1288,40 @@
                         srv_free(cdc);
                         cdc = NULL;
 
                         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) {
                                 DEBUG1STATUS(ctx, "(no DNS response)");
                                 return (NULL);

@@ -1334,19 +1344,18 @@
                                 DEBUG1STATUS(ctx, "(no LDAP response)");
                                 return (NULL);
                         }
                         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);
 }
 
 ad_disc_ds_t *
 ad_disc_get_DomainController(ad_disc_t ctx, enum ad_disc_req req,

@@ -1514,60 +1523,75 @@
         /* If the values is fixed there will not be a site specific version */
         if (is_fixed(&ctx->global_catalog))
                 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)
                 validate_global = B_TRUE;
         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.
                          */
                         dc_item = validate_DomainController(ctx, req);
                         if (dc_item != NULL) {
                                 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;
                                         }
                                 }
                         }
 
                         /*
                          * 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);
 
                         /*
                          * Filter out unresponsive servers, and

@@ -1581,64 +1605,59 @@
                         srv_free(cgc);
                         cgc = NULL;
 
                         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.
                          */
                         dc_item = validate_DomainController(ctx, req);
                         if (dc_item != NULL) {
                                 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;
                                         }
                                 }
                         }
 
                         /*
                          * 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) {
                                 DEBUG1STATUS(ctx, "(no DNS response)");
                                 return (NULL);

@@ -1661,19 +1680,17 @@
                                 DEBUG1STATUS(ctx, "(no LDAP response)");
                                 return (NULL);
                         }
                         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);
 }