mirror of
https://github.com/samba-team/samba.git
synced 2025-01-11 05:18:09 +03:00
r25763: Handle modifies, in the easy case (add/delete of elements), for the
linked attributes.
Andrew Bartlett
(This used to be commit c6a6246fbd
)
This commit is contained in:
parent
a4c79f06ae
commit
3c5a71f7e5
@ -220,18 +220,168 @@ static int linked_attributes_add(struct ldb_module *module, struct ldb_request *
|
||||
/* modify */
|
||||
static int linked_attributes_modify(struct ldb_module *module, struct ldb_request *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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user