[SCM] Samba Shared Repository - branch master updated - tevent-0-9-8-953-gbe938ab
Matthias Dieter Wallnöfer
mdw at samba.org
Sat Oct 3 04:49:48 MDT 2009
The branch, master has been updated
via be938ab44b6095818501b23ca8422c731e14015a (commit)
via 4bc9a39eed3e47cd87ea8cd24f9ac4f9e2712f43 (commit)
via 0e028fcb7d141d68de2baadeb2c0fae262f2bedc (commit)
via f86beaaad96ac2dd7cf6a3a9d57f42c57c2440c2 (commit)
from dac0346906b7494f203e1e56b8f2e18c93fc2912 (commit)
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit be938ab44b6095818501b23ca8422c731e14015a
Author: Matthias Dieter Wallnöfer <mwallnoefer at yahoo.de>
Date: Sat Oct 3 11:37:30 2009 +0200
s4:ldap.py - add tests for valid parent and RDN
commit 4bc9a39eed3e47cd87ea8cd24f9ac4f9e2712f43
Author: Andrew Bartlett <abartlet at samba.org>
Date: Thu Sep 24 15:14:49 2009 -0700
s4:dsdb Use possibleInferiors to restrict creation of child objects
This also uses systemPossibleInferiors when the 'relax' control is
specified, which is done by the provision.
Andrew Bartlett
commit 0e028fcb7d141d68de2baadeb2c0fae262f2bedc
Author: Andrew Bartlett <abartlet at samba.org>
Date: Thu Sep 24 15:12:49 2009 -0700
s4:dsdb add systemPossibleInferiors to schema code
This allows us to figure out what the system can add, which will not
be in possibleInferiors due to the systemOnly flag.
Andrew Bartlett
commit f86beaaad96ac2dd7cf6a3a9d57f42c57c2440c2
Author: Andrew Bartlett <abartlet at samba.org>
Date: Wed Sep 23 21:16:42 2009 -0700
s4:dsdb Add objectClass and RDN constraints to objectClass module
These additional constraints are applied, found by the Microsoft testsuite.
- When the parent is not present, we now return 'NO_SUCH_OBJECT'.
- Restrict the choice of RDN to the correct one per the schema
- Honour the allowedChildClasses attribute from the parent's objectClass.
Andrew Bartlett
-----------------------------------------------------------------------
Summary of changes:
source4/dsdb/samdb/ldb_modules/objectclass.c | 54 ++++++++++++++++++++++----
source4/dsdb/schema/schema.h | 1 +
source4/dsdb/schema/schema_inferiors.c | 20 +++++++++
source4/lib/ldb/tests/python/ldap.py | 39 ++++++++++++++++++
4 files changed, 106 insertions(+), 8 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c
index b3d5461..51a1ac8 100644
--- a/source4/dsdb/samdb/ldb_modules/objectclass.c
+++ b/source4/dsdb/samdb/ldb_modules/objectclass.c
@@ -2,7 +2,7 @@
ldb database library
Copyright (C) Simo Sorce 2006-2008
- Copyright (C) Andrew Bartlett <abartlet at samba.org> 2005-2007
+ Copyright (C) Andrew Bartlett <abartlet at samba.org> 2005-2009
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -42,6 +42,7 @@
#include "libcli/security/security.h"
#include "auth/auth.h"
#include "param/param.h"
+#include "../libds/common/flags.h"
struct oc_context {
@@ -381,7 +382,7 @@ static int objectclass_add(struct ldb_module *module, struct ldb_request *req)
struct oc_context *ac;
struct ldb_dn *parent_dn;
int ret;
- static const char * const parent_attrs[] = { "objectGUID", NULL };
+ static const char * const parent_attrs[] = { "objectGUID", "objectClass", NULL };
ldb = ldb_module_get_ctx(module);
@@ -465,7 +466,7 @@ static int objectclass_do_add(struct oc_context *ac)
ldb_asprintf_errstring(ldb, "objectclass: Cannot add %s, parent does not exist!",
ldb_dn_get_linearized(msg->dn));
talloc_free(mem_ctx);
- return LDB_ERR_UNWILLING_TO_PERFORM;
+ return LDB_ERR_NO_SUCH_OBJECT;
}
} else {
const struct ldb_val *parent_guid;
@@ -491,9 +492,6 @@ static int objectclass_do_add(struct oc_context *ac)
return LDB_ERR_UNWILLING_TO_PERFORM;
}
- /* TODO: Check this is a valid child to this parent,
- * by reading the allowedChildClasses and
- * allowedChildClasssesEffective attributes */
ret = ldb_msg_add_steal_value(msg, "parentGUID", discard_const(parent_guid));
if (ret != LDB_SUCCESS) {
ldb_asprintf_errstring(ldb, "objectclass: Cannot add %s, failed to add parentGUID",
@@ -555,12 +553,52 @@ static int objectclass_do_add(struct oc_context *ac)
struct ldb_message_element *el;
int32_t systemFlags = 0;
const char *rdn_name = ldb_dn_get_rdn_name(msg->dn);
- if (ldb_attr_cmp(rdn_name, current->objectclass->rDNAttID) != 0) {
- ldb_asprintf_errstring(ldb, "RDN %s is not correct for most specific structural objectclass %s, should be %s",
+ if (current->objectclass->rDNAttID
+ && ldb_attr_cmp(rdn_name, current->objectclass->rDNAttID) != 0) {
+ ldb_asprintf_errstring(ldb,
+ "RDN %s is not correct for most specific structural objectclass %s, should be %s",
rdn_name, current->objectclass->lDAPDisplayName, current->objectclass->rDNAttID);
return LDB_ERR_NAMING_VIOLATION;
}
+ if (ac->search_res && ac->search_res->message) {
+ struct ldb_message_element *oc_el
+ = ldb_msg_find_element(ac->search_res->message, "objectClass");
+
+ bool allowed_class = false;
+ int i, j;
+ for (i=0; allowed_class == false && oc_el && i < oc_el->num_values; i++) {
+ const struct dsdb_class *sclass;
+
+ sclass = dsdb_class_by_lDAPDisplayName_ldb_val(schema, &oc_el->values[i]);
+ if (!sclass) {
+ /* We don't know this class? what is going on? */
+ continue;
+ }
+ if (ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID)) {
+ for (j=0; sclass->systemPossibleInferiors && sclass->systemPossibleInferiors[j]; j++) {
+ if (ldb_attr_cmp(current->objectclass->lDAPDisplayName, sclass->systemPossibleInferiors[j]) == 0) {
+ allowed_class = true;
+ break;
+ }
+ }
+ } else {
+ for (j=0; sclass->systemPossibleInferiors && sclass->systemPossibleInferiors[j]; j++) {
+ if (ldb_attr_cmp(current->objectclass->lDAPDisplayName, sclass->systemPossibleInferiors[j]) == 0) {
+ allowed_class = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (!allowed_class) {
+ ldb_asprintf_errstring(ldb, "structural objectClass %s is not a valid child class for %s",
+ current->objectclass->lDAPDisplayName, ldb_dn_get_linearized(ac->search_res->message->dn));
+ return LDB_ERR_NAMING_VIOLATION;
+ }
+ }
+
if (current->objectclass->systemOnly && !ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID)) {
ldb_asprintf_errstring(ldb, "objectClass %s is systemOnly, rejecting creation of %s",
current->objectclass->lDAPDisplayName, ldb_dn_get_linearized(msg->dn));
diff --git a/source4/dsdb/schema/schema.h b/source4/dsdb/schema/schema.h
index 4e7e503..ddd9b37 100644
--- a/source4/dsdb/schema/schema.h
+++ b/source4/dsdb/schema/schema.h
@@ -119,6 +119,7 @@ struct dsdb_class {
const char **mustContain;
const char **mayContain;
const char **possibleInferiors;
+ const char **systemPossibleInferiors;
const char *defaultSecurityDescriptor;
diff --git a/source4/dsdb/schema/schema_inferiors.c b/source4/dsdb/schema/schema_inferiors.c
index b02d557..264e471 100644
--- a/source4/dsdb/schema/schema_inferiors.c
+++ b/source4/dsdb/schema/schema_inferiors.c
@@ -198,6 +198,25 @@ static void schema_fill_possible_inferiors(struct dsdb_schema *schema, struct ds
schema_class->possibleInferiors = str_list_unique(schema_class->possibleInferiors);
}
+static void schema_fill_system_possible_inferiors(struct dsdb_schema *schema, struct dsdb_class *schema_class)
+{
+ struct dsdb_class *c2;
+
+ for (c2=schema->classes; c2; c2=c2->next) {
+ char **superiors = schema_posssuperiors(schema, c2);
+ if (c2->objectClassCategory != 2
+ && c2->objectClassCategory != 3
+ && str_list_check(superiors, schema_class->lDAPDisplayName)) {
+ if (schema_class->possibleInferiors == NULL) {
+ schema_class->systemPossibleInferiors = str_list_make_empty(schema_class);
+ }
+ schema_class->systemPossibleInferiors = str_list_add_const(schema_class->systemPossibleInferiors,
+ c2->lDAPDisplayName);
+ }
+ }
+ schema_class->systemPossibleInferiors = str_list_unique(schema_class->systemPossibleInferiors);
+}
+
/*
fill in a string class name from a governs_ID
*/
@@ -285,6 +304,7 @@ void schema_fill_constructed(struct dsdb_schema *schema)
for (schema_class=schema->classes; schema_class; schema_class=schema_class->next) {
schema_fill_possible_inferiors(schema, schema_class);
+ schema_fill_system_possible_inferiors(schema, schema_class);
}
/* free up our internal cache elements */
diff --git a/source4/lib/ldb/tests/python/ldap.py b/source4/lib/ldb/tests/python/ldap.py
index 7fa25fb..59bb5d2 100755
--- a/source4/lib/ldb/tests/python/ldap.py
+++ b/source4/lib/ldb/tests/python/ldap.py
@@ -21,6 +21,7 @@ from ldb import ERR_ENTRY_ALREADY_EXISTS, ERR_UNWILLING_TO_PERFORM
from ldb import ERR_NOT_ALLOWED_ON_NON_LEAF, ERR_OTHER, ERR_INVALID_DN_SYNTAX
from ldb import ERR_NO_SUCH_ATTRIBUTE, ERR_INSUFFICIENT_ACCESS_RIGHTS
from ldb import ERR_OBJECT_CLASS_VIOLATION, ERR_NOT_ALLOWED_ON_RDN
+from ldb import ERR_NAMING_VIOLATION
from ldb import Message, MessageElement, Dn, FLAG_MOD_ADD, FLAG_MOD_REPLACE
from samba import Ldb, param, dom_sid_to_rid
from samba import UF_NORMAL_ACCOUNT, UF_TEMP_DUPLICATE_ACCOUNT
@@ -118,6 +119,8 @@ class BasicTests(unittest.TestCase):
self.delete_force(self.ldb, "cn=parentguidtest,cn=testotherusers," + self.base_dn)
self.delete_force(self.ldb, "cn=testotherusers," + self.base_dn)
self.delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
+ self.delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn)
+ self.delete_force(self.ldb, "ou=testou,cn=users," + self.base_dn)
def test_system_only(self):
"""Test systemOnly objects"""
@@ -133,6 +136,32 @@ class BasicTests(unittest.TestCase):
self.delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
+ def test_invalid_parent(self):
+ """Test adding an object with invalid parent"""
+ print "Test adding an object with invalid parent"""
+
+ try:
+ self.ldb.add({
+ "dn": "cn=ldaptestgroup,cn=thisdoesnotexist123,"
+ + self.base_dn,
+ "objectclass": "group"})
+ self.fail()
+ except LdbError, (num, _):
+ self.assertEquals(num, ERR_NO_SUCH_OBJECT)
+
+ self.delete_force(self.ldb, "cn=ldaptestgroup,cn=thisdoesnotexist123,"
+ + self.base_dn)
+
+ try:
+ self.ldb.add({
+ "dn": "ou=testou,cn=users," + self.base_dn,
+ "objectclass": "organizationalUnit"})
+ self.fail()
+ except LdbError, (num, _):
+ self.assertEquals(num, ERR_NAMING_VIOLATION)
+
+ self.delete_force(self.ldb, "ou=testou,cn=users," + self.base_dn)
+
def test_invalid_attribute(self):
"""Test adding invalid attributes (not in schema)"""
print "Test adding invalid attributes (not in schema)"""
@@ -188,6 +217,16 @@ class BasicTests(unittest.TestCase):
"""Tests the RDN"""
print "Tests the RDN"""
+ try:
+ self.ldb.add({
+ "dn": "description=xyz,cn=users," + self.base_dn,
+ "objectclass": "group"})
+ self.fail()
+ except LdbError, (num, _):
+ self.assertEquals(num, ERR_NAMING_VIOLATION)
+
+ self.delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn)
+
self.ldb.add({
"dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
"objectclass": "group"})
--
Samba Shared Repository
More information about the samba-cvs
mailing list