[SCM] Samba Shared Repository - branch master updated

Nadezhda Ivanova nivanova at samba.org
Wed Dec 8 04:01:02 MST 2010


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 <nivanova at 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 <nivanova at samba.org>
    Autobuild-Date: Wed Dec  8 12:00:27 CET 2010 on sn-devel-104

commit fe98b9aaebd57e3461fa2ac59a2924a6ef6f09fa
Author: Nadezhda Ivanova <nivanova at 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


More information about the samba-cvs mailing list