summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
Diffstat (limited to 'source4')
-rw-r--r--source4/rpc_server/drsuapi/dcesrv_drsuapi.c5
-rw-r--r--source4/rpc_server/drsuapi/dcesrv_drsuapi.h2
-rw-r--r--source4/rpc_server/drsuapi/drsuapi_cracknames.c163
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;
}