enhance error handling of winbind

kawasa_r at itg.hitachi.co.jp kawasa_r at itg.hitachi.co.jp
Fri May 7 14:34:26 GMT 2004


Processes that communicate winbind daemon hang when the LDAP server does 
not work. 
This happens winbind daemon is used and LDAP is set as idmap backend.

Since winbind daemon can not manage plural requests at once, processes that
communicate winbindd should wait until the bind from the winbind daemon to
the LDAP server detect timeout.

If communication to the LDAP server is failed, we changed the management 
as follows.
* Do not reconnect the LDAP server.
* Do not user remote_map as the idmap for 5 minutes.(this means, 
do not connect the LDAP server)
* Abort the management of getpwent() and getgrent().


Index: samba-302/source/lib/smbldap.c
===================================================================
RCS file: /cvs/samba-302/source/lib/smbldap.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- samba-302/source/lib/smbldap.c	16 Feb 2004 01:13:35 -0000	1.1
+++ samba-302/source/lib/smbldap.c	4 Mar 2004 04:43:05 -0000	1.2
@@ -33,7 +33,7 @@
 /* Try not to hit the up or down server forever */
 
 #define SMBLDAP_DONT_PING_TIME 10	/* ping only all 10 seconds */
-#define SMBLDAP_NUM_RETRIES 8	        /* retry only 8 times */
+#define SMBLDAP_NUM_RETRIES 1	        /* retry only 1 times */
 
 #define SMBLDAP_IDLE_TIME 150		/* After 2.5 minutes disconnect */
 
@@ -797,6 +797,8 @@
 /**********************************************************************
 Connect to LDAP server (called before every ldap operation)
 *********************************************************************/
+BOOL ldap_server_down = False;
+time_t ldap_server_down_time = NULL;
 static int smbldap_open(struct smbldap_state *ldap_state)
 {
 	int rc;
@@ -826,6 +828,7 @@
 
 	if (ldap_state->ldap_struct != NULL) {
 		DEBUG(11,("smbldap_open: already connected to the LDAP server\n"));
+		ldap_server_down = False;
 		return LDAP_SUCCESS;
 	}
 
@@ -836,6 +839,10 @@
 	if ((rc = smbldap_connect_system(ldap_state, ldap_state->ldap_struct))) {
 		ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
 		ldap_state->ldap_struct = NULL;
+		if (rc == LDAP_SERVER_DOWN ) {
+			ldap_server_down = True;
+			ldap_server_down_time = time(NULL);
+		}
 		return rc;
 	}
 
@@ -843,6 +850,7 @@
 	ldap_state->last_ping = time(NULL);
 	DEBUG(4,("The LDAP server is succesful connected\n"));
 
+	ldap_server_down = False;
 	return LDAP_SUCCESS;
 }
 
Index: samba-302/source/sam/idmap.c
===================================================================
RCS file: /cvs/samba-302/source/sam/idmap.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- samba-302/source/sam/idmap.c	16 Feb 2004 01:13:37 -0000	1.1
+++ samba-302/source/sam/idmap.c	30 Mar 2004 10:48:56 -0000	1.2
@@ -36,6 +36,29 @@
 static struct idmap_methods *cache_map;
 static struct idmap_methods *remote_map;
 
+#define DONT_USE_REMOTE_MAP_TIME 300
+extern BOOL ldap_server_down;
+extern time_t ldap_server_down_time;
+
+BOOL use_remote_map()
+{
+	BOOL _use_remote_map = True;
+
+	if ( ldap_server_down ) {
+		if ((ldap_server_down_time + DONT_USE_REMOTE_MAP_TIME) < time(NULL)) {
+			DEBUG(1,("start using remote_map. ldap_server_down_time = %u\n",
+					ldap_server_down_time));
+			ldap_server_down = False;
+			_use_remote_map = True;
+		} else {
+			DEBUG(3,("stop using remote_map. ldap_server_down_time = %u\n",
+					ldap_server_down_time));
+			_use_remote_map = False;
+		}
+	}
+	return _use_remote_map;
+}
+
 /**********************************************************************
  Get idmap methods. Don't allow tdb to be a remote method.
 **********************************************************************/
@@ -168,6 +191,10 @@
 		return NT_STATUS_OK;
 	}
 
+	if (!use_remote_map()) {
+		return NT_STATUS_UNSUCCESSFUL;
+	}
+
 	if (map == NULL) {
 		/* Ok, we don't have a authoritative remote
 			mapping. So update our local cache only. */
@@ -205,6 +232,10 @@
 		return ret;
 	}
 
+	if (!use_remote_map()) {
+		return ret;
+	}
+
 	/* Ok, the mapping was not in the cache, give the remote map a
            second try. */
 
@@ -239,6 +270,10 @@
 
 	if (remote_map == NULL)
 		return ret;
+
+	if (!use_remote_map()) {
+		return ret;
+	}
 
 	/* We have a second chance, ask our authoritative backend */
 
Index: samba-302/source/nsswitch/winbindd_user.c
===================================================================
RCS file: /cvs/samba-302/source/nsswitch/winbindd_user.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- samba-302/source/nsswitch/winbindd_user.c	16 Feb 2004 01:13:36 -0000	1.1
+++ samba-302/source/nsswitch/winbindd_user.c	4 Mar 2004 05:23:25 -0000	1.2
@@ -475,6 +475,7 @@
 /* Fetch next passwd entry from ntdom database */
 
 #define MAX_GETPWENT_USERS 500
+extern BOOL ldap_server_down;
 
 enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state)
 {
@@ -558,9 +559,14 @@
 			state->response.length += 
 				sizeof(struct winbindd_pw);
 
-		} else
+		} else {
 			DEBUG(1, ("could not lookup domain user %s\n",
 				  name_list[ent->sam_entry_index].name));
+			if (ldap_server_down) {
+				DEBUG(1, ("LDAP server is down. return winbindd error.\n"));
+				return WINBINDD_ERROR;
+			}
+		}
 	}
 
 	/* Out of domains */
Index: samba-302/source/nsswitch/winbindd_group.c
===================================================================
RCS file: /cvs/samba-302/source/nsswitch/winbindd_group.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- samba-302/source/nsswitch/winbindd_group.c	16 Feb 2004 01:13:36 -0000	1.1
+++ samba-302/source/nsswitch/winbindd_group.c	4 Mar 2004 05:23:29 -0000	1.2
@@ -591,6 +591,7 @@
 /* Fetch next group entry from ntdom database */
 
 #define MAX_GETGRENT_GROUPS 500
+extern BOOL ldap_server_down;
 
 enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
 {
@@ -681,6 +682,10 @@
 			DEBUG(1, ("could not look up gid for group %s\n", 
 				  name_list[ent->sam_entry_index].acct_name));
 			
+			if (ldap_server_down) {
+				DEBUG(1, ("LDAP server is down. return winbindd error.\n"));
+				return WINBINDD_ERROR;
+			}
 			ent->sam_entry_index++;
 			goto tryagain;
 		}


More information about the samba-technical mailing list