2 Unix SMB/CIFS implementation.
4 Copyright (C) James Myers 2003
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) James Peach 2007
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "libcli/raw/libcliraw.h"
24 #include "libcli/raw/raw_proto.h"
25 #include "librpc/gen_ndr/ndr_security.h"
29 Handle setfileinfo/setpathinfo passthu constructions
31 bool smb_raw_setfileinfo_passthru(TALLOC_CTX
*mem_ctx
,
32 enum smb_setfileinfo_level level
,
33 union smb_setfileinfo
*parms
,
38 #define NEED_BLOB(n) do { \
39 *blob = data_blob_talloc(mem_ctx, NULL, n); \
40 if (blob->data == NULL && n != 0) return false; \
44 case RAW_SFILEINFO_BASIC_INFORMATION
:
46 smbcli_push_nttime(blob
->data
, 0, parms
->basic_info
.in
.create_time
);
47 smbcli_push_nttime(blob
->data
, 8, parms
->basic_info
.in
.access_time
);
48 smbcli_push_nttime(blob
->data
, 16, parms
->basic_info
.in
.write_time
);
49 smbcli_push_nttime(blob
->data
, 24, parms
->basic_info
.in
.change_time
);
50 SIVAL(blob
->data
, 32, parms
->basic_info
.in
.attrib
);
51 SIVAL(blob
->data
, 36, 0); /* padding */
54 case RAW_SFILEINFO_DISPOSITION_INFORMATION
:
56 SIVAL(blob
->data
, 0, parms
->disposition_info
.in
.delete_on_close
);
59 case RAW_SFILEINFO_ALLOCATION_INFORMATION
:
61 SBVAL(blob
->data
, 0, parms
->allocation_info
.in
.alloc_size
);
64 case RAW_SFILEINFO_END_OF_FILE_INFORMATION
:
66 SBVAL(blob
->data
, 0, parms
->end_of_file_info
.in
.size
);
69 case RAW_SFILEINFO_RENAME_INFORMATION
:
71 SIVAL(blob
->data
, 0, parms
->rename_information
.in
.overwrite
);
72 SIVAL(blob
->data
, 4, parms
->rename_information
.in
.root_fid
);
73 len
= smbcli_blob_append_string(NULL
, mem_ctx
, blob
,
74 parms
->rename_information
.in
.new_name
,
75 STR_UNICODE
|STR_TERMINATE
);
76 SIVAL(blob
->data
, 8, len
- 2);
79 case RAW_SFILEINFO_RENAME_INFORMATION_SMB2
:
81 SIVAL(blob
->data
, 0, parms
->rename_information
.in
.overwrite
);
82 SBVAL(blob
->data
, 8, parms
->rename_information
.in
.root_fid
);
83 len
= smbcli_blob_append_string(NULL
, mem_ctx
, blob
,
84 parms
->rename_information
.in
.new_name
,
85 STR_UNICODE
|STR_TERMINATE
);
86 SIVAL(blob
->data
, 16, len
- 2);
89 case RAW_SFILEINFO_POSITION_INFORMATION
:
91 SBVAL(blob
->data
, 0, parms
->position_information
.in
.position
);
94 case RAW_SFILEINFO_MODE_INFORMATION
:
96 SIVAL(blob
->data
, 0, parms
->mode_information
.in
.mode
);
99 case RAW_FILEINFO_SEC_DESC
: {
100 enum ndr_err_code ndr_err
;
102 ndr_err
= ndr_push_struct_blob(blob
, mem_ctx
, parms
->set_secdesc
.in
.sd
,
103 (ndr_push_flags_fn_t
)ndr_push_security_descriptor
);
104 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
111 case RAW_SFILEINFO_FULL_EA_INFORMATION
:
112 printf("num_eas=%d\n", parms
->full_ea_information
.in
.eas
.num_eas
);
113 NEED_BLOB(ea_list_size_chained(
114 parms
->full_ea_information
.in
.eas
.num_eas
,
115 parms
->full_ea_information
.in
.eas
.eas
, 4));
116 ea_put_list_chained(blob
->data
,
117 parms
->full_ea_information
.in
.eas
.num_eas
,
118 parms
->full_ea_information
.in
.eas
.eas
, 4);
121 /* Unhandled levels */
122 case RAW_SFILEINFO_PIPE_INFORMATION
:
123 case RAW_SFILEINFO_VALID_DATA_INFORMATION
:
124 case RAW_SFILEINFO_SHORT_NAME_INFORMATION
:
125 case RAW_SFILEINFO_1025
:
126 case RAW_SFILEINFO_1027
:
127 case RAW_SFILEINFO_1029
:
128 case RAW_SFILEINFO_1030
:
129 case RAW_SFILEINFO_1031
:
130 case RAW_SFILEINFO_1032
:
131 case RAW_SFILEINFO_1036
:
132 case RAW_SFILEINFO_1041
:
133 case RAW_SFILEINFO_1042
:
134 case RAW_SFILEINFO_1043
:
135 case RAW_SFILEINFO_1044
:
139 DEBUG(0,("Unhandled setfileinfo passthru level %d\n", level
));
147 Handle setfileinfo/setpathinfo trans2 backend.
149 static bool smb_raw_setinfo_backend(struct smbcli_tree
*tree
,
151 union smb_setfileinfo
*parms
,
154 switch (parms
->generic
.level
) {
155 case RAW_SFILEINFO_GENERIC
:
156 case RAW_SFILEINFO_SETATTR
:
157 case RAW_SFILEINFO_SETATTRE
:
158 case RAW_SFILEINFO_SEC_DESC
:
159 /* not handled here */
162 case RAW_SFILEINFO_STANDARD
:
164 raw_push_dos_date2(tree
->session
->transport
,
165 blob
->data
, 0, parms
->standard
.in
.create_time
);
166 raw_push_dos_date2(tree
->session
->transport
,
167 blob
->data
, 4, parms
->standard
.in
.access_time
);
168 raw_push_dos_date2(tree
->session
->transport
,
169 blob
->data
, 8, parms
->standard
.in
.write_time
);
172 case RAW_SFILEINFO_EA_SET
:
173 NEED_BLOB(ea_list_size(parms
->ea_set
.in
.num_eas
, parms
->ea_set
.in
.eas
));
174 ea_put_list(blob
->data
, parms
->ea_set
.in
.num_eas
, parms
->ea_set
.in
.eas
);
177 case RAW_SFILEINFO_BASIC_INFO
:
178 case RAW_SFILEINFO_BASIC_INFORMATION
:
179 return smb_raw_setfileinfo_passthru(mem_ctx
, RAW_SFILEINFO_BASIC_INFORMATION
,
182 case RAW_SFILEINFO_UNIX_BASIC
:
184 SBVAL(blob
->data
, 0, parms
->unix_basic
.in
.end_of_file
);
185 SBVAL(blob
->data
, 8, parms
->unix_basic
.in
.num_bytes
);
186 smbcli_push_nttime(blob
->data
, 16, parms
->unix_basic
.in
.status_change_time
);
187 smbcli_push_nttime(blob
->data
, 24, parms
->unix_basic
.in
.access_time
);
188 smbcli_push_nttime(blob
->data
, 32, parms
->unix_basic
.in
.change_time
);
189 SBVAL(blob
->data
, 40, parms
->unix_basic
.in
.uid
);
190 SBVAL(blob
->data
, 48, parms
->unix_basic
.in
.gid
);
191 SIVAL(blob
->data
, 56, parms
->unix_basic
.in
.file_type
);
192 SBVAL(blob
->data
, 60, parms
->unix_basic
.in
.dev_major
);
193 SBVAL(blob
->data
, 68, parms
->unix_basic
.in
.dev_minor
);
194 SBVAL(blob
->data
, 76, parms
->unix_basic
.in
.unique_id
);
195 SBVAL(blob
->data
, 84, parms
->unix_basic
.in
.permissions
);
196 SBVAL(blob
->data
, 92, parms
->unix_basic
.in
.nlink
);
199 case RAW_SFILEINFO_UNIX_INFO2
:
201 SBVAL(blob
->data
, 0, parms
->unix_info2
.in
.end_of_file
);
202 SBVAL(blob
->data
, 8, parms
->unix_info2
.in
.num_bytes
);
203 smbcli_push_nttime(blob
->data
, 16, parms
->unix_info2
.in
.status_change_time
);
204 smbcli_push_nttime(blob
->data
, 24, parms
->unix_info2
.in
.access_time
);
205 smbcli_push_nttime(blob
->data
, 32, parms
->unix_info2
.in
.change_time
);
206 SBVAL(blob
->data
, 40,parms
->unix_info2
.in
.uid
);
207 SBVAL(blob
->data
, 48,parms
->unix_info2
.in
.gid
);
208 SIVAL(blob
->data
, 56,parms
->unix_info2
.in
.file_type
);
209 SBVAL(blob
->data
, 60,parms
->unix_info2
.in
.dev_major
);
210 SBVAL(blob
->data
, 68,parms
->unix_info2
.in
.dev_minor
);
211 SBVAL(blob
->data
, 76,parms
->unix_info2
.in
.unique_id
);
212 SBVAL(blob
->data
, 84,parms
->unix_info2
.in
.permissions
);
213 SBVAL(blob
->data
, 92,parms
->unix_info2
.in
.nlink
);
214 smbcli_push_nttime(blob
->data
, 100, parms
->unix_info2
.in
.create_time
);
215 SIVAL(blob
->data
, 108, parms
->unix_info2
.in
.file_flags
);
216 SIVAL(blob
->data
, 112, parms
->unix_info2
.in
.flags_mask
);
219 case RAW_SFILEINFO_DISPOSITION_INFO
:
220 case RAW_SFILEINFO_DISPOSITION_INFORMATION
:
221 return smb_raw_setfileinfo_passthru(mem_ctx
, RAW_SFILEINFO_DISPOSITION_INFORMATION
,
224 case RAW_SFILEINFO_ALLOCATION_INFO
:
225 case RAW_SFILEINFO_ALLOCATION_INFORMATION
:
226 return smb_raw_setfileinfo_passthru(mem_ctx
, RAW_SFILEINFO_ALLOCATION_INFORMATION
,
229 case RAW_SFILEINFO_END_OF_FILE_INFO
:
230 case RAW_SFILEINFO_END_OF_FILE_INFORMATION
:
231 return smb_raw_setfileinfo_passthru(mem_ctx
, RAW_SFILEINFO_END_OF_FILE_INFORMATION
,
234 case RAW_SFILEINFO_RENAME_INFORMATION
:
235 return smb_raw_setfileinfo_passthru(mem_ctx
, RAW_SFILEINFO_RENAME_INFORMATION
,
238 case RAW_SFILEINFO_POSITION_INFORMATION
:
239 return smb_raw_setfileinfo_passthru(mem_ctx
, RAW_SFILEINFO_POSITION_INFORMATION
,
242 case RAW_SFILEINFO_MODE_INFORMATION
:
243 return smb_raw_setfileinfo_passthru(mem_ctx
, RAW_SFILEINFO_MODE_INFORMATION
,
246 /* Unhandled passthru levels */
247 case RAW_SFILEINFO_PIPE_INFORMATION
:
248 case RAW_SFILEINFO_VALID_DATA_INFORMATION
:
249 case RAW_SFILEINFO_SHORT_NAME_INFORMATION
:
250 case RAW_SFILEINFO_FULL_EA_INFORMATION
:
251 case RAW_SFILEINFO_1025
:
252 case RAW_SFILEINFO_1027
:
253 case RAW_SFILEINFO_1029
:
254 case RAW_SFILEINFO_1030
:
255 case RAW_SFILEINFO_1031
:
256 case RAW_SFILEINFO_1032
:
257 case RAW_SFILEINFO_1036
:
258 case RAW_SFILEINFO_1041
:
259 case RAW_SFILEINFO_1042
:
260 case RAW_SFILEINFO_1043
:
261 case RAW_SFILEINFO_1044
:
262 return smb_raw_setfileinfo_passthru(mem_ctx
, parms
->generic
.level
,
265 /* Unhandled levels */
266 case RAW_SFILEINFO_UNIX_LINK
:
267 case RAW_SFILEINFO_UNIX_HLINK
:
268 case RAW_SFILEINFO_RENAME_INFORMATION_SMB2
:
269 case RAW_SFILEINFO_LINK_INFORMATION
:
276 /****************************************************************************
277 Very raw set file info - takes data blob (async send)
278 ****************************************************************************/
279 static struct smbcli_request
*smb_raw_setfileinfo_blob_send(struct smbcli_tree
*tree
,
285 struct smb_trans2 tp
;
286 uint16_t setup
= TRANSACT2_SETFILEINFO
;
291 tp
.in
.setup_count
= 1;
294 tp
.in
.setup
= &setup
;
296 tp
.in
.params
= data_blob_talloc(mem_ctx
, NULL
, 6);
297 if (!tp
.in
.params
.data
) {
300 SSVAL(tp
.in
.params
.data
, 0, fnum
);
301 SSVAL(tp
.in
.params
.data
, 2, info_level
);
302 SSVAL(tp
.in
.params
.data
, 4, 0); /* reserved */
306 return smb_raw_trans2_send(tree
, &tp
);
309 /****************************************************************************
310 Very raw set path info - takes data blob
311 ****************************************************************************/
312 static struct smbcli_request
*smb_raw_setpathinfo_blob_send(struct smbcli_tree
*tree
,
318 struct smb_trans2 tp
;
319 uint16_t setup
= TRANSACT2_SETPATHINFO
;
324 tp
.in
.setup_count
= 1;
327 tp
.in
.setup
= &setup
;
329 tp
.in
.params
= data_blob_talloc(mem_ctx
, NULL
, 6);
330 if (!tp
.in
.params
.data
) {
333 SSVAL(tp
.in
.params
.data
, 0, info_level
);
334 SIVAL(tp
.in
.params
.data
, 2, 0);
335 smbcli_blob_append_string(tree
->session
, mem_ctx
,
337 fname
, STR_TERMINATE
);
341 return smb_raw_trans2_send(tree
, &tp
);
344 /****************************************************************************
345 Handle setattr (async send)
346 ****************************************************************************/
347 static struct smbcli_request
*smb_raw_setattr_send(struct smbcli_tree
*tree
,
348 union smb_setfileinfo
*parms
)
350 struct smbcli_request
*req
;
352 req
= smbcli_request_setup(tree
, SMBsetatr
, 8, 0);
353 if (!req
) return NULL
;
355 SSVAL(req
->out
.vwv
, VWV(0), parms
->setattr
.in
.attrib
);
356 raw_push_dos_date3(tree
->session
->transport
,
357 req
->out
.vwv
, VWV(1), parms
->setattr
.in
.write_time
);
358 memset(req
->out
.vwv
+ VWV(3), 0, 10); /* reserved */
359 smbcli_req_append_ascii4(req
, parms
->setattr
.in
.file
.path
, STR_TERMINATE
);
360 smbcli_req_append_ascii4(req
, "", STR_TERMINATE
);
362 if (!smbcli_request_send(req
)) {
363 smbcli_request_destroy(req
);
370 /****************************************************************************
371 Handle setattrE. (async send)
372 ****************************************************************************/
373 static struct smbcli_request
*smb_raw_setattrE_send(struct smbcli_tree
*tree
,
374 union smb_setfileinfo
*parms
)
376 struct smbcli_request
*req
;
378 req
= smbcli_request_setup(tree
, SMBsetattrE
, 7, 0);
379 if (!req
) return NULL
;
381 SSVAL(req
->out
.vwv
, VWV(0), parms
->setattre
.in
.file
.fnum
);
382 raw_push_dos_date2(tree
->session
->transport
,
383 req
->out
.vwv
, VWV(1), parms
->setattre
.in
.create_time
);
384 raw_push_dos_date2(tree
->session
->transport
,
385 req
->out
.vwv
, VWV(3), parms
->setattre
.in
.access_time
);
386 raw_push_dos_date2(tree
->session
->transport
,
387 req
->out
.vwv
, VWV(5), parms
->setattre
.in
.write_time
);
389 if (!smbcli_request_send(req
)) {
390 smbcli_request_destroy(req
);
397 /****************************************************************************
398 Set file info (async send)
399 ****************************************************************************/
400 struct smbcli_request
*smb_raw_setfileinfo_send(struct smbcli_tree
*tree
,
401 union smb_setfileinfo
*parms
)
405 struct smbcli_request
*req
;
407 if (parms
->generic
.level
== RAW_SFILEINFO_SETATTRE
) {
408 return smb_raw_setattrE_send(tree
, parms
);
410 if (parms
->generic
.level
== RAW_SFILEINFO_SEC_DESC
) {
411 return smb_raw_set_secdesc_send(tree
, parms
);
413 if (parms
->generic
.level
>= RAW_SFILEINFO_GENERIC
) {
417 mem_ctx
= talloc_init("setpathinfo");
418 if (!mem_ctx
) return NULL
;
420 if (!smb_raw_setinfo_backend(tree
, mem_ctx
, parms
, &blob
)) {
421 talloc_free(mem_ctx
);
425 /* send request and process the output */
426 req
= smb_raw_setfileinfo_blob_send(tree
,
428 parms
->generic
.in
.file
.fnum
,
429 parms
->generic
.level
,
432 talloc_free(mem_ctx
);
436 /****************************************************************************
437 Set file info (async send)
438 ****************************************************************************/
439 _PUBLIC_ NTSTATUS
smb_raw_setfileinfo(struct smbcli_tree
*tree
,
440 union smb_setfileinfo
*parms
)
442 struct smbcli_request
*req
= smb_raw_setfileinfo_send(tree
, parms
);
443 return smbcli_request_simple_recv(req
);
447 /****************************************************************************
448 Set path info (async send)
449 ****************************************************************************/
450 _PUBLIC_
struct smbcli_request
*smb_raw_setpathinfo_send(struct smbcli_tree
*tree
,
451 union smb_setfileinfo
*parms
)
455 struct smbcli_request
*req
;
457 if (parms
->generic
.level
== RAW_SFILEINFO_SETATTR
) {
458 return smb_raw_setattr_send(tree
, parms
);
460 if (parms
->generic
.level
>= RAW_SFILEINFO_GENERIC
) {
464 mem_ctx
= talloc_init("setpathinfo");
465 if (!mem_ctx
) return NULL
;
467 if (!smb_raw_setinfo_backend(tree
, mem_ctx
, parms
, &blob
)) {
468 talloc_free(mem_ctx
);
472 /* send request and process the output */
473 req
= smb_raw_setpathinfo_blob_send(tree
,
475 parms
->generic
.in
.file
.path
,
476 parms
->generic
.level
,
479 talloc_free(mem_ctx
);
483 /****************************************************************************
484 Set path info (sync interface)
485 ****************************************************************************/
486 _PUBLIC_ NTSTATUS
smb_raw_setpathinfo(struct smbcli_tree
*tree
,
487 union smb_setfileinfo
*parms
)
489 struct smbcli_request
*req
= smb_raw_setpathinfo_send(tree
, parms
);
490 return smbcli_request_simple_recv(req
);