svn commit: samba r25747 - in branches/SAMBA_4_0/source: dsdb/samdb/ldb_modules scripting/libjs setup

abartlet at samba.org abartlet at samba.org
Mon Oct 29 10:54:06 GMT 2007


Author: abartlet
Date: 2007-10-29 10:54:06 +0000 (Mon, 29 Oct 2007)
New Revision: 25747

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

Log:
Implement linked attributes, for add operations.

Much more work is still required here, particularly to handle this
better during the provision, and to handle modifies and deletes, but
this is a start.

Andrew Bartlett

Added:
   branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/linked_attributes.c
Modified:
   branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/config.mk
   branches/SAMBA_4_0/source/scripting/libjs/provision.js
   branches/SAMBA_4_0/source/setup/provision_users.ldif


Changeset:
Modified: branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/config.mk
===================================================================
--- branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/config.mk	2007-10-27 10:00:44 UTC (rev 25746)
+++ branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/config.mk	2007-10-29 10:54:06 UTC (rev 25747)
@@ -244,3 +244,15 @@
 # End MODULE ldb_subtree_rename
 ################################################
 
+################################################
+# Start MODULE ldb_linked_attributes
+[MODULE::ldb_linked_attributes]
+INIT_FUNCTION = ldb_linked_attributes_init
+CFLAGS = -Ilib/ldb/include
+PRIVATE_DEPENDENCIES = LIBTALLOC SAMDB 
+SUBSYSTEM = LIBLDB
+OBJ_FILES = \
+		linked_attributes.o
+# End MODULE ldb_linked_attributes
+################################################
+

