r1654: rename cli_ -> smbcli_
[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 setfileinfo/setpathinfo trans2 backend.
26 ****************************************************************************/
27 static BOOL smb_raw_setinfo_backend(struct smbcli_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                 raw_push_dos_date2(tree->session->transport, 
49                                   blob->data, 0, parms->standard.in.create_time);
50                 raw_push_dos_date2(tree->session->transport, 
51                                   blob->data, 4, parms->standard.in.access_time);
52                 raw_push_dos_date2(tree->session->transport, 
53                                   blob->data, 8, parms->standard.in.write_time);
54                 return True;
55
56         case RAW_SFILEINFO_EA_SET:
57                 NEED_BLOB(ea_list_size(1, &parms->ea_set.in.ea));
58                 ea_put_list(blob->data, 1, &parms->ea_set.in.ea);
59                 return True;
60
61         case RAW_SFILEINFO_BASIC_INFO:
62         case RAW_SFILEINFO_BASIC_INFORMATION:
63                 NEED_BLOB(40);
64                 smbcli_push_nttime(blob->data,  0, parms->basic_info.in.create_time);
65                 smbcli_push_nttime(blob->data,  8, parms->basic_info.in.access_time);
66                 smbcli_push_nttime(blob->data, 16, parms->basic_info.in.write_time);
67                 smbcli_push_nttime(blob->data, 24, parms->basic_info.in.change_time);
68                 SIVAL(blob->data,           32, parms->basic_info.in.attrib);
69                 SIVAL(blob->data,           36, 0); /* padding */
70                 return True;
71
72         case RAW_SFILEINFO_UNIX_BASIC:
73                 NEED_BLOB(92);
74                 SBVAL(blob->data, 0, parms->unix_basic.in.end_of_file);
75                 SBVAL(blob->data, 8, parms->unix_basic.in.num_bytes);
76                 smbcli_push_nttime(blob->data, 16, parms->unix_basic.in.status_change_time);
77                 smbcli_push_nttime(blob->data, 24, parms->unix_basic.in.access_time);
78                 smbcli_push_nttime(blob->data, 32, parms->unix_basic.in.change_time);
79                 SBVAL(blob->data, 40, parms->unix_basic.in.uid);
80                 SBVAL(blob->data, 48, parms->unix_basic.in.gid);
81                 SIVAL(blob->data, 56, parms->unix_basic.in.file_type);
82                 SBVAL(blob->data, 60, parms->unix_basic.in.dev_major);
83                 SBVAL(blob->data, 68, parms->unix_basic.in.dev_minor);
84                 SBVAL(blob->data, 76, parms->unix_basic.in.unique_id);
85                 SBVAL(blob->data, 84, parms->unix_basic.in.nlink);
86                 return True;
87
88         case RAW_SFILEINFO_DISPOSITION_INFO:
89         case RAW_SFILEINFO_DISPOSITION_INFORMATION:
90                 NEED_BLOB(4);
91                 SIVAL(blob->data, 0, parms->disposition_info.in.delete_on_close);
92                 return True;
93
94         case RAW_SFILEINFO_ALLOCATION_INFO:
95         case RAW_SFILEINFO_ALLOCATION_INFORMATION:
96                 NEED_BLOB(8);
97                 SBVAL(blob->data, 0, parms->allocation_info.in.alloc_size);
98                 return True;
99
100         case RAW_SFILEINFO_END_OF_FILE_INFO:
101         case RAW_SFILEINFO_END_OF_FILE_INFORMATION:
102                 NEED_BLOB(8);
103                 SBVAL(blob->data, 0, parms->end_of_file_info.in.size);
104                 return True;
105
106         case RAW_SFILEINFO_RENAME_INFORMATION:
107                 NEED_BLOB(12);
108                 SIVAL(blob->data, 0, parms->rename_information.in.overwrite);
109                 SIVAL(blob->data, 4, parms->rename_information.in.root_fid);
110                 len = smbcli_blob_append_string(tree->session, mem_ctx, blob,
111                                              parms->rename_information.in.new_name, 
112                                              STR_UNICODE|STR_TERMINATE);
113                 SIVAL(blob->data, 8, len - 2);
114                 return True;
115
116         case RAW_SFILEINFO_POSITION_INFORMATION:
117                 NEED_BLOB(8);
118                 SBVAL(blob->data, 0, parms->position_information.in.position);
119                 return True;
120
121         case RAW_SFILEINFO_MODE_INFORMATION:
122                 NEED_BLOB(4);
123                 SIVAL(blob->data, 0, parms->mode_information.in.mode);
124                 return True;
125         }
126
127         return False;
128 }
129
130 /****************************************************************************
131  Very raw set file info - takes data blob (async send)
132 ****************************************************************************/
133 static struct smbcli_request *smb_raw_setfileinfo_blob_send(struct smbcli_tree *tree,
134                                                          TALLOC_CTX *mem_ctx,
135                                                          uint16_t fnum,
136                                                          uint16_t info_level,
137                                                          DATA_BLOB *blob)
138 {
139         struct smb_trans2 tp;
140         uint16_t setup = TRANSACT2_SETFILEINFO;
141         
142         tp.in.max_setup = 0;
143         tp.in.flags = 0; 
144         tp.in.timeout = 0;
145         tp.in.setup_count = 1;
146         tp.in.max_param = 2;
147         tp.in.max_data = 0;
148         tp.in.setup = &setup;
149         
150         tp.in.params = data_blob_talloc(mem_ctx, NULL, 6);
151         if (!tp.in.params.data) {
152                 return NULL;
153         }
154         SSVAL(tp.in.params.data, 0, fnum);
155         SSVAL(tp.in.params.data, 2, info_level);
156         SSVAL(tp.in.params.data, 4, 0); /* reserved */
157
158         tp.in.data = *blob;
159
160         return smb_raw_trans2_send(tree, &tp);
161 }
162
163 /****************************************************************************
164  Very raw set path info - takes data blob
165 ****************************************************************************/
166 static struct smbcli_request *smb_raw_setpathinfo_blob_send(struct smbcli_tree *tree,
167                                                          TALLOC_CTX *mem_ctx,
168                                                          const char *fname,
169                                                          uint16_t info_level,
170                                                          DATA_BLOB *blob)
171 {
172         struct smb_trans2 tp;
173         uint16_t setup = TRANSACT2_SETPATHINFO;
174         
175         tp.in.max_setup = 0;
176         tp.in.flags = 0; 
177         tp.in.timeout = 0;
178         tp.in.setup_count = 1;
179         tp.in.max_param = 2;
180         tp.in.max_data = 0;
181         tp.in.setup = &setup;
182         
183         tp.in.params = data_blob_talloc(mem_ctx, NULL, 4);
184         if (!tp.in.params.data) {
185                 return NULL;
186         }
187         SSVAL(tp.in.params.data, 0, info_level);
188         SSVAL(tp.in.params.data, 2, 0);
189         smbcli_blob_append_string(tree->session, mem_ctx, 
190                                &tp.in.params,
191                                fname, STR_TERMINATE);
192
193         tp.in.data = *blob;
194
195         return smb_raw_trans2_send(tree, &tp);
196 }
197                 
198 /****************************************************************************
199  Handle setattr (async send)
200 ****************************************************************************/
201 static struct smbcli_request *smb_raw_setattr_send(struct smbcli_tree *tree,
202                                                 union smb_setfileinfo *parms)
203 {
204         struct smbcli_request *req;
205
206         req = smbcli_request_setup(tree, SMBsetatr, 8, 0);
207         if (!req) return NULL;
208         
209         SSVAL(req->out.vwv,         VWV(0), parms->setattr.in.attrib);
210         raw_push_dos_date3(tree->session->transport, 
211                           req->out.vwv, VWV(1), parms->setattr.in.write_time);
212         memset(req->out.vwv + VWV(3), 0, 10); /* reserved */
213         smbcli_req_append_ascii4(req, parms->setattr.file.fname, STR_TERMINATE);
214         smbcli_req_append_ascii4(req, "", STR_TERMINATE);
215         
216         if (!smbcli_request_send(req)) {
217                 smbcli_request_destroy(req);
218                 return NULL;
219         }
220
221         return req;
222 }
223                 
224 /****************************************************************************
225  Handle setattrE. (async send)
226 ****************************************************************************/
227 static struct smbcli_request *smb_raw_setattrE_send(struct smbcli_tree *tree,
228                                                  union smb_setfileinfo *parms)
229 {
230         struct smbcli_request *req;
231
232         req = smbcli_request_setup(tree, SMBsetattrE, 7, 0);
233         if (!req) return NULL;
234         
235         SSVAL(req->out.vwv,         VWV(0), parms->setattre.file.fnum);
236         raw_push_dos_date2(tree->session->transport, 
237                           req->out.vwv, VWV(1), parms->setattre.in.create_time);
238         raw_push_dos_date2(tree->session->transport, 
239                           req->out.vwv, VWV(3), parms->setattre.in.access_time);
240         raw_push_dos_date2(tree->session->transport, 
241                           req->out.vwv, VWV(5), parms->setattre.in.write_time);
242
243         if (!smbcli_request_send(req)) {
244                 smbcli_request_destroy(req);
245                 return NULL;
246         }
247
248         return req;
249 }
250
251 /****************************************************************************
252  Set file info (async send)
253 ****************************************************************************/
254 struct smbcli_request *smb_raw_setfileinfo_send(struct smbcli_tree *tree,
255                                              union smb_setfileinfo *parms)
256 {
257         DATA_BLOB blob;
258         TALLOC_CTX *mem_ctx;
259         struct smbcli_request *req;
260
261         if (parms->generic.level == RAW_SFILEINFO_SETATTRE) {
262                 return smb_raw_setattrE_send(tree, parms);
263         }
264         if (parms->generic.level >= RAW_SFILEINFO_GENERIC) {
265                 return NULL;
266         }
267
268         mem_ctx = talloc_init("setpathinfo");
269         if (!mem_ctx) return NULL;
270
271         if (!smb_raw_setinfo_backend(tree, mem_ctx, parms, &blob)) {
272                 talloc_destroy(mem_ctx);
273                 return NULL;
274         }
275         
276         /* send request and process the output */
277         req = smb_raw_setfileinfo_blob_send(tree, 
278                                             mem_ctx,
279                                             parms->generic.file.fnum, 
280                                             parms->generic.level, 
281                                             &blob);
282
283         talloc_destroy(mem_ctx);
284         return req;
285 }
286
287 /****************************************************************************
288  Set file info (async send)
289 ****************************************************************************/
290 NTSTATUS smb_raw_setfileinfo(struct smbcli_tree *tree,
291                              union smb_setfileinfo *parms)
292 {
293         struct smbcli_request *req = smb_raw_setfileinfo_send(tree, parms);
294         return smbcli_request_simple_recv(req);
295 }
296
297
298 /****************************************************************************
299  Set path info (async send)
300 ****************************************************************************/
301 struct smbcli_request *smb_raw_setpathinfo_send(struct smbcli_tree *tree,
302                                              union smb_setfileinfo *parms)
303 {
304         DATA_BLOB blob;
305         TALLOC_CTX *mem_ctx;
306         struct smbcli_request *req;
307
308         if (parms->generic.level == RAW_SFILEINFO_SETATTR) {
309                 return smb_raw_setattr_send(tree, parms);
310         }
311         if (parms->generic.level >= RAW_SFILEINFO_GENERIC) {
312                 return NULL;
313         }
314
315         mem_ctx = talloc_init("setpathinfo");
316         if (!mem_ctx) return NULL;
317
318         if (!smb_raw_setinfo_backend(tree, mem_ctx, parms, &blob)) {
319                 talloc_destroy(mem_ctx);
320                 return NULL;
321         }
322
323         /* send request and process the output */
324         req = smb_raw_setpathinfo_blob_send(tree, 
325                                             mem_ctx,
326                                             parms->generic.file.fname, 
327                                             parms->generic.level,
328                                             &blob);
329
330         talloc_destroy(mem_ctx);
331         return req;
332 }
333
334 /****************************************************************************
335  Set path info (sync interface)
336 ****************************************************************************/
337 NTSTATUS smb_raw_setpathinfo(struct smbcli_tree *tree,
338                              union smb_setfileinfo *parms)
339 {
340         struct smbcli_request *req = smb_raw_setpathinfo_send(tree, parms);
341         return smbcli_request_simple_recv(req);
342 }