diff options
author | Matthieu Patou <mat@matws.net> | 2012-12-27 18:29:49 -0800 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2013-02-08 15:06:40 +1100 |
commit | 2dc9c072cbb9b857bf52e229573d92c9a70bdcf6 (patch) | |
tree | 126e33150fefa30170433b86a2b9f7b79acd894d /source4/dsdb/samdb | |
parent | 13b481594585cdb079dcf9b8cf892f5094f44a16 (diff) | |
download | samba-2dc9c072cbb9b857bf52e229573d92c9a70bdcf6.tar.gz samba-2dc9c072cbb9b857bf52e229573d92c9a70bdcf6.tar.bz2 samba-2dc9c072cbb9b857bf52e229573d92c9a70bdcf6.zip |
dsdb-operational: rework the loop for attribute removal
Instead of doing ldb_in_list size(operational_remove) * (attrs_user +
attr_searched) * number of entries times to get the list of attributes to remove we construct this
list before the search and then use it for every entries.
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'source4/dsdb/samdb')
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/operational.c | 133 |
1 files changed, 92 insertions, 41 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/operational.c b/source4/dsdb/samdb/ldb_modules/operational.c index b1122b3d42..a34dee04f8 100644 --- a/source4/dsdb/samdb/ldb_modules/operational.c +++ b/source4/dsdb/samdb/ldb_modules/operational.c @@ -667,10 +667,12 @@ enum op_remove { Some of these are attributes that were once stored, but are now calculated */ -static const struct { +struct op_attributes_operations { const char *attr; enum op_remove op; -} operational_remove[] = { +}; + +static const struct op_attributes_operations operational_remove[] = { { "nTSecurityDescriptor", OPERATIONAL_SD_FLAGS }, { "msDS-KeyVersionNumber", OPERATIONAL_REMOVE_UNLESS_CONTROL }, { "parentGUID", OPERATIONAL_REMOVE_ALWAYS }, @@ -692,6 +694,8 @@ static int operational_search_post_process(struct ldb_module *module, const char * const *attrs_from_user, const char * const *attrs_searched_for, struct op_controls_flags* controls_flags, + struct op_attributes_operations *list, + unsigned int list_size, struct ldb_request *parent) { struct ldb_context *ldb; @@ -701,43 +705,8 @@ static int operational_search_post_process(struct ldb_module *module, ldb = ldb_module_get_ctx(module); /* removed any attrs that should not be shown to the user */ - for (i=0; i<ARRAY_SIZE(operational_remove); i++) { - switch (operational_remove[i].op) { - case OPERATIONAL_REMOVE_UNASKED: - if (ldb_attr_in_list(attrs_from_user, operational_remove[i].attr)) { - continue; - } - if (ldb_attr_in_list(attrs_searched_for, operational_remove[i].attr)) { - continue; - } - case OPERATIONAL_REMOVE_ALWAYS: - ldb_msg_remove_attr(msg, operational_remove[i].attr); - break; - case OPERATIONAL_REMOVE_UNLESS_CONTROL: - if (!check_keep_control_for_attribute(controls_flags, operational_remove[i].attr)) { - ldb_msg_remove_attr(msg, operational_remove[i].attr); - break; - } else { - continue; - } - case OPERATIONAL_SD_FLAGS: - if (ldb_attr_in_list(attrs_from_user, operational_remove[i].attr)) { - continue; - } - if (controls_flags->sd) { - if (attrs_from_user == NULL) { - continue; - } - if (attrs_from_user[0] == NULL) { - continue; - } - if (ldb_attr_in_list(attrs_from_user, "*")) { - continue; - } - } - ldb_msg_remove_attr(msg, operational_remove[i].attr); - break; - } + for (i=0; i < list_size; i++) { + ldb_msg_remove_attr(msg, list[i].attr); } for (a=0;attrs_from_user && attrs_from_user[a];a++) { @@ -802,6 +771,8 @@ struct operational_context { enum ldb_scope scope; const char * const *attrs; struct op_controls_flags* controls_flags; + struct op_attributes_operations *list_operations; + unsigned int list_operations_size; }; static int operational_callback(struct ldb_request *req, struct ldb_reply *ares) @@ -829,7 +800,10 @@ static int operational_callback(struct ldb_request *req, struct ldb_reply *ares) ac->scope, ac->attrs, req->op.search.attrs, - ac->controls_flags, req); + ac->controls_flags, + ac->list_operations, + ac->list_operations_size, + req); if (ret != 0) { return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); @@ -849,6 +823,74 @@ static int operational_callback(struct ldb_request *req, struct ldb_reply *ares) return LDB_SUCCESS; } +static struct op_attributes_operations* operation_get_op_list(TALLOC_CTX *ctx, + const char* const* attrs, + const char* const* searched_attrs, + struct op_controls_flags* controls_flags) +{ + int idx = 0; + int i; + struct op_attributes_operations *list = talloc_zero_array(ctx, + struct op_attributes_operations, + ARRAY_SIZE(operational_remove) + 1); + + if (list == NULL) { + return NULL; + } + + for (i=0; i<ARRAY_SIZE(operational_remove); i++) { + switch (operational_remove[i].op) { + case OPERATIONAL_REMOVE_UNASKED: + if (ldb_attr_in_list(attrs, operational_remove[i].attr)) { + continue; + } + if (ldb_attr_in_list(searched_attrs, operational_remove[i].attr)) { + continue; + } + list[idx].attr = operational_remove[i].attr; + list[idx].op = OPERATIONAL_REMOVE_UNASKED; + idx++; + break; + + case OPERATIONAL_REMOVE_ALWAYS: + list[idx].attr = operational_remove[i].attr; + list[idx].op = OPERATIONAL_REMOVE_ALWAYS; + idx++; + break; + + case OPERATIONAL_REMOVE_UNLESS_CONTROL: + if (!check_keep_control_for_attribute(controls_flags, operational_remove[i].attr)) { + list[idx].attr = operational_remove[i].attr; + list[idx].op = OPERATIONAL_REMOVE_UNLESS_CONTROL; + idx++; + } + break; + + case OPERATIONAL_SD_FLAGS: + if (ldb_attr_in_list(attrs, operational_remove[i].attr)) { + continue; + } + if (controls_flags->sd) { + if (attrs == NULL) { + continue; + } + if (attrs[0] == NULL) { + continue; + } + if (ldb_attr_in_list(attrs, "*")) { + continue; + } + } + list[idx].attr = operational_remove[i].attr; + list[idx].op = OPERATIONAL_SD_FLAGS; + idx++; + break; + } + } + + return list; +} + static int operational_search(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb; @@ -930,7 +972,16 @@ static int operational_search(struct ldb_module *module, struct ldb_request *req } } } - + ac->list_operations = operation_get_op_list(ac, ac->attrs, + search_attrs == NULL?req->op.search.attrs:search_attrs, + ac->controls_flags); + ac->list_operations_size = 0; + i = 0; + + while (ac->list_operations && ac->list_operations[i].attr != NULL) { + i++; + } + ac->list_operations_size = i; ret = ldb_build_search_req_ex(&down_req, ldb, ac, req->op.search.base, req->op.search.scope, |