LCOV - code coverage report
Current view: top level - source3/winbindd - wb_next_pwent.c (source / functions) Hit Total Coverage
Test: coverage report for support-claim-type-attributes 6b5c566e Lines: 53 68 77.9 %
Date: 2023-11-21 12:31:41 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    async next_pwent
       4             :    Copyright (C) Volker Lendecke 2009
       5             : 
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             : 
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : #include "includes.h"
      21             : #include "winbindd.h"
      22             : #include "librpc/gen_ndr/ndr_winbind_c.h"
      23             : #include "libcli/security/dom_sid.h"
      24             : #include "passdb/machine_sid.h"
      25             : 
      26             : struct wb_next_pwent_state {
      27             :         struct tevent_context *ev;
      28             :         struct getpwent_state *gstate;
      29             :         struct dom_sid next_sid;
      30             :         struct winbindd_pw *pw;
      31             : };
      32             : 
      33             : static void wb_next_pwent_fetch_done(struct tevent_req *subreq);
      34             : static void wb_next_pwent_fill_done(struct tevent_req *subreq);
      35             : 
      36        1852 : static void wb_next_pwent_send_do(struct tevent_req *req,
      37             :                                   struct wb_next_pwent_state *state)
      38             : {
      39           0 :         struct tevent_req *subreq;
      40           0 :         struct dom_sid_buf buf, buf1;
      41             : 
      42        1852 :         if (state->gstate->next_user >= state->gstate->rids.num_rids) {
      43         108 :                 TALLOC_FREE(state->gstate->rids.rids);
      44         108 :                 state->gstate->rids.num_rids = 0;
      45             : 
      46         108 :                 state->gstate->domain = wb_next_domain(state->gstate->domain);
      47         108 :                 if (state->gstate->domain == NULL) {
      48          30 :                         tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES);
      49          30 :                         return;
      50             :                 }
      51             : 
      52          78 :                 D_DEBUG("Query user RID list for domain %s.\n",
      53             :                         state->gstate->domain->name);
      54          78 :                 subreq = dcerpc_wbint_QueryUserRidList_send(
      55             :                         state, state->ev,
      56          78 :                         dom_child_handle(state->gstate->domain),
      57          78 :                         &state->gstate->rids);
      58          78 :                 if (tevent_req_nomem(subreq, req)) {
      59           0 :                         return;
      60             :                 }
      61             : 
      62          78 :                 tevent_req_set_callback(subreq, wb_next_pwent_fetch_done, req);
      63          78 :                 return;
      64             :         }
      65             : 
      66        1744 :         sid_compose(&state->next_sid, &state->gstate->domain->sid,
      67        1744 :                     state->gstate->rids.rids[state->gstate->next_user]);
      68             : 
      69        1744 :         D_DEBUG("Get pw for SID %s composed from domain SID %s and RID %"PRIu32".\n",
      70             :                 dom_sid_str_buf(&state->next_sid, &buf),
      71             :                 dom_sid_str_buf(&state->gstate->domain->sid, &buf1),
      72             :                 state->gstate->rids.rids[state->gstate->next_user]);
      73        1744 :         subreq = wb_getpwsid_send(state, state->ev, &state->next_sid,
      74             :                                   state->pw);
      75        1744 :         if (tevent_req_nomem(subreq, req)) {
      76           0 :                 return;
      77             :         }
      78             : 
      79        1744 :         tevent_req_set_callback(subreq, wb_next_pwent_fill_done, req);
      80             : }
      81             : 
      82        1774 : struct tevent_req *wb_next_pwent_send(TALLOC_CTX *mem_ctx,
      83             :                                       struct tevent_context *ev,
      84             :                                       struct getpwent_state *gstate,
      85             :                                       struct winbindd_pw *pw)
      86             : {
      87           0 :         struct tevent_req *req;
      88           0 :         struct wb_next_pwent_state *state;
      89             : 
      90        1774 :         req = tevent_req_create(mem_ctx, &state, struct wb_next_pwent_state);
      91        1774 :         if (req == NULL) {
      92           0 :                 return NULL;
      93             :         }
      94        1774 :         D_INFO("WB command next_pwent start.\n");
      95        1774 :         state->ev = ev;
      96        1774 :         state->gstate = gstate;
      97        1774 :         state->pw = pw;
      98             : 
      99        1774 :         wb_next_pwent_send_do(req, state);
     100        1774 :         if (!tevent_req_is_in_progress(req)) {
     101          10 :                 return tevent_req_post(req, ev);
     102             :         }
     103             : 
     104        1764 :         return req;
     105             : }
     106             : 
     107          78 : static void wb_next_pwent_fetch_done(struct tevent_req *subreq)
     108             : {
     109          78 :         struct tevent_req *req = tevent_req_callback_data(
     110             :                 subreq, struct tevent_req);
     111          78 :         struct wb_next_pwent_state *state = tevent_req_data(
     112             :                 req, struct wb_next_pwent_state);
     113           0 :         NTSTATUS status, result;
     114             : 
     115          78 :         status = dcerpc_wbint_QueryUserRidList_recv(subreq, state->gstate,
     116             :                                                     &result);
     117          78 :         TALLOC_FREE(subreq);
     118          78 :         if (any_nt_status_not_ok(status, result, &status)) {
     119             :                 /* Ignore errors here, just log it */
     120           0 :                 D_DEBUG("query_user_list for domain %s returned %s\n",
     121             :                            state->gstate->domain->name,
     122             :                            nt_errstr(status));
     123           0 :                 state->gstate->rids.num_rids = 0;
     124             :         }
     125             : 
     126          78 :         state->gstate->next_user = 0;
     127             : 
     128          78 :         wb_next_pwent_send_do(req, state);
     129          78 : }
     130             : 
     131        1744 : static void wb_next_pwent_fill_done(struct tevent_req *subreq)
     132             : {
     133        1744 :         struct tevent_req *req = tevent_req_callback_data(
     134             :                 subreq, struct tevent_req);
     135        1744 :         struct wb_next_pwent_state *state = tevent_req_data(
     136             :                 req, struct wb_next_pwent_state);
     137           0 :         NTSTATUS status;
     138             : 
     139        1744 :         status = wb_getpwsid_recv(subreq);
     140        1744 :         TALLOC_FREE(subreq);
     141             :         /*
     142             :          * When you try to enumerate users with 'getent passwd' and the user
     143             :          * doesn't have a uid set we should just move on.
     144             :          */
     145        1744 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
     146           0 :                 state->gstate->next_user += 1;
     147             : 
     148           0 :                 wb_next_pwent_send_do(req, state);
     149             : 
     150           0 :                 return;
     151        1744 :         } else if (tevent_req_nterror(req, status)) {
     152           0 :                 return;
     153             :         }
     154        1744 :         state->gstate->next_user += 1;
     155        1744 :         tevent_req_done(req);
     156             : }
     157             : 
     158        1774 : NTSTATUS wb_next_pwent_recv(struct tevent_req *req)
     159             : {
     160        1774 :         D_INFO("WB command next_pwent end.\n");
     161        1774 :         return tevent_req_simple_recv_ntstatus(req);
     162             : }

Generated by: LCOV version 1.14