summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/librpc/idl/netlogon.idl23
-rw-r--r--source4/rpc_server/netlogon/dcerpc_netlogon.c45
-rw-r--r--source4/torture/rpc/netlogon.c44
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);