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 /* Unhandled levels */
123 case RAW_SFILEINFO_PIPE_INFORMATION
:
124 case RAW_SFILEINFO_VALID_DATA_INFORMATION
:
125 case RAW_SFILEINFO_SHORT_NAME_INFORMATION
:
126 case RAW_SFILEINFO_1025
:
127 case RAW_SFILEINFO_1027
:
128 case RAW_SFILEINFO_1029
:
129 case RAW_SFILEINFO_1030
:
130 case RAW_SFILEINFO_1031
:
131 case RAW_SFILEINFO_1032
:
132 case RAW_SFILEINFO_1036
:
133 case RAW_SFILEINFO_1041
:
134 case RAW_SFILEINFO_1042
:
135 case RAW_SFILEINFO_1043
:
136 case RAW_SFILEINFO_1044
:
140 DEBUG(0,("Unhandled setfileinfo passthru level %d\n", level
));
148 Handle setfileinfo/setpathinfo trans2 backend.
150 static bool smb_raw_setinfo_backend(struct smbcli_tree
*tree
,
152 union smb_setfileinfo
*parms
,
155 switch (parms
->generic
.level
) {
156 case RAW_SFILEINFO_GENERIC
:
157 case RAW_SFILEINFO_SETATTR
:
158 case RAW_SFILEINFO_SETATTRE
:
159 case RAW_SFILEINFO_SEC_DESC
:
160 /* not handled here */
163 case RAW_SFILEINFO_STANDARD
:
165 raw_push_dos_date2(tree
->session
->transport
,
166 blob
->data
, 0, parms
->standard
.in
.create_time
);
167 raw_push_dos_date2(tree
->session
->transport
,
168 blob
->data
, 4, parms
->standard
.in
.access_time
);
169 raw_push_dos_date2(tree
->session
->transport
,
170 blob
->data
, 8, parms
->standard
.in
.write_time
);
173 case RAW_SFILEINFO_EA_SET
:
174 NEED_BLOB(ea_list_size(parms
->ea_set
.in
.num_eas
, parms
->ea_set
.in
.eas
));
175 ea_put_list(blob
->data
, parms
->ea_set
.in
.num_eas
, parms
->ea_set
.in
.eas
);
178 case RAW_SFILEINFO_BASIC_INFO
:
179 case RAW_SFILEINFO_BASIC_INFORMATION
:
180 return smb_raw_setfileinfo_passthru(mem_ctx
, RAW_SFILEINFO_BASIC_INFORMATION
,
183 case RAW_SFILEINFO_UNIX_BASIC
:
185 SBVAL(blob
->data
, 0, parms
->unix_basic
.in
.end_of_file
);
186 SBVAL(blob
->data
, 8, parms
->unix_basic
.in
.num_bytes
);
187 smbcli_push_nttime(blob
->data
, 16, parms
->unix_basic
.in
.status_change_time
);
188 smbcli_push_nttime(blob
->data
, 24, parms
->unix_basic
.in
.access_time
);
189 smbcli_push_nttime(blob
->data
, 32, parms
->unix_basic
.in
.change_time
);
190 SBVAL(blob
->data
, 40, parms
->unix_basic
.in
.uid
);
191 SBVAL(blob
->data
, 48, parms
->unix_basic
.in
.gid
);
192 SIVAL(blob
->data
, 56, parms
->unix_basic
.in
.file_type
);
193 SBVAL(blob
->data
, 60, parms
->unix_basic
.in
.dev_major
);
194 SBVAL(blob
->data
, 68, parms
->unix_basic
.in
.dev_minor
);
195 SBVAL(blob
->data
, 76, parms
->unix_basic
.in
.unique_id
);
196 SBVAL(blob
->data
, 84, parms
->unix_basic
.in
.permissions
);
197 SBVAL(blob
->data
, 92, parms
->unix_basic
.in
.nlink
);
200 case RAW_SFILEINFO_UNIX_INFO2
:
202 SBVAL(blob
->data
, 0, parms
->unix_info2
.in
.end_of_file
);
203 SBVAL(blob
->data
, 8, parms
->unix_info2
.in
.num_bytes
);
204 smbcli_push_nttime(blob
->data
, 16, parms
->unix_info2
.in
.status_change_time
);
205 smbcli_push_nttime(blob
->data
, 24, parms
->unix_info2
.in
.access_time
);
206 smbcli_push_nttime(blob
->data
, 32, parms
->unix_info2
.in
.change_time
);
207 SBVAL(blob
->data
, 40,parms
->unix_info2
.in
.uid
);
208 SBVAL(blob
->data
, 48,parms
->unix_info2
.in
.gid
);
209 SIVAL(blob
->data
, 56,parms
->unix_info2
.in
.file_type
);
210 SBVAL(blob
->data
, 60,parms
->unix_info2
.in
.dev_major
);
211 SBVAL(blob
->data
, 68,parms
->unix_info2
.in
.dev_minor
);
212 SBVAL(blob
->data
, 76,parms
->unix_info2
.in
.unique_id
);
213 SBVAL(blob
->data
, 84,parms
->unix_info2
.in
.permissions
);
214 SBVAL(blob
->data
, 92,parms
->unix_info2
.in
.nlink
);
215 smbcli_push_nttime(blob
->data
, 100, parms
->unix_info2
.in
.create_time
);
216 SIVAL(blob
->data
, 108, parms
->unix_info2
.in
.file_flags
);
217 SIVAL(blob
->data
, 112, parms
->unix_info2
.in
.flags_mask
);
220 case RAW_SFILEINFO_DISPOSITION_INFO
:
221 case RAW_SFILEINFO_DISPOSITION_INFORMATION
:
222 return smb_raw_setfileinfo_passthru(mem_ctx
, RAW_SFILEINFO_DISPOSITION_INFORMATION
,
225 case RAW_SFILEINFO_ALLOCATION_INFO
:
226 case RAW_SFILEINFO_ALLOCATION_INFORMATION
:
227 return smb_raw_setfileinfo_passthru(mem_ctx
, RAW_SFILEINFO_ALLOCATION_INFORMATION
,
230 case RAW_SFILEINFO_END_OF_FILE_INFO
:
231 case RAW_SFILEINFO_END_OF_FILE_INFORMATION
:
232 return smb_raw_setfileinfo_passthru(mem_ctx
, RAW_SFILEINFO_END_OF_FILE_INFORMATION
,
235 case RAW_SFILEINFO_RENAME_INFORMATION
:
236 return smb_raw_setfileinfo_passthru(mem_ctx
, RAW_SFILEINFO_RENAME_INFORMATION
,
239 case RAW_SFILEINFO_POSITION_INFORMATION
:
240 return smb_raw_setfileinfo_passthru(mem_ctx
, RAW_SFILEINFO_POSITION_INFORMATION
,
243 case RAW_SFILEINFO_MODE_INFORMATION
:
244 return smb_raw_setfileinfo_passthru(mem_ctx
, RAW_SFILEINFO_MODE_INFORMATION
,
247 /* Unhandled passthru levels */
248 case RAW_SFILEINFO_PIPE_INFORMATION
:
249 case RAW_SFILEINFO_VALID_DATA_INFORMATION
:
250 case RAW_SFILEINFO_SHORT_NAME_INFORMATION
:
251 case RAW_SFILEINFO_FULL_EA_INFORMATION
:
252 case RAW_SFILEINFO_1025
:
253 case RAW_SFILEINFO_1027
:
254 case RAW_SFILEINFO_1029
:
255 case RAW_SFILEINFO_1030
:
256 case RAW_SFILEINFO_1031
:
257 case RAW_SFILEINFO_1032
:
258 case RAW_SFILEINFO_1036
:
259 case RAW_SFILEINFO_1041
:
260 case RAW_SFILEINFO_1042
:
261 case RAW_SFILEINFO_1043
:
262 case RAW_SFILEINFO_1044
:
263 return smb_raw_setfileinfo_passthru(mem_ctx
, parms
->generic
.level
,
266 /* Unhandled levels */
267 case RAW_SFILEINFO_UNIX_LINK
:
268 case RAW_SFILEINFO_UNIX_HLINK
:
269 case RAW_SFILEINFO_RENAME_INFORMATION_SMB2
:
270 case RAW_SFILEINFO_LINK_INFORMATION
:
277 /****************************************************************************
278 Very raw set file info - takes data blob (async send)
279 ****************************************************************************/
280 static struct smbcli_request
*smb_raw_setfileinfo_blob_send(struct smbcli_tree
*tree
,
286 struct smb_trans2 tp
;
287 uint16_t setup
= TRANSACT2_SETFILEINFO
;
292 tp
.in
.setup_count
= 1;
295 tp
.in
.setup
= &setup
;
297 tp
.in
.params
= data_blob_talloc(mem_ctx
, NULL
, 6);
298 if (!tp
.in
.params
.data
) {
301 SSVAL(tp
.in
.params
.data
, 0, fnum
);
302 SSVAL(tp
.in
.params
.data
, 2, info_level
);
303 SSVAL(tp
.in
.params
.data
, 4, 0); /* reserved */
307 return smb_raw_trans2_send(tree
, &tp
);
310 /****************************************************************************
311 Very raw set path info - takes data blob
312 ****************************************************************************/
313 static struct smbcli_request
*smb_raw_setpathinfo_blob_send(struct smbcli_tree
*tree
,
319 struct smb_trans2 tp
;
320 uint16_t setup
= TRANSACT2_SETPATHINFO
;
325 tp
.in
.setup_count
= 1;
328 tp
.in
.setup
= &setup
;
330 tp
.in
.params
= data_blob_talloc(mem_ctx
, NULL
, 6);
331 if (!tp
.in
.params
.data
) {
334 SSVAL(tp
.in
.params
.data
, 0, info_level
);
335 SIVAL(tp
.in
.params
.data
, 2, 0);
336 smbcli_blob_append_string(tree
->session
, mem_ctx
,
338 fname
, STR_TERMINATE
);
342 return smb_raw_trans2_send(tree
, &tp
);
345 /****************************************************************************
346 Handle setattr (async send)
347 ****************************************************************************/
348 static struct smbcli_request
*smb_raw_setattr_send(struct smbcli_tree
*tree
,
349 union smb_setfileinfo
*parms
)
351 struct smbcli_request
*req
;
353 req
= smbcli_request_setup(tree
, SMBsetatr
, 8, 0);
354 if (!req
) return NULL
;
356 SSVAL(req
->out
.vwv
, VWV(0), parms
->setattr
.in
.attrib
);
357 raw_push_dos_date3(tree
->session
->transport
,
358 req
->out
.vwv
, VWV(1), parms
->setattr
.in
.write_time
);
359 memset(req
->out
.vwv
+ VWV(3), 0, 10); /* reserved */
360 smbcli_req_append_ascii4(req
, parms
->setattr
.in
.file
.path
, STR_TERMINATE
);
361 smbcli_req_append_ascii4(req
, "", STR_TERMINATE
);
363 if (!smbcli_request_send(req
)) {
364 smbcli_request_destroy(req
);
371 /****************************************************************************
372 Handle setattrE. (async send)
373 ****************************************************************************/
374 static struct smbcli_request
*smb_raw_setattrE_send(struct smbcli_tree
*tree
,
375 union smb_setfileinfo
*parms
)
377 struct smbcli_request
*req
;
379 req
= smbcli_request_setup(tree
, SMBsetattrE
, 7, 0);
380 if (!req
) return NULL
;
382 SSVAL(req
->out
.vwv
, VWV(0), parms
->setattre
.in
.file
.fnum
);
383 raw_push_dos_date2(tree
->session
->transport
,
384 req
->out
.vwv
, VWV(1), parms
->setattre
.in
.create_time
);
385 raw_push_dos_date2(tree
->session
->transport
,
386 req
->out
.vwv
, VWV(3), parms
->setattre
.in
.access_time
);
387 raw_push_dos_date2(tree
->session
->transport
,
388 req
->out
.vwv
, VWV(5), parms
->setattre
.in
.write_time
);
390 if (!smbcli_request_send(req
)) {
391 smbcli_request_destroy(req
);
398 /****************************************************************************
399 Set file info (async send)
400 ****************************************************************************/
401 struct smbcli_request
*smb_raw_setfileinfo_send(struct smbcli_tree
*tree
,
402 union smb_setfileinfo
*parms
)
406 struct smbcli_request
*req
;
408 if (parms
->generic
.level
== RAW_SFILEINFO_SETATTRE
) {
409 return smb_raw_setattrE_send(tree
, parms
);
411 if (parms
->generic
.level
== RAW_SFILEINFO_SEC_DESC
) {
412 return smb_raw_set_secdesc_send(tree
, parms
);
414 if (parms
->generic
.level
>= RAW_SFILEINFO_GENERIC
) {
418 mem_ctx
= talloc_init("setpathinfo");
419 if (!mem_ctx
) return NULL
;
421 if (!smb_raw_setinfo_backend(tree
, mem_ctx
, parms
, &blob
)) {
422 talloc_free(mem_ctx
);
426 /* send request and process the output */
427 req
= smb_raw_setfileinfo_blob_send(tree
,
429 parms
->generic
.in
.file
.fnum
,
430 parms
->generic
.level
,
433 talloc_free(mem_ctx
);
437 /****************************************************************************
438 Set file info (async send)
439 ****************************************************************************/
440 _PUBLIC_ NTSTATUS
smb_raw_setfileinfo(struct smbcli_tree
*tree
,
441 union smb_setfileinfo
*parms
)
443 struct smbcli_request
*req
= smb_raw_setfileinfo_send(tree
, parms
);
444 return smbcli_request_simple_recv(req
);
448 /****************************************************************************
449 Set path info (async send)
450 ****************************************************************************/
451 _PUBLIC_
struct smbcli_request
*smb_raw_setpathinfo_send(struct smbcli_tree
*tree
,
452 union smb_setfileinfo
*parms
)
456 struct smbcli_request
*req
;
458 if (parms
->generic
.level
== RAW_SFILEINFO_SETATTR
) {
459 return smb_raw_setattr_send(tree
, parms
);
461 if (parms
->generic
.level
>= RAW_SFILEINFO_GENERIC
) {
465 mem_ctx
= talloc_init("setpathinfo");
466 if (!mem_ctx
) return NULL
;
468 if (!smb_raw_setinfo_backend(tree
, mem_ctx
, parms
, &blob
)) {
469 talloc_free(mem_ctx
);
473 /* send request and process the output */
474 req
= smb_raw_setpathinfo_blob_send(tree
,
476 parms
->generic
.in
.file
.path
,
477 parms
->generic
.level
,
480 talloc_free(mem_ctx
);
484 /****************************************************************************
485 Set path info (sync interface)
486 ****************************************************************************/
487 _PUBLIC_ NTSTATUS
smb_raw_setpathinfo(struct smbcli_tree
*tree
,
488 union smb_setfileinfo
*parms
)
490 struct smbcli_request
*req
= smb_raw_setpathinfo_send(tree
, parms
);
491 return smbcli_request_simple_recv(req
);