[PATCH] some LDAP fixes

Stefan Metzmacher metze at metzemix.de
Tue Nov 11 22:07:38 GMT 2003


Hi *,

here're a patch which adds a --with-ldap-oldserver option
to let us working together with server which cannot handle the 
LDAP_MOD_ADD/LDAP_MOD_DEL update
and use LDAP_MOD_REPLACE.

This patch also fixes some mem leaks!

-- 

metze

-------------------------------------------
Stefan (metze) Metzmacher <metze at metzemix.de>

-------------- next part --------------
Index: configure.in
===================================================================
RCS file: /cvsroot/samba/source/configure.in,v
retrieving revision 1.300.2.189
diff -u -r1.300.2.189 configure.in
--- configure.in	10 Nov 2003 05:34:51 -0000	1.300.2.189
+++ configure.in	11 Nov 2003 20:18:13 -0000
@@ -2902,6 +2902,24 @@
   AC_MSG_RESULT(no)
 )
 
+#################################################
+# check for a LDAP password database configuration backwards compatibility
+# for old OpenLDAP server's which cannot handle MOD_ADD+MOD_DELETE instead of MOD_REPLACE 
+AC_MSG_CHECKING(whether to use OpenLDAP 2.0.* compatiblity)
+AC_ARG_WITH(ldap-oldserver,
+[  --with-ldap-oldserver   Include OpenLDAP 2.0.* compatiblity (default=no)],
+[ case "$withval" in
+  yes)
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(WITH_LDAP_OLD_SERVER_HACK,1,[Whether to include OpenLDAP 2.0.* compatiblity])
+    ;;
+  *)
+    AC_MSG_RESULT(no)
+    ;;
+  esac ],
+  AC_MSG_RESULT(no)
+)
+
 ########################################################################################
 ##
 ## END OF TESTS FOR SAM BACKENDS.  
