[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Thu Dec 12 02:01:03 UTC 2019


The branch, master has been updated
       via  3f69c6b1328 selftest: Do not force the endpoint for fsrvp tests
       via  4a608b281cf s4:torture/rpc: Fix torture comment in mdssvc.c
       via  e24ce0023fa pidl:NDR/Server: Allow to define endpoint server shutdown functions
       via  79af978c815 librpc:core: Add a function to reinitialize the dcesrv_context
       via  90eb485cf9d librpc:core: Add public functions to initialize endpoint servers
       via  39dfc5c82b2 librpc:core: Split dcesrv context init and endpoint servers init
       via  fee5c6a4247 librpc/idl/dnsserver.idl: Ensure DnsProperty id matches what is pulled from the stored buffer
       via  ee4617ec5f4 librpc dnsp test: Ensure length matches union selector
      from  049f0c38701 lib/krb5_wrap: Remove unused smb_krb5_get_allowed_weak_crypto()

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 3f69c6b1328cda318f78620d19616411705b7034
Author: Samuel Cabrero <scabrero at suse.de>
Date:   Thu Mar 7 11:35:07 2019 +0100

    selftest: Do not force the endpoint for fsrvp tests
    
    The test suite will bind to the srvsvc interface, let it find the
    correct endpoint through the endpoint mapper.
    
    Signed-off-by: Samuel Cabrero <scabrero at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Thu Dec 12 02:00:19 UTC 2019 on sn-devel-184

commit 4a608b281cf945b0550d1bf81971f690a5e7ed8a
Author: Samuel Cabrero <scabrero at suse.de>
Date:   Mon Nov 4 18:39:10 2019 +0100

    s4:torture/rpc: Fix torture comment in mdssvc.c
    
    Signed-off-by: Samuel Cabrero <scabrero at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit e24ce0023fa00a33d22f5f475e9280a8cad612c3
Author: Samuel Cabrero <scabrero at samba.org>
Date:   Fri Sep 6 15:16:01 2019 +0200

    pidl:NDR/Server: Allow to define endpoint server shutdown functions
    
    The next commits will register legacy api_struct when the endpoint server
    is initialized. This commit adds a shutdown function which will be used
    to unregister the legacy api_struct.
    
    The shutdown function will be also used to replace the rpc_srv_callbacks
    struct shutdown member used, for example, by the spoolss service to
    cleanup before exiting.
    
    Signed-off-by: Samuel Cabrero <scabrero at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 79af978c815e6ad94797742c8755f4fe8142160e
Author: Samuel Cabrero <scabrero at samba.org>
Date:   Tue Oct 1 16:59:07 2019 +0200

    librpc:core: Add a function to reinitialize the dcesrv_context
    
    Clears all registered endpoints and interfaces, association groups and
    broken connections.
    
    To be used by S3 forked daemons.
    
    Signed-off-by: Samuel Cabrero <scabrero at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 90eb485cf9d8eaecfab31044e52e8f41b3a51452
Author: Samuel Cabrero <scabrero at samba.org>
Date:   Fri Sep 6 14:38:29 2019 +0200

    librpc:core: Add public functions to initialize endpoint servers
    
    The dcesrv_init_registered_ep_servers() will be used by the S3 server to
    initialize all registered endpoint servers (for embedded services), and
    the dcesrv_init_ep_server() function will be used by the external
    daemons to initialize the required ones.
    
    As serveral S3 services may require to initialize another one before
    itself (svcctl and eventlog for example require winreg) a boolean flag is
    added to track the initialization status.
    
    Signed-off-by: Samuel Cabrero <scabrero at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 39dfc5c82b2345f2eee7d14f6f2cc3ee8b2aef3d
Author: Samuel Cabrero <scabrero at suse.de>
Date:   Tue Feb 5 18:54:02 2019 +0100

    librpc:core: Split dcesrv context init and endpoint servers init
    
    The S4 server will initialize the endpoint servers specified in smb.conf,
    but the S3 server need to initialize all registered endpoint servers (the
    embedded ones).
    
    Signed-off-by: Samuel Cabrero <scabrero at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit fee5c6a4247aeac71318186bbff7708d25de5912
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Dec 2 11:20:31 2019 +1300

    librpc/idl/dnsserver.idl: Ensure DnsProperty id matches what is pulled from the stored buffer
    
    There are two concerns here, assuming the attacker can place arbitary values
    in a dnsProperty attribute over LDAP (eg is a DNS administrator).
    
    This comes from the fact that id is used as the switch value at the C layer
    but at the NDR layer the wDataLength value is considered first.
    
    One concern is that a pull/push round-trip could include server memory:
    
     The previous switch_is() behaviour could store the server memory back
     into the attribute.
    
     However this pattern of pull/push only happens in ndrdump and fuzzing tools, as
     dnsserver_db_do_reset_dword() operates only on the uint32/bitmap union
     arms, and fully initialises those.
    
    The other is that a pull of the attacker-supplied value could
    cause the server to expose memory.
    
     This would be over the network via DNS or the RPC dnsserver protocols.
     However at all times the ndr_pull_struct_blob is passed zeroed memory.
    
    The final concern (which fuzz_ndr_X found) is that in the ndr_size_dnsPropertyData()
    the union descriminent is only id.
    
     This has no impact as only zeroed memory is used so there will be a
     zero value in all scalars, including data->d_ns_servers.AddrArray.
    
     Therefore the server will not crash processing the attacker-supplied blob
    
    [MS-DNSP] 2.3.2.1 dnsProperty has no mention of this special behaviour.
    https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dnsp/445c7843-e4a1-4222-8c0f-630c230a4c80
    
    This was known as CVE-2019-14908 before being triaged back to a normal bug.
    
    Found by Douglas Bagnall using Hongfuzz and the new fuzz_ndr_X fuzzer.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14206
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Gary Lockyer <gary at samba.org>

commit ee4617ec5f4017e7ee3bbc29102054e7b64f3e3a
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Mon Dec 9 09:19:47 2019 +1300

    librpc dnsp test: Ensure length matches union selector
    
    Ensure that a dnsp_DnsProperty is rejected if the length data does not not
    correspond to the length indicated by the union id.  It was possible for
    the union to be referencing memory past the end of the structure.
    
    Found by Douglas Bagnall using Hongfuzz and the new fuzz_ndr_X fuzzer.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=14206
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 librpc/idl/dnsp.idl                       |   2 +-
 librpc/rpc/dcesrv_core.c                  | 162 ++++++++++++++++++++++++++----
 librpc/rpc/dcesrv_core.h                  |  17 +++-
 pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm  |  13 +++
 source3/selftest/tests.py                 |   2 +-
 source4/rpc_server/remote/dcesrv_remote.c |   9 ++
 source4/rpc_server/service_rpc.c          |   8 +-
 source4/torture/ndr/dnsp.c                |  23 +++++
 source4/torture/ndr/ndr.c                 |  67 ++++++++++++
 source4/torture/ndr/ndr.h                 |  20 ++++
 source4/torture/rpc/mdssvc.c              |   2 +-
 source4/torture/rpc/spoolss_notify.c      |  17 +++-
 12 files changed, 316 insertions(+), 26 deletions(-)


Changeset truncated at 500 lines:

diff --git a/librpc/idl/dnsp.idl b/librpc/idl/dnsp.idl
index 1bbcaca6bfa..814d573cddf 100644
--- a/librpc/idl/dnsp.idl
+++ b/librpc/idl/dnsp.idl
@@ -257,7 +257,7 @@ interface dnsp
 		[value(0)] uint32   flag;
 		[value(1)] uint32   version;
 		dns_property_id     id;
-		[switch_is(wDataLength?id:DSPROPERTY_ZONE_EMPTY)]     dnsPropertyData data;
+		[switch_is(id)]     dnsPropertyData data;
 		uint32              name;
 	} dnsp_DnsProperty;
 }
