Author: abartlet
Date: 2007-10-31 05:14:31 +0000 (Wed, 31 Oct 2007)
New Revision: 25763

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

Log:
Handle modifies, in the easy case (add/delete of elements), for the
linked attributes.

Andrew Bartlett

Modified:
   branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/linked_attributes.c


Changeset:
Modified: 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-31 04:41:36 UTC (rev 25762)
+++ branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/linked_attributes.c        
2007-10-31 05:14:31 UTC (rev 25763)
@@ -220,18 +220,168 @@
 /* modify */
 static int linked_attributes_modify(struct ldb_module *module, struct 
ldb_request *req)
 {
-       return ldb_next_request(module, req);
+       /* Look over list of modifications */
+       /* Find if any are for linked attributes */
+       /* Determine the effect of the modification */
+       /* Apply the modify to the linked entry */
+
+       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.mod.message->num_elements; i++) {
+               const struct dsdb_attribute *target_attr;
+               const struct ldb_message_element *el = 
&req->op.mod.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.mod.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.mod.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.mod.message->elements[i].name);
+                       return LDB_ERR_OBJECT_CLASS_VIOLATION;                  
+               }
+
+               if ((el->flags & LDB_FLAG_MOD_MASK) == LDB_FLAG_MOD_REPLACE) {
+                       ldb_asprintf_errstring(module->ldb, 
+                                              "attribute %s may not be 
replaced, only added or deleted", req->op.mod.message->elements[i].name);
+                       return LDB_ERR_UNWILLING_TO_PERFORM;
+               }
+               /* Prepare the modify (mod element) on the targets */
+
+               /* For each value being moded, 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.mod.message->elements[i].name,
+                                                      el->values[j].data);
+                               return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+                       }
+
+                       ret = ldb_msg_add_empty(new_msg, 
target_attr->lDAPDisplayName, 
+                                               el->flags & LDB_FLAG_MOD_MASK, 
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;
 }
 
 /* delete */
 static int linked_attributes_delete(struct ldb_module *module, struct 
ldb_request *req)
 {
+       /* Look up list of linked attributes */
+       /* Search to see if any linked attributes are in this entry */
        return ldb_next_request(module, req);
 }
 
 /* rename */
 static int linked_attributes_rename(struct ldb_module *module, struct 
ldb_request *req)
 {
+       /* Look up list of linked attributes */
+       /* Search to see if any linked attributes are in this entry */
        return ldb_next_request(module, req);
 }
 

Reply via email to