svn commit: samba r12566 - in trunk/source: include lib passdb

vlendec at samba.org vlendec at samba.org
Thu Dec 29 13:18:30 GMT 2005


Author: vlendec
Date: 2005-12-29 13:18:28 +0000 (Thu, 29 Dec 2005)
New Revision: 12566

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=12566

Log:
Move adding RIDs to pdb_ldap. Now I need to look at creating aliases, and I
can (should I?) remove allocating RIDs from winbind. Nobody will be using that
anymore...

Volker

Modified:
   trunk/source/include/smbldap.h
   trunk/source/lib/smbldap.c
   trunk/source/passdb/pdb_ldap.c


Changeset:
Modified: trunk/source/include/smbldap.h
===================================================================
--- trunk/source/include/smbldap.h	2005-12-29 13:10:36 UTC (rev 12565)
+++ trunk/source/include/smbldap.h	2005-12-29 13:18:28 UTC (rev 12566)
@@ -209,6 +209,15 @@
                           const char *location);
 const char** get_userattr_list( int schema_ver );
 
+char * smbldap_talloc_single_attribute(LDAP *ldap_struct, LDAPMessage *entry,
+				       const char *attribute,
+				       TALLOC_CTX *mem_ctx);
+void talloc_autodestroy_ldapmsg(TALLOC_CTX *mem_ctx, LDAPMessage *result);
+const char *smbldap_talloc_dn(TALLOC_CTX *mem_ctx, LDAP *ld,
+			      LDAPMessage *entry);
+
+
+
 #endif 	/* HAVE_LDAP */
 
 #define LDAP_CONNECT_DEFAULT_TIMEOUT   15

Modified: trunk/source/lib/smbldap.c
===================================================================
--- trunk/source/lib/smbldap.c	2005-12-29 13:10:36 UTC (rev 12565)
+++ trunk/source/lib/smbldap.c	2005-12-29 13:18:28 UTC (rev 12566)
@@ -321,6 +321,63 @@
 					    sizeof(pstring));
 }
 
+ char * smbldap_talloc_single_attribute(LDAP *ldap_struct, LDAPMessage *entry,
+					const char *attribute,
+					TALLOC_CTX *mem_ctx)
+{
+	char **values;
+	char *result;
+
+	if (attribute == NULL) {
+		return NULL;
+	}
+
+	values = ldap_get_values(ldap_struct, entry, attribute);
+
+	if (values == NULL) {
+		DEBUG(10, ("attribute %s does not exist\n", attribute));
+		return NULL;
+	}
+
+	if (ldap_count_values(values) != 1) {
+		DEBUG(10, ("attribute %s has %d values, expected only one\n",
+			   attribute, ldap_count_values(values)));
+		ldap_value_free(values);
+		return NULL;
+	}
+
+	if (pull_utf8_talloc(mem_ctx, &result, values[0]) < 0) {
+		DEBUG(10, ("pull_utf8_talloc failed\n"));
+		ldap_value_free(values);
+		return NULL;
+	}
+
+	ldap_value_free(values);
+
+#ifdef DEBUG_PASSWORDS
+	DEBUG (100, ("smbldap_get_single_attribute: [%s] = [%s]\n",
+		     attribute, result));
+#endif	
+	return result;
+}
+
+ static int ldapmsg_destructor(void *p) {
+	LDAPMessage **result = talloc_get_type_abort(p, LDAPMessage *);
+	ldap_msgfree(*result);
+	return 0;
+}
+
+ void talloc_autodestroy_ldapmsg(TALLOC_CTX *mem_ctx, LDAPMessage *result)
+{
+	LDAPMessage **handle;
+
+	handle = TALLOC_P(mem_ctx, LDAPMessage *);
+	SMB_ASSERT(handle != NULL);
+
+	*handle = result;
+	talloc_set_destructor(handle, ldapmsg_destructor);
+}
+
 /************************************************************************
  Routine to manage the LDAPMod structure array
  manage memory used by the array, by each struct, and values
@@ -1442,6 +1499,25 @@
 	return unix_dn;
 }
 
+ const char *smbldap_talloc_dn(TALLOC_CTX *mem_ctx, LDAP *ld,
+			       LDAPMessage *entry)
+{
+	char *utf8_dn, *unix_dn;
+
+	utf8_dn = ldap_get_dn(ld, entry);
+	if (!utf8_dn) {
+		DEBUG (5, ("smbldap_get_dn: ldap_get_dn failed\n"));
+		return NULL;
+	}
+	if (pull_utf8_talloc(mem_ctx, &unix_dn, utf8_dn) == (size_t)-1) {
+		DEBUG (0, ("smbldap_get_dn: String conversion failure utf8 "
+			   "[%s]\n", utf8_dn));
+		return NULL;
+	}
+	ldap_memfree(utf8_dn);
+	return unix_dn;
+}
+
 /*******************************************************************
  Check if root-dse has a certain Control or Extension
 ********************************************************************/

