[prev in list] [next in list] [prev in thread] [next in thread]
List: samba-technical
Subject: Re: Unable to add posixAccount objectclass to AD user
From: brendan powers <brendan0powers () gmail ! com>
Date: 2009-12-07 23:37:25
Message-ID: c547abb70912071537j4fc41dcatfdddcff17dd9ed28 () mail ! gmail ! com
[Download RAW message or body]
Here are the patches we discussed.
["0001-check-for-NULL-src-in-strlower_talloc.patch" (application/octet-stream)]
From 61dab3cf423dea1d39effc2b2b6c398b6e37012a Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Mon, 7 Dec 2009 18:18:47 -0500
Subject: [PATCH] check for NULL src in strlower_talloc
---
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-check-if-an-attribute-exists-before-debugging-it.patch" (application/octet-stream)]
From 9b8737657221b99b64e05b00eef8584db2cac8e0 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Mon, 7 Dec 2009 18:19:31 -0500
Subject: [PATCH] check if an attribute exists before debugging it
---
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 13e71e5..f646df5 100644
--- a/source4/dsdb/samdb/ldb_modules/acl.c
+++ b/source4/dsdb/samdb/ldb_modules/acl.c
@@ -272,7 +272,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-make-sure-samAccountName-exists-when-adding-updating.patch" (application/octet-stream)]
From 609a8d8bea6dfc342ea272f2045d453aef2a5601 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Mon, 7 Dec 2009 18:20:05 -0500
Subject: [PATCH] make sure samAccountName exists when adding/updating an account
---
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 8791db2..45ec34a 100644
--- a/source4/dsdb/samdb/ldb_modules/password_hash.c
+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c
@@ -1491,6 +1491,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
["0004-move-get_last_structural_class-to-util.c.patch" (application/octet-stream)]
From 08644a220e37c6dbcaf17e9b9d055cb05aae31af Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Mon, 7 Dec 2009 18:21:05 -0500
Subject: [PATCH] move get_last_structural_class to util.c
make get_last_structural_class ignore auxiliary classes
---
source4/dsdb/samdb/ldb_modules/descriptor.c | 17 +----------------
source4/dsdb/samdb/ldb_modules/util.c | 18 ++++++++++++++++++
source4/dsdb/samdb/ldb_modules/util.h | 1 +
3 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/source4/dsdb/samdb/ldb_modules/descriptor.c \
b/source4/dsdb/samdb/ldb_modules/descriptor.c index da80ee5..8ea6042 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 b0f22de..3fc2993 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) {
@@ -198,3 +199,20 @@ 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->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 b612c64..230f997 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
["0005-reimplement-objectclass_sort-to-use-ldb_qsort-to-sor.patch" (application/octet-stream)]
From ab4651aec5b6388ddf7aca732a08e5c5fa49fe92 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Mon, 7 Dec 2009 18:21:45 -0500
Subject: [PATCH] reimplement objectclass_sort to use ldb_qsort to sort classes by \
importance use get_last_structural_class to check validity instead of using the last \
class in the list
---
source4/dsdb/samdb/ldb_modules/objectclass.c | 499 ++++++++------------------
1 files changed, 159 insertions(+), 340 deletions(-)
diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c \
b/source4/dsdb/samdb/ldb_modules/objectclass.c index c47e360..e91f812 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 {
@@ -81,161 +82,28 @@ static struct oc_context *oc_init_context(struct ldb_module \
*module,
static int objectclass_do_add(struct oc_context *ac);
+/* this function does not check for errors. Inputs are expected to be verfied before \
this function is called */ +static int do_compare_objectclass(const struct ldb_val \
*obj1, + const struct ldb_val *obj2,
+ void *opaque)
+{
+ const struct dsdb_schema *schema = opaque;
+ const struct dsdb_class *class1 = \
dsdb_class_by_lDAPDisplayName_ldb_val(schema,obj1); + const struct dsdb_class *class2 \
= dsdb_class_by_lDAPDisplayName_ldb_val(schema,obj2); +
+ return(class1->subClass_order > class2->subClass_order);
+}
+
/* Sort objectClasses into correct order, and validate that all
* objectClasses specified actually exist in the schema
*/
-
static int objectclass_sort(struct ldb_module *module,
const struct dsdb_schema *schema,
TALLOC_CTX *mem_ctx,
- struct ldb_message_element *objectclass_element,
- struct class_list **sorted_out)
+ struct ldb_message_element *objectclass_element)
{
- 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;
-
- ldb = ldb_module_get_ctx(module);
-
- /* DESIGN:
- *
- * We work on 4 different 'bins' (implemented here as linked lists):
- *
- * * sorted: the eventual list, in the order we wish to push
- * into the database. This is the only ordered list.
- *
- * * parent_class: The current parent class 'bin' we are
- * trying to find subclasses for
- *
- * * subclass: The subclasses we have found so far
- *
- * * unsorted: The remaining objectClasses
- *
- * The process is a matter of filtering objectClasses up from
- * unsorted into sorted. Order is irrelevent in the later 3 'bins'.
- *
- * We start with 'top' (found and promoted to parent_class
- * initially). Then we find (in unsorted) all the direct
- * subclasses of 'top'. parent_classes is concatenated onto
- * the end of 'sorted', and subclass becomes the list in
- * parent_class.
- *
- * We then repeat, until we find no more subclasses. Any left
- * over classes are added to the end.
- *
- */
-
- /* Firstly, dump all the objectClass elements into the
- * unsorted bin, except for 'top', which is special */
- for (i=0; i < objectclass_element->num_values; i++) {
- current = talloc(mem_ctx, struct class_list);
- if (!current) {
- ldb_oom(ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- current->objectclass = dsdb_class_by_lDAPDisplayName_ldb_val(schema, \
&objectclass_element->values[i]);
- if (!current->objectclass) {
- ldb_asprintf_errstring(ldb, "objectclass %.*s is not a valid objectClass in \
schema",
- (int)objectclass_element->values[i].length, (const char \
*)objectclass_element->values[i].data);
- /* This looks weird, but windows apparently returns this for invalid objectClass \
values */
- return LDB_ERR_NO_SUCH_ATTRIBUTE;
- } else if (current->objectclass->isDefunct) {
- ldb_asprintf_errstring(ldb, "objectclass %.*s marked as isDefunct objectClass in \
schema - not valid for new objects",
- (int)objectclass_element->values[i].length, (const char \
*)objectclass_element->values[i].data);
- /* This looks weird, but windows apparently returns this for invalid objectClass \
values */
- 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 {
- 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 *);
- }
-
- /* For each object: find parent chain */
- for (current = unsorted; schema && current; current = current->next) {
- for (poss_parent = unsorted; poss_parent; poss_parent = poss_parent->next) {
- if (ldb_attr_cmp(poss_parent->objectclass->lDAPDisplayName, \
current->objectclass->subClassOf) == 0) {
- break;
- }
- }
- /* If we didn't get to the end of the list, we need to add this parent */
- if (poss_parent || (ldb_attr_cmp("top", current->objectclass->subClassOf) == 0)) {
- continue;
- }
-
- new_parent = talloc(mem_ctx, struct class_list);
- 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;
- }
- }
-
- /* 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 (!unsorted) {
- *sorted_out = sorted;
- return LDB_SUCCESS;
- }
-
- if (!schema) {
- /* If we don't have schema yet, then just merge the lists again */
- DLIST_CONCATENATE(sorted, unsorted, struct class_list *);
- *sorted_out = sorted;
- return LDB_SUCCESS;
- }
-
- /* This shouldn't happen, and would break MMC, perhaps there
- * was no 'top', a conflict in the objectClasses or some other
- * schema error?
- */
- ldb_asprintf_errstring(ldb, "objectclass %s is not a valid objectClass in \
objectClass chain", unsorted->objectclass->lDAPDisplayName);
- return LDB_ERR_OBJECT_CLASS_VIOLATION;
+ ldb_qsort(objectclass_element->values,objectclass_element->num_values,sizeof(struct \
ldb_val),discard_const_p(struct schema \
,schema),(ldb_qsort_cmp_fn_t)do_compare_objectclass); + return LDB_SUCCESS;
}
static int get_search_callback(struct ldb_request *req, struct ldb_reply *ares)
@@ -469,8 +337,8 @@ static int objectclass_do_add(struct oc_context *ac)
struct ldb_message_element *objectclass_element;
struct ldb_message *msg;
TALLOC_CTX *mem_ctx;
- struct class_list *sorted, *current;
- int ret;
+ int ret, i;
+ const struct dsdb_class * structural, *objectclass;
ldb = ldb_module_get_ctx(ac->module);
schema = dsdb_get_schema(ldb);
@@ -487,7 +355,6 @@ static int objectclass_do_add(struct oc_context *ac)
if (ldb_dn_compare(ldb_get_root_basedn(ldb),
msg->dn) == 0) {
/* Allow the tree to be started */
-
/* but don't keep any error string, it's meaningless */
ldb_set_errstring(ldb, NULL);
} else {
@@ -513,6 +380,10 @@ static int objectclass_do_add(struct oc_context *ac)
}
if (schema) {
+ struct ldb_message_element *el;
+ int32_t systemFlags = 0;
+ const char *rdn_name = ldb_dn_get_rdn_name(msg->dn);
+
ret = fix_check_attributes(ldb, schema, msg, ac->req->operation);
if (ret != LDB_SUCCESS) {
talloc_free(mem_ctx);
@@ -527,160 +398,145 @@ static int objectclass_do_add(struct oc_context *ac)
talloc_free(mem_ctx);
return LDB_ERR_OPERATIONS_ERROR;
}
- ret = objectclass_sort(ac->module, schema, mem_ctx, objectclass_element, &sorted);
- if (ret != LDB_SUCCESS) {
- talloc_free(mem_ctx);
- return ret;
+
+
+ /* Fix up the objectClass values to canonical case */
+ for (i=0; i < objectclass_element->num_values; i++) {
+ objectclass = dsdb_class_by_lDAPDisplayName_ldb_val(schema,&objectclass_element->values[i]);
+ if(objectclass == NULL) {
+ ldb_oom(ldb);
+ talloc_free(mem_ctx);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ objectclass_element->values[i] = \
data_blob_string_const(objectclass->lDAPDisplayName); }
-
- ldb_msg_remove_attr(msg, "objectClass");
- ret = ldb_msg_add_empty(msg, "objectClass", 0, NULL);
-
+
+ ret = objectclass_sort(ac->module, schema, mem_ctx, objectclass_element);
if (ret != LDB_SUCCESS) {
talloc_free(mem_ctx);
return ret;
}
- /* We must completely replace the existing objectClass entry,
- * because we need it sorted */
+ structural = get_last_structural_class(schema, objectclass_element);
- /* Move from the linked list back into an ldb msg */
- for (current = sorted; current; current = current->next) {
- value = talloc_strdup(msg, current->objectclass->lDAPDisplayName);
- if (value == NULL) {
- ldb_oom(ldb);
- talloc_free(mem_ctx);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- ret = ldb_msg_add_string(msg, "objectClass", value);
- if (ret != LDB_SUCCESS) {
- ldb_set_errstring(ldb,
- "objectclass: could not re-add sorted "
- "objectclass to modify msg");
- 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;
- }
+ /* Check the most structural class */
+ if (structural->rDNAttID
+ && ldb_attr_cmp(rdn_name, structural->rDNAttID) != 0) {
+ ldb_asprintf_errstring(ldb,
+ "RDN %s is not correct for most specific structural objectclass %s, should be \
%s", + rdn_name, structural->lDAPDisplayName, structural->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");
+ 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;
+ bool allowed_class = false;
+ int 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;
- }
- }
+ 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(structural->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;
+ } else {
+ for (j=0; sclass->systemPossibleInferiors && \
sclass->systemPossibleInferiors[j]; j++) { + if \
(ldb_attr_cmp(structural->lDAPDisplayName, sclass->systemPossibleInferiors[j]) == 0) \
{ + allowed_class = true;
+ break;
+ }
}
}
+ }
- 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;
- }
+ if (!allowed_class) {
+ ldb_asprintf_errstring(ldb, "structural objectClass %s is not a valid child \
class for %s", + structural->lDAPDisplayName, \
ldb_dn_get_linearized(ac->search_res->message->dn));
- 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);
- }
- 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") && \
(current->objectclass->defaultHidingValue == true)) {
- ldb_msg_add_string(msg, "showInAdvancedViewOnly",
- "TRUE");
- }
+ return LDB_ERR_NAMING_VIOLATION;
+ }
+ }
- /* There are very special rules for systemFlags, see MS-ADTS 3.1.1.5.2.4 */
- el = ldb_msg_find_element(msg, "systemFlags");
+ if (structural->systemOnly && !ldb_request_get_control(ac->req, \
LDB_CONTROL_RELAX_OID)) { + ldb_asprintf_errstring(ldb, "objectClass %s is \
systemOnly, rejecting creation of %s", + structural->lDAPDisplayName, \
ldb_dn_get_linearized(msg->dn)); + return LDB_ERR_UNWILLING_TO_PERFORM;
+ }
- systemFlags = ldb_msg_find_attr_as_int(msg, "systemFlags", 0);
+ 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, structural->defaultObjectCategory);
+ value = ldb_dn_alloc_linearized(msg, dn);
+ talloc_free(dn);
+ } else {
+ value = talloc_strdup(msg, structural->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") && \
(structural->defaultHidingValue == true)) { + ldb_msg_add_string(msg, \
"showInAdvancedViewOnly", + "TRUE");
+ }
- 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);
- }
+ /* There are very special rules for systemFlags, see MS-ADTS 3.1.1.5.2.4 */
+ el = ldb_msg_find_element(msg, "systemFlags");
- /* This flag is only allowed on attributeSchema objects */
- if (ldb_attr_cmp(current->objectclass->lDAPDisplayName, "attributeSchema") == 0) \
{
- systemFlags &= ~SYSTEM_FLAG_ATTR_IS_RDN;
- }
+ systemFlags = ldb_msg_find_attr_as_int(msg, "systemFlags", 0);
- 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);
- }
+ 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);
+ }
- /* TODO: If parent object is site or subnet, also add \
(SYSTEM_FLAG_CONFIG_ALLOW_RENAME) */ + /* This flag is only allowed on \
attributeSchema objects */ + if (ldb_attr_cmp(structural->lDAPDisplayName, \
"attributeSchema") == 0) { + systemFlags &= ~SYSTEM_FLAG_ATTR_IS_RDN;
+ }
- if (el || systemFlags != 0) {
- samdb_msg_add_int(ldb, msg, msg, "systemFlags", systemFlags);
- }
- }
+ if (ldb_attr_cmp(structural->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(structural->lDAPDisplayName, "site") == 0 + || \
ldb_attr_cmp(structural->lDAPDisplayName, "serverContainer") == 0 + || \
ldb_attr_cmp(structural->lDAPDisplayName, "ntDSDSA") == 0) { + systemFlags |= \
(int32_t)(SYSTEM_FLAG_DISALLOW_MOVE_ON_DELETE); +
+ } else if (ldb_attr_cmp(structural->lDAPDisplayName, "siteLink") == 0
+ || ldb_attr_cmp(structural->lDAPDisplayName, "siteLinkBridge") == 0
+ || ldb_attr_cmp(structural->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);
+ }
+
}
+
talloc_free(mem_ctx);
ret = ldb_msg_sanity_check(ldb, msg);
-
if (ret != LDB_SUCCESS) {
return ret;
}
@@ -695,7 +551,7 @@ static int objectclass_do_add(struct oc_context *ac)
}
/* perform the add */
- return ldb_next_request(ac->module, add_req);
+ ret ldb_next_request(ac->module, add_req);
}
static int oc_modify_callback(struct ldb_request *req,
@@ -708,12 +564,11 @@ static int objectclass_modify(struct ldb_module *module, struct \
ldb_request *req struct ldb_message_element *objectclass_element;
struct ldb_message *msg;
const struct dsdb_schema *schema = dsdb_get_schema(ldb);
- struct class_list *sorted, *current;
struct ldb_request *down_req;
struct oc_context *ac;
TALLOC_CTX *mem_ctx;
- char *value;
- int ret;
+ const struct dsdb_class *objectclass;
+ int ret, i;
ldb_debug(ldb, LDB_DEBUG_TRACE, "objectclass_modify\n");
@@ -794,43 +649,22 @@ static int objectclass_modify(struct ldb_module *module, struct \
ldb_request *req return ret;
}
- ret = objectclass_sort(module, schema, mem_ctx, objectclass_element, &sorted);
- if (ret != LDB_SUCCESS) {
- talloc_free(mem_ctx);
- return ret;
- }
-
- /* We must completely replace the existing objectClass entry,
- * because we need it sorted */
-
- ldb_msg_remove_attr(msg, "objectClass");
- ret = ldb_msg_add_empty(msg, "objectClass", LDB_FLAG_MOD_REPLACE, NULL);
-
- if (ret != LDB_SUCCESS) {
- talloc_free(mem_ctx);
- return ret;
- }
- /* Move from the linked list back into an ldb msg */
- for (current = sorted; current; current = current->next) {
- /* copy the value as this string is on the schema
- * context and we can't rely on it not changing
- * before the operation is over */
- value = talloc_strdup(msg,
- current->objectclass->lDAPDisplayName);
- if (value == NULL) {
+ /* Fix up the objectClass values to canonical case */
+ for (i=0; i < objectclass_element->num_values; i++) {
+ objectclass = dsdb_class_by_lDAPDisplayName_ldb_val(schema,&objectclass_element->values[i]);
+ if(objectclass == NULL) {
ldb_oom(ldb);
talloc_free(mem_ctx);
return LDB_ERR_OPERATIONS_ERROR;
}
- ret = ldb_msg_add_string(msg, "objectClass", value);
- if (ret != LDB_SUCCESS) {
- ldb_set_errstring(ldb,
- "objectclass: could not re-add sorted "
- "objectclass to modify msg");
- talloc_free(mem_ctx);
- return ret;
- }
+ objectclass_element->values[i] = \
data_blob_string_const(objectclass->lDAPDisplayName); + }
+
+ ret = objectclass_sort(module, schema, mem_ctx, objectclass_element);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(mem_ctx);
+ return ret;
}
talloc_free(mem_ctx);
@@ -934,12 +768,11 @@ static int objectclass_do_mod(struct oc_context *ac)
struct ldb_context *ldb;
const struct dsdb_schema *schema;
struct ldb_request *mod_req;
- char *value;
struct ldb_message_element *objectclass_element;
struct ldb_message *msg;
TALLOC_CTX *mem_ctx;
- struct class_list *sorted, *current;
- int ret;
+ const struct dsdb_class *objectclass;
+ int ret, i;
ldb = ldb_module_get_ctx(ac->module);
@@ -974,35 +807,21 @@ static int objectclass_do_mod(struct oc_context *ac)
/* modify dn */
msg->dn = ac->req->op.mod.message->dn;
- ret = objectclass_sort(ac->module, schema, mem_ctx, objectclass_element, &sorted);
- if (ret != LDB_SUCCESS) {
- return ret;
- }
-
- /* We must completely replace the existing objectClass entry.
- * We could do a constrained add/del, but we are meant to be
- * in a transaction... */
-
- ret = ldb_msg_add_empty(msg, "objectClass", LDB_FLAG_MOD_REPLACE, NULL);
- if (ret != LDB_SUCCESS) {
- ldb_set_errstring(ldb, "objectclass: could not clear objectclass in modify msg");
- talloc_free(mem_ctx);
- return ret;
- }
- /* Move from the linked list back into an ldb msg */
- for (current = sorted; current; current = current->next) {
- value = talloc_strdup(msg, current->objectclass->lDAPDisplayName);
- if (value == NULL) {
+ /* Fix up the objectClass values to canonical case */
+ for (i=0; i < objectclass_element->num_values; i++) {
+ objectclass = dsdb_class_by_lDAPDisplayName_ldb_val(schema,&objectclass_element->values[i]);
+ if(objectclass == NULL) {
ldb_oom(ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- ret = ldb_msg_add_string(msg, "objectClass", value);
- if (ret != LDB_SUCCESS) {
- ldb_set_errstring(ldb, "objectclass: could not re-add sorted objectclass to \
modify msg"); talloc_free(mem_ctx);
- return ret;
+ return LDB_ERR_OPERATIONS_ERROR;
}
+ objectclass_element->values[i] = \
data_blob_string_const(objectclass->lDAPDisplayName); + }
+
+ ret = objectclass_sort(ac->module, schema, mem_ctx, objectclass_element);
+ if (ret != LDB_SUCCESS) {
+ return ret;
}
ret = ldb_msg_sanity_check(ldb, msg);
--
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