[PATCH 6/6] Move wbc global variables into global context instead
Matthew Newton
mcn4 at leicester.ac.uk
Sun Feb 22 18:21:05 MST 2015
There are some global variables in use in the libwbclient
library. Now that we have a context, move these into it so that
they are thread-safe when the wbcCtx* functions are used.
Signed-off-by: Matthew Newton <matthew-git at newtoncomputing.co.uk>
---
nsswitch/libwbclient/wbc_pwd.c | 127 ++++++++++++++++++------------
nsswitch/libwbclient/wbclient.c | 9 +++
nsswitch/libwbclient/wbclient.h | 4 +
nsswitch/libwbclient/wbclient_internal.h | 2 +
4 files changed, 90 insertions(+), 52 deletions(-)
diff --git a/nsswitch/libwbclient/wbc_pwd.c b/nsswitch/libwbclient/wbc_pwd.c
index 0b05133..3bf437c 100644
--- a/nsswitch/libwbclient/wbc_pwd.c
+++ b/nsswitch/libwbclient/wbc_pwd.c
@@ -4,6 +4,7 @@
Winbind client API
Copyright (C) Gerald (Jerry) Carter 2007
+ Copyright (C) Matthew Newton 2015
This library is free software; you can redistribute it and/or
@@ -359,28 +360,24 @@ wbcErr wbcGetgrgid(gid_t gid, struct group **grp)
return wbcCtxGetgrgid(NULL, gid, grp);
}
-/** @brief Number of cached passwd structs
- *
- */
-static uint32_t pw_cache_size;
-
-/** @brief Position of the pwent context
- *
- */
-static uint32_t pw_cache_idx;
-
/** @brief Winbindd response containing the passwd structs
*
*/
static struct winbindd_response pw_response;
/* Reset the passwd iterator */
-wbcErr wbcCtxSetpwent(struct wbcContext *ctx)
+wbcErr wbcCtxSetpwent(struct wbcContext *_ctx)
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ struct wbcContext *ctx;
- if (pw_cache_size > 0) {
- pw_cache_idx = pw_cache_size = 0;
+ ctx = _ctx;
+ if (!ctx) {
+ ctx = &wbcGlobalCtx;
+ }
+
+ if (ctx->pw_cache_size > 0) {
+ ctx->pw_cache_idx = ctx->pw_cache_size = 0;
winbindd_free_response(&pw_response);
}
@@ -400,12 +397,18 @@ wbcErr wbcSetpwent(void)
}
/* Close the passwd iterator */
-wbcErr wbcCtxEndpwent(struct wbcContext *ctx)
+wbcErr wbcCtxEndpwent(struct wbcContext *_ctx)
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ struct wbcContext *ctx;
+
+ ctx = _ctx;
+ if (!ctx) {
+ ctx = &wbcGlobalCtx;
+ }
- if (pw_cache_size > 0) {
- pw_cache_idx = pw_cache_size = 0;
+ if (ctx->pw_cache_size > 0) {
+ ctx->pw_cache_idx = ctx->pw_cache_size = 0;
winbindd_free_response(&pw_response);
}
@@ -423,20 +426,26 @@ wbcErr wbcEndpwent(void)
}
/* Return the next struct passwd* entry from the pwent iterator */
-wbcErr wbcCtxGetpwent(struct wbcContext *ctx, struct passwd **pwd)
+wbcErr wbcCtxGetpwent(struct wbcContext *_ctx, struct passwd **pwd)
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
struct winbindd_request request;
struct winbindd_pw *wb_pw;
+ struct wbcContext *ctx;
+
+ ctx = _ctx;
+ if (!ctx) {
+ ctx = &wbcGlobalCtx;
+ }
/* If there's a cached result, return that. */
- if (pw_cache_idx < pw_cache_size) {
+ if (ctx->pw_cache_idx < ctx->pw_cache_size) {
goto return_result;
}
/* Otherwise, query winbindd for some entries. */
- pw_cache_idx = 0;
+ ctx->pw_cache_idx = 0;
winbindd_free_response(&pw_response);
@@ -448,17 +457,17 @@ wbcErr wbcCtxGetpwent(struct wbcContext *ctx, struct passwd **pwd)
BAIL_ON_WBC_ERROR(wbc_status);
- pw_cache_size = pw_response.data.num_entries;
+ ctx->pw_cache_size = pw_response.data.num_entries;
return_result:
wb_pw = (struct winbindd_pw *) pw_response.extra_data.data;
- *pwd = copy_passwd_entry(&wb_pw[pw_cache_idx]);
+ *pwd = copy_passwd_entry(&wb_pw[ctx->pw_cache_idx]);
BAIL_ON_PTR_ERROR(*pwd, wbc_status);
- pw_cache_idx++;
+ ctx->pw_cache_idx++;
done:
return wbc_status;
@@ -469,28 +478,24 @@ wbcErr wbcGetpwent(struct passwd **pwd)
return wbcCtxGetpwent(NULL, pwd);
}
-/** @brief Number of cached group structs
- *
- */
-static uint32_t gr_cache_size;
-
-/** @brief Position of the grent context
- *
- */
-static uint32_t gr_cache_idx;
-
/** @brief Winbindd response containing the group structs
*
*/
static struct winbindd_response gr_response;
/* Reset the group iterator */
-wbcErr wbcCtxSetgrent(struct wbcContext *ctx)
+wbcErr wbcCtxSetgrent(struct wbcContext *_ctx)
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ struct wbcContext *ctx;
+
+ ctx = _ctx;
+ if (!ctx) {
+ ctx = &wbcGlobalCtx;
+ }
- if (gr_cache_size > 0) {
- gr_cache_idx = gr_cache_size = 0;
+ if (ctx->gr_cache_size > 0) {
+ ctx->gr_cache_idx = ctx->gr_cache_size = 0;
winbindd_free_response(&gr_response);
}
@@ -510,12 +515,18 @@ wbcErr wbcSetgrent(void)
}
/* Close the group iterator */
-wbcErr wbcCtxEndgrent(struct wbcContext *ctx)
+wbcErr wbcCtxEndgrent(struct wbcContext *_ctx)
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ struct wbcContext *ctx;
- if (gr_cache_size > 0) {
- gr_cache_idx = gr_cache_size = 0;
+ ctx = _ctx;
+ if (!ctx) {
+ ctx = &wbcGlobalCtx;
+ }
+
+ if (ctx->gr_cache_size > 0) {
+ ctx->gr_cache_idx = ctx->gr_cache_size = 0;
winbindd_free_response(&gr_response);
}
@@ -533,21 +544,27 @@ wbcErr wbcEndgrent(void)
}
/* Return the next struct group* entry from the pwent iterator */
-wbcErr wbcCtxGetgrent(struct wbcContext *ctx, struct group **grp)
+wbcErr wbcCtxGetgrent(struct wbcContext *_ctx, struct group **grp)
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
struct winbindd_request request;
struct winbindd_gr *wb_gr;
uint32_t mem_ofs;
+ struct wbcContext *ctx;
+
+ ctx = _ctx;
+ if (!ctx) {
+ ctx = &wbcGlobalCtx;
+ }
/* If there's a cached result, return that. */
- if (gr_cache_idx < gr_cache_size) {
+ if (ctx->gr_cache_idx < ctx->gr_cache_size) {
goto return_result;
}
/* Otherwise, query winbindd for some entries. */
- gr_cache_idx = 0;
+ ctx->gr_cache_idx = 0;
winbindd_free_response(&gr_response);
@@ -559,21 +576,21 @@ wbcErr wbcCtxGetgrent(struct wbcContext *ctx, struct group **grp)
BAIL_ON_WBC_ERROR(wbc_status);
- gr_cache_size = gr_response.data.num_entries;
+ ctx->gr_cache_size = gr_response.data.num_entries;
return_result:
wb_gr = (struct winbindd_gr *) gr_response.extra_data.data;
- mem_ofs = wb_gr[gr_cache_idx].gr_mem_ofs +
- gr_cache_size * sizeof(struct winbindd_gr);
+ mem_ofs = wb_gr[ctx->gr_cache_idx].gr_mem_ofs +
+ ctx->gr_cache_size * sizeof(struct winbindd_gr);
- *grp = copy_group_entry(&wb_gr[gr_cache_idx],
+ *grp = copy_group_entry(&wb_gr[ctx->gr_cache_idx],
((char *)gr_response.extra_data.data)+mem_ofs);
BAIL_ON_PTR_ERROR(*grp, wbc_status);
- gr_cache_idx++;
+ ctx->gr_cache_idx++;
done:
return wbc_status;
@@ -585,20 +602,26 @@ wbcErr wbcGetgrent(struct group **grp)
}
/* Return the next struct group* entry from the pwent iterator */
-wbcErr wbcCtxGetgrlist(struct wbcContext *ctx, struct group **grp)
+wbcErr wbcCtxGetgrlist(struct wbcContext *_ctx, struct group **grp)
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
struct winbindd_request request;
struct winbindd_gr *wb_gr;
+ struct wbcContext *ctx;
+
+ ctx = _ctx;
+ if (!ctx) {
+ ctx = &wbcGlobalCtx;
+ }
/* If there's a cached result, return that. */
- if (gr_cache_idx < gr_cache_size) {
+ if (ctx->gr_cache_idx < ctx->gr_cache_size) {
goto return_result;
}
/* Otherwise, query winbindd for some entries. */
- gr_cache_idx = 0;
+ ctx->gr_cache_idx = 0;
winbindd_free_response(&gr_response);
ZERO_STRUCT(gr_response);
@@ -611,17 +634,17 @@ wbcErr wbcCtxGetgrlist(struct wbcContext *ctx, struct group **grp)
BAIL_ON_WBC_ERROR(wbc_status);
- gr_cache_size = gr_response.data.num_entries;
+ ctx->gr_cache_size = gr_response.data.num_entries;
return_result:
wb_gr = (struct winbindd_gr *) gr_response.extra_data.data;
- *grp = copy_group_entry(&wb_gr[gr_cache_idx], NULL);
+ *grp = copy_group_entry(&wb_gr[ctx->gr_cache_idx], NULL);
BAIL_ON_PTR_ERROR(*grp, wbc_status);
- gr_cache_idx++;
+ ctx->gr_cache_idx++;
done:
return wbc_status;
diff --git a/nsswitch/libwbclient/wbclient.c b/nsswitch/libwbclient/wbclient.c
index 1d50f88..bdf9854 100644
--- a/nsswitch/libwbclient/wbclient.c
+++ b/nsswitch/libwbclient/wbclient.c
@@ -39,6 +39,15 @@ NSS_STATUS winbindd_priv_request_response(struct winbindd_context *wbctx,
struct winbindd_context *winbindd_ctx_create(void);
void winbindd_ctx_free(struct winbindd_context *ctx);
+/* Global context used for non-Ctx functions */
+
+static struct wbcContext wbcGlobalCtx = {
+ .winbindd_ctx = NULL,
+ .pw_cache_size = 0,
+ .pw_cache_idx = 0,
+ .gr_cache_size = 0,
+ .gr_cache_idx = 0
+};
/*
result == NSS_STATUS_UNAVAIL: winbind not around
diff --git a/nsswitch/libwbclient/wbclient.h b/nsswitch/libwbclient/wbclient.h
index 7994621..8e4d0a1 100644
--- a/nsswitch/libwbclient/wbclient.h
+++ b/nsswitch/libwbclient/wbclient.h
@@ -103,6 +103,10 @@ struct wbcInterfaceDetails {
struct wbcContext {
void *winbindd_ctx; /* winbindd context */
+ uint32_t pw_cache_size; /* Number of cached passwd structs */
+ uint32_t pw_cache_idx; /* Position of the pwent context */
+ uint32_t gr_cache_size; /* Number of cached group structs */
+ uint32_t gr_cache_idx; /* Position of the grent context */
};
/*
diff --git a/nsswitch/libwbclient/wbclient_internal.h b/nsswitch/libwbclient/wbclient_internal.h
index c63180a..1424a2c 100644
--- a/nsswitch/libwbclient/wbclient_internal.h
+++ b/nsswitch/libwbclient/wbclient_internal.h
@@ -38,4 +38,6 @@ void *wbcAllocateMemory(size_t nelem, size_t elsize,
char *wbcStrDup(const char *str);
const char **wbcAllocateStringArray(int num_strings);
+static struct wbcContext wbcGlobalCtx;
+
#endif /* _WBCLIENT_INTERNAL_H */
--
1.7.10.4
--
Matthew Newton, Ph.D. <mcn4 at le.ac.uk>
Systems Specialist, Infrastructure Services,
I.T. Services, University of Leicester, Leicester LE1 7RH, United Kingdom
For IT help contact helpdesk extn. 2253, <ithelp at le.ac.uk>
More information about the samba-technical
mailing list