The branch, master has been updated
       via  12fdfc9... s4:ldap.py - add another test about linked attributes
       via  53afe4e... s4:ldif-handlers Add a custom handler for DNs that knows 
about deleted values
       via  5779c21... s4:provision.py - we do now support the "Windows 2000 
Native" domain function level
       via  233ce18... s4:linked attributes LDB module - strip trailing 
whitespaces
       via  e190683... s4:linked_attributes LDB module - cosmetics
      from  b4364ad... s3-auth: in make_user_info_for_reply_enc make sure to 
check length and data pointer of nt and lm hash.

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


- Log -----------------------------------------------------------------
commit 12fdfc94307b5f1b7982fc82c525b260806c8323
Author: Matthias Dieter Wallnöfer <m...@samba.org>
Date:   Wed Jun 16 14:51:05 2010 +0200

    s4:ldap.py - add another test about linked attributes
    
    In addition this test makes sure that the bug regarding the search with 
deleted
    linked attributes in the filter has been fixed.

commit 53afe4e018cb3bd8728e68699910ec4501fd658d
Author: Andrew Bartlett <abart...@samba.org>
Date:   Mon Jun 14 15:52:01 2010 +1000

    s4:ldif-handlers Add a custom handler for DNs that knows about deleted 
values
    
    In Samba we my store a deleted DN for a linked attribute.  We must
    ensure that we can't match on it, or else searches for member= will
    still reveal it.
    
    Andrew Bartlett

commit 5779c21e41c6da9eabaaaf373d6a45311b234e90
Author: Matthias Dieter Wallnöfer <m...@samba.org>
Date:   Wed Jun 16 15:18:34 2010 +0200

    s4:provision.py - we do now support the "Windows 2000 Native" domain 
function level

commit 233ce18a176fc8c7c8b6b6dbf2eadd30a225405d
Author: Matthias Dieter Wallnöfer <m...@samba.org>
Date:   Wed Jun 16 15:15:39 2010 +0200

    s4:linked attributes LDB module - strip trailing whitespaces

commit e190683b59db4d22c89644a72d0dd3779ac3d706
Author: Matthias Dieter Wallnöfer <m...@samba.org>
Date:   Wed Jun 16 14:49:08 2010 +0200

    s4:linked_attributes LDB module - cosmetics
    
    - unsigned counters for LDB objects
    - we tend to have the "ret" variable always as the last declaration to see
      which type of error a function returns

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

Summary of changes:
 source4/dsdb/samdb/ldb_modules/linked_attributes.c |   92 ++++++++++----------
 source4/lib/ldb-samba/ldif_handlers.c              |   78 +++++++++++++++++
 source4/lib/ldb/tests/python/ldap.py               |   91 +++++++++++++++++++-
 source4/scripting/python/samba/provision.py        |    3 -
 4 files changed, 213 insertions(+), 51 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/samdb/ldb_modules/linked_attributes.c 
