diff options
-rw-r--r-- | source4/librpc/idl/netlogon.idl | 23 | ||||
-rw-r--r-- | source4/rpc_server/netlogon/dcerpc_netlogon.c | 45 | ||||
-rw-r--r-- | source4/torture/rpc/netlogon.c | 44 |
3 files changed, 107 insertions, 5 deletions
diff --git a/source4/librpc/idl/netlogon.idl b/source4/librpc/idl/netlogon.idl index 45632a022d..0f44c0616d 100644 --- a/source4/librpc/idl/netlogon.idl +++ b/source4/librpc/idl/netlogon.idl @@ -1007,7 +1007,28 @@ interface netlogon /****************/ /* Function 0x22 */ - WERROR netr_DSRGETDCNAMEEX2(); + typedef struct { + unistr *dc_unc; + unistr *dc_address; + int32 dc_address_type; + GUID domain_guid; + unistr *domain_name; + unistr *forest_name; + uint32 dc_flags; + unistr *dc_site_name; + unistr *client_site_name; + } netr_DrsGetDCNameEx2Info; + + WERROR netr_DrsGetDCNameEx2( + [in] unistr *server_unc, + [in] unistr *client_account, + [in] uint32 mask, + [in] unistr *domain_name, + [in] GUID *domain_guid, + [in] unistr *site_name, + [in] uint32 flags, + [out] netr_DrsGetDCNameEx2Info *info + ); /****************/ /* Function 0x23 */ diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index c4a4208667..00e27c75a8 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -1045,12 +1045,49 @@ static WERROR netr_DSRADDRESSTOSITENAMESW(struct dcesrv_call_state *dce_call, TA /* - netr_DSRGETDCNAMEEX2 + netr_DrsGetDCNameEx2 */ -static WERROR netr_DSRGETDCNAMEEX2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, - struct netr_DSRGETDCNAMEEX2 *r) +static WERROR netr_DrsGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct netr_DrsGetDCNameEx2 *r) { - DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); + const char * const attrs[] = { "dnsDomain", "objectGUID", NULL }; + void *sam_ctx; + struct ldb_message **res; + int ret; + + ZERO_STRUCT(r->out); + + sam_ctx = samdb_connect(mem_ctx); + if (sam_ctx == NULL) { + return WERR_DS_SERVICE_UNAVAILABLE; + } + + ret = samdb_search(sam_ctx, mem_ctx, NULL, &res, attrs, + "(&(objectClass=domainDNS)(dnsDomain=%s))", + r->in.domain_name); + if (ret != 1) { + return WERR_NO_SUCH_DOMAIN; + } + + r->out.info = talloc_p(mem_ctx, struct netr_DrsGetDCNameEx2Info); + if (!r->out.info) { + return WERR_NOMEM; + } + + /* TODO: - return real IP address + * - check all r->in.* parameters (server_unc is ignored by w2k3!) + */ + r->out.info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s", lp_netbios_name(),lp_realm()); + r->out.info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0"); + r->out.info->dc_address_type = 1; + r->out.info->domain_guid = samdb_result_guid(res[0], "objectGUID"); + r->out.info->domain_name = samdb_result_string(res[0], "dnsDomain", NULL); + r->out.info->forest_name = samdb_result_string(res[0], "dnsDomain", NULL); + r->out.info->dc_flags = 0xE00001FD; + r->out.info->dc_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name"); + r->out.info->client_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name"); + + return WERR_OK; } diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c index 9c87106550..a23cdb8b0c 100644 --- a/source4/torture/rpc/netlogon.c +++ b/source4/torture/rpc/netlogon.c @@ -887,6 +887,46 @@ static BOOL test_DsrEnumerateDomainTrusts(struct dcerpc_pipe *p, TALLOC_CTX *mem return True; } +/* + try a netlogon netr_DrsGetDCNameEx2 +*/ +static BOOL test_netr_DrsGetDCNameEx2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) +{ + NTSTATUS status; + struct netr_DrsGetDCNameEx2 r; + BOOL ret = True; + + r.in.server_unc = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p)); + r.in.client_account = NULL; + r.in.mask = 0x00000000; + r.in.domain_name = talloc_asprintf(mem_ctx, "%s", lp_realm()); + r.in.domain_guid = NULL; + r.in.site_name = NULL; + r.in.flags = 0x40000000; + + printf("Testing netr_DrsGetDCNameEx2 without client account\n"); + + status = dcerpc_netr_DrsGetDCNameEx2(p, mem_ctx, &r); + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) { + printf("netr_DrsGetDCNameEx2 - %s/%s\n", + nt_errstr(status), win_errstr(r.out.result)); + ret = False; + } + + printf("Testing netr_DrsGetDCNameEx2 with client acount\n"); + r.in.client_account = TEST_MACHINE_NAME"$"; + r.in.mask = 0x00002000; + r.in.flags = 0x80000000; + + status = dcerpc_netr_DrsGetDCNameEx2(p, mem_ctx, &r); + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) { + printf("netr_DrsGetDCNameEx2 - %s/%s\n", + nt_errstr(status), win_errstr(r.out.result)); + ret = False; + } + + return ret; +} static BOOL test_GetDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) { @@ -1122,6 +1162,10 @@ BOOL torture_rpc_netlogon(void) ret = False; } + if (!test_netr_DrsGetDCNameEx2(p, mem_ctx)) { + ret = False; + } + talloc_destroy(mem_ctx); torture_rpc_close(p); |