Index: lib/smbldap.c
===================================================================
RCS file: /cvsroot/samba/source/lib/smbldap.c,v
retrieving revision 1.1.2.18
diff -u -r1.1.2.18 smbldap.c
--- lib/smbldap.c	29 Oct 2003 21:27:59 -0000	1.1.2.18
+++ lib/smbldap.c	11 Nov 2003 20:18:17 -0000
@@ -437,7 +437,11 @@
 	   the old value, should it exist. */
 
 	if ((newval != NULL) && (strlen(newval) > 0)) {
+#ifndef WITH_LDAP_OLD_SERVER_HACK
 		smbldap_set_mod(mods, LDAP_MOD_ADD, attribute, newval);
+#else	
+		smbldap_set_mod(mods, (existed ? LDAP_MOD_REPLACE : LDAP_MOD_ADD), attribute, newval);
+#endif
 	}
 
 	if (!existed) {
@@ -452,7 +456,13 @@
 	   deny the complete operation if somebody changed the
 	   attribute behind our back. */
 
+#ifndef WITH_LDAP_OLD_SERVER_HACK
 	smbldap_set_mod(mods, LDAP_MOD_DELETE, attribute, oldval);
+#else
+	if ((newval == NULL) || (strlen(newval) == 0)) {
+		smbldap_set_mod(mods, LDAP_MOD_DELETE, attribute, oldval);
+	}
+#endif
 }
 
 /**********************************************************************
Index: passdb/pdb_ldap.c
===================================================================
RCS file: /cvsroot/samba/source/passdb/pdb_ldap.c,v
retrieving revision 1.28.2.95
diff -u -r1.28.2.95 pdb_ldap.c
--- passdb/pdb_ldap.c	31 Oct 2003 19:16:59 -0000	1.28.2.95
+++ passdb/pdb_ldap.c	11 Nov 2003 20:18:31 -0000
@@ -5,7 +5,7 @@
    Copyright (C) Gerald Carter			2001-2003
    Copyright (C) Shahms King			2001
    Copyright (C) Andrew Bartlett		2002-2003
-   Copyright (C) Stefan (metze) Metzmacher	2002
+   Copyright (C) Stefan (metze) Metzmacher	2002-2003
     
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -258,7 +258,7 @@
 				     char **attrs)
 {
 	int rc;
-	LDAPMessage *entry;
+	LDAPMessage *entry = NULL;
 	LDAPMod **mods = NULL;
 	char *name, *dn;
 	BerElement *ptr = NULL;
@@ -1017,8 +1017,8 @@
 {
 	NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
 	struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
-	LDAPMessage *result;
-	LDAPMessage *entry;
+	LDAPMessage *result = NULL;
+	LDAPMessage *entry = NULL;
 	int count;
 	char ** attr_list;
 	int rc;
@@ -1099,8 +1099,8 @@
 static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
 {
 	struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
-	LDAPMessage *result;
-	LDAPMessage *entry;
+	LDAPMessage *result = NULL;
+	LDAPMessage *entry = NULL;
 	int count;
 	int rc;
 	fstring sid_string;
@@ -1264,7 +1264,7 @@
 	struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
 	const char *sname;
 	int rc;
-	LDAPMessage *result;
+	LDAPMessage *result = NULL;
 	NTSTATUS ret;
 	char **attr_list;
 	fstring objclass;
@@ -1328,9 +1328,9 @@
 	struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
 	int rc = 0;
 	char *dn;
-	LDAPMessage *result;
-	LDAPMessage *entry;
-	LDAPMod **mods;
+	LDAPMessage *result = NULL;
+	LDAPMessage *entry = NULL;
+	LDAPMod **mods = NULL;
 	char **attr_list;
 
 	result = pdb_get_backend_private_data(newpwd, my_methods);
@@ -1361,13 +1361,14 @@
 				element_is_changed)) {
 		DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
 		SAFE_FREE(dn);
+		if (mods != NULL)
+			ldap_mods_free(mods,True);
 		return NT_STATUS_UNSUCCESSFUL;
 	}
 	
 	if (mods == NULL) {
 		DEBUG(4,("ldapsam_update_sam_account: mods is empty: nothing to update for user: %s\n",
 			 pdb_get_username(newpwd)));
-		ldap_mods_free(mods, True);
 		SAFE_FREE(dn);
 		return NT_STATUS_OK;
 	}
@@ -1458,6 +1459,7 @@
 				DEBUG(0,("ldapsam_add_sam_account: SID '%s' already in the base, with samba attributes\n", 
 					 sid_to_string(sid_string, sid)));
 				free_attr_list( attr_list );
+				ldap_msgfree(result);
 				return NT_STATUS_UNSUCCESSFUL;
 			}
 			ldap_msgfree(result);
@@ -1514,6 +1516,11 @@
 			 LDAP_OBJ_IDMAP_ENTRY,
 			 LDAP_OBJ_SID_ENTRY);
 		
+		/* free old result before doing a new search */
+		if (result != NULL) {
+			ldap_msgfree(result);
+			result = NULL;
+		}
 		rc = smbldap_search_suffix(ldap_state->smbldap_state, 
 					   filter, attr_list, &result);
 			
@@ -1566,6 +1573,8 @@
 				element_is_set_or_changed)) {
 		DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
 		ldap_msgfree(result);
+		if (mods != NULL)
+			ldap_mods_free(mods,True);
 		return NT_STATUS_UNSUCCESSFUL;		
 	}
 	
@@ -1626,9 +1635,9 @@
 		ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
 				&ld_error);
 		DEBUG(0, ("ldapsam_search_one_group: "
-			  "Problem during the LDAP search: LDAP error: %s (%s)",
+			  "Problem during the LDAP search: LDAP error: %s (%s)\n",
 			  ld_error?ld_error:"(unknown)", ldap_err2string(rc)));
-		DEBUG(3, ("ldapsam_search_one_group: Query was: %s, %s\n",
+		DEBUGADD(3, ("ldapsam_search_one_group: Query was: %s, %s\n",
 			  lp_ldap_group_suffix(), filter));
 		SAFE_FREE(ld_error);
 	}
@@ -1745,8 +1754,8 @@
 {
 	struct ldapsam_privates *ldap_state =
 		(struct ldapsam_privates *)methods->private_data;
-	LDAPMessage *result;
-	LDAPMessage *entry;
+	LDAPMessage *result = NULL;
+	LDAPMessage *entry = NULL;
 	int count;
 
 	if (ldapsam_search_one_group(ldap_state, filter, &result)
@@ -1957,10 +1966,10 @@
 	struct ldapsam_privates *ldap_state =
 		(struct ldapsam_privates *)methods->private_data;
 	int rc;
-	char *dn;
-	LDAPMessage *result;
-	LDAPMessage *entry;
-	LDAPMod **mods;
+	char *dn = NULL;
+	LDAPMessage *result = NULL;
+	LDAPMessage *entry = NULL;
+	LDAPMod **mods = NULL;
 
 	rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result);
 
@@ -1980,6 +1989,8 @@
 				  result, &mods, map)) {
 		DEBUG(0, ("ldapsam_update_group_mapping_entry: init_ldap_from_group failed\n"));
 		ldap_msgfree(result);
+		if (mods != NULL)
+			ldap_mods_free(mods,True);
 		return NT_STATUS_UNSUCCESSFUL;
 	}
 
