The Samba-Bugzilla – Attachment 10862 Details for
Bug 11149
libwbclient uses global variables and is not thread safe
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
git-am backport from master.
look (text/plain), 144.43 KB, created by
Jeremy Allison
on 2015-03-11 18:11:55 UTC
(
hide
)
Description:
git-am backport from master.
Filename:
MIME Type:
Creator:
Jeremy Allison
Created:
2015-03-11 18:11:55 UTC
Size:
144.43 KB
patch
obsolete
>From 49dd14678703c9680408039791c28c19c0ddaae7 Mon Sep 17 00:00:00 2001 >From: Matthew Newton <matthew-git@newtoncomputing.co.uk> >Date: Fri, 23 Jan 2015 22:35:50 +0000 >Subject: [PATCH 1/7] Make winbind client library thread-safe by adding context > >Rather than keep state in global variables, store the current >context such as the winbind file descriptor in a struct that is >passed in. This makes the winbind client library thread-safe. > >https://bugzilla.samba.org/show_bug.cgi?id=11149 > >Signed-off-by: Matthew Newton <matthew-git@newtoncomputing.co.uk> >Reviewed-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 60c7571984d7f1612828a72fae3ed8e66037d1f7) >--- > nsswitch/wb_common.c | 181 +++++++++++++++++++++++---------- > nsswitch/winbind_client.h | 23 +++-- > source4/torture/winbind/struct_based.c | 2 +- > 3 files changed, 144 insertions(+), 62 deletions(-) > >diff --git a/nsswitch/wb_common.c b/nsswitch/wb_common.c >index 44bfaf4..1bccfda 100644 >--- a/nsswitch/wb_common.c >+++ b/nsswitch/wb_common.c >@@ -6,6 +6,7 @@ > Copyright (C) Tim Potter 2000 > Copyright (C) Andrew Tridgell 2000 > Copyright (C) Andrew Bartlett 2002 >+ Copyright (C) Matthew Newton 2015 > > > This library is free software; you can redistribute it and/or >@@ -26,10 +27,19 @@ > #include "system/select.h" > #include "winbind_client.h" > >-/* Global variables. These are effectively the client state information */ >+/* Global context */ > >-int winbindd_fd = -1; /* fd for winbindd socket */ >-static int is_privileged = 0; >+struct winbindd_context { >+ int winbindd_fd; /* winbind file descriptor */ >+ bool is_privileged; /* using the privileged socket? */ >+ pid_t our_pid; /* calling process pid */ >+}; >+ >+static struct winbindd_context wb_global_ctx = { >+ .winbindd_fd = -1, >+ .is_privileged = 0, >+ .our_pid = 0 >+}; > > /* Free a response structure */ > >@@ -64,15 +74,26 @@ static void init_response(struct winbindd_response *response) > > /* Close established socket */ > >+static void winbind_close_sock(struct winbindd_context *ctx) >+{ >+ if (!ctx) { >+ return; >+ } >+ >+ if (ctx->winbindd_fd != -1) { >+ close(ctx->winbindd_fd); >+ ctx->winbindd_fd = -1; >+ } >+} >+ >+/* Destructor for global context to ensure fd is closed */ >+ > #if HAVE_FUNCTION_ATTRIBUTE_DESTRUCTOR > __attribute__((destructor)) > #endif >-static void winbind_close_sock(void) >+static void winbind_destructor(void) > { >- if (winbindd_fd != -1) { >- close(winbindd_fd); >- winbindd_fd = -1; >- } >+ winbind_close_sock(&wb_global_ctx); > } > > #define CONNECT_TIMEOUT 30 >@@ -333,43 +354,52 @@ static const char *winbindd_socket_dir(void) > > /* Connect to winbindd socket */ > >-static int winbind_open_pipe_sock(int recursing, int need_priv) >+static int winbind_open_pipe_sock(struct winbindd_context *ctx, >+ int recursing, int need_priv) > { > #ifdef HAVE_UNIXSOCKET >- static pid_t our_pid; > struct winbindd_request request; > struct winbindd_response response; >+ > ZERO_STRUCT(request); > ZERO_STRUCT(response); > >- if (our_pid != getpid()) { >- winbind_close_sock(); >- our_pid = getpid(); >+ if (!ctx) { >+ return -1; > } > >- if ((need_priv != 0) && (is_privileged == 0)) { >- winbind_close_sock(); >+ if (ctx->our_pid != getpid()) { >+ winbind_close_sock(ctx); >+ ctx->our_pid = getpid(); > } > >- if (winbindd_fd != -1) { >- return winbindd_fd; >+ if ((need_priv != 0) && (ctx->is_privileged == 0)) { >+ winbind_close_sock(ctx); >+ } >+ >+ if (ctx->winbindd_fd != -1) { >+ return ctx->winbindd_fd; > } > > if (recursing) { > return -1; > } > >- if ((winbindd_fd = winbind_named_pipe_sock(winbindd_socket_dir())) == -1) { >+ ctx->winbindd_fd = winbind_named_pipe_sock(winbindd_socket_dir()); >+ >+ if (ctx->winbindd_fd == -1) { > return -1; > } > >- is_privileged = 0; >+ ctx->is_privileged = 0; > > /* version-check the socket */ > > request.wb_flags = WBFLAG_RECURSE; >- if ((winbindd_request_response(WINBINDD_INTERFACE_VERSION, &request, &response) != NSS_STATUS_SUCCESS) || (response.data.interface_version != WINBIND_INTERFACE_VERSION)) { >- winbind_close_sock(); >+ if ((winbindd_request_response(ctx, WINBINDD_INTERFACE_VERSION, &request, >+ &response) != NSS_STATUS_SUCCESS) || >+ (response.data.interface_version != WINBIND_INTERFACE_VERSION)) { >+ winbind_close_sock(ctx); > return -1; > } > >@@ -383,22 +413,24 @@ static int winbind_open_pipe_sock(int recursing, int need_priv) > * thus response.extra_data.data will not be NULL even though > * winbindd response did not write over it due to a failure */ > ZERO_STRUCT(response); >- if (winbindd_request_response(WINBINDD_PRIV_PIPE_DIR, &request, &response) == NSS_STATUS_SUCCESS) { >+ if (winbindd_request_response(ctx, WINBINDD_PRIV_PIPE_DIR, &request, >+ &response) == NSS_STATUS_SUCCESS) { > int fd; >- if ((fd = winbind_named_pipe_sock((char *)response.extra_data.data)) != -1) { >- close(winbindd_fd); >- winbindd_fd = fd; >- is_privileged = 1; >+ fd = winbind_named_pipe_sock((char *)response.extra_data.data); >+ if (fd != -1) { >+ close(ctx->winbindd_fd); >+ ctx->winbindd_fd = fd; >+ ctx->is_privileged = 1; > } > } > >- if ((need_priv != 0) && (is_privileged == 0)) { >+ if ((need_priv != 0) && (ctx->is_privileged == 0)) { > return -1; > } > > SAFE_FREE(response.extra_data.data); > >- return winbindd_fd; >+ return ctx->winbindd_fd; > #else > return -1; > #endif /* HAVE_UNIXSOCKET */ >@@ -406,8 +438,8 @@ static int winbind_open_pipe_sock(int recursing, int need_priv) > > /* Write data to winbindd socket */ > >-static int winbind_write_sock(void *buffer, int count, int recursing, >- int need_priv) >+static int winbind_write_sock(struct winbindd_context *ctx, void *buffer, >+ int count, int recursing, int need_priv) > { > int fd, result, nwritten; > >@@ -415,7 +447,7 @@ static int winbind_write_sock(void *buffer, int count, int recursing, > > restart: > >- fd = winbind_open_pipe_sock(recursing, need_priv); >+ fd = winbind_open_pipe_sock(ctx, recursing, need_priv); > if (fd == -1) { > errno = ENOENT; > return -1; >@@ -437,7 +469,7 @@ static int winbind_write_sock(void *buffer, int count, int recursing, > > ret = poll(&pfd, 1, -1); > if (ret == -1) { >- winbind_close_sock(); >+ winbind_close_sock(ctx); > return -1; /* poll error */ > } > >@@ -447,7 +479,7 @@ static int winbind_write_sock(void *buffer, int count, int recursing, > > /* Pipe has closed on remote end */ > >- winbind_close_sock(); >+ winbind_close_sock(ctx); > goto restart; > } > >@@ -460,7 +492,7 @@ static int winbind_write_sock(void *buffer, int count, int recursing, > > /* Write failed */ > >- winbind_close_sock(); >+ winbind_close_sock(ctx); > return -1; > } > >@@ -472,13 +504,14 @@ static int winbind_write_sock(void *buffer, int count, int recursing, > > /* Read data from winbindd socket */ > >-static int winbind_read_sock(void *buffer, int count) >+static int winbind_read_sock(struct winbindd_context *ctx, >+ void *buffer, int count) > { > int fd; > int nread = 0; > int total_time = 0; > >- fd = winbind_open_pipe_sock(false, false); >+ fd = winbind_open_pipe_sock(ctx, false, false); > if (fd == -1) { > return -1; > } >@@ -498,7 +531,7 @@ static int winbind_read_sock(void *buffer, int count) > > ret = poll(&pfd, 1, 5000); > if (ret == -1) { >- winbind_close_sock(); >+ winbind_close_sock(ctx); > return -1; /* poll error */ > } > >@@ -506,7 +539,7 @@ static int winbind_read_sock(void *buffer, int count) > /* Not ready for read yet... */ > if (total_time >= 30) { > /* Timeout */ >- winbind_close_sock(); >+ winbind_close_sock(ctx); > return -1; > } > total_time += 5; >@@ -526,7 +559,7 @@ static int winbind_read_sock(void *buffer, int count) > can do here is just return -1 and fail since the > transaction has failed half way through. */ > >- winbind_close_sock(); >+ winbind_close_sock(ctx); > return -1; > } > >@@ -540,7 +573,8 @@ static int winbind_read_sock(void *buffer, int count) > > /* Read reply */ > >-static int winbindd_read_reply(struct winbindd_response *response) >+static int winbindd_read_reply(struct winbindd_context *ctx, >+ struct winbindd_response *response) > { > int result1, result2 = 0; > >@@ -550,7 +584,7 @@ static int winbindd_read_reply(struct winbindd_response *response) > > /* Read fixed length response */ > >- result1 = winbind_read_sock(response, >+ result1 = winbind_read_sock(ctx, response, > sizeof(struct winbindd_response)); > if (result1 == -1) { > return -1; >@@ -578,7 +612,7 @@ static int winbindd_read_reply(struct winbindd_response *response) > return -1; > } > >- result2 = winbind_read_sock(response->extra_data.data, >+ result2 = winbind_read_sock(ctx, response->extra_data.data, > extra_data_len); > if (result2 == -1) { > winbindd_free_response(response); >@@ -595,7 +629,8 @@ static int winbindd_read_reply(struct winbindd_response *response) > * send simple types of requests > */ > >-NSS_STATUS winbindd_send_request(int req_type, int need_priv, >+NSS_STATUS winbindd_send_request(struct winbindd_context *ctx, >+ int req_type, int need_priv, > struct winbindd_request *request) > { > struct winbindd_request lrequest; >@@ -615,7 +650,7 @@ NSS_STATUS winbindd_send_request(int req_type, int need_priv, > > winbindd_init_request(request, req_type); > >- if (winbind_write_sock(request, sizeof(*request), >+ if (winbind_write_sock(ctx, request, sizeof(*request), > request->wb_flags & WBFLAG_RECURSE, > need_priv) == -1) > { >@@ -626,7 +661,7 @@ NSS_STATUS winbindd_send_request(int req_type, int need_priv, > } > > if ((request->extra_len != 0) && >- (winbind_write_sock(request->extra_data.data, >+ (winbind_write_sock(ctx, request->extra_data.data, > request->extra_len, > request->wb_flags & WBFLAG_RECURSE, > need_priv) == -1)) >@@ -644,7 +679,8 @@ NSS_STATUS winbindd_send_request(int req_type, int need_priv, > * Get results from winbindd request > */ > >-NSS_STATUS winbindd_get_response(struct winbindd_response *response) >+NSS_STATUS winbindd_get_response(struct winbindd_context *ctx, >+ struct winbindd_response *response) > { > struct winbindd_response lresponse; > >@@ -656,7 +692,7 @@ NSS_STATUS winbindd_get_response(struct winbindd_response *response) > init_response(response); > > /* Wait for reply */ >- if (winbindd_read_reply(response) == -1) { >+ if (winbindd_read_reply(ctx, response) == -1) { > /* Set ENOENT for consistency. Required by some apps */ > errno = ENOENT; > >@@ -678,38 +714,73 @@ NSS_STATUS winbindd_get_response(struct winbindd_response *response) > > /* Handle simple types of requests */ > >-NSS_STATUS winbindd_request_response(int req_type, >- struct winbindd_request *request, >- struct winbindd_response *response) >+NSS_STATUS winbindd_request_response(struct winbindd_context *ctx, >+ int req_type, >+ struct winbindd_request *request, >+ struct winbindd_response *response) > { > NSS_STATUS status = NSS_STATUS_UNAVAIL; > int count = 0; >+ struct winbindd_context *wb_ctx = ctx; >+ >+ if (ctx == NULL) { >+ wb_ctx = &wb_global_ctx; >+ } > > while ((status == NSS_STATUS_UNAVAIL) && (count < 10)) { >- status = winbindd_send_request(req_type, 0, request); >+ status = winbindd_send_request(wb_ctx, req_type, 0, request); > if (status != NSS_STATUS_SUCCESS) > return(status); >- status = winbindd_get_response(response); >+ status = winbindd_get_response(wb_ctx, response); > count += 1; > } > > return status; > } > >-NSS_STATUS winbindd_priv_request_response(int req_type, >+NSS_STATUS winbindd_priv_request_response(struct winbindd_context *ctx, >+ int req_type, > struct winbindd_request *request, > struct winbindd_response *response) > { > NSS_STATUS status = NSS_STATUS_UNAVAIL; > int count = 0; >+ struct winbindd_context *wb_ctx; >+ >+ if (ctx == NULL) { >+ wb_ctx = &wb_global_ctx; >+ } > > while ((status == NSS_STATUS_UNAVAIL) && (count < 10)) { >- status = winbindd_send_request(req_type, 1, request); >+ status = winbindd_send_request(wb_ctx, req_type, 1, request); > if (status != NSS_STATUS_SUCCESS) > return(status); >- status = winbindd_get_response(response); >+ status = winbindd_get_response(wb_ctx, response); > count += 1; > } > > return status; > } >+ >+/* Create and free winbindd context */ >+ >+struct winbindd_context *winbindd_ctx_create(void) >+{ >+ struct winbindd_context *ctx; >+ >+ ctx = calloc(1, sizeof(struct winbindd_context)); >+ >+ if (!ctx) { >+ return NULL; >+ } >+ >+ ctx->winbindd_fd = -1; >+ >+ return ctx; >+} >+ >+void winbindd_ctx_free(struct winbindd_context *ctx) >+{ >+ winbind_close_sock(ctx); >+ free(ctx); >+} >diff --git a/nsswitch/winbind_client.h b/nsswitch/winbind_client.h >index 905a189..d6b46fc 100644 >--- a/nsswitch/winbind_client.h >+++ b/nsswitch/winbind_client.h >@@ -6,6 +6,7 @@ > Copyright (C) Tim Potter 2000 > Copyright (C) Andrew Tridgell 2000 > Copyright (C) Andrew Bartlett 2002 >+ Copyright (C) Matthew Newton 2015 > > > This library is free software; you can redistribute it and/or >@@ -28,16 +29,26 @@ > #include "winbind_nss_config.h" > #include "winbind_struct_protocol.h" > >+struct winbindd_context; >+ >+struct winbindd_context *winbindd_ctx_create(void); >+void winbindd_ctx_free(struct winbindd_context *ctx); >+ > void winbindd_free_response(struct winbindd_response *response); >-NSS_STATUS winbindd_send_request(int req_type, int need_priv, >+NSS_STATUS winbindd_send_request(struct winbindd_context *ctx, >+ int req_type, int need_priv, > struct winbindd_request *request); >-NSS_STATUS winbindd_get_response(struct winbindd_response *response); >-NSS_STATUS winbindd_request_response(int req_type, >- struct winbindd_request *request, >- struct winbindd_response *response); >-NSS_STATUS winbindd_priv_request_response(int req_type, >+NSS_STATUS winbindd_get_response(struct winbindd_context *ctx, >+ struct winbindd_response *response); >+NSS_STATUS winbindd_request_response(struct winbindd_context *ctx, >+ int req_type, >+ struct winbindd_request *request, >+ struct winbindd_response *response); >+NSS_STATUS winbindd_priv_request_response(struct winbindd_context *ctx, >+ int req_type, > struct winbindd_request *request, > struct winbindd_response *response); >+ > #define winbind_env_set() \ > (strcmp(getenv(WINBINDD_DONT_ENV)?getenv(WINBINDD_DONT_ENV):"0","1") == 0) > >diff --git a/source4/torture/winbind/struct_based.c b/source4/torture/winbind/struct_based.c >index d47d068..883b38c 100644 >--- a/source4/torture/winbind/struct_based.c >+++ b/source4/torture/winbind/struct_based.c >@@ -29,7 +29,7 @@ > > #define DO_STRUCT_REQ_REP_EXT(op,req,rep,expected,strict,warnaction,cmt) do { \ > NSS_STATUS __got, __expected = (expected); \ >- __got = winbindd_request_response(op, req, rep); \ >+ __got = winbindd_request_response(NULL, op, req, rep); \ > if (__got != __expected) { \ > const char *__cmt = (cmt); \ > if (strict) { \ >-- >1.9.1 > > >From b85dc8e70548853a91ac89d43e71446c10538c00 Mon Sep 17 00:00:00 2001 >From: Matthew Newton <matthew-git@newtoncomputing.co.uk> >Date: Fri, 23 Jan 2015 23:58:53 +0000 >Subject: [PATCH 2/7] Use global context for winbindd_request_response > >Updating API call in libwbclient, wbinfo, ntlm_auth and >winbind_nss_* as per previous commit to wb_common.c. > >https://bugzilla.samba.org/show_bug.cgi?id=11149 > >Signed-off-by: Matthew Newton <matthew-git@newtoncomputing.co.uk> >Reviewed-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 83cfb84b78ce7141652f1fdc7f01978cdb69343f) >--- > nsswitch/libwbclient/wbclient.c | 10 +++++---- > nsswitch/wbinfo.c | 4 ++-- > nsswitch/winbind_nss_aix.c | 30 ++++++++++++++++--------- > nsswitch/winbind_nss_linux.c | 49 +++++++++++++++++++++++++---------------- > nsswitch/winbind_nss_netbsd.c | 3 ++- > nsswitch/winbind_nss_solaris.c | 9 +++++--- > source3/utils/ntlm_auth.c | 16 +++++++------- > 7 files changed, 74 insertions(+), 47 deletions(-) > >diff --git a/nsswitch/libwbclient/wbclient.c b/nsswitch/libwbclient/wbclient.c >index 19bb3e9..93c0318e 100644 >--- a/nsswitch/libwbclient/wbclient.c >+++ b/nsswitch/libwbclient/wbclient.c >@@ -27,10 +27,12 @@ > > /* From wb_common.c */ > >-NSS_STATUS winbindd_request_response(int req_type, >+NSS_STATUS winbindd_request_response(struct winbindd_context *wbctx, >+ int req_type, > struct winbindd_request *request, > struct winbindd_response *response); >-NSS_STATUS winbindd_priv_request_response(int req_type, >+NSS_STATUS winbindd_priv_request_response(struct winbindd_context *wbctx, >+ int req_type, > struct winbindd_request *request, > struct winbindd_response *response); > >@@ -51,7 +53,7 @@ static wbcErr wbcRequestResponseInt( > int cmd, > struct winbindd_request *request, > struct winbindd_response *response, >- NSS_STATUS (*fn)(int req_type, >+ NSS_STATUS (*fn)(struct winbindd_context *wbctx, int req_type, > struct winbindd_request *request, > struct winbindd_response *response)) > { >@@ -60,7 +62,7 @@ static wbcErr wbcRequestResponseInt( > > /* for some calls the request and/or response can be NULL */ > >- nss_status = fn(cmd, request, response); >+ nss_status = fn(NULL, cmd, request, response); > > switch (nss_status) { > case NSS_STATUS_SUCCESS: >diff --git a/nsswitch/wbinfo.c b/nsswitch/wbinfo.c >index a31fbdf..216379f 100644 >--- a/nsswitch/wbinfo.c >+++ b/nsswitch/wbinfo.c >@@ -688,7 +688,7 @@ static bool wbinfo_getdcname(const char *domain_name) > > /* Send request */ > >- if (winbindd_request_response(WINBINDD_GETDCNAME, &request, >+ if (winbindd_request_response(NULL, WINBINDD_GETDCNAME, &request, > &response) != NSS_STATUS_SUCCESS) { > d_fprintf(stderr, "Could not get dc name for %s\n",domain_name); > return false; >@@ -1898,7 +1898,7 @@ static bool wbinfo_klog(char *username) > > request.flags |= WBFLAG_PAM_AFS_TOKEN; > >- result = winbindd_request_response(WINBINDD_PAM_AUTH, &request, >+ result = winbindd_request_response(NULL, WINBINDD_PAM_AUTH, &request, > &response); > > /* Display response */ >diff --git a/nsswitch/winbind_nss_aix.c b/nsswitch/winbind_nss_aix.c >index 66200f3..7a847b2 100644 >--- a/nsswitch/winbind_nss_aix.c >+++ b/nsswitch/winbind_nss_aix.c >@@ -279,7 +279,8 @@ static struct group *wb_aix_getgrgid(gid_t gid) > > request.data.gid = gid; > >- ret = winbindd_request_response(WINBINDD_GETGRGID, &request, &response); >+ ret = winbindd_request_response(NULL, WINBINDD_GETGRGID, >+ &request, &response); > > logit("getgrgid ret=%d\n", ret); > >@@ -311,7 +312,8 @@ static struct group *wb_aix_getgrnam(const char *name) > > STRCPY_RETNULL(request.data.groupname, name); > >- ret = winbindd_request_response(WINBINDD_GETGRNAM, &request, &response); >+ ret = winbindd_request_response(NULL, WINBINDD_GETGRNAM, >+ &request, &response); > > HANDLE_ERRORS(ret); > >@@ -370,7 +372,8 @@ static char *wb_aix_getgrset(char *user) > free(r_user); > } > >- ret = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response); >+ ret = winbindd_request_response(NULL, WINBINDD_GETGROUPS, >+ &request, &response); > > HANDLE_ERRORS(ret); > >@@ -409,7 +412,8 @@ static struct passwd *wb_aix_getpwuid(uid_t uid) > > request.data.uid = uid; > >- ret = winbindd_request_response(WINBINDD_GETPWUID, &request, &response); >+ ret = winbindd_request_response(NULL, WINBINDD_GETPWUID, >+ &request, &response); > > HANDLE_ERRORS(ret); > >@@ -442,7 +446,8 @@ static struct passwd *wb_aix_getpwnam(const char *name) > > STRCPY_RETNULL(request.data.username, name); > >- ret = winbindd_request_response(WINBINDD_GETPWNAM, &request, &response); >+ ret = winbindd_request_response(NULL, WINBINDD_GETPWNAM, >+ &request, &response); > > HANDLE_ERRORS(ret); > >@@ -475,7 +480,8 @@ static int wb_aix_lsuser(char *attributes[], attrval_t results[], int size) > ZERO_STRUCT(request); > ZERO_STRUCT(response); > >- ret = winbindd_request_response(WINBINDD_LIST_USERS, &request, &response); >+ ret = winbindd_request_response(NULL, WINBINDD_LIST_USERS, >+ &request, &response); > if (ret != 0) { > errno = EINVAL; > return -1; >@@ -523,7 +529,8 @@ static int wb_aix_lsgroup(char *attributes[], attrval_t results[], int size) > ZERO_STRUCT(request); > ZERO_STRUCT(response); > >- ret = winbindd_request_response(WINBINDD_LIST_GROUPS, &request, &response); >+ ret = winbindd_request_response(NULL, WINBINDD_LIST_GROUPS, >+ &request, &response); > if (ret != 0) { > errno = EINVAL; > return -1; >@@ -602,7 +609,8 @@ static attrval_t pwd_to_sid(struct passwd *pwd) > > request.data.uid = pwd->pw_uid; > >- if (winbindd_request_response(WINBINDD_UID_TO_SID, &request, &response) != >+ if (winbindd_request_response(NULL, WINBINDD_UID_TO_SID, >+ &request, &response) != > NSS_STATUS_SUCCESS) { > r.attr_flag = ENOENT; > } else { >@@ -888,7 +896,8 @@ static int wb_aix_authenticate(char *user, char *pass, > free(r_user); > } > >- result = winbindd_request_response(WINBINDD_PAM_AUTH, &request, &response); >+ result = winbindd_request_response(NULL, WINBINDD_PAM_AUTH, >+ &request, &response); > > winbindd_free_response(&response); > >@@ -937,7 +946,8 @@ static int wb_aix_chpass(char *user, char *oldpass, char *newpass, char **messag > free(r_user); > } > >- result = winbindd_request_response(WINBINDD_PAM_CHAUTHTOK, &request, &response); >+ result = winbindd_request_response(NULL, WINBINDD_PAM_CHAUTHTOK, >+ &request, &response); > > winbindd_free_response(&response); > >diff --git a/nsswitch/winbind_nss_linux.c b/nsswitch/winbind_nss_linux.c >index 70ede3e..58020e3 100644 >--- a/nsswitch/winbind_nss_linux.c >+++ b/nsswitch/winbind_nss_linux.c >@@ -401,7 +401,7 @@ _nss_winbind_setpwent(void) > winbindd_free_response(&getpwent_response); > } > >- ret = winbindd_request_response(WINBINDD_SETPWENT, NULL, NULL); >+ ret = winbindd_request_response(NULL, WINBINDD_SETPWENT, NULL, NULL); > #ifdef DEBUG_NSS > fprintf(stderr, "[%5d]: setpwent returns %s (%d)\n", getpid(), > nss_err_str(ret), ret); >@@ -432,7 +432,7 @@ _nss_winbind_endpwent(void) > winbindd_free_response(&getpwent_response); > } > >- ret = winbindd_request_response(WINBINDD_ENDPWENT, NULL, NULL); >+ ret = winbindd_request_response(NULL, WINBINDD_ENDPWENT, NULL, NULL); > #ifdef DEBUG_NSS > fprintf(stderr, "[%5d]: endpwent returns %s (%d)\n", getpid(), > nss_err_str(ret), ret); >@@ -481,7 +481,7 @@ _nss_winbind_getpwent_r(struct passwd *result, char *buffer, > > request.data.num_entries = MAX_GETPWENT_USERS; > >- ret = winbindd_request_response(WINBINDD_GETPWENT, &request, >+ ret = winbindd_request_response(NULL, WINBINDD_GETPWENT, &request, > &getpwent_response); > > if (ret == NSS_STATUS_SUCCESS) { >@@ -569,7 +569,7 @@ _nss_winbind_getpwuid_r(uid_t uid, struct passwd *result, char *buffer, > > request.data.uid = uid; > >- ret = winbindd_request_response(WINBINDD_GETPWUID, &request, &response); >+ ret = winbindd_request_response(NULL, WINBINDD_GETPWUID, &request, &response); > > if (ret == NSS_STATUS_SUCCESS) { > ret = fill_pwent(result, &response.data.pw, >@@ -645,7 +645,7 @@ _nss_winbind_getpwnam_r(const char *name, struct passwd *result, char *buffer, > request.data.username > [sizeof(request.data.username) - 1] = '\0'; > >- ret = winbindd_request_response(WINBINDD_GETPWNAM, &request, &response); >+ ret = winbindd_request_response(NULL, WINBINDD_GETPWNAM, &request, &response); > > if (ret == NSS_STATUS_SUCCESS) { > ret = fill_pwent(result, &response.data.pw, &buffer, >@@ -716,7 +716,7 @@ _nss_winbind_setgrent(void) > winbindd_free_response(&getgrent_response); > } > >- ret = winbindd_request_response(WINBINDD_SETGRENT, NULL, NULL); >+ ret = winbindd_request_response(NULL, WINBINDD_SETGRENT, NULL, NULL); > #ifdef DEBUG_NSS > fprintf(stderr, "[%5d]: setgrent returns %s (%d)\n", getpid(), > nss_err_str(ret), ret); >@@ -748,7 +748,7 @@ _nss_winbind_endgrent(void) > winbindd_free_response(&getgrent_response); > } > >- ret = winbindd_request_response(WINBINDD_ENDGRENT, NULL, NULL); >+ ret = winbindd_request_response(NULL, WINBINDD_ENDGRENT, NULL, NULL); > #ifdef DEBUG_NSS > fprintf(stderr, "[%5d]: endgrent returns %s (%d)\n", getpid(), > nss_err_str(ret), ret); >@@ -799,7 +799,7 @@ winbind_getgrent(enum winbindd_cmd cmd, > > request.data.num_entries = MAX_GETGRENT_USERS; > >- ret = winbindd_request_response(cmd, &request, >+ ret = winbindd_request_response(NULL, cmd, &request, > &getgrent_response); > > if (ret == NSS_STATUS_SUCCESS) { >@@ -918,7 +918,8 @@ _nss_winbind_getgrnam_r(const char *name, > request.data.groupname > [sizeof(request.data.groupname) - 1] = '\0'; > >- ret = winbindd_request_response(WINBINDD_GETGRNAM, &request, &response); >+ ret = winbindd_request_response(NULL, WINBINDD_GETGRNAM, >+ &request, &response); > > if (ret == NSS_STATUS_SUCCESS) { > ret = fill_grent(result, &response.data.gr, >@@ -996,7 +997,8 @@ _nss_winbind_getgrgid_r(gid_t gid, > > request.data.gid = gid; > >- ret = winbindd_request_response(WINBINDD_GETGRGID, &request, &response); >+ ret = winbindd_request_response(NULL, WINBINDD_GETGRGID, >+ &request, &response); > > if (ret == NSS_STATUS_SUCCESS) { > >@@ -1069,7 +1071,8 @@ _nss_winbind_initgroups_dyn(char *user, gid_t group, long int *start, > strncpy(request.data.username, user, > sizeof(request.data.username) - 1); > >- ret = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response); >+ ret = winbindd_request_response(NULL, WINBINDD_GETGROUPS, >+ &request, &response); > > if (ret == NSS_STATUS_SUCCESS) { > int num_gids = response.data.num_entries; >@@ -1181,7 +1184,8 @@ _nss_winbind_getusersids(const char *user_sid, char **group_sids, > strncpy(request.data.sid, user_sid,sizeof(request.data.sid) - 1); > request.data.sid[sizeof(request.data.sid) - 1] = '\0'; > >- ret = winbindd_request_response(WINBINDD_GETUSERSIDS, &request, &response); >+ ret = winbindd_request_response(NULL, WINBINDD_GETUSERSIDS, >+ &request, &response); > > if (ret != NSS_STATUS_SUCCESS) { > goto done; >@@ -1233,7 +1237,8 @@ _nss_winbind_nametosid(const char *name, char **sid, char *buffer, > sizeof(request.data.name.name) - 1); > request.data.name.name[sizeof(request.data.name.name) - 1] = '\0'; > >- ret = winbindd_request_response(WINBINDD_LOOKUPNAME, &request, &response); >+ ret = winbindd_request_response(NULL, WINBINDD_LOOKUPNAME, >+ &request, &response); > if (ret != NSS_STATUS_SUCCESS) { > *errnop = errno = EINVAL; > goto failed; >@@ -1283,7 +1288,8 @@ _nss_winbind_sidtoname(const char *sid, char **name, char *buffer, > > /* we need to fetch the separator first time through */ > if (!sep_char) { >- ret = winbindd_request_response(WINBINDD_INFO, &request, &response); >+ ret = winbindd_request_response(NULL, WINBINDD_INFO, >+ &request, &response); > if (ret != NSS_STATUS_SUCCESS) { > *errnop = errno = EINVAL; > goto failed; >@@ -1298,7 +1304,8 @@ _nss_winbind_sidtoname(const char *sid, char **name, char *buffer, > sizeof(request.data.sid) - 1); > request.data.sid[sizeof(request.data.sid) - 1] = '\0'; > >- ret = winbindd_request_response(WINBINDD_LOOKUPSID, &request, &response); >+ ret = winbindd_request_response(NULL, WINBINDD_LOOKUPSID, >+ &request, &response); > if (ret != NSS_STATUS_SUCCESS) { > *errnop = errno = EINVAL; > goto failed; >@@ -1354,7 +1361,8 @@ _nss_winbind_sidtouid(const char *sid, uid_t *uid, int *errnop) > strncpy(request.data.sid, sid, sizeof(request.data.sid) - 1); > request.data.sid[sizeof(request.data.sid) - 1] = '\0'; > >- ret = winbindd_request_response(WINBINDD_SID_TO_UID, &request, &response); >+ ret = winbindd_request_response(NULL, WINBINDD_SID_TO_UID, >+ &request, &response); > if (ret != NSS_STATUS_SUCCESS) { > *errnop = errno = EINVAL; > goto failed; >@@ -1393,7 +1401,8 @@ _nss_winbind_sidtogid(const char *sid, gid_t *gid, int *errnop) > strncpy(request.data.sid, sid, sizeof(request.data.sid) - 1); > request.data.sid[sizeof(request.data.sid) - 1] = '\0'; > >- ret = winbindd_request_response(WINBINDD_SID_TO_GID, &request, &response); >+ ret = winbindd_request_response(NULL, WINBINDD_SID_TO_GID, >+ &request, &response); > if (ret != NSS_STATUS_SUCCESS) { > *errnop = errno = EINVAL; > goto failed; >@@ -1432,7 +1441,8 @@ _nss_winbind_uidtosid(uid_t uid, char **sid, char *buffer, > > request.data.uid = uid; > >- ret = winbindd_request_response(WINBINDD_UID_TO_SID, &request, &response); >+ ret = winbindd_request_response(NULL, WINBINDD_UID_TO_SID, >+ &request, &response); > if (ret != NSS_STATUS_SUCCESS) { > *errnop = errno = EINVAL; > goto failed; >@@ -1480,7 +1490,8 @@ _nss_winbind_gidtosid(gid_t gid, char **sid, char *buffer, > > request.data.gid = gid; > >- ret = winbindd_request_response(WINBINDD_GID_TO_SID, &request, &response); >+ ret = winbindd_request_response(NULL, WINBINDD_GID_TO_SID, >+ &request, &response); > if (ret != NSS_STATUS_SUCCESS) { > *errnop = errno = EINVAL; > goto failed; >diff --git a/nsswitch/winbind_nss_netbsd.c b/nsswitch/winbind_nss_netbsd.c >index f673806..eb843ee 100644 >--- a/nsswitch/winbind_nss_netbsd.c >+++ b/nsswitch/winbind_nss_netbsd.c >@@ -228,7 +228,8 @@ netbsdwinbind_getgroupmembership(void *nsrv, void *nscb, va_list ap) > ZERO_STRUCT(response); > strncpy(request.data.username, uname, > sizeof(request.data.username) - 1); >- i = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response); >+ i = winbindd_request_response(NULL, WINBINDD_GETGROUPS, >+ &request, &response); > if (i != NSS_STATUS_SUCCESS) > return NS_NOTFOUND; > wblistv = (gid_t *)response.extra_data.data; >diff --git a/nsswitch/winbind_nss_solaris.c b/nsswitch/winbind_nss_solaris.c >index 6d3c8a9..1d0ac90 100644 >--- a/nsswitch/winbind_nss_solaris.c >+++ b/nsswitch/winbind_nss_solaris.c >@@ -515,7 +515,8 @@ _nss_winbind_ipnodes_getbyname(nss_backend_t* be, void *args) > strncpy(request.data.winsreq, argp->key.name, sizeof(request.data.winsreq) - 1); > request.data.winsreq[sizeof(request.data.winsreq) - 1] = '\0'; > >- if( (ret = winbindd_request_response(WINBINDD_WINS_BYNAME, &request, &response)) >+ if( (ret = winbindd_request_response(NULL, WINBINDD_WINS_BYNAME, >+ &request, &response)) > == NSS_STATUS_SUCCESS ) { > ret = parse_response(af, argp, &response); > } >@@ -538,7 +539,8 @@ _nss_winbind_hosts_getbyname(nss_backend_t* be, void *args) > strncpy(request.data.winsreq, argp->key.name, sizeof(request.data.winsreq) - 1); > request.data.winsreq[sizeof(request.data.winsreq) - 1] = '\0'; > >- if( (ret = winbindd_request_response(WINBINDD_WINS_BYNAME, &request, &response)) >+ if( (ret = winbindd_request_response(NULL, WINBINDD_WINS_BYNAME, >+ &request, &response)) > == NSS_STATUS_SUCCESS ) { > ret = parse_response(AF_INET, argp, &response); > } >@@ -577,7 +579,8 @@ _nss_winbind_hosts_getbyaddr(nss_backend_t* be, void *args) > ((unsigned char *)argp->key.hostaddr.addr)[3]); > #endif > >- ret = winbindd_request_response(WINBINDD_WINS_BYIP, &request, &response); >+ ret = winbindd_request_response(NULL, WINBINDD_WINS_BYIP, >+ &request, &response); > > if( ret == NSS_STATUS_SUCCESS) { > parse_response(argp->key.hostaddr.type, argp, &response); >diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c >index f907742..3906f38 100644 >--- a/source3/utils/ntlm_auth.c >+++ b/source3/utils/ntlm_auth.c >@@ -269,7 +269,7 @@ static char winbind_separator(void) > > /* Send off request */ > >- if (winbindd_request_response(WINBINDD_INFO, NULL, &response) != >+ if (winbindd_request_response(NULL, WINBINDD_INFO, NULL, &response) != > NSS_STATUS_SUCCESS) { > d_printf("could not obtain winbind separator!\n"); > return *lp_winbind_separator(); >@@ -299,7 +299,7 @@ const char *get_winbind_domain(void) > > /* Send off request */ > >- if (winbindd_request_response(WINBINDD_DOMAIN_NAME, NULL, &response) != >+ if (winbindd_request_response(NULL, WINBINDD_DOMAIN_NAME, NULL, &response) != > NSS_STATUS_SUCCESS) { > DEBUG(1, ("could not obtain winbind domain name!\n")); > return lp_workgroup(); >@@ -325,7 +325,7 @@ const char *get_winbind_netbios_name(void) > > /* Send off request */ > >- if (winbindd_request_response(WINBINDD_NETBIOS_NAME, NULL, &response) != >+ if (winbindd_request_response(NULL, WINBINDD_NETBIOS_NAME, NULL, &response) != > NSS_STATUS_SUCCESS) { > DEBUG(1, ("could not obtain winbind netbios name!\n")); > return lp_netbios_name(); >@@ -393,7 +393,7 @@ static bool get_require_membership_sid(void) { > return False; > } > >- if (winbindd_request_response(WINBINDD_LOOKUPNAME, &request, &response) != >+ if (winbindd_request_response(NULL, WINBINDD_LOOKUPNAME, &request, &response) != > NSS_STATUS_SUCCESS) { > DEBUG(0, ("Winbindd lookupname failed to resolve %s into a SID!\n", > require_membership_of)); >@@ -463,7 +463,7 @@ static bool check_plaintext_auth(const char *user, const char *pass, > sizeof(request.data.auth.require_membership_of_sid)); > } > >- result = winbindd_request_response(WINBINDD_PAM_AUTH, &request, &response); >+ result = winbindd_request_response(NULL, WINBINDD_PAM_AUTH, &request, &response); > > /* Display response */ > >@@ -558,7 +558,7 @@ NTSTATUS contact_winbind_auth_crap(const char *username, > request.data.auth_crap.nt_resp_len = nt_response->length; > } > >- result = winbindd_request_response(WINBINDD_PAM_AUTH_CRAP, &request, &response); >+ result = winbindd_request_response(NULL, WINBINDD_PAM_AUTH_CRAP, &request, &response); > SAFE_FREE(request.extra_data.data); > > /* Display response */ >@@ -653,7 +653,7 @@ static NTSTATUS contact_winbind_change_pswd_auth_crap(const char *username, > request.data.chng_pswd_auth_crap.old_lm_hash_enc_len = old_lm_hash_enc.length; > } > >- result = winbindd_request_response(WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, &request, &response); >+ result = winbindd_request_response(NULL, WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, &request, &response); > > /* Display response */ > >@@ -1194,7 +1194,7 @@ static NTSTATUS do_ccache_ntlm_auth(DATA_BLOB initial_msg, DATA_BLOB challenge_m > challenge_msg.data, challenge_msg.length); > } > >- result = winbindd_request_response(WINBINDD_CCACHE_NTLMAUTH, &wb_request, &wb_response); >+ result = winbindd_request_response(NULL, WINBINDD_CCACHE_NTLMAUTH, &wb_request, &wb_response); > SAFE_FREE(wb_request.extra_data.data); > > if (result != NSS_STATUS_SUCCESS) { >-- >1.9.1 > > >From 3a9e1c47098d679ef479a566b0044cc420b2a422 Mon Sep 17 00:00:00 2001 >From: Matthew Newton <matthew-git@newtoncomputing.co.uk> >Date: Sat, 21 Feb 2015 00:19:32 +0000 >Subject: [PATCH 3/7] Add wbcContext struct, create and free functions > >The basic context structure and functions for libwbclient so that >libwbclient can be made thread-safe. > >https://bugzilla.samba.org/show_bug.cgi?id=11149 > >Signed-off-by: Matthew Newton <matthew-git@newtoncomputing.co.uk> >Reviewed-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit bc75e723ce063149278c95327ef91959718d27be) >--- > nsswitch/libwbclient/wbclient.c | 44 ++++++++++++++++++++++++++++++++ > nsswitch/libwbclient/wbclient.h | 30 ++++++++++++++++++++++ > nsswitch/libwbclient/wbclient_internal.h | 4 +++ > 3 files changed, 78 insertions(+) > >diff --git a/nsswitch/libwbclient/wbclient.c b/nsswitch/libwbclient/wbclient.c >index 93c0318e..e6b3e4e 100644 >--- a/nsswitch/libwbclient/wbclient.c >+++ b/nsswitch/libwbclient/wbclient.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 >@@ -27,6 +28,8 @@ > > /* From wb_common.c */ > >+struct winbindd_context; >+ > NSS_STATUS winbindd_request_response(struct winbindd_context *wbctx, > int req_type, > struct winbindd_request *request, >@@ -35,6 +38,9 @@ NSS_STATUS winbindd_priv_request_response(struct winbindd_context *wbctx, > int req_type, > struct winbindd_request *request, > struct winbindd_response *response); >+struct winbindd_context *winbindd_ctx_create(void); >+void winbindd_ctx_free(struct winbindd_context *ctx); >+ > > /* > result == NSS_STATUS_UNAVAIL: winbind not around >@@ -259,3 +265,41 @@ wbcErr wbcLibraryDetails(struct wbcLibraryDetails **_details) > *_details = info; > return WBC_ERR_SUCCESS; > } >+ >+/* Context handling functions */ >+ >+static void wbcContextDestructor(void *ptr) >+{ >+ struct wbcContext *ctx = (struct wbcContext *)ptr; >+ >+ winbindd_ctx_free(ctx->winbindd_ctx); >+} >+ >+struct wbcContext *wbcCtxCreate(void) >+{ >+ struct wbcContext *ctx; >+ struct winbindd_context *wbctx; >+ >+ ctx = (struct wbcContext *)wbcAllocateMemory( >+ 1, sizeof(struct wbcContext), wbcContextDestructor); >+ >+ if (!ctx) { >+ return NULL; >+ } >+ >+ wbctx = winbindd_ctx_create(); >+ >+ if (!wbctx) { >+ wbcFreeMemory(ctx); >+ return NULL; >+ } >+ >+ ctx->winbindd_ctx = wbctx; >+ >+ return ctx; >+} >+ >+void wbcCtxFree(struct wbcContext *ctx) >+{ >+ wbcFreeMemory(ctx); >+} >diff --git a/nsswitch/libwbclient/wbclient.h b/nsswitch/libwbclient/wbclient.h >index dc3e822..265cf43 100644 >--- a/nsswitch/libwbclient/wbclient.h >+++ b/nsswitch/libwbclient/wbclient.h >@@ -5,6 +5,7 @@ > > Copyright (C) Gerald (Jerry) Carter 2007 > Copyright (C) Volker Lendecke 2009 >+ Copyright (C) Matthew Newton 2015 > > This library is free software; you can redistribute it and/or > modify it under the terms of the GNU Lesser General Public >@@ -94,6 +95,13 @@ struct wbcInterfaceDetails { > char *dns_domain; > }; > >+/** >+ * @brief Library context data >+ * >+ **/ >+ >+struct wbcContext; >+ > /* > * Data types used by the Winbind Client API > */ >@@ -523,6 +531,28 @@ struct wbcDomainControllerInfoEx { > void wbcFreeMemory(void*); > > >+/********************************************************** >+ * Context Management >+ **********************************************************/ >+ >+/** >+ * @brief Create a new wbcContext context >+ * >+ * @return wbcContext >+ **/ >+struct wbcContext *wbcCtxCreate(void); >+ >+/** >+ * @brief Free a library context >+ * >+ * @param ctx wbcContext to free >+ * >+ * @return void >+ **/ >+void wbcCtxFree(struct wbcContext *ctx); >+ >+ >+ > /* > * Utility functions for dealing with SIDs > */ >diff --git a/nsswitch/libwbclient/wbclient_internal.h b/nsswitch/libwbclient/wbclient_internal.h >index 31f4130..e55bf27 100644 >--- a/nsswitch/libwbclient/wbclient_internal.h >+++ b/nsswitch/libwbclient/wbclient_internal.h >@@ -22,6 +22,10 @@ > #ifndef _WBCLIENT_INTERNAL_H > #define _WBCLIENT_INTERNAL_H > >+struct wbcContext { >+ struct winbindd_context *winbindd_ctx; >+}; >+ > /* Private functions */ > > wbcErr wbcRequestResponse(int cmd, >-- >1.9.1 > > >From 12edc0d6abb76da8a38e3a5a9582838a774e4aac Mon Sep 17 00:00:00 2001 >From: Matthew Newton <matthew-git@newtoncomputing.co.uk> >Date: Sat, 24 Jan 2015 00:30:00 +0000 >Subject: [PATCH 4/7] Add wbcContext to wbcRequestResponse > >To enable libwbclient to pass winbindd context through >to the winbind client library in wb_common. > >https://bugzilla.samba.org/show_bug.cgi?id=11149 > >Signed-off-by: Matthew Newton <matthew-git@newtoncomputing.co.uk> >Reviewed-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 348f93ff6e25c43e0233432bd2134bb9eacb0b87) >--- > nsswitch/libwbclient/wbclient.c | 24 +++++++++++++++++++----- > nsswitch/libwbclient/wbclient_internal.h | 4 ++-- > 2 files changed, 21 insertions(+), 7 deletions(-) > >diff --git a/nsswitch/libwbclient/wbclient.c b/nsswitch/libwbclient/wbclient.c >index e6b3e4e..ab1159a 100644 >--- a/nsswitch/libwbclient/wbclient.c >+++ b/nsswitch/libwbclient/wbclient.c >@@ -56,6 +56,7 @@ void winbindd_ctx_free(struct winbindd_context *ctx); > */ > > static wbcErr wbcRequestResponseInt( >+ struct winbindd_context *wbctx, > int cmd, > struct winbindd_request *request, > struct winbindd_response *response, >@@ -68,7 +69,7 @@ static wbcErr wbcRequestResponseInt( > > /* for some calls the request and/or response can be NULL */ > >- nss_status = fn(NULL, cmd, request, response); >+ nss_status = fn(wbctx, cmd, request, response); > > switch (nss_status) { > case NSS_STATUS_SUCCESS: >@@ -91,25 +92,38 @@ static wbcErr wbcRequestResponseInt( > /** > * @brief Wrapper around Winbind's send/receive API call > * >+ * @param ctx Context > * @param cmd Winbind command operation to perform > * @param request Send structure > * @param response Receive structure > * > * @return #wbcErr > */ >-wbcErr wbcRequestResponse(int cmd, >+wbcErr wbcRequestResponse(struct wbcContext *ctx, int cmd, > struct winbindd_request *request, > struct winbindd_response *response) > { >- return wbcRequestResponseInt(cmd, request, response, >+ struct winbindd_context *wbctx = NULL; >+ >+ if (ctx) { >+ wbctx = ctx->winbindd_ctx; >+ } >+ >+ return wbcRequestResponseInt(wbctx, cmd, request, response, > winbindd_request_response); > } > >-wbcErr wbcRequestResponsePriv(int cmd, >+wbcErr wbcRequestResponsePriv(struct wbcContext *ctx, int cmd, > struct winbindd_request *request, > struct winbindd_response *response) > { >- return wbcRequestResponseInt(cmd, request, response, >+ struct winbindd_context *wbctx = NULL; >+ >+ if (ctx) { >+ wbctx = ctx->winbindd_ctx; >+ } >+ >+ return wbcRequestResponseInt(wbctx, cmd, request, response, > winbindd_priv_request_response); > } > >diff --git a/nsswitch/libwbclient/wbclient_internal.h b/nsswitch/libwbclient/wbclient_internal.h >index e55bf27..becddac 100644 >--- a/nsswitch/libwbclient/wbclient_internal.h >+++ b/nsswitch/libwbclient/wbclient_internal.h >@@ -28,11 +28,11 @@ struct wbcContext { > > /* Private functions */ > >-wbcErr wbcRequestResponse(int cmd, >+wbcErr wbcRequestResponse(struct wbcContext *ctx, int cmd, > struct winbindd_request *request, > struct winbindd_response *response); > >-wbcErr wbcRequestResponsePriv(int cmd, >+wbcErr wbcRequestResponsePriv(struct wbcContext *ctx, int cmd, > struct winbindd_request *request, > struct winbindd_response *response); > >-- >1.9.1 > > >From a3f35104adc727b9ee575b2e493338f01b192883 Mon Sep 17 00:00:00 2001 >From: Matthew Newton <matthew-git@newtoncomputing.co.uk> >Date: Sat, 21 Feb 2015 22:30:11 +0000 >Subject: [PATCH 5/7] Add context versions of wbclient functions > >To make the libwbclient library thread-safe, all functions >that call through to wb_common winbindd_request_response need >to have context that they can use. This commit adds all the >necessary functions. > >https://bugzilla.samba.org/show_bug.cgi?id=11149 > >Signed-off-by: Matthew Newton <matthew-git@newtoncomputing.co.uk> >Reviewed-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 063c56dba590eec69439eb791a420b40505d4cc0) >--- > nsswitch/libwbclient/wbc_idmap.c | 70 ++++- > nsswitch/libwbclient/wbc_pam.c | 198 +++++++++--- > nsswitch/libwbclient/wbc_pwd.c | 127 ++++++-- > nsswitch/libwbclient/wbc_sid.c | 169 +++++++--- > nsswitch/libwbclient/wbc_util.c | 123 ++++++-- > nsswitch/libwbclient/wbclient.h | 650 ++++++++++++++++++++++++++++++++++++++- > 6 files changed, 1161 insertions(+), 176 deletions(-) > >diff --git a/nsswitch/libwbclient/wbc_idmap.c b/nsswitch/libwbclient/wbc_idmap.c >index 04e7d02..3e8366a 100644 >--- a/nsswitch/libwbclient/wbc_idmap.c >+++ b/nsswitch/libwbclient/wbc_idmap.c >@@ -26,7 +26,8 @@ > #include "../winbind_client.h" > > /* Convert a Windows SID to a Unix uid, allocating an uid if needed */ >-wbcErr wbcSidToUid(const struct wbcDomainSid *sid, uid_t *puid) >+wbcErr wbcCtxSidToUid(struct wbcContext *ctx, const struct wbcDomainSid *sid, >+ uid_t *puid) > { > struct winbindd_request request; > struct winbindd_response response; >@@ -46,7 +47,7 @@ wbcErr wbcSidToUid(const struct wbcDomainSid *sid, uid_t *puid) > > /* Make request */ > >- wbc_status = wbcRequestResponse(WINBINDD_SID_TO_UID, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_SID_TO_UID, > &request, > &response); > BAIL_ON_WBC_ERROR(wbc_status); >@@ -59,6 +60,11 @@ wbcErr wbcSidToUid(const struct wbcDomainSid *sid, uid_t *puid) > return wbc_status; > } > >+wbcErr wbcSidToUid(const struct wbcDomainSid *sid, uid_t *puid) >+{ >+ return wbcCtxSidToUid(NULL, sid, puid); >+} >+ > /* Convert a Windows SID to a Unix uid if there already is a mapping */ > wbcErr wbcQuerySidToUid(const struct wbcDomainSid *sid, > uid_t *puid) >@@ -67,7 +73,8 @@ wbcErr wbcQuerySidToUid(const struct wbcDomainSid *sid, > } > > /* Convert a Unix uid to a Windows SID, allocating a SID if needed */ >-wbcErr wbcUidToSid(uid_t uid, struct wbcDomainSid *sid) >+wbcErr wbcCtxUidToSid(struct wbcContext *ctx, uid_t uid, >+ struct wbcDomainSid *sid) > { > wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; > struct winbindd_request request; >@@ -87,7 +94,7 @@ wbcErr wbcUidToSid(uid_t uid, struct wbcDomainSid *sid) > > /* Make request */ > >- wbc_status = wbcRequestResponse(WINBINDD_UID_TO_SID, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_UID_TO_SID, > &request, > &response); > BAIL_ON_WBC_ERROR(wbc_status); >@@ -99,6 +106,11 @@ done: > return wbc_status; > } > >+wbcErr wbcUidToSid(uid_t uid, struct wbcDomainSid *sid) >+{ >+ return wbcCtxUidToSid(NULL, uid, sid); >+} >+ > /* Convert a Unix uid to a Windows SID if there already is a mapping */ > wbcErr wbcQueryUidToSid(uid_t uid, > struct wbcDomainSid *sid) >@@ -115,7 +127,8 @@ wbcErr wbcQueryUidToSid(uid_t uid, > * > **/ > >-wbcErr wbcSidToGid(const struct wbcDomainSid *sid, gid_t *pgid) >+wbcErr wbcCtxSidToGid(struct wbcContext *ctx, const struct wbcDomainSid *sid, >+ gid_t *pgid) > { > struct winbindd_request request; > struct winbindd_response response; >@@ -135,7 +148,7 @@ wbcErr wbcSidToGid(const struct wbcDomainSid *sid, gid_t *pgid) > > /* Make request */ > >- wbc_status = wbcRequestResponse(WINBINDD_SID_TO_GID, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_SID_TO_GID, > &request, > &response); > BAIL_ON_WBC_ERROR(wbc_status); >@@ -148,6 +161,10 @@ wbcErr wbcSidToGid(const struct wbcDomainSid *sid, gid_t *pgid) > return wbc_status; > } > >+wbcErr wbcSidToGid(const struct wbcDomainSid *sid, gid_t *pgid) >+{ >+ return wbcCtxSidToGid(NULL, sid, pgid); >+} > > /* Convert a Windows SID to a Unix gid if there already is a mapping */ > >@@ -159,7 +176,8 @@ wbcErr wbcQuerySidToGid(const struct wbcDomainSid *sid, > > > /* Convert a Unix gid to a Windows SID, allocating a SID if needed */ >-wbcErr wbcGidToSid(gid_t gid, struct wbcDomainSid *sid) >+wbcErr wbcCtxGidToSid(struct wbcContext *ctx, gid_t gid, >+ struct wbcDomainSid *sid) > { > struct winbindd_request request; > struct winbindd_response response; >@@ -179,7 +197,7 @@ wbcErr wbcGidToSid(gid_t gid, struct wbcDomainSid *sid) > > /* Make request */ > >- wbc_status = wbcRequestResponse(WINBINDD_GID_TO_SID, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_GID_TO_SID, > &request, > &response); > BAIL_ON_WBC_ERROR(wbc_status); >@@ -191,6 +209,11 @@ done: > return wbc_status; > } > >+wbcErr wbcGidToSid(gid_t gid, struct wbcDomainSid *sid) >+{ >+ return wbcCtxGidToSid(NULL, gid, sid); >+} >+ > /* Convert a Unix gid to a Windows SID if there already is a mapping */ > wbcErr wbcQueryGidToSid(gid_t gid, > struct wbcDomainSid *sid) >@@ -199,7 +222,7 @@ wbcErr wbcQueryGidToSid(gid_t gid, > } > > /* Obtain a new uid from Winbind */ >-wbcErr wbcAllocateUid(uid_t *puid) >+wbcErr wbcCtxAllocateUid(struct wbcContext *ctx, uid_t *puid) > { > struct winbindd_request request; > struct winbindd_response response; >@@ -215,7 +238,7 @@ wbcErr wbcAllocateUid(uid_t *puid) > > /* Make request */ > >- wbc_status = wbcRequestResponsePriv(WINBINDD_ALLOCATE_UID, >+ wbc_status = wbcRequestResponsePriv(ctx, WINBINDD_ALLOCATE_UID, > &request, &response); > BAIL_ON_WBC_ERROR(wbc_status); > >@@ -228,8 +251,13 @@ wbcErr wbcAllocateUid(uid_t *puid) > return wbc_status; > } > >+wbcErr wbcAllocateUid(uid_t *puid) >+{ >+ return wbcCtxAllocateUid(NULL, puid); >+} >+ > /* Obtain a new gid from Winbind */ >-wbcErr wbcAllocateGid(gid_t *pgid) >+wbcErr wbcCtxAllocateGid(struct wbcContext *ctx, gid_t *pgid) > { > struct winbindd_request request; > struct winbindd_response response; >@@ -245,7 +273,7 @@ wbcErr wbcAllocateGid(gid_t *pgid) > > /* Make request */ > >- wbc_status = wbcRequestResponsePriv(WINBINDD_ALLOCATE_GID, >+ wbc_status = wbcRequestResponsePriv(ctx, WINBINDD_ALLOCATE_GID, > &request, &response); > BAIL_ON_WBC_ERROR(wbc_status); > >@@ -258,6 +286,11 @@ wbcErr wbcAllocateGid(gid_t *pgid) > return wbc_status; > } > >+wbcErr wbcAllocateGid(gid_t *pgid) >+{ >+ return wbcCtxAllocateGid(NULL, pgid); >+} >+ > /* we can't include smb.h here... */ > #define _ID_TYPE_UID 1 > #define _ID_TYPE_GID 2 >@@ -299,8 +332,9 @@ wbcErr wbcSetGidHwm(gid_t gid_hwm) > } > > /* Convert a list of SIDs */ >-wbcErr wbcSidsToUnixIds(const struct wbcDomainSid *sids, uint32_t num_sids, >- struct wbcUnixId *ids) >+wbcErr wbcCtxSidsToUnixIds(struct wbcContext *ctx, >+ const struct wbcDomainSid *sids, >+ uint32_t num_sids, struct wbcUnixId *ids) > { > struct winbindd_request request; > struct winbindd_response response; >@@ -341,7 +375,7 @@ wbcErr wbcSidsToUnixIds(const struct wbcDomainSid *sids, uint32_t num_sids, > request.extra_data.data = sidlist; > request.extra_len = p - sidlist; > >- wbc_status = wbcRequestResponse(WINBINDD_SIDS_TO_XIDS, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_SIDS_TO_XIDS, > &request, &response); > free(sidlist); > if (!WBC_ERROR_IS_OK(wbc_status)) { >@@ -393,3 +427,9 @@ done: > winbindd_free_response(&response); > return wbc_status; > } >+ >+wbcErr wbcSidsToUnixIds(const struct wbcDomainSid *sids, uint32_t num_sids, >+ struct wbcUnixId *ids) >+{ >+ return wbcCtxSidsToUnixIds(NULL, sids, num_sids, ids); >+} >diff --git a/nsswitch/libwbclient/wbc_pam.c b/nsswitch/libwbclient/wbc_pam.c >index 11b59f6..390d73e 100644 >--- a/nsswitch/libwbclient/wbc_pam.c >+++ b/nsswitch/libwbclient/wbc_pam.c >@@ -28,8 +28,8 @@ > #include "../winbind_client.h" > > /* Authenticate a username/password pair */ >-wbcErr wbcAuthenticateUser(const char *username, >- const char *password) >+wbcErr wbcCtxAuthenticateUser(struct wbcContext *ctx, >+ const char *username, const char *password) > { > wbcErr wbc_status = WBC_ERR_SUCCESS; > struct wbcAuthUserParams params; >@@ -40,13 +40,18 @@ wbcErr wbcAuthenticateUser(const char *username, > params.level = WBC_AUTH_USER_LEVEL_PLAIN; > params.password.plaintext = password; > >- wbc_status = wbcAuthenticateUserEx(¶ms, NULL, NULL); >+ wbc_status = wbcCtxAuthenticateUserEx(ctx, ¶ms, NULL, NULL); > BAIL_ON_WBC_ERROR(wbc_status); > > done: > return wbc_status; > } > >+wbcErr wbcAuthenticateUser(const char *username, const char *password) >+{ >+ return wbcCtxAuthenticateUser(NULL, username, password); >+} >+ > static bool sid_attr_compose(struct wbcSidWithAttr *s, > const struct wbcDomainSid *d, > uint32_t rid, uint32_t attr) >@@ -342,9 +347,10 @@ done: > > > /* Authenticate with more detailed information */ >-wbcErr wbcAuthenticateUserEx(const struct wbcAuthUserParams *params, >- struct wbcAuthUserInfo **info, >- struct wbcAuthErrorInfo **error) >+wbcErr wbcCtxAuthenticateUserEx(struct wbcContext *ctx, >+ const struct wbcAuthUserParams *params, >+ struct wbcAuthUserInfo **info, >+ struct wbcAuthErrorInfo **error) > { > wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; > int cmd = 0; >@@ -388,7 +394,7 @@ wbcErr wbcAuthenticateUserEx(const struct wbcAuthUserParams *params, > > ZERO_STRUCT(sep_response); > >- wbc_status = wbcRequestResponse(WINBINDD_INFO, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_INFO, > NULL, &sep_response); > BAIL_ON_WBC_ERROR(wbc_status); > >@@ -518,9 +524,11 @@ wbcErr wbcAuthenticateUserEx(const struct wbcAuthUserParams *params, > } > > if (cmd == WINBINDD_PAM_AUTH_CRAP) { >- wbc_status = wbcRequestResponsePriv(cmd, &request, &response); >+ wbc_status = wbcRequestResponsePriv(ctx, cmd, >+ &request, &response); > } else { >- wbc_status = wbcRequestResponse(cmd, &request, &response); >+ wbc_status = wbcRequestResponse(ctx, cmd, >+ &request, &response); > } > if (response.data.auth.nt_status != 0) { > if (error) { >@@ -547,9 +555,16 @@ done: > return wbc_status; > } > >+wbcErr wbcAuthenticateUserEx(const struct wbcAuthUserParams *params, >+ struct wbcAuthUserInfo **info, >+ struct wbcAuthErrorInfo **error) >+{ >+ return wbcCtxAuthenticateUserEx(NULL, params, info, error); >+} >+ > /* Trigger a verification of the trust credentials of a specific domain */ >-wbcErr wbcCheckTrustCredentials(const char *domain, >- struct wbcAuthErrorInfo **error) >+wbcErr wbcCtxCheckTrustCredentials(struct wbcContext *ctx, const char *domain, >+ struct wbcAuthErrorInfo **error) > { > struct winbindd_request request; > struct winbindd_response response; >@@ -565,7 +580,7 @@ wbcErr wbcCheckTrustCredentials(const char *domain, > > /* Send request */ > >- wbc_status = wbcRequestResponsePriv(WINBINDD_CHECK_MACHACC, >+ wbc_status = wbcRequestResponsePriv(ctx, WINBINDD_CHECK_MACHACC, > &request, &response); > if (response.data.auth.nt_status != 0) { > if (error) { >@@ -583,9 +598,15 @@ wbcErr wbcCheckTrustCredentials(const char *domain, > return wbc_status; > } > >+wbcErr wbcCheckTrustCredentials(const char *domain, >+ struct wbcAuthErrorInfo **error) >+{ >+ return wbcCtxCheckTrustCredentials(NULL, domain, error); >+} >+ > /* Trigger a change of the trust credentials for a specific domain */ >-wbcErr wbcChangeTrustCredentials(const char *domain, >- struct wbcAuthErrorInfo **error) >+wbcErr wbcCtxChangeTrustCredentials(struct wbcContext *ctx, const char *domain, >+ struct wbcAuthErrorInfo **error) > { > struct winbindd_request request; > struct winbindd_response response; >@@ -601,8 +622,8 @@ wbcErr wbcChangeTrustCredentials(const char *domain, > > /* Send request */ > >- wbc_status = wbcRequestResponsePriv(WINBINDD_CHANGE_MACHACC, >- &request, &response); >+ wbc_status = wbcRequestResponsePriv(ctx, WINBINDD_CHANGE_MACHACC, >+ &request, &response); > if (response.data.auth.nt_status != 0) { > if (error) { > wbc_status = wbc_create_error_info(&response, >@@ -619,10 +640,22 @@ wbcErr wbcChangeTrustCredentials(const char *domain, > return wbc_status; > } > >+wbcErr wbcChangeTrustCredentials(const char *domain, >+ struct wbcAuthErrorInfo **error) >+{ >+ return wbcCtxChangeTrustCredentials(NULL, domain, error); >+} >+ > /* > * Trigger a no-op NETLOGON call. Lightweight version of > * wbcCheckTrustCredentials > */ >+wbcErr wbcCtxPingDc(struct wbcContext *ctx, const char *domain, >+ struct wbcAuthErrorInfo **error) >+{ >+ return wbcCtxPingDc2(ctx, domain, error, NULL); >+} >+ > wbcErr wbcPingDc(const char *domain, struct wbcAuthErrorInfo **error) > { > return wbcPingDc2(domain, error, NULL); >@@ -632,8 +665,8 @@ wbcErr wbcPingDc(const char *domain, struct wbcAuthErrorInfo **error) > * Trigger a no-op NETLOGON call. Lightweight version of > * wbcCheckTrustCredentials, optionally return attempted DC > */ >-wbcErr wbcPingDc2(const char *domain, struct wbcAuthErrorInfo **error, >- char **dcname) >+wbcErr wbcCtxPingDc2(struct wbcContext *ctx, const char *domain, >+ struct wbcAuthErrorInfo **error, char **dcname) > { > struct winbindd_request request; > struct winbindd_response response; >@@ -653,7 +686,7 @@ wbcErr wbcPingDc2(const char *domain, struct wbcAuthErrorInfo **error, > > /* Send request */ > >- wbc_status = wbcRequestResponse(WINBINDD_PING_DC, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_PING_DC, > &request, > &response); > >@@ -683,9 +716,16 @@ wbcErr wbcPingDc2(const char *domain, struct wbcAuthErrorInfo **error, > return wbc_status; > } > >+wbcErr wbcPingDc2(const char *domain, struct wbcAuthErrorInfo **error, >+ char **dcname) >+{ >+ return wbcCtxPingDc2(NULL, domain, error, dcname); >+} >+ > /* Trigger an extended logoff notification to Winbind for a specific user */ >-wbcErr wbcLogoffUserEx(const struct wbcLogoffUserParams *params, >- struct wbcAuthErrorInfo **error) >+wbcErr wbcCtxLogoffUserEx(struct wbcContext *ctx, >+ const struct wbcLogoffUserParams *params, >+ struct wbcAuthErrorInfo **error) > { > struct winbindd_request request; > struct winbindd_response response; >@@ -748,7 +788,7 @@ wbcErr wbcLogoffUserEx(const struct wbcLogoffUserParams *params, > > /* Send request */ > >- wbc_status = wbcRequestResponse(WINBINDD_PAM_LOGOFF, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_PAM_LOGOFF, > &request, > &response); > >@@ -769,10 +809,16 @@ wbcErr wbcLogoffUserEx(const struct wbcLogoffUserParams *params, > return wbc_status; > } > >+wbcErr wbcLogoffUserEx(const struct wbcLogoffUserParams *params, >+ struct wbcAuthErrorInfo **error) >+{ >+ return wbcCtxLogoffUserEx(NULL, params, error); >+} >+ > /* Trigger a logoff notification to Winbind for a specific user */ >-wbcErr wbcLogoffUser(const char *username, >- uid_t uid, >- const char *ccfilename) >+wbcErr wbcCtxLogoffUser(struct wbcContext *ctx, >+ const char *username, uid_t uid, >+ const char *ccfilename) > { > struct winbindd_request request; > struct winbindd_response response; >@@ -799,7 +845,7 @@ wbcErr wbcLogoffUser(const char *username, > > /* Send request */ > >- wbc_status = wbcRequestResponse(WINBINDD_PAM_LOGOFF, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_PAM_LOGOFF, > &request, > &response); > >@@ -809,11 +855,19 @@ wbcErr wbcLogoffUser(const char *username, > return wbc_status; > } > >+wbcErr wbcLogoffUser(const char *username, >+ uid_t uid, >+ const char *ccfilename) >+{ >+ return wbcCtxLogoffUser(NULL, username, uid, ccfilename); >+} >+ > /* Change a password for a user with more detailed information upon failure */ >-wbcErr wbcChangeUserPasswordEx(const struct wbcChangePasswordParams *params, >- struct wbcAuthErrorInfo **error, >- enum wbcPasswordChangeRejectReason *reject_reason, >- struct wbcUserPasswordPolicyInfo **policy) >+wbcErr wbcCtxChangeUserPasswordEx(struct wbcContext *ctx, >+ const struct wbcChangePasswordParams *params, >+ struct wbcAuthErrorInfo **error, >+ enum wbcPasswordChangeRejectReason *reject_reason, >+ struct wbcUserPasswordPolicyInfo **policy) > { > struct winbindd_request request; > struct winbindd_response response; >@@ -972,7 +1026,7 @@ wbcErr wbcChangeUserPasswordEx(const struct wbcChangePasswordParams *params, > > /* Send request */ > >- wbc_status = wbcRequestResponse(cmd, >+ wbc_status = wbcRequestResponse(ctx, cmd, > &request, > &response); > if (WBC_ERROR_IS_OK(wbc_status)) { >@@ -1007,10 +1061,20 @@ wbcErr wbcChangeUserPasswordEx(const struct wbcChangePasswordParams *params, > return wbc_status; > } > >+wbcErr wbcChangeUserPasswordEx(const struct wbcChangePasswordParams *params, >+ struct wbcAuthErrorInfo **error, >+ enum wbcPasswordChangeRejectReason *reject_reason, >+ struct wbcUserPasswordPolicyInfo **policy) >+{ >+ return wbcCtxChangeUserPasswordEx(NULL, params, error, >+ reject_reason, policy); >+} >+ > /* Change a password for a user */ >-wbcErr wbcChangeUserPassword(const char *username, >- const char *old_password, >- const char *new_password) >+wbcErr wbcCtxChangeUserPassword(struct wbcContext *ctx, >+ const char *username, >+ const char *old_password, >+ const char *new_password) > { > wbcErr wbc_status = WBC_ERR_SUCCESS; > struct wbcChangePasswordParams params; >@@ -1022,21 +1086,30 @@ wbcErr wbcChangeUserPassword(const char *username, > params.old_password.plaintext = old_password; > params.new_password.plaintext = new_password; > >- wbc_status = wbcChangeUserPasswordEx(¶ms, >- NULL, >- NULL, >- NULL); >+ wbc_status = wbcCtxChangeUserPasswordEx(ctx, ¶ms, >+ NULL, >+ NULL, >+ NULL); > BAIL_ON_WBC_ERROR(wbc_status); > > done: > return wbc_status; > } > >+wbcErr wbcChangeUserPassword(const char *username, >+ const char *old_password, >+ const char *new_password) >+{ >+ return wbcCtxChangeUserPassword(NULL, username, >+ old_password, new_password); >+} >+ > /* Logon a User */ >-wbcErr wbcLogonUser(const struct wbcLogonUserParams *params, >- struct wbcLogonUserInfo **info, >- struct wbcAuthErrorInfo **error, >- struct wbcUserPasswordPolicyInfo **policy) >+wbcErr wbcCtxLogonUser(struct wbcContext *ctx, >+ const struct wbcLogonUserParams *params, >+ struct wbcLogonUserInfo **info, >+ struct wbcAuthErrorInfo **error, >+ struct wbcUserPasswordPolicyInfo **policy) > { > wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; > struct winbindd_request request; >@@ -1138,7 +1211,7 @@ wbcErr wbcLogonUser(const struct wbcLogonUserParams *params, > } > } > >- wbc_status = wbcRequestResponse(WINBINDD_PAM_AUTH, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_PAM_AUTH, > &request, > &response); > >@@ -1172,6 +1245,14 @@ done: > return wbc_status; > } > >+wbcErr wbcLogonUser(const struct wbcLogonUserParams *params, >+ struct wbcLogonUserInfo **info, >+ struct wbcAuthErrorInfo **error, >+ struct wbcUserPasswordPolicyInfo **policy) >+{ >+ return wbcCtxLogonUser(NULL, params, info, error, policy); >+} >+ > static void wbcCredentialCacheInfoDestructor(void *ptr) > { > struct wbcCredentialCacheInfo *i = >@@ -1180,9 +1261,10 @@ static void wbcCredentialCacheInfoDestructor(void *ptr) > } > > /* Authenticate a user with cached credentials */ >-wbcErr wbcCredentialCache(struct wbcCredentialCacheParams *params, >- struct wbcCredentialCacheInfo **info, >- struct wbcAuthErrorInfo **error) >+wbcErr wbcCtxCredentialCache(struct wbcContext *ctx, >+ struct wbcCredentialCacheParams *params, >+ struct wbcCredentialCacheInfo **info, >+ struct wbcAuthErrorInfo **error) > { > wbcErr status = WBC_ERR_UNKNOWN_FAILURE; > struct wbcCredentialCacheInfo *result = NULL; >@@ -1227,7 +1309,8 @@ wbcErr wbcCredentialCache(struct wbcCredentialCacheParams *params, > } > > if (params->domain_name != NULL) { >- status = wbcRequestResponse(WINBINDD_INFO, NULL, &response); >+ status = wbcRequestResponse(ctx, WINBINDD_INFO, >+ NULL, &response); > if (!WBC_ERROR_IS_OK(status)) { > goto fail; > } >@@ -1276,8 +1359,8 @@ wbcErr wbcCredentialCache(struct wbcCredentialCacheParams *params, > challenge_blob->blob.length); > } > >- status = wbcRequestResponse(WINBINDD_CCACHE_NTLMAUTH, &request, >- &response); >+ status = wbcRequestResponse(ctx, WINBINDD_CCACHE_NTLMAUTH, >+ &request, &response); > if (!WBC_ERROR_IS_OK(status)) { > goto fail; > } >@@ -1316,8 +1399,16 @@ fail: > return status; > } > >+wbcErr wbcCredentialCache(struct wbcCredentialCacheParams *params, >+ struct wbcCredentialCacheInfo **info, >+ struct wbcAuthErrorInfo **error) >+{ >+ return wbcCtxCredentialCache(NULL, params, info, error); >+} >+ > /* Authenticate a user with cached credentials */ >-wbcErr wbcCredentialSave(const char *user, const char *password) >+wbcErr wbcCtxCredentialSave(struct wbcContext *ctx, >+ const char *user, const char *password) > { > struct winbindd_request request; > struct winbindd_response response; >@@ -1331,5 +1422,10 @@ wbcErr wbcCredentialSave(const char *user, const char *password) > sizeof(request.data.ccache_save.pass)-1); > request.data.ccache_save.uid = getuid(); > >- return wbcRequestResponse(WINBINDD_CCACHE_SAVE, &request, &response); >+ return wbcRequestResponse(ctx, WINBINDD_CCACHE_SAVE, &request, &response); >+} >+ >+wbcErr wbcCredentialSave(const char *user, const char *password) >+{ >+ return wbcCtxCredentialSave(NULL, user, password); > } >diff --git a/nsswitch/libwbclient/wbc_pwd.c b/nsswitch/libwbclient/wbc_pwd.c >index 6df694d..0b05133 100644 >--- a/nsswitch/libwbclient/wbc_pwd.c >+++ b/nsswitch/libwbclient/wbc_pwd.c >@@ -167,7 +167,8 @@ fail: > } > > /* Fill in a struct passwd* for a domain user based on username */ >-wbcErr wbcGetpwnam(const char *name, struct passwd **pwd) >+wbcErr wbcCtxGetpwnam(struct wbcContext *ctx, >+ const char *name, struct passwd **pwd) > { > wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; > struct winbindd_request request; >@@ -187,7 +188,7 @@ wbcErr wbcGetpwnam(const char *name, struct passwd **pwd) > > strncpy(request.data.username, name, sizeof(request.data.username)-1); > >- wbc_status = wbcRequestResponse(WINBINDD_GETPWNAM, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_GETPWNAM, > &request, > &response); > BAIL_ON_WBC_ERROR(wbc_status); >@@ -199,8 +200,13 @@ wbcErr wbcGetpwnam(const char *name, struct passwd **pwd) > return wbc_status; > } > >+wbcErr wbcGetpwnam(const char *name, struct passwd **pwd) >+{ >+ return wbcCtxGetpwnam(NULL, name, pwd); >+} >+ > /* Fill in a struct passwd* for a domain user based on uid */ >-wbcErr wbcGetpwuid(uid_t uid, struct passwd **pwd) >+wbcErr wbcCtxGetpwuid(struct wbcContext *ctx, uid_t uid, struct passwd **pwd) > { > wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; > struct winbindd_request request; >@@ -218,7 +224,7 @@ wbcErr wbcGetpwuid(uid_t uid, struct passwd **pwd) > > request.data.uid = uid; > >- wbc_status = wbcRequestResponse(WINBINDD_GETPWUID, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_GETPWUID, > &request, > &response); > BAIL_ON_WBC_ERROR(wbc_status); >@@ -230,8 +236,14 @@ wbcErr wbcGetpwuid(uid_t uid, struct passwd **pwd) > return wbc_status; > } > >+wbcErr wbcGetpwuid(uid_t uid, struct passwd **pwd) >+{ >+ return wbcCtxGetpwuid(NULL, uid, pwd); >+} >+ > /* Fill in a struct passwd* for a domain user based on sid */ >-wbcErr wbcGetpwsid(struct wbcDomainSid *sid, struct passwd **pwd) >+wbcErr wbcCtxGetpwsid(struct wbcContext *ctx, >+ struct wbcDomainSid *sid, struct passwd **pwd) > { > wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; > struct winbindd_request request; >@@ -249,7 +261,7 @@ wbcErr wbcGetpwsid(struct wbcDomainSid *sid, struct passwd **pwd) > > wbcSidToStringBuf(sid, request.data.sid, sizeof(request.data.sid)); > >- wbc_status = wbcRequestResponse(WINBINDD_GETPWSID, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_GETPWSID, > &request, > &response); > BAIL_ON_WBC_ERROR(wbc_status); >@@ -261,8 +273,14 @@ wbcErr wbcGetpwsid(struct wbcDomainSid *sid, struct passwd **pwd) > return wbc_status; > } > >+wbcErr wbcGetpwsid(struct wbcDomainSid *sid, struct passwd **pwd) >+{ >+ return wbcCtxGetpwsid(NULL, sid, pwd); >+} >+ > /* Fill in a struct passwd* for a domain user based on username */ >-wbcErr wbcGetgrnam(const char *name, struct group **grp) >+wbcErr wbcCtxGetgrnam(struct wbcContext *ctx, >+ const char *name, struct group **grp) > { > wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; > struct winbindd_request request; >@@ -282,7 +300,7 @@ wbcErr wbcGetgrnam(const char *name, struct group **grp) > > strncpy(request.data.groupname, name, sizeof(request.data.groupname)-1); > >- wbc_status = wbcRequestResponse(WINBINDD_GETGRNAM, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_GETGRNAM, > &request, > &response); > BAIL_ON_WBC_ERROR(wbc_status); >@@ -297,8 +315,13 @@ wbcErr wbcGetgrnam(const char *name, struct group **grp) > return wbc_status; > } > >+wbcErr wbcGetgrnam(const char *name, struct group **grp) >+{ >+ return wbcCtxGetgrnam(NULL, name, grp); >+} >+ > /* Fill in a struct passwd* for a domain user based on uid */ >-wbcErr wbcGetgrgid(gid_t gid, struct group **grp) >+wbcErr wbcCtxGetgrgid(struct wbcContext *ctx, gid_t gid, struct group **grp) > { > wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; > struct winbindd_request request; >@@ -316,7 +339,7 @@ wbcErr wbcGetgrgid(gid_t gid, struct group **grp) > > request.data.gid = gid; > >- wbc_status = wbcRequestResponse(WINBINDD_GETGRGID, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_GETGRGID, > &request, > &response); > BAIL_ON_WBC_ERROR(wbc_status); >@@ -331,6 +354,11 @@ wbcErr wbcGetgrgid(gid_t gid, struct group **grp) > return wbc_status; > } > >+wbcErr wbcGetgrgid(gid_t gid, struct group **grp) >+{ >+ return wbcCtxGetgrgid(NULL, gid, grp); >+} >+ > /** @brief Number of cached passwd structs > * > */ >@@ -347,7 +375,7 @@ static uint32_t pw_cache_idx; > static struct winbindd_response pw_response; > > /* Reset the passwd iterator */ >-wbcErr wbcSetpwent(void) >+wbcErr wbcCtxSetpwent(struct wbcContext *ctx) > { > wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; > >@@ -358,7 +386,7 @@ wbcErr wbcSetpwent(void) > > ZERO_STRUCT(pw_response); > >- wbc_status = wbcRequestResponse(WINBINDD_SETPWENT, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_SETPWENT, > NULL, NULL); > BAIL_ON_WBC_ERROR(wbc_status); > >@@ -366,8 +394,13 @@ wbcErr wbcSetpwent(void) > return wbc_status; > } > >+wbcErr wbcSetpwent(void) >+{ >+ return wbcCtxSetpwent(NULL); >+} >+ > /* Close the passwd iterator */ >-wbcErr wbcEndpwent(void) >+wbcErr wbcCtxEndpwent(struct wbcContext *ctx) > { > wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; > >@@ -376,7 +409,7 @@ wbcErr wbcEndpwent(void) > winbindd_free_response(&pw_response); > } > >- wbc_status = wbcRequestResponse(WINBINDD_ENDPWENT, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_ENDPWENT, > NULL, NULL); > BAIL_ON_WBC_ERROR(wbc_status); > >@@ -384,8 +417,13 @@ wbcErr wbcEndpwent(void) > return wbc_status; > } > >+wbcErr wbcEndpwent(void) >+{ >+ return wbcCtxEndpwent(NULL); >+} >+ > /* Return the next struct passwd* entry from the pwent iterator */ >-wbcErr wbcGetpwent(struct passwd **pwd) >+wbcErr wbcCtxGetpwent(struct wbcContext *ctx, struct passwd **pwd) > { > wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; > struct winbindd_request request; >@@ -405,7 +443,7 @@ wbcErr wbcGetpwent(struct passwd **pwd) > ZERO_STRUCT(request); > request.data.num_entries = MAX_GETPWENT_USERS; > >- wbc_status = wbcRequestResponse(WINBINDD_GETPWENT, &request, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_GETPWENT, &request, > &pw_response); > > BAIL_ON_WBC_ERROR(wbc_status); >@@ -426,6 +464,11 @@ done: > return wbc_status; > } > >+wbcErr wbcGetpwent(struct passwd **pwd) >+{ >+ return wbcCtxGetpwent(NULL, pwd); >+} >+ > /** @brief Number of cached group structs > * > */ >@@ -442,7 +485,7 @@ static uint32_t gr_cache_idx; > static struct winbindd_response gr_response; > > /* Reset the group iterator */ >-wbcErr wbcSetgrent(void) >+wbcErr wbcCtxSetgrent(struct wbcContext *ctx) > { > wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; > >@@ -453,7 +496,7 @@ wbcErr wbcSetgrent(void) > > ZERO_STRUCT(gr_response); > >- wbc_status = wbcRequestResponse(WINBINDD_SETGRENT, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_SETGRENT, > NULL, NULL); > BAIL_ON_WBC_ERROR(wbc_status); > >@@ -461,8 +504,13 @@ wbcErr wbcSetgrent(void) > return wbc_status; > } > >+wbcErr wbcSetgrent(void) >+{ >+ return wbcCtxSetgrent(NULL); >+} >+ > /* Close the group iterator */ >-wbcErr wbcEndgrent(void) >+wbcErr wbcCtxEndgrent(struct wbcContext *ctx) > { > wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; > >@@ -471,7 +519,7 @@ wbcErr wbcEndgrent(void) > winbindd_free_response(&gr_response); > } > >- wbc_status = wbcRequestResponse(WINBINDD_ENDGRENT, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_ENDGRENT, > NULL, NULL); > BAIL_ON_WBC_ERROR(wbc_status); > >@@ -479,8 +527,13 @@ wbcErr wbcEndgrent(void) > return wbc_status; > } > >+wbcErr wbcEndgrent(void) >+{ >+ return wbcCtxEndgrent(NULL); >+} >+ > /* Return the next struct group* entry from the pwent iterator */ >-wbcErr wbcGetgrent(struct group **grp) >+wbcErr wbcCtxGetgrent(struct wbcContext *ctx, struct group **grp) > { > wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; > struct winbindd_request request; >@@ -501,8 +554,8 @@ wbcErr wbcGetgrent(struct group **grp) > ZERO_STRUCT(request); > request.data.num_entries = MAX_GETGRENT_GROUPS; > >- wbc_status = wbcRequestResponse(WINBINDD_GETGRENT, &request, >- &gr_response); >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_GETGRENT, >+ &request, &gr_response); > > BAIL_ON_WBC_ERROR(wbc_status); > >@@ -526,8 +579,13 @@ done: > return wbc_status; > } > >+wbcErr wbcGetgrent(struct group **grp) >+{ >+ return wbcCtxGetgrent(NULL, grp); >+} >+ > /* Return the next struct group* entry from the pwent iterator */ >-wbcErr wbcGetgrlist(struct group **grp) >+wbcErr wbcCtxGetgrlist(struct wbcContext *ctx, struct group **grp) > { > wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; > struct winbindd_request request; >@@ -548,8 +606,8 @@ wbcErr wbcGetgrlist(struct group **grp) > ZERO_STRUCT(request); > request.data.num_entries = MAX_GETGRENT_GROUPS; > >- wbc_status = wbcRequestResponse(WINBINDD_GETGRLST, &request, >- &gr_response); >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_GETGRLST, >+ &request, &gr_response); > > BAIL_ON_WBC_ERROR(wbc_status); > >@@ -569,10 +627,14 @@ done: > return wbc_status; > } > >+wbcErr wbcGetgrlist(struct group **grp) >+{ >+ return wbcCtxGetgrlist(NULL, grp); >+} >+ > /* Return the unix group array belonging to the given user */ >-wbcErr wbcGetGroups(const char *account, >- uint32_t *num_groups, >- gid_t **_groups) >+wbcErr wbcCtxGetGroups(struct wbcContext *ctx, const char *account, >+ uint32_t *num_groups, gid_t **_groups) > { > wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; > struct winbindd_request request; >@@ -594,7 +656,7 @@ wbcErr wbcGetGroups(const char *account, > > strncpy(request.data.username, account, sizeof(request.data.username)-1); > >- wbc_status = wbcRequestResponse(WINBINDD_GETGROUPS, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_GETGROUPS, > &request, > &response); > BAIL_ON_WBC_ERROR(wbc_status); >@@ -618,3 +680,8 @@ wbcErr wbcGetGroups(const char *account, > wbcFreeMemory(groups); > return wbc_status; > } >+ >+wbcErr wbcGetGroups(const char *account, uint32_t *num_groups, gid_t **_groups) >+{ >+ return wbcCtxGetGroups(NULL, account, num_groups, _groups); >+} >diff --git a/nsswitch/libwbclient/wbc_sid.c b/nsswitch/libwbclient/wbc_sid.c >index 0877ed0..cc71b9e 100644 >--- a/nsswitch/libwbclient/wbc_sid.c >+++ b/nsswitch/libwbclient/wbc_sid.c >@@ -180,10 +180,11 @@ done: > > > /* Convert a domain and name to SID */ >-wbcErr wbcLookupName(const char *domain, >- const char *name, >- struct wbcDomainSid *sid, >- enum wbcSidType *name_type) >+wbcErr wbcCtxLookupName(struct wbcContext *ctx, >+ const char *domain, >+ const char *name, >+ struct wbcDomainSid *sid, >+ enum wbcSidType *name_type) > { > struct winbindd_request request; > struct winbindd_response response; >@@ -206,7 +207,7 @@ wbcErr wbcLookupName(const char *domain, > strncpy(request.data.name.name, name, > sizeof(request.data.name.name)-1); > >- wbc_status = wbcRequestResponse(WINBINDD_LOOKUPNAME, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_LOOKUPNAME, > &request, > &response); > BAIL_ON_WBC_ERROR(wbc_status); >@@ -222,12 +223,21 @@ wbcErr wbcLookupName(const char *domain, > return wbc_status; > } > >+wbcErr wbcLookupName(const char *domain, >+ const char *name, >+ struct wbcDomainSid *sid, >+ enum wbcSidType *name_type) >+{ >+ return wbcCtxLookupName(NULL, domain, name, sid, name_type); >+} >+ > > /* Convert a SID to a domain and name */ >-wbcErr wbcLookupSid(const struct wbcDomainSid *sid, >- char **pdomain, >- char **pname, >- enum wbcSidType *pname_type) >+wbcErr wbcCtxLookupSid(struct wbcContext *ctx, >+ const struct wbcDomainSid *sid, >+ char **pdomain, >+ char **pname, >+ enum wbcSidType *pname_type) > { > struct winbindd_request request; > struct winbindd_response response; >@@ -247,7 +257,8 @@ wbcErr wbcLookupSid(const struct wbcDomainSid *sid, > > /* Make request */ > >- wbc_status = wbcRequestResponse(WINBINDD_LOOKUPSID, &request, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_LOOKUPSID, >+ &request, > &response); > if (!WBC_ERROR_IS_OK(wbc_status)) { > return wbc_status; >@@ -285,6 +296,14 @@ done: > return wbc_status; > } > >+wbcErr wbcLookupSid(const struct wbcDomainSid *sid, >+ char **pdomain, >+ char **pname, >+ enum wbcSidType *pname_type) >+{ >+ return wbcCtxLookupSid(NULL, sid, pdomain, pname, pname_type); >+} >+ > static void wbcDomainInfosDestructor(void *ptr) > { > struct wbcDomainInfo *i = (struct wbcDomainInfo *)ptr; >@@ -306,9 +325,10 @@ static void wbcTranslatedNamesDestructor(void *ptr) > } > } > >-wbcErr wbcLookupSids(const struct wbcDomainSid *sids, int num_sids, >- struct wbcDomainInfo **pdomains, int *pnum_domains, >- struct wbcTranslatedName **pnames) >+wbcErr wbcCtxLookupSids(struct wbcContext *ctx, >+ const struct wbcDomainSid *sids, int num_sids, >+ struct wbcDomainInfo **pdomains, int *pnum_domains, >+ struct wbcTranslatedName **pnames) > { > struct winbindd_request request; > struct winbindd_response response; >@@ -350,7 +370,7 @@ wbcErr wbcLookupSids(const struct wbcDomainSid *sids, int num_sids, > request.extra_data.data = sidlist; > request.extra_len = p - sidlist; > >- wbc_status = wbcRequestResponse(WINBINDD_LOOKUPSIDS, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_LOOKUPSIDS, > &request, &response); > free(sidlist); > if (!WBC_ERROR_IS_OK(wbc_status)) { >@@ -475,9 +495,17 @@ fail: > return wbc_status; > } > >+wbcErr wbcLookupSids(const struct wbcDomainSid *sids, int num_sids, >+ struct wbcDomainInfo **pdomains, int *pnum_domains, >+ struct wbcTranslatedName **pnames) >+{ >+ return wbcCtxLookupSids(NULL, sids, num_sids, pdomains, >+ pnum_domains, pnames); >+} >+ > /* Translate a collection of RIDs within a domain to names */ > >-wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid, >+wbcErr wbcCtxLookupRids(struct wbcContext *ctx, struct wbcDomainSid *dom_sid, > int num_rids, > uint32_t *rids, > const char **pp_domain_name, >@@ -527,7 +555,7 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid, > request.extra_data.data = ridlist; > request.extra_len = len; > >- wbc_status = wbcRequestResponse(WINBINDD_LOOKUPRIDS, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_LOOKUPRIDS, > &request, > &response); > free(ridlist); >@@ -599,11 +627,23 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid, > return wbc_status; > } > >+wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid, >+ int num_rids, >+ uint32_t *rids, >+ const char **pp_domain_name, >+ const char ***pnames, >+ enum wbcSidType **ptypes) >+{ >+ return wbcCtxLookupRids(NULL, dom_sid, num_rids, rids, >+ pp_domain_name, pnames, ptypes); >+} >+ > /* Get the groups a user belongs to */ >-wbcErr wbcLookupUserSids(const struct wbcDomainSid *user_sid, >- bool domain_groups_only, >- uint32_t *num_sids, >- struct wbcDomainSid **_sids) >+wbcErr wbcCtxLookupUserSids(struct wbcContext *ctx, >+ const struct wbcDomainSid *user_sid, >+ bool domain_groups_only, >+ uint32_t *num_sids, >+ struct wbcDomainSid **_sids) > { > uint32_t i; > const char *s; >@@ -631,7 +671,7 @@ wbcErr wbcLookupUserSids(const struct wbcDomainSid *user_sid, > cmd = WINBINDD_GETUSERSIDS; > } > >- wbc_status = wbcRequestResponse(cmd, >+ wbc_status = wbcRequestResponse(ctx, cmd, > &request, > &response); > BAIL_ON_WBC_ERROR(wbc_status); >@@ -672,6 +712,15 @@ wbcErr wbcLookupUserSids(const struct wbcDomainSid *user_sid, > return wbc_status; > } > >+wbcErr wbcLookupUserSids(const struct wbcDomainSid *user_sid, >+ bool domain_groups_only, >+ uint32_t *num_sids, >+ struct wbcDomainSid **_sids) >+{ >+ return wbcCtxLookupUserSids(NULL, user_sid, domain_groups_only, >+ num_sids, _sids); >+} >+ > static inline > wbcErr _sid_to_rid(struct wbcDomainSid *sid, uint32_t *rid) > { >@@ -684,11 +733,12 @@ wbcErr _sid_to_rid(struct wbcDomainSid *sid, uint32_t *rid) > } > > /* Get alias membership for sids */ >-wbcErr wbcGetSidAliases(const struct wbcDomainSid *dom_sid, >- struct wbcDomainSid *sids, >- uint32_t num_sids, >- uint32_t **alias_rids, >- uint32_t *num_alias_rids) >+wbcErr wbcCtxGetSidAliases(struct wbcContext *ctx, >+ const struct wbcDomainSid *dom_sid, >+ struct wbcDomainSid *sids, >+ uint32_t num_sids, >+ uint32_t **alias_rids, >+ uint32_t *num_alias_rids) > { > uint32_t i; > const char *s; >@@ -749,7 +799,7 @@ wbcErr wbcGetSidAliases(const struct wbcDomainSid *dom_sid, > request.extra_data.data = extra_data; > request.extra_len = extra_data_len; > >- wbc_status = wbcRequestResponse(WINBINDD_GETSIDALIASES, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_GETSIDALIASES, > &request, > &response); > BAIL_ON_WBC_ERROR(wbc_status); >@@ -789,11 +839,22 @@ wbcErr wbcGetSidAliases(const struct wbcDomainSid *dom_sid, > return wbc_status; > } > >+wbcErr wbcGetSidAliases(const struct wbcDomainSid *dom_sid, >+ struct wbcDomainSid *sids, >+ uint32_t num_sids, >+ uint32_t **alias_rids, >+ uint32_t *num_alias_rids) >+{ >+ return wbcCtxGetSidAliases(NULL, dom_sid, sids, num_sids, >+ alias_rids, num_alias_rids); >+} >+ > > /* Lists Users */ >-wbcErr wbcListUsers(const char *domain_name, >- uint32_t *_num_users, >- const char ***_users) >+wbcErr wbcCtxListUsers(struct wbcContext *ctx, >+ const char *domain_name, >+ uint32_t *_num_users, >+ const char ***_users) > { > wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; > struct winbindd_request request; >@@ -812,7 +873,7 @@ wbcErr wbcListUsers(const char *domain_name, > sizeof(request.domain_name)-1); > } > >- wbc_status = wbcRequestResponse(WINBINDD_LIST_USERS, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_LIST_USERS, > &request, > &response); > BAIL_ON_WBC_ERROR(wbc_status); >@@ -864,10 +925,18 @@ wbcErr wbcListUsers(const char *domain_name, > return wbc_status; > } > >+wbcErr wbcListUsers(const char *domain_name, >+ uint32_t *_num_users, >+ const char ***_users) >+{ >+ return wbcCtxListUsers(NULL, domain_name, _num_users, _users); >+} >+ > /* Lists Groups */ >-wbcErr wbcListGroups(const char *domain_name, >- uint32_t *_num_groups, >- const char ***_groups) >+wbcErr wbcCtxListGroups(struct wbcContext *ctx, >+ const char *domain_name, >+ uint32_t *_num_groups, >+ const char ***_groups) > { > wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; > struct winbindd_request request; >@@ -886,7 +955,7 @@ wbcErr wbcListGroups(const char *domain_name, > sizeof(request.domain_name)-1); > } > >- wbc_status = wbcRequestResponse(WINBINDD_LIST_GROUPS, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_LIST_GROUPS, > &request, > &response); > BAIL_ON_WBC_ERROR(wbc_status); >@@ -938,27 +1007,35 @@ wbcErr wbcListGroups(const char *domain_name, > return wbc_status; > } > >-wbcErr wbcGetDisplayName(const struct wbcDomainSid *sid, >- char **pdomain, >- char **pfullname, >- enum wbcSidType *pname_type) >+wbcErr wbcListGroups(const char *domain_name, >+ uint32_t *_num_groups, >+ const char ***_groups) >+{ >+ return wbcCtxListGroups(NULL, domain_name, _num_groups, _groups); >+} >+ >+wbcErr wbcCtxGetDisplayName(struct wbcContext *ctx, >+ const struct wbcDomainSid *sid, >+ char **pdomain, >+ char **pfullname, >+ enum wbcSidType *pname_type) > { > wbcErr wbc_status; > char *domain = NULL; > char *name = NULL; > enum wbcSidType name_type; > >- wbc_status = wbcLookupSid(sid, &domain, &name, &name_type); >+ wbc_status = wbcCtxLookupSid(ctx, sid, &domain, &name, &name_type); > BAIL_ON_WBC_ERROR(wbc_status); > > if (name_type == WBC_SID_NAME_USER) { > uid_t uid; > struct passwd *pwd; > >- wbc_status = wbcSidToUid(sid, &uid); >+ wbc_status = wbcCtxSidToUid(ctx, sid, &uid); > BAIL_ON_WBC_ERROR(wbc_status); > >- wbc_status = wbcGetpwuid(uid, &pwd); >+ wbc_status = wbcCtxGetpwuid(ctx, uid, &pwd); > BAIL_ON_WBC_ERROR(wbc_status); > > wbcFreeMemory(name); >@@ -983,6 +1060,14 @@ wbcErr wbcGetDisplayName(const struct wbcDomainSid *sid, > return wbc_status; > } > >+wbcErr wbcGetDisplayName(const struct wbcDomainSid *sid, >+ char **pdomain, >+ char **pfullname, >+ enum wbcSidType *pname_type) >+{ >+ return wbcCtxGetDisplayName(NULL, sid, pdomain, pfullname, pname_type); >+} >+ > const char* wbcSidTypeString(enum wbcSidType type) > { > switch (type) { >diff --git a/nsswitch/libwbclient/wbc_util.c b/nsswitch/libwbclient/wbc_util.c >index 4060e25..3dab0a2 100644 >--- a/nsswitch/libwbclient/wbc_util.c >+++ b/nsswitch/libwbclient/wbc_util.c >@@ -28,9 +28,11 @@ > > /** @brief Ping winbindd to see if the daemon is running > * >+ * @param *ctx wbclient Context >+ * > * @return #wbcErr > **/ >-wbcErr wbcPing(void) >+wbcErr wbcCtxPing(struct wbcContext *ctx) > { > struct winbindd_request request; > struct winbindd_response response; >@@ -40,7 +42,12 @@ wbcErr wbcPing(void) > ZERO_STRUCT(request); > ZERO_STRUCT(response); > >- return wbcRequestResponse(WINBINDD_PING, &request, &response); >+ return wbcRequestResponse(ctx, WINBINDD_PING, &request, &response); >+} >+ >+wbcErr wbcPing(void) >+{ >+ return wbcCtxPing(NULL); > } > > static void wbcInterfaceDetailsDestructor(void *ptr) >@@ -60,7 +67,8 @@ static void wbcInterfaceDetailsDestructor(void *ptr) > * @return #wbcErr > */ > >-wbcErr wbcInterfaceDetails(struct wbcInterfaceDetails **_details) >+wbcErr wbcCtxInterfaceDetails(struct wbcContext *ctx, >+ struct wbcInterfaceDetails **_details) > { > wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; > struct wbcInterfaceDetails *info; >@@ -79,12 +87,13 @@ wbcErr wbcInterfaceDetails(struct wbcInterfaceDetails **_details) > BAIL_ON_PTR_ERROR(info, wbc_status); > > /* first the interface version */ >- wbc_status = wbcRequestResponse(WINBINDD_INTERFACE_VERSION, NULL, &response); >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_INTERFACE_VERSION, >+ NULL, &response); > BAIL_ON_WBC_ERROR(wbc_status); > info->interface_version = response.data.interface_version; > > /* then the samba version and the winbind separator */ >- wbc_status = wbcRequestResponse(WINBINDD_INFO, NULL, &response); >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_INFO, NULL, &response); > BAIL_ON_WBC_ERROR(wbc_status); > > info->winbind_version = strdup(response.data.info.samba_version); >@@ -92,20 +101,22 @@ wbcErr wbcInterfaceDetails(struct wbcInterfaceDetails **_details) > info->winbind_separator = response.data.info.winbind_separator; > > /* then the local netbios name */ >- wbc_status = wbcRequestResponse(WINBINDD_NETBIOS_NAME, NULL, &response); >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_NETBIOS_NAME, >+ NULL, &response); > BAIL_ON_WBC_ERROR(wbc_status); > > info->netbios_name = strdup(response.data.netbios_name); > BAIL_ON_PTR_ERROR(info->netbios_name, wbc_status); > > /* then the local workgroup name */ >- wbc_status = wbcRequestResponse(WINBINDD_DOMAIN_NAME, NULL, &response); >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_DOMAIN_NAME, >+ NULL, &response); > BAIL_ON_WBC_ERROR(wbc_status); > > info->netbios_domain = strdup(response.data.domain_name); > BAIL_ON_PTR_ERROR(info->netbios_domain, wbc_status); > >- wbc_status = wbcDomainInfo(info->netbios_domain, &domain); >+ wbc_status = wbcCtxDomainInfo(ctx, info->netbios_domain, &domain); > if (wbc_status == WBC_ERR_DOMAIN_NOT_FOUND) { > /* maybe it's a standalone server */ > domain = NULL; >@@ -132,6 +143,11 @@ done: > return wbc_status; > } > >+wbcErr wbcInterfaceDetails(struct wbcInterfaceDetails **_details) >+{ >+ return wbcCtxInterfaceDetails(NULL, _details); >+} >+ > static void wbcDomainInfoDestructor(void *ptr) > { > struct wbcDomainInfo *i = (struct wbcDomainInfo *)ptr; >@@ -147,7 +163,9 @@ static void wbcDomainInfoDestructor(void *ptr) > * @return #wbcErr > */ > >-wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo **dinfo) >+wbcErr wbcCtxDomainInfo(struct wbcContext *ctx, >+ const char *domain, >+ struct wbcDomainInfo **dinfo) > { > struct winbindd_request request; > struct winbindd_response response; >@@ -167,7 +185,7 @@ wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo **dinfo) > strncpy(request.domain_name, domain, > sizeof(request.domain_name)-1); > >- wbc_status = wbcRequestResponse(WINBINDD_DOMAIN_INFO, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_DOMAIN_INFO, > &request, > &response); > BAIL_ON_WBC_ERROR(wbc_status); >@@ -203,9 +221,15 @@ wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo **dinfo) > return wbc_status; > } > >+wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo **dinfo) >+{ >+ return wbcCtxDomainInfo(NULL, domain, dinfo); >+} >+ > /* Get the list of current DCs */ >-wbcErr wbcDcInfo(const char *domain, size_t *num_dcs, >- const char ***dc_names, const char ***dc_ips) >+wbcErr wbcCtxDcInfo(struct wbcContext *ctx, >+ const char *domain, size_t *num_dcs, >+ const char ***dc_names, const char ***dc_ips) > { > struct winbindd_request request; > struct winbindd_response response; >@@ -226,7 +250,7 @@ wbcErr wbcDcInfo(const char *domain, size_t *num_dcs, > sizeof(request.domain_name) - 1); > } > >- wbc_status = wbcRequestResponse(WINBINDD_DC_INFO, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_DC_INFO, > &request, &response); > BAIL_ON_WBC_ERROR(wbc_status); > >@@ -290,8 +314,15 @@ done: > return wbc_status; > } > >+wbcErr wbcDcInfo(const char *domain, size_t *num_dcs, >+ const char ***dc_names, const char ***dc_ips) >+{ >+ return wbcCtxDcInfo(NULL, domain, num_dcs, dc_names, dc_ips); >+} >+ > /* Resolve a NetbiosName via WINS */ >-wbcErr wbcResolveWinsByName(const char *name, char **ip) >+wbcErr wbcCtxResolveWinsByName(struct wbcContext *ctx, >+ const char *name, char **ip) > { > struct winbindd_request request; > struct winbindd_response response; >@@ -306,7 +337,7 @@ wbcErr wbcResolveWinsByName(const char *name, char **ip) > strncpy(request.data.winsreq, name, > sizeof(request.data.winsreq)-1); > >- wbc_status = wbcRequestResponse(WINBINDD_WINS_BYNAME, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_WINS_BYNAME, > &request, > &response); > BAIL_ON_WBC_ERROR(wbc_status); >@@ -323,8 +354,14 @@ wbcErr wbcResolveWinsByName(const char *name, char **ip) > return wbc_status; > } > >+wbcErr wbcResolveWinsByName(const char *name, char **ip) >+{ >+ return wbcCtxResolveWinsByName(NULL, name, ip); >+} >+ > /* Resolve an IP address via WINS into a NetbiosName */ >-wbcErr wbcResolveWinsByIP(const char *ip, char **name) >+wbcErr wbcCtxResolveWinsByIP(struct wbcContext *ctx, >+ const char *ip, char **name) > { > struct winbindd_request request; > struct winbindd_response response; >@@ -339,7 +376,7 @@ wbcErr wbcResolveWinsByIP(const char *ip, char **name) > strncpy(request.data.winsreq, ip, > sizeof(request.data.winsreq)-1); > >- wbc_status = wbcRequestResponse(WINBINDD_WINS_BYIP, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_WINS_BYIP, > &request, > &response); > BAIL_ON_WBC_ERROR(wbc_status); >@@ -356,6 +393,11 @@ wbcErr wbcResolveWinsByIP(const char *ip, char **name) > return wbc_status; > } > >+wbcErr wbcResolveWinsByIP(const char *ip, char **name) >+{ >+ return wbcCtxResolveWinsByIP(NULL, ip, name); >+} >+ > /** > */ > >@@ -489,7 +531,8 @@ static void wbcDomainInfoListDestructor(void *ptr) > } > > /* Enumerate the domain trusts known by Winbind */ >-wbcErr wbcListTrusts(struct wbcDomainInfo **domains, size_t *num_domains) >+wbcErr wbcCtxListTrusts(struct wbcContext *ctx, >+ struct wbcDomainInfo **domains, size_t *num_domains) > { > struct winbindd_response response; > wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; >@@ -505,7 +548,7 @@ wbcErr wbcListTrusts(struct wbcDomainInfo **domains, size_t *num_domains) > > /* Send request */ > >- wbc_status = wbcRequestResponse(WINBINDD_LIST_TRUSTDOM, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_LIST_TRUSTDOM, > NULL, > &response); > BAIL_ON_WBC_ERROR(wbc_status); >@@ -559,6 +602,11 @@ wbcErr wbcListTrusts(struct wbcDomainInfo **domains, size_t *num_domains) > return wbc_status; > } > >+wbcErr wbcListTrusts(struct wbcDomainInfo **domains, size_t *num_domains) >+{ >+ return wbcCtxListTrusts(NULL, domains, num_domains); >+} >+ > static void wbcDomainControllerInfoDestructor(void *ptr) > { > struct wbcDomainControllerInfo *i = >@@ -567,9 +615,9 @@ static void wbcDomainControllerInfoDestructor(void *ptr) > } > > /* Enumerate the domain trusts known by Winbind */ >-wbcErr wbcLookupDomainController(const char *domain, >- uint32_t flags, >- struct wbcDomainControllerInfo **dc_info) >+wbcErr wbcCtxLookupDomainController(struct wbcContext *ctx, >+ const char *domain, uint32_t flags, >+ struct wbcDomainControllerInfo **dc_info) > { > wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; > struct winbindd_request request; >@@ -598,7 +646,7 @@ wbcErr wbcLookupDomainController(const char *domain, > > /* Send request */ > >- wbc_status = wbcRequestResponse(WINBINDD_DSGETDCNAME, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_DSGETDCNAME, > &request, > &response); > BAIL_ON_WBC_ERROR(wbc_status); >@@ -614,6 +662,12 @@ done: > return wbc_status; > } > >+wbcErr wbcLookupDomainController(const char *domain, uint32_t flags, >+ struct wbcDomainControllerInfo **dc_info) >+{ >+ return wbcCtxLookupDomainController(NULL, domain, flags, dc_info); >+} >+ > static void wbcDomainControllerInfoExDestructor(void *ptr) > { > struct wbcDomainControllerInfoEx *i = >@@ -688,11 +742,12 @@ done: > } > > /* Get extended domain controller information */ >-wbcErr wbcLookupDomainControllerEx(const char *domain, >- struct wbcGuid *guid, >- const char *site, >- uint32_t flags, >- struct wbcDomainControllerInfoEx **dc_info) >+wbcErr wbcCtxLookupDomainControllerEx(struct wbcContext *ctx, >+ const char *domain, >+ struct wbcGuid *guid, >+ const char *site, >+ uint32_t flags, >+ struct wbcDomainControllerInfoEx **dc_info) > { > wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; > struct winbindd_request request; >@@ -732,7 +787,7 @@ wbcErr wbcLookupDomainControllerEx(const char *domain, > > /* Send request */ > >- wbc_status = wbcRequestResponse(WINBINDD_DSGETDCNAME, >+ wbc_status = wbcRequestResponse(ctx, WINBINDD_DSGETDCNAME, > &request, > &response); > BAIL_ON_WBC_ERROR(wbc_status); >@@ -748,6 +803,16 @@ done: > return wbc_status; > } > >+wbcErr wbcLookupDomainControllerEx(const char *domain, >+ struct wbcGuid *guid, >+ const char *site, >+ uint32_t flags, >+ struct wbcDomainControllerInfoEx **dc_info) >+{ >+ return wbcCtxLookupDomainControllerEx(NULL, domain, guid, site, >+ flags, dc_info); >+} >+ > static void wbcNamedBlobDestructor(void *ptr) > { > struct wbcNamedBlob *b = (struct wbcNamedBlob *)ptr; >diff --git a/nsswitch/libwbclient/wbclient.h b/nsswitch/libwbclient/wbclient.h >index 265cf43..6aa4e12 100644 >--- a/nsswitch/libwbclient/wbclient.h >+++ b/nsswitch/libwbclient/wbclient.h >@@ -630,12 +630,23 @@ wbcErr wbcStringToGuid(const char *guid_string, > /** > * @brief Ping winbindd to see if the daemon is running > * >+ * @param *ctx wbclient Context >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxPing(struct wbcContext *ctx); >+ >+/** >+ * @brief Ping winbindd to see if the daemon is running >+ * > * @return #wbcErr > **/ > wbcErr wbcPing(void); > > wbcErr wbcLibraryDetails(struct wbcLibraryDetails **details); > >+wbcErr wbcCtxInterfaceDetails(struct wbcContext *ctx, >+ struct wbcInterfaceDetails **details); > wbcErr wbcInterfaceDetails(struct wbcInterfaceDetails **details); > > /********************************************************** >@@ -645,6 +656,23 @@ wbcErr wbcInterfaceDetails(struct wbcInterfaceDetails **details); > /** > * @brief Convert a domain and name to SID > * >+ * @param *ctx wbclient Context >+ * @param dom_name Domain name (possibly "") >+ * @param name User or group name >+ * @param *sid Pointer to the resolved domain SID >+ * @param *name_type Pointer to the SID type >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxLookupName(struct wbcContext *ctx, >+ const char *dom_name, >+ const char *name, >+ struct wbcDomainSid *sid, >+ enum wbcSidType *name_type); >+ >+/** >+ * @brief Convert a domain and name to SID >+ * > * @param dom_name Domain name (possibly "") > * @param name User or group name > * @param *sid Pointer to the resolved domain SID >@@ -660,7 +688,24 @@ wbcErr wbcLookupName(const char *dom_name, > /** > * @brief Convert a SID to a domain and name > * >- * @param *sid Pointer to the domain SID to be resolved >+ * @param *ctx wbclient Context >+ * @param *sid Pointer to the domain SID to be resolved >+ * @param domain Resolved Domain name (possibly "") >+ * @param name Resolved User or group name >+ * @param *name_type Pointer to the resolved SID type >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxLookupSid(struct wbcContext *ctx, >+ const struct wbcDomainSid *sid, >+ char **domain, >+ char **name, >+ enum wbcSidType *name_type); >+ >+/** >+ * @brief Convert a SID to a domain and name >+ * >+ * @param *sid Pointer to the domain SID to be resolved > * @param domain Resolved Domain name (possibly "") > * @param name Resolved User or group name > * @param *name_type Pointer to the resolved SID type >@@ -678,6 +723,11 @@ struct wbcTranslatedName { > int domain_index; > }; > >+wbcErr wbcCtxLookupSids(struct wbcContext *ctx, >+ const struct wbcDomainSid *sids, int num_sids, >+ struct wbcDomainInfo **domains, int *num_domains, >+ struct wbcTranslatedName **names); >+ > wbcErr wbcLookupSids(const struct wbcDomainSid *sids, int num_sids, > struct wbcDomainInfo **domains, int *num_domains, > struct wbcTranslatedName **names); >@@ -685,6 +735,17 @@ wbcErr wbcLookupSids(const struct wbcDomainSid *sids, int num_sids, > /** > * @brief Translate a collection of RIDs within a domain to names > */ >+wbcErr wbcCtxLookupRids(struct wbcContext *ctx, >+ struct wbcDomainSid *dom_sid, >+ int num_rids, >+ uint32_t *rids, >+ const char **domain_name, >+ const char ***names, >+ enum wbcSidType **types); >+ >+/** >+ * @brief Translate a collection of RIDs within a domain to names >+ */ > wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid, > int num_rids, > uint32_t *rids, >@@ -695,6 +756,15 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid, > /* > * @brief Get the groups a user belongs to > **/ >+wbcErr wbcCtxLookupUserSids(struct wbcContext *ctx, >+ const struct wbcDomainSid *user_sid, >+ bool domain_groups_only, >+ uint32_t *num_sids, >+ struct wbcDomainSid **sids); >+ >+/* >+ * @brief Get the groups a user belongs to >+ **/ > wbcErr wbcLookupUserSids(const struct wbcDomainSid *user_sid, > bool domain_groups_only, > uint32_t *num_sids, >@@ -703,6 +773,16 @@ wbcErr wbcLookupUserSids(const struct wbcDomainSid *user_sid, > /* > * @brief Get alias membership for sids > **/ >+wbcErr wbcCtxGetSidAliases(struct wbcContext *ctx, >+ const struct wbcDomainSid *dom_sid, >+ struct wbcDomainSid *sids, >+ uint32_t num_sids, >+ uint32_t **alias_rids, >+ uint32_t *num_alias_rids); >+ >+/* >+ * @brief Get alias membership for sids >+ **/ > wbcErr wbcGetSidAliases(const struct wbcDomainSid *dom_sid, > struct wbcDomainSid *sids, > uint32_t num_sids, >@@ -712,6 +792,14 @@ wbcErr wbcGetSidAliases(const struct wbcDomainSid *dom_sid, > /** > * @brief Lists Users > **/ >+wbcErr wbcCtxListUsers(struct wbcContext *ctx, >+ const char *domain_name, >+ uint32_t *num_users, >+ const char ***users); >+ >+/** >+ * @brief Lists Users >+ **/ > wbcErr wbcListUsers(const char *domain_name, > uint32_t *num_users, > const char ***users); >@@ -719,10 +807,24 @@ wbcErr wbcListUsers(const char *domain_name, > /** > * @brief Lists Groups > **/ >+wbcErr wbcCtxListGroups(struct wbcContext *ctx, >+ const char *domain_name, >+ uint32_t *num_groups, >+ const char ***groups); >+ >+/** >+ * @brief Lists Groups >+ **/ > wbcErr wbcListGroups(const char *domain_name, > uint32_t *num_groups, > const char ***groups); > >+wbcErr wbcCtxGetDisplayName(struct wbcContext *ctx, >+ const struct wbcDomainSid *sid, >+ char **pdomain, >+ char **pfullname, >+ enum wbcSidType *pname_type); >+ > wbcErr wbcGetDisplayName(const struct wbcDomainSid *sid, > char **pdomain, > char **pfullname, >@@ -735,6 +837,20 @@ wbcErr wbcGetDisplayName(const struct wbcDomainSid *sid, > /** > * @brief Convert a Windows SID to a Unix uid, allocating an uid if needed > * >+ * @param *ctx wbclient Context >+ * @param *sid Pointer to the domain SID to be resolved >+ * @param *puid Pointer to the resolved uid_t value >+ * >+ * @return #wbcErr >+ * >+ **/ >+wbcErr wbcCtxSidToUid(struct wbcContext *ctx, >+ const struct wbcDomainSid *sid, >+ uid_t *puid); >+ >+/** >+ * @brief Convert a Windows SID to a Unix uid, allocating an uid if needed >+ * > * @param *sid Pointer to the domain SID to be resolved > * @param *puid Pointer to the resolved uid_t value > * >@@ -759,6 +875,19 @@ wbcErr wbcQuerySidToUid(const struct wbcDomainSid *sid, > /** > * @brief Convert a Unix uid to a Windows SID, allocating a SID if needed > * >+ * @param *ctx wbclient Context >+ * @param uid Unix uid to be resolved >+ * @param *sid Pointer to the resolved domain SID >+ * >+ * @return #wbcErr >+ * >+ **/ >+wbcErr wbcCtxUidToSid(struct wbcContext *ctx, uid_t uid, >+ struct wbcDomainSid *sid); >+ >+/** >+ * @brief Convert a Unix uid to a Windows SID, allocating a SID if needed >+ * > * @param uid Unix uid to be resolved > * @param *sid Pointer to the resolved domain SID > * >@@ -783,6 +912,20 @@ wbcErr wbcQueryUidToSid(uid_t uid, > /** > * @brief Convert a Windows SID to a Unix gid, allocating a gid if needed > * >+ * @param *ctx wbclient Context >+ * @param *sid Pointer to the domain SID to be resolved >+ * @param *pgid Pointer to the resolved gid_t value >+ * >+ * @return #wbcErr >+ * >+ **/ >+wbcErr wbcCtxSidToGid(struct wbcContext *ctx, >+ const struct wbcDomainSid *sid, >+ gid_t *pgid); >+ >+/** >+ * @brief Convert a Windows SID to a Unix gid, allocating a gid if needed >+ * > * @param *sid Pointer to the domain SID to be resolved > * @param *pgid Pointer to the resolved gid_t value > * >@@ -807,6 +950,19 @@ wbcErr wbcQuerySidToGid(const struct wbcDomainSid *sid, > /** > * @brief Convert a Unix gid to a Windows SID, allocating a SID if needed > * >+ * @param *ctx wbclient Context >+ * @param gid Unix gid to be resolved >+ * @param *sid Pointer to the resolved domain SID >+ * >+ * @return #wbcErr >+ * >+ **/ >+wbcErr wbcCtxGidToSid(struct wbcContext *ctx, gid_t gid, >+ struct wbcDomainSid *sid); >+ >+/** >+ * @brief Convert a Unix gid to a Windows SID, allocating a SID if needed >+ * > * @param gid Unix gid to be resolved > * @param *sid Pointer to the resolved domain SID > * >@@ -848,6 +1004,21 @@ struct wbcUnixId { > /** > * @brief Convert a list of sids to unix ids > * >+ * @param *ctx wbclient Context >+ * @param sids Pointer to an array of SIDs to convert >+ * @param num_sids Number of SIDs >+ * @param ids Preallocated output array for translated IDs >+ * >+ * @return #wbcErr >+ * >+ **/ >+wbcErr wbcCtxSidsToUnixIds(struct wbcContext *ctx, >+ const struct wbcDomainSid *sids, uint32_t num_sids, >+ struct wbcUnixId *ids); >+ >+/** >+ * @brief Convert a list of sids to unix ids >+ * > * @param sids Pointer to an array of SIDs to convert > * @param num_sids Number of SIDs > * @param ids Preallocated output array for translated IDs >@@ -861,7 +1032,17 @@ wbcErr wbcSidsToUnixIds(const struct wbcDomainSid *sids, uint32_t num_sids, > /** > * @brief Obtain a new uid from Winbind > * >- * @param *puid *pointer to the allocated uid >+ * @param *ctx wbclient Context >+ * @param *puid Pointer to the allocated uid >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxAllocateUid(struct wbcContext *ctx, uid_t *puid); >+ >+/** >+ * @brief Obtain a new uid from Winbind >+ * >+ * @param *puid Pointer to the allocated uid > * > * @return #wbcErr > **/ >@@ -870,7 +1051,17 @@ wbcErr wbcAllocateUid(uid_t *puid); > /** > * @brief Obtain a new gid from Winbind > * >- * @param *pgid Pointer to the allocated gid >+ * @param *ctx wbclient Context >+ * @param *pgid Pointer to the allocated gid >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxAllocateGid(struct wbcContext *ctx, gid_t *pgid); >+ >+/** >+ * @brief Obtain a new gid from Winbind >+ * >+ * @param *pgid Pointer to the allocated gid > * > * @return #wbcErr > **/ >@@ -960,6 +1151,19 @@ wbcErr wbcSetGidHwm(gid_t gid_hwm); > * @brief Fill in a struct passwd* for a domain user based > * on username > * >+ * @param *ctx wbclient Context >+ * @param *name Username to lookup >+ * @param **pwd Pointer to resulting struct passwd* from the query. >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxGetpwnam(struct wbcContext *ctx, >+ const char *name, struct passwd **pwd); >+ >+/** >+ * @brief Fill in a struct passwd* for a domain user based >+ * on username >+ * > * @param *name Username to lookup > * @param **pwd Pointer to resulting struct passwd* from the query. > * >@@ -971,6 +1175,19 @@ wbcErr wbcGetpwnam(const char *name, struct passwd **pwd); > * @brief Fill in a struct passwd* for a domain user based > * on uid > * >+ * @param *ctx wbclient Context >+ * @param uid Uid to lookup >+ * @param **pwd Pointer to resulting struct passwd* from the query. >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxGetpwuid(struct wbcContext *ctx, >+ uid_t uid, struct passwd **pwd); >+ >+/** >+ * @brief Fill in a struct passwd* for a domain user based >+ * on uid >+ * > * @param uid Uid to lookup > * @param **pwd Pointer to resulting struct passwd* from the query. > * >@@ -982,6 +1199,19 @@ wbcErr wbcGetpwuid(uid_t uid, struct passwd **pwd); > * @brief Fill in a struct passwd* for a domain user based > * on sid > * >+ * @param *ctx wbclient Context >+ * @param sid Sid to lookup >+ * @param **pwd Pointer to resulting struct passwd* from the query. >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxGetpwsid(struct wbcContext *ctx, >+ struct wbcDomainSid * sid, struct passwd **pwd); >+ >+/** >+ * @brief Fill in a struct passwd* for a domain user based >+ * on sid >+ * > * @param sid Sid to lookup > * @param **pwd Pointer to resulting struct passwd* from the query. > * >@@ -993,6 +1223,19 @@ wbcErr wbcGetpwsid(struct wbcDomainSid * sid, struct passwd **pwd); > * @brief Fill in a struct passwd* for a domain user based > * on username > * >+ * @param *ctx wbclient Context >+ * @param *name Username to lookup >+ * @param **grp Pointer to resulting struct group* from the query. >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxGetgrnam(struct wbcContext *ctx, >+ const char *name, struct group **grp); >+ >+/** >+ * @brief Fill in a struct passwd* for a domain user based >+ * on username >+ * > * @param *name Username to lookup > * @param **grp Pointer to resulting struct group* from the query. > * >@@ -1004,6 +1247,19 @@ wbcErr wbcGetgrnam(const char *name, struct group **grp); > * @brief Fill in a struct passwd* for a domain user based > * on uid > * >+ * @param *ctx wbclient Context >+ * @param gid Uid to lookup >+ * @param **grp Pointer to resulting struct group* from the query. >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxGetgrgid(struct wbcContext *ctx, >+ gid_t gid, struct group **grp); >+ >+/** >+ * @brief Fill in a struct passwd* for a domain user based >+ * on uid >+ * > * @param gid Uid to lookup > * @param **grp Pointer to resulting struct group* from the query. > * >@@ -1014,6 +1270,15 @@ wbcErr wbcGetgrgid(gid_t gid, struct group **grp); > /** > * @brief Reset the passwd iterator > * >+ * @param *ctx wbclient Context >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxSetpwent(struct wbcContext *ctx); >+ >+/** >+ * @brief Reset the passwd iterator >+ * > * @return #wbcErr > **/ > wbcErr wbcSetpwent(void); >@@ -1021,6 +1286,15 @@ wbcErr wbcSetpwent(void); > /** > * @brief Close the passwd iterator > * >+ * @param *ctx wbclient Context >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxEndpwent(struct wbcContext *ctx); >+ >+/** >+ * @brief Close the passwd iterator >+ * > * @return #wbcErr > **/ > wbcErr wbcEndpwent(void); >@@ -1028,7 +1302,17 @@ wbcErr wbcEndpwent(void); > /** > * @brief Return the next struct passwd* entry from the pwent iterator > * >- * @param **pwd Pointer to resulting struct passwd* from the query. >+ * @param *ctx wbclient Context >+ * @param **pwd Pointer to resulting struct passwd* from the query. >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxGetpwent(struct wbcContext *ctx, struct passwd **pwd); >+ >+/** >+ * @brief Return the next struct passwd* entry from the pwent iterator >+ * >+ * @param **pwd Pointer to resulting struct passwd* from the query. > * > * @return #wbcErr > **/ >@@ -1037,6 +1321,15 @@ wbcErr wbcGetpwent(struct passwd **pwd); > /** > * @brief Reset the group iterator > * >+ * @param *ctx wbclient Context >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxSetgrent(struct wbcContext *ctx); >+ >+/** >+ * @brief Reset the group iterator >+ * > * @return #wbcErr > **/ > wbcErr wbcSetgrent(void); >@@ -1044,6 +1337,15 @@ wbcErr wbcSetgrent(void); > /** > * @brief Close the group iterator > * >+ * @param *ctx wbclient Context >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxEndgrent(struct wbcContext *ctx); >+ >+/** >+ * @brief Close the group iterator >+ * > * @return #wbcErr > **/ > wbcErr wbcEndgrent(void); >@@ -1051,7 +1353,17 @@ wbcErr wbcEndgrent(void); > /** > * @brief Return the next struct group* entry from the pwent iterator > * >- * @param **grp Pointer to resulting struct group* from the query. >+ * @param *ctx wbclient Context >+ * @param **grp Pointer to resulting struct group* from the query. >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxGetgrent(struct wbcContext *ctx, struct group **grp); >+ >+/** >+ * @brief Return the next struct group* entry from the pwent iterator >+ * >+ * @param **grp Pointer to resulting struct group* from the query. > * > * @return #wbcErr > **/ >@@ -1062,7 +1374,19 @@ wbcErr wbcGetgrent(struct group **grp); > * > * This is similar to #wbcGetgrent, just that the member list is empty > * >- * @param **grp Pointer to resulting struct group* from the query. >+ * @param *ctx wbclient Context >+ * @param **grp Pointer to resulting struct group* from the query. >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxGetgrlist(struct wbcContext *ctx, struct group **grp); >+ >+/** >+ * @brief Return the next struct group* entry from the pwent iterator >+ * >+ * This is similar to #wbcGetgrent, just that the member list is empty >+ * >+ * @param **grp Pointer to resulting struct group* from the query. > * > * @return #wbcErr > **/ >@@ -1071,6 +1395,21 @@ wbcErr wbcGetgrlist(struct group **grp); > /** > * @brief Return the unix group array belonging to the given user > * >+ * @param *ctx wbclient Context >+ * @param *account The given user name >+ * @param *num_groups Number of elements returned in the groups array >+ * @param **_groups Pointer to resulting gid_t array. >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxGetGroups(struct wbcContext *ctx, >+ const char *account, >+ uint32_t *num_groups, >+ gid_t **_groups); >+ >+/** >+ * @brief Return the unix group array belonging to the given user >+ * > * @param *account The given user name > * @param *num_groups Number of elements returned in the groups array > * @param **_groups Pointer to resulting gid_t array. >@@ -1089,7 +1428,21 @@ wbcErr wbcGetGroups(const char *account, > /** > * @brief Lookup the current status of a trusted domain > * >- * @param domain The domain to query >+ * @param *ctx wbclient Context >+ * @param domain The domain to query >+ * >+ * @param dinfo A pointer to store the returned domain_info struct. >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxDomainInfo(struct wbcContext *ctx, >+ const char *domain, >+ struct wbcDomainInfo **dinfo); >+ >+/** >+ * @brief Lookup the current status of a trusted domain >+ * >+ * @param domain The domain to query > * > * @param dinfo A pointer to store the returned domain_info struct. > * >@@ -1101,6 +1454,22 @@ wbcErr wbcDomainInfo(const char *domain, > /** > * @brief Lookup the currently contacted DCs > * >+ * @param *ctx wbclient Context >+ * @param domain The domain to query >+ * >+ * @param num_dcs Number of DCs currently known >+ * @param dc_names Names of the currently known DCs >+ * @param dc_ips IP addresses of the currently known DCs >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxDcInfo(struct wbcContext *ctx, >+ const char *domain, size_t *num_dcs, >+ const char ***dc_names, const char ***dc_ips); >+ >+/** >+ * @brief Lookup the currently contacted DCs >+ * > * @param domain The domain to query > * > * @param num_dcs Number of DCs currently known >@@ -1115,6 +1484,19 @@ wbcErr wbcDcInfo(const char *domain, size_t *num_dcs, > /** > * @brief Enumerate the domain trusts known by Winbind > * >+ * @param *ctx wbclient Context >+ * @param **domains Pointer to the allocated domain list array >+ * @param *num_domains Pointer to number of domains returned >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxListTrusts(struct wbcContext *ctx, >+ struct wbcDomainInfo **domains, >+ size_t *num_domains); >+ >+/** >+ * @brief Enumerate the domain trusts known by Winbind >+ * > * @param **domains Pointer to the allocated domain list array > * @param *num_domains Pointer to number of domains returned > * >@@ -1148,6 +1530,21 @@ wbcErr wbcListTrusts(struct wbcDomainInfo **domains, > /** > * @brief Enumerate the domain trusts known by Winbind > * >+ * @param *ctx wbclient Context >+ * @param domain Name of the domain to query for a DC >+ * @param flags Bit flags used to control the domain location query >+ * @param *dc_info Pointer to the returned domain controller information >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxLookupDomainController(struct wbcContext *ctx, >+ const char *domain, >+ uint32_t flags, >+ struct wbcDomainControllerInfo **dc_info); >+ >+/** >+ * @brief Enumerate the domain trusts known by Winbind >+ * > * @param domain Name of the domain to query for a DC > * @param flags Bit flags used to control the domain location query > * @param *dc_info Pointer to the returned domain controller information >@@ -1161,6 +1558,25 @@ wbcErr wbcLookupDomainController(const char *domain, > /** > * @brief Get extended domain controller information > * >+ * @param *ctx wbclient Context >+ * @param domain Name of the domain to query for a DC >+ * @param guid Guid of the domain to query for a DC >+ * @param site Site of the domain to query for a DC >+ * @param flags Bit flags used to control the domain location query >+ * @param *dc_info Pointer to the returned extended domain controller information >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxLookupDomainControllerEx(struct wbcContext *ctx, >+ const char *domain, >+ struct wbcGuid *guid, >+ const char *site, >+ uint32_t flags, >+ struct wbcDomainControllerInfoEx **dc_info); >+ >+/** >+ * @brief Get extended domain controller information >+ * > * @param domain Name of the domain to query for a DC > * @param guid Guid of the domain to query for a DC > * @param site Site of the domain to query for a DC >@@ -1182,6 +1598,19 @@ wbcErr wbcLookupDomainControllerEx(const char *domain, > /** > * @brief Authenticate a username/password pair > * >+ * @param *ctx wbclient Context >+ * @param username Name of user to authenticate >+ * @param password Clear text password os user >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxAuthenticateUser(struct wbcContext *ctx, >+ const char *username, >+ const char *password); >+ >+/** >+ * @brief Authenticate a username/password pair >+ * > * @param username Name of user to authenticate > * @param password Clear text password os user > * >@@ -1193,6 +1622,22 @@ wbcErr wbcAuthenticateUser(const char *username, > /** > * @brief Authenticate with more detailed information > * >+ * @param *ctx wbclient Context >+ * @param params Input parameters, WBC_AUTH_USER_LEVEL_HASH >+ * is not supported yet >+ * @param info Output details on WBC_ERR_SUCCESS >+ * @param error Output details on WBC_ERR_AUTH_ERROR >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxAuthenticateUserEx(struct wbcContext *ctx, >+ const struct wbcAuthUserParams *params, >+ struct wbcAuthUserInfo **info, >+ struct wbcAuthErrorInfo **error); >+ >+/** >+ * @brief Authenticate with more detailed information >+ * > * @param params Input parameters, WBC_AUTH_USER_LEVEL_HASH > * is not supported yet > * @param info Output details on WBC_ERR_SUCCESS >@@ -1207,6 +1652,23 @@ wbcErr wbcAuthenticateUserEx(const struct wbcAuthUserParams *params, > /** > * @brief Logon a User > * >+ * @param[in] *ctx wbclient Context >+ * @param[in] params Pointer to a wbcLogonUserParams structure >+ * @param[out] info Pointer to a pointer to a wbcLogonUserInfo structure >+ * @param[out] error Pointer to a pointer to a wbcAuthErrorInfo structure >+ * @param[out] policy Pointer to a pointer to a wbcUserPasswordPolicyInfo structure >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxLogonUser(struct wbcContext *ctx, >+ const struct wbcLogonUserParams *params, >+ struct wbcLogonUserInfo **info, >+ struct wbcAuthErrorInfo **error, >+ struct wbcUserPasswordPolicyInfo **policy); >+ >+/** >+ * @brief Logon a User >+ * > * @param[in] params Pointer to a wbcLogonUserParams structure > * @param[out] info Pointer to a pointer to a wbcLogonUserInfo structure > * @param[out] error Pointer to a pointer to a wbcAuthErrorInfo structure >@@ -1222,6 +1684,22 @@ wbcErr wbcLogonUser(const struct wbcLogonUserParams *params, > /** > * @brief Trigger a logoff notification to Winbind for a specific user > * >+ * @param *ctx wbclient Context >+ * @param username Name of user to remove from Winbind's list of >+ * logged on users. >+ * @param uid Uid assigned to the username >+ * @param ccfilename Absolute path to the Krb5 credentials cache to >+ * be removed >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxLogoffUser(struct wbcContext *ctx, >+ const char *username, uid_t uid, >+ const char *ccfilename); >+ >+/** >+ * @brief Trigger a logoff notification to Winbind for a specific user >+ * > * @param username Name of user to remove from Winbind's list of > * logged on users. > * @param uid Uid assigned to the username >@@ -1237,6 +1715,19 @@ wbcErr wbcLogoffUser(const char *username, > /** > * @brief Trigger an extended logoff notification to Winbind for a specific user > * >+ * @param *ctx wbclient Context >+ * @param params A wbcLogoffUserParams structure >+ * @param error User output details on error >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxLogoffUserEx(struct wbcContext *ctx, >+ const struct wbcLogoffUserParams *params, >+ struct wbcAuthErrorInfo **error); >+ >+/** >+ * @brief Trigger an extended logoff notification to Winbind for a specific user >+ * > * @param params A wbcLogoffUserParams structure > * @param error User output details on error > * >@@ -1248,6 +1739,21 @@ wbcErr wbcLogoffUserEx(const struct wbcLogoffUserParams *params, > /** > * @brief Change a password for a user > * >+ * @param *ctx wbclient Context >+ * @param username Name of user to authenticate >+ * @param old_password Old clear text password of user >+ * @param new_password New clear text password of user >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxChangeUserPassword(struct wbcContext *ctx, >+ const char *username, >+ const char *old_password, >+ const char *new_password); >+ >+/** >+ * @brief Change a password for a user >+ * > * @param username Name of user to authenticate > * @param old_password Old clear text password of user > * @param new_password New clear text password of user >@@ -1262,6 +1768,24 @@ wbcErr wbcChangeUserPassword(const char *username, > * @brief Change a password for a user with more detailed information upon > * failure > * >+ * @param *ctx wbclient Context >+ * @param params Input parameters >+ * @param error User output details on WBC_ERR_PWD_CHANGE_FAILED >+ * @param reject_reason New password reject reason on WBC_ERR_PWD_CHANGE_FAILED >+ * @param policy Password policy output details on WBC_ERR_PWD_CHANGE_FAILED >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxChangeUserPasswordEx(struct wbcContext *ctx, >+ const struct wbcChangePasswordParams *params, >+ struct wbcAuthErrorInfo **error, >+ enum wbcPasswordChangeRejectReason *reject_reason, >+ struct wbcUserPasswordPolicyInfo **policy); >+ >+/** >+ * @brief Change a password for a user with more detailed information upon >+ * failure >+ * > * @param params Input parameters > * @param error User output details on WBC_ERR_PWD_CHANGE_FAILED > * @param reject_reason New password reject reason on WBC_ERR_PWD_CHANGE_FAILED >@@ -1277,6 +1801,21 @@ wbcErr wbcChangeUserPasswordEx(const struct wbcChangePasswordParams *params, > /** > * @brief Authenticate a user with cached credentials > * >+ * @param *ctx wbclient Context >+ * @param *params Pointer to a wbcCredentialCacheParams structure >+ * @param **info Pointer to a pointer to a wbcCredentialCacheInfo structure >+ * @param **error Pointer to a pointer to a wbcAuthErrorInfo structure >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxCredentialCache(struct wbcContext *ctx, >+ struct wbcCredentialCacheParams *params, >+ struct wbcCredentialCacheInfo **info, >+ struct wbcAuthErrorInfo **error); >+ >+/** >+ * @brief Authenticate a user with cached credentials >+ * > * @param *params Pointer to a wbcCredentialCacheParams structure > * @param **info Pointer to a pointer to a wbcCredentialCacheInfo structure > * @param **error Pointer to a pointer to a wbcAuthErrorInfo structure >@@ -1290,6 +1829,18 @@ wbcErr wbcCredentialCache(struct wbcCredentialCacheParams *params, > /** > * @brief Save a password with winbind for doing wbcCredentialCache() later > * >+ * @param *ctx wbclient Context >+ * @param *user Username >+ * @param *password Password >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxCredentialSave(struct wbcContext *ctx, >+ const char *user, const char *password); >+ >+/** >+ * @brief Save a password with winbind for doing wbcCredentialCache() later >+ * > * @param *user Username > * @param *password Password > * >@@ -1304,6 +1855,18 @@ wbcErr wbcCredentialSave(const char *user, const char *password); > /** > * @brief Resolve a NetbiosName via WINS > * >+ * @param *ctx wbclient Context >+ * @param name Name to resolve >+ * @param *ip Pointer to the ip address string >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxResolveWinsByName(struct wbcContext *ctx, >+ const char *name, char **ip); >+ >+/** >+ * @brief Resolve a NetbiosName via WINS >+ * > * @param name Name to resolve > * @param *ip Pointer to the ip address string > * >@@ -1314,8 +1877,21 @@ wbcErr wbcResolveWinsByName(const char *name, char **ip); > /** > * @brief Resolve an IP address via WINS into a NetbiosName > * >- * @param ip The ip address string >- * @param *name Pointer to the name >+ * @param *ctx wbclient Context >+ * @param ip The ip address string >+ * @param *name Pointer to the name >+ * >+ * @return #wbcErr >+ * >+ **/ >+wbcErr wbcCtxResolveWinsByIP(struct wbcContext *ctx, >+ const char *ip, char **name); >+ >+/** >+ * @brief Resolve an IP address via WINS into a NetbiosName >+ * >+ * @param ip The ip address string >+ * @param *name Pointer to the name > * > * @return #wbcErr > * >@@ -1329,6 +1905,18 @@ wbcErr wbcResolveWinsByIP(const char *ip, char **name); > /** > * @brief Trigger a verification of the trust credentials of a specific domain > * >+ * @param *ctx wbclient Context >+ * @param *domain The name of the domain. >+ * @param error Output details on WBC_ERR_AUTH_ERROR >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxCheckTrustCredentials(struct wbcContext *ctx, const char *domain, >+ struct wbcAuthErrorInfo **error); >+ >+/** >+ * @brief Trigger a verification of the trust credentials of a specific domain >+ * > * @param *domain The name of the domain. > * @param error Output details on WBC_ERR_AUTH_ERROR > * >@@ -1340,6 +1928,18 @@ wbcErr wbcCheckTrustCredentials(const char *domain, > /** > * @brief Trigger a change of the trust credentials for a specific domain > * >+ * @param *ctx wbclient Context >+ * @param *domain The name of the domain. >+ * @param error Output details on WBC_ERR_AUTH_ERROR >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxChangeTrustCredentials(struct wbcContext *ctx, const char *domain, >+ struct wbcAuthErrorInfo **error); >+ >+/** >+ * @brief Trigger a change of the trust credentials for a specific domain >+ * > * @param *domain The name of the domain. > * @param error Output details on WBC_ERR_AUTH_ERROR > * >@@ -1352,6 +1952,21 @@ wbcErr wbcChangeTrustCredentials(const char *domain, > * @brief Trigger a no-op call through the NETLOGON pipe. Low-cost > * version of wbcCheckTrustCredentials > * >+ * @param *ctx wbclient Context >+ * @param *domain The name of the domain, only NULL for the default domain is >+ * supported yet. Other values than NULL will result in >+ * WBC_ERR_NOT_IMPLEMENTED. >+ * @param error Output details on WBC_ERR_AUTH_ERROR >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxPingDc(struct wbcContext *ctx, const char *domain, >+ struct wbcAuthErrorInfo **error); >+ >+/** >+ * @brief Trigger a no-op call through the NETLOGON pipe. Low-cost >+ * version of wbcCheckTrustCredentials >+ * > * @param *domain The name of the domain, only NULL for the default domain is > * supported yet. Other values than NULL will result in > * WBC_ERR_NOT_IMPLEMENTED. >@@ -1365,6 +1980,23 @@ wbcErr wbcPingDc(const char *domain, struct wbcAuthErrorInfo **error); > * @brief Trigger a no-op call through the NETLOGON pipe. Low-cost > * version of wbcCheckTrustCredentials > * >+ * @param *ctx wbclient Context >+ * @param *domain The name of the domain, only NULL for the default domain is >+ * supported yet. Other values than NULL will result in >+ * WBC_ERR_NOT_IMPLEMENTED. >+ * @param error Output details on WBC_ERR_AUTH_ERROR >+ * @param dcname DC that was attempted to ping >+ * >+ * @return #wbcErr >+ **/ >+wbcErr wbcCtxPingDc2(struct wbcContext *ctx, const char *domain, >+ struct wbcAuthErrorInfo **error, >+ char **dcname); >+ >+/** >+ * @brief Trigger a no-op call through the NETLOGON pipe. Low-cost >+ * version of wbcCheckTrustCredentials >+ * > * @param *domain The name of the domain, only NULL for the default domain is > * supported yet. Other values than NULL will result in > * WBC_ERR_NOT_IMPLEMENTED. >-- >1.9.1 > > >From 0ac0c36b2280607e3eba99d7e3f8cacafc3bf44d Mon Sep 17 00:00:00 2001 >From: Matthew Newton <matthew-git@newtoncomputing.co.uk> >Date: Sun, 22 Feb 2015 23:31:48 +0000 >Subject: [PATCH 6/7] Move wbc global variables into global context instead > >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. > >https://bugzilla.samba.org/show_bug.cgi?id=11149 > >Signed-off-by: Matthew Newton <matthew-git@newtoncomputing.co.uk> >Reviewed-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 2664d9070f3c21231627380822e619fb695db662) >--- > nsswitch/libwbclient/wbc_pwd.c | 99 +++++++++++++++++--------------- > nsswitch/libwbclient/wbclient.c | 14 +++++ > nsswitch/libwbclient/wbclient_internal.h | 5 ++ > 3 files changed, 73 insertions(+), 45 deletions(-) > >diff --git a/nsswitch/libwbclient/wbc_pwd.c b/nsswitch/libwbclient/wbc_pwd.c >index 0b05133..805ab63 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,16 +360,6 @@ 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 > * > */ >@@ -379,8 +370,12 @@ wbcErr wbcCtxSetpwent(struct wbcContext *ctx) > { > wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; > >- if (pw_cache_size > 0) { >- pw_cache_idx = pw_cache_size = 0; >+ if (!ctx) { >+ ctx = wbcGetGlobalCtx(); >+ } >+ >+ if (ctx->pw_cache_size > 0) { >+ ctx->pw_cache_idx = ctx->pw_cache_size = 0; > winbindd_free_response(&pw_response); > } > >@@ -404,8 +399,12 @@ wbcErr wbcCtxEndpwent(struct wbcContext *ctx) > { > wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; > >- if (pw_cache_size > 0) { >- pw_cache_idx = pw_cache_size = 0; >+ if (!ctx) { >+ ctx = wbcGetGlobalCtx(); >+ } >+ >+ if (ctx->pw_cache_size > 0) { >+ ctx->pw_cache_idx = ctx->pw_cache_size = 0; > winbindd_free_response(&pw_response); > } > >@@ -429,14 +428,18 @@ wbcErr wbcCtxGetpwent(struct wbcContext *ctx, struct passwd **pwd) > struct winbindd_request request; > struct winbindd_pw *wb_pw; > >+ if (!ctx) { >+ ctx = wbcGetGlobalCtx(); >+ } >+ > /* 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 +451,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,16 +472,6 @@ 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 > * > */ >@@ -489,8 +482,12 @@ wbcErr wbcCtxSetgrent(struct wbcContext *ctx) > { > wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; > >- if (gr_cache_size > 0) { >- gr_cache_idx = gr_cache_size = 0; >+ if (!ctx) { >+ ctx = wbcGetGlobalCtx(); >+ } >+ >+ if (ctx->gr_cache_size > 0) { >+ ctx->gr_cache_idx = ctx->gr_cache_size = 0; > winbindd_free_response(&gr_response); > } > >@@ -514,8 +511,12 @@ wbcErr wbcCtxEndgrent(struct wbcContext *ctx) > { > wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; > >- if (gr_cache_size > 0) { >- gr_cache_idx = gr_cache_size = 0; >+ if (!ctx) { >+ ctx = wbcGetGlobalCtx(); >+ } >+ >+ if (ctx->gr_cache_size > 0) { >+ ctx->gr_cache_idx = ctx->gr_cache_size = 0; > winbindd_free_response(&gr_response); > } > >@@ -540,14 +541,18 @@ wbcErr wbcCtxGetgrent(struct wbcContext *ctx, struct group **grp) > struct winbindd_gr *wb_gr; > uint32_t mem_ofs; > >+ if (!ctx) { >+ ctx = wbcGetGlobalCtx(); >+ } >+ > /* 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 +564,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; >@@ -591,14 +596,18 @@ wbcErr wbcCtxGetgrlist(struct wbcContext *ctx, struct group **grp) > struct winbindd_request request; > struct winbindd_gr *wb_gr; > >+ if (!ctx) { >+ ctx = wbcGetGlobalCtx(); >+ } >+ > /* 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 +620,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 ab1159a..5444e82 100644 >--- a/nsswitch/libwbclient/wbclient.c >+++ b/nsswitch/libwbclient/wbclient.c >@@ -41,6 +41,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 >@@ -317,3 +326,8 @@ void wbcCtxFree(struct wbcContext *ctx) > { > wbcFreeMemory(ctx); > } >+ >+struct wbcContext *wbcGetGlobalCtx(void) >+{ >+ return &wbcGlobalCtx; >+} >diff --git a/nsswitch/libwbclient/wbclient_internal.h b/nsswitch/libwbclient/wbclient_internal.h >index becddac..6d815c0 100644 >--- a/nsswitch/libwbclient/wbclient_internal.h >+++ b/nsswitch/libwbclient/wbclient_internal.h >@@ -24,6 +24,10 @@ > > struct wbcContext { > struct winbindd_context *winbindd_ctx; >+ 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 */ > }; > > /* Private functions */ >@@ -41,5 +45,6 @@ void *wbcAllocateMemory(size_t nelem, size_t elsize, > > char *wbcStrDup(const char *str); > const char **wbcAllocateStringArray(int num_strings); >+struct wbcContext *wbcGetGlobalCtx(void); > > #endif /* _WBCLIENT_INTERNAL_H */ >-- >1.9.1 > > >From 8189612572d33d6fcf3b9147135e7a8042132963 Mon Sep 17 00:00:00 2001 >From: Matthew Newton <matthew-git@newtoncomputing.co.uk> >Date: Sun, 1 Mar 2015 23:14:07 +0000 >Subject: [PATCH 7/7] Update libwbclient version to 0.12 > >Increment the minor version of the libwbclient library after new >context functions added. (Major version increase not required as >the only two functions with changed parameters are private to the >library.) > >https://bugzilla.samba.org/show_bug.cgi?id=11149 > >Signed-off-by: Matthew Newton <matthew-git@newtoncomputing.co.uk> >Reviewed-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> > >Autobuild-User(master): Jeremy Allison <jra@samba.org> >Autobuild-Date(master): Tue Mar 10 03:24:45 CET 2015 on sn-devel-104 > >(cherry picked from commit c6cb2d650872a8c37820b65bb2d5882207263e88) >--- > nsswitch/libwbclient/ABI/wbclient-0.12.sigs | 130 ++++++++++++++++++++++++++++ > nsswitch/libwbclient/wbclient.h | 3 +- > nsswitch/libwbclient/wscript | 2 +- > 3 files changed, 133 insertions(+), 2 deletions(-) > create mode 100644 nsswitch/libwbclient/ABI/wbclient-0.12.sigs > >diff --git a/nsswitch/libwbclient/ABI/wbclient-0.12.sigs b/nsswitch/libwbclient/ABI/wbclient-0.12.sigs >new file mode 100644 >index 0000000..3b71917 >--- /dev/null >+++ b/nsswitch/libwbclient/ABI/wbclient-0.12.sigs >@@ -0,0 +1,130 @@ >+wbcAddNamedBlob: wbcErr (size_t *, struct wbcNamedBlob **, const char *, uint32_t, uint8_t *, size_t) >+wbcAllocateGid: wbcErr (gid_t *) >+wbcAllocateMemory: void *(size_t, size_t, void (*)(void *)) >+wbcAllocateStringArray: const char **(int) >+wbcAllocateUid: wbcErr (uid_t *) >+wbcAuthenticateUser: wbcErr (const char *, const char *) >+wbcAuthenticateUserEx: wbcErr (const struct wbcAuthUserParams *, struct wbcAuthUserInfo **, struct wbcAuthErrorInfo **) >+wbcChangeTrustCredentials: wbcErr (const char *, struct wbcAuthErrorInfo **) >+wbcChangeUserPassword: wbcErr (const char *, const char *, const char *) >+wbcChangeUserPasswordEx: wbcErr (const struct wbcChangePasswordParams *, struct wbcAuthErrorInfo **, enum wbcPasswordChangeRejectReason *, struct wbcUserPasswordPolicyInfo **) >+wbcCheckTrustCredentials: wbcErr (const char *, struct wbcAuthErrorInfo **) >+wbcCredentialCache: wbcErr (struct wbcCredentialCacheParams *, struct wbcCredentialCacheInfo **, struct wbcAuthErrorInfo **) >+wbcCredentialSave: wbcErr (const char *, const char *) >+wbcCtxAllocateGid: wbcErr (struct wbcContext *, gid_t *) >+wbcCtxAllocateUid: wbcErr (struct wbcContext *, uid_t *) >+wbcCtxAuthenticateUser: wbcErr (struct wbcContext *, const char *, const char *) >+wbcCtxAuthenticateUserEx: wbcErr (struct wbcContext *, const struct wbcAuthUserParams *, struct wbcAuthUserInfo **, struct wbcAuthErrorInfo **) >+wbcCtxChangeTrustCredentials: wbcErr (struct wbcContext *, const char *, struct wbcAuthErrorInfo **) >+wbcCtxChangeUserPassword: wbcErr (struct wbcContext *, const char *, const char *, const char *) >+wbcCtxChangeUserPasswordEx: wbcErr (struct wbcContext *, const struct wbcChangePasswordParams *, struct wbcAuthErrorInfo **, enum wbcPasswordChangeRejectReason *, struct wbcUserPasswordPolicyInfo **) >+wbcCtxCheckTrustCredentials: wbcErr (struct wbcContext *, const char *, struct wbcAuthErrorInfo **) >+wbcCtxCreate: struct wbcContext *(void) >+wbcCtxCredentialCache: wbcErr (struct wbcContext *, struct wbcCredentialCacheParams *, struct wbcCredentialCacheInfo **, struct wbcAuthErrorInfo **) >+wbcCtxCredentialSave: wbcErr (struct wbcContext *, const char *, const char *) >+wbcCtxDcInfo: wbcErr (struct wbcContext *, const char *, size_t *, const char ***, const char ***) >+wbcCtxDomainInfo: wbcErr (struct wbcContext *, const char *, struct wbcDomainInfo **) >+wbcCtxEndgrent: wbcErr (struct wbcContext *) >+wbcCtxEndpwent: wbcErr (struct wbcContext *) >+wbcCtxFree: void (struct wbcContext *) >+wbcCtxGetDisplayName: wbcErr (struct wbcContext *, const struct wbcDomainSid *, char **, char **, enum wbcSidType *) >+wbcCtxGetGroups: wbcErr (struct wbcContext *, const char *, uint32_t *, gid_t **) >+wbcCtxGetSidAliases: wbcErr (struct wbcContext *, const struct wbcDomainSid *, struct wbcDomainSid *, uint32_t, uint32_t **, uint32_t *) >+wbcCtxGetgrent: wbcErr (struct wbcContext *, struct group **) >+wbcCtxGetgrgid: wbcErr (struct wbcContext *, gid_t, struct group **) >+wbcCtxGetgrlist: wbcErr (struct wbcContext *, struct group **) >+wbcCtxGetgrnam: wbcErr (struct wbcContext *, const char *, struct group **) >+wbcCtxGetpwent: wbcErr (struct wbcContext *, struct passwd **) >+wbcCtxGetpwnam: wbcErr (struct wbcContext *, const char *, struct passwd **) >+wbcCtxGetpwsid: wbcErr (struct wbcContext *, struct wbcDomainSid *, struct passwd **) >+wbcCtxGetpwuid: wbcErr (struct wbcContext *, uid_t, struct passwd **) >+wbcCtxGidToSid: wbcErr (struct wbcContext *, gid_t, struct wbcDomainSid *) >+wbcCtxInterfaceDetails: wbcErr (struct wbcContext *, struct wbcInterfaceDetails **) >+wbcCtxListGroups: wbcErr (struct wbcContext *, const char *, uint32_t *, const char ***) >+wbcCtxListTrusts: wbcErr (struct wbcContext *, struct wbcDomainInfo **, size_t *) >+wbcCtxListUsers: wbcErr (struct wbcContext *, const char *, uint32_t *, const char ***) >+wbcCtxLogoffUser: wbcErr (struct wbcContext *, const char *, uid_t, const char *) >+wbcCtxLogoffUserEx: wbcErr (struct wbcContext *, const struct wbcLogoffUserParams *, struct wbcAuthErrorInfo **) >+wbcCtxLogonUser: wbcErr (struct wbcContext *, const struct wbcLogonUserParams *, struct wbcLogonUserInfo **, struct wbcAuthErrorInfo **, struct wbcUserPasswordPolicyInfo **) >+wbcCtxLookupDomainController: wbcErr (struct wbcContext *, const char *, uint32_t, struct wbcDomainControllerInfo **) >+wbcCtxLookupDomainControllerEx: wbcErr (struct wbcContext *, const char *, struct wbcGuid *, const char *, uint32_t, struct wbcDomainControllerInfoEx **) >+wbcCtxLookupName: wbcErr (struct wbcContext *, const char *, const char *, struct wbcDomainSid *, enum wbcSidType *) >+wbcCtxLookupRids: wbcErr (struct wbcContext *, struct wbcDomainSid *, int, uint32_t *, const char **, const char ***, enum wbcSidType **) >+wbcCtxLookupSid: wbcErr (struct wbcContext *, const struct wbcDomainSid *, char **, char **, enum wbcSidType *) >+wbcCtxLookupSids: wbcErr (struct wbcContext *, const struct wbcDomainSid *, int, struct wbcDomainInfo **, int *, struct wbcTranslatedName **) >+wbcCtxLookupUserSids: wbcErr (struct wbcContext *, const struct wbcDomainSid *, bool, uint32_t *, struct wbcDomainSid **) >+wbcCtxPing: wbcErr (struct wbcContext *) >+wbcCtxPingDc: wbcErr (struct wbcContext *, const char *, struct wbcAuthErrorInfo **) >+wbcCtxPingDc2: wbcErr (struct wbcContext *, const char *, struct wbcAuthErrorInfo **, char **) >+wbcCtxResolveWinsByIP: wbcErr (struct wbcContext *, const char *, char **) >+wbcCtxResolveWinsByName: wbcErr (struct wbcContext *, const char *, char **) >+wbcCtxSetgrent: wbcErr (struct wbcContext *) >+wbcCtxSetpwent: wbcErr (struct wbcContext *) >+wbcCtxSidToGid: wbcErr (struct wbcContext *, const struct wbcDomainSid *, gid_t *) >+wbcCtxSidToUid: wbcErr (struct wbcContext *, const struct wbcDomainSid *, uid_t *) >+wbcCtxSidsToUnixIds: wbcErr (struct wbcContext *, const struct wbcDomainSid *, uint32_t, struct wbcUnixId *) >+wbcCtxUidToSid: wbcErr (struct wbcContext *, uid_t, struct wbcDomainSid *) >+wbcDcInfo: wbcErr (const char *, size_t *, const char ***, const char ***) >+wbcDomainInfo: wbcErr (const char *, struct wbcDomainInfo **) >+wbcEndgrent: wbcErr (void) >+wbcEndpwent: wbcErr (void) >+wbcErrorString: const char *(wbcErr) >+wbcFreeMemory: void (void *) >+wbcGetDisplayName: wbcErr (const struct wbcDomainSid *, char **, char **, enum wbcSidType *) >+wbcGetGlobalCtx: struct wbcContext *(void) >+wbcGetGroups: wbcErr (const char *, uint32_t *, gid_t **) >+wbcGetSidAliases: wbcErr (const struct wbcDomainSid *, struct wbcDomainSid *, uint32_t, uint32_t **, uint32_t *) >+wbcGetgrent: wbcErr (struct group **) >+wbcGetgrgid: wbcErr (gid_t, struct group **) >+wbcGetgrlist: wbcErr (struct group **) >+wbcGetgrnam: wbcErr (const char *, struct group **) >+wbcGetpwent: wbcErr (struct passwd **) >+wbcGetpwnam: wbcErr (const char *, struct passwd **) >+wbcGetpwsid: wbcErr (struct wbcDomainSid *, struct passwd **) >+wbcGetpwuid: wbcErr (uid_t, struct passwd **) >+wbcGidToSid: wbcErr (gid_t, struct wbcDomainSid *) >+wbcGuidToString: wbcErr (const struct wbcGuid *, char **) >+wbcInterfaceDetails: wbcErr (struct wbcInterfaceDetails **) >+wbcLibraryDetails: wbcErr (struct wbcLibraryDetails **) >+wbcListGroups: wbcErr (const char *, uint32_t *, const char ***) >+wbcListTrusts: wbcErr (struct wbcDomainInfo **, size_t *) >+wbcListUsers: wbcErr (const char *, uint32_t *, const char ***) >+wbcLogoffUser: wbcErr (const char *, uid_t, const char *) >+wbcLogoffUserEx: wbcErr (const struct wbcLogoffUserParams *, struct wbcAuthErrorInfo **) >+wbcLogonUser: wbcErr (const struct wbcLogonUserParams *, struct wbcLogonUserInfo **, struct wbcAuthErrorInfo **, struct wbcUserPasswordPolicyInfo **) >+wbcLookupDomainController: wbcErr (const char *, uint32_t, struct wbcDomainControllerInfo **) >+wbcLookupDomainControllerEx: wbcErr (const char *, struct wbcGuid *, const char *, uint32_t, struct wbcDomainControllerInfoEx **) >+wbcLookupName: wbcErr (const char *, const char *, struct wbcDomainSid *, enum wbcSidType *) >+wbcLookupRids: wbcErr (struct wbcDomainSid *, int, uint32_t *, const char **, const char ***, enum wbcSidType **) >+wbcLookupSid: wbcErr (const struct wbcDomainSid *, char **, char **, enum wbcSidType *) >+wbcLookupSids: wbcErr (const struct wbcDomainSid *, int, struct wbcDomainInfo **, int *, struct wbcTranslatedName **) >+wbcLookupUserSids: wbcErr (const struct wbcDomainSid *, bool, uint32_t *, struct wbcDomainSid **) >+wbcPing: wbcErr (void) >+wbcPingDc: wbcErr (const char *, struct wbcAuthErrorInfo **) >+wbcPingDc2: wbcErr (const char *, struct wbcAuthErrorInfo **, char **) >+wbcQueryGidToSid: wbcErr (gid_t, struct wbcDomainSid *) >+wbcQuerySidToGid: wbcErr (const struct wbcDomainSid *, gid_t *) >+wbcQuerySidToUid: wbcErr (const struct wbcDomainSid *, uid_t *) >+wbcQueryUidToSid: wbcErr (uid_t, struct wbcDomainSid *) >+wbcRemoveGidMapping: wbcErr (gid_t, const struct wbcDomainSid *) >+wbcRemoveUidMapping: wbcErr (uid_t, const struct wbcDomainSid *) >+wbcRequestResponse: wbcErr (struct wbcContext *, int, struct winbindd_request *, struct winbindd_response *) >+wbcRequestResponsePriv: wbcErr (struct wbcContext *, int, struct winbindd_request *, struct winbindd_response *) >+wbcResolveWinsByIP: wbcErr (const char *, char **) >+wbcResolveWinsByName: wbcErr (const char *, char **) >+wbcSetGidHwm: wbcErr (gid_t) >+wbcSetGidMapping: wbcErr (gid_t, const struct wbcDomainSid *) >+wbcSetUidHwm: wbcErr (uid_t) >+wbcSetUidMapping: wbcErr (uid_t, const struct wbcDomainSid *) >+wbcSetgrent: wbcErr (void) >+wbcSetpwent: wbcErr (void) >+wbcSidToGid: wbcErr (const struct wbcDomainSid *, gid_t *) >+wbcSidToString: wbcErr (const struct wbcDomainSid *, char **) >+wbcSidToStringBuf: int (const struct wbcDomainSid *, char *, int) >+wbcSidToUid: wbcErr (const struct wbcDomainSid *, uid_t *) >+wbcSidTypeString: const char *(enum wbcSidType) >+wbcSidsToUnixIds: wbcErr (const struct wbcDomainSid *, uint32_t, struct wbcUnixId *) >+wbcStrDup: char *(const char *) >+wbcStringToGuid: wbcErr (const char *, struct wbcGuid *) >+wbcStringToSid: wbcErr (const char *, struct wbcDomainSid *) >+wbcUidToSid: wbcErr (uid_t, struct wbcDomainSid *) >diff --git a/nsswitch/libwbclient/wbclient.h b/nsswitch/libwbclient/wbclient.h >index 6aa4e12..adf8fe3 100644 >--- a/nsswitch/libwbclient/wbclient.h >+++ b/nsswitch/libwbclient/wbclient.h >@@ -72,9 +72,10 @@ const char *wbcErrorString(wbcErr error); > * 0.9: Added support for WBC_ID_TYPE_BOTH > * 0.10: Added wbcPingDc2() > * 0.11: Extended wbcAuthenticateUserEx to provide PAC parsing >+ * 0.12: Added wbcCtxCreate and friends > **/ > #define WBCLIENT_MAJOR_VERSION 0 >-#define WBCLIENT_MINOR_VERSION 11 >+#define WBCLIENT_MINOR_VERSION 12 > #define WBCLIENT_VENDOR_VERSION "Samba libwbclient" > struct wbcLibraryDetails { > uint16_t major_version; >diff --git a/nsswitch/libwbclient/wscript b/nsswitch/libwbclient/wscript >index 9c4da16..8602c1c 100644 >--- a/nsswitch/libwbclient/wscript >+++ b/nsswitch/libwbclient/wscript >@@ -3,7 +3,7 @@ > import Options, Logs > > # Remember to also update wbclient.h >-VERSION="0.11" >+VERSION="0.12" > > # It may be useful at some point to allow Samba to build against a > # system libwbclient, such as the one provided by Likewise. To to >-- >1.9.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
vl
:
review+
Actions:
View
Attachments on
bug 11149
: 10862 |
10875