• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt/router/samba-3.5.8/source3/winbindd/
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/cli_wbint.h"
23
24struct wb_next_pwent_state {
25	struct tevent_context *ev;
26	struct getpwent_state *gstate;
27	struct winbindd_pw *pw;
28};
29
30static void wb_next_pwent_fetch_done(struct tevent_req *subreq);
31static void wb_next_pwent_fill_done(struct tevent_req *subreq);
32
33struct tevent_req *wb_next_pwent_send(TALLOC_CTX *mem_ctx,
34				      struct tevent_context *ev,
35				      struct getpwent_state *gstate,
36				      struct winbindd_pw *pw)
37{
38	struct tevent_req *req, *subreq;
39	struct wb_next_pwent_state *state;
40
41	req = tevent_req_create(mem_ctx, &state, struct wb_next_pwent_state);
42	if (req == NULL) {
43		return NULL;
44	}
45	state->ev = ev;
46	state->gstate = gstate;
47	state->pw = pw;
48
49	if (state->gstate->next_user >= state->gstate->num_users) {
50		TALLOC_FREE(state->gstate->users);
51
52		if (state->gstate->domain == NULL) {
53			state->gstate->domain = domain_list();
54		} else {
55			state->gstate->domain = state->gstate->domain->next;
56		}
57
58		if ((state->gstate->domain != NULL)
59		    && sid_check_is_domain(&state->gstate->domain->sid)) {
60			state->gstate->domain = state->gstate->domain->next;
61		}
62
63		if (state->gstate->domain == NULL) {
64			tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES);
65			return tevent_req_post(req, ev);
66		}
67		subreq = wb_query_user_list_send(state, state->ev,
68						 state->gstate->domain);
69		if (tevent_req_nomem(subreq, req)) {
70			return tevent_req_post(req, ev);
71		}
72		tevent_req_set_callback(subreq, wb_next_pwent_fetch_done, req);
73		return req;
74	}
75
76	subreq = wb_fill_pwent_send(
77		state, state->ev,
78		&state->gstate->users[state->gstate->next_user],
79		state->pw);
80	if (tevent_req_nomem(subreq, req)) {
81		return tevent_req_post(req, ev);
82	}
83	tevent_req_set_callback(subreq, wb_next_pwent_fill_done, req);
84	return req;
85}
86
87static void wb_next_pwent_fetch_done(struct tevent_req *subreq)
88{
89	struct tevent_req *req = tevent_req_callback_data(
90		subreq, struct tevent_req);
91	struct wb_next_pwent_state *state = tevent_req_data(
92		req, struct wb_next_pwent_state);
93	NTSTATUS status;
94
95	status = wb_query_user_list_recv(subreq, state->gstate,
96					 &state->gstate->num_users,
97					 &state->gstate->users);
98	TALLOC_FREE(subreq);
99	if (!NT_STATUS_IS_OK(status)) {
100		/* Ignore errors here, just log it */
101		DEBUG(10, ("query_user_list for domain %s returned %s\n",
102			   state->gstate->domain->name,
103			   nt_errstr(status)));
104		state->gstate->num_users = 0;
105	}
106
107	if (state->gstate->num_users == 0) {
108		state->gstate->domain = state->gstate->domain->next;
109
110		if ((state->gstate->domain != NULL)
111		    && sid_check_is_domain(&state->gstate->domain->sid)) {
112			state->gstate->domain = state->gstate->domain->next;
113		}
114
115		if (state->gstate->domain == NULL) {
116			tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES);
117			return;
118		}
119		subreq = wb_query_user_list_send(state, state->ev,
120						 state->gstate->domain);
121		if (tevent_req_nomem(subreq, req)) {
122			return;
123		}
124		tevent_req_set_callback(subreq, wb_next_pwent_fetch_done, req);
125		return;
126	}
127
128	state->gstate->next_user = 0;
129
130	subreq = wb_fill_pwent_send(
131		state, state->ev,
132		&state->gstate->users[state->gstate->next_user],
133		state->pw);
134	if (tevent_req_nomem(subreq, req)) {
135		return;
136	}
137	tevent_req_set_callback(subreq, wb_next_pwent_fill_done, req);
138}
139
140static void wb_next_pwent_fill_done(struct tevent_req *subreq)
141{
142	struct tevent_req *req = tevent_req_callback_data(
143		subreq, struct tevent_req);
144	struct wb_next_pwent_state *state = tevent_req_data(
145		req, struct wb_next_pwent_state);
146	NTSTATUS status;
147
148	status = wb_fill_pwent_recv(subreq);
149	TALLOC_FREE(subreq);
150	if (!NT_STATUS_IS_OK(status)) {
151		tevent_req_nterror(req, status);
152		return;
153	}
154	state->gstate->next_user += 1;
155	tevent_req_done(req);
156}
157
158NTSTATUS wb_next_pwent_recv(struct tevent_req *req)
159{
160	return tevent_req_simple_recv_ntstatus(req);
161}
162