diff --git a/librpc/rpc/dcesrv_core.c b/librpc/rpc/dcesrv_core.c
index daa95afcab7..4148c3f0f1a 100644
--- a/librpc/rpc/dcesrv_core.c
+++ b/librpc/rpc/dcesrv_core.c
@@ -2320,18 +2320,10 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
 
 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
 				      struct loadparm_context *lp_ctx,
-				      const char **endpoint_servers,
 				      struct dcesrv_context_callbacks *cb,
 				      struct dcesrv_context **_dce_ctx)
 {
-	NTSTATUS status;
 	struct dcesrv_context *dce_ctx;
-	int i;
-
-	if (!endpoint_servers) {
-		DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
-		return NT_STATUS_INTERNAL_ERROR;
-	}
 
 	dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
 	NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
@@ -2353,24 +2345,59 @@ _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
 		dce_ctx->callbacks = *cb;
 	}
 
-	for (i=0;endpoint_servers[i];i++) {
-		const struct dcesrv_endpoint_server *ep_server;
+	*_dce_ctx = dce_ctx;
+	return NT_STATUS_OK;
+}
 
-		ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
-		if (!ep_server) {
-			DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
-			return NT_STATUS_INTERNAL_ERROR;
-		}
+_PUBLIC_ NTSTATUS dcesrv_reinit_context(struct dcesrv_context *dce_ctx)
+{
+	NTSTATUS status;
+
+	status = dcesrv_shutdown_registered_ep_servers(dce_ctx);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	/* Clear endpoints */
+	while (dce_ctx->endpoint_list != NULL) {
+		struct dcesrv_endpoint *e = dce_ctx->endpoint_list;
+		DLIST_REMOVE(dce_ctx->endpoint_list, e);
+		TALLOC_FREE(e);
+	}
+
+	/* Remove broken connections */
+	dcesrv_cleanup_broken_connections(dce_ctx);
+
+	/* Reinit assoc group idr */
+	TALLOC_FREE(dce_ctx->assoc_groups_idr);
+	dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
+	if (dce_ctx->assoc_groups_idr == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
 
-		status = ep_server->init_server(dce_ctx, ep_server);
+	return NT_STATUS_OK;
+}
+
+_PUBLIC_ NTSTATUS dcesrv_init_ep_servers(struct dcesrv_context *dce_ctx,
+					 const char **endpoint_servers)
+{
+	NTSTATUS status;
+	int i;
+
+	if (endpoint_servers == NULL) {
+		DBG_ERR("No endpoint servers configured\n");
+		return NT_STATUS_INTERNAL_ERROR;
+	}
+
+	for (i=0;endpoint_servers[i];i++) {
+		status = dcesrv_init_ep_server(dce_ctx, endpoint_servers[i]);
 		if (!NT_STATUS_IS_OK(status)) {
-			DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
-				nt_errstr(status)));
+			DBG_ERR("failed to init endpoint server = '%s': %s\n",
+				endpoint_servers[i], nt_errstr(status));
 			return status;
 		}
 	}
 
