static WERROR DsCrackNameOneSyntactical(TALLOC_CTX *mem_ctx, uint32_t format_offered, uint32_t format_desired, struct ldb_dn *name_dn, const char *name, struct drsuapi_DsNameInfo1 *info1) { char *cracked; if (format_offered != DRSUAPI_DS_NAME_FORMAT_FQDN_1779) { info1->status = DRSUAPI_DS_NAME_STATUS_NO_SYNTACTICAL_MAPPING; return WERR_OK; } switch (format_desired) { case DRSUAPI_DS_NAME_FORMAT_CANONICAL: cracked = ldb_dn_canonical_string(mem_ctx, name_dn); break; case DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX: cracked = ldb_dn_canonical_ex_string(mem_ctx, name_dn); break; default: info1->status = DRSUAPI_DS_NAME_STATUS_NO_SYNTACTICAL_MAPPING; return WERR_OK; } info1->status = DRSUAPI_DS_NAME_STATUS_OK; info1->result_name = cracked; if (!cracked) { return WERR_NOMEM; } return WERR_OK; }
bool test_DsCrackNames(struct torture_context *tctx, struct DsPrivate *priv) { NTSTATUS status; const char *err_msg; struct drsuapi_DsCrackNames r; union drsuapi_DsNameRequest req; uint32_t level_out; union drsuapi_DsNameCtr ctr; struct drsuapi_DsNameString names[1]; const char *dns_domain; const char *nt4_domain; const char *FQDN_1779_name; struct ldb_context *ldb; struct ldb_dn *FQDN_1779_dn; struct ldb_dn *realm_dn; const char *realm_dn_str; const char *realm_canonical; const char *realm_canonical_ex; const char *user_principal_name; char *user_principal_name_short; const char *service_principal_name; const char *canonical_name; const char *canonical_ex_name; const char *dom_sid; const char *test_dc = torture_join_netbios_name(priv->join); struct dcerpc_pipe *p = priv->drs_pipe; TALLOC_CTX *mem_ctx = priv; ZERO_STRUCT(r); r.in.bind_handle = &priv->bind_handle; r.in.level = 1; r.in.req = &req; r.in.req->req1.codepage = 1252; /* german */ r.in.req->req1.language = 0x00000407; /* german */ r.in.req->req1.count = 1; r.in.req->req1.names = names; r.in.req->req1.format_flags = DRSUAPI_DS_NAME_FLAG_NO_FLAGS; r.in.req->req1.format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY; r.in.req->req1.format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT; r.out.level_out = &level_out; r.out.ctr = &ctr; dom_sid = dom_sid_string(mem_ctx, torture_join_sid(priv->join)); names[0].str = dom_sid; torture_comment(tctx, "Testing DsCrackNames with name '%s' desired format:%d\n", names[0].str, r.in.req->req1.format_desired); status = dcerpc_drsuapi_DsCrackNames_r(p->binding_handle, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { const char *errstr = nt_errstr(status); err_msg = talloc_asprintf(mem_ctx, "dcerpc_drsuapi_DsCrackNames failed - %s", errstr); torture_fail(tctx, err_msg); } else if (!W_ERROR_IS_OK(r.out.result)) { err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed - %s", win_errstr(r.out.result)); torture_fail(tctx, err_msg); } else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) { err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed on name - %d", r.out.ctr->ctr1->array[0].status); torture_fail(tctx, err_msg); } dns_domain = r.out.ctr->ctr1->array[0].dns_domain_name; nt4_domain = r.out.ctr->ctr1->array[0].result_name; r.in.req->req1.format_desired = DRSUAPI_DS_NAME_FORMAT_GUID; torture_comment(tctx, "Testing DsCrackNames with name '%s' desired format:%d\n", names[0].str, r.in.req->req1.format_desired); status = dcerpc_drsuapi_DsCrackNames_r(p->binding_handle, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { const char *errstr = nt_errstr(status); err_msg = talloc_asprintf(mem_ctx, "dcerpc_drsuapi_DsCrackNames failed - %s", errstr); torture_fail(tctx, err_msg); } else if (!W_ERROR_IS_OK(r.out.result)) { err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed - %s", win_errstr(r.out.result)); torture_fail(tctx, err_msg); } else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) { err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed on name - %d", r.out.ctr->ctr1->array[0].status); torture_fail(tctx, err_msg); } priv->domain_dns_name = r.out.ctr->ctr1->array[0].dns_domain_name; priv->domain_guid_str = r.out.ctr->ctr1->array[0].result_name; GUID_from_string(priv->domain_guid_str, &priv->domain_guid); r.in.req->req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779; torture_comment(tctx, "Testing DsCrackNames with name '%s' desired format:%d\n", names[0].str, r.in.req->req1.format_desired); status = dcerpc_drsuapi_DsCrackNames_r(p->binding_handle, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { const char *errstr = nt_errstr(status); err_msg = talloc_asprintf(mem_ctx, "dcerpc_drsuapi_DsCrackNames failed - %s", errstr); torture_fail(tctx, err_msg); } else if (!W_ERROR_IS_OK(r.out.result)) { err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed - %s", win_errstr(r.out.result)); torture_fail(tctx, err_msg); } else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) { err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed on name - %d", r.out.ctr->ctr1->array[0].status); torture_fail(tctx, err_msg); } ldb = ldb_init(mem_ctx, tctx->ev); realm_dn_str = r.out.ctr->ctr1->array[0].result_name; realm_dn = ldb_dn_new(mem_ctx, ldb, realm_dn_str); realm_canonical = ldb_dn_canonical_string(mem_ctx, realm_dn); if (strcmp(realm_canonical, talloc_asprintf(mem_ctx, "%s/", dns_domain))!= 0) { err_msg = talloc_asprintf(mem_ctx, "local Round trip on canonical name failed: %s != %s!", realm_canonical, talloc_asprintf(mem_ctx, "%s/", dns_domain)); torture_fail(tctx, err_msg); }; realm_canonical_ex = ldb_dn_canonical_ex_string(mem_ctx, realm_dn); if (strcmp(realm_canonical_ex, talloc_asprintf(mem_ctx, "%s\n", dns_domain))!= 0) { err_msg = talloc_asprintf(mem_ctx, "local Round trip on canonical ex name failed: %s != %s!", realm_canonical, talloc_asprintf(mem_ctx, "%s\n", dns_domain)); torture_fail(tctx, err_msg); }; r.in.req->req1.format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT; r.in.req->req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779; names[0].str = nt4_domain; torture_comment(tctx, "Testing DsCrackNames with name '%s' desired format:%d\n", names[0].str, r.in.req->req1.format_desired); status = dcerpc_drsuapi_DsCrackNames_r(p->binding_handle, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { const char *errstr = nt_errstr(status); err_msg = talloc_asprintf(mem_ctx, "dcerpc_drsuapi_DsCrackNames failed - %s", errstr); torture_fail(tctx, err_msg); } else if (!W_ERROR_IS_OK(r.out.result)) { err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed - %s", win_errstr(r.out.result)); torture_fail(tctx, err_msg); } else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) { err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed on name - %d", r.out.ctr->ctr1->array[0].status); torture_fail(tctx, err_msg); } priv->domain_obj_dn = r.out.ctr->ctr1->array[0].result_name; r.in.req->req1.format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT; r.in.req->req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779; names[0].str = talloc_asprintf(mem_ctx, "%s%s$", nt4_domain, test_dc); torture_comment(tctx, "Testing DsCrackNames with name '%s' desired format:%d\n", names[0].str, r.in.req->req1.format_desired); status = dcerpc_drsuapi_DsCrackNames_r(p->binding_handle, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { const char *errstr = nt_errstr(status); err_msg = talloc_asprintf(mem_ctx, "dcerpc_drsuapi_DsCrackNames failed - %s", errstr); torture_fail(tctx, err_msg); } else if (!W_ERROR_IS_OK(r.out.result)) { err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed - %s", win_errstr(r.out.result)); torture_fail(tctx, err_msg); } else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) { err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed on name - %d", r.out.ctr->ctr1->array[0].status); torture_fail(tctx, err_msg); } FQDN_1779_name = r.out.ctr->ctr1->array[0].result_name; r.in.req->req1.format_offered = DRSUAPI_DS_NAME_FORMAT_GUID; r.in.req->req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779; names[0].str = priv->domain_guid_str; torture_comment(tctx, "Testing DsCrackNames with name '%s' desired format:%d\n", names[0].str, r.in.req->req1.format_desired); status = dcerpc_drsuapi_DsCrackNames_r(p->binding_handle, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { const char *errstr = nt_errstr(status); err_msg = talloc_asprintf(mem_ctx, "dcerpc_drsuapi_DsCrackNames failed - %s", errstr); torture_fail(tctx, err_msg); } else if (!W_ERROR_IS_OK(r.out.result)) { err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed - %s", win_errstr(r.out.result)); torture_fail(tctx, err_msg); } else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) { err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed on name - %d", r.out.ctr->ctr1->array[0].status); torture_fail(tctx, err_msg); } if (strcmp(priv->domain_dns_name, r.out.ctr->ctr1->array[0].dns_domain_name) != 0) { err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed to return same DNS name - expected %s got %s", priv->domain_dns_name, r.out.ctr->ctr1->array[0].dns_domain_name); torture_fail(tctx, err_msg); } FQDN_1779_dn = ldb_dn_new(mem_ctx, ldb, FQDN_1779_name); canonical_name = ldb_dn_canonical_string(mem_ctx, FQDN_1779_dn); canonical_ex_name = ldb_dn_canonical_ex_string(mem_ctx, FQDN_1779_dn); user_principal_name = talloc_asprintf(mem_ctx, "%s$@%s", test_dc, dns_domain); /* form up a user@DOMAIN */ user_principal_name_short = talloc_asprintf(mem_ctx, "%s$@%s", test_dc, nt4_domain); /* variable nt4_domain includs a trailing \ */ user_principal_name_short[strlen(user_principal_name_short) - 1] = '\0'; service_principal_name = talloc_asprintf(mem_ctx, "HOST/%s", test_dc); { struct { enum drsuapi_DsNameFormat format_offered; enum drsuapi_DsNameFormat format_desired; const char *comment; const char *str; const char *expected_str; const char *expected_dns; enum drsuapi_DsNameStatus status; enum drsuapi_DsNameStatus alternate_status; enum drsuapi_DsNameFlags flags; bool skip; } crack[] = { { .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL, .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779, .str = user_principal_name, .expected_str = FQDN_1779_name, .status = DRSUAPI_DS_NAME_STATUS_OK }, { .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL, .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779, .str = user_principal_name_short, .expected_str = FQDN_1779_name, .status = DRSUAPI_DS_NAME_STATUS_OK }, { .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, struct smb_krb5_context *smb_krb5_context, uint32_t format_flags, enum drsuapi_DsNameFormat format_offered, enum drsuapi_DsNameFormat format_desired, struct ldb_dn *name_dn, const char *name, const char *domain_filter, const char *result_filter, struct drsuapi_DsNameInfo1 *info1, int scope, struct ldb_dn *search_dn) { 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; 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\n", 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 = ldb_msg_find_attr_as_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; uint32_t dsdb_flags = 0; struct ldb_dn *real_search_dn = NULL; info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; /* * From 4.1.4.2.11 of MS-DRSR * if DS_NAME_FLAG_GCVERIFY in flags then * rt := select all O from all * where attrValue in GetAttrVals(O, att, false) * else * rt := select all O from subtree DefaultNC() * where attrValue in GetAttrVals(O, att, false) * endif * return rt */ if (format_flags & DRSUAPI_DS_NAME_FLAG_GCVERIFY || format_offered == DRSUAPI_DS_NAME_FORMAT_GUID) { dsdb_flags = DSDB_SEARCH_SEARCH_ALL_PARTITIONS; } else if (domain_res) { if (!search_dn) { struct ldb_dn *tmp_dn = samdb_result_dn(sam_ctx, mem_ctx, domain_res->msgs[0], "ncName", NULL); real_search_dn = tmp_dn; } else { real_search_dn = search_dn; } } else { real_search_dn = ldb_get_default_basedn(sam_ctx); } if (format_desired == DRSUAPI_DS_NAME_FORMAT_GUID){ dsdb_flags |= DSDB_SEARCH_SHOW_RECYCLED; } /* search with the 'phantom root' flag */ ret = dsdb_search(sam_ctx, mem_ctx, &res, real_search_dn, scope, result_attrs, dsdb_flags, "%s", result_filter); if (ret != LDB_SUCCESS) { DEBUG(2, ("DsCrackNameOneFilter search from '%s' with flags 0x%08x failed: %s\n", ldb_dn_get_linearized(real_search_dn), dsdb_flags, 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) { ldb_ret = gendb_search_dn(sam_ctx, mem_ctx, name_dn, &result_res, result_attrs); } else if (domain_res) { name_dn = samdb_result_dn(sam_ctx, mem_ctx, domain_res->msgs[0], "ncName", NULL); ldb_ret = gendb_search_dn(sam_ctx, mem_ctx, name_dn, &result_res, result_attrs); } else { /* Can't happen */ DEBUG(0, ("LOGIC ERROR: DsCrackNameOneFilter domain ref search not available: This can't happen...\n")); info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR; return WERR_OK; } switch (ldb_ret) { case 1: result = result_res[0]; break; case 0: switch (format_offered) { case DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL: return DsCrackNameSPNAlias(sam_ctx, mem_ctx, smb_krb5_context, format_flags, format_offered, format_desired, name, info1); case DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL: return DsCrackNameUPN(sam_ctx, mem_ctx, smb_krb5_context, format_flags, format_offered, format_desired, name, info1); default: break; } info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; return WERR_OK; case -1: DEBUG(2, ("DsCrackNameOneFilter result search failed: %s\n", ldb_errstring(sam_ctx))); info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR; return WERR_OK; default: switch (format_offered) { case DRSUAPI_DS_NAME_FORMAT_CANONICAL: case DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX: { const char *canonical_name = NULL; /* Not required, but we get warnings... */ /* We may need to manually filter further */ for (i = 0; i < ldb_ret; i++) { switch (format_offered) { case DRSUAPI_DS_NAME_FORMAT_CANONICAL: canonical_name = ldb_dn_canonical_string(mem_ctx, result_res[i]->dn); break; case DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX: canonical_name = ldb_dn_canonical_ex_string(mem_ctx, result_res[i]->dn); break; default: break; } if (strcasecmp_m(canonical_name, name) == 0) { result = result_res[i]; break; } } if (!result) { info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; return WERR_OK; } } /* FALL TROUGH */ default: info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE; return WERR_OK; } } info1->dns_domain_name = ldb_dn_canonical_string(mem_ctx, result->dn); W_ERROR_HAVE_NO_MEMORY(info1->dns_domain_name); p = strchr(info1->dns_domain_name, '/'); if (p) { p[0] = '\0'; } /* here we can use result and domain_res[0] */ switch (format_desired) { case DRSUAPI_DS_NAME_FORMAT_FQDN_1779: { info1->result_name = ldb_dn_alloc_linearized(mem_ctx, result->dn); W_ERROR_HAVE_NO_MEMORY(info1->result_name); info1->status = DRSUAPI_DS_NAME_STATUS_OK; return WERR_OK; } case DRSUAPI_DS_NAME_FORMAT_CANONICAL: { info1->result_name = ldb_msg_find_attr_as_string(result, "canonicalName", NULL); info1->status = DRSUAPI_DS_NAME_STATUS_OK; return WERR_OK; } case DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX: { /* Not in the virtual ldb attribute */ return DsCrackNameOneSyntactical(mem_ctx, DRSUAPI_DS_NAME_FORMAT_FQDN_1779, DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX, result->dn, name, info1); } case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT: { const struct dom_sid *sid = samdb_result_dom_sid(mem_ctx, result, "objectSid"); const char *_acc = "", *_dom = ""; if (sid == NULL) { info1->status = DRSUAPI_DS_NAME_STATUS_NO_MAPPING; return WERR_OK; } if (samdb_find_attribute(sam_ctx, result, "objectClass", "domain")) { /* This can also find a DomainDNSZones entry, * but it won't have the SID we just * checked. */ ldb_ret = ldb_search(sam_ctx, mem_ctx, &domain_res, partitions_basedn, LDB_SCOPE_ONELEVEL, domain_attrs, "(ncName=%s)", ldb_dn_get_linearized(result->dn)); if (ldb_ret != LDB_SUCCESS) { DEBUG(2, ("DsCrackNameOneFilter domain ref search failed: %s\n", 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; } _dom = ldb_msg_find_attr_as_string(domain_res->msgs[0], "nETBIOSName", NULL); W_ERROR_HAVE_NO_MEMORY(_dom); } else { _acc = ldb_msg_find_attr_as_string(result, "sAMAccountName", NULL); if (!_acc) { info1->status = DRSUAPI_DS_NAME_STATUS_NO_MAPPING; return WERR_OK; } if (dom_sid_in_domain(dom_sid_parse_talloc(mem_ctx, SID_BUILTIN), sid)) { _dom = "BUILTIN"; } else { const char *attrs[] = { NULL }; struct ldb_result *domain_res2; struct dom_sid *dom_sid = dom_sid_dup(mem_ctx, sid); if (!dom_sid) { return WERR_OK; } dom_sid->num_auths--; ldb_ret = ldb_search(sam_ctx, mem_ctx, &domain_res, NULL, LDB_SCOPE_BASE, attrs, "(&(objectSid=%s)(objectClass=domain))", ldap_encode_ndr_dom_sid(mem_ctx, dom_sid)); if (ldb_ret != LDB_SUCCESS) { DEBUG(2, ("DsCrackNameOneFilter domain search failed: %s\n", 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; } ldb_ret = ldb_search(sam_ctx, mem_ctx, &domain_res2, partitions_basedn, LDB_SCOPE_ONELEVEL, domain_attrs, "(ncName=%s)", ldb_dn_get_linearized(domain_res->msgs[0]->dn)); if (ldb_ret != LDB_SUCCESS) { DEBUG(2, ("DsCrackNameOneFilter domain ref search failed: %s\n", ldb_errstring(sam_ctx))); info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR; return WERR_OK; } switch (domain_res2->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; } _dom = ldb_msg_find_attr_as_string(domain_res2->msgs[0], "nETBIOSName", NULL); W_ERROR_HAVE_NO_MEMORY(_dom); } } info1->result_name = talloc_asprintf(mem_ctx, "%s\\%s", _dom, _acc); W_ERROR_HAVE_NO_MEMORY(info1->result_name); info1->status = DRSUAPI_DS_NAME_STATUS_OK; return WERR_OK; } case DRSUAPI_DS_NAME_FORMAT_GUID: { struct GUID guid; guid = samdb_result_guid(result, "objectGUID"); info1->result_name = GUID_string2(mem_ctx, &guid); W_ERROR_HAVE_NO_MEMORY(info1->result_name); info1->status = DRSUAPI_DS_NAME_STATUS_OK; return WERR_OK; } case DRSUAPI_DS_NAME_FORMAT_DISPLAY: { info1->result_name = ldb_msg_find_attr_as_string(result, "displayName", NULL); if (!info1->result_name) { info1->result_name = ldb_msg_find_attr_as_string(result, "sAMAccountName", NULL); } if (!info1->result_name) { info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; } else { info1->status = DRSUAPI_DS_NAME_STATUS_OK; } return WERR_OK; } case DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL: { info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE; return WERR_OK; } case DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN: case DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY: { info1->dns_domain_name = NULL; info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR; return WERR_OK; } default: info1->status = DRSUAPI_DS_NAME_STATUS_NO_MAPPING; return WERR_OK; } }