[prev in list] [next in list] [prev in thread] [next in thread]
List: samba-technical
Subject: Re: [PATCHS] fix handling of AUX classes in objectclass.c
From: brendan powers <brendan0powers () gmail ! com>
Date: 2009-12-16 22:33:55
Message-ID: c547abb70912161433j14341185o85482e0d4234c855 () mail ! gmail ! com
[Download RAW message or body]
Here are the updated patches with a new email address and more verbose
commit messages.
On Wed, Dec 16, 2009 at 3:05 PM, Andrew Bartlett <abartlet@samba.org> wrote=
:
> On Tue, 2009-12-15 at 10:14 -0500, brendan powers wrote:
>> On Tue, Dec 15, 2009 at 12:23 AM, Andrew Bartlett <abartlet@samba.org> w=
rote:
>> > On Mon, 2009-12-14 at 21:16 -0500, brendan powers wrote:
>> >> These patches fix the handling of AUX classes in objectclass.c. Befor=
e
>> >> this, adding an AUX class such as posixAccount to a user would fail
>> >> with LDB_ERR_OBJECT_CLASS_VIOLATION.
>> >
>> > Great.
>> >
>> >> Here is a description of the patches
>> >
>> > Can you please put these in the commit message for each patch? =A0We w=
ant
>> > to remember why these were done in the GIT history.
>>
>> Sure
>>
>> >> * 0001-return-NULL-in-strlower_talloc-if-src-is-NULL.patch, prevents
>> >> strlower_talloc from segfaulting if you pass it a NULL string.
>> >> * 0002-s4-dsdb-Add-a-check-to-prevent-acl_modify-from-debu.patch,
>> >> Check to see if there were any messages passed to acl_modify before
>> >> debugging the first one. I think I caused this by some malformed
>> >> ldiff. Unfortunately, I don't have the file that caused the problem.
>> >> * 0003-s4-dsdb-Move-get_last_structural-class-from-descrip.patch, Mov=
e
>> >> get_last_structural_class from descriptor.c to util.c so it can be
>> >> used by objectclass.c. Also, make get_last_structural_class ignore AU=
X
>> >> classes, as they are not structural classes.
>> >> * 0004-s4-dsdb-return-an-error-if-samAccountName-is-not-sp.patch,
>> >> makes sure samAccountName has been specified before adding a user.
>> >> This happened while I was trying to add a user with the posixAccount
>> >> objectclass. I forgot to specify the user objectClass, and samba
>> >> segfaulted. It now returns LDB_ERR_CONSTRAINT_VIOLATION.
>> >> * 0005-s4-dsdb-fix-handling-of-AUX-classes-in-objectclass_.patch, thi=
s
>> >> is the main patch in this set. It fixes the handling of AUX classes i=
n
>> >> objectclass_sort. They were being sorted by building a class tree, an=
d
>> >> adding the classes to the list in that order. However, AUX classes
>> >> usually don't fit into that tree, so LDB_ERR_OBJECT_CLASS_VIOLATION
>> >> was returned. I have changed the behavior to sort the classes by
>> >> subClass_order instead. Also this patch makes objectclass_do_add chec=
k
>> >> if the last structural class is a valid class to add, instead of the
>> >> last class returned by objectclass_sort.
>> >
>> > If it could be made to work, I would really prefer the qsort() variant
>> > of this patch. =A0Did you discover anything in the building of this pa=
tch
>> > to indicate why it didn't work?
>>
>> The objectclass_sort function often adds important classes to the
>> list. One example is the domain class to the base DN during
>> provisioning. In doing so it changes the length of the array. So to
>> use the qsort function, I would need to allocate a new array, copy the
>> objects into it, sort it with qsort, and copy it back out to a linked
>> list. For lists usually less than 5 items, I'm not sure its worth it.
>> I can certainly do this though, if you want me to.
>
> Ahh, I didn't realise it did that too. =A0It's been a while since I wrote
> this horror - the odd thing is, while believe you, reading the code I
> still can't see how it does it!
>
>> >> * 0006-s4-dsdb-Add-a-test-for-adding-deleting-and-append.patch, add a
>> >> test to make sure you can add the posixAccount class to an object.
>> >> This was the original reason for this set of patches.
>> >>
>> >> These patches now pass make test. So I thought it was time to send
>> >> them to the list. Hopefully I did things right this time:)
>> >
>> > Almost :-)
>> >
>> > Finally, was it deliberate having a different e-mail address in the
>> > patches to the mail? =A0(At least it's no longer root!).
>>
>> That is the address I like to be contacted at, as I check it more
>> often. I'l change it to the address I use on this list, as it makes
>> more sense.
>
> Either is fine, I just wanted to check.
>
> Andrew Bartlett
>
> --
> Andrew Bartlett =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0http://samba.org/~abartlet/
> Authentication Developer, Samba Team =A0 =A0 =A0 =A0 =A0 http://samba.org
> Samba Developer, Cisco Inc.
>
>
["0001-return-NULL-in-strlower_talloc-if-src-is-NULL.patch" (text/x-diff)]
From feba7a68d7a465cc73d55013a04c1eb0c14bf56f Mon Sep 17 00:00:00 2001
From: Brendan Powers <brendan0powers@gmail.com>
Date: Mon, 14 Dec 2009 20:28:48 -0500
Subject: [PATCH] Return NULL in strlower_talloc if src is NULL
Prevents strlower_talloc from segfaulting if you pass it a NULL string.
---
lib/util/charset/util_unistr.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/lib/util/charset/util_unistr.c b/lib/util/charset/util_unistr.c
index 045aa4a..f820726 100644
--- a/lib/util/charset/util_unistr.c
+++ b/lib/util/charset/util_unistr.c
@@ -430,6 +430,10 @@ _PUBLIC_ char *strlower_talloc(TALLOC_CTX *ctx, const char *src)
char *dest;
struct smb_iconv_convenience *iconv_convenience = get_iconv_convenience();
+ if(src == NULL) {
+ return NULL;
+ }
+
/* this takes advantage of the fact that upper/lower can't
change the length of a character by more than 1 byte */
dest = talloc_array(ctx, char, 2*(strlen(src))+1);
--
1.5.4.3
["0002-s4-dsdb-Add-a-check-to-prevent-acl_modify-from-debu.patch" (text/x-diff)]
From 01570ffef3f476905034d4a528bcc6ad44a2c157 Mon Sep 17 00:00:00 2001
From: Brendan Powers <brendan0powers@gmail.com>
Date: Mon, 14 Dec 2009 20:32:28 -0500
Subject: [PATCH] s4-dsdb: Add a check to prevent acl_modify from debuging a NULL \
message Check to see if there were any messages passed to acl_modify before \
debugging the first one. I think I caused this by some malformed ldiff.
---
source4/dsdb/samdb/ldb_modules/acl.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/source4/dsdb/samdb/ldb_modules/acl.c \
b/source4/dsdb/samdb/ldb_modules/acl.c index 45aa294..fc29ba9 100644
--- a/source4/dsdb/samdb/ldb_modules/acl.c
+++ b/source4/dsdb/samdb/ldb_modules/acl.c
@@ -700,7 +700,11 @@ static int acl_modify(struct ldb_module *module, struct \
ldb_request *req) NULL
};
- DEBUG(10, ("ldb:acl_modify: %s\n", req->op.mod.message->elements[0].name));
+ /* Don't print this debug statement if elements[0].name is going to be NULL */
+ if(req->op.mod.message->num_elements > 0)
+ {
+ DEBUG(10, ("ldb:acl_modify: %s\n", req->op.mod.message->elements[0].name));
+ }
if (what_is_user(module) == SECURITY_SYSTEM) {
return ldb_next_request(module, req);
}
--
1.5.4.3
["0003-s4-dsdb-Move-get_last_structural-class-from-descrip.patch" (text/x-diff)]
From 17f1efcff60aa1ee9dac0ecab99f3b3e4246ecbc Mon Sep 17 00:00:00 2001
From: Brendan Powers <brendan0powers@gmail.com>
Date: Mon, 14 Dec 2009 20:36:44 -0500
Subject: [PATCH] s4-dsdb: Move get_last_structural class from descriptor.c to util.c \
so it can be used by objectclass.c s4-dsdb: get_last_structural_class now ignores \
AUX classes, because they are not structural
---
source4/dsdb/samdb/ldb_modules/descriptor.c | 17 +----------------
source4/dsdb/samdb/ldb_modules/util.c | 27 +++++++++++++++++++++++++++
source4/dsdb/samdb/ldb_modules/util.h | 1 +
3 files changed, 29 insertions(+), 16 deletions(-)
diff --git a/source4/dsdb/samdb/ldb_modules/descriptor.c \
b/source4/dsdb/samdb/ldb_modules/descriptor.c index 03cb1ff..8df93dd 100644
--- a/source4/dsdb/samdb/ldb_modules/descriptor.c
+++ b/source4/dsdb/samdb/ldb_modules/descriptor.c
@@ -41,6 +41,7 @@
#include "libcli/security/security.h"
#include "auth/auth.h"
#include "param/param.h"
+#include "util.h"
struct descriptor_data {
int _dummy;
@@ -56,22 +57,6 @@ struct descriptor_context {
int (*step_fn)(struct descriptor_context *);
};
-static const struct dsdb_class * get_last_structural_class(const struct dsdb_schema \
*schema, struct ldb_message_element *element)
-{
- const struct dsdb_class *last_class = NULL;
- int i;
- for (i = 0; i < element->num_values; i++){
- if (!last_class) {
- last_class = dsdb_class_by_lDAPDisplayName_ldb_val(schema, &element->values[i]);
- } else {
- const struct dsdb_class *tmp_class = \
dsdb_class_by_lDAPDisplayName_ldb_val(schema, &element->values[i]);
- if (tmp_class->subClass_order > last_class->subClass_order)
- last_class = tmp_class;
- }
- }
- return last_class;
-}
-
struct dom_sid *get_default_ag(TALLOC_CTX *mem_ctx,
struct ldb_dn *dn,
struct security_token *token,
diff --git a/source4/dsdb/samdb/ldb_modules/util.c \
b/source4/dsdb/samdb/ldb_modules/util.c index fe6ddfa..ed65ca4 100644
--- a/source4/dsdb/samdb/ldb_modules/util.c
+++ b/source4/dsdb/samdb/ldb_modules/util.c
@@ -24,6 +24,7 @@
#include "ldb_module.h"
#include "dsdb/samdb/ldb_modules/util.h"
#include "dsdb/samdb/samdb.h"
+#include "util.h"
int dsdb_module_search_handle_flags(struct ldb_module *module, struct ldb_request \
*req, int dsdb_flags) {
@@ -205,3 +206,29 @@ int dsdb_module_search(struct ldb_module *module,
return ret;
}
+const struct dsdb_class * get_last_structural_class(const struct dsdb_schema \
*schema,const struct ldb_message_element *element) +{
+ const struct dsdb_class *last_class = NULL;
+ int i;
+
+ for (i = 0; i < element->num_values; i++){
+ const struct dsdb_class *tmp_class = dsdb_class_by_lDAPDisplayName_ldb_val(schema, \
&element->values[i]); +
+ if(tmp_class == NULL) {
+ continue;
+ }
+
+ if(tmp_class->objectClassCategory == 3) {
+ continue;
+ }
+
+ if (!last_class) {
+ last_class = tmp_class;
+ } else {
+ if (tmp_class->subClass_order > last_class->subClass_order)
+ last_class = tmp_class;
+ }
+ }
+
+ return last_class;
+}
diff --git a/source4/dsdb/samdb/ldb_modules/util.h \
b/source4/dsdb/samdb/ldb_modules/util.h index 56db27d..41ec873 100644
--- a/source4/dsdb/samdb/ldb_modules/util.h
+++ b/source4/dsdb/samdb/ldb_modules/util.h
@@ -19,6 +19,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+struct dsdb_schema; /* predeclare schema struct */
#include "dsdb/samdb/ldb_modules/util_proto.h"
#define DSDB_SEARCH_SEARCH_ALL_PARTITIONS 0x0001
--
1.5.4.3
["0004-s4-dsdb-return-an-error-if-samAccountName-is-not-sp.patch" (text/x-diff)]
From 4ebbf6c89c537a275c8d387f40411097d311337d Mon Sep 17 00:00:00 2001
From: Brendan Powers <brendan0powers@gmail.com>
Date: Mon, 14 Dec 2009 20:40:26 -0500
Subject: [PATCH] s4-dsdb: return an error if samAccountName is not specified when \
creating a user. Makes sure samAccountName has been specified before adding a user. \
This happened while I was trying to add a user with the posixAccount objectclass. I \
forgot to specify the user objectClass, and samba segfaulted. It now returns \
LDB_ERR_CONSTRAINT_VIOLATION.
---
source4/dsdb/samdb/ldb_modules/password_hash.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c \
b/source4/dsdb/samdb/ldb_modules/password_hash.c index 4d4f500..35ce08f 100644
--- a/source4/dsdb/samdb/ldb_modules/password_hash.c
+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c
@@ -1487,6 +1487,13 @@ static int setup_io(struct ph_context *ac,
io->n.lm_hash = samdb_result_hash(io->ac, new_msg, "dBCSPwd");
+ if(io->u.sAMAccountName == NULL)
+ {
+ ldb_asprintf_errstring(ldb, "samAccountName is missing on %s for attempted \
password set/change", + ldb_dn_get_linearized(new_msg->dn));
+ return(LDB_ERR_CONSTRAINT_VIOLATION);
+ }
+
return LDB_SUCCESS;
}
--
1.5.4.3
["0005-s4-dsdb-fix-handling-of-AUX-classes-in-objectclass_.patch" (text/x-diff)]
From 6708fb4257e57a39d75afc45b61df1c906e5578e Mon Sep 17 00:00:00 2001
From: Brendan Powers <brendan0powers@gmail.com>
Date: Mon, 14 Dec 2009 20:47:18 -0500
Subject: [PATCH] s4-dsdb: fix handling of AUX classes in objectclass_sort by sorting \
the classes by subClass_order s4-dsdb: check if the last structural class is valid \
to add in objectclass_do_add instead of the last class in the list fixes the \
handling of AUX classes in objectclass_sort. They were being sorted by building a \
class tree, and adding the classes to the list in that order. However, AUX classes \
usually don't fit into that tree, so LDB_ERR_OBJECT_CLASS_VIOLATION was returned. I \
have changed the behavior to sort the classes by subClass_order instead. Also this \
patch makes objectclass_do_add check if the last structural class is a valid class to \
add, instead of the last class returned by objectclass_sort.
---
source4/dsdb/samdb/ldb_modules/objectclass.c | 285 ++++++++++++--------------
1 files changed, 136 insertions(+), 149 deletions(-)
diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c \
b/source4/dsdb/samdb/ldb_modules/objectclass.c index c47e360..d9705ce 100644
--- a/source4/dsdb/samdb/ldb_modules/objectclass.c
+++ b/source4/dsdb/samdb/ldb_modules/objectclass.c
@@ -43,6 +43,7 @@
#include "auth/auth.h"
#include "param/param.h"
#include "../libds/common/flags.h"
+#include "util.h"
struct oc_context {
@@ -92,10 +93,8 @@ static int objectclass_sort(struct ldb_module *module,
struct class_list **sorted_out)
{
struct ldb_context *ldb;
- int i;
- int layer;
- struct class_list *sorted = NULL, *parent_class = NULL,
- *subclass = NULL, *unsorted = NULL, *current, *poss_subclass, *poss_parent, \
*new_parent; + int i, lowest;
+ struct class_list *unsorted = NULL, *sorted = NULL, *current = NULL, *poss_parent = \
NULL, *new_parent = NULL, *current_lowest = NULL;
ldb = ldb_module_get_ctx(module);
@@ -148,20 +147,17 @@ static int objectclass_sort(struct ldb_module *module,
return LDB_ERR_NO_SUCH_ATTRIBUTE;
}
- /* this is the root of the tree. We will start
- * looking for subclasses from here */
- if (ldb_attr_cmp("top", current->objectclass->lDAPDisplayName) == 0) {
- DLIST_ADD_END(parent_class, current, struct class_list *);
- } else {
+ /* Don't add top to list, we will do that later */
+ if (ldb_attr_cmp("top", current->objectclass->lDAPDisplayName) != 0) {
DLIST_ADD_END(unsorted, current, struct class_list *);
}
}
- if (parent_class == NULL) {
- current = talloc(mem_ctx, struct class_list);
- current->objectclass = dsdb_class_by_lDAPDisplayName(schema, "top");
- DLIST_ADD_END(parent_class, current, struct class_list *);
- }
+ /* Add top here, to prevent duplicates */
+ current = talloc(mem_ctx, struct class_list);
+ current->objectclass = dsdb_class_by_lDAPDisplayName(schema, "top");
+ DLIST_ADD_END(sorted, current, struct class_list *);
+
/* For each object: find parent chain */
for (current = unsorted; schema && current; current = current->next) {
@@ -179,44 +175,24 @@ static int objectclass_sort(struct ldb_module *module,
new_parent->objectclass = dsdb_class_by_lDAPDisplayName(schema, \
current->objectclass->subClassOf); DLIST_ADD_END(unsorted, new_parent, struct \
class_list *); }
-
- /* DEBUGGING aid: how many layers are we down now? */
- layer = 0;
- do {
- layer++;
- /* Find all the subclasses of classes in the
- * parent_classes. Push them onto the subclass list */
-
- /* Ensure we don't bother if there are no unsorted entries left */
- for (current = parent_class; schema && unsorted && current; current = \
current->next) {
- /* Walk the list of possible subclasses in unsorted */
- for (poss_subclass = unsorted; poss_subclass; ) {
- struct class_list *next;
-
- /* Save the next pointer, as the DLIST_ macros will change poss_subclass->next \
*/
- next = poss_subclass->next;
-
- if (ldb_attr_cmp(poss_subclass->objectclass->subClassOf, \
current->objectclass->lDAPDisplayName) == 0) {
- DLIST_REMOVE(unsorted, poss_subclass);
- DLIST_ADD(subclass, poss_subclass);
-
- break;
- }
- poss_subclass = next;
+
+ do
+ {
+ lowest = INT_MAX;
+ current_lowest = NULL;
+ for (current = unsorted; schema && current; current = current->next) {
+ if(current->objectclass->subClass_order < lowest) {
+ current_lowest = current;
+ lowest = current->objectclass->subClass_order;
}
}
-
- /* Now push the parent_classes as sorted, we are done with
- these. Add to the END of the list by concatenation */
- DLIST_CONCATENATE(sorted, parent_class, struct class_list *);
-
- /* and now find subclasses of these */
- parent_class = subclass;
- subclass = NULL;
-
- /* If we didn't find any subclasses we will fall out
- * the bottom here */
- } while (parent_class);
+
+ if(current_lowest != NULL) {
+ DLIST_REMOVE(unsorted,current_lowest);
+ DLIST_ADD_END(sorted,current_lowest, struct class_list *);
+ }
+ } while(unsorted);
+
if (!unsorted) {
*sorted_out = sorted;
@@ -466,11 +442,14 @@ static int objectclass_do_add(struct oc_context *ac)
const struct dsdb_schema *schema;
struct ldb_request *add_req;
char *value;
- struct ldb_message_element *objectclass_element;
+ struct ldb_message_element *objectclass_element, *el;
struct ldb_message *msg;
TALLOC_CTX *mem_ctx;
struct class_list *sorted, *current;
int ret;
+ const struct dsdb_class *objectclass;
+ int32_t systemFlags = 0;
+ const char *rdn_name = NULL;
ldb = ldb_module_get_ctx(ac->module);
schema = dsdb_get_schema(ldb);
@@ -560,120 +539,128 @@ static int objectclass_do_add(struct oc_context *ac)
talloc_free(mem_ctx);
return ret;
}
- /* Last one is the critical one */
- if (!current->next) {
- struct ldb_message_element *el;
- int32_t systemFlags = 0;
- const char *rdn_name = ldb_dn_get_rdn_name(msg->dn);
- 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");
+ /* Retrive the message again so get_last_structural_class works */
+ objectclass_element = ldb_msg_find_element(msg, "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;
+ /* Make sure its valid to add an object of this type */
+ objectclass = get_last_structural_class(schema,objectclass_element);
+ if(objectclass == NULL) {
+ ldb_asprintf_errstring(ldb,
+ "Failed to find a structural class for %s",
+ ldb_dn_get_linearized(msg->dn));
+ return LDB_ERR_NAMING_VIOLATION;
+ }
- 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;
- }
- }
- }
- }
+ rdn_name = ldb_dn_get_rdn_name(msg->dn);
+ if (objectclass->rDNAttID
+ && ldb_attr_cmp(rdn_name, objectclass->rDNAttID) != 0) {
+ ldb_asprintf_errstring(ldb,
+ "RDN %s is not correct for most specific structural objectclass %s, should be \
%s", + rdn_name, objectclass->lDAPDisplayName, objectclass->rDNAttID);
+ return LDB_ERR_NAMING_VIOLATION;
+ }
- 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 (ac->search_res && ac->search_res->message) {
+ struct ldb_message_element *oc_el
+ = ldb_msg_find_element(ac->search_res->message, "objectClass");
- 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));
- return LDB_ERR_UNWILLING_TO_PERFORM;
- }
+ 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;
- if (!ldb_msg_find_element(msg, "objectCategory")) {
- struct dsdb_extended_dn_store_format *dn_format = \
talloc_get_type(ldb_module_get_private(ac->module), struct \
dsdb_extended_dn_store_format);
- if (dn_format && dn_format->store_extended_dn_in_ldb == false) {
- /* Strip off extended components */
- struct ldb_dn *dn = ldb_dn_new(msg, ldb, \
current->objectclass->defaultObjectCategory);
- value = ldb_dn_alloc_linearized(msg, dn);
- talloc_free(dn);
- } else {
- value = talloc_strdup(msg, current->objectclass->defaultObjectCategory);
+ 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(objectclass->lDAPDisplayName, sclass->systemPossibleInferiors[j]) == 0) \
{ + allowed_class = true;
+ break;
+ }
}
- if (value == NULL) {
- ldb_oom(ldb);
- talloc_free(mem_ctx);
- return LDB_ERR_OPERATIONS_ERROR;
+ } else {
+ for (j=0; sclass->systemPossibleInferiors && \
sclass->systemPossibleInferiors[j]; j++) { + if \
(ldb_attr_cmp(objectclass->lDAPDisplayName, sclass->systemPossibleInferiors[j]) == 0) \
{ + allowed_class = true;
+ break;
+ }
}
- ldb_msg_add_string(msg, "objectCategory", value);
- }
- if (!ldb_msg_find_element(msg, "showInAdvancedViewOnly") && \
(current->objectclass->defaultHidingValue == true)) {
- ldb_msg_add_string(msg, "showInAdvancedViewOnly",
- "TRUE");
}
+ }
- /* There are very special rules for systemFlags, see MS-ADTS 3.1.1.5.2.4 */
- el = ldb_msg_find_element(msg, "systemFlags");
+ if (!allowed_class) {
+ ldb_asprintf_errstring(ldb, "structural objectClass %s is not a valid child \
class for %s", + objectclass->lDAPDisplayName, \
ldb_dn_get_linearized(ac->search_res->message->dn)); + return \
LDB_ERR_NAMING_VIOLATION; + }
+ }
- systemFlags = ldb_msg_find_attr_as_int(msg, "systemFlags", 0);
+ if (objectclass->systemOnly && !ldb_request_get_control(ac->req, \
LDB_CONTROL_RELAX_OID)) { + ldb_asprintf_errstring(ldb, "objectClass %s is \
systemOnly, rejecting creation of %s", + objectclass->lDAPDisplayName, \
ldb_dn_get_linearized(msg->dn)); + return LDB_ERR_UNWILLING_TO_PERFORM;
+ }
- if (el) {
- /* Only these flags may be set by a client, but we can't tell between a client \
and our provision at this point */
- /* systemFlags &= ( SYSTEM_FLAG_CONFIG_ALLOW_RENAME | \
SYSTEM_FLAG_CONFIG_ALLOW_MOVE | SYSTEM_FLAG_CONFIG_LIMITED_MOVE); */
- ldb_msg_remove_element(msg, el);
- }
+ if (!ldb_msg_find_element(msg, "objectCategory")) {
+ struct dsdb_extended_dn_store_format *dn_format = \
talloc_get_type(ldb_module_get_private(ac->module), struct \
dsdb_extended_dn_store_format); + if (dn_format && \
dn_format->store_extended_dn_in_ldb == false) { + /* Strip off extended components \
*/ + struct ldb_dn *dn = ldb_dn_new(msg, ldb, objectclass->defaultObjectCategory);
+ value = ldb_dn_alloc_linearized(msg, dn);
+ talloc_free(dn);
+ } else {
+ value = talloc_strdup(msg, objectclass->defaultObjectCategory);
+ }
+ if (value == NULL) {
+ ldb_oom(ldb);
+ talloc_free(mem_ctx);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ ldb_msg_add_string(msg, "objectCategory", value);
+ }
+ if (!ldb_msg_find_element(msg, "showInAdvancedViewOnly") && \
(objectclass->defaultHidingValue == true)) { + ldb_msg_add_string(msg, \
"showInAdvancedViewOnly", + "TRUE");
+ }
- /* This flag is only allowed on attributeSchema objects */
- if (ldb_attr_cmp(current->objectclass->lDAPDisplayName, "attributeSchema") == 0) \
{
- systemFlags &= ~SYSTEM_FLAG_ATTR_IS_RDN;
- }
+ /* There are very special rules for systemFlags, see MS-ADTS 3.1.1.5.2.4 */
+ el = ldb_msg_find_element(msg, "systemFlags");
- if (ldb_attr_cmp(current->objectclass->lDAPDisplayName, "server") == 0) {
- systemFlags |= (int32_t)(SYSTEM_FLAG_DISALLOW_MOVE_ON_DELETE | \
SYSTEM_FLAG_CONFIG_ALLOW_RENAME | \
SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE);
- } else if (ldb_attr_cmp(current->objectclass->lDAPDisplayName, "site") == 0
- || ldb_attr_cmp(current->objectclass->lDAPDisplayName, "serverContainer") == \
0
- || ldb_attr_cmp(current->objectclass->lDAPDisplayName, "ntDSDSA") == 0) {
- systemFlags |= (int32_t)(SYSTEM_FLAG_DISALLOW_MOVE_ON_DELETE);
-
- } else if (ldb_attr_cmp(current->objectclass->lDAPDisplayName, "siteLink") == 0
- || ldb_attr_cmp(current->objectclass->lDAPDisplayName, "siteLinkBridge") == \
0
- || ldb_attr_cmp(current->objectclass->lDAPDisplayName, "nTDSConnection") == \
0) {
- systemFlags |= (int32_t)(SYSTEM_FLAG_CONFIG_ALLOW_RENAME);
- }
+ systemFlags = ldb_msg_find_attr_as_int(msg, "systemFlags", 0);
- /* TODO: If parent object is site or subnet, also add \
(SYSTEM_FLAG_CONFIG_ALLOW_RENAME) */ + if (el) {
+ /* Only these flags may be set by a client, but we can't tell between a client \
and our provision at this point */ + /* systemFlags &= ( \
SYSTEM_FLAG_CONFIG_ALLOW_RENAME | SYSTEM_FLAG_CONFIG_ALLOW_MOVE | \
SYSTEM_FLAG_CONFIG_LIMITED_MOVE); */ + ldb_msg_remove_element(msg, el);
+ }
- if (el || systemFlags != 0) {
- samdb_msg_add_int(ldb, msg, msg, "systemFlags", systemFlags);
- }
- }
+ /* This flag is only allowed on attributeSchema objects */
+ if (ldb_attr_cmp(objectclass->lDAPDisplayName, "attributeSchema") == 0) {
+ systemFlags &= ~SYSTEM_FLAG_ATTR_IS_RDN;
+ }
+
+ if (ldb_attr_cmp(objectclass->lDAPDisplayName, "server") == 0) {
+ systemFlags |= (int32_t)(SYSTEM_FLAG_DISALLOW_MOVE_ON_DELETE | \
SYSTEM_FLAG_CONFIG_ALLOW_RENAME | SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE); + } else \
if (ldb_attr_cmp(objectclass->lDAPDisplayName, "site") == 0 + || \
ldb_attr_cmp(objectclass->lDAPDisplayName, "serverContainer") == 0 + || \
ldb_attr_cmp(objectclass->lDAPDisplayName, "ntDSDSA") == 0) { + systemFlags |= \
(int32_t)(SYSTEM_FLAG_DISALLOW_MOVE_ON_DELETE); +
+ } else if (ldb_attr_cmp(objectclass->lDAPDisplayName, "siteLink") == 0
+ || ldb_attr_cmp(objectclass->lDAPDisplayName, "siteLinkBridge") == 0
+ || ldb_attr_cmp(objectclass->lDAPDisplayName, "nTDSConnection") == 0) {
+ systemFlags |= (int32_t)(SYSTEM_FLAG_CONFIG_ALLOW_RENAME);
+ }
+
+ /* TODO: If parent object is site or subnet, also add \
(SYSTEM_FLAG_CONFIG_ALLOW_RENAME) */ +
+ if (el || systemFlags != 0) {
+ samdb_msg_add_int(ldb, msg, msg, "systemFlags", systemFlags);
}
}
--
1.5.4.3
["0006-s4-dsdb-Add-a-test-for-adding-deleting-and-append.patch" (text/x-diff)]
From 08e8f82c0b52a213ddc1ed475e6bb2a1ad7e455a Mon Sep 17 00:00:00 2001
From: Brendan Powers <brendan0powers@gmail.com>
Date: Mon, 14 Dec 2009 20:51:10 -0500
Subject: [PATCH] s4-dsdb: Add a test for adding, deleting, and appending a \
psoxAccount objectClass to a user
---
source4/lib/ldb/tests/python/ldap.py | 30 ++++++++++++++++++++++++++++++
1 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/source4/lib/ldb/tests/python/ldap.py \
b/source4/lib/ldb/tests/python/ldap.py index d0a0ed2..54b623a 100755
--- a/source4/lib/ldb/tests/python/ldap.py
+++ b/source4/lib/ldb/tests/python/ldap.py
@@ -1719,6 +1719,36 @@ member: CN=ldaptestutf8user èùéìòà ,CN=Users,""" + \
self.base_dn + """
res = ldb.search(self.base_dn, expression="objectCategory=group", \
scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"]) \
self.assertTrue(len(res) > 0)
+ print "Testing creating a user with the posixAccount objectClass"
+ self.ldb.add_ldif("""dn: cn=posixuser,CN=Users,%s
+objectClass: top
+objectClass: person
+objectClass: posixAccount
+objectClass: user
+objectClass: organizationalPerson
+cn: posixuser
+uid: posixuser
+sn: posixuser
+uidNumber: 10126
+gidNumber: 10126
+homeDirectory: /home/posixuser
+loginShell: /bin/bash
+gecos: Posix User;;;
+description: A POSIX user"""% (self.base_dn))
+
+ print "Testing removing the posixAccount objectClass from an existing user"
+ self.ldb.modify_ldif("""dn: cn=posixuser,CN=Users,%s
+changetype: modify
+delete: objectClass
+objectClass: posixAccount"""% (self.base_dn))
+
+ print "Testing adding the posixAccount objectClass to an existing user"
+ self.ldb.modify_ldif("""dn: cn=posixuser,CN=Users,%s
+changetype: modify
+add: objectClass
+objectClass: posixAccount"""% (self.base_dn))
+
+ self.delete_force(self.ldb, "cn=posixuser,cn=users," + self.base_dn)
self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
self.delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
--
1.5.4.3
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic