changeset 13328:2f33da224406

849 domain controller "hot fail over" can take forever Reviewed by: Albert Lee <trisk@nexenta.com> Reviewed by: Garrett D'Amore <garrett@nexenta.com> Reviewed by: Richard Lowe <richlowe@richlowe.net> Approved by: Richard Lowe <richlowe@richlowe.net>
author Gordon Ross <gwr@nexenta.com>
date Thu, 07 Apr 2011 19:44:19 -0400
parents b9e92167922a
children c48b8bf84ab7
files usr/src/lib/smbsrv/libmlsvc/common/dssetup_clnt.c usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h usr/src/lib/smbsrv/libmlsvc/common/mlsvc_domain.c usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c usr/src/lib/smbsrv/libsmb/common/libsmb.h usr/src/lib/smbsrv/libsmb/common/mapfile-vers usr/src/lib/smbsrv/libsmb/common/smb_domain.c usr/src/lib/smbsrv/libsmbrdr/common/smbrdr.h usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_netbios.c usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_session.c
diffstat 11 files changed, 92 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/lib/smbsrv/libmlsvc/common/dssetup_clnt.c	Wed Apr 06 20:07:39 2011 -0500
+++ b/usr/src/lib/smbsrv/libmlsvc/common/dssetup_clnt.c	Thu Apr 07 19:44:19 2011 -0400
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  */
 
 /*
@@ -30,6 +31,7 @@
 #include <strings.h>
 #include <smbsrv/wintypes.h>
 #include <smbsrv/libsmb.h>
+#include <smbsrv/libsmbrdr.h>
 #include <smbsrv/ndl/dssetup.ndl>
 #include <smbsrv/libmlsvc.h>
 
@@ -78,19 +80,22 @@
 	return (0);
 }
 
+/*
+ * Check whether our connection to the DC is working.
+ * Note: Do NOT want to block opening a connection,
+ * as that would interfere with smbd_dc_monitor
+ * getting to smbd_dc_update, smb_locate_dc.
+ */
 int
 dssetup_check_service(void)
 {
-	ds_primary_domain_info_t	ds_info;
-	int				rc;
+	char	cur_dc[MAXHOSTNAMELEN];
 
-	bzero(&ds_info, sizeof (ds_primary_domain_info_t));
+	bzero(cur_dc, sizeof (cur_dc));
+	smb_domain_current_dc(cur_dc, sizeof (cur_dc));
 
-	if ((rc = dssetup_get_domain_info(&ds_info)) == 0) {
-		free(ds_info.nt_domain);
-		free(ds_info.dns_domain);
-		free(ds_info.forest);
-	}
+	if (smbrdr_echo(cur_dc) < 0)
+		return (-1);
 
-	return (rc);
+	return (0);
 }
--- a/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h	Wed Apr 06 20:07:39 2011 -0500
+++ b/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h	Thu Apr 07 19:44:19 2011 -0400
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #ifndef	_LIBMLSVC_H
@@ -59,6 +60,7 @@
  */
 
 extern boolean_t smb_locate_dc(char *, char *, smb_domainex_t *);
+extern int smb_ddiscover_wait(void);
 
 extern int dssetup_check_service(void);
 extern void dssetup_clear_domain_info(void);
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_domain.c	Wed Apr 06 20:07:39 2011 -0500
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_domain.c	Thu Apr 07 19:44:19 2011 -0400
@@ -21,6 +21,7 @@
 
 /*
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #include <syslog.h>
@@ -154,6 +155,30 @@
 }
 
 /*
+ * 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
  * ==========================================================
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c	Wed Apr 06 20:07:39 2011 -0500
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c	Thu Apr 07 19:44:19 2011 -0400
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #include <sys/errno.h>
@@ -101,12 +102,17 @@
 	for (;;) {
 		(void) sleep(MLSVC_TIMECHECK_INTERVAL);
 
-		if (smb_config_get_secmode() == SMB_SECMODE_DOMAIN) {
-			if (!smb_domain_getinfo(&di))
-				continue;
+		if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN)
+			continue;
 
-			ndr_srvsvc_timecheck(di.d_dc, di.d_primary.di_nbname);
-		}
+		/* Avoid interfering with DC discovery. */
+		if (smb_ddiscover_wait() != 0)
+			continue;
+
+		if (!smb_domain_getinfo(&di))
+			continue;
+
+		ndr_srvsvc_timecheck(di.d_dc, di.d_primary.di_nbname);
 	}
 
 	/*NOTREACHED*/
--- a/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c	Wed Apr 06 20:07:39 2011 -0500
+++ b/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c	Thu Apr 07 19:44:19 2011 -0400
@@ -21,6 +21,7 @@
 
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  */
 
 /*
@@ -155,7 +156,9 @@
 
 	(void) smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN);
 
-	if (!smb_domain_getinfo(&di)) {
+	/* Avoid interfering with DC discovery. */
+	if (smb_ddiscover_wait() != 0 ||
+	    !smb_domain_getinfo(&di)) {
 		netr_invalidate_chain();
 		return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
 	}
