4 Copyright (C) Simo Sorce 2006-2008
5 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005-2009
6 Copyright (C) Matthias Dieter Wallnöfer 2010
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 * Component: objectClass sorting and constraint checking module
28 * - sort the objectClass attribute into the class
29 * hierarchy and perform constraint checks (correct RDN name,
31 * - fix DNs into 'standard' case
32 * - Add objectCategory and some other attribute defaults
34 * Author: Andrew Bartlett
39 #include "ldb_module.h"
40 #include "util/dlinklist.h"
41 #include "dsdb/samdb/samdb.h"
42 #include "librpc/ndr/libndr.h"
43 #include "librpc/gen_ndr/ndr_security.h"
44 #include "libcli/security/security.h"
45 #include "auth/auth.h"
46 #include "param/param.h"
47 #include "../libds/common/flags.h"
52 struct ldb_module *module;
53 struct ldb_request *req;
54 const struct dsdb_schema *schema;
56 struct ldb_reply *search_res;
57 struct ldb_reply *search_res2;
59 int (*step_fn)(struct oc_context *);
63 struct class_list *prev, *next;
64 const struct dsdb_class *objectclass;
67 static struct oc_context *oc_init_context(struct ldb_module *module,
68 struct ldb_request *req)
70 struct ldb_context *ldb;
71 struct oc_context *ac;
73 ldb = ldb_module_get_ctx(module);
75 ac = talloc_zero(req, struct oc_context);
83 ac->schema = dsdb_get_schema(ldb, ac);
88 static int objectclass_do_add(struct oc_context *ac);
90 /* Sort objectClasses into correct order, and validate that all
91 * objectClasses specified actually exist in the schema
94 static int objectclass_sort(struct ldb_module *module,
95 const struct dsdb_schema *schema,
97 struct ldb_message_element *objectclass_element,
98 struct class_list **sorted_out)
100 struct ldb_context *ldb;
101 unsigned int i, lowest;
102 struct class_list *unsorted = NULL, *sorted = NULL, *current = NULL, *poss_parent = NULL, *new_parent = NULL, *current_lowest = NULL;
104 ldb = ldb_module_get_ctx(module);
108 * We work on 4 different 'bins' (implemented here as linked lists):
110 * * sorted: the eventual list, in the order we wish to push
111 * into the database. This is the only ordered list.
113 * * parent_class: The current parent class 'bin' we are
114 * trying to find subclasses for
116 * * subclass: The subclasses we have found so far
118 * * unsorted: The remaining objectClasses
120 * The process is a matter of filtering objectClasses up from
121 * unsorted into sorted. Order is irrelevent in the later 3 'bins'.
123 * We start with 'top' (found and promoted to parent_class
124 * initially). Then we find (in unsorted) all the direct
125 * subclasses of 'top'. parent_classes is concatenated onto
126 * the end of 'sorted', and subclass becomes the list in
129 * We then repeat, until we find no more subclasses. Any left
130 * over classes are added to the end.
134 /* Firstly, dump all the objectClass elements into the
135 * unsorted bin, except for 'top', which is special */
136 for (i=0; i < objectclass_element->num_values; i++) {
137 current = talloc(mem_ctx, struct class_list);
141 current->objectclass = dsdb_class_by_lDAPDisplayName_ldb_val(schema, &objectclass_element->values[i]);
142 if (!current->objectclass) {
143 ldb_asprintf_errstring(ldb, "objectclass %.*s is not a valid objectClass in schema",
144 (int)objectclass_element->values[i].length, (const char *)objectclass_element->values[i].data);
145 /* This looks weird, but windows apparently returns this for invalid objectClass values */
146 return LDB_ERR_NO_SUCH_ATTRIBUTE;
147 } else if (current->objectclass->isDefunct) {
148 ldb_asprintf_errstring(ldb, "objectclass %.*s marked as isDefunct objectClass in schema - not valid for new objects",
149 (int)objectclass_element->values[i].length, (const char *)objectclass_element->values[i].data);
150 /* This looks weird, but windows apparently returns this for invalid objectClass values */
151 return LDB_ERR_NO_SUCH_ATTRIBUTE;
154 /* Don't add top to list, we will do that later */
155 if (ldb_attr_cmp("top", current->objectclass->lDAPDisplayName) != 0) {
156 DLIST_ADD_END(unsorted, current, struct class_list *);
160 /* Add top here, to prevent duplicates */
161 current = talloc(mem_ctx, struct class_list);
162 current->objectclass = dsdb_class_by_lDAPDisplayName(schema, "top");
163 DLIST_ADD_END(sorted, current, struct class_list *);
166 /* For each object: find parent chain */
167 for (current = unsorted; schema && current; current = current->next) {
168 for (poss_parent = unsorted; poss_parent; poss_parent = poss_parent->next) {
169 if (ldb_attr_cmp(poss_parent->objectclass->lDAPDisplayName, current->objectclass->subClassOf) == 0) {
173 /* If we didn't get to the end of the list, we need to add this parent */
174 if (poss_parent || (ldb_attr_cmp("top", current->objectclass->subClassOf) == 0)) {
178 new_parent = talloc(mem_ctx, struct class_list);
179 new_parent->objectclass = dsdb_class_by_lDAPDisplayName(schema, current->objectclass->subClassOf);
180 DLIST_ADD_END(unsorted, new_parent, struct class_list *);
186 current_lowest = NULL;
187 for (current = unsorted; schema && current; current = current->next) {
188 if(current->objectclass->subClass_order < lowest) {
189 current_lowest = current;
190 lowest = current->objectclass->subClass_order;
194 if(current_lowest != NULL) {
195 DLIST_REMOVE(unsorted,current_lowest);
196 DLIST_ADD_END(sorted,current_lowest, struct class_list *);
202 *sorted_out = sorted;
207 /* If we don't have schema yet, then just merge the lists again */
208 DLIST_CONCATENATE(sorted, unsorted, struct class_list *);
209 *sorted_out = sorted;
213 /* This shouldn't happen, and would break MMC, perhaps there
214 * was no 'top', a conflict in the objectClasses or some other
217 ldb_asprintf_errstring(ldb, "objectclass %s is not a valid objectClass in objectClass chain", unsorted->objectclass->lDAPDisplayName);
218 return LDB_ERR_OBJECT_CLASS_VIOLATION;
221 static int get_search_callback(struct ldb_request *req, struct ldb_reply *ares)
223 struct ldb_context *ldb;
224 struct oc_context *ac;
227 ac = talloc_get_type(req->context, struct oc_context);
228 ldb = ldb_module_get_ctx(ac->module);
231 return ldb_module_done(ac->req, NULL, NULL,
232 LDB_ERR_OPERATIONS_ERROR);
234 if (ares->error != LDB_SUCCESS &&
235 ares->error != LDB_ERR_NO_SUCH_OBJECT) {
236 return ldb_module_done(ac->req, ares->controls,
237 ares->response, ares->error);
240 ldb_reset_err_string(ldb);
242 switch (ares->type) {
243 case LDB_REPLY_ENTRY:
244 if (ac->search_res != NULL) {
245 ldb_set_errstring(ldb, "Too many results");
247 return ldb_module_done(ac->req, NULL, NULL,
248 LDB_ERR_OPERATIONS_ERROR);
251 ac->search_res = talloc_steal(ac, ares);
254 case LDB_REPLY_REFERRAL:
261 ret = ac->step_fn(ac);
262 if (ret != LDB_SUCCESS) {
263 return ldb_module_done(ac->req, NULL, NULL, ret);
271 static int oc_op_callback(struct ldb_request *req, struct ldb_reply *ares)
273 struct oc_context *ac;
275 ac = talloc_get_type(req->context, struct oc_context);
278 return ldb_module_done(ac->req, NULL, NULL,
279 LDB_ERR_OPERATIONS_ERROR);
282 if (ares->type == LDB_REPLY_REFERRAL) {
283 return ldb_module_send_referral(ac->req, ares->referral);
286 if (ares->error != LDB_SUCCESS) {
287 return ldb_module_done(ac->req, ares->controls,
288 ares->response, ares->error);
291 if (ares->type != LDB_REPLY_DONE) {
293 return ldb_module_done(ac->req, NULL, NULL,
294 LDB_ERR_OPERATIONS_ERROR);
297 return ldb_module_done(ac->req, ares->controls,
298 ares->response, ares->error);
301 /* Fix up the DN to be in the standard form, taking particular care to match the parent DN
303 This should mean that if the parent is:
304 CN=Users,DC=samba,DC=example,DC=com
305 and a proposed child is
306 cn=Admins ,cn=USERS,dc=Samba,dc=example,dc=COM
308 The resulting DN should be:
310 CN=Admins,CN=Users,DC=samba,DC=example,DC=com
313 static int fix_dn(struct ldb_context *ldb,
315 struct ldb_dn *newdn, struct ldb_dn *parent_dn,
316 struct ldb_dn **fixed_dn)
318 char *upper_rdn_attr;
319 const struct ldb_val *rdn_val;
321 /* Fix up the DN to be in the standard form, taking particular care to match the parent DN */
322 *fixed_dn = ldb_dn_copy(mem_ctx, parent_dn);
324 /* We need the attribute name in upper case */
325 upper_rdn_attr = strupper_talloc(*fixed_dn,
326 ldb_dn_get_rdn_name(newdn));
327 if (!upper_rdn_attr) {
328 return ldb_operr(ldb);
331 /* Create a new child */
332 if (ldb_dn_add_child_fmt(*fixed_dn, "X=X") == false) {
333 return ldb_operr(ldb);
337 rdn_val = ldb_dn_get_rdn_val(newdn);
340 /* the rules for rDN length constraints are more complex than
341 this. Until we understand them we need to leave this
342 constraint out. Otherwise we break replication, as windows
343 does sometimes send us rDNs longer than 64 */
344 if (!rdn_val || rdn_val->length > 64) {
345 DEBUG(2,(__location__ ": WARNING: rDN longer than 64 limit for '%s'\n", ldb_dn_get_linearized(newdn)));
350 /* And replace it with CN=foo (we need the attribute in upper case */
351 return ldb_dn_set_component(*fixed_dn, 0, upper_rdn_attr, *rdn_val);
355 static int objectclass_do_add(struct oc_context *ac);
357 static int objectclass_add(struct ldb_module *module, struct ldb_request *req)
359 struct ldb_context *ldb;
360 struct ldb_request *search_req;
361 struct oc_context *ac;
362 struct ldb_dn *parent_dn;
363 const struct ldb_val *val;
366 static const char * const parent_attrs[] = { "objectGUID", "objectClass", NULL };
368 ldb = ldb_module_get_ctx(module);
370 ldb_debug(ldb, LDB_DEBUG_TRACE, "objectclass_add\n");
372 /* do not manipulate our control entries */
373 if (ldb_dn_is_special(req->op.add.message->dn)) {
374 return ldb_next_request(module, req);
377 /* An add operation on the basedn without "NC-add" operation isn't
379 if (ldb_dn_compare(ldb_get_default_basedn(ldb), req->op.add.message->dn) == 0) {
380 unsigned int instanceType;
382 instanceType = ldb_msg_find_attr_as_uint(req->op.add.message,
384 if (!(instanceType & INSTANCE_TYPE_IS_NC_HEAD)) {
385 /* When we are trying to readd the root basedn then
386 * this is denied, but with an interesting mechanism:
387 * there is generated a referral with the last
388 * component value as hostname. */
389 val = ldb_dn_get_component_val(req->op.add.message->dn,
390 ldb_dn_get_comp_num(req->op.add.message->dn) - 1);
392 return ldb_operr(ldb);
394 value = talloc_asprintf(req, "ldap://%s/%s", val->data,
395 ldb_dn_get_linearized(req->op.add.message->dn));
400 return ldb_module_send_referral(req, value);
404 ac = oc_init_context(module, req);
406 return ldb_operr(ldb);
409 /* If there isn't a parent, just go on to the add processing */
410 if (ldb_dn_get_comp_num(ac->req->op.add.message->dn) == 1) {
411 return objectclass_do_add(ac);
414 /* get copy of parent DN */
415 parent_dn = ldb_dn_get_parent(ac, ac->req->op.add.message->dn);
416 if (parent_dn == NULL) {
420 ret = ldb_build_search_req(&search_req, ldb,
421 ac, parent_dn, LDB_SCOPE_BASE,
422 "(objectClass=*)", parent_attrs,
424 ac, get_search_callback,
426 LDB_REQ_SET_LOCATION(search_req);
427 if (ret != LDB_SUCCESS) {
431 ac->step_fn = objectclass_do_add;
433 return ldb_next_request(ac->module, search_req);
438 check if this is a special RODC nTDSDSA add
440 static bool check_rodc_ntdsdsa_add(struct oc_context *ac,
441 const struct dsdb_class *objectclass)
443 struct ldb_control *rodc_control;
445 if (strcasecmp(objectclass->lDAPDisplayName, "nTDSDSA") != 0) {
448 rodc_control = ldb_request_get_control(ac->req, LDB_CONTROL_RODC_DCPROMO_OID);
453 rodc_control->critical = false;
457 static int objectclass_do_add(struct oc_context *ac)
459 struct ldb_context *ldb;
460 struct ldb_request *add_req;
461 struct ldb_message_element *objectclass_element, *el;
462 struct ldb_message *msg;
464 struct class_list *sorted, *current;
465 const char *rdn_name = NULL;
467 const struct dsdb_class *objectclass;
468 struct ldb_dn *objectcategory;
469 int32_t systemFlags = 0;
472 ldb = ldb_module_get_ctx(ac->module);
474 msg = ldb_msg_copy_shallow(ac, ac->req->op.add.message);
476 /* Check if we have a valid parent - this check is needed since
477 * we don't get a LDB_ERR_NO_SUCH_OBJECT error. */
478 if (ac->search_res == NULL) {
479 unsigned int instanceType;
481 /* An add operation on partition DNs without "NC-add" operation
483 instanceType = ldb_msg_find_attr_as_uint(ac->req->op.add.message,
485 if (!(instanceType & INSTANCE_TYPE_IS_NC_HEAD)) {
486 ldb_asprintf_errstring(ldb, "objectclass: Cannot add %s, parent does not exist!",
487 ldb_dn_get_linearized(msg->dn));
488 return LDB_ERR_NO_SUCH_OBJECT;
491 /* Don't keep any error messages - we've to add a partition */
492 ldb_set_errstring(ldb, NULL);
494 /* Fix up the DN to be in the standard form, taking
495 * particular care to match the parent DN */
496 ret = fix_dn(ldb, msg,
497 ac->req->op.add.message->dn,
498 ac->search_res->message->dn,
500 if (ret != LDB_SUCCESS) {
501 ldb_asprintf_errstring(ldb, "objectclass: Could not munge DN %s into normal form",
502 ldb_dn_get_linearized(ac->req->op.add.message->dn));
507 mem_ctx = talloc_new(ac);
508 if (mem_ctx == NULL) {
512 if (ac->schema != NULL) {
513 objectclass_element = ldb_msg_find_element(msg, "objectClass");
514 if (!objectclass_element) {
515 ldb_asprintf_errstring(ldb, "objectclass: Cannot add %s, no objectclass specified!",
516 ldb_dn_get_linearized(msg->dn));
517 talloc_free(mem_ctx);
518 return LDB_ERR_OBJECT_CLASS_VIOLATION;
521 /* Here we do now get the "objectClass" list from the
523 ret = objectclass_sort(ac->module, ac->schema, mem_ctx,
524 objectclass_element, &sorted);
525 if (ret != LDB_SUCCESS) {
526 talloc_free(mem_ctx);
530 ldb_msg_remove_element(msg, objectclass_element);
532 /* Well, now we shouldn't find any additional "objectClass"
533 * message element (required by the AD specification). */
534 objectclass_element = ldb_msg_find_element(msg, "objectClass");
535 if (objectclass_element != NULL) {
536 ldb_asprintf_errstring(ldb, "objectclass: Cannot add %s, only one 'objectclass' attribute specification is allowed!",
537 ldb_dn_get_linearized(msg->dn));
538 talloc_free(mem_ctx);
539 return LDB_ERR_OBJECT_CLASS_VIOLATION;
542 /* We must completely replace the existing objectClass entry,
543 * because we need it sorted. */
544 ret = ldb_msg_add_empty(msg, "objectClass", 0, NULL);
545 if (ret != LDB_SUCCESS) {
546 talloc_free(mem_ctx);
550 /* Move from the linked list back into an ldb msg */
551 for (current = sorted; current; current = current->next) {
552 value = talloc_strdup(msg, current->objectclass->lDAPDisplayName);
554 talloc_free(mem_ctx);
557 ret = ldb_msg_add_string(msg, "objectClass", value);
558 if (ret != LDB_SUCCESS) {
559 ldb_set_errstring(ldb,
560 "objectclass: could not re-add sorted "
561 "objectclass to modify msg");
562 talloc_free(mem_ctx);
567 talloc_free(mem_ctx);
569 /* Retrive the message again so get_last_structural_class works */
570 objectclass_element = ldb_msg_find_element(msg, "objectClass");
572 /* Make sure its valid to add an object of this type */
573 objectclass = get_last_structural_class(ac->schema,
574 objectclass_element);
575 if(objectclass == NULL) {
576 ldb_asprintf_errstring(ldb,
577 "Failed to find a structural class for %s",
578 ldb_dn_get_linearized(msg->dn));
579 return LDB_ERR_UNWILLING_TO_PERFORM;
582 rdn_name = ldb_dn_get_rdn_name(msg->dn);
583 if (objectclass->rDNAttID
584 && ldb_attr_cmp(rdn_name, objectclass->rDNAttID) != 0) {
585 ldb_asprintf_errstring(ldb,
586 "RDN %s is not correct for most specific structural objectclass %s, should be %s",
587 rdn_name, objectclass->lDAPDisplayName, objectclass->rDNAttID);
588 return LDB_ERR_NAMING_VIOLATION;
591 if (objectclass->systemOnly &&
592 !ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID) &&
593 !check_rodc_ntdsdsa_add(ac, objectclass)) {
594 ldb_asprintf_errstring(ldb, "objectClass %s is systemOnly, rejecting creation of %s",
595 objectclass->lDAPDisplayName, ldb_dn_get_linearized(msg->dn));
596 return LDB_ERR_UNWILLING_TO_PERFORM;
599 if (((strcmp(objectclass->lDAPDisplayName, "secret") == 0) ||
600 (strcmp(objectclass->lDAPDisplayName, "trustedDomain") == 0)) &&
601 !ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID)) {
602 ldb_asprintf_errstring(ldb, "objectClass %s is LSA-specific, rejecting creation of %s",
603 objectclass->lDAPDisplayName, ldb_dn_get_linearized(msg->dn));
604 return LDB_ERR_UNWILLING_TO_PERFORM;
607 if (ac->search_res && ac->search_res->message) {
608 struct ldb_message_element *oc_el
609 = ldb_msg_find_element(ac->search_res->message, "objectClass");
611 bool allowed_class = false;
613 for (i=0; allowed_class == false && oc_el && i < oc_el->num_values; i++) {
614 const struct dsdb_class *sclass;
616 sclass = dsdb_class_by_lDAPDisplayName_ldb_val(ac->schema,
619 /* We don't know this class? what is going on? */
622 for (j=0; sclass->systemPossibleInferiors && sclass->systemPossibleInferiors[j]; j++) {
623 if (ldb_attr_cmp(objectclass->lDAPDisplayName, sclass->systemPossibleInferiors[j]) == 0) {
624 allowed_class = true;
630 if (!allowed_class) {
631 ldb_asprintf_errstring(ldb, "structural objectClass %s is not a valid child class for %s",
632 objectclass->lDAPDisplayName, ldb_dn_get_linearized(ac->search_res->message->dn));
633 return LDB_ERR_NAMING_VIOLATION;
637 objectcategory = ldb_msg_find_attr_as_dn(ldb, ac, msg,
639 if (objectcategory == NULL) {
640 struct dsdb_extended_dn_store_format *dn_format =
641 talloc_get_type(ldb_module_get_private(ac->module),
642 struct dsdb_extended_dn_store_format);
643 if (dn_format && dn_format->store_extended_dn_in_ldb == false) {
644 /* Strip off extended components */
645 struct ldb_dn *dn = ldb_dn_new(ac, ldb,
646 objectclass->defaultObjectCategory);
647 value = ldb_dn_alloc_linearized(msg, dn);
650 value = talloc_strdup(msg,
651 objectclass->defaultObjectCategory);
657 ret = ldb_msg_add_string(msg, "objectCategory", value);
658 if (ret != LDB_SUCCESS) {
662 const struct dsdb_class *ocClass =
663 dsdb_class_by_cn_ldb_val(ac->schema,
664 ldb_dn_get_rdn_val(objectcategory));
665 if (ocClass != NULL) {
666 struct ldb_dn *dn = ldb_dn_new(ac, ldb,
667 ocClass->defaultObjectCategory);
668 if (ldb_dn_compare(objectcategory, dn) != 0) {
672 talloc_free(objectcategory);
673 if (ocClass == NULL) {
674 ldb_asprintf_errstring(ldb, "objectclass: Cannot add %s, 'objectCategory' attribute invalid!",
675 ldb_dn_get_linearized(msg->dn));
676 return LDB_ERR_OBJECT_CLASS_VIOLATION;
680 if (!ldb_msg_find_element(msg, "showInAdvancedViewOnly") && (objectclass->defaultHidingValue == true)) {
681 ldb_msg_add_string(msg, "showInAdvancedViewOnly",
685 /* There are very special rules for systemFlags, see MS-ADTS
686 * MS-ADTS 3.1.1.5.2.4 */
688 el = ldb_msg_find_element(msg, "systemFlags");
689 if ((el != NULL) && (el->num_values > 1)) {
690 ldb_asprintf_errstring(ldb, "objectclass: Cannot add %s, 'systemFlags' attribute multivalued!",
691 ldb_dn_get_linearized(msg->dn));
692 return LDB_ERR_CONSTRAINT_VIOLATION;
695 systemFlags = ldb_msg_find_attr_as_int(msg, "systemFlags", 0);
697 ldb_msg_remove_attr(msg, "systemFlags");
699 /* Only the following flags may be set by a client */
700 if (ldb_request_get_control(ac->req,
701 LDB_CONTROL_RELAX_OID) == NULL) {
702 systemFlags &= ( SYSTEM_FLAG_CONFIG_ALLOW_RENAME
703 | SYSTEM_FLAG_CONFIG_ALLOW_MOVE
704 | SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE
705 | SYSTEM_FLAG_ATTR_IS_RDN );
708 /* But the last one ("ATTR_IS_RDN") is only allowed on
709 * "attributeSchema" objects. So truncate if it does not fit. */
710 if (ldb_attr_cmp(objectclass->lDAPDisplayName, "attributeSchema") != 0) {
711 systemFlags &= ~SYSTEM_FLAG_ATTR_IS_RDN;
714 if (ldb_attr_cmp(objectclass->lDAPDisplayName, "server") == 0) {
715 systemFlags |= (int32_t)(SYSTEM_FLAG_DISALLOW_MOVE_ON_DELETE | SYSTEM_FLAG_CONFIG_ALLOW_RENAME | SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE);
716 } else if (ldb_attr_cmp(objectclass->lDAPDisplayName, "site") == 0
717 || ldb_attr_cmp(objectclass->lDAPDisplayName, "serversContainer") == 0
718 || ldb_attr_cmp(objectclass->lDAPDisplayName, "nTDSDSA") == 0) {
719 systemFlags |= (int32_t)(SYSTEM_FLAG_DISALLOW_MOVE_ON_DELETE);
721 } else if (ldb_attr_cmp(objectclass->lDAPDisplayName, "siteLink") == 0
722 || ldb_attr_cmp(objectclass->lDAPDisplayName, "siteLinkBridge") == 0
723 || ldb_attr_cmp(objectclass->lDAPDisplayName, "nTDSConnection") == 0) {
724 systemFlags |= (int32_t)(SYSTEM_FLAG_CONFIG_ALLOW_RENAME);
727 /* TODO: If parent object is site or subnet, also add (SYSTEM_FLAG_CONFIG_ALLOW_RENAME) */
729 if (el || systemFlags != 0) {
730 ret = samdb_msg_add_int(ldb, msg, msg, "systemFlags",
732 if (ret != LDB_SUCCESS) {
738 ret = ldb_msg_sanity_check(ldb, msg);
739 if (ret != LDB_SUCCESS) {
743 ret = ldb_build_add_req(&add_req, ldb, ac,
748 LDB_REQ_SET_LOCATION(add_req);
749 if (ret != LDB_SUCCESS) {
753 /* perform the add */
754 return ldb_next_request(ac->module, add_req);
757 static int oc_modify_callback(struct ldb_request *req,
758 struct ldb_reply *ares);
759 static int objectclass_do_mod(struct oc_context *ac);
761 static int objectclass_modify(struct ldb_module *module, struct ldb_request *req)
763 struct ldb_context *ldb = ldb_module_get_ctx(module);
764 struct ldb_message_element *objectclass_element;
765 struct ldb_message *msg;
766 struct ldb_request *down_req;
767 struct oc_context *ac;
768 bool oc_changes = false;
771 ldb_debug(ldb, LDB_DEBUG_TRACE, "objectclass_modify\n");
773 /* do not manipulate our control entries */
774 if (ldb_dn_is_special(req->op.mod.message->dn)) {
775 return ldb_next_request(module, req);
778 /* As with the "real" AD we don't accept empty messages */
779 if (req->op.mod.message->num_elements == 0) {
780 ldb_set_errstring(ldb, "objectclass: modify message must have "
781 "elements/attributes!");
782 return LDB_ERR_UNWILLING_TO_PERFORM;
785 ac = oc_init_context(module, req);
787 return ldb_operr(ldb);
790 /* Without schema, there isn't much to do here */
791 if (ac->schema == NULL) {
793 return ldb_next_request(module, req);
796 msg = ldb_msg_copy_shallow(ac, req->op.mod.message);
798 return ldb_operr(ldb);
801 /* For now change everything except the objectclasses */
803 objectclass_element = ldb_msg_find_element(msg, "objectClass");
804 if (objectclass_element != NULL) {
805 ldb_msg_remove_attr(msg, "objectClass");
809 ret = ldb_build_mod_req(&down_req, ldb, ac,
812 oc_changes ? oc_modify_callback : oc_op_callback,
814 LDB_REQ_SET_LOCATION(down_req);
815 if (ret != LDB_SUCCESS) {
819 return ldb_next_request(module, down_req);
822 static int oc_modify_callback(struct ldb_request *req, struct ldb_reply *ares)
824 static const char * const attrs[] = { "objectClass", NULL };
825 struct ldb_context *ldb;
826 struct ldb_request *search_req;
827 struct oc_context *ac;
830 ac = talloc_get_type(req->context, struct oc_context);
831 ldb = ldb_module_get_ctx(ac->module);
834 return ldb_module_done(ac->req, NULL, NULL,
835 LDB_ERR_OPERATIONS_ERROR);
838 if (ares->type == LDB_REPLY_REFERRAL) {
839 return ldb_module_send_referral(ac->req, ares->referral);
842 if (ares->error != LDB_SUCCESS) {
843 return ldb_module_done(ac->req, ares->controls,
844 ares->response, ares->error);
847 if (ares->type != LDB_REPLY_DONE) {
849 return ldb_module_done(ac->req, NULL, NULL,
850 LDB_ERR_OPERATIONS_ERROR);
855 /* this looks up the real existing object for fetching some important
856 * informations (objectclasses) */
857 ret = ldb_build_search_req(&search_req, ldb,
858 ac, ac->req->op.mod.message->dn,
862 ac, get_search_callback,
864 LDB_REQ_SET_LOCATION(search_req);
865 if (ret != LDB_SUCCESS) {
866 return ldb_module_done(ac->req, NULL, NULL, ret);
869 ac->step_fn = objectclass_do_mod;
871 ret = ldb_next_request(ac->module, search_req);
872 if (ret != LDB_SUCCESS) {
873 return ldb_module_done(ac->req, NULL, NULL, ret);
879 static int objectclass_do_mod(struct oc_context *ac)
881 struct ldb_context *ldb;
882 struct ldb_request *mod_req;
884 struct ldb_message_element *oc_el_entry, *oc_el_change;
885 struct ldb_val *vals;
886 struct ldb_message *msg;
888 struct class_list *sorted, *current;
889 const struct dsdb_class *objectclass;
891 bool found, replace = false;
894 ldb = ldb_module_get_ctx(ac->module);
896 /* we should always have a valid entry when we enter here */
897 if (ac->search_res == NULL) {
898 return ldb_operr(ldb);
901 oc_el_entry = ldb_msg_find_element(ac->search_res->message,
903 if (oc_el_entry == NULL) {
904 /* existing entry without a valid object class? */
905 return ldb_operr(ldb);
908 oc_el_change = ldb_msg_find_element(ac->req->op.mod.message,
910 if (oc_el_change == NULL) {
911 /* we should have an objectclass change operation */
912 return ldb_operr(ldb);
915 /* use a new message structure */
916 msg = ldb_msg_new(ac);
921 msg->dn = ac->req->op.mod.message->dn;
923 mem_ctx = talloc_new(ac);
924 if (mem_ctx == NULL) {
928 switch (oc_el_change->flags & LDB_FLAG_MOD_MASK) {
929 case LDB_FLAG_MOD_ADD:
930 /* Merge the two message elements */
931 for (i = 0; i < oc_el_change->num_values; i++) {
932 for (j = 0; j < oc_el_entry->num_values; j++) {
933 if (strcasecmp((char *)oc_el_change->values[i].data,
934 (char *)oc_el_entry->values[j].data) == 0) {
935 /* we cannot add an already existing object class */
936 talloc_free(mem_ctx);
937 return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
940 /* append the new object class value - code was copied
941 * from "ldb_msg_add_value" */
942 vals = talloc_realloc(oc_el_entry, oc_el_entry->values,
944 oc_el_entry->num_values + 1);
946 talloc_free(mem_ctx);
949 oc_el_entry->values = vals;
950 oc_el_entry->values[oc_el_entry->num_values] =
951 oc_el_change->values[i];
952 ++(oc_el_entry->num_values);
955 objectclass = get_last_structural_class(ac->schema,
957 if (objectclass != NULL) {
958 /* we cannot add a new structural object class */
959 talloc_free(mem_ctx);
960 return LDB_ERR_OBJECT_CLASS_VIOLATION;
963 /* Now do the sorting */
964 ret = objectclass_sort(ac->module, ac->schema, mem_ctx,
965 oc_el_entry, &sorted);
966 if (ret != LDB_SUCCESS) {
967 talloc_free(mem_ctx);
973 case LDB_FLAG_MOD_REPLACE:
974 /* Do the sorting for the change message element */
975 ret = objectclass_sort(ac->module, ac->schema, mem_ctx,
976 oc_el_change, &sorted);
977 if (ret != LDB_SUCCESS) {
978 talloc_free(mem_ctx);
982 /* this is a replace */
987 case LDB_FLAG_MOD_DELETE:
988 /* get the actual top-most structural objectclass */
989 objectclass = get_last_structural_class(ac->schema,
991 if (objectclass == NULL) {
992 talloc_free(mem_ctx);
993 return ldb_operr(ldb);
996 /* Merge the two message elements */
997 for (i = 0; i < oc_el_change->num_values; i++) {
999 for (j = 0; j < oc_el_entry->num_values; j++) {
1000 if (strcasecmp((char *)oc_el_change->values[i].data,
1001 (char *)oc_el_entry->values[j].data) == 0) {
1003 /* delete the object class value -
1004 * code was copied from
1005 * "ldb_msg_remove_element" */
1006 if (j != oc_el_entry->num_values - 1) {
1007 memmove(&oc_el_entry->values[j],
1008 &oc_el_entry->values[j+1],
1009 ((oc_el_entry->num_values-1) - j)*sizeof(struct ldb_val));
1011 --(oc_el_entry->num_values);
1016 /* we cannot delete a not existing object class */
1017 ldb_asprintf_errstring(ldb, "Cannot delete this %.*s ",
1018 (int)oc_el_change->values[i].length, (const char *)oc_el_change->values[i].data);
1020 talloc_free(mem_ctx);
1021 return LDB_ERR_NO_SUCH_ATTRIBUTE;
1025 /* Make sure that the top-most structural objectclass wasn't
1028 for (i = 0; i < oc_el_entry->num_values; i++) {
1029 if (strcasecmp(objectclass->lDAPDisplayName,
1030 (char *)oc_el_entry->values[i].data) == 0) {
1031 found = true; break;
1035 talloc_free(mem_ctx);
1036 return LDB_ERR_OBJECT_CLASS_VIOLATION;
1040 /* Now do the sorting */
1041 ret = objectclass_sort(ac->module, ac->schema, mem_ctx,
1042 oc_el_entry, &sorted);
1043 if (ret != LDB_SUCCESS) {
1044 talloc_free(mem_ctx);
1051 ret = ldb_msg_add_empty(msg, "objectClass",
1052 LDB_FLAG_MOD_REPLACE, &oc_el_change);
1053 if (ret != LDB_SUCCESS) {
1055 talloc_free(mem_ctx);
1059 /* Move from the linked list back into an ldb msg */
1060 for (current = sorted; current; current = current->next) {
1061 value = talloc_strdup(msg,
1062 current->objectclass->lDAPDisplayName);
1063 if (value == NULL) {
1064 talloc_free(mem_ctx);
1065 return ldb_oom(ldb);
1067 ret = ldb_msg_add_string(msg, "objectClass", value);
1068 if (ret != LDB_SUCCESS) {
1069 ldb_set_errstring(ldb, "objectclass: could not re-add sorted objectclass to modify msg");
1070 talloc_free(mem_ctx);
1075 talloc_free(mem_ctx);
1078 /* Well, on replace we are nearly done: we have to test if
1079 * the change and entry message element are identically. We
1080 * can use "ldb_msg_element_compare" since now the specified
1081 * objectclasses match for sure in case. */
1082 ret = ldb_msg_element_compare(oc_el_entry, oc_el_change);
1084 ret = ldb_msg_element_compare(oc_el_change,
1088 /* they are the same so we are done in this case */
1089 return ldb_module_done(ac->req, NULL, NULL,
1092 /* they're not exactly the same */
1093 return LDB_ERR_OBJECT_CLASS_VIOLATION;
1097 /* in the other cases we have the real change left to do */
1099 ret = ldb_msg_sanity_check(ldb, msg);
1100 if (ret != LDB_SUCCESS) {
1104 ret = ldb_build_mod_req(&mod_req, ldb, ac,
1109 LDB_REQ_SET_LOCATION(mod_req);
1110 if (ret != LDB_SUCCESS) {
1114 return ldb_next_request(ac->module, mod_req);
1117 static int objectclass_do_rename(struct oc_context *ac);
1119 static int objectclass_rename(struct ldb_module *module, struct ldb_request *req)
1121 static const char * const attrs[] = { "objectClass", NULL };
1122 struct ldb_context *ldb;
1123 struct ldb_request *search_req;
1124 struct oc_context *ac;
1125 struct ldb_dn *parent_dn;
1128 ldb = ldb_module_get_ctx(module);
1130 ldb_debug(ldb, LDB_DEBUG_TRACE, "objectclass_rename\n");
1132 /* do not manipulate our control entries */
1133 if (ldb_dn_is_special(req->op.rename.newdn)) {
1134 return ldb_next_request(module, req);
1137 ac = oc_init_context(module, req);
1139 return ldb_operr(ldb);
1142 parent_dn = ldb_dn_get_parent(ac, req->op.rename.newdn);
1143 if (parent_dn == NULL) {
1144 ldb_asprintf_errstring(ldb, "objectclass: Cannot rename %s, the parent DN does not exist!",
1145 ldb_dn_get_linearized(req->op.rename.olddn));
1146 return LDB_ERR_NO_SUCH_OBJECT;
1149 /* this looks up the parent object for fetching some important
1150 * informations (objectclasses, DN normalisation...) */
1151 ret = ldb_build_search_req(&search_req, ldb,
1152 ac, parent_dn, LDB_SCOPE_BASE,
1155 ac, get_search_callback,
1157 LDB_REQ_SET_LOCATION(search_req);
1158 if (ret != LDB_SUCCESS) {
1162 /* we have to add the show recycled control, as otherwise DRS
1163 deletes will be refused as we will think the target parent
1165 ret = ldb_request_add_control(search_req, LDB_CONTROL_SHOW_RECYCLED_OID,
1168 if (ret != LDB_SUCCESS) {
1172 ac->step_fn = objectclass_do_rename;
1174 return ldb_next_request(ac->module, search_req);
1177 static int objectclass_do_rename2(struct oc_context *ac);
1179 static int objectclass_do_rename(struct oc_context *ac)
1181 static const char * const attrs[] = { "objectClass", NULL };
1182 struct ldb_context *ldb;
1183 struct ldb_request *search_req;
1186 ldb = ldb_module_get_ctx(ac->module);
1188 /* Check if we have a valid parent - this check is needed since
1189 * we don't get a LDB_ERR_NO_SUCH_OBJECT error. */
1190 if (ac->search_res == NULL) {
1191 ldb_asprintf_errstring(ldb, "objectclass: Cannot rename %s, parent does not exist!",
1192 ldb_dn_get_linearized(ac->req->op.rename.olddn));
1193 return LDB_ERR_OTHER;
1196 /* now assign "search_res2" to the parent entry to have "search_res"
1197 * free for another lookup */
1198 ac->search_res2 = ac->search_res;
1199 ac->search_res = NULL;
1201 /* this looks up the real existing object for fetching some important
1202 * informations (objectclasses) */
1203 ret = ldb_build_search_req(&search_req, ldb,
1204 ac, ac->req->op.rename.olddn,
1208 ac, get_search_callback,
1210 LDB_REQ_SET_LOCATION(search_req);
1211 if (ret != LDB_SUCCESS) {
1215 ac->step_fn = objectclass_do_rename2;
1217 return ldb_next_request(ac->module, search_req);
1220 static int objectclass_do_rename2(struct oc_context *ac)
1222 struct ldb_context *ldb;
1223 struct ldb_request *rename_req;
1224 struct ldb_dn *fixed_dn;
1227 ldb = ldb_module_get_ctx(ac->module);
1229 /* Check if we have a valid entry - this check is needed since
1230 * we don't get a LDB_ERR_NO_SUCH_OBJECT error. */
1231 if (ac->search_res == NULL) {
1232 ldb_asprintf_errstring(ldb, "objectclass: Cannot rename %s, entry does not exist!",
1233 ldb_dn_get_linearized(ac->req->op.rename.olddn));
1234 return LDB_ERR_NO_SUCH_OBJECT;
1237 if (ac->schema != NULL) {
1238 struct ldb_message_element *oc_el_entry, *oc_el_parent;
1239 const struct dsdb_class *objectclass;
1240 const char *rdn_name;
1241 bool allowed_class = false;
1244 oc_el_entry = ldb_msg_find_element(ac->search_res->message,
1246 if (oc_el_entry == NULL) {
1247 /* existing entry without a valid object class? */
1248 return ldb_operr(ldb);
1250 objectclass = get_last_structural_class(ac->schema, oc_el_entry);
1251 if (objectclass == NULL) {
1252 /* existing entry without a valid object class? */
1253 return ldb_operr(ldb);
1256 rdn_name = ldb_dn_get_rdn_name(ac->req->op.rename.newdn);
1257 if ((objectclass->rDNAttID != NULL) &&
1258 (ldb_attr_cmp(rdn_name, objectclass->rDNAttID) != 0)) {
1259 ldb_asprintf_errstring(ldb,
1260 "objectclass: RDN %s is not correct for most specific structural objectclass %s, should be %s",
1262 objectclass->lDAPDisplayName,
1263 objectclass->rDNAttID);
1264 return LDB_ERR_UNWILLING_TO_PERFORM;
1267 oc_el_parent = ldb_msg_find_element(ac->search_res2->message,
1269 if (oc_el_parent == NULL) {
1270 /* existing entry without a valid object class? */
1271 return ldb_operr(ldb);
1274 for (i=0; allowed_class == false && i < oc_el_parent->num_values; i++) {
1275 const struct dsdb_class *sclass;
1277 sclass = dsdb_class_by_lDAPDisplayName_ldb_val(ac->schema,
1278 &oc_el_parent->values[i]);
1280 /* We don't know this class? what is going on? */
1283 for (j=0; sclass->systemPossibleInferiors && sclass->systemPossibleInferiors[j]; j++) {
1284 if (ldb_attr_cmp(objectclass->lDAPDisplayName, sclass->systemPossibleInferiors[j]) == 0) {
1285 allowed_class = true;
1291 if (!allowed_class) {
1292 ldb_asprintf_errstring(ldb,
1293 "objectclass: structural objectClass %s is not a valid child class for %s",
1294 objectclass->lDAPDisplayName, ldb_dn_get_linearized(ac->search_res2->message->dn));
1295 return LDB_ERR_NAMING_VIOLATION;
1299 /* Ensure we are not trying to rename it to be a child of itself */
1300 if ((ldb_dn_compare_base(ac->req->op.rename.olddn,
1301 ac->req->op.rename.newdn) == 0) &&
1302 (ldb_dn_compare(ac->req->op.rename.olddn,
1303 ac->req->op.rename.newdn) != 0)) {
1304 ldb_asprintf_errstring(ldb, "objectclass: Cannot rename %s to be a child of itself",
1305 ldb_dn_get_linearized(ac->req->op.rename.olddn));
1306 return LDB_ERR_UNWILLING_TO_PERFORM;
1309 /* Fix up the DN to be in the standard form, taking
1310 * particular care to match the parent DN */
1311 ret = fix_dn(ldb, ac,
1312 ac->req->op.rename.newdn,
1313 ac->search_res2->message->dn,
1315 if (ret != LDB_SUCCESS) {
1316 ldb_asprintf_errstring(ldb, "objectclass: Could not munge DN %s into normal form",
1317 ldb_dn_get_linearized(ac->req->op.rename.newdn));
1322 ret = ldb_build_rename_req(&rename_req, ldb, ac,
1323 ac->req->op.rename.olddn, fixed_dn,
1327 LDB_REQ_SET_LOCATION(rename_req);
1328 if (ret != LDB_SUCCESS) {
1332 /* perform the rename */
1333 return ldb_next_request(ac->module, rename_req);
1336 static int objectclass_do_delete(struct oc_context *ac);
1338 static int objectclass_delete(struct ldb_module *module, struct ldb_request *req)
1340 static const char * const attrs[] = { "nCName", "objectClass",
1341 "systemFlags", NULL };
1342 struct ldb_context *ldb;
1343 struct ldb_request *search_req;
1344 struct oc_context *ac;
1347 ldb = ldb_module_get_ctx(module);
1349 ldb_debug(ldb, LDB_DEBUG_TRACE, "objectclass_delete\n");
1351 /* do not manipulate our control entries */
1352 if (ldb_dn_is_special(req->op.del.dn)) {
1353 return ldb_next_request(module, req);
1356 /* Bypass the constraint checks when we do have the "RELAX" control
1358 if (ldb_request_get_control(req, LDB_CONTROL_RELAX_OID) != NULL) {
1359 return ldb_next_request(module, req);
1362 ac = oc_init_context(module, req);
1364 return ldb_operr(ldb);
1367 /* this looks up the entry object for fetching some important
1368 * informations (object classes, system flags...) */
1369 ret = ldb_build_search_req(&search_req, ldb,
1370 ac, req->op.del.dn, LDB_SCOPE_BASE,
1373 ac, get_search_callback,
1375 LDB_REQ_SET_LOCATION(search_req);
1376 if (ret != LDB_SUCCESS) {
1380 ac->step_fn = objectclass_do_delete;
1382 return ldb_next_request(ac->module, search_req);
1385 static int objectclass_do_delete(struct oc_context *ac)
1387 struct ldb_context *ldb;
1389 int32_t systemFlags;
1392 ldb = ldb_module_get_ctx(ac->module);
1394 /* Check if we have a valid entry - this check is needed since
1395 * we don't get a LDB_ERR_NO_SUCH_OBJECT error. */
1396 if (ac->search_res == NULL) {
1397 ldb_asprintf_errstring(ldb, "objectclass: Cannot delete %s, entry does not exist!",
1398 ldb_dn_get_linearized(ac->req->op.del.dn));
1399 return LDB_ERR_NO_SUCH_OBJECT;
1402 /* DC's ntDSDSA object */
1403 if (ldb_dn_compare(ac->req->op.del.dn, samdb_ntds_settings_dn(ldb)) == 0) {
1404 ldb_asprintf_errstring(ldb, "objectclass: Cannot delete %s, it's the DC's ntDSDSA object!",
1405 ldb_dn_get_linearized(ac->req->op.del.dn));
1406 return LDB_ERR_UNWILLING_TO_PERFORM;
1409 /* DC's rIDSet object */
1410 /* Perform this check only when it does exist - this is needed in order
1411 * to don't let existing provisions break. */
1412 ret = samdb_rid_set_dn(ldb, ac, &dn);
1413 if ((ret != LDB_SUCCESS) && (ret != LDB_ERR_NO_SUCH_OBJECT)) {
1416 if (ret == LDB_SUCCESS) {
1417 if (ldb_dn_compare(ac->req->op.del.dn, dn) == 0) {
1419 ldb_asprintf_errstring(ldb, "objectclass: Cannot delete %s, it's the DC's rIDSet object!",
1420 ldb_dn_get_linearized(ac->req->op.del.dn));
1421 return LDB_ERR_UNWILLING_TO_PERFORM;
1426 /* crossRef objects regarding config, schema and default domain NCs */
1427 if (samdb_find_attribute(ldb, ac->search_res->message, "objectClass",
1428 "crossRef") != NULL) {
1429 dn = ldb_msg_find_attr_as_dn(ldb, ac, ac->search_res->message,
1431 if ((ldb_dn_compare(dn, ldb_get_default_basedn(ldb)) == 0) ||
1432 (ldb_dn_compare(dn, ldb_get_config_basedn(ldb)) == 0)) {
1435 ldb_asprintf_errstring(ldb, "objectclass: Cannot delete %s, it's a crossRef object to the main or configuration partition!",
1436 ldb_dn_get_linearized(ac->req->op.del.dn));
1437 return LDB_ERR_NOT_ALLOWED_ON_NON_LEAF;
1439 if (ldb_dn_compare(dn, ldb_get_schema_basedn(ldb)) == 0) {
1442 ldb_asprintf_errstring(ldb, "objectclass: Cannot delete %s, it's a crossRef object to the schema partition!",
1443 ldb_dn_get_linearized(ac->req->op.del.dn));
1444 return LDB_ERR_UNWILLING_TO_PERFORM;
1451 systemFlags = ldb_msg_find_attr_as_int(ac->search_res->message,
1453 if ((systemFlags & SYSTEM_FLAG_DISALLOW_DELETE) != 0) {
1454 ldb_asprintf_errstring(ldb, "objectclass: Cannot delete %s, it isn't permitted!",
1455 ldb_dn_get_linearized(ac->req->op.del.dn));
1456 return LDB_ERR_UNWILLING_TO_PERFORM;
1459 return ldb_next_request(ac->module, ac->req);
1462 static int objectclass_init(struct ldb_module *module)
1464 struct ldb_context *ldb = ldb_module_get_ctx(module);
1467 /* Init everything else */
1468 ret = ldb_next_init(module);
1469 if (ret != LDB_SUCCESS) {
1473 /* Look for the opaque to indicate we might have to cut down the DN of defaultObjectCategory */
1474 ldb_module_set_private(module, ldb_get_opaque(ldb, DSDB_EXTENDED_DN_STORE_FORMAT_OPAQUE_NAME));
1479 _PUBLIC_ const struct ldb_module_ops ldb_objectclass_module_ops = {
1480 .name = "objectclass",
1481 .add = objectclass_add,
1482 .modify = objectclass_modify,
1483 .rename = objectclass_rename,
1484 .del = objectclass_delete,
1485 .init_context = objectclass_init