From 49dd14678703c9680408039791c28c19c0ddaae7 Mon Sep 17 00:00:00 2001 From: Matthew Newton 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 Reviewed-by: Volker Lendecke Reviewed-by: Jeremy Allison (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 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 Reviewed-by: Volker Lendecke Reviewed-by: Jeremy Allison (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 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 Reviewed-by: Volker Lendecke Reviewed-by: Jeremy Allison (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 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 Reviewed-by: Volker Lendecke Reviewed-by: Jeremy Allison (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 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 Reviewed-by: Volker Lendecke Reviewed-by: Jeremy Allison (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 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 Reviewed-by: Volker Lendecke Reviewed-by: Jeremy Allison (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 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 Reviewed-by: Volker Lendecke Reviewed-by: Jeremy Allison Autobuild-User(master): Jeremy Allison 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