📄 objectclass.c
字号:
h = oc_init_handle(req, module); if (!h) { return LDB_ERR_OPERATIONS_ERROR; } ac = talloc_get_type(h->private_data, struct oc_context); /* return or own handle to deal with this call */ req->handle = h; /* If there isn't a parent, just go on to the add processing */ if (ldb_dn_get_comp_num(ac->orig_req->op.add.message->dn) == 1) { return objectclass_do_add(h); } parent_dn = ldb_dn_get_parent(ac, ac->orig_req->op.add.message->dn); if (parent_dn == NULL) { ldb_oom(module->ldb); return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_build_search_req(&ac->search_req, module->ldb, ac, parent_dn, LDB_SCOPE_BASE, "(objectClass=*)", attrs, NULL, ac, get_search_callback); if (ret != LDB_SUCCESS) { return ret; } talloc_steal(ac->search_req, parent_dn); ldb_set_timeout_from_prev_req(ac->module->ldb, ac->orig_req, ac->search_req); ac->step = OC_SEARCH_ADD_PARENT; return ldb_next_request(ac->module, ac->search_req);}static int objectclass_do_add(struct ldb_handle *h) { const struct dsdb_schema *schema; 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; ac = talloc_get_type(h->private_data, struct oc_context); schema = dsdb_get_schema(ac->module->ldb); mem_ctx = talloc_new(ac); if (mem_ctx == NULL) { return LDB_ERR_OPERATIONS_ERROR; } ac->add_req = talloc(ac, struct ldb_request); if (ac->add_req == NULL) { talloc_free(mem_ctx); return LDB_ERR_OPERATIONS_ERROR; } *ac->add_req = *ac->orig_req; ac->add_req->op.add.message = msg = ldb_msg_copy_shallow(ac->add_req, ac->orig_req->op.add.message); ldb_set_timeout_from_prev_req(ac->module->ldb, ac->orig_req, ac->add_req); /* Check we have a valid parent */ if (ac->search_res == NULL) { if (ldb_dn_compare(ldb_get_root_basedn(ac->module->ldb), ac->orig_req->op.add.message->dn) == 0) { /* Allow the tree to be started */ /* but don't keep any error string, it's meaningless */ ldb_set_errstring(ac->module->ldb, NULL); } else { ldb_asprintf_errstring(ac->module->ldb, "objectclass: Cannot add %s, parent does not exist!", ldb_dn_get_linearized(ac->orig_req->op.add.message->dn)); return LDB_ERR_UNWILLING_TO_PERFORM; } } else { /* Fix up the DN to be in the standard form, taking particular care to match the parent DN */ ret = fix_dn(msg, ac->orig_req->op.add.message->dn, ac->search_res->message->dn, &msg->dn); if (ret != LDB_SUCCESS) { ldb_asprintf_errstring(ac->module->ldb, "Could not munge DN %s into normal form", ldb_dn_get_linearized(ac->orig_req->op.add.message->dn)); return ret; } /* TODO: Check this is a valid child to this parent, * by reading the allowedChildClasses and * allowedChildClasssesEffective attributes */ } if (schema) { ret = fix_attributes(ac->module->ldb, schema, msg); if (ret != LDB_SUCCESS) { talloc_free(mem_ctx); return ret; } /* This is now the objectClass list from the database */ objectclass_element = ldb_msg_find_element(msg, "objectClass"); if (!objectclass_element) { /* Where did it go? bail now... */ talloc_free(mem_ctx); return LDB_ERR_OPERATIONS_ERROR; } ret = objectclass_sort(ac->module, schema, msg, mem_ctx, objectclass_element, &sorted); if (ret != LDB_SUCCESS) { talloc_free(mem_ctx); return ret; } ldb_msg_remove_attr(msg, "objectClass"); ret = ldb_msg_add_empty(msg, "objectClass", 0, NULL); if (ret != LDB_SUCCESS) { talloc_free(mem_ctx); return ret; } /* We must completely replace the existing objectClass entry, * because we need it sorted */ /* Move from the linked list back into an ldb msg */ for (current = sorted; current; current = current->next) { ret = ldb_msg_add_string(msg, "objectClass", current->objectclass->lDAPDisplayName); if (ret != LDB_SUCCESS) { ldb_set_errstring(ac->module->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) { if (!ldb_msg_find_element(msg, "objectCategory")) { ldb_msg_add_string(msg, "objectCategory", current->objectclass->defaultObjectCategory); } if (!ldb_msg_find_element(msg, "showInAdvancedViewOnly") && (current->objectclass->defaultHidingValue == true)) { ldb_msg_add_string(msg, "showInAdvancedViewOnly", "TRUE"); } if (!ldb_msg_find_element(msg, "nTSecurityDescriptor")) { DATA_BLOB *sd = get_sd(ac->module, mem_ctx, current->objectclass); if (sd) { ldb_msg_add_steal_value(msg, "nTSecurityDescriptor", sd); } } } } } talloc_free(mem_ctx); ret = ldb_msg_sanity_check(ac->module->ldb, msg); if (ret != LDB_SUCCESS) { return ret; } h->state = LDB_ASYNC_INIT; h->status = LDB_SUCCESS; ac->step = OC_DO_ADD; /* perform the add */ return ldb_next_request(ac->module, ac->add_req);}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(module->ldb); int ret; ldb_debug(module->ldb, LDB_DEBUG_TRACE, "objectclass_modify\n"); /* do not manipulate our control entries */ if (ldb_dn_is_special(req->op.mod.message->dn)) { return ldb_next_request(module, req); } /* Without schema, there isn't much to do here */ if (!schema) { return ldb_next_request(module, req); } objectclass_element = ldb_msg_find_element(req->op.mod.message, "objectClass"); /* If no part of this touches the objectClass, then we don't * need to make any changes. */ /* If the only operation is the deletion of the objectClass * then go on with just fixing the attribute case */ if (!objectclass_element) { struct ldb_request *down_req = talloc(req, struct ldb_request); if (down_req == NULL) { ldb_set_errstring(module->ldb, "Out of memory!"); return LDB_ERR_OPERATIONS_ERROR; } *down_req = *req; /* copy the request */ down_req->op.mod.message = msg = ldb_msg_copy_shallow(down_req, req->op.mod.message); if (down_req->op.mod.message == NULL) { return LDB_ERR_OPERATIONS_ERROR; } ret = fix_attributes(module->ldb, schema, msg); if (ret != LDB_SUCCESS) { return ret; } /* go on with the call chain */ ret = ldb_next_request(module, down_req); /* do not free down_req as the call results may be linked to it, * it will be freed when the upper level request get freed */ if (ret == LDB_SUCCESS) { req->handle = down_req->handle; } return ret; } switch (objectclass_element->flags & LDB_FLAG_MOD_MASK) { case LDB_FLAG_MOD_DELETE: if (objectclass_element->num_values == 0) { return LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED; } break; case LDB_FLAG_MOD_REPLACE: { struct ldb_request *down_req; struct class_list *sorted, *current; TALLOC_CTX *mem_ctx; mem_ctx = talloc_new(req); if (mem_ctx == NULL) { return LDB_ERR_OPERATIONS_ERROR; } /* prepare the first operation */ down_req = talloc(req, struct ldb_request); if (down_req == NULL) { ldb_set_errstring(module->ldb, "Out of memory!"); talloc_free(mem_ctx); return LDB_ERR_OPERATIONS_ERROR; } *down_req = *req; /* copy the request */ down_req->op.mod.message = msg = ldb_msg_copy_shallow(down_req, req->op.mod.message); if (down_req->op.mod.message == NULL) { talloc_free(mem_ctx); return LDB_ERR_OPERATIONS_ERROR; } ret = fix_attributes(module->ldb, schema, msg); if (ret != LDB_SUCCESS) { talloc_free(mem_ctx); return ret; } ret = objectclass_sort(module, schema, msg, mem_ctx, objectclass_element, &sorted); if (ret != LDB_SUCCESS) { 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) { ret = ldb_msg_add_string(msg, "objectClass", current->objectclass->lDAPDisplayName); if (ret != LDB_SUCCESS) { ldb_set_errstring(module->ldb, "objectclass: could not re-add sorted objectclass to modify msg"); talloc_free(mem_ctx); return ret; } } talloc_free(mem_ctx); ret = ldb_msg_sanity_check(module->ldb, msg); if (ret != LDB_SUCCESS) { talloc_free(mem_ctx); return ret; } /* go on with the call chain */ ret = ldb_next_request(module, down_req); /* do not free down_req as the call results may be linked to it, * it will be freed when the upper level request get freed */ if (ret == LDB_SUCCESS) { req->handle = down_req->handle; } return ret; } } /* This isn't the default branch of the switch, but a 'in any * other case'. When a delete isn't for all objectClasses for * example */ { struct ldb_handle *h; struct oc_context *ac; h = oc_init_handle(req, module); if (!h) { return LDB_ERR_OPERATIONS_ERROR; } ac = talloc_get_type(h->private_data, struct oc_context); /* return or own handle to deal with this call */ req->handle = h; /* prepare the first operation */ ac->down_req = talloc(ac, struct ldb_request); if (ac->down_req == NULL) { ldb_oom(ac->module->ldb); return LDB_ERR_OPERATIONS_ERROR; } *(ac->down_req) = *req; /* copy the request */ ac->down_req->op.mod.message = msg = ldb_msg_copy_shallow(ac->down_req, req->op.mod.message); if (ac->down_req->op.mod.message == NULL) { ldb_oom(ac->module->ldb); return LDB_ERR_OPERATIONS_ERROR; } ret = fix_attributes(ac->module->ldb, schema, msg); if (ret != LDB_SUCCESS) { ldb_oom(ac->module->ldb); return ret; } ac->down_req->context = NULL; ac->down_req->callback = NULL; ldb_set_timeout_from_prev_req(module->ldb, req, ac->down_req); ac->step = OC_DO_REQ; return ldb_next_request(module, ac->down_req); }}static int objectclass_search_self(struct ldb_handle *h) { int ret; struct oc_context *ac; static const char * const attrs[] = { "objectClass", NULL }; ac = talloc_get_type(h->private_data, struct oc_context); ret = ldb_build_search_req(&ac->search_req, ac->module->ldb, ac, ac->orig_req->op.mod.message->dn, LDB_SCOPE_BASE, "(objectClass=*)", attrs, NULL, ac, get_search_callback); if (ret != LDB_SUCCESS) { return ret; } ldb_set_timeout_from_prev_req(ac->module->ldb, ac->orig_req, ac->search_req); ac->step = OC_SEARCH_SELF;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -