The branch, master has been updated
       via  2079a6d s4-acl: Changed the mechanism of attribute removal to speed 
it up.
       via  fe98b9a s4-acl: Added a flag to mark an element as failing an 
access check.
      from  af3414f ndr: Another try to support the build on non-IPv6 systems

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 2079a6d110ae12f12497605a03deae6720434a6c
Author: Nadezhda Ivanova <nivan...@samba.org>
Date:   Wed Dec 8 12:12:34 2010 +0200

    s4-acl: Changed the mechanism of attribute removal to speed it up.
    
    Instead of using ldb_msg_remove_attr, now we are flagging the attributes to 
be removed,
    and allocating the new elements array to be returned at once. This seems to 
decrease the
    overhead by 50 percent.
    
    Autobuild-User: Nadezhda Ivanova <nivan...@samba.org>
    Autobuild-Date: Wed Dec  8 12:00:27 CET 2010 on sn-devel-104

commit fe98b9aaebd57e3461fa2ac59a2924a6ef6f09fa
Author: Nadezhda Ivanova <nivan...@samba.org>
Date:   Wed Dec 8 12:03:43 2010 +0200

    s4-acl: Added a flag to mark an element as failing an access check.

-----------------------------------------------------------------------

Summary of changes:
 source4/dsdb/samdb/ldb_modules/acl_read.c |  129 ++++++++++++++++++++---------
 source4/lib/ldb/include/ldb_module.h      |    3 +
 2 files changed, 91 insertions(+), 41 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/samdb/ldb_modules/acl_read.c 
b/source4/dsdb/samdb/ldb_modules/acl_read.c
index 87144f9..c7aaf11 100644
--- a/source4/dsdb/samdb/ldb_modules/acl_read.c
+++ b/source4/dsdb/samdb/ldb_modules/acl_read.c
@@ -53,12 +53,22 @@ struct aclread_private {
        bool enabled;
 };
 
+static void aclread_mark_inaccesslible(struct ldb_message_element *el) {
+        el->flags |= LDB_FLAG_INTERNAL_INACCESSIBLE_ATTRIBUTE;
+}
+
+static bool aclread_is_inaccessible(struct ldb_message_element *el) {
+       return el->flags & LDB_FLAG_INTERNAL_INACCESSIBLE_ATTRIBUTE;
+}
+
 static int aclread_callback(struct ldb_request *req, struct ldb_reply *ares)
 {
         struct ldb_context *ldb;
         struct aclread_context *ac;
-        int ret;
-        unsigned int i;
+        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;
@@ -76,20 +86,21 @@ static int aclread_callback(struct ldb_request *req, struct 
ldb_reply *ares)
         tmp_ctx = talloc_new(ac);
         switch (ares->type) {
         case LDB_REPLY_ENTRY:
-                ret = dsdb_get_sd_from_ldb_message(ldb, tmp_ctx, 
ares->message, &sd);
+                msg = ares->message;
+                ret = dsdb_get_sd_from_ldb_message(ldb, tmp_ctx, msg, &sd);
                 if (ret != LDB_SUCCESS) {
                         DEBUG(10, ("acl_read: cannot get descriptor\n"));
                         ret = LDB_ERR_OPERATIONS_ERROR;
                         goto fail;
                 }
-                sid = samdb_result_dom_sid(tmp_ctx, ares->message, 
"objectSid");
+                sid = samdb_result_dom_sid(tmp_ctx, msg, "objectSid");
                 /* get the object instance type */
-                instanceType = ldb_msg_find_attr_as_uint(ares->message,
+                instanceType = ldb_msg_find_attr_as_uint(msg,
                                                         "instanceType", 0);
-                if (!ldb_dn_is_null(ares->message->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, 
ares->message->dn);
+                       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,
@@ -103,61 +114,97 @@ static int aclread_callback(struct ldb_request *req, 
struct ldb_reply *ares)
                        }
                 }
                 /* for every element in the message check RP */
-                i = 0;
-                while (i < ares->message->num_elements) {
+                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,
-                                                                  
ares->message->elements[i].name);
+                                                                  
msg->elements[i].name);
                         if (!attr) {
                                 DEBUG(2, ("acl_read: cannot find attribute %s 
in schema\n",
-                                          ares->message->elements[i].name));
+                                          msg->elements[i].name));
                                 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 (ldb_attr_cmp("nTSecurityDescriptor",
-                                         ares->message->elements[i].name) == 
0) {
-                                if (ac->sd) {
-                                        ldb_msg_remove_attr(ares->message, 
ares->message->elements[i].name);
-                                        ret = LDB_SUCCESS;
-                                }
-                                ret = acl_check_access_on_attribute(ac->module,
-                                                                    tmp_ctx,
-                                                                    sd,
-                                                                    sid,
-                                                                    
SEC_FLAG_SYSTEM_SECURITY|SEC_STD_READ_CONTROL,
-                                                                    attr);
+                        if (is_sd) {
+                                access_mask = 
SEC_FLAG_SYSTEM_SECURITY|SEC_STD_READ_CONTROL;
                         } else {
-                                ret = acl_check_access_on_attribute(ac->module,
-                                                                    tmp_ctx,
-                                                                    sd,
-                                                                    sid,
-                                                                    
SEC_ADS_READ_PROP,
-                                                                    attr);
+                                access_mask = SEC_ADS_READ_PROP;
                         }
-                        if (ret == LDB_SUCCESS) {
-                                i++;
-                        } else if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) {
+                        ret = acl_check_access_on_attribute(ac->module,
+                                                            tmp_ctx,
+                                                            sd,
+                                                            sid,
+                                                            access_mask,
+                                                            attr);
+
+                        if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) {
                                 /* do not return this entry if attribute is
-                                           part of the search filter */
+                                   part of the search filter */
                                 if 
(dsdb_attr_in_parse_tree(ac->req->op.search.tree,
-                                                            
ares->message->elements[i].name)) {
+                                                            
msg->elements[i].name)) {
                                         talloc_free(tmp_ctx);
                                         return LDB_SUCCESS;
                                 }