-	*_dce_ctx = dce_ctx;
 	return NT_STATUS_OK;
 }
 
@@ -2381,6 +2408,103 @@ static struct ep_server {
 } *ep_servers = NULL;
 static int num_ep_servers = 0;
 
+_PUBLIC_ NTSTATUS dcesrv_init_registered_ep_servers(
+					struct dcesrv_context *dce_ctx)
+{
+	NTSTATUS status;
+	int i;
+
+	for (i = 0; i < num_ep_servers; i++) {
+		status = dcesrv_init_ep_server(dce_ctx,
+					       ep_servers[i].ep_server->name);
+		if (!NT_STATUS_IS_OK(status)) {
+			return status;
+		}
+	}
+
+	return NT_STATUS_OK;
+}
+
+_PUBLIC_ NTSTATUS dcesrv_init_ep_server(struct dcesrv_context *dce_ctx,
+					const char *ep_server_name)
+{
+	struct dcesrv_endpoint_server *ep_server = NULL;
+	NTSTATUS status;
+
+	ep_server = discard_const_p(struct dcesrv_endpoint_server,
+				    dcesrv_ep_server_byname(ep_server_name));
+	if (ep_server == NULL) {
+		DBG_ERR("Failed to find endpoint server '%s'\n",
+			ep_server_name);
+		return NT_STATUS_INTERNAL_ERROR;
+	}
+
+	if (ep_server->initialized) {
+		return NT_STATUS_OK;
+	}
+
+	status = ep_server->init_server(dce_ctx, ep_server);
+	if (!NT_STATUS_IS_OK(status)) {
+		DBG_ERR("Failed to init endpoint server '%s': %s\n",
+			ep_server_name, nt_errstr(status));
+		return status;
+	}
+
+	ep_server->initialized = true;
+
+	return NT_STATUS_OK;
+}
+
+_PUBLIC_ NTSTATUS dcesrv_shutdown_registered_ep_servers(
+					struct dcesrv_context *dce_ctx)
+{
+	NTSTATUS status;
+	int i;
+
+	for (i = 0; i < num_ep_servers; i++) {
+		status = dcesrv_shutdown_ep_server(dce_ctx,
+					ep_servers[i].ep_server->name);
+		if (!NT_STATUS_IS_OK(status)) {
+			return status;
+		}
+	}
+
+	return NT_STATUS_OK;
+}
+
+_PUBLIC_ NTSTATUS dcesrv_shutdown_ep_server(struct dcesrv_context *dce_ctx,
+					    const char *ep_server_name)
+{
+	struct dcesrv_endpoint_server *ep_server = NULL;
+	NTSTATUS status;
+
+	ep_server = discard_const_p(struct dcesrv_endpoint_server,
+				    dcesrv_ep_server_byname(ep_server_name));
+	if (ep_server == NULL) {
+		DBG_ERR("Failed to find endpoint server '%s'\n",
+			ep_server_name);
+		return NT_STATUS_INTERNAL_ERROR;
+	}
+
+	if (!ep_server->initialized) {
+		return NT_STATUS_OK;
+	}
+
+	DBG_INFO("Shutting down DCE/RPC endpoint server '%s'\n",
+		 ep_server_name);
+
+	status = ep_server->shutdown_server(dce_ctx, ep_server);
+	if (!NT_STATUS_IS_OK(status)) {
+		DBG_ERR("Failed to shutdown endpoint server '%s': %s\n",
+			ep_server_name, nt_errstr(status));
+		return status;
+	}
+
+	ep_server->initialized = false;
+
+	return NT_STATUS_OK;
+}
+
 /*
   register a DCERPC endpoint server.
 
diff --git a/librpc/rpc/dcesrv_core.h b/librpc/rpc/dcesrv_core.h
index 5e47976ced9..74ce956032e 100644
--- a/librpc/rpc/dcesrv_core.h
+++ b/librpc/rpc/dcesrv_core.h
@@ -325,11 +325,18 @@ struct dcesrv_endpoint_server {
 	/* this is the name of the endpoint server */
 	const char *name;
 
