s3:smb2_create: fix allocation size return value when opening existing files
[kai/samba.git] / source3 / smbd / smb2_create.c
1 /*
2    Unix SMB/CIFS implementation.
3    Core SMB2 server
4
5    Copyright (C) Stefan Metzmacher 2009
6    Copyright (C) Jeremy Allison 2010
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 "printing.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
26 #include "../libcli/smb/smb_common.h"
27 #include "../librpc/gen_ndr/ndr_security.h"
28 #include "../lib/util/tevent_ntstatus.h"
29
30 int map_smb2_oplock_levels_to_samba(uint8_t in_oplock_level)
31 {
32         switch(in_oplock_level) {
33         case SMB2_OPLOCK_LEVEL_NONE:
34                 return NO_OPLOCK;
35         case SMB2_OPLOCK_LEVEL_II:
36                 return LEVEL_II_OPLOCK;
37         case SMB2_OPLOCK_LEVEL_EXCLUSIVE:
38                 return EXCLUSIVE_OPLOCK;
39         case SMB2_OPLOCK_LEVEL_BATCH:
40                 return BATCH_OPLOCK;
41         case SMB2_OPLOCK_LEVEL_LEASE:
42                 DEBUG(2,("map_smb2_oplock_levels_to_samba: "
43                         "LEASE_OPLOCK_REQUESTED\n"));
44                 return NO_OPLOCK;
45         default:
46                 DEBUG(2,("map_smb2_oplock_levels_to_samba: "
47                         "unknown level %u\n",
48                         (unsigned int)in_oplock_level));
49                 return NO_OPLOCK;
50         }
51 }
52
53 static uint8_t map_samba_oplock_levels_to_smb2(int oplock_type)
54 {
55         if (BATCH_OPLOCK_TYPE(oplock_type)) {
56                 return SMB2_OPLOCK_LEVEL_BATCH;
57         } else if (EXCLUSIVE_OPLOCK_TYPE(oplock_type)) {
58                 return SMB2_OPLOCK_LEVEL_EXCLUSIVE;
59         } else if (oplock_type == LEVEL_II_OPLOCK) {
60                 /*
61                  * Don't use LEVEL_II_OPLOCK_TYPE here as
62                  * this also includes FAKE_LEVEL_II_OPLOCKs
63                  * which are internal only.
64                  */
65                 return SMB2_OPLOCK_LEVEL_II;
66         } else {
67                 return SMB2_OPLOCK_LEVEL_NONE;
68         }
69 }
70
71 static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
72                         struct tevent_context *ev,
73                         struct smbd_smb2_request *smb2req,
74                         uint8_t in_oplock_level,
75                         uint32_t in_impersonation_level,
76                         uint32_t in_desired_access,
77                         uint32_t in_file_attributes,
78                         uint32_t in_share_access,
79                         uint32_t in_create_disposition,
80                         uint32_t in_create_options,
81                         const char *in_name,
82                         struct smb2_create_blobs in_context_blobs);
83 static NTSTATUS smbd_smb2_create_recv(struct tevent_req *req,
84                         TALLOC_CTX *mem_ctx,
85                         uint8_t *out_oplock_level,
86                         uint32_t *out_create_action,
87                         NTTIME *out_creation_time,
88                         NTTIME *out_last_access_time,
89                         NTTIME *out_last_write_time,
90                         NTTIME *out_change_time,
91                         uint64_t *out_allocation_size,
92                         uint64_t *out_end_of_file,
93                         uint32_t *out_file_attributes,
94                         uint64_t *out_file_id_persistent,
95                         uint64_t *out_file_id_volatile,
96                         struct smb2_create_blobs *out_context_blobs);
97
98 static void smbd_smb2_request_create_done(struct tevent_req *tsubreq);
99 NTSTATUS smbd_smb2_request_process_create(struct smbd_smb2_request *smb2req)
100 {
101         const uint8_t *inbody;
102         int i = smb2req->current_idx;
103         uint8_t in_oplock_level;
104         uint32_t in_impersonation_level;
105         uint32_t in_desired_access;
106         uint32_t in_file_attributes;
107         uint32_t in_share_access;
108         uint32_t in_create_disposition;
109         uint32_t in_create_options;
110         uint16_t in_name_offset;
111         uint16_t in_name_length;
112         DATA_BLOB in_name_buffer;
113         char *in_name_string;
114         size_t in_name_string_size;
115         uint32_t name_offset = 0;
116         uint32_t name_available_length = 0;
117         uint32_t in_context_offset;
118         uint32_t in_context_length;
119         DATA_BLOB in_context_buffer;
120         struct smb2_create_blobs in_context_blobs;
121         uint32_t context_offset = 0;
122         uint32_t context_available_length = 0;
123         uint32_t dyn_offset;
124         NTSTATUS status;
125         bool ok;
126         struct tevent_req *tsubreq;
127
128         status = smbd_smb2_request_verify_sizes(smb2req, 0x39);
129         if (!NT_STATUS_IS_OK(status)) {
130                 return smbd_smb2_request_error(smb2req, status);
131         }
132         inbody = (const uint8_t *)smb2req->in.vector[i+1].iov_base;
133
134         in_oplock_level         = CVAL(inbody, 0x03);
135         in_impersonation_level  = IVAL(inbody, 0x04);
136         in_desired_access       = IVAL(inbody, 0x18);
137         in_file_attributes      = IVAL(inbody, 0x1C);
138         in_share_access         = IVAL(inbody, 0x20);
139         in_create_disposition   = IVAL(inbody, 0x24);
140         in_create_options       = IVAL(inbody, 0x28);
141         in_name_offset          = SVAL(inbody, 0x2C);
142         in_name_length          = SVAL(inbody, 0x2E);
143         in_context_offset       = IVAL(inbody, 0x30);
144         in_context_length       = IVAL(inbody, 0x34);
145
146         /*
147          * First check if the dynamic name and context buffers
148          * are correctly specified.
149          *
150          * Note: That we don't check if the name and context buffers
151          *       overlap
152          */
153
154         dyn_offset = SMB2_HDR_BODY + smb2req->in.vector[i+1].iov_len;
155
156         if (in_name_offset == 0 && in_name_length == 0) {
157                 /* This is ok */
158                 name_offset = 0;
159         } else if (in_name_offset < dyn_offset) {
160                 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
161         } else {
162                 name_offset = in_name_offset - dyn_offset;
163         }
164
165         if (name_offset > smb2req->in.vector[i+2].iov_len) {
166                 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
167         }
168
169         name_available_length = smb2req->in.vector[i+2].iov_len - name_offset;
170
171         if (in_name_length > name_available_length) {
172                 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
173         }
174
175         in_name_buffer.data = (uint8_t *)smb2req->in.vector[i+2].iov_base +
176                               name_offset;
177         in_name_buffer.length = in_name_length;
178
179         if (in_context_offset == 0 && in_context_length == 0) {
180                 /* This is ok */
181                 context_offset = 0;
182         } else if (in_context_offset < dyn_offset) {
183                 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
184         } else {
185                 context_offset = in_context_offset - dyn_offset;
186         }
187
188         if (context_offset > smb2req->in.vector[i+2].iov_len) {
189                 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
190         }
191
192         context_available_length = smb2req->in.vector[i+2].iov_len - context_offset;
193
194         if (in_context_length > context_available_length) {
195                 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
196         }
197
198         in_context_buffer.data = (uint8_t *)smb2req->in.vector[i+2].iov_base +
199                                   context_offset;
200         in_context_buffer.length = in_context_length;
201
202         /*
203          * Now interpret the name and context buffers
204          */
205
206         ok = convert_string_talloc(smb2req, CH_UTF16, CH_UNIX,
207                                    in_name_buffer.data,
208                                    in_name_buffer.length,
209                                    &in_name_string,
210                                    &in_name_string_size);
211         if (!ok) {
212                 return smbd_smb2_request_error(smb2req, NT_STATUS_ILLEGAL_CHARACTER);
213         }
214
215         if (in_name_buffer.length == 0) {
216                 in_name_string_size = 0;
217         }
218
219         if (strlen(in_name_string) != in_name_string_size) {
220                 return smbd_smb2_request_error(smb2req, NT_STATUS_OBJECT_NAME_INVALID);
221         }
222
223         ZERO_STRUCT(in_context_blobs);
224         status = smb2_create_blob_parse(smb2req, in_context_buffer, &in_context_blobs);
225         if (!NT_STATUS_IS_OK(status)) {
226                 return smbd_smb2_request_error(smb2req, status);
227         }
228
229         tsubreq = smbd_smb2_create_send(smb2req,
230                                        smb2req->sconn->smb2.event_ctx,
231                                        smb2req,
232                                        in_oplock_level,
233                                        in_impersonation_level,
234                                        in_desired_access,
235                                        in_file_attributes,
236                                        in_share_access,
237                                        in_create_disposition,
238                                        in_create_options,
239                                        in_name_string,
240                                        in_context_blobs);
241         if (tsubreq == NULL) {
242                 smb2req->subreq = NULL;
243                 return smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
244         }
245         tevent_req_set_callback(tsubreq, smbd_smb2_request_create_done, smb2req);
246
247         return smbd_smb2_request_pending_queue(smb2req, tsubreq);
248 }
249
250 static uint64_t get_mid_from_smb2req(struct smbd_smb2_request *smb2req)
251 {
252         uint8_t *reqhdr = (uint8_t *)smb2req->out.vector[smb2req->current_idx].iov_base;
253         return BVAL(reqhdr, SMB2_HDR_MESSAGE_ID);
254 }
255
256 static void smbd_smb2_request_create_done(struct tevent_req *tsubreq)
257 {
258         struct smbd_smb2_request *smb2req = tevent_req_callback_data(tsubreq,
259                                         struct smbd_smb2_request);
260         int i = smb2req->current_idx;
261         uint8_t *outhdr;
262         DATA_BLOB outbody;
263         DATA_BLOB outdyn;
264         uint8_t out_oplock_level = 0;
265         uint32_t out_create_action = 0;
266         NTTIME out_creation_time = 0;
267         NTTIME out_last_access_time = 0;
268         NTTIME out_last_write_time = 0;
269         NTTIME out_change_time = 0;
270         uint64_t out_allocation_size = 0;
271         uint64_t out_end_of_file = 0;
272         uint32_t out_file_attributes = 0;
273         uint64_t out_file_id_persistent = 0;
274         uint64_t out_file_id_volatile = 0;
275         struct smb2_create_blobs out_context_blobs;
276         DATA_BLOB out_context_buffer;
277         uint16_t out_context_buffer_offset = 0;
278         NTSTATUS status;
279         NTSTATUS error; /* transport error */
280
281         if (smb2req->cancelled) {
282                 uint64_t mid = get_mid_from_smb2req(smb2req);
283                 DEBUG(10,("smbd_smb2_request_create_done: cancelled mid %llu\n",
284                         (unsigned long long)mid ));
285                 error = smbd_smb2_request_error(smb2req, NT_STATUS_CANCELLED);
286                 if (!NT_STATUS_IS_OK(error)) {
287                         smbd_server_connection_terminate(smb2req->sconn,
288                                 nt_errstr(error));
289                         return;
290                 }
291                 return;
292         }
293
294         status = smbd_smb2_create_recv(tsubreq,
295                                        smb2req,
296                                        &out_oplock_level,
297                                        &out_create_action,
298                                        &out_creation_time,
299                                        &out_last_access_time,
300                                        &out_last_write_time,
301                                        &out_change_time,
302                                        &out_allocation_size,
303                                        &out_end_of_file,
304                                        &out_file_attributes,
305                                        &out_file_id_persistent,
306                                        &out_file_id_volatile,
307                                        &out_context_blobs);
308         if (!NT_STATUS_IS_OK(status)) {
309                 error = smbd_smb2_request_error(smb2req, status);
310                 if (!NT_STATUS_IS_OK(error)) {
311                         smbd_server_connection_terminate(smb2req->sconn,
312                                                          nt_errstr(error));
313                         return;
314                 }
315                 return;
316         }
317
318         status = smb2_create_blob_push(smb2req, &out_context_buffer, out_context_blobs);
319         if (!NT_STATUS_IS_OK(status)) {
320                 error = smbd_smb2_request_error(smb2req, status);
321                 if (!NT_STATUS_IS_OK(error)) {
322                         smbd_server_connection_terminate(smb2req->sconn,
323                                                          nt_errstr(error));
324                         return;
325                 }
326                 return;
327         }
328
329         if (out_context_buffer.length > 0) {
330                 out_context_buffer_offset = SMB2_HDR_BODY + 0x58;
331         }
332
333         outhdr = (uint8_t *)smb2req->out.vector[i].iov_base;
334
335         outbody = data_blob_talloc(smb2req->out.vector, NULL, 0x58);
336         if (outbody.data == NULL) {
337                 error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
338                 if (!NT_STATUS_IS_OK(error)) {
339                         smbd_server_connection_terminate(smb2req->sconn,
340                                                          nt_errstr(error));
341                         return;
342                 }
343                 return;
344         }
345
346         SSVAL(outbody.data, 0x00, 0x58 + 1);    /* struct size */
347         SCVAL(outbody.data, 0x02,
348               out_oplock_level);                /* oplock level */
349         SCVAL(outbody.data, 0x03, 0);           /* reserved */
350         SIVAL(outbody.data, 0x04,
351               out_create_action);               /* create action */
352         SBVAL(outbody.data, 0x08,
353               out_creation_time);               /* creation time */
354         SBVAL(outbody.data, 0x10,
355               out_last_access_time);            /* last access time */
356         SBVAL(outbody.data, 0x18,
357               out_last_write_time);             /* last write time */
358         SBVAL(outbody.data, 0x20,
359               out_change_time);                 /* change time */
360         SBVAL(outbody.data, 0x28,
361               out_allocation_size);             /* allocation size */
362         SBVAL(outbody.data, 0x30,
363               out_end_of_file);                 /* end of file */
364         SIVAL(outbody.data, 0x38,
365               out_file_attributes);             /* file attributes */
366         SIVAL(outbody.data, 0x3C, 0);           /* reserved */
367         SBVAL(outbody.data, 0x40,
368               out_file_id_persistent);          /* file id (persistent) */
369         SBVAL(outbody.data, 0x48,
370               out_file_id_volatile);            /* file id (volatile) */
371         SIVAL(outbody.data, 0x50,
372               out_context_buffer_offset);       /* create contexts offset */
373         SIVAL(outbody.data, 0x54,
374               out_context_buffer.length);       /* create contexts length */
375
376         outdyn = out_context_buffer;
377
378         error = smbd_smb2_request_done(smb2req, outbody, &outdyn);
379         if (!NT_STATUS_IS_OK(error)) {
380                 smbd_server_connection_terminate(smb2req->sconn,
381                                                  nt_errstr(error));
382                 return;
383         }
384 }
385
386 struct smbd_smb2_create_state {
387         struct smbd_smb2_request *smb2req;
388         struct smb_request *smb1req;
389         struct timed_event *te;
390         struct tevent_immediate *im;
391         struct timeval request_time;
392         struct file_id id;
393         DATA_BLOB private_data;
394         uint8_t out_oplock_level;
395         uint32_t out_create_action;
396         NTTIME out_creation_time;
397         NTTIME out_last_access_time;
398         NTTIME out_last_write_time;
399         NTTIME out_change_time;
400         uint64_t out_allocation_size;
401         uint64_t out_end_of_file;
402         uint32_t out_file_attributes;
403         uint64_t out_file_id_persistent;
404         uint64_t out_file_id_volatile;
405         struct smb2_create_blobs out_context_blobs;
406 };
407
408 static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
409                         struct tevent_context *ev,
410                         struct smbd_smb2_request *smb2req,
411                         uint8_t in_oplock_level,
412                         uint32_t in_impersonation_level,
413                         uint32_t in_desired_access,
414                         uint32_t in_file_attributes,
415                         uint32_t in_share_access,
416                         uint32_t in_create_disposition,
417                         uint32_t in_create_options,
418                         const char *in_name,
419                         struct smb2_create_blobs in_context_blobs)
420 {
421         struct tevent_req *req = NULL;
422         struct smbd_smb2_create_state *state = NULL;
423         NTSTATUS status;
424         struct smb_request *smb1req = NULL;
425         files_struct *result = NULL;
426         int info;
427         struct timespec write_time_ts;
428         struct smb2_create_blobs out_context_blobs;
429         int requested_oplock_level;
430
431         ZERO_STRUCT(out_context_blobs);
432
433         if(lp_fake_oplocks(SNUM(smb2req->tcon->compat_conn))) {
434                 requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
435         } else {
436                 requested_oplock_level = in_oplock_level;
437         }
438
439
440         if (!smb2req->async) {
441                 /* New create call. */
442                 req = tevent_req_create(mem_ctx, &state,
443                                 struct smbd_smb2_create_state);
444                 if (req == NULL) {
445                         return NULL;
446                 }
447                 state->smb2req = smb2req;
448                 smb2req->subreq = req; /* So we can find this when going async. */
449
450                 smb1req = smbd_smb2_fake_smb_request(smb2req);
451                 if (tevent_req_nomem(smb1req, req)) {
452                         return tevent_req_post(req, ev);
453                 }
454                 state->smb1req = smb1req;
455                 DEBUG(10,("smbd_smb2_create: name[%s]\n",
456                         in_name));
457         } else {
458                 /* Re-entrant create call. */
459                 req = smb2req->subreq;
460                 state = tevent_req_data(req,
461                                 struct smbd_smb2_create_state);
462                 smb1req = state->smb1req;
463                 DEBUG(10,("smbd_smb2_create_send: reentrant for file %s\n",
464                         in_name ));
465         }
466
467         if (IS_IPC(smb1req->conn)) {
468                 const char *pipe_name = in_name;
469
470                 if (!lp_nt_pipe_support()) {
471                         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
472                         return tevent_req_post(req, ev);
473                 }
474
475                 /* Strip \\ off the name. */
476                 if (pipe_name[0] == '\\') {
477                         pipe_name++;
478                 }
479
480                 status = open_np_file(smb1req, pipe_name, &result);
481                 if (!NT_STATUS_IS_OK(status)) {
482                         tevent_req_nterror(req, status);
483                         return tevent_req_post(req, ev);
484                 }
485                 info = FILE_WAS_OPENED;
486         } else if (CAN_PRINT(smb1req->conn)) {
487                 status = file_new(smb1req, smb1req->conn, &result);
488                 if(!NT_STATUS_IS_OK(status)) {
489                         tevent_req_nterror(req, status);
490                         return tevent_req_post(req, ev);
491                 }
492
493                 status = print_spool_open(result, in_name,
494                                           smb1req->vuid);
495                 if (!NT_STATUS_IS_OK(status)) {
496                         file_free(smb1req, result);
497                         tevent_req_nterror(req, status);
498                         return tevent_req_post(req, ev);
499                 }
500                 info = FILE_WAS_CREATED;
501         } else {
502                 char *fname;
503                 struct smb_filename *smb_fname = NULL;
504                 struct smb2_create_blob *exta = NULL;
505                 struct ea_list *ea_list = NULL;
506                 struct smb2_create_blob *mxac = NULL;
507                 NTTIME max_access_time = 0;
508                 struct smb2_create_blob *secd = NULL;
509                 struct security_descriptor *sec_desc = NULL;
510                 struct smb2_create_blob *dhnq = NULL;
511                 struct smb2_create_blob *dhnc = NULL;
512                 struct smb2_create_blob *alsi = NULL;
513                 uint64_t allocation_size = 0;
514                 struct smb2_create_blob *twrp = NULL;
515                 struct smb2_create_blob *qfid = NULL;
516
517                 exta = smb2_create_blob_find(&in_context_blobs,
518                                              SMB2_CREATE_TAG_EXTA);
519                 mxac = smb2_create_blob_find(&in_context_blobs,
520                                              SMB2_CREATE_TAG_MXAC);
521                 secd = smb2_create_blob_find(&in_context_blobs,
522                                              SMB2_CREATE_TAG_SECD);
523                 dhnq = smb2_create_blob_find(&in_context_blobs,
524                                              SMB2_CREATE_TAG_DHNQ);
525                 dhnc = smb2_create_blob_find(&in_context_blobs,
526                                              SMB2_CREATE_TAG_DHNC);
527                 alsi = smb2_create_blob_find(&in_context_blobs,
528                                              SMB2_CREATE_TAG_ALSI);
529                 twrp = smb2_create_blob_find(&in_context_blobs,
530                                              SMB2_CREATE_TAG_TWRP);
531                 qfid = smb2_create_blob_find(&in_context_blobs,
532                                              SMB2_CREATE_TAG_QFID);
533
534                 fname = talloc_strdup(state, in_name);
535                 if (tevent_req_nomem(fname, req)) {
536                         return tevent_req_post(req, ev);
537                 }
538
539                 if (exta) {
540                         if (dhnc) {
541                                 tevent_req_nterror(req,NT_STATUS_OBJECT_NAME_NOT_FOUND);
542                                 return tevent_req_post(req, ev);
543                         }
544
545                         ea_list = read_nttrans_ea_list(mem_ctx,
546                                 (const char *)exta->data.data, exta->data.length);
547                         if (!ea_list) {
548                                 DEBUG(10,("smbd_smb2_create_send: read_ea_name_list failed.\n"));
549                                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
550                                 return tevent_req_post(req, ev);
551                         }
552                 }
553
554                 if (mxac) {
555                         if (dhnc) {
556                                 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
557                                 return tevent_req_post(req, ev);
558                         }
559
560                         if (mxac->data.length == 0) {
561                                 max_access_time = 0;
562                         } else if (mxac->data.length == 8) {
563                                 max_access_time = BVAL(mxac->data.data, 0);
564                         } else {
565                                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
566                                 return tevent_req_post(req, ev);
567                         }
568                 }
569
570                 if (secd) {
571                         enum ndr_err_code ndr_err;
572
573                         if (dhnc) {
574                                 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
575                                 return tevent_req_post(req, ev);
576                         }
577
578                         sec_desc = talloc_zero(state, struct security_descriptor);
579                         if (tevent_req_nomem(sec_desc, req)) {
580                                 return tevent_req_post(req, ev);
581                         }
582
583                         ndr_err = ndr_pull_struct_blob(&secd->data,
584                                 sec_desc, sec_desc,
585                                 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
586                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
587                                 DEBUG(2,("ndr_pull_security_descriptor failed: %s\n",
588                                          ndr_errstr(ndr_err)));
589                                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
590                                 return tevent_req_post(req, ev);
591                         }
592                 }
593
594                 if (dhnq) {
595                         if (dhnc) {
596                                 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
597                                 return tevent_req_post(req, ev);
598                         }
599
600                         if (dhnq->data.length != 16) {
601                                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
602                                 return tevent_req_post(req, ev);
603                         }
604                         /*
605                          * we don't support durable handles yet
606                          * and have to ignore this
607                          */
608                 }
609
610                 if (dhnc) {
611                         if (dhnc->data.length != 16) {
612                                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
613                                 return tevent_req_post(req, ev);
614                         }
615                         /* we don't support durable handles yet */
616                         tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
617                         return tevent_req_post(req, ev);
618                 }
619
620                 if (alsi) {
621                         if (dhnc) {
622                                 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
623                                 return tevent_req_post(req, ev);
624                         }
625
626                         if (alsi->data.length != 8) {
627                                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
628                                 return tevent_req_post(req, ev);
629                         }
630                         allocation_size = BVAL(alsi->data.data, 0);
631                 }
632
633                 if (twrp) {
634                         NTTIME nttime;
635                         time_t t;
636                         struct tm *tm;
637
638                         if (dhnc) {
639                                 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
640                                 return tevent_req_post(req, ev);
641                         }
642
643                         if (twrp->data.length != 8) {
644                                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
645                                 return tevent_req_post(req, ev);
646                         }
647
648                         nttime = BVAL(twrp->data.data, 0);
649                         t = nt_time_to_unix(nttime);
650                         tm = gmtime(&t);
651
652                         TALLOC_FREE(fname);
653                         fname = talloc_asprintf(state,
654                                         "@GMT-%04u.%02u.%02u-%02u.%02u.%02u\\%s",
655                                         tm->tm_year + 1900,
656                                         tm->tm_mon + 1,
657                                         tm->tm_mday,
658                                         tm->tm_hour,
659                                         tm->tm_min,
660                                         tm->tm_sec,
661                                         in_name);
662                         if (tevent_req_nomem(fname, req)) {
663                                 return tevent_req_post(req, ev);
664                         }
665                 }
666
667                 if (qfid) {
668                         if (qfid->data.length != 0) {
669                                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
670                                 return tevent_req_post(req, ev);
671                         }
672                 }
673
674                 /* these are ignored for SMB2 */
675                 in_create_options &= ~(0x10);/* NTCREATEX_OPTIONS_SYNC_ALERT */
676                 in_create_options &= ~(0x20);/* NTCREATEX_OPTIONS_ASYNC_ALERT */
677
678                 /*
679                  * For a DFS path the function parse_dfs_path()
680                  * will do the path processing.
681                  */
682
683                 if (!(smb1req->flags2 & FLAGS2_DFS_PATHNAMES)) {
684                         /* convert '\\' into '/' */
685                         status = check_path_syntax(fname);
686                         if (!NT_STATUS_IS_OK(status)) {
687                                 tevent_req_nterror(req, status);
688                                 return tevent_req_post(req, ev);
689                         }
690                 }
691
692                 status = filename_convert(req,
693                                           smb1req->conn,
694                                           smb1req->flags2 & FLAGS2_DFS_PATHNAMES,
695                                           fname,
696                                           0,
697                                           NULL,
698                                           &smb_fname);
699                 if (!NT_STATUS_IS_OK(status)) {
700                         tevent_req_nterror(req, status);
701                         return tevent_req_post(req, ev);
702                 }
703
704                 in_file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS;
705
706                 status = SMB_VFS_CREATE_FILE(smb1req->conn,
707                                              smb1req,
708                                              0, /* root_dir_fid */
709                                              smb_fname,
710                                              in_desired_access,
711                                              in_share_access,
712                                              in_create_disposition,
713                                              in_create_options,
714                                              in_file_attributes,
715                                              map_smb2_oplock_levels_to_samba(requested_oplock_level),
716                                              allocation_size,
717                                              0, /* private_flags */
718                                              sec_desc,
719                                              ea_list,
720                                              &result,
721                                              &info);
722                 if (!NT_STATUS_IS_OK(status)) {
723                         if (open_was_deferred(smb1req->sconn, smb1req->mid)) {
724                                 return req;
725                         }
726                         tevent_req_nterror(req, status);
727                         return tevent_req_post(req, ev);
728                 }
729
730                 if (mxac) {
731                         NTTIME last_write_time;
732
733                         unix_timespec_to_nt_time(&last_write_time,
734                                                  result->fsp_name->st.st_ex_mtime);
735                         if (last_write_time != max_access_time) {
736                                 uint8_t p[8];
737                                 uint32_t max_access_granted;
738                                 DATA_BLOB blob = data_blob_const(p, sizeof(p));
739
740                                 status = smbd_calculate_access_mask(smb1req->conn,
741                                                         result->fsp_name,
742                                                         /*
743                                                          * at this stage
744                                                          * it exists
745                                                          */
746                                                         true,
747                                                         SEC_FLAG_MAXIMUM_ALLOWED,
748                                                         &max_access_granted);
749
750                                 SIVAL(p, 0, NT_STATUS_V(status));
751                                 SIVAL(p, 4, max_access_granted);
752
753                                 status = smb2_create_blob_add(state,
754                                                         &out_context_blobs,
755                                                         SMB2_CREATE_TAG_MXAC,
756                                                         blob);
757                                 if (!NT_STATUS_IS_OK(status)) {
758                                         tevent_req_nterror(req, status);
759                                         return tevent_req_post(req, ev);
760                                 }
761                         }
762                 }
763
764                 if (qfid) {
765                         uint8_t p[32];
766                         uint64_t file_index = get_FileIndex(result->conn,
767                                                         &result->fsp_name->st);
768                         DATA_BLOB blob = data_blob_const(p, sizeof(p));
769
770                         ZERO_STRUCT(p);
771
772                         /* From conversations with Microsoft engineers at
773                            the MS plugfest. The first 8 bytes are the "volume index"
774                            == inode, the second 8 bytes are the "volume id",
775                            == dev. This will be updated in the SMB2 doc. */
776                         SBVAL(p, 0, file_index);
777                         SIVAL(p, 8, result->fsp_name->st.st_ex_dev);/* FileIndexHigh */
778
779                         status = smb2_create_blob_add(state, &out_context_blobs,
780                                                       SMB2_CREATE_TAG_QFID,
781                                                       blob);
782                         if (!NT_STATUS_IS_OK(status)) {
783                                 tevent_req_nterror(req, status);
784                                 return tevent_req_post(req, ev);
785                         }
786                 }
787         }
788
789         smb2req->compat_chain_fsp = smb1req->chain_fsp;
790
791         if(lp_fake_oplocks(SNUM(smb2req->tcon->compat_conn))) {
792                 state->out_oplock_level = in_oplock_level;
793         } else {
794                 state->out_oplock_level = map_samba_oplock_levels_to_smb2(result->oplock_type);
795         }
796
797         if ((in_create_disposition == FILE_SUPERSEDE)
798             && (info == FILE_WAS_OVERWRITTEN)) {
799                 state->out_create_action = FILE_WAS_SUPERSEDED;
800         } else {
801                 state->out_create_action = info;
802         }
803         state->out_file_attributes = dos_mode(result->conn,
804                                            result->fsp_name);
805         /* Deal with other possible opens having a modified
806            write time. JRA. */
807         ZERO_STRUCT(write_time_ts);
808         get_file_infos(result->file_id, 0, NULL, &write_time_ts);
809         if (!null_timespec(write_time_ts)) {
810                 update_stat_ex_mtime(&result->fsp_name->st, write_time_ts);
811         }
812
813         unix_timespec_to_nt_time(&state->out_creation_time,
814                         get_create_timespec(smb1req->conn, result,
815                                         result->fsp_name));
816         unix_timespec_to_nt_time(&state->out_last_access_time,
817                         result->fsp_name->st.st_ex_atime);
818         unix_timespec_to_nt_time(&state->out_last_write_time,
819                         result->fsp_name->st.st_ex_mtime);
820         unix_timespec_to_nt_time(&state->out_change_time,
821                         get_change_timespec(smb1req->conn, result,
822                                         result->fsp_name));
823         state->out_allocation_size =
824                         SMB_VFS_GET_ALLOC_SIZE(smb1req->conn, result,
825                                                &(result->fsp_name->st));
826         state->out_end_of_file = result->fsp_name->st.st_ex_size;
827         if (state->out_file_attributes == 0) {
828                 state->out_file_attributes = FILE_ATTRIBUTE_NORMAL;
829         }
830         state->out_file_id_persistent = result->fnum;
831         state->out_file_id_volatile = result->fnum;
832         state->out_context_blobs = out_context_blobs;
833
834         tevent_req_done(req);
835         return tevent_req_post(req, ev);
836 }
837
838 static NTSTATUS smbd_smb2_create_recv(struct tevent_req *req,
839                         TALLOC_CTX *mem_ctx,
840                         uint8_t *out_oplock_level,
841                         uint32_t *out_create_action,
842                         NTTIME *out_creation_time,
843                         NTTIME *out_last_access_time,
844                         NTTIME *out_last_write_time,
845                         NTTIME *out_change_time,
846                         uint64_t *out_allocation_size,
847                         uint64_t *out_end_of_file,
848                         uint32_t *out_file_attributes,
849                         uint64_t *out_file_id_persistent,
850                         uint64_t *out_file_id_volatile,
851                         struct smb2_create_blobs *out_context_blobs)
852 {
853         NTSTATUS status;
854         struct smbd_smb2_create_state *state = tevent_req_data(req,
855                                                struct smbd_smb2_create_state);
856
857         if (tevent_req_is_nterror(req, &status)) {
858                 tevent_req_received(req);
859                 return status;
860         }
861
862         *out_oplock_level       = state->out_oplock_level;
863         *out_create_action      = state->out_create_action;
864         *out_creation_time      = state->out_creation_time;
865         *out_last_access_time   = state->out_last_access_time;
866         *out_last_write_time    = state->out_last_write_time;
867         *out_change_time        = state->out_change_time;
868         *out_allocation_size    = state->out_allocation_size;
869         *out_end_of_file        = state->out_end_of_file;
870         *out_file_attributes    = state->out_file_attributes;
871         *out_file_id_persistent = state->out_file_id_persistent;
872         *out_file_id_volatile   = state->out_file_id_volatile;
873         *out_context_blobs      = state->out_context_blobs;
874
875         talloc_steal(mem_ctx, state->out_context_blobs.blobs);
876
877         tevent_req_received(req);
878         return NT_STATUS_OK;
879 }
880
881 /*********************************************************
882  Code for dealing with deferred opens.
883 *********************************************************/
884
885 bool get_deferred_open_message_state_smb2(struct smbd_smb2_request *smb2req,
886                         struct timeval *p_request_time,
887                         void **pp_state)
888 {
889         struct smbd_smb2_create_state *state = NULL;
890         struct tevent_req *req = NULL;
891
892         if (!smb2req) {
893                 return false;
894         }
895         if (!smb2req->async) {
896                 return false;
897         }
898         req = smb2req->subreq;
899         if (!req) {
900                 return false;
901         }
902         state = tevent_req_data(req, struct smbd_smb2_create_state);
903         if (!state) {
904                 return false;
905         }
906         if (p_request_time) {
907                 *p_request_time = state->request_time;
908         }
909         if (pp_state) {
910                 *pp_state = (void *)state->private_data.data;
911         }
912         return true;
913 }
914
915 /*********************************************************
916  Re-process this call early - requested by message or
917  close.
918 *********************************************************/
919
920 static struct smbd_smb2_request *find_open_smb2req(
921         struct smbd_server_connection *sconn, uint64_t mid)
922 {
923         struct smbd_smb2_request *smb2req;
924
925         for (smb2req = sconn->smb2.requests; smb2req; smb2req = smb2req->next) {
926                 uint64_t message_id;
927                 if (smb2req->subreq == NULL) {
928                         /* This message has been processed. */
929                         continue;
930                 }
931                 if (!tevent_req_is_in_progress(smb2req->subreq)) {
932                         /* This message has been processed. */
933                         continue;
934                 }
935                 message_id = get_mid_from_smb2req(smb2req);
936                 if (message_id == mid) {
937                         return smb2req;
938                 }
939         }
940         return NULL;
941 }
942
943 bool open_was_deferred_smb2(struct smbd_server_connection *sconn, uint64_t mid)
944 {
945         struct smbd_smb2_create_state *state = NULL;
946         struct smbd_smb2_request *smb2req;
947
948         smb2req = find_open_smb2req(sconn, mid);
949
950         if (!smb2req) {
951                 DEBUG(10,("open_was_deferred_smb2: mid %llu smb2req == NULL\n",
952                         (unsigned long long)mid));
953                 return false;
954         }
955         if (!smb2req->subreq) {
956                 return false;
957         }
958         if (!tevent_req_is_in_progress(smb2req->subreq)) {
959                 return false;
960         }
961         state = tevent_req_data(smb2req->subreq,
962                         struct smbd_smb2_create_state);
963         if (!state) {
964                 return false;
965         }
966         /* It's not in progress if there's no timeout event. */
967         if (!state->te) {
968                 return false;
969         }
970
971         DEBUG(10,("open_was_deferred_smb2: mid = %llu\n",
972                         (unsigned long long)mid));
973
974         return true;
975 }
976
977 static void remove_deferred_open_message_smb2_internal(struct smbd_smb2_request *smb2req,
978                                                         uint64_t mid)
979 {
980         struct smbd_smb2_create_state *state = NULL;
981
982         if (!smb2req->subreq) {
983                 return;
984         }
985         if (!tevent_req_is_in_progress(smb2req->subreq)) {
986                 return;
987         }
988         state = tevent_req_data(smb2req->subreq,
989                         struct smbd_smb2_create_state);
990         if (!state) {
991                 return;
992         }
993
994         DEBUG(10,("remove_deferred_open_message_smb2_internal: "
995                 "mid %llu\n",
996                 (unsigned long long)mid ));
997
998         /* Ensure we don't have any outstanding timer event. */
999         TALLOC_FREE(state->te);
1000         /* Ensure we don't have any outstanding immediate event. */
1001         TALLOC_FREE(state->im);
1002 }
1003
1004 void remove_deferred_open_message_smb2(
1005         struct smbd_server_connection *sconn, uint64_t mid)
1006 {
1007         struct smbd_smb2_request *smb2req;
1008
1009         smb2req = find_open_smb2req(sconn, mid);
1010
1011         if (!smb2req) {
1012                 DEBUG(10,("remove_deferred_open_message_smb2: "
1013                         "can't find mid %llu\n",
1014                         (unsigned long long)mid ));
1015                 return;
1016         }
1017         remove_deferred_open_message_smb2_internal(smb2req, mid);
1018 }
1019
1020 static void smbd_smb2_create_request_dispatch_immediate(struct tevent_context *ctx,
1021                                         struct tevent_immediate *im,
1022                                         void *private_data)
1023 {
1024         struct smbd_smb2_request *smb2req = talloc_get_type_abort(private_data,
1025                                         struct smbd_smb2_request);
1026         struct smbd_server_connection *sconn = smb2req->sconn;
1027         uint64_t mid = get_mid_from_smb2req(smb2req);
1028         NTSTATUS status;
1029
1030         DEBUG(10,("smbd_smb2_create_request_dispatch_immediate: "
1031                 "re-dispatching mid %llu\n",
1032                 (unsigned long long)mid ));
1033
1034         status = smbd_smb2_request_dispatch(smb2req);
1035         if (!NT_STATUS_IS_OK(status)) {
1036                 smbd_server_connection_terminate(sconn, nt_errstr(status));
1037                 return;
1038         }
1039 }
1040
1041 void schedule_deferred_open_message_smb2(
1042         struct smbd_server_connection *sconn, uint64_t mid)
1043 {
1044         struct smbd_smb2_create_state *state = NULL;
1045         struct smbd_smb2_request *smb2req;
1046
1047         smb2req = find_open_smb2req(sconn, mid);
1048
1049         if (!smb2req) {
1050                 DEBUG(10,("schedule_deferred_open_message_smb2: "
1051                         "can't find mid %llu\n",
1052                         (unsigned long long)mid ));
1053                 return;
1054         }
1055         if (!smb2req->subreq) {
1056                 return;
1057         }
1058         if (!tevent_req_is_in_progress(smb2req->subreq)) {
1059                 return;
1060         }
1061         state = tevent_req_data(smb2req->subreq,
1062                         struct smbd_smb2_create_state);
1063         if (!state) {
1064                 return;
1065         }
1066
1067         /* Ensure we don't have any outstanding timer event. */
1068         TALLOC_FREE(state->te);
1069         /* Ensure we don't have any outstanding immediate event. */
1070         TALLOC_FREE(state->im);
1071
1072         /*
1073          * This is subtle. We must null out the callback
1074          * before resheduling, else the first call to
1075          * tevent_req_nterror() causes the _receive()
1076          * function to be called, this causing tevent_req_post()
1077          * to crash.
1078          */
1079         tevent_req_set_callback(smb2req->subreq, NULL, NULL);
1080
1081         state->im = tevent_create_immediate(smb2req);
1082         if (!state->im) {
1083                 smbd_server_connection_terminate(smb2req->sconn,
1084                         nt_errstr(NT_STATUS_NO_MEMORY));
1085                 return;
1086         }
1087
1088         DEBUG(10,("schedule_deferred_open_message_smb2: "
1089                 "re-processing mid %llu\n",
1090                 (unsigned long long)mid ));
1091
1092         tevent_schedule_immediate(state->im,
1093                         smb2req->sconn->smb2.event_ctx,
1094                         smbd_smb2_create_request_dispatch_immediate,
1095                         smb2req);
1096 }
1097
1098 /*********************************************************
1099  Re-process this call.
1100 *********************************************************/
1101
1102 static void smb2_deferred_open_timer(struct event_context *ev,
1103                                         struct timed_event *te,
1104                                         struct timeval _tval,
1105                                         void *private_data)
1106 {
1107         NTSTATUS status;
1108         struct smbd_smb2_create_state *state = NULL;
1109         struct smbd_smb2_request *smb2req = talloc_get_type(private_data,
1110                                                 struct smbd_smb2_request);
1111
1112         DEBUG(10,("smb2_deferred_open_timer: [idx=%d], %s\n",
1113                 smb2req->current_idx,
1114                 tevent_req_default_print(smb2req->subreq, talloc_tos()) ));
1115
1116         state = tevent_req_data(smb2req->subreq,
1117                         struct smbd_smb2_create_state);
1118         if (!state) {
1119                 return;
1120         }
1121         /*
1122          * Null this out, don't talloc_free. It will
1123          * be talloc_free'd by the tevent library when
1124          * this returns.
1125          */
1126         state->te = NULL;
1127         /* Ensure we don't have any outstanding immediate event. */
1128         TALLOC_FREE(state->im);
1129
1130         /*
1131          * This is subtle. We must null out the callback
1132          * before resheduling, else the first call to
1133          * tevent_req_nterror() causes the _receive()
1134          * function to be called, this causing tevent_req_post()
1135          * to crash.
1136          */
1137         tevent_req_set_callback(smb2req->subreq, NULL, NULL);
1138
1139         status = smbd_smb2_request_dispatch(smb2req);
1140
1141         if (!NT_STATUS_IS_OK(status)) {
1142                 smbd_server_connection_terminate(smb2req->sconn,
1143                                 nt_errstr(status));
1144         }
1145 }
1146
1147 static bool smbd_smb2_create_cancel(struct tevent_req *req)
1148 {
1149         struct smbd_smb2_request *smb2req = NULL;
1150         struct smbd_smb2_create_state *state = tevent_req_data(req,
1151                                 struct smbd_smb2_create_state);
1152         uint64_t mid;
1153
1154         if (!state) {
1155                 return false;
1156         }
1157
1158         if (!state->smb2req) {
1159                 return false;
1160         }
1161
1162         smb2req = state->smb2req;
1163         mid = get_mid_from_smb2req(smb2req);
1164
1165         remove_deferred_open_entry(state->id, mid,
1166                                    sconn_server_id(smb2req->sconn));
1167         remove_deferred_open_message_smb2_internal(smb2req, mid);
1168         smb2req->cancelled = true;
1169
1170         tevent_req_done(req);
1171         return true;
1172 }
1173
1174 bool push_deferred_open_message_smb2(struct smbd_smb2_request *smb2req,
1175                                 struct timeval request_time,
1176                                 struct timeval timeout,
1177                                 struct file_id id,
1178                                 char *private_data,
1179                                 size_t priv_len)
1180 {
1181         struct tevent_req *req = NULL;
1182         struct smbd_smb2_create_state *state = NULL;
1183         struct timeval end_time;
1184
1185         if (!smb2req) {
1186                 return false;
1187         }
1188         req = smb2req->subreq;
1189         if (!req) {
1190                 return false;
1191         }
1192         state = tevent_req_data(req, struct smbd_smb2_create_state);
1193         if (!state) {
1194                 return false;
1195         }
1196         state->id = id;
1197         state->request_time = request_time;
1198         state->private_data = data_blob_talloc(state, private_data,
1199                                                 priv_len);
1200         if (!state->private_data.data) {
1201                 return false;
1202         }
1203
1204 #if 1
1205         /* Boo - turns out this isn't what W2K8R2
1206            does. It actually sends the STATUS_PENDING
1207            message followed by the STATUS_SHARING_VIOLATION
1208            message. Surely this means that all open
1209            calls (even on directories) will potentially
1210            fail in a chain.... ? And I've seen directory
1211            opens as the start of a chain. JRA.
1212
1213            Update: 19th May 2010. Talking with Microsoft
1214            engineers at the plugfest this is a bug in
1215            Windows. Re-enable this code.
1216         */
1217         /*
1218          * More subtlety. To match W2K8R2 don't
1219          * send a "gone async" message if it's simply
1220          * a STATUS_SHARING_VIOLATION (short) wait, not
1221          * an oplock break wait. We do this by prematurely
1222          * setting smb2req->async flag.
1223          */
1224         if (timeout.tv_sec < 2) {
1225                 DEBUG(10,("push_deferred_open_message_smb2: "
1226                         "short timer wait (usec = %u). "
1227                         "Don't send async message.\n",
1228                         (unsigned int)timeout.tv_usec ));
1229                 smb2req->async = true;
1230         }
1231 #endif
1232
1233         /* Re-schedule us to retry on timer expiry. */
1234         end_time = timeval_sum(&request_time, &timeout);
1235
1236         DEBUG(10,("push_deferred_open_message_smb2: "
1237                 "timeout at %s\n",
1238                 timeval_string(talloc_tos(),
1239                                 &end_time,
1240                                 true) ));
1241
1242         state->te = event_add_timed(smb2req->sconn->smb2.event_ctx,
1243                                 state,
1244                                 end_time,
1245                                 smb2_deferred_open_timer,
1246                                 smb2req);
1247         if (!state->te) {
1248                 return false;
1249         }
1250
1251         /* allow this request to be canceled */
1252         tevent_req_set_cancel_fn(req, smbd_smb2_create_cancel);
1253
1254         return true;
1255 }