summaryrefslogtreecommitdiff
path: root/source4/dsdb
diff options
context:
space:
mode:
Diffstat (limited to 'source4/dsdb')
-rw-r--r--source4/dsdb/samdb/ldb_modules/operational.c49
1 files changed, 39 insertions, 10 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/operational.c b/source4/dsdb/samdb/ldb_modules/operational.c
index e967f8a5eb..e5aa516fbd 100644
--- a/source4/dsdb/samdb/ldb_modules/operational.c
+++ b/source4/dsdb/samdb/ldb_modules/operational.c
@@ -478,6 +478,18 @@ static int construct_msds_keyversionnumber(struct ldb_module *module,
}
+struct op_controls_flags {
+ bool sd;
+ bool bypassoperational;
+};
+
+static bool check_keep_control_for_attribute(struct op_controls_flags* controls_flags, const char* attr) {
+ if (ldb_attr_cmp(attr, "msDS-KeyVersionNumber") == 0 && controls_flags->bypassoperational) {
+ return true;
+ }
+ return false;
+}
+
/*
a list of attribute names that should be substituted in the parse
tree before the search is done
@@ -517,7 +529,8 @@ static const struct {
enum op_remove {
OPERATIONAL_REMOVE_ALWAYS, /* remove always */
OPERATIONAL_REMOVE_UNASKED,/* remove if not requested */
- OPERATIONAL_SD_FLAGS /* show if SD_FLAGS_OID set, or asked for */
+ OPERATIONAL_SD_FLAGS, /* show if SD_FLAGS_OID set, or asked for */
+ OPERATIONAL_REMOVE_UNLESS_CONTROL /* remove always unless an adhoc control has been specified */
};
/*
@@ -531,7 +544,7 @@ static const struct {
enum op_remove op;
} operational_remove[] = {
{ "nTSecurityDescriptor", OPERATIONAL_SD_FLAGS },
- { "msDS-KeyVersionNumber", OPERATIONAL_REMOVE_ALWAYS },
+ { "msDS-KeyVersionNumber", OPERATIONAL_REMOVE_UNLESS_CONTROL },
{ "parentGUID", OPERATIONAL_REMOVE_ALWAYS },
{ "replPropertyMetaData", OPERATIONAL_REMOVE_UNASKED },
{ "unicodePwd", OPERATIONAL_REMOVE_UNASKED },
@@ -553,7 +566,7 @@ static int operational_search_post_process(struct ldb_module *module,
enum ldb_scope scope,
const char * const *attrs_from_user,
const char * const *attrs_searched_for,
- bool sd_flags_set)
+ struct op_controls_flags* controls_flags)
{
struct ldb_context *ldb;
unsigned int i, a = 0;
@@ -574,8 +587,15 @@ static int operational_search_post_process(struct ldb_module *module,
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 (sd_flags_set ||
+ if (controls_flags->sd ||
ldb_attr_in_list(attrs_from_user, operational_remove[i].attr)) {
continue;
}
@@ -585,6 +605,9 @@ static int operational_search_post_process(struct ldb_module *module,
}
for (a=0;attrs_from_user && attrs_from_user[a];a++) {
+ if (check_keep_control_for_attribute(controls_flags, attrs_from_user[a])) {
+ continue;
+ }
for (i=0;i<ARRAY_SIZE(search_sub);i++) {
if (ldb_attr_cmp(attrs_from_user[a], search_sub[i].attr) != 0) {
continue;
@@ -633,7 +656,6 @@ failed:
return -1;
}
-
/*
hook search operations
*/
@@ -643,7 +665,7 @@ struct operational_context {
struct ldb_request *req;
enum ldb_scope scope;
const char * const *attrs;
- bool sd_flags_set;
+ struct op_controls_flags* controls_flags;
};
static int operational_callback(struct ldb_request *req, struct ldb_reply *ares)
@@ -671,7 +693,7 @@ static int operational_callback(struct ldb_request *req, struct ldb_reply *ares)
ac->scope,
ac->attrs,
req->op.search.attrs,
- ac->sd_flags_set);
+ ac->controls_flags);
if (ret != 0) {
return ldb_module_done(ac->req, NULL, NULL,
LDB_ERR_OPERATIONS_ERROR);
@@ -728,10 +750,20 @@ static int operational_search(struct ldb_module *module, struct ldb_request *req
parse_tree_sub[i].replace);
}
+ ac->controls_flags = talloc(ac, struct op_controls_flags);
+ /* remember if the SD_FLAGS_OID was set */
+ ac->controls_flags->sd = (ldb_request_get_control(req, LDB_CONTROL_SD_FLAGS_OID) != NULL);
+ /* remember if the LDB_CONTROL_BYPASSOPERATIONAL_OID */
+ ac->controls_flags->bypassoperational = (ldb_request_get_control(req,
+ LDB_CONTROL_BYPASSOPERATIONAL_OID) != NULL);
+
/* in the list of attributes we are looking for, rename any
attributes to the alias for any hidden attributes that can
be fetched directly using non-hidden names */
for (a=0;ac->attrs && ac->attrs[a];a++) {
+ if (check_keep_control_for_attribute(ac->controls_flags, ac->attrs[a])) {
+ continue;
+ }
for (i=0;i<ARRAY_SIZE(search_sub);i++) {
if (ldb_attr_cmp(ac->attrs[a], search_sub[i].attr) == 0 &&
search_sub[i].replace) {
@@ -763,9 +795,6 @@ static int operational_search(struct ldb_module *module, struct ldb_request *req
}
}
- /* remember if the SD_FLAGS_OID was set */
- ac->sd_flags_set = (ldb_request_get_control(req, LDB_CONTROL_SD_FLAGS_OID) != NULL);
-
ret = ldb_build_search_req_ex(&down_req, ldb, ac,
req->op.search.base,
req->op.search.scope,