added --noacls options and checking for same mismatch in backtracking
[kai/samba.git] / source / ntvfs / posix / pvfs_open.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    POSIX NTVFS backend - open and close
5
6    Copyright (C) Andrew Tridgell 2004
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 "vfs_posix.h"
24 #include "system/dir.h"
25 #include "system/time.h"
26 #include "lib/util/dlinklist.h"
27 #include "messaging/messaging.h"
28 #include "librpc/gen_ndr/xattr.h"
29
30 /*
31   find open file handle given fnum
32 */
33 struct pvfs_file *pvfs_find_fd(struct pvfs_state *pvfs,
34                                struct ntvfs_request *req, struct ntvfs_handle *h)
35 {
36         void *p;
37         struct pvfs_file *f;
38
39         p = ntvfs_handle_get_backend_data(h, pvfs->ntvfs);
40         if (!p) return NULL;
41
42         f = talloc_get_type(p, struct pvfs_file);
43         if (!f) return NULL;
44
45         return f;
46 }
47
48 /*
49   cleanup a open directory handle
50 */
51 static int pvfs_dir_handle_destructor(struct pvfs_file_handle *h)
52 {
53         if (h->have_opendb_entry) {
54                 struct odb_lock *lck;
55                 NTSTATUS status;
56                 const char *delete_path = NULL;
57
58                 lck = odb_lock(h, h->pvfs->odb_context, &h->odb_locking_key);
59                 if (lck == NULL) {
60                         DEBUG(0,("Unable to lock opendb for close\n"));
61                         return 0;
62                 }
63
64                 status = odb_close_file(lck, h, &delete_path);
65                 if (!NT_STATUS_IS_OK(status)) {
66                         DEBUG(0,("Unable to remove opendb entry for '%s' - %s\n",
67                                  h->name->full_name, nt_errstr(status)));
68                 }
69
70                 if (h->name->stream_name == NULL && delete_path) {
71                         status = pvfs_xattr_unlink_hook(h->pvfs, delete_path);
72                         if (!NT_STATUS_IS_OK(status)) {
73                                 DEBUG(0,("Warning: xattr unlink hook failed for '%s' - %s\n",
74                                          delete_path, nt_errstr(status)));
75                         }
76                         if (rmdir(delete_path) != 0) {
77                                 DEBUG(0,("pvfs_dir_handle_destructor: failed to rmdir '%s' - %s\n",
78                                          delete_path, strerror(errno)));
79                         }
80                 }
81
82                 talloc_free(lck);
83         }
84
85         return 0;
86 }
87
88 /*
89   cleanup a open directory fnum
90 */
91 static int pvfs_dir_fnum_destructor(struct pvfs_file *f)
92 {
93         DLIST_REMOVE(f->pvfs->files.list, f);
94         ntvfs_handle_remove_backend_data(f->ntvfs, f->pvfs->ntvfs);
95
96         return 0;
97 }
98
99 /*
100   setup any EAs and the ACL on newly created files/directories
101 */
102 static NTSTATUS pvfs_open_setup_eas_acl(struct pvfs_state *pvfs,
103                                         struct ntvfs_request *req,
104                                         struct pvfs_filename *name,
105                                         int fd, struct pvfs_file *f,
106                                         union smb_open *io)
107 {
108         NTSTATUS status;
109
110         /* setup any EAs that were asked for */
111         if (io->ntcreatex.in.ea_list) {
112                 status = pvfs_setfileinfo_ea_set(pvfs, name, fd, 
113                                                  io->ntcreatex.in.ea_list->num_eas,
114                                                  io->ntcreatex.in.ea_list->eas);
115                 if (!NT_STATUS_IS_OK(status)) {
116                         return status;
117                 }
118         }
119
120         /* setup an initial sec_desc if requested */
121         if (io->ntcreatex.in.sec_desc) {
122                 union smb_setfileinfo set;
123 /* 
124  * TODO: set the full ACL! 
125  *       - vista denies the creation of the file with NT_STATUS_PRIVILEGE_NOT_HELD,
126  *         when a SACL is present on the sd,
127  *         but the user doesn't have SeSecurityPrivilege
128  *       - w2k3 allows it
129  */
130                 set.set_secdesc.in.file.ntvfs = f->ntvfs;
131                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
132                 set.set_secdesc.in.sd = io->ntcreatex.in.sec_desc;
133
134                 status = pvfs_acl_set(pvfs, req, name, fd, SEC_STD_WRITE_DAC, &set);
135         } else {
136                 /* otherwise setup an inherited acl from the parent */
137                 status = pvfs_acl_inherit(pvfs, req, name, fd);
138         }
139
140         return status;
141 }
142
143 /*
144   form the lock context used for opendb locking. Note that we must
145   zero here to take account of possible padding on some architectures
146 */
147 NTSTATUS pvfs_locking_key(struct pvfs_filename *name,
148                           TALLOC_CTX *mem_ctx, DATA_BLOB *key)
149 {
150         struct {
151                 dev_t device;
152                 ino_t inode;
153         } lock_context;
154         ZERO_STRUCT(lock_context);
155
156         lock_context.device = name->st.st_dev;
157         lock_context.inode = name->st.st_ino;
158
159         *key = data_blob_talloc(mem_ctx, &lock_context, sizeof(lock_context));
160         if (key->data == NULL) {
161                 return NT_STATUS_NO_MEMORY;
162         }
163         
164         return NT_STATUS_OK;
165 }
166
167
168 /*
169   open a directory
170 */
171 static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, 
172                                     struct ntvfs_request *req, 
173                                     struct pvfs_filename *name, 
174                                     union smb_open *io)
175 {
176         struct pvfs_file *f;
177         struct ntvfs_handle *h;
178         NTSTATUS status;
179         uint32_t create_action;
180         uint32_t access_mask = io->generic.in.access_mask;
181         struct odb_lock *lck;
182         bool del_on_close;
183         uint32_t create_options;
184         uint32_t share_access;
185         bool forced;
186
187         create_options = io->generic.in.create_options;
188         share_access   = io->generic.in.share_access;
189
190         forced = (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY)?true:false;
191
192         if (name->stream_name) {
193                 if (forced) {
194                         return NT_STATUS_NOT_A_DIRECTORY;
195                 } else {
196                         return NT_STATUS_FILE_IS_A_DIRECTORY;
197                 }
198         }
199
200         /* if the client says it must be a directory, and it isn't,
201            then fail */
202         if (name->exists && !(name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) {
203                 return NT_STATUS_NOT_A_DIRECTORY;
204         }
205
206         /* found with gentest */
207         if (io->ntcreatex.in.access_mask == SEC_FLAG_MAXIMUM_ALLOWED &&
208             (io->ntcreatex.in.create_options & NTCREATEX_OPTIONS_DIRECTORY) &&
209             (io->ntcreatex.in.create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) {
210                 return NT_STATUS_INVALID_PARAMETER;
211         }
212         
213         switch (io->generic.in.open_disposition) {
214         case NTCREATEX_DISP_OPEN_IF:
215                 break;
216
217         case NTCREATEX_DISP_OPEN:
218                 if (!name->exists) {
219                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
220                 }
221                 break;
222
223         case NTCREATEX_DISP_CREATE:
224                 if (name->exists) {
225                         return NT_STATUS_OBJECT_NAME_COLLISION;
226                 }
227                 break;
228
229         case NTCREATEX_DISP_OVERWRITE_IF:
230         case NTCREATEX_DISP_OVERWRITE:
231         case NTCREATEX_DISP_SUPERSEDE:
232         default:
233                 return NT_STATUS_INVALID_PARAMETER;
234         }
235
236         status = ntvfs_handle_new(pvfs->ntvfs, req, &h);
237         NT_STATUS_NOT_OK_RETURN(status);
238
239         f = talloc(h, struct pvfs_file);
240         if (f == NULL) {
241                 return NT_STATUS_NO_MEMORY;
242         }
243
244         f->handle = talloc(f, struct pvfs_file_handle);
245         if (f->handle == NULL) {
246                 return NT_STATUS_NO_MEMORY;
247         }
248
249         if (name->exists) {
250                 /* check the security descriptor */
251                 status = pvfs_access_check(pvfs, req, name, &access_mask);
252         } else {
253                 status = pvfs_access_check_create(pvfs, req, name, &access_mask);
254         }
255         if (!NT_STATUS_IS_OK(status)) {
256                 return status;
257         }
258
259         f->ntvfs         = h;
260         f->pvfs          = pvfs;
261         f->pending_list  = NULL;
262         f->lock_count    = 0;
263         f->share_access  = io->generic.in.share_access;
264         f->impersonation = io->generic.in.impersonation;
265         f->access_mask   = access_mask;
266         f->brl_handle    = NULL;
267         f->notify_buffer = NULL;
268         f->search        = NULL;
269
270         f->handle->pvfs              = pvfs;
271         f->handle->name              = talloc_steal(f->handle, name);
272         f->handle->fd                = -1;
273         f->handle->odb_locking_key   = data_blob(NULL, 0);
274         f->handle->create_options    = io->generic.in.create_options;
275         f->handle->seek_offset       = 0;
276         f->handle->position          = 0;
277         f->handle->mode              = 0;
278         f->handle->oplock            = NULL;
279         f->handle->open_completed    = false;
280
281         if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) &&
282             pvfs_directory_empty(pvfs, f->handle->name)) {
283                 del_on_close = true;
284         } else {
285                 del_on_close = false;
286         }
287
288         if (name->exists) {
289                 /* form the lock context used for opendb locking */
290                 status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key);
291                 if (!NT_STATUS_IS_OK(status)) {
292                         return status;
293                 }
294
295                 /* get a lock on this file before the actual open */
296                 lck = odb_lock(req, pvfs->odb_context, &f->handle->odb_locking_key);
297                 if (lck == NULL) {
298                         DEBUG(0,("pvfs_open: failed to lock file '%s' in opendb\n",
299                                  name->full_name));
300                         /* we were supposed to do a blocking lock, so something
301                            is badly wrong! */
302                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
303                 }
304                 
305                 /* see if we are allowed to open at the same time as existing opens */
306                 status = odb_can_open(lck, name->stream_id,
307                                       share_access, access_mask, del_on_close,
308                                       io->generic.in.open_disposition, false);
309                 if (!NT_STATUS_IS_OK(status)) {
310                         talloc_free(lck);
311                         return status;
312                 }
313
314                 /* now really mark the file as open */
315                 status = odb_open_file(lck, f->handle, name->full_name,
316                                        NULL, false, OPLOCK_NONE, NULL);
317
318                 if (!NT_STATUS_IS_OK(status)) {
319                         talloc_free(lck);
320                         return status;
321                 }
322
323                 f->handle->have_opendb_entry = true;
324         }
325
326         DLIST_ADD(pvfs->files.list, f);
327
328         /* setup destructors to avoid leaks on abnormal termination */
329         talloc_set_destructor(f->handle, pvfs_dir_handle_destructor);
330         talloc_set_destructor(f, pvfs_dir_fnum_destructor);
331
332         if (!name->exists) {
333                 uint32_t attrib = io->generic.in.file_attr | FILE_ATTRIBUTE_DIRECTORY;
334                 mode_t mode = pvfs_fileperms(pvfs, attrib);
335
336                 if (mkdir(name->full_name, mode) == -1) {
337                         return pvfs_map_errno(pvfs,errno);
338                 }
339
340                 pvfs_xattr_unlink_hook(pvfs, name->full_name);
341
342                 status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, 0, &name);
343                 if (!NT_STATUS_IS_OK(status)) {
344                         goto cleanup_delete;
345                 }
346
347                 status = pvfs_open_setup_eas_acl(pvfs, req, name, -1, f, io);
348                 if (!NT_STATUS_IS_OK(status)) {
349                         goto cleanup_delete;
350                 }
351
352                 /* form the lock context used for opendb locking */
353                 status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key);
354                 if (!NT_STATUS_IS_OK(status)) {
355                         return status;
356                 }
357
358                 lck = odb_lock(req, pvfs->odb_context, &f->handle->odb_locking_key);
359                 if (lck == NULL) {
360                         DEBUG(0,("pvfs_open: failed to lock file '%s' in opendb\n",
361                                  name->full_name));
362                         /* we were supposed to do a blocking lock, so something
363                            is badly wrong! */
364                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
365                 }
366
367                 status = odb_can_open(lck, name->stream_id,
368                                       share_access, access_mask, del_on_close,
369                                       io->generic.in.open_disposition, false);
370
371                 if (!NT_STATUS_IS_OK(status)) {
372                         goto cleanup_delete;
373                 }
374
375                 status = odb_open_file(lck, f->handle, name->full_name,
376                                        NULL, false, OPLOCK_NONE, NULL);
377
378                 if (!NT_STATUS_IS_OK(status)) {
379                         goto cleanup_delete;
380                 }
381
382                 f->handle->have_opendb_entry = true;
383
384                 create_action = NTCREATEX_ACTION_CREATED;
385
386                 notify_trigger(pvfs->notify_context, 
387                                NOTIFY_ACTION_ADDED, 
388                                FILE_NOTIFY_CHANGE_DIR_NAME,
389                                name->full_name);
390         } else {
391                 create_action = NTCREATEX_ACTION_EXISTED;
392         }
393
394         if (!name->exists) {
395                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
396         }
397
398         /* the open succeeded, keep this handle permanently */
399         status = ntvfs_handle_set_backend_data(h, pvfs->ntvfs, f);
400         if (!NT_STATUS_IS_OK(status)) {
401                 goto cleanup_delete;
402         }
403
404         f->handle->open_completed = true;
405
406         io->generic.out.oplock_level  = OPLOCK_NONE;
407         io->generic.out.file.ntvfs    = h;
408         io->generic.out.create_action = create_action;
409         io->generic.out.create_time   = name->dos.create_time;
410         io->generic.out.access_time   = name->dos.access_time;
411         io->generic.out.write_time    = name->dos.write_time;
412         io->generic.out.change_time   = name->dos.change_time;
413         io->generic.out.attrib        = name->dos.attrib;
414         io->generic.out.alloc_size    = name->dos.alloc_size;
415         io->generic.out.size          = name->st.st_size;
416         io->generic.out.file_type     = FILE_TYPE_DISK;
417         io->generic.out.ipc_state     = 0;
418         io->generic.out.is_directory  = 1;
419
420         return NT_STATUS_OK;
421
422 cleanup_delete:
423         rmdir(name->full_name);
424         return status;
425 }
426
427 /*
428   destroy a struct pvfs_file_handle
429 */
430 static int pvfs_handle_destructor(struct pvfs_file_handle *h)
431 {
432         if ((h->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) &&
433             h->name->stream_name) {
434                 NTSTATUS status;
435                 status = pvfs_stream_delete(h->pvfs, h->name, h->fd);
436                 if (!NT_STATUS_IS_OK(status)) {
437                         DEBUG(0,("Failed to delete stream '%s' on close of '%s'\n",
438                                  h->name->stream_name, h->name->full_name));
439                 }
440         }
441
442         if (h->fd != -1) {
443                 if (close(h->fd) != 0) {
444                         DEBUG(0,("pvfs_handle_destructor: close(%d) failed for %s - %s\n",
445                                  h->fd, h->name->full_name, strerror(errno)));
446                 }
447                 h->fd = -1;
448         }
449
450         if (h->have_opendb_entry) {
451                 struct odb_lock *lck;
452                 NTSTATUS status;
453                 const char *delete_path = NULL;
454
455                 lck = odb_lock(h, h->pvfs->odb_context, &h->odb_locking_key);
456                 if (lck == NULL) {
457                         DEBUG(0,("Unable to lock opendb for close\n"));
458                         return 0;
459                 }
460
461                 status = odb_close_file(lck, h, &delete_path);
462                 if (!NT_STATUS_IS_OK(status)) {
463                         DEBUG(0,("Unable to remove opendb entry for '%s' - %s\n", 
464                                  h->name->full_name, nt_errstr(status)));
465                 }
466
467                 if (h->name->stream_name == NULL &&
468                     h->open_completed && delete_path) {
469                         status = pvfs_xattr_unlink_hook(h->pvfs, delete_path);
470                         if (!NT_STATUS_IS_OK(status)) {
471                                 DEBUG(0,("Warning: xattr unlink hook failed for '%s' - %s\n",
472                                          delete_path, nt_errstr(status)));
473                         }
474                         if (unlink(delete_path) != 0) {
475                                 DEBUG(0,("pvfs_close: failed to delete '%s' - %s\n",
476                                          delete_path, strerror(errno)));
477                         } else {
478                                 notify_trigger(h->pvfs->notify_context,
479                                                NOTIFY_ACTION_REMOVED,
480                                                FILE_NOTIFY_CHANGE_FILE_NAME,
481                                                delete_path);
482                         }
483                 }
484
485                 talloc_free(lck);
486         }
487
488         return 0;
489 }
490
491
492 /*
493   destroy a struct pvfs_file
494 */
495 static int pvfs_fnum_destructor(struct pvfs_file *f)
496 {
497         DLIST_REMOVE(f->pvfs->files.list, f);
498         pvfs_lock_close(f->pvfs, f);
499         ntvfs_handle_remove_backend_data(f->ntvfs, f->pvfs->ntvfs);
500
501         return 0;
502 }
503
504
505 /*
506   form the lock context used for byte range locking. This is separate
507   from the locking key used for opendb locking as it needs to take
508   account of file streams (each stream is a separate byte range
509   locking space)
510 */
511 static NTSTATUS pvfs_brl_locking_handle(TALLOC_CTX *mem_ctx,
512                                         struct pvfs_filename *name,
513                                         struct ntvfs_handle *ntvfs,
514                                         struct brl_handle **_h)
515 {
516         DATA_BLOB odb_key, key;
517         NTSTATUS status;
518         struct brl_handle *h;
519
520         status = pvfs_locking_key(name, mem_ctx, &odb_key);
521         NT_STATUS_NOT_OK_RETURN(status);
522
523         if (name->stream_name == NULL) {
524                 key = odb_key;
525         } else {
526                 key = data_blob_talloc(mem_ctx, NULL, 
527                                        odb_key.length + strlen(name->stream_name) + 1);
528                 NT_STATUS_HAVE_NO_MEMORY(key.data);
529                 memcpy(key.data, odb_key.data, odb_key.length);
530                 memcpy(key.data + odb_key.length, 
531                        name->stream_name, strlen(name->stream_name) + 1);
532                 data_blob_free(&odb_key);
533         }
534
535         h = brl_create_handle(mem_ctx, ntvfs, &key);
536         NT_STATUS_HAVE_NO_MEMORY(h);
537
538         *_h = h;
539         return NT_STATUS_OK;
540 }
541
542 /*
543   create a new file
544 */
545 static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, 
546                                  struct ntvfs_request *req, 
547                                  struct pvfs_filename *name, 
548                                  union smb_open *io)
549 {
550         struct pvfs_file *f;
551         NTSTATUS status;
552         struct ntvfs_handle *h;
553         int flags, fd;
554         struct odb_lock *lck;
555         uint32_t create_options = io->generic.in.create_options;
556         uint32_t share_access = io->generic.in.share_access;
557         uint32_t access_mask = io->generic.in.access_mask;
558         mode_t mode;
559         uint32_t attrib;
560         bool del_on_close;
561         struct pvfs_filename *parent;
562         uint32_t oplock_level = OPLOCK_NONE, oplock_granted;
563         bool allow_level_II_oplock = false;
564
565         if (io->ntcreatex.in.file_attr & ~FILE_ATTRIBUTE_ALL_MASK) {
566                 return NT_STATUS_INVALID_PARAMETER;
567         }
568
569         if (io->ntcreatex.in.file_attr & FILE_ATTRIBUTE_ENCRYPTED) {
570                 return NT_STATUS_ACCESS_DENIED;
571         }
572             
573         if ((io->ntcreatex.in.file_attr & FILE_ATTRIBUTE_READONLY) &&
574             (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) {
575                 return NT_STATUS_CANNOT_DELETE;
576         }
577
578         status = pvfs_access_check_create(pvfs, req, name, &access_mask);
579         NT_STATUS_NOT_OK_RETURN(status);
580
581         /* check that the parent isn't opened with delete on close set */
582         status = pvfs_resolve_parent(pvfs, req, name, &parent);
583         if (NT_STATUS_IS_OK(status)) {
584                 DATA_BLOB locking_key;
585                 status = pvfs_locking_key(parent, req, &locking_key);
586                 NT_STATUS_NOT_OK_RETURN(status);
587                 status = odb_get_delete_on_close(pvfs->odb_context, &locking_key, 
588                                                  &del_on_close);
589                 NT_STATUS_NOT_OK_RETURN(status);
590                 if (del_on_close) {
591                         return NT_STATUS_DELETE_PENDING;
592                 }
593         }
594
595         if (access_mask & (SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA)) {
596                 flags = O_RDWR;
597         } else {
598                 flags = O_RDONLY;
599         }
600
601         status = ntvfs_handle_new(pvfs->ntvfs, req, &h);
602         NT_STATUS_NOT_OK_RETURN(status);
603
604         f = talloc(h, struct pvfs_file);
605         NT_STATUS_HAVE_NO_MEMORY(f);
606
607         f->handle = talloc(f, struct pvfs_file_handle);
608         NT_STATUS_HAVE_NO_MEMORY(f->handle);
609
610         attrib = io->ntcreatex.in.file_attr | FILE_ATTRIBUTE_ARCHIVE;
611         mode = pvfs_fileperms(pvfs, attrib);
612
613         /* create the file */
614         fd = open(name->full_name, flags | O_CREAT | O_EXCL| O_NONBLOCK, mode);
615         if (fd == -1) {
616                 return pvfs_map_errno(pvfs, errno);
617         }
618
619         pvfs_xattr_unlink_hook(pvfs, name->full_name);
620
621         /* if this was a stream create then create the stream as well */
622         if (name->stream_name) {
623                 status = pvfs_stream_create(pvfs, name, fd);
624                 if (!NT_STATUS_IS_OK(status)) {
625                         close(fd);
626                         return status;
627                 }
628         }
629
630         /* re-resolve the open fd */
631         status = pvfs_resolve_name_fd(pvfs, fd, name);
632         if (!NT_STATUS_IS_OK(status)) {
633                 close(fd);
634                 return status;
635         }
636
637         /* support initial alloc sizes */
638         name->dos.alloc_size = io->ntcreatex.in.alloc_size;
639         name->dos.attrib = attrib;
640         status = pvfs_dosattrib_save(pvfs, name, fd);
641         if (!NT_STATUS_IS_OK(status)) {
642                 goto cleanup_delete;
643         }
644
645
646         status = pvfs_open_setup_eas_acl(pvfs, req, name, fd, f, io);
647         if (!NT_STATUS_IS_OK(status)) {
648                 goto cleanup_delete;
649         }
650
651         /* form the lock context used for byte range locking and
652            opendb locking */
653         status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key);
654         if (!NT_STATUS_IS_OK(status)) {
655                 goto cleanup_delete;
656         }
657
658         status = pvfs_brl_locking_handle(f, name, h, &f->brl_handle);
659         if (!NT_STATUS_IS_OK(status)) {
660                 goto cleanup_delete;
661         }
662
663         /* grab a lock on the open file record */
664         lck = odb_lock(req, pvfs->odb_context, &f->handle->odb_locking_key);
665         if (lck == NULL) {
666                 DEBUG(0,("pvfs_open: failed to lock file '%s' in opendb\n",
667                          name->full_name));
668                 /* we were supposed to do a blocking lock, so something
669                    is badly wrong! */
670                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
671                 goto cleanup_delete;
672         }
673
674         if (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) {
675                 del_on_close = true;
676         } else {
677                 del_on_close = false;
678         }
679
680         if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) {
681                 oplock_level = OPLOCK_NONE;
682         } else if (io->ntcreatex.in.flags & NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK) {
683                 oplock_level = OPLOCK_BATCH;
684         } else if (io->ntcreatex.in.flags & NTCREATEX_FLAGS_REQUEST_OPLOCK) {
685                 oplock_level = OPLOCK_EXCLUSIVE;
686         }
687
688         if (req->client_caps & NTVFS_CLIENT_CAP_LEVEL_II_OPLOCKS) {
689                 allow_level_II_oplock = true;
690         }
691
692         status = odb_can_open(lck, name->stream_id,
693                               share_access, access_mask, del_on_close,
694                               io->generic.in.open_disposition, false);
695         if (!NT_STATUS_IS_OK(status)) {
696                 talloc_free(lck);
697                 /* bad news, we must have hit a race - we don't delete the file
698                    here as the most likely scenario is that someone else created
699                    the file at the same time */
700                 close(fd);
701                 return status;
702         }
703
704         f->ntvfs             = h;
705         f->pvfs              = pvfs;
706         f->pending_list      = NULL;
707         f->lock_count        = 0;
708         f->share_access      = io->generic.in.share_access;
709         f->access_mask       = access_mask;
710         f->impersonation     = io->generic.in.impersonation;
711         f->notify_buffer     = NULL;
712         f->search            = NULL;
713
714         f->handle->pvfs              = pvfs;
715         f->handle->name              = talloc_steal(f->handle, name);
716         f->handle->fd                = fd;
717         f->handle->create_options    = io->generic.in.create_options;
718         f->handle->seek_offset       = 0;
719         f->handle->position          = 0;
720         f->handle->mode              = 0;
721         f->handle->oplock            = NULL;
722         f->handle->have_opendb_entry = true;
723         f->handle->open_completed    = false;
724
725         status = odb_open_file(lck, f->handle, name->full_name,
726                                &f->handle->fd, allow_level_II_oplock,
727                                oplock_level, &oplock_granted);
728         talloc_free(lck);
729         if (!NT_STATUS_IS_OK(status)) {
730                 /* bad news, we must have hit a race - we don't delete the file
731                    here as the most likely scenario is that someone else created
732                    the file at the same time */
733                 close(fd);
734                 return status;
735         }
736
737         DLIST_ADD(pvfs->files.list, f);
738
739         /* setup a destructor to avoid file descriptor leaks on
740            abnormal termination */
741         talloc_set_destructor(f, pvfs_fnum_destructor);
742         talloc_set_destructor(f->handle, pvfs_handle_destructor);
743
744         if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) {
745                 oplock_granted = OPLOCK_BATCH;
746         } else if (oplock_granted != OPLOCK_NONE) {
747                 status = pvfs_setup_oplock(f, oplock_granted);
748                 if (!NT_STATUS_IS_OK(status)) {
749                         return status;
750                 }
751         }
752
753         io->generic.out.oplock_level  = oplock_granted;
754         io->generic.out.file.ntvfs    = f->ntvfs;
755         io->generic.out.create_action = NTCREATEX_ACTION_CREATED;
756         io->generic.out.create_time   = name->dos.create_time;
757         io->generic.out.access_time   = name->dos.access_time;
758         io->generic.out.write_time    = name->dos.write_time;
759         io->generic.out.change_time   = name->dos.change_time;
760         io->generic.out.attrib        = name->dos.attrib;
761         io->generic.out.alloc_size    = name->dos.alloc_size;
762         io->generic.out.size          = name->st.st_size;
763         io->generic.out.file_type     = FILE_TYPE_DISK;
764         io->generic.out.ipc_state     = 0;
765         io->generic.out.is_directory  = 0;
766
767         /* success - keep the file handle */
768         status = ntvfs_handle_set_backend_data(h, pvfs->ntvfs, f);
769         if (!NT_STATUS_IS_OK(status)) {
770                 goto cleanup_delete;
771         }
772
773         f->handle->open_completed = true;
774
775         notify_trigger(pvfs->notify_context, 
776                        NOTIFY_ACTION_ADDED, 
777                        FILE_NOTIFY_CHANGE_FILE_NAME,
778                        name->full_name);
779
780         return NT_STATUS_OK;
781
782 cleanup_delete:
783         close(fd);
784         unlink(name->full_name);
785         return status;
786 }
787
788 /*
789   state of a pending retry
790 */
791 struct pvfs_odb_retry {
792         struct ntvfs_module_context *ntvfs;
793         struct ntvfs_request *req;
794         DATA_BLOB odb_locking_key;
795         void *io;
796         void *private_data;
797         void (*callback)(struct pvfs_odb_retry *r,
798                          struct ntvfs_module_context *ntvfs,
799                          struct ntvfs_request *req,
800                          void *io,
801                          void *private_data,
802                          enum pvfs_wait_notice reason);
803 };
804
805 /* destroy a pending request */
806 static int pvfs_odb_retry_destructor(struct pvfs_odb_retry *r)
807 {
808         struct pvfs_state *pvfs = r->ntvfs->private_data;
809         if (r->odb_locking_key.data) {
810                 struct odb_lock *lck;
811                 lck = odb_lock(r->req, pvfs->odb_context, &r->odb_locking_key);
812                 if (lck != NULL) {
813                         odb_remove_pending(lck, r);
814                 }
815                 talloc_free(lck);
816         }
817         return 0;
818 }
819
820 static void pvfs_odb_retry_callback(void *_r, enum pvfs_wait_notice reason)
821 {
822         struct pvfs_odb_retry *r = talloc_get_type(_r, struct pvfs_odb_retry);
823
824         if (reason == PVFS_WAIT_EVENT) {
825                 /*
826                  * The pending odb entry is already removed.
827                  * We use a null locking key to indicate this
828                  * to the destructor.
829                  */
830                 data_blob_free(&r->odb_locking_key);
831         }
832
833         r->callback(r, r->ntvfs, r->req, r->io, r->private_data, reason);
834 }
835
836 /*
837   setup for a retry of a request that was rejected
838   by odb_can_open()
839 */
840 NTSTATUS pvfs_odb_retry_setup(struct ntvfs_module_context *ntvfs,
841                               struct ntvfs_request *req,
842                               struct odb_lock *lck,
843                               struct timeval end_time,
844                               void *io,
845                               void *private_data,
846                               void (*callback)(struct pvfs_odb_retry *r,
847                                                struct ntvfs_module_context *ntvfs,
848                                                struct ntvfs_request *req,
849                                                void *io,
850                                                void *private_data,
851                                                enum pvfs_wait_notice reason))
852 {
853         struct pvfs_state *pvfs = ntvfs->private_data;
854         struct pvfs_odb_retry *r;
855         struct pvfs_wait *wait_handle;
856         NTSTATUS status;
857
858         r = talloc(req, struct pvfs_odb_retry);
859         NT_STATUS_HAVE_NO_MEMORY(r);
860
861         r->ntvfs = ntvfs;
862         r->req = req;
863         r->io = io;
864         r->private_data = private_data;
865         r->callback = callback;
866         r->odb_locking_key = odb_get_key(r, lck);
867         if (r->odb_locking_key.data == NULL) {
868                 return NT_STATUS_NO_MEMORY;
869         }
870
871         /* setup a pending lock */
872         status = odb_open_file_pending(lck, r);
873         if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND,status)) {
874                 /*
875                  * maybe only a unix application
876                  * has the file open
877                  */
878                 data_blob_free(&r->odb_locking_key);
879         } else if (!NT_STATUS_IS_OK(status)) {
880                 return status;
881         }
882
883         talloc_free(lck);
884
885         talloc_set_destructor(r, pvfs_odb_retry_destructor);
886
887         wait_handle = pvfs_wait_message(pvfs, req,
888                                         MSG_PVFS_RETRY_OPEN, end_time,
889                                         pvfs_odb_retry_callback, r);
890         if (wait_handle == NULL) {
891                 return NT_STATUS_NO_MEMORY;
892         }
893
894         talloc_steal(r, wait_handle);
895
896         return NT_STATUS_OK;
897 }
898
899 /*
900   retry an open after a sharing violation
901 */
902 static void pvfs_retry_open_sharing(struct pvfs_odb_retry *r,
903                                     struct ntvfs_module_context *ntvfs,
904                                     struct ntvfs_request *req,
905                                     void *_io,
906                                     void *private_data,
907                                     enum pvfs_wait_notice reason)
908 {
909         union smb_open *io = talloc_get_type(_io, union smb_open);
910         struct timeval *final_timeout = NULL;
911         NTSTATUS status;
912
913         if (private_data) {
914                 final_timeout = talloc_get_type(private_data,
915                                                 struct timeval);
916         }
917
918         /* w2k3 ignores SMBntcancel for outstanding open requests. It's probably
919            just a bug in their server, but we better do the same */
920         if (reason == PVFS_WAIT_CANCEL) {
921                 return;
922         }
923
924         if (reason == PVFS_WAIT_TIMEOUT) {
925                 if (final_timeout &&
926                     !timeval_expired(final_timeout)) {
927                         /*
928                          * we need to retry periodictly
929                          * after an EAGAIN as there's
930                          * no way the kernel tell us
931                          * an oplock is released.
932                          */
933                         goto retry;
934                 }
935                 /* if it timed out, then give the failure
936                    immediately */
937                 talloc_free(r);
938                 req->async_states->status = NT_STATUS_SHARING_VIOLATION;
939                 req->async_states->send_fn(req);
940                 return;
941         }
942
943 retry:
944         talloc_free(r);
945
946         /* try the open again, which could trigger another retry setup
947            if it wants to, so we have to unmark the async flag so we
948            will know if it does a second async reply */
949         req->async_states->state &= ~NTVFS_ASYNC_STATE_ASYNC;
950
951         status = pvfs_open(ntvfs, req, io);
952         if (req->async_states->state & NTVFS_ASYNC_STATE_ASYNC) {
953                 /* the 2nd try also replied async, so we don't send
954                    the reply yet */
955                 return;
956         }
957
958         /* re-mark it async, just in case someone up the chain does
959            paranoid checking */
960         req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC;
961
962         /* send the reply up the chain */
963         req->async_states->status = status;
964         req->async_states->send_fn(req);
965 }
966
967
968 /*
969   special handling for openx DENY_DOS semantics
970
971   This function attempts a reference open using an existing handle. If its allowed,
972   then it returns NT_STATUS_OK, otherwise it returns any other code and normal
973   open processing continues.
974 */
975 static NTSTATUS pvfs_open_deny_dos(struct ntvfs_module_context *ntvfs,
976                                    struct ntvfs_request *req, union smb_open *io,
977                                    struct pvfs_file *f, struct odb_lock *lck)
978 {
979         struct pvfs_state *pvfs = ntvfs->private_data;
980         struct pvfs_file *f2;
981         struct pvfs_filename *name;
982         NTSTATUS status;
983
984         /* search for an existing open with the right parameters. Note
985            the magic ntcreatex options flag, which is set in the
986            generic mapping code. This might look ugly, but its
987            actually pretty much now w2k does it internally as well. 
988            
989            If you look at the BASE-DENYDOS test you will see that a
990            DENY_DOS is a very special case, and in the right
991            circumstances you actually get the _same_ handle back
992            twice, rather than a new handle.
993         */
994         for (f2=pvfs->files.list;f2;f2=f2->next) {
995                 if (f2 != f &&
996                     f2->ntvfs->session_info == req->session_info &&
997                     f2->ntvfs->smbpid == req->smbpid &&
998                     (f2->handle->create_options & 
999                      (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS |
1000                       NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) &&
1001                     (f2->access_mask & SEC_FILE_WRITE_DATA) &&
1002                     strcasecmp_m(f2->handle->name->original_name, 
1003                                io->generic.in.fname)==0) {
1004                         break;
1005                 }
1006         }
1007
1008         if (!f2) {
1009                 return NT_STATUS_SHARING_VIOLATION;
1010         }
1011
1012         /* quite an insane set of semantics ... */
1013         if (is_exe_filename(io->generic.in.fname) &&
1014             (f2->handle->create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS)) {
1015                 return NT_STATUS_SHARING_VIOLATION;
1016         }
1017
1018         /*
1019           setup a reference to the existing handle
1020          */
1021         talloc_free(f->handle);
1022         f->handle = talloc_reference(f, f2->handle);
1023
1024         talloc_free(lck);
1025
1026         name = f->handle->name;
1027
1028         io->generic.out.oplock_level  = OPLOCK_NONE;
1029         io->generic.out.file.ntvfs    = f->ntvfs;
1030         io->generic.out.create_action = NTCREATEX_ACTION_EXISTED;
1031         io->generic.out.create_time   = name->dos.create_time;
1032         io->generic.out.access_time   = name->dos.access_time;
1033         io->generic.out.write_time    = name->dos.write_time;
1034         io->generic.out.change_time   = name->dos.change_time;
1035         io->generic.out.attrib        = name->dos.attrib;
1036         io->generic.out.alloc_size    = name->dos.alloc_size;
1037         io->generic.out.size          = name->st.st_size;
1038         io->generic.out.file_type     = FILE_TYPE_DISK;
1039         io->generic.out.ipc_state     = 0;
1040         io->generic.out.is_directory  = 0;
1041  
1042         status = ntvfs_handle_set_backend_data(f->ntvfs, ntvfs, f);
1043         NT_STATUS_NOT_OK_RETURN(status);
1044
1045         return NT_STATUS_OK;
1046 }
1047
1048
1049
1050 /*
1051   setup for a open retry after a sharing violation
1052 */
1053 static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs,
1054                                       struct ntvfs_request *req, 
1055                                       union smb_open *io,
1056                                       struct pvfs_file *f,
1057                                       struct odb_lock *lck,
1058                                       NTSTATUS parent_status)
1059 {
1060         struct pvfs_state *pvfs = ntvfs->private_data;
1061         NTSTATUS status;
1062         struct timeval end_time;
1063         struct timeval *final_timeout = NULL;
1064
1065         if (io->generic.in.create_options & 
1066             (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS | NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
1067                 /* see if we can satisfy the request using the special DENY_DOS
1068                    code */
1069                 status = pvfs_open_deny_dos(ntvfs, req, io, f, lck);
1070                 if (NT_STATUS_IS_OK(status)) {
1071                         return status;
1072                 }
1073         }
1074
1075         /* the retry should allocate a new file handle */
1076         talloc_free(f);
1077
1078         if (NT_STATUS_EQUAL(parent_status, NT_STATUS_SHARING_VIOLATION)) {
1079                 end_time = timeval_add(&req->statistics.request_time,
1080                                        0, pvfs->sharing_violation_delay);
1081         } else if (NT_STATUS_EQUAL(parent_status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
1082                 end_time = timeval_add(&req->statistics.request_time,
1083                                        pvfs->oplock_break_timeout, 0);
1084         } else if (NT_STATUS_EQUAL(parent_status, STATUS_MORE_ENTRIES)) {
1085                 /*
1086                  * we got EAGAIN which means a unix application
1087                  * has an oplock or share mode
1088                  *
1089                  * we retry every 4/5 of the sharing violation delay
1090                  * to see if the unix application
1091                  * has released the oplock or share mode.
1092                  */
1093                 final_timeout = talloc(req, struct timeval);
1094                 NT_STATUS_HAVE_NO_MEMORY(final_timeout);
1095                 *final_timeout = timeval_add(&req->statistics.request_time,
1096                                              pvfs->oplock_break_timeout,
1097                                              0);
1098                 end_time = timeval_current_ofs(0, (pvfs->sharing_violation_delay*4)/5);
1099                 end_time = timeval_min(final_timeout, &end_time);
1100         } else {
1101                 return NT_STATUS_INTERNAL_ERROR;
1102         }
1103
1104         return pvfs_odb_retry_setup(ntvfs, req, lck, end_time, io,
1105                                     final_timeout, pvfs_retry_open_sharing);
1106 }
1107
1108 /*
1109   open a file
1110 */
1111 NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
1112                    struct ntvfs_request *req, union smb_open *io)
1113 {
1114         struct pvfs_state *pvfs = ntvfs->private_data;
1115         int flags;
1116         struct pvfs_filename *name;
1117         struct pvfs_file *f;
1118         struct ntvfs_handle *h;
1119         NTSTATUS status;
1120         int fd;
1121         struct odb_lock *lck;
1122         uint32_t create_options;
1123         uint32_t share_access;
1124         uint32_t access_mask;
1125         bool del_on_close;
1126         bool stream_existed, stream_truncate=false;
1127         uint32_t oplock_level = OPLOCK_NONE, oplock_granted;
1128         bool allow_level_II_oplock = false;
1129
1130         /* use the generic mapping code to avoid implementing all the
1131            different open calls. */
1132         if (io->generic.level != RAW_OPEN_GENERIC &&
1133             io->generic.level != RAW_OPEN_NTTRANS_CREATE) {
1134                 return ntvfs_map_open(ntvfs, req, io);
1135         }
1136
1137         create_options = io->generic.in.create_options;
1138         share_access   = io->generic.in.share_access;
1139         access_mask    = io->generic.in.access_mask;
1140
1141         if (share_access & ~NTCREATEX_SHARE_ACCESS_MASK) {
1142                 return NT_STATUS_INVALID_PARAMETER;
1143         }
1144
1145         /* some create options are not supported */
1146         if (create_options & NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK) {
1147                 return NT_STATUS_NOT_SUPPORTED;
1148         }
1149
1150         /* other create options are not allowed */
1151         if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) &&
1152             !(access_mask & SEC_STD_DELETE)) {
1153                 return NT_STATUS_INVALID_PARAMETER;
1154         }
1155
1156         if (access_mask & SEC_MASK_INVALID) {
1157                 return NT_STATUS_ACCESS_DENIED;
1158         }
1159
1160         /* what does this bit really mean?? */
1161         if (req->ctx->protocol == PROTOCOL_SMB2 &&
1162             access_mask == SEC_STD_SYNCHRONIZE) {
1163                 return NT_STATUS_ACCESS_DENIED;
1164         }
1165
1166         if (io->ntcreatex.in.file_attr & (FILE_ATTRIBUTE_DEVICE|
1167                                           FILE_ATTRIBUTE_VOLUME| 
1168                                           (~FILE_ATTRIBUTE_ALL_MASK))) {
1169                 return NT_STATUS_INVALID_PARAMETER;
1170         }
1171
1172         /* resolve the cifs name to a posix name */
1173         status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, 
1174                                    PVFS_RESOLVE_STREAMS, &name);
1175         if (!NT_STATUS_IS_OK(status)) {
1176                 return status;
1177         }
1178
1179         /* if the client specified that it must not be a directory then
1180            check that it isn't */
1181         if (name->exists && (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) &&
1182             (io->generic.in.create_options & NTCREATEX_OPTIONS_NON_DIRECTORY_FILE)) {
1183                 return NT_STATUS_FILE_IS_A_DIRECTORY;
1184         }
1185
1186         /* if the client specified that it must be a directory then
1187            check that it is */
1188         if (name->exists && !(name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) &&
1189             (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY)) {
1190                 return NT_STATUS_NOT_A_DIRECTORY;
1191         }
1192
1193         /* directory opens are handled separately */
1194         if ((name->exists && (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) ||
1195             (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY)) {
1196                 return pvfs_open_directory(pvfs, req, name, io);
1197         }
1198
1199         /* FILE_ATTRIBUTE_DIRECTORY is ignored if the above test for directory
1200            open doesn't match */
1201         io->generic.in.file_attr &= ~FILE_ATTRIBUTE_DIRECTORY;
1202
1203         flags = 0;
1204
1205         switch (io->generic.in.open_disposition) {
1206         case NTCREATEX_DISP_SUPERSEDE:
1207         case NTCREATEX_DISP_OVERWRITE_IF:
1208                 if (name->stream_name == NULL) {
1209                         flags = O_TRUNC;
1210                 } else {
1211                         stream_truncate = true;
1212                 }
1213                 break;
1214
1215         case NTCREATEX_DISP_OPEN:
1216                 if (!name->stream_exists) {
1217                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1218                 }
1219                 flags = 0;
1220                 break;
1221
1222         case NTCREATEX_DISP_OVERWRITE:
1223                 if (!name->stream_exists) {
1224                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1225                 }
1226                 if (name->stream_name == NULL) {
1227                         flags = O_TRUNC;
1228                 } else {
1229                         stream_truncate = true;
1230                 }
1231                 break;
1232
1233         case NTCREATEX_DISP_CREATE:
1234                 if (name->stream_exists) {
1235                         return NT_STATUS_OBJECT_NAME_COLLISION;
1236                 }
1237                 flags = 0;
1238                 break;
1239
1240         case NTCREATEX_DISP_OPEN_IF:
1241                 flags = 0;
1242                 break;
1243
1244         default:
1245                 return NT_STATUS_INVALID_PARAMETER;
1246         }
1247
1248         /* handle creating a new file separately */
1249         if (!name->exists) {
1250                 status = pvfs_create_file(pvfs, req, name, io);
1251                 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
1252                         return status;
1253                 }
1254
1255                 /* we've hit a race - the file was created during this call */
1256                 if (io->generic.in.open_disposition == NTCREATEX_DISP_CREATE) {
1257                         return status;
1258                 }
1259
1260                 /* try re-resolving the name */
1261                 status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, 0, &name);
1262                 if (!NT_STATUS_IS_OK(status)) {
1263                         return status;
1264                 }
1265                 /* fall through to a normal open */
1266         }
1267
1268         if ((name->dos.attrib & FILE_ATTRIBUTE_READONLY) &&
1269             (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) {
1270                 return NT_STATUS_CANNOT_DELETE;
1271         }
1272
1273         /* check the security descriptor */
1274         status = pvfs_access_check(pvfs, req, name, &access_mask);
1275         if (!NT_STATUS_IS_OK(status)) {
1276                 return status;
1277         }
1278
1279         status = ntvfs_handle_new(pvfs->ntvfs, req, &h);
1280         NT_STATUS_NOT_OK_RETURN(status);
1281
1282         f = talloc(h, struct pvfs_file);
1283         if (f == NULL) {
1284                 return NT_STATUS_NO_MEMORY;
1285         }
1286
1287         f->handle = talloc(f, struct pvfs_file_handle);
1288         if (f->handle == NULL) {
1289                 return NT_STATUS_NO_MEMORY;
1290         }
1291
1292         f->ntvfs         = h;
1293         f->pvfs          = pvfs;
1294         f->pending_list  = NULL;
1295         f->lock_count    = 0;
1296         f->share_access  = io->generic.in.share_access;
1297         f->access_mask   = access_mask;
1298         f->impersonation = io->generic.in.impersonation;
1299         f->notify_buffer = NULL;
1300         f->search        = NULL;
1301
1302         f->handle->pvfs              = pvfs;
1303         f->handle->fd                = -1;
1304         f->handle->name              = talloc_steal(f->handle, name);
1305         f->handle->create_options    = io->generic.in.create_options;
1306         f->handle->seek_offset       = 0;
1307         f->handle->position          = 0;
1308         f->handle->mode              = 0;
1309         f->handle->oplock            = NULL;
1310         f->handle->have_opendb_entry = false;
1311         f->handle->open_completed    = false;
1312
1313         /* form the lock context used for byte range locking and
1314            opendb locking */
1315         status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key);
1316         if (!NT_STATUS_IS_OK(status)) {
1317                 return status;
1318         }
1319
1320         status = pvfs_brl_locking_handle(f, name, h, &f->brl_handle);
1321         if (!NT_STATUS_IS_OK(status)) {
1322                 return status;
1323         }
1324
1325         /* get a lock on this file before the actual open */
1326         lck = odb_lock(req, pvfs->odb_context, &f->handle->odb_locking_key);
1327         if (lck == NULL) {
1328                 DEBUG(0,("pvfs_open: failed to lock file '%s' in opendb\n",
1329                          name->full_name));
1330                 /* we were supposed to do a blocking lock, so something
1331                    is badly wrong! */
1332                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1333         }
1334
1335         DLIST_ADD(pvfs->files.list, f);
1336
1337         /* setup a destructor to avoid file descriptor leaks on
1338            abnormal termination */
1339         talloc_set_destructor(f, pvfs_fnum_destructor);
1340         talloc_set_destructor(f->handle, pvfs_handle_destructor);
1341
1342         /* 
1343          * Only SMB2 takes care of the delete_on_close,
1344          * on existing files
1345          */
1346         if (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE &&
1347             req->ctx->protocol == PROTOCOL_SMB2) {
1348                 del_on_close = true;
1349         } else {
1350                 del_on_close = false;
1351         }
1352
1353         if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) {
1354                 oplock_level = OPLOCK_NONE;
1355         } else if (io->ntcreatex.in.flags & NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK) {
1356                 oplock_level = OPLOCK_BATCH;
1357         } else if (io->ntcreatex.in.flags & NTCREATEX_FLAGS_REQUEST_OPLOCK) {
1358                 oplock_level = OPLOCK_EXCLUSIVE;
1359         }
1360
1361         if (req->client_caps & NTVFS_CLIENT_CAP_LEVEL_II_OPLOCKS) {
1362                 allow_level_II_oplock = true;
1363         }
1364
1365         /* see if we are allowed to open at the same time as existing opens */
1366         status = odb_can_open(lck, name->stream_id,
1367                               share_access, access_mask, del_on_close,
1368                               io->generic.in.open_disposition, false);
1369
1370         /*
1371          * on a sharing violation we need to retry when the file is closed by
1372          * the other user, or after 1 second
1373          * on a non granted oplock we need to retry when the file is closed by
1374          * the other user, or after 30 seconds
1375         */
1376         if ((NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) ||
1377              NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) &&
1378             (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {
1379                 return pvfs_open_setup_retry(ntvfs, req, io, f, lck, status);
1380         }
1381
1382         if (!NT_STATUS_IS_OK(status)) {
1383                 talloc_free(lck);
1384                 return status;
1385         }
1386
1387         if (access_mask & (SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA)) {
1388                 flags |= O_RDWR;
1389         } else {
1390                 flags |= O_RDONLY;
1391         }
1392
1393         /* do the actual open */
1394         fd = open(f->handle->name->full_name, flags | O_NONBLOCK);
1395         if (fd == -1) {
1396                 status = pvfs_map_errno(f->pvfs, errno);
1397
1398                 /*
1399                  * STATUS_MORE_ENTRIES is EAGAIN or EWOULDBLOCK
1400                  */
1401                 if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
1402                     (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {
1403                         return pvfs_open_setup_retry(ntvfs, req, io, f, lck, status);
1404                 }
1405
1406                 talloc_free(lck);
1407                 return status;
1408         }
1409
1410         f->handle->fd = fd;
1411
1412         /* now really mark the file as open */
1413         status = odb_open_file(lck, f->handle, name->full_name,
1414                                &f->handle->fd, allow_level_II_oplock,
1415                                oplock_level, &oplock_granted);
1416
1417         if (!NT_STATUS_IS_OK(status)) {
1418                 talloc_free(lck);
1419                 return status;
1420         }
1421
1422         f->handle->have_opendb_entry = true;
1423
1424         if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) {
1425                 oplock_granted = OPLOCK_BATCH;
1426         } else if (oplock_granted != OPLOCK_NONE) {
1427                 status = pvfs_setup_oplock(f, oplock_granted);
1428                 if (!NT_STATUS_IS_OK(status)) {
1429                         talloc_free(lck);
1430                         return status;
1431                 }
1432         }
1433
1434         stream_existed = name->stream_exists;
1435
1436         /* if this was a stream create then create the stream as well */
1437         if (!name->stream_exists) {
1438                 status = pvfs_stream_create(pvfs, f->handle->name, fd);
1439                 if (!NT_STATUS_IS_OK(status)) {
1440                         talloc_free(lck);
1441                         return status;
1442                 }
1443                 if (stream_truncate) {
1444                         status = pvfs_stream_truncate(pvfs, f->handle->name, fd, 0);
1445                         if (!NT_STATUS_IS_OK(status)) {
1446                                 talloc_free(lck);
1447                                 return status;
1448                         }
1449                 }
1450         }
1451
1452         /* re-resolve the open fd */
1453         status = pvfs_resolve_name_fd(f->pvfs, fd, f->handle->name);
1454         if (!NT_STATUS_IS_OK(status)) {
1455                 talloc_free(lck);
1456                 return status;
1457         }
1458
1459         if (f->handle->name->stream_id == 0 &&
1460             (io->generic.in.open_disposition == NTCREATEX_DISP_OVERWRITE ||
1461              io->generic.in.open_disposition == NTCREATEX_DISP_OVERWRITE_IF)) {
1462                 /* for overwrite we need to replace file permissions */
1463                 uint32_t attrib = io->ntcreatex.in.file_attr | FILE_ATTRIBUTE_ARCHIVE;
1464                 mode_t mode = pvfs_fileperms(pvfs, attrib);
1465                 if (fchmod(fd, mode) == -1) {
1466                         talloc_free(lck);
1467                         return pvfs_map_errno(pvfs, errno);
1468                 }
1469                 name->dos.alloc_size = io->ntcreatex.in.alloc_size;
1470                 name->dos.attrib = attrib;
1471                 status = pvfs_dosattrib_save(pvfs, name, fd);
1472                 if (!NT_STATUS_IS_OK(status)) {
1473                         talloc_free(lck);
1474                         return status;
1475                 }
1476         }
1477             
1478         talloc_free(lck);
1479
1480         status = ntvfs_handle_set_backend_data(h, ntvfs, f);
1481         NT_STATUS_NOT_OK_RETURN(status);
1482
1483         /* mark the open as having completed fully, so delete on close
1484            can now be used */
1485         f->handle->open_completed     = true;
1486
1487         io->generic.out.oplock_level  = oplock_granted;
1488         io->generic.out.file.ntvfs    = h;
1489         io->generic.out.create_action = stream_existed?
1490                 NTCREATEX_ACTION_EXISTED:NTCREATEX_ACTION_CREATED;
1491         io->generic.out.create_time   = name->dos.create_time;
1492         io->generic.out.access_time   = name->dos.access_time;
1493         io->generic.out.write_time    = name->dos.write_time;
1494         io->generic.out.change_time   = name->dos.change_time;
1495         io->generic.out.attrib        = name->dos.attrib;
1496         io->generic.out.alloc_size    = name->dos.alloc_size;
1497         io->generic.out.size          = name->st.st_size;
1498         io->generic.out.file_type     = FILE_TYPE_DISK;
1499         io->generic.out.ipc_state     = 0;
1500         io->generic.out.is_directory  = 0;
1501
1502         return NT_STATUS_OK;
1503 }
1504
1505
1506 /*
1507   close a file
1508 */
1509 NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs,
1510                     struct ntvfs_request *req, union smb_close *io)
1511 {
1512         struct pvfs_state *pvfs = ntvfs->private_data;
1513         struct pvfs_file *f;
1514         struct utimbuf unix_times;
1515
1516         if (io->generic.level == RAW_CLOSE_SPLCLOSE) {
1517                 return NT_STATUS_DOS(ERRSRV, ERRerror);
1518         }
1519
1520         if (io->generic.level != RAW_CLOSE_GENERIC) {
1521                 return ntvfs_map_close(ntvfs, req, io);
1522         }
1523
1524         f = pvfs_find_fd(pvfs, req, io->generic.in.file.ntvfs);
1525         if (!f) {
1526                 return NT_STATUS_INVALID_HANDLE;
1527         }
1528
1529         if (!null_time(io->generic.in.write_time)) {
1530                 unix_times.actime = 0;
1531                 unix_times.modtime = io->close.in.write_time;
1532                 utime(f->handle->name->full_name, &unix_times);
1533         }
1534
1535         if (io->generic.in.flags & SMB2_CLOSE_FLAGS_FULL_INFORMATION) {
1536                 struct pvfs_filename *name;
1537                 NTSTATUS status;
1538                 struct pvfs_file_handle *h = f->handle;
1539
1540                 status = pvfs_resolve_name_handle(pvfs, h);
1541                 if (!NT_STATUS_IS_OK(status)) {
1542                         return status;
1543                 }
1544                 name = h->name;
1545
1546                 io->generic.out.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION;
1547                 io->generic.out.create_time = name->dos.create_time;
1548                 io->generic.out.access_time = name->dos.access_time;
1549                 io->generic.out.write_time  = name->dos.write_time;
1550                 io->generic.out.change_time = name->dos.change_time;
1551                 io->generic.out.alloc_size  = name->dos.alloc_size;
1552                 io->generic.out.size        = name->st.st_size;
1553                 io->generic.out.file_attr   = name->dos.attrib;         
1554         } else {
1555                 ZERO_STRUCT(io->generic.out);
1556         }
1557
1558         talloc_free(f);
1559
1560         return NT_STATUS_OK;
1561 }
1562
1563
1564 /*
1565   logoff - close all file descriptors open by a vuid
1566 */
1567 NTSTATUS pvfs_logoff(struct ntvfs_module_context *ntvfs,
1568                      struct ntvfs_request *req)
1569 {
1570         struct pvfs_state *pvfs = ntvfs->private_data;
1571         struct pvfs_file *f, *next;
1572
1573         for (f=pvfs->files.list;f;f=next) {
1574                 next = f->next;
1575                 if (f->ntvfs->session_info == req->session_info) {
1576                         talloc_free(f);
1577                 }
1578         }
1579
1580         return NT_STATUS_OK;
1581 }
1582
1583
1584 /*
1585   exit - close files for the current pid
1586 */
1587 NTSTATUS pvfs_exit(struct ntvfs_module_context *ntvfs,
1588                    struct ntvfs_request *req)
1589 {
1590         struct pvfs_state *pvfs = ntvfs->private_data;
1591         struct pvfs_file *f, *next;
1592
1593         for (f=pvfs->files.list;f;f=next) {
1594                 next = f->next;
1595                 if (f->ntvfs->session_info == req->session_info &&
1596                     f->ntvfs->smbpid == req->smbpid) {
1597                         talloc_free(f);
1598                 }
1599         }
1600
1601         return NT_STATUS_OK;
1602 }
1603
1604
1605 /*
1606   change the delete on close flag on an already open file
1607 */
1608 NTSTATUS pvfs_set_delete_on_close(struct pvfs_state *pvfs,
1609                                   struct ntvfs_request *req, 
1610                                   struct pvfs_file *f, bool del_on_close)
1611 {
1612         struct odb_lock *lck;
1613         NTSTATUS status;
1614
1615         if ((f->handle->name->dos.attrib & FILE_ATTRIBUTE_READONLY) && del_on_close) {
1616                 return NT_STATUS_CANNOT_DELETE;
1617         }
1618         
1619         if ((f->handle->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) &&
1620             !pvfs_directory_empty(pvfs, f->handle->name)) {
1621                 return NT_STATUS_DIRECTORY_NOT_EMPTY;
1622         }
1623
1624         if (del_on_close) {
1625                 f->handle->create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
1626         } else {
1627                 f->handle->create_options &= ~NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
1628         }
1629         
1630         lck = odb_lock(req, pvfs->odb_context, &f->handle->odb_locking_key);
1631         if (lck == NULL) {
1632                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1633         }
1634
1635         status = odb_set_delete_on_close(lck, del_on_close);
1636
1637         talloc_free(lck);
1638
1639         return status;
1640 }
1641
1642
1643 /*
1644   determine if a file can be deleted, or if it is prevented by an
1645   already open file
1646 */
1647 NTSTATUS pvfs_can_delete(struct pvfs_state *pvfs, 
1648                          struct ntvfs_request *req,
1649                          struct pvfs_filename *name,
1650                          struct odb_lock **lckp)
1651 {
1652         NTSTATUS status;
1653         DATA_BLOB key;
1654         struct odb_lock *lck;
1655         uint32_t share_access;
1656         uint32_t access_mask;
1657         bool delete_on_close;
1658
1659         status = pvfs_locking_key(name, name, &key);
1660         if (!NT_STATUS_IS_OK(status)) {
1661                 return NT_STATUS_NO_MEMORY;
1662         }
1663
1664         lck = odb_lock(req, pvfs->odb_context, &key);
1665         if (lck == NULL) {
1666                 DEBUG(0,("Unable to lock opendb for can_delete\n"));
1667                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1668         }
1669
1670         share_access    = NTCREATEX_SHARE_ACCESS_READ |
1671                           NTCREATEX_SHARE_ACCESS_WRITE |
1672                           NTCREATEX_SHARE_ACCESS_DELETE;
1673         access_mask     = SEC_STD_DELETE;
1674         delete_on_close = true;
1675
1676         status = odb_can_open(lck, name->stream_id,
1677                               share_access, access_mask, delete_on_close,
1678                               NTCREATEX_DISP_OPEN, false);
1679
1680         if (NT_STATUS_IS_OK(status)) {
1681                 status = pvfs_access_check_simple(pvfs, req, name, access_mask);
1682         }
1683
1684         /*
1685          * if it's a sharing violation or we got no oplock
1686          * only keep the lock if the caller requested access
1687          * to the lock
1688          */
1689         if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) ||
1690             NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
1691                 if (lckp) {
1692                         *lckp = lck;
1693                 } else {
1694                         talloc_free(lck);
1695                 }
1696         } else if (!NT_STATUS_IS_OK(status)) {
1697                 talloc_free(lck);
1698                 if (lckp) {
1699                         *lckp = NULL;
1700                 }
1701         } else if (lckp) {
1702                 *lckp = lck;
1703         }
1704
1705         return status;
1706 }
1707
1708 /*
1709   determine if a file can be renamed, or if it is prevented by an
1710   already open file
1711 */
1712 NTSTATUS pvfs_can_rename(struct pvfs_state *pvfs, 
1713                          struct ntvfs_request *req,
1714                          struct pvfs_filename *name,
1715                          struct odb_lock **lckp)
1716 {
1717         NTSTATUS status;
1718         DATA_BLOB key;
1719         struct odb_lock *lck;
1720         uint32_t share_access;
1721         uint32_t access_mask;
1722         bool delete_on_close;
1723
1724         status = pvfs_locking_key(name, name, &key);
1725         if (!NT_STATUS_IS_OK(status)) {
1726                 return NT_STATUS_NO_MEMORY;
1727         }
1728
1729         lck = odb_lock(req, pvfs->odb_context, &key);
1730         if (lck == NULL) {
1731                 DEBUG(0,("Unable to lock opendb for can_stat\n"));
1732                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1733         }
1734
1735         share_access    = NTCREATEX_SHARE_ACCESS_READ |
1736                           NTCREATEX_SHARE_ACCESS_WRITE;
1737         access_mask     = SEC_STD_DELETE;
1738         delete_on_close = false;
1739
1740         status = odb_can_open(lck, name->stream_id,
1741                               share_access, access_mask, delete_on_close,
1742                               NTCREATEX_DISP_OPEN, false);
1743
1744         /*
1745          * if it's a sharing violation or we got no oplock
1746          * only keep the lock if the caller requested access
1747          * to the lock
1748          */
1749         if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) ||
1750             NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
1751                 if (lckp) {
1752                         *lckp = lck;
1753                 } else {
1754                         talloc_free(lck);
1755                 }
1756         } else if (!NT_STATUS_IS_OK(status)) {
1757                 talloc_free(lck);
1758                 if (lckp) {
1759                         *lckp = NULL;
1760                 }
1761         } else if (lckp) {
1762                 *lckp = lck;
1763         }
1764
1765         return status;
1766 }
1767
1768 /*
1769   determine if the file size of a file can be changed,
1770   or if it is prevented by an already open file
1771 */
1772 NTSTATUS pvfs_can_update_file_size(struct pvfs_state *pvfs,
1773                                    struct ntvfs_request *req,
1774                                    struct pvfs_filename *name,
1775                                    struct odb_lock **lckp)
1776 {
1777         NTSTATUS status;
1778         DATA_BLOB key;
1779         struct odb_lock *lck;
1780         uint32_t share_access;
1781         uint32_t access_mask;
1782         bool break_to_none;
1783         bool delete_on_close;
1784
1785         status = pvfs_locking_key(name, name, &key);
1786         if (!NT_STATUS_IS_OK(status)) {
1787                 return NT_STATUS_NO_MEMORY;
1788         }
1789
1790         lck = odb_lock(req, pvfs->odb_context, &key);
1791         if (lck == NULL) {
1792                 DEBUG(0,("Unable to lock opendb for can_stat\n"));
1793                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1794         }
1795
1796         share_access    = NTCREATEX_SHARE_ACCESS_READ |
1797                           NTCREATEX_SHARE_ACCESS_WRITE |
1798                           NTCREATEX_SHARE_ACCESS_DELETE;
1799         /*
1800          * I would have thought that we would need to pass
1801          * SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA here too
1802          *
1803          * But you only need SEC_FILE_WRITE_ATTRIBUTE permissions
1804          * to set the filesize.
1805          *
1806          * --metze
1807          */
1808         access_mask     = SEC_FILE_WRITE_ATTRIBUTE;
1809         delete_on_close = false;
1810         break_to_none   = true;
1811
1812         status = odb_can_open(lck, name->stream_id,
1813                               share_access, access_mask, delete_on_close,
1814                               NTCREATEX_DISP_OPEN, break_to_none);
1815
1816         /*
1817          * if it's a sharing violation or we got no oplock
1818          * only keep the lock if the caller requested access
1819          * to the lock
1820          */
1821         if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) ||
1822             NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
1823                 if (lckp) {
1824                         *lckp = lck;
1825                 } else {
1826                         talloc_free(lck);
1827                 }
1828         } else if (!NT_STATUS_IS_OK(status)) {
1829                 talloc_free(lck);
1830                 if (lckp) {
1831                         *lckp = NULL;
1832                 }
1833         } else if (lckp) {
1834                 *lckp = lck;
1835         }
1836
1837         return status;
1838 }
1839
1840 /*
1841   determine if file meta data can be accessed, or if it is prevented by an
1842   already open file
1843 */
1844 NTSTATUS pvfs_can_stat(struct pvfs_state *pvfs, 
1845                        struct ntvfs_request *req,
1846                        struct pvfs_filename *name)
1847 {
1848         NTSTATUS status;
1849         DATA_BLOB key;
1850         struct odb_lock *lck;
1851         uint32_t share_access;
1852         uint32_t access_mask;
1853         bool delete_on_close;
1854
1855         status = pvfs_locking_key(name, name, &key);
1856         if (!NT_STATUS_IS_OK(status)) {
1857                 return NT_STATUS_NO_MEMORY;
1858         }
1859
1860         lck = odb_lock(req, pvfs->odb_context, &key);
1861         if (lck == NULL) {
1862                 DEBUG(0,("Unable to lock opendb for can_stat\n"));
1863                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1864         }
1865
1866         share_access    = NTCREATEX_SHARE_ACCESS_READ |
1867                           NTCREATEX_SHARE_ACCESS_WRITE;
1868         access_mask     = SEC_FILE_READ_ATTRIBUTE;
1869         delete_on_close = false;
1870
1871         status = odb_can_open(lck, name->stream_id,
1872                               share_access, access_mask, delete_on_close,
1873                               NTCREATEX_DISP_OPEN, false);
1874
1875         if (!NT_STATUS_IS_OK(status)) {
1876                 talloc_free(lck);
1877         }
1878
1879         return status;
1880 }
1881
1882
1883 /*
1884   determine if delete on close is set on 
1885 */
1886 bool pvfs_delete_on_close_set(struct pvfs_state *pvfs, struct pvfs_file_handle *h)
1887 {
1888         NTSTATUS status;
1889         bool del_on_close;
1890
1891         status = odb_get_delete_on_close(pvfs->odb_context, &h->odb_locking_key, 
1892                                          &del_on_close);
1893         if (!NT_STATUS_IS_OK(status)) {
1894                 DEBUG(1,("WARNING: unable to determine delete on close status for open file\n"));
1895                 return false;
1896         }
1897
1898         return del_on_close;
1899 }