ADS_STATUS ads_do_search_all_sd_flags (ADS_STRUCT *ads, const char *dn, int scope, const char *filter, const char **attrs, uint32_t sd_flags, LDAPMessage **res) { int rv; struct ldb_request *req; struct ldb_control **controls; struct ldb_parse_tree *tree; struct ldb_dn *ldb_dn; controls = talloc_zero_array(ads, struct ldb_control *, 2); controls[0] = talloc(ads, struct ldb_control); controls[0]->oid = LDB_CONTROL_SD_FLAGS_OID; controls[0]->data = &sd_flags; controls[0]->critical = 1; tree = ldb_parse_tree(ads, filter); ldb_dn = ldb_dn_new(ads, ads->ldbctx, dn); rv = ldb_build_search_req_ex(&req, ads->ldbctx, (TALLOC_CTX *)res, ldb_dn, scope, tree, attrs, controls, res, ldb_search_default_callback, NULL); if (rv != LDB_SUCCESS) { talloc_free(*res); talloc_free(req); talloc_free(tree); return ADS_ERROR(rv); } rv = ldb_request(ads->ldbctx, req); if (rv == LDB_SUCCESS) { rv = ldb_wait(req->handle, LDB_WAIT_ALL); } talloc_free(req); talloc_free(tree); return ADS_ERROR(rv); }
/* search for attrs on one DN, in the modules below */ int dsdb_module_search_dn(struct ldb_module *module, TALLOC_CTX *mem_ctx, struct ldb_result **_res, struct ldb_dn *basedn, const char * const *attrs, uint32_t dsdb_flags, struct ldb_request *parent) { int ret; struct ldb_request *req; TALLOC_CTX *tmp_ctx; struct ldb_result *res; tmp_ctx = talloc_new(mem_ctx); res = talloc_zero(tmp_ctx, struct ldb_result); if (!res) { talloc_free(tmp_ctx); return ldb_oom(ldb_module_get_ctx(module)); } ret = ldb_build_search_req(&req, ldb_module_get_ctx(module), tmp_ctx, basedn, LDB_SCOPE_BASE, NULL, attrs, NULL, res, ldb_search_default_callback, parent); LDB_REQ_SET_LOCATION(req); if (ret != LDB_SUCCESS) { talloc_free(tmp_ctx); return ret; } ret = dsdb_request_add_controls(req, dsdb_flags); if (ret != LDB_SUCCESS) { talloc_free(tmp_ctx); return ret; } if (dsdb_flags & DSDB_FLAG_TRUSTED) { ldb_req_mark_trusted(req); } /* Run the new request */ if (dsdb_flags & DSDB_FLAG_NEXT_MODULE) { ret = ldb_next_request(module, req); } else if (dsdb_flags & DSDB_FLAG_TOP_MODULE) { ret = ldb_request(ldb_module_get_ctx(module), req); } else { const struct ldb_module_ops *ops = ldb_module_get_ops(module); SMB_ASSERT(dsdb_flags & DSDB_FLAG_OWN_MODULE); ret = ops->search(module, req); } if (ret == LDB_SUCCESS) { ret = ldb_wait(req->handle, LDB_WAIT_ALL); } if (ret != LDB_SUCCESS) { talloc_free(tmp_ctx); return ret; } if (res->count != 1) { /* we may be reading a DB that does not have the 'check base on search' option... */ ret = LDB_ERR_NO_SUCH_OBJECT; ldb_asprintf_errstring(ldb_module_get_ctx(module), "dsdb_module_search_dn: did not find base dn %s (%d results)", ldb_dn_get_linearized(basedn), res->count); } else { *_res = talloc_steal(mem_ctx, res); } talloc_free(tmp_ctx); return ret; }
int dsdb_module_search_tree(struct ldb_module *module, TALLOC_CTX *mem_ctx, struct ldb_result **_res, struct ldb_dn *basedn, enum ldb_scope scope, struct ldb_parse_tree *tree, const char * const *attrs, int dsdb_flags, struct ldb_request *parent) { int ret; struct ldb_request *req; TALLOC_CTX *tmp_ctx; struct ldb_result *res; tmp_ctx = talloc_new(mem_ctx); /* cross-partitions searches with a basedn break multi-domain support */ SMB_ASSERT(basedn == NULL || (dsdb_flags & DSDB_SEARCH_SEARCH_ALL_PARTITIONS) == 0); res = talloc_zero(tmp_ctx, struct ldb_result); if (!res) { talloc_free(tmp_ctx); return ldb_oom(ldb_module_get_ctx(module)); } ret = ldb_build_search_req_ex(&req, ldb_module_get_ctx(module), tmp_ctx, basedn, scope, tree, attrs, NULL, res, ldb_search_default_callback, parent); LDB_REQ_SET_LOCATION(req); if (ret != LDB_SUCCESS) { talloc_free(tmp_ctx); return ret; } ret = dsdb_request_add_controls(req, dsdb_flags); if (ret != LDB_SUCCESS) { talloc_free(tmp_ctx); return ret; } if (dsdb_flags & DSDB_FLAG_TRUSTED) { ldb_req_mark_trusted(req); } if (dsdb_flags & DSDB_FLAG_NEXT_MODULE) { ret = ldb_next_request(module, req); } else if (dsdb_flags & DSDB_FLAG_TOP_MODULE) { ret = ldb_request(ldb_module_get_ctx(module), req); } else { const struct ldb_module_ops *ops = ldb_module_get_ops(module); SMB_ASSERT(dsdb_flags & DSDB_FLAG_OWN_MODULE); ret = ops->search(module, req); } if (ret == LDB_SUCCESS) { ret = ldb_wait(req->handle, LDB_WAIT_ALL); } talloc_free(req); if (ret == LDB_SUCCESS) { *_res = talloc_steal(mem_ctx, res); } talloc_free(tmp_ctx); return ret; }
/* search for attrs on one DN, in the modules below */ int dsdb_module_search_dn(struct ldb_module *module, TALLOC_CTX *mem_ctx, struct ldb_result **_res, struct ldb_dn *basedn, const char * const *attrs, uint32_t dsdb_flags) { int ret; struct ldb_request *req; TALLOC_CTX *tmp_ctx; struct ldb_result *res; tmp_ctx = talloc_new(mem_ctx); res = talloc_zero(tmp_ctx, struct ldb_result); if (!res) { return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_build_search_req(&req, ldb_module_get_ctx(module), tmp_ctx, basedn, LDB_SCOPE_BASE, NULL, attrs, NULL, res, ldb_search_default_callback, NULL); if (ret != LDB_SUCCESS) { talloc_free(tmp_ctx); return ret; } ret = dsdb_request_add_controls(module, req, dsdb_flags); if (ret != LDB_SUCCESS) { talloc_free(tmp_ctx); return ret; } ret = ldb_next_request(module, req); if (ret == LDB_SUCCESS) { ret = ldb_wait(req->handle, LDB_WAIT_ALL); } if (ret != LDB_SUCCESS) { talloc_free(tmp_ctx); return ret; } if (res->count != 1) { /* we may be reading a DB that does not have the 'check base on search' option... */ ret = LDB_ERR_NO_SUCH_OBJECT; ldb_asprintf_errstring(ldb_module_get_ctx(module), "dsdb_module_search_dn: did not find base dn %s (%d results)", ldb_dn_get_linearized(basedn), res->count); } else { *_res = talloc_steal(mem_ctx, res); } talloc_free(tmp_ctx); return ret; }
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; }
/** * Commits a list of replicated objects. * * @param working_schema dsdb_schema to be used for resolving * Classes/Attributes during Schema replication. If not NULL, * it will be set on ldb and used while committing replicated objects */ WERROR dsdb_replicated_objects_commit(struct ldb_context *ldb, struct dsdb_schema *working_schema, struct dsdb_extended_replicated_objects *objects, uint64_t *notify_uSN) { WERROR werr; struct ldb_result *ext_res; struct dsdb_schema *cur_schema = NULL; struct dsdb_schema *new_schema = NULL; int ret; uint64_t seq_num1, seq_num2; bool used_global_schema = false; TALLOC_CTX *tmp_ctx = talloc_new(objects); if (!tmp_ctx) { DEBUG(0,("Failed to start talloc\n")); return WERR_NOMEM; } /* TODO: handle linked attributes */ /* wrap the extended operation in a transaction See [MS-DRSR] 3.3.2 Transactions */ ret = ldb_transaction_start(ldb); if (ret != LDB_SUCCESS) { DEBUG(0,(__location__ " Failed to start transaction\n")); return WERR_FOOBAR; } ret = dsdb_load_partition_usn(ldb, objects->partition_dn, &seq_num1, NULL); if (ret != LDB_SUCCESS) { DEBUG(0,(__location__ " Failed to load partition uSN\n")); ldb_transaction_cancel(ldb); TALLOC_FREE(tmp_ctx); return WERR_FOOBAR; } /* * Set working_schema for ldb in case we are replicating from Schema NC. * Schema won't be reloaded during Replicated Objects commit, as it is * done in a transaction. So we need some way to search for newly * added Classes and Attributes */ if (working_schema) { /* store current schema so we can fall back in case of failure */ cur_schema = dsdb_get_schema(ldb, tmp_ctx); used_global_schema = dsdb_uses_global_schema(ldb); ret = dsdb_reference_schema(ldb, working_schema, false); if (ret != LDB_SUCCESS) { DEBUG(0,(__location__ "Failed to reference working schema - %s\n", ldb_strerror(ret))); /* TODO: Map LDB Error to NTSTATUS? */ ldb_transaction_cancel(ldb); TALLOC_FREE(tmp_ctx); return WERR_INTERNAL_ERROR; } } ret = ldb_extended(ldb, DSDB_EXTENDED_REPLICATED_OBJECTS_OID, objects, &ext_res); if (ret != LDB_SUCCESS) { /* restore previous schema */ if (used_global_schema) { dsdb_set_global_schema(ldb); } else if (cur_schema) { dsdb_reference_schema(ldb, cur_schema, false); } DEBUG(0,("Failed to apply records: %s: %s\n", ldb_errstring(ldb), ldb_strerror(ret))); ldb_transaction_cancel(ldb); TALLOC_FREE(tmp_ctx); return WERR_FOOBAR; } talloc_free(ext_res); /* Save our updated prefixMap */ if (working_schema) { werr = dsdb_write_prefixes_from_schema_to_ldb(working_schema, ldb, working_schema); if (!W_ERROR_IS_OK(werr)) { /* restore previous schema */ if (used_global_schema) { dsdb_set_global_schema(ldb); } else if (cur_schema ) { dsdb_reference_schema(ldb, cur_schema, false); } DEBUG(0,("Failed to save updated prefixMap: %s\n", win_errstr(werr))); TALLOC_FREE(tmp_ctx); return werr; } } ret = ldb_transaction_prepare_commit(ldb); if (ret != LDB_SUCCESS) { /* restore previous schema */ if (used_global_schema) { dsdb_set_global_schema(ldb); } else if (cur_schema ) { dsdb_reference_schema(ldb, cur_schema, false); } DEBUG(0,(__location__ " Failed to prepare commit of transaction: %s\n", ldb_errstring(ldb))); TALLOC_FREE(tmp_ctx); return WERR_FOOBAR; } ret = dsdb_load_partition_usn(ldb, objects->partition_dn, &seq_num2, NULL); if (ret != LDB_SUCCESS) { /* restore previous schema */ if (used_global_schema) { dsdb_set_global_schema(ldb); } else if (cur_schema ) { dsdb_reference_schema(ldb, cur_schema, false); } DEBUG(0,(__location__ " Failed to load partition uSN\n")); ldb_transaction_cancel(ldb); TALLOC_FREE(tmp_ctx); return WERR_FOOBAR; } ret = ldb_transaction_commit(ldb); if (ret != LDB_SUCCESS) { /* restore previous schema */ if (used_global_schema) { dsdb_set_global_schema(ldb); } else if (cur_schema ) { dsdb_reference_schema(ldb, cur_schema, false); } DEBUG(0,(__location__ " Failed to commit transaction\n")); TALLOC_FREE(tmp_ctx); return WERR_FOOBAR; } /* if this replication partner didn't need to be notified before this transaction then it still doesn't need to be notified, as the changes came from this server */ if (seq_num2 > seq_num1 && seq_num1 <= *notify_uSN) { *notify_uSN = seq_num2; } /* * Reset the Schema used by ldb. This will lead to * a schema cache being refreshed from database. */ if (working_schema) { struct ldb_message *msg; struct ldb_request *req; /* Force a reload */ working_schema->last_refresh = 0; new_schema = dsdb_get_schema(ldb, tmp_ctx); /* TODO: * If dsdb_get_schema() fails, we just fall back * to what we had. However, the database is probably * unable to operate for other users from this * point... */ if (new_schema && used_global_schema) { dsdb_make_schema_global(ldb, new_schema); } else if (used_global_schema) { DEBUG(0,("Failed to re-load schema after commit of transaction\n")); dsdb_set_global_schema(ldb); TALLOC_FREE(tmp_ctx); return WERR_INTERNAL_ERROR; } else { DEBUG(0,("Failed to re-load schema after commit of transaction\n")); dsdb_reference_schema(ldb, cur_schema, false); TALLOC_FREE(tmp_ctx); return WERR_INTERNAL_ERROR; } msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { TALLOC_FREE(tmp_ctx); return WERR_NOMEM; } msg->dn = ldb_dn_new(msg, ldb, ""); if (msg->dn == NULL) { TALLOC_FREE(tmp_ctx); return WERR_NOMEM; } ret = ldb_msg_add_string(msg, "schemaUpdateNow", "1"); if (ret != LDB_SUCCESS) { TALLOC_FREE(tmp_ctx); return WERR_INTERNAL_ERROR; } ret = ldb_build_mod_req(&req, ldb, objects, msg, NULL, NULL, ldb_op_default_callback, NULL); if (ret != LDB_SUCCESS) { TALLOC_FREE(tmp_ctx); return WERR_DS_DRA_INTERNAL_ERROR; } ret = ldb_transaction_start(ldb); if (ret != LDB_SUCCESS) { TALLOC_FREE(tmp_ctx); DEBUG(0, ("Autotransaction start failed\n")); return WERR_DS_DRA_INTERNAL_ERROR; } ret = ldb_request(ldb, req); if (ret == LDB_SUCCESS) { ret = ldb_wait(req->handle, LDB_WAIT_ALL); } if (ret == LDB_SUCCESS) { ret = ldb_transaction_commit(ldb); } else { DEBUG(0, ("Schema update now failed: %s\n", ldb_errstring(ldb))); ldb_transaction_cancel(ldb); } if (ret != LDB_SUCCESS) { DEBUG(0, ("Commit failed: %s\n", ldb_errstring(ldb))); TALLOC_FREE(tmp_ctx); return WERR_DS_INTERNAL_FAILURE; } } DEBUG(2,("Replicated %u objects (%u linked attributes) for %s\n", objects->num_objects, objects->linked_attributes_count, ldb_dn_get_linearized(objects->partition_dn))); TALLOC_FREE(tmp_ctx); return WERR_OK; }
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; }