static int subtree_delete(struct ldb_module *module, struct ldb_request *req) { static const char * const attrs[] = { NULL }; int ret; struct ldb_result *res = NULL; if (ldb_dn_is_special(req->op.del.dn)) { /* do not manipulate our control entries */ return ldb_next_request(module, req); } /* see if we have any children */ ret = dsdb_module_search(module, req, &res, req->op.del.dn, LDB_SCOPE_ONELEVEL, attrs, DSDB_SEARCH_SHOW_DELETED, NULL); if (ret != LDB_SUCCESS) { talloc_free(res); return ret; } if (res->count > 0) { ldb_asprintf_errstring(ldb_module_get_ctx(module), "Cannot delete %s, not a leaf node " "(has %d children)\n", ldb_dn_get_linearized(req->op.del.dn), res->count); talloc_free(res); return LDB_ERR_NOT_ALLOWED_ON_NON_LEAF; } talloc_free(res); return ldb_next_request(module, req); }
/** * Reads schema_info structure from schemaInfo * attribute on SCHEMA partition * * @param dsdb_flags DSDB_FLAG_... flag of 0 */ int dsdb_module_schema_info_blob_read(struct ldb_module *ldb_module, uint32_t dsdb_flags, TALLOC_CTX *mem_ctx, struct ldb_val *schema_info_blob, struct ldb_request *parent) { int ldb_err; const struct ldb_val *blob_val; struct ldb_dn *schema_dn; struct ldb_result *schema_res = NULL; static const char *schema_attrs[] = { "schemaInfo", NULL }; schema_dn = ldb_get_schema_basedn(ldb_module_get_ctx(ldb_module)); if (!schema_dn) { DEBUG(0,("dsdb_module_schema_info_blob_read: no schema dn present!\n")); return ldb_operr(ldb_module_get_ctx(ldb_module)); } ldb_err = dsdb_module_search(ldb_module, mem_ctx, &schema_res, schema_dn, LDB_SCOPE_BASE, schema_attrs, dsdb_flags, parent, NULL); if (ldb_err == LDB_ERR_NO_SUCH_OBJECT) { DEBUG(0,("dsdb_module_schema_info_blob_read: Schema DN not found!\n")); talloc_free(schema_res); return ldb_err; } else if (ldb_err != LDB_SUCCESS) { DEBUG(0,("dsdb_module_schema_info_blob_read: failed to find schemaInfo attribute\n")); talloc_free(schema_res); return ldb_err; } blob_val = ldb_msg_find_ldb_val(schema_res->msgs[0], "schemaInfo"); if (!blob_val) { ldb_asprintf_errstring(ldb_module_get_ctx(ldb_module), "dsdb_module_schema_info_blob_read: no schemaInfo attribute found"); talloc_free(schema_res); return LDB_ERR_NO_SUCH_ATTRIBUTE; } /* transfer .data ownership to mem_ctx */ schema_info_blob->length = blob_val->length; schema_info_blob->data = talloc_steal(mem_ctx, blob_val->data); talloc_free(schema_res); return LDB_SUCCESS; }
static int subtree_delete(struct ldb_module *module, struct ldb_request *req) { static const char * const attrs[] = { NULL }; struct ldb_result *res = NULL; uint32_t flags; unsigned int i; int ret; if (ldb_dn_is_special(req->op.del.dn)) { /* do not manipulate our control entries */ return ldb_next_request(module, req); } /* see if we have any children */ ret = dsdb_module_search(module, req, &res, req->op.del.dn, LDB_SCOPE_ONELEVEL, attrs, DSDB_FLAG_NEXT_MODULE, req, "(objectClass=*)"); if (ret != LDB_SUCCESS) { talloc_free(res); return ret; } if (res->count == 0) { talloc_free(res); return ldb_next_request(module, req); } if (ldb_request_get_control(req, LDB_CONTROL_TREE_DELETE_OID) == NULL) { /* Do not add any DN outputs to this error string! * Some MMC consoles (eg release 2000) have a strange * bug and prevent subtree deletes afterwards. */ ldb_asprintf_errstring(ldb_module_get_ctx(module), "subtree_delete: Unable to " "delete a non-leaf node " "(it has %u children)!", res->count); talloc_free(res); return LDB_ERR_NOT_ALLOWED_ON_NON_LEAF; } /* * First we sort the results from the leaf to the root */ LDB_TYPESAFE_QSORT(res->msgs, res->count, NULL, subtree_delete_sort); /* * we need to start from the top since other LDB modules could * enforce constraints (eg "objectclass" and "samldb" do so). * * We pass DSDB_FLAG_AS_SYSTEM as the acl module above us * has already checked for SEC_ADS_DELETE_TREE. */ flags = DSDB_FLAG_TOP_MODULE | DSDB_FLAG_AS_SYSTEM | DSDB_FLAG_TRUSTED | DSDB_TREE_DELETE; if (ldb_request_get_control(req, LDB_CONTROL_RELAX_OID) != NULL) { flags |= DSDB_MODIFY_RELAX; } for (i = 0; i < res->count; i++) { ret = dsdb_module_del(module, res->msgs[i]->dn, flags, req); if (ret != LDB_SUCCESS) { return ret; } } talloc_free(res); return ldb_next_request(module, req); }