winbind: Avoid a few talloc_tos() in winbindd_cache.c
[Samba.git] / source3 / winbindd / winbindd_show_sequence.c
blob8e53781e5afd92ece96a74a1d58d91954364df6c
1 /*
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/>.
20 #include "includes.h"
21 #include "winbindd.h"
23 struct winbindd_show_sequence_state {
24 bool one_domain;
25 /* One domain */
26 uint32_t seqnum;
28 /* All domains */
29 int num_domains;
30 NTSTATUS *stati;
31 struct winbindd_domain **domains;
32 uint32_t *seqnums;
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_cli_state *cli,
41 struct winbindd_request *request)
43 struct tevent_req *req, *subreq;
44 struct winbindd_show_sequence_state *state;
46 req = tevent_req_create(mem_ctx, &state,
47 struct winbindd_show_sequence_state);
48 if (req == NULL) {
49 return NULL;
51 state->one_domain = false;
52 state->domains = NULL;
53 state->stati = NULL;
54 state->seqnums = NULL;
56 /* Ensure null termination */
57 request->domain_name[sizeof(request->domain_name)-1]='\0';
59 DEBUG(3, ("show_sequence %s\n", request->domain_name));
61 if (request->domain_name[0] != '\0') {
62 struct winbindd_domain *domain;
64 state->one_domain = true;
66 domain = find_domain_from_name_noinit(
67 request->domain_name);
68 if (domain == NULL) {
69 tevent_req_nterror(req, NT_STATUS_NO_SUCH_DOMAIN);
70 return tevent_req_post(req, ev);
73 subreq = wb_seqnum_send(state, ev, domain);
74 if (tevent_req_nomem(subreq, req)) {
75 return tevent_req_post(req, ev);
77 tevent_req_set_callback(
78 subreq, winbindd_show_sequence_done_one, req);
79 return req;
82 subreq = wb_seqnums_send(state, ev);
83 if (tevent_req_nomem(subreq, req)) {
84 return tevent_req_post(req, ev);
86 tevent_req_set_callback(subreq, winbindd_show_sequence_done_all, req);
87 return req;
90 static void winbindd_show_sequence_done_one(struct tevent_req *subreq)
92 struct tevent_req *req = tevent_req_callback_data(
93 subreq, struct tevent_req);
94 struct winbindd_show_sequence_state *state = tevent_req_data(
95 req, struct winbindd_show_sequence_state);
96 NTSTATUS status;
98 status = wb_seqnum_recv(subreq, &state->seqnum);
99 TALLOC_FREE(subreq);
100 if (tevent_req_nterror(req, status)) {
101 return;
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);
112 NTSTATUS status;
114 status = wb_seqnums_recv(subreq, state, &state->num_domains,
115 &state->domains, &state->stati,
116 &state->seqnums);
117 TALLOC_FREE(subreq);
118 if (tevent_req_nterror(req, status)) {
119 return;
121 tevent_req_done(req);
124 NTSTATUS winbindd_show_sequence_recv(struct tevent_req *req,
125 struct winbindd_response *response)
127 struct winbindd_show_sequence_state *state = tevent_req_data(
128 req, struct winbindd_show_sequence_state);
129 NTSTATUS status;
130 char *extra_data;
131 int i;
133 if (tevent_req_is_nterror(req, &status)) {
134 return status;
137 if (state->one_domain) {
138 response->data.sequence_number = state->seqnum;
139 return NT_STATUS_OK;
142 extra_data = talloc_strdup(response, "");
143 if (extra_data == NULL) {
144 return NT_STATUS_NO_MEMORY;
147 for (i=0; i<state->num_domains; i++) {
148 if (!NT_STATUS_IS_OK(state->stati[i])
149 || (state->seqnums[i] == DOM_SEQUENCE_NONE)) {
150 extra_data = talloc_asprintf_append_buffer(
151 extra_data, "%s : DISCONNECTED\n",
152 state->domains[i]->name);
153 } else {
154 extra_data = talloc_asprintf_append_buffer(
155 extra_data, "%s : %d\n",
156 state->domains[i]->name,
157 (int)state->seqnums[i]);
159 if (extra_data == NULL) {
160 return NT_STATUS_NO_MEMORY;
164 response->extra_data.data = extra_data;
165 response->length += talloc_get_size(extra_data);
166 return NT_STATUS_OK;