diff options
Diffstat (limited to 'source4/lib')
-rw-r--r-- | source4/lib/ldb-samba/ldif_handlers.c | 78 | ||||
-rwxr-xr-x | source4/lib/ldb/tests/python/ldap.py | 91 |
2 files changed, 168 insertions, 1 deletions
diff --git a/source4/lib/ldb-samba/ldif_handlers.c b/source4/lib/ldb-samba/ldif_handlers.c index 480335f411..2ce1055d0d 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 ddf0254c21..40cbb9feb3 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) + m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn, + FLAG_MOD_ADD, "memberOf") + try: + ldb.modify(m) + self.fail() + except LdbError, (num, _): + self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) + + m = Message() + m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) + m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn, + FLAG_MOD_ADD, "member") + ldb.modify(m) + + m = Message() + m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn) + m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn, + FLAG_MOD_REPLACE, "memberOf") + try: + ldb.modify(m) + self.fail() + except LdbError, (num, _): + self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) + + m = Message() + m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn) + m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn, + FLAG_MOD_DELETE, "memberOf") + try: + ldb.modify(m) + self.fail() + except LdbError, (num, _): + self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) + + m = Message() + m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) + m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn, + FLAG_MOD_DELETE, "member") + ldb.modify(m) + + # This should yield no results since the member attribute for + # "ldaptestuser" should have been deleted + res1 = ldb.search("cn=ldaptestgroup, cn=users," + self.base_dn, + scope=SCOPE_BASE, + expression="(member=cn=ldaptestuser,cn=users," + self.base_dn + ")", + attrs=[]) + self.assertTrue(len(res1) == 0) + + self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) + + ldb.add({ + "dn": "cn=ldaptestgroup,cn=users," + self.base_dn, + "objectclass": "group", + "member": "cn=ldaptestuser,cn=users," + self.base_dn}) + + self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) + + # Make sure that the "member" attribute for "ldaptestuser" has been + # removed + res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn, + scope=SCOPE_BASE, attrs=["member"]) + self.assertTrue(len(res) == 1) + self.assertFalse("member" in res[0]) + + self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) + def test_groups(self): """This tests the group behaviour (setting, changing) of a user account""" print "Testing group behaviour\n" @@ -2072,7 +2161,7 @@ member: cn=ldaptestuser2,cn=users,""" + self.base_dn + """ self.assertTrue(("<GUID=" + ldb.schema_format_value("objectGUID", ldaptestuser2_guid) + ">;<SID=" + ldb.schema_format_value("objectSid", ldaptestuser2_sid) + ">;CN=ldaptestuser2,CN=Users," + self.base_dn).upper() in memberUP) - print "Testing Linked attribute behaviours" + print "Quicktest for linked attributes" ldb.modify_ldif(""" dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """ changetype: modify |