diff options
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/acl_read.c | 252 |
1 files changed, 128 insertions, 124 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/acl_read.c b/source4/dsdb/samdb/ldb_modules/acl_read.c index 35a840e1f4..8542163f98 100644 --- a/source4/dsdb/samdb/ldb_modules/acl_read.c +++ b/source4/dsdb/samdb/ldb_modules/acl_read.c @@ -55,7 +55,7 @@ struct aclread_private { }; static void aclread_mark_inaccesslible(struct ldb_message_element *el) { - el->flags |= LDB_FLAG_INTERNAL_INACCESSIBLE_ATTRIBUTE; + el->flags |= LDB_FLAG_INTERNAL_INACCESSIBLE_ATTRIBUTE; } static bool aclread_is_inaccessible(struct ldb_message_element *el) { @@ -64,44 +64,45 @@ static bool aclread_is_inaccessible(struct ldb_message_element *el) { static int aclread_callback(struct ldb_request *req, struct ldb_reply *ares) { - struct ldb_context *ldb; - struct aclread_context *ac; - struct ldb_message *ret_msg; - struct ldb_message *msg; - int ret, num_of_attrs = 0; - unsigned int i, k = 0; - struct security_descriptor *sd; - struct dom_sid *sid = NULL; - TALLOC_CTX *tmp_ctx; - uint32_t instanceType; + struct ldb_context *ldb; + struct aclread_context *ac; + struct ldb_message *ret_msg; + struct ldb_message *msg; + int ret, num_of_attrs = 0; + unsigned int i, k = 0; + struct security_descriptor *sd; + struct dom_sid *sid = NULL; + TALLOC_CTX *tmp_ctx; + uint32_t instanceType; - ac = talloc_get_type(req->context, struct aclread_context); - ldb = ldb_module_get_ctx(ac->module); - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR ); - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - tmp_ctx = talloc_new(ac); - switch (ares->type) { - case LDB_REPLY_ENTRY: - msg = ares->message; - ret = dsdb_get_sd_from_ldb_message(ldb, tmp_ctx, msg, &sd); - if (ret != LDB_SUCCESS || sd == NULL ) { - DEBUG(10, ("acl_read: cannot get descriptor\n")); - ret = LDB_ERR_OPERATIONS_ERROR; - goto fail; - } - sid = samdb_result_dom_sid(tmp_ctx, msg, "objectSid"); - /* get the object instance type */ - instanceType = ldb_msg_find_attr_as_uint(msg, + ac = talloc_get_type(req->context, struct aclread_context); + ldb = ldb_module_get_ctx(ac->module); + if (!ares) { + return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR ); + } + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } + tmp_ctx = talloc_new(ac); + switch (ares->type) { + case LDB_REPLY_ENTRY: + msg = ares->message; + ret = dsdb_get_sd_from_ldb_message(ldb, tmp_ctx, msg, &sd); + if (ret != LDB_SUCCESS || sd == NULL ) { + DEBUG(10, ("acl_read: cannot get descriptor\n")); + ret = LDB_ERR_OPERATIONS_ERROR; + goto fail; + } + sid = samdb_result_dom_sid(tmp_ctx, msg, "objectSid"); + /* get the object instance type */ + instanceType = ldb_msg_find_attr_as_uint(msg, "instanceType", 0); - if (!ldb_dn_is_null(msg->dn) && !(instanceType & INSTANCE_TYPE_IS_NC_HEAD)) - { + if (!ldb_dn_is_null(msg->dn) && !(instanceType & INSTANCE_TYPE_IS_NC_HEAD)) + { /* the object has a parent, so we have to check for visibility */ struct ldb_dn *parent_dn = ldb_dn_get_parent(tmp_ctx, msg->dn); + ret = dsdb_module_check_access_on_dn(ac->module, tmp_ctx, parent_dn, @@ -113,51 +114,52 @@ static int aclread_callback(struct ldb_request *req, struct ldb_reply *ares) } else if (ret != LDB_SUCCESS) { goto fail; } - } - /* for every element in the message check RP */ - for (i=0; i < msg->num_elements; i++) { - const struct dsdb_attribute *attr; - bool is_sd, is_objectsid, is_instancetype; - uint32_t access_mask; - attr = dsdb_attribute_by_lDAPDisplayName(ac->schema, - msg->elements[i].name); - if (!attr) { - DEBUG(2, ("acl_read: cannot find attribute %s in schema\n", + } + /* for every element in the message check RP */ + for (i=0; i < msg->num_elements; i++) { + const struct dsdb_attribute *attr; + bool is_sd, is_objectsid, is_instancetype; + uint32_t access_mask; + attr = dsdb_attribute_by_lDAPDisplayName(ac->schema, + msg->elements[i].name); + if (!attr) { + DEBUG(2, ("acl_read: cannot find attribute %s in schema\n", msg->elements[i].name)); - ret = LDB_ERR_OPERATIONS_ERROR; - goto fail; - } - is_sd = ldb_attr_cmp("nTSecurityDescriptor", + ret = LDB_ERR_OPERATIONS_ERROR; + goto fail; + } + is_sd = ldb_attr_cmp("nTSecurityDescriptor", msg->elements[i].name) == 0; - is_objectsid = ldb_attr_cmp("objectSid", - msg->elements[i].name) == 0; - is_instancetype = ldb_attr_cmp("instanceType", - msg->elements[i].name) == 0; - /* these attributes were added to perform access checks and must be removed */ - if (is_objectsid && ac->object_sid) { - aclread_mark_inaccesslible(&msg->elements[i]); - continue; - } - if (is_instancetype && ac->instance_type) { - aclread_mark_inaccesslible(&msg->elements[i]); - continue; - } - if (is_sd && ac->sd) { - aclread_mark_inaccesslible(&msg->elements[i]); - continue; - } - /* nTSecurityDescriptor is a special case */ - if (is_sd) { - access_mask = SEC_FLAG_SYSTEM_SECURITY|SEC_STD_READ_CONTROL; - } else { - access_mask = SEC_ADS_READ_PROP; - } - ret = acl_check_access_on_attribute(ac->module, - tmp_ctx, - sd, - sid, - access_mask, - attr); + is_objectsid = ldb_attr_cmp("objectSid", + msg->elements[i].name) == 0; + is_instancetype = ldb_attr_cmp("instanceType", + msg->elements[i].name) == 0; + /* these attributes were added to perform access checks and must be removed */ + if (is_objectsid && ac->object_sid) { + aclread_mark_inaccesslible(&msg->elements[i]); + continue; + } + if (is_instancetype && ac->instance_type) { + aclread_mark_inaccesslible(&msg->elements[i]); + continue; + } + if (is_sd && ac->sd) { + aclread_mark_inaccesslible(&msg->elements[i]); + continue; + } + /* nTSecurityDescriptor is a special case */ + if (is_sd) { + access_mask = SEC_FLAG_SYSTEM_SECURITY|SEC_STD_READ_CONTROL; + } else { + access_mask = SEC_ADS_READ_PROP; + } + + ret = acl_check_access_on_attribute(ac->module, + tmp_ctx, + sd, + sid, + access_mask, + attr); /* * Dirsync control needs the replpropertymetadata attribute @@ -166,8 +168,10 @@ static int aclread_callback(struct ldb_request *req, struct ldb_reply *ares) */ if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) { if (!ac->indirsync) { - /* do not return this entry if attribute is - part of the search filter */ + /* + * do not return this entry if attribute is + * part of the search filter + */ if (dsdb_attr_in_parse_tree(ac->req->op.search.tree, msg->elements[i].name)) { talloc_free(tmp_ctx); @@ -194,50 +198,50 @@ static int aclread_callback(struct ldb_request *req, struct ldb_reply *ares) } else if (ret != LDB_SUCCESS) { goto fail; } - } - for (i=0; i < msg->num_elements; i++) { - if (!aclread_is_inaccessible(&msg->elements[i])) { - num_of_attrs++; - } - } - /*create a new message to return*/ - ret_msg = ldb_msg_new(ac->req); - ret_msg->dn = msg->dn; - talloc_steal(ret_msg, msg->dn); - ret_msg->num_elements = num_of_attrs; - if (num_of_attrs > 0) { - ret_msg->elements = talloc_array(ret_msg, - struct ldb_message_element, - num_of_attrs); - if (ret_msg->elements == NULL) { - return ldb_oom(ldb); - } - for (i=0; i < msg->num_elements; i++) { - bool to_remove = aclread_is_inaccessible(&msg->elements[i]); - if (!to_remove) { - ret_msg->elements[k] = msg->elements[i]; - talloc_steal(ret_msg->elements, msg->elements[i].name); - talloc_steal(ret_msg->elements, msg->elements[i].values); - k++; - } - } - } else { - ret_msg->elements = NULL; - } - talloc_free(tmp_ctx); + } + for (i=0; i < msg->num_elements; i++) { + if (!aclread_is_inaccessible(&msg->elements[i])) { + num_of_attrs++; + } + } + /*create a new message to return*/ + ret_msg = ldb_msg_new(ac->req); + ret_msg->dn = msg->dn; + talloc_steal(ret_msg, msg->dn); + ret_msg->num_elements = num_of_attrs; + if (num_of_attrs > 0) { + ret_msg->elements = talloc_array(ret_msg, + struct ldb_message_element, + num_of_attrs); + if (ret_msg->elements == NULL) { + return ldb_oom(ldb); + } + for (i=0; i < msg->num_elements; i++) { + bool to_remove = aclread_is_inaccessible(&msg->elements[i]); + if (!to_remove) { + ret_msg->elements[k] = msg->elements[i]; + talloc_steal(ret_msg->elements, msg->elements[i].name); + talloc_steal(ret_msg->elements, msg->elements[i].values); + k++; + } + } + } else { + ret_msg->elements = NULL; + } + talloc_free(tmp_ctx); - return ldb_module_send_entry(ac->req, ret_msg, ares->controls); - case LDB_REPLY_REFERRAL: - return ldb_module_send_referral(ac->req, ares->referral); - case LDB_REPLY_DONE: - return ldb_module_done(ac->req, ares->controls, + return ldb_module_send_entry(ac->req, ret_msg, ares->controls); + case LDB_REPLY_REFERRAL: + return ldb_module_send_referral(ac->req, ares->referral); + case LDB_REPLY_DONE: + return ldb_module_done(ac->req, ares->controls, ares->response, LDB_SUCCESS); - } - return LDB_SUCCESS; + } + return LDB_SUCCESS; fail: - talloc_free(tmp_ctx); - return ldb_module_done(ac->req, NULL, NULL, ret); + talloc_free(tmp_ctx); + return ldb_module_done(ac->req, NULL, NULL, ret); } @@ -255,8 +259,8 @@ static int aclread_search(struct ldb_module *module, struct ldb_request *req) const char * const *attrs = NULL; uint32_t instanceType; static const char *acl_attrs[] = { - "instanceType", - NULL + "instanceType", + NULL }; ldb = ldb_module_get_ctx(module); @@ -282,10 +286,10 @@ static int aclread_search(struct ldb_module *module, struct ldb_request *req) DSDB_SEARCH_SHOW_DELETED, req); if (ret != LDB_SUCCESS) { return ldb_error(ldb, ret, - "acl_read: Error retrieving instanceType for base."); + "acl_read: Error retrieving instanceType for base."); } instanceType = ldb_msg_find_attr_as_uint(res->msgs[0], - "instanceType", 0); + "instanceType", 0); if (instanceType != 0 && !(instanceType & INSTANCE_TYPE_IS_NC_HEAD)) { /* the object has a parent, so we have to check for visibility */ |