/* * Attempt to modify an objectSID DSDB_CONTROL_REPLICATED_UPDATE_OID set * this should succeed */ static void test_modify_of_objectSID_replicated(void **state) { struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); struct ldb_context *ldb = test_ctx->ldb; struct ldb_message *msg = ldb_msg_new(test_ctx); struct ldb_message_element *el = NULL; struct ldb_request *request = NULL; struct ldb_request *original_request = NULL; int rc; msg->dn = ldb_dn_new(msg, ldb, "dc=test"); add_sid(msg, LOCAL_SID); rc = ldb_build_mod_req( &request, test_ctx->ldb, test_ctx, msg, NULL, NULL, ldb_op_default_callback, NULL); assert_int_equal(rc, LDB_SUCCESS); assert_non_null(request); original_request = request; rc = ldb_request_add_control( request, DSDB_CONTROL_REPLICATED_UPDATE_OID, false, NULL); assert_int_equal(rc, LDB_SUCCESS); rc = unique_object_sids_modify(test_ctx->module, request); assert_int_equal(rc, LDB_SUCCESS); /* * Check that a copy of the request was passed to the next module * and not the original request */ assert_ptr_not_equal(last_request, original_request); /* * Check the flag was set on the request passed to the next * module */ el = ldb_msg_find_element(last_request->op.add.message, "objectSID"); assert_non_null(el); assert_true(el->flags & LDB_FLAG_INTERNAL_FORCE_UNIQUE_INDEX); /* * Check the flag was not set on the original request */ el = ldb_msg_find_element(request->op.add.message, "objectSID"); assert_non_null(el); assert_false(el->flags & LDB_FLAG_INTERNAL_FORCE_UNIQUE_INDEX); }
/* add a set of controls to a ldb_request structure based on a set of flags. See util.h for a list of available flags */ int dsdb_request_add_controls(struct ldb_module *module, struct ldb_request *req, uint32_t dsdb_flags) { int ret; if (dsdb_flags & DSDB_SEARCH_SEARCH_ALL_PARTITIONS) { struct ldb_search_options_control *options; /* Using the phantom root control allows us to search all partitions */ options = talloc(req, struct ldb_search_options_control); if (options == NULL) { ldb_module_oom(module); return LDB_ERR_OPERATIONS_ERROR; } options->search_options = LDB_SEARCH_OPTION_PHANTOM_ROOT; ret = ldb_request_add_control(req, LDB_CONTROL_SEARCH_OPTIONS_OID, true, options); if (ret != LDB_SUCCESS) { return ret; } } if (dsdb_flags & DSDB_SEARCH_SHOW_DELETED) { ret = ldb_request_add_control(req, LDB_CONTROL_SHOW_DELETED_OID, true, NULL); if (ret != LDB_SUCCESS) { return ret; } } if (dsdb_flags & DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT) { ret = ldb_request_add_control(req, DSDB_CONTROL_DN_STORAGE_FORMAT_OID, true, NULL); if (ret != LDB_SUCCESS) { return ret; } } if (dsdb_flags & DSDB_SEARCH_SHOW_EXTENDED_DN) { struct ldb_extended_dn_control *extended_ctrl = talloc(req, struct ldb_extended_dn_control); if (!extended_ctrl) { ldb_module_oom(module); return LDB_ERR_OPERATIONS_ERROR; } extended_ctrl->type = 1; ret = ldb_request_add_control(req, LDB_CONTROL_EXTENDED_DN_OID, true, extended_ctrl); if (ret != LDB_SUCCESS) { return ret; } } if (dsdb_flags & DSDB_SEARCH_REVEAL_INTERNALS) { ret = ldb_request_add_control(req, LDB_CONTROL_REVEAL_INTERNALS, false, NULL); if (ret != LDB_SUCCESS) { return ret; } } if (dsdb_flags & DSDB_MODIFY_RELAX) { ret = ldb_request_add_control(req, LDB_CONTROL_RELAX_OID, false, NULL); if (ret != LDB_SUCCESS) { return ret; } } return LDB_SUCCESS; }
WERROR dsdb_origin_objects_commit(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const struct drsuapi_DsReplicaObjectListItem *first_object, uint32_t *_num, struct drsuapi_DsReplicaObjectIdentifier2 **_ids) { WERROR status; const struct dsdb_schema *schema; const struct drsuapi_DsReplicaObjectListItem *cur; struct ldb_message **objects; struct drsuapi_DsReplicaObjectIdentifier2 *ids; uint32_t i; uint32_t num_objects = 0; const char * const attrs[] = { "objectGUID", "objectSid", NULL }; struct ldb_result *res; int ret; schema = dsdb_get_schema(ldb); if (!schema) { return WERR_DS_SCHEMA_NOT_LOADED; } for (cur = first_object; cur; cur = cur->next_object) { num_objects++; } if (num_objects == 0) { return WERR_OK; } ret = ldb_transaction_start(ldb); if (ret != LDB_SUCCESS) { return WERR_DS_INTERNAL_FAILURE; } objects = talloc_array(mem_ctx, struct ldb_message *, num_objects); if (objects == NULL) { status = WERR_NOMEM; goto cancel; } for (i=0, cur = first_object; cur; cur = cur->next_object, i++) { status = dsdb_convert_object(ldb, schema, cur, objects, &objects[i]); if (!W_ERROR_IS_OK(status)) { goto cancel; } } ids = talloc_array(mem_ctx, struct drsuapi_DsReplicaObjectIdentifier2, num_objects); if (ids == NULL) { status = WERR_NOMEM; goto cancel; } for (i=0; i < num_objects; i++) { struct dom_sid *sid = NULL; struct ldb_request *add_req; DEBUG(6,(__location__ ": adding %s\n", ldb_dn_get_linearized(objects[i]->dn))); ret = ldb_build_add_req(&add_req, ldb, objects, objects[i], NULL, NULL, ldb_op_default_callback, NULL); if (ret != LDB_SUCCESS) { status = WERR_DS_INTERNAL_FAILURE; goto cancel; } ret = ldb_request_add_control(add_req, LDB_CONTROL_RELAX_OID, true, NULL); if (ret != LDB_SUCCESS) { status = WERR_DS_INTERNAL_FAILURE; goto cancel; } ret = ldb_request(ldb, add_req); if (ret == LDB_SUCCESS) { ret = ldb_wait(add_req->handle, LDB_WAIT_ALL); } if (ret != LDB_SUCCESS) { DEBUG(0,(__location__ ": Failed add of %s - %s\n", ldb_dn_get_linearized(objects[i]->dn), ldb_errstring(ldb))); status = WERR_DS_INTERNAL_FAILURE; goto cancel; } talloc_free(add_req); ret = ldb_search(ldb, objects, &res, objects[i]->dn, LDB_SCOPE_BASE, attrs, "(objectClass=*)"); if (ret != LDB_SUCCESS) { status = WERR_DS_INTERNAL_FAILURE; goto cancel; } ids[i].guid = samdb_result_guid(res->msgs[0], "objectGUID"); sid = samdb_result_dom_sid(objects, res->msgs[0], "objectSid"); if (sid) { ids[i].sid = *sid; } else { ZERO_STRUCT(ids[i].sid); } } ret = ldb_transaction_commit(ldb); if (ret != LDB_SUCCESS) { return WERR_DS_INTERNAL_FAILURE; } talloc_free(objects); *_num = num_objects; *_ids = ids; return WERR_OK; cancel: talloc_free(objects); ldb_transaction_cancel(ldb); return status; }
WERROR dsdb_origin_objects_commit(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const struct drsuapi_DsReplicaObjectListItem *first_object, uint32_t *_num, uint32_t dsdb_repl_flags, struct drsuapi_DsReplicaObjectIdentifier2 **_ids) { WERROR status; const struct dsdb_schema *schema; const struct drsuapi_DsReplicaObjectListItem *cur; struct ldb_message **objects; struct drsuapi_DsReplicaObjectIdentifier2 *ids; uint32_t i; uint32_t num_objects = 0; const char * const attrs[] = { "objectGUID", "objectSid", NULL }; struct ldb_result *res; int ret; for (cur = first_object; cur; cur = cur->next_object) { num_objects++; } if (num_objects == 0) { return WERR_OK; } ret = ldb_transaction_start(ldb); if (ret != LDB_SUCCESS) { return WERR_DS_INTERNAL_FAILURE; } objects = talloc_array(mem_ctx, struct ldb_message *, num_objects); if (objects == NULL) { status = WERR_NOMEM; goto cancel; } schema = dsdb_get_schema(ldb, objects); if (!schema) { return WERR_DS_SCHEMA_NOT_LOADED; } for (i=0, cur = first_object; cur; cur = cur->next_object, i++) { status = dsdb_origin_object_convert(ldb, schema, cur, objects, &objects[i]); if (!W_ERROR_IS_OK(status)) { goto cancel; } } ids = talloc_array(mem_ctx, struct drsuapi_DsReplicaObjectIdentifier2, num_objects); if (ids == NULL) { status = WERR_NOMEM; goto cancel; } if (dsdb_repl_flags & DSDB_REPL_FLAG_ADD_NCNAME) { /* check for possible NC creation */ for (i=0; i < num_objects; i++) { struct ldb_message *msg = objects[i]; struct ldb_message_element *el; struct ldb_dn *nc_dn; if (ldb_msg_check_string_attribute(msg, "objectClass", "crossRef") == 0) { continue; } el = ldb_msg_find_element(msg, "nCName"); if (el == NULL || el->num_values != 1) { continue; } nc_dn = ldb_dn_from_ldb_val(objects, ldb, &el->values[0]); if (!ldb_dn_validate(nc_dn)) { continue; } ret = dsdb_create_partial_replica_NC(ldb, nc_dn); if (ret != LDB_SUCCESS) { status = WERR_DS_INTERNAL_FAILURE; goto cancel; } } } for (i=0; i < num_objects; i++) { struct dom_sid *sid = NULL; struct ldb_request *add_req; DEBUG(6,(__location__ ": adding %s\n", ldb_dn_get_linearized(objects[i]->dn))); ret = ldb_build_add_req(&add_req, ldb, objects, objects[i], NULL, NULL, ldb_op_default_callback, NULL); if (ret != LDB_SUCCESS) { status = WERR_DS_INTERNAL_FAILURE; goto cancel; } ret = ldb_request_add_control(add_req, LDB_CONTROL_RELAX_OID, true, NULL); if (ret != LDB_SUCCESS) { status = WERR_DS_INTERNAL_FAILURE; goto cancel; } ret = ldb_request(ldb, add_req); if (ret == LDB_SUCCESS) { ret = ldb_wait(add_req->handle, LDB_WAIT_ALL); } if (ret != LDB_SUCCESS) { DEBUG(0,(__location__ ": Failed add of %s - %s\n", ldb_dn_get_linearized(objects[i]->dn), ldb_errstring(ldb))); status = WERR_DS_INTERNAL_FAILURE; goto cancel; } talloc_free(add_req); ret = ldb_search(ldb, objects, &res, objects[i]->dn, LDB_SCOPE_BASE, attrs, "(objectClass=*)"); if (ret != LDB_SUCCESS) { status = WERR_DS_INTERNAL_FAILURE; goto cancel; } ids[i].guid = samdb_result_guid(res->msgs[0], "objectGUID"); sid = samdb_result_dom_sid(objects, res->msgs[0], "objectSid"); if (sid) { ids[i].sid = *sid; } else { ZERO_STRUCT(ids[i].sid); } } ret = ldb_transaction_commit(ldb); if (ret != LDB_SUCCESS) { return WERR_DS_INTERNAL_FAILURE; } talloc_free(objects); *_num = num_objects; *_ids = ids; return WERR_OK; cancel: talloc_free(objects); ldb_transaction_cancel(ldb); return status; }
static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, struct smb_krb5_context *smb_krb5_context, uint32_t format_flags, uint32_t format_offered, uint32_t format_desired, struct ldb_dn *name_dn, const char *name, const char *domain_filter, const char *result_filter, struct drsuapi_DsNameInfo1 *info1) { int ldb_ret; struct ldb_result *domain_res = NULL; const char * const *domain_attrs; const char * const *result_attrs; struct ldb_message **result_res = NULL; struct ldb_message *result = NULL; struct ldb_dn *result_basedn = NULL; int i; char *p; struct ldb_dn *partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx); const char * const _domain_attrs_1779[] = { "ncName", "dnsRoot", NULL}; const char * const _result_attrs_null[] = { NULL }; const char * const _domain_attrs_canonical[] = { "ncName", "dnsRoot", NULL}; const char * const _result_attrs_canonical[] = { "canonicalName", NULL }; const char * const _domain_attrs_nt4[] = { "ncName", "dnsRoot", "nETBIOSName", NULL}; const char * const _result_attrs_nt4[] = { "sAMAccountName", "objectSid", "objectClass", NULL}; const char * const _domain_attrs_guid[] = { "ncName", "dnsRoot", NULL}; const char * const _result_attrs_guid[] = { "objectGUID", NULL}; const char * const _domain_attrs_display[] = { "ncName", "dnsRoot", NULL}; const char * const _result_attrs_display[] = { "displayName", "samAccountName", NULL}; const char * const _domain_attrs_none[] = { "ncName", "dnsRoot" , NULL}; const char * const _result_attrs_none[] = { NULL}; /* here we need to set the attrs lists for domain and result lookups */ switch (format_desired) { case DRSUAPI_DS_NAME_FORMAT_FQDN_1779: case DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX: domain_attrs = _domain_attrs_1779; result_attrs = _result_attrs_null; break; case DRSUAPI_DS_NAME_FORMAT_CANONICAL: domain_attrs = _domain_attrs_canonical; result_attrs = _result_attrs_canonical; break; case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT: domain_attrs = _domain_attrs_nt4; result_attrs = _result_attrs_nt4; break; case DRSUAPI_DS_NAME_FORMAT_GUID: domain_attrs = _domain_attrs_guid; result_attrs = _result_attrs_guid; break; case DRSUAPI_DS_NAME_FORMAT_DISPLAY: domain_attrs = _domain_attrs_display; result_attrs = _result_attrs_display; break; default: domain_attrs = _domain_attrs_none; result_attrs = _result_attrs_none; break; } if (domain_filter) { /* if we have a domain_filter look it up and set the result_basedn and the dns_domain_name */ ldb_ret = ldb_search(sam_ctx, mem_ctx, &domain_res, partitions_basedn, LDB_SCOPE_ONELEVEL, domain_attrs, "%s", domain_filter); if (ldb_ret != LDB_SUCCESS) { DEBUG(2, ("DsCrackNameOneFilter domain ref search failed: %s", ldb_errstring(sam_ctx))); info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR; return WERR_OK; } switch (domain_res->count) { case 1: break; case 0: info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; return WERR_OK; default: info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE; return WERR_OK; } info1->dns_domain_name = samdb_result_string(domain_res->msgs[0], "dnsRoot", NULL); W_ERROR_HAVE_NO_MEMORY(info1->dns_domain_name); info1->status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY; } else { info1->dns_domain_name = NULL; info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR; } if (result_filter) { int ret; struct ldb_result *res; if (domain_res) { result_basedn = samdb_result_dn(sam_ctx, mem_ctx, domain_res->msgs[0], "ncName", NULL); ret = ldb_search(sam_ctx, mem_ctx, &res, result_basedn, LDB_SCOPE_SUBTREE, result_attrs, "%s", result_filter); if (ret != LDB_SUCCESS) { talloc_free(result_res); info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR; return WERR_OK; } ldb_ret = res->count; result_res = res->msgs; } else { /* search with the 'phantom root' flag */ struct ldb_request *req; res = talloc_zero(mem_ctx, struct ldb_result); W_ERROR_HAVE_NO_MEMORY(res); ret = ldb_build_search_req(&req, sam_ctx, mem_ctx, ldb_get_root_basedn(sam_ctx), LDB_SCOPE_SUBTREE, result_filter, result_attrs, NULL, res, ldb_search_default_callback, NULL); if (ret == LDB_SUCCESS) { struct ldb_search_options_control *search_options; search_options = talloc(req, struct ldb_search_options_control); W_ERROR_HAVE_NO_MEMORY(search_options); search_options->search_options = LDB_SEARCH_OPTION_PHANTOM_ROOT; ret = ldb_request_add_control(req, LDB_CONTROL_SEARCH_OPTIONS_OID, false, search_options); } if (ret != LDB_SUCCESS) { talloc_free(res); info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR; return WERR_OK; } ret = ldb_request(sam_ctx, req); if (ret == LDB_SUCCESS) { ret = ldb_wait(req->handle, LDB_WAIT_ALL); } talloc_free(req); if (ret != LDB_SUCCESS) { DEBUG(2, ("DsCrackNameOneFilter phantom root search failed: %s", ldb_errstring(sam_ctx))); info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR; return WERR_OK; } ldb_ret = res->count; result_res = res->msgs; } } else if (format_offered == DRSUAPI_DS_NAME_FORMAT_FQDN_1779) {
bool torture_ldap_sort(struct torture_context *torture) { struct ldb_context *ldb; bool ret = false; const char *host = torture_setting_string(torture, "host", NULL); char *url; int i; codepoint_t j; struct ldb_message_element *elem; struct ldb_message *msg; struct ldb_server_sort_control **control; struct ldb_request *req; struct ldb_result *ctx; struct ldb_val *prev = NULL; const char *prev_txt = NULL; int prev_len = 0; struct ldb_val *cur = NULL; const char *cur_txt = NULL; int cur_len = 0; struct ldb_dn *dn; /* TALLOC_CTX* ctx;*/ url = talloc_asprintf(torture, "ldap://%s/", host); ldb = ldb_wrap_connect(torture, torture->ev, torture->lp_ctx, url, NULL, popt_get_cmdline_credentials(), 0); torture_assert(torture, ldb, "Failed to make LDB connection to target"); ctx = talloc_zero(ldb, struct ldb_result); control = talloc_array(ctx, struct ldb_server_sort_control *, 2); control[0] = talloc(control, struct ldb_server_sort_control); control[0]->attributeName = talloc_strdup(control, "cn"); control[0]->orderingRule = NULL; control[0]->reverse = 0; control[1] = NULL; dn = ldb_get_default_basedn(ldb); ldb_dn_add_child_fmt(dn, "cn=users"); ret = ldb_build_search_req(&req, ldb, ctx, dn, LDB_SCOPE_SUBTREE, "(objectClass=*)", NULL, NULL, ctx, ldb_search_default_callback, NULL); torture_assert(torture, ret == LDB_SUCCESS, "Failed to build search request"); ret = ldb_request_add_control(req, LDB_CONTROL_SERVER_SORT_OID, true, control); torture_assert(torture, ret == LDB_SUCCESS, "Failed to add control to search request"); ret = ldb_request(ldb, req); torture_assert(torture, ret == LDB_SUCCESS, ldb_errstring(ldb)); ret = ldb_wait(req->handle, LDB_WAIT_ALL); torture_assert(torture, ret == LDB_SUCCESS, ldb_errstring(ldb)); ret = true; if (ctx->count > 1) { for (i=0;i<ctx->count;i++) { msg = ctx->msgs[i]; elem = ldb_msg_find_element(msg,"cn"); torture_assert_not_null(torture, elem, "msg lacks CN"); cur = elem->values; torture_comment(torture, "cn: %s\n",cur->data); if (prev != NULL) { /* Do only the ascii case right now ... */ cur_txt = (const char *) cur->data; cur_len = cur->length; prev_txt = (const char *) prev->data; prev_len = prev->length; /* Remove leading whitespace as the sort function do so ... */ while ( cur_txt[0] == cur_txt[1] ) { cur_txt++; cur_len--;} while ( prev_txt[0] == prev_txt[1] ) { prev_txt++; prev_len--;} while( *(cur_txt) && *(prev_txt) && cur_len && prev_len ) { j = toupper_m(*(prev_txt))-toupper_m(*(cur_txt)); if ( j > 0 ) { /* Just check that is not due to trailling white space in prev_txt * That is to say *cur_txt = 0 and prev_txt = 20 */ /* Remove trailling whitespace */ while ( *prev_txt == ' ' ) { prev_txt++; prev_len--;} while ( *cur_txt == ' ' ) { cur_txt++; cur_len--;} /* Now that potential whitespace are removed if we are at the end * of the cur_txt then it means that in fact strings were identical */ torture_assert(torture, *cur_txt && *prev_txt, "Data wrongly sorted"); break; } else { if ( j == 0 ) { if ( *(cur_txt) == ' ') { while ( cur_txt[0] == cur_txt[1] ) { cur_txt++; cur_len--;} while ( prev_txt[0] == prev_txt[1] ) { prev_txt++; prev_len--;} } cur_txt++; prev_txt++; prev_len--; cur_len--; } else { break; } } } if ( ret != 1 ) { break; } } prev = cur; } } return ret; }