2 Unix SMB/CIFS implementation.
3 async implementation of WINBINDD_SHOW_SEQUENCE
4 Copyright (C) Volker Lendecke 2009
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.
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.
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/>.
23 struct winbindd_show_sequence_state {
31 struct winbindd_domain **domains;
35 static void winbindd_show_sequence_done_one(struct tevent_req *subreq);
36 static void winbindd_show_sequence_done_all(struct tevent_req *subreq);
38 struct tevent_req *winbindd_show_sequence_send(TALLOC_CTX *mem_ctx,
39 struct tevent_context *ev,
40 struct winbindd_request *request)
42 struct tevent_req *req, *subreq;
43 struct winbindd_show_sequence_state *state;
45 req = tevent_req_create(mem_ctx, &state,
46 struct winbindd_show_sequence_state);
50 state->one_domain = false;
51 state->domains = NULL;
53 state->seqnums = NULL;
55 /* Ensure null termination */
56 request->domain_name[sizeof(request->domain_name)-1]='\0';
58 DEBUG(3, ("show_sequence %s\n", request->domain_name));
60 if (request->domain_name[0] != '\0') {
61 struct winbindd_domain *domain;
63 state->one_domain = true;
65 domain = find_domain_from_name_noinit(
66 request->domain_name);
68 tevent_req_nterror(req, NT_STATUS_NO_SUCH_DOMAIN);
69 return tevent_req_post(req, ev);
72 subreq = wb_seqnum_send(state, ev, domain);
73 if (tevent_req_nomem(subreq, req)) {
74 return tevent_req_post(req, ev);
76 tevent_req_set_callback(
77 subreq, winbindd_show_sequence_done_one, req);
81 subreq = wb_seqnums_send(state, ev);
82 if (tevent_req_nomem(subreq, req)) {
83 return tevent_req_post(req, ev);
85 tevent_req_set_callback(subreq, winbindd_show_sequence_done_all, req);
89 static void winbindd_show_sequence_done_one(struct tevent_req *subreq)
91 struct tevent_req *req = tevent_req_callback_data(
92 subreq, struct tevent_req);
93 struct winbindd_show_sequence_state *state = tevent_req_data(
94 req, struct winbindd_show_sequence_state);
97 status = wb_seqnum_recv(subreq, &state->seqnum);
99 if (!NT_STATUS_IS_OK(status)) {
100 tevent_req_nterror(req, status);
103 tevent_req_done(req);
106 static void winbindd_show_sequence_done_all(struct tevent_req *subreq)
108 struct tevent_req *req = tevent_req_callback_data(
109 subreq, struct tevent_req);
110 struct winbindd_show_sequence_state *state = tevent_req_data(
111 req, struct winbindd_show_sequence_state);
114 status = wb_seqnums_recv(subreq, state, &state->num_domains,
115 &state->domains, &state->stati,
118 if (!NT_STATUS_IS_OK(status)) {
119 tevent_req_nterror(req, status);
122 tevent_req_done(req);
125 NTSTATUS winbindd_show_sequence_recv(struct tevent_req *req,
126 struct winbindd_response *response)
128 struct winbindd_show_sequence_state *state = tevent_req_data(
129 req, struct winbindd_show_sequence_state);
134 if (tevent_req_is_nterror(req, &status)) {
138 if (state->one_domain) {
139 response->data.sequence_number = state->seqnum;
143 extra_data = talloc_strdup(response, "");
144 if (extra_data == NULL) {
145 return NT_STATUS_NO_MEMORY;
148 for (i=0; i<state->num_domains; i++) {
149 if (!NT_STATUS_IS_OK(state->stati[i])
150 || (state->seqnums[i] == DOM_SEQUENCE_NONE)) {
151 extra_data = talloc_asprintf_append_buffer(
152 extra_data, "%s : DISCONNECTED\n",
153 state->domains[i]->name);
155 extra_data = talloc_asprintf_append_buffer(
156 extra_data, "%s : %d\n",
157 state->domains[i]->name,
158 (int)state->seqnums[i]);
160 if (extra_data == NULL) {
161 return NT_STATUS_NO_MEMORY;
165 response->extra_data.data = extra_data;
166 response->length += talloc_get_size(extra_data);