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) <noreply@anthropic.com>
Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: David Mulder <dmulder@samba.org>
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 =
{
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,
/* 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,