302cfd7035a43361b771e7e4043a583534ab5c05
[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->ev_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         /*
248          * For now we keep the logic that we do not send STATUS_PENDING
249          * for sharing violations, so we just wait 2 seconds.
250          *
251          * TODO: we need more tests for this.
252          */
253         return smbd_smb2_request_pending_queue(smb2req, tsubreq, 2000000);
254 }
255
256 static uint64_t get_mid_from_smb2req(struct smbd_smb2_request *smb2req)
257 {
258         uint8_t *reqhdr = (uint8_t *)smb2req->out.vector[smb2req->current_idx].iov_base;
259         return BVAL(reqhdr, SMB2_HDR_MESSAGE_ID);
260 }
261
262 static void smbd_smb2_request_create_done(struct tevent_req *tsubreq)
263 {
264         struct smbd_smb2_request *smb2req = tevent_req_callback_data(tsubreq,
265                                         struct smbd_smb2_request);
266         int i = smb2req->current_idx;
267         uint8_t *outhdr;
268         DATA_BLOB outbody;
269         DATA_BLOB outdyn;
270         uint8_t out_oplock_level = 0;
271         uint32_t out_create_action = 0;
272         NTTIME out_creation_time = 0;
273         NTTIME out_last_access_time = 0;
274         NTTIME out_last_write_time = 0;
275         NTTIME out_change_time = 0;
276         uint64_t out_allocation_size = 0;
277         uint64_t out_end_of_file = 0;
278         uint32_t out_file_attributes = 0;
279         uint64_t out_file_id_persistent = 0;
280         uint64_t out_file_id_volatile = 0;
281         struct smb2_create_blobs out_context_blobs;
282         DATA_BLOB out_context_buffer;
283         uint16_t out_context_buffer_offset = 0;
284         NTSTATUS status;
285         NTSTATUS error; /* transport error */
286
287         if (smb2req->cancelled) {
288                 uint64_t mid = get_mid_from_smb2req(smb2req);
289                 DEBUG(10,("smbd_smb2_request_create_done: cancelled mid %llu\n",
290                         (unsigned long long)mid ));
291                 error = smbd_smb2_request_error(smb2req, NT_STATUS_CANCELLED);
292                 if (!NT_STATUS_IS_OK(error)) {
293                         smbd_server_connection_terminate(smb2req->sconn,
294                                 nt_errstr(error));
295                         return;
296                 }
297                 return;
298         }
299
300         status = smbd_smb2_create_recv(tsubreq,
301                                        smb2req,
302                                        &out_oplock_level,
303                                        &out_create_action,
304                                        &out_creation_time,
305                                        &out_last_access_time,
306                                        &out_last_write_time,
307                                        &out_change_time,
308                                        &out_allocation_size,
309                                        &out_end_of_file,
310                                        &out_file_attributes,
311                                        &out_file_id_persistent,
312                                        &out_file_id_volatile,
313                                        &out_context_blobs);
314         if (!NT_STATUS_IS_OK(status)) {
315                 error = smbd_smb2_request_error(smb2req, status);
316                 if (!NT_STATUS_IS_OK(error)) {
317                         smbd_server_connection_terminate(smb2req->sconn,
318                                                          nt_errstr(error));
319                         return;
320                 }
321                 return;
322         }
323
324         status = smb2_create_blob_push(smb2req, &out_context_buffer, out_context_blobs);
325         if (!NT_STATUS_IS_OK(status)) {
326                 error = smbd_smb2_request_error(smb2req, status);
327                 if (!NT_STATUS_IS_OK(error)) {
328                         smbd_server_connection_terminate(smb2req->sconn,
329                                                          nt_errstr(error));
330                         return;
331                 }
332                 return;
333         }
334
335         if (out_context_buffer.length > 0) {
336                 out_context_buffer_offset = SMB2_HDR_BODY + 0x58;
337         }
338
339         outhdr = (uint8_t *)smb2req->out.vector[i].iov_base;
340
341         outbody = data_blob_talloc(smb2req->out.vector, NULL, 0x58);
342         if (outbody.data == NULL) {
343                 error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
344                 if (!NT_STATUS_IS_OK(error)) {
345                         smbd_server_connection_terminate(smb2req->sconn,
346                                                          nt_errstr(error));
347                         return;
348                 }
349                 return;
350         }
351
352         SSVAL(outbody.data, 0x00, 0x58 + 1);    /* struct size */
353         SCVAL(outbody.data, 0x02,
354               out_oplock_level);                /* oplock level */
355         SCVAL(outbody.data, 0x03, 0);           /* reserved */
356         SIVAL(outbody.data, 0x04,
357               out_create_action);               /* create action */
358         SBVAL(outbody.data, 0x08,
359               out_creation_time);               /* creation time */
360         SBVAL(outbody.data, 0x10,
361               out_last_access_time);            /* last access time */
362         SBVAL(outbody.data, 0x18,
363               out_last_write_time);             /* last write time */
364         SBVAL(outbody.data, 0x20,
365               out_change_time);                 /* change time */
366         SBVAL(outbody.data, 0x28,
367               out_allocation_size);             /* allocation size */
368         SBVAL(outbody.data, 0x30,
369               out_end_of_file);                 /* end of file */
370         SIVAL(outbody.data, 0x38,
371               out_file_attributes);             /* file attributes */
372         SIVAL(outbody.data, 0x3C, 0);           /* reserved */
373         SBVAL(outbody.data, 0x40,
374               out_file_id_persistent);          /* file id (persistent) */
375         SBVAL(outbody.data, 0x48,
376               out_file_id_volatile);            /* file id (volatile) */
377         SIVAL(outbody.data, 0x50,
378               out_context_buffer_offset);       /* create contexts offset */
379         SIVAL(outbody.data, 0x54,
380               out_context_buffer.length);       /* create contexts length */
381
382         outdyn = out_context_buffer;
383
384         error = smbd_smb2_request_done(smb2req, outbody, &outdyn);
385         if (!NT_STATUS_IS_OK(error)) {
386                 smbd_server_connection_terminate(smb2req->sconn,
387                                                  nt_errstr(error));
388                 return;
389         }
390 }
391
392 struct smbd_smb2_create_state {
393         struct smbd_smb2_request *smb2req;
394         struct smb_request *smb1req;
395         struct timed_event *te;
396         struct tevent_immediate *im;
397         struct timeval request_time;
398         struct file_id id;
399         DATA_BLOB private_data;
400         uint8_t out_oplock_level;
401         uint32_t out_create_action;
402         NTTIME out_creation_time;
403         NTTIME out_last_access_time;
404         NTTIME out_last_write_time;
405         NTTIME out_change_time;
406         uint64_t out_allocation_size;
407         uint64_t out_end_of_file;
408         uint32_t out_file_attributes;
409         uint64_t out_file_id_persistent;
410         uint64_t out_file_id_volatile;
411         struct smb2_create_blobs out_context_blobs;
412 };
413
414 static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
415                         struct tevent_context *ev,
416                         struct smbd_smb2_request *smb2req,
417                         uint8_t in_oplock_level,
418                         uint32_t in_impersonation_level,
419                         uint32_t in_desired_access,
420                         uint32_t in_file_attributes,
421                         uint32_t in_share_access,
422                         uint32_t in_create_disposition,
423                         uint32_t in_create_options,
424                         const char *in_name,
425                         struct smb2_create_blobs in_context_blobs)
426 {
427         struct tevent_req *req = NULL;
428         struct smbd_smb2_create_state *state = NULL;
429         NTSTATUS status;
430         struct smb_request *smb1req = NULL;
431         files_struct *result = NULL;
432         int info;
433         struct timespec write_time_ts;
434         struct smb2_create_blobs out_context_blobs;
435         int requested_oplock_level;
436
437         ZERO_STRUCT(out_context_blobs);
438
439         if(lp_fake_oplocks(SNUM(smb2req->tcon->compat_conn))) {
440                 requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
441         } else {
442                 requested_oplock_level = in_oplock_level;
443         }
444
445
446         if (smb2req->subreq == NULL) {
447                 /* New create call. */
448                 req = tevent_req_create(mem_ctx, &state,
449                                 struct smbd_smb2_create_state);
450                 if (req == NULL) {
451                         return NULL;
452                 }
453                 state->smb2req = smb2req;
454
455                 smb1req = smbd_smb2_fake_smb_request(smb2req);
456                 if (tevent_req_nomem(smb1req, req)) {
457                         return tevent_req_post(req, ev);
458                 }
459                 state->smb1req = smb1req;
460                 DEBUG(10,("smbd_smb2_create: name[%s]\n",
461                         in_name));
462         } else {
463                 /* Re-entrant create call. */
464                 req = smb2req->subreq;
465                 state = tevent_req_data(req,
466                                 struct smbd_smb2_create_state);
467                 smb1req = state->smb1req;
468                 DEBUG(10,("smbd_smb2_create_send: reentrant for file %s\n",
469                         in_name ));
470         }
471
472         if (IS_IPC(smb1req->conn)) {
473                 const char *pipe_name = in_name;
474
475                 if (!lp_nt_pipe_support()) {
476                         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
477                         return tevent_req_post(req, ev);
478                 }
479
480                 /* Strip \\ off the name. */
481                 if (pipe_name[0] == '\\') {
482                         pipe_name++;
483                 }
484
485                 status = open_np_file(smb1req, pipe_name, &result);
486                 if (!NT_STATUS_IS_OK(status)) {
487                         tevent_req_nterror(req, status);
488                         return tevent_req_post(req, ev);
489                 }
490                 info = FILE_WAS_OPENED;
491         } else if (CAN_PRINT(smb1req->conn)) {
492                 status = file_new(smb1req, smb1req->conn, &result);
493                 if(!NT_STATUS_IS_OK(status)) {
494                         tevent_req_nterror(req, status);
495                         return tevent_req_post(req, ev);
496                 }
497
498                 status = print_spool_open(result, in_name,
499                                           smb1req->vuid);
500                 if (!NT_STATUS_IS_OK(status)) {
501                         file_free(smb1req, result);
502                         tevent_req_nterror(req, status);
503                         return tevent_req_post(req, ev);
504                 }
505                 info = FILE_WAS_CREATED;
506         } else {
507                 char *fname;
508                 struct smb_filename *smb_fname = NULL;
509                 struct smb2_create_blob *exta = NULL;
510                 struct ea_list *ea_list = NULL;
511                 struct smb2_create_blob *mxac = NULL;
512                 NTTIME max_access_time = 0;
513                 struct smb2_create_blob *secd = NULL;
514                 struct security_descriptor *sec_desc = NULL;
515                 struct smb2_create_blob *dhnq = NULL;
516                 struct smb2_create_blob *dhnc = NULL;
517                 struct smb2_create_blob *alsi = NULL;
518                 uint64_t allocation_size = 0;
519                 struct smb2_create_blob *twrp = NULL;
520                 struct smb2_create_blob *qfid = NULL;
521
522                 exta = smb2_create_blob_find(&in_context_blobs,
523                                              SMB2_CREATE_TAG_EXTA);
524                 mxac = smb2_create_blob_find(&in_context_blobs,
525                                              SMB2_CREATE_TAG_MXAC);
526                 secd = smb2_create_blob_find(&in_context_blobs,
527                                              SMB2_CREATE_TAG_SECD);
528                 dhnq = smb2_create_blob_find(&in_context_blobs,
529                                              SMB2_CREATE_TAG_DHNQ);
530                 dhnc = smb2_create_blob_find(&in_context_blobs,
531                                              SMB2_CREATE_TAG_DHNC);
532                 alsi = smb2_create_blob_find(&in_context_blobs,
533                                              SMB2_CREATE_TAG_ALSI);
534                 twrp = smb2_create_blob_find(&in_context_blobs,
535                                              SMB2_CREATE_TAG_TWRP);
536                 qfid = smb2_create_blob_find(&in_context_blobs,
537                                              SMB2_CREATE_TAG_QFID);
538
539                 fname = talloc_strdup(state, in_name);
540                 if (tevent_req_nomem(fname, req)) {
541                         return tevent_req_post(req, ev);
542                 }
543
544                 if (exta) {
545                         if (dhnc) {
546                                 tevent_req_nterror(req,NT_STATUS_OBJECT_NAME_NOT_FOUND);
547                                 return tevent_req_post(req, ev);
548                         }
549
550                         ea_list = read_nttrans_ea_list(mem_ctx,
551                                 (const char *)exta->data.data, exta->data.length);
552                         if (!ea_list) {
553                                 DEBUG(10,("smbd_smb2_create_send: read_ea_name_list failed.\n"));
554                                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
555                                 return tevent_req_post(req, ev);
556                         }
557                 }
558
559                 if (mxac) {
560                         if (dhnc) {
561                                 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
562                                 return tevent_req_post(req, ev);
563                         }
564
565                         if (mxac->data.length == 0) {
566                                 max_access_time = 0;
567                         } else if (mxac->data.length == 8) {
568                                 max_access_time = BVAL(mxac->data.data, 0);
569                         } else {
570                                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
571                                 return tevent_req_post(req, ev);
572                         }
573                 }
574
575                 if (secd) {
576                         enum ndr_err_code ndr_err;
577
578                         if (dhnc) {
579                                 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
580                                 return tevent_req_post(req, ev);
581                         }
582
583                         sec_desc = talloc_zero(state, struct security_descriptor);
584                         if (tevent_req_nomem(sec_desc, req)) {
585                                 return tevent_req_post(req, ev);
586                         }
587
588                         ndr_err = ndr_pull_struct_blob(&secd->data,
589                                 sec_desc, sec_desc,
590                                 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
591                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
592                                 DEBUG(2,("ndr_pull_security_descriptor failed: %s\n",
593                                          ndr_errstr(ndr_err)));
594                                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
595                                 return tevent_req_post(req, ev);
596                         }
597                 }
598
599                 if (dhnq) {
600                         if (dhnc) {
601                                 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
602                                 return tevent_req_post(req, ev);
603                         }
604
605                         if (dhnq->data.length != 16) {
606                                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
607                                 return tevent_req_post(req, ev);
608                         }
609                         /*
610                          * we don't support durable handles yet
611                          * and have to ignore this
612                          */
613                 }
614
615                 if (dhnc) {
616                         if (dhnc->data.length != 16) {
617                                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
618                                 return tevent_req_post(req, ev);
619                         }
620                         /* we don't support durable handles yet */
621                         tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
622                         return tevent_req_post(req, ev);
623                 }
624
625                 if (alsi) {
626                         if (dhnc) {
627                                 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
628                                 return tevent_req_post(req, ev);
629                         }
630
631                         if (alsi->data.length != 8) {
632                                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
633                                 return tevent_req_post(req, ev);
634                         }
635                         allocation_size = BVAL(alsi->data.data, 0);
636                 }
637
638                 if (twrp) {
639                         NTTIME nttime;
640                         time_t t;
641                         struct tm *tm;
642
643                         if (dhnc) {
644                                 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
645                                 return tevent_req_post(req, ev);
646                         }
647
648                         if (twrp->data.length != 8) {
649                                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
650                                 return tevent_req_post(req, ev);
651                         }
652
653                         nttime = BVAL(twrp->data.data, 0);
654                         t = nt_time_to_unix(nttime);
655                         tm = gmtime(&t);
656
657                         TALLOC_FREE(fname);
658                         fname = talloc_asprintf(state,
659                                         "@GMT-%04u.%02u.%02u-%02u.%02u.%02u\\%s",
660                                         tm->tm_year + 1900,
661                                         tm->tm_mon + 1,
662                                         tm->tm_mday,
663                                         tm->tm_hour,
664                                         tm->tm_min,
665                                         tm->tm_sec,
666                                         in_name);
667                         if (tevent_req_nomem(fname, req)) {
668                                 return tevent_req_post(req, ev);
669                         }
670                 }
671
672                 if (qfid) {
673                         if (qfid->data.length != 0) {
674                                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
675                                 return tevent_req_post(req, ev);
676                         }
677                 }
678
679                 /* these are ignored for SMB2 */
680                 in_create_options &= ~(0x10);/* NTCREATEX_OPTIONS_SYNC_ALERT */
681                 in_create_options &= ~(0x20);/* NTCREATEX_OPTIONS_ASYNC_ALERT */
682
683                 /*
684                  * For a DFS path the function parse_dfs_path()
685                  * will do the path processing.
686                  */
687
688                 if (!(smb1req->flags2 & FLAGS2_DFS_PATHNAMES)) {
689                         /* convert '\\' into '/' */
690                         status = check_path_syntax(fname);
691                         if (!NT_STATUS_IS_OK(status)) {
692                                 tevent_req_nterror(req, status);
693                                 return tevent_req_post(req, ev);
694                         }
695                 }
696
697                 status = filename_convert(req,
698                                           smb1req->conn,
699                                           smb1req->flags2 & FLAGS2_DFS_PATHNAMES,
700                                           fname,
701                                           0,
702                                           NULL,
703                                           &smb_fname);
704                 if (!NT_STATUS_IS_OK(status)) {
705                         tevent_req_nterror(req, status);
706                         return tevent_req_post(req, ev);
707                 }
708
709                 in_file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS;
710
711                 status = SMB_VFS_CREATE_FILE(smb1req->conn,
712                                              smb1req,
713                                              0, /* root_dir_fid */
714                                              smb_fname,
715                                              in_desired_access,
716                                              in_share_access,
717                                              in_create_disposition,
718                                              in_create_options,
719                                              in_file_attributes,
720                                              map_smb2_oplock_levels_to_samba(requested_oplock_level),
721                                              allocation_size,
722                                              0, /* private_flags */
723                                              sec_desc,
724                                              ea_list,
725                                              &result,
726                                              &info);
727                 if (!NT_STATUS_IS_OK(status)) {
728                         if (open_was_deferred(smb1req->sconn, smb1req->mid)) {
729                                 return req;
730                         }
731                         tevent_req_nterror(req, status);
732                         return tevent_req_post(req, ev);
733                 }
734
735                 if (mxac) {
736                         NTTIME last_write_time;
737
738                         unix_timespec_to_nt_time(&last_write_time,
739                                                  result->fsp_name->st.st_ex_mtime);
740                         if (last_write_time != max_access_time) {
741                                 uint8_t p[8];
742                                 uint32_t max_access_granted;
743                                 DATA_BLOB blob = data_blob_const(p, sizeof(p));
744
745                                 status = smbd_calculate_access_mask(smb1req->conn,
746                                                         result->fsp_name,
747                                                         /*
748                                                          * at this stage
749                                                          * it exists
750                                                          */
751                                                         true,
752                                                         SEC_FLAG_MAXIMUM_ALLOWED,
753                                                         &max_access_granted);
754
755                                 SIVAL(p, 0, NT_STATUS_V(status));
756                                 SIVAL(p, 4, max_access_granted);
757
758                                 status = smb2_create_blob_add(state,
759                                                         &out_context_blobs,
760                                                         SMB2_CREATE_TAG_MXAC,
761                                                         blob);
762                                 if (!NT_STATUS_IS_OK(status)) {
763                                         tevent_req_nterror(req, status);
764                                         return tevent_req_post(req, ev);
765                                 }
766                         }
767                 }
768
769                 if (qfid) {
770                         uint8_t p[32];
771                         uint64_t file_index = get_FileIndex(result->conn,
772                                                         &result->fsp_name->st);
773                         DATA_BLOB blob = data_blob_const(p, sizeof(p));
774
775                         ZERO_STRUCT(p);
776
777                         /* From conversations with Microsoft engineers at
778                            the MS plugfest. The first 8 bytes are the "volume index"
779                            == inode, the second 8 bytes are the "volume id",
780                            == dev. This will be updated in the SMB2 doc. */
781                         SBVAL(p, 0, file_index);
782                         SIVAL(p, 8, result->fsp_name->st.st_ex_dev);/* FileIndexHigh */
783
784                         status = smb2_create_blob_add(state, &out_context_blobs,
785                                                       SMB2_CREATE_TAG_QFID,
786                                                       blob);
787                         if (!NT_STATUS_IS_OK(status)) {
788                                 tevent_req_nterror(req, status);
789                                 return tevent_req_post(req, ev);
790                         }
791                 }
792         }
793
794         smb2req->compat_chain_fsp = smb1req->chain_fsp;
795
796         if(lp_fake_oplocks(SNUM(smb2req->tcon->compat_conn))) {
797                 state->out_oplock_level = in_oplock_level;
798         } else {
799                 state->out_oplock_level = map_samba_oplock_levels_to_smb2(result->oplock_type);
800         }
801
802         if ((in_create_disposition == FILE_SUPERSEDE)
803             && (info == FILE_WAS_OVERWRITTEN)) {
804                 state->out_create_action = FILE_WAS_SUPERSEDED;
805         } else {
806                 state->out_create_action = info;
807         }
808         state->out_file_attributes = dos_mode(result->conn,
809                                            result->fsp_name);
810         /* Deal with other possible opens having a modified
811            write time. JRA. */
812         ZERO_STRUCT(write_time_ts);
813         get_file_infos(result->file_id, 0, NULL, &write_time_ts);
814         if (!null_timespec(write_time_ts)) {
815                 update_stat_ex_mtime(&result->fsp_name->st, write_time_ts);
816         }
817
818         unix_timespec_to_nt_time(&state->out_creation_time,
819                         get_create_timespec(smb1req->conn, result,
820                                         result->fsp_name));
821         unix_timespec_to_nt_time(&state->out_last_access_time,
822                         result->fsp_name->st.st_ex_atime);
823         unix_timespec_to_nt_time(&state->out_last_write_time,
824                         result->fsp_name->st.st_ex_mtime);
825         unix_timespec_to_nt_time(&state->out_change_time,
826                         get_change_timespec(smb1req->conn, result,
827                                         result->fsp_name));
828         state->out_allocation_size =
829                         SMB_VFS_GET_ALLOC_SIZE(smb1req->conn, result,
830                                                &(result->fsp_name->st));
831         state->out_end_of_file = result->fsp_name->st.st_ex_size;
832         if (state->out_file_attributes == 0) {
833                 state->out_file_attributes = FILE_ATTRIBUTE_NORMAL;
834         }
835         state->out_file_id_persistent = result->fnum;
836         state->out_file_id_volatile = result->fnum;
837         state->out_context_blobs = out_context_blobs;
838
839         tevent_req_done(req);
840         return tevent_req_post(req, ev);
841 }
842
843 static NTSTATUS smbd_smb2_create_recv(struct tevent_req *req,
844                         TALLOC_CTX *mem_ctx,
845                         uint8_t *out_oplock_level,
846                         uint32_t *out_create_action,
847                         NTTIME *out_creation_time,
848                         NTTIME *out_last_access_time,
849                         NTTIME *out_last_write_time,
850                         NTTIME *out_change_time,
851                         uint64_t *out_allocation_size,
852                         uint64_t *out_end_of_file,
853                         uint32_t *out_file_attributes,
854                         uint64_t *out_file_id_persistent,
855                         uint64_t *out_file_id_volatile,
856                         struct smb2_create_blobs *out_context_blobs)
857 {
858         NTSTATUS status;
859         struct smbd_smb2_create_state *state = tevent_req_data(req,
860                                                struct smbd_smb2_create_state);
861
862         if (tevent_req_is_nterror(req, &status)) {
863                 tevent_req_received(req);
864                 return status;
865         }
866
867         *out_oplock_level       = state->out_oplock_level;
868         *out_create_action      = state->out_create_action;
869         *out_creation_time      = state->out_creation_time;
870         *out_last_access_time   = state->out_last_access_time;
871         *out_last_write_time    = state->out_last_write_time;
872         *out_change_time        = state->out_change_time;
873         *out_allocation_size    = state->out_allocation_size;
874         *out_end_of_file        = state->out_end_of_file;
875         *out_file_attributes    = state->out_file_attributes;
876         *out_file_id_persistent = state->out_file_id_persistent;
877         *out_file_id_volatile   = state->out_file_id_volatile;
878         *out_context_blobs      = state->out_context_blobs;
879
880         talloc_steal(mem_ctx, state->out_context_blobs.blobs);
881
882         tevent_req_received(req);
883         return NT_STATUS_OK;
884 }
885
886 /*********************************************************
887  Code for dealing with deferred opens.
888 *********************************************************/
889
890 bool get_deferred_open_message_state_smb2(struct smbd_smb2_request *smb2req,
891                         struct timeval *p_request_time,
892                         void **pp_state)
893 {
894         struct smbd_smb2_create_state *state = NULL;
895         struct tevent_req *req = NULL;
896
897         if (!smb2req) {
898                 return false;
899         }
900         if (smb2req->subreq == NULL) {
901                 return false;
902         }
903         req = smb2req->subreq;
904         if (!req) {
905                 return false;
906         }
907         state = tevent_req_data(req, struct smbd_smb2_create_state);
908         if (!state) {
909                 return false;
910         }
911         if (p_request_time) {
912                 *p_request_time = state->request_time;
913         }
914         if (pp_state) {
915                 *pp_state = (void *)state->private_data.data;
916         }
917         return true;
918 }
919
920 /*********************************************************
921  Re-process this call early - requested by message or
922  close.
923 *********************************************************/
924
925 static struct smbd_smb2_request *find_open_smb2req(
926         struct smbd_server_connection *sconn, uint64_t mid)
927 {
928         struct smbd_smb2_request *smb2req;
929
930         for (smb2req = sconn->smb2.requests; smb2req; smb2req = smb2req->next) {
931                 uint64_t message_id;
932                 if (smb2req->subreq == NULL) {
933                         /* This message has been processed. */
934                         continue;
935                 }
936                 if (!tevent_req_is_in_progress(smb2req->subreq)) {
937                         /* This message has been processed. */
938                         continue;
939                 }
940                 message_id = get_mid_from_smb2req(smb2req);
941                 if (message_id == mid) {
942                         return smb2req;
943                 }
944         }
945         return NULL;
946 }
947
948 bool open_was_deferred_smb2(struct smbd_server_connection *sconn, uint64_t mid)
949 {
950         struct smbd_smb2_create_state *state = NULL;
951         struct smbd_smb2_request *smb2req;
952
953         smb2req = find_open_smb2req(sconn, mid);
954
955         if (!smb2req) {
956                 DEBUG(10,("open_was_deferred_smb2: mid %llu smb2req == NULL\n",
957                         (unsigned long long)mid));
958                 return false;
959         }
960         if (!smb2req->subreq) {
961                 return false;
962         }
963         if (!tevent_req_is_in_progress(smb2req->subreq)) {
964                 return false;
965         }
966         state = tevent_req_data(smb2req->subreq,
967                         struct smbd_smb2_create_state);
968         if (!state) {
969                 return false;
970         }
971         /* It's not in progress if there's no timeout event. */
972         if (!state->te) {
973                 return false;
974         }
975
976         DEBUG(10,("open_was_deferred_smb2: mid = %llu\n",
977                         (unsigned long long)mid));
978
979         return true;
980 }
981
982 static void remove_deferred_open_message_smb2_internal(struct smbd_smb2_request *smb2req,
983                                                         uint64_t mid)
984 {
985         struct smbd_smb2_create_state *state = NULL;
986
987         if (!smb2req->subreq) {
988                 return;
989         }
990         if (!tevent_req_is_in_progress(smb2req->subreq)) {
991                 return;
992         }
993         state = tevent_req_data(smb2req->subreq,
994                         struct smbd_smb2_create_state);
995         if (!state) {
996                 return;
997         }
998
999         DEBUG(10,("remove_deferred_open_message_smb2_internal: "
1000                 "mid %llu\n",
1001                 (unsigned long long)mid ));
1002
1003         /* Ensure we don't have any outstanding timer event. */
1004         TALLOC_FREE(state->te);
1005         /* Ensure we don't have any outstanding immediate event. */
1006         TALLOC_FREE(state->im);
1007 }
1008
1009 void remove_deferred_open_message_smb2(
1010         struct smbd_server_connection *sconn, uint64_t mid)
1011 {
1012         struct smbd_smb2_request *smb2req;
1013
1014         smb2req = find_open_smb2req(sconn, mid);
1015
1016         if (!smb2req) {
1017                 DEBUG(10,("remove_deferred_open_message_smb2: "
1018                         "can't find mid %llu\n",
1019                         (unsigned long long)mid ));
1020                 return;
1021         }
1022         remove_deferred_open_message_smb2_internal(smb2req, mid);
1023 }
1024
1025 static void smbd_smb2_create_request_dispatch_immediate(struct tevent_context *ctx,
1026                                         struct tevent_immediate *im,
1027                                         void *private_data)
1028 {
1029         struct smbd_smb2_request *smb2req = talloc_get_type_abort(private_data,
1030                                         struct smbd_smb2_request);
1031         struct smbd_server_connection *sconn = smb2req->sconn;
1032         uint64_t mid = get_mid_from_smb2req(smb2req);
1033         NTSTATUS status;
1034
1035         DEBUG(10,("smbd_smb2_create_request_dispatch_immediate: "
1036                 "re-dispatching mid %llu\n",
1037                 (unsigned long long)mid ));
1038
1039         status = smbd_smb2_request_dispatch(smb2req);
1040         if (!NT_STATUS_IS_OK(status)) {
1041                 smbd_server_connection_terminate(sconn, nt_errstr(status));
1042                 return;
1043         }
1044 }
1045
1046 void schedule_deferred_open_message_smb2(
1047         struct smbd_server_connection *sconn, uint64_t mid)
1048 {
1049         struct smbd_smb2_create_state *state = NULL;
1050         struct smbd_smb2_request *smb2req;
1051
1052         smb2req = find_open_smb2req(sconn, mid);
1053
1054         if (!smb2req) {
1055                 DEBUG(10,("schedule_deferred_open_message_smb2: "
1056                         "can't find mid %llu\n",
1057                         (unsigned long long)mid ));
1058                 return;
1059         }
1060         if (!smb2req->subreq) {
1061                 return;
1062         }
1063         if (!tevent_req_is_in_progress(smb2req->subreq)) {
1064                 return;
1065         }
1066         state = tevent_req_data(smb2req->subreq,
1067                         struct smbd_smb2_create_state);
1068         if (!state) {
1069                 return;
1070         }
1071
1072         /* Ensure we don't have any outstanding timer event. */
1073         TALLOC_FREE(state->te);
1074         /* Ensure we don't have any outstanding immediate event. */
1075         TALLOC_FREE(state->im);
1076
1077         /*
1078          * This is subtle. We must null out the callback
1079          * before resheduling, else the first call to
1080          * tevent_req_nterror() causes the _receive()
1081          * function to be called, this causing tevent_req_post()
1082          * to crash.
1083          */
1084         tevent_req_set_callback(smb2req->subreq, NULL, NULL);
1085
1086         state->im = tevent_create_immediate(smb2req);
1087         if (!state->im) {
1088                 smbd_server_connection_terminate(smb2req->sconn,
1089                         nt_errstr(NT_STATUS_NO_MEMORY));
1090                 return;
1091         }
1092
1093         DEBUG(10,("schedule_deferred_open_message_smb2: "
1094                 "re-processing mid %llu\n",
1095                 (unsigned long long)mid ));
1096
1097         tevent_schedule_immediate(state->im,
1098                         smb2req->sconn->ev_ctx,
1099                         smbd_smb2_create_request_dispatch_immediate,
1100                         smb2req);
1101 }
1102
1103 /*********************************************************
1104  Re-process this call.
1105 *********************************************************/
1106
1107 static void smb2_deferred_open_timer(struct event_context *ev,
1108                                         struct timed_event *te,
1109                                         struct timeval _tval,
1110                                         void *private_data)
1111 {
1112         NTSTATUS status;
1113         struct smbd_smb2_create_state *state = NULL;
1114         struct smbd_smb2_request *smb2req = talloc_get_type(private_data,
1115                                                 struct smbd_smb2_request);
1116
1117         DEBUG(10,("smb2_deferred_open_timer: [idx=%d], %s\n",
1118                 smb2req->current_idx,
1119                 tevent_req_default_print(smb2req->subreq, talloc_tos()) ));
1120
1121         state = tevent_req_data(smb2req->subreq,
1122                         struct smbd_smb2_create_state);
1123         if (!state) {
1124                 return;
1125         }
1126         /*
1127          * Null this out, don't talloc_free. It will
1128          * be talloc_free'd by the tevent library when
1129          * this returns.
1130          */
1131         state->te = NULL;
1132         /* Ensure we don't have any outstanding immediate event. */
1133         TALLOC_FREE(state->im);
1134
1135         /*
1136          * This is subtle. We must null out the callback
1137          * before resheduling, else the first call to
1138          * tevent_req_nterror() causes the _receive()
1139          * function to be called, this causing tevent_req_post()
1140          * to crash.
1141          */
1142         tevent_req_set_callback(smb2req->subreq, NULL, NULL);
1143
1144         status = smbd_smb2_request_dispatch(smb2req);
1145
1146         if (!NT_STATUS_IS_OK(status)) {
1147                 smbd_server_connection_terminate(smb2req->sconn,
1148                                 nt_errstr(status));
1149         }
1150 }
1151
1152 static bool smbd_smb2_create_cancel(struct tevent_req *req)
1153 {
1154         struct smbd_smb2_request *smb2req = NULL;
1155         struct smbd_smb2_create_state *state = tevent_req_data(req,
1156                                 struct smbd_smb2_create_state);
1157         uint64_t mid;
1158
1159         if (!state) {
1160                 return false;
1161         }
1162
1163         if (!state->smb2req) {
1164                 return false;
1165         }
1166
1167         smb2req = state->smb2req;
1168         mid = get_mid_from_smb2req(smb2req);
1169
1170         remove_deferred_open_entry(state->id, mid,
1171                                    sconn_server_id(smb2req->sconn));
1172         remove_deferred_open_message_smb2_internal(smb2req, mid);
1173         smb2req->cancelled = true;
1174
1175         tevent_req_done(req);
1176         return true;
1177 }
1178
1179 bool push_deferred_open_message_smb2(struct smbd_smb2_request *smb2req,
1180                                 struct timeval request_time,
1181                                 struct timeval timeout,
1182                                 struct file_id id,
1183                                 char *private_data,
1184                                 size_t priv_len)
1185 {
1186         struct tevent_req *req = NULL;
1187         struct smbd_smb2_create_state *state = NULL;
1188         struct timeval end_time;
1189
1190         if (!smb2req) {
1191                 return false;
1192         }
1193         req = smb2req->subreq;
1194         if (!req) {
1195                 return false;
1196         }
1197         state = tevent_req_data(req, struct smbd_smb2_create_state);
1198         if (!state) {
1199                 return false;
1200         }
1201         state->id = id;
1202         state->request_time = request_time;
1203         state->private_data = data_blob_talloc(state, private_data,
1204                                                 priv_len);
1205         if (!state->private_data.data) {
1206                 return false;
1207         }
1208
1209         /* Re-schedule us to retry on timer expiry. */
1210         end_time = timeval_sum(&request_time, &timeout);
1211
1212         DEBUG(10,("push_deferred_open_message_smb2: "
1213                 "timeout at %s\n",
1214                 timeval_string(talloc_tos(),
1215                                 &end_time,
1216                                 true) ));
1217
1218         state->te = tevent_add_timer(smb2req->sconn->ev_ctx,
1219                                 state,
1220                                 end_time,
1221                                 smb2_deferred_open_timer,
1222                                 smb2req);
1223         if (!state->te) {
1224                 return false;
1225         }
1226
1227         /* allow this request to be canceled */
1228         tevent_req_set_cancel_fn(req, smbd_smb2_create_cancel);
1229
1230         return true;
1231 }