[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Tue Jul 25 21:03:01 UTC 2023


The branch, master has been updated
       via  e86e0da9de6 WHATSNEW: Add TLS cert reload feature
       via  a1b1f8ffd20 doc-xml: Add entry for reload-certs for new LDAP certificate reload function
       via  9facc2e1d85 docs-xml: Fix invalid XML in smbcontrol manpage
       via  4516fee9b52 testprogs/blackbox: add test_ldap_tls_reload.sh
       via  0c7cfb7a115 s4:ldap_server: reload tls certificates on smbcontrol reload-certs
       via  321162c9bfc s4:ldap_server: remember dns_host_name in ldap_service
       via  cc4995d932d s4:ldap_server: don't store task_server in ldapsrv_service
       via  7804bf55ad0 s4:tls_tstream: create tstream_tls_params_internal
       via  bed915d098e s3:smbcontrol: improve destination resolution using names db
       via  1472e4c9dbf s4:process_prefork: create new messaging context for the master process
       via  3af6ad6eea7 s4:process: add method called before entering the tevent_loop_wait
       via  c8ee3d45252 s4:process_prefork: avoid memory leaks caused by messaging_post_self
      from  dd998cc1633 s3:winbindd: Fix double close(fd)

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


- Log -----------------------------------------------------------------
commit e86e0da9de6a7d108348ad37f1ae9885ebb74c37
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Jul 21 16:56:49 2023 +1200

    WHATSNEW: Add TLS cert reload feature
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Tue Jul 25 21:02:35 UTC 2023 on atb-devel-224

commit a1b1f8ffd20dac0c04959abe056ce8265f3b5d66
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Jul 21 16:44:54 2023 +1200

    doc-xml: Add entry for reload-certs for new LDAP certificate reload function
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 9facc2e1d85c408b18c1551fcb32ef09b3039423
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Jul 21 16:42:23 2023 +1200

    docs-xml: Fix invalid XML in smbcontrol manpage
    
    This was picked by a mode in Emacs.
    
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit 4516fee9b5265f62388f927f188634525e4f489c
Author: Jule Anger <janger at samba.org>
Date:   Mon Jun 5 15:23:11 2023 +0200

    testprogs/blackbox: add test_ldap_tls_reload.sh
    
    This tests the reload (and if needed regeneration) of
    tls certificates.
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Jule Anger <janger at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 0c7cfb7a11516ac685c4283d080701346e0d5a70
Author: Jule Anger <janger at samba.org>
Date:   Wed Mar 1 09:53:53 2023 +0000

    s4:ldap_server: reload tls certificates on smbcontrol reload-certs
    
    Reload certificates with the command 'smbcontrol ldap_server reload-certs'.
    The message is send to the master process, who forwards it to the workers
    processes.
    The master process reload and, if necessary, create the certificates first,
    then the workers processes reload them.
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Jule Anger <janger at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 321162c9bfc7c0385d894171cc145eb52f6f1a2a
Author: Jule Anger <janger at samba.org>
Date:   Tue Jan 31 13:50:06 2023 +0100

    s4:ldap_server: remember dns_host_name in ldap_service
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Jule Anger <janger at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit cc4995d932d4566f12735bcad9bcc4cd96bfc151
Author: Jule Anger <janger at samba.org>
Date:   Wed Mar 1 09:53:53 2023 +0000

    s4:ldap_server: don't store task_server in ldapsrv_service
    
    We store individual pointers we need and adjust them
    as needed in ldapsrv_post_fork() and the newly added
    ldapsrv_before_loop().
    
    This will be required for the next steps.
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Jule Anger <janger at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 7804bf55ad036336c357be117a3282d15d633a84
Author: Jule Anger <janger at samba.org>
Date:   Tue Jan 31 15:08:31 2023 +0100

    s4:tls_tstream: create tstream_tls_params_internal
    
    The following commits will implement the reloading of tls certificates.
    Therefore we need to overwrite the interal memory.
    
    Note we need to make sure x509_cred and dh_params from
    tstream_tls_params_internal stay alive for the whole lifetime
    of this session!
    
    See 'man gnutls_credentials_set' and
    'man gnutls_certificate_set_dh_params'.
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Jule Anger <janger at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit bed915d098e27bb21249227e671146ef42f52129
Author: jule <janger at samba.org>
Date:   Mon Feb 6 13:28:36 2023 +0000

    s3:smbcontrol: improve destination resolution using names db
    
    With this change it's possible to use 'smbcontrol ldap_server ...'
    instead of 'smbcontrol prefork-master-ldap ...'
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Jule Anger <janger at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 1472e4c9dbf5eb98f7074d17bf4e3dabfec14fd0
Author: Jule Anger <janger at samba.org>
Date:   Wed Mar 1 10:02:00 2023 +0000

    s4:process_prefork: create new messaging context for the master process
    
    In order to allow the before_loop() hook to register messages or event
    handlers, we need to fix up task->event_ctx and create a new
    task->msg_ctx. It also means the struct task_server pointer
    changes in the master before_loop() hook.
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Jule Anger <janger at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 3af6ad6eea7b35c0149490578b508252d3cd6514
Author: Jule Anger <janger at samba.org>
Date:   Wed Mar 1 09:48:18 2023 +0000

    s4:process: add method called before entering the tevent_loop_wait
    
    This gives the service a chance to register messaging and/or event handlers
    on the correct contexts.
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Jule Anger <janger at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit c8ee3d452520a0096a2fa36ca7465f65d7955330
Author: Jule Anger <janger at samba.org>
Date:   Wed Mar 1 09:47:09 2023 +0000

    s4:process_prefork: avoid memory leaks caused by messaging_post_self
    
    Sending a message to a process with multiple tevent contexts
    can cause a message to get stuck and cause a data leak.
    
    In general it's safer to call imessaging_dgm_unref_ev() before
    talloc_free()...
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Jule Anger <janger at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

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

Summary of changes:
 WHATSNEW.txt                               |  10 ++
 docs-xml/manpages/smbcontrol.1.xml         |  11 +-
 librpc/idl/messaging.idl                   |   1 +
 source3/utils/smbcontrol.c                 |  34 +++++-
 source4/ldap_server/ldap_server.c          | 176 ++++++++++++++++++++++++++---
 source4/ldap_server/ldap_server.h          |   6 +-
 source4/lib/tls/tls_tstream.c              | 143 +++++++++++++++++------
 source4/samba/process_prefork.c            |  64 +++++++++++
 source4/samba/process_single.c             |   3 +
 source4/samba/process_standard.c           |   3 +
 source4/samba/service.h                    |  29 +++++
 source4/selftest/tests.py                  |   5 +
 testprogs/blackbox/test_ldap_tls_reload.sh |  64 +++++++++++
 13 files changed, 496 insertions(+), 53 deletions(-)
 create mode 100755 testprogs/blackbox/test_ldap_tls_reload.sh


Changeset truncated at 500 lines:

diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 17067eb7e27..4619a5009c4 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -210,6 +210,16 @@ administrator to use an encrypted connection in the future.
 NOTE WELL: If Samba is accessed via a TLS frontend or load balancer,
 the LDAP request will be regarded as plaintext.
 
+Samba AD TLS Certificates can be reloaded
+-----------------------------------------
+
+The TLS certificates used for Samba's AD DC LDAP server were
+previously only read on startup, and this meant that when then expired
+it was required to restart Samba, disrupting service to other users.
+
+ smbcontrol ldap_server reload-certs
+
+This will now allow these certificates to be reloaded 'on the fly'
 
 ================
 REMOVED FEATURES
diff --git a/docs-xml/manpages/smbcontrol.1.xml b/docs-xml/manpages/smbcontrol.1.xml
index 4b5d90c47b2..33152debd33 100644
--- a/docs-xml/manpages/smbcontrol.1.xml
+++ b/docs-xml/manpages/smbcontrol.1.xml
@@ -305,7 +305,7 @@
 	<term>idmap</term>
 	<listitem><para>Notify about changes of id mapping. Can be sent
 	to <constant>smbd</constant> or (not implemented yet) <constant>winbindd</constant>.
-	</para></listitem>
+	</para>
 
 	<variablelist>
 	  <varlistentry>
@@ -325,6 +325,7 @@
 	    the id is currently in use.</para></listitem>
 	  </varlistentry>
 	</variablelist>
+	</listitem>
 	</varlistentry>
 
 	<varlistentry>
@@ -334,6 +335,14 @@
 	to <constant>smbd</constant>.</para></listitem>
 	</varlistentry>
 
+	<varlistentry>
+	<term>reload-certs</term>
+	<listitem><para>Instruct the LDAP server of a Samba AD DC to
+	reload the TLS certificates protecting ldaps:// connections. This
+	message can only be sent
+	to <constant>ldap_server</constant>.</para></listitem>
+	</varlistentry>
+
 </variablelist>
 </refsect1>
 
diff --git a/librpc/idl/messaging.idl b/librpc/idl/messaging.idl
index 398deed8e4c..2bcf1021453 100644
--- a/librpc/idl/messaging.idl
+++ b/librpc/idl/messaging.idl
@@ -41,6 +41,7 @@ interface messaging
 
 		/* Changes to smb.conf are really of general interest */
 		MSG_SMB_CONF_UPDATED		= 0x0021,
+		MSG_RELOAD_TLS_CERTIFICATES	= 0x0022,
 
 		MSG_PREFORK_CHILD_EVENT		= 0x0031,
 		MSG_PREFORK_PARENT_EVENT	= 0x0032,
diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c
index ab57bd48042..863f8c93dd1 100644
--- a/source3/utils/smbcontrol.c
+++ b/source3/utils/smbcontrol.c
@@ -35,6 +35,7 @@
 #include "util_tdb.h"
 #include "../lib/util/pidfile.h"
 #include "serverid.h"
+#include "lib/util/server_id_db.h"
 #include "cmdline_contexts.h"
 #include "lib/util/string_wrappers.h"
 #include "lib/global_contexts.h"
@@ -1341,6 +1342,18 @@ static bool do_winbind_validate_cache(struct tevent_context *ev_ctx,
 	return num_replies;
 }
 
+static bool do_reload_certs(struct tevent_context *ev_ctx,
+					struct messaging_context *msg_ctx,
+					const struct server_id pid,
+					const int argc, const char **argv)
+{
+	if (argc != 1) {
+		fprintf(stderr, "Usage: smbcontrol ldap_server reload-certs \n");
+		return false;
+	}
+
+	return send_message(msg_ctx, pid, MSG_RELOAD_TLS_CERTIFICATES, NULL, 0);
+}
 static bool do_reload_config(struct tevent_context *ev_ctx,
 			     struct messaging_context *msg_ctx,
 			     const struct server_id pid,
@@ -1542,6 +1555,11 @@ static const struct {
 		.fn   = do_drvupgrade,
 		.help = "Notify a printer driver has changed",
 	},
+	{
+		.name = "reload-certs",
+		.fn   = do_reload_certs,
+		.help = "Reload TLS certificates"
+	},
 	{
 		.name = "reload-config",
 		.fn   = do_reload_config,
@@ -1614,8 +1632,8 @@ static void usage(poptContext pc)
 	poptPrintHelp(pc, stderr, 0);
 
 	fprintf(stderr, "\n");
-	fprintf(stderr, "<destination> is one of \"nmbd\", \"smbd\", \"winbindd\" or a "
-		"process ID\n");
+	fprintf(stderr, "<destination> is one of \"nmbd\", \"smbd\", \"winbindd\", "
+		"\"ldap_server\" or a process ID\n");
 
 	fprintf(stderr, "\n");
 	fprintf(stderr, "<message-type> is one of:\n");
@@ -1642,6 +1660,8 @@ static struct server_id parse_dest(struct messaging_context *msg,
 		.pid = (uint64_t)-1,
 	};
 	pid_t pid;
+	struct server_id_db *names_db = NULL;
+	bool ok;
 
 	/* Zero is a special return value for broadcast to all processes */
 
@@ -1674,6 +1694,16 @@ static struct server_id parse_dest(struct messaging_context *msg,
 		return pid_to_procid(pid);
 	}
 
+	names_db = messaging_names_db(msg);
+	if (names_db == NULL) {
+		goto fail;
+	}
+	ok = server_id_db_lookup_one(names_db, dest, &result);
+	if (ok) {
+		return result;
+	}
+
+fail:
 	fprintf(stderr,"Can't find pid for destination '%s'\n", dest);
 
 	return result;
diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c
index 4198caa451a..38c29be3ecb 100644
--- a/source4/ldap_server/ldap_server.c
+++ b/source4/ldap_server/ldap_server.c
@@ -48,6 +48,9 @@
 #include "../libcli/util/tstream.h"
 #include "libds/common/roles.h"
 #include "lib/util/time.h"
+#include "lib/util/server_id.h"
+#include "lib/util/server_id_db.h"
+#include "lib/messaging/messaging_internal.h"
 
 #undef strcasecmp
 
@@ -338,7 +341,7 @@ static void ldapsrv_accept(struct stream_connection *c,
 
 	conn->connection  = c;
 	conn->service     = ldapsrv_service;
-	conn->lp_ctx      = ldapsrv_service->task->lp_ctx;
+	conn->lp_ctx      = ldapsrv_service->lp_ctx;
 
 	c->private_data   = conn;
 
@@ -920,7 +923,7 @@ void ldapsrv_notification_retry_setup(struct ldapsrv_service *service, bool forc
 	}
 
 	service->notification.retry = tevent_wakeup_send(service,
-							 service->task->event_ctx,
+							 service->current_ev,
 							 retry);
 	if (service->notification.retry == NULL) {
 		/* retry later */
@@ -1117,7 +1120,7 @@ static void ldapsrv_accept_nonpriv(struct stream_connection *c)
 	NTSTATUS status;
 
 	status = auth_anonymous_session_info(
-		c, ldapsrv_service->task->lp_ctx, &session_info);
+		c, ldapsrv_service->lp_ctx, &session_info);
 	if (!NT_STATUS_IS_OK(status)) {
 		stream_terminate_connection(c, "failed to setup anonymous "
 					    "session info");
@@ -1145,7 +1148,7 @@ static void ldapsrv_accept_priv(struct stream_connection *c)
 		c->private_data, struct ldapsrv_service);
 	struct auth_session_info *session_info;
 
-	session_info = system_session(ldapsrv_service->task->lp_ctx);
+	session_info = system_session(ldapsrv_service->lp_ctx);
 	if (!session_info) {
 		stream_terminate_connection(c, "failed to setup system "
 					    "session info");
@@ -1206,7 +1209,7 @@ static NTSTATUS add_socket(struct task_server *task,
 
 	/* Load LDAP database, but only to read our settings */
 	ldb = samdb_connect(ldap_service,
-			    ldap_service->task->event_ctx,
+			    ldap_service->current_ev,
 			    lp_ctx,
 			    system_session(lp_ctx),
 			    NULL,
@@ -1254,6 +1257,106 @@ static NTSTATUS add_socket(struct task_server *task,
 	return NT_STATUS_OK;
 }
 
+static void ldap_reload_certs(struct imessaging_context *msg_ctx,
+			      void *private_data,
+			      uint32_t msg_type,
+			      struct server_id server_id,
+			      size_t num_fds,
+			      int *fds,
+			      DATA_BLOB *data)
+{
+	TALLOC_CTX *frame = talloc_stackframe();
+	struct ldapsrv_service *ldap_service =
+		talloc_get_type_abort(private_data,
+		struct ldapsrv_service);
+	int default_children;
+	int num_children;
+	int i;
+	bool ok;
+	struct server_id ldap_master_id;
+	NTSTATUS status;
+	struct tstream_tls_params *new_tls_params = NULL;
+
+	SMB_ASSERT(msg_ctx == ldap_service->current_msg);
+
+	/* reload certificates */
+	status = tstream_tls_params_server(ldap_service,
+					   ldap_service->dns_host_name,
+					   lpcfg_tls_enabled(ldap_service->lp_ctx),
+					   lpcfg_tls_keyfile(frame, ldap_service->lp_ctx),
+					   lpcfg_tls_certfile(frame, ldap_service->lp_ctx),
+					   lpcfg_tls_cafile(frame, ldap_service->lp_ctx),
+					   lpcfg_tls_crlfile(frame, ldap_service->lp_ctx),
+					   lpcfg_tls_dhpfile(frame, ldap_service->lp_ctx),
+					   lpcfg_tls_priority(ldap_service->lp_ctx),
+					   &new_tls_params);
+	if (!NT_STATUS_IS_OK(status)) {
+		DBG_ERR("ldapsrv failed tstream_tls_params_server - %s\n",
+			nt_errstr(status));
+		TALLOC_FREE(frame);
+		return;
+	}
+
+	TALLOC_FREE(ldap_service->tls_params);
+	ldap_service->tls_params = new_tls_params;
+
+	if (getpid() != ldap_service->parent_pid) {
+		/*
+		 * If we are not the master process we are done
+		 */
+		TALLOC_FREE(frame);
+		return;
+	}
+
+	/*
+	 * Check we're running under the prefork model,
+	 * by checking if the prefork-master-ldap name
+	 * was registered
+	 */
+	ok = server_id_db_lookup_one(msg_ctx->names, "prefork-master-ldap", &ldap_master_id);
+	if (!ok) {
+		/*
+		 * We are done if another process model is in use.
+		 */
+		TALLOC_FREE(frame);
+		return;
+	}
+
+	/*
+	 * Now we loop over all possible prefork workers
+	 * in order to notify them about the reload
+	 */
+	default_children = lpcfg_prefork_children(ldap_service->lp_ctx);
+	num_children = lpcfg_parm_int(ldap_service->lp_ctx,
+				      NULL, "prefork children", "ldap",
+				      default_children);
+	for (i = 0; i < num_children; i++) {
+		char child_name[64] = { 0, };
+		struct server_id ldap_worker_id;
+
+		snprintf(child_name, sizeof(child_name), "prefork-worker-ldap-%d", i);
+		ok = server_id_db_lookup_one(msg_ctx->names, child_name, &ldap_worker_id);
+		if (!ok) {
+			DBG_ERR("server_id_db_lookup_one(%s) - failed\n",
+				child_name);
+			continue;
+		}
+
+		status = imessaging_send(msg_ctx, ldap_worker_id,
+				         MSG_RELOAD_TLS_CERTIFICATES, NULL);
+		if (!NT_STATUS_IS_OK(status)) {
+			struct server_id_buf id_buf;
+			DBG_ERR("ldapsrv failed imessaging_send(%s, %s) - %s\n",
+				child_name,
+				server_id_str_buf(ldap_worker_id, &id_buf),
+				nt_errstr(status));
+			continue;
+		}
+	}
+
+	TALLOC_FREE(frame);
+}
+
 /*
   open the ldap server sockets
 */
@@ -1263,7 +1366,6 @@ static NTSTATUS ldapsrv_task_init(struct task_server *task)
 #ifdef WITH_LDAPI_PRIV_SOCKET
 	char *priv_dir;
 #endif
-	const char *dns_host_name;
 	struct ldapsrv_service *ldap_service;
 	NTSTATUS status;
 
@@ -1289,18 +1391,22 @@ static NTSTATUS ldapsrv_task_init(struct task_server *task)
 		goto failed;
 	}
 
-	ldap_service->task = task;
+	ldap_service->lp_ctx = task->lp_ctx;
+	ldap_service->current_ev = task->event_ctx;
+	ldap_service->current_msg = task->msg_ctx;
 
-	dns_host_name = talloc_asprintf(ldap_service, "%s.%s",
+	ldap_service->dns_host_name = talloc_asprintf(ldap_service, "%s.%s",
 					lpcfg_netbios_name(task->lp_ctx),
 					lpcfg_dnsdomain(task->lp_ctx));
-	if (dns_host_name == NULL) {
+	if (ldap_service->dns_host_name == NULL) {
 		status = NT_STATUS_NO_MEMORY;
 		goto failed;
 	}
 
+	ldap_service->parent_pid = getpid();
+
 	status = tstream_tls_params_server(ldap_service,
-					   dns_host_name,
+					   ldap_service->dns_host_name,
 					   lpcfg_tls_enabled(task->lp_ctx),
 					   lpcfg_tls_keyfile(ldap_service, task->lp_ctx),
 					   lpcfg_tls_certfile(ldap_service, task->lp_ctx),
@@ -1437,10 +1543,18 @@ static void ldapsrv_post_fork(struct task_server *task, struct process_details *
 	struct ldapsrv_service *ldap_service =
 		talloc_get_type_abort(task->private_data, struct ldapsrv_service);
 
+	/*
+	 * As ldapsrv_before_loop() may changed the values for the parent loop
+	 * we need to adjust the pointers to the correct value in the child
+	 */
+	ldap_service->lp_ctx = task->lp_ctx;
+	ldap_service->current_ev = task->event_ctx;
+	ldap_service->current_msg = task->msg_ctx;
+
 	ldap_service->sam_ctx = samdb_connect(ldap_service,
-					      ldap_service->task->event_ctx,
-					      ldap_service->task->lp_ctx,
-					      system_session(ldap_service->task->lp_ctx),
+					      ldap_service->current_ev,
+					      ldap_service->lp_ctx,
+					      system_session(ldap_service->lp_ctx),
 					      NULL,
 					      0);
 	if (ldap_service->sam_ctx == NULL) {
@@ -1450,6 +1564,41 @@ static void ldapsrv_post_fork(struct task_server *task, struct process_details *
 	}
 }
 
+static void ldapsrv_before_loop(struct task_server *task)
+{
+	struct ldapsrv_service *ldap_service =
+		talloc_get_type_abort(task->private_data, struct ldapsrv_service);
+	NTSTATUS status;
+
+	if (ldap_service->sam_ctx != NULL) {
+		/*
+		 * Make sure the values are still the same
+		 * as set in ldapsrv_post_fork()
+		 */
+		SMB_ASSERT(task->lp_ctx == ldap_service->lp_ctx);
+		SMB_ASSERT(task->event_ctx == ldap_service->current_ev);
+		SMB_ASSERT(task->msg_ctx == ldap_service->current_msg);
+	} else {
+		/*
+		 * We need to adjust the pointers to the correct value
+		 * in the parent loop.
+		 */
+		ldap_service->lp_ctx = task->lp_ctx;
+		ldap_service->current_ev = task->event_ctx;
+		ldap_service->current_msg = task->msg_ctx;
+	}
+
+	status = imessaging_register(ldap_service->current_msg,
+				     ldap_service,
+				     MSG_RELOAD_TLS_CERTIFICATES,
+				     ldap_reload_certs);
+	if (!NT_STATUS_IS_OK(status)) {
+		task_server_terminate(task, "Cannot register ldap_reload_certs",
+				      true);
+		return;
+	}
+}
+
 /*
  * Check the size of an ldap request packet.
  *
@@ -1535,6 +1684,7 @@ NTSTATUS server_service_ldap_init(TALLOC_CTX *ctx)
 		.inhibit_pre_fork = false,
 		.task_init = ldapsrv_task_init,
 		.post_fork = ldapsrv_post_fork,
+		.before_loop = ldapsrv_before_loop,
 	};
 	return register_server_service(ctx, "ldap", &details);
 }
diff --git a/source4/ldap_server/ldap_server.h b/source4/ldap_server/ldap_server.h
index c94bd914b9b..a56aa8f8c4a 100644
--- a/source4/ldap_server/ldap_server.h
+++ b/source4/ldap_server/ldap_server.h
@@ -114,8 +114,9 @@ struct ldapsrv_call {
 #define LDAP_SERVER_MAX_CHUNK_SIZE ((size_t)(25 * 1024 * 1024))
 
 struct ldapsrv_service {
+	const char *dns_host_name;
+	pid_t parent_pid;
 	struct tstream_tls_params *tls_params;
-	struct task_server *task;
 	struct tevent_queue *call_queue;
 	struct ldapsrv_connection *connections;
 	struct {
@@ -123,6 +124,9 @@ struct ldapsrv_service {
 		struct tevent_req *retry;
 	} notification;
 
+	struct loadparm_context *lp_ctx;
+	struct tevent_context *current_ev;
+	struct imessaging_context *current_msg;
 	struct ldb_context *sam_ctx;
 };
 
diff --git a/source4/lib/tls/tls_tstream.c b/source4/lib/tls/tls_tstream.c
index f1bfe474d6e..58500a54ac5 100644
--- a/source4/lib/tls/tls_tstream.c
+++ b/source4/lib/tls/tls_tstream.c
@@ -864,7 +864,7 @@ static const struct tstream_context_ops tstream_tls_ops = {
 	.disconnect_recv	= tstream_tls_disconnect_recv,
 };
 
-struct tstream_tls_params {
+struct tstream_tls_params_internal {
 	gnutls_certificate_credentials_t x509_cred;
 	gnutls_dh_params_t dh_params;
 	const char *tls_priority;
@@ -873,7 +873,11 @@ struct tstream_tls_params {
 	const char *peer_name;
 };
 
-static int tstream_tls_params_destructor(struct tstream_tls_params *tlsp)
+struct tstream_tls_params {
+	struct tstream_tls_params_internal *internal;
+};
+
+static int tstream_tls_params_internal_destructor(struct tstream_tls_params_internal *tlsp)
 {
 	if (tlsp->x509_cred) {
 		gnutls_certificate_free_credentials(tlsp->x509_cred);
@@ -887,8 +891,10 @@ static int tstream_tls_params_destructor(struct tstream_tls_params *tlsp)
 	return 0;
 }
 
-bool tstream_tls_params_enabled(struct tstream_tls_params *tlsp)
+bool tstream_tls_params_enabled(struct tstream_tls_params *tls_params)
 {
+	struct tstream_tls_params_internal *tlsp = tls_params->internal;
+
 	return tlsp->tls_enabled;
 }
 
@@ -900,33 +906,42 @@ NTSTATUS tstream_tls_params_client(TALLOC_CTX *mem_ctx,
 				   const char *peer_name,
 				   struct tstream_tls_params **_tlsp)
 {
-	struct tstream_tls_params *tlsp;
+	struct tstream_tls_params *__tlsp = NULL;
+	struct tstream_tls_params_internal *tlsp = NULL;
 	int ret;
 
-	tlsp = talloc_zero(mem_ctx, struct tstream_tls_params);
-	NT_STATUS_HAVE_NO_MEMORY(tlsp);
+	__tlsp = talloc_zero(mem_ctx, struct tstream_tls_params);
+	if (__tlsp == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}


-- 
Samba Shared Repository



More information about the samba-cvs mailing list