s3:release-scripts: fix create-tarball to treat vendor patch level correctly
[Samba.git] / source4 / libcli / smb_composite / smb2.c
blobd71708a974ef0975304b312cb4490d1c127895eb
1 /*
2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 2008
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 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
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"
35 continue after a SMB2 close
37 static void continue_close(struct smb2_request *req)
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;
44 status = smb2_close_recv(req, &close_parm);
45 composite_error(ctx, status);
49 continue after the create in a composite unlink
51 static void continue_unlink(struct smb2_request *req)
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;
60 status = smb2_create_recv(req, ctx, &create_parm);
61 if (!NT_STATUS_IS_OK(status)) {
62 composite_error(ctx, status);
63 return;
66 ZERO_STRUCT(close_parm);
67 close_parm.in.file.handle = create_parm.out.file.handle;
69 req = smb2_close_send(tree, &close_parm);
70 composite_continue_smb2(ctx, req, continue_close, ctx);
74 composite SMB2 unlink call
76 struct composite_context *smb2_composite_unlink_send(struct smb2_tree *tree,
77 union smb_unlink *io)
79 struct composite_context *ctx;
80 struct smb2_create create_parm;
81 struct smb2_request *req;
83 ctx = composite_create(tree, tree->session->transport->socket->event.ctx);
84 if (ctx == NULL) return NULL;
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;
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++;
108 req = smb2_create_send(tree, &create_parm);
110 composite_continue_smb2(ctx, req, continue_unlink, ctx);
111 return ctx;
116 composite unlink call - sync interface
118 NTSTATUS smb2_composite_unlink(struct smb2_tree *tree, union smb_unlink *io)
120 struct composite_context *c = smb2_composite_unlink_send(tree, io);
121 return composite_wait_free(c);
128 continue after the create in a composite mkdir
130 static void continue_mkdir(struct smb2_request *req)
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;
139 status = smb2_create_recv(req, ctx, &create_parm);
140 if (!NT_STATUS_IS_OK(status)) {
141 composite_error(ctx, status);
142 return;
145 ZERO_STRUCT(close_parm);
146 close_parm.in.file.handle = create_parm.out.file.handle;
148 req = smb2_close_send(tree, &close_parm);
149 composite_continue_smb2(ctx, req, continue_close, ctx);
153 composite SMB2 mkdir call
155 struct composite_context *smb2_composite_mkdir_send(struct smb2_tree *tree,
156 union smb_mkdir *io)
158 struct composite_context *ctx;
159 struct smb2_create create_parm;
160 struct smb2_request *req;
162 ctx = composite_create(tree, tree->session->transport->socket->event.ctx);
163 if (ctx == NULL) return NULL;
165 ZERO_STRUCT(create_parm);
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++;
179 req = smb2_create_send(tree, &create_parm);
181 composite_continue_smb2(ctx, req, continue_mkdir, ctx);
183 return ctx;
188 composite mkdir call - sync interface
190 NTSTATUS smb2_composite_mkdir(struct smb2_tree *tree, union smb_mkdir *io)
192 struct composite_context *c = smb2_composite_mkdir_send(tree, io);
193 return composite_wait_free(c);
199 continue after the create in a composite rmdir
201 static void continue_rmdir(struct smb2_request *req)
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;
210 status = smb2_create_recv(req, ctx, &create_parm);
211 if (!NT_STATUS_IS_OK(status)) {
212 composite_error(ctx, status);
213 return;
216 ZERO_STRUCT(close_parm);
217 close_parm.in.file.handle = create_parm.out.file.handle;
219 req = smb2_close_send(tree, &close_parm);
220 composite_continue_smb2(ctx, req, continue_close, ctx);
224 composite SMB2 rmdir call
226 struct composite_context *smb2_composite_rmdir_send(struct smb2_tree *tree,
227 struct smb_rmdir *io)
229 struct composite_context *ctx;
230 struct smb2_create create_parm;
231 struct smb2_request *req;
233 ctx = composite_create(tree, tree->session->transport->socket->event.ctx);
234 if (ctx == NULL) return NULL;
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++;
251 req = smb2_create_send(tree, &create_parm);
253 composite_continue_smb2(ctx, req, continue_rmdir, ctx);
254 return ctx;
259 composite rmdir call - sync interface
261 NTSTATUS smb2_composite_rmdir(struct smb2_tree *tree, struct smb_rmdir *io)
263 struct composite_context *c = smb2_composite_rmdir_send(tree, io);
264 return composite_wait_free(c);
269 continue after the setfileinfo in a composite setpathinfo
271 static void continue_setpathinfo_close(struct smb2_request *req)
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);
281 status = smb2_setinfo_recv(req);
282 if (!NT_STATUS_IS_OK(status)) {
283 composite_error(ctx, status);
284 return;
287 ZERO_STRUCT(close_parm);
288 close_parm.in.file.handle = io2->generic.in.file.handle;
290 req = smb2_close_send(tree, &close_parm);
291 composite_continue_smb2(ctx, req, continue_close, ctx);
296 continue after the create in a composite setpathinfo
298 static void continue_setpathinfo(struct smb2_request *req)
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);
308 status = smb2_create_recv(req, ctx, &create_parm);
309 if (!NT_STATUS_IS_OK(status)) {
310 composite_error(ctx, status);
311 return;
314 io2->generic.in.file.handle = create_parm.out.file.handle;
316 req = smb2_setinfo_file_send(tree, io2);
317 composite_continue_smb2(ctx, req, continue_setpathinfo_close, ctx);
322 composite SMB2 setpathinfo call
324 struct composite_context *smb2_composite_setpathinfo_send(struct smb2_tree *tree,
325 union smb_setfileinfo *io)
327 struct composite_context *ctx;
328 struct smb2_create create_parm;
329 struct smb2_request *req;
330 union smb_setfileinfo *io2;
332 ctx = composite_create(tree, tree->session->transport->socket->event.ctx);
333 if (ctx == NULL) return NULL;
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++;
348 req = smb2_create_send(tree, &create_parm);
350 io2 = talloc(ctx, union smb_setfileinfo);
351 if (composite_nomem(io2, ctx)) {
352 return ctx;
354 *io2 = *io;
356 ctx->private_data = io2;
358 composite_continue_smb2(ctx, req, continue_setpathinfo, ctx);
359 return ctx;
364 composite setpathinfo call
366 NTSTATUS smb2_composite_setpathinfo(struct smb2_tree *tree, union smb_setfileinfo *io)
368 struct composite_context *c = smb2_composite_setpathinfo_send(tree, io);
369 return composite_wait_free(c);