summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/dsdb/samdb/ldb_modules/operational.c133
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,