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 SIVAL(blob
->data
, 4, 0);
83 SBVAL(blob
->data
, 8, parms
->rename_information
.in
.root_fid
);
84 len
= smbcli_blob_append_string(NULL
, mem_ctx
, blob
,
85 parms
->rename_information
.in
.new_name
,
86 STR_UNICODE
|STR_TERMINATE
);
87 SIVAL(blob
->data
, 16, len
- 2);
90 case RAW_SFILEINFO_POSITION_INFORMATION
:
92 SBVAL(blob
->data
, 0, parms
->position_information
.in
.position
);
95 case RAW_SFILEINFO_MODE_INFORMATION
:
97 SIVAL(blob
->data
, 0, parms
->mode_information
.in
.mode
);
100 case RAW_FILEINFO_SEC_DESC
: {
101 enum ndr_err_code ndr_err
;
103 ndr_err
= ndr_push_struct_blob(blob
, mem_ctx
, parms
->set_secdesc
.in
.sd
,
104 (ndr_push_flags_fn_t
)ndr_push_security_descriptor
);
105 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
112 case RAW_SFILEINFO_FULL_EA_INFORMATION
:
113 printf("num_eas=%d\n", parms
->full_ea_information
.in
.eas
.num_eas
);
114 NEED_BLOB(ea_list_size_chained(
115 parms
->full_ea_information
.in
.eas
.num_eas
,
116 parms
->full_ea_information
.in
.eas
.eas
, 4));
117 ea_put_list_chained(blob
->data
,
118 parms
->full_ea_information
.in
.eas
.num_eas
,
119 parms
->full_ea_information
.in
.eas
.eas
, 4);
122 case RAW_SFILEINFO_LINK_INFORMATION
:
124 memset(blob
->data
, 0, blob
->length
);
126 PUSH_LE_U8(blob
->data
, 0, parms
->link_information
.in
.overwrite
);
127 PUSH_LE_U64(blob
->data
, 8, parms
->link_information
.in
.root_fid
);
129 len
= smbcli_blob_append_string(
131 parms
->link_information
.in
.new_name
,
132 STR_UNICODE
| STR_TERMINATE
);
133 PUSH_LE_U32(blob
->data
, 16, len
- 2);
136 /* Unhandled levels */
137 case RAW_SFILEINFO_PIPE_INFORMATION
:
138 case RAW_SFILEINFO_VALID_DATA_INFORMATION
:
139 case RAW_SFILEINFO_SHORT_NAME_INFORMATION
:
140 case RAW_SFILEINFO_1025
:
141 case RAW_SFILEINFO_1027
:
142 case RAW_SFILEINFO_1029
:
143 case RAW_SFILEINFO_1030
:
144 case RAW_SFILEINFO_1031
:
145 case RAW_SFILEINFO_1032
:
146 case RAW_SFILEINFO_1036
:
147 case RAW_SFILEINFO_1041
:
148 case RAW_SFILEINFO_1042
:
149 case RAW_SFILEINFO_1043
:
150 case RAW_SFILEINFO_1044
:
154 DEBUG(0,("Unhandled setfileinfo passthru level %d\n", level
));
162 Handle setfileinfo/setpathinfo trans2 backend.
164 static bool smb_raw_setinfo_backend(struct smbcli_tree
*tree
,
166 union smb_setfileinfo
*parms
,
169 switch (parms
->generic
.level
) {
170 case RAW_SFILEINFO_GENERIC
:
171 case RAW_SFILEINFO_SETATTR
:
172 case RAW_SFILEINFO_SETATTRE
:
173 case RAW_SFILEINFO_SEC_DESC
:
174 /* not handled here */
177 case RAW_SFILEINFO_STANDARD
:
179 raw_push_dos_date2(tree
->session
->transport
,
180 blob
->data
, 0, parms
->standard
.in
.create_time
);
181 raw_push_dos_date2(tree
->session
->transport
,
182 blob
->data
, 4, parms
->standard
.in
.access_time
);
183 raw_push_dos_date2(tree
->session
->transport
,
184 blob
->data
, 8, parms
->standard
.in
.write_time
);
187 case RAW_SFILEINFO_EA_SET
:
188 NEED_BLOB(ea_list_size(parms
->ea_set
.in
.num_eas
, parms
->ea_set
.in
.eas
));
189 ea_put_list(blob
->data
, parms
->ea_set
.in
.num_eas
, parms
->ea_set
.in
.eas
);
192 case RAW_SFILEINFO_BASIC_INFO
:
193 case RAW_SFILEINFO_BASIC_INFORMATION
:
194 return smb_raw_setfileinfo_passthru(mem_ctx
, RAW_SFILEINFO_BASIC_INFORMATION
,
197 case RAW_SFILEINFO_UNIX_BASIC
:
199 SBVAL(blob
->data
, 0, parms
->unix_basic
.in
.end_of_file
);
200 SBVAL(blob
->data
, 8, parms
->unix_basic
.in
.num_bytes
);
201 smbcli_push_nttime(blob
->data
, 16, parms
->unix_basic
.in
.status_change_time
);
202 smbcli_push_nttime(blob
->data
, 24, parms
->unix_basic
.in
.access_time
);
203 smbcli_push_nttime(blob
->data
, 32, parms
->unix_basic
.in
.change_time
);
204 SBVAL(blob
->data
, 40, parms
->unix_basic
.in
.uid
);
205 SBVAL(blob
->data
, 48, parms
->unix_basic
.in
.gid
);
206 SIVAL(blob
->data
, 56, parms
->unix_basic
.in
.file_type
);
207 SBVAL(blob
->data
, 60, parms
->unix_basic
.in
.dev_major
);
208 SBVAL(blob
->data
, 68, parms
->unix_basic
.in
.dev_minor
);
209 SBVAL(blob
->data
, 76, parms
->unix_basic
.in
.unique_id
);
210 SBVAL(blob
->data
, 84, parms
->unix_basic
.in
.permissions
);
211 SBVAL(blob
->data
, 92, parms
->unix_basic
.in
.nlink
);
214 case RAW_SFILEINFO_UNIX_INFO2
:
216 SBVAL(blob
->data
, 0, parms
->unix_info2
.in
.end_of_file
);
217 SBVAL(blob
->data
, 8, parms
->unix_info2
.in
.num_bytes
);
218 smbcli_push_nttime(blob
->data
, 16, parms
->unix_info2
.in
.status_change_time
);
219 smbcli_push_nttime(blob
->data
, 24, parms
->unix_info2
.in
.access_time
);
220 smbcli_push_nttime(blob
->data
, 32, parms
->unix_info2
.in
.change_time
);
221 SBVAL(blob
->data
, 40,parms
->unix_info2
.in
.uid
);
222 SBVAL(blob
->data
, 48,parms
->unix_info2
.in
.gid
);
223 SIVAL(blob
->data
, 56,parms
->unix_info2
.in
.file_type
);
224 SBVAL(blob
->data
, 60,parms
->unix_info2
.in
.dev_major
);
225 SBVAL(blob
->data
, 68,parms
->unix_info2
.in
.dev_minor
);
226 SBVAL(blob
->data
, 76,parms
->unix_info2
.in
.unique_id
);
227 SBVAL(blob
->data
, 84,parms
->unix_info2
.in
.permissions
);
228 SBVAL(blob
->data
, 92,parms
->unix_info2
.in
.nlink
);
229 smbcli_push_nttime(blob
->data
, 100, parms
->unix_info2
.in
.create_time
);
230 SIVAL(blob
->data
, 108, parms
->unix_info2
.in
.file_flags
);
231 SIVAL(blob
->data
, 112, parms
->unix_info2
.in
.flags_mask
);
234 case RAW_SFILEINFO_DISPOSITION_INFO
:
235 case RAW_SFILEINFO_DISPOSITION_INFORMATION
:
236 return smb_raw_setfileinfo_passthru(mem_ctx
, RAW_SFILEINFO_DISPOSITION_INFORMATION
,
239 case RAW_SFILEINFO_ALLOCATION_INFO
:
240 case RAW_SFILEINFO_ALLOCATION_INFORMATION
:
241 return smb_raw_setfileinfo_passthru(mem_ctx
, RAW_SFILEINFO_ALLOCATION_INFORMATION
,
244 case RAW_SFILEINFO_END_OF_FILE_INFO
:
245 case RAW_SFILEINFO_END_OF_FILE_INFORMATION
:
246 return smb_raw_setfileinfo_passthru(mem_ctx
, RAW_SFILEINFO_END_OF_FILE_INFORMATION
,
249 case RAW_SFILEINFO_RENAME_INFORMATION
:
250 return smb_raw_setfileinfo_passthru(mem_ctx
, RAW_SFILEINFO_RENAME_INFORMATION
,
253 case RAW_SFILEINFO_POSITION_INFORMATION
:
254 return smb_raw_setfileinfo_passthru(mem_ctx
, RAW_SFILEINFO_POSITION_INFORMATION
,
257 case RAW_SFILEINFO_MODE_INFORMATION
:
258 return smb_raw_setfileinfo_passthru(mem_ctx
, RAW_SFILEINFO_MODE_INFORMATION
,
261 /* Unhandled passthru levels */
262 case RAW_SFILEINFO_PIPE_INFORMATION
:
263 case RAW_SFILEINFO_VALID_DATA_INFORMATION
:
264 case RAW_SFILEINFO_SHORT_NAME_INFORMATION
:
265 case RAW_SFILEINFO_FULL_EA_INFORMATION
:
266 case RAW_SFILEINFO_1025
:
267 case RAW_SFILEINFO_1027
:
268 case RAW_SFILEINFO_1029
:
269 case RAW_SFILEINFO_1030
:
270 case RAW_SFILEINFO_1031
:
271 case RAW_SFILEINFO_1032
:
272 case RAW_SFILEINFO_1036
:
273 case RAW_SFILEINFO_1041
:
274 case RAW_SFILEINFO_1042
:
275 case RAW_SFILEINFO_1043
:
276 case RAW_SFILEINFO_1044
:
277 return smb_raw_setfileinfo_passthru(mem_ctx
, parms
->generic
.level
,
280 /* Unhandled levels */
281 case RAW_SFILEINFO_UNIX_LINK
:
282 case RAW_SFILEINFO_UNIX_HLINK
:
283 case RAW_SFILEINFO_RENAME_INFORMATION_SMB2
:
284 case RAW_SFILEINFO_LINK_INFORMATION
:
291 /****************************************************************************
292 Very raw set file info - takes data blob (async send)
293 ****************************************************************************/
294 static struct smbcli_request
*smb_raw_setfileinfo_blob_send(struct smbcli_tree
*tree
,
300 struct smb_trans2 tp
;
301 uint16_t setup
= TRANSACT2_SETFILEINFO
;
306 tp
.in
.setup_count
= 1;
309 tp
.in
.setup
= &setup
;
311 tp
.in
.params
= data_blob_talloc(mem_ctx
, NULL
, 6);
312 if (!tp
.in
.params
.data
) {
315 SSVAL(tp
.in
.params
.data
, 0, fnum
);
316 SSVAL(tp
.in
.params
.data
, 2, info_level
);
317 SSVAL(tp
.in
.params
.data
, 4, 0); /* reserved */
321 return smb_raw_trans2_send(tree
, &tp
);
324 /****************************************************************************
325 Very raw set path info - takes data blob
326 ****************************************************************************/
327 static struct smbcli_request
*smb_raw_setpathinfo_blob_send(struct smbcli_tree
*tree
,
333 struct smb_trans2 tp
;
334 uint16_t setup
= TRANSACT2_SETPATHINFO
;
339 tp
.in
.setup_count
= 1;
342 tp
.in
.setup
= &setup
;
344 tp
.in
.params
= data_blob_talloc(mem_ctx
, NULL
, 6);
345 if (!tp
.in
.params
.data
) {
348 SSVAL(tp
.in
.params
.data
, 0, info_level
);
349 SIVAL(tp
.in
.params
.data
, 2, 0);
350 smbcli_blob_append_string(tree
->session
, mem_ctx
,
352 fname
, STR_TERMINATE
);
356 return smb_raw_trans2_send(tree
, &tp
);
359 /****************************************************************************
360 Handle setattr (async send)
361 ****************************************************************************/
362 static struct smbcli_request
*smb_raw_setattr_send(struct smbcli_tree
*tree
,
363 union smb_setfileinfo
*parms
)
365 struct smbcli_request
*req
;
367 req
= smbcli_request_setup(tree
, SMBsetatr
, 8, 0);
368 if (!req
) return NULL
;
370 SSVAL(req
->out
.vwv
, VWV(0), parms
->setattr
.in
.attrib
);
371 raw_push_dos_date3(tree
->session
->transport
,
372 req
->out
.vwv
, VWV(1), parms
->setattr
.in
.write_time
);
373 memset(req
->out
.vwv
+ VWV(3), 0, 10); /* reserved */
374 smbcli_req_append_ascii4(req
, parms
->setattr
.in
.file
.path
, STR_TERMINATE
);
375 smbcli_req_append_ascii4(req
, "", STR_TERMINATE
);
377 if (!smbcli_request_send(req
)) {
378 smbcli_request_destroy(req
);
385 /****************************************************************************
386 Handle setattrE. (async send)
387 ****************************************************************************/
388 static struct smbcli_request
*smb_raw_setattrE_send(struct smbcli_tree
*tree
,
389 union smb_setfileinfo
*parms
)
391 struct smbcli_request
*req
;
393 req
= smbcli_request_setup(tree
, SMBsetattrE
, 7, 0);
394 if (!req
) return NULL
;
396 SSVAL(req
->out
.vwv
, VWV(0), parms
->setattre
.in
.file
.fnum
);
397 raw_push_dos_date2(tree
->session
->transport
,
398 req
->out
.vwv
, VWV(1), parms
->setattre
.in
.create_time
);
399 raw_push_dos_date2(tree
->session
->transport
,
400 req
->out
.vwv
, VWV(3), parms
->setattre
.in
.access_time
);
401 raw_push_dos_date2(tree
->session
->transport
,
402 req
->out
.vwv
, VWV(5), parms
->setattre
.in
.write_time
);
404 if (!smbcli_request_send(req
)) {
405 smbcli_request_destroy(req
);
412 /****************************************************************************
413 Set file info (async send)
414 ****************************************************************************/
415 struct smbcli_request
*smb_raw_setfileinfo_send(struct smbcli_tree
*tree
,
416 union smb_setfileinfo
*parms
)
420 struct smbcli_request
*req
;
422 if (parms
->generic
.level
== RAW_SFILEINFO_SETATTRE
) {
423 return smb_raw_setattrE_send(tree
, parms
);
425 if (parms
->generic
.level
== RAW_SFILEINFO_SEC_DESC
) {
426 return smb_raw_set_secdesc_send(tree
, parms
);
428 if (parms
->generic
.level
>= RAW_SFILEINFO_GENERIC
) {
432 mem_ctx
= talloc_init("setpathinfo");
433 if (!mem_ctx
) return NULL
;
435 if (!smb_raw_setinfo_backend(tree
, mem_ctx
, parms
, &blob
)) {
436 talloc_free(mem_ctx
);
440 /* send request and process the output */
441 req
= smb_raw_setfileinfo_blob_send(tree
,
443 parms
->generic
.in
.file
.fnum
,
444 parms
->generic
.level
,
447 talloc_free(mem_ctx
);
451 /****************************************************************************
452 Set file info (async send)
453 ****************************************************************************/
454 _PUBLIC_ NTSTATUS
smb_raw_setfileinfo(struct smbcli_tree
*tree
,
455 union smb_setfileinfo
*parms
)
457 struct smbcli_request
*req
= smb_raw_setfileinfo_send(tree
, parms
);
458 return smbcli_request_simple_recv(req
);
462 /****************************************************************************
463 Set path info (async send)
464 ****************************************************************************/
465 _PUBLIC_
struct smbcli_request
*smb_raw_setpathinfo_send(struct smbcli_tree
*tree
,
466 union smb_setfileinfo
*parms
)
470 struct smbcli_request
*req
;
472 if (parms
->generic
.level
== RAW_SFILEINFO_SETATTR
) {
473 return smb_raw_setattr_send(tree
, parms
);
475 if (parms
->generic
.level
>= RAW_SFILEINFO_GENERIC
) {
479 mem_ctx
= talloc_init("setpathinfo");
480 if (!mem_ctx
) return NULL
;
482 if (!smb_raw_setinfo_backend(tree
, mem_ctx
, parms
, &blob
)) {
483 talloc_free(mem_ctx
);
487 /* send request and process the output */
488 req
= smb_raw_setpathinfo_blob_send(tree
,
490 parms
->generic
.in
.file
.path
,
491 parms
->generic
.level
,
494 talloc_free(mem_ctx
);
498 /****************************************************************************
499 Set path info (sync interface)
500 ****************************************************************************/
501 _PUBLIC_ NTSTATUS
smb_raw_setpathinfo(struct smbcli_tree
*tree
,
502 union smb_setfileinfo
*parms
)
504 struct smbcli_request
*req
= smb_raw_setpathinfo_send(tree
, parms
);
505 return smbcli_request_simple_recv(req
);