Modified: trunk/source/passdb/pdb_ldap.c
===================================================================
--- trunk/source/passdb/pdb_ldap.c	2005-12-29 13:10:36 UTC (rev 12565)
+++ trunk/source/passdb/pdb_ldap.c	2005-12-29 13:18:28 UTC (rev 12566)
@@ -4258,9 +4258,120 @@
 	return False;
 }
 
+static NTSTATUS ldapsam_get_new_rid(struct ldapsam_privates *ldap_state,
+				    uint32 *rid)
+{
+	struct smbldap_state *smbldap_state = ldap_state->smbldap_state;
+	LDAP *ldap_struct = smbldap_state->ldap_struct;
+
+	LDAPMessage *result = NULL;
+	LDAPMessage *entry = NULL;
+	LDAPMod **mods = NULL;
+	NTSTATUS status;
+	char *value;
+	int rc;
+	uint32 nextRid = 0;
+
+	TALLOC_CTX *mem_ctx;
+
+	mem_ctx = talloc_new(NULL);
+	if (mem_ctx == NULL) {
+		DEBUG(0, ("talloc_new failed\n"));
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	status = smbldap_search_domain_info(smbldap_state, &result,
+					    get_global_sam_name(), False);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(3, ("Could not get domain info: %s\n",
+			  nt_errstr(status)));
+		goto done;
+	}
+
+	talloc_autodestroy_ldapmsg(mem_ctx, result);
+
+	entry = ldap_first_entry(ldap_struct, result);
+	if (entry == NULL) {
+		DEBUG(0, ("Could not get domain info entry\n"));
+		status = NT_STATUS_INTERNAL_DB_CORRUPTION;
+		goto done;
+	}
+
+	/* Find the largest of the three attributes "sambaNextRid",
+	   "sambaNextGroupRid" and "sambaNextUserRid". I gave up on the
+	   concept of differentiating between user and group rids, and will
+	   use only "sambaNextRid" in the future. But for compatibility
+	   reasons I look if others have chosen different strategies -- VL */
+
+	value = smbldap_talloc_single_attribute(ldap_struct, entry,
+						"sambaNextRid", mem_ctx);
+	if (value != NULL) {
+		uint32 tmp = (uint32)strtoul(value, NULL, 10);
+		nextRid = MAX(nextRid, tmp);
+	}
+
+	value = smbldap_talloc_single_attribute(ldap_struct, entry,
+						"sambaNextUserRid", mem_ctx);
+	if (value != NULL) {
+		uint32 tmp = (uint32)strtoul(value, NULL, 10);
+		nextRid = MAX(nextRid, tmp);
+	}
+
+	value = smbldap_talloc_single_attribute(ldap_struct, entry,
+						"sambaNextGroupRid", mem_ctx);
+	if (value != NULL) {
+		uint32 tmp = (uint32)strtoul(value, NULL, 10);
+		nextRid = MAX(nextRid, tmp);
+	}
+
+	if (nextRid == 0) {
+		nextRid = BASE_RID-1;
+	}
+
+	nextRid += 1;
+
+	smbldap_make_mod(ldap_struct, entry, &mods, "sambaNextRid",
+			 talloc_asprintf(mem_ctx, "%d", nextRid));
+
+	rc = smbldap_modify(smbldap_state,
+			    smbldap_talloc_dn(mem_ctx, ldap_struct, entry),
+			    mods);
+
+	/* ACCESS_DENIED is used as a placeholder for "the modify failed,
+	 * please retry" */
+
+	status = (rc == LDAP_SUCCESS) ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
+
+ done:
+	if (NT_STATUS_IS_OK(status)) {
+		*rid = nextRid;
+	}
+
+	ldap_mods_free(mods, True);
+	talloc_free(mem_ctx);
+	return status;
+}
+
 static BOOL ldapsam_new_rid(struct pdb_methods *methods, uint32 *rid)
 {
-	return winbind_allocate_rid(rid);
+	int i;
+
+	for (i=0; i<10; i++) {
+		NTSTATUS result = ldapsam_get_new_rid(methods->private_data,
+						      rid);
+		if (NT_STATUS_IS_OK(result)) {
+			return True;
+		}
+
+		if (!NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)) {
+			return False;
+		}
+
+		/* The ldap update failed (maybe a race condition), retry */
+	}
+
+	/* Tried 10 times, fail. */
+	return False;
 }
 
 /**********************************************************************



More information about the samba-cvs mailing list