b/source4/dsdb/samdb/ldb_modules/linked_attributes.c
index c21fda5..c204571 100644
--- a/source4/dsdb/samdb/ldb_modules/linked_attributes.c
+++ b/source4/dsdb/samdb/ldb_modules/linked_attributes.c
@@ -1,4 +1,4 @@
-/* 
+/*
    ldb database library
 
    Copyright (C) Andrew Bartlett <abart...@samba.org> 2007
@@ -8,12 +8,12 @@
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
@@ -93,8 +93,8 @@ static struct la_context *linked_attributes_init(struct 
ldb_module *module,
  */
 static int la_guid_from_dn(struct la_context *ac, struct ldb_dn *dn, struct 
GUID *guid)
 {
-       int ret;
        NTSTATUS status;
+       int ret;
 
        status = dsdb_get_extended_dn_guid(dn, guid, "GUID");
        if (NT_STATUS_IS_OK(status)) {
@@ -131,7 +131,7 @@ static int la_store_op(struct la_context *ac,
 
        op_dn = ldb_dn_from_ldb_val(ac, ldb, dn);
        if (!op_dn) {
-               ldb_asprintf_errstring(ldb, 
+               ldb_asprintf_errstring(ldb,
                                       "could not parse attribute as a DN");
                return LDB_ERR_INVALID_DN_SYNTAX;
        }
@@ -191,8 +191,8 @@ static int linked_attributes_add(struct ldb_module *module, 
struct ldb_request *
        struct la_context *ac;
        const char *attr_name;
        struct ldb_control *ctrl;
+       unsigned int i, j;
        int ret;
-       int i, j;
 
        ldb = ldb_module_get_ctx(module);
 
@@ -224,9 +224,9 @@ static int linked_attributes_add(struct ldb_module *module, 
struct ldb_request *
                const struct dsdb_attribute *schema_attr
                        = dsdb_attribute_by_lDAPDisplayName(ac->schema, 
el->name);
                if (!schema_attr) {
-                       ldb_asprintf_errstring(ldb, 
+                       ldb_asprintf_errstring(ldb,
                                               "attribute %s is not a valid 
attribute in schema", el->name);
-                       return LDB_ERR_OBJECT_CLASS_VIOLATION;                  
+                       return LDB_ERR_OBJECT_CLASS_VIOLATION;
                }
                /* We have a valid attribute, now find out if it is a forward 
link */
                if ((schema_attr->linkID == 0)) {
@@ -235,11 +235,11 @@ static int linked_attributes_add(struct ldb_module 
*module, struct ldb_request *
 
                if ((schema_attr->linkID & 1) == 1) {
                        unsigned int functional_level;
-                       
+
                        functional_level = dsdb_functional_level(ldb);
                        SMB_ASSERT(functional_level > DS_DOMAIN_FUNCTION_2000);
                }
-               
+
                /* Even link IDs are for the originating attribute */
                target_attr = dsdb_attribute_by_linkID(ac->schema, 
schema_attr->linkID + 1);
                if (!target_attr) {
@@ -289,7 +289,7 @@ static int la_mod_search_callback(struct ldb_request *req, 
struct ldb_reply *are
        struct replace_context *rc;
        struct la_context *ac;
        const char *attr_name;
-       int i, j;
+       unsigned int i, j;
        int ret = LDB_SUCCESS;
 
        ac = talloc_get_type(req->context, struct la_context);
@@ -310,8 +310,8 @@ static int la_mod_search_callback(struct ldb_request *req, 
struct ldb_reply *are
        case LDB_REPLY_ENTRY:
 
                if (ldb_dn_compare(ares->message->dn, 
ac->req->op.mod.message->dn) != 0) {
-                       ldb_asprintf_errstring(ldb, 
-                                              "linked_attributes: %s is not 
the DN we were looking for", 
+                       ldb_asprintf_errstring(ldb,
+                                              "linked_attributes: %s is not 
the DN we were looking for",
                                               
ldb_dn_get_linearized(ares->message->dn));
                        /* Guh?  We only asked for this DN */
                        talloc_free(ares);
@@ -412,12 +412,11 @@ static int linked_attributes_modify(struct ldb_module 
*module, struct ldb_reques
        /* Apply the modify to the linked entry */
 
        struct ldb_context *ldb;
-       int i, j;
+       unsigned int i, j;
        struct la_context *ac;
        struct ldb_request *search_req;
        const char **attrs;
        struct ldb_control *ctrl;
-
        int ret;
 
        ldb = ldb_module_get_ctx(module);
@@ -457,9 +456,9 @@ static int linked_attributes_modify(struct ldb_module 
*module, struct ldb_reques
                const struct dsdb_attribute *schema_attr
                        = dsdb_attribute_by_lDAPDisplayName(ac->schema, 
el->name);
                if (!schema_attr) {
-                       ldb_asprintf_errstring(ldb, 
+                       ldb_asprintf_errstring(ldb,
                                               "attribute %s is not a valid 
attribute in schema", el->name);
-                       return LDB_ERR_OBJECT_CLASS_VIOLATION;                  
+                       return LDB_ERR_OBJECT_CLASS_VIOLATION;
                }
                /* We have a valid attribute, now find out if it is a forward 
link
                   (Even link IDs are for the originating attribute) */
@@ -469,7 +468,7 @@ static int linked_attributes_modify(struct ldb_module 
*module, struct ldb_reques
 
                if ((schema_attr->linkID & 1) == 1) {
                        unsigned int functional_level;
-                       
+
                        functional_level = dsdb_functional_level(ldb);
                        SMB_ASSERT(functional_level > DS_DOMAIN_FUNCTION_2000);
                }
@@ -487,7 +486,7 @@ static int linked_attributes_modify(struct ldb_module 
*module, struct ldb_reques
                }
 
                attr_name = target_attr->lDAPDisplayName;
-       
+
                switch (el->flags & LDB_FLAG_MOD_MASK) {
                case LDB_FLAG_MOD_REPLACE:
                        /* treat as just a normal add the delete part is 
handled by the callback */
@@ -546,11 +545,11 @@ static int linked_attributes_modify(struct ldb_module 
*module, struct ldb_reques
                        ac->rc->num_elements++;
                }
        }
-       
+
        if (ac->ops || ac->rc->el) {
                /* both replace and delete without values are handled in the 
callback
                 * after the search on the entry to be modified is performed */
-               
+
                attrs = talloc_array(ac->rc, const char *, ac->rc->num_elements 
+ 1);
                if (!attrs) {
                        ldb_oom(ldb);
@@ -560,7 +559,7 @@ static int linked_attributes_modify(struct ldb_module 
*module, struct ldb_reques
                        attrs[i] = ac->rc->el[i].name;
                }
                attrs[i] = NULL;
-               
+
                /* The callback does all the hard work here */
                ret = ldb_build_search_req(&search_req, ldb, ac,
                                           req->op.mod.message->dn,
@@ -578,7 +577,7 @@ static int linked_attributes_modify(struct ldb_module 
*module, struct ldb_reques
                }
                if (ret == LDB_SUCCESS) {
                        talloc_steal(search_req, attrs);
-                       
+
                        ret = ldb_next_request(module, search_req);
                }
 
@@ -596,11 +595,12 @@ static int linked_attributes_fix_links(struct ldb_module 
*module,
                                       struct ldb_message_element *el, struct 
dsdb_schema *schema,
                                       const struct dsdb_attribute *schema_attr)
 {
-       unsigned int i;
+       unsigned int i, j;
        TALLOC_CTX *tmp_ctx = talloc_new(module);
        struct ldb_context *ldb = ldb_module_get_ctx(module);
        const struct dsdb_attribute *target;
        const char *attrs[2];
+       int ret;
 
        target = dsdb_attribute_by_linkID(schema, schema_attr->linkID ^ 1);
        if (target == NULL) {
@@ -613,8 +613,6 @@ static int linked_attributes_fix_links(struct ldb_module 
*module,
 
        for (i=0; i<el->num_values; i++) {
                struct dsdb_dn *dsdb_dn;
-               unsigned int j;
-               int ret;
                struct ldb_result *res;
                struct ldb_message *msg;
                struct ldb_message_element *el2;
@@ -645,7 +643,7 @@ static int linked_attributes_fix_links(struct ldb_module 
*module,
                        /* Forward link without backlink remaining - nothing to 
do here */
                        continue;
                } else if (msg->num_elements != 1) {
-                       ldb_asprintf_errstring(ldb, "Bad msg elements - got %u 
elements, expected one element to be returned in linked_attributes_fix_links 
for %s", 
+                       ldb_asprintf_errstring(ldb, "Bad msg elements - got %u 
elements, expected one element to be returned in linked_attributes_fix_links 
for %s",
                                               msg->num_elements, 
ldb_dn_get_linearized(msg->dn));
                        talloc_free(tmp_ctx);
                        return LDB_ERR_OPERATIONS_ERROR;
@@ -709,9 +707,9 @@ static int linked_attributes_rename(struct ldb_module 
*module, struct ldb_reques
        struct ldb_result *res;
        struct ldb_message *msg;
        unsigned int i;
-       int ret;
        struct ldb_context *ldb = ldb_module_get_ctx(module);
        struct dsdb_schema *schema;
+       int ret;
        /*
           - load the current msg
           - find any linked attributes
@@ -757,7 +755,7 @@ static int linked_attributes_rename(struct ldb_module 
*module, struct ldb_reques
    structure */
 static int la_queue_mod_request(struct la_context *ac)
 {
-       struct la_private *la_private = 
+       struct la_private *la_private =
                talloc_get_type(ldb_module_get_private(ac->module), struct 
la_private);
 
        if (la_private == NULL) {
@@ -775,9 +773,9 @@ static int la_queue_mod_request(struct la_context *ac)
 /* Having done the original operation, then try to fix up all the linked 
attributes for modify and delete */
 static int la_mod_del_callback(struct ldb_request *req, struct ldb_reply *ares)
 {
-       int ret;
        struct la_context *ac;
        struct ldb_context *ldb;
+       int ret;
 
        ac = talloc_get_type(req->context, struct la_context);
        ldb = ldb_module_get_ctx(ac->module);
@@ -798,13 +796,13 @@ static int la_mod_del_callback(struct ldb_request *req, 
struct ldb_reply *ares)
                return ldb_module_done(ac->req, NULL, NULL,
                                        LDB_ERR_OPERATIONS_ERROR);
        }
-       
+
        ac->op_controls = talloc_steal(ac, ares->controls);
        ac->op_response = talloc_steal(ac, ares->response);
 
        /* If we have modfies to make, this is the time to do them for modify 
and delete */
        ret = la_queue_mod_request(ac);
-       
+
        if (ret != LDB_SUCCESS) {
                return ldb_module_done(ac->req, NULL, NULL, ret);
        }
@@ -821,9 +819,9 @@ static int la_mod_del_callback(struct ldb_request *req, 
struct ldb_reply *ares)
  */
 static int la_add_callback(struct ldb_request *req, struct ldb_reply *ares)
 {
-       int ret;
        struct la_context *ac;
        struct ldb_context *ldb;
+       int ret;
 
        ac = talloc_get_type(req->context, struct la_context);
        ldb = ldb_module_get_ctx(ac->module);
@@ -844,11 +842,11 @@ static int la_add_callback(struct ldb_request *req, 
struct ldb_reply *ares)
                return ldb_module_done(ac->req, NULL, NULL,
                                        LDB_ERR_OPERATIONS_ERROR);
        }
-       
+
        if (ac->ops) {
                struct ldb_request *search_req;
                static const char *attrs[] = { NULL };
-               
+
                /* The callback does all the hard work here - we need
                 * the objectGUID and SID of the added record */
                ret = ldb_build_search_req(&search_req, ldb, ac,
@@ -858,7 +856,7 @@ static int la_add_callback(struct ldb_request *req, struct 
ldb_reply *ares)
                                           NULL,
                                           ac, la_mod_search_callback,
                                           ac->req);
-               
+
                if (ret == LDB_SUCCESS) {
                        ret = ldb_request_add_control(search_req,
                                                      
LDB_CONTROL_EXTENDED_DN_OID,
@@ -873,7 +871,7 @@ static int la_add_callback(struct ldb_request *req, struct 
ldb_reply *ares)
                ac->op_response = talloc_steal(ac, ares->response);
 
                return ldb_next_request(ac->module, search_req);
-               
+
        } else {
                return ldb_module_done(ac->req, ares->controls,
                                       ares->response, ares->error);
@@ -884,8 +882,8 @@ static int la_add_callback(struct ldb_request *req, struct 
ldb_reply *ares)
 static int la_down_req(struct la_context *ac)
 {
        struct ldb_request *down_req;
-       int ret;
        struct ldb_context *ldb;
+       int ret;
 
        ldb = ldb_module_get_ctx(ac->module);
 
@@ -918,7 +916,7 @@ static int la_down_req(struct la_context *ac)
   use the GUID part of an extended DN to find the target DN, in case
   it has moved
  */
-static int la_find_dn_target(struct ldb_module *module, struct la_context *ac, 
+static int la_find_dn_target(struct ldb_module *module, struct la_context *ac,
                             struct GUID *guid, struct ldb_dn **dn)
 {
        return dsdb_find_dn_by_guid(ldb_module_get_ctx(ac->module), ac, guid, 
dn);
@@ -970,10 +968,10 @@ static int la_do_op_request(struct ldb_module *module, 
struct la_context *ac, st
 
 #if 0
        ldb_debug(ldb, LDB_DEBUG_WARNING,
-                 "link on %s %s: %s %s\n", 
-                 ldb_dn_get_linearized(new_msg->dn), ret_el->name, 
+                 "link on %s %s: %s %s\n",
+                 ldb_dn_get_linearized(new_msg->dn), ret_el->name,
                  ret_el->values[0].data, ac->ops->op == LA_OP_ADD ? "added" : 
"deleted");
-#endif 
+#endif
 
        if (DEBUGLVL(4)) {
                DEBUG(4,("Applying linked attribute change:\n%s\n",
@@ -1009,7 +1007,7 @@ static int la_do_mod_request(struct ldb_module *module, 
struct la_context *ac)
 
 
 /*
-  we hook into the transaction operations to allow us to 
+  we hook into the transaction operations to allow us to
   perform the linked attribute updates at the end of the whole
   transaction. This allows a forward linked attribute to be created
   before the target is created, as long as the target is created
@@ -1036,7 +1034,7 @@ static int linked_attributes_start_transaction(struct 
ldb_module *module)
  */
 static int linked_attributes_prepare_commit(struct ldb_module *module)
 {
-       struct la_private *la_private = 
+       struct la_private *la_private =
                talloc_get_type(ldb_module_get_private(module), struct 
la_private);
        struct la_context *ac;
 
@@ -1060,20 +1058,20 @@ static int linked_attributes_prepare_commit(struct 
ldb_module *module)
                if (ret != LDB_SUCCESS) {
                        DEBUG(0,(__location__ ": Failed mod request ret=%d\n", 
ret));
                        talloc_free(la_private);
-                       ldb_module_set_private(module, NULL);   
+                       ldb_module_set_private(module, NULL);
                        return ret;
                }
        }
 
        talloc_free(la_private);
-       ldb_module_set_private(module, NULL);   
+       ldb_module_set_private(module, NULL);
 
        return ldb_next_prepare_commit(module);
 }
 
 static int linked_attributes_del_transaction(struct ldb_module *module)
 {
-       struct la_private *la_private = 
+       struct la_private *la_private =
                talloc_get_type(ldb_module_get_private(module), struct 
la_private);
        talloc_free(la_private);
        ldb_module_set_private(module, NULL);
diff --git a/source4/lib/ldb-samba/ldif_handlers.c 
b/source4/lib/ldb-samba/ldif_handlers.c
index 480335f..2ce1055 100644
--- a/source4/lib/ldb-samba/ldif_handlers.c
+++ b/source4/lib/ldb-samba/ldif_handlers.c
@@ -878,6 +878,78 @@ static int extended_dn_write_hex(struct ldb_context *ldb, 
void *mem_ctx,
        return 0;
 }
 
+/*
+  compare two dns
+*/
+static int samba_ldb_dn_link_comparison(struct ldb_context *ldb, void *mem_ctx,
+                                       const struct ldb_val *v1, const struct 
ldb_val *v2)
+{
+       struct ldb_dn *dn1 = NULL, *dn2 = NULL;
+       int ret;
+
+       if (dsdb_dn_is_deleted_val(v1)) {
+               /* If the DN is deleted, then we can't search for it */
+               return -1;
+       }
+
+       if (dsdb_dn_is_deleted_val(v2)) {
+               /* If the DN is deleted, then we can't search for it */
+               return -1;
+       }
+
+       dn1 = ldb_dn_from_ldb_val(mem_ctx, ldb, v1);
+       if ( ! ldb_dn_validate(dn1)) return -1;
+
+       dn2 = ldb_dn_from_ldb_val(mem_ctx, ldb, v2);
+       if ( ! ldb_dn_validate(dn2)) {
+               talloc_free(dn1);
+               return -1;
+       }
+
+       ret = ldb_dn_compare(dn1, dn2);
+
+       talloc_free(dn1);
+       talloc_free(dn2);
+       return ret;
+}
+
+static int samba_ldb_dn_link_canonicalise(struct ldb_context *ldb, void 
*mem_ctx,
+                                         const struct ldb_val *in, struct 
ldb_val *out)
+{
+       struct ldb_dn *dn;
+       int ret = -1;
+
+       out->length = 0;
+       out->data = NULL;
+
+       dn = ldb_dn_from_ldb_val(mem_ctx, ldb, in);
+       if ( ! ldb_dn_validate(dn)) {
+               return LDB_ERR_INVALID_DN_SYNTAX;
+       }
+
+       /* By including the RMD_FLAGS of a deleted DN, we ensure it
+        * does not casually match a not deleted DN */
+       if (dsdb_dn_is_deleted_val(in)) {
+               out->data = talloc_asprintf(mem_ctx, "<RMD_FLAGS=%u>%s",
+                                           dsdb_dn_val_rmd_flags(in),
+                                           ldb_dn_get_casefold(dn));
+       } else {
+               out->data = (uint8_t *)ldb_dn_alloc_casefold(mem_ctx, dn);
+       }
+
+       if (out->data == NULL) {
+               goto done;
+       }
+       out->length = strlen((char *)out->data);
+
+       ret = 0;
+
+done:
+       talloc_free(dn);
+
+       return ret;
+}
+
 
 /*
   write a 64 bit 2-part range
@@ -1010,6 +1082,12 @@ static const struct ldb_schema_syntax samba_syntaxes[] = 
{
                .canonicalise_fn  = dsdb_dn_string_canonicalise,
                .comparison_fn    = dsdb_dn_string_comparison
        },{
+               .name             = LDB_SYNTAX_DN,
+               .ldif_read_fn     = ldb_handler_copy,
+               .ldif_write_fn    = ldb_handler_copy,
+               .canonicalise_fn  = samba_ldb_dn_link_canonicalise,
+               .comparison_fn    = samba_ldb_dn_link_comparison,
+       },{
                .name             = LDB_SYNTAX_SAMBA_RANGE64,
                .ldif_read_fn     = ldif_read_range64,
                .ldif_write_fn    = ldif_write_range64,
diff --git a/source4/lib/ldb/tests/python/ldap.py 
b/source4/lib/ldb/tests/python/ldap.py
index ddf0254..40cbb9f 100755
--- a/source4/lib/ldb/tests/python/ldap.py
+++ b/source4/lib/ldb/tests/python/ldap.py
@@ -969,6 +969,95 @@ objectClass: container
 
         self.assertEquals(res1[0]["groupType"][0], "-2147483643")
 
+    def test_linked_attributes(self):
+        """This tests the linked attribute behaviour"""
+        print "Testing linked attribute behaviour\n"
+
+        ldb.add({
+            "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
+            "objectclass": "group"})
+
+        # This should not work since "memberOf" is linked to "member"
+        try:
+            ldb.add({
+                "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+                "objectclass": ["user", "person"],
+                "memberOf": "cn=ldaptestgroup,cn=users," + self.base_dn})
+        except LdbError, (num, _):
+            self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+
+        ldb.add({
+            "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+            "objectclass": ["user", "person"]})
+
+        m = Message()
+        m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)


-- 
Samba Shared Repository

Reply via email to