diff -Nur samba-4.18.6/nsswitch/libwbclient/wscript samba-4.18.6-fix-winbind/nsswitch/libwbclient/wscript --- samba-4.18.6/nsswitch/libwbclient/wscript 2023-09-02 13:38:31.262884402 -0700 +++ samba-4.18.6-fix-winbind/nsswitch/libwbclient/wscript 2023-09-02 13:37:58.293056486 -0700 @@ -27,13 +27,9 @@ # # Logs.info("\tSelected embedded libwbclient build") - wbclient_internal_deps = 'replace' - if bld.CONFIG_SET('HAVE_PTHREAD'): - wbclient_internal_deps += ' pthread' - bld.SAMBA_SUBSYSTEM('wbclient-internal', source='../wb_common.c', - deps=wbclient_internal_deps, + deps='replace', cflags='-DWINBINDD_SOCKET_DIR=\"%s\"' % bld.env.WINBINDD_SOCKET_DIR, hide_symbols=True, provide_builtin_linking=True, diff -Nur samba-4.18.6/nsswitch/wb_common.c samba-4.18.6-fix-winbind/nsswitch/wb_common.c --- samba-4.18.6/nsswitch/wb_common.c 2023-09-02 13:38:34.506064173 -0700 +++ samba-4.18.6-fix-winbind/nsswitch/wb_common.c 2023-09-02 13:37:58.293056486 -0700 @@ -26,7 +26,6 @@ #include "replace.h" #include "system/select.h" #include "winbind_client.h" -#include #ifdef HAVE_PTHREAD_H #include @@ -42,123 +41,30 @@ pid_t our_pid; /* calling process pid */ }; -static struct wb_global_ctx { - bool initialized; #ifdef HAVE_PTHREAD - pthread_once_t control; - pthread_key_t key; -#else - bool dummy; -#endif -} wb_global_ctx = { -#ifdef HAVE_PTHREAD - .control = PTHREAD_ONCE_INIT, -#endif -}; - -static void winbind_close_sock(struct winbindd_context *ctx); - -#ifdef HAVE_PTHREAD -static void wb_thread_ctx_initialize(void); - -static void wb_atfork_child(void) -{ - struct winbindd_context *ctx = NULL; - int ret; - - ctx = (struct winbindd_context *)pthread_getspecific(wb_global_ctx.key); - if (ctx == NULL) { - return; - } - - ret = pthread_setspecific(wb_global_ctx.key, NULL); - assert(ret == 0); - - winbind_close_sock(ctx); - free(ctx); - - ret = pthread_key_delete(wb_global_ctx.key); - assert(ret == 0); - - wb_global_ctx.control = (pthread_once_t)PTHREAD_ONCE_INIT; -} - -static void wb_thread_ctx_destructor(void *p) -{ - struct winbindd_context *ctx = (struct winbindd_context *)p; - - winbind_close_sock(ctx); - free(ctx); -} - -static void wb_thread_ctx_initialize(void) -{ - int ret; - - ret = pthread_atfork(NULL, - NULL, - wb_atfork_child); - assert(ret == 0); - - ret = pthread_key_create(&wb_global_ctx.key, - wb_thread_ctx_destructor); - assert(ret == 0); -} +static pthread_mutex_t wb_global_ctx_mutex = PTHREAD_MUTEX_INITIALIZER; #endif -static struct winbindd_context *get_wb_thread_ctx(void) +static struct winbindd_context *get_wb_global_ctx(void) { - struct winbindd_context *ctx = NULL; - int ret; - - ret = pthread_once(&wb_global_ctx.control, - wb_thread_ctx_initialize); - assert(ret == 0); - - ctx = (struct winbindd_context *)pthread_getspecific( - wb_global_ctx.key); - if (ctx != NULL) { - return ctx; - } - - ctx = malloc(sizeof(struct winbindd_context)); - if (ctx == NULL) { - return NULL; - } - - *ctx = (struct winbindd_context) { + static struct winbindd_context wb_global_ctx = { .winbindd_fd = -1, .is_privileged = false, .our_pid = 0 }; - ret = pthread_setspecific(wb_global_ctx.key, ctx); - if (ret != 0) { - free(ctx); - return NULL; - } - return ctx; +#ifdef HAVE_PTHREAD + pthread_mutex_lock(&wb_global_ctx_mutex); +#endif + return &wb_global_ctx; } -static struct winbindd_context *get_wb_global_ctx(void) +static void put_wb_global_ctx(void) { - struct winbindd_context *ctx = NULL; -#ifndef HAVE_PTHREAD - static struct winbindd_context _ctx = { - .winbindd_fd = -1, - .is_privileged = false, - .our_pid = 0 - }; -#endif - #ifdef HAVE_PTHREAD - ctx = get_wb_thread_ctx(); -#else - ctx = &_ctx; + pthread_mutex_unlock(&wb_global_ctx_mutex); #endif - - wb_global_ctx.initialized = true; - return ctx; + return; } void winbind_set_client_name(const char *name) @@ -242,20 +148,9 @@ { struct winbindd_context *ctx; - if (!wb_global_ctx.initialized) { - return; - } - -#ifdef HAVE_PTHREAD_H - ctx = (struct winbindd_context *)pthread_getspecific(wb_global_ctx.key); - if (ctx == NULL) { - return; - } -#else ctx = get_wb_global_ctx(); -#endif - winbind_close_sock(ctx); + put_wb_global_ctx(); } #define CONNECT_TIMEOUT 30 @@ -887,9 +782,11 @@ struct winbindd_response *response) { NSS_STATUS status = NSS_STATUS_UNAVAIL; + bool release_global_ctx = false; if (ctx == NULL) { ctx = get_wb_global_ctx(); + release_global_ctx = true; } status = winbindd_send_request(ctx, req_type, 0, request); @@ -899,6 +796,9 @@ status = winbindd_get_response(ctx, response); out: + if (release_global_ctx) { + put_wb_global_ctx(); + } return status; } @@ -908,9 +808,11 @@ struct winbindd_response *response) { NSS_STATUS status = NSS_STATUS_UNAVAIL; + bool release_global_ctx = false; if (ctx == NULL) { ctx = get_wb_global_ctx(); + release_global_ctx = true; } status = winbindd_send_request(ctx, req_type, 1, request); @@ -920,6 +822,9 @@ status = winbindd_get_response(ctx, response); out: + if (release_global_ctx) { + put_wb_global_ctx(); + } return status; }