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 if (ret != LDB_SUCCESS) {
430 ac->step_fn = objectclass_do_add;
432 return ldb_next_request(ac->module, search_req);
437 check if this is a special RODC nTDSDSA add
439 static bool check_rodc_ntdsdsa_add(struct oc_context *ac,
440 const struct dsdb_class *objectclass)
442 struct ldb_control *rodc_control;
444 if (strcasecmp(objectclass->lDAPDisplayName, "nTDSDSA") != 0) {
447 rodc_control = ldb_request_get_control(ac->req, LDB_CONTROL_RODC_DCPROMO_OID);
452 rodc_control->critical = false;
456 static int objectclass_do_add(struct oc_context *ac)
458 struct ldb_context *ldb;
459 struct ldb_request *add_req;
460 struct ldb_message_element *objectclass_element, *el;
461 struct ldb_message *msg;
463 struct class_list *sorted, *current;
464 const char *rdn_name = NULL;
466 const struct dsdb_class *objectclass;
467 struct ldb_dn *objectcategory;
468 int32_t systemFlags = 0;
471 ldb = ldb_module_get_ctx(ac->module);
473 msg = ldb_msg_copy_shallow(ac, ac->req->op.add.message);
475 /* Check if we have a valid parent - this check is needed since
476 * we don't get a LDB_ERR_NO_SUCH_OBJECT error. */
477 if (ac->search_res == NULL) {
478 unsigned int instanceType;
480 /* An add operation on partition DNs without "NC-add" operation
482 instanceType = ldb_msg_find_attr_as_uint(ac->req->op.add.message,
484 if (!(instanceType & INSTANCE_TYPE_IS_NC_HEAD)) {
485 ldb_asprintf_errstring(ldb, "objectclass: Cannot add %s, parent does not exist!",
486 ldb_dn_get_linearized(msg->dn));
487 return LDB_ERR_NO_SUCH_OBJECT;
490 /* Don't keep any error messages - we've to add a partition */
491 ldb_set_errstring(ldb, NULL);
493 /* Fix up the DN to be in the standard form, taking
494 * particular care to match the parent DN */
495 ret = fix_dn(ldb, msg,
496 ac->req->op.add.message->dn,
497 ac->search_res->message->dn,
499 if (ret != LDB_SUCCESS) {
500 ldb_asprintf_errstring(ldb, "objectclass: Could not munge DN %s into normal form",
501 ldb_dn_get_linearized(ac->req->op.add.message->dn));
506 mem_ctx = talloc_new(ac);
507 if (mem_ctx == NULL) {
511 if (ac->schema != NULL) {
512 objectclass_element = ldb_msg_find_element(msg, "objectClass");
513 if (!objectclass_element) {
514 ldb_asprintf_errstring(ldb, "objectclass: Cannot add %s, no objectclass specified!",
515 ldb_dn_get_linearized(msg->dn));
516 talloc_free(mem_ctx);
517 return LDB_ERR_OBJECT_CLASS_VIOLATION;
520 /* Here we do now get the "objectClass" list from the
522 ret = objectclass_sort(ac->module, ac->schema, mem_ctx,
523 objectclass_element, &sorted);
524 if (ret != LDB_SUCCESS) {
525 talloc_free(mem_ctx);
529 ldb_msg_remove_element(msg, objectclass_element);
531 /* Well, now we shouldn't find any additional "objectClass"
532 * message element (required by the AD specification). */
533 objectclass_element = ldb_msg_find_element(msg, "objectClass");
534 if (objectclass_element != NULL) {
535 ldb_asprintf_errstring(ldb, "objectclass: Cannot add %s, only one 'objectclass' attribute specification is allowed!",
536 ldb_dn_get_linearized(msg->dn));
537 talloc_free(mem_ctx);
538 return LDB_ERR_OBJECT_CLASS_VIOLATION;
541 /* We must completely replace the existing objectClass entry,
542 * because we need it sorted. */
543 ret = ldb_msg_add_empty(msg, "objectClass", 0, NULL);
544 if (ret != LDB_SUCCESS) {
545 talloc_free(mem_ctx);
549 /* Move from the linked list back into an ldb msg */
550 for (current = sorted; current; current = current->next) {
551 value = talloc_strdup(msg, current->objectclass->lDAPDisplayName);
553 talloc_free(mem_ctx);
556 ret = ldb_msg_add_string(msg, "objectClass", value);
557 if (ret != LDB_SUCCESS) {
558 ldb_set_errstring(ldb,
559 "objectclass: could not re-add sorted "
560 "objectclass to modify msg");
561 talloc_free(mem_ctx);
566 talloc_free(mem_ctx);
568 /* Retrive the message again so get_last_structural_class works */
569 objectclass_element = ldb_msg_find_element(msg, "objectClass");
571 /* Make sure its valid to add an object of this type */
572 objectclass = get_last_structural_class(ac->schema,
573 objectclass_element);
574 if(objectclass == NULL) {
575 ldb_asprintf_errstring(ldb,
576 "Failed to find a structural class for %s",
577 ldb_dn_get_linearized(msg->dn));
578 return LDB_ERR_UNWILLING_TO_PERFORM;
581 rdn_name = ldb_dn_get_rdn_name(msg->dn);
582 if (objectclass->rDNAttID
583 && ldb_attr_cmp(rdn_name, objectclass->rDNAttID) != 0) {
584 ldb_asprintf_errstring(ldb,
585 "RDN %s is not correct for most specific structural objectclass %s, should be %s",
586 rdn_name, objectclass->lDAPDisplayName, objectclass->rDNAttID);
587 return LDB_ERR_NAMING_VIOLATION;
590 if (objectclass->systemOnly &&
591 !ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID) &&
592 !check_rodc_ntdsdsa_add(ac, objectclass)) {
593 ldb_asprintf_errstring(ldb, "objectClass %s is systemOnly, rejecting creation of %s",
594 objectclass->lDAPDisplayName, ldb_dn_get_linearized(msg->dn));
595 return LDB_ERR_UNWILLING_TO_PERFORM;
598 if (((strcmp(objectclass->lDAPDisplayName, "secret") == 0) ||
599 (strcmp(objectclass->lDAPDisplayName, "trustedDomain") == 0)) &&
600 !ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID)) {
601 ldb_asprintf_errstring(ldb, "objectClass %s is LSA-specific, rejecting creation of %s",
602 objectclass->lDAPDisplayName, ldb_dn_get_linearized(msg->dn));
603 return LDB_ERR_UNWILLING_TO_PERFORM;
606 if (ac->search_res && ac->search_res->message) {
607 struct ldb_message_element *oc_el
608 = ldb_msg_find_element(ac->search_res->message, "objectClass");
610 bool allowed_class = false;
612 for (i=0; allowed_class == false && oc_el && i < oc_el->num_values; i++) {
613 const struct dsdb_class *sclass;
615 sclass = dsdb_class_by_lDAPDisplayName_ldb_val(ac->schema,
618 /* We don't know this class? what is going on? */
621 for (j=0; sclass->systemPossibleInferiors && sclass->systemPossibleInferiors[j]; j++) {
622 if (ldb_attr_cmp(objectclass->lDAPDisplayName, sclass->systemPossibleInferiors[j]) == 0) {
623 allowed_class = true;
629 if (!allowed_class) {
630 ldb_asprintf_errstring(ldb, "structural objectClass %s is not a valid child class for %s",
631 objectclass->lDAPDisplayName, ldb_dn_get_linearized(ac->search_res->message->dn));
632 return LDB_ERR_NAMING_VIOLATION;
636 objectcategory = ldb_msg_find_attr_as_dn(ldb, ac, msg,
638 if (objectcategory == NULL) {
639 struct dsdb_extended_dn_store_format *dn_format =
640 talloc_get_type(ldb_module_get_private(ac->module),
641 struct dsdb_extended_dn_store_format);
642 if (dn_format && dn_format->store_extended_dn_in_ldb == false) {
643 /* Strip off extended components */
644 struct ldb_dn *dn = ldb_dn_new(ac, ldb,
645 objectclass->defaultObjectCategory);
646 value = ldb_dn_alloc_linearized(msg, dn);
649 value = talloc_strdup(msg,
650 objectclass->defaultObjectCategory);
656 ret = ldb_msg_add_string(msg, "objectCategory", value);
657 if (ret != LDB_SUCCESS) {
661 const struct dsdb_class *ocClass =
662 dsdb_class_by_cn_ldb_val(ac->schema,
663 ldb_dn_get_rdn_val(objectcategory));
664 if (ocClass != NULL) {
665 struct ldb_dn *dn = ldb_dn_new(ac, ldb,
666 ocClass->defaultObjectCategory);
667 if (ldb_dn_compare(objectcategory, dn) != 0) {
671 talloc_free(objectcategory);
672 if (ocClass == NULL) {
673 ldb_asprintf_errstring(ldb, "objectclass: Cannot add %s, 'objectCategory' attribute invalid!",
674 ldb_dn_get_linearized(msg->dn));
675 return LDB_ERR_OBJECT_CLASS_VIOLATION;
679 if (!ldb_msg_find_element(msg, "showInAdvancedViewOnly") && (objectclass->defaultHidingValue == true)) {
680 ldb_msg_add_string(msg, "showInAdvancedViewOnly",
684 /* There are very special rules for systemFlags, see MS-ADTS
685 * MS-ADTS 3.1.1.5.2.4 */
687 el = ldb_msg_find_element(msg, "systemFlags");
688 if ((el != NULL) && (el->num_values > 1)) {
689 ldb_asprintf_errstring(ldb, "objectclass: Cannot add %s, 'systemFlags' attribute multivalued!",
690 ldb_dn_get_linearized(msg->dn));
691 return LDB_ERR_CONSTRAINT_VIOLATION;
694 systemFlags = ldb_msg_find_attr_as_int(msg, "systemFlags", 0);
696 ldb_msg_remove_attr(msg, "systemFlags");
698 /* Only these flags may be set by a client, but we can't tell
699 * between a client and our provision at this point
700 * systemFlags &= ( SYSTEM_FLAG_CONFIG_ALLOW_RENAME | SYSTEM_FLAG_CONFIG_ALLOW_MOVE | SYSTEM_FLAG_CONFIG_LIMITED_MOVE);
703 /* This flag is only allowed on attributeSchema objects */
704 if (ldb_attr_cmp(objectclass->lDAPDisplayName, "attributeSchema") == 0) {
705 systemFlags &= ~SYSTEM_FLAG_ATTR_IS_RDN;
708 if (ldb_attr_cmp(objectclass->lDAPDisplayName, "server") == 0) {
709 systemFlags |= (int32_t)(SYSTEM_FLAG_DISALLOW_MOVE_ON_DELETE | SYSTEM_FLAG_CONFIG_ALLOW_RENAME | SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE);
710 } else if (ldb_attr_cmp(objectclass->lDAPDisplayName, "site") == 0
711 || ldb_attr_cmp(objectclass->lDAPDisplayName, "serverContainer") == 0
712 || ldb_attr_cmp(objectclass->lDAPDisplayName, "ntDSDSA") == 0) {
713 systemFlags |= (int32_t)(SYSTEM_FLAG_DISALLOW_MOVE_ON_DELETE);
715 } else if (ldb_attr_cmp(objectclass->lDAPDisplayName, "siteLink") == 0
716 || ldb_attr_cmp(objectclass->lDAPDisplayName, "siteLinkBridge") == 0
717 || ldb_attr_cmp(objectclass->lDAPDisplayName, "nTDSConnection") == 0) {
718 systemFlags |= (int32_t)(SYSTEM_FLAG_CONFIG_ALLOW_RENAME);
721 /* TODO: If parent object is site or subnet, also add (SYSTEM_FLAG_CONFIG_ALLOW_RENAME) */
723 if (el || systemFlags != 0) {
724 ret = samdb_msg_add_int(ldb, msg, msg, "systemFlags",
726 if (ret != LDB_SUCCESS) {
732 ret = ldb_msg_sanity_check(ldb, msg);
733 if (ret != LDB_SUCCESS) {
737 ret = ldb_build_add_req(&add_req, ldb, ac,
742 if (ret != LDB_SUCCESS) {
746 /* perform the add */
747 return ldb_next_request(ac->module, add_req);
750 static int oc_modify_callback(struct ldb_request *req,
751 struct ldb_reply *ares);
752 static int objectclass_do_mod(struct oc_context *ac);
754 static int objectclass_modify(struct ldb_module *module, struct ldb_request *req)
756 struct ldb_context *ldb = ldb_module_get_ctx(module);
757 struct ldb_message_element *objectclass_element;
758 struct ldb_message *msg;
759 struct ldb_request *down_req;
760 struct oc_context *ac;
761 bool oc_changes = false;
764 ldb_debug(ldb, LDB_DEBUG_TRACE, "objectclass_modify\n");
766 /* do not manipulate our control entries */
767 if (ldb_dn_is_special(req->op.mod.message->dn)) {
768 return ldb_next_request(module, req);
771 /* As with the "real" AD we don't accept empty messages */
772 if (req->op.mod.message->num_elements == 0) {
773 ldb_set_errstring(ldb, "objectclass: modify message must have "
774 "elements/attributes!");
775 return LDB_ERR_UNWILLING_TO_PERFORM;
778 ac = oc_init_context(module, req);
780 return ldb_operr(ldb);
783 /* Without schema, there isn't much to do here */
784 if (ac->schema == NULL) {
786 return ldb_next_request(module, req);
789 msg = ldb_msg_copy_shallow(ac, req->op.mod.message);
791 return ldb_operr(ldb);
794 /* For now change everything except the objectclasses */
796 objectclass_element = ldb_msg_find_element(msg, "objectClass");
797 if (objectclass_element != NULL) {
798 ldb_msg_remove_attr(msg, "objectClass");
802 ret = ldb_build_mod_req(&down_req, ldb, ac,
805 oc_changes ? oc_modify_callback : oc_op_callback,
807 if (ret != LDB_SUCCESS) {
811 return ldb_next_request(module, down_req);
814 static int oc_modify_callback(struct ldb_request *req, struct ldb_reply *ares)
816 static const char * const attrs[] = { "objectClass", NULL };
817 struct ldb_context *ldb;
818 struct ldb_request *search_req;
819 struct oc_context *ac;
822 ac = talloc_get_type(req->context, struct oc_context);
823 ldb = ldb_module_get_ctx(ac->module);
826 return ldb_module_done(ac->req, NULL, NULL,
827 LDB_ERR_OPERATIONS_ERROR);
830 if (ares->type == LDB_REPLY_REFERRAL) {
831 return ldb_module_send_referral(ac->req, ares->referral);
834 if (ares->error != LDB_SUCCESS) {
835 return ldb_module_done(ac->req, ares->controls,
836 ares->response, ares->error);
839 if (ares->type != LDB_REPLY_DONE) {
841 return ldb_module_done(ac->req, NULL, NULL,
842 LDB_ERR_OPERATIONS_ERROR);
847 /* this looks up the real existing object for fetching some important
848 * informations (objectclasses) */
849 ret = ldb_build_search_req(&search_req, ldb,
850 ac, ac->req->op.mod.message->dn,
854 ac, get_search_callback,
856 if (ret != LDB_SUCCESS) {
857 return ldb_module_done(ac->req, NULL, NULL, ret);
860 ac->step_fn = objectclass_do_mod;
862 ret = ldb_next_request(ac->module, search_req);
863 if (ret != LDB_SUCCESS) {
864 return ldb_module_done(ac->req, NULL, NULL, ret);
870 static int objectclass_do_mod(struct oc_context *ac)
872 struct ldb_context *ldb;
873 struct ldb_request *mod_req;
875 struct ldb_message_element *oc_el_entry, *oc_el_change;
876 struct ldb_val *vals;
877 struct ldb_message *msg;
879 struct class_list *sorted, *current;
880 const struct dsdb_class *objectclass;
882 bool found, replace = false;
885 ldb = ldb_module_get_ctx(ac->module);
887 /* we should always have a valid entry when we enter here */
888 if (ac->search_res == NULL) {
889 return ldb_operr(ldb);
892 oc_el_entry = ldb_msg_find_element(ac->search_res->message,
894 if (oc_el_entry == NULL) {
895 /* existing entry without a valid object class? */
896 return ldb_operr(ldb);
899 oc_el_change = ldb_msg_find_element(ac->req->op.mod.message,
901 if (oc_el_change == NULL) {
902 /* we should have an objectclass change operation */
903 return ldb_operr(ldb);
906 /* use a new message structure */
907 msg = ldb_msg_new(ac);
912 msg->dn = ac->req->op.mod.message->dn;
914 mem_ctx = talloc_new(ac);
915 if (mem_ctx == NULL) {
919 switch (oc_el_change->flags & LDB_FLAG_MOD_MASK) {
920 case LDB_FLAG_MOD_ADD:
921 /* Merge the two message elements */
922 for (i = 0; i < oc_el_change->num_values; i++) {
923 for (j = 0; j < oc_el_entry->num_values; j++) {
924 if (strcasecmp((char *)oc_el_change->values[i].data,
925 (char *)oc_el_entry->values[j].data) == 0) {
926 /* we cannot add an already existing object class */
927 talloc_free(mem_ctx);
928 return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
931 /* append the new object class value - code was copied
932 * from "ldb_msg_add_value" */
933 vals = talloc_realloc(oc_el_entry, oc_el_entry->values,
935 oc_el_entry->num_values + 1);
937 talloc_free(mem_ctx);
940 oc_el_entry->values = vals;
941 oc_el_entry->values[oc_el_entry->num_values] =
942 oc_el_change->values[i];
943 ++(oc_el_entry->num_values);
946 objectclass = get_last_structural_class(ac->schema,
948 if (objectclass != NULL) {
949 /* we cannot add a new structural object class */
950 talloc_free(mem_ctx);
951 return LDB_ERR_OBJECT_CLASS_VIOLATION;
954 /* Now do the sorting */
955 ret = objectclass_sort(ac->module, ac->schema, mem_ctx,
956 oc_el_entry, &sorted);
957 if (ret != LDB_SUCCESS) {
958 talloc_free(mem_ctx);
964 case LDB_FLAG_MOD_REPLACE:
965 /* Do the sorting for the change message element */
966 ret = objectclass_sort(ac->module, ac->schema, mem_ctx,
967 oc_el_change, &sorted);
968 if (ret != LDB_SUCCESS) {
969 talloc_free(mem_ctx);
973 /* this is a replace */
978 case LDB_FLAG_MOD_DELETE:
979 /* get the actual top-most structural objectclass */
980 objectclass = get_last_structural_class(ac->schema,
982 if (objectclass == NULL) {
983 talloc_free(mem_ctx);
984 return ldb_operr(ldb);
987 /* Merge the two message elements */
988 for (i = 0; i < oc_el_change->num_values; i++) {
990 for (j = 0; j < oc_el_entry->num_values; j++) {
991 if (strcasecmp((char *)oc_el_change->values[i].data,
992 (char *)oc_el_entry->values[j].data) == 0) {
994 /* delete the object class value -
995 * code was copied from
996 * "ldb_msg_remove_element" */
997 if (j != oc_el_entry->num_values - 1) {
998 memmove(&oc_el_entry->values[j],
999 &oc_el_entry->values[j+1],
1000 ((oc_el_entry->num_values-1) - j)*sizeof(struct ldb_val));
1002 --(oc_el_entry->num_values);
1007 /* we cannot delete a not existing object class */
1008 talloc_free(mem_ctx);
1009 return LDB_ERR_NO_SUCH_ATTRIBUTE;
1013 /* Make sure that the top-most structural objectclass wasn't
1016 for (i = 0; i < oc_el_entry->num_values; i++) {
1017 if (strcasecmp(objectclass->lDAPDisplayName,
1018 (char *)oc_el_entry->values[i].data) == 0) {
1019 found = true; break;
1023 talloc_free(mem_ctx);
1024 return LDB_ERR_OBJECT_CLASS_VIOLATION;
1028 /* Now do the sorting */
1029 ret = objectclass_sort(ac->module, ac->schema, mem_ctx,
1030 oc_el_entry, &sorted);
1031 if (ret != LDB_SUCCESS) {
1032 talloc_free(mem_ctx);
1039 ret = ldb_msg_add_empty(msg, "objectClass",
1040 LDB_FLAG_MOD_REPLACE, &oc_el_change);
1041 if (ret != LDB_SUCCESS) {
1043 talloc_free(mem_ctx);
1047 /* Move from the linked list back into an ldb msg */
1048 for (current = sorted; current; current = current->next) {
1049 value = talloc_strdup(msg,
1050 current->objectclass->lDAPDisplayName);
1051 if (value == NULL) {
1052 talloc_free(mem_ctx);
1053 return ldb_oom(ldb);
1055 ret = ldb_msg_add_string(msg, "objectClass", value);
1056 if (ret != LDB_SUCCESS) {
1057 ldb_set_errstring(ldb, "objectclass: could not re-add sorted objectclass to modify msg");
1058 talloc_free(mem_ctx);
1063 talloc_free(mem_ctx);
1066 /* Well, on replace we are nearly done: we have to test if
1067 * the change and entry message element are identically. We
1068 * can use "ldb_msg_element_compare" since now the specified
1069 * objectclasses match for sure in case. */
1070 ret = ldb_msg_element_compare(oc_el_entry, oc_el_change);
1072 ret = ldb_msg_element_compare(oc_el_change,
1076 /* they are the same so we are done in this case */
1077 return ldb_module_done(ac->req, NULL, NULL,
1080 /* they're not exactly the same */
1081 return LDB_ERR_OBJECT_CLASS_VIOLATION;
1085 /* in the other cases we have the real change left to do */
1087 ret = ldb_msg_sanity_check(ldb, msg);
1088 if (ret != LDB_SUCCESS) {
1092 ret = ldb_build_mod_req(&mod_req, ldb, ac,
1097 if (ret != LDB_SUCCESS) {
1101 return ldb_next_request(ac->module, mod_req);
1104 static int objectclass_do_rename(struct oc_context *ac);
1106 static int objectclass_rename(struct ldb_module *module, struct ldb_request *req)
1108 static const char * const attrs[] = { "objectClass", NULL };
1109 struct ldb_context *ldb;
1110 struct ldb_request *search_req;
1111 struct oc_context *ac;
1112 struct ldb_dn *parent_dn;
1115 ldb = ldb_module_get_ctx(module);
1117 ldb_debug(ldb, LDB_DEBUG_TRACE, "objectclass_rename\n");
1119 /* do not manipulate our control entries */
1120 if (ldb_dn_is_special(req->op.rename.newdn)) {
1121 return ldb_next_request(module, req);
1124 ac = oc_init_context(module, req);
1126 return ldb_operr(ldb);
1129 parent_dn = ldb_dn_get_parent(ac, req->op.rename.newdn);
1130 if (parent_dn == NULL) {
1131 ldb_asprintf_errstring(ldb, "objectclass: Cannot rename %s, the parent DN does not exist!",
1132 ldb_dn_get_linearized(req->op.rename.olddn));
1133 return LDB_ERR_NO_SUCH_OBJECT;
1136 /* this looks up the parent object for fetching some important
1137 * informations (objectclasses, DN normalisation...) */
1138 ret = ldb_build_search_req(&search_req, ldb,
1139 ac, parent_dn, LDB_SCOPE_BASE,
1142 ac, get_search_callback,
1144 if (ret != LDB_SUCCESS) {
1148 /* we have to add the show deleted control, as otherwise DRS
1149 deletes will be refused as we will think the target parent
1151 ret = ldb_request_add_control(search_req, LDB_CONTROL_SHOW_DELETED_OID, false, NULL);
1153 if (ret != LDB_SUCCESS) {
1157 ac->step_fn = objectclass_do_rename;
1159 return ldb_next_request(ac->module, search_req);
1162 static int objectclass_do_rename2(struct oc_context *ac);
1164 static int objectclass_do_rename(struct oc_context *ac)
1166 static const char * const attrs[] = { "objectClass", NULL };
1167 struct ldb_context *ldb;
1168 struct ldb_request *search_req;
1171 ldb = ldb_module_get_ctx(ac->module);
1173 /* Check if we have a valid parent - this check is needed since
1174 * we don't get a LDB_ERR_NO_SUCH_OBJECT error. */
1175 if (ac->search_res == NULL) {
1176 ldb_asprintf_errstring(ldb, "objectclass: Cannot rename %s, parent does not exist!",
1177 ldb_dn_get_linearized(ac->req->op.rename.olddn));
1178 return LDB_ERR_OTHER;
1181 /* now assign "search_res2" to the parent entry to have "search_res"
1182 * free for another lookup */
1183 ac->search_res2 = ac->search_res;
1184 ac->search_res = NULL;
1186 /* this looks up the real existing object for fetching some important
1187 * informations (objectclasses) */
1188 ret = ldb_build_search_req(&search_req, ldb,
1189 ac, ac->req->op.rename.olddn,
1193 ac, get_search_callback,
1195 if (ret != LDB_SUCCESS) {
1199 ac->step_fn = objectclass_do_rename2;
1201 return ldb_next_request(ac->module, search_req);
1204 static int objectclass_do_rename2(struct oc_context *ac)
1206 struct ldb_context *ldb;
1207 struct ldb_request *rename_req;
1208 struct ldb_dn *fixed_dn;
1211 ldb = ldb_module_get_ctx(ac->module);
1213 /* Check if we have a valid entry - this check is needed since
1214 * we don't get a LDB_ERR_NO_SUCH_OBJECT error. */
1215 if (ac->search_res == NULL) {
1216 ldb_asprintf_errstring(ldb, "objectclass: Cannot rename %s, entry does not exist!",
1217 ldb_dn_get_linearized(ac->req->op.rename.olddn));
1218 return LDB_ERR_NO_SUCH_OBJECT;
1221 if (ac->schema != NULL) {
1222 struct ldb_message_element *oc_el_entry, *oc_el_parent;
1223 const struct dsdb_class *objectclass;
1224 const char *rdn_name;
1225 bool allowed_class = false;
1228 oc_el_entry = ldb_msg_find_element(ac->search_res->message,
1230 if (oc_el_entry == NULL) {
1231 /* existing entry without a valid object class? */
1232 return ldb_operr(ldb);
1234 objectclass = get_last_structural_class(ac->schema, oc_el_entry);
1235 if (objectclass == NULL) {
1236 /* existing entry without a valid object class? */
1237 return ldb_operr(ldb);
1240 rdn_name = ldb_dn_get_rdn_name(ac->req->op.rename.newdn);
1241 if ((objectclass->rDNAttID != NULL) &&
1242 (ldb_attr_cmp(rdn_name, objectclass->rDNAttID) != 0)) {
1243 ldb_asprintf_errstring(ldb,
1244 "objectclass: RDN %s is not correct for most specific structural objectclass %s, should be %s",
1246 objectclass->lDAPDisplayName,
1247 objectclass->rDNAttID);
1248 return LDB_ERR_UNWILLING_TO_PERFORM;
1251 oc_el_parent = ldb_msg_find_element(ac->search_res2->message,
1253 if (oc_el_parent == NULL) {
1254 /* existing entry without a valid object class? */
1255 return ldb_operr(ldb);
1258 for (i=0; allowed_class == false && i < oc_el_parent->num_values; i++) {
1259 const struct dsdb_class *sclass;
1261 sclass = dsdb_class_by_lDAPDisplayName_ldb_val(ac->schema,
1262 &oc_el_parent->values[i]);
1264 /* We don't know this class? what is going on? */
1267 for (j=0; sclass->systemPossibleInferiors && sclass->systemPossibleInferiors[j]; j++) {
1268 if (ldb_attr_cmp(objectclass->lDAPDisplayName, sclass->systemPossibleInferiors[j]) == 0) {
1269 allowed_class = true;
1275 if (!allowed_class) {
1276 ldb_asprintf_errstring(ldb,
1277 "objectclass: structural objectClass %s is not a valid child class for %s",
1278 objectclass->lDAPDisplayName, ldb_dn_get_linearized(ac->search_res2->message->dn));
1279 return LDB_ERR_NAMING_VIOLATION;
1283 /* Ensure we are not trying to rename it to be a child of itself */
1284 if ((ldb_dn_compare_base(ac->req->op.rename.olddn,
1285 ac->req->op.rename.newdn) == 0) &&
1286 (ldb_dn_compare(ac->req->op.rename.olddn,
1287 ac->req->op.rename.newdn) != 0)) {
1288 ldb_asprintf_errstring(ldb, "objectclass: Cannot rename %s to be a child of itself",
1289 ldb_dn_get_linearized(ac->req->op.rename.olddn));
1290 return LDB_ERR_UNWILLING_TO_PERFORM;
1293 /* Fix up the DN to be in the standard form, taking
1294 * particular care to match the parent DN */
1295 ret = fix_dn(ldb, ac,
1296 ac->req->op.rename.newdn,
1297 ac->search_res2->message->dn,
1299 if (ret != LDB_SUCCESS) {
1300 ldb_asprintf_errstring(ldb, "objectclass: Could not munge DN %s into normal form",
1301 ldb_dn_get_linearized(ac->req->op.rename.newdn));
1306 ret = ldb_build_rename_req(&rename_req, ldb, ac,
1307 ac->req->op.rename.olddn, fixed_dn,
1311 if (ret != LDB_SUCCESS) {
1315 /* perform the rename */
1316 return ldb_next_request(ac->module, rename_req);
1319 static int objectclass_do_delete(struct oc_context *ac);
1321 static int objectclass_delete(struct ldb_module *module, struct ldb_request *req)
1323 static const char * const attrs[] = { "nCName", "objectClass",
1324 "systemFlags", NULL };
1325 struct ldb_context *ldb;
1326 struct ldb_request *search_req;
1327 struct oc_context *ac;
1330 ldb = ldb_module_get_ctx(module);
1332 ldb_debug(ldb, LDB_DEBUG_TRACE, "objectclass_delete\n");
1334 /* do not manipulate our control entries */
1335 if (ldb_dn_is_special(req->op.del.dn)) {
1336 return ldb_next_request(module, req);
1339 /* Bypass the constraint checks when we do have the "RELAX" control
1341 if (ldb_request_get_control(req, LDB_CONTROL_RELAX_OID) != NULL) {
1342 return ldb_next_request(module, req);
1345 ac = oc_init_context(module, req);
1347 return ldb_operr(ldb);
1350 /* this looks up the entry object for fetching some important
1351 * informations (object classes, system flags...) */
1352 ret = ldb_build_search_req(&search_req, ldb,
1353 ac, req->op.del.dn, LDB_SCOPE_BASE,
1356 ac, get_search_callback,
1358 if (ret != LDB_SUCCESS) {
1362 ac->step_fn = objectclass_do_delete;
1364 return ldb_next_request(ac->module, search_req);
1367 static int objectclass_do_delete(struct oc_context *ac)
1369 struct ldb_context *ldb;
1371 int32_t systemFlags;
1374 ldb = ldb_module_get_ctx(ac->module);
1376 /* Check if we have a valid entry - this check is needed since
1377 * we don't get a LDB_ERR_NO_SUCH_OBJECT error. */
1378 if (ac->search_res == NULL) {
1379 ldb_asprintf_errstring(ldb, "objectclass: Cannot delete %s, entry does not exist!",
1380 ldb_dn_get_linearized(ac->req->op.del.dn));
1381 return LDB_ERR_NO_SUCH_OBJECT;
1384 /* DC's ntDSDSA object */
1385 if (ldb_dn_compare(ac->req->op.del.dn, samdb_ntds_settings_dn(ldb)) == 0) {
1386 ldb_asprintf_errstring(ldb, "objectclass: Cannot delete %s, it's the DC's ntDSDSA object!",
1387 ldb_dn_get_linearized(ac->req->op.del.dn));
1388 return LDB_ERR_UNWILLING_TO_PERFORM;
1391 /* DC's rIDSet object */
1392 /* Perform this check only when it does exist - this is needed in order
1393 * to don't let existing provisions break. */
1394 ret = samdb_rid_set_dn(ldb, ac, &dn);
1395 if ((ret != LDB_SUCCESS) && (ret != LDB_ERR_NO_SUCH_OBJECT)) {
1398 if (ret == LDB_SUCCESS) {
1399 if (ldb_dn_compare(ac->req->op.del.dn, dn) == 0) {
1401 ldb_asprintf_errstring(ldb, "objectclass: Cannot delete %s, it's the DC's rIDSet object!",
1402 ldb_dn_get_linearized(ac->req->op.del.dn));
1403 return LDB_ERR_UNWILLING_TO_PERFORM;
1408 /* crossRef objects regarding config, schema and default domain NCs */
1409 if (samdb_find_attribute(ldb, ac->search_res->message, "objectClass",
1410 "crossRef") != NULL) {
1411 dn = ldb_msg_find_attr_as_dn(ldb, ac, ac->search_res->message,
1413 if ((ldb_dn_compare(dn, ldb_get_default_basedn(ldb)) == 0) ||
1414 (ldb_dn_compare(dn, ldb_get_config_basedn(ldb)) == 0) ||
1415 (ldb_dn_compare(dn, ldb_get_schema_basedn(ldb)) == 0)) {
1418 ldb_asprintf_errstring(ldb, "objectclass: Cannot delete %s, it's a crossRef object to the three main partitions!",
1419 ldb_dn_get_linearized(ac->req->op.del.dn));
1420 return LDB_ERR_UNWILLING_TO_PERFORM;
1427 systemFlags = ldb_msg_find_attr_as_int(ac->search_res->message,
1429 if ((systemFlags & SYSTEM_FLAG_DISALLOW_DELETE) != 0) {
1430 ldb_asprintf_errstring(ldb, "objectclass: Cannot delete %s, it isn't permitted!",
1431 ldb_dn_get_linearized(ac->req->op.del.dn));
1432 return LDB_ERR_UNWILLING_TO_PERFORM;
1435 return ldb_next_request(ac->module, ac->req);
1438 static int objectclass_init(struct ldb_module *module)
1440 struct ldb_context *ldb = ldb_module_get_ctx(module);
1443 /* Init everything else */
1444 ret = ldb_next_init(module);
1445 if (ret != LDB_SUCCESS) {
1449 /* Look for the opaque to indicate we might have to cut down the DN of defaultObjectCategory */
1450 ldb_module_set_private(module, ldb_get_opaque(ldb, DSDB_EXTENDED_DN_STORE_FORMAT_OPAQUE_NAME));
1455 _PUBLIC_ const struct ldb_module_ops ldb_objectclass_module_ops = {
1456 .name = "objectclass",
1457 .add = objectclass_add,
1458 .modify = objectclass_modify,
1459 .rename = objectclass_rename,
1460 .del = objectclass_delete,
1461 .init_context = objectclass_init