source: trunk/server/source3/winbindd/winbindd_show_sequence.c

Last change on this file was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

File size: 4.6 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 async implementation of WINBINDD_SHOW_SEQUENCE
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
23struct winbindd_show_sequence_state {
24 bool one_domain;
25 /* One domain */
26 uint32_t seqnum;
27
28 /* All domains */
29 int num_domains;
30 NTSTATUS *stati;
31 struct winbindd_domain **domains;
32 uint32_t *seqnums;
33};
34
35static void winbindd_show_sequence_done_one(struct tevent_req *subreq);
36static void winbindd_show_sequence_done_all(struct tevent_req *subreq);
37
38struct 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)
42{
43 struct tevent_req *req, *subreq;
44 struct winbindd_show_sequence_state *state;
45
46 req = tevent_req_create(mem_ctx, &state,
47 struct winbindd_show_sequence_state);
48 if (req == NULL) {
49 return NULL;
50 }
51 state->one_domain = false;
52 state->domains = NULL;
53 state->stati = NULL;
54 state->seqnums = NULL;
55
56 /* Ensure null termination */
57 request->domain_name[sizeof(request->domain_name)-1]='\0';
58
59 DEBUG(3, ("show_sequence %s\n", request->domain_name));
60
61 if (request->domain_name[0] != '\0') {
62 struct winbindd_domain *domain;
63
64 state->one_domain = true;
65
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);
71 }
72
73 subreq = wb_seqnum_send(state, ev, domain);
74 if (tevent_req_nomem(subreq, req)) {
75 return tevent_req_post(req, ev);
76 }
77 tevent_req_set_callback(
78 subreq, winbindd_show_sequence_done_one, req);
79 return req;
80 }
81
82 subreq = wb_seqnums_send(state, ev);
83 if (tevent_req_nomem(subreq, req)) {
84 return tevent_req_post(req, ev);
85 }
86 tevent_req_set_callback(subreq, winbindd_show_sequence_done_all, req);
87 return req;
88}
89
90static void winbindd_show_sequence_done_one(struct tevent_req *subreq)
91{
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;
97
98 status = wb_seqnum_recv(subreq, &state->seqnum);
99 TALLOC_FREE(subreq);
100 if (tevent_req_nterror(req, status)) {
101 return;
102 }
103 tevent_req_done(req);
104}
105
106static void winbindd_show_sequence_done_all(struct tevent_req *subreq)
107{
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;
113
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;
120 }
121 tevent_req_done(req);
122}
123
124NTSTATUS winbindd_show_sequence_recv(struct tevent_req *req,
125 struct winbindd_response *response)
126{
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;
132
133 if (tevent_req_is_nterror(req, &status)) {
134 return status;
135 }
136
137 if (state->one_domain) {
138 response->data.sequence_number = state->seqnum;
139 return NT_STATUS_OK;
140 }
141
142 extra_data = talloc_strdup(response, "");
143 if (extra_data == NULL) {
144 return NT_STATUS_NO_MEMORY;
145 }
146
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]);
158 }
159 if (extra_data == NULL) {
160 return NT_STATUS_NO_MEMORY;
161 }
162 }
163
164 response->extra_data.data = extra_data;
165 response->length += talloc_get_size(extra_data);
166 return NT_STATUS_OK;
167}
Note: See TracBrowser for help on using the repository browser.