fixed create_action for truncated files
[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         uint32_t create_action = NTCREATEX_ACTION_EXISTED;
1126         bool del_on_close;
1127         bool stream_existed, stream_truncate=false;
1128         uint32_t oplock_level = OPLOCK_NONE, oplock_granted;
1129         bool allow_level_II_oplock = false;
1130
1131         /* use the generic mapping code to avoid implementing all the
1132            different open calls. */
1133         if (io->generic.level != RAW_OPEN_GENERIC &&
1134             io->generic.level != RAW_OPEN_NTTRANS_CREATE) {
1135                 return ntvfs_map_open(ntvfs, req, io);
1136         }
1137
1138         create_options = io->generic.in.create_options;
1139         share_access   = io->generic.in.share_access;
1140         access_mask    = io->generic.in.access_mask;
1141
1142         if (share_access & ~NTCREATEX_SHARE_ACCESS_MASK) {
1143                 return NT_STATUS_INVALID_PARAMETER;
1144         }
1145
1146         /* some create options are not supported */
1147         if (create_options & NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK) {
1148                 return NT_STATUS_NOT_SUPPORTED;
1149         }
1150
1151         /* other create options are not allowed */
1152         if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) &&
1153             !(access_mask & SEC_STD_DELETE)) {
1154                 return NT_STATUS_INVALID_PARAMETER;
1155         }
1156
1157         if (access_mask & SEC_MASK_INVALID) {
1158                 return NT_STATUS_ACCESS_DENIED;
1159         }
1160
1161         /* what does this bit really mean?? */
1162         if (req->ctx->protocol == PROTOCOL_SMB2 &&
1163             access_mask == SEC_STD_SYNCHRONIZE) {
1164                 return NT_STATUS_ACCESS_DENIED;
1165         }
1166
1167         if (io->ntcreatex.in.file_attr & (FILE_ATTRIBUTE_DEVICE|
1168                                           FILE_ATTRIBUTE_VOLUME| 
1169                                           (~FILE_ATTRIBUTE_ALL_MASK))) {
1170                 return NT_STATUS_INVALID_PARAMETER;
1171         }
1172
1173         /* we ignore some file_attr bits */
1174         io->ntcreatex.in.file_attr &= ~(FILE_ATTRIBUTE_NONINDEXED | 
1175                                         FILE_ATTRIBUTE_COMPRESSED |
1176                                         FILE_ATTRIBUTE_REPARSE_POINT |
1177                                         FILE_ATTRIBUTE_SPARSE |
1178                                         FILE_ATTRIBUTE_NORMAL);
1179
1180         /* resolve the cifs name to a posix name */
1181         status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, 
1182                                    PVFS_RESOLVE_STREAMS, &name);
1183         if (!NT_STATUS_IS_OK(status)) {
1184                 return status;
1185         }
1186
1187         /* if the client specified that it must not be a directory then
1188            check that it isn't */
1189         if (name->exists && (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) &&
1190             (io->generic.in.create_options & NTCREATEX_OPTIONS_NON_DIRECTORY_FILE)) {
1191                 return NT_STATUS_FILE_IS_A_DIRECTORY;
1192         }
1193
1194         /* if the client specified that it must be a directory then
1195            check that it is */
1196         if (name->exists && !(name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) &&
1197             (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY)) {
1198                 return NT_STATUS_NOT_A_DIRECTORY;
1199         }
1200
1201         /* directory opens are handled separately */
1202         if ((name->exists && (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) ||
1203             (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY)) {
1204                 return pvfs_open_directory(pvfs, req, name, io);
1205         }
1206
1207         /* FILE_ATTRIBUTE_DIRECTORY is ignored if the above test for directory
1208            open doesn't match */
1209         io->generic.in.file_attr &= ~FILE_ATTRIBUTE_DIRECTORY;
1210
1211         flags = 0;
1212
1213         switch (io->generic.in.open_disposition) {
1214         case NTCREATEX_DISP_SUPERSEDE:
1215         case NTCREATEX_DISP_OVERWRITE_IF:
1216                 if (name->stream_name == NULL) {
1217                         flags = O_TRUNC;
1218                 } else {
1219                         stream_truncate = true;
1220                 }
1221                 create_action = NTCREATEX_ACTION_TRUNCATED;
1222                 break;
1223
1224         case NTCREATEX_DISP_OPEN:
1225                 if (!name->stream_exists) {
1226                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1227                 }
1228                 flags = 0;
1229                 break;
1230
1231         case NTCREATEX_DISP_OVERWRITE:
1232                 if (!name->stream_exists) {
1233                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1234                 }
1235                 if (name->stream_name == NULL) {
1236                         flags = O_TRUNC;
1237                 } else {
1238                         stream_truncate = true;
1239                 }
1240                 create_action = NTCREATEX_ACTION_TRUNCATED;
1241                 break;
1242
1243         case NTCREATEX_DISP_CREATE:
1244                 if (name->stream_exists) {
1245                         return NT_STATUS_OBJECT_NAME_COLLISION;
1246                 }
1247                 flags = 0;
1248                 break;
1249
1250         case NTCREATEX_DISP_OPEN_IF:
1251                 flags = 0;
1252                 break;
1253
1254         default:
1255                 return NT_STATUS_INVALID_PARAMETER;
1256         }
1257
1258         /* handle creating a new file separately */
1259         if (!name->exists) {
1260                 status = pvfs_create_file(pvfs, req, name, io);
1261                 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
1262                         return status;
1263                 }
1264
1265                 /* we've hit a race - the file was created during this call */
1266                 if (io->generic.in.open_disposition == NTCREATEX_DISP_CREATE) {
1267                         return status;
1268                 }
1269
1270                 /* try re-resolving the name */
1271                 status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, 0, &name);
1272                 if (!NT_STATUS_IS_OK(status)) {
1273                         return status;
1274                 }
1275                 /* fall through to a normal open */
1276         }
1277
1278         if ((name->dos.attrib & FILE_ATTRIBUTE_READONLY) &&
1279             (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) {
1280                 return NT_STATUS_CANNOT_DELETE;
1281         }
1282
1283         /* check the security descriptor */
1284         status = pvfs_access_check(pvfs, req, name, &access_mask);
1285         if (!NT_STATUS_IS_OK(status)) {
1286                 return status;
1287         }
1288
1289         status = ntvfs_handle_new(pvfs->ntvfs, req, &h);
1290         NT_STATUS_NOT_OK_RETURN(status);
1291
1292         f = talloc(h, struct pvfs_file);
1293         if (f == NULL) {
1294                 return NT_STATUS_NO_MEMORY;
1295         }
1296
1297         f->handle = talloc(f, struct pvfs_file_handle);
1298         if (f->handle == NULL) {
1299                 return NT_STATUS_NO_MEMORY;
1300         }
1301
1302         f->ntvfs         = h;
1303         f->pvfs          = pvfs;
1304         f->pending_list  = NULL;
1305         f->lock_count    = 0;
1306         f->share_access  = io->generic.in.share_access;
1307         f->access_mask   = access_mask;
1308         f->impersonation = io->generic.in.impersonation;
1309         f->notify_buffer = NULL;
1310         f->search        = NULL;
1311
1312         f->handle->pvfs              = pvfs;
1313         f->handle->fd                = -1;
1314         f->handle->name              = talloc_steal(f->handle, name);
1315         f->handle->create_options    = io->generic.in.create_options;
1316         f->handle->seek_offset       = 0;
1317         f->handle->position          = 0;
1318         f->handle->mode              = 0;
1319         f->handle->oplock            = NULL;
1320         f->handle->have_opendb_entry = false;
1321         f->handle->open_completed    = false;
1322
1323         /* form the lock context used for byte range locking and
1324            opendb locking */
1325         status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key);
1326         if (!NT_STATUS_IS_OK(status)) {
1327                 return status;
1328         }
1329
1330         status = pvfs_brl_locking_handle(f, name, h, &f->brl_handle);
1331         if (!NT_STATUS_IS_OK(status)) {
1332                 return status;
1333         }
1334
1335         /* get a lock on this file before the actual open */
1336         lck = odb_lock(req, pvfs->odb_context, &f->handle->odb_locking_key);
1337         if (lck == NULL) {
1338                 DEBUG(0,("pvfs_open: failed to lock file '%s' in opendb\n",
1339                          name->full_name));
1340                 /* we were supposed to do a blocking lock, so something
1341                    is badly wrong! */
1342                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1343         }
1344
1345         DLIST_ADD(pvfs->files.list, f);
1346
1347         /* setup a destructor to avoid file descriptor leaks on
1348            abnormal termination */
1349         talloc_set_destructor(f, pvfs_fnum_destructor);
1350         talloc_set_destructor(f->handle, pvfs_handle_destructor);
1351
1352         /* 
1353          * Only SMB2 takes care of the delete_on_close,
1354          * on existing files
1355          */
1356         if (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE &&
1357             req->ctx->protocol == PROTOCOL_SMB2) {
1358                 del_on_close = true;
1359         } else {
1360                 del_on_close = false;
1361         }
1362
1363         if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) {
1364                 oplock_level = OPLOCK_NONE;
1365         } else if (io->ntcreatex.in.flags & NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK) {
1366                 oplock_level = OPLOCK_BATCH;
1367         } else if (io->ntcreatex.in.flags & NTCREATEX_FLAGS_REQUEST_OPLOCK) {
1368                 oplock_level = OPLOCK_EXCLUSIVE;
1369         }
1370
1371         if (req->client_caps & NTVFS_CLIENT_CAP_LEVEL_II_OPLOCKS) {
1372                 allow_level_II_oplock = true;
1373         }
1374
1375         /* see if we are allowed to open at the same time as existing opens */
1376         status = odb_can_open(lck, name->stream_id,
1377                               share_access, access_mask, del_on_close,
1378                               io->generic.in.open_disposition, false);
1379
1380         /*
1381          * on a sharing violation we need to retry when the file is closed by
1382          * the other user, or after 1 second
1383          * on a non granted oplock we need to retry when the file is closed by
1384          * the other user, or after 30 seconds
1385         */
1386         if ((NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) ||
1387              NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) &&
1388             (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {
1389                 return pvfs_open_setup_retry(ntvfs, req, io, f, lck, status);
1390         }
1391
1392         if (!NT_STATUS_IS_OK(status)) {
1393                 talloc_free(lck);
1394                 return status;
1395         }
1396
1397         if (access_mask & (SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA)) {
1398                 flags |= O_RDWR;
1399         } else {
1400                 flags |= O_RDONLY;
1401         }
1402
1403         /* do the actual open */
1404         fd = open(f->handle->name->full_name, flags | O_NONBLOCK);
1405         if (fd == -1) {
1406                 status = pvfs_map_errno(f->pvfs, errno);
1407
1408                 /*
1409                  * STATUS_MORE_ENTRIES is EAGAIN or EWOULDBLOCK
1410                  */
1411                 if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
1412                     (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {
1413                         return pvfs_open_setup_retry(ntvfs, req, io, f, lck, status);
1414                 }
1415
1416                 talloc_free(lck);
1417                 return status;
1418         }
1419
1420         f->handle->fd = fd;
1421
1422         /* now really mark the file as open */
1423         status = odb_open_file(lck, f->handle, name->full_name,
1424                                &f->handle->fd, allow_level_II_oplock,
1425                                oplock_level, &oplock_granted);
1426
1427         if (!NT_STATUS_IS_OK(status)) {
1428                 talloc_free(lck);
1429                 return status;
1430         }
1431
1432         f->handle->have_opendb_entry = true;
1433
1434         if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) {
1435                 oplock_granted = OPLOCK_BATCH;
1436         } else if (oplock_granted != OPLOCK_NONE) {
1437                 status = pvfs_setup_oplock(f, oplock_granted);
1438                 if (!NT_STATUS_IS_OK(status)) {
1439                         talloc_free(lck);
1440                         return status;
1441                 }
1442         }
1443
1444         stream_existed = name->stream_exists;
1445
1446         /* if this was a stream create then create the stream as well */
1447         if (!name->stream_exists) {
1448                 status = pvfs_stream_create(pvfs, f->handle->name, fd);
1449                 if (!NT_STATUS_IS_OK(status)) {
1450                         talloc_free(lck);
1451                         return status;
1452                 }
1453                 if (stream_truncate) {
1454                         status = pvfs_stream_truncate(pvfs, f->handle->name, fd, 0);
1455                         if (!NT_STATUS_IS_OK(status)) {
1456                                 talloc_free(lck);
1457                                 return status;
1458                         }
1459                 }
1460         }
1461
1462         /* re-resolve the open fd */
1463         status = pvfs_resolve_name_fd(f->pvfs, fd, f->handle->name);
1464         if (!NT_STATUS_IS_OK(status)) {
1465                 talloc_free(lck);
1466                 return status;
1467         }
1468
1469         if (f->handle->name->stream_id == 0 &&
1470             (io->generic.in.open_disposition == NTCREATEX_DISP_OVERWRITE ||
1471              io->generic.in.open_disposition == NTCREATEX_DISP_OVERWRITE_IF)) {
1472                 /* for overwrite we need to replace file permissions */
1473                 uint32_t attrib = io->ntcreatex.in.file_attr | FILE_ATTRIBUTE_ARCHIVE;
1474                 mode_t mode = pvfs_fileperms(pvfs, attrib);
1475                 if (fchmod(fd, mode) == -1) {
1476                         talloc_free(lck);
1477                         return pvfs_map_errno(pvfs, errno);
1478                 }
1479                 name->dos.alloc_size = io->ntcreatex.in.alloc_size;
1480                 name->dos.attrib = attrib;
1481                 status = pvfs_dosattrib_save(pvfs, name, fd);
1482                 if (!NT_STATUS_IS_OK(status)) {
1483                         talloc_free(lck);
1484                         return status;
1485                 }
1486         }
1487             
1488         talloc_free(lck);
1489
1490         status = ntvfs_handle_set_backend_data(h, ntvfs, f);
1491         NT_STATUS_NOT_OK_RETURN(status);
1492
1493         /* mark the open as having completed fully, so delete on close
1494            can now be used */
1495         f->handle->open_completed     = true;
1496
1497         io->generic.out.oplock_level  = oplock_granted;
1498         io->generic.out.file.ntvfs    = h;
1499         io->generic.out.create_action = stream_existed?
1500                 create_action:NTCREATEX_ACTION_CREATED;
1501         
1502         io->generic.out.create_time   = name->dos.create_time;
1503         io->generic.out.access_time   = name->dos.access_time;
1504         io->generic.out.write_time    = name->dos.write_time;
1505         io->generic.out.change_time   = name->dos.change_time;
1506         io->generic.out.attrib        = name->dos.attrib;
1507         io->generic.out.alloc_size    = name->dos.alloc_size;
1508         io->generic.out.size          = name->st.st_size;
1509         io->generic.out.file_type     = FILE_TYPE_DISK;
1510         io->generic.out.ipc_state     = 0;
1511         io->generic.out.is_directory  = 0;
1512
1513         return NT_STATUS_OK;
1514 }
1515
1516
1517 /*
1518   close a file
1519 */
1520 NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs,
1521                     struct ntvfs_request *req, union smb_close *io)
1522 {
1523         struct pvfs_state *pvfs = ntvfs->private_data;
1524         struct pvfs_file *f;
1525         struct utimbuf unix_times;
1526
1527         if (io->generic.level == RAW_CLOSE_SPLCLOSE) {
1528                 return NT_STATUS_DOS(ERRSRV, ERRerror);
1529         }
1530
1531         if (io->generic.level != RAW_CLOSE_GENERIC) {
1532                 return ntvfs_map_close(ntvfs, req, io);
1533         }
1534
1535         f = pvfs_find_fd(pvfs, req, io->generic.in.file.ntvfs);
1536         if (!f) {
1537                 return NT_STATUS_INVALID_HANDLE;
1538         }
1539
1540         if (!null_time(io->generic.in.write_time)) {
1541                 unix_times.actime = 0;
1542                 unix_times.modtime = io->close.in.write_time;
1543                 utime(f->handle->name->full_name, &unix_times);
1544         }
1545
1546         if (io->generic.in.flags & SMB2_CLOSE_FLAGS_FULL_INFORMATION) {
1547                 struct pvfs_filename *name;
1548                 NTSTATUS status;
1549                 struct pvfs_file_handle *h = f->handle;
1550
1551                 status = pvfs_resolve_name_handle(pvfs, h);
1552                 if (!NT_STATUS_IS_OK(status)) {
1553                         return status;
1554                 }
1555                 name = h->name;
1556
1557                 io->generic.out.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION;
1558                 io->generic.out.create_time = name->dos.create_time;
1559                 io->generic.out.access_time = name->dos.access_time;
1560                 io->generic.out.write_time  = name->dos.write_time;
1561                 io->generic.out.change_time = name->dos.change_time;
1562                 io->generic.out.alloc_size  = name->dos.alloc_size;
1563                 io->generic.out.size        = name->st.st_size;
1564                 io->generic.out.file_attr   = name->dos.attrib;         
1565         } else {
1566                 ZERO_STRUCT(io->generic.out);
1567         }
1568
1569         talloc_free(f);
1570
1571         return NT_STATUS_OK;
1572 }
1573
1574
1575 /*
1576   logoff - close all file descriptors open by a vuid
1577 */
1578 NTSTATUS pvfs_logoff(struct ntvfs_module_context *ntvfs,
1579                      struct ntvfs_request *req)
1580 {
1581         struct pvfs_state *pvfs = ntvfs->private_data;
1582         struct pvfs_file *f, *next;
1583
1584         for (f=pvfs->files.list;f;f=next) {
1585                 next = f->next;
1586                 if (f->ntvfs->session_info == req->session_info) {
1587                         talloc_free(f);
1588                 }
1589         }
1590
1591         return NT_STATUS_OK;
1592 }
1593
1594
1595 /*
1596   exit - close files for the current pid
1597 */
1598 NTSTATUS pvfs_exit(struct ntvfs_module_context *ntvfs,
1599                    struct ntvfs_request *req)
1600 {
1601         struct pvfs_state *pvfs = ntvfs->private_data;
1602         struct pvfs_file *f, *next;
1603
1604         for (f=pvfs->files.list;f;f=next) {
1605                 next = f->next;
1606                 if (f->ntvfs->session_info == req->session_info &&
1607                     f->ntvfs->smbpid == req->smbpid) {
1608                         talloc_free(f);
1609                 }
1610         }
1611
1612         return NT_STATUS_OK;
1613 }
1614
1615
1616 /*
1617   change the delete on close flag on an already open file
1618 */
1619 NTSTATUS pvfs_set_delete_on_close(struct pvfs_state *pvfs,
1620                                   struct ntvfs_request *req, 
1621                                   struct pvfs_file *f, bool del_on_close)
1622 {
1623         struct odb_lock *lck;
1624         NTSTATUS status;
1625
1626         if ((f->handle->name->dos.attrib & FILE_ATTRIBUTE_READONLY) && del_on_close) {
1627                 return NT_STATUS_CANNOT_DELETE;
1628         }
1629         
1630         if ((f->handle->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) &&
1631             !pvfs_directory_empty(pvfs, f->handle->name)) {
1632                 return NT_STATUS_DIRECTORY_NOT_EMPTY;
1633         }
1634
1635         if (del_on_close) {
1636                 f->handle->create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
1637         } else {
1638                 f->handle->create_options &= ~NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
1639         }
1640         
1641         lck = odb_lock(req, pvfs->odb_context, &f->handle->odb_locking_key);
1642         if (lck == NULL) {
1643                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1644         }
1645
1646         status = odb_set_delete_on_close(lck, del_on_close);
1647
1648         talloc_free(lck);
1649
1650         return status;
1651 }
1652
1653
1654 /*
1655   determine if a file can be deleted, or if it is prevented by an
1656   already open file
1657 */
1658 NTSTATUS pvfs_can_delete(struct pvfs_state *pvfs, 
1659                          struct ntvfs_request *req,
1660                          struct pvfs_filename *name,
1661                          struct odb_lock **lckp)
1662 {
1663         NTSTATUS status;
1664         DATA_BLOB key;
1665         struct odb_lock *lck;
1666         uint32_t share_access;
1667         uint32_t access_mask;
1668         bool delete_on_close;
1669
1670         status = pvfs_locking_key(name, name, &key);
1671         if (!NT_STATUS_IS_OK(status)) {
1672                 return NT_STATUS_NO_MEMORY;
1673         }
1674
1675         lck = odb_lock(req, pvfs->odb_context, &key);
1676         if (lck == NULL) {
1677                 DEBUG(0,("Unable to lock opendb for can_delete\n"));
1678                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1679         }
1680
1681         share_access    = NTCREATEX_SHARE_ACCESS_READ |
1682                           NTCREATEX_SHARE_ACCESS_WRITE |
1683                           NTCREATEX_SHARE_ACCESS_DELETE;
1684         access_mask     = SEC_STD_DELETE;
1685         delete_on_close = true;
1686
1687         status = odb_can_open(lck, name->stream_id,
1688                               share_access, access_mask, delete_on_close,
1689                               NTCREATEX_DISP_OPEN, false);
1690
1691         if (NT_STATUS_IS_OK(status)) {
1692                 status = pvfs_access_check_simple(pvfs, req, name, access_mask);
1693         }
1694
1695         /*
1696          * if it's a sharing violation or we got no oplock
1697          * only keep the lock if the caller requested access
1698          * to the lock
1699          */
1700         if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) ||
1701             NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
1702                 if (lckp) {
1703                         *lckp = lck;
1704                 } else {
1705                         talloc_free(lck);
1706                 }
1707         } else if (!NT_STATUS_IS_OK(status)) {
1708                 talloc_free(lck);
1709                 if (lckp) {
1710                         *lckp = NULL;
1711                 }
1712         } else if (lckp) {
1713                 *lckp = lck;
1714         }
1715
1716         return status;
1717 }
1718
1719 /*
1720   determine if a file can be renamed, or if it is prevented by an
1721   already open file
1722 */
1723 NTSTATUS pvfs_can_rename(struct pvfs_state *pvfs, 
1724                          struct ntvfs_request *req,
1725                          struct pvfs_filename *name,
1726                          struct odb_lock **lckp)
1727 {
1728         NTSTATUS status;
1729         DATA_BLOB key;
1730         struct odb_lock *lck;
1731         uint32_t share_access;
1732         uint32_t access_mask;
1733         bool delete_on_close;
1734
1735         status = pvfs_locking_key(name, name, &key);
1736         if (!NT_STATUS_IS_OK(status)) {
1737                 return NT_STATUS_NO_MEMORY;
1738         }
1739
1740         lck = odb_lock(req, pvfs->odb_context, &key);
1741         if (lck == NULL) {
1742                 DEBUG(0,("Unable to lock opendb for can_stat\n"));
1743                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1744         }
1745
1746         share_access    = NTCREATEX_SHARE_ACCESS_READ |
1747                           NTCREATEX_SHARE_ACCESS_WRITE;
1748         access_mask     = SEC_STD_DELETE;
1749         delete_on_close = false;
1750
1751         status = odb_can_open(lck, name->stream_id,
1752                               share_access, access_mask, delete_on_close,
1753                               NTCREATEX_DISP_OPEN, false);
1754
1755         /*
1756          * if it's a sharing violation or we got no oplock
1757          * only keep the lock if the caller requested access
1758          * to the lock
1759          */
1760         if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) ||
1761             NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
1762                 if (lckp) {
1763                         *lckp = lck;
1764                 } else {
1765                         talloc_free(lck);
1766                 }
1767         } else if (!NT_STATUS_IS_OK(status)) {
1768                 talloc_free(lck);
1769                 if (lckp) {
1770                         *lckp = NULL;
1771                 }
1772         } else if (lckp) {
1773                 *lckp = lck;
1774         }
1775
1776         return status;
1777 }
1778
1779 /*
1780   determine if the file size of a file can be changed,
1781   or if it is prevented by an already open file
1782 */
1783 NTSTATUS pvfs_can_update_file_size(struct pvfs_state *pvfs,
1784                                    struct ntvfs_request *req,
1785                                    struct pvfs_filename *name,
1786                                    struct odb_lock **lckp)
1787 {
1788         NTSTATUS status;
1789         DATA_BLOB key;
1790         struct odb_lock *lck;
1791         uint32_t share_access;
1792         uint32_t access_mask;
1793         bool break_to_none;
1794         bool delete_on_close;
1795
1796         status = pvfs_locking_key(name, name, &key);
1797         if (!NT_STATUS_IS_OK(status)) {
1798                 return NT_STATUS_NO_MEMORY;
1799         }
1800
1801         lck = odb_lock(req, pvfs->odb_context, &key);
1802         if (lck == NULL) {
1803                 DEBUG(0,("Unable to lock opendb for can_stat\n"));
1804                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1805         }
1806
1807         share_access    = NTCREATEX_SHARE_ACCESS_READ |
1808                           NTCREATEX_SHARE_ACCESS_WRITE |
1809                           NTCREATEX_SHARE_ACCESS_DELETE;
1810         /*
1811          * I would have thought that we would need to pass
1812          * SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA here too
1813          *
1814          * But you only need SEC_FILE_WRITE_ATTRIBUTE permissions
1815          * to set the filesize.
1816          *
1817          * --metze
1818          */
1819         access_mask     = SEC_FILE_WRITE_ATTRIBUTE;
1820         delete_on_close = false;
1821         break_to_none   = true;
1822
1823         status = odb_can_open(lck, name->stream_id,
1824                               share_access, access_mask, delete_on_close,
1825                               NTCREATEX_DISP_OPEN, break_to_none);
1826
1827         /*
1828          * if it's a sharing violation or we got no oplock
1829          * only keep the lock if the caller requested access
1830          * to the lock
1831          */
1832         if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) ||
1833             NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
1834                 if (lckp) {
1835                         *lckp = lck;
1836                 } else {
1837                         talloc_free(lck);
1838                 }
1839         } else if (!NT_STATUS_IS_OK(status)) {
1840                 talloc_free(lck);
1841                 if (lckp) {
1842                         *lckp = NULL;
1843                 }
1844         } else if (lckp) {
1845                 *lckp = lck;
1846         }
1847
1848         return status;
1849 }
1850
1851 /*
1852   determine if file meta data can be accessed, or if it is prevented by an
1853   already open file
1854 */
1855 NTSTATUS pvfs_can_stat(struct pvfs_state *pvfs, 
1856                        struct ntvfs_request *req,
1857                        struct pvfs_filename *name)
1858 {
1859         NTSTATUS status;
1860         DATA_BLOB key;
1861         struct odb_lock *lck;
1862         uint32_t share_access;
1863         uint32_t access_mask;
1864         bool delete_on_close;
1865
1866         status = pvfs_locking_key(name, name, &key);
1867         if (!NT_STATUS_IS_OK(status)) {
1868                 return NT_STATUS_NO_MEMORY;
1869         }
1870
1871         lck = odb_lock(req, pvfs->odb_context, &key);
1872         if (lck == NULL) {
1873                 DEBUG(0,("Unable to lock opendb for can_stat\n"));
1874                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1875         }
1876
1877         share_access    = NTCREATEX_SHARE_ACCESS_READ |
1878                           NTCREATEX_SHARE_ACCESS_WRITE;
1879         access_mask     = SEC_FILE_READ_ATTRIBUTE;
1880         delete_on_close = false;
1881
1882         status = odb_can_open(lck, name->stream_id,
1883                               share_access, access_mask, delete_on_close,
1884                               NTCREATEX_DISP_OPEN, false);
1885
1886         if (!NT_STATUS_IS_OK(status)) {
1887                 talloc_free(lck);
1888         }
1889
1890         return status;
1891 }
1892
1893
1894 /*
1895   determine if delete on close is set on 
1896 */
1897 bool pvfs_delete_on_close_set(struct pvfs_state *pvfs, struct pvfs_file_handle *h)
1898 {
1899         NTSTATUS status;
1900         bool del_on_close;
1901
1902         status = odb_get_delete_on_close(pvfs->odb_context, &h->odb_locking_key, 
1903                                          &del_on_close);
1904         if (!NT_STATUS_IS_OK(status)) {
1905                 DEBUG(1,("WARNING: unable to determine delete on close status for open file\n"));
1906                 return false;
1907         }
1908
1909         return del_on_close;
1910 }