diff options
Diffstat (limited to 'source4/rpc_server')
-rw-r--r-- | source4/rpc_server/config.mk | 2 | ||||
-rw-r--r-- | source4/rpc_server/drsuapi/dcesrv_drsuapi.c | 53 | ||||
-rw-r--r-- | source4/rpc_server/drsuapi/drsuapi_cracknames.c | 830 |
3 files changed, 50 insertions, 835 deletions
diff --git a/source4/rpc_server/config.mk b/source4/rpc_server/config.mk index 1d6913c40b..821c60978a 100644 --- a/source4/rpc_server/config.mk +++ b/source4/rpc_server/config.mk @@ -176,8 +176,6 @@ INIT_FUNCTION = dcerpc_server_drsuapi_init SUBSYSTEM = DCERPC INIT_OBJ_FILES = \ drsuapi/dcesrv_drsuapi.o -ADD_OBJ_FILES = \ - drsuapi/drsuapi_cracknames.o REQUIRED_SUBSYSTEMS = \ SAMDB \ DCERPC_COMMON \ diff --git a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c index c8578a7cc1..a762b44878 100644 --- a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c +++ b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c @@ -201,10 +201,57 @@ static WERROR DRSUAPI_GET_NT4_CHANGELOG(struct dcesrv_call_state *dce_call, TALL /* - drsuapi_DsCrackNames => drsuapip_cracknames.c + drsuapi_DsCrackNames */ -static WERROR (*drsuapi_DsCrackNames)(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, - struct drsuapi_DsCrackNames *r) = dcesrv_drsuapi_DsCrackNames; +WERROR drsuapi_DsCrackNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct drsuapi_DsCrackNames *r) +{ + WERROR status; + struct drsuapi_bind_state *b_state; + struct dcesrv_handle *h; + + r->out.level = r->in.level; + ZERO_STRUCT(r->out.ctr); + + DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE); + b_state = h->data; + + switch (r->in.level) { + case 1: { + struct drsuapi_DsNameCtr1 *ctr1; + struct drsuapi_DsNameInfo1 *names; + int count; + int i; + + ctr1 = talloc(mem_ctx, struct drsuapi_DsNameCtr1); + WERR_TALLOC_CHECK(ctr1); + + count = r->in.req.req1.count; + names = talloc_array(mem_ctx, struct drsuapi_DsNameInfo1, count); + WERR_TALLOC_CHECK(names); + + for (i=0; i < count; i++) { + status = DsCrackNameOneName(b_state->sam_ctx, mem_ctx, + r->in.req.req1.format_flags, + r->in.req.req1.format_offered, + r->in.req.req1.format_desired, + r->in.req.req1.names[i].str, + &names[i]); + if (!W_ERROR_IS_OK(status)) { + return status; + } + } + + ctr1->count = count; + ctr1->array = names; + r->out.ctr.ctr1 = ctr1; + + return WERR_OK; + } + } + + return WERR_UNKNOWN_LEVEL; +} /* drsuapi_DsWriteAccountSpn diff --git a/source4/rpc_server/drsuapi/drsuapi_cracknames.c b/source4/rpc_server/drsuapi/drsuapi_cracknames.c deleted file mode 100644 index 3a4d337154..0000000000 --- a/source4/rpc_server/drsuapi/drsuapi_cracknames.c +++ /dev/null @@ -1,830 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - endpoint server for the drsuapi pipe - DsCrackNames() - - Copyright (C) Stefan Metzmacher 2004 - Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" -#include "librpc/gen_ndr/ndr_drsuapi.h" -#include "rpc_server/dcerpc_server.h" -#include "rpc_server/common/common.h" -#include "rpc_server/drsuapi/dcesrv_drsuapi.h" -#include "lib/ldb/include/ldb.h" -#include "system/kerberos.h" -#include "auth/kerberos/kerberos.h" - -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, - const struct ldb_dn *name_dn, const char *name, - const char *domain_filter, const char *result_filter, - struct drsuapi_DsNameInfo1 *info1); -static WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, - uint32_t format_flags, uint32_t format_offered, uint32_t format_desired, - const char *name, struct drsuapi_DsNameInfo1 *info1); - -static WERROR DsCrackNameOneSyntactical(TALLOC_CTX *mem_ctx, - uint32_t format_offered, uint32_t format_desired, - const struct ldb_dn *name_dn, const char *name, - struct drsuapi_DsNameInfo1 *info1); - -static enum drsuapi_DsNameStatus LDB_lookup_spn_alias(krb5_context context, struct ldb_context *ldb_ctx, - TALLOC_CTX *mem_ctx, - const char *alias_from, - char **alias_to) -{ - int i; - int count; - struct ldb_message **msg; - struct ldb_message_element *spnmappings; - struct ldb_dn *service_dn = ldb_dn_string_compose(mem_ctx, samdb_base_dn(mem_ctx), - "CN=Directory Service,CN=Windows NT" - ",CN=Services,CN=Configuration"); - char *service_dn_str = ldb_dn_linearize(mem_ctx, service_dn); - const char *directory_attrs[] = { - "sPNMappings", - NULL - }; - - count = ldb_search(ldb_ctx, service_dn, LDB_SCOPE_BASE, "(objectClass=nTDSService)", - directory_attrs, &msg); - talloc_steal(mem_ctx, msg); - - if (count < 1) { - DEBUG(1, ("ldb_search: dn: %s not found: %d", service_dn_str, count)); - return DRSUAPI_DS_NAME_STATUS_NOT_FOUND; - } else if (count > 1) { - DEBUG(1, ("ldb_search: dn: %s found %d times!", service_dn_str, count)); - return DRSUAPI_DS_NAME_STATUS_NOT_FOUND; - } - - spnmappings = ldb_msg_find_element(msg[0], "sPNMappings"); - if (!spnmappings || spnmappings->num_values == 0) { - DEBUG(1, ("ldb_search: dn: %s no sPNMappings attribute", service_dn_str)); - return DRSUAPI_DS_NAME_STATUS_NOT_FOUND; - } - - for (i = 0; i < spnmappings->num_values; i++) { - char *mapping, *p, *str; - mapping = talloc_strdup(mem_ctx, - (const char *)spnmappings->values[i].data); - if (!mapping) { - DEBUG(1, ("LDB_lookup_spn_alias: ldb_search: dn: %s did not have an sPNMapping\n", service_dn_str)); - return DRSUAPI_DS_NAME_STATUS_NOT_FOUND; - } - - /* C string manipulation sucks */ - - p = strchr(mapping, '='); - if (!p) { - DEBUG(1, ("ldb_search: dn: %s sPNMapping malformed: %s\n", - service_dn_str, mapping)); - return DRSUAPI_DS_NAME_STATUS_NOT_FOUND; - } - p[0] = '\0'; - p++; - do { - str = p; - p = strchr(p, ','); - if (p) { - p[0] = '\0'; - p++; - } - if (strcasecmp(str, alias_from) == 0) { - *alias_to = mapping; - return DRSUAPI_DS_NAME_STATUS_OK; - } - } while (p); - } - DEBUG(1, ("LDB_lookup_spn_alias: no alias for service %s applicable\n", alias_from)); - return DRSUAPI_DS_NAME_STATUS_NOT_FOUND; -} - -static WERROR DsCrackNameSPNAlias(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, - const char *name, struct drsuapi_DsNameInfo1 *info1) -{ - WERROR wret; - krb5_error_code ret; - krb5_principal principal; - const char *service; - char *new_service; - char *new_princ; - enum drsuapi_DsNameStatus namestatus; - - /* parse principal */ - ret = krb5_parse_name_norealm(smb_krb5_context->krb5_context, - name, &principal); - if (ret) { - DEBUG(2, ("Could not parse principal: %s: %s", - name, smb_get_krb5_error_message(smb_krb5_context->krb5_context, - ret, mem_ctx))); - return WERR_NOMEM; - } - - /* grab cifs/, http/ etc */ - - /* This is checked for in callers, but be safe */ - if (principal->name.name_string.len < 2) { - info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; - return WERR_OK; - } - service = principal->name.name_string.val[0]; - - /* MAP it */ - namestatus = LDB_lookup_spn_alias(smb_krb5_context->krb5_context, - sam_ctx, mem_ctx, - service, &new_service); - - if (namestatus != DRSUAPI_DS_NAME_STATUS_OK) { - info1->status = namestatus; - return WERR_OK; - } - - if (ret != 0) { - info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR; - return WERR_OK; - } - - /* ooh, very nasty playing around in the Principal... */ - free(principal->name.name_string.val[0]); - principal->name.name_string.val[0] = strdup(new_service); - if (!principal->name.name_string.val[0]) { - krb5_free_principal(smb_krb5_context->krb5_context, principal); - return WERR_NOMEM; - } - - /* reform principal */ - ret = krb5_unparse_name_norealm(smb_krb5_context->krb5_context, principal, &new_princ); - - krb5_free_principal(smb_krb5_context->krb5_context, principal); - - if (ret) { - return WERR_NOMEM; - } - - wret = DsCrackNameOneName(sam_ctx, mem_ctx, format_flags, format_offered, format_desired, - new_princ, info1); - free(new_princ); - return wret; -} - -static WERROR DsCrackNameUPN(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, - const char *name, struct drsuapi_DsNameInfo1 *info1) -{ - WERROR status; - const char *domain_filter = NULL; - const char *result_filter = NULL; - krb5_error_code ret; - krb5_principal principal; - char **realm; - char *unparsed_name_short; - - /* Prevent recursion */ - if (!name) { - info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; - return WERR_OK; - } - - ret = krb5_parse_name_mustrealm(smb_krb5_context->krb5_context, name, &principal); - if (ret) { - info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; - return WERR_OK; - } - - domain_filter = NULL; - realm = krb5_princ_realm(smb_krb5_context->krb5_context, principal); - domain_filter = talloc_asprintf(mem_ctx, - "(&(&(|(&(dnsRoot=%s)(nETBIOSName=*))(nETBIOSName=%s))(objectclass=crossRef))(ncName=*))", - *realm, *realm); - ret = krb5_unparse_name_norealm(smb_krb5_context->krb5_context, principal, &unparsed_name_short); - krb5_free_principal(smb_krb5_context->krb5_context, principal); - - if (ret) { - free(unparsed_name_short); - return WERR_NOMEM; - } - - /* This may need to be extended for more userPrincipalName variations */ - result_filter = talloc_asprintf(mem_ctx, "(&(objectClass=user)(samAccountName=%s))", - unparsed_name_short); - if (!result_filter || !domain_filter) { - free(unparsed_name_short); - return WERR_NOMEM; - } - status = DsCrackNameOneFilter(sam_ctx, mem_ctx, - smb_krb5_context, - format_flags, format_offered, format_desired, - NULL, unparsed_name_short, domain_filter, result_filter, - info1); - free(unparsed_name_short); - return status; -} - -static WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, - uint32_t format_flags, uint32_t format_offered, uint32_t format_desired, - const char *name, struct drsuapi_DsNameInfo1 *info1) -{ - krb5_error_code ret; - const char *domain_filter = NULL; - const char *result_filter = NULL; - struct ldb_dn *name_dn = NULL; - - struct smb_krb5_context *smb_krb5_context; - ret = smb_krb5_init_context(mem_ctx, &smb_krb5_context); - - if (ret) { - return WERR_NOMEM; - } - - info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR; - info1->dns_domain_name = NULL; - info1->result_name = NULL; - - if (!name) { - return WERR_INVALID_PARAM; - } - - /* TODO: - fill the correct names in all cases! - * - handle format_flags - */ - - /* here we need to set the domain_filter and/or the result_filter */ - switch (format_offered) { - case DRSUAPI_DS_NAME_FORMAT_CANONICAL: { - char *str; - - str = talloc_strdup(mem_ctx, name); - WERR_TALLOC_CHECK(str); - - if (strlen(str) == 0 || str[strlen(str)-1] != '/') { - info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR; - return WERR_OK; - } - - str[strlen(str)-1] = '\0'; - - domain_filter = talloc_asprintf(mem_ctx, - "(&(&(&(dnsRoot=%s)(objectclass=crossRef)))(nETBIOSName=*)(ncName=*))", - str); - WERR_TALLOC_CHECK(domain_filter); - - break; - } - case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT: { - char *p; - char *domain; - const char *account = NULL; - - domain = talloc_strdup(mem_ctx, name); - WERR_TALLOC_CHECK(domain); - - p = strchr(domain, '\\'); - if (!p) { - /* invalid input format */ - info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; - return WERR_OK; - } - p[0] = '\0'; - - if (p[1]) { - account = &p[1]; - } - - domain_filter = talloc_asprintf(mem_ctx, - "(&(&(nETBIOSName=%s)(objectclass=crossRef))(ncName=*))", - domain); - WERR_TALLOC_CHECK(domain_filter); - if (account) { - result_filter = talloc_asprintf(mem_ctx, "(sAMAccountName=%s)", - account); - WERR_TALLOC_CHECK(result_filter); - } - - talloc_free(domain); - break; - } - case DRSUAPI_DS_NAME_FORMAT_FQDN_1779: { - name_dn = ldb_dn_explode(mem_ctx, name); - domain_filter = NULL; - if (!name_dn) { - info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; - return WERR_OK; - } - break; - } - case DRSUAPI_DS_NAME_FORMAT_GUID: { - struct GUID guid; - char *ldap_guid; - NTSTATUS nt_status; - domain_filter = NULL; - - nt_status = GUID_from_string(name, &guid); - if (!NT_STATUS_IS_OK(nt_status)) { - info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; - return WERR_OK; - } - - ldap_guid = ldap_encode_ndr_GUID(mem_ctx, &guid); - if (!ldap_guid) { - return WERR_NOMEM; - } - result_filter = talloc_asprintf(mem_ctx, "(objectGUID=%s)", - ldap_guid); - WERR_TALLOC_CHECK(result_filter); - break; - } - case DRSUAPI_DS_NAME_FORMAT_DISPLAY: { - domain_filter = NULL; - - result_filter = talloc_asprintf(mem_ctx, "(|(displayName=%s)(samAccountName=%s))", - name, name); - WERR_TALLOC_CHECK(result_filter); - break; - } - - case DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY: { - struct dom_sid *sid = dom_sid_parse_talloc(mem_ctx, name); - char *ldap_sid; - - domain_filter = NULL; - if (!sid) { - info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; - return WERR_OK; - } - ldap_sid = ldap_encode_ndr_dom_sid(mem_ctx, - sid); - if (!ldap_sid) { - return WERR_NOMEM; - } - result_filter = talloc_asprintf(mem_ctx, "(objectSid=%s)", - ldap_sid); - WERR_TALLOC_CHECK(result_filter); - break; - } - case DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL: { - krb5_principal principal; - char *unparsed_name; - ret = krb5_parse_name(smb_krb5_context->krb5_context, name, &principal); - if (ret) { - info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; - return WERR_OK; - } - - domain_filter = NULL; - - ret = krb5_unparse_name(smb_krb5_context->krb5_context, principal, &unparsed_name); - if (ret) { - krb5_free_principal(smb_krb5_context->krb5_context, principal); - return WERR_NOMEM; - } - - krb5_free_principal(smb_krb5_context->krb5_context, principal); - result_filter = talloc_asprintf(mem_ctx, "(&(objectClass=user)(userPrincipalName=%s))", - unparsed_name); - - free(unparsed_name); - WERR_TALLOC_CHECK(result_filter); - break; - } - case DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL: { - krb5_principal principal; - char *unparsed_name_short; - ret = krb5_parse_name_norealm(smb_krb5_context->krb5_context, name, &principal); - if (ret || (principal->name.name_string.len < 2)) { - info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; - return WERR_OK; - } - - domain_filter = NULL; - - ret = krb5_unparse_name_norealm(smb_krb5_context->krb5_context, principal, &unparsed_name_short); - krb5_free_principal(smb_krb5_context->krb5_context, principal); - if (ret) { - return WERR_NOMEM; - } - - result_filter = talloc_asprintf(mem_ctx, "(&(objectClass=user)(servicePrincipalName=%s))", - unparsed_name_short); - free(unparsed_name_short); - WERR_TALLOC_CHECK(result_filter); - - break; - } - default: { - info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; - return WERR_OK; - } - - } - - if (format_flags & DRSUAPI_DS_NAME_FLAG_SYNTACTICAL_ONLY) { - return DsCrackNameOneSyntactical(mem_ctx, format_offered, format_desired, - name_dn, name, info1); - } - - return DsCrackNameOneFilter(sam_ctx, mem_ctx, - smb_krb5_context, - format_flags, format_offered, format_desired, - name_dn, name, - domain_filter, result_filter, - info1); -} - -static WERROR DsCrackNameOneSyntactical(TALLOC_CTX *mem_ctx, - uint32_t format_offered, uint32_t format_desired, - const 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; - -} - -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, - const 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_message **domain_res = NULL; - const char * const *domain_attrs; - const char * const *result_attrs; - struct ldb_message **result_res = NULL; - const struct ldb_dn *result_basedn; - - /* 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: { - const char * const _domain_attrs[] = { "ncName", "dnsRoot", NULL}; - const char * const _result_attrs[] = { NULL}; - - domain_attrs = _domain_attrs; - result_attrs = _result_attrs; - break; - } - case DRSUAPI_DS_NAME_FORMAT_CANONICAL: { - const char * const _domain_attrs[] = { "ncName", "dnsRoot", NULL}; - const char * const _result_attrs[] = { "canonicalName", NULL }; - - domain_attrs = _domain_attrs; - result_attrs = _result_attrs; - break; - } - case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT: { - const char * const _domain_attrs[] = { "ncName", "dnsRoot", "nETBIOSName", NULL}; - const char * const _result_attrs[] = { "sAMAccountName", "objectSid", NULL}; - - domain_attrs = _domain_attrs; - result_attrs = _result_attrs; - break; - } - case DRSUAPI_DS_NAME_FORMAT_GUID: { - const char * const _domain_attrs[] = { "ncName", "dnsRoot", NULL}; - const char * const _result_attrs[] = { "objectGUID", NULL}; - - domain_attrs = _domain_attrs; - result_attrs = _result_attrs; - break; - } - case DRSUAPI_DS_NAME_FORMAT_DISPLAY: { - const char * const _domain_attrs[] = { "ncName", "dnsRoot", NULL}; - const char * const _result_attrs[] = { "displayName", "samAccountName", NULL}; - - domain_attrs = _domain_attrs; - result_attrs = _result_attrs; - break; - } - default: - return WERR_OK; - } - - if (domain_filter) { - /* if we have a domain_filter look it up and set the result_basedn and the dns_domain_name */ - ldb_ret = gendb_search(sam_ctx, mem_ctx, NULL, &domain_res, domain_attrs, - "%s", domain_filter); - } else { - ldb_ret = gendb_search(sam_ctx, mem_ctx, NULL, &domain_res, domain_attrs, - "(ncName=%s)", ldb_dn_linearize(mem_ctx, samdb_base_dn(mem_ctx))); - } - - switch (ldb_ret) { - case 1: - break; - case 0: - info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; - return WERR_OK; - case -1: - info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR; - return WERR_OK; - default: - info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE; - return WERR_OK; - } - - info1->dns_domain_name = samdb_result_string(domain_res[0], "dnsRoot", NULL); - WERR_TALLOC_CHECK(info1->dns_domain_name); - info1->status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY; - - if (result_filter) { - result_basedn = samdb_result_dn(mem_ctx, domain_res[0], "ncName", NULL); - - ldb_ret = gendb_search(sam_ctx, mem_ctx, result_basedn, &result_res, - result_attrs, "%s", result_filter); - } 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 { - name_dn = samdb_result_dn(mem_ctx, domain_res[0], "ncName", NULL); - ldb_ret = gendb_search_dn(sam_ctx, mem_ctx, name_dn, &result_res, - result_attrs); - } - - switch (ldb_ret) { - case 1: - 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); - } - info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; - return WERR_OK; - case -1: - info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR; - return WERR_OK; - default: - info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE; - return WERR_OK; - } - - /* here we can use result_res[0] and domain_res[0] */ - switch (format_desired) { - case DRSUAPI_DS_NAME_FORMAT_FQDN_1779: { - info1->result_name = ldb_dn_linearize(mem_ctx, result_res[0]->dn); - WERR_TALLOC_CHECK(info1->result_name); - - info1->status = DRSUAPI_DS_NAME_STATUS_OK; - return WERR_OK; - } - case DRSUAPI_DS_NAME_FORMAT_CANONICAL: { - info1->result_name = samdb_result_string(result_res[0], "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_res[0]->dn, name, info1); - } - case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT: { - const struct dom_sid *sid = samdb_result_dom_sid(mem_ctx, result_res[0], "objectSid"); - const char *_acc = "", *_dom = ""; - - if ((sid->num_auths < 4) || (sid->num_auths > 5)) { - info1->status = DRSUAPI_DS_NAME_STATUS_NO_MAPPING; - return WERR_OK; - } - - if (sid->num_auths == 4) { - ldb_ret = gendb_search(sam_ctx, mem_ctx, NULL, &domain_res, domain_attrs, - "(ncName=%s)", ldb_dn_linearize(mem_ctx, result_res[0]->dn)); - if (ldb_ret != 1) { - info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; - return WERR_OK; - } - _dom = samdb_result_string(domain_res[0], "nETBIOSName", NULL); - WERR_TALLOC_CHECK(_dom); - - } else if (sid->num_auths == 5) { - const char *attrs[] = { NULL }; - struct ldb_message **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 = gendb_search(sam_ctx, mem_ctx, NULL, &domain_res, attrs, - "(objectSid=%s)", ldap_encode_ndr_dom_sid(mem_ctx, dom_sid)); - if (ldb_ret != 1) { - info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; - return WERR_OK; - } - ldb_ret = gendb_search(sam_ctx, mem_ctx, NULL, &domain_res2, domain_attrs, - "(ncName=%s)", ldb_dn_linearize(mem_ctx, domain_res[0]->dn)); - if (ldb_ret != 1) { - info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; - return WERR_OK; - } - - _dom = samdb_result_string(domain_res2[0], "nETBIOSName", NULL); - WERR_TALLOC_CHECK(_dom); - - _acc = samdb_result_string(result_res[0], "sAMAccountName", NULL); - WERR_TALLOC_CHECK(_acc); - } - - info1->result_name = talloc_asprintf(mem_ctx, "%s\\%s", _dom, _acc); - WERR_TALLOC_CHECK(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_res[0], "objectGUID"); - - info1->result_name = GUID_string2(mem_ctx, &guid); - WERR_TALLOC_CHECK(info1->result_name); - - info1->status = DRSUAPI_DS_NAME_STATUS_OK; - return WERR_OK; - } - case DRSUAPI_DS_NAME_FORMAT_DISPLAY: { - info1->result_name = samdb_result_string(result_res[0], "displayName", NULL); - if (!info1->result_name) { - info1->result_name = samdb_result_string(result_res[0], "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; - } - default: - return WERR_OK; - } - - return WERR_INVALID_PARAM; -} - -/* - drsuapi_DsCrackNames -*/ -WERROR dcesrv_drsuapi_DsCrackNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, - struct drsuapi_DsCrackNames *r) -{ - WERROR status; - struct drsuapi_bind_state *b_state; - struct dcesrv_handle *h; - - r->out.level = r->in.level; - ZERO_STRUCT(r->out.ctr); - - DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE); - b_state = h->data; - - switch (r->in.level) { - case 1: { - struct drsuapi_DsNameCtr1 *ctr1; - struct drsuapi_DsNameInfo1 *names; - int count; - int i; - - ctr1 = talloc(mem_ctx, struct drsuapi_DsNameCtr1); - WERR_TALLOC_CHECK(ctr1); - - count = r->in.req.req1.count; - names = talloc_array(mem_ctx, struct drsuapi_DsNameInfo1, count); - WERR_TALLOC_CHECK(names); - - for (i=0; i < count; i++) { - status = DsCrackNameOneName(b_state->sam_ctx, mem_ctx, - r->in.req.req1.format_flags, - r->in.req.req1.format_offered, - r->in.req.req1.format_desired, - r->in.req.req1.names[i].str, - &names[i]); - if (!W_ERROR_IS_OK(status)) { - return status; - } - } - - ctr1->count = count; - ctr1->array = names; - r->out.ctr.ctr1 = ctr1; - - return WERR_OK; - } - } - - return WERR_UNKNOWN_LEVEL; -} - -NTSTATUS crack_user_principal_name(struct ldb_context *sam_ctx, - TALLOC_CTX *mem_ctx, - const char *user_principal_name, - struct ldb_dn **user_dn, - struct ldb_dn **domain_dn) -{ - WERROR werr; - NTSTATUS status; - struct drsuapi_DsNameInfo1 info1; - werr = DsCrackNameOneName(sam_ctx, mem_ctx, 0, - DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL, - DRSUAPI_DS_NAME_FORMAT_FQDN_1779, - user_principal_name, - &info1); - if (!W_ERROR_IS_OK(werr)) { - return NT_STATUS_NO_MEMORY; - } - switch (info1.status) { - case DRSUAPI_DS_NAME_STATUS_OK: - break; - case DRSUAPI_DS_NAME_STATUS_NOT_FOUND: - case DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY: - case DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE: - return NT_STATUS_NO_SUCH_USER; - case DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR: - default: - return NT_STATUS_UNSUCCESSFUL; - } - - *user_dn = ldb_dn_explode(mem_ctx, info1.result_name); - - if (domain_dn) { - werr = DsCrackNameOneName(sam_ctx, mem_ctx, 0, - DRSUAPI_DS_NAME_FORMAT_CANONICAL, - DRSUAPI_DS_NAME_FORMAT_FQDN_1779, - talloc_asprintf(mem_ctx, "%s/", - info1.dns_domain_name), - &info1); - if (!W_ERROR_IS_OK(werr)) { - return NT_STATUS_NO_MEMORY; - } - switch (info1.status) { - case DRSUAPI_DS_NAME_STATUS_OK: - break; - case DRSUAPI_DS_NAME_STATUS_NOT_FOUND: - case DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY: - case DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE: - return NT_STATUS_NO_SUCH_USER; - case DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR: - default: - return NT_STATUS_UNSUCCESSFUL; - } - - *domain_dn = ldb_dn_explode(mem_ctx, info1.result_name); - } - - return NT_STATUS_OK; - -} |