first public release of samba4 code
[jelmer/samba4-debian.git] / source / 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    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23
24 /****************************************************************************
25  Handle qfileinfo/qpathinfo trans2 backend.
26 ****************************************************************************/
27 static BOOL smb_raw_setinfo_backend(struct cli_tree *tree,
28                                     TALLOC_CTX *mem_ctx,
29                                     union smb_setfileinfo *parms, 
30                                     DATA_BLOB *blob)
31 {       
32         uint_t len;
33
34 #define NEED_BLOB(n) do { \
35           *blob = data_blob_talloc(mem_ctx, NULL, n); \
36           if (blob->data == NULL) return False; \
37         } while (0)
38
39         switch (parms->generic.level) {
40         case RAW_SFILEINFO_GENERIC:
41         case RAW_SFILEINFO_SETATTR:
42         case RAW_SFILEINFO_SETATTRE:
43                 /* not handled here */
44                 return False;
45
46         case RAW_SFILEINFO_STANDARD:
47                 NEED_BLOB(12);
48                 put_dos_date2(blob->data, 0, parms->standard.in.create_time);
49                 put_dos_date2(blob->data, 4, parms->standard.in.access_time);
50                 put_dos_date2(blob->data, 8, parms->standard.in.write_time);
51                 return True;
52
53         case RAW_SFILEINFO_EA_SET:
54                 NEED_BLOB(ea_list_size(1, &parms->ea_set.in.ea));
55                 ea_put_list(blob->data, 1, &parms->ea_set.in.ea);
56                 return True;
57
58         case RAW_SFILEINFO_BASIC_INFO:
59         case RAW_SFILEINFO_BASIC_INFORMATION:
60                 NEED_BLOB(40);
61                 cli_push_nttime(blob->data,  0, &parms->basic_info.in.create_time);
62                 cli_push_nttime(blob->data,  8, &parms->basic_info.in.access_time);
63                 cli_push_nttime(blob->data, 16, &parms->basic_info.in.write_time);
64                 cli_push_nttime(blob->data, 24, &parms->basic_info.in.change_time);
65                 SIVAL(blob->data,           32, parms->basic_info.in.attrib);
66                 SIVAL(blob->data,           36, 0); /* padding */
67                 return True;
68
69         case RAW_SFILEINFO_UNIX_BASIC:
70                 NEED_BLOB(92);
71                 SBVAL(blob->data, 0, parms->unix_basic.in.end_of_file);
72                 SBVAL(blob->data, 8, parms->unix_basic.in.num_bytes);
73                 cli_push_nttime(blob->data, 16, &parms->unix_basic.in.status_change_time);
74                 cli_push_nttime(blob->data, 24, &parms->unix_basic.in.access_time);
75                 cli_push_nttime(blob->data, 32, &parms->unix_basic.in.change_time);
76                 SBVAL(blob->data, 40, parms->unix_basic.in.uid);
77                 SBVAL(blob->data, 48, parms->unix_basic.in.gid);
78                 SIVAL(blob->data, 56, parms->unix_basic.in.file_type);
79                 SBVAL(blob->data, 60, parms->unix_basic.in.dev_major);
80                 SBVAL(blob->data, 68, parms->unix_basic.in.dev_minor);
81                 SBVAL(blob->data, 76, parms->unix_basic.in.unique_id);
82                 SBVAL(blob->data, 84, parms->unix_basic.in.nlink);
83                 return True;
84
85         case RAW_SFILEINFO_DISPOSITION_INFO:
86         case RAW_SFILEINFO_DISPOSITION_INFORMATION:
87                 NEED_BLOB(4);
88                 SIVAL(blob->data, 0, parms->disposition_info.in.delete_on_close);
89                 return True;
90
91         case RAW_SFILEINFO_ALLOCATION_INFO:
92         case RAW_SFILEINFO_ALLOCATION_INFORMATION:
93                 NEED_BLOB(8);
94                 SBVAL(blob->data, 0, parms->allocation_info.in.alloc_size);
95                 return True;
96
97         case RAW_SFILEINFO_END_OF_FILE_INFO:
98         case RAW_SFILEINFO_END_OF_FILE_INFORMATION:
99                 NEED_BLOB(8);
100                 SBVAL(blob->data, 0, parms->end_of_file_info.in.size);
101                 return True;
102
103         case RAW_SFILEINFO_RENAME_INFORMATION:
104                 NEED_BLOB(12);
105                 SIVAL(blob->data, 0, parms->rename_information.in.overwrite);
106                 SIVAL(blob->data, 4, parms->rename_information.in.root_fid);
107                 len = cli_blob_append_string(tree->session, mem_ctx, blob,
108                                              parms->rename_information.in.new_name, 
109                                              STR_UNICODE|STR_TERMINATE);
110                 SIVAL(blob->data, 8, len - 2);
111                 return True;
112
113         case RAW_SFILEINFO_POSITION_INFORMATION:
114                 NEED_BLOB(8);
115                 SBVAL(blob->data, 0, parms->position_information.in.position);
116                 return True;
117
118         case RAW_SFILEINFO_MODE_INFORMATION:
119                 NEED_BLOB(4);
120                 SIVAL(blob->data, 0, parms->mode_information.in.mode);
121                 return True;
122         }
123
124         return False;
125 }
126
127 /****************************************************************************
128  Very raw set file info - takes data blob (async send)
129 ****************************************************************************/
130 static struct cli_request *smb_raw_setfileinfo_blob_send(struct cli_tree *tree,
131                                                          TALLOC_CTX *mem_ctx,
132                                                          uint16 fnum,
133                                                          uint16 info_level,
134                                                          DATA_BLOB *blob)
135 {
136         struct smb_trans2 tp;
137         uint16 setup = TRANSACT2_SETFILEINFO;
138         
139         tp.in.max_setup = 0;
140         tp.in.flags = 0; 
141         tp.in.timeout = 0;
142         tp.in.setup_count = 1;
143         tp.in.max_param = 2;
144         tp.in.max_data = 0;
145         tp.in.setup = &setup;
146         
147         tp.in.params = data_blob_talloc(mem_ctx, NULL, 6);
148         if (!tp.in.params.data) {
149                 return NULL;
150         }
151         SSVAL(tp.in.params.data, 0, fnum);
152         SSVAL(tp.in.params.data, 2, info_level);
153         SSVAL(tp.in.params.data, 4, 0); /* reserved */
154
155         tp.in.data = *blob;
156
157         return smb_raw_trans2_send(tree, &tp);
158 }
159
160 /****************************************************************************
161  Very raw set path info - takes data blob
162 ****************************************************************************/
163 static struct cli_request *smb_raw_setpathinfo_blob_send(struct cli_tree *tree,
164                                                          TALLOC_CTX *mem_ctx,
165                                                          const char *fname,
166                                                          uint16 info_level,
167                                                          DATA_BLOB *blob)
168 {
169         struct smb_trans2 tp;
170         uint16 setup = TRANSACT2_SETPATHINFO;
171         
172         tp.in.max_setup = 0;
173         tp.in.flags = 0; 
174         tp.in.timeout = 0;
175         tp.in.setup_count = 1;
176         tp.in.max_param = 2;
177         tp.in.max_data = 0;
178         tp.in.setup = &setup;
179         
180         tp.in.params = data_blob_talloc(mem_ctx, NULL, 4);
181         if (!tp.in.params.data) {
182                 return NULL;
183         }
184         SSVAL(tp.in.params.data, 0, info_level);
185         SSVAL(tp.in.params.data, 2, 0);
186         cli_blob_append_string(tree->session, mem_ctx, 
187                                &tp.in.params,
188                                fname, STR_TERMINATE);
189
190         tp.in.data = *blob;
191
192         return smb_raw_trans2_send(tree, &tp);
193 }
194                 
195 /****************************************************************************
196  Handle setattr (async send)
197 ****************************************************************************/
198 static struct cli_request *smb_raw_setattr_send(struct cli_tree *tree,
199                                                 union smb_setfileinfo *parms)
200 {
201         struct cli_request *req;
202
203         req = cli_request_setup(tree, SMBsetatr, 8, 0);
204         if (!req) return NULL;
205         
206         SSVAL(req->out.vwv,         VWV(0), parms->setattr.in.attrib);
207         put_dos_date3(req->out.vwv, VWV(1), parms->setattr.in.write_time);
208         memset(req->out.vwv + VWV(3), 0, 10); /* reserved */
209         cli_req_append_ascii4(req, parms->setattr.file.fname, STR_TERMINATE);
210         cli_req_append_ascii4(req, "", STR_TERMINATE);
211         
212         if (!cli_request_send(req)) {
213                 cli_request_destroy(req);
214                 return NULL;
215         }
216
217         return req;
218 }
219                 
220 /****************************************************************************
221  Handle setattrE. (async send)
222 ****************************************************************************/
223 static struct cli_request *smb_raw_setattrE_send(struct cli_tree *tree,
224                                                  union smb_setfileinfo *parms)
225 {
226         struct cli_request *req;
227
228         req = cli_request_setup(tree, SMBsetattrE, 7, 0);
229         if (!req) return NULL;
230         
231         SSVAL(req->out.vwv,         VWV(0), parms->setattre.file.fnum);
232         put_dos_date2(req->out.vwv, VWV(1), parms->setattre.in.create_time);
233         put_dos_date2(req->out.vwv, VWV(3), parms->setattre.in.access_time);
234         put_dos_date2(req->out.vwv, VWV(5), parms->setattre.in.write_time);
235         
236         if (!cli_request_send(req)) {
237                 cli_request_destroy(req);
238                 return NULL;
239         }
240
241         return req;
242 }
243
244 /****************************************************************************
245  Set file info (async send)
246 ****************************************************************************/
247 struct cli_request *smb_raw_setfileinfo_send(struct cli_tree *tree,
248                                              union smb_setfileinfo *parms)
249 {
250         DATA_BLOB blob;
251         TALLOC_CTX *mem_ctx;
252         struct cli_request *req;
253
254         if (parms->generic.level == RAW_SFILEINFO_SETATTRE) {
255                 return smb_raw_setattrE_send(tree, parms);
256         }
257         if (parms->generic.level >= RAW_SFILEINFO_GENERIC) {
258                 return NULL;
259         }
260
261         mem_ctx = talloc_init("setpathinfo");
262         if (!mem_ctx) return NULL;
263
264         if (!smb_raw_setinfo_backend(tree, mem_ctx, parms, &blob)) {
265                 talloc_destroy(mem_ctx);
266                 return NULL;
267         }
268         
269         /* send request and process the output */
270         req = smb_raw_setfileinfo_blob_send(tree, 
271                                             mem_ctx,
272                                             parms->generic.file.fnum, 
273                                             parms->generic.level, 
274                                             &blob);
275
276         talloc_destroy(mem_ctx);
277         return req;
278 }
279
280 /****************************************************************************
281  Set file info (async send)
282 ****************************************************************************/
283 NTSTATUS smb_raw_setfileinfo(struct cli_tree *tree,
284                              union smb_setfileinfo *parms)
285 {
286         struct cli_request *req = smb_raw_setfileinfo_send(tree, parms);
287         return cli_request_simple_recv(req);
288 }
289
290
291 /****************************************************************************
292  Set path info (async send)
293 ****************************************************************************/
294 struct cli_request *smb_raw_setpathinfo_send(struct cli_tree *tree,
295                                              union smb_setfileinfo *parms)
296 {
297         DATA_BLOB blob;
298         TALLOC_CTX *mem_ctx;
299         struct cli_request *req;
300
301         if (parms->generic.level == RAW_SFILEINFO_SETATTR) {
302                 return smb_raw_setattr_send(tree, parms);
303         }
304         if (parms->generic.level >= RAW_SFILEINFO_GENERIC) {
305                 return NULL;
306         }
307
308         mem_ctx = talloc_init("setpathinfo");
309         if (!mem_ctx) return NULL;
310
311         if (!smb_raw_setinfo_backend(tree, mem_ctx, parms, &blob)) {
312                 talloc_destroy(mem_ctx);
313                 return NULL;
314         }
315
316         /* send request and process the output */
317         req = smb_raw_setpathinfo_blob_send(tree, 
318                                             mem_ctx,
319                                             parms->generic.file.fname, 
320                                             parms->generic.level,
321                                             &blob);
322
323         talloc_destroy(mem_ctx);
324         return req;
325 }
326
327 /****************************************************************************
328  Set path info (sync interface)
329 ****************************************************************************/
330 NTSTATUS smb_raw_setpathinfo(struct cli_tree *tree,
331                              union smb_setfileinfo *parms)
332 {
333         struct cli_request *req = smb_raw_setpathinfo_send(tree, parms);
334         return cli_request_simple_recv(req);
335 }