Print this page
NEX-15558 SMB logon fails during 1st second after service start
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15558 SMB logon fails during 1st second after service start
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-2667 Wrong error when join domain with wrong password
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Bayard Bell <bayard.bell@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
re #12435 rb3958 r10 is added 2 times to panic info
re #12393 rb3935 Kerberos and smbd disagree about who is our AD server

@@ -19,11 +19,11 @@
  * CDDL HEADER END
  */
 
 /*
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #include <syslog.h>
 #include <synch.h>
 #include <pthread.h>

@@ -88,10 +88,18 @@
 smb_dclocator_init(void)
 {
         pthread_attr_t tattr;
         int rc;
 
+        /*
+         * We need the smb_ddiscover_service to run on startup,
+         * so it will enter smb_ddiscover_main() and put the
+         * SMB "domain cache" into "updating" state so clients
+         * trying to logon will wait while we're finding a DC.
+         */
+        smb_dclocator.sdl_locate = B_TRUE;
+
         (void) pthread_attr_init(&tattr);
         (void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
         rc = pthread_create(&smb_dclocator_thr, &tattr,
             smb_ddiscover_service, &smb_dclocator);
         (void) pthread_attr_destroy(&tattr);

@@ -239,10 +247,11 @@
          * Mark the current DC as "bad" and let the DC Locator
          * run again if it's not already.
          */
         syslog(LOG_INFO, "smb_ddiscover, bad DC: %s", bad_dc);
         smb_dclocator.sdl_bad_dc = B_TRUE;
+        smb_domain_bad_dc();
 
         /* In-line smb_ddiscover_kick */
         if (!smb_dclocator.sdl_locate) {
                 smb_dclocator.sdl_locate = B_TRUE;
                 (void) cond_broadcast(&smb_dclocator.sdl_cv);

@@ -250,34 +259,11 @@
 
 out:
         (void) mutex_unlock(&smb_dclocator.sdl_mtx);
 }
 
-/*
- * If domain discovery is running, wait for it to finish.
- */
-int
-smb_ddiscover_wait(void)
-{
-        timestruc_t to;
-        int rc = 0;
 
-        (void) mutex_lock(&smb_dclocator.sdl_mtx);
-
-        if (smb_dclocator.sdl_locate) {
-                to.tv_sec = SMB_DCLOCATOR_TIMEOUT;
-                to.tv_nsec = 0;
-                rc = cond_reltimedwait(&smb_dclocator.sdl_cv,
-                    &smb_dclocator.sdl_mtx, &to);
-        }
-
-        (void) mutex_unlock(&smb_dclocator.sdl_mtx);
-
-        return (rc);
-}
-
-
 /*
  * ==========================================================
  * DC discovery functions
  * ==========================================================
  */

@@ -352,14 +338,23 @@
                  */
                 bzero(&dxi, sizeof (dxi));
                 status = smb_ddiscover_main(sdl->sdl_domain, &dxi);
                 if (status == 0)
                         smb_domain_save();
+
                 (void) mutex_lock(&sdl->sdl_mtx);
+
                 sdl->sdl_status = status;
-                if (status == 0)
+                if (status == 0) {
                         sdl->sdl_dci = dxi.d_dci;
+                } else {
+                        syslog(LOG_DEBUG, "smb_ddiscover_service "
+                            "retry after STATUS_%s",
+                            xlate_nt_status(status));
+                        (void) sleep(5);
+                        goto find_again;
+                }
 
                 /*
                  * Run again if either of cfg_chg or bad_dc
                  * was turned on during smb_ddiscover_main().
                  * Note: mutex held here.

@@ -403,15 +398,10 @@
         if (domain[0] == '\0') {
                 syslog(LOG_DEBUG, "smb_ddiscover_main NULL domain");
                 return (NT_STATUS_INTERNAL_ERROR);
         }
 
-        if (smb_domain_start_update() != SMB_DOMAIN_SUCCESS) {
-                syslog(LOG_DEBUG, "smb_ddiscover_main can't get lock");
-                return (NT_STATUS_INTERNAL_ERROR);
-        }
-
         status = smb_ads_lookup_msdcs(domain, &dxi->d_dci);
         if (status != 0) {
                 syslog(LOG_DEBUG, "smb_ddiscover_main can't find DC (%s)",
                     xlate_nt_status(status));
                 goto out;

@@ -423,15 +413,19 @@
                     "smb_ddiscover_main can't get domain info (%s)",
                     xlate_nt_status(status));
                 goto out;
         }
 
+        if (smb_domain_start_update() != SMB_DOMAIN_SUCCESS) {
+                syslog(LOG_DEBUG, "smb_ddiscover_main can't get lock");
+                status = NT_STATUS_INTERNAL_ERROR;
+        } else {
         smb_domain_update(dxi);
-
-out:
         smb_domain_end_update();
+        }
 
+out:
         /* Don't need the trusted domain list anymore. */
         smb_domainex_free(dxi);
 
         return (status);
 }