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