-                                ldb_msg_remove_attr(ares->message, 
ares->message->elements[i].name);
-                        } else {
+                                aclread_mark_inaccesslible(&msg->elements[i]);
+                        } else if (ret != LDB_SUCCESS) {
                                 goto fail;
                         }
                 }
-                if (ac->instance_type) {
-                        ldb_msg_remove_attr(ares->message, "instanceType");
+                for (i=0; i < msg->num_elements; i++) {
+                        if (!aclread_is_inaccessible(&msg->elements[i])) {
+                                num_of_attrs++;
+                        }
                 }
-                if (ac->object_sid) {
-                        ldb_msg_remove_attr(ares->message, "objectSid");
+                /*create a new message to return*/
+                ret_msg = ldb_msg_new(req);
+                ret_msg->dn = 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];
+                                        if 
(!talloc_reference(ret_msg->elements,
+                                                              
msg->elements[i].values)) {
+                                                talloc_free(tmp_ctx);
+                                                return ldb_operr(ldb);
+                                        }
+                                        k++;
+                                }
+                        }
+                } else {
+                        ret_msg->elements = NULL;
                 }
                 talloc_free(tmp_ctx);
-                return ldb_module_send_entry(ac->req, ares->message, 
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:
diff --git a/source4/lib/ldb/include/ldb_module.h 
b/source4/lib/ldb/include/ldb_module.h
index 50c606b..a6a4d16 100644
--- a/source4/lib/ldb/include/ldb_module.h
+++ b/source4/lib/ldb/include/ldb_module.h
@@ -46,6 +46,9 @@ struct ldb_module;
 /* disable any single value checking on this attribute */
 #define LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK 0x20
 
+/* attribute has failed access check and must not be exposed */
+#define LDB_FLAG_INTERNAL_INACCESSIBLE_ATTRIBUTE 0x30
+
 
 /*
    these function pointers define the operations that a ldb module can 
intercept


-- 
Samba Shared Repository

Reply via email to