source: branches/samba-3.5.x/source4/libcli/smb_composite/smb2.c

Last change on this file was 414, checked in by Herwig Bauernfeind, 15 years ago

Samba 3.5.0: Initial import

File size: 9.8 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3
4 Copyright (C) Andrew Tridgell 2008
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 a composite API for making SMB-like calls using SMB2. This is useful
21 as SMB2 often requires more than one requests where a single SMB
22 request would do. In converting code that uses SMB to use SMB2,
23 these routines make life a lot easier
24*/
25
26
27#include "includes.h"
28#include "libcli/raw/libcliraw.h"
29#include "libcli/raw/raw_proto.h"
30#include "libcli/composite/composite.h"
31#include "libcli/smb_composite/smb_composite.h"
32#include "libcli/smb2/smb2_calls.h"
33
34/*
35 continue after a SMB2 close
36 */
37static void continue_close(struct smb2_request *req)
38{
39 struct composite_context *ctx = talloc_get_type(req->async.private_data,
40 struct composite_context);
41 NTSTATUS status;
42 struct smb2_close close_parm;
43
44 status = smb2_close_recv(req, &close_parm);
45 composite_error(ctx, status);
46}
47
48/*
49 continue after the create in a composite unlink
50 */
51static void continue_unlink(struct smb2_request *req)
52{
53 struct composite_context *ctx = talloc_get_type(req->async.private_data,
54 struct composite_context);
55 struct smb2_tree *tree = req->tree;
56 struct smb2_create create_parm;
57 struct smb2_close close_parm;
58 NTSTATUS status;
59
60 status = smb2_create_recv(req, ctx, &create_parm);
61 if (!NT_STATUS_IS_OK(status)) {
62 composite_error(ctx, status);
63 return;
64 }
65
66 ZERO_STRUCT(close_parm);
67 close_parm.in.file.handle = create_parm.out.file.handle;
68
69 req = smb2_close_send(tree, &close_parm);
70 composite_continue_smb2(ctx, req, continue_close, ctx);
71}
72
73/*
74 composite SMB2 unlink call
75*/
76struct composite_context *smb2_composite_unlink_send(struct smb2_tree *tree,
77 union smb_unlink *io)
78{
79 struct composite_context *ctx;
80 struct smb2_create create_parm;
81 struct smb2_request *req;
82
83 ctx = composite_create(tree, tree->session->transport->socket->event.ctx);
84 if (ctx == NULL) return NULL;
85
86 /* check for wildcards - we could support these with a
87 search, but for now they aren't necessary */
88 if (strpbrk(io->unlink.in.pattern, "*?<>") != NULL) {
89 composite_error(ctx, NT_STATUS_NOT_SUPPORTED);
90 return ctx;
91 }
92
93 ZERO_STRUCT(create_parm);
94 create_parm.in.desired_access = SEC_STD_DELETE;
95 create_parm.in.create_disposition = NTCREATEX_DISP_OPEN;
96 create_parm.in.share_access =
97 NTCREATEX_SHARE_ACCESS_DELETE|
98 NTCREATEX_SHARE_ACCESS_READ|
99 NTCREATEX_SHARE_ACCESS_WRITE;
100 create_parm.in.create_options =
101 NTCREATEX_OPTIONS_DELETE_ON_CLOSE |
102 NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
103 create_parm.in.fname = io->unlink.in.pattern;
104 if (create_parm.in.fname[0] == '\\') {
105 create_parm.in.fname++;
106 }
107
108 req = smb2_create_send(tree, &create_parm);
109
110 composite_continue_smb2(ctx, req, continue_unlink, ctx);
111 return ctx;
112}
113
114
115/*
116 composite unlink call - sync interface
117*/
118NTSTATUS smb2_composite_unlink(struct smb2_tree *tree, union smb_unlink *io)
119{
120 struct composite_context *c = smb2_composite_unlink_send(tree, io);
121 return composite_wait_free(c);
122}
123
124
125
126
127/*
128 continue after the create in a composite mkdir
129 */
130static void continue_mkdir(struct smb2_request *req)
131{
132 struct composite_context *ctx = talloc_get_type(req->async.private_data,
133 struct composite_context);
134 struct smb2_tree *tree = req->tree;
135 struct smb2_create create_parm;
136 struct smb2_close close_parm;
137 NTSTATUS status;
138
139 status = smb2_create_recv(req, ctx, &create_parm);
140 if (!NT_STATUS_IS_OK(status)) {
141 composite_error(ctx, status);
142 return;
143 }
144
145 ZERO_STRUCT(close_parm);
146 close_parm.in.file.handle = create_parm.out.file.handle;
147
148 req = smb2_close_send(tree, &close_parm);
149 composite_continue_smb2(ctx, req, continue_close, ctx);
150}
151
152/*
153 composite SMB2 mkdir call
154*/
155struct composite_context *smb2_composite_mkdir_send(struct smb2_tree *tree,
156 union smb_mkdir *io)
157{
158 struct composite_context *ctx;
159 struct smb2_create create_parm;
160 struct smb2_request *req;
161
162 ctx = composite_create(tree, tree->session->transport->socket->event.ctx);
163 if (ctx == NULL) return NULL;
164
165 ZERO_STRUCT(create_parm);
166
167 create_parm.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
168 create_parm.in.share_access =
169 NTCREATEX_SHARE_ACCESS_READ|
170 NTCREATEX_SHARE_ACCESS_WRITE;
171 create_parm.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
172 create_parm.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
173 create_parm.in.create_disposition = NTCREATEX_DISP_CREATE;
174 create_parm.in.fname = io->mkdir.in.path;
175 if (create_parm.in.fname[0] == '\\') {
176 create_parm.in.fname++;
177 }
178
179 req = smb2_create_send(tree, &create_parm);
180
181 composite_continue_smb2(ctx, req, continue_mkdir, ctx);
182
183 return ctx;
184}
185
186
187/*
188 composite mkdir call - sync interface
189*/
190NTSTATUS smb2_composite_mkdir(struct smb2_tree *tree, union smb_mkdir *io)
191{
192 struct composite_context *c = smb2_composite_mkdir_send(tree, io);
193 return composite_wait_free(c);
194}
195
196
197
198/*
199 continue after the create in a composite rmdir
200 */
201static void continue_rmdir(struct smb2_request *req)
202{
203 struct composite_context *ctx = talloc_get_type(req->async.private_data,
204 struct composite_context);
205 struct smb2_tree *tree = req->tree;
206 struct smb2_create create_parm;
207 struct smb2_close close_parm;
208 NTSTATUS status;
209
210 status = smb2_create_recv(req, ctx, &create_parm);
211 if (!NT_STATUS_IS_OK(status)) {
212 composite_error(ctx, status);
213 return;
214 }
215
216 ZERO_STRUCT(close_parm);
217 close_parm.in.file.handle = create_parm.out.file.handle;
218
219 req = smb2_close_send(tree, &close_parm);
220 composite_continue_smb2(ctx, req, continue_close, ctx);
221}
222
223/*
224 composite SMB2 rmdir call
225*/
226struct composite_context *smb2_composite_rmdir_send(struct smb2_tree *tree,
227 struct smb_rmdir *io)
228{
229 struct composite_context *ctx;
230 struct smb2_create create_parm;
231 struct smb2_request *req;
232
233 ctx = composite_create(tree, tree->session->transport->socket->event.ctx);
234 if (ctx == NULL) return NULL;
235
236 ZERO_STRUCT(create_parm);
237 create_parm.in.desired_access = SEC_STD_DELETE;
238 create_parm.in.create_disposition = NTCREATEX_DISP_OPEN;
239 create_parm.in.share_access =
240 NTCREATEX_SHARE_ACCESS_DELETE|
241 NTCREATEX_SHARE_ACCESS_READ|
242 NTCREATEX_SHARE_ACCESS_WRITE;
243 create_parm.in.create_options =
244 NTCREATEX_OPTIONS_DIRECTORY |
245 NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
246 create_parm.in.fname = io->in.path;
247 if (create_parm.in.fname[0] == '\\') {
248 create_parm.in.fname++;
249 }
250
251 req = smb2_create_send(tree, &create_parm);
252
253 composite_continue_smb2(ctx, req, continue_rmdir, ctx);
254 return ctx;
255}
256
257
258/*
259 composite rmdir call - sync interface
260*/
261NTSTATUS smb2_composite_rmdir(struct smb2_tree *tree, struct smb_rmdir *io)
262{
263 struct composite_context *c = smb2_composite_rmdir_send(tree, io);
264 return composite_wait_free(c);
265}
266
267
268/*
269 continue after the setfileinfo in a composite setpathinfo
270 */
271static void continue_setpathinfo_close(struct smb2_request *req)
272{
273 struct composite_context *ctx = talloc_get_type(req->async.private_data,
274 struct composite_context);
275 struct smb2_tree *tree = req->tree;
276 struct smb2_close close_parm;
277 NTSTATUS status;
278 union smb_setfileinfo *io2 = talloc_get_type(ctx->private_data,
279 union smb_setfileinfo);
280
281 status = smb2_setinfo_recv(req);
282 if (!NT_STATUS_IS_OK(status)) {
283 composite_error(ctx, status);
284 return;
285 }
286
287 ZERO_STRUCT(close_parm);
288 close_parm.in.file.handle = io2->generic.in.file.handle;
289
290 req = smb2_close_send(tree, &close_parm);
291 composite_continue_smb2(ctx, req, continue_close, ctx);
292}
293
294
295/*
296 continue after the create in a composite setpathinfo
297 */
298static void continue_setpathinfo(struct smb2_request *req)
299{
300 struct composite_context *ctx = talloc_get_type(req->async.private_data,
301 struct composite_context);
302 struct smb2_tree *tree = req->tree;
303 struct smb2_create create_parm;
304 NTSTATUS status;
305 union smb_setfileinfo *io2 = talloc_get_type(ctx->private_data,
306 union smb_setfileinfo);
307
308 status = smb2_create_recv(req, ctx, &create_parm);
309 if (!NT_STATUS_IS_OK(status)) {
310 composite_error(ctx, status);
311 return;
312 }
313
314 io2->generic.in.file.handle = create_parm.out.file.handle;
315
316 req = smb2_setinfo_file_send(tree, io2);
317 composite_continue_smb2(ctx, req, continue_setpathinfo_close, ctx);
318}
319
320
321/*
322 composite SMB2 setpathinfo call
323*/
324struct composite_context *smb2_composite_setpathinfo_send(struct smb2_tree *tree,
325 union smb_setfileinfo *io)
326{
327 struct composite_context *ctx;
328 struct smb2_create create_parm;
329 struct smb2_request *req;
330 union smb_setfileinfo *io2;
331
332 ctx = composite_create(tree, tree->session->transport->socket->event.ctx);
333 if (ctx == NULL) return NULL;
334
335 ZERO_STRUCT(create_parm);
336 create_parm.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
337 create_parm.in.create_disposition = NTCREATEX_DISP_OPEN;
338 create_parm.in.share_access =
339 NTCREATEX_SHARE_ACCESS_DELETE|
340 NTCREATEX_SHARE_ACCESS_READ|
341 NTCREATEX_SHARE_ACCESS_WRITE;
342 create_parm.in.create_options = 0;
343 create_parm.in.fname = io->generic.in.file.path;
344 if (create_parm.in.fname[0] == '\\') {
345 create_parm.in.fname++;
346 }
347
348 req = smb2_create_send(tree, &create_parm);
349
350 io2 = talloc(ctx, union smb_setfileinfo);
351 if (composite_nomem(io2, ctx)) {
352 return ctx;
353 }
354 *io2 = *io;
355
356 ctx->private_data = io2;
357
358 composite_continue_smb2(ctx, req, continue_setpathinfo, ctx);
359 return ctx;
360}
361
362
363/*
364 composite setpathinfo call
365 */
366NTSTATUS smb2_composite_setpathinfo(struct smb2_tree *tree, union smb_setfileinfo *io)
367{
368 struct composite_context *c = smb2_composite_setpathinfo_send(tree, io);
369 return composite_wait_free(c);
370}
Note: See TracBrowser for help on using the repository browser.