}
+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
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 */
};
/*
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 },
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;
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;
}
}
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;
return -1;
}
-
/*
hook search operations
*/
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)
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);
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) {
}
}
- /* 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,