diff options
-rw-r--r-- | source4/rpc_server/drsuapi/dcesrv_drsuapi.c | 5 | ||||
-rw-r--r-- | source4/rpc_server/drsuapi/dcesrv_drsuapi.h | 2 | ||||
-rw-r--r-- | source4/rpc_server/drsuapi/drsuapi_cracknames.c | 163 |
3 files changed, 154 insertions, 16 deletions
diff --git a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c index 468d608f4f..c758f70da7 100644 --- a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c +++ b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c @@ -50,6 +50,11 @@ static WERROR drsuapi_DsBind(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem WERR_TALLOC_CHECK(b_state); /* TODO: fill b_state here */ + b_state->sam_ctx = samdb_connect(b_state); + if (!b_state->sam_ctx) { + talloc_free(b_state); + return WERR_FOOBAR; + } handle = dcesrv_handle_new(dce_call->conn, DRSUAPI_BIND_HANDLE); if (!handle) { diff --git a/source4/rpc_server/drsuapi/dcesrv_drsuapi.h b/source4/rpc_server/drsuapi/dcesrv_drsuapi.h index 4c31d4d710..15eace70e1 100644 --- a/source4/rpc_server/drsuapi/dcesrv_drsuapi.h +++ b/source4/rpc_server/drsuapi/dcesrv_drsuapi.h @@ -31,5 +31,5 @@ enum drsuapi_handle { state asscoiated with a drsuapi_DsBind*() operation */ struct drsuapi_bind_state { - uint8_t __dummy; + void *sam_ctx; }; diff --git a/source4/rpc_server/drsuapi/drsuapi_cracknames.c b/source4/rpc_server/drsuapi/drsuapi_cracknames.c index 72b3da1733..a0802d0dcd 100644 --- a/source4/rpc_server/drsuapi/drsuapi_cracknames.c +++ b/source4/rpc_server/drsuapi/drsuapi_cracknames.c @@ -26,12 +26,21 @@ #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" static WERROR DsCrackNameOneName(struct drsuapi_bind_state *b_state, TALLOC_CTX *mem_ctx, uint32 format_offered, uint32 format_desired, const char *name, struct drsuapi_DsNameInfo1 *info1) { + int ret; + const char *domain_filter; + const char * const *domain_attrs; + struct ldb_message **domain_res; + const char *result_basedn; + const char *result_filter = NULL; + const char * const *result_attrs; + struct ldb_message **result_res; + info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR; info1->dns_domain_name = NULL; info1->result_name = NULL; @@ -39,7 +48,6 @@ static WERROR DsCrackNameOneName(struct drsuapi_bind_state *b_state, TALLOC_CTX /* TODO: fill crack the correct names in all cases! */ switch (format_offered) { case DRSUAPI_DS_NAME_FORMAT_CANONICAL: { - int ret; char *str; str = talloc_asprintf(mem_ctx, "%s/", lp_realm()); @@ -52,20 +60,43 @@ static WERROR DsCrackNameOneName(struct drsuapi_bind_state *b_state, TALLOC_CTX return WERR_OK; } - info1->status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY; - info1->dns_domain_name = talloc_asprintf(mem_ctx, "%s", lp_realm()); - WERR_TALLOC_CHECK(info1->dns_domain_name); - switch (format_desired) { - case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT: - info1->status = DRSUAPI_DS_NAME_STATUS_OK; - info1->result_name = talloc_asprintf(mem_ctx, "%s\\", - lp_workgroup()); - WERR_TALLOC_CHECK(info1->result_name); - return WERR_OK; - default: - return WERR_OK; + domain_filter = talloc_asprintf(mem_ctx, "(&(objectClass=domainDNS)(name=%s))", + lp_workgroup()); + 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_RESOLVE_ERROR; + return WERR_OK; + } + p[0] = '\0'; + + if (p[1]) { + account = &p[1]; + } + + domain_filter = talloc_asprintf(mem_ctx, "(&(objectClass=domainDNS)(name=%s))", + domain); + WERR_TALLOC_CHECK(domain_filter); + if (account) { + result_filter = talloc_asprintf(mem_ctx, "(sAMAccountName=%s)", + account); + WERR_TALLOC_CHECK(result_filter); } - return WERR_INVALID_PARAM; + + talloc_free(domain); + break; } default: { info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; @@ -73,6 +104,108 @@ static WERROR DsCrackNameOneName(struct drsuapi_bind_state *b_state, TALLOC_CTX } } + switch (format_desired) { + case DRSUAPI_DS_NAME_FORMAT_FQDN_1779: { + const char * const _domain_attrs[] = { "dn", "dnsDomain", NULL}; + const char * const _result_attrs[] = { "dn", NULL}; + + domain_attrs = _domain_attrs; + result_attrs = _result_attrs; + break; + } + case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT: { + const char * const _domain_attrs[] = { "name", "dnsDomain", "dn", NULL}; + const char * const _result_attrs[] = { "sAMAccountName", NULL}; + + domain_attrs = _domain_attrs; + result_attrs = _result_attrs; + break; + } + case DRSUAPI_DS_NAME_FORMAT_GUID: { + const char * const _domain_attrs[] = { "objectGUID", "dnsDomain", "dn", NULL}; + const char * const _result_attrs[] = { "objectGUID", NULL}; + + domain_attrs = _domain_attrs; + result_attrs = _result_attrs; + break; + } + default: + return WERR_OK; + } + + ret = samdb_search(b_state->sam_ctx, mem_ctx, NULL, &domain_res, domain_attrs, + "%s", domain_filter); + switch (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], "dnsDomain", NULL); + WERR_TALLOC_CHECK(info1->dns_domain_name); + info1->status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY; + + if (result_filter) { + result_basedn = samdb_result_string(domain_res[0], "dn", NULL); + + ret = samdb_search(b_state->sam_ctx, mem_ctx, result_basedn, &result_res, + result_attrs, "%s", result_filter); + switch (ret) { + case 1: + break; + case 0: + 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; + } + } else { + result_res = domain_res; + } + + switch (format_desired) { + case DRSUAPI_DS_NAME_FORMAT_FQDN_1779: { + info1->result_name = samdb_result_string(result_res[0], "dn", NULL); + WERR_TALLOC_CHECK(info1->result_name); + info1->status = DRSUAPI_DS_NAME_STATUS_OK; + return WERR_OK; + } + case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT: { + const char *_dom = samdb_result_string(domain_res[0], "name", NULL); + const char *_acc = ""; + WERR_TALLOC_CHECK(_dom); + if (result_filter) { + _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: { + const char *result = samdb_result_string(result_res[0], "objectGUID", NULL); + WERR_TALLOC_CHECK(result); + info1->result_name = talloc_asprintf(mem_ctx, "{%s}", result); + WERR_TALLOC_CHECK(info1->result_name); + info1->status = DRSUAPI_DS_NAME_STATUS_OK; + return WERR_OK; + } + default: + return WERR_OK; + } + return WERR_INVALID_PARAM; } |