#include "system/select.h"
#include "winbind_client.h"
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+
+static char client_name[32];
+
/* Global context */
struct winbindd_context {
pid_t our_pid; /* calling process pid */
};
-static struct winbindd_context wb_global_ctx = {
- .winbindd_fd = -1,
- .is_privileged = 0,
- .our_pid = 0
-};
+#ifdef HAVE_PTHREAD
+static pthread_mutex_t wb_global_ctx_mutex = PTHREAD_MUTEX_INITIALIZER;
+#endif
+
+static struct winbindd_context *get_wb_global_ctx(void)
+{
+ static struct winbindd_context wb_global_ctx = {
+ .winbindd_fd = -1,
+ .is_privileged = false,
+ .our_pid = 0
+ };
+
+#ifdef HAVE_PTHREAD
+ pthread_mutex_lock(&wb_global_ctx_mutex);
+#endif
+ return &wb_global_ctx;
+}
+
+static void put_wb_global_ctx(void)
+{
+#ifdef HAVE_PTHREAD
+ pthread_mutex_unlock(&wb_global_ctx_mutex);
+#endif
+ return;
+}
/* Free a response structure */
SAFE_FREE(response->extra_data.data);
}
+void winbind_set_client_name(const char *name)
+{
+ if (name == NULL || strlen(name) == 0) {
+ return;
+ }
+
+ (void)snprintf(client_name, sizeof(client_name), "%s", name);
+}
+
+static const char *winbind_get_client_name(void)
+{
+ if (client_name[0] == '\0') {
+ const char *progname = getprogname();
+ int len;
+
+ if (progname == NULL) {
+ progname = "<unknown>";
+ }
+
+ len = snprintf(client_name,
+ sizeof(client_name),
+ "%s",
+ progname);
+ if (len <= 0) {
+ return progname;
+ }
+ }
+
+ return client_name;
+}
+
/* Initialise a request structure */
static void winbindd_init_request(struct winbindd_request *request,
request->cmd = (enum winbindd_cmd)request_type;
request->pid = getpid();
+ (void)snprintf(request->client_name,
+ sizeof(request->client_name),
+ "%s",
+ winbind_get_client_name());
}
/* Initialise a response structure */
/* Destructor for global context to ensure fd is closed */
-#if HAVE_DESTRUCTOR_ATTRIBUTE
+#ifdef HAVE_DESTRUCTOR_ATTRIBUTE
__attribute__((destructor))
#endif
static void winbind_destructor(void)
{
- winbind_close_sock(&wb_global_ctx);
+ struct winbindd_context *ctx;
+
+ ctx = get_wb_global_ctx();
+ winbind_close_sock(ctx);
+ put_wb_global_ctx();
}
#define CONNECT_TIMEOUT 30
ctx->our_pid = getpid();
}
- if ((need_priv != 0) && (ctx->is_privileged == 0)) {
+ if ((need_priv != 0) && !ctx->is_privileged) {
winbind_close_sock(ctx);
}
return -1;
}
- ctx->is_privileged = 0;
+ ctx->is_privileged = false;
/* version-check the socket */
if (fd != -1) {
close(ctx->winbindd_fd);
ctx->winbindd_fd = fd;
- ctx->is_privileged = 1;
+ ctx->is_privileged = true;
}
SAFE_FREE(response.extra_data.data);
}
- if (ctx->is_privileged == 0) {
+ if (!ctx->is_privileged) {
return -1;
}
struct winbindd_response *response)
{
NSS_STATUS status = NSS_STATUS_UNAVAIL;
+ bool release_global_ctx = false;
if (ctx == NULL) {
- ctx = &wb_global_ctx;
+ ctx = get_wb_global_ctx();
+ release_global_ctx = true;
}
status = winbindd_send_request(ctx, req_type, 0, request);
- if (status != NSS_STATUS_SUCCESS)
- return (status);
+ if (status != NSS_STATUS_SUCCESS) {
+ goto out;
+ }
status = winbindd_get_response(ctx, response);
+out:
+ if (release_global_ctx) {
+ put_wb_global_ctx();
+ }
return status;
}
struct winbindd_response *response)
{
NSS_STATUS status = NSS_STATUS_UNAVAIL;
+ bool release_global_ctx = false;
if (ctx == NULL) {
- ctx = &wb_global_ctx;
+ ctx = get_wb_global_ctx();
+ release_global_ctx = true;
}
status = winbindd_send_request(ctx, req_type, 1, request);
- if (status != NSS_STATUS_SUCCESS)
- return (status);
+ if (status != NSS_STATUS_SUCCESS) {
+ goto out;
+ }
status = winbindd_get_response(ctx, response);
+out:
+ if (release_global_ctx) {
+ put_wb_global_ctx();
+ }
return status;
}