summaryrefslogtreecommitdiffstats
path: root/source/nsswitch
diff options
context:
space:
mode:
authorKai Blin <kai@samba.org>2008-11-23 16:36:01 +0100
committerKarolin Seeger <kseeger@samba.org>2008-11-27 15:32:20 +0100
commitb1166f41688b863aacd271609ea46ba9962d66cc (patch)
treef768c93186a82323e5cc9d1b9856c8e941feecda /source/nsswitch
parentfcba785fde04cd4506ec1a04f8302245d566d807 (diff)
downloadsamba-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.c79
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