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
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 "param/param.h"
33 #include "libcli/smb2/smb2_calls.h"
36 continue after a SMB2 close
38 static void continue_close(struct smb2_request *req)
40 struct composite_context *ctx = talloc_get_type(req->async.private_data,
41 struct composite_context);
43 struct smb2_close close_parm;
45 status = smb2_close_recv(req, &close_parm);
46 composite_error(ctx, status);
50 continue after the create in a composite unlink
52 static void continue_unlink(struct smb2_request *req)
54 struct composite_context *ctx = talloc_get_type(req->async.private_data,
55 struct composite_context);
56 struct smb2_tree *tree = req->tree;
57 struct smb2_create create_parm;
58 struct smb2_close close_parm;
61 status = smb2_create_recv(req, ctx, &create_parm);
62 if (!NT_STATUS_IS_OK(status)) {
63 composite_error(ctx, status);
67 ZERO_STRUCT(close_parm);
68 close_parm.in.file.handle = create_parm.out.file.handle;
70 req = smb2_close_send(tree, &close_parm);
71 composite_continue_smb2(ctx, req, continue_close, ctx);
75 composite SMB2 unlink call
77 struct composite_context *smb2_composite_unlink_send(struct smb2_tree *tree,
80 struct composite_context *ctx;
81 struct smb2_create create_parm;
82 struct smb2_request *req;
84 ctx = composite_create(tree, tree->session->transport->socket->event.ctx);
85 if (ctx == NULL) return NULL;
87 /* check for wildcards - we could support these with a
88 search, but for now they aren't necessary */
89 if (strpbrk(io->unlink.in.pattern, "*?<>") != NULL) {
90 composite_error(ctx, NT_STATUS_NOT_SUPPORTED);
94 ZERO_STRUCT(create_parm);
95 create_parm.in.desired_access = SEC_STD_DELETE;
96 create_parm.in.create_disposition = NTCREATEX_DISP_OPEN;
97 create_parm.in.share_access =
98 NTCREATEX_SHARE_ACCESS_DELETE|
99 NTCREATEX_SHARE_ACCESS_READ|
100 NTCREATEX_SHARE_ACCESS_WRITE;
101 create_parm.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
102 create_parm.in.fname = io->unlink.in.pattern;
103 if (create_parm.in.fname[0] == '\\') {
104 create_parm.in.fname++;
107 req = smb2_create_send(tree, &create_parm);
109 composite_continue_smb2(ctx, req, continue_unlink, ctx);
115 composite unlink call - sync interface
117 NTSTATUS smb2_composite_unlink(struct smb2_tree *tree, union smb_unlink *io)
119 struct composite_context *c = smb2_composite_unlink_send(tree, io);
120 return composite_wait_free(c);
127 continue after the create in a composite mkdir
129 static void continue_mkdir(struct smb2_request *req)
131 struct composite_context *ctx = talloc_get_type(req->async.private_data,
132 struct composite_context);
133 struct smb2_tree *tree = req->tree;
134 struct smb2_create create_parm;
135 struct smb2_close close_parm;
138 status = smb2_create_recv(req, ctx, &create_parm);
139 if (!NT_STATUS_IS_OK(status)) {
140 composite_error(ctx, status);
144 ZERO_STRUCT(close_parm);
145 close_parm.in.file.handle = create_parm.out.file.handle;
147 req = smb2_close_send(tree, &close_parm);
148 composite_continue_smb2(ctx, req, continue_close, ctx);
152 composite SMB2 mkdir call
154 struct composite_context *smb2_composite_mkdir_send(struct smb2_tree *tree,
157 struct composite_context *ctx;
158 struct smb2_create create_parm;
159 struct smb2_request *req;
161 ctx = composite_create(tree, tree->session->transport->socket->event.ctx);
162 if (ctx == NULL) return NULL;
164 ZERO_STRUCT(create_parm);
166 create_parm.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
167 create_parm.in.share_access =
168 NTCREATEX_SHARE_ACCESS_READ|
169 NTCREATEX_SHARE_ACCESS_WRITE;
170 create_parm.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
171 create_parm.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
172 create_parm.in.create_disposition = NTCREATEX_DISP_CREATE;
173 create_parm.in.fname = io->mkdir.in.path;
174 if (create_parm.in.fname[0] == '\\') {
175 create_parm.in.fname++;
178 req = smb2_create_send(tree, &create_parm);
180 composite_continue_smb2(ctx, req, continue_mkdir, ctx);
187 composite mkdir call - sync interface
189 NTSTATUS smb2_composite_mkdir(struct smb2_tree *tree, union smb_mkdir *io)
191 struct composite_context *c = smb2_composite_mkdir_send(tree, io);
192 return composite_wait_free(c);