+	/* true if the endpoint server has been initialized */
+	bool initialized;
+
 	/* this function should register endpoints and some other setup stuff,
 	 * it is called when the dcesrv_context gets initialized.
 	 */
 	NTSTATUS (*init_server)(struct dcesrv_context *, const struct dcesrv_endpoint_server *);
 
+	/* this function should cleanup endpoint server state and unregister
+	 * the endpoint server from dcesrv_context */
+	NTSTATUS (*shutdown_server)(struct dcesrv_context *, const struct dcesrv_endpoint_server *);
+
 	/* this function can be used by other endpoint servers to
 	 * ask for a dcesrv_interface implementation
 	 * - iface must be reference to an already existing struct !
@@ -444,13 +451,21 @@ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
 				   const struct dcesrv_interface *iface,
 				   const struct security_descriptor *sd);
 NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server);
+NTSTATUS dcesrv_init_ep_servers(struct dcesrv_context *dce_ctx,
+				const char **ep_servers);
+NTSTATUS dcesrv_init_registered_ep_servers(struct dcesrv_context *dce_ctx);
+NTSTATUS dcesrv_shutdown_registered_ep_servers(struct dcesrv_context *dce_ctx);
+NTSTATUS dcesrv_init_ep_server(struct dcesrv_context *dce_ctx,
+			       const char *ep_server_name);
+NTSTATUS dcesrv_shutdown_ep_server(struct dcesrv_context *dce_ctx,
+				   const char *name);
 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name);
 
 NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
 			     struct loadparm_context *lp_ctx,
-			     const char **endpoint_servers,
 			     struct dcesrv_context_callbacks *cb,
 			     struct dcesrv_context **_dce_ctx);
+NTSTATUS dcesrv_reinit_context(struct dcesrv_context *dce_ctx);
 
 NTSTATUS dcesrv_reply(struct dcesrv_call_state *call);
 struct dcesrv_handle *dcesrv_handle_create(struct dcesrv_call_state *call,
diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm
index 01974ed244b..eed7d799c0e 100644
--- a/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm
@@ -240,6 +240,11 @@ static NTSTATUS $name\__op_init_server(struct dcesrv_context *dce_ctx, const str
 	return NT_STATUS_OK;
 }
 
+static NTSTATUS $name\__op_shutdown_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server)
+{
+	return NT_STATUS_OK;
+}
+
 static bool $name\__op_interface_by_uuid(struct dcesrv_interface *iface, const struct GUID *uuid, uint32_t if_version)
 {
 	if (dcesrv_$name\_interface.syntax_id.if_version == if_version &&
@@ -268,11 +273,19 @@ NTSTATUS dcerpc_server_$name\_init(TALLOC_CTX *ctx)
 	    /* fill in our name */
 	    .name = \"$name\",
 
