summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2012-11-09 17:05:44 +0100
committerAndrew Bartlett <abartlet@samba.org>2012-11-12 09:42:31 +1100
commitf6fa7243f81891cb7703264da526fd873a9745e4 (patch)
tree4f357ae60b03e6cb10633b717ac55440a6a3e796
parented8b27516b212b59167bb932de949a7b54dc44cb (diff)
downloadsamba-f6fa7243f81891cb7703264da526fd873a9745e4.tar.gz
samba-f6fa7243f81891cb7703264da526fd873a9745e4.tar.xz
samba-f6fa7243f81891cb7703264da526fd873a9745e4.zip
s4:dsdb/acl: only give administrators access to attributes marked as confidential (bug #8620)
The full fix will to implement and use the code of the read_acl module, but this is better than nothing for now. Signed-off-by: Stefan Metzmacher <metze@samba.org> Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
-rw-r--r--source4/dsdb/samdb/ldb_modules/acl.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c
index 60750b5be4..1a41ee231f 100644
--- a/source4/dsdb/samdb/ldb_modules/acl.c
+++ b/source4/dsdb/samdb/ldb_modules/acl.c
@@ -51,12 +51,17 @@ struct extended_access_check_attribute {
struct acl_private {
bool acl_perform;
const char **password_attrs;
+ void *cached_schema_ptr;
+ uint64_t cached_schema_metadata_usn;
+ uint64_t cached_schema_loaded_usn;
+ const char **confidential_attrs;
};
struct acl_context {
struct ldb_module *module;
struct ldb_request *req;
bool am_system;
+ bool am_administrator;
bool modify_search;
bool constructed_attrs;
bool allowedAttributes;
@@ -1377,6 +1382,55 @@ static int acl_rename(struct ldb_module *module, struct ldb_request *req)
return ldb_next_request(module, req);
}
+static int acl_search_update_confidential_attrs(struct acl_context *ac,
+ struct acl_private *data)
+{
+ struct dsdb_attribute *a;
+ uint32_t n = 0;
+
+ if ((ac->schema == data->cached_schema_ptr) &&
+ (ac->schema->loaded_usn == data->cached_schema_loaded_usn) &&
+ (ac->schema->metadata_usn == data->cached_schema_metadata_usn))
+ {
+ return LDB_SUCCESS;
+ }
+
+ data->cached_schema_ptr = NULL;
+ data->cached_schema_loaded_usn = 0;
+ data->cached_schema_metadata_usn = 0;
+ TALLOC_FREE(data->confidential_attrs);
+
+ if (ac->schema == NULL) {
+ return LDB_SUCCESS;
+ }
+
+ for (a = ac->schema->attributes; a; a = a->next) {
+ const char **attrs = data->confidential_attrs;
+
+ if (!(a->searchFlags & SEARCH_FLAG_CONFIDENTIAL)) {
+ continue;
+ }
+
+ attrs = talloc_realloc(data, attrs, const char *, n + 2);
+ if (attrs == NULL) {
+ TALLOC_FREE(data->confidential_attrs);
+ return ldb_module_oom(ac->module);
+ }
+
+ attrs[n] = a->lDAPDisplayName;
+ attrs[n+1] = NULL;
+ n++;
+
+ data->confidential_attrs = attrs;
+ }
+
+ data->cached_schema_ptr = ac->schema;
+ data->cached_schema_loaded_usn = ac->schema->loaded_usn;
+ data->cached_schema_metadata_usn = ac->schema->metadata_usn;
+
+ return LDB_SUCCESS;
+}
+
static int acl_search_callback(struct ldb_request *req, struct ldb_reply *ares)
{
struct acl_context *ac;
@@ -1473,6 +1527,24 @@ static int acl_search_callback(struct ldb_request *req, struct ldb_reply *ares)
ldb_msg_remove_attr(ares->message, data->password_attrs[i]);
}
}
+
+ if (ac->am_administrator) {
+ return ldb_module_send_entry(ac->req, ares->message,
+ ares->controls);
+ }
+
+ ret = acl_search_update_confidential_attrs(ac, data);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+
+ if (data->confidential_attrs != NULL) {
+ for (i = 0; data->confidential_attrs[i]; i++) {
+ ldb_msg_remove_attr(ares->message,
+ data->confidential_attrs[i]);
+ }
+ }
+
return ldb_module_send_entry(ac->req, ares->message, ares->controls);
case LDB_REPLY_REFERRAL:
@@ -1507,6 +1579,7 @@ static int acl_search(struct ldb_module *module, struct ldb_request *req)
ac->module = module;
ac->req = req;
ac->am_system = dsdb_module_am_system(module);
+ ac->am_administrator = dsdb_module_am_administrator(module);
ac->constructed_attrs = false;
ac->modify_search = true;
ac->allowedAttributes = ldb_attr_in_list(req->op.search.attrs, "allowedAttributes");
@@ -1534,6 +1607,11 @@ static int acl_search(struct ldb_module *module, struct ldb_request *req)
return ldb_next_request(module, req);
}
+ ret = acl_search_update_confidential_attrs(ac, data);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+
down_tree = ldb_parse_tree_copy_shallow(ac, req->op.search.tree);
if (down_tree == NULL) {
return ldb_oom(ldb);
@@ -1553,6 +1631,15 @@ static int acl_search(struct ldb_module *module, struct ldb_request *req)
"kludgeACLredactedattribute");
}
}
+
+ if (!ac->am_system && !ac->am_administrator && data->confidential_attrs) {
+ for (i = 0; data->confidential_attrs[i]; i++) {
+ ldb_parse_tree_attr_replace(down_tree,
+ data->confidential_attrs[i],
+ "kludgeACLredactedattribute");
+ }
+ }
+
ret = ldb_build_search_req_ex(&down_req,
ldb, ac,
req->op.search.base,