s3-winbind: Implemented samr backend function sam_query_user_list.
authorAndreas Schneider <asn@samba.org>
Mon, 7 Jun 2010 14:18:12 +0000 (16:18 +0200)
committerAndreas Schneider <asn@samba.org>
Mon, 5 Jul 2010 13:59:05 +0000 (15:59 +0200)
source3/winbindd/winbindd_samr.c

index 6065f3cfb4d792614aca1c16847af2b9d55647fa..e4faaef1191f899720420ce7ee1af01af4bf1928 100644 (file)
@@ -184,11 +184,127 @@ static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
 /* Query display info for a domain */
 static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
                                    TALLOC_CTX *mem_ctx,
-                                   uint32_t *num_entries,
-                                   struct wbint_userinfo **info)
+                                   uint32_t *pnum_info,
+                                   struct wbint_userinfo **pinfo)
 {
-       /* TODO FIXME */
-       return NT_STATUS_NOT_IMPLEMENTED;
+       struct rpc_pipe_client *samr_pipe = NULL;
+       struct wbint_userinfo *info = NULL;
+       struct policy_handle dom_pol;
+       uint32_t num_info = 0;
+       uint32_t loop_count = 0;
+       uint32_t start_idx = 0;
+       uint32_t i = 0;
+       TALLOC_CTX *tmp_ctx;
+       NTSTATUS status;
+
+       DEBUG(3,("samr: query_user_list\n"));
+
+       if (pnum_info) {
+               *pnum_info = 0;
+       }
+
+       tmp_ctx = talloc_stackframe();
+       if (tmp_ctx == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto error;
+       }
+
+       do {
+               uint32_t j;
+               uint32_t num_dom_users;
+               uint32_t max_entries, max_size;
+               uint32_t total_size, returned_size;
+               union samr_DispInfo disp_info;
+
+               get_query_dispinfo_params(loop_count,
+                                         &max_entries,
+                                         &max_size);
+
+               status = rpccli_samr_QueryDisplayInfo(samr_pipe,
+                                                     tmp_ctx,
+                                                     &dom_pol,
+                                                     1, /* level */
+                                                     start_idx,
+                                                     max_entries,
+                                                     max_size,
+                                                     &total_size,
+                                                     &returned_size,
+                                                     &disp_info);
+               if (!NT_STATUS_IS_OK(status)) {
+                       if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
+                               goto error;
+                       }
+               }
+
+               /* increment required start query values */
+               start_idx += disp_info.info1.count;
+               loop_count++;
+               num_dom_users = disp_info.info1.count;
+
+               num_info += num_dom_users;
+
+               info = TALLOC_REALLOC_ARRAY(tmp_ctx,
+                                           info,
+                                           struct wbint_userinfo,
+                                           num_info);
+               if (info == NULL) {
+                       status = NT_STATUS_NO_MEMORY;
+                       goto error;
+               }
+
+               for (j = 0; j < num_dom_users; i++, j++) {
+                       uint32_t rid = disp_info.info1.entries[j].rid;
+                       struct samr_DispEntryGeneral *src;
+                       struct wbint_userinfo *dst;
+
+                       src = &(disp_info.info1.entries[j]);
+                       dst = &(info[i]);
+
+                       dst->acct_name = talloc_strdup(info,
+                                                      src->account_name.string);
+                       if (dst->acct_name == NULL) {
+                               status = NT_STATUS_NO_MEMORY;
+                               goto error;
+                       }
+
+                       dst->full_name = talloc_strdup(info, src->full_name.string);
+                       if (dst->full_name == NULL) {
+                               status = NT_STATUS_NO_MEMORY;
+                               goto error;
+                       }
+
+                       dst->homedir = NULL;
+                       dst->shell = NULL;
+
+                       sid_compose(&dst->user_sid, &domain->sid, rid);
+
+                       /* For the moment we set the primary group for
+                          every user to be the Domain Users group.
+                          There are serious problems with determining
+                          the actual primary group for large domains.
+                          This should really be made into a 'winbind
+                          force group' smb.conf parameter or
+                          something like that. */
+                       sid_compose(&dst->group_sid, &domain->sid,
+                                   DOMAIN_RID_USERS);
+               }
+       } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
+
+       if (pnum_info) {
+               *pnum_info = num_info;
+       }
+
+       if (pinfo) {
+               *pinfo = talloc_move(mem_ctx, &info);
+       }
+
+error:
+       TALLOC_FREE(tmp_ctx);
+       return status;
 }
 
 /* Lookup user information from a rid or username. */