[SCM] Samba Shared Repository - branch master updated

Volker Lendecke vlendec at samba.org
Tue Sep 21 11:00:01 UTC 2021


The branch, master has been updated
       via  af06d73a756 s3:rpc_server: Do not use the default ncalrpc endpoint for external services
       via  9c8521848bb librpc:core: Add a function to register an interface passing the binding handle
       via  99bf0c1b264 pidl:NDR/ServerCompat.pm: Do not register disabled services
      from  b09efc8b8b9 lib: Move closefrom_except*() to a separate file

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


- Log -----------------------------------------------------------------
commit af06d73a7563f6a7dec7653b7de1748de099b051
Author: Samuel Cabrero <scabrero at suse.de>
Date:   Mon Aug 23 14:27:49 2021 +0200

    s3:rpc_server: Do not use the default ncalrpc endpoint for external services
    
    In samba3 it is possible to run some services externally, for example:
    
    rpc_daemon:lsasd = fork
    rpc_server:netlogon = disabled
    rpc_server:samr = external
    rpc_server:lsarpc = external
    
    The external services running in separate processes have to use its own
    dedicated ncalrpc endpoint, otherwise will race with main smbd serving the
    embedded services to accept connections on ncalrpc default socket. If the
    connection ends in an external process and the client tries to bind to an
    interface not registered there (like winreg for example) the bind will fail.
    
    Signed-off-by: Samuel Cabrero <scabrero at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    
    Autobuild-User(master): Volker Lendecke <vl at samba.org>
    Autobuild-Date(master): Tue Sep 21 11:00:01 UTC 2021 on sn-devel-184

commit 9c8521848bb5fedb3501d03e564a759d8709f418
Author: Samuel Cabrero <scabrero at suse.de>
Date:   Thu Aug 19 12:52:04 2021 +0200

    librpc:core: Add a function to register an interface passing the binding handle
    
    Signed-off-by: Samuel Cabrero <scabrero at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 99bf0c1b2649f74a3199c59bbc16c6e604ff4e79
Author: Samuel Cabrero <scabrero at suse.de>
Date:   Mon Aug 23 14:23:58 2021 +0200

    pidl:NDR/ServerCompat.pm: Do not register disabled services
    
    In samba3 it is possible to disable RPC services, for exapmle:
    
    rpc_server:netlogon = disabled
    
    If a service is disabled do not register the interface neither create its
    endpoint.
    
    Signed-off-by: Samuel Cabrero <scabrero at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

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

Summary of changes:
 librpc/rpc/dcesrv_core.c                       | 80 +++++++++++++++++---------
 librpc/rpc/dcesrv_core.h                       |  5 ++
 pidl/lib/Parse/Pidl/Samba4/NDR/ServerCompat.pm | 62 +++++++++++++++++++-
 selftest/knownfail                             | 19 +++++-
 source3/rpc_server/rpc_ncacn_np.c              | 24 +++++++-
 source3/winbindd/winbindd_dual_ndr.c           | 10 ++++
 6 files changed, 169 insertions(+), 31 deletions(-)


Changeset truncated at 500 lines:

diff --git a/librpc/rpc/dcesrv_core.c b/librpc/rpc/dcesrv_core.c
index b75336d0a85..6a2e0c25e7f 100644
--- a/librpc/rpc/dcesrv_core.c
+++ b/librpc/rpc/dcesrv_core.c
@@ -176,11 +176,47 @@ _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
 				   const char *ncacn_np_secondary_endpoint,
 				   const struct dcesrv_interface *iface,
 				   const struct security_descriptor *sd)
