selftest: run smb signing tests as part of make quicktest
[gd/samba/.git] / source4 / libcli / raw / rawsetfileinfo.c
1 /* 
2    Unix SMB/CIFS implementation.
3    RAW_SFILEINFO_* calls
4    Copyright (C) James Myers 2003
5    Copyright (C) Andrew Tridgell 2003
6    Copyright (C) James Peach 2007
7    
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.
12    
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.
17    
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/>.
20 */
21
22 #include "includes.h"
23 #include "libcli/raw/libcliraw.h"
24 #include "libcli/raw/raw_proto.h"
25 #include "librpc/gen_ndr/ndr_security.h"
26
27
28 /*
29   Handle setfileinfo/setpathinfo passthu constructions
30 */
31 bool smb_raw_setfileinfo_passthru(TALLOC_CTX *mem_ctx,
32                                   enum smb_setfileinfo_level level,
33                                   union smb_setfileinfo *parms, 
34                                   DATA_BLOB *blob)
35 {       
36         uint_t len;
37
38 #define NEED_BLOB(n) do { \
39           *blob = data_blob_talloc(mem_ctx, NULL, n); \
40           if (blob->data == NULL) return false; \
41         } while (0)
42
43         switch (level) {
44         case RAW_SFILEINFO_BASIC_INFORMATION:
45                 NEED_BLOB(40);
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 */
52                 return true;
53
54         case RAW_SFILEINFO_DISPOSITION_INFORMATION:
55                 NEED_BLOB(4);
56                 SIVAL(blob->data, 0, parms->disposition_info.in.delete_on_close);
57                 return true;
58
59         case RAW_SFILEINFO_ALLOCATION_INFORMATION:
60                 NEED_BLOB(8);
61                 SBVAL(blob->data, 0, parms->allocation_info.in.alloc_size);
62                 return true;
63
64         case RAW_SFILEINFO_END_OF_FILE_INFORMATION:
65                 NEED_BLOB(8);
66                 SBVAL(blob->data, 0, parms->end_of_file_info.in.size);
67                 return true;
68
69         case RAW_SFILEINFO_RENAME_INFORMATION:
70                 NEED_BLOB(12);
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);
77                 return true;
78
79         case RAW_SFILEINFO_RENAME_INFORMATION_SMB2:
80                 NEED_BLOB(20);
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);
87                 return true;
88
89         case RAW_SFILEINFO_POSITION_INFORMATION:
90                 NEED_BLOB(8);
91                 SBVAL(blob->data, 0, parms->position_information.in.position);
92                 return true;
93
94         case RAW_SFILEINFO_MODE_INFORMATION:
95                 NEED_BLOB(4);
96                 SIVAL(blob->data, 0, parms->mode_information.in.mode);
97                 return true;
98
99         case RAW_FILEINFO_SEC_DESC: {
100                 enum ndr_err_code ndr_err;
101
102                 ndr_err = ndr_push_struct_blob(blob, mem_ctx, NULL,
103                                                parms->set_secdesc.in.sd,
104                                                (ndr_push_flags_fn_t)ndr_push_security_descriptor);
105                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
106                         return false;
107                 }
108
109                 return true;
110         }
111
112                 /* Unhandled levels */
113         case RAW_SFILEINFO_PIPE_INFORMATION:
114         case RAW_SFILEINFO_VALID_DATA_INFORMATION:
115         case RAW_SFILEINFO_SHORT_NAME_INFORMATION:
116         case RAW_SFILEINFO_1025:
117         case RAW_SFILEINFO_1027:
118         case RAW_SFILEINFO_1029:
119         case RAW_SFILEINFO_1030:
120         case RAW_SFILEINFO_1031:
121         case RAW_SFILEINFO_1032:
122         case RAW_SFILEINFO_1036:
123         case RAW_SFILEINFO_1041:
124         case RAW_SFILEINFO_1042:
125         case RAW_SFILEINFO_1043:
126         case RAW_SFILEINFO_1044:
127                 break;
128
129         default:
130                 DEBUG(0,("Unhandled setfileinfo passthru level %d\n", level));
131                 return false;
132         }
133
134         return false;
135 }
136
137 /*
138   Handle setfileinfo/setpathinfo trans2 backend.
139 */
140 static bool smb_raw_setinfo_backend(struct smbcli_tree *tree,
141                                     TALLOC_CTX *mem_ctx,
142                                     union smb_setfileinfo *parms, 
143                                     DATA_BLOB *blob)
144 {       
145         switch (parms->generic.level) {
146         case RAW_SFILEINFO_GENERIC:
147         case RAW_SFILEINFO_SETATTR:
148         case RAW_SFILEINFO_SETATTRE:
149         case RAW_SFILEINFO_SEC_DESC:
150                 /* not handled here */
151                 return false;
152
153         case RAW_SFILEINFO_STANDARD:
154                 NEED_BLOB(12);
155                 raw_push_dos_date2(tree->session->transport, 
156                                   blob->data, 0, parms->standard.in.create_time);
157                 raw_push_dos_date2(tree->session->transport, 
158                                   blob->data, 4, parms->standard.in.access_time);
159                 raw_push_dos_date2(tree->session->transport, 
160                                   blob->data, 8, parms->standard.in.write_time);
161                 return true;
162
163         case RAW_SFILEINFO_EA_SET:
164                 NEED_BLOB(ea_list_size(parms->ea_set.in.num_eas, parms->ea_set.in.eas));
165                 ea_put_list(blob->data, parms->ea_set.in.num_eas, parms->ea_set.in.eas);
166                 return true;
167
168         case RAW_SFILEINFO_BASIC_INFO:
169         case RAW_SFILEINFO_BASIC_INFORMATION:
170                 return smb_raw_setfileinfo_passthru(mem_ctx, RAW_SFILEINFO_BASIC_INFORMATION, 
171                                                     parms, blob);
172
173         case RAW_SFILEINFO_UNIX_BASIC:
174                 NEED_BLOB(100);
175                 SBVAL(blob->data, 0, parms->unix_basic.in.end_of_file);
176                 SBVAL(blob->data, 8, parms->unix_basic.in.num_bytes);
177                 smbcli_push_nttime(blob->data, 16, parms->unix_basic.in.status_change_time);
178                 smbcli_push_nttime(blob->data, 24, parms->unix_basic.in.access_time);
179                 smbcli_push_nttime(blob->data, 32, parms->unix_basic.in.change_time);
180                 SBVAL(blob->data, 40, parms->unix_basic.in.uid);
181                 SBVAL(blob->data, 48, parms->unix_basic.in.gid);
182                 SIVAL(blob->data, 56, parms->unix_basic.in.file_type);
183                 SBVAL(blob->data, 60, parms->unix_basic.in.dev_major);
184                 SBVAL(blob->data, 68, parms->unix_basic.in.dev_minor);
185                 SBVAL(blob->data, 76, parms->unix_basic.in.unique_id);
186                 SBVAL(blob->data, 84, parms->unix_basic.in.permissions);
187                 SBVAL(blob->data, 92, parms->unix_basic.in.nlink);
188                 return true;
189
190         case RAW_SFILEINFO_UNIX_INFO2:
191                 NEED_BLOB(116);
192                 SBVAL(blob->data,   0, parms->unix_info2.in.end_of_file);
193                 SBVAL(blob->data,   8, parms->unix_info2.in.num_bytes);
194                 smbcli_push_nttime(blob->data, 16, parms->unix_info2.in.status_change_time);
195                 smbcli_push_nttime(blob->data, 24, parms->unix_info2.in.access_time);
196                 smbcli_push_nttime(blob->data, 32, parms->unix_info2.in.change_time);
197                 SBVAL(blob->data,  40,parms->unix_info2.in.uid);
198                 SBVAL(blob->data,  48,parms->unix_info2.in.gid);
199                 SIVAL(blob->data,  56,parms->unix_info2.in.file_type);
200                 SBVAL(blob->data,  60,parms->unix_info2.in.dev_major);
201                 SBVAL(blob->data,  68,parms->unix_info2.in.dev_minor);
202                 SBVAL(blob->data,  76,parms->unix_info2.in.unique_id);
203                 SBVAL(blob->data,  84,parms->unix_info2.in.permissions);
204                 SBVAL(blob->data,  92,parms->unix_info2.in.nlink);
205                 smbcli_push_nttime(blob->data, 100, parms->unix_info2.in.create_time);
206                 SIVAL(blob->data, 108, parms->unix_info2.in.file_flags);
207                 SIVAL(blob->data, 112, parms->unix_info2.in.flags_mask);
208                 return true;
209
210         case RAW_SFILEINFO_DISPOSITION_INFO:
211         case RAW_SFILEINFO_DISPOSITION_INFORMATION:
212                 return smb_raw_setfileinfo_passthru(mem_ctx, RAW_SFILEINFO_DISPOSITION_INFORMATION,
213                                                     parms, blob);
214
215         case RAW_SFILEINFO_ALLOCATION_INFO:
216         case RAW_SFILEINFO_ALLOCATION_INFORMATION:
217                 return smb_raw_setfileinfo_passthru(mem_ctx, RAW_SFILEINFO_ALLOCATION_INFORMATION,
218                                                     parms, blob);
219
220         case RAW_SFILEINFO_END_OF_FILE_INFO:
221         case RAW_SFILEINFO_END_OF_FILE_INFORMATION:
222                 return smb_raw_setfileinfo_passthru(mem_ctx, RAW_SFILEINFO_END_OF_FILE_INFORMATION,
223                                                     parms, blob);
224
225         case RAW_SFILEINFO_RENAME_INFORMATION:
226                 return smb_raw_setfileinfo_passthru(mem_ctx, RAW_SFILEINFO_RENAME_INFORMATION,
227                                                     parms, blob);
228
229         case RAW_SFILEINFO_POSITION_INFORMATION:
230                 return smb_raw_setfileinfo_passthru(mem_ctx, RAW_SFILEINFO_POSITION_INFORMATION,
231                                                     parms, blob);
232
233         case RAW_SFILEINFO_MODE_INFORMATION:
234                 return smb_raw_setfileinfo_passthru(mem_ctx, RAW_SFILEINFO_MODE_INFORMATION,
235                                                     parms, blob);
236                 
237                 /* Unhandled passthru levels */
238         case RAW_SFILEINFO_PIPE_INFORMATION:
239         case RAW_SFILEINFO_VALID_DATA_INFORMATION:
240         case RAW_SFILEINFO_SHORT_NAME_INFORMATION:
241         case RAW_SFILEINFO_FULL_EA_INFORMATION:
242         case RAW_SFILEINFO_1025:
243         case RAW_SFILEINFO_1027:
244         case RAW_SFILEINFO_1029:
245         case RAW_SFILEINFO_1030:
246         case RAW_SFILEINFO_1031:
247         case RAW_SFILEINFO_1032:
248         case RAW_SFILEINFO_1036:
249         case RAW_SFILEINFO_1041:
250         case RAW_SFILEINFO_1042:
251         case RAW_SFILEINFO_1043:
252         case RAW_SFILEINFO_1044:
253                 return smb_raw_setfileinfo_passthru(mem_ctx, parms->generic.level,
254                                                     parms, blob);
255
256                 /* Unhandled levels */
257
258         case RAW_SFILEINFO_UNIX_LINK:
259         case RAW_SFILEINFO_UNIX_HLINK:
260         case RAW_SFILEINFO_RENAME_INFORMATION_SMB2:
261                 break;
262         }
263
264         return false;
265 }
266
267 /****************************************************************************
268  Very raw set file info - takes data blob (async send)
269 ****************************************************************************/
270 static struct smbcli_request *smb_raw_setfileinfo_blob_send(struct smbcli_tree *tree,
271                                                          TALLOC_CTX *mem_ctx,
272                                                          uint16_t fnum,
273                                                          uint16_t info_level,
274                                                          DATA_BLOB *blob)
275 {
276         struct smb_trans2 tp;
277         uint16_t setup = TRANSACT2_SETFILEINFO;
278         
279         tp.in.max_setup = 0;
280         tp.in.flags = 0; 
281         tp.in.timeout = 0;
282         tp.in.setup_count = 1;
283         tp.in.max_param = 2;
284         tp.in.max_data = 0;
285         tp.in.setup = &setup;
286         
287         tp.in.params = data_blob_talloc(mem_ctx, NULL, 6);
288         if (!tp.in.params.data) {
289                 return NULL;
290         }
291         SSVAL(tp.in.params.data, 0, fnum);
292         SSVAL(tp.in.params.data, 2, info_level);
293         SSVAL(tp.in.params.data, 4, 0); /* reserved */
294
295         tp.in.data = *blob;
296
297         return smb_raw_trans2_send(tree, &tp);
298 }
299
300 /****************************************************************************
301  Very raw set path info - takes data blob
302 ****************************************************************************/
303 static struct smbcli_request *smb_raw_setpathinfo_blob_send(struct smbcli_tree *tree,
304                                                             TALLOC_CTX *mem_ctx,
305                                                             const char *fname,
306                                                             uint16_t info_level,
307                                                             DATA_BLOB *blob)
308 {
309         struct smb_trans2 tp;
310         uint16_t setup = TRANSACT2_SETPATHINFO;
311         
312         tp.in.max_setup = 0;
313         tp.in.flags = 0; 
314         tp.in.timeout = 0;
315         tp.in.setup_count = 1;
316         tp.in.max_param = 2;
317         tp.in.max_data = 0;
318         tp.in.setup = &setup;
319         
320         tp.in.params = data_blob_talloc(mem_ctx, NULL, 6);
321         if (!tp.in.params.data) {
322                 return NULL;
323         }
324         SSVAL(tp.in.params.data, 0, info_level);
325         SIVAL(tp.in.params.data, 2, 0);
326         smbcli_blob_append_string(tree->session, mem_ctx, 
327                                   &tp.in.params,
328                                   fname, STR_TERMINATE);
329
330         tp.in.data = *blob;
331
332         return smb_raw_trans2_send(tree, &tp);
333 }
334                 
335 /****************************************************************************
336  Handle setattr (async send)
337 ****************************************************************************/
338 static struct smbcli_request *smb_raw_setattr_send(struct smbcli_tree *tree,
339                                                 union smb_setfileinfo *parms)
340 {
341         struct smbcli_request *req;
342
343         req = smbcli_request_setup(tree, SMBsetatr, 8, 0);
344         if (!req) return NULL;
345         
346         SSVAL(req->out.vwv,         VWV(0), parms->setattr.in.attrib);
347         raw_push_dos_date3(tree->session->transport, 
348                           req->out.vwv, VWV(1), parms->setattr.in.write_time);
349         memset(req->out.vwv + VWV(3), 0, 10); /* reserved */
350         smbcli_req_append_ascii4(req, parms->setattr.in.file.path, STR_TERMINATE);
351         smbcli_req_append_ascii4(req, "", STR_TERMINATE);
352         
353         if (!smbcli_request_send(req)) {
354                 smbcli_request_destroy(req);
355                 return NULL;
356         }
357
358         return req;
359 }
360                 
361 /****************************************************************************
362  Handle setattrE. (async send)
363 ****************************************************************************/
364 static struct smbcli_request *smb_raw_setattrE_send(struct smbcli_tree *tree,
365                                                  union smb_setfileinfo *parms)
366 {
367         struct smbcli_request *req;
368
369         req = smbcli_request_setup(tree, SMBsetattrE, 7, 0);
370         if (!req) return NULL;
371         
372         SSVAL(req->out.vwv,         VWV(0), parms->setattre.in.file.fnum);
373         raw_push_dos_date2(tree->session->transport, 
374                           req->out.vwv, VWV(1), parms->setattre.in.create_time);
375         raw_push_dos_date2(tree->session->transport, 
376                           req->out.vwv, VWV(3), parms->setattre.in.access_time);
377         raw_push_dos_date2(tree->session->transport, 
378                           req->out.vwv, VWV(5), parms->setattre.in.write_time);
379
380         if (!smbcli_request_send(req)) {
381                 smbcli_request_destroy(req);
382                 return NULL;
383         }
384
385         return req;
386 }
387
388 /****************************************************************************
389  Set file info (async send)
390 ****************************************************************************/
391 struct smbcli_request *smb_raw_setfileinfo_send(struct smbcli_tree *tree,
392                                              union smb_setfileinfo *parms)
393 {
394         DATA_BLOB blob;
395         TALLOC_CTX *mem_ctx;
396         struct smbcli_request *req;
397
398         if (parms->generic.level == RAW_SFILEINFO_SETATTRE) {
399                 return smb_raw_setattrE_send(tree, parms);
400         }
401         if (parms->generic.level == RAW_SFILEINFO_SEC_DESC) {
402                 return smb_raw_set_secdesc_send(tree, parms);
403         }
404         if (parms->generic.level >= RAW_SFILEINFO_GENERIC) {
405                 return NULL;
406         }
407
408         mem_ctx = talloc_init("setpathinfo");
409         if (!mem_ctx) return NULL;
410
411         if (!smb_raw_setinfo_backend(tree, mem_ctx, parms, &blob)) {
412                 talloc_free(mem_ctx);
413                 return NULL;
414         }
415         
416         /* send request and process the output */
417         req = smb_raw_setfileinfo_blob_send(tree, 
418                                             mem_ctx,
419                                             parms->generic.in.file.fnum, 
420                                             parms->generic.level, 
421                                             &blob);
422
423         talloc_free(mem_ctx);
424         return req;
425 }
426
427 /****************************************************************************
428  Set file info (async send)
429 ****************************************************************************/
430 _PUBLIC_ NTSTATUS smb_raw_setfileinfo(struct smbcli_tree *tree,
431                              union smb_setfileinfo *parms)
432 {
433         struct smbcli_request *req = smb_raw_setfileinfo_send(tree, parms);
434         return smbcli_request_simple_recv(req);
435 }
436
437
438 /****************************************************************************
439  Set path info (async send)
440 ****************************************************************************/
441 _PUBLIC_ struct smbcli_request *smb_raw_setpathinfo_send(struct smbcli_tree *tree,
442                                              union smb_setfileinfo *parms)
443 {
444         DATA_BLOB blob;
445         TALLOC_CTX *mem_ctx;
446         struct smbcli_request *req;
447
448         if (parms->generic.level == RAW_SFILEINFO_SETATTR) {
449                 return smb_raw_setattr_send(tree, parms);
450         }
451         if (parms->generic.level >= RAW_SFILEINFO_GENERIC) {
452                 return NULL;
453         }
454
455         mem_ctx = talloc_init("setpathinfo");
456         if (!mem_ctx) return NULL;
457
458         if (!smb_raw_setinfo_backend(tree, mem_ctx, parms, &blob)) {
459                 talloc_free(mem_ctx);
460                 return NULL;
461         }
462
463         /* send request and process the output */
464         req = smb_raw_setpathinfo_blob_send(tree, 
465                                             mem_ctx,
466                                             parms->generic.in.file.path, 
467                                             parms->generic.level,
468                                             &blob);
469
470         talloc_free(mem_ctx);
471         return req;
472 }
473
474 /****************************************************************************
475  Set path info (sync interface)
476 ****************************************************************************/
477 _PUBLIC_ NTSTATUS smb_raw_setpathinfo(struct smbcli_tree *tree,
478                              union smb_setfileinfo *parms)
479 {
480         struct smbcli_request *req = smb_raw_setpathinfo_send(tree, parms);
481         return smbcli_request_simple_recv(req);
482 }