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