--- a/usr/src/lib/smbsrv/libsmb/common/libsmb.h	Wed Apr 06 20:07:39 2011 -0500
+++ b/usr/src/lib/smbsrv/libsmb/common/libsmb.h	Thu Apr 07 19:44:19 2011 -0400
@@ -21,6 +21,7 @@
 
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #ifndef	_LIBSMB_H
@@ -665,6 +666,7 @@
     smb_domain_t *);
 void smb_domain_set_trust_info(char *, char *, char *,
     uint32_t, uint32_t, uint32_t, smb_domain_t *);
+void smb_domain_current_dc(char *buf, size_t len);
 
 typedef struct smb_gsid {
 	smb_sid_t *gs_sid;
--- a/usr/src/lib/smbsrv/libsmb/common/mapfile-vers	Wed Apr 06 20:07:39 2011 -0500
+++ b/usr/src/lib/smbsrv/libsmb/common/mapfile-vers	Thu Apr 07 19:44:19 2011 -0400
@@ -19,6 +19,7 @@
 #
 #
 # Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
 #
 
 #
@@ -124,6 +125,7 @@
 	smb_ctxbuf_printf;
 	smb_dlclose;
 	smb_dlopen;
+	smb_domain_current_dc;
 	smb_domain_end_update;
 	smb_domain_fini;
 	smb_domain_getinfo;
--- a/usr/src/lib/smbsrv/libsmb/common/smb_domain.c	Wed Apr 06 20:07:39 2011 -0500
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_domain.c	Thu Apr 07 19:44:19 2011 -0400
@@ -21,6 +21,8 @@
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  */
 
 /*
@@ -301,6 +303,16 @@
 }
 
 /*
+ * Get the name of the current DC (if any)
+ * Does NOT block.
+ */
+void
+smb_domain_current_dc(char *buf, size_t len)
+{
+	smb_dcache_getdc(buf, len);
+}
+
+/*
  * Transfer the cache to updating state.
  * In this state any request for reading the cache would
  * be blocked until the update is finished.
--- a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr.h	Wed Apr 06 20:07:39 2011 -0500
+++ b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr.h	Thu Apr 07 19:44:19 2011 -0400
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #ifndef _SMBRDR_H_
@@ -258,6 +259,8 @@
 #endif
 } smb_read_andx_rsp_t;
 
+extern int smbrdr_default_timeout; /* seconds */
+
 /*
  * smbrdr_netbios.c
  */
--- a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_netbios.c	Wed Apr 06 20:07:39 2011 -0500
+++ b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_netbios.c	Thu Apr 07 19:44:19 2011 -0400
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  */
 
 /*
@@ -63,6 +64,8 @@
 #define	NB_READ_MSG_ERR_UNDERFLOW		-3
 #define	NB_RCV_MSG_ERR_INVTYPE			-4
 
+int smbrdr_default_timeout = 45; /* sec. */
+
 /*
  * Semaphore object used to serialize access through NetBIOS exchange.
  */
@@ -329,7 +332,9 @@
 
 	FD_ZERO(&readfds);
 	FD_SET(fd, &readfds);
-	tval.tv_sec = (timeout == 0) ? 45 : timeout;
+	if (timeout == 0)
+		timeout = smbrdr_default_timeout;
+	tval.tv_sec = timeout;
 	tval.tv_usec = 0;
 
 	if ((rc = select(fd + 1, &readfds, 0, 0, &tval)) <= 0) {
--- a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_session.c	Wed Apr 06 20:07:39 2011 -0500
+++ b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_session.c	Thu Apr 07 19:44:19 2011 -0400
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  */
 
 /*
@@ -211,7 +212,7 @@
 	char hostname[MAXHOSTNAMELEN];
 	struct sockaddr_in sin;
 	struct sockaddr_in6 sin6;
-	int sock, rc;
+	int sock, rc, tmo;
 	smb_wchar_t unicode_server_name[SMB_PI_MAX_DOMAIN];
 	char server_name[SMB_PI_MAX_DOMAIN];
 	char ipstr[INET6_ADDRSTRLEN];
@@ -222,6 +223,15 @@
 		    strerror(errno));
 		return (-1);
 	}
+
+	/*
+	 * The default connect timeout is very long.
+	 * We want to give up after 45 sec.
+	 */
+	tmo = 1000 * smbrdr_default_timeout;
+	setsockopt(sock, IPPROTO_TCP, TCP_CONN_ABORT_THRESHOLD,
+	    &tmo, sizeof (tmo));
+
 	if (sess->srv_ipaddr.a_family == AF_INET) {
 		bzero(&sin, sizeof (struct sockaddr_in));
 		sin.sin_family = AF_INET;