Added: branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/linked_attributes.c
===================================================================
--- branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/linked_attributes.c	2007-10-27 10:00:44 UTC (rev 25746)
+++ branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/linked_attributes.c	2007-10-29 10:54:06 UTC (rev 25747)
@@ -0,0 +1,312 @@
+/* 
+   ldb database library
+
+   Copyright (C) Andrew Bartlett <abartlet at samba.org> 2007
+
+   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
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ *  Name: ldb
+ *
+ *  Component: ldb linked_attributes module
+ *
+ *  Description: Module to ensure linked attribute pairs remain in sync
+ *
+ *  Author: Andrew Bartlett
+ */
+
+#include "includes.h"
+#include "ldb/include/ldb.h"
+#include "ldb/include/ldb_errors.h"
+#include "ldb/include/ldb_private.h"
+#include "dsdb/samdb/samdb.h"
+
+struct linked_attributes_context {
+	struct ldb_module *module;
+	struct ldb_handle *handle;
+	struct ldb_request *orig_req;
+
+	struct ldb_request **down_req;
+	int num_requests;
+	int finished_requests;
+};
+
+static struct linked_attributes_context *linked_attributes_init_handle(struct ldb_request *req, 
+								 struct ldb_module *module)
+{
+	struct linked_attributes_context *ac;
+	struct ldb_handle *h;
+
+	h = talloc_zero(req, struct ldb_handle);
+	if (h == NULL) {
+		ldb_set_errstring(module->ldb, "Out of Memory");
+		return NULL;
+	}
+
+	h->module = module;
+
+	ac = talloc_zero(h, struct linked_attributes_context);
+	if (ac == NULL) {
+		ldb_set_errstring(module->ldb, "Out of Memory");
+		talloc_free(h);
+		return NULL;
+	}
+
+	h->private_data	= ac;
+
+	ac->module = module;
+	ac->handle = h;
+	ac->orig_req = req;
+
+	req->handle = h;
+
+	return ac;
+}
+
+/* add */
+static int linked_attributes_add(struct ldb_module *module, struct ldb_request *req)
+{
+	int i, j, ret;
+	struct linked_attributes_context *ac;
+
+	const struct dsdb_schema *schema = dsdb_get_schema(module->ldb);
+	if (!schema) {
+		/* without schema, this doesn't make any sense */
+		return ldb_next_request(module, req);
+	}
+
+	if (ldb_dn_is_special(req->op.mod.message->dn)) {
+		/* do not manipulate our control entries */
+		return ldb_next_request(module, req);
+	}
+
+
+	ac = linked_attributes_init_handle(req, module);
+	if (!ac) {
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+	
+	/* prepare the first operation */
+	ac->down_req = talloc_realloc(ac, ac->down_req, 
+				      struct ldb_request *, 1);
+	if (!ac->down_req) {
+		ldb_oom(ac->module->ldb);
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+	
+	ac->down_req[0] = talloc(ac->down_req, struct ldb_request);
+	if (!ac->down_req[0]) {
+		ldb_oom(ac->module->ldb);
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+	*(ac->down_req[0]) = *req; /* copy the request */
+	
+	ac->num_requests++;
+	
+	/* Run the original request */
+	ret = ldb_next_request(module, req);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+
+	for (i=0; i < req->op.add.message->num_elements; i++) {
+		const struct dsdb_attribute *target_attr;
+		const struct ldb_message_element *el = &req->op.add.message->elements[i];
+		const struct dsdb_attribute *schema_attr
+			= dsdb_attribute_by_lDAPDisplayName(schema, el->name);
+		if (!schema_attr) {
+			ldb_asprintf_errstring(module->ldb, 
+					       "attribute %s is not a valid attribute in schema", req->op.add.message->elements[i].name);
+			return LDB_ERR_OBJECT_CLASS_VIOLATION;			
+		}
+		/* We have a valid attribute, not find out if it is linked */
+		if (schema_attr->linkID == 0) {
+			continue;
+		}
+		
+		if ((schema_attr->linkID & 1) == 1) {
+			/* Odd is for the target.  Illigal to modify */
+			ldb_asprintf_errstring(module->ldb, 
+					       "attribute %s must not be modified directly, it is a linked attribute", req->op.add.message->elements[i].name);
+			return LDB_ERR_UNWILLING_TO_PERFORM;
+		}
+		
+		/* Even link IDs are for the originating attribute */
+		
+		/* Now find the target attribute */
+		target_attr = dsdb_attribute_by_linkID(schema, schema_attr->linkID + 1);
+		if (!target_attr) {
+			ldb_asprintf_errstring(module->ldb, 
+					       "attribute %s does not have valid link target", req->op.add.message->elements[i].name);
+			return LDB_ERR_OBJECT_CLASS_VIOLATION;			
+		}
+
+		/* Prepare the modify (add element) on the targets */
+
+		/* For each value being added, we need to setup the modify */
+		for (j=0; j < el->num_values; j++) {
+			struct ldb_request *new_req;
+			/* Create the modify request */
+			struct ldb_message *new_msg = ldb_msg_new(ac->down_req);
+			if (!new_msg) {
+				ldb_oom(module->ldb);
+				return LDB_ERR_OPERATIONS_ERROR;
+			}
+			new_msg->dn = ldb_dn_new(new_msg, module->ldb, (char *)el->values[j].data);
+			if (!new_msg->dn) {
+				ldb_asprintf_errstring(module->ldb, 
+					       "attribute %s value %s was not a valid DN", req->op.add.message->elements[i].name,
+						       el->values[j].data);
+				return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+			}
+
+			ret = ldb_msg_add_empty(new_msg, target_attr->lDAPDisplayName, 
+						LDB_FLAG_MOD_ADD, NULL);
+			if (ret != LDB_SUCCESS) {
+				return ret;
+			}
+			
+			ret = ldb_msg_add_string(new_msg, target_attr->lDAPDisplayName, 
+						 ldb_dn_get_linearized(ac->orig_req->op.add.message->dn));
+			if (ret != LDB_SUCCESS) {
+				return ret;
+			}
+
+			ret = ldb_build_mod_req(&new_req, module->ldb, ac->down_req,
+						new_msg,
+						NULL,
+						NULL,
+						NULL);
+			if (ret != LDB_SUCCESS) {
+				return ret;
+			}
+			
+			talloc_steal(new_req, new_msg);
+			
+			ldb_set_timeout_from_prev_req(module->ldb, req, new_req);
+			
+			/* Now add it to the list */
+			ac->down_req = talloc_realloc(ac, ac->down_req, 
+						      struct ldb_request *, ac->num_requests + 1);
+			if (!ac->down_req) {
+				ldb_oom(ac->module->ldb);
+				return LDB_ERR_OPERATIONS_ERROR;
+			}
+			ac->down_req[ac->num_requests] = new_req;
+			ac->num_requests++;
+
+			/* Run the new request */
+			ret = ldb_next_request(module, new_req);
+			if (ret != LDB_SUCCESS) {
+				return ret;
+			}
+		}
+	}
+	return ret;
+}
+
+/* modify */
+static int linked_attributes_modify(struct ldb_module *module, struct ldb_request *req)
+{
+	return ldb_next_request(module, req);
+}
+
+/* delete */
+static int linked_attributes_delete(struct ldb_module *module, struct ldb_request *req)
+{
+	return ldb_next_request(module, req);
+}
+
+/* rename */
+static int linked_attributes_rename(struct ldb_module *module, struct ldb_request *req)
+{
+	return ldb_next_request(module, req);
+}
+
+static int linked_attributes_wait_none(struct ldb_handle *handle) {
+	struct linked_attributes_context *ac;
+	int i, ret = LDB_ERR_OPERATIONS_ERROR;
+	if (!handle || !handle->private_data) {
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+
+	if (handle->state == LDB_ASYNC_DONE) {
+		return handle->status;
+	}
+
+	handle->state = LDB_ASYNC_PENDING;
+	handle->status = LDB_SUCCESS;
+
+	ac = talloc_get_type(handle->private_data, struct linked_attributes_context);
+
+	for (i=0; i < ac->num_requests; i++) {
+		ret = ldb_wait(ac->down_req[i]->handle, LDB_WAIT_NONE);
+		
+		if (ret != LDB_SUCCESS) {
+			handle->status = ret;
+			goto done;
+		}
+		if (ac->down_req[i]->handle->status != LDB_SUCCESS) {
+			handle->status = ac->down_req[i]->handle->status;
+			goto done;
+		}
+		
+		if (ac->down_req[i]->handle->state != LDB_ASYNC_DONE) {
+			return LDB_SUCCESS;
+		}
+	}
+
+done:
+	handle->state = LDB_ASYNC_DONE;
+	return ret;
+
+}
+
+static int linked_attributes_wait_all(struct ldb_handle *handle) {
+
+	int ret;
+
+	while (handle->state != LDB_ASYNC_DONE) {
+		ret = linked_attributes_wait_none(handle);
+		if (ret != LDB_SUCCESS) {
+			return ret;
+		}
+	}
+
+	return handle->status;
+}
+
+static int linked_attributes_wait(struct ldb_handle *handle, enum ldb_wait_type type)
+{
+	if (type == LDB_WAIT_ALL) {
+		return linked_attributes_wait_all(handle);
+	} else {
+		return linked_attributes_wait_none(handle);
+	}
+}
+
+static const struct ldb_module_ops linked_attributes_ops = {
+	.name		   = "linked_attributes",
+	.add               = linked_attributes_add,
+	.modify            = linked_attributes_modify,
+	.del               = linked_attributes_delete,
+	.rename            = linked_attributes_rename,
+	.wait              = linked_attributes_wait,
+};
+
+int ldb_linked_attributes_init(void)
+{
+	return ldb_register_module(&linked_attributes_ops);
+}

Modified: branches/SAMBA_4_0/source/scripting/libjs/provision.js
===================================================================
--- branches/SAMBA_4_0/source/scripting/libjs/provision.js	2007-10-27 10:00:44 UTC (rev 25746)
+++ branches/SAMBA_4_0/source/scripting/libjs/provision.js	2007-10-29 10:54:06 UTC (rev 25747)
@@ -966,6 +966,7 @@
 					"objectclass",
 					"rdn_name",
 					"subtree_rename",
+					"linked_attributes",
 					"show_deleted",
 					"partition");
 	subobj.MODULES_LIST = join(",", modules_list);

Modified: branches/SAMBA_4_0/source/setup/provision_users.ldif
===================================================================
--- branches/SAMBA_4_0/source/setup/provision_users.ldif	2007-10-27 10:00:44 UTC (rev 25746)
+++ branches/SAMBA_4_0/source/setup/provision_users.ldif	2007-10-29 10:54:06 UTC (rev 25747)
@@ -2,11 +2,6 @@
 objectClass: user
 cn: Administrator
 description: Built-in account for administering the computer/domain
-memberOf: CN=Group Policy Creator Owners,CN=Users,${DOMAINDN}
-memberOf: CN=Domain Admins,CN=Users,${DOMAINDN}
-memberOf: CN=Enterprise Admins,CN=Users,${DOMAINDN}
-memberOf: CN=Schema Admins,CN=Users,${DOMAINDN}
-memberOf: CN=Administrators,CN=Builtin,${DOMAINDN}
 userAccountControl: 66048
 objectSid: ${DOMAINSID}-500
 adminCount: 1
@@ -19,7 +14,6 @@
 objectClass: user
 cn: Guest
 description: Built-in account for guest access to the computer/domain
-memberOf: CN=Guests,CN=Builtin,${DOMAINDN}
 userAccountControl: 66082
 primaryGroupID: 514
 objectSid: ${DOMAINSID}-501
@@ -241,7 +235,6 @@
 cn: Enterprise Admins
 description: Designated administrators of the enterprise
 member: CN=Administrator,CN=Users,${DOMAINDN}
-memberOf: CN=Administrators,CN=Builtin,${DOMAINDN}
 objectSid: ${DOMAINSID}-519
 adminCount: 1
 sAMAccountName: Enterprise Admins
@@ -264,7 +257,6 @@
 cn: Domain Admins
 description: Designated administrators of the domain
 member: CN=Administrator,CN=Users,${DOMAINDN}
-memberOf: CN=Administrators,CN=Builtin,${DOMAINDN}
 objectSid: ${DOMAINSID}-512
 adminCount: 1
 sAMAccountName: Domain Admins
@@ -275,7 +267,6 @@
 objectClass: group
 cn: Domain Users
 description: All domain users
-memberOf: CN=Users,CN=Builtin,${DOMAINDN}
 objectSid: ${DOMAINSID}-513
 sAMAccountName: Domain Users
 isCriticalSystemObject: TRUE
@@ -285,7 +276,6 @@
 objectClass: group
 cn: Domain Guests
 description: All domain guests
-memberOf: CN=Guests,CN=Builtin,${DOMAINDN}
 objectSid: ${DOMAINSID}-514
 sAMAccountName: Domain Guests
 isCriticalSystemObject: TRUE



More information about the samba-cvs mailing list