winbind retries excessively for illegal id allocation

kawasa_r at itg.hitachi.co.jp kawasa_r at itg.hitachi.co.jp
Fri May 7 14:33:56 GMT 2004


This happens when idmap backend is set to LDAP. When getpwent()/getgrent() 
functions try to allocate an id that exceed the specified range
(the range is specified "winbind uid/winbind gid" in the configuration file), 
"ldap_allocate_id: Cannot allocate uid above XXXX!" is massively
appeared in the log file of winbind daemon.

This happens because the winbind daemon repeatedly retry the 
out-of-ranged-allocation and fail.(Is there any reason for this?)

The following patch abolished the retry management except for 
duplicated registrations to the LDAP server. In the exceptional
case, winbind daemon retries once.

Index: samba-302/source/sam/idmap_ldap.c
===================================================================
RCS file: /cvs/samba-302/source/sam/idmap_ldap.c,v
retrieving revision 1.1
retrieving revision 1.3
diff -u -r1.1 -r1.3
--- samba-302/source/sam/idmap_ldap.c	16 Feb 2004 01:13:37 -0000	1.1
+++ samba-302/source/sam/idmap_ldap.c	30 Mar 2004 07:28:00 -0000	1.3
@@ -42,7 +42,9 @@
 static struct ldap_idmap_state ldap_state;
 
 /* number tries while allocating new id */
-#define LDAP_MAX_ALLOC_ID 128
+#define LDAP_MAX_ALLOC_ID 2
+BOOL ldap_allocate_id_error = False;
+BOOL ldap_alloc_collision = False;
 
 
 /***********************************************************************
@@ -466,6 +468,9 @@
 
 	ldap_mods_free( mods, True );
 	if (rc != LDAP_SUCCESS) {
+		if ( rc == LDAP_NO_SUCH_ATTRIBUTE ) {
+			ldap_alloc_collision = True;
+		}
 		DEBUG(0,("ldap_allocate_id: Failed to allocate new %s.  ldap_modify() failed.\n",
 			type));
 		goto out;
@@ -563,6 +568,9 @@
 	char *dn = NULL;
 	NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
 
+	ldap_allocate_id_error = False;
+	ldap_alloc_collision = False;
+
 	sid_to_string(sid_str, sid);
 
 	DEBUG(8,("ldap_get_id_from_sid: %s (%s)\n", sid_str,
@@ -611,10 +619,16 @@
 
 		DEBUG(8,("ldap_get_id_from_sid: Allocating new id\n"));
 		
+		ldap_allocate_id_error = False;
 		for (i = 0; i < LDAP_MAX_ALLOC_ID; i++) {
 			ret = ldap_allocate_id(id, *id_type);
-			if ( NT_STATUS_IS_OK(ret) )
+			if ( NT_STATUS_IS_OK(ret) ) {
+				ldap_allocate_id_error = False;
 				break;
+			} else if ( !ldap_alloc_collision ) {
+				ldap_allocate_id_error = True;
+				break;
+			}
 		}
 		
 		if ( !NT_STATUS_IS_OK(ret) ) {
Index: samba-302/source/nsswitch/winbindd_user.c
===================================================================
RCS file: /cvs/samba-302/source/nsswitch/winbindd_user.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- samba-302/source/nsswitch/winbindd_user.c	4 Mar 2004 05:23:25 -0000	1.2
+++ samba-302/source/nsswitch/winbindd_user.c	15 Mar 2004 01:29:37 -0000	1.3
@@ -476,6 +476,7 @@
 
 #define MAX_GETPWENT_USERS 500
 extern BOOL ldap_server_down;
+extern BOOL ldap_allocate_id_error;
 
 enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state)
 {
@@ -564,6 +565,9 @@
 				  name_list[ent->sam_entry_index].name));
 			if (ldap_server_down) {
 				DEBUG(1, ("LDAP server is down. return winbindd error.\n"));
+				return WINBINDD_ERROR;
+			} else if (ldap_allocate_id_error) {
+				DEBUG(1, ("LDAP allocate id error. return winbindd error.\n"));
 				return WINBINDD_ERROR;
 			}
 		}
Index: samba-302/source/nsswitch/winbindd_group.c
===================================================================
RCS file: /cvs/samba-302/source/nsswitch/winbindd_group.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- samba-302/source/nsswitch/winbindd_group.c	4 Mar 2004 05:23:29 -0000	1.2
+++ samba-302/source/nsswitch/winbindd_group.c	15 Mar 2004 01:29:46 -0000	1.3
@@ -592,6 +592,7 @@
 
 #define MAX_GETGRENT_GROUPS 500
 extern BOOL ldap_server_down;
+extern BOOL ldap_allocate_id_error;
 
 enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
 {
@@ -684,6 +685,9 @@
 			
 			if (ldap_server_down) {
 				DEBUG(1, ("LDAP server is down. return winbindd error.\n"));
+				return WINBINDD_ERROR;
+			} else if (ldap_allocate_id_error) {
+				DEBUG(1, ("LDAP allocate id error. return winbindd error.\n"));
 				return WINBINDD_ERROR;
 			}
 			ent->sam_entry_index++;


More information about the samba-technical mailing list