+{
+	struct dcerpc_binding *binding = NULL;
+	struct dcerpc_binding *binding2 = NULL;
+	NTSTATUS ret;
+
+	ret = dcerpc_parse_binding(dce_ctx, ep_name, &binding);
+	if (NT_STATUS_IS_ERR(ret)) {
+		DBG_ERR("Trouble parsing binding string '%s'\n", ep_name);
+		goto out;
+	}
+
+	if (ncacn_np_secondary_endpoint != NULL) {
+		ret = dcerpc_parse_binding(dce_ctx,
+					   ncacn_np_secondary_endpoint,
+					   &binding2);
+		if (NT_STATUS_IS_ERR(ret)) {
+			DBG_ERR("Trouble parsing 2nd binding string '%s'\n",
+				ncacn_np_secondary_endpoint);
+			goto out;
+		}
+	}
+
+	ret = dcesrv_interface_register_b(dce_ctx,
+					  binding,
+					  binding2,
+					  iface,
+					  sd);
+out:
+	TALLOC_FREE(binding);
+	TALLOC_FREE(binding2);
+	return ret;
+}
+
+_PUBLIC_ NTSTATUS dcesrv_interface_register_b(struct dcesrv_context *dce_ctx,
+					struct dcerpc_binding *binding,
+					struct dcerpc_binding *binding2,
+					const struct dcesrv_interface *iface,
+					const struct security_descriptor *sd)
 {
 	struct dcesrv_endpoint *ep;
 	struct dcesrv_if_list *ifl;
-	struct dcerpc_binding *binding;
-	struct dcerpc_binding *binding2 = NULL;
 	bool add_ep = false;
 	NTSTATUS status;
 	enum dcerpc_transport_t transport;
@@ -201,13 +237,6 @@ _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
 		use_single_process = false;
 	}
 
-	status = dcerpc_parse_binding(dce_ctx, ep_name, &binding);
-
-	if (NT_STATUS_IS_ERR(status)) {
-		DEBUG(0, ("Trouble parsing binding string '%s'\n", ep_name));
-		return status;
-	}
-
 	transport = dcerpc_binding_get_transport(binding);
 	if (transport == NCACN_IP_TCP) {
 		int port;
@@ -245,26 +274,19 @@ _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
 		}
 	}
 
