Talloc doc: Fix a cut&paste error
[Samba/gebeck_regimport.git] / source3 / torture / test_chain3.c
blob7b9eeb0b7b38bcac20eaea4201040ae382352ec4
1 /*
2 Unix SMB/CIFS implementation.
3 Test smbd chain routines
5 Copyright (C) Volker Lendecke 2012
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
22 #include "torture/proto.h"
23 #include "libsmb/libsmb.h"
24 #include "system/filesys.h"
25 #include "async_smb.h"
26 #include "lib/util/tevent_ntstatus.h"
27 #include "libcli/security/security.h"
29 struct chain3_andx_state {
30 uint16_t fnum;
31 size_t written;
32 char str[6];
35 static void chain3_andx_open_done(struct tevent_req *subreq);
36 static void chain3_andx_write_done(struct tevent_req *subreq);
37 static void chain3_andx_close_done(struct tevent_req *subreq);
39 static struct tevent_req *chain3_andx_send(TALLOC_CTX *mem_ctx,
40 struct tevent_context *ev,
41 struct cli_state *cli,
42 const char *fname)
44 struct tevent_req *req, *subreq;
45 struct tevent_req *smbreqs[3];
46 struct chain3_andx_state *state;
47 NTSTATUS status;
49 req = tevent_req_create(mem_ctx, &state, struct chain3_andx_state);
50 if (req == NULL) {
51 return NULL;
54 strlcpy(state->str, "hello", sizeof(state->str));
56 subreq = cli_openx_create(state, ev, cli, fname,
57 O_CREAT|O_RDWR, 0, &smbreqs[0]);
58 if (tevent_req_nomem(subreq, req)) {
59 return tevent_req_post(req, ev);
61 tevent_req_set_callback(subreq, chain3_andx_open_done, req);
63 subreq = cli_write_andx_create(state, ev, cli, 0, 0,
64 (const uint8_t *)state->str, 0,
65 strlen(state->str)+1,
66 smbreqs, 1, &smbreqs[1]);
67 if (tevent_req_nomem(subreq, req)) {
68 return tevent_req_post(req, ev);
70 tevent_req_set_callback(subreq, chain3_andx_write_done, req);
72 subreq = cli_close_create(state, ev, cli, 0, &smbreqs[2]);
73 if (tevent_req_nomem(subreq, req)) {
74 return tevent_req_post(req, ev);
76 tevent_req_set_callback(subreq, chain3_andx_close_done, req);
78 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
79 if (tevent_req_nterror(req, status)) {
80 return tevent_req_post(req, ev);
82 return req;
85 static void chain3_andx_open_done(struct tevent_req *subreq)
87 struct tevent_req *req = tevent_req_callback_data(
88 subreq, struct tevent_req);
89 struct chain3_andx_state *state = tevent_req_data(
90 req, struct chain3_andx_state);
91 NTSTATUS status;
93 status = cli_openx_recv(subreq, &state->fnum);
94 printf("cli_openx returned %s, fnum=%u\n", nt_errstr(status),
95 (unsigned)state->fnum);
96 TALLOC_FREE(subreq);
97 if (tevent_req_nterror(req, status)) {
98 return;
102 static void chain3_andx_write_done(struct tevent_req *subreq)
104 struct tevent_req *req = tevent_req_callback_data(
105 subreq, struct tevent_req);
106 struct chain3_andx_state *state = tevent_req_data(
107 req, struct chain3_andx_state);
108 NTSTATUS status;
110 status = cli_write_andx_recv(subreq, &state->written);
111 printf("cli_write_andx returned %s, written=%u\n", nt_errstr(status),
112 (unsigned)state->written);
113 TALLOC_FREE(subreq);
114 if (tevent_req_nterror(req, status)) {
115 return;
119 static void chain3_andx_close_done(struct tevent_req *subreq)
121 struct tevent_req *req = tevent_req_callback_data(
122 subreq, struct tevent_req);
123 NTSTATUS status;
125 status = cli_close_recv(subreq);
126 printf("cli_close returned %s\n", nt_errstr(status));
127 TALLOC_FREE(subreq);
128 if (tevent_req_nterror(req, status)) {
129 return;
131 tevent_req_done(req);
134 static NTSTATUS chain3_andx_recv(struct tevent_req *req)
136 return tevent_req_simple_recv_ntstatus(req);
139 struct chain3_state {
140 struct tevent_context *ev;
141 struct cli_state *cli;
142 const char *fname;
143 uint16_t fnum;
146 static void chain3_got_break(struct tevent_req *subreq);
147 static void chain3_ntcreate_done(struct tevent_req *subreq);
148 static void chain3_break_close_done(struct tevent_req *subreq);
149 static void chain3_andx_done(struct tevent_req *subreq);
151 static struct tevent_req *chain3_send(TALLOC_CTX *mem_ctx,
152 struct tevent_context *ev)
154 struct tevent_req *req, *subreq;
155 struct chain3_state *state;
157 req = tevent_req_create(mem_ctx, &state, struct chain3_state);
158 if (req == NULL) {
159 return NULL;
161 state->ev = ev;
162 state->fname = "chain3.txt";
164 if (!torture_open_connection(&state->cli, 0)) {
165 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
166 return tevent_req_post(req, ev);
169 subreq = cli_smb_oplock_break_waiter_send(
170 state, state->ev, state->cli);
171 if (tevent_req_nomem(subreq, req)) {
172 return tevent_req_post(req, ev);
174 tevent_req_set_callback(subreq, chain3_got_break, req);
176 subreq = cli_ntcreate_send(
177 state, state->ev, state->cli, state->fname,
178 REQUEST_OPLOCK|REQUEST_BATCH_OPLOCK,
179 GENERIC_READ_ACCESS|GENERIC_WRITE_ACCESS,
180 FILE_ATTRIBUTE_NORMAL,
181 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
182 FILE_OVERWRITE_IF, 0, 0);
183 if (tevent_req_nomem(subreq, req)) {
184 return tevent_req_post(req, ev);
186 tevent_req_set_callback(subreq, chain3_ntcreate_done, req);
187 return req;
190 static void chain3_got_break(struct tevent_req *subreq)
192 struct tevent_req *req = tevent_req_callback_data(
193 subreq, struct tevent_req);
194 struct chain3_state *state = tevent_req_data(
195 req, struct chain3_state);
196 uint16_t fnum;
197 uint8_t level;
198 NTSTATUS status;
200 status = cli_smb_oplock_break_waiter_recv(subreq, &fnum, &level);
201 TALLOC_FREE(subreq);
202 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
203 nt_errstr(status));
204 if (tevent_req_nterror(req, status)) {
205 return;
207 subreq = cli_close_send(state, state->ev, state->cli, fnum);
208 if (tevent_req_nomem(subreq, req)) {
209 return;
211 tevent_req_set_callback(subreq, chain3_break_close_done, req);
214 static void chain3_break_close_done(struct tevent_req *subreq)
216 struct tevent_req *req = tevent_req_callback_data(
217 subreq, struct tevent_req);
218 NTSTATUS status;
220 status = cli_close_recv(subreq);
221 TALLOC_FREE(subreq);
222 printf("cli_close_recv returned %s\n", nt_errstr(status));
223 if (tevent_req_nterror(req, status)) {
224 return;
228 static void chain3_ntcreate_done(struct tevent_req *subreq)
230 struct tevent_req *req = tevent_req_callback_data(
231 subreq, struct tevent_req);
232 struct chain3_state *state = tevent_req_data(
233 req, struct chain3_state);
234 NTSTATUS status;
236 status = cli_ntcreate_recv(subreq, &state->fnum);
237 TALLOC_FREE(subreq);
238 printf("cli_ntcreate returned %s, fnum=%u\n", nt_errstr(status),
239 (unsigned)state->fnum);
240 if (tevent_req_nterror(req, status)) {
241 return;
244 subreq = chain3_andx_send(state, state->ev, state->cli, state->fname);
245 if (tevent_req_nomem(subreq, req)) {
246 return;
248 tevent_req_set_callback(subreq, chain3_andx_done, req);
251 static void chain3_andx_done(struct tevent_req *subreq)
253 struct tevent_req *req = tevent_req_callback_data(
254 subreq, struct tevent_req);
255 NTSTATUS status;
257 status = chain3_andx_recv(subreq);
258 TALLOC_FREE(subreq);
259 printf("chain3_andx_recv returned %s\n", nt_errstr(status));
260 if (tevent_req_nterror(req, status)) {
261 return;
263 tevent_req_done(req);
266 static NTSTATUS chain3_recv(struct tevent_req *req)
268 return tevent_req_simple_recv_ntstatus(req);
271 bool run_chain3(int dummy)
273 TALLOC_CTX *frame = talloc_stackframe();
274 struct tevent_context *ev;
275 struct tevent_req *req;
276 NTSTATUS status = NT_STATUS_NO_MEMORY;
278 ev = tevent_context_init(frame);
279 if (ev == NULL) {
280 goto fail;
282 req = chain3_send(frame, ev);
283 if (req == NULL) {
284 goto fail;
286 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
287 goto fail;
289 status = chain3_recv(req);
290 fail:
291 TALLOC_FREE(frame);
292 printf("run_chain3 returns %s\n", nt_errstr(status));
293 return NT_STATUS_IS_OK(status);