From: Jeremy Allison Date: Fri, 10 Apr 2026 21:15:48 +0000 (-0700) Subject: s3:loadparm: add lp_register_snum_in_use_fn() callback registration X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9a4f9666d14d8b4d96181ecc15d9047d29b66ccb;p=thirdparty%2Fsamba.git s3:loadparm: add lp_register_snum_in_use_fn() callback registration Add a mechanism for smbd to register a callback that checks whether a service number is currently in use by any active connection. This will be used by subsequent commits to guard free_service_byindex() calls in lp_servicenumber() and other sites that currently destroy services without checking if they are in use, which can leave active connections holding stale service numbers that lead to NULL pointer dereferences. The callback is registered by smbd during smbd_process() startup via connections_snum_used. Non-smbd programs (testparm, net, etc.) leave the callback as NULL, meaning no connections exist and it is always safe to free services. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14978 Co-Authored-By: Claude Opus 4.6 (1M context) Signed-off-by: Jeremy Allison Reviewed-by: David Mulder --- diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index b081b917a82..02ad996c265 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -119,6 +119,21 @@ static bool defaults_saved = false; static struct loadparm_global Globals; +/* + * Callback to check if a service number is currently in use + * by any active connection. Registered by smbd at startup. + * When NULL (non-smbd programs), no connections exist so + * it is always safe to free services. + */ +static bool (*snum_in_use)(struct smbd_server_connection *unused, + int snum) = NULL; + +void lp_register_snum_in_use_fn(bool (*fn)(struct smbd_server_connection *, + int)) +{ + snum_in_use = fn; +} + /* This is a default service used to prime a services structure */ static const struct loadparm_service _sDefault = { diff --git a/source3/param/loadparm.h b/source3/param/loadparm.h index 72773a8b2ec..43f6c61804d 100644 --- a/source3/param/loadparm.h +++ b/source3/param/loadparm.h @@ -144,6 +144,8 @@ void lp_killunused(struct smbd_server_connection *sconn, bool (*snumused) (struct smbd_server_connection *, int)); void lp_kill_all_services(void); void lp_killservice(int iServiceIn); +void lp_register_snum_in_use_fn(bool (*fn)(struct smbd_server_connection *, + int)); const char* server_role_str(uint32_t role); enum usershare_err parse_usershare_file(TALLOC_CTX *ctx, SMB_STRUCT_STAT *psbuf, diff --git a/source3/smbd/smb2_process.c b/source3/smbd/smb2_process.c index 9290714e8ae..f16a1496438 100644 --- a/source3/smbd/smb2_process.c +++ b/source3/smbd/smb2_process.c @@ -2031,6 +2031,7 @@ void smbd_process(struct tevent_context *ev_ctx, /* this is needed so that we get decent entries in smbstatus for port 445 connects */ set_remote_machine_name(remaddr, false); + lp_register_snum_in_use_fn(connections_snum_used); reload_services(sconn, conn_snum_used, true); sub_set_socket_ids(remaddr, sconn->remote_hostname,