From 1df008ff9bba026af064563a1b5c1ac1f282d90a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 29 Sep 2010 20:36:40 +0200 Subject: [PATCH 1/6] TODO vaildate chars s4:rpc_server/netlogon: netr_GetDcName should return WERR_DCNOTFOUND for invalid names Only netbios domain names are allowed. metze --- source4/rpc_server/netlogon/dcerpc_netlogon.c | 14 ++++++++++++++ 1 files changed, 14 insertions(+), 0 deletions(-) diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index dee4dc4..0a1a2af 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -940,6 +940,20 @@ static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_C int ret; const char *dcname; + /* + * [MS-NRPC] 3.5.5.3.4 NetrGetDCName says + * that the domainname needs to be a valid netbios domain + * name, if it is not NULL. + */ + if (r->in.domainname) { + const char *dot = strchr(r->in.domainname, '.'); + size_t len = strlen(r->in.domainname); + + if (dot || len > 15) { + return WERR_DCNOTFOUND; + } + } + sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info); -- 1.7.0.4 From 9e7b9ef95c5d3a48604158be96cdf3777f012f65 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 29 Sep 2010 23:17:14 +0200 Subject: [PATCH 2/6] NT_STATUS_NO_TRUST_SAM_ACCOUNT ... --- source4/rpc_server/netlogon/dcerpc_netlogon.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 0a1a2af..794c617 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -157,7 +157,7 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca if (num_records == 0) { DEBUG(3,("Couldn't find trust [%s] in samdb.\n", encoded_account)); - return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_NO_TRUST_SAM_ACCOUNT; } if (num_records > 1) { @@ -188,7 +188,7 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca if (num_records == 0) { DEBUG(3,("Couldn't find user [%s] in samdb.\n", r->in.account_name)); - return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_NO_TRUST_SAM_ACCOUNT; } if (num_records > 1) { -- 1.7.0.4 From b4b7c50ae438be5fe022afb286090d8af578f277 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 30 Sep 2010 00:26:33 +0200 Subject: [PATCH 3/6] netlogon.idl: add missing flags to DSGETDC_VALID_FLAGS metze --- librpc/idl/netlogon.idl | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/librpc/idl/netlogon.idl b/librpc/idl/netlogon.idl index 1685cf9..b3612ab 100644 --- a/librpc/idl/netlogon.idl +++ b/librpc/idl/netlogon.idl @@ -1105,6 +1105,9 @@ interface netlogon DS_ONLY_LDAP_NEEDED | DS_IS_FLAT_NAME | DS_IS_DNS_NAME | + DS_TRY_NEXTCLOSEST_SITE | + DS_DIRECTORY_SERVICE_6_REQUIRED | + DS_WEB_SERVICE_REQUIRED | DS_RETURN_FLAT_NAME | DS_RETURN_DNS_NAME); -- 1.7.0.4 From 96e5fd1677bd362d7d6b75c27fe980350d8aabdd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 30 Sep 2010 00:27:52 +0200 Subject: [PATCH 4/6] s4:rpc_server/netlogon: validate flags in netr_DsRGetDCNameEx2() and callers Thanks to Tarun Chopra for the help of looking up all the bits in the docs. metze --- source4/rpc_server/netlogon/dcerpc_netlogon.c | 39 +++++++++++++++++++++++- 1 files changed, 37 insertions(+), 2 deletions(-) diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 794c617..20dc5d4 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -1584,6 +1584,43 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, /* "server_unc" is ignored by w2k3 */ + if (r->in.flags & ~(DSGETDC_VALID_FLAGS)) { + return WERR_INVALID_FLAGS; + } + + if (r->in.flags & DS_GC_SERVER_REQUIRED && + r->in.flags & DS_PDC_REQUIRED && + r->in.flags & DS_KDC_REQUIRED) { + return WERR_INVALID_FLAGS; + } + if (r->in.flags & DC_IS_FLAT_NAME && + r->in.flags & DC_IS_DNS_NAME) { + return WERR_INVALID_FLAGS; + } + if (r->in.flags & DC_RETURN_DNS_NAME && + r->in.flags & DC_RETURN_FLAT_NAME) + return WERR_INVALID_FLAGS; + } + if (r->in.flags & DS_DIRECTORY_SERVICE_REQUIRED && + r->in.flags & DS_DIRECTORY_SERVICE_6_REQUIRED) + return WERR_INVALID_FLAGS; + } + + if (r->in.flags & DS_TIMESERV_REQUIRED && + r->in.flags & + (DS_DIRECTORY_SERVICE_PREFERRED | + DS_DIRECTORY_SERVICE_PREFERRED | + DS_GC_SERVER_REQUIRED | + DS_PDC_REQUIRED | + DS_KDC_REQUIRED)) { + return WERR_INVALID_FLAGS; + } + + if (r->in.flags & DS_TRY_NEXTCLOSEST_SITE && + r->in.site_name) + return WERR_INVALID_FLAGS; + } + /* Proof server site parameter "site_name" if it was specified */ server_site_name = samdb_server_site_name(sam_ctx, mem_ctx); W_ERROR_HAVE_NO_MEMORY(server_site_name); @@ -1592,8 +1629,6 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, return WERR_NO_SUCH_DOMAIN; } - /* TODO: the flags are ignored for now */ - guid_str = r->in.domain_guid != NULL ? GUID_string(mem_ctx, r->in.domain_guid) : NULL; -- 1.7.0.4 From d69e6d8ef55fd4122c3d0671811ce269f885ee97 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 30 Sep 2010 00:29:48 +0200 Subject: [PATCH 5/6] s4:rpc_server/netlogon: handle DC_RETURN_NETBIOS and DC_RETURN_DNS in netr_DsRGetDCNameEx2() metze --- source4/rpc_server/netlogon/dcerpc_netlogon.c | 32 ++++++++++++++++++++++-- 1 files changed, 29 insertions(+), 3 deletions(-) diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 20dc5d4..abcee6a 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -1567,6 +1567,8 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, char *guid_str; struct netlogon_samlogon_response response; NTSTATUS status; + const char *dc_name = NULL; + const char *domain_name = NULL; ZERO_STRUCTP(r->out.info); @@ -1644,17 +1646,41 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, return ntstatus_to_werror(status); } + if (r->in.flags & DC_RETURN_DNS) { + dc_name = response.data.nt5_ex.pdc_dns_name; + domain_name = response.data.nt5_ex.dns_domain; + } else if (r->in.flags & DC_RETURN_NETBIOS) { + dc_name = response.data.nt5_ex.pdc_name; + domain_name = response.data.nt5_ex.domain_name; + } else { + + /* + * TODO: autodetect what we need to return + * based on the given arguments + */ + dc_name = response.data.nt5_ex.pdc_name; + domain_name = response.data.nt5_ex.domain_name; + } + + if (!dc_name || !dc_name[0]) { + return WERR_NO_SUCH_DOMAIN; + } + + if (!domain_name || !domain_name[0]) { + return WERR_NO_SUCH_DOMAIN; + } + info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo); W_ERROR_HAVE_NO_MEMORY(info); - info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s", - response.data.nt5_ex.pdc_dns_name); + if (r->in.flags & DC_RETURN_DNS) { + info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s", dc_name); W_ERROR_HAVE_NO_MEMORY(info->dc_unc); info->dc_address = talloc_asprintf(mem_ctx, "\\\\%s", response.data.nt5_ex.sockaddr.pdc_ip); W_ERROR_HAVE_NO_MEMORY(info->dc_address); info->dc_address_type = DS_ADDRESS_TYPE_INET; /* TODO: make this dynamic? for ipv6 */ info->domain_guid = response.data.nt5_ex.domain_uuid; - info->domain_name = response.data.nt5_ex.dns_domain; + info->domain_name = domain_name; info->forest_name = response.data.nt5_ex.forest; info->dc_flags = response.data.nt5_ex.server_type; info->dc_site_name = response.data.nt5_ex.server_site; -- 1.7.0.4 From 5ea38b0e6781fd2d8db54fe83f45bd03b3db398c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 30 Sep 2010 00:33:18 +0200 Subject: [PATCH 6/6] s4:rpc_server/netlogon: fix comment in netr_DsRGetDCName() metze --- source4/rpc_server/netlogon/dcerpc_netlogon.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index abcee6a..3bae0b2 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -1733,7 +1733,7 @@ static WERROR dcesrv_netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLO r2.in.domain_name = r->in.domain_name; r2.in.domain_guid = r->in.domain_guid; - r2.in.site_name = NULL; /* should fill in from site GUID */ + r2.in.site_name = NULL; /* this is correct, we should ignore site GUID */ r2.in.flags = r->in.flags; r2.out.info = r->out.info; -- 1.7.0.4