-	if (transport == NCACN_NP && ncacn_np_secondary_endpoint != NULL) {
+	if (transport == NCACN_NP && binding2 != NULL) {
 		enum dcerpc_transport_t transport2;
 
-		status = dcerpc_parse_binding(dce_ctx,
-					      ncacn_np_secondary_endpoint,
-					      &binding2);
-		if (!NT_STATUS_IS_OK(status)) {
-			DEBUG(0, ("Trouble parsing 2nd binding string '%s'\n",
-				  ncacn_np_secondary_endpoint));
-			return status;
-		}
-
 		transport2 = dcerpc_binding_get_transport(binding2);
 		SMB_ASSERT(transport2 == transport);
 	}
 
 	/* see if the interface is already registered on the endpoint */
 	if (find_interface_by_binding(dce_ctx, binding, iface)!=NULL) {
-		DEBUG(0,("dcesrv_interface_register: interface '%s' already registered on endpoint '%s'\n",
-			 iface->name, ep_name));
+		char *binding_string = dcerpc_binding_string(dce_ctx, binding);
+		DBG_ERR("Interface '%s' already registered on endpoint '%s'\n",
+			iface->name, binding_string);
+		TALLOC_FREE(binding_string);
 		return NT_STATUS_OBJECT_NAME_COLLISION;
 	}
 
@@ -299,8 +321,11 @@ _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
 		if (!ep) {
 			return NT_STATUS_NO_MEMORY;
 		}
-		ep->ep_description = talloc_move(ep, &binding);
-		ep->ep_2nd_description = talloc_move(ep, &binding2);
+		ep->ep_description = dcerpc_binding_dup(ep, binding);
+		if (transport == NCACN_NP && binding2 != NULL) {
+			ep->ep_2nd_description =
+				dcerpc_binding_dup(ep, binding2);
+		}
 		add_ep = true;
 
 		/* add mgmt interface */
@@ -367,9 +392,12 @@ _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
 		 * or there was already one on the endpoint
 		 */
 		if (ep->sd != NULL) {
-			DEBUG(0,("dcesrv_interface_register: interface '%s' failed to setup a security descriptor\n"
-			         "                           on endpoint '%s'\n",
-				iface->name, ep_name));
+			char *binding_string =
+				dcerpc_binding_string(dce_ctx, binding);
+			DBG_ERR("Interface '%s' failed to setup a security "
+				"descriptor on endpoint '%s'\n",
+				iface->name, binding_string);
+			TALLOC_FREE(binding_string);
 			if (add_ep) free(ep);
 			free(ifl);
 			return NT_STATUS_OBJECT_NAME_COLLISION;
diff --git a/librpc/rpc/dcesrv_core.h b/librpc/rpc/dcesrv_core.h
index d8d5f903095..e20bc00bbc1 100644
--- a/librpc/rpc/dcesrv_core.h
+++ b/librpc/rpc/dcesrv_core.h
@@ -462,6 +462,11 @@ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
 				   const char *ncacn_np_secondary_endpoint,
 				   const struct dcesrv_interface *iface,
 				   const struct security_descriptor *sd);
+NTSTATUS dcesrv_interface_register_b(struct dcesrv_context *dce_ctx,
+				   struct dcerpc_binding *binding,
+				   struct dcerpc_binding *binding2,
+				   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);
diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/ServerCompat.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/ServerCompat.pm
index d1368c3dbca..e35813a24ab 100644
--- a/pidl/lib/Parse/Pidl/Samba4/NDR/ServerCompat.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/NDR/ServerCompat.pm
@@ -469,6 +469,15 @@ sub boilerplate_ep_server($)
 	$self->pidl("static NTSTATUS $name\__check_register_in_endpoint(const char *name, struct dcerpc_binding *binding) {");
 	$self->indent();
 	$self->pidl("enum dcerpc_transport_t transport = dcerpc_binding_get_transport(binding);");
+	$self->pidl("NTSTATUS status;");
+	$self->pidl("");
+	$self->pidl("/* If service is disabled, do not register */");
+	$self->pidl("if (rpc_service_mode(name) == RPC_SERVICE_MODE_DISABLED) {");
+	$self->indent();
+	$self->pidl("return NT_STATUS_NOT_IMPLEMENTED;");
+	$self->deindent();
+	$self->pidl("}");
+
 	$self->pidl("");
 	$self->pidl("/* If service is embedded, register only for ncacn_np");
 	$self->pidl(" * see 8466b3c85e4b835e57e41776853093f4a0edc8b8");
@@ -479,6 +488,38 @@ sub boilerplate_ep_server($)
 	$self->pidl("return NT_STATUS_NOT_SUPPORTED;");
 	$self->deindent();
 	$self->pidl("}");
+
+	$self->pidl("");
+	$self->pidl("/*");
+	$self->pidl(" * If rpc service is external then change the default ncalrpc endpoint,");
+	$self->pidl(" * otherwise if the rpc daemon running this service is configured in");
+	$self->pidl(" * fork mode the forked process will race with main smbd to accept the");
+	$self->pidl(" * connections in the default ncalrpc socket, and the forked process");
+	$self->pidl(" * may not have the requested interface registered.");
+	$self->pidl(" * For example, in the ad_member test environment:");
+	$self->pidl(" *");
+	$self->pidl(" *   rpc_server:lsarpc = external");
+	$self->pidl(" *   rpc_server:samr = external");
+	$self->pidl(" *   rpc_server:netlogon = disabled");
+	$self->pidl(" *   rpc_daemon:lsasd = fork");
+	$self->pidl(" *");
+	$self->pidl(" * With these settings both, the main smbd and all the preforked lsasd");
+	$self->pidl(" * processes would be listening in the default ncalrpc socket if it is");
+	$self->pidl(" * not changed. If a client connection is accepted by one of the lsasd");
+	$self->pidl(" * worker processes and the client asks for an interface not registered");
+	$self->pidl(" * in these processes (winreg for example) it will get an error.");
+	$self->pidl(" */");
+	$self->pidl("if (rpc_service_mode(name) == RPC_SERVICE_MODE_EXTERNAL && transport == NCALRPC) {");
+	$self->indent();
+	$self->pidl("status = dcerpc_binding_set_string_option(binding, \"endpoint\", \"$uname\");");
+	$self->pidl("if (!NT_STATUS_IS_OK(status)) {");
+	$self->indent();
+	$self->pidl("return status;");
+	$self->deindent();
+	$self->pidl("}");
+	$self->deindent();
+	$self->pidl("}");
+
 	$self->pidl("");
 	$self->pidl("return NT_STATUS_OK;");
 	$self->deindent();
@@ -491,6 +532,7 @@ sub boilerplate_ep_server($)
 	$self->pidl("uint32_t i;");
 	$self->pidl("NTSTATUS ret;");
 	$self->pidl("struct dcerpc_binding *binding;");
+	$self->pidl("struct dcerpc_binding *binding2 = NULL;");
 	$self->pidl("");
 	$self->pidlnoindent("#ifdef DCESRV_INTERFACE_$uname\_NCACN_NP_SECONDARY_ENDPOINT");
 	$self->pidl("const char *ncacn_np_secondary_endpoint = DCESRV_INTERFACE_$uname\_NCACN_NP_SECONDARY_ENDPOINT;");
@@ -517,9 +559,25 @@ sub boilerplate_ep_server($)
 	$self->pidl("continue;");
 	$self->deindent();
 	$self->pidl("}");
-	$self->pidl("talloc_free(binding);");
 	$self->pidl("");
-	$self->pidl("ret = dcesrv_interface_register(dce_ctx, name, ncacn_np_secondary_endpoint, &dcesrv_$name\_interface, NULL);");
+
+	$self->pidl("if (ncacn_np_secondary_endpoint != NULL) {");
+	$self->indent();
+	$self->pidl("ret = dcerpc_parse_binding(dce_ctx, ncacn_np_secondary_endpoint, &binding2);");
+	$self->pidl("if (NT_STATUS_IS_ERR(ret)) {");
+	$self->indent();
+	$self->pidl("DBG_ERR(\"Failed to parse 2nd binding string \'%s\'\\n\", ncacn_np_secondary_endpoint);");
+	$self->pidl("TALLOC_FREE(binding);");
+	$self->pidl("return ret;");
+	$self->deindent();
+	$self->pidl("}");
+	$self->deindent();
+	$self->pidl("}");
+	$self->pidl("");
+
+	$self->pidl("ret = dcesrv_interface_register_b(dce_ctx, binding, binding2, &dcesrv_$name\_interface, NULL);");
+	$self->pidl("TALLOC_FREE(binding);");
+	$self->pidl("TALLOC_FREE(binding2);");
 	$self->pidl("if (!NT_STATUS_IS_OK(ret)) {");
 	$self->indent();
 	$self->pidl("DBG_ERR(\"Failed to register endpoint \'%s\'\\n\",name);");
diff --git a/selftest/knownfail b/selftest/knownfail
index 73ae7142563..94af250d4eb 100644
--- a/selftest/knownfail
+++ b/selftest/knownfail
@@ -347,6 +347,24 @@
 ^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_assoc_group_fail1\(ad_member\)
 ^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_assoc_group_fail2\(ad_member\)
 ^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_assoc_group_fail3\(ad_member\)
+# NETLOGON is disabled in any non-DC environments
+^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_2nd_cancel_requests\(ad_member\)
+^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_first_08_requests\(ad_member\)
+^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_first_cancel_requests\(ad_member\)
+^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_first_cmpx_requests\(ad_member\)
+^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_first_didnot_requests\(ad_member\)
+^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_first_maybe_requests\(ad_member\)
+^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_first_only_requests\(ad_member\)
+^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_fragmented_requests01\(ad_member\)
+^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_fragmented_requests02\(ad_member\)
+^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_fragmented_requests03\(ad_member\)
+^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_fragmented_requests04\(ad_member\)
+^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_fragmented_requests05\(ad_member\)
+^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_last_cancel_requests\(ad_member\)
+^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_last_only_requests\(ad_member\)
+^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_mix_requests\(ad_member\)
+^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_none_only_requests\(ad_member\)
+
 ^samba4.rpc.echo.*on.*with.object.echo.doublepointer.*nt4_dc
 ^samba4.rpc.echo.*on.*with.object.echo.surrounding.*nt4_dc
 ^samba4.rpc.echo.*on.*with.object.echo.enum.*nt4_dc
@@ -376,4 +394,3 @@
 ^samba.tests.ntlmdisabled.python\(ktest\).ntlmdisabled.NtlmDisabledTests.test_samr_change_password\(ktest\)
 ^samba.tests.ntlmdisabled.python\(ad_dc_no_ntlm\).ntlmdisabled.NtlmDisabledTests.test_ntlm_connection\(ad_dc_no_ntlm\)
 
-
diff --git a/source3/rpc_server/rpc_ncacn_np.c b/source3/rpc_server/rpc_ncacn_np.c
index ee362e409d1..bb95c678e7b 100644
--- a/source3/rpc_server/rpc_ncacn_np.c
+++ b/source3/rpc_server/rpc_ncacn_np.c
@@ -314,7 +314,8 @@ fail:
 }
 
 static NTSTATUS find_ncalrpc_default_endpoint(struct dcesrv_context *dce_ctx,
-					      struct dcesrv_endpoint **ep)
+				const struct ndr_interface_table *ndr_table,
+				struct dcesrv_endpoint **ep)
 {
 	TALLOC_CTX *tmp_ctx = NULL;
 	struct dcerpc_binding *binding = NULL;
@@ -326,6 +327,25 @@ static NTSTATUS find_ncalrpc_default_endpoint(struct dcesrv_context *dce_ctx,
 		return NT_STATUS_NO_MEMORY;
 	}
 
+	if (rpc_service_mode(ndr_table->name) == RPC_SERVICE_MODE_EXTERNAL) {
+		ep_description = talloc_asprintf(tmp_ctx, "ncalrpc:[%s]",
+				talloc_strdup_upper(tmp_ctx, ndr_table->name));
+		if (ep_description == NULL) {
+			status = NT_STATUS_NO_MEMORY;
+			goto out;
+		}
+
+		status = dcerpc_parse_binding(tmp_ctx, ep_description, &binding);
+		if (!NT_STATUS_IS_OK(status)) {
+			goto out;
+		}
+
+		status = dcesrv_find_endpoint(dce_ctx, binding, ep);
+		if (NT_STATUS_IS_OK(status)) {
+			goto out;
+		}
+	}
+
 	/*
 	 * Some services use a rpcint binding handle in their initialization,
 	 * before the server is fully initialized. Search the NCALRPC endpoint
@@ -380,7 +400,7 @@ static NTSTATUS make_internal_dcesrv_connection(TALLOC_CTX *mem_ctx,
 	conn->preferred_transfer = &ndr_transfer_syntax_ndr;
 	conn->transport.private_data = ncacn_conn;
 
-	status = find_ncalrpc_default_endpoint(conn->dce_ctx, &endpoint);
+	status = find_ncalrpc_default_endpoint(conn->dce_ctx, ndr_table, &endpoint);
 	if (!NT_STATUS_IS_OK(status)) {
 		goto fail;
 	}
diff --git a/source3/winbindd/winbindd_dual_ndr.c b/source3/winbindd/winbindd_dual_ndr.c
index 5f0ec82067c..36f01224e24 100644
--- a/source3/winbindd/winbindd_dual_ndr.c
+++ b/source3/winbindd/winbindd_dual_ndr.c
@@ -378,6 +378,16 @@ static NTSTATUS find_ncalrpc_default_endpoint(struct dcesrv_context *dce_ctx,
 		goto out;
 	}
 
+	status = dcerpc_parse_binding(tmp_ctx, "ncalrpc:[WINBIND]", &binding);
+	if (!NT_STATUS_IS_OK(status)) {
+		goto out;
+	}
+
+	status = dcesrv_find_endpoint(dce_ctx, binding, ep);
+	if (NT_STATUS_IS_OK(status)) {
+		goto out;
+	}
+
 	status = dcerpc_parse_binding(tmp_ctx, "ncalrpc:[DEFAULT]", &binding);
 	if (!NT_STATUS_IS_OK(status)) {
 		goto out;


-- 
Samba Shared Repository



More information about the samba-cvs mailing list