diff options
author | Kai Blin <kai@samba.org> | 2008-11-23 16:36:01 +0100 |
---|---|---|
committer | Karolin Seeger <kseeger@samba.org> | 2008-11-27 15:32:20 +0100 |
commit | b1166f41688b863aacd271609ea46ba9962d66cc (patch) | |
tree | f768c93186a82323e5cc9d1b9856c8e941feecda /source/nsswitch | |
parent | fcba785fde04cd4506ec1a04f8302245d566d807 (diff) | |
download | samba-b1166f41688b863aacd271609ea46ba9962d66cc.tar.gz samba-b1166f41688b863aacd271609ea46ba9962d66cc.tar.xz samba-b1166f41688b863aacd271609ea46ba9962d66cc.zip |
libwbclient: Implement wbcGetpwent
(cherry picked from commit e30448bfbeaebfa5a3225dcc87244d9d0024f082)
Diffstat (limited to 'source/nsswitch')
-rw-r--r-- | source/nsswitch/libwbclient/wbc_pwd.c | 79 |
1 files changed, 77 insertions, 2 deletions
diff --git a/source/nsswitch/libwbclient/wbc_pwd.c b/source/nsswitch/libwbclient/wbc_pwd.c index 70d3f3ce9d1..87908bb5e7f 100644 --- a/source/nsswitch/libwbclient/wbc_pwd.c +++ b/source/nsswitch/libwbclient/wbc_pwd.c @@ -24,6 +24,11 @@ #include "libwbclient.h" +/** @brief The maximum number of pwent structs to get from winbindd + * + */ +#define MAX_GETPWENT_USERS 500 + /** * **/ @@ -284,6 +289,21 @@ wbcErr wbcGetgrgid(gid_t gid, struct group **grp) return wbc_status; } +/** @brief Number of cached passwd structs + * + */ +static uint32_t pw_cache_size; + +/** @brief Position of the pwent context + * + */ +static uint32_t pw_cache_idx; + +/** @brief Winbindd response containing the passwd structs + * + */ +static struct winbindd_response pw_response; + /** @brief Reset the passwd iterator * * @return #wbcErr @@ -293,6 +313,15 @@ wbcErr wbcSetpwent(void) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + if (pw_cache_size > 0) { + pw_cache_idx = pw_cache_size = 0; + if (pw_response.extra_data.data) { + free(pw_response.extra_data.data); + } + } + + ZERO_STRUCT(pw_response); + wbc_status = wbcRequestResponse(WINBINDD_SETPWENT, NULL, NULL); BAIL_ON_WBC_ERROR(wbc_status); @@ -310,6 +339,13 @@ wbcErr wbcEndpwent(void) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + if (pw_cache_size > 0) { + pw_cache_idx = pw_cache_size = 0; + if (pw_response.extra_data.data) { + free(pw_response.extra_data.data); + } + } + wbc_status = wbcRequestResponse(WINBINDD_ENDPWENT, NULL, NULL); BAIL_ON_WBC_ERROR(wbc_status); @@ -320,14 +356,53 @@ wbcErr wbcEndpwent(void) /** @brief Return the next struct passwd* entry from the pwent iterator * - * @param **pwd Pointer to resulting struct group* from the query. + * @param **pwd Pointer to resulting struct passwd* from the query. * * @return #wbcErr **/ wbcErr wbcGetpwent(struct passwd **pwd) { - return WBC_ERR_NOT_IMPLEMENTED; + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + struct winbindd_request request; + struct winbindd_pw *wb_pw; + + /* If there's a cached result, return that. */ + if (pw_cache_idx < pw_cache_size) { + goto return_result; + } + + /* Otherwise, query winbindd for some entries. */ + + pw_cache_idx = 0; + + if (pw_response.extra_data.data) { + free(pw_response.extra_data.data); + ZERO_STRUCT(pw_response); + } + + ZERO_STRUCT(request); + request.data.num_entries = MAX_GETPWENT_USERS; + + wbc_status = wbcRequestResponse(WINBINDD_GETPWENT, &request, + &pw_response); + + BAIL_ON_WBC_ERROR(wbc_status); + + 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]); + + BAIL_ON_PTR_ERROR(*pwd, wbc_status); + + pw_cache_idx++; + +done: + return wbc_status; } /** @brief Reset the group iterator |