@@ -2022,7 +2033,7 @@
 {
 	struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)methods->private_data;
 	pstring sidstring, filter;
-	LDAPMessage *result;
+	LDAPMessage *result = NULL;
 	int rc;
 	NTSTATUS ret;
 	char **attr_list;
@@ -2176,6 +2187,11 @@
 
 	smbldap_free_struct(&(*ldap_state)->smbldap_state);
 
+	if ((*ldap_state)->result != NULL) {
+		ldap_msgfree((*ldap_state)->result);
+		(*ldap_state)->result = NULL;
+	}
+
 	*ldap_state = NULL;
 
 	/* No need to free any further, as it is talloc()ed */
@@ -2342,8 +2358,8 @@
 				 alg_rid_base_string)) {
 		alg_rid_base = (uint32)atol(alg_rid_base_string);
 		if (alg_rid_base != algorithmic_rid_base()) {
-			DEBUG(0, ("pdb_init_ldapsam: The value of 'algorithmic RID base' has changed since the LDAP\n\
-database was initialised.  Aborting. \n"));
+			DEBUG(0, ("The value of 'algorithmic RID base' has changed since the LDAP\n"
+				  "database was initialised.  Aborting. \n"));
 			ldap_msgfree(result);
 			return NT_STATUS_UNSUCCESSFUL;
 		}
Index: sam/idmap_ldap.c
===================================================================
RCS file: /cvsroot/samba/source/sam/idmap_ldap.c,v
retrieving revision 1.1.2.18
diff -u -r1.1.2.18 idmap_ldap.c
--- sam/idmap_ldap.c	7 Nov 2003 14:39:47 -0000	1.1.2.18
+++ sam/idmap_ldap.c	11 Nov 2003 20:18:33 -0000
@@ -234,6 +234,7 @@
 
 			next_rid = *rid+1;
 			if (next_rid >= alg_rid_base) {
+				ldap_msgfree(domain_result);
 				return NT_STATUS_UNSUCCESSFUL;
 			}
 			
@@ -382,7 +383,7 @@
 	pstring id_str, new_id_str;
 	LDAPMod **mods = NULL;
 	const char *type;
-	char *dn;
+	char *dn = NULL;
 	char **attr_list;
 	pstring filter;
 	uid_t	luid, huid;
@@ -452,15 +453,22 @@
 	pstr_sprintf(new_id_str, "%lu", 
 		 ((id_type & ID_USERID) ? (unsigned long)id->uid : 
 		  (unsigned long)id->gid) + 1);
-		 
+
+#ifndef WITH_LDAP_OLD_SERVER_HACK		 
 	smbldap_set_mod( &mods, LDAP_MOD_DELETE, type, id_str );		 
 	smbldap_set_mod( &mods, LDAP_MOD_ADD, type, new_id_str );
-	
+#else
+	smbldap_set_mod( &mods, LDAP_MOD_REPLACE, type, new_id_str );
+#endif
+
+	if (mods == NULL) {
+		DEBUG(0,("ldap_allocate_id: smbldap_set_mod() failed.\n"));
+		goto out;		
+	}
+
 	rc = smbldap_modify(ldap_state.smbldap_state, dn, mods);
 
-	SAFE_FREE(dn);
 	ldap_mods_free( mods, True );
-	
 	if (rc != LDAP_SUCCESS) {
 		DEBUG(0,("ldap_allocate_id: Failed to allocate new %s.  ldap_modify() failed.\n",
 			type));
@@ -469,6 +477,10 @@
 	
 	ret = NT_STATUS_OK;
 out:
+	SAFE_FREE(dn);
+	if (result != NULL)
+		ldap_msgfree(result);
+
 	return ret;
 }
 
@@ -682,6 +694,8 @@
 		return NT_STATUS_UNSUCCESSFUL;
 
 	count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result);
+
+	ldap_msgfree(result);
 
 	if ( count > 1 ) {
 		DEBUG(0,("ldap_idmap_init: multiple entries returned from %s (base == %s)\n",


More information about the samba-technical mailing list