+	    /* Initialization flag */
+	    .initialized = false,
+
 	    /* fill in all the operations */
 #ifdef DCESRV_INTERFACE_$uname\_INIT_SERVER
 	    .init_server = DCESRV_INTERFACE_$uname\_INIT_SERVER,
 #else
 	    .init_server = $name\__op_init_server,
+#endif
+#ifdef DCESRV_INTERFACE_$uname\_SHUTDOWN_SERVER
+	    .shutdown_server = DCESRV_INTERFACE_$uname\_SHUTDOWN_SERVER,
+#else
+	    .shutdown_server = $name\__op_shutdown_server,
 #endif
 	    .interface_by_uuid = $name\__op_interface_by_uuid,
 	    .interface_by_name = $name\__op_interface_by_name
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index f1434c860d3..25aa08a79f5 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -885,7 +885,7 @@ for e in endianness_options:
             plansmbtorture4testsuite(test, "nt4_dc", options, 'over ncacn_ip_tcp with [%s%s%s] ' % (a, s, e))
 
 plansmbtorture4testsuite('rpc.epmapper', 'nt4_dc:local', 'ncalrpc: -U$USERNAME%$PASSWORD', 'over ncalrpc')
-plansmbtorture4testsuite('rpc.fsrvp', 'nt4_dc:local', 'ncacn_np:$SERVER_IP[/pipe/FssagentRpc] -U$USERNAME%$PASSWORD', 'over ncacn_np')
+plansmbtorture4testsuite('rpc.fsrvp', 'nt4_dc:local', 'ncacn_np:$SERVER_IP -U$USERNAME%$PASSWORD', 'over ncacn_np')
 
 for env in ["ad_member_idmap_rid:local", "maptoguest:local"]:
     plantestsuite("samba3.blackbox.guest", env,
diff --git a/source4/rpc_server/remote/dcesrv_remote.c b/source4/rpc_server/remote/dcesrv_remote.c
index 8de9190e03e..825c4cd9bd2 100644
--- a/source4/rpc_server/remote/dcesrv_remote.c
+++ b/source4/rpc_server/remote/dcesrv_remote.c
@@ -446,6 +446,12 @@ static NTSTATUS remote_op_init_server(struct dcesrv_context *dce_ctx, const stru
 	return NT_STATUS_OK;
 }
 
+static NTSTATUS remote_op_shutdown_server(struct dcesrv_context *dce_ctx,
+				const struct dcesrv_endpoint_server *ep_server)
+{
+	return NT_STATUS_OK;
+}
+
 static bool remote_fill_interface(struct dcesrv_interface *iface, const struct ndr_interface_table *if_tabl)
 {
 	iface->name = if_tabl->name;
@@ -496,8 +502,11 @@ NTSTATUS dcerpc_server_remote_init(TALLOC_CTX *ctx)
 		/* fill in our name */
 		.name = "remote",
 
+		.initialized = false,
+
 		/* fill in all the operations */
 		.init_server = remote_op_init_server,
+		.shutdown_server = remote_op_shutdown_server,
 
 		.interface_by_uuid = remote_op_interface_by_uuid,
 		.interface_by_name = remote_op_interface_by_name
diff --git a/source4/rpc_server/service_rpc.c b/source4/rpc_server/service_rpc.c
index ef4bfab237a..96ebc2dbe57 100644
--- a/source4/rpc_server/service_rpc.c
+++ b/source4/rpc_server/service_rpc.c
@@ -129,6 +129,7 @@ static NTSTATUS dcesrv_task_init(struct task_server *task)
 {
 	NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
 	struct dcesrv_context *dce_ctx;
+	const char **ep_servers = NULL;
 
 	dcerpc_server_init(task->lp_ctx);
 
@@ -136,13 +137,18 @@ static NTSTATUS dcesrv_task_init(struct task_server *task)
 
 	status = dcesrv_init_context(task->event_ctx,
 				     task->lp_ctx,
-				     lpcfg_dcerpc_endpoint_servers(task->lp_ctx),
 				     &srv_callbacks,
 				     &dce_ctx);
 	if (!NT_STATUS_IS_OK(status)) {
 		return status;
 	}
 
+	ep_servers = lpcfg_dcerpc_endpoint_servers(task->lp_ctx);
+	status = dcesrv_init_ep_servers(dce_ctx, ep_servers);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
 	/* Make sure the directory for NCALRPC exists */
 	if (!directory_exist(lpcfg_ncalrpc_dir(task->lp_ctx))) {
 		mkdir(lpcfg_ncalrpc_dir(task->lp_ctx), 0755);
diff --git a/source4/torture/ndr/dnsp.c b/source4/torture/ndr/dnsp.c
index 07bebeceb01..3d0cd942d11 100644
--- a/source4/torture/ndr/dnsp.c
+++ b/source4/torture/ndr/dnsp.c
@@ -337,6 +337,23 @@ static bool dnsp_dnsProperty_deleted_by_check(struct torture_context *tctx,
 	return true;
 }
 
+/*
+ * Copy of dnsp_dnsProperty_deleted_by_b64 with wDataLength set to 0
+ * and no data in the data element.
+ * This is a reproducer for https://bugzilla.samba.org/show_bug.cgi?id=14206
+ * The dns_property_id was retained so once parsed this structure referenced
+ * memory past it's end.
+ *
+ * [0000] 00 00 00 00 01 EE C4 71   00 00 00 00 01 00 00 00   &......q ........
+ * [0010] 80 00 00 00 77 00 32 00   6B 00 33 00 2D 00 31 00   ....w.2. k.3.-.1.
+ * [0020] 39 00 31 00 2E 00 77 00   32 00 6B 00 33 00 2E 00   9.1...w. 2.k.3...
+ * [0030] 62 00 61 00 73 00 65 00   00 00 C4 71 EC F3         b.a.s.e. ...q..
+ */
+static const uint8_t dnsp_dnsProperty_deleted_by_zero_wDataLength[] = {
+	0x00, 0x00, 0x00, 0x00, 0x01, 0xEE, 0xC4, 0x71, 0x00, 0x00, 0x00,
+	0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+	0xC4, 0x71, 0xEC, 0xF3 };
+
 struct torture_suite *ndr_dnsp_suite(TALLOC_CTX *ctx)
 {
 	struct torture_suite *suite = torture_suite_create(ctx, "dnsp");
@@ -362,5 +379,11 @@ struct torture_suite *ndr_dnsp_suite(TALLOC_CTX *ctx)
 		dnsp_dnsProperty_deleted_by_b64,
 		dnsp_dnsProperty_deleted_by_check);
 
+	torture_suite_add_ndr_pull_invalid_data_test(
+		suite,
+		dnsp_DnsProperty,
+		dnsp_dnsProperty_deleted_by_zero_wDataLength,
+		NDR_ERR_BUFSIZE);
+
 	return suite;
 }
diff --git a/source4/torture/ndr/ndr.c b/source4/torture/ndr/ndr.c
index e65a39ddb7f..32efe90757d 100644
--- a/source4/torture/ndr/ndr.c
+++ b/source4/torture/ndr/ndr.c
@@ -35,6 +35,7 @@ struct ndr_pull_test_data {
 	ndr_print_function_t print_function;
 	int ndr_flags;
 	int flags;
+	enum ndr_err_code ndr_err;
 };
 
 static enum ndr_err_code torture_ndr_push_struct_blob_flags(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, uint32_t flags, uint32_t ndr_flags, const void *p, ndr_push_flags_fn_t fn)
@@ -301,6 +302,72 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_inout_test(
 	return test;
 }
 
+static bool wrap_ndr_pull_invalid_data_test(struct torture_context *tctx,
+					    struct torture_tcase *tcase,
+					    struct torture_test *test)
+{
+	const struct ndr_pull_test_data *data = (const struct ndr_pull_test_data *)test->data;
+	struct ndr_pull *ndr = ndr_pull_init_blob(&(data->data), tctx);
+	void *ds = talloc_zero_size(ndr, data->struct_size);
+	bool ret = true;
+
+	torture_assert(tctx, data, "out of memory");
+	torture_assert(tctx, ndr, "out of memory");
+	torture_assert(tctx, ds, "out of memory");
+
+	ndr->flags |= data->flags;
+
+	ndr->flags |= LIBNDR_FLAG_REF_ALLOC;
+
+	torture_assert_ndr_err_equal(
+		tctx,
+		data->pull_fn(ndr, data->ndr_flags, ds),
+		NDR_ERR_BUFSIZE,
+		"pulling invalid data");
+
+	talloc_free(ndr);
+	return ret;
+}
+
+_PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_invalid_data_test(
+	struct torture_suite *suite,
+	const char *name,
+	ndr_pull_flags_fn_t pull_fn,
+	DATA_BLOB db,
+	size_t struct_size,
+	int ndr_flags,
+	int flags,
+	enum ndr_err_code ndr_err)
+{
+	struct torture_test *test;
+	struct torture_tcase *tcase;
+	struct ndr_pull_test_data *data;
+
+	tcase = torture_suite_add_tcase(suite, name);
+
+	test = talloc(tcase, struct torture_test);
+
+	test->name = talloc_strdup(test, name);
+	test->description = NULL;
+	test->run = wrap_ndr_pull_invalid_data_test;
+
+	data = talloc_zero(test, struct ndr_pull_test_data);
+	data->data = db;
+	data->ndr_flags = ndr_flags;
+	data->flags = flags;
+	data->struct_size = struct_size;
+	data->pull_fn = pull_fn;
+	data->ndr_err = ndr_err;
+
+	test->data = data;
+	test->fn = NULL;
+	test->dangerous = false;
+
+	DLIST_ADD_END(tcase->tests, test);
+
+	return test;
+}
+
 static bool test_check_string_terminator(struct torture_context *tctx)
 {
 	struct ndr_pull *ndr;
diff --git a/source4/torture/ndr/ndr.h b/source4/torture/ndr/ndr.h
index 58ab19354ab..0cc21825fb4 100644
--- a/source4/torture/ndr/ndr.h
+++ b/source4/torture/ndr/ndr.h
@@ -48,6 +48,16 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_inout_test(
 					int flags,
 					bool (*check_fn) (struct torture_context *ctx, void *data));
 


-- 
Samba Shared Repository



More information about the samba-cvs mailing list