struct class_list *sorted, *current;
const char *rdn_name = NULL;
char *value;
+ const struct ldb_val *tmp_val;
const struct dsdb_class *objectclass;
- struct ldb_dn *objectcategory;
+ struct ldb_dn *objectcategory, *tmp_dn;
int32_t systemFlags = 0;
unsigned int i, j;
bool found;
int ret;
+ bool relax_asked = false;
msg = ldb_msg_copy_shallow(ac, ac->req->op.add.message);
if (msg == NULL) {
/* Don't keep any error messages - we've to add a partition */
ldb_set_errstring(ldb, NULL);
} else {
+ if (ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID)) {
+ relax_asked = true;
+ }
/* Fix up the DN to be in the standard form, taking
* particular care to match the parent DN */
ret = fix_dn(ldb, msg,
}
if (objectclass->systemOnly &&
- !ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID) &&
+ relax_asked == false &&
!check_rodc_ntdsdsa_add(ac, objectclass)) {
ldb_asprintf_errstring(ldb,
"objectclass: object class '%s' is system-only, rejecting creation of '%s'!",
return LDB_ERR_NAMING_VIOLATION;
}
}
+ if (relax_asked == false) {
+ tmp_val = ldb_msg_find_ldb_val(msg, "defaultObjectCategory");
+
+ if (tmp_val != NULL) {
+ tmp_dn = ldb_dn_from_ldb_val(ac, ldb, tmp_val);
+ if (tmp_dn == NULL) {
+ ldb_asprintf_errstring(ldb, "objectclass: Cannot parse defaultObjectCategory on %s as a valid DN",
+ ldb_dn_get_linearized(msg->dn));
+ return LDB_ERR_CONSTRAINT_VIOLATION;
+ } else {
+ if (ldb_dn_compare(msg->dn, tmp_dn) != 0) {
+ static const char * const attrs[] = { "objectClass", NULL };
+ struct ldb_result *tmp_res;
+ ret = dsdb_module_search_dn(ac->module, ac->req, &tmp_res, tmp_dn,
+ attrs,
+ DSDB_FLAG_NEXT_MODULE |
+ DSDB_SEARCH_SHOW_DELETED, ac->req);
+ if (ret != LDB_SUCCESS) {
+ ldb_asprintf_errstring(ldb, "objectclass: DN for defaultObjectCategory %s is not valid.",
+ ldb_dn_get_linearized(tmp_dn));
+ return LDB_ERR_CONSTRAINT_VIOLATION;
+ }
+ }
+ }
+ }
+ }
objectcategory = ldb_msg_find_attr_as_dn(ldb, ac, msg,
"objectCategory");
ldb_msg_remove_attr(msg, "systemFlags");
/* Only the following flags may be set by a client */
- if (ldb_request_get_control(ac->req,
- LDB_CONTROL_RELAX_OID) == NULL) {
+ if (relax_asked == false) {
systemFlags &= ( SYSTEM_FLAG_CONFIG_ALLOW_RENAME
| SYSTEM_FLAG_CONFIG_ALLOW_MOVE
| SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE
/* make sure that "isCriticalSystemObject" is not specified! */
el = ldb_msg_find_element(msg, "isCriticalSystemObject");
- if ((el != NULL) &&
- !ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID)) {
+ if ((el != NULL) && relax_asked == false) {
ldb_set_errstring(ldb,
"objectclass: 'isCriticalSystemObject' must not be specified!");
return LDB_ERR_UNWILLING_TO_PERFORM;