LCOV - code coverage report
Current view: top level - source3/smbd - open.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 1289 2328 55.4 %
Date: 2024-06-13 04:01:37 Functions: 44 70 62.9 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    file opening and share modes
       4             :    Copyright (C) Andrew Tridgell 1992-1998
       5             :    Copyright (C) Jeremy Allison 2001-2004
       6             :    Copyright (C) Volker Lendecke 2005
       7             :    Copyright (C) Ralph Boehme 2017
       8             : 
       9             :    This program is free software; you can redistribute it and/or modify
      10             :    it under the terms of the GNU General Public License as published by
      11             :    the Free Software Foundation; either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    This program is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : #include "includes.h"
      24             : #include "system/filesys.h"
      25             : #include "lib/util/server_id.h"
      26             : #include "printing.h"
      27             : #include "locking/share_mode_lock.h"
      28             : #include "smbd/smbd.h"
      29             : #include "smbd/globals.h"
      30             : #include "fake_file.h"
      31             : #include "../libcli/security/security.h"
      32             : #include "../librpc/gen_ndr/ndr_security.h"
      33             : #include "../librpc/gen_ndr/ndr_open_files.h"
      34             : #include "../librpc/gen_ndr/idmap.h"
      35             : #include "../librpc/gen_ndr/ioctl.h"
      36             : #include "passdb/lookup_sid.h"
      37             : #include "auth.h"
      38             : #include "serverid.h"
      39             : #include "messages.h"
      40             : #include "source3/lib/dbwrap/dbwrap_watch.h"
      41             : #include "locking/leases_db.h"
      42             : #include "librpc/gen_ndr/ndr_leases_db.h"
      43             : #include "lib/util/time_basic.h"
      44             : 
      45             : extern const struct generic_mapping file_generic_mapping;
      46             : 
      47             : struct deferred_open_record {
      48             :         struct smbXsrv_connection *xconn;
      49             :         uint64_t mid;
      50             : 
      51             :         bool async_open;
      52             : 
      53             :         /*
      54             :          * Timer for async opens, needed because they don't use a watch on
      55             :          * a locking.tdb record. This is currently only used for real async
      56             :          * opens and just terminates smbd if the async open times out.
      57             :          */
      58             :         struct tevent_timer *te;
      59             : 
      60             :         /*
      61             :          * For the samba kernel oplock case we use both a timeout and
      62             :          * a watch on locking.tdb. This way in case it's smbd holding
      63             :          * the kernel oplock we get directly notified for the retry
      64             :          * once the kernel oplock is properly broken. Store the req
      65             :          * here so that it can be timely discarded once the timer
      66             :          * above fires.
      67             :          */
      68             :         struct tevent_req *watch_req;
      69             : };
      70             : 
      71             : /****************************************************************************
      72             :  If the requester wanted DELETE_ACCESS and was rejected because
      73             :  the file ACL didn't include DELETE_ACCESS, see if the parent ACL
      74             :  overrides this.
      75             : ****************************************************************************/
      76             : 
      77          22 : static bool parent_override_delete(connection_struct *conn,
      78             :                                         struct files_struct *dirfsp,
      79             :                                         const struct smb_filename *smb_fname,
      80             :                                         uint32_t access_mask,
      81             :                                         uint32_t rejected_mask)
      82             : {
      83          26 :         if ((access_mask & DELETE_ACCESS) &&
      84          16 :                     (rejected_mask & DELETE_ACCESS) &&
      85           8 :                     can_delete_file_in_directory(conn,
      86             :                                 dirfsp,
      87             :                                 smb_fname))
      88             :         {
      89           6 :                 return true;
      90             :         }
      91          16 :         return false;
      92             : }
      93             : 
      94             : /****************************************************************************
      95             :  Check if we have open rights.
      96             : ****************************************************************************/
      97             : 
      98       10766 : static NTSTATUS smbd_check_access_rights_fname(
      99             :                                 struct connection_struct *conn,
     100             :                                 const struct smb_filename *smb_fname,
     101             :                                 bool use_privs,
     102             :                                 uint32_t access_mask,
     103             :                                 uint32_t do_not_check_mask)
     104             : {
     105             :         uint32_t rejected_share_access;
     106             :         uint32_t effective_access;
     107             : 
     108       10766 :         rejected_share_access = access_mask & ~(conn->share_access);
     109             : 
     110       10766 :         if (rejected_share_access) {
     111           0 :                 DBG_DEBUG("rejected share access 0x%"PRIx32" on "
     112             :                           "%s (0x%"PRIx32")\n",
     113             :                           access_mask,
     114             :                           smb_fname_str_dbg(smb_fname),
     115             :                           rejected_share_access);
     116           0 :                 return NT_STATUS_ACCESS_DENIED;
     117             :         }
     118             : 
     119       10766 :         effective_access = access_mask & ~do_not_check_mask;
     120       10766 :         if (effective_access == 0) {
     121        6216 :                 DBG_DEBUG("do_not_check_mask override on %s. Granting 0x%x for free.\n",
     122             :                           smb_fname_str_dbg(smb_fname),
     123             :                           (unsigned int)access_mask);
     124        6216 :                 return NT_STATUS_OK;
     125             :         }
     126             : 
     127        4550 :         if (!use_privs && get_current_uid(conn) == (uid_t)0) {
     128             :                 /* I'm sorry sir, I didn't know you were root... */
     129        1755 :                 DBG_DEBUG("root override on %s. Granting 0x%x\n",
     130             :                           smb_fname_str_dbg(smb_fname),
     131             :                           (unsigned int)access_mask);
     132        1755 :                 return NT_STATUS_OK;
     133             :         }
     134             : 
     135        3295 :         if ((access_mask & DELETE_ACCESS) &&
     136         615 :             !lp_acl_check_permissions(SNUM(conn)))
     137             :         {
     138           0 :                 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on file %s. "
     139             :                           "Granting 0x%"PRIx32"\n",
     140             :                           smb_fname_str_dbg(smb_fname),
     141             :                           access_mask);
     142           0 :                 return NT_STATUS_OK;
     143             :         }
     144             : 
     145        3270 :         if (access_mask == DELETE_ACCESS &&
     146        1056 :             VALID_STAT(smb_fname->st) &&
     147         581 :             S_ISLNK(smb_fname->st.st_ex_mode))
     148             :         {
     149             :                 /* We can always delete a symlink. */
     150           0 :                 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on symlink %s.\n",
     151             :                           smb_fname_str_dbg(smb_fname));
     152           0 :                 return NT_STATUS_OK;
     153             :         }
     154             : 
     155        2795 :         return NT_STATUS_MORE_PROCESSING_REQUIRED;
     156             : }
     157             : 
     158        2795 : static NTSTATUS smbd_check_access_rights_sd(
     159             :                                 struct connection_struct *conn,
     160             :                                 struct files_struct *dirfsp,
     161             :                                 const struct smb_filename *smb_fname,
     162             :                                 struct security_descriptor *sd,
     163             :                                 bool use_privs,
     164             :                                 uint32_t access_mask,
     165             :                                 uint32_t do_not_check_mask)
     166             : {
     167        2795 :         uint32_t rejected_mask = access_mask;
     168             :         NTSTATUS status;
     169             : 
     170        2795 :         if (sd == NULL) {
     171           0 :                 goto access_denied;
     172             :         }
     173             : 
     174        2795 :         status = se_file_access_check(sd,
     175             :                                 get_current_nttok(conn),
     176             :                                 use_privs,
     177        2795 :                                 (access_mask & ~do_not_check_mask),
     178             :                                 &rejected_mask);
     179             : 
     180        2795 :         DBG_DEBUG("File [%s] requesting [0x%"PRIx32"] "
     181             :                   "returning [0x%"PRIx32"] (%s)\n",
     182             :                   smb_fname_str_dbg(smb_fname),
     183             :                   access_mask,
     184             :                   rejected_mask,
     185             :                   nt_errstr(status));
     186             : 
     187        2795 :         if (!NT_STATUS_IS_OK(status)) {
     188          22 :                 if (DEBUGLEVEL >= 10) {
     189           0 :                         DBG_DEBUG("acl for %s is:\n",
     190             :                                   smb_fname_str_dbg(smb_fname));
     191           0 :                         NDR_PRINT_DEBUG(security_descriptor, sd);
     192             :                 }
     193             :         }
     194             : 
     195        2795 :         TALLOC_FREE(sd);
     196             : 
     197        2808 :         if (NT_STATUS_IS_OK(status) ||
     198          22 :             !NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED))
     199             :         {
     200        2773 :                 return status;
     201             :         }
     202             : 
     203             :         /* Here we know status == NT_STATUS_ACCESS_DENIED. */
     204             : 
     205          22 : access_denied:
     206             : 
     207          23 :         if ((access_mask & FILE_WRITE_ATTRIBUTES) &&
     208           2 :             (rejected_mask & FILE_WRITE_ATTRIBUTES) &&
     209           1 :             !lp_store_dos_attributes(SNUM(conn)) &&
     210           0 :             (lp_map_readonly(SNUM(conn)) ||
     211           0 :              lp_map_archive(SNUM(conn)) ||
     212           0 :              lp_map_hidden(SNUM(conn)) ||
     213           0 :              lp_map_system(SNUM(conn))))
     214             :         {
     215           0 :                 rejected_mask &= ~FILE_WRITE_ATTRIBUTES;
     216             : 
     217           0 :                 DBG_DEBUG("overrode FILE_WRITE_ATTRIBUTES on file %s\n",
     218             :                           smb_fname_str_dbg(smb_fname));
     219             :         }
     220             : 
     221          22 :         if (parent_override_delete(conn,
     222             :                                    dirfsp,
     223             :                                    smb_fname,
     224             :                                    access_mask,
     225             :                                    rejected_mask))
     226             :         {
     227             :                 /*
     228             :                  * Were we trying to do an open for delete and didn't get DELETE
     229             :                  * access. Check if the directory allows DELETE_CHILD.
     230             :                  * See here:
     231             :                  * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
     232             :                  * for details.
     233             :                  */
     234             : 
     235           6 :                 rejected_mask &= ~DELETE_ACCESS;
     236             : 
     237           6 :                 DBG_DEBUG("Overrode DELETE_ACCESS on file %s\n",
     238             :                           smb_fname_str_dbg(smb_fname));
     239             :         }
     240             : 
     241          22 :         if (rejected_mask != 0) {
     242          16 :                 return NT_STATUS_ACCESS_DENIED;
     243             :         }
     244           6 :         return NT_STATUS_OK;
     245             : }
     246             : 
     247       10766 : NTSTATUS smbd_check_access_rights_fsp(struct files_struct *dirfsp,
     248             :                                       struct files_struct *fsp,
     249             :                                       bool use_privs,
     250             :                                       uint32_t access_mask)
     251             : {
     252       10766 :         struct security_descriptor *sd = NULL;
     253       10766 :         uint32_t do_not_check_mask = 0;
     254             :         NTSTATUS status;
     255             : 
     256             :         /* Cope with fake/printer fsp's. */
     257       10766 :         if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
     258           0 :                 if ((fsp->access_mask & access_mask) != access_mask) {
     259           0 :                         return NT_STATUS_ACCESS_DENIED;
     260             :                 }
     261           0 :                 return NT_STATUS_OK;
     262             :         }
     263             : 
     264       10766 :         if (fsp_get_pathref_fd(fsp) == -1) {
     265             :                 /*
     266             :                  * This is a POSIX open on a symlink. For the pathname
     267             :                  * version of this function we used to return the st_mode
     268             :                  * bits turned into an NT ACL. For a symlink the mode bits
     269             :                  * are always rwxrwxrwx which means the pathname version always
     270             :                  * returned NT_STATUS_OK for a symlink. For the handle reference
     271             :                  * to a symlink use the handle access bits.
     272             :                  */
     273           0 :                 if ((fsp->access_mask & access_mask) != access_mask) {
     274           0 :                         return NT_STATUS_ACCESS_DENIED;
     275             :                 }
     276           0 :                 return NT_STATUS_OK;
     277             :         }
     278             : 
     279             :         /*
     280             :          * If we can access the path to this file, by
     281             :          * default we have FILE_READ_ATTRIBUTES from the
     282             :          * containing directory. See the section:
     283             :          * "Algorithm to Check Access to an Existing File"
     284             :          * in MS-FSA.pdf.
     285             :          *
     286             :          * se_file_access_check() also takes care of
     287             :          * owner WRITE_DAC and READ_CONTROL.
     288             :          */
     289       10766 :         do_not_check_mask = FILE_READ_ATTRIBUTES;
     290             : 
     291             :         /*
     292             :          * Samba 3.6 and earlier granted execute access even
     293             :          * if the ACL did not contain execute rights.
     294             :          * Samba 4.0 is more correct and checks it.
     295             :          * The compatibilty mode allows one to skip this check
     296             :          * to smoothen upgrades.
     297             :          */
     298       10766 :         if (lp_acl_allow_execute_always(SNUM(fsp->conn))) {
     299           0 :                 do_not_check_mask |= FILE_EXECUTE;
     300             :         }
     301             : 
     302       20484 :         status = smbd_check_access_rights_fname(fsp->conn,
     303       10766 :                                                 fsp->fsp_name,
     304             :                                                 use_privs,
     305             :                                                 access_mask,
     306             :                                                 do_not_check_mask);
     307       10766 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     308        7971 :                 return status;
     309             :         }
     310             : 
     311        2795 :         status = SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp),
     312             :                                      (SECINFO_OWNER |
     313             :                                       SECINFO_GROUP |
     314             :                                       SECINFO_DACL),
     315             :                                      talloc_tos(),
     316             :                                      &sd);
     317        2795 :         if (!NT_STATUS_IS_OK(status)) {
     318           0 :                 DBG_DEBUG("Could not get acl on %s: %s\n",
     319             :                           fsp_str_dbg(fsp),
     320             :                           nt_errstr(status));
     321           0 :                 return status;
     322             :         }
     323             : 
     324        4922 :         return smbd_check_access_rights_sd(fsp->conn,
     325             :                                            dirfsp,
     326        2795 :                                            fsp->fsp_name,
     327             :                                            sd,
     328             :                                            use_privs,
     329             :                                            access_mask,
     330             :                                            do_not_check_mask);
     331             : }
     332             : 
     333             : /*
     334             :  * Given an fsp that represents a parent directory,
     335             :  * check if the requested access can be granted.
     336             :  */
     337        1358 : NTSTATUS check_parent_access_fsp(struct files_struct *fsp,
     338             :                                  uint32_t access_mask)
     339             : {
     340             :         NTSTATUS status;
     341        1358 :         struct security_descriptor *parent_sd = NULL;
     342        1358 :         uint32_t access_granted = 0;
     343        1358 :         struct share_mode_lock *lck = NULL;
     344             :         uint32_t name_hash;
     345             :         bool delete_on_close_set;
     346        1358 :         TALLOC_CTX *frame = talloc_stackframe();
     347             : 
     348        1358 :         if (get_current_uid(fsp->conn) == (uid_t)0) {
     349             :                 /* I'm sorry sir, I didn't know you were root... */
     350         677 :                 DBG_DEBUG("root override on %s. Granting 0x%x\n",
     351             :                         fsp_str_dbg(fsp),
     352             :                         (unsigned int)access_mask);
     353         677 :                 status = NT_STATUS_OK;
     354         677 :                 goto out;
     355             :         }
     356             : 
     357         681 :         status = SMB_VFS_FGET_NT_ACL(fsp,
     358             :                                 SECINFO_DACL,
     359             :                                 frame,
     360             :                                 &parent_sd);
     361             : 
     362         681 :         if (!NT_STATUS_IS_OK(status)) {
     363           0 :                 DBG_INFO("SMB_VFS_FGET_NT_ACL failed for "
     364             :                         "%s with error %s\n",
     365             :                         fsp_str_dbg(fsp),
     366             :                         nt_errstr(status));
     367           0 :                 goto out;
     368             :         }
     369             : 
     370             :         /*
     371             :          * If we can access the path to this file, by
     372             :          * default we have FILE_READ_ATTRIBUTES from the
     373             :          * containing directory. See the section:
     374             :          * "Algorithm to Check Access to an Existing File"
     375             :          * in MS-FSA.pdf.
     376             :          *
     377             :          * se_file_access_check() also takes care of
     378             :          * owner WRITE_DAC and READ_CONTROL.
     379             :          */
     380        1197 :         status = se_file_access_check(parent_sd,
     381         681 :                                 get_current_nttok(fsp->conn),
     382             :                                 false,
     383             :                                 (access_mask & ~FILE_READ_ATTRIBUTES),
     384             :                                 &access_granted);
     385         681 :         if(!NT_STATUS_IS_OK(status)) {
     386           0 :                 DBG_INFO("access check "
     387             :                         "on directory %s for mask 0x%x returned (0x%x) %s\n",
     388             :                         fsp_str_dbg(fsp),
     389             :                         access_mask,
     390             :                         access_granted,
     391             :                         nt_errstr(status));
     392           0 :                 goto out;
     393             :         }
     394             : 
     395         681 :         if (!(access_mask & (SEC_DIR_ADD_FILE | SEC_DIR_ADD_SUBDIR))) {
     396           0 :                 status = NT_STATUS_OK;
     397           0 :                 goto out;
     398             :         }
     399         681 :         if (!lp_check_parent_directory_delete_on_close(SNUM(fsp->conn))) {
     400         644 :                 status = NT_STATUS_OK;
     401         644 :                 goto out;
     402             :         }
     403             : 
     404             :         /* Check if the directory has delete-on-close set */
     405          37 :         status = file_name_hash(fsp->conn,
     406          37 :                                 fsp->fsp_name->base_name,
     407             :                                 &name_hash);
     408          37 :         if (!NT_STATUS_IS_OK(status)) {
     409           0 :                 goto out;
     410             :         }
     411             : 
     412             :         /*
     413             :          * Don't take a lock here. We just need a snapshot
     414             :          * of the current state of delete on close and this is
     415             :          * called in a codepath where we may already have a lock
     416             :          * (and we explicitly can't hold 2 locks at the same time
     417             :          * as that may deadlock).
     418             :          */
     419          37 :         lck = fetch_share_mode_unlocked(frame, fsp->file_id);
     420          37 :         if (lck == NULL) {
     421          21 :                 status = NT_STATUS_OK;
     422          21 :                 goto out;
     423             :         }
     424             : 
     425          16 :         delete_on_close_set = is_delete_on_close_set(lck, name_hash);
     426          16 :         if (delete_on_close_set) {
     427           0 :                 status = NT_STATUS_DELETE_PENDING;
     428           0 :                 goto out;
     429             :         }
     430             : 
     431          16 :         status = NT_STATUS_OK;
     432             : 
     433        1358 : out:
     434        1358 :         TALLOC_FREE(frame);
     435        1358 :         return status;
     436             : }
     437             : 
     438             : /****************************************************************************
     439             :  Ensure when opening a base file for a stream open that we have permissions
     440             :  to do so given the access mask on the base file.
     441             : ****************************************************************************/
     442             : 
     443          56 : static NTSTATUS check_base_file_access(struct files_struct *fsp,
     444             :                                 uint32_t access_mask)
     445             : {
     446             :         NTSTATUS status;
     447             : 
     448          56 :         status = smbd_calculate_access_mask_fsp(fsp->conn->cwd_fsp,
     449             :                                         fsp,
     450             :                                         false,
     451             :                                         access_mask,
     452             :                                         &access_mask);
     453          56 :         if (!NT_STATUS_IS_OK(status)) {
     454           0 :                 DEBUG(10, ("smbd_calculate_access_mask "
     455             :                         "on file %s returned %s\n",
     456             :                         fsp_str_dbg(fsp),
     457             :                         nt_errstr(status)));
     458           0 :                 return status;
     459             :         }
     460             : 
     461          56 :         if (access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) {
     462             :                 uint32_t dosattrs;
     463          16 :                 if (!CAN_WRITE(fsp->conn)) {
     464           0 :                         return NT_STATUS_ACCESS_DENIED;
     465             :                 }
     466          16 :                 dosattrs = fdos_mode(fsp);
     467          16 :                 if (IS_DOS_READONLY(dosattrs)) {
     468           0 :                         return NT_STATUS_ACCESS_DENIED;
     469             :                 }
     470             :         }
     471             : 
     472          56 :         return smbd_check_access_rights_fsp(fsp->conn->cwd_fsp,
     473             :                                         fsp,
     474             :                                         false,
     475             :                                         access_mask);
     476             : }
     477             : 
     478             : /****************************************************************************
     479             :  Handle differing symlink errno's
     480             : ****************************************************************************/
     481             : 
     482        2493 : static NTSTATUS link_errno_convert(int err)
     483             : {
     484             : #if defined(ENOTSUP) && defined(OSF1)
     485             :         /* handle special Tru64 errno */
     486             :         if (err == ENOTSUP) {
     487             :                 err = ELOOP;
     488             :         }
     489             : #endif /* ENOTSUP */
     490             : #ifdef EFTYPE
     491             :         /* fix broken NetBSD errno */
     492             :         if (err == EFTYPE) {
     493             :                 err = ELOOP;
     494             :         }
     495             : #endif /* EFTYPE */
     496             :         /* fix broken FreeBSD errno */
     497        2493 :         if (err == EMLINK) {
     498           0 :                 err = ELOOP;
     499             :         }
     500        2493 :         if (err == ELOOP) {
     501           0 :                 return NT_STATUS_STOPPED_ON_SYMLINK;
     502             :         }
     503        2493 :         return map_nt_error_from_unix(err);
     504             : }
     505             : 
     506             : static NTSTATUS non_widelink_open(const struct files_struct *dirfsp,
     507             :                         files_struct *fsp,
     508             :                         struct smb_filename *smb_fname,
     509             :                         const struct vfs_open_how *how,
     510             :                         unsigned int link_depth);
     511             : 
     512             : /****************************************************************************
     513             :  Follow a symlink in userspace.
     514             : ****************************************************************************/
     515             : 
     516        1880 : static NTSTATUS process_symlink_open(const struct files_struct *dirfsp,
     517             :                         files_struct *fsp,
     518             :                         struct smb_filename *smb_fname,
     519             :                         const struct vfs_open_how *how,
     520             :                         unsigned int link_depth)
     521             : {
     522        1880 :         struct connection_struct *conn = dirfsp->conn;
     523        1880 :         const char *conn_rootdir = NULL;
     524        1880 :         struct smb_filename conn_rootdir_fname = { 0 };
     525        1880 :         char *link_target = NULL;
     526        1880 :         int link_len = -1;
     527        1880 :         struct smb_filename *oldwd_fname = NULL;
     528        1880 :         size_t rootdir_len = 0;
     529        1880 :         struct smb_filename *resolved_fname = NULL;
     530        1880 :         char *resolved_name = NULL;
     531        1880 :         bool matched = false;
     532        1880 :         struct smb_filename *full_fname = NULL;
     533             :         NTSTATUS status;
     534             : 
     535        1880 :         conn_rootdir = SMB_VFS_CONNECTPATH(conn, smb_fname);
     536        1880 :         if (conn_rootdir == NULL) {
     537           0 :                 return NT_STATUS_NO_MEMORY;
     538             :         }
     539             :         /*
     540             :          * With shadow_copy2 conn_rootdir can be talloc_freed
     541             :          * whilst we use it in this function. We must take a copy.
     542             :          */
     543        1880 :         conn_rootdir_fname.base_name = talloc_strdup(talloc_tos(),
     544             :                                                      conn_rootdir);
     545        1880 :         if (conn_rootdir_fname.base_name == NULL) {
     546           0 :                 return NT_STATUS_NO_MEMORY;
     547             :         }
     548             : 
     549             :         /*
     550             :          * Ensure we don't get stuck in a symlink loop.
     551             :          */
     552        1880 :         link_depth++;
     553        1880 :         if (link_depth >= 20) {
     554           0 :                 status = NT_STATUS_STOPPED_ON_SYMLINK;
     555           0 :                 goto out;
     556             :         }
     557             : 
     558             :         /* Allocate space for the link target. */
     559        1880 :         link_target = talloc_array(talloc_tos(), char, PATH_MAX);
     560        1880 :         if (link_target == NULL) {
     561           0 :                 status = NT_STATUS_NO_MEMORY;
     562           0 :                 goto out;
     563             :         }
     564             : 
     565             :         /*
     566             :          * Read the link target. We do this just to verify that smb_fname indeed
     567             :          * points at a symbolic link and return NT_STATUS_NOT_A_DIRECTORY
     568             :          * and failure in case smb_fname is NOT a symlink.
     569             :          *
     570             :          * The caller needs this piece of information to distinguish two cases
     571             :          * where open() fails with errno=ENOTDIR, cf the comment in
     572             :          * non_widelink_open().
     573             :          *
     574             :          * We rely on SMB_VFS_REALPATH() to resolve the path including the
     575             :          * symlink. Once we have SMB_VFS_STATX() or something similar in our VFS
     576             :          * we may want to use that instead of SMB_VFS_READLINKAT().
     577             :          */
     578        1880 :         link_len = SMB_VFS_READLINKAT(conn,
     579             :                                 dirfsp,
     580             :                                 smb_fname,
     581             :                                 link_target,
     582             :                                 PATH_MAX - 1);
     583        1880 :         if (link_len == -1) {
     584           0 :                 status = NT_STATUS_INVALID_PARAMETER;
     585           0 :                 goto out;
     586             :         }
     587             : 
     588        1880 :         full_fname = full_path_from_dirfsp_atname(
     589             :                 talloc_tos(), dirfsp, smb_fname);
     590        1880 :         if (full_fname == NULL) {
     591           0 :                 status = NT_STATUS_NO_MEMORY;
     592           0 :                 goto out;
     593             :         }
     594             : 
     595             :         /* Convert to an absolute path. */
     596        1880 :         resolved_fname = SMB_VFS_REALPATH(conn, talloc_tos(), full_fname);
     597        1880 :         if (resolved_fname == NULL) {
     598         956 :                 status = map_nt_error_from_unix(errno);
     599         956 :                 goto out;
     600             :         }
     601         924 :         resolved_name = resolved_fname->base_name;
     602             : 
     603             :         /*
     604             :          * We know conn_rootdir starts with '/' and
     605             :          * does not end in '/'. FIXME ! Should we
     606             :          * smb_assert this ?
     607             :          */
     608         924 :         rootdir_len = strlen(conn_rootdir_fname.base_name);
     609             : 
     610         924 :         matched = (strncmp(conn_rootdir_fname.base_name,
     611             :                                 resolved_name,
     612             :                                 rootdir_len) == 0);
     613         924 :         if (!matched) {
     614           0 :                 status = NT_STATUS_STOPPED_ON_SYMLINK;
     615           0 :                 goto out;
     616             :         }
     617             : 
     618             :         /*
     619             :          * Turn into a path relative to the share root.
     620             :          */
     621         924 :         if (resolved_name[rootdir_len] == '\0') {
     622             :                 /* Link to the root of the share. */
     623          24 :                 TALLOC_FREE(smb_fname->base_name);
     624          24 :                 smb_fname->base_name = talloc_strdup(smb_fname, ".");
     625         900 :         } else if (resolved_name[rootdir_len] == '/') {
     626         888 :                 TALLOC_FREE(smb_fname->base_name);
     627         888 :                 smb_fname->base_name = talloc_strdup(smb_fname,
     628         888 :                                         &resolved_name[rootdir_len+1]);
     629             :         } else {
     630          12 :                 status = NT_STATUS_STOPPED_ON_SYMLINK;
     631          12 :                 goto out;
     632             :         }
     633             : 
     634         912 :         if (smb_fname->base_name == NULL) {
     635           0 :                 status = NT_STATUS_NO_MEMORY;
     636           0 :                 goto out;
     637             :         }
     638             : 
     639         912 :         oldwd_fname = vfs_GetWd(talloc_tos(), dirfsp->conn);
     640         912 :         if (oldwd_fname == NULL) {
     641           0 :                 status = map_nt_error_from_unix(errno);
     642           0 :                 goto out;
     643             :         }
     644             : 
     645             :         /* Ensure we operate from the root of the share. */
     646         912 :         if (vfs_ChDir(conn, &conn_rootdir_fname) == -1) {
     647           0 :                 status = map_nt_error_from_unix(errno);
     648           0 :                 goto out;
     649             :         }
     650             : 
     651             :         /*
     652             :          * And do it all again... As smb_fname is not relative to the passed in
     653             :          * dirfsp anymore, we pass conn->cwd_fsp as dirfsp to
     654             :          * non_widelink_open() to trigger the chdir(parentdir) logic.
     655             :          */
     656         912 :         status = non_widelink_open(conn->cwd_fsp,
     657             :                                 fsp,
     658             :                                 smb_fname,
     659             :                                 how,
     660             :                                 link_depth);
     661             : 
     662        1880 :   out:
     663             : 
     664        1880 :         TALLOC_FREE(resolved_fname);
     665        1880 :         TALLOC_FREE(link_target);
     666        1880 :         TALLOC_FREE(conn_rootdir_fname.base_name);
     667        1880 :         if (oldwd_fname != NULL) {
     668         912 :                 int ret = vfs_ChDir(conn, oldwd_fname);
     669         912 :                 if (ret == -1) {
     670           0 :                         smb_panic("unable to get back to old directory\n");
     671             :                 }
     672         912 :                 TALLOC_FREE(oldwd_fname);
     673             :         }
     674             : 
     675        1880 :         return status;
     676             : }
     677             : 
     678             : /****************************************************************************
     679             :  Non-widelink open.
     680             : ****************************************************************************/
     681             : 
     682      119562 : static NTSTATUS non_widelink_open(const struct files_struct *dirfsp,
     683             :                              files_struct *fsp,
     684             :                              struct smb_filename *smb_fname,
     685             :                              const struct vfs_open_how *_how,
     686             :                              unsigned int link_depth)
     687             : {
     688      119562 :         struct connection_struct *conn = fsp->conn;
     689             :         NTSTATUS saved_status;
     690      119562 :         NTSTATUS status = NT_STATUS_OK;
     691      119562 :         int fd = -1;
     692      119562 :         struct smb_filename *orig_fsp_name = fsp->fsp_name;
     693      119562 :         struct smb_filename *smb_fname_rel = NULL;
     694      119562 :         struct smb_filename *oldwd_fname = NULL;
     695      119562 :         struct smb_filename *parent_dir_fname = NULL;
     696      119562 :         bool have_opath = false;
     697      119562 :         bool is_share_root = false;
     698      119562 :         struct vfs_open_how how = *_how;
     699             :         int ret;
     700             : 
     701             : #ifdef O_PATH
     702      119562 :         have_opath = true;
     703             : #endif
     704             : 
     705      119562 :         SMB_ASSERT(!fsp_is_alternate_stream(fsp));
     706             : 
     707      119562 :         if (smb_fname->base_name[0] == '/') {
     708       35609 :                 const char *connpath = SMB_VFS_CONNECTPATH(conn, smb_fname);
     709       35609 :                 int cmp = strcmp(connpath, smb_fname->base_name);
     710             : 
     711       35609 :                 if (cmp == 0) {
     712       28882 :                         is_share_root = true;
     713             :                 }
     714             :         }
     715             : 
     716      159798 :         if (!is_share_root && (dirfsp == conn->cwd_fsp)) {
     717       60920 :                 struct smb_filename *smb_fname_dot = NULL;
     718             : 
     719       60920 :                 status = SMB_VFS_PARENT_PATHNAME(fsp->conn,
     720             :                                                  talloc_tos(),
     721             :                                                  smb_fname,
     722             :                                                  &parent_dir_fname,
     723             :                                                  &smb_fname_rel);
     724       60920 :                 if (!NT_STATUS_IS_OK(status)) {
     725           0 :                         goto out;
     726             :                 }
     727             : 
     728       60920 :                 if (!ISDOT(parent_dir_fname->base_name)) {
     729       13926 :                         oldwd_fname = vfs_GetWd(talloc_tos(), conn);
     730       13926 :                         if (oldwd_fname == NULL) {
     731           0 :                                 status = map_nt_error_from_unix(errno);
     732           0 :                                 goto out;
     733             :                         }
     734             : 
     735             :                         /* Pin parent directory in place. */
     736       13926 :                         if (vfs_ChDir(conn, parent_dir_fname) == -1) {
     737         819 :                                 status = map_nt_error_from_unix(errno);
     738         819 :                                 goto out;
     739             :                         }
     740             :                 }
     741             : 
     742       60101 :                 smb_fname_dot = synthetic_smb_fname(
     743             :                         parent_dir_fname,
     744             :                         ".",
     745             :                         NULL,
     746             :                         NULL,
     747             :                         0,
     748             :                         smb_fname->flags);
     749       60101 :                 if (smb_fname_dot == NULL) {
     750           0 :                         status = NT_STATUS_NO_MEMORY;
     751           0 :                         goto out;
     752             :                 }
     753             : 
     754             :                 /* Ensure the relative path is below the share. */
     755       60101 :                 status = check_reduced_name(conn, parent_dir_fname, smb_fname_dot);
     756       60101 :                 TALLOC_FREE(smb_fname_dot);
     757       60101 :                 if (!NT_STATUS_IS_OK(status)) {
     758        9033 :                         goto out;
     759             :                 }
     760             : 
     761             :                 /* Setup fsp->fsp_name to be relative to cwd */
     762       51068 :                 fsp->fsp_name = smb_fname_rel;
     763             :         } else {
     764             :                 /*
     765             :                  * fsp->fsp_name is unchanged as it is already correctly
     766             :                  * relative to conn->cwd.
     767             :                  */
     768       58642 :                 smb_fname_rel = smb_fname;
     769             :         }
     770             : 
     771      109710 :         if (!is_share_root) {
     772       80828 :                 char *slash = strchr_m(smb_fname_rel->base_name, '/');
     773       80828 :                 SMB_ASSERT(slash == NULL);
     774             :         }
     775             : 
     776      109710 :         how.flags |= O_NOFOLLOW;
     777             : 
     778      109710 :         fd = SMB_VFS_OPENAT(conn,
     779             :                             dirfsp,
     780             :                             smb_fname_rel,
     781             :                             fsp,
     782             :                             &how);
     783      109710 :         if (fd == -1) {
     784        2493 :                 status = link_errno_convert(errno);
     785             :         }
     786      109710 :         fsp_set_fd(fsp, fd);
     787             : 
     788      111686 :         if ((fd == -1) &&
     789        2493 :             NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK) &&
     790           0 :             fsp->fsp_flags.is_pathref &&
     791           0 :             !have_opath) {
     792           0 :                 ret = SMB_VFS_FSTATAT(
     793             :                         fsp->conn,
     794             :                         dirfsp,
     795             :                         smb_fname_rel,
     796             :                         &fsp->fsp_name->st,
     797             :                         AT_SYMLINK_NOFOLLOW);
     798           0 :                 if (ret == -1) {
     799           0 :                         status = map_nt_error_from_unix(errno);
     800           0 :                         DBG_DEBUG("fstatat(%s) failed: %s\n",
     801             :                                   smb_fname_str_dbg(smb_fname),
     802             :                                   strerror(errno));
     803           0 :                         goto out;
     804             :                 }
     805           0 :                 orig_fsp_name->st = fsp->fsp_name->st;
     806             :         }
     807             : 
     808      109710 :         if (fd != -1) {
     809      107217 :                 status = vfs_stat_fsp(fsp);
     810      107217 :                 if (!NT_STATUS_IS_OK(status)) {
     811           0 :                         goto out;
     812             :                 }
     813      107217 :                 orig_fsp_name->st = fsp->fsp_name->st;
     814             :         }
     815             : 
     816      109710 :         if (!is_ntfs_stream_smb_fname(fsp->fsp_name) &&
     817      104937 :             fsp->fsp_flags.is_pathref &&
     818             :             have_opath)
     819             :         {
     820             :                 /*
     821             :                  * Opening with O_PATH and O_NOFOLLOW opens a handle on the
     822             :                  * symlink. In follow symlink=yes mode we must avoid this and
     823             :                  * instead should open a handle on the symlink target.
     824             :                  *
     825             :                  * Check for this case by doing an fstat, forcing
     826             :                  * process_symlink_open() codepath down below by setting fd=-1
     827             :                  * and errno=ELOOP.
     828             :                  */
     829      104937 :                 if (S_ISLNK(fsp->fsp_name->st.st_ex_mode)) {
     830        1884 :                         status = fd_close(fsp);
     831        1884 :                         SMB_ASSERT(NT_STATUS_IS_OK(status));
     832        1884 :                         fd = -1;
     833        1884 :                         status = NT_STATUS_STOPPED_ON_SYMLINK;
     834             :                 }
     835             :         }
     836             : 
     837      112630 :         if ((fd == -1) &&
     838        6353 :             (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK) ||
     839        2493 :              NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)))
     840             :         {
     841             :                 /*
     842             :                  * Trying to open a symlink to a directory with O_NOFOLLOW and
     843             :                  * O_DIRECTORY can return either of ELOOP and ENOTDIR. So
     844             :                  * ENOTDIR really means: might be a symlink, but we're not sure.
     845             :                  * In this case, we just assume there's a symlink. If we were
     846             :                  * wrong, process_symlink_open() will return EINVAL. We check
     847             :                  * this below, and fall back to returning the initial
     848             :                  * saved_errno.
     849             :                  *
     850             :                  * BUG: https://bugzilla.samba.org/show_bug.cgi?id=12860
     851             :                  */
     852        1884 :                 saved_status = status;
     853             : 
     854        1884 :                 if (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH) {
     855             :                         /* Never follow symlinks on posix open. */
     856           2 :                         goto out;
     857             :                 }
     858        1884 :                 if (!lp_follow_symlinks(SNUM(conn))) {
     859             :                         /* Explicitly no symlinks. */
     860           4 :                         goto out;
     861             :                 }
     862             : 
     863        1880 :                 fsp->fsp_name = orig_fsp_name;
     864             : 
     865             :                 /*
     866             :                  * We may have a symlink. Follow in userspace
     867             :                  * to ensure it's under the share definition.
     868             :                  */
     869        1880 :                 status = process_symlink_open(dirfsp,
     870             :                                               fsp,
     871             :                                               smb_fname_rel,
     872             :                                               &how,
     873             :                                               link_depth);
     874        1880 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER) &&
     875           0 :                     NT_STATUS_EQUAL(saved_status, NT_STATUS_NOT_A_DIRECTORY))
     876             :                 {
     877           0 :                         status = saved_status;
     878             :                 }
     879             :         }
     880             : 
     881      204921 :   out:
     882      119562 :         fsp->fsp_name = orig_fsp_name;
     883             : 
     884      119562 :         TALLOC_FREE(parent_dir_fname);
     885             : 
     886      119562 :         if (oldwd_fname != NULL) {
     887       13926 :                 ret = vfs_ChDir(conn, oldwd_fname);
     888       13926 :                 if (ret == -1) {
     889           0 :                         smb_panic("unable to get back to old directory\n");
     890             :                 }
     891       13926 :                 TALLOC_FREE(oldwd_fname);
     892             :         }
     893      119562 :         return status;
     894             : }
     895             : 
     896             : /****************************************************************************
     897             :  fd support routines - attempt to do a dos_open.
     898             : ****************************************************************************/
     899             : 
     900      118740 : NTSTATUS fd_openat(const struct files_struct *dirfsp,
     901             :                    struct smb_filename *smb_fname,
     902             :                    files_struct *fsp,
     903             :                    const struct vfs_open_how *_how)
     904             : {
     905      118740 :         struct vfs_open_how how = *_how;
     906      118740 :         struct connection_struct *conn = fsp->conn;
     907      118740 :         NTSTATUS status = NT_STATUS_OK;
     908      118740 :         bool fsp_is_stream = fsp_is_alternate_stream(fsp);
     909      118740 :         bool smb_fname_is_stream = is_named_stream(smb_fname);
     910             : 
     911      118740 :         SMB_ASSERT(fsp_is_stream == smb_fname_is_stream);
     912             : 
     913             :         /*
     914             :          * Never follow symlinks on a POSIX client. The
     915             :          * client should be doing this.
     916             :          */
     917             : 
     918      118740 :         if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) || !lp_follow_symlinks(SNUM(conn))) {
     919        1080 :                 how.flags |= O_NOFOLLOW;
     920             :         }
     921             : 
     922      118740 :         if (fsp_is_stream) {
     923             :                 int fd;
     924             : 
     925          90 :                 fd = SMB_VFS_OPENAT(
     926             :                         conn,
     927             :                         NULL,   /* stream open is relative to fsp->base_fsp */
     928             :                         smb_fname,
     929             :                         fsp,
     930             :                         &how);
     931          90 :                 if (fd == -1) {
     932          10 :                         status = map_nt_error_from_unix(errno);
     933             :                 }
     934          90 :                 fsp_set_fd(fsp, fd);
     935             : 
     936          90 :                 if (fd != -1) {
     937          80 :                         status = vfs_stat_fsp(fsp);
     938          80 :                         if (!NT_STATUS_IS_OK(status)) {
     939           0 :                                 DBG_DEBUG("vfs_stat_fsp failed: %s\n",
     940             :                                           nt_errstr(status));
     941           0 :                                 fd_close(fsp);
     942             :                         }
     943             :                 }
     944             : 
     945          90 :                 return status;
     946             :         }
     947             : 
     948             :         /*
     949             :          * Only follow symlinks within a share
     950             :          * definition.
     951             :          */
     952      118650 :         status = non_widelink_open(dirfsp, fsp, smb_fname, &how, 0);
     953      118650 :         if (!NT_STATUS_IS_OK(status)) {
     954       13317 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_TOO_MANY_OPENED_FILES)) {
     955             :                         static time_t last_warned = 0L;
     956             : 
     957           0 :                         if (time((time_t *) NULL) > last_warned) {
     958           0 :                                 DEBUG(0,("Too many open files, unable "
     959             :                                         "to open more!  smbd's max "
     960             :                                         "open files = %d\n",
     961             :                                         lp_max_open_files()));
     962           0 :                                 last_warned = time((time_t *) NULL);
     963             :                         }
     964             :                 }
     965             : 
     966       13317 :                 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
     967             :                           smb_fname_str_dbg(smb_fname),
     968             :                           how.flags,
     969             :                           (int)how.mode,
     970             :                           fsp_get_pathref_fd(fsp),
     971             :                           nt_errstr(status));
     972       13317 :                 return status;
     973             :         }
     974             : 
     975      105333 :         DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d\n",
     976             :                   smb_fname_str_dbg(smb_fname),
     977             :                   how.flags,
     978             :                   (int)how.mode,
     979             :                   fsp_get_pathref_fd(fsp));
     980             : 
     981      105333 :         return status;
     982             : }
     983             : 
     984             : /****************************************************************************
     985             :  Close the file associated with a fsp.
     986             : ****************************************************************************/
     987             : 
     988      134388 : NTSTATUS fd_close(files_struct *fsp)
     989             : {
     990             :         NTSTATUS status;
     991             :         int ret;
     992             : 
     993      134388 :         if (fsp == fsp->conn->cwd_fsp) {
     994           0 :                 return NT_STATUS_OK;
     995             :         }
     996             : 
     997      134388 :         if (fsp->fsp_flags.fstat_before_close) {
     998           0 :                 status = vfs_stat_fsp(fsp);
     999           0 :                 if (!NT_STATUS_IS_OK(status)) {
    1000           0 :                         return status;
    1001             :                 }
    1002             :         }
    1003             : 
    1004      134388 :         if (fsp->dptr) {
    1005        2165 :                 dptr_CloseDir(fsp);
    1006             :         }
    1007      134388 :         if (fsp_get_pathref_fd(fsp) == -1) {
    1008             :                 /*
    1009             :                  * Either a directory where the dptr_CloseDir() already closed
    1010             :                  * the fd or a stat open.
    1011             :                  */
    1012       16718 :                 return NT_STATUS_OK;
    1013             :         }
    1014      117670 :         if (fh_get_refcount(fsp->fh) > 1) {
    1015           0 :                 return NT_STATUS_OK; /* Shared handle. Only close last reference. */
    1016             :         }
    1017             : 
    1018      117670 :         ret = SMB_VFS_CLOSE(fsp);
    1019      117670 :         fsp_set_fd(fsp, -1);
    1020      117670 :         if (ret == -1) {
    1021           0 :                 return map_nt_error_from_unix(errno);
    1022             :         }
    1023      117670 :         return NT_STATUS_OK;
    1024             : }
    1025             : 
    1026             : /****************************************************************************
    1027             :  Change the ownership of a file to that of the parent directory.
    1028             :  Do this by fd if possible.
    1029             : ****************************************************************************/
    1030             : 
    1031           0 : static void change_file_owner_to_parent_fsp(struct files_struct *parent_fsp,
    1032             :                                             struct files_struct *fsp)
    1033             : {
    1034             :         int ret;
    1035             : 
    1036           0 :         if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
    1037             :                 /* Already this uid - no need to change. */
    1038           0 :                 DBG_DEBUG("file %s is already owned by uid %u\n",
    1039             :                         fsp_str_dbg(fsp),
    1040             :                         (unsigned int)fsp->fsp_name->st.st_ex_uid);
    1041           0 :                 return;
    1042             :         }
    1043             : 
    1044           0 :         become_root();
    1045           0 :         ret = SMB_VFS_FCHOWN(fsp,
    1046             :                              parent_fsp->fsp_name->st.st_ex_uid,
    1047             :                              (gid_t)-1);
    1048           0 :         unbecome_root();
    1049           0 :         if (ret == -1) {
    1050           0 :                 DBG_ERR("failed to fchown "
    1051             :                         "file %s to parent directory uid %u. Error "
    1052             :                         "was %s\n",
    1053             :                         fsp_str_dbg(fsp),
    1054             :                         (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
    1055             :                         strerror(errno));
    1056             :         } else {
    1057           0 :                 DBG_DEBUG("changed new file %s to "
    1058             :                           "parent directory uid %u.\n",
    1059             :                           fsp_str_dbg(fsp),
    1060             :                           (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
    1061             :                 /* Ensure the uid entry is updated. */
    1062           0 :                 fsp->fsp_name->st.st_ex_uid =
    1063           0 :                         parent_fsp->fsp_name->st.st_ex_uid;
    1064             :         }
    1065             : }
    1066             : 
    1067           0 : static NTSTATUS change_dir_owner_to_parent_fsp(struct files_struct *parent_fsp,
    1068             :                                                struct files_struct *fsp)
    1069             : {
    1070             :         NTSTATUS status;
    1071             :         int ret;
    1072             : 
    1073           0 :         if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
    1074             :                 /* Already this uid - no need to change. */
    1075           0 :                 DBG_DEBUG("directory %s is already owned by uid %u\n",
    1076             :                         fsp_str_dbg(fsp),
    1077             :                         (unsigned int)fsp->fsp_name->st.st_ex_uid);
    1078           0 :                 return NT_STATUS_OK;
    1079             :         }
    1080             : 
    1081           0 :         become_root();
    1082           0 :         ret = SMB_VFS_FCHOWN(fsp,
    1083             :                              parent_fsp->fsp_name->st.st_ex_uid,
    1084             :                              (gid_t)-1);
    1085           0 :         unbecome_root();
    1086           0 :         if (ret == -1) {
    1087           0 :                 status = map_nt_error_from_unix(errno);
    1088           0 :                 DBG_ERR("failed to chown "
    1089             :                           "directory %s to parent directory uid %u. "
    1090             :                           "Error was %s\n",
    1091             :                           fsp_str_dbg(fsp),
    1092             :                           (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
    1093             :                           nt_errstr(status));
    1094           0 :                 return status;
    1095             :         }
    1096             : 
    1097           0 :         DBG_DEBUG("changed ownership of new "
    1098             :                   "directory %s to parent directory uid %u.\n",
    1099             :                   fsp_str_dbg(fsp),
    1100             :                   (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
    1101             : 
    1102             :         /* Ensure the uid entry is updated. */
    1103           0 :         fsp->fsp_name->st.st_ex_uid = parent_fsp->fsp_name->st.st_ex_uid;
    1104             : 
    1105           0 :         return NT_STATUS_OK;
    1106             : }
    1107             : 
    1108             : /****************************************************************************
    1109             :  Open a file - returning a guaranteed ATOMIC indication of if the
    1110             :  file was created or not.
    1111             : ****************************************************************************/
    1112             : 
    1113         607 : static NTSTATUS fd_open_atomic(struct files_struct *dirfsp,
    1114             :                                struct smb_filename *smb_fname,
    1115             :                                files_struct *fsp,
    1116             :                                int flags,
    1117             :                                mode_t mode,
    1118             :                                bool *file_created)
    1119             : {
    1120         607 :         struct vfs_open_how how = { .flags = flags, .mode = mode, };
    1121         607 :         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
    1122             :         NTSTATUS retry_status;
    1123         607 :         bool file_existed = VALID_STAT(smb_fname->st);
    1124             : 
    1125         607 :         if (!(how.flags & O_CREAT)) {
    1126             :                 /*
    1127             :                  * We're not creating the file, just pass through.
    1128             :                  */
    1129           1 :                 status = fd_openat(dirfsp, smb_fname, fsp, &how);
    1130           1 :                 *file_created = false;
    1131           1 :                 return status;
    1132             :         }
    1133             : 
    1134         606 :         if (how.flags & O_EXCL) {
    1135             :                 /*
    1136             :                  * Fail if already exists, just pass through.
    1137             :                  */
    1138          23 :                 status = fd_openat(dirfsp, smb_fname, fsp, &how);
    1139             : 
    1140             :                 /*
    1141             :                  * Here we've opened with O_CREAT|O_EXCL. If that went
    1142             :                  * NT_STATUS_OK, we *know* we created this file.
    1143             :                  */
    1144          23 :                 *file_created = NT_STATUS_IS_OK(status);
    1145             : 
    1146          23 :                 return status;
    1147             :         }
    1148             : 
    1149             :         /*
    1150             :          * Now it gets tricky. We have O_CREAT, but not O_EXCL.
    1151             :          * To know absolutely if we created the file or not,
    1152             :          * we can never call O_CREAT without O_EXCL. So if
    1153             :          * we think the file existed, try without O_CREAT|O_EXCL.
    1154             :          * If we think the file didn't exist, try with
    1155             :          * O_CREAT|O_EXCL.
    1156             :          *
    1157             :          * The big problem here is dangling symlinks. Opening
    1158             :          * without O_NOFOLLOW means both bad symlink
    1159             :          * and missing path return -1, ENOENT from open(). As POSIX
    1160             :          * is pathname based it's not possible to tell
    1161             :          * the difference between these two cases in a
    1162             :          * non-racy way, so change to try only two attempts before
    1163             :          * giving up.
    1164             :          *
    1165             :          * We don't have this problem for the O_NOFOLLOW
    1166             :          * case as it just returns NT_STATUS_OBJECT_PATH_NOT_FOUND
    1167             :          * mapped from the ELOOP POSIX error.
    1168             :          */
    1169             : 
    1170         583 :         if (file_existed) {
    1171           0 :                 how.flags = flags & ~(O_CREAT);
    1172           0 :                 retry_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
    1173             :         } else {
    1174         583 :                 how.flags = flags | O_EXCL;
    1175         583 :                 retry_status = NT_STATUS_OBJECT_NAME_COLLISION;
    1176             :         }
    1177             : 
    1178         583 :         status = fd_openat(dirfsp, smb_fname, fsp, &how);
    1179         583 :         if (NT_STATUS_IS_OK(status)) {
    1180         583 :                 *file_created = !file_existed;
    1181         583 :                 return NT_STATUS_OK;
    1182             :         }
    1183           0 :         if (NT_STATUS_EQUAL(status, retry_status)) {
    1184             : 
    1185           0 :                 file_existed = !file_existed;
    1186             : 
    1187           0 :                 DBG_DEBUG("File %s %s. Retry.\n",
    1188             :                           fsp_str_dbg(fsp),
    1189             :                           file_existed ? "existed" : "did not exist");
    1190             : 
    1191           0 :                 if (file_existed) {
    1192           0 :                         how.flags = flags & ~(O_CREAT);
    1193             :                 } else {
    1194           0 :                         how.flags = flags | O_EXCL;
    1195             :                 }
    1196             : 
    1197           0 :                 status = fd_openat(dirfsp, smb_fname, fsp, &how);
    1198             :         }
    1199             : 
    1200           0 :         *file_created = (NT_STATUS_IS_OK(status) && !file_existed);
    1201           0 :         return status;
    1202             : }
    1203             : 
    1204        3412 : static NTSTATUS reopen_from_procfd(struct files_struct *fsp,
    1205             :                                    int flags,
    1206             :                                    mode_t mode)
    1207             : {
    1208        3412 :         struct vfs_open_how how = { .flags = flags, .mode = mode };
    1209             :         struct smb_filename proc_fname;
    1210        3412 :         const char *p = NULL;
    1211             :         char buf[PATH_MAX];
    1212             :         int old_fd;
    1213             :         int new_fd;
    1214             :         NTSTATUS status;
    1215             : 
    1216        3412 :         if (!fsp->fsp_flags.have_proc_fds) {
    1217         607 :                 return NT_STATUS_MORE_PROCESSING_REQUIRED;
    1218             :         }
    1219             : 
    1220        2805 :         old_fd = fsp_get_pathref_fd(fsp);
    1221        2805 :         if (old_fd == -1) {
    1222           0 :                 return NT_STATUS_MORE_PROCESSING_REQUIRED;
    1223             :         }
    1224             : 
    1225        2805 :         if (!fsp->fsp_flags.is_pathref) {
    1226           0 :                 DBG_ERR("[%s] is not a pathref\n",
    1227             :                         fsp_str_dbg(fsp));
    1228             : #ifdef DEVELOPER
    1229           0 :                 smb_panic("Not a pathref");
    1230             : #endif
    1231             :                 return NT_STATUS_INVALID_HANDLE;
    1232             :         }
    1233             : 
    1234        2805 :         p = sys_proc_fd_path(old_fd, buf, sizeof(buf));
    1235        2805 :         if (p == NULL) {
    1236           0 :                 return NT_STATUS_NO_MEMORY;
    1237             :         }
    1238             : 
    1239        2805 :         proc_fname = (struct smb_filename) {
    1240             :                 .base_name = discard_const_p(char, p),
    1241             :         };
    1242             : 
    1243        2805 :         fsp->fsp_flags.is_pathref = false;
    1244             : 
    1245        2805 :         new_fd = SMB_VFS_OPENAT(fsp->conn,
    1246             :                                 fsp->conn->cwd_fsp,
    1247             :                                 &proc_fname,
    1248             :                                 fsp,
    1249             :                                 &how);
    1250        2805 :         if (new_fd == -1) {
    1251           4 :                 status = map_nt_error_from_unix(errno);
    1252           4 :                 fd_close(fsp);
    1253           4 :                 return status;
    1254             :         }
    1255             : 
    1256        2801 :         status = fd_close(fsp);
    1257        2801 :         if (!NT_STATUS_IS_OK(status)) {
    1258           0 :                 return status;
    1259             :         }
    1260             : 
    1261        2801 :         fsp_set_fd(fsp, new_fd);
    1262        2801 :         return NT_STATUS_OK;
    1263             : }
    1264             : 
    1265        3412 : static NTSTATUS reopen_from_fsp(struct files_struct *dirfsp,
    1266             :                                 struct smb_filename *smb_fname,
    1267             :                                 struct files_struct *fsp,
    1268             :                                 int flags,
    1269             :                                 mode_t mode,
    1270             :                                 bool *p_file_created)
    1271             : {
    1272        3412 :         bool __unused_file_created = false;
    1273             :         NTSTATUS status;
    1274             : 
    1275        3412 :         if (p_file_created == NULL) {
    1276        2244 :                 p_file_created = &__unused_file_created;
    1277             :         }
    1278             : 
    1279             :         /*
    1280             :          * TODO: should we move this to the VFS layer?
    1281             :          *       SMB_VFS_REOPEN_FSP()?
    1282             :          */
    1283             : 
    1284        3412 :         status = reopen_from_procfd(fsp,
    1285             :                                     flags,
    1286             :                                     mode);
    1287        3412 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    1288        2805 :                 return status;
    1289             :         }
    1290             : 
    1291             :         /*
    1292             :          * Close the existing pathref fd and set the fsp flag
    1293             :          * is_pathref to false so we get a "normal" fd this time.
    1294             :          */
    1295         607 :         status = fd_close(fsp);
    1296         607 :         if (!NT_STATUS_IS_OK(status)) {
    1297           0 :                 return status;
    1298             :         }
    1299             : 
    1300         607 :         fsp->fsp_flags.is_pathref = false;
    1301             : 
    1302         607 :         status = fd_open_atomic(
    1303             :                 dirfsp,
    1304             :                 smb_fname,
    1305             :                 fsp,
    1306             :                 flags,
    1307             :                 mode,
    1308             :                 p_file_created);
    1309         607 :         return status;
    1310             : }
    1311             : 
    1312             : /****************************************************************************
    1313             :  Open a file.
    1314             : ****************************************************************************/
    1315             : 
    1316        6324 : static NTSTATUS open_file(struct smb_request *req,
    1317             :                           struct files_struct *dirfsp,
    1318             :                           struct smb_filename *smb_fname_atname,
    1319             :                           files_struct *fsp,
    1320             :                           int flags,
    1321             :                           mode_t unx_mode,
    1322             :                           uint32_t access_mask, /* client requested access mask. */
    1323             :                           uint32_t open_access_mask, /* what we're actually using in the open. */
    1324             :                           uint32_t private_flags,
    1325             :                           bool *p_file_created)
    1326             : {
    1327        6324 :         connection_struct *conn = fsp->conn;
    1328        6324 :         struct smb_filename *smb_fname = fsp->fsp_name;
    1329        6324 :         NTSTATUS status = NT_STATUS_OK;
    1330        6324 :         int accmode = (flags & O_ACCMODE);
    1331        6324 :         int local_flags = flags;
    1332        6324 :         bool file_existed = VALID_STAT(fsp->fsp_name->st);
    1333        6324 :         uint32_t need_fd_mask =
    1334             :                 FILE_READ_DATA |
    1335             :                 FILE_WRITE_DATA |
    1336             :                 FILE_APPEND_DATA |
    1337             :                 FILE_EXECUTE |
    1338             :                 SEC_FLAG_SYSTEM_SECURITY;
    1339        6324 :         bool creating = !file_existed && (flags & O_CREAT);
    1340        6324 :         bool truncating = (flags & O_TRUNC);
    1341        6324 :         bool open_fd = false;
    1342        6324 :         bool posix_open = (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN);
    1343             : 
    1344             :         /*
    1345             :          * Catch early an attempt to open an existing
    1346             :          * directory as a file.
    1347             :          */
    1348        6324 :         if (file_existed && S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
    1349        4455 :                 return NT_STATUS_FILE_IS_A_DIRECTORY;
    1350             :         }
    1351             : 
    1352             :         /* Check permissions */
    1353             : 
    1354             :         /*
    1355             :          * This code was changed after seeing a client open request 
    1356             :          * containing the open mode of (DENY_WRITE/read-only) with
    1357             :          * the 'create if not exist' bit set. The previous code
    1358             :          * would fail to open the file read only on a read-only share
    1359             :          * as it was checking the flags parameter  directly against O_RDONLY,
    1360             :          * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
    1361             :          * JRA.
    1362             :          */
    1363             : 
    1364        1869 :         if (!CAN_WRITE(conn)) {
    1365             :                 /* It's a read-only share - fail if we wanted to write. */
    1366           0 :                 if(accmode != O_RDONLY || (flags & O_TRUNC) || (flags & O_APPEND)) {
    1367           0 :                         DEBUG(3,("Permission denied opening %s\n",
    1368             :                                  smb_fname_str_dbg(smb_fname)));
    1369           0 :                         return NT_STATUS_ACCESS_DENIED;
    1370             :                 }
    1371           0 :                 if (flags & O_CREAT) {
    1372             :                         /* We don't want to write - but we must make sure that
    1373             :                            O_CREAT doesn't create the file if we have write
    1374             :                            access into the directory.
    1375             :                         */
    1376           0 :                         flags &= ~(O_CREAT|O_EXCL);
    1377           0 :                         local_flags &= ~(O_CREAT|O_EXCL);
    1378             :                 }
    1379             :         }
    1380             : 
    1381             :         /*
    1382             :          * This little piece of insanity is inspired by the
    1383             :          * fact that an NT client can open a file for O_RDONLY,
    1384             :          * but set the create disposition to FILE_EXISTS_TRUNCATE.
    1385             :          * If the client *can* write to the file, then it expects to
    1386             :          * truncate the file, even though it is opening for readonly.
    1387             :          * Quicken uses this stupid trick in backup file creation...
    1388             :          * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
    1389             :          * for helping track this one down. It didn't bite us in 2.0.x
    1390             :          * as we always opened files read-write in that release. JRA.
    1391             :          */
    1392             : 
    1393        1869 :         if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
    1394           0 :                 DEBUG(10,("open_file: truncate requested on read-only open "
    1395             :                           "for file %s\n", smb_fname_str_dbg(smb_fname)));
    1396           0 :                 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
    1397             :         }
    1398             : 
    1399        1869 :         if ((open_access_mask & need_fd_mask) || creating || truncating) {
    1400        1172 :                 open_fd = true;
    1401             :         }
    1402             : 
    1403        1869 :         if (open_fd) {
    1404             :                 const char *wild;
    1405             :                 int ret;
    1406             : 
    1407             : #if defined(O_NONBLOCK) && defined(S_ISFIFO)
    1408             :                 /*
    1409             :                  * We would block on opening a FIFO with no one else on the
    1410             :                  * other end. Do what we used to do and add O_NONBLOCK to the
    1411             :                  * open flags. JRA.
    1412             :                  */
    1413             : 
    1414        1172 :                 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
    1415           0 :                         local_flags &= ~O_TRUNC; /* Can't truncate a FIFO. */
    1416           0 :                         local_flags |= O_NONBLOCK;
    1417           0 :                         truncating = false;
    1418             :                 }
    1419             : #endif
    1420             : 
    1421             :                 /* Don't create files with Microsoft wildcard characters. */
    1422        1172 :                 if (fsp_is_alternate_stream(fsp)) {
    1423             :                         /*
    1424             :                          * wildcard characters are allowed in stream names
    1425             :                          * only test the basefilename
    1426             :                          */
    1427          24 :                         wild = fsp->base_fsp->fsp_name->base_name;
    1428             :                 } else {
    1429        1148 :                         wild = smb_fname->base_name;
    1430             :                 }
    1431        1670 :                 if ((local_flags & O_CREAT) && !file_existed &&
    1432        1212 :                     !(fsp->posix_flags & FSP_POSIX_FLAGS_PATHNAMES) &&
    1433         606 :                     ms_has_wild(wild))  {
    1434           0 :                         return NT_STATUS_OBJECT_NAME_INVALID;
    1435             :                 }
    1436             : 
    1437             :                 /* Can we access this file ? */
    1438        1172 :                 if (!fsp_is_alternate_stream(fsp)) {
    1439             :                         /* Only do this check on non-stream open. */
    1440        1148 :                         if (file_existed) {
    1441         560 :                                 status = smbd_check_access_rights_fsp(
    1442             :                                                 dirfsp,
    1443             :                                                 fsp,
    1444             :                                                 false,
    1445             :                                                 open_access_mask);
    1446             : 
    1447         560 :                                 if (!NT_STATUS_IS_OK(status)) {
    1448           4 :                                         DBG_DEBUG("smbd_check_access_rights_fsp"
    1449             :                                                   " on file %s returned %s\n",
    1450             :                                                   fsp_str_dbg(fsp),
    1451             :                                                   nt_errstr(status));
    1452             :                                 }
    1453             : 
    1454         564 :                                 if (!NT_STATUS_IS_OK(status) &&
    1455           4 :                                     !NT_STATUS_EQUAL(status,
    1456             :                                         NT_STATUS_OBJECT_NAME_NOT_FOUND))
    1457             :                                 {
    1458           4 :                                         return status;
    1459             :                                 }
    1460             : 
    1461         556 :                                 if (NT_STATUS_EQUAL(status,
    1462             :                                         NT_STATUS_OBJECT_NAME_NOT_FOUND))
    1463             :                                 {
    1464           0 :                                         DEBUG(10, ("open_file: "
    1465             :                                                 "file %s vanished since we "
    1466             :                                                 "checked for existence.\n",
    1467             :                                                 smb_fname_str_dbg(smb_fname)));
    1468           0 :                                         file_existed = false;
    1469           0 :                                         SET_STAT_INVALID(fsp->fsp_name->st);
    1470             :                                 }
    1471             :                         }
    1472             : 
    1473        1144 :                         if (!file_existed) {
    1474         588 :                                 if (!(local_flags & O_CREAT)) {
    1475             :                                         /* File didn't exist and no O_CREAT. */
    1476           0 :                                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    1477             :                                 }
    1478             : 
    1479         588 :                                 status = check_parent_access_fsp(
    1480             :                                                         dirfsp,
    1481             :                                                         SEC_DIR_ADD_FILE);
    1482         588 :                                 if (!NT_STATUS_IS_OK(status)) {
    1483           0 :                                         DBG_DEBUG("check_parent_access_fsp on "
    1484             :                                                   "directory %s for file %s "
    1485             :                                                   "returned %s\n",
    1486             :                                                   smb_fname_str_dbg(
    1487             :                                                           dirfsp->fsp_name),
    1488             :                                                   smb_fname_str_dbg(smb_fname),
    1489             :                                                   nt_errstr(status));
    1490           0 :                                         return status;
    1491             :                                 }
    1492             :                         }
    1493             :                 }
    1494             : 
    1495             :                 /*
    1496             :                  * Actually do the open - if O_TRUNC is needed handle it
    1497             :                  * below under the share mode lock.
    1498             :                  */
    1499        1168 :                 status = reopen_from_fsp(dirfsp,
    1500             :                                          smb_fname_atname,
    1501             :                                          fsp,
    1502             :                                          local_flags & ~O_TRUNC,
    1503             :                                          unx_mode,
    1504             :                                          p_file_created);
    1505        1168 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
    1506             :                         /*
    1507             :                          * POSIX client that hit a symlink. We don't want to
    1508             :                          * return NT_STATUS_STOPPED_ON_SYMLINK to avoid handling
    1509             :                          * this special error code in all callers, so we map
    1510             :                          * this to NT_STATUS_OBJECT_NAME_NOT_FOUND to match
    1511             :                          * openat_pathref_fsp().
    1512             :                          */
    1513           0 :                         status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
    1514             :                 }
    1515        1168 :                 if (!NT_STATUS_IS_OK(status)) {
    1516           1 :                         DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
    1517             :                                  "(flags=%d)\n", smb_fname_str_dbg(smb_fname),
    1518             :                                  nt_errstr(status),local_flags,flags));
    1519           1 :                         return status;
    1520             :                 }
    1521             : 
    1522        1167 :                 if (local_flags & O_NONBLOCK) {
    1523             :                         /*
    1524             :                          * GPFS can return ETIMEDOUT for pread on
    1525             :                          * nonblocking file descriptors when files
    1526             :                          * migrated to tape need to be recalled. I
    1527             :                          * could imagine this happens elsewhere
    1528             :                          * too. With blocking file descriptors this
    1529             :                          * does not happen.
    1530             :                          */
    1531        1167 :                         ret = vfs_set_blocking(fsp, true);
    1532        1167 :                         if (ret == -1) {
    1533           0 :                                 status = map_nt_error_from_unix(errno);
    1534           0 :                                 DBG_WARNING("Could not set fd to blocking: "
    1535             :                                             "%s\n", strerror(errno));
    1536           0 :                                 fd_close(fsp);
    1537           0 :                                 return status;
    1538             :                         }
    1539             :                 }
    1540             : 
    1541        1167 :                 if (*p_file_created) {
    1542             :                         /* We created this file. */
    1543             : 
    1544         605 :                         bool need_re_stat = false;
    1545             :                         /* Do all inheritance work after we've
    1546             :                            done a successful fstat call and filled
    1547             :                            in the stat struct in fsp->fsp_name. */
    1548             : 
    1549             :                         /* Inherit the ACL if required */
    1550         605 :                         if (lp_inherit_permissions(SNUM(conn))) {
    1551           0 :                                 inherit_access_posix_acl(conn,
    1552             :                                                          dirfsp,
    1553             :                                                          smb_fname,
    1554             :                                                          unx_mode);
    1555           0 :                                 need_re_stat = true;
    1556             :                         }
    1557             : 
    1558             :                         /* Change the owner if required. */
    1559         605 :                         if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
    1560           0 :                                 change_file_owner_to_parent_fsp(dirfsp, fsp);
    1561           0 :                                 need_re_stat = true;
    1562             :                         }
    1563             : 
    1564         605 :                         if (need_re_stat) {
    1565           0 :                                 status = vfs_stat_fsp(fsp);
    1566             :                                 /*
    1567             :                                  * If we have an fd, this stat should succeed.
    1568             :                                  */
    1569           0 :                                 if (!NT_STATUS_IS_OK(status)) {
    1570           0 :                                         DBG_ERR("Error doing fstat on open "
    1571             :                                                 "file %s (%s)\n",
    1572             :                                                  smb_fname_str_dbg(smb_fname),
    1573             :                                                  nt_errstr(status));
    1574           0 :                                         fd_close(fsp);
    1575           0 :                                         return status;
    1576             :                                 }
    1577             :                         }
    1578             : 
    1579         605 :                         notify_fname(conn, NOTIFY_ACTION_ADDED,
    1580             :                                      FILE_NOTIFY_CHANGE_FILE_NAME,
    1581         605 :                                      smb_fname->base_name);
    1582             :                 }
    1583             :         } else {
    1584         697 :                 if (!file_existed) {
    1585             :                         /* File must exist for a stat open. */
    1586           0 :                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    1587             :                 }
    1588             : 
    1589         697 :                 if (S_ISLNK(smb_fname->st.st_ex_mode) &&
    1590           0 :                     !posix_open)
    1591             :                 {
    1592             :                         /*
    1593             :                          * Don't allow stat opens on symlinks directly unless
    1594             :                          * it's a POSIX open. Match the return code from
    1595             :                          * openat_pathref_fsp().
    1596             :                          */
    1597           0 :                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    1598             :                 }
    1599             : 
    1600         697 :                 if (!fsp->fsp_flags.is_pathref) {
    1601             :                         /*
    1602             :                          * There is only one legit case where end up here:
    1603             :                          * openat_pathref_fsp() failed to open a symlink, so the
    1604             :                          * fsp was created by fsp_new() which doesn't set
    1605             :                          * is_pathref. Other then that, we should always have a
    1606             :                          * pathref fsp at this point. The subsequent checks
    1607             :                          * assert this.
    1608             :                          */
    1609           0 :                         if (!(smb_fname->flags & SMB_FILENAME_POSIX_PATH)) {
    1610           0 :                                 DBG_ERR("[%s] is not a POSIX pathname\n",
    1611             :                                         smb_fname_str_dbg(smb_fname));
    1612           0 :                                 return NT_STATUS_INTERNAL_ERROR;
    1613             :                         }
    1614           0 :                         if (!S_ISLNK(smb_fname->st.st_ex_mode)) {
    1615           0 :                                 DBG_ERR("[%s] is not a symlink\n",
    1616             :                                         smb_fname_str_dbg(smb_fname));
    1617           0 :                                 return NT_STATUS_INTERNAL_ERROR;
    1618             :                         }
    1619           0 :                         if (fsp_get_pathref_fd(fsp) != -1) {
    1620           0 :                                 DBG_ERR("fd for [%s] is not -1: fd [%d]\n",
    1621             :                                         smb_fname_str_dbg(smb_fname),
    1622             :                                         fsp_get_pathref_fd(fsp));
    1623           0 :                                 return NT_STATUS_INTERNAL_ERROR;
    1624             :                         }
    1625             :                 }
    1626             : 
    1627             :                 /*
    1628             :                  * Access to streams is checked by checking the basefile and
    1629             :                  * that has alreay been checked by check_base_file_access()
    1630             :                  * in create_file_unixpath().
    1631             :                  */
    1632         697 :                 if (!fsp_is_alternate_stream(fsp)) {
    1633         657 :                         status = smbd_check_access_rights_fsp(dirfsp,
    1634             :                                                               fsp,
    1635             :                                                               false,
    1636             :                                                               open_access_mask);
    1637             : 
    1638         657 :                         if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
    1639           0 :                             posix_open &&
    1640           0 :                             S_ISLNK(smb_fname->st.st_ex_mode)) {
    1641             :                                 /* This is a POSIX stat open for delete
    1642             :                                  * or rename on a symlink that points
    1643             :                                  * nowhere. Allow. */
    1644           0 :                                 DEBUG(10,("open_file: allowing POSIX "
    1645             :                                           "open on bad symlink %s\n",
    1646             :                                           smb_fname_str_dbg(smb_fname)));
    1647           0 :                                 status = NT_STATUS_OK;
    1648             :                         }
    1649             : 
    1650         657 :                         if (!NT_STATUS_IS_OK(status)) {
    1651           2 :                                 DBG_DEBUG("smbd_check_access_rights_fsp on file "
    1652             :                                           "%s returned %s\n",
    1653             :                                           fsp_str_dbg(fsp),
    1654             :                                           nt_errstr(status));
    1655           2 :                                 return status;
    1656             :                         }
    1657             :                 }
    1658             :         }
    1659             : 
    1660        1862 :         fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
    1661        1862 :         fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
    1662        1862 :         fsp->file_pid = req ? req->smbpid : 0;
    1663        1862 :         fsp->fsp_flags.can_lock = true;
    1664        1862 :         fsp->fsp_flags.can_read = ((access_mask & FILE_READ_DATA) != 0);
    1665        1862 :         fsp->fsp_flags.can_write =
    1666        3724 :                 CAN_WRITE(conn) &&
    1667        1862 :                 ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0);
    1668        1862 :         fsp->print_file = NULL;
    1669        1862 :         fsp->fsp_flags.modified = false;
    1670        1862 :         fsp->sent_oplock_break = NO_BREAK_SENT;
    1671        1862 :         fsp->fsp_flags.is_directory = false;
    1672        1862 :         if (conn->aio_write_behind_list &&
    1673           0 :             is_in_path(smb_fname->base_name, conn->aio_write_behind_list,
    1674           0 :                        posix_open ? true: conn->case_sensitive)) {
    1675           0 :                 fsp->fsp_flags.aio_write_behind = true;
    1676             :         }
    1677             : 
    1678        1862 :         DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
    1679             :                  conn->session_info->unix_info->unix_name,
    1680             :                  smb_fname_str_dbg(smb_fname),
    1681             :                  BOOLSTR(fsp->fsp_flags.can_read),
    1682             :                  BOOLSTR(fsp->fsp_flags.can_write),
    1683             :                  conn->num_files_open));
    1684             : 
    1685        1862 :         return NT_STATUS_OK;
    1686             : }
    1687             : 
    1688          72 : static bool mask_conflict(
    1689             :         uint32_t new_access,
    1690             :         uint32_t existing_access,
    1691             :         uint32_t access_mask,
    1692             :         uint32_t new_sharemode,
    1693             :         uint32_t existing_sharemode,
    1694             :         uint32_t sharemode_mask)
    1695             : {
    1696          72 :         bool want_access = (new_access & access_mask);
    1697          72 :         bool allow_existing = (existing_sharemode & sharemode_mask);
    1698          72 :         bool have_access = (existing_access & access_mask);
    1699          72 :         bool allow_new = (new_sharemode & sharemode_mask);
    1700             : 
    1701          72 :         if (want_access && !allow_existing) {
    1702          36 :                 DBG_DEBUG("Access request 0x%"PRIx32"/0x%"PRIx32" conflicts "
    1703             :                           "with existing sharemode 0x%"PRIx32"/0x%"PRIx32"\n",
    1704             :                           new_access,
    1705             :                           access_mask,
    1706             :                           existing_sharemode,
    1707             :                           sharemode_mask);
    1708          36 :                 return true;
    1709             :         }
    1710          36 :         if (have_access && !allow_new) {
    1711           2 :                 DBG_DEBUG("Sharemode request 0x%"PRIx32"/0x%"PRIx32" conflicts "
    1712             :                           "with existing access 0x%"PRIx32"/0x%"PRIx32"\n",
    1713             :                           new_sharemode,
    1714             :                           sharemode_mask,
    1715             :                           existing_access,
    1716             :                           access_mask);
    1717           2 :                 return true;
    1718             :         }
    1719          34 :         return false;
    1720             : }
    1721             : 
    1722             : /****************************************************************************
    1723             :  Check if we can open a file with a share mode.
    1724             :  Returns True if conflict, False if not.
    1725             : ****************************************************************************/
    1726             : 
    1727             : static const uint32_t conflicting_access =
    1728             :         FILE_WRITE_DATA|
    1729             :         FILE_APPEND_DATA|
    1730             :         FILE_READ_DATA|
    1731             :         FILE_EXECUTE|
    1732             :         DELETE_ACCESS;
    1733             : 
    1734        5119 : static bool share_conflict(uint32_t e_access_mask,
    1735             :                            uint32_t e_share_access,
    1736             :                            uint32_t access_mask,
    1737             :                            uint32_t share_access)
    1738             : {
    1739             :         bool conflict;
    1740             : 
    1741        5119 :         DBG_DEBUG("existing access_mask = 0x%"PRIx32", "
    1742             :                   "existing share access = 0x%"PRIx32", "
    1743             :                   "access_mask = 0x%"PRIx32", "
    1744             :                   "share_access = 0x%"PRIx32"\n",
    1745             :                   e_access_mask,
    1746             :                   e_share_access,
    1747             :                   access_mask,
    1748             :                   share_access);
    1749             : 
    1750        5119 :         if ((e_access_mask & conflicting_access) == 0) {
    1751        5094 :                 DBG_DEBUG("No conflict due to "
    1752             :                           "existing access_mask = 0x%"PRIx32"\n",
    1753             :                           e_access_mask);
    1754        5094 :                 return false;
    1755             :         }
    1756          25 :         if ((access_mask & conflicting_access) == 0) {
    1757           1 :                 DBG_DEBUG("No conflict due to access_mask = 0x%"PRIx32"\n",
    1758             :                           access_mask);
    1759           1 :                 return false;
    1760             :         }
    1761             : 
    1762          24 :         conflict = mask_conflict(
    1763             :                 access_mask, e_access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
    1764             :                 share_access, e_share_access, FILE_SHARE_WRITE);
    1765          24 :         conflict |= mask_conflict(
    1766             :                 access_mask, e_access_mask, FILE_READ_DATA | FILE_EXECUTE,
    1767             :                 share_access, e_share_access, FILE_SHARE_READ);
    1768          24 :         conflict |= mask_conflict(
    1769             :                 access_mask, e_access_mask, DELETE_ACCESS,
    1770             :                 share_access, e_share_access, FILE_SHARE_DELETE);
    1771             : 
    1772          24 :         DBG_DEBUG("conflict=%s\n", conflict ? "true" : "false");
    1773          24 :         return conflict;
    1774             : }
    1775             : 
    1776             : #if defined(DEVELOPER)
    1777             : 
    1778             : struct validate_my_share_entries_state {
    1779             :         struct smbd_server_connection *sconn;
    1780             :         struct file_id fid;
    1781             :         struct server_id self;
    1782             : };
    1783             : 
    1784          28 : static bool validate_my_share_entries_fn(
    1785             :         struct share_mode_entry *e,
    1786             :         bool *modified,
    1787             :         void *private_data)
    1788             : {
    1789          28 :         struct validate_my_share_entries_state *state = private_data;
    1790             :         files_struct *fsp;
    1791             : 
    1792          28 :         if (!server_id_equal(&state->self, &e->pid)) {
    1793           8 :                 return false;
    1794             :         }
    1795             : 
    1796          20 :         if (e->op_mid == 0) {
    1797             :                 /* INTERNAL_OPEN_ONLY */
    1798           0 :                 return false;
    1799             :         }
    1800             : 
    1801          20 :         fsp = file_find_dif(state->sconn, state->fid, e->share_file_id);
    1802          20 :         if (!fsp) {
    1803           0 :                 DBG_ERR("PANIC : %s\n",
    1804             :                         share_mode_str(talloc_tos(), 0, &state->fid, e));
    1805           0 :                 smb_panic("validate_my_share_entries: Cannot match a "
    1806             :                           "share entry with an open file\n");
    1807             :         }
    1808             : 
    1809          20 :         if (((uint16_t)fsp->oplock_type) != e->op_type) {
    1810           0 :                 goto panic;
    1811             :         }
    1812             : 
    1813          20 :         return false;
    1814             : 
    1815           0 :  panic:
    1816             :         {
    1817             :                 char *str;
    1818           0 :                 DBG_ERR("validate_my_share_entries: PANIC : %s\n",
    1819             :                         share_mode_str(talloc_tos(), 0, &state->fid, e));
    1820           0 :                 str = talloc_asprintf(talloc_tos(),
    1821             :                         "validate_my_share_entries: "
    1822             :                         "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
    1823           0 :                          fsp->fsp_name->base_name,
    1824           0 :                          (unsigned int)fsp->oplock_type,
    1825           0 :                          (unsigned int)e->op_type);
    1826           0 :                 smb_panic(str);
    1827             :         }
    1828             : 
    1829             :         return false;
    1830             : }
    1831             : #endif
    1832             : 
    1833             : /**
    1834             :  * Allowed access mask for stat opens relevant to oplocks
    1835             :  **/
    1836       19648 : bool is_oplock_stat_open(uint32_t access_mask)
    1837             : {
    1838       19648 :         const uint32_t stat_open_bits =
    1839             :                 (SYNCHRONIZE_ACCESS|
    1840             :                  FILE_READ_ATTRIBUTES|
    1841             :                  FILE_WRITE_ATTRIBUTES);
    1842             : 
    1843       35076 :         return (((access_mask &  stat_open_bits) != 0) &&
    1844       15428 :                 ((access_mask & ~stat_open_bits) == 0));
    1845             : }
    1846             : 
    1847             : /**
    1848             :  * Allowed access mask for stat opens relevant to leases
    1849             :  **/
    1850           0 : bool is_lease_stat_open(uint32_t access_mask)
    1851             : {
    1852           0 :         const uint32_t stat_open_bits =
    1853             :                 (SYNCHRONIZE_ACCESS|
    1854             :                  FILE_READ_ATTRIBUTES|
    1855             :                  FILE_WRITE_ATTRIBUTES|
    1856             :                  READ_CONTROL_ACCESS);
    1857             : 
    1858           0 :         return (((access_mask &  stat_open_bits) != 0) &&
    1859           0 :                 ((access_mask & ~stat_open_bits) == 0));
    1860             : }
    1861             : 
    1862             : struct has_delete_on_close_state {
    1863             :         bool ret;
    1864             : };
    1865             : 
    1866           0 : static bool has_delete_on_close_fn(
    1867             :         struct share_mode_entry *e,
    1868             :         bool *modified,
    1869             :         void *private_data)
    1870             : {
    1871           0 :         struct has_delete_on_close_state *state = private_data;
    1872           0 :         state->ret = !share_entry_stale_pid(e);
    1873           0 :         return state->ret;
    1874             : }
    1875             : 
    1876       12080 : static bool has_delete_on_close(struct share_mode_lock *lck,
    1877             :                                 uint32_t name_hash)
    1878             : {
    1879       12080 :         struct has_delete_on_close_state state = { .ret = false };
    1880             :         bool ok;
    1881             : 
    1882       12080 :         if (!is_delete_on_close_set(lck, name_hash)) {
    1883       12080 :                 return false;
    1884             :         }
    1885             : 
    1886           0 :         ok= share_mode_forall_entries(lck, has_delete_on_close_fn, &state);
    1887           0 :         if (!ok) {
    1888           0 :                 DBG_DEBUG("share_mode_forall_entries failed\n");
    1889           0 :                 return false;
    1890             :         }
    1891           0 :         return state.ret;
    1892             : }
    1893             : 
    1894       12066 : static void share_mode_flags_restrict(
    1895             :         struct share_mode_lock *lck,
    1896             :         uint32_t access_mask,
    1897             :         uint32_t share_mode,
    1898             :         uint32_t lease_type)
    1899             : {
    1900             :         uint32_t existing_access_mask, existing_share_mode;
    1901             :         uint32_t existing_lease_type;
    1902             : 
    1903       12066 :         share_mode_flags_get(
    1904             :                 lck,
    1905             :                 &existing_access_mask,
    1906             :                 &existing_share_mode,
    1907             :                 &existing_lease_type);
    1908             : 
    1909       12066 :         existing_access_mask |= access_mask;
    1910       12066 :         if (access_mask & conflicting_access) {
    1911        4619 :                 existing_share_mode &= share_mode;
    1912             :         }
    1913       12066 :         existing_lease_type |= lease_type;
    1914             : 
    1915       12066 :         share_mode_flags_set(
    1916             :                 lck,
    1917             :                 existing_access_mask,
    1918             :                 existing_share_mode,
    1919             :                 existing_lease_type,
    1920             :                 NULL);
    1921       12066 : }
    1922             : 
    1923             : /****************************************************************************
    1924             :  Deal with share modes
    1925             :  Invariant: Share mode must be locked on entry and exit.
    1926             :  Returns -1 on error, or number of share modes on success (may be zero).
    1927             : ****************************************************************************/
    1928             : 
    1929             : struct open_mode_check_state {
    1930             :         struct file_id fid;
    1931             :         uint32_t access_mask;
    1932             :         uint32_t share_access;
    1933             :         uint32_t lease_type;
    1934             : };
    1935             : 
    1936          15 : static bool open_mode_check_fn(
    1937             :         struct share_mode_entry *e,
    1938             :         bool *modified,
    1939             :         void *private_data)
    1940             : {
    1941          15 :         struct open_mode_check_state *state = private_data;
    1942             :         bool disconnected, stale;
    1943             :         uint32_t access_mask, share_access, lease_type;
    1944             : 
    1945          15 :         disconnected = server_id_is_disconnected(&e->pid);
    1946          15 :         if (disconnected) {
    1947           0 :                 return false;
    1948             :         }
    1949             : 
    1950          15 :         access_mask = state->access_mask | e->access_mask;
    1951          15 :         share_access = state->share_access;
    1952          15 :         if (e->access_mask & conflicting_access) {
    1953          15 :                 share_access &= e->share_access;
    1954             :         }
    1955          15 :         lease_type = state->lease_type | get_lease_type(e, state->fid);
    1956             : 
    1957          16 :         if ((access_mask == state->access_mask) &&
    1958           2 :             (share_access == state->share_access) &&
    1959           1 :             (lease_type == state->lease_type)) {
    1960           1 :                 return false;
    1961             :         }
    1962             : 
    1963          14 :         stale = share_entry_stale_pid(e);
    1964          14 :         if (stale) {
    1965           0 :                 return false;
    1966             :         }
    1967             : 
    1968          14 :         state->access_mask = access_mask;
    1969          14 :         state->share_access = share_access;
    1970          14 :         state->lease_type = lease_type;
    1971             : 
    1972          14 :         return false;
    1973             : }
    1974             : 
    1975       12080 : static NTSTATUS open_mode_check(connection_struct *conn,
    1976             :                                 struct file_id fid,
    1977             :                                 struct share_mode_lock *lck,
    1978             :                                 uint32_t access_mask,
    1979             :                                 uint32_t share_access)
    1980             : {
    1981             :         struct open_mode_check_state state;
    1982             :         bool ok, conflict;
    1983       12080 :         bool modified = false;
    1984             : 
    1985       12080 :         if (is_oplock_stat_open(access_mask)) {
    1986             :                 /* Stat open that doesn't trigger oplock breaks or share mode
    1987             :                  * checks... ! JRA. */
    1988        6961 :                 return NT_STATUS_OK;
    1989             :         }
    1990             : 
    1991             :         /*
    1992             :          * Check if the share modes will give us access.
    1993             :          */
    1994             : 
    1995             : #if defined(DEVELOPER)
    1996             :         {
    1997        9483 :                 struct validate_my_share_entries_state validate_state = {
    1998        5119 :                         .sconn = conn->sconn,
    1999             :                         .fid = fid,
    2000        5119 :                         .self = messaging_server_id(conn->sconn->msg_ctx),
    2001             :                 };
    2002        5119 :                 ok = share_mode_forall_entries(
    2003             :                         lck, validate_my_share_entries_fn, &validate_state);
    2004        5119 :                 SMB_ASSERT(ok);
    2005             :         }
    2006             : #endif
    2007             : 
    2008        5119 :         share_mode_flags_get(
    2009             :                 lck, &state.access_mask, &state.share_access, NULL);
    2010             : 
    2011        5119 :         conflict = share_conflict(
    2012             :                 state.access_mask,
    2013             :                 state.share_access,
    2014             :                 access_mask,
    2015             :                 share_access);
    2016        5119 :         if (!conflict) {
    2017        5105 :                 DBG_DEBUG("No conflict due to share_mode_flags access\n");
    2018        5105 :                 return NT_STATUS_OK;
    2019             :         }
    2020             : 
    2021          14 :         state = (struct open_mode_check_state) {
    2022             :                 .fid = fid,
    2023             :                 .share_access = (FILE_SHARE_READ|
    2024             :                                  FILE_SHARE_WRITE|
    2025             :                                  FILE_SHARE_DELETE),
    2026             :         };
    2027             : 
    2028             :         /*
    2029             :          * Walk the share mode array to recalculate d->flags
    2030             :          */
    2031             : 
    2032          14 :         ok = share_mode_forall_entries(lck, open_mode_check_fn, &state);
    2033          14 :         if (!ok) {
    2034           0 :                 DBG_DEBUG("share_mode_forall_entries failed\n");
    2035           0 :                 return NT_STATUS_INTERNAL_ERROR;
    2036             :         }
    2037             : 
    2038          14 :         share_mode_flags_set(
    2039             :                 lck,
    2040             :                 state.access_mask,
    2041             :                 state.share_access,
    2042             :                 state.lease_type,
    2043             :                 &modified);
    2044          14 :         if (!modified) {
    2045             :                 /*
    2046             :                  * We only end up here if we had a sharing violation
    2047             :                  * from d->flags and have recalculated it.
    2048             :                  */
    2049          14 :                 return NT_STATUS_SHARING_VIOLATION;
    2050             :         }
    2051             : 
    2052           0 :         conflict = share_conflict(
    2053             :                 state.access_mask,
    2054             :                 state.share_access,
    2055             :                 access_mask,
    2056             :                 share_access);
    2057           0 :         if (!conflict) {
    2058           0 :                 DBG_DEBUG("No conflict due to share_mode_flags access\n");
    2059           0 :                 return NT_STATUS_OK;
    2060             :         }
    2061             : 
    2062           0 :         return NT_STATUS_SHARING_VIOLATION;
    2063             : }
    2064             : 
    2065             : /*
    2066             :  * Send a break message to the oplock holder and delay the open for
    2067             :  * our client.
    2068             :  */
    2069             : 
    2070           0 : NTSTATUS send_break_message(struct messaging_context *msg_ctx,
    2071             :                             const struct file_id *id,
    2072             :                             const struct share_mode_entry *exclusive,
    2073             :                             uint16_t break_to)
    2074             : {
    2075           0 :         struct oplock_break_message msg = {
    2076             :                 .id = *id,
    2077           0 :                 .share_file_id = exclusive->share_file_id,
    2078             :                 .break_to = break_to,
    2079             :         };
    2080             :         enum ndr_err_code ndr_err;
    2081             :         DATA_BLOB blob;
    2082             :         NTSTATUS status;
    2083             : 
    2084           0 :         if (DEBUGLVL(10)) {
    2085             :                 struct server_id_buf buf;
    2086           0 :                 DBG_DEBUG("Sending break message to %s\n",
    2087             :                           server_id_str_buf(exclusive->pid, &buf));
    2088           0 :                 NDR_PRINT_DEBUG(oplock_break_message, &msg);
    2089             :         }
    2090             : 
    2091           0 :         ndr_err = ndr_push_struct_blob(
    2092             :                 &blob,
    2093             :                 talloc_tos(),
    2094             :                 &msg,
    2095             :                 (ndr_push_flags_fn_t)ndr_push_oplock_break_message);
    2096           0 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    2097           0 :                 DBG_WARNING("ndr_push_oplock_break_message failed: %s\n",
    2098             :                             ndr_errstr(ndr_err));
    2099           0 :                 return ndr_map_error2ntstatus(ndr_err);
    2100             :         }
    2101             : 
    2102           0 :         status = messaging_send(
    2103             :                 msg_ctx, exclusive->pid, MSG_SMB_BREAK_REQUEST, &blob);
    2104           0 :         TALLOC_FREE(blob.data);
    2105           0 :         if (!NT_STATUS_IS_OK(status)) {
    2106           0 :                 DEBUG(3, ("Could not send oplock break message: %s\n",
    2107             :                           nt_errstr(status)));
    2108             :         }
    2109             : 
    2110           0 :         return status;
    2111             : }
    2112             : 
    2113             : struct validate_oplock_types_state {
    2114             :         bool valid;
    2115             :         bool batch;
    2116             :         bool ex_or_batch;
    2117             :         bool level2;
    2118             :         bool no_oplock;
    2119             :         uint32_t num_non_stat_opens;
    2120             : };
    2121             : 
    2122          20 : static bool validate_oplock_types_fn(
    2123             :         struct share_mode_entry *e,
    2124             :         bool *modified,
    2125             :         void *private_data)
    2126             : {
    2127          20 :         struct validate_oplock_types_state *state = private_data;
    2128             : 
    2129          20 :         if (e->op_mid == 0) {
    2130             :                 /* INTERNAL_OPEN_ONLY */
    2131           0 :                 return false;
    2132             :         }
    2133             : 
    2134          20 :         if (e->op_type == NO_OPLOCK && is_oplock_stat_open(e->access_mask)) {
    2135             :                 /*
    2136             :                  * We ignore stat opens in the table - they always
    2137             :                  * have NO_OPLOCK and never get or cause breaks. JRA.
    2138             :                  */
    2139           0 :                 return false;
    2140             :         }
    2141             : 
    2142          20 :         state->num_non_stat_opens += 1;
    2143             : 
    2144          20 :         if (BATCH_OPLOCK_TYPE(e->op_type)) {
    2145             :                 /* batch - can only be one. */
    2146           0 :                 if (share_entry_stale_pid(e)) {
    2147           0 :                         DBG_DEBUG("Found stale batch oplock\n");
    2148           0 :                         return false;
    2149             :                 }
    2150           0 :                 if (state->ex_or_batch ||
    2151           0 :                     state->batch ||
    2152           0 :                     state->level2 ||
    2153           0 :                     state->no_oplock) {
    2154           0 :                         DBG_ERR("Bad batch oplock entry\n");
    2155           0 :                         state->valid = false;
    2156           0 :                         return true;
    2157             :                 }
    2158           0 :                 state->batch = true;
    2159             :         }
    2160             : 
    2161          20 :         if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
    2162           0 :                 if (share_entry_stale_pid(e)) {
    2163           0 :                         DBG_DEBUG("Found stale duplicate oplock\n");
    2164           0 :                         return false;
    2165             :                 }
    2166             :                 /* Exclusive or batch - can only be one. */
    2167           0 :                 if (state->ex_or_batch ||
    2168           0 :                     state->level2 ||
    2169           0 :                     state->no_oplock) {
    2170           0 :                         DBG_ERR("Bad exclusive or batch oplock entry\n");
    2171           0 :                         state->valid = false;
    2172           0 :                         return true;
    2173             :                 }
    2174           0 :                 state->ex_or_batch = true;
    2175             :         }
    2176             : 
    2177          20 :         if (LEVEL_II_OPLOCK_TYPE(e->op_type)) {
    2178           0 :                 if (state->batch || state->ex_or_batch) {
    2179           0 :                         if (share_entry_stale_pid(e)) {
    2180           0 :                                 DBG_DEBUG("Found stale LevelII oplock\n");
    2181           0 :                                 return false;
    2182             :                         }
    2183           0 :                         DBG_DEBUG("Bad levelII oplock entry\n");
    2184           0 :                         state->valid = false;
    2185           0 :                         return true;
    2186             :                 }
    2187           0 :                 state->level2 = true;
    2188             :         }
    2189             : 
    2190          20 :         if (e->op_type == NO_OPLOCK) {
    2191          20 :                 if (state->batch || state->ex_or_batch) {
    2192           0 :                         if (share_entry_stale_pid(e)) {
    2193           0 :                                 DBG_DEBUG("Found stale NO_OPLOCK entry\n");
    2194           0 :                                 return false;
    2195             :                         }
    2196           0 :                         DBG_ERR("Bad no oplock entry\n");
    2197           0 :                         state->valid = false;
    2198           0 :                         return true;
    2199             :                 }
    2200          20 :                 state->no_oplock = true;
    2201             :         }
    2202             : 
    2203          20 :         return false;
    2204             : }
    2205             : 
    2206             : /*
    2207             :  * Do internal consistency checks on the share mode for a file.
    2208             :  */
    2209             : 
    2210        1862 : static bool validate_oplock_types(struct share_mode_lock *lck)
    2211             : {
    2212        1862 :         struct validate_oplock_types_state state = { .valid = true };
    2213             :         static bool skip_validation;
    2214             :         bool validate;
    2215             :         bool ok;
    2216             : 
    2217        1862 :         if (skip_validation) {
    2218           0 :                 return true;
    2219             :         }
    2220             : 
    2221        1862 :         validate = lp_parm_bool(-1, "smbd", "validate_oplock_types", false);
    2222        1862 :         if (!validate) {
    2223           0 :                 DBG_DEBUG("smbd:validate_oplock_types not set to yes\n");
    2224           0 :                 skip_validation = true;
    2225           0 :                 return true;
    2226             :         }
    2227             : 
    2228        1862 :         ok = share_mode_forall_entries(lck, validate_oplock_types_fn, &state);
    2229        1862 :         if (!ok) {
    2230           0 :                 DBG_DEBUG("share_mode_forall_entries failed\n");
    2231           0 :                 return false;
    2232             :         }
    2233        1862 :         if (!state.valid) {
    2234           0 :                 DBG_DEBUG("Got invalid oplock configuration\n");
    2235           0 :                 return false;
    2236             :         }
    2237             : 
    2238        1862 :         if ((state.batch || state.ex_or_batch) &&
    2239           0 :             (state.num_non_stat_opens != 1)) {
    2240           0 :                 DBG_WARNING("got batch (%d) or ex (%d) non-exclusively "
    2241             :                             "(%"PRIu32")\n",
    2242             :                             (int)state.batch,
    2243             :                             (int)state.ex_or_batch,
    2244             :                             state.num_non_stat_opens);
    2245           0 :                 return false;
    2246             :         }
    2247             : 
    2248        1862 :         return true;
    2249             : }
    2250             : 
    2251          20 : static bool is_same_lease(const files_struct *fsp,
    2252             :                           const struct share_mode_entry *e,
    2253             :                           const struct smb2_lease *lease)
    2254             : {
    2255          20 :         if (e->op_type != LEASE_OPLOCK) {
    2256          20 :                 return false;
    2257             :         }
    2258           0 :         if (lease == NULL) {
    2259           0 :                 return false;
    2260             :         }
    2261             : 
    2262           0 :         return smb2_lease_equal(fsp_client_guid(fsp),
    2263             :                                 &lease->lease_key,
    2264             :                                 &e->client_guid,
    2265             :                                 &e->lease_key);
    2266             : }
    2267             : 
    2268        1818 : static bool file_has_brlocks(files_struct *fsp)
    2269             : {
    2270             :         struct byte_range_lock *br_lck;
    2271             : 
    2272        1818 :         br_lck = brl_get_locks_readonly(fsp);
    2273        1818 :         if (!br_lck)
    2274           0 :                 return false;
    2275             : 
    2276        1818 :         return (brl_num_locks(br_lck) > 0);
    2277             : }
    2278             : 
    2279           0 : struct fsp_lease *find_fsp_lease(struct files_struct *new_fsp,
    2280             :                                  const struct smb2_lease_key *key,
    2281             :                                  uint32_t current_state,
    2282             :                                  uint16_t lease_version,
    2283             :                                  uint16_t lease_epoch)
    2284             : {
    2285             :         struct files_struct *fsp;
    2286             : 
    2287             :         /*
    2288             :          * TODO: Measure how expensive this loop is with thousands of open
    2289             :          * handles...
    2290             :          */
    2291             : 
    2292           0 :         for (fsp = file_find_di_first(new_fsp->conn->sconn, new_fsp->file_id, true);
    2293           0 :              fsp != NULL;
    2294           0 :              fsp = file_find_di_next(fsp, true)) {
    2295             : 
    2296           0 :                 if (fsp == new_fsp) {
    2297           0 :                         continue;
    2298             :                 }
    2299           0 :                 if (fsp->oplock_type != LEASE_OPLOCK) {
    2300           0 :                         continue;
    2301             :                 }
    2302           0 :                 if (smb2_lease_key_equal(&fsp->lease->lease.lease_key, key)) {
    2303           0 :                         fsp->lease->ref_count += 1;
    2304           0 :                         return fsp->lease;
    2305             :                 }
    2306             :         }
    2307             : 
    2308             :         /* Not found - must be leased in another smbd. */
    2309           0 :         new_fsp->lease = talloc_zero(new_fsp->conn->sconn, struct fsp_lease);
    2310           0 :         if (new_fsp->lease == NULL) {
    2311           0 :                 return NULL;
    2312             :         }
    2313           0 :         new_fsp->lease->ref_count = 1;
    2314           0 :         new_fsp->lease->sconn = new_fsp->conn->sconn;
    2315           0 :         new_fsp->lease->lease.lease_key = *key;
    2316           0 :         new_fsp->lease->lease.lease_state = current_state;
    2317             :         /*
    2318             :          * We internally treat all leases as V2 and update
    2319             :          * the epoch, but when sending breaks it matters if
    2320             :          * the requesting lease was v1 or v2.
    2321             :          */
    2322           0 :         new_fsp->lease->lease.lease_version = lease_version;
    2323           0 :         new_fsp->lease->lease.lease_epoch = lease_epoch;
    2324           0 :         return new_fsp->lease;
    2325             : }
    2326             : 
    2327           0 : static NTSTATUS try_lease_upgrade(struct files_struct *fsp,
    2328             :                                   struct share_mode_lock *lck,
    2329             :                                   const struct GUID *client_guid,
    2330             :                                   const struct smb2_lease *lease,
    2331             :                                   uint32_t granted)
    2332             : {
    2333             :         bool do_upgrade;
    2334             :         uint32_t current_state, breaking_to_requested, breaking_to_required;
    2335             :         bool breaking;
    2336             :         uint16_t lease_version, epoch;
    2337             :         uint32_t existing, requested;
    2338             :         NTSTATUS status;
    2339             : 
    2340           0 :         status = leases_db_get(
    2341             :                 client_guid,
    2342             :                 &lease->lease_key,
    2343           0 :                 &fsp->file_id,
    2344             :                 &current_state,
    2345             :                 &breaking,
    2346             :                 &breaking_to_requested,
    2347             :                 &breaking_to_required,
    2348             :                 &lease_version,
    2349             :                 &epoch);
    2350           0 :         if (!NT_STATUS_IS_OK(status)) {
    2351           0 :                 return status;
    2352             :         }
    2353             : 
    2354           0 :         fsp->lease = find_fsp_lease(
    2355             :                 fsp,
    2356             :                 &lease->lease_key,
    2357             :                 current_state,
    2358             :                 lease_version,
    2359             :                 epoch);
    2360           0 :         if (fsp->lease == NULL) {
    2361           0 :                 DEBUG(1, ("Did not find existing lease for file %s\n",
    2362             :                           fsp_str_dbg(fsp)));
    2363           0 :                 return NT_STATUS_NO_MEMORY;
    2364             :         }
    2365             : 
    2366             :         /*
    2367             :          * Upgrade only if the requested lease is a strict upgrade.
    2368             :          */
    2369           0 :         existing = current_state;
    2370           0 :         requested = lease->lease_state;
    2371             : 
    2372             :         /*
    2373             :          * Tricky: This test makes sure that "requested" is a
    2374             :          * strict bitwise superset of "existing".
    2375             :          */
    2376           0 :         do_upgrade = ((existing & requested) == existing);
    2377             : 
    2378             :         /*
    2379             :          * Upgrade only if there's a change.
    2380             :          */
    2381           0 :         do_upgrade &= (granted != existing);
    2382             : 
    2383             :         /*
    2384             :          * Upgrade only if other leases don't prevent what was asked
    2385             :          * for.
    2386             :          */
    2387           0 :         do_upgrade &= (granted == requested);
    2388             : 
    2389             :         /*
    2390             :          * only upgrade if we are not in breaking state
    2391             :          */
    2392           0 :         do_upgrade &= !breaking;
    2393             : 
    2394           0 :         DEBUG(10, ("existing=%"PRIu32", requested=%"PRIu32", "
    2395             :                    "granted=%"PRIu32", do_upgrade=%d\n",
    2396             :                    existing, requested, granted, (int)do_upgrade));
    2397             : 
    2398           0 :         if (do_upgrade) {
    2399             :                 NTSTATUS set_status;
    2400             : 
    2401           0 :                 current_state = granted;
    2402           0 :                 epoch += 1;
    2403             : 
    2404           0 :                 set_status = leases_db_set(
    2405             :                         client_guid,
    2406             :                         &lease->lease_key,
    2407             :                         current_state,
    2408             :                         breaking,
    2409             :                         breaking_to_requested,
    2410             :                         breaking_to_required,
    2411             :                         lease_version,
    2412             :                         epoch);
    2413             : 
    2414           0 :                 if (!NT_STATUS_IS_OK(set_status)) {
    2415           0 :                         DBG_DEBUG("leases_db_set failed: %s\n",
    2416             :                                   nt_errstr(set_status));
    2417           0 :                         return set_status;
    2418             :                 }
    2419             :         }
    2420             : 
    2421           0 :         fsp_lease_update(fsp);
    2422             : 
    2423           0 :         return NT_STATUS_OK;
    2424             : }
    2425             : 
    2426           0 : static NTSTATUS grant_new_fsp_lease(struct files_struct *fsp,
    2427             :                                     struct share_mode_lock *lck,
    2428             :                                     const struct GUID *client_guid,
    2429             :                                     const struct smb2_lease *lease,
    2430             :                                     uint32_t granted)
    2431             : {
    2432             :         NTSTATUS status;
    2433             : 
    2434           0 :         fsp->lease = talloc_zero(fsp->conn->sconn, struct fsp_lease);
    2435           0 :         if (fsp->lease == NULL) {
    2436           0 :                 return NT_STATUS_INSUFFICIENT_RESOURCES;
    2437             :         }
    2438           0 :         fsp->lease->ref_count = 1;
    2439           0 :         fsp->lease->sconn = fsp->conn->sconn;
    2440           0 :         fsp->lease->lease.lease_version = lease->lease_version;
    2441           0 :         fsp->lease->lease.lease_key = lease->lease_key;
    2442           0 :         fsp->lease->lease.lease_state = granted;
    2443           0 :         fsp->lease->lease.lease_epoch = lease->lease_epoch + 1;
    2444             : 
    2445           0 :         status = leases_db_add(client_guid,
    2446             :                                &lease->lease_key,
    2447           0 :                                &fsp->file_id,
    2448           0 :                                fsp->lease->lease.lease_state,
    2449           0 :                                fsp->lease->lease.lease_version,
    2450           0 :                                fsp->lease->lease.lease_epoch,
    2451           0 :                                fsp->conn->connectpath,
    2452           0 :                                fsp->fsp_name->base_name,
    2453           0 :                                fsp->fsp_name->stream_name);
    2454           0 :         if (!NT_STATUS_IS_OK(status)) {
    2455           0 :                 DEBUG(10, ("%s: leases_db_add failed: %s\n", __func__,
    2456             :                            nt_errstr(status)));
    2457           0 :                 TALLOC_FREE(fsp->lease);
    2458           0 :                 return NT_STATUS_INSUFFICIENT_RESOURCES;
    2459             :         }
    2460             : 
    2461             :         /*
    2462             :          * We used to set lck->data->modified=true here without
    2463             :          * actually modifying lck->data, triggering a needless
    2464             :          * writeback of lck->data.
    2465             :          *
    2466             :          * Apart from that writeback, setting modified=true has the
    2467             :          * effect of triggering all waiters for this file to
    2468             :          * retry. This only makes sense if any blocking condition
    2469             :          * (i.e. waiting for a lease to be downgraded or removed) is
    2470             :          * gone. This routine here only adds a lease, so it will never
    2471             :          * free up resources that blocked waiters can now claim. So
    2472             :          * that second effect also does not matter in this
    2473             :          * routine. Thus setting lck->data->modified=true does not
    2474             :          * need to be done here.
    2475             :          */
    2476             : 
    2477           0 :         return NT_STATUS_OK;
    2478             : }
    2479             : 
    2480           0 : static NTSTATUS grant_fsp_lease(struct files_struct *fsp,
    2481             :                                 struct share_mode_lock *lck,
    2482             :                                 const struct smb2_lease *lease,
    2483             :                                 uint32_t granted)
    2484             : {
    2485           0 :         const struct GUID *client_guid = fsp_client_guid(fsp);
    2486             :         NTSTATUS status;
    2487             : 
    2488           0 :         status = try_lease_upgrade(fsp, lck, client_guid, lease, granted);
    2489             : 
    2490           0 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
    2491           0 :                 status = grant_new_fsp_lease(
    2492             :                         fsp, lck, client_guid, lease, granted);
    2493             :         }
    2494             : 
    2495           0 :         return status;
    2496             : }
    2497             : 
    2498        1818 : static int map_lease_type_to_oplock(uint32_t lease_type)
    2499             : {
    2500        1818 :         int result = NO_OPLOCK;
    2501             : 
    2502        1818 :         switch (lease_type) {
    2503         124 :         case SMB2_LEASE_READ|SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE:
    2504         124 :                 result = BATCH_OPLOCK|EXCLUSIVE_OPLOCK;
    2505         124 :                 break;
    2506           0 :         case SMB2_LEASE_READ|SMB2_LEASE_WRITE:
    2507           0 :                 result = EXCLUSIVE_OPLOCK;
    2508           0 :                 break;
    2509           0 :         case SMB2_LEASE_READ|SMB2_LEASE_HANDLE:
    2510             :         case SMB2_LEASE_READ:
    2511           0 :                 result = LEVEL_II_OPLOCK;
    2512           0 :                 break;
    2513             :         }
    2514             : 
    2515        1818 :         return result;
    2516             : }
    2517             : 
    2518             : struct delay_for_oplock_state {
    2519             :         struct files_struct *fsp;
    2520             :         const struct smb2_lease *lease;
    2521             :         bool will_overwrite;
    2522             :         uint32_t delay_mask;
    2523             :         bool first_open_attempt;
    2524             :         bool got_handle_lease;
    2525             :         bool got_oplock;
    2526             :         bool have_other_lease;
    2527             :         bool delay;
    2528             : };
    2529             : 
    2530          20 : static bool delay_for_oplock_fn(
    2531             :         struct share_mode_entry *e,
    2532             :         bool *modified,
    2533             :         void *private_data)
    2534             : {
    2535          20 :         struct delay_for_oplock_state *state = private_data;
    2536          20 :         struct files_struct *fsp = state->fsp;
    2537          20 :         const struct smb2_lease *lease = state->lease;
    2538          20 :         bool e_is_lease = (e->op_type == LEASE_OPLOCK);
    2539          20 :         uint32_t e_lease_type = SMB2_LEASE_NONE;
    2540             :         uint32_t break_to;
    2541          20 :         bool lease_is_breaking = false;
    2542             : 
    2543          20 :         if (e_is_lease) {
    2544             :                 NTSTATUS status;
    2545             : 
    2546           0 :                 if (lease != NULL) {
    2547           0 :                         bool our_lease = is_same_lease(fsp, e, lease);
    2548           0 :                         if (our_lease) {
    2549           0 :                                 DBG_DEBUG("Ignoring our own lease\n");
    2550           0 :                                 return false;
    2551             :                         }
    2552             :                 }
    2553             : 
    2554           0 :                 status = leases_db_get(
    2555           0 :                         &e->client_guid,
    2556           0 :                         &e->lease_key,
    2557           0 :                         &fsp->file_id,
    2558             :                         &e_lease_type, /* current_state */
    2559             :                         &lease_is_breaking,
    2560             :                         NULL, /* breaking_to_requested */
    2561             :                         NULL, /* breaking_to_required */
    2562             :                         NULL, /* lease_version */
    2563             :                         NULL); /* epoch */
    2564             : 
    2565             :                 /*
    2566             :                  * leases_db_get() can return NT_STATUS_NOT_FOUND
    2567             :                  * if the share_mode_entry e is stale and the
    2568             :                  * lease record was already removed. In this case return
    2569             :                  * false so the traverse continues.
    2570             :                  */
    2571             : 
    2572           0 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) &&
    2573           0 :                     share_entry_stale_pid(e))
    2574             :                 {
    2575             :                         struct GUID_txt_buf guid_strbuf;
    2576             :                         struct file_id_buf file_id_strbuf;
    2577           0 :                         DBG_DEBUG("leases_db_get for client_guid [%s] "
    2578             :                                   "lease_key [%"PRIu64"/%"PRIu64"] "
    2579             :                                   "file_id [%s] failed for stale "
    2580             :                                   "share_mode_entry\n",
    2581             :                                   GUID_buf_string(&e->client_guid, &guid_strbuf),
    2582             :                                   e->lease_key.data[0],
    2583             :                                   e->lease_key.data[1],
    2584             :                                   file_id_str_buf(fsp->file_id, &file_id_strbuf));
    2585           0 :                         return false;
    2586             :                 }
    2587           0 :                 if (!NT_STATUS_IS_OK(status)) {
    2588             :                         struct GUID_txt_buf guid_strbuf;
    2589             :                         struct file_id_buf file_id_strbuf;
    2590           0 :                         DBG_ERR("leases_db_get for client_guid [%s] "
    2591             :                                 "lease_key [%"PRIu64"/%"PRIu64"] "
    2592             :                                 "file_id [%s] failed: %s\n",
    2593             :                                 GUID_buf_string(&e->client_guid, &guid_strbuf),
    2594             :                                 e->lease_key.data[0],
    2595             :                                 e->lease_key.data[1],
    2596             :                                 file_id_str_buf(fsp->file_id, &file_id_strbuf),
    2597             :                                 nt_errstr(status));
    2598           0 :                         smb_panic("leases_db_get() failed");
    2599             :                 }
    2600             :         } else {
    2601          20 :                 e_lease_type = get_lease_type(e, fsp->file_id);
    2602             :         }
    2603             : 
    2604          34 :         if (!state->got_handle_lease &&
    2605          20 :             ((e_lease_type & SMB2_LEASE_HANDLE) != 0) &&
    2606           0 :             !share_entry_stale_pid(e)) {
    2607           0 :                 state->got_handle_lease = true;
    2608             :         }
    2609             : 
    2610          34 :         if (!state->got_oplock &&
    2611          34 :             (e->op_type != LEASE_OPLOCK) &&
    2612          20 :             !share_entry_stale_pid(e)) {
    2613          20 :                 state->got_oplock = true;
    2614             :         }
    2615             : 
    2616          34 :         if (!state->have_other_lease &&
    2617          34 :             !is_same_lease(fsp, e, lease) &&
    2618          20 :             !share_entry_stale_pid(e)) {
    2619          20 :                 state->have_other_lease = true;
    2620             :         }
    2621             : 
    2622          20 :         if (e_is_lease && is_lease_stat_open(fsp->access_mask)) {
    2623           0 :                 return false;
    2624             :         }
    2625             : 
    2626          20 :         break_to = e_lease_type & ~state->delay_mask;
    2627             : 
    2628          20 :         if (state->will_overwrite) {
    2629           1 :                 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_READ);
    2630             :         }
    2631             : 
    2632          20 :         DBG_DEBUG("e_lease_type %u, will_overwrite: %u\n",
    2633             :                   (unsigned)e_lease_type,
    2634             :                   (unsigned)state->will_overwrite);
    2635             : 
    2636          20 :         if ((e_lease_type & ~break_to) == 0) {
    2637          20 :                 if (lease_is_breaking) {
    2638           0 :                         state->delay = true;
    2639             :                 }
    2640          20 :                 return false;
    2641             :         }
    2642             : 
    2643           0 :         if (share_entry_stale_pid(e)) {
    2644           0 :                 return false;
    2645             :         }
    2646             : 
    2647           0 :         if (state->will_overwrite) {
    2648             :                 /*
    2649             :                  * If we break anyway break to NONE directly.
    2650             :                  * Otherwise vfs_set_filelen() will trigger the
    2651             :                  * break.
    2652             :                  */
    2653           0 :                 break_to &= ~(SMB2_LEASE_READ|SMB2_LEASE_WRITE);
    2654             :         }
    2655             : 
    2656           0 :         if (!e_is_lease) {
    2657             :                 /*
    2658             :                  * Oplocks only support breaking to R or NONE.
    2659             :                  */
    2660           0 :                 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
    2661             :         }
    2662             : 
    2663           0 :         DBG_DEBUG("breaking from %d to %d\n",
    2664             :                   (int)e_lease_type,
    2665             :                   (int)break_to);
    2666           0 :         send_break_message(
    2667           0 :                 fsp->conn->sconn->msg_ctx, &fsp->file_id, e, break_to);
    2668           0 :         if (e_lease_type & state->delay_mask) {
    2669           0 :                 state->delay = true;
    2670             :         }
    2671           0 :         if (lease_is_breaking && !state->first_open_attempt) {
    2672           0 :                 state->delay = true;
    2673             :         }
    2674             : 
    2675           0 :         return false;
    2676             : };
    2677             : 
    2678        1830 : static NTSTATUS delay_for_oplock(files_struct *fsp,
    2679             :                                  int oplock_request,
    2680             :                                  const struct smb2_lease *lease,
    2681             :                                  struct share_mode_lock *lck,
    2682             :                                  bool have_sharing_violation,
    2683             :                                  uint32_t create_disposition,
    2684             :                                  bool first_open_attempt)
    2685             : {
    2686        1830 :         struct delay_for_oplock_state state = {
    2687             :                 .fsp = fsp,
    2688             :                 .lease = lease,
    2689             :                 .first_open_attempt = first_open_attempt,
    2690             :         };
    2691             :         uint32_t granted;
    2692             :         NTSTATUS status;
    2693             :         bool ok;
    2694             : 
    2695        1830 :         if (is_oplock_stat_open(fsp->access_mask)) {
    2696         201 :                 goto grant;
    2697             :         }
    2698             : 
    2699        1629 :         state.delay_mask = have_sharing_violation ?
    2700        1629 :                 SMB2_LEASE_HANDLE : SMB2_LEASE_WRITE;
    2701             : 
    2702        1629 :         switch (create_disposition) {
    2703         518 :         case FILE_SUPERSEDE:
    2704             :         case FILE_OVERWRITE:
    2705             :         case FILE_OVERWRITE_IF:
    2706         518 :                 state.will_overwrite = true;
    2707         518 :                 break;
    2708        1111 :         default:
    2709        1111 :                 state.will_overwrite = false;
    2710        1111 :                 break;
    2711             :         }
    2712             : 
    2713        1629 :         ok = share_mode_forall_entries(lck, delay_for_oplock_fn, &state);
    2714        1629 :         if (!ok) {
    2715           0 :                 return NT_STATUS_INTERNAL_ERROR;
    2716             :         }
    2717             : 
    2718        1629 :         if (state.delay) {
    2719           0 :                 return NT_STATUS_RETRY;
    2720             :         }
    2721             : 
    2722        1629 : grant:
    2723        1830 :         if (have_sharing_violation) {
    2724          12 :                 return NT_STATUS_SHARING_VIOLATION;
    2725             :         }
    2726             : 
    2727        1818 :         if (oplock_request == LEASE_OPLOCK) {
    2728           0 :                 if (lease == NULL) {
    2729             :                         /*
    2730             :                          * The SMB2 layer should have checked this
    2731             :                          */
    2732           0 :                         return NT_STATUS_INTERNAL_ERROR;
    2733             :                 }
    2734             : 
    2735           0 :                 granted = lease->lease_state;
    2736             : 
    2737           0 :                 if (lp_kernel_oplocks(SNUM(fsp->conn))) {
    2738           0 :                         DEBUG(10, ("No lease granted because kernel oplocks are enabled\n"));
    2739           0 :                         granted = SMB2_LEASE_NONE;
    2740             :                 }
    2741           0 :                 if ((granted & (SMB2_LEASE_READ|SMB2_LEASE_WRITE)) == 0) {
    2742           0 :                         DEBUG(10, ("No read or write lease requested\n"));
    2743           0 :                         granted = SMB2_LEASE_NONE;
    2744             :                 }
    2745           0 :                 if (granted == SMB2_LEASE_WRITE) {
    2746           0 :                         DEBUG(10, ("pure write lease requested\n"));
    2747           0 :                         granted = SMB2_LEASE_NONE;
    2748             :                 }
    2749           0 :                 if (granted == (SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE)) {
    2750           0 :                         DEBUG(10, ("write and handle lease requested\n"));
    2751           0 :                         granted = SMB2_LEASE_NONE;
    2752             :                 }
    2753             :         } else {
    2754        1818 :                 granted = map_oplock_to_lease_type(
    2755        1818 :                         oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
    2756             :         }
    2757             : 
    2758        1818 :         if (lp_locking(fsp->conn->params) && file_has_brlocks(fsp)) {
    2759           1 :                 DBG_DEBUG("file %s has byte range locks\n",
    2760             :                           fsp_str_dbg(fsp));
    2761           1 :                 granted &= ~SMB2_LEASE_READ;
    2762             :         }
    2763             : 
    2764        1818 :         if (state.have_other_lease) {
    2765             :                 /*
    2766             :                  * Can grant only one writer
    2767             :                  */
    2768           8 :                 granted &= ~SMB2_LEASE_WRITE;
    2769             :         }
    2770             : 
    2771        1818 :         if ((granted & SMB2_LEASE_READ) && !(granted & SMB2_LEASE_WRITE)) {
    2772           0 :                 bool allow_level2 =
    2773           0 :                         (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
    2774           0 :                         lp_level2_oplocks(SNUM(fsp->conn));
    2775             : 
    2776           0 :                 if (!allow_level2) {
    2777           0 :                         granted = SMB2_LEASE_NONE;
    2778             :                 }
    2779             :         }
    2780             : 
    2781        1818 :         if (oplock_request == LEASE_OPLOCK) {
    2782           0 :                 if (state.got_oplock) {
    2783           0 :                         granted &= ~SMB2_LEASE_HANDLE;
    2784             :                 }
    2785             : 
    2786           0 :                 fsp->oplock_type = LEASE_OPLOCK;
    2787             : 
    2788           0 :                 status = grant_fsp_lease(fsp, lck, lease, granted);
    2789           0 :                 if (!NT_STATUS_IS_OK(status)) {
    2790           0 :                         return status;
    2791             : 
    2792             :                 }
    2793             : 
    2794           0 :                 DBG_DEBUG("lease_state=%d\n", fsp->lease->lease.lease_state);
    2795             :         } else {
    2796        1818 :                 if (state.got_handle_lease) {
    2797           0 :                         granted = SMB2_LEASE_NONE;
    2798             :                 }
    2799             : 
    2800        1818 :                 fsp->oplock_type = map_lease_type_to_oplock(granted);
    2801             : 
    2802        1818 :                 status = set_file_oplock(fsp);
    2803        1818 :                 if (!NT_STATUS_IS_OK(status)) {
    2804             :                         /*
    2805             :                          * Could not get the kernel oplock
    2806             :                          */
    2807           0 :                         fsp->oplock_type = NO_OPLOCK;
    2808             :                 }
    2809             :         }
    2810             : 
    2811        1818 :         if (granted & SMB2_LEASE_READ) {
    2812             :                 uint32_t acc, sh, ls;
    2813         124 :                 share_mode_flags_get(lck, &acc, &sh, &ls);
    2814         124 :                 ls |= SMB2_LEASE_READ;
    2815         124 :                 share_mode_flags_set(lck, acc, sh, ls, NULL);
    2816             :         }
    2817             : 
    2818        1818 :         DBG_DEBUG("oplock type 0x%x on file %s\n",
    2819             :                   fsp->oplock_type, fsp_str_dbg(fsp));
    2820             : 
    2821        1818 :         return NT_STATUS_OK;
    2822             : }
    2823             : 
    2824        1862 : static NTSTATUS handle_share_mode_lease(
    2825             :         files_struct *fsp,
    2826             :         struct share_mode_lock *lck,
    2827             :         uint32_t create_disposition,
    2828             :         uint32_t access_mask,
    2829             :         uint32_t share_access,
    2830             :         int oplock_request,
    2831             :         const struct smb2_lease *lease,
    2832             :         bool first_open_attempt)
    2833             : {
    2834        1862 :         bool sharing_violation = false;
    2835             :         NTSTATUS status;
    2836             : 
    2837        1862 :         status = open_mode_check(
    2838        1862 :                 fsp->conn, fsp->file_id, lck, access_mask, share_access);
    2839        1862 :         if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
    2840          12 :                 sharing_violation = true;
    2841          12 :                 status = NT_STATUS_OK; /* handled later */
    2842             :         }
    2843             : 
    2844        1862 :         if (!NT_STATUS_IS_OK(status)) {
    2845           0 :                 return status;
    2846             :         }
    2847             : 
    2848        1862 :         if (oplock_request == INTERNAL_OPEN_ONLY) {
    2849          32 :                 if (sharing_violation) {
    2850           0 :                         DBG_DEBUG("Sharing violation for internal open\n");
    2851           0 :                         return NT_STATUS_SHARING_VIOLATION;
    2852             :                 }
    2853             : 
    2854             :                 /*
    2855             :                  * Internal opens never do oplocks or leases. We don't
    2856             :                  * need to go through delay_for_oplock().
    2857             :                  */
    2858          32 :                 fsp->oplock_type = NO_OPLOCK;
    2859             : 
    2860          32 :                 return NT_STATUS_OK;
    2861             :         }
    2862             : 
    2863        1830 :         status = delay_for_oplock(
    2864             :                 fsp,
    2865             :                 oplock_request,
    2866             :                 lease,
    2867             :                 lck,
    2868             :                 sharing_violation,
    2869             :                 create_disposition,
    2870             :                 first_open_attempt);
    2871        1830 :         if (!NT_STATUS_IS_OK(status)) {
    2872          12 :                 return status;
    2873             :         }
    2874             : 
    2875        1818 :         return NT_STATUS_OK;
    2876             : }
    2877             : 
    2878           0 : static bool request_timed_out(struct smb_request *req, struct timeval timeout)
    2879             : {
    2880             :         struct timeval now, end_time;
    2881           0 :         GetTimeOfDay(&now);
    2882           0 :         end_time = timeval_sum(&req->request_time, &timeout);
    2883           0 :         return (timeval_compare(&end_time, &now) < 0);
    2884             : }
    2885             : 
    2886             : struct defer_open_state {
    2887             :         struct smbXsrv_connection *xconn;
    2888             :         uint64_t mid;
    2889             : };
    2890             : 
    2891             : static void defer_open_done(struct tevent_req *req);
    2892             : 
    2893             : /**
    2894             :  * Defer an open and watch a locking.tdb record
    2895             :  *
    2896             :  * This defers an open that gets rescheduled once the locking.tdb record watch
    2897             :  * is triggered by a change to the record.
    2898             :  *
    2899             :  * It is used to defer opens that triggered an oplock break and for the SMB1
    2900             :  * sharing violation delay.
    2901             :  **/
    2902           0 : static void defer_open(struct share_mode_lock *lck,
    2903             :                        struct timeval timeout,
    2904             :                        struct smb_request *req,
    2905             :                        struct file_id id)
    2906             : {
    2907           0 :         struct deferred_open_record *open_rec = NULL;
    2908             :         struct timeval abs_timeout;
    2909             :         struct defer_open_state *watch_state;
    2910             :         struct tevent_req *watch_req;
    2911             :         struct timeval_buf tvbuf1, tvbuf2;
    2912             :         struct file_id_buf fbuf;
    2913             :         bool ok;
    2914             : 
    2915           0 :         abs_timeout = timeval_sum(&req->request_time, &timeout);
    2916             : 
    2917           0 :         DBG_DEBUG("request time [%s] timeout [%s] mid [%" PRIu64 "] "
    2918             :                   "file_id [%s]\n",
    2919             :                   timeval_str_buf(&req->request_time, false, true, &tvbuf1),
    2920             :                   timeval_str_buf(&abs_timeout, false, true, &tvbuf2),
    2921             :                   req->mid,
    2922             :                   file_id_str_buf(id, &fbuf));
    2923             : 
    2924           0 :         open_rec = talloc_zero(NULL, struct deferred_open_record);
    2925           0 :         if (open_rec == NULL) {
    2926           0 :                 TALLOC_FREE(lck);
    2927           0 :                 exit_server("talloc failed");
    2928             :         }
    2929             : 
    2930           0 :         watch_state = talloc(open_rec, struct defer_open_state);
    2931           0 :         if (watch_state == NULL) {
    2932           0 :                 exit_server("talloc failed");
    2933             :         }
    2934           0 :         watch_state->xconn = req->xconn;
    2935           0 :         watch_state->mid = req->mid;
    2936             : 
    2937           0 :         DBG_DEBUG("defering mid %" PRIu64 "\n", req->mid);
    2938             : 
    2939           0 :         watch_req = share_mode_watch_send(
    2940             :                 watch_state,
    2941           0 :                 req->sconn->ev_ctx,
    2942             :                 lck,
    2943           0 :                 (struct server_id){0});
    2944           0 :         if (watch_req == NULL) {
    2945           0 :                 exit_server("Could not watch share mode record");
    2946             :         }
    2947           0 :         tevent_req_set_callback(watch_req, defer_open_done, watch_state);
    2948             : 
    2949           0 :         ok = tevent_req_set_endtime(watch_req, req->sconn->ev_ctx, abs_timeout);
    2950           0 :         if (!ok) {
    2951           0 :                 exit_server("tevent_req_set_endtime failed");
    2952             :         }
    2953             : 
    2954           0 :         ok = push_deferred_open_message_smb(req, timeout, id, open_rec);
    2955           0 :         if (!ok) {
    2956           0 :                 TALLOC_FREE(lck);
    2957           0 :                 exit_server("push_deferred_open_message_smb failed");
    2958             :         }
    2959           0 : }
    2960             : 
    2961           0 : static void defer_open_done(struct tevent_req *req)
    2962             : {
    2963           0 :         struct defer_open_state *state = tevent_req_callback_data(
    2964             :                 req, struct defer_open_state);
    2965             :         NTSTATUS status;
    2966             :         bool ret;
    2967             : 
    2968           0 :         status = share_mode_watch_recv(req, NULL, NULL);
    2969           0 :         TALLOC_FREE(req);
    2970           0 :         if (!NT_STATUS_IS_OK(status)) {
    2971           0 :                 DEBUG(5, ("dbwrap_watched_watch_recv returned %s\n",
    2972             :                           nt_errstr(status)));
    2973             :                 /*
    2974             :                  * Even if it failed, retry anyway. TODO: We need a way to
    2975             :                  * tell a re-scheduled open about that error.
    2976             :                  */
    2977             :         }
    2978             : 
    2979           0 :         DEBUG(10, ("scheduling mid %llu\n", (unsigned long long)state->mid));
    2980             : 
    2981           0 :         ret = schedule_deferred_open_message_smb(state->xconn, state->mid);
    2982           0 :         SMB_ASSERT(ret);
    2983           0 :         TALLOC_FREE(state);
    2984           0 : }
    2985             : 
    2986             : /**
    2987             :  * Actually attempt the kernel oplock polling open.
    2988             :  */
    2989             : 
    2990           0 : static void poll_open_fn(struct tevent_context *ev,
    2991             :                          struct tevent_timer *te,
    2992             :                          struct timeval current_time,
    2993             :                          void *private_data)
    2994             : {
    2995           0 :         struct deferred_open_record *open_rec = talloc_get_type_abort(
    2996             :                 private_data, struct deferred_open_record);
    2997             :         bool ok;
    2998             : 
    2999           0 :         TALLOC_FREE(open_rec->watch_req);
    3000             : 
    3001           0 :         ok = schedule_deferred_open_message_smb(
    3002             :                 open_rec->xconn, open_rec->mid);
    3003           0 :         if (!ok) {
    3004           0 :                 exit_server("schedule_deferred_open_message_smb failed");
    3005             :         }
    3006           0 :         DBG_DEBUG("timer fired. Retrying open !\n");
    3007           0 : }
    3008             : 
    3009             : static void poll_open_done(struct tevent_req *subreq);
    3010             : 
    3011             : /**
    3012             :  * Reschedule an open for 1 second from now, if not timed out.
    3013             :  **/
    3014           0 : static bool setup_poll_open(
    3015             :         struct smb_request *req,
    3016             :         struct share_mode_lock *lck,
    3017             :         struct file_id id,
    3018             :         struct timeval max_timeout,
    3019             :         struct timeval interval)
    3020             : {
    3021             :         bool ok;
    3022           0 :         struct deferred_open_record *open_rec = NULL;
    3023             :         struct timeval endtime, next_interval;
    3024             :         struct file_id_buf ftmp;
    3025             : 
    3026           0 :         if (request_timed_out(req, max_timeout)) {
    3027           0 :                 return false;
    3028             :         }
    3029             : 
    3030           0 :         open_rec = talloc_zero(NULL, struct deferred_open_record);
    3031           0 :         if (open_rec == NULL) {
    3032           0 :                 DBG_WARNING("talloc failed\n");
    3033           0 :                 return false;
    3034             :         }
    3035           0 :         open_rec->xconn = req->xconn;
    3036           0 :         open_rec->mid = req->mid;
    3037             : 
    3038             :         /*
    3039             :          * Make sure open_rec->te does not come later than the
    3040             :          * request's maximum endtime.
    3041             :          */
    3042             : 
    3043           0 :         endtime = timeval_sum(&req->request_time, &max_timeout);
    3044           0 :         next_interval = timeval_current_ofs(interval.tv_sec, interval.tv_usec);
    3045           0 :         next_interval = timeval_min(&endtime, &next_interval);
    3046             : 
    3047           0 :         open_rec->te = tevent_add_timer(
    3048             :                 req->sconn->ev_ctx,
    3049             :                 open_rec,
    3050             :                 next_interval,
    3051             :                 poll_open_fn,
    3052             :                 open_rec);
    3053           0 :         if (open_rec->te == NULL) {
    3054           0 :                 DBG_WARNING("tevent_add_timer failed\n");
    3055           0 :                 TALLOC_FREE(open_rec);
    3056           0 :                 return false;
    3057             :         }
    3058             : 
    3059           0 :         if (lck != NULL) {
    3060           0 :                 open_rec->watch_req = share_mode_watch_send(
    3061             :                         open_rec,
    3062           0 :                         req->sconn->ev_ctx,
    3063             :                         lck,
    3064           0 :                         (struct server_id) {0});
    3065           0 :                 if (open_rec->watch_req == NULL) {
    3066           0 :                         DBG_WARNING("share_mode_watch_send failed\n");
    3067           0 :                         TALLOC_FREE(open_rec);
    3068           0 :                         return false;
    3069             :                 }
    3070           0 :                 tevent_req_set_callback(
    3071             :                         open_rec->watch_req, poll_open_done, open_rec);
    3072             :         }
    3073             : 
    3074           0 :         ok = push_deferred_open_message_smb(req, max_timeout, id, open_rec);
    3075           0 :         if (!ok) {
    3076           0 :                 DBG_WARNING("push_deferred_open_message_smb failed\n");
    3077           0 :                 TALLOC_FREE(open_rec);
    3078           0 :                 return false;
    3079             :         }
    3080             : 
    3081           0 :         DBG_DEBUG("poll request time [%s] mid [%" PRIu64 "] file_id [%s]\n",
    3082             :                   timeval_string(talloc_tos(), &req->request_time, false),
    3083             :                   req->mid,
    3084             :                   file_id_str_buf(id, &ftmp));
    3085             : 
    3086           0 :         return true;
    3087             : }
    3088             : 
    3089           0 : static void poll_open_done(struct tevent_req *subreq)
    3090             : {
    3091           0 :         struct deferred_open_record *open_rec = tevent_req_callback_data(
    3092             :                 subreq, struct deferred_open_record);
    3093             :         NTSTATUS status;
    3094             :         bool ok;
    3095             : 
    3096           0 :         status = share_mode_watch_recv(subreq, NULL, NULL);
    3097           0 :         TALLOC_FREE(subreq);
    3098           0 :         open_rec->watch_req = NULL;
    3099           0 :         TALLOC_FREE(open_rec->te);
    3100             : 
    3101           0 :         DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n",
    3102             :                   nt_errstr(status));
    3103             : 
    3104           0 :         ok = schedule_deferred_open_message_smb(
    3105             :                 open_rec->xconn, open_rec->mid);
    3106           0 :         if (!ok) {
    3107           0 :                 exit_server("schedule_deferred_open_message_smb failed");
    3108             :         }
    3109           0 : }
    3110             : 
    3111           0 : bool defer_smb1_sharing_violation(struct smb_request *req)
    3112             : {
    3113             :         bool ok;
    3114             :         int timeout_usecs;
    3115             : 
    3116           0 :         if (!lp_defer_sharing_violations()) {
    3117           0 :                 return false;
    3118             :         }
    3119             : 
    3120             :         /*
    3121             :          * Try every 200msec up to (by default) one second. To be
    3122             :          * precise, according to behaviour note <247> in [MS-CIFS],
    3123             :          * the server tries 5 times. But up to one second should be
    3124             :          * close enough.
    3125             :          */
    3126             : 
    3127           0 :         timeout_usecs = lp_parm_int(
    3128           0 :                 SNUM(req->conn),
    3129             :                 "smbd",
    3130             :                 "sharedelay",
    3131             :                 SHARING_VIOLATION_USEC_WAIT);
    3132             : 
    3133           0 :         ok = setup_poll_open(
    3134             :                 req,
    3135             :                 NULL,
    3136           0 :                 (struct file_id) {0},
    3137           0 :                 (struct timeval) { .tv_usec = timeout_usecs },
    3138           0 :                 (struct timeval) { .tv_usec = 200000 });
    3139           0 :         return ok;
    3140             : }
    3141             : 
    3142             : /****************************************************************************
    3143             :  On overwrite open ensure that the attributes match.
    3144             : ****************************************************************************/
    3145             : 
    3146          69 : static bool open_match_attributes(connection_struct *conn,
    3147             :                                   uint32_t old_dos_attr,
    3148             :                                   uint32_t new_dos_attr,
    3149             :                                   mode_t new_unx_mode,
    3150             :                                   mode_t *returned_unx_mode)
    3151             : {
    3152             :         uint32_t noarch_old_dos_attr, noarch_new_dos_attr;
    3153             : 
    3154          69 :         noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
    3155          69 :         noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
    3156             : 
    3157          69 :         if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) || 
    3158           6 :            (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
    3159           0 :                 *returned_unx_mode = new_unx_mode;
    3160             :         } else {
    3161          69 :                 *returned_unx_mode = (mode_t)0;
    3162             :         }
    3163             : 
    3164          69 :         DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
    3165             :                   "new_dos_attr = 0x%x "
    3166             :                   "returned_unx_mode = 0%o\n",
    3167             :                   (unsigned int)old_dos_attr,
    3168             :                   (unsigned int)new_dos_attr,
    3169             :                   (unsigned int)*returned_unx_mode ));
    3170             : 
    3171             :         /* If we're mapping SYSTEM and HIDDEN ensure they match. */
    3172          69 :         if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
    3173          69 :                 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
    3174           0 :                     !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
    3175           0 :                         return False;
    3176             :                 }
    3177             :         }
    3178          69 :         if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
    3179          69 :                 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
    3180           0 :                     !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
    3181           0 :                         return False;
    3182             :                 }
    3183             :         }
    3184          69 :         return True;
    3185             : }
    3186             : 
    3187           0 : static void schedule_defer_open(struct share_mode_lock *lck,
    3188             :                                 struct file_id id,
    3189             :                                 struct smb_request *req)
    3190             : {
    3191             :         /* This is a relative time, added to the absolute
    3192             :            request_time value to get the absolute timeout time.
    3193             :            Note that if this is the second or greater time we enter
    3194             :            this codepath for this particular request mid then
    3195             :            request_time is left as the absolute time of the *first*
    3196             :            time this request mid was processed. This is what allows
    3197             :            the request to eventually time out. */
    3198             : 
    3199             :         struct timeval timeout;
    3200             : 
    3201             :         /* Normally the smbd we asked should respond within
    3202             :          * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
    3203             :          * the client did, give twice the timeout as a safety
    3204             :          * measure here in case the other smbd is stuck
    3205             :          * somewhere else. */
    3206             : 
    3207           0 :         timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0);
    3208             : 
    3209           0 :         if (request_timed_out(req, timeout)) {
    3210           0 :                 return;
    3211             :         }
    3212             : 
    3213           0 :         defer_open(lck, timeout, req, id);
    3214             : }
    3215             : 
    3216             : /****************************************************************************
    3217             :  Reschedule an open call that went asynchronous.
    3218             : ****************************************************************************/
    3219             : 
    3220           0 : static void schedule_async_open_timer(struct tevent_context *ev,
    3221             :                                       struct tevent_timer *te,
    3222             :                                       struct timeval current_time,
    3223             :                                       void *private_data)
    3224             : {
    3225           0 :         exit_server("async open timeout");
    3226             : }
    3227             : 
    3228           0 : static void schedule_async_open(struct smb_request *req)
    3229             : {
    3230           0 :         struct deferred_open_record *open_rec = NULL;
    3231           0 :         struct timeval timeout = timeval_set(20, 0);
    3232             :         bool ok;
    3233             : 
    3234           0 :         if (request_timed_out(req, timeout)) {
    3235           0 :                 return;
    3236             :         }
    3237             : 
    3238           0 :         open_rec = talloc_zero(NULL, struct deferred_open_record);
    3239           0 :         if (open_rec == NULL) {
    3240           0 :                 exit_server("deferred_open_record_create failed");
    3241             :         }
    3242           0 :         open_rec->async_open = true;
    3243             : 
    3244           0 :         ok = push_deferred_open_message_smb(
    3245           0 :                 req, timeout, (struct file_id){0}, open_rec);
    3246           0 :         if (!ok) {
    3247           0 :                 exit_server("push_deferred_open_message_smb failed");
    3248             :         }
    3249             : 
    3250           0 :         open_rec->te = tevent_add_timer(req->sconn->ev_ctx,
    3251             :                                         req,
    3252             :                                         timeval_current_ofs(20, 0),
    3253             :                                         schedule_async_open_timer,
    3254             :                                         open_rec);
    3255           0 :         if (open_rec->te == NULL) {
    3256           0 :                 exit_server("tevent_add_timer failed");
    3257             :         }
    3258             : }
    3259             : 
    3260             : /****************************************************************************
    3261             :  Work out what access_mask to use from what the client sent us.
    3262             : ****************************************************************************/
    3263             : 
    3264          41 : static NTSTATUS smbd_calculate_maximum_allowed_access_fsp(
    3265             :                         struct files_struct *dirfsp,
    3266             :                         struct files_struct *fsp,
    3267             :                         bool use_privs,
    3268             :                         uint32_t *p_access_mask)
    3269             : {
    3270          41 :         struct security_descriptor *sd = NULL;
    3271          41 :         uint32_t access_granted = 0;
    3272             :         NTSTATUS status;
    3273             : 
    3274             :         /* Cope with symlinks */
    3275          41 :         if (fsp == NULL || fsp_get_pathref_fd(fsp) == -1) {
    3276          16 :                 *p_access_mask = FILE_GENERIC_ALL;
    3277          16 :                 return NT_STATUS_OK;
    3278             :         }
    3279             : 
    3280             :         /* Cope with fake/printer fsp's. */
    3281          25 :         if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
    3282           0 :                 *p_access_mask = FILE_GENERIC_ALL;
    3283           0 :                 return NT_STATUS_OK;
    3284             :         }
    3285             : 
    3286          25 :         if (!use_privs && (get_current_uid(fsp->conn) == (uid_t)0)) {
    3287          12 :                 *p_access_mask |= FILE_GENERIC_ALL;
    3288          12 :                 return NT_STATUS_OK;
    3289             :         }
    3290             : 
    3291          13 :         status = SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp),
    3292             :                                      (SECINFO_OWNER |
    3293             :                                         SECINFO_GROUP |
    3294             :                                         SECINFO_DACL),
    3295             :                                      talloc_tos(),
    3296             :                                      &sd);
    3297             : 
    3298          13 :         if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    3299             :                 /*
    3300             :                  * File did not exist
    3301             :                  */
    3302           0 :                 *p_access_mask = FILE_GENERIC_ALL;
    3303           0 :                 return NT_STATUS_OK;
    3304             :         }
    3305          13 :         if (!NT_STATUS_IS_OK(status)) {
    3306           0 :                 DBG_ERR("Could not get acl on file %s: %s\n",
    3307             :                         fsp_str_dbg(fsp),
    3308             :                         nt_errstr(status));
    3309           0 :                 return status;
    3310             :         }
    3311             : 
    3312             :         /*
    3313             :          * If we can access the path to this file, by
    3314             :          * default we have FILE_READ_ATTRIBUTES from the
    3315             :          * containing directory. See the section:
    3316             :          * "Algorithm to Check Access to an Existing File"
    3317             :          * in MS-FSA.pdf.
    3318             :          *
    3319             :          * se_file_access_check()
    3320             :          * also takes care of owner WRITE_DAC and READ_CONTROL.
    3321             :          */
    3322          26 :         status = se_file_access_check(sd,
    3323          13 :                                 get_current_nttok(fsp->conn),
    3324             :                                 use_privs,
    3325          13 :                                 (*p_access_mask & ~FILE_READ_ATTRIBUTES),
    3326             :                                 &access_granted);
    3327             : 
    3328          13 :         TALLOC_FREE(sd);
    3329             : 
    3330          13 :         if (!NT_STATUS_IS_OK(status)) {
    3331           0 :                 DBG_ERR("Status %s on file %s: "
    3332             :                         "when calculating maximum access\n",
    3333             :                         nt_errstr(status),
    3334             :                         fsp_str_dbg(fsp));
    3335           0 :                 return status;
    3336             :         }
    3337             : 
    3338          13 :         *p_access_mask = (access_granted | FILE_READ_ATTRIBUTES);
    3339             : 
    3340          13 :         if (!(access_granted & DELETE_ACCESS)) {
    3341           0 :                 if (can_delete_file_in_directory(fsp->conn,
    3342             :                                 dirfsp,
    3343           0 :                                 fsp->fsp_name)) {
    3344           0 :                         *p_access_mask |= DELETE_ACCESS;
    3345             :                 }
    3346             :         }
    3347             : 
    3348          13 :         return NT_STATUS_OK;
    3349             : }
    3350             : 
    3351       17291 : NTSTATUS smbd_calculate_access_mask_fsp(struct files_struct *dirfsp,
    3352             :                         struct files_struct *fsp,
    3353             :                         bool use_privs,
    3354             :                         uint32_t access_mask,
    3355             :                         uint32_t *access_mask_out)
    3356             : {
    3357             :         NTSTATUS status;
    3358       17291 :         uint32_t orig_access_mask = access_mask;
    3359             :         uint32_t rejected_share_access;
    3360             : 
    3361       17291 :         if (access_mask & SEC_MASK_INVALID) {
    3362           0 :                 DBG_DEBUG("access_mask [%8x] contains invalid bits\n",
    3363             :                           access_mask);
    3364           0 :                 return NT_STATUS_ACCESS_DENIED;
    3365             :         }
    3366             : 
    3367             :         /*
    3368             :          * Convert GENERIC bits to specific bits.
    3369             :          */
    3370             : 
    3371       17291 :         se_map_generic(&access_mask, &file_generic_mapping);
    3372             : 
    3373             :         /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
    3374       17291 :         if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
    3375             : 
    3376          41 :                 status = smbd_calculate_maximum_allowed_access_fsp(
    3377             :                                                    dirfsp,
    3378             :                                                    fsp,
    3379             :                                                    use_privs,
    3380             :                                                    &access_mask);
    3381             : 
    3382          41 :                 if (!NT_STATUS_IS_OK(status)) {
    3383           0 :                         return status;
    3384             :                 }
    3385             : 
    3386          41 :                 access_mask &= fsp->conn->share_access;
    3387             :         }
    3388             : 
    3389       17291 :         rejected_share_access = access_mask & ~(fsp->conn->share_access);
    3390             : 
    3391       17291 :         if (rejected_share_access) {
    3392           0 :                 DBG_INFO("Access denied on file %s: "
    3393             :                         "rejected by share access mask[0x%08X] "
    3394             :                         "orig[0x%08X] mapped[0x%08X] reject[0x%08X]\n",
    3395             :                         fsp_str_dbg(fsp),
    3396             :                         fsp->conn->share_access,
    3397             :                         orig_access_mask, access_mask,
    3398             :                         rejected_share_access);
    3399           0 :                 return NT_STATUS_ACCESS_DENIED;
    3400             :         }
    3401             : 
    3402       17291 :         *access_mask_out = access_mask;
    3403       17291 :         return NT_STATUS_OK;
    3404             : }
    3405             : 
    3406             : /****************************************************************************
    3407             :  Remove the deferred open entry under lock.
    3408             : ****************************************************************************/
    3409             : 
    3410             : /****************************************************************************
    3411             :  Return true if this is a state pointer to an asynchronous create.
    3412             : ****************************************************************************/
    3413             : 
    3414           0 : bool is_deferred_open_async(const struct deferred_open_record *rec)
    3415             : {
    3416           0 :         return rec->async_open;
    3417             : }
    3418             : 
    3419        1245 : static bool clear_ads(uint32_t create_disposition)
    3420             : {
    3421        1245 :         bool ret = false;
    3422             : 
    3423        1245 :         switch (create_disposition) {
    3424          70 :         case FILE_SUPERSEDE:
    3425             :         case FILE_OVERWRITE_IF:
    3426             :         case FILE_OVERWRITE:
    3427          70 :                 ret = true;
    3428          70 :                 break;
    3429        1175 :         default:
    3430        1175 :                 break;
    3431             :         }
    3432        1245 :         return ret;
    3433             : }
    3434             : 
    3435        6324 : static int disposition_to_open_flags(uint32_t create_disposition)
    3436             : {
    3437        6324 :         int ret = 0;
    3438             : 
    3439             :         /*
    3440             :          * Currently we're using FILE_SUPERSEDE as the same as
    3441             :          * FILE_OVERWRITE_IF but they really are
    3442             :          * different. FILE_SUPERSEDE deletes an existing file
    3443             :          * (requiring delete access) then recreates it.
    3444             :          */
    3445             : 
    3446        6324 :         switch (create_disposition) {
    3447         517 :         case FILE_SUPERSEDE:
    3448             :         case FILE_OVERWRITE_IF:
    3449             :                 /*
    3450             :                  * If file exists replace/overwrite. If file doesn't
    3451             :                  * exist create.
    3452             :                  */
    3453         517 :                 ret = O_CREAT|O_TRUNC;
    3454         517 :                 break;
    3455             : 
    3456        5615 :         case FILE_OPEN:
    3457             :                 /*
    3458             :                  * If file exists open. If file doesn't exist error.
    3459             :                  */
    3460        5615 :                 ret = 0;
    3461        5615 :                 break;
    3462             : 
    3463           1 :         case FILE_OVERWRITE:
    3464             :                 /*
    3465             :                  * If file exists overwrite. If file doesn't exist
    3466             :                  * error.
    3467             :                  */
    3468           1 :                 ret = O_TRUNC;
    3469           1 :                 break;
    3470             : 
    3471          23 :         case FILE_CREATE:
    3472             :                 /*
    3473             :                  * If file exists error. If file doesn't exist create.
    3474             :                  */
    3475          23 :                 ret = O_CREAT|O_EXCL;
    3476          23 :                 break;
    3477             : 
    3478         168 :         case FILE_OPEN_IF:
    3479             :                 /*
    3480             :                  * If file exists open. If file doesn't exist create.
    3481             :                  */
    3482         168 :                 ret = O_CREAT;
    3483         168 :                 break;
    3484             :         }
    3485        6324 :         return ret;
    3486             : }
    3487             : 
    3488        6324 : static int calculate_open_access_flags(uint32_t access_mask,
    3489             :                                        uint32_t private_flags)
    3490             : {
    3491             :         bool need_write, need_read;
    3492             : 
    3493             :         /*
    3494             :          * Note that we ignore the append flag as append does not
    3495             :          * mean the same thing under DOS and Unix.
    3496             :          */
    3497             : 
    3498        6324 :         need_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA));
    3499        6324 :         if (!need_write) {
    3500        5630 :                 return O_RDONLY;
    3501             :         }
    3502             : 
    3503             :         /* DENY_DOS opens are always underlying read-write on the
    3504             :            file handle, no matter what the requested access mask
    3505             :            says. */
    3506             : 
    3507         694 :         need_read =
    3508        1388 :                 ((private_flags & NTCREATEX_FLAG_DENY_DOS) ||
    3509         694 :                  access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|
    3510             :                                 FILE_READ_EA|FILE_EXECUTE));
    3511             : 
    3512         694 :         if (!need_read) {
    3513         423 :                 return O_WRONLY;
    3514             :         }
    3515         271 :         return O_RDWR;
    3516             : }
    3517             : 
    3518             : /****************************************************************************
    3519             :  Open a file with a share mode. Passed in an already created files_struct *.
    3520             : ****************************************************************************/
    3521             : 
    3522        6512 : static NTSTATUS open_file_ntcreate(connection_struct *conn,
    3523             :                             struct smb_request *req,
    3524             :                             uint32_t access_mask,               /* access bits (FILE_READ_DATA etc.) */
    3525             :                             uint32_t share_access,      /* share constants (FILE_SHARE_READ etc) */
    3526             :                             uint32_t create_disposition,        /* FILE_OPEN_IF etc. */
    3527             :                             uint32_t create_options,    /* options such as delete on close. */
    3528             :                             uint32_t new_dos_attributes,        /* attributes used for new file. */
    3529             :                             int oplock_request,         /* internal Samba oplock codes. */
    3530             :                             const struct smb2_lease *lease,
    3531             :                                                         /* Information (FILE_EXISTS etc.) */
    3532             :                             uint32_t private_flags,     /* Samba specific flags. */
    3533             :                             struct smb_filename *parent_dir_fname, /* parent. */
    3534             :                             struct smb_filename *smb_fname_atname, /* atname relative to parent. */
    3535             :                             int *pinfo,
    3536             :                             files_struct *fsp)
    3537             : {
    3538        6512 :         struct smb_filename *smb_fname = fsp->fsp_name;
    3539        6512 :         int flags=0;
    3540        6512 :         int flags2=0;
    3541        6512 :         bool file_existed = VALID_STAT(smb_fname->st);
    3542        6512 :         bool def_acl = False;
    3543        6512 :         bool posix_open = False;
    3544        6512 :         bool new_file_created = False;
    3545        6512 :         bool first_open_attempt = true;
    3546        6512 :         NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
    3547        6512 :         mode_t new_unx_mode = (mode_t)0;
    3548        6512 :         mode_t unx_mode = (mode_t)0;
    3549             :         int info;
    3550        6512 :         uint32_t existing_dos_attributes = 0;
    3551        6512 :         struct share_mode_lock *lck = NULL;
    3552        6512 :         uint32_t open_access_mask = access_mask;
    3553        6512 :         const struct smb2_lease_key *lease_key = NULL;
    3554             :         NTSTATUS status;
    3555        6512 :         SMB_STRUCT_STAT saved_stat = smb_fname->st;
    3556             :         struct timespec old_write_time;
    3557        6512 :         bool setup_poll = false;
    3558             :         bool ok;
    3559             : 
    3560        6512 :         if (conn->printer) {
    3561             :                 /*
    3562             :                  * Printers are handled completely differently.
    3563             :                  * Most of the passed parameters are ignored.
    3564             :                  */
    3565             : 
    3566           0 :                 if (pinfo) {
    3567           0 :                         *pinfo = FILE_WAS_CREATED;
    3568             :                 }
    3569             : 
    3570           0 :                 DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n",
    3571             :                            smb_fname_str_dbg(smb_fname)));
    3572             : 
    3573           0 :                 if (!req) {
    3574           0 :                         DEBUG(0,("open_file_ntcreate: printer open without "
    3575             :                                 "an SMB request!\n"));
    3576           0 :                         return NT_STATUS_INTERNAL_ERROR;
    3577             :                 }
    3578             : 
    3579           0 :                 return print_spool_open(fsp, smb_fname->base_name,
    3580             :                                         req->vuid);
    3581             :         }
    3582             : 
    3583        6512 :         if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
    3584           0 :                 posix_open = True;
    3585           0 :                 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
    3586           0 :                 new_dos_attributes = 0;
    3587             :         } else {
    3588             :                 /* Windows allows a new file to be created and
    3589             :                    silently removes a FILE_ATTRIBUTE_DIRECTORY
    3590             :                    sent by the client. Do the same. */
    3591             : 
    3592        6512 :                 new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY;
    3593             : 
    3594             :                 /* We add FILE_ATTRIBUTE_ARCHIVE to this as this mode is only used if the file is
    3595             :                  * created new. */
    3596        6512 :                 unx_mode = unix_mode(
    3597             :                         conn,
    3598             :                         new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
    3599             :                         smb_fname,
    3600             :                         parent_dir_fname->fsp);
    3601             :         }
    3602             : 
    3603        6512 :         DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
    3604             :                    "access_mask=0x%x share_access=0x%x "
    3605             :                    "create_disposition = 0x%x create_options=0x%x "
    3606             :                    "unix mode=0%o oplock_request=%d private_flags = 0x%x\n",
    3607             :                    smb_fname_str_dbg(smb_fname), new_dos_attributes,
    3608             :                    access_mask, share_access, create_disposition,
    3609             :                    create_options, (unsigned int)unx_mode, oplock_request,
    3610             :                    (unsigned int)private_flags));
    3611             : 
    3612        6512 :         if (req == NULL) {
    3613             :                 /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
    3614          80 :                 SMB_ASSERT(oplock_request == INTERNAL_OPEN_ONLY);
    3615             :         } else {
    3616             :                 /* And req != NULL means no INTERNAL_OPEN_ONLY */
    3617        6432 :                 SMB_ASSERT(((oplock_request & INTERNAL_OPEN_ONLY) == 0));
    3618             :         }
    3619             : 
    3620             :         /*
    3621             :          * Only non-internal opens can be deferred at all
    3622             :          */
    3623             : 
    3624        6512 :         if (req) {
    3625             :                 struct deferred_open_record *open_rec;
    3626        6432 :                 if (get_deferred_open_message_state(req, NULL, &open_rec)) {
    3627             : 
    3628             :                         /* If it was an async create retry, the file
    3629             :                            didn't exist. */
    3630             : 
    3631           0 :                         if (is_deferred_open_async(open_rec)) {
    3632           0 :                                 SET_STAT_INVALID(smb_fname->st);
    3633           0 :                                 file_existed = false;
    3634             :                         }
    3635             : 
    3636             :                         /* Ensure we don't reprocess this message. */
    3637           0 :                         remove_deferred_open_message_smb(req->xconn, req->mid);
    3638             : 
    3639           0 :                         first_open_attempt = false;
    3640             :                 }
    3641             :         }
    3642             : 
    3643        6512 :         if (!posix_open) {
    3644        6512 :                 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
    3645        6512 :                 if (file_existed) {
    3646             :                         /*
    3647             :                          * Only use stored DOS attributes for checks
    3648             :                          * against requested attributes (below via
    3649             :                          * open_match_attributes()), cf bug #11992
    3650             :                          * for details. -slow
    3651             :                          */
    3652        5721 :                         uint32_t attr = 0;
    3653             : 
    3654        5721 :                         status = vfs_fget_dos_attributes(smb_fname->fsp, &attr);
    3655        5721 :                         if (NT_STATUS_IS_OK(status)) {
    3656        1453 :                                 existing_dos_attributes = attr;
    3657             :                         }
    3658             :                 }
    3659             :         }
    3660             : 
    3661             :         /* ignore any oplock requests if oplocks are disabled */
    3662        6512 :         if (!lp_oplocks(SNUM(conn)) ||
    3663        6512 :             IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
    3664             :                 /* Mask off everything except the private Samba bits. */
    3665           0 :                 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
    3666             :         }
    3667             : 
    3668             :         /* this is for OS/2 long file names - say we don't support them */
    3669       12498 :         if (req != NULL && !req->posix_pathnames &&
    3670        6432 :                         strstr(smb_fname->base_name,".+,;=[].")) {
    3671             :                 /* OS/2 Workplace shell fix may be main code stream in a later
    3672             :                  * release. */
    3673           0 :                 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
    3674             :                          "supported.\n"));
    3675           0 :                 if (use_nt_status()) {
    3676           0 :                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    3677             :                 }
    3678           0 :                 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
    3679             :         }
    3680             : 
    3681        6512 :         switch( create_disposition ) {
    3682        5798 :                 case FILE_OPEN:
    3683             :                         /* If file exists open. If file doesn't exist error. */
    3684        5798 :                         if (!file_existed) {
    3685         183 :                                 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
    3686             :                                          "requested for file %s and file "
    3687             :                                          "doesn't exist.\n",
    3688             :                                          smb_fname_str_dbg(smb_fname)));
    3689         183 :                                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    3690             :                         }
    3691        5615 :                         break;
    3692             : 
    3693           2 :                 case FILE_OVERWRITE:
    3694             :                         /* If file exists overwrite. If file doesn't exist
    3695             :                          * error. */
    3696           2 :                         if (!file_existed) {
    3697           1 :                                 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
    3698             :                                          "requested for file %s and file "
    3699             :                                          "doesn't exist.\n",
    3700             :                                          smb_fname_str_dbg(smb_fname) ));
    3701           1 :                                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    3702             :                         }
    3703           1 :                         break;
    3704             : 
    3705          25 :                 case FILE_CREATE:
    3706             :                         /* If file exists error. If file doesn't exist
    3707             :                          * create. */
    3708          25 :                         if (file_existed) {
    3709           2 :                                 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
    3710             :                                          "requested for file %s and file "
    3711             :                                          "already exists.\n",
    3712             :                                          smb_fname_str_dbg(smb_fname)));
    3713           2 :                                 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
    3714           0 :                                         return NT_STATUS_FILE_IS_A_DIRECTORY;
    3715             :                                 }
    3716           2 :                                 return NT_STATUS_OBJECT_NAME_COLLISION;
    3717             :                         }
    3718          23 :                         break;
    3719             : 
    3720         685 :                 case FILE_SUPERSEDE:
    3721             :                 case FILE_OVERWRITE_IF:
    3722             :                 case FILE_OPEN_IF:
    3723         685 :                         break;
    3724           2 :                 default:
    3725           2 :                         return NT_STATUS_INVALID_PARAMETER;
    3726             :         }
    3727             : 
    3728        6324 :         flags2 = disposition_to_open_flags(create_disposition);
    3729             : 
    3730             :         /* We only care about matching attributes on file exists and
    3731             :          * overwrite. */
    3732             : 
    3733        6324 :         if (!posix_open && file_existed &&
    3734        5717 :             ((create_disposition == FILE_OVERWRITE) ||
    3735             :              (create_disposition == FILE_OVERWRITE_IF))) {
    3736          69 :                 if (!open_match_attributes(conn, existing_dos_attributes,
    3737             :                                            new_dos_attributes,
    3738             :                                            unx_mode, &new_unx_mode)) {
    3739           0 :                         DEBUG(5,("open_file_ntcreate: attributes mismatch "
    3740             :                                  "for file %s (%x %x) (0%o, 0%o)\n",
    3741             :                                  smb_fname_str_dbg(smb_fname),
    3742             :                                  existing_dos_attributes,
    3743             :                                  new_dos_attributes,
    3744             :                                  (unsigned int)smb_fname->st.st_ex_mode,
    3745             :                                  (unsigned int)unx_mode ));
    3746           0 :                         return NT_STATUS_ACCESS_DENIED;
    3747             :                 }
    3748             :         }
    3749             : 
    3750        6324 :         status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
    3751             :                                                 smb_fname->fsp,
    3752             :                                                 false,
    3753             :                                                 access_mask,
    3754             :                                                 &access_mask);
    3755        6324 :         if (!NT_STATUS_IS_OK(status)) {
    3756           0 :                 DBG_DEBUG("smbd_calculate_access_mask_fsp "
    3757             :                         "on file %s returned %s\n",
    3758             :                         smb_fname_str_dbg(smb_fname),
    3759             :                         nt_errstr(status));
    3760           0 :                 return status;
    3761             :         }
    3762             : 
    3763        6324 :         open_access_mask = access_mask;
    3764             : 
    3765        6324 :         if (flags2 & O_TRUNC) {
    3766         518 :                 open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
    3767             :         }
    3768             : 
    3769        6324 :         if (file_existed) {
    3770             :                 /*
    3771             :                  * stat opens on existing files don't get oplocks.
    3772             :                  * They can get leases.
    3773             :                  *
    3774             :                  * Note that we check for stat open on the *open_access_mask*,
    3775             :                  * i.e. the access mask we actually used to do the open,
    3776             :                  * not the one the client asked for (which is in
    3777             :                  * fsp->access_mask). This is due to the fact that
    3778             :                  * FILE_OVERWRITE and FILE_OVERWRITE_IF add in O_TRUNC,
    3779             :                  * which adds FILE_WRITE_DATA to open_access_mask.
    3780             :                  */
    3781        5718 :                 if (is_oplock_stat_open(open_access_mask) && lease == NULL) {
    3782        4186 :                         oplock_request = NO_OPLOCK;
    3783             :                 }
    3784             :         }
    3785             : 
    3786        6324 :         DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
    3787             :                    "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname),
    3788             :                     access_mask));
    3789             : 
    3790             :         /*
    3791             :          * Note that we ignore the append flag as append does not
    3792             :          * mean the same thing under DOS and Unix.
    3793             :          */
    3794             : 
    3795        6324 :         flags = calculate_open_access_flags(access_mask, private_flags);
    3796             : 
    3797             :         /*
    3798             :          * Currently we only look at FILE_WRITE_THROUGH for create options.
    3799             :          */
    3800             : 
    3801             : #if defined(O_SYNC)
    3802        6324 :         if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) {
    3803           0 :                 flags2 |= O_SYNC;
    3804             :         }
    3805             : #endif /* O_SYNC */
    3806             : 
    3807        6324 :         if (posix_open && (access_mask & FILE_APPEND_DATA)) {
    3808           0 :                 flags2 |= O_APPEND;
    3809             :         }
    3810             : 
    3811        6324 :         if (!posix_open && !CAN_WRITE(conn)) {
    3812             :                 /*
    3813             :                  * We should really return a permission denied error if either
    3814             :                  * O_CREAT or O_TRUNC are set, but for compatibility with
    3815             :                  * older versions of Samba we just AND them out.
    3816             :                  */
    3817           0 :                 flags2 &= ~(O_CREAT|O_TRUNC);
    3818             :         }
    3819             : 
    3820             :         /*
    3821             :          * With kernel oplocks the open breaking an oplock
    3822             :          * blocks until the oplock holder has given up the
    3823             :          * oplock or closed the file. We prevent this by always
    3824             :          * trying to open the file with O_NONBLOCK (see "man
    3825             :          * fcntl" on Linux).
    3826             :          *
    3827             :          * If a process that doesn't use the smbd open files
    3828             :          * database or communication methods holds a kernel
    3829             :          * oplock we must periodically poll for available open
    3830             :          * using O_NONBLOCK.
    3831             :          */
    3832        6324 :         flags2 |= O_NONBLOCK;
    3833             : 
    3834             :         /*
    3835             :          * Ensure we can't write on a read-only share or file.
    3836             :          */
    3837             : 
    3838        6414 :         if (flags != O_RDONLY && file_existed &&
    3839         191 :             (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
    3840           0 :                 DEBUG(5,("open_file_ntcreate: write access requested for "
    3841             :                          "file %s on read only %s\n",
    3842             :                          smb_fname_str_dbg(smb_fname),
    3843             :                          !CAN_WRITE(conn) ? "share" : "file" ));
    3844           0 :                 return NT_STATUS_ACCESS_DENIED;
    3845             :         }
    3846             : 
    3847        6324 :         if (VALID_STAT(smb_fname->st)) {
    3848             :                 /*
    3849             :                  * Only try and create a file id before open
    3850             :                  * for an existing file. For a file being created
    3851             :                  * this won't do anything useful until the file
    3852             :                  * exists and has a valid stat struct.
    3853             :                  */
    3854        5718 :                 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
    3855             :         }
    3856        6324 :         fh_set_private_options(fsp->fh, private_flags);
    3857        6324 :         fsp->access_mask = open_access_mask; /* We change this to the
    3858             :                                               * requested access_mask after
    3859             :                                               * the open is done. */
    3860        6324 :         if (posix_open) {
    3861           0 :                 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
    3862             :         }
    3863             : 
    3864        6799 :         if ((create_options & FILE_DELETE_ON_CLOSE) &&
    3865         622 :                         (flags2 & O_CREAT) &&
    3866         106 :                         !file_existed) {
    3867             :                 /* Delete on close semantics for new files. */
    3868         106 :                 status = can_set_delete_on_close(fsp,
    3869             :                                                 new_dos_attributes);
    3870         106 :                 if (!NT_STATUS_IS_OK(status)) {
    3871           0 :                         fd_close(fsp);
    3872           0 :                         return status;
    3873             :                 }
    3874             :         }
    3875             : 
    3876             :         /*
    3877             :          * Ensure we pay attention to default ACLs on directories if required.
    3878             :          */
    3879             : 
    3880        7024 :         if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
    3881         700 :             (def_acl = directory_has_default_acl_fsp(parent_dir_fname->fsp)))
    3882             :         {
    3883         700 :                 unx_mode = (0777 & lp_create_mask(SNUM(conn)));
    3884             :         }
    3885             : 
    3886        6324 :         DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o, "
    3887             :                 "access_mask = 0x%x, open_access_mask = 0x%x\n",
    3888             :                  (unsigned int)flags, (unsigned int)flags2,
    3889             :                  (unsigned int)unx_mode, (unsigned int)access_mask,
    3890             :                  (unsigned int)open_access_mask));
    3891             : 
    3892        6324 :         fsp_open = open_file(req,
    3893             :                              parent_dir_fname->fsp,
    3894             :                              smb_fname_atname,
    3895             :                              fsp,
    3896             :                              flags|flags2,
    3897             :                              unx_mode,
    3898             :                              access_mask,
    3899             :                              open_access_mask,
    3900             :                              private_flags,
    3901             :                              &new_file_created);
    3902        6324 :         if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_NETWORK_BUSY)) {
    3903           0 :                 if (file_existed && S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
    3904           0 :                         DEBUG(10, ("FIFO busy\n"));
    3905           0 :                         return NT_STATUS_NETWORK_BUSY;
    3906             :                 }
    3907           0 :                 if (req == NULL) {
    3908           0 :                         DEBUG(10, ("Internal open busy\n"));
    3909           0 :                         return NT_STATUS_NETWORK_BUSY;
    3910             :                 }
    3911             :                 /*
    3912             :                  * This handles the kernel oplock case:
    3913             :                  *
    3914             :                  * the file has an active kernel oplock and the open() returned
    3915             :                  * EWOULDBLOCK/EAGAIN which maps to NETWORK_BUSY.
    3916             :                  *
    3917             :                  * "Samba locking.tdb oplocks" are handled below after acquiring
    3918             :                  * the sharemode lock with get_share_mode_lock().
    3919             :                  */
    3920           0 :                 setup_poll = true;
    3921             :         }
    3922             : 
    3923        6324 :         if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_RETRY)) {
    3924             :                 /*
    3925             :                  * EINTR from the open(2) syscall. Just setup a retry
    3926             :                  * in a bit. We can't use the sys_write() tight retry
    3927             :                  * loop here, as we might have to actually deal with
    3928             :                  * lease-break signals to avoid a deadlock.
    3929             :                  */
    3930           0 :                 setup_poll = true;
    3931             :         }
    3932             : 
    3933        6324 :         if (setup_poll) {
    3934             :                 /*
    3935             :                  * From here on we assume this is an oplock break triggered
    3936             :                  */
    3937             : 
    3938           0 :                 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
    3939             : 
    3940           0 :                 if ((lck != NULL) && !validate_oplock_types(lck)) {
    3941           0 :                         smb_panic("validate_oplock_types failed");
    3942             :                 }
    3943             : 
    3944             :                 /*
    3945             :                  * Retry once a second. If there's a share_mode_lock
    3946             :                  * around, also wait for it in case it was smbd
    3947             :                  * holding that kernel oplock that can quickly tell us
    3948             :                  * the oplock got removed.
    3949             :                  */
    3950             : 
    3951           0 :                 setup_poll_open(
    3952             :                         req,
    3953             :                         lck,
    3954             :                         fsp->file_id,
    3955             :                         timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0),
    3956             :                         timeval_set(1, 0));
    3957             : 
    3958           0 :                 TALLOC_FREE(lck);
    3959             : 
    3960           0 :                 return NT_STATUS_SHARING_VIOLATION;
    3961             :         }
    3962             : 
    3963        6324 :         if (!NT_STATUS_IS_OK(fsp_open)) {
    3964        4462 :                 bool wait_for_aio = NT_STATUS_EQUAL(
    3965             :                         fsp_open, NT_STATUS_MORE_PROCESSING_REQUIRED);
    3966        4462 :                 if (wait_for_aio) {
    3967           0 :                         schedule_async_open(req);
    3968             :                 }
    3969        4462 :                 return fsp_open;
    3970             :         }
    3971             : 
    3972        1862 :         if (new_file_created) {
    3973             :                 /*
    3974             :                  * As we atomically create using O_CREAT|O_EXCL,
    3975             :                  * then if new_file_created is true, then
    3976             :                  * file_existed *MUST* have been false (even
    3977             :                  * if the file was previously detected as being
    3978             :                  * there).
    3979             :                  */
    3980         605 :                 file_existed = false;
    3981             :         }
    3982             : 
    3983        1862 :         if (file_existed && !check_same_dev_ino(&saved_stat, &smb_fname->st)) {
    3984             :                 /*
    3985             :                  * The file did exist, but some other (local or NFS)
    3986             :                  * process either renamed/unlinked and re-created the
    3987             :                  * file with different dev/ino after we walked the path,
    3988             :                  * but before we did the open. We could retry the
    3989             :                  * open but it's a rare enough case it's easier to
    3990             :                  * just fail the open to prevent creating any problems
    3991             :                  * in the open file db having the wrong dev/ino key.
    3992             :                  */
    3993           0 :                 fd_close(fsp);
    3994           0 :                 DBG_WARNING("file %s - dev/ino mismatch. "
    3995             :                             "Old (dev=%ju, ino=%ju). "
    3996             :                             "New (dev=%ju, ino=%ju). Failing open "
    3997             :                             "with NT_STATUS_ACCESS_DENIED.\n",
    3998             :                             smb_fname_str_dbg(smb_fname),
    3999             :                             (uintmax_t)saved_stat.st_ex_dev,
    4000             :                             (uintmax_t)saved_stat.st_ex_ino,
    4001             :                             (uintmax_t)smb_fname->st.st_ex_dev,
    4002             :                             (uintmax_t)smb_fname->st.st_ex_ino);
    4003           0 :                 return NT_STATUS_ACCESS_DENIED;
    4004             :         }
    4005             : 
    4006        1862 :         old_write_time = smb_fname->st.st_ex_mtime;
    4007             : 
    4008             :         /*
    4009             :          * Deal with the race condition where two smbd's detect the
    4010             :          * file doesn't exist and do the create at the same time. One
    4011             :          * of them will win and set a share mode, the other (ie. this
    4012             :          * one) should check if the requested share mode for this
    4013             :          * create is allowed.
    4014             :          */
    4015             : 
    4016             :         /*
    4017             :          * Now the file exists and fsp is successfully opened,
    4018             :          * fsp->dev and fsp->inode are valid and should replace the
    4019             :          * dev=0,inode=0 from a non existent file. Spotted by
    4020             :          * Nadav Danieli <nadavd@exanet.com>. JRA.
    4021             :          */
    4022             : 
    4023        1862 :         lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
    4024        1862 :                                   conn->connectpath,
    4025             :                                   smb_fname, &old_write_time);
    4026             : 
    4027        1862 :         if (lck == NULL) {
    4028           0 :                 DEBUG(0, ("open_file_ntcreate: Could not get share "
    4029             :                           "mode lock for %s\n",
    4030             :                           smb_fname_str_dbg(smb_fname)));
    4031           0 :                 fd_close(fsp);
    4032           0 :                 return NT_STATUS_SHARING_VIOLATION;
    4033             :         }
    4034             : 
    4035             :         /* Get the types we need to examine. */
    4036        1862 :         if (!validate_oplock_types(lck)) {
    4037           0 :                 smb_panic("validate_oplock_types failed");
    4038             :         }
    4039             : 
    4040        1862 :         if (has_delete_on_close(lck, fsp->name_hash)) {
    4041           0 :                 TALLOC_FREE(lck);
    4042           0 :                 fd_close(fsp);
    4043           0 :                 return NT_STATUS_DELETE_PENDING;
    4044             :         }
    4045             : 
    4046        1862 :         status = handle_share_mode_lease(
    4047             :                 fsp,
    4048             :                 lck,
    4049             :                 create_disposition,
    4050             :                 access_mask,
    4051             :                 share_access,
    4052             :                 oplock_request,
    4053             :                 lease,
    4054             :                 first_open_attempt);
    4055             : 
    4056        1862 :         if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
    4057           0 :                 schedule_defer_open(lck, fsp->file_id, req);
    4058           0 :                 TALLOC_FREE(lck);
    4059           0 :                 fd_close(fsp);
    4060           0 :                 return NT_STATUS_SHARING_VIOLATION;
    4061             :         }
    4062             : 
    4063        1862 :         if (!NT_STATUS_IS_OK(status)) {
    4064          12 :                 TALLOC_FREE(lck);
    4065          12 :                 fd_close(fsp);
    4066          12 :                 return status;
    4067             :         }
    4068             : 
    4069        1850 :         if (fsp->oplock_type == LEASE_OPLOCK) {
    4070           0 :                 lease_key = &lease->lease_key;
    4071             :         }
    4072             : 
    4073        1850 :         share_mode_flags_restrict(lck, access_mask, share_access, 0);
    4074             : 
    4075        5260 :         ok = set_share_mode(
    4076             :                 lck,
    4077             :                 fsp,
    4078        1850 :                 get_current_uid(fsp->conn),
    4079             :                 req ? req->mid : 0,
    4080        1850 :                 fsp->oplock_type,
    4081             :                 lease_key,
    4082             :                 share_access,
    4083             :                 access_mask);
    4084        1850 :         if (!ok) {
    4085           0 :                 if (fsp->oplock_type == LEASE_OPLOCK) {
    4086           0 :                         status = remove_lease_if_stale(
    4087             :                                 lck,
    4088             :                                 fsp_client_guid(fsp),
    4089           0 :                                 &fsp->lease->lease.lease_key);
    4090           0 :                         if (!NT_STATUS_IS_OK(status)) {
    4091           0 :                                 DBG_WARNING("remove_lease_if_stale "
    4092             :                                             "failed: %s\n",
    4093             :                                             nt_errstr(status));
    4094             :                         }
    4095             :                 }
    4096           0 :                 TALLOC_FREE(lck);
    4097           0 :                 fd_close(fsp);
    4098           0 :                 return NT_STATUS_NO_MEMORY;
    4099             :         }
    4100             : 
    4101             :         /* Should we atomically (to the client at least) truncate ? */
    4102        2913 :         if ((!new_file_created) &&
    4103        1312 :             (flags2 & O_TRUNC) &&
    4104          70 :             (S_ISREG(fsp->fsp_name->st.st_ex_mode))) {
    4105             :                 int ret;
    4106             : 
    4107          70 :                 ret = SMB_VFS_FTRUNCATE(fsp, 0);
    4108          70 :                 if (ret != 0) {
    4109           0 :                         status = map_nt_error_from_unix(errno);
    4110           0 :                         del_share_mode(lck, fsp);
    4111           0 :                         TALLOC_FREE(lck);
    4112           0 :                         fd_close(fsp);
    4113           0 :                         return status;
    4114             :                 }
    4115          70 :                 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
    4116             :                              FILE_NOTIFY_CHANGE_SIZE
    4117             :                              | FILE_NOTIFY_CHANGE_ATTRIBUTES,
    4118          70 :                              fsp->fsp_name->base_name);
    4119             :         }
    4120             : 
    4121             :         /*
    4122             :          * We have the share entry *locked*.....
    4123             :          */
    4124             : 
    4125             :         /* Delete streams if create_disposition requires it */
    4126        3095 :         if (!new_file_created &&
    4127        1312 :             clear_ads(create_disposition) &&
    4128          70 :             !fsp_is_alternate_stream(fsp)) {
    4129          64 :                 status = delete_all_streams(conn, smb_fname);
    4130          64 :                 if (!NT_STATUS_IS_OK(status)) {
    4131           0 :                         del_share_mode(lck, fsp);
    4132           0 :                         TALLOC_FREE(lck);
    4133           0 :                         fd_close(fsp);
    4134           0 :                         return status;
    4135             :                 }
    4136             :         }
    4137             : 
    4138        3005 :         if (!fsp->fsp_flags.is_pathref &&
    4139        2310 :             fsp_get_io_fd(fsp) != -1 &&
    4140        1155 :             lp_kernel_share_modes(SNUM(conn)))
    4141             :         {
    4142             :                 int ret;
    4143             :                 /*
    4144             :                  * Beware: streams implementing VFS modules may
    4145             :                  * implement streams in a way that fsp will have the
    4146             :                  * basefile open in the fsp fd, so lacking a distinct
    4147             :                  * fd for the stream the file-system sharemode will
    4148             :                  * apply on the basefile which is wrong. The actual
    4149             :                  * check is deferred to the VFS module implementing
    4150             :                  * the file-system sharemode call.
    4151             :                  */
    4152           0 :                 ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp,
    4153             :                                                    share_access,
    4154             :                                                    access_mask);
    4155           0 :                 if (ret == -1){
    4156           0 :                         del_share_mode(lck, fsp);
    4157           0 :                         TALLOC_FREE(lck);
    4158           0 :                         fd_close(fsp);
    4159             : 
    4160           0 :                         return NT_STATUS_SHARING_VIOLATION;
    4161             :                 }
    4162             : 
    4163           0 :                 fsp->fsp_flags.kernel_share_modes_taken = true;
    4164             :         }
    4165             : 
    4166             :         /*
    4167             :          * At this point onwards, we can guarantee that the share entry
    4168             :          * is locked, whether we created the file or not, and that the
    4169             :          * deny mode is compatible with all current opens.
    4170             :          */
    4171             : 
    4172             :         /*
    4173             :          * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
    4174             :          * but we don't have to store this - just ignore it on access check.
    4175             :          */
    4176        1850 :         if (conn->sconn->using_smb2) {
    4177             :                 /*
    4178             :                  * SMB2 doesn't return it (according to Microsoft tests).
    4179             :                  * Test Case: TestSuite_ScenarioNo009GrantedAccessTestS0
    4180             :                  * File created with access = 0x7 (Read, Write, Delete)
    4181             :                  * Query Info on file returns 0x87 (Read, Write, Delete, Read Attributes)
    4182             :                  */
    4183        1850 :                 fsp->access_mask = access_mask;
    4184             :         } else {
    4185             :                 /* But SMB1 does. */
    4186           0 :                 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
    4187             :         }
    4188             : 
    4189        1850 :         if (new_file_created) {
    4190         605 :                 info = FILE_WAS_CREATED;
    4191             :         } else {
    4192        1245 :                 if (flags2 & O_TRUNC) {
    4193          70 :                         info = FILE_WAS_OVERWRITTEN;
    4194             :                 } else {
    4195        1175 :                         info = FILE_WAS_OPENED;
    4196             :                 }
    4197             :         }
    4198             : 
    4199        1850 :         if (pinfo) {
    4200        1850 :                 *pinfo = info;
    4201             :         }
    4202             : 
    4203             :         /* Handle strange delete on close create semantics. */
    4204        1850 :         if (create_options & FILE_DELETE_ON_CLOSE) {
    4205         556 :                 if (!new_file_created) {
    4206         450 :                         status = can_set_delete_on_close(fsp,
    4207             :                                          existing_dos_attributes);
    4208             : 
    4209         450 :                         if (!NT_STATUS_IS_OK(status)) {
    4210             :                                 /* Remember to delete the mode we just added. */
    4211           0 :                                 del_share_mode(lck, fsp);
    4212           0 :                                 TALLOC_FREE(lck);
    4213           0 :                                 fd_close(fsp);
    4214           0 :                                 return status;
    4215             :                         }
    4216             :                 }
    4217             :                 /* Note that here we set the *initial* delete on close flag,
    4218             :                    not the regular one. The magic gets handled in close. */
    4219         556 :                 fsp->fsp_flags.initial_delete_on_close = true;
    4220             :         }
    4221             : 
    4222        1850 :         if (info != FILE_WAS_OPENED) {
    4223             :                 /* Overwritten files should be initially set as archive */
    4224        1335 :                 if ((info == FILE_WAS_OVERWRITTEN && lp_map_archive(SNUM(conn))) ||
    4225         660 :                     lp_store_dos_attributes(SNUM(conn))) {
    4226         675 :                         (void)fdos_mode(fsp);
    4227         675 :                         if (!posix_open) {
    4228         675 :                                 if (file_set_dosmode(conn, smb_fname,
    4229             :                                             new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
    4230             :                                             parent_dir_fname, true) == 0) {
    4231         675 :                                         unx_mode = smb_fname->st.st_ex_mode;
    4232             :                                 }
    4233             :                         }
    4234             :                 }
    4235             :         }
    4236             : 
    4237             :         /* Determine sparse flag. */
    4238        1850 :         if (posix_open) {
    4239             :                 /* POSIX opens are sparse by default. */
    4240           0 :                 fsp->fsp_flags.is_sparse = true;
    4241             :         } else {
    4242        1850 :                 fsp->fsp_flags.is_sparse =
    4243        1850 :                         (existing_dos_attributes & FILE_ATTRIBUTE_SPARSE);
    4244             :         }
    4245             : 
    4246             :         /*
    4247             :          * Take care of inherited ACLs on created files - if default ACL not
    4248             :          * selected.
    4249             :          */
    4250             : 
    4251        1850 :         if (!posix_open && new_file_created && !def_acl) {
    4252           6 :                 if (unx_mode != smb_fname->st.st_ex_mode) {
    4253           0 :                         int ret = SMB_VFS_FCHMOD(fsp, unx_mode);
    4254           0 :                         if (ret == -1) {
    4255           0 :                                 DBG_INFO("failed to reset "
    4256             :                                   "attributes of file %s to 0%o\n",
    4257             :                                   smb_fname_str_dbg(smb_fname),
    4258             :                                   (unsigned int)unx_mode);
    4259             :                         }
    4260             :                 }
    4261             : 
    4262        1846 :         } else if (new_unx_mode) {
    4263             :                 /*
    4264             :                  * We only get here in the case of:
    4265             :                  *
    4266             :                  * a). Not a POSIX open.
    4267             :                  * b). File already existed.
    4268             :                  * c). File was overwritten.
    4269             :                  * d). Requested DOS attributes didn't match
    4270             :                  *     the DOS attributes on the existing file.
    4271             :                  *
    4272             :                  * In that case new_unx_mode has been set
    4273             :                  * equal to the calculated mode (including
    4274             :                  * possible inheritance of the mode from the
    4275             :                  * containing directory).
    4276             :                  *
    4277             :                  * Note this mode was calculated with the
    4278             :                  * DOS attribute FILE_ATTRIBUTE_ARCHIVE added,
    4279             :                  * so the mode change here is suitable for
    4280             :                  * an overwritten file.
    4281             :                  */
    4282             : 
    4283           0 :                 if (new_unx_mode != smb_fname->st.st_ex_mode) {
    4284           0 :                         int ret = SMB_VFS_FCHMOD(fsp, new_unx_mode);
    4285           0 :                         if (ret == -1) {
    4286           0 :                                 DBG_INFO("failed to reset "
    4287             :                                   "attributes of file %s to 0%o\n",
    4288             :                                   smb_fname_str_dbg(smb_fname),
    4289             :                                   (unsigned int)new_unx_mode);
    4290             :                         }
    4291             :                 }
    4292             :         }
    4293             : 
    4294             :         {
    4295             :                 /*
    4296             :                  * Deal with other opens having a modified write time.
    4297             :                  */
    4298        1850 :                 struct timespec write_time = get_share_mode_write_time(lck);
    4299             : 
    4300        1850 :                 if (!is_omit_timespec(&write_time)) {
    4301        1850 :                         update_stat_ex_mtime(&fsp->fsp_name->st, write_time);
    4302             :                 }
    4303             :         }
    4304             : 
    4305        1850 :         TALLOC_FREE(lck);
    4306             : 
    4307        1850 :         return NT_STATUS_OK;
    4308             : }
    4309             : 
    4310         750 : static NTSTATUS mkdir_internal(connection_struct *conn,
    4311             :                                struct smb_filename *parent_dir_fname, /* parent. */
    4312             :                                struct smb_filename *smb_fname_atname, /* atname relative to parent. */
    4313             :                                struct smb_filename *smb_dname, /* full pathname from root of share. */
    4314             :                                uint32_t file_attributes,
    4315             :                                struct files_struct *fsp)
    4316             : {
    4317         694 :         const struct loadparm_substitution *lp_sub =
    4318          56 :                 loadparm_s3_global_substitution();
    4319             :         mode_t mode;
    4320             :         NTSTATUS status;
    4321         750 :         bool posix_open = false;
    4322         750 :         bool need_re_stat = false;
    4323         750 :         uint32_t access_mask = SEC_DIR_ADD_SUBDIR;
    4324         750 :         struct vfs_open_how how = { .flags = O_RDONLY|O_DIRECTORY, };
    4325             :         int ret;
    4326             : 
    4327         750 :         if (!CAN_WRITE(conn) || (access_mask & ~(conn->share_access))) {
    4328           0 :                 DEBUG(5,("mkdir_internal: failing share access "
    4329             :                          "%s\n", lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
    4330           0 :                 return NT_STATUS_ACCESS_DENIED;
    4331             :         }
    4332             : 
    4333         750 :         if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
    4334           0 :                 posix_open = true;
    4335           0 :                 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
    4336             :         } else {
    4337         750 :                 mode = unix_mode(conn,
    4338             :                                  FILE_ATTRIBUTE_DIRECTORY,
    4339             :                                  smb_dname,
    4340             :                                  parent_dir_fname->fsp);
    4341             :         }
    4342             : 
    4343         750 :         status = check_parent_access_fsp(parent_dir_fname->fsp, access_mask);
    4344         750 :         if(!NT_STATUS_IS_OK(status)) {
    4345           0 :                 DBG_INFO("check_parent_access_fsp "
    4346             :                         "on directory %s for path %s returned %s\n",
    4347             :                         smb_fname_str_dbg(parent_dir_fname),
    4348             :                         smb_dname->base_name,
    4349             :                         nt_errstr(status));
    4350           0 :                 return status;
    4351             :         }
    4352             : 
    4353         750 :         if (lp_inherit_acls(SNUM(conn))) {
    4354         746 :                 if (directory_has_default_acl_fsp(parent_dir_fname->fsp)) {
    4355         742 :                         mode = (0777 & lp_directory_mask(SNUM(conn)));
    4356             :                 }
    4357             :         }
    4358             : 
    4359         750 :         ret = SMB_VFS_MKDIRAT(conn,
    4360             :                               parent_dir_fname->fsp,
    4361             :                               smb_fname_atname,
    4362             :                               mode);
    4363         750 :         if (ret != 0) {
    4364           1 :                 return map_nt_error_from_unix(errno);
    4365             :         }
    4366             : 
    4367             :         /*
    4368             :          * Make this a pathref fsp for now. open_directory() will reopen as a
    4369             :          * full fsp.
    4370             :          */
    4371         749 :         fsp->fsp_flags.is_pathref = true;
    4372             : 
    4373         749 :         status = fd_openat(parent_dir_fname->fsp, smb_fname_atname, fsp, &how);
    4374         749 :         if (!NT_STATUS_IS_OK(status)) {
    4375           0 :                 return status;
    4376             :         }
    4377             : 
    4378             :         /* Ensure we're checking for a symlink here.... */
    4379             :         /* We don't want to get caught by a symlink racer. */
    4380             : 
    4381         749 :         status = vfs_stat_fsp(fsp);
    4382         749 :         if (!NT_STATUS_IS_OK(status)) {
    4383           0 :                 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
    4384             :                           smb_fname_str_dbg(smb_dname), nt_errstr(status)));
    4385           0 :                 return status;
    4386             :         }
    4387             : 
    4388         749 :         if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
    4389           0 :                 DEBUG(0, ("Directory '%s' just created is not a directory !\n",
    4390             :                           smb_fname_str_dbg(smb_dname)));
    4391           0 :                 return NT_STATUS_NOT_A_DIRECTORY;
    4392             :         }
    4393             : 
    4394         749 :         if (lp_store_dos_attributes(SNUM(conn)) && !posix_open) {
    4395         749 :                 file_set_dosmode(conn,
    4396             :                                  smb_dname,
    4397             :                                  file_attributes | FILE_ATTRIBUTE_DIRECTORY,
    4398             :                                  parent_dir_fname,
    4399             :                                  true);
    4400             :         }
    4401             : 
    4402         749 :         if (lp_inherit_permissions(SNUM(conn))) {
    4403           0 :                 inherit_access_posix_acl(conn, parent_dir_fname->fsp,
    4404             :                                          smb_dname, mode);
    4405           0 :                 need_re_stat = true;
    4406             :         }
    4407             : 
    4408         749 :         if (!posix_open) {
    4409             :                 /*
    4410             :                  * Check if high bits should have been set,
    4411             :                  * then (if bits are missing): add them.
    4412             :                  * Consider bits automagically set by UNIX, i.e. SGID bit from parent
    4413             :                  * dir.
    4414             :                  */
    4415         749 :                 if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) &&
    4416           0 :                     (mode & ~smb_dname->st.st_ex_mode)) {
    4417           0 :                         SMB_VFS_FCHMOD(fsp,
    4418             :                                       (smb_dname->st.st_ex_mode |
    4419             :                                           (mode & ~smb_dname->st.st_ex_mode)));
    4420           0 :                         need_re_stat = true;
    4421             :                 }
    4422             :         }
    4423             : 
    4424             :         /* Change the owner if required. */
    4425         749 :         if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
    4426           0 :                 change_dir_owner_to_parent_fsp(parent_dir_fname->fsp,
    4427             :                                                fsp);
    4428           0 :                 need_re_stat = true;
    4429             :         }
    4430             : 
    4431         749 :         if (need_re_stat) {
    4432           0 :                 status = vfs_stat_fsp(fsp);
    4433           0 :                 if (!NT_STATUS_IS_OK(status)) {
    4434           0 :                         DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
    4435             :                           smb_fname_str_dbg(smb_dname), nt_errstr(status)));
    4436           0 :                         return status;
    4437             :                 }
    4438             :         }
    4439             : 
    4440         749 :         notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
    4441         749 :                      smb_dname->base_name);
    4442             : 
    4443         749 :         return NT_STATUS_OK;
    4444             : }
    4445             : 
    4446             : /****************************************************************************
    4447             :  Open a directory from an NT SMB call.
    4448             : ****************************************************************************/
    4449             : 
    4450       10908 : static NTSTATUS open_directory(connection_struct *conn,
    4451             :                                struct smb_request *req,
    4452             :                                uint32_t access_mask,
    4453             :                                uint32_t share_access,
    4454             :                                uint32_t create_disposition,
    4455             :                                uint32_t create_options,
    4456             :                                uint32_t file_attributes,
    4457             :                                struct smb_filename *parent_dir_fname,
    4458             :                                struct smb_filename *smb_fname_atname,
    4459             :                                int *pinfo,
    4460             :                                struct files_struct *fsp)
    4461             : {
    4462       10908 :         struct smb_filename *smb_dname = fsp->fsp_name;
    4463       10908 :         bool dir_existed = VALID_STAT(smb_dname->st);
    4464       10908 :         struct share_mode_lock *lck = NULL;
    4465             :         NTSTATUS status;
    4466             :         struct timespec mtimespec;
    4467       10908 :         int info = 0;
    4468             :         bool ok;
    4469             :         uint32_t need_fd_access;
    4470             : 
    4471       10908 :         if (is_ntfs_stream_smb_fname(smb_dname)) {
    4472           0 :                 DEBUG(2, ("open_directory: %s is a stream name!\n",
    4473             :                           smb_fname_str_dbg(smb_dname)));
    4474           0 :                 return NT_STATUS_NOT_A_DIRECTORY;
    4475             :         }
    4476             : 
    4477       10908 :         if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
    4478             :                 /* Ensure we have a directory attribute. */
    4479       10908 :                 file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
    4480             :         }
    4481             : 
    4482       10908 :         DBG_INFO("opening directory %s, access_mask = 0x%"PRIx32", "
    4483             :                  "share_access = 0x%"PRIx32" create_options = 0x%"PRIx32", "
    4484             :                  "create_disposition = 0x%"PRIx32", "
    4485             :                  "file_attributes = 0x%"PRIx32"\n",
    4486             :                  smb_fname_str_dbg(smb_dname),
    4487             :                  access_mask,
    4488             :                  share_access,
    4489             :                  create_options,
    4490             :                  create_disposition,
    4491             :                  file_attributes);
    4492             : 
    4493       10908 :         status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
    4494             :                                         smb_dname->fsp,
    4495             :                                         false,
    4496             :                                         access_mask,
    4497             :                                         &access_mask);
    4498       10908 :         if (!NT_STATUS_IS_OK(status)) {
    4499           0 :                 DBG_DEBUG("smbd_calculate_access_mask_fsp "
    4500             :                         "on file %s returned %s\n",
    4501             :                         smb_fname_str_dbg(smb_dname),
    4502             :                         nt_errstr(status));
    4503           0 :                 return status;
    4504             :         }
    4505             : 
    4506       11137 :         if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
    4507         231 :                         !security_token_has_privilege(get_current_nttok(conn),
    4508             :                                         SEC_PRIV_SECURITY)) {
    4509           0 :                 DEBUG(10, ("open_directory: open on %s "
    4510             :                         "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
    4511             :                         smb_fname_str_dbg(smb_dname)));
    4512           0 :                 return NT_STATUS_PRIVILEGE_NOT_HELD;
    4513             :         }
    4514             : 
    4515       10908 :         switch( create_disposition ) {
    4516       10096 :                 case FILE_OPEN:
    4517             : 
    4518       10096 :                         if (!dir_existed) {
    4519         277 :                                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    4520             :                         }
    4521             : 
    4522        9819 :                         info = FILE_WAS_OPENED;
    4523        9819 :                         break;
    4524             : 
    4525         786 :                 case FILE_CREATE:
    4526             : 
    4527             :                         /* If directory exists error. If directory doesn't
    4528             :                          * exist create. */
    4529             : 
    4530         786 :                         if (dir_existed) {
    4531          42 :                                 status = NT_STATUS_OBJECT_NAME_COLLISION;
    4532          42 :                                 DEBUG(2, ("open_directory: unable to create "
    4533             :                                           "%s. Error was %s\n",
    4534             :                                           smb_fname_str_dbg(smb_dname),
    4535             :                                           nt_errstr(status)));
    4536          42 :                                 return status;
    4537             :                         }
    4538             : 
    4539         744 :                         status = mkdir_internal(conn,
    4540             :                                                 parent_dir_fname,
    4541             :                                                 smb_fname_atname,
    4542             :                                                 smb_dname,
    4543             :                                                 file_attributes,
    4544             :                                                 fsp);
    4545             : 
    4546         744 :                         if (!NT_STATUS_IS_OK(status)) {
    4547           0 :                                 DEBUG(2, ("open_directory: unable to create "
    4548             :                                           "%s. Error was %s\n",
    4549             :                                           smb_fname_str_dbg(smb_dname),
    4550             :                                           nt_errstr(status)));
    4551           0 :                                 return status;
    4552             :                         }
    4553             : 
    4554         744 :                         info = FILE_WAS_CREATED;
    4555         744 :                         break;
    4556             : 
    4557          26 :                 case FILE_OPEN_IF:
    4558             :                         /*
    4559             :                          * If directory exists open. If directory doesn't
    4560             :                          * exist create.
    4561             :                          */
    4562             : 
    4563          26 :                         if (dir_existed) {
    4564          20 :                                 status = NT_STATUS_OK;
    4565          20 :                                 info = FILE_WAS_OPENED;
    4566             :                         } else {
    4567           6 :                                 status = mkdir_internal(conn,
    4568             :                                                         parent_dir_fname,
    4569             :                                                         smb_fname_atname,
    4570             :                                                         smb_dname,
    4571             :                                                         file_attributes,
    4572             :                                                         fsp);
    4573             : 
    4574           6 :                                 if (NT_STATUS_IS_OK(status)) {
    4575           5 :                                         info = FILE_WAS_CREATED;
    4576             :                                 } else {
    4577             :                                         /* Cope with create race. */
    4578           1 :                                         if (!NT_STATUS_EQUAL(status,
    4579             :                                                         NT_STATUS_OBJECT_NAME_COLLISION)) {
    4580           0 :                                                 DEBUG(2, ("open_directory: unable to create "
    4581             :                                                         "%s. Error was %s\n",
    4582             :                                                         smb_fname_str_dbg(smb_dname),
    4583             :                                                         nt_errstr(status)));
    4584           0 :                                                 return status;
    4585             :                                         }
    4586             : 
    4587             :                                         /*
    4588             :                                          * If mkdir_internal() returned
    4589             :                                          * NT_STATUS_OBJECT_NAME_COLLISION
    4590             :                                          * we still must lstat the path.
    4591             :                                          */
    4592             : 
    4593           1 :                                         if (SMB_VFS_LSTAT(conn, smb_dname)
    4594             :                                                         == -1) {
    4595           0 :                                                 DEBUG(2, ("Could not stat "
    4596             :                                                         "directory '%s' just "
    4597             :                                                         "opened: %s\n",
    4598             :                                                         smb_fname_str_dbg(
    4599             :                                                                 smb_dname),
    4600             :                                                         strerror(errno)));
    4601           0 :                                                 return map_nt_error_from_unix(
    4602           0 :                                                                 errno);
    4603             :                                         }
    4604             : 
    4605           1 :                                         info = FILE_WAS_OPENED;
    4606             :                                 }
    4607             :                         }
    4608             : 
    4609          26 :                         break;
    4610             : 
    4611           0 :                 case FILE_SUPERSEDE:
    4612             :                 case FILE_OVERWRITE:
    4613             :                 case FILE_OVERWRITE_IF:
    4614             :                 default:
    4615           0 :                         DEBUG(5,("open_directory: invalid create_disposition "
    4616             :                                  "0x%x for directory %s\n",
    4617             :                                  (unsigned int)create_disposition,
    4618             :                                  smb_fname_str_dbg(smb_dname)));
    4619           0 :                         return NT_STATUS_INVALID_PARAMETER;
    4620             :         }
    4621             : 
    4622       10589 :         if(!S_ISDIR(smb_dname->st.st_ex_mode)) {
    4623         367 :                 DEBUG(5,("open_directory: %s is not a directory !\n",
    4624             :                          smb_fname_str_dbg(smb_dname)));
    4625         367 :                 return NT_STATUS_NOT_A_DIRECTORY;
    4626             :         }
    4627             : 
    4628             :         /*
    4629             :          * Setup the files_struct for it.
    4630             :          */
    4631             : 
    4632       10222 :         fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
    4633       10222 :         fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
    4634       10222 :         fsp->file_pid = req ? req->smbpid : 0;
    4635       10222 :         fsp->fsp_flags.can_lock = false;
    4636       10222 :         fsp->fsp_flags.can_read = false;
    4637       10222 :         fsp->fsp_flags.can_write = false;
    4638             : 
    4639       10222 :         fh_set_private_options(fsp->fh, 0);
    4640             :         /*
    4641             :          * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
    4642             :          */
    4643       10222 :         fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
    4644       10222 :         fsp->print_file = NULL;
    4645       10222 :         fsp->fsp_flags.modified = false;
    4646       10222 :         fsp->oplock_type = NO_OPLOCK;
    4647       10222 :         fsp->sent_oplock_break = NO_BREAK_SENT;
    4648       10222 :         fsp->fsp_flags.is_directory = true;
    4649       10222 :         if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
    4650           0 :                 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
    4651             :         }
    4652             : 
    4653             :         /* Don't store old timestamps for directory
    4654             :            handles in the internal database. We don't
    4655             :            update them in there if new objects
    4656             :            are created in the directory. Currently
    4657             :            we only update timestamps on file writes.
    4658             :            See bug #9870.
    4659             :         */
    4660       10222 :         mtimespec = make_omit_timespec();
    4661             : 
    4662             :         /*
    4663             :          * Obviously for FILE_LIST_DIRECTORY we need to reopen to get an fd
    4664             :          * usable for reading a directory. SMB2_FLUSH may be called on
    4665             :          * directories opened with FILE_ADD_FILE and FILE_ADD_SUBDIRECTORY so
    4666             :          * for those we need to reopen as well.
    4667             :          */
    4668       10222 :         need_fd_access =
    4669             :                 FILE_LIST_DIRECTORY |
    4670             :                 FILE_ADD_FILE |
    4671             :                 FILE_ADD_SUBDIRECTORY;
    4672             : 
    4673       10222 :         if (access_mask & need_fd_access) {
    4674        4005 :                 status = reopen_from_fsp(
    4675        2244 :                         fsp->conn->cwd_fsp,
    4676             :                         fsp->fsp_name,
    4677             :                         fsp,
    4678             :                         O_RDONLY | O_DIRECTORY,
    4679             :                         0,
    4680             :                         NULL);
    4681        2244 :                 if (!NT_STATUS_IS_OK(status)) {
    4682           4 :                         DBG_INFO("Could not open fd for [%s]: %s\n",
    4683             :                                  smb_fname_str_dbg(smb_dname),
    4684             :                                  nt_errstr(status));
    4685           4 :                         return status;
    4686             :                 }
    4687             :         }
    4688             : 
    4689       10218 :         status = vfs_stat_fsp(fsp);
    4690       10218 :         if (!NT_STATUS_IS_OK(status)) {
    4691           0 :                 fd_close(fsp);
    4692           0 :                 return status;
    4693             :         }
    4694             : 
    4695       10218 :         if(!S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
    4696           0 :                 DEBUG(5,("open_directory: %s is not a directory !\n",
    4697             :                          smb_fname_str_dbg(smb_dname)));
    4698           0 :                 fd_close(fsp);
    4699           0 :                 return NT_STATUS_NOT_A_DIRECTORY;
    4700             :         }
    4701             : 
    4702             :         /* Ensure there was no race condition.  We need to check
    4703             :          * dev/inode but not permissions, as these can change
    4704             :          * legitimately */
    4705       10218 :         if (!check_same_dev_ino(&smb_dname->st, &fsp->fsp_name->st)) {
    4706           0 :                 DEBUG(5,("open_directory: stat struct differs for "
    4707             :                         "directory %s.\n",
    4708             :                         smb_fname_str_dbg(smb_dname)));
    4709           0 :                 fd_close(fsp);
    4710           0 :                 return NT_STATUS_ACCESS_DENIED;
    4711             :         }
    4712             : 
    4713       10218 :         if (info == FILE_WAS_OPENED) {
    4714        9469 :                 status = smbd_check_access_rights_fsp(parent_dir_fname->fsp,
    4715             :                                                 fsp,
    4716             :                                                 false,
    4717             :                                                 access_mask);
    4718        9469 :                 if (!NT_STATUS_IS_OK(status)) {
    4719           0 :                         DBG_DEBUG("smbd_check_access_rights_fsp on "
    4720             :                                   "file %s failed with %s\n",
    4721             :                                   fsp_str_dbg(fsp),
    4722             :                                   nt_errstr(status));
    4723           0 :                         fd_close(fsp);
    4724           0 :                         return status;
    4725             :                 }
    4726             :         }
    4727             : 
    4728       10218 :         lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
    4729       10218 :                                   conn->connectpath, smb_dname,
    4730             :                                   &mtimespec);
    4731             : 
    4732       10218 :         if (lck == NULL) {
    4733           0 :                 DEBUG(0, ("open_directory: Could not get share mode lock for "
    4734             :                           "%s\n", smb_fname_str_dbg(smb_dname)));
    4735           0 :                 fd_close(fsp);
    4736           0 :                 return NT_STATUS_SHARING_VIOLATION;
    4737             :         }
    4738             : 
    4739       10218 :         if (has_delete_on_close(lck, fsp->name_hash)) {
    4740           0 :                 TALLOC_FREE(lck);
    4741           0 :                 fd_close(fsp);
    4742           0 :                 return NT_STATUS_DELETE_PENDING;
    4743             :         }
    4744             : 
    4745       10218 :         status = open_mode_check(conn, fsp->file_id, lck,
    4746             :                                  access_mask, share_access);
    4747             : 
    4748       10218 :         if (!NT_STATUS_IS_OK(status)) {
    4749           2 :                 TALLOC_FREE(lck);
    4750           2 :                 fd_close(fsp);
    4751           2 :                 return status;
    4752             :         }
    4753             : 
    4754       10216 :         share_mode_flags_restrict(lck, access_mask, share_access, 0);
    4755             : 
    4756       10216 :         ok = set_share_mode(
    4757             :                 lck,
    4758             :                 fsp,
    4759             :                 get_current_uid(conn),
    4760             :                 req ? req->mid : 0,
    4761             :                 NO_OPLOCK,
    4762             :                 NULL,
    4763             :                 share_access,
    4764             :                 fsp->access_mask);
    4765       10216 :         if (!ok) {
    4766           0 :                 TALLOC_FREE(lck);
    4767           0 :                 fd_close(fsp);
    4768           0 :                 return NT_STATUS_NO_MEMORY;
    4769             :         }
    4770             : 
    4771             :         /* For directories the delete on close bit at open time seems
    4772             :            always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
    4773       10216 :         if (create_options & FILE_DELETE_ON_CLOSE) {
    4774          12 :                 status = can_set_delete_on_close(fsp, 0);
    4775          12 :                 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
    4776           0 :                         del_share_mode(lck, fsp);
    4777           0 :                         TALLOC_FREE(lck);
    4778           0 :                         fd_close(fsp);
    4779           0 :                         return status;
    4780             :                 }
    4781             : 
    4782          12 :                 if (NT_STATUS_IS_OK(status)) {
    4783             :                         /* Note that here we set the *initial* delete on close flag,
    4784             :                            not the regular one. The magic gets handled in close. */
    4785          10 :                         fsp->fsp_flags.initial_delete_on_close = true;
    4786             :                 }
    4787             :         }
    4788             : 
    4789             :         {
    4790             :                 /*
    4791             :                  * Deal with other opens having a modified write time. Is this
    4792             :                  * possible for directories?
    4793             :                  */
    4794       10216 :                 struct timespec write_time = get_share_mode_write_time(lck);
    4795             : 
    4796       10216 :                 if (!is_omit_timespec(&write_time)) {
    4797           0 :                         update_stat_ex_mtime(&fsp->fsp_name->st, write_time);
    4798             :                 }
    4799             :         }
    4800             : 
    4801       10216 :         TALLOC_FREE(lck);
    4802             : 
    4803       10216 :         if (pinfo) {
    4804       10216 :                 *pinfo = info;
    4805             :         }
    4806             : 
    4807       10216 :         return NT_STATUS_OK;
    4808             : }
    4809             : 
    4810           0 : NTSTATUS create_directory(connection_struct *conn,
    4811             :                           struct smb_request *req,
    4812             :                           struct files_struct *dirfsp,
    4813             :                           struct smb_filename *smb_dname)
    4814             : {
    4815             :         NTSTATUS status;
    4816             :         files_struct *fsp;
    4817             : 
    4818           0 :         status = SMB_VFS_CREATE_FILE(
    4819             :                 conn,                                   /* conn */
    4820             :                 req,                                    /* req */
    4821             :                 dirfsp,                                 /* dirfsp */
    4822             :                 smb_dname,                              /* fname */
    4823             :                 FILE_READ_ATTRIBUTES,                   /* access_mask */
    4824             :                 FILE_SHARE_NONE,                        /* share_access */
    4825             :                 FILE_CREATE,                            /* create_disposition*/
    4826             :                 FILE_DIRECTORY_FILE,                    /* create_options */
    4827             :                 FILE_ATTRIBUTE_DIRECTORY,               /* file_attributes */
    4828             :                 0,                                      /* oplock_request */
    4829             :                 NULL,                                   /* lease */
    4830             :                 0,                                      /* allocation_size */
    4831             :                 0,                                      /* private_flags */
    4832             :                 NULL,                                   /* sd */
    4833             :                 NULL,                                   /* ea_list */
    4834             :                 &fsp,                                       /* result */
    4835             :                 NULL,                                   /* pinfo */
    4836             :                 NULL, NULL);                            /* create context */
    4837             : 
    4838           0 :         if (NT_STATUS_IS_OK(status)) {
    4839           0 :                 close_file_free(req, &fsp, NORMAL_CLOSE);
    4840             :         }
    4841             : 
    4842           0 :         return status;
    4843             : }
    4844             : 
    4845             : /****************************************************************************
    4846             :  Receive notification that one of our open files has been renamed by another
    4847             :  smbd process.
    4848             : ****************************************************************************/
    4849             : 
    4850           0 : void msg_file_was_renamed(struct messaging_context *msg_ctx,
    4851             :                           void *private_data,
    4852             :                           uint32_t msg_type,
    4853             :                           struct server_id src,
    4854             :                           DATA_BLOB *data)
    4855             : {
    4856           0 :         struct file_rename_message *msg = NULL;
    4857             :         enum ndr_err_code ndr_err;
    4858             :         files_struct *fsp;
    4859           0 :         struct smb_filename *smb_fname = NULL;
    4860           0 :         struct smbd_server_connection *sconn =
    4861           0 :                 talloc_get_type_abort(private_data,
    4862             :                 struct smbd_server_connection);
    4863             : 
    4864           0 :         msg = talloc(talloc_tos(), struct file_rename_message);
    4865           0 :         if (msg == NULL) {
    4866           0 :                 DBG_WARNING("talloc failed\n");
    4867           0 :                 return;
    4868             :         }
    4869             : 
    4870           0 :         ndr_err = ndr_pull_struct_blob_all(
    4871             :                 data,
    4872             :                 msg,
    4873             :                 msg,
    4874             :                 (ndr_pull_flags_fn_t)ndr_pull_file_rename_message);
    4875           0 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    4876           0 :                 DBG_DEBUG("ndr_pull_oplock_break_message failed: %s\n",
    4877             :                           ndr_errstr(ndr_err));
    4878           0 :                 goto out;
    4879             :         }
    4880           0 :         if (DEBUGLEVEL >= 10) {
    4881             :                 struct server_id_buf buf;
    4882           0 :                 DBG_DEBUG("Got rename message from %s\n",
    4883             :                           server_id_str_buf(src, &buf));
    4884           0 :                 NDR_PRINT_DEBUG(file_rename_message, msg);
    4885             :         }
    4886             : 
    4887             :         /* stream_name must always be NULL if there is no stream. */
    4888           0 :         if ((msg->stream_name != NULL) && (msg->stream_name[0] == '\0')) {
    4889           0 :                 msg->stream_name = NULL;
    4890             :         }
    4891             : 
    4892           0 :         smb_fname = synthetic_smb_fname(msg,
    4893             :                                         msg->base_name,
    4894             :                                         msg->stream_name,
    4895             :                                         NULL,
    4896             :                                         0,
    4897             :                                         0);
    4898           0 :         if (smb_fname == NULL) {
    4899           0 :                 DBG_DEBUG("synthetic_smb_fname failed\n");
    4900           0 :                 goto out;
    4901             :         }
    4902             : 
    4903           0 :         fsp = file_find_dif(sconn, msg->id, msg->share_file_id);
    4904           0 :         if (fsp == NULL) {
    4905           0 :                 DBG_DEBUG("fsp not found\n");
    4906           0 :                 goto out;
    4907             :         }
    4908             : 
    4909           0 :         if (strcmp(fsp->conn->connectpath, msg->servicepath) == 0) {
    4910             :                 SMB_STRUCT_STAT fsp_orig_sbuf;
    4911             :                 NTSTATUS status;
    4912           0 :                 DBG_DEBUG("renaming file %s from %s -> %s\n",
    4913             :                           fsp_fnum_dbg(fsp),
    4914             :                           fsp_str_dbg(fsp),
    4915             :                           smb_fname_str_dbg(smb_fname));
    4916             : 
    4917             :                 /*
    4918             :                  * The incoming smb_fname here has an
    4919             :                  * invalid stat struct from synthetic_smb_fname()
    4920             :                  * above.
    4921             :                  * Preserve the existing stat from the
    4922             :                  * open fsp after fsp_set_smb_fname()
    4923             :                  * overwrites with the invalid stat.
    4924             :                  *
    4925             :                  * (We could just copy this into
    4926             :                  * smb_fname->st, but keep this code
    4927             :                  * identical to the fix in rename_open_files()
    4928             :                  * for clarity.
    4929             :                  *
    4930             :                  * We will do an fstat before returning
    4931             :                  * any of this metadata to the client anyway.
    4932             :                  */
    4933           0 :                 fsp_orig_sbuf = fsp->fsp_name->st;
    4934           0 :                 status = fsp_set_smb_fname(fsp, smb_fname);
    4935           0 :                 if (!NT_STATUS_IS_OK(status)) {
    4936           0 :                         DBG_DEBUG("fsp_set_smb_fname failed: %s\n",
    4937             :                                   nt_errstr(status));
    4938             :                 }
    4939           0 :                 fsp->fsp_name->st = fsp_orig_sbuf;
    4940             :         } else {
    4941             :                 /* TODO. JRA. */
    4942             :                 /*
    4943             :                  * Now we have the complete path we can work out if
    4944             :                  * this is actually within this share and adjust
    4945             :                  * newname accordingly.
    4946             :                  */
    4947           0 :                 DBG_DEBUG("share mismatch (sharepath %s not sharepath %s) "
    4948             :                           "%s from %s -> %s\n",
    4949             :                           fsp->conn->connectpath,
    4950             :                           msg->servicepath,
    4951             :                           fsp_fnum_dbg(fsp),
    4952             :                           fsp_str_dbg(fsp),
    4953             :                           smb_fname_str_dbg(smb_fname));
    4954             :         }
    4955           0 :  out:
    4956           0 :         TALLOC_FREE(msg);
    4957             : }
    4958             : 
    4959             : /*
    4960             :  * If a main file is opened for delete, all streams need to be checked for
    4961             :  * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
    4962             :  * If that works, delete them all by setting the delete on close and close.
    4963             :  */
    4964             : 
    4965        1642 : static NTSTATUS open_streams_for_delete(connection_struct *conn,
    4966             :                                         const struct smb_filename *smb_fname)
    4967             : {
    4968        1642 :         struct stream_struct *stream_info = NULL;
    4969        1642 :         files_struct **streams = NULL;
    4970             :         int j;
    4971        1642 :         unsigned int i, num_streams = 0;
    4972        1642 :         TALLOC_CTX *frame = talloc_stackframe();
    4973        1642 :         const struct smb_filename *pathref = NULL;
    4974             :         NTSTATUS status;
    4975             : 
    4976        1642 :         if (smb_fname->fsp == NULL) {
    4977         315 :                 struct smb_filename *tmp = NULL;
    4978         492 :                 status = synthetic_pathref(frame,
    4979             :                                         conn->cwd_fsp,
    4980         315 :                                         smb_fname->base_name,
    4981             :                                         NULL,
    4982             :                                         NULL,
    4983         138 :                                         smb_fname->twrp,
    4984         138 :                                         smb_fname->flags,
    4985             :                                         &tmp);
    4986         315 :                 if (!NT_STATUS_IS_OK(status)) {
    4987         315 :                         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
    4988         315 :                             || NT_STATUS_EQUAL(status,
    4989             :                                        NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    4990         315 :                                 DBG_DEBUG("no streams around\n");
    4991         315 :                                 TALLOC_FREE(frame);
    4992         315 :                                 return NT_STATUS_OK;
    4993             :                         }
    4994           0 :                         DBG_DEBUG("synthetic_pathref failed: %s\n",
    4995             :                            nt_errstr(status));
    4996           0 :                         goto fail;
    4997             :                 }
    4998           0 :                 pathref = tmp;
    4999             :         } else {
    5000        1327 :                 pathref = smb_fname;
    5001             :         }
    5002        1327 :         status = vfs_fstreaminfo(pathref->fsp, talloc_tos(),
    5003             :                                 &num_streams, &stream_info);
    5004             : 
    5005        1327 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
    5006        1327 :             || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    5007           0 :                 DEBUG(10, ("no streams around\n"));
    5008           0 :                 TALLOC_FREE(frame);
    5009           0 :                 return NT_STATUS_OK;
    5010             :         }
    5011             : 
    5012        1327 :         if (!NT_STATUS_IS_OK(status)) {
    5013           0 :                 DEBUG(10, ("vfs_fstreaminfo failed: %s\n",
    5014             :                            nt_errstr(status)));
    5015           0 :                 goto fail;
    5016             :         }
    5017             : 
    5018        1327 :         DEBUG(10, ("open_streams_for_delete found %d streams\n",
    5019             :                    num_streams));
    5020             : 
    5021        1327 :         if (num_streams == 0) {
    5022         825 :                 TALLOC_FREE(frame);
    5023         825 :                 return NT_STATUS_OK;
    5024             :         }
    5025             : 
    5026         502 :         streams = talloc_array(talloc_tos(), files_struct *, num_streams);
    5027         502 :         if (streams == NULL) {
    5028           0 :                 DEBUG(0, ("talloc failed\n"));
    5029           0 :                 status = NT_STATUS_NO_MEMORY;
    5030           0 :                 goto fail;
    5031             :         }
    5032             : 
    5033        1012 :         for (i=0; i<num_streams; i++) {
    5034             :                 struct smb_filename *smb_fname_cp;
    5035             : 
    5036         510 :                 if (strequal(stream_info[i].name, "::$DATA")) {
    5037         494 :                         streams[i] = NULL;
    5038         494 :                         continue;
    5039             :                 }
    5040             : 
    5041          24 :                 smb_fname_cp = synthetic_smb_fname(talloc_tos(),
    5042          16 :                                         smb_fname->base_name,
    5043          16 :                                         stream_info[i].name,
    5044             :                                         NULL,
    5045           8 :                                         smb_fname->twrp,
    5046          16 :                                         (smb_fname->flags &
    5047             :                                                 ~SMB_FILENAME_POSIX_PATH));
    5048          16 :                 if (smb_fname_cp == NULL) {
    5049           0 :                         status = NT_STATUS_NO_MEMORY;
    5050           0 :                         goto fail;
    5051             :                 }
    5052             : 
    5053          16 :                 status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_cp);
    5054          16 :                 if (!NT_STATUS_IS_OK(status)) {
    5055           0 :                         DBG_DEBUG("Unable to open stream [%s]: %s\n",
    5056             :                                   smb_fname_str_dbg(smb_fname_cp),
    5057             :                                   nt_errstr(status));
    5058           0 :                         TALLOC_FREE(smb_fname_cp);
    5059           0 :                         break;
    5060             :                 }
    5061             : 
    5062          16 :                 status = SMB_VFS_CREATE_FILE(
    5063             :                          conn,                  /* conn */
    5064             :                          NULL,                  /* req */
    5065             :                          NULL,                  /* dirfsp */
    5066             :                          smb_fname_cp,          /* fname */
    5067             :                          DELETE_ACCESS,         /* access_mask */
    5068             :                          (FILE_SHARE_READ |     /* share_access */
    5069             :                              FILE_SHARE_WRITE | FILE_SHARE_DELETE),
    5070             :                          FILE_OPEN,             /* create_disposition*/
    5071             :                          0,                     /* create_options */
    5072             :                          FILE_ATTRIBUTE_NORMAL, /* file_attributes */
    5073             :                          0,                     /* oplock_request */
    5074             :                          NULL,                  /* lease */
    5075             :                          0,                     /* allocation_size */
    5076             :                          0,                     /* private_flags */
    5077             :                          NULL,                  /* sd */
    5078             :                          NULL,                  /* ea_list */
    5079             :                          &streams[i],               /* result */
    5080             :                          NULL,                  /* pinfo */
    5081             :                          NULL, NULL);           /* create context */
    5082             : 
    5083          16 :                 if (!NT_STATUS_IS_OK(status)) {
    5084           0 :                         DEBUG(10, ("Could not open stream %s: %s\n",
    5085             :                                    smb_fname_str_dbg(smb_fname_cp),
    5086             :                                    nt_errstr(status)));
    5087             : 
    5088           0 :                         TALLOC_FREE(smb_fname_cp);
    5089           0 :                         break;
    5090             :                 }
    5091          16 :                 TALLOC_FREE(smb_fname_cp);
    5092             :         }
    5093             : 
    5094             :         /*
    5095             :          * don't touch the variable "status" beyond this point :-)
    5096             :          */
    5097             : 
    5098        1012 :         for (j = i-1 ; j >= 0; j--) {
    5099         510 :                 if (streams[j] == NULL) {
    5100         494 :                         continue;
    5101             :                 }
    5102             : 
    5103          16 :                 DEBUG(10, ("Closing stream # %d, %s\n", j,
    5104             :                            fsp_str_dbg(streams[j])));
    5105          16 :                 close_file_free(NULL, &streams[j], NORMAL_CLOSE);
    5106             :         }
    5107             : 
    5108         502 :  fail:
    5109         502 :         TALLOC_FREE(frame);
    5110         502 :         return status;
    5111             : }
    5112             : 
    5113             : /*********************************************************************
    5114             :  Create a default ACL by inheriting from the parent. If no inheritance
    5115             :  from the parent available, don't set anything. This will leave the actual
    5116             :  permissions the new file or directory already got from the filesystem
    5117             :  as the NT ACL when read.
    5118             : *********************************************************************/
    5119             : 
    5120        1325 : static NTSTATUS inherit_new_acl(files_struct *dirfsp, files_struct *fsp)
    5121             : {
    5122        1325 :         TALLOC_CTX *frame = talloc_stackframe();
    5123        1325 :         struct security_descriptor *parent_desc = NULL;
    5124        1325 :         NTSTATUS status = NT_STATUS_OK;
    5125        1325 :         struct security_descriptor *psd = NULL;
    5126        1325 :         const struct dom_sid *owner_sid = NULL;
    5127        1325 :         const struct dom_sid *group_sid = NULL;
    5128        1325 :         uint32_t security_info_sent = (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL);
    5129        1325 :         struct security_token *token = fsp->conn->session_info->security_token;
    5130        1325 :         bool inherit_owner =
    5131        1325 :             (lp_inherit_owner(SNUM(fsp->conn)) == INHERIT_OWNER_WINDOWS_AND_UNIX);
    5132        1325 :         bool inheritable_components = false;
    5133        1325 :         bool try_builtin_administrators = false;
    5134        1325 :         const struct dom_sid *BA_U_sid = NULL;
    5135        1325 :         const struct dom_sid *BA_G_sid = NULL;
    5136        1325 :         bool try_system = false;
    5137        1325 :         const struct dom_sid *SY_U_sid = NULL;
    5138        1325 :         const struct dom_sid *SY_G_sid = NULL;
    5139        1325 :         size_t size = 0;
    5140             :         bool ok;
    5141             : 
    5142        1325 :         status = SMB_VFS_FGET_NT_ACL(dirfsp,
    5143             :                                 (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL),
    5144             :                                 frame,
    5145             :                                 &parent_desc);
    5146        1325 :         if (!NT_STATUS_IS_OK(status)) {
    5147           0 :                 TALLOC_FREE(frame);
    5148           0 :                 return status;
    5149             :         }
    5150             : 
    5151        1325 :         inheritable_components = sd_has_inheritable_components(parent_desc,
    5152        1325 :                                         fsp->fsp_flags.is_directory);
    5153             : 
    5154        1325 :         if (!inheritable_components && !inherit_owner) {
    5155           4 :                 TALLOC_FREE(frame);
    5156             :                 /* Nothing to inherit and not setting owner. */
    5157           4 :                 return NT_STATUS_OK;
    5158             :         }
    5159             : 
    5160             :         /* Create an inherited descriptor from the parent. */
    5161             : 
    5162        1321 :         if (DEBUGLEVEL >= 10) {
    5163           0 :                 DEBUG(10,("inherit_new_acl: parent acl for %s is:\n",
    5164             :                         fsp_str_dbg(fsp) ));
    5165           0 :                 NDR_PRINT_DEBUG(security_descriptor, parent_desc);
    5166             :         }
    5167             : 
    5168             :         /* Inherit from parent descriptor if "inherit owner" set. */
    5169        1321 :         if (inherit_owner) {
    5170           0 :                 owner_sid = parent_desc->owner_sid;
    5171           0 :                 group_sid = parent_desc->group_sid;
    5172             :         }
    5173             : 
    5174        1321 :         if (owner_sid == NULL) {
    5175        1321 :                 if (security_token_has_builtin_administrators(token)) {
    5176        1137 :                         try_builtin_administrators = true;
    5177         184 :                 } else if (security_token_is_system(token)) {
    5178           0 :                         try_builtin_administrators = true;
    5179           0 :                         try_system = true;
    5180             :                 }
    5181             :         }
    5182             : 
    5183        2491 :         if (group_sid == NULL &&
    5184        1321 :             token->num_sids == PRIMARY_GROUP_SID_INDEX)
    5185             :         {
    5186           0 :                 if (security_token_is_system(token)) {
    5187           0 :                         try_builtin_administrators = true;
    5188           0 :                         try_system = true;
    5189             :                 }
    5190             :         }
    5191             : 
    5192        1321 :         if (try_builtin_administrators) {
    5193        1137 :                 struct unixid ids = { .id = 0 };
    5194             : 
    5195        1137 :                 ok = sids_to_unixids(&global_sid_Builtin_Administrators, 1, &ids);
    5196        1137 :                 if (ok) {
    5197        1137 :                         switch (ids.type) {
    5198         990 :                         case ID_TYPE_BOTH:
    5199         990 :                                 BA_U_sid = &global_sid_Builtin_Administrators;
    5200         990 :                                 BA_G_sid = &global_sid_Builtin_Administrators;
    5201         990 :                                 break;
    5202           0 :                         case ID_TYPE_UID:
    5203           0 :                                 BA_U_sid = &global_sid_Builtin_Administrators;
    5204           0 :                                 break;
    5205         147 :                         case ID_TYPE_GID:
    5206         147 :                                 BA_G_sid = &global_sid_Builtin_Administrators;
    5207         147 :                                 break;
    5208           0 :                         default:
    5209           0 :                                 break;
    5210             :                         }
    5211           0 :                 }
    5212             :         }
    5213             : 
    5214        1321 :         if (try_system) {
    5215           0 :                 struct unixid ids = { .id = 0 };
    5216             : 
    5217           0 :                 ok = sids_to_unixids(&global_sid_System, 1, &ids);
    5218           0 :                 if (ok) {
    5219           0 :                         switch (ids.type) {
    5220           0 :                         case ID_TYPE_BOTH:
    5221           0 :                                 SY_U_sid = &global_sid_System;
    5222           0 :                                 SY_G_sid = &global_sid_System;
    5223           0 :                                 break;
    5224           0 :                         case ID_TYPE_UID:
    5225           0 :                                 SY_U_sid = &global_sid_System;
    5226           0 :                                 break;
    5227           0 :                         case ID_TYPE_GID:
    5228           0 :                                 SY_G_sid = &global_sid_System;
    5229           0 :                                 break;
    5230           0 :                         default:
    5231           0 :                                 break;
    5232             :                         }
    5233           0 :                 }
    5234             :         }
    5235             : 
    5236        1321 :         if (owner_sid == NULL) {
    5237        1321 :                 owner_sid = BA_U_sid;
    5238             :         }
    5239             : 
    5240        1321 :         if (owner_sid == NULL) {
    5241         331 :                 owner_sid = SY_U_sid;
    5242             :         }
    5243             : 
    5244        1321 :         if (group_sid == NULL) {
    5245        1321 :                 group_sid = SY_G_sid;
    5246             :         }
    5247             : 
    5248        1321 :         if (try_system && group_sid == NULL) {
    5249           0 :                 group_sid = BA_G_sid;
    5250             :         }
    5251             : 
    5252        1321 :         if (owner_sid == NULL) {
    5253         331 :                 owner_sid = &token->sids[PRIMARY_USER_SID_INDEX];
    5254             :         }
    5255        1321 :         if (group_sid == NULL) {
    5256        1321 :                 if (token->num_sids == PRIMARY_GROUP_SID_INDEX) {
    5257           0 :                         group_sid = &token->sids[PRIMARY_USER_SID_INDEX];
    5258             :                 } else {
    5259        1321 :                         group_sid = &token->sids[PRIMARY_GROUP_SID_INDEX];
    5260             :                 }
    5261             :         }
    5262             : 
    5263        1321 :         status = se_create_child_secdesc(frame,
    5264             :                         &psd,
    5265             :                         &size,
    5266             :                         parent_desc,
    5267             :                         owner_sid,
    5268             :                         group_sid,
    5269        1321 :                         fsp->fsp_flags.is_directory);
    5270        1321 :         if (!NT_STATUS_IS_OK(status)) {
    5271           0 :                 TALLOC_FREE(frame);
    5272           0 :                 return status;
    5273             :         }
    5274             : 
    5275             :         /* If inheritable_components == false,
    5276             :            se_create_child_secdesc()
    5277             :            creates a security descriptor with a NULL dacl
    5278             :            entry, but with SEC_DESC_DACL_PRESENT. We need
    5279             :            to remove that flag. */
    5280             : 
    5281        1321 :         if (!inheritable_components) {
    5282           0 :                 security_info_sent &= ~SECINFO_DACL;
    5283           0 :                 psd->type &= ~SEC_DESC_DACL_PRESENT;
    5284             :         }
    5285             : 
    5286        1321 :         if (DEBUGLEVEL >= 10) {
    5287           0 :                 DEBUG(10,("inherit_new_acl: child acl for %s is:\n",
    5288             :                         fsp_str_dbg(fsp) ));
    5289           0 :                 NDR_PRINT_DEBUG(security_descriptor, psd);
    5290             :         }
    5291             : 
    5292        1321 :         if (inherit_owner) {
    5293             :                 /* We need to be root to force this. */
    5294           0 :                 become_root();
    5295             :         }
    5296        1321 :         status = SMB_VFS_FSET_NT_ACL(metadata_fsp(fsp),
    5297             :                         security_info_sent,
    5298             :                         psd);
    5299        1321 :         if (inherit_owner) {
    5300           0 :                 unbecome_root();
    5301             :         }
    5302        1321 :         TALLOC_FREE(frame);
    5303        1321 :         return status;
    5304             : }
    5305             : 
    5306             : /*
    5307             :  * If we already have a lease, it must match the new file id. [MS-SMB2]
    5308             :  * 3.3.5.9.8 speaks about INVALID_PARAMETER if an already used lease key is
    5309             :  * used for a different file name.
    5310             :  */
    5311             : 
    5312             : struct lease_match_state {
    5313             :         /* Input parameters. */
    5314             :         TALLOC_CTX *mem_ctx;
    5315             :         const char *servicepath;
    5316             :         const struct smb_filename *fname;
    5317             :         bool file_existed;
    5318             :         struct file_id id;
    5319             :         /* Return parameters. */
    5320             :         uint32_t num_file_ids;
    5321             :         struct file_id *ids;
    5322             :         NTSTATUS match_status;
    5323             : };
    5324             : 
    5325             : /*************************************************************
    5326             :  File doesn't exist but this lease key+guid is already in use.
    5327             : 
    5328             :  This is only allowable in the dynamic share case where the
    5329             :  service path must be different.
    5330             : 
    5331             :  There is a small race condition here in the multi-connection
    5332             :  case where a client sends two create calls on different connections,
    5333             :  where the file doesn't exist and one smbd creates the leases_db
    5334             :  entry first, but this will get fixed by the multichannel cleanup
    5335             :  when all identical client_guids get handled by a single smbd.
    5336             : **************************************************************/
    5337             : 
    5338           0 : static void lease_match_parser_new_file(
    5339             :         uint32_t num_files,
    5340             :         const struct leases_db_file *files,
    5341             :         struct lease_match_state *state)
    5342             : {
    5343             :         uint32_t i;
    5344             : 
    5345           0 :         for (i = 0; i < num_files; i++) {
    5346           0 :                 const struct leases_db_file *f = &files[i];
    5347           0 :                 if (strequal(state->servicepath, f->servicepath)) {
    5348           0 :                         state->match_status = NT_STATUS_INVALID_PARAMETER;
    5349           0 :                         return;
    5350             :                 }
    5351             :         }
    5352             : 
    5353             :         /* Dynamic share case. Break leases on all other files. */
    5354           0 :         state->match_status = leases_db_copy_file_ids(state->mem_ctx,
    5355             :                                         num_files,
    5356             :                                         files,
    5357             :                                         &state->ids);
    5358           0 :         if (!NT_STATUS_IS_OK(state->match_status)) {
    5359           0 :                 return;
    5360             :         }
    5361             : 
    5362           0 :         state->num_file_ids = num_files;
    5363           0 :         state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
    5364           0 :         return;
    5365             : }
    5366             : 
    5367           0 : static void lease_match_parser(
    5368             :         uint32_t num_files,
    5369             :         const struct leases_db_file *files,
    5370             :         void *private_data)
    5371             : {
    5372           0 :         struct lease_match_state *state =
    5373             :                 (struct lease_match_state *)private_data;
    5374             :         uint32_t i;
    5375             : 
    5376           0 :         if (!state->file_existed) {
    5377             :                 /*
    5378             :                  * Deal with name mismatch or
    5379             :                  * possible dynamic share case separately
    5380             :                  * to make code clearer.
    5381             :                  */
    5382           0 :                 lease_match_parser_new_file(num_files,
    5383             :                                                 files,
    5384             :                                                 state);
    5385           0 :                 return;
    5386             :         }
    5387             : 
    5388             :         /* File existed. */
    5389           0 :         state->match_status = NT_STATUS_OK;
    5390             : 
    5391           0 :         for (i = 0; i < num_files; i++) {
    5392           0 :                 const struct leases_db_file *f = &files[i];
    5393             : 
    5394             :                 /* Everything should be the same. */
    5395           0 :                 if (!file_id_equal(&state->id, &f->id)) {
    5396             :                         /*
    5397             :                          * The client asked for a lease on a
    5398             :                          * file that doesn't match the file_id
    5399             :                          * in the database.
    5400             :                          *
    5401             :                          * Maybe this is a dynamic share, i.e.
    5402             :                          * a share where the servicepath is
    5403             :                          * different for different users (e.g.
    5404             :                          * the [HOMES] share.
    5405             :                          *
    5406             :                          * If the servicepath is different, but the requested
    5407             :                          * file name + stream name is the same then this is
    5408             :                          * a dynamic share, the client is using the same share
    5409             :                          * name and doesn't know that the underlying servicepath
    5410             :                          * is different. It was expecting a lease on the
    5411             :                          * same file. Return NT_STATUS_OPLOCK_NOT_GRANTED
    5412             :                          * to break leases
    5413             :                          *
    5414             :                          * Otherwise the client has messed up, or is
    5415             :                          * testing our error codes, so return
    5416             :                          * NT_STATUS_INVALID_PARAMETER.
    5417             :                          */
    5418           0 :                         if (!strequal(f->servicepath, state->servicepath) &&
    5419           0 :                             strequal(f->base_name, state->fname->base_name) &&
    5420           0 :                             strequal(f->stream_name, state->fname->stream_name))
    5421           0 :                         {
    5422             :                                 /*
    5423             :                                  * Name is the same but servicepath is
    5424             :                                  * different, dynamic share. Break leases.
    5425             :                                  */
    5426           0 :                                 state->match_status =
    5427             :                                         NT_STATUS_OPLOCK_NOT_GRANTED;
    5428             :                         } else {
    5429           0 :                                 state->match_status =
    5430             :                                         NT_STATUS_INVALID_PARAMETER;
    5431             :                         }
    5432           0 :                         break;
    5433             :                 }
    5434           0 :                 if (!strequal(f->servicepath, state->servicepath)) {
    5435           0 :                         state->match_status = NT_STATUS_INVALID_PARAMETER;
    5436           0 :                         break;
    5437             :                 }
    5438           0 :                 if (!strequal(f->base_name, state->fname->base_name)) {
    5439           0 :                         state->match_status = NT_STATUS_INVALID_PARAMETER;
    5440           0 :                         break;
    5441             :                 }
    5442           0 :                 if (!strequal(f->stream_name, state->fname->stream_name)) {
    5443           0 :                         state->match_status = NT_STATUS_INVALID_PARAMETER;
    5444           0 :                         break;
    5445             :                 }
    5446             :         }
    5447             : 
    5448           0 :         if (NT_STATUS_IS_OK(state->match_status)) {
    5449             :                 /*
    5450             :                  * Common case - just opening another handle on a
    5451             :                  * file on a non-dynamic share.
    5452             :                  */
    5453           0 :                 return;
    5454             :         }
    5455             : 
    5456           0 :         if (NT_STATUS_EQUAL(state->match_status, NT_STATUS_INVALID_PARAMETER)) {
    5457             :                 /* Mismatched path. Error back to client. */
    5458           0 :                 return;
    5459             :         }
    5460             : 
    5461             :         /*
    5462             :          * File id mismatch. Dynamic share case NT_STATUS_OPLOCK_NOT_GRANTED.
    5463             :          * Don't allow leases.
    5464             :          */
    5465             : 
    5466           0 :         state->match_status = leases_db_copy_file_ids(state->mem_ctx,
    5467             :                                         num_files,
    5468             :                                         files,
    5469             :                                         &state->ids);
    5470           0 :         if (!NT_STATUS_IS_OK(state->match_status)) {
    5471           0 :                 return;
    5472             :         }
    5473             : 
    5474           0 :         state->num_file_ids = num_files;
    5475           0 :         state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
    5476           0 :         return;
    5477             : }
    5478             : 
    5479             : struct lease_match_break_state {
    5480             :         struct messaging_context *msg_ctx;
    5481             :         const struct smb2_lease_key *lease_key;
    5482             :         struct file_id id;
    5483             : 
    5484             :         bool found_lease;
    5485             :         uint16_t version;
    5486             :         uint16_t epoch;
    5487             : };
    5488             : 
    5489           0 : static bool lease_match_break_fn(
    5490             :         struct share_mode_entry *e,
    5491             :         void *private_data)
    5492             : {
    5493           0 :         struct lease_match_break_state *state = private_data;
    5494             :         bool stale, equal;
    5495           0 :         uint32_t e_lease_type = SMB2_LEASE_NONE;
    5496             :         NTSTATUS status;
    5497             : 
    5498           0 :         stale = share_entry_stale_pid(e);
    5499           0 :         if (stale) {
    5500           0 :                 return false;
    5501             :         }
    5502             : 
    5503           0 :         equal = smb2_lease_key_equal(&e->lease_key, state->lease_key);
    5504           0 :         if (!equal) {
    5505           0 :                 return false;
    5506             :         }
    5507             : 
    5508           0 :         status = leases_db_get(
    5509           0 :                 &e->client_guid,
    5510           0 :                 &e->lease_key,
    5511           0 :                 &state->id,
    5512             :                 &e_lease_type, /* current_state */
    5513             :                 NULL, /* breaking */
    5514             :                 NULL, /* breaking_to_requested */
    5515             :                 NULL, /* breaking_to_required */
    5516             :                 &state->version, /* lease_version */
    5517             :                 &state->epoch); /* epoch */
    5518           0 :         if (NT_STATUS_IS_OK(status)) {
    5519           0 :                 state->found_lease = true;
    5520             :         } else {
    5521           0 :                 DBG_WARNING("Could not find version/epoch: %s\n",
    5522             :                             nt_errstr(status));
    5523           0 :                 return false;
    5524             :         }
    5525             : 
    5526           0 :         if (e_lease_type == SMB2_LEASE_NONE) {
    5527           0 :                 return false;
    5528             :         }
    5529           0 :         send_break_message(state->msg_ctx, &state->id, e, SMB2_LEASE_NONE);
    5530             : 
    5531             :         /*
    5532             :          * Windows 7 and 8 lease clients are broken in that they will
    5533             :          * not respond to lease break requests whilst waiting for an
    5534             :          * outstanding open request on that lease handle on the same
    5535             :          * TCP connection, due to holding an internal inode lock.
    5536             :          *
    5537             :          * This means we can't reschedule ourselves here, but must
    5538             :          * return from the create.
    5539             :          *
    5540             :          * Work around:
    5541             :          *
    5542             :          * Send the breaks and then return SMB2_LEASE_NONE in the
    5543             :          * lease handle to cause them to acknowledge the lease
    5544             :          * break. Consultation with Microsoft engineering confirmed
    5545             :          * this approach is safe.
    5546             :          */
    5547             : 
    5548           0 :         return false;
    5549             : }
    5550             : 
    5551           0 : static NTSTATUS lease_match(connection_struct *conn,
    5552             :                             struct smb_request *req,
    5553             :                             const struct smb2_lease_key *lease_key,
    5554             :                             const char *servicepath,
    5555             :                             const struct smb_filename *fname,
    5556             :                             uint16_t *p_version,
    5557             :                             uint16_t *p_epoch)
    5558             : {
    5559           0 :         struct smbd_server_connection *sconn = req->sconn;
    5560           0 :         TALLOC_CTX *tos = talloc_tos();
    5561           0 :         struct lease_match_state state = {
    5562             :                 .mem_ctx = tos,
    5563             :                 .servicepath = servicepath,
    5564             :                 .fname = fname,
    5565             :                 .match_status = NT_STATUS_OK
    5566             :         };
    5567             :         uint32_t i;
    5568             :         NTSTATUS status;
    5569             : 
    5570           0 :         state.file_existed = VALID_STAT(fname->st);
    5571           0 :         if (state.file_existed) {
    5572           0 :                 state.id = vfs_file_id_from_sbuf(conn, &fname->st);
    5573             :         }
    5574             : 
    5575           0 :         status = leases_db_parse(&sconn->client->global->client_guid,
    5576             :                                  lease_key, lease_match_parser, &state);
    5577           0 :         if (!NT_STATUS_IS_OK(status)) {
    5578             :                 /*
    5579             :                  * Not found or error means okay: We can make the lease pass
    5580             :                  */
    5581           0 :                 return NT_STATUS_OK;
    5582             :         }
    5583           0 :         if (!NT_STATUS_EQUAL(state.match_status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
    5584             :                 /*
    5585             :                  * Anything but NT_STATUS_OPLOCK_NOT_GRANTED, let the caller
    5586             :                  * deal with it.
    5587             :                  */
    5588           0 :                 return state.match_status;
    5589             :         }
    5590             : 
    5591             :         /* We have to break all existing leases. */
    5592           0 :         for (i = 0; i < state.num_file_ids; i++) {
    5593           0 :                 struct lease_match_break_state break_state = {
    5594           0 :                         .msg_ctx = conn->sconn->msg_ctx,
    5595             :                         .lease_key = lease_key,
    5596             :                 };
    5597             :                 struct share_mode_lock *lck;
    5598             :                 bool ok;
    5599             : 
    5600           0 :                 if (file_id_equal(&state.ids[i], &state.id)) {
    5601             :                         /* Don't need to break our own file. */
    5602           0 :                         continue;
    5603             :                 }
    5604             : 
    5605           0 :                 break_state.id = state.ids[i];
    5606             : 
    5607           0 :                 lck = get_existing_share_mode_lock(
    5608             :                         talloc_tos(), break_state.id);
    5609           0 :                 if (lck == NULL) {
    5610             :                         /* Race condition - file already closed. */
    5611           0 :                         continue;
    5612             :                 }
    5613             : 
    5614           0 :                 ok = share_mode_forall_leases(
    5615             :                         lck, lease_match_break_fn, &break_state);
    5616           0 :                 if (!ok) {
    5617           0 :                         DBG_DEBUG("share_mode_forall_leases failed\n");
    5618           0 :                         continue;
    5619             :                 }
    5620             : 
    5621           0 :                 TALLOC_FREE(lck);
    5622             : 
    5623           0 :                 if (break_state.found_lease) {
    5624           0 :                         *p_version = break_state.version;
    5625           0 :                         *p_epoch = break_state.epoch;
    5626             :                 }
    5627             :         }
    5628             :         /*
    5629             :          * Ensure we don't grant anything more so we
    5630             :          * never upgrade.
    5631             :          */
    5632           0 :         return NT_STATUS_OPLOCK_NOT_GRANTED;
    5633             : }
    5634             : 
    5635             : /*
    5636             :  * Wrapper around open_file_ntcreate and open_directory
    5637             :  */
    5638             : 
    5639       12977 : static NTSTATUS create_file_unixpath(connection_struct *conn,
    5640             :                                      struct smb_request *req,
    5641             :                                      struct files_struct *dirfsp,
    5642             :                                      struct smb_filename *smb_fname,
    5643             :                                      uint32_t access_mask,
    5644             :                                      uint32_t share_access,
    5645             :                                      uint32_t create_disposition,
    5646             :                                      uint32_t create_options,
    5647             :                                      uint32_t file_attributes,
    5648             :                                      uint32_t oplock_request,
    5649             :                                      const struct smb2_lease *lease,
    5650             :                                      uint64_t allocation_size,
    5651             :                                      uint32_t private_flags,
    5652             :                                      struct security_descriptor *sd,
    5653             :                                      struct ea_list *ea_list,
    5654             : 
    5655             :                                      files_struct **result,
    5656             :                                      int *pinfo)
    5657             : {
    5658             :         struct smb2_lease none_lease;
    5659       12977 :         int info = FILE_WAS_OPENED;
    5660       12977 :         files_struct *base_fsp = NULL;
    5661       12977 :         files_struct *fsp = NULL;
    5662       12977 :         bool free_fsp_on_error = false;
    5663             :         NTSTATUS status;
    5664             :         int ret;
    5665       12977 :         struct smb_filename *parent_dir_fname = NULL;
    5666       12977 :         struct smb_filename *smb_fname_atname = NULL;
    5667             : 
    5668       12977 :         DBG_DEBUG("access_mask = 0x%"PRIx32" "
    5669             :                   "file_attributes = 0x%"PRIx32" "
    5670             :                   "share_access = 0x%"PRIx32" "
    5671             :                   "create_disposition = 0x%"PRIx32" "
    5672             :                   "create_options = 0x%"PRIx32" "
    5673             :                   "oplock_request = 0x%"PRIx32" "
    5674             :                   "private_flags = 0x%"PRIx32" "
    5675             :                   "ea_list = %p, "
    5676             :                   "sd = %p, "
    5677             :                   "fname = %s\n",
    5678             :                   access_mask,
    5679             :                   file_attributes,
    5680             :                   share_access,
    5681             :                   create_disposition,
    5682             :                   create_options,
    5683             :                   oplock_request,
    5684             :                   private_flags,
    5685             :                   ea_list,
    5686             :                   sd,
    5687             :                   smb_fname_str_dbg(smb_fname));
    5688             : 
    5689       12977 :         if (create_options & FILE_OPEN_BY_FILE_ID) {
    5690           0 :                 status = NT_STATUS_NOT_SUPPORTED;
    5691           0 :                 goto fail;
    5692             :         }
    5693             : 
    5694       12977 :         if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
    5695           1 :                 status = NT_STATUS_INVALID_PARAMETER;
    5696           1 :                 goto fail;
    5697             :         }
    5698             : 
    5699       12976 :         if (req == NULL) {
    5700          80 :                 oplock_request |= INTERNAL_OPEN_ONLY;
    5701             :         }
    5702             : 
    5703       12976 :         if (lease != NULL) {
    5704           0 :                 uint16_t epoch = lease->lease_epoch;
    5705           0 :                 uint16_t version = lease->lease_version;
    5706             : 
    5707           0 :                 if (req == NULL) {
    5708           0 :                         DBG_WARNING("Got lease on internal open\n");
    5709           0 :                         status = NT_STATUS_INTERNAL_ERROR;
    5710           0 :                         goto fail;
    5711             :                 }
    5712             : 
    5713           0 :                 status = lease_match(conn,
    5714             :                                 req,
    5715             :                                 &lease->lease_key,
    5716           0 :                                 conn->connectpath,
    5717             :                                 smb_fname,
    5718             :                                 &version,
    5719             :                                 &epoch);
    5720           0 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
    5721             :                         /* Dynamic share file. No leases and update epoch... */
    5722           0 :                         none_lease = *lease;
    5723           0 :                         none_lease.lease_state = SMB2_LEASE_NONE;
    5724           0 :                         none_lease.lease_epoch = epoch;
    5725           0 :                         none_lease.lease_version = version;
    5726           0 :                         lease = &none_lease;
    5727           0 :                 } else if (!NT_STATUS_IS_OK(status)) {
    5728           0 :                         goto fail;
    5729             :                 }
    5730             :         }
    5731             : 
    5732       12976 :         if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
    5733       12976 :             && (access_mask & DELETE_ACCESS)
    5734        1658 :             && !is_named_stream(smb_fname)) {
    5735             :                 /*
    5736             :                  * We can't open a file with DELETE access if any of the
    5737             :                  * streams is open without FILE_SHARE_DELETE
    5738             :                  */
    5739        1642 :                 status = open_streams_for_delete(conn, smb_fname);
    5740             : 
    5741        1642 :                 if (!NT_STATUS_IS_OK(status)) {
    5742           0 :                         goto fail;
    5743             :                 }
    5744             :         }
    5745             : 
    5746       12976 :         if (access_mask & SEC_FLAG_SYSTEM_SECURITY) {
    5747             :                 bool ok;
    5748             : 
    5749         298 :                 ok = security_token_has_privilege(get_current_nttok(conn),
    5750             :                                                   SEC_PRIV_SECURITY);
    5751         298 :                 if (!ok) {
    5752           0 :                         DBG_DEBUG("open on %s failed - "
    5753             :                                 "SEC_FLAG_SYSTEM_SECURITY denied.\n",
    5754             :                                 smb_fname_str_dbg(smb_fname));
    5755           0 :                         status = NT_STATUS_PRIVILEGE_NOT_HELD;
    5756           0 :                         goto fail;
    5757             :                 }
    5758             : 
    5759         298 :                 if (conn->sconn->using_smb2 &&
    5760             :                     (access_mask == SEC_FLAG_SYSTEM_SECURITY))
    5761             :                 {
    5762             :                         /*
    5763             :                          * No other bits set. Windows SMB2 refuses this.
    5764             :                          * See smbtorture3 SMB2-SACL test.
    5765             :                          *
    5766             :                          * Note this is an SMB2-only behavior,
    5767             :                          * smbtorture3 SMB1-SYSTEM-SECURITY already tests
    5768             :                          * that SMB1 allows this.
    5769             :                          */
    5770           0 :                         status = NT_STATUS_ACCESS_DENIED;
    5771           0 :                         goto fail;
    5772             :                 }
    5773             :         }
    5774             : 
    5775             :         /*
    5776             :          * Files or directories can't be opened DELETE_ON_CLOSE without
    5777             :          * delete access.
    5778             :          * BUG: https://bugzilla.samba.org/show_bug.cgi?id=13358
    5779             :          */
    5780       12976 :         if (create_options & FILE_DELETE_ON_CLOSE) {
    5781         742 :                 if ((access_mask & DELETE_ACCESS) == 0) {
    5782           0 :                         status = NT_STATUS_INVALID_PARAMETER;
    5783           0 :                         goto fail;
    5784             :                 }
    5785             :         }
    5786             : 
    5787       12976 :         if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
    5788       12976 :             && is_named_stream(smb_fname))
    5789             :         {
    5790             :                 uint32_t base_create_disposition;
    5791          64 :                 struct smb_filename *smb_fname_base = NULL;
    5792             :                 uint32_t base_privflags;
    5793             : 
    5794          64 :                 if (create_options & FILE_DIRECTORY_FILE) {
    5795           0 :                         DBG_DEBUG("Can't open a stream as directory\n");
    5796           0 :                         status = NT_STATUS_NOT_A_DIRECTORY;
    5797           0 :                         goto fail;
    5798             :                 }
    5799             : 
    5800          64 :                 switch (create_disposition) {
    5801          40 :                 case FILE_OPEN:
    5802          40 :                         base_create_disposition = FILE_OPEN;
    5803          40 :                         break;
    5804          24 :                 default:
    5805          24 :                         base_create_disposition = FILE_OPEN_IF;
    5806          24 :                         break;
    5807             :                 }
    5808             : 
    5809          64 :                 smb_fname_base = cp_smb_filename_nostream(
    5810             :                         talloc_tos(), smb_fname);
    5811             : 
    5812          64 :                 if (smb_fname_base == NULL) {
    5813           0 :                         status = NT_STATUS_NO_MEMORY;
    5814           0 :                         goto fail;
    5815             :                 }
    5816             : 
    5817             :                 /*
    5818             :                  * We may be creating the basefile as part of creating the
    5819             :                  * stream, so it's legal if the basefile doesn't exist at this
    5820             :                  * point, the create_file_unixpath() below will create it. But
    5821             :                  * if the basefile exists we want a handle so we can fstat() it.
    5822             :                  */
    5823             : 
    5824          64 :                 ret = vfs_stat(conn, smb_fname_base);
    5825          64 :                 if (ret == -1 && errno != ENOENT) {
    5826           0 :                         status = map_nt_error_from_unix(errno);
    5827           0 :                         TALLOC_FREE(smb_fname_base);
    5828           0 :                         goto fail;
    5829             :                 }
    5830          64 :                 if (ret == 0) {
    5831          56 :                         status = openat_pathref_fsp(conn->cwd_fsp,
    5832             :                                                     smb_fname_base);
    5833          56 :                         if (!NT_STATUS_IS_OK(status)) {
    5834           0 :                                 DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n",
    5835             :                                         smb_fname_str_dbg(smb_fname_base),
    5836             :                                         nt_errstr(status));
    5837           0 :                                 TALLOC_FREE(smb_fname_base);
    5838           0 :                                 goto fail;
    5839             :                         }
    5840             : 
    5841             :                         /*
    5842             :                          * https://bugzilla.samba.org/show_bug.cgi?id=10229
    5843             :                          * We need to check if the requested access mask
    5844             :                          * could be used to open the underlying file (if
    5845             :                          * it existed), as we're passing in zero for the
    5846             :                          * access mask to the base filename.
    5847             :                          */
    5848          56 :                         status = check_base_file_access(smb_fname_base->fsp,
    5849             :                                                         access_mask);
    5850             : 
    5851          56 :                         if (!NT_STATUS_IS_OK(status)) {
    5852           0 :                                 DEBUG(10, ("Permission check "
    5853             :                                         "for base %s failed: "
    5854             :                                         "%s\n", smb_fname->base_name,
    5855             :                                         nt_errstr(status)));
    5856           0 :                                 TALLOC_FREE(smb_fname_base);
    5857           0 :                                 goto fail;
    5858             :                         }
    5859             :                 }
    5860             : 
    5861          64 :                 base_privflags = NTCREATEX_FLAG_STREAM_BASEOPEN;
    5862             : 
    5863             :                 /* Open the base file. */
    5864          64 :                 status = create_file_unixpath(conn,
    5865             :                                               NULL,
    5866             :                                               dirfsp,
    5867             :                                               smb_fname_base,
    5868             :                                               0,
    5869             :                                               FILE_SHARE_READ
    5870             :                                               | FILE_SHARE_WRITE
    5871             :                                               | FILE_SHARE_DELETE,
    5872             :                                               base_create_disposition,
    5873             :                                               0,
    5874             :                                               0,
    5875             :                                               0,
    5876             :                                               NULL,
    5877             :                                               0,
    5878             :                                               base_privflags,
    5879             :                                               NULL,
    5880             :                                               NULL,
    5881             :                                               &base_fsp,
    5882             :                                               NULL);
    5883          64 :                 TALLOC_FREE(smb_fname_base);
    5884             : 
    5885          64 :                 if (!NT_STATUS_IS_OK(status)) {
    5886           0 :                         DEBUG(10, ("create_file_unixpath for base %s failed: "
    5887             :                                    "%s\n", smb_fname->base_name,
    5888             :                                    nt_errstr(status)));
    5889           0 :                         goto fail;
    5890             :                 }
    5891             :         }
    5892             : 
    5893       12976 :         if (smb_fname->fsp != NULL) {
    5894             : 
    5895       11158 :                 fsp = smb_fname->fsp;
    5896             : 
    5897             :                 /*
    5898             :                  * We're about to use smb_fname->fsp for the fresh open.
    5899             :                  *
    5900             :                  * Every fsp passed in via smb_fname->fsp already
    5901             :                  * holds a fsp->fsp_name. If it is already this
    5902             :                  * fsp->fsp_name that we got passed in as our input
    5903             :                  * argument smb_fname, these two are assumed to have
    5904             :                  * the same lifetime: Every fsp hangs of "conn", and
    5905             :                  * fsp->fsp_name is its talloc child.
    5906             :                  */
    5907             : 
    5908       11158 :                 if (smb_fname != smb_fname->fsp->fsp_name) {
    5909             :                         /*
    5910             :                          * "smb_fname" is temporary in this case, but
    5911             :                          * the destructor of smb_fname would also tear
    5912             :                          * down the fsp we're about to use. Unlink
    5913             :                          * them from each other.
    5914             :                          */
    5915       11158 :                         smb_fname_fsp_unlink(smb_fname);
    5916             : 
    5917             :                         /*
    5918             :                          * "fsp" is ours now
    5919             :                          */
    5920       11158 :                         free_fsp_on_error = true;
    5921             :                 }
    5922             : 
    5923       11158 :                 status = fsp_bind_smb(fsp, req);
    5924       11158 :                 if (!NT_STATUS_IS_OK(status)) {
    5925           0 :                         goto fail;
    5926             :                 }
    5927             : 
    5928       11158 :                 if (fsp_is_alternate_stream(fsp)) {
    5929          46 :                         struct files_struct *tmp_base_fsp = fsp->base_fsp;
    5930             : 
    5931          46 :                         fsp_set_base_fsp(fsp, NULL);
    5932             : 
    5933          46 :                         fd_close(tmp_base_fsp);
    5934          46 :                         file_free(NULL, tmp_base_fsp);
    5935             :                 }
    5936             :         } else {
    5937             :                 /*
    5938             :                  * No fsp passed in that we can use, create one
    5939             :                  */
    5940        1818 :                 status = file_new(req, conn, &fsp);
    5941        1818 :                 if(!NT_STATUS_IS_OK(status)) {
    5942           0 :                         goto fail;
    5943             :                 }
    5944        1818 :                 free_fsp_on_error = true;
    5945             : 
    5946        1818 :                 status = fsp_set_smb_fname(fsp, smb_fname);
    5947        1818 :                 if (!NT_STATUS_IS_OK(status)) {
    5948           0 :                         goto fail;
    5949             :                 }
    5950             :         }
    5951             : 
    5952       12976 :         SMB_ASSERT(fsp->fsp_name->fsp != NULL);
    5953       12976 :         SMB_ASSERT(fsp->fsp_name->fsp == fsp);
    5954             : 
    5955       12976 :         if (base_fsp) {
    5956             :                 /*
    5957             :                  * We're opening the stream element of a
    5958             :                  * base_fsp we already opened. Set up the
    5959             :                  * base_fsp pointer.
    5960             :                  */
    5961          64 :                 fsp_set_base_fsp(fsp, base_fsp);
    5962             :         }
    5963             : 
    5964       12976 :         if (dirfsp != NULL) {
    5965       12944 :                 status = SMB_VFS_PARENT_PATHNAME(
    5966             :                         conn,
    5967             :                         talloc_tos(),
    5968             :                         smb_fname,
    5969             :                         &parent_dir_fname,
    5970             :                         &smb_fname_atname);
    5971       12944 :                 if (!NT_STATUS_IS_OK(status)) {
    5972           0 :                         goto fail;
    5973             :                 }
    5974             :         } else {
    5975             :                 /*
    5976             :                  * Get a pathref on the parent. We can re-use this for
    5977             :                  * multiple calls to check parent ACLs etc. to avoid
    5978             :                  * pathname calls.
    5979             :                  */
    5980          32 :                 status = parent_pathref(talloc_tos(),
    5981             :                                         conn->cwd_fsp,
    5982             :                                         smb_fname,
    5983             :                                         &parent_dir_fname,
    5984             :                                         &smb_fname_atname);
    5985          32 :                 if (!NT_STATUS_IS_OK(status)) {
    5986           0 :                         goto fail;
    5987             :                 }
    5988             : 
    5989          32 :                 dirfsp = parent_dir_fname->fsp;
    5990          32 :                 status = fsp_set_smb_fname(dirfsp, parent_dir_fname);
    5991          32 :                 if (!NT_STATUS_IS_OK(status)) {
    5992           0 :                         goto fail;
    5993             :                 }
    5994             :         }
    5995             : 
    5996             :         /*
    5997             :          * If it's a request for a directory open, deal with it separately.
    5998             :          */
    5999             : 
    6000       12976 :         if (create_options & FILE_DIRECTORY_FILE) {
    6001             : 
    6002        6464 :                 if (create_options & FILE_NON_DIRECTORY_FILE) {
    6003           0 :                         status = NT_STATUS_INVALID_PARAMETER;
    6004           0 :                         goto fail;
    6005             :                 }
    6006             : 
    6007             :                 /* Can't open a temp directory. IFS kit test. */
    6008       12108 :                 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
    6009        6464 :                      (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
    6010           0 :                         status = NT_STATUS_INVALID_PARAMETER;
    6011           0 :                         goto fail;
    6012             :                 }
    6013             : 
    6014             :                 /*
    6015             :                  * We will get a create directory here if the Win32
    6016             :                  * app specified a security descriptor in the
    6017             :                  * CreateDirectory() call.
    6018             :                  */
    6019             : 
    6020        6464 :                 oplock_request = 0;
    6021        6464 :                 status = open_directory(conn,
    6022             :                                         req,
    6023             :                                         access_mask,
    6024             :                                         share_access,
    6025             :                                         create_disposition,
    6026             :                                         create_options,
    6027             :                                         file_attributes,
    6028             :                                         dirfsp->fsp_name,
    6029             :                                         smb_fname_atname,
    6030             :                                         &info,
    6031             :                                         fsp);
    6032             :         } else {
    6033             : 
    6034             :                 /*
    6035             :                  * Ordinary file case.
    6036             :                  */
    6037             : 
    6038        6512 :                 if (allocation_size) {
    6039          26 :                         fsp->initial_allocation_size = smb_roundup(fsp->conn,
    6040             :                                                         allocation_size);
    6041             :                 }
    6042             : 
    6043        6512 :                 status = open_file_ntcreate(conn,
    6044             :                                             req,
    6045             :                                             access_mask,
    6046             :                                             share_access,
    6047             :                                             create_disposition,
    6048             :                                             create_options,
    6049             :                                             file_attributes,
    6050             :                                             oplock_request,
    6051             :                                             lease,
    6052             :                                             private_flags,
    6053             :                                             dirfsp->fsp_name,
    6054             :                                             smb_fname_atname,
    6055             :                                             &info,
    6056             :                                             fsp);
    6057        6512 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
    6058             : 
    6059             :                         /* A stream open never opens a directory */
    6060             : 
    6061        4455 :                         if (base_fsp) {
    6062           0 :                                 status = NT_STATUS_FILE_IS_A_DIRECTORY;
    6063           0 :                                 goto fail;
    6064             :                         }
    6065             : 
    6066             :                         /*
    6067             :                          * Fail the open if it was explicitly a non-directory
    6068             :                          * file.
    6069             :                          */
    6070             : 
    6071        4455 :                         if (create_options & FILE_NON_DIRECTORY_FILE) {
    6072          11 :                                 status = NT_STATUS_FILE_IS_A_DIRECTORY;
    6073          11 :                                 goto fail;
    6074             :                         }
    6075             : 
    6076        4444 :                         oplock_request = 0;
    6077        4444 :                         status = open_directory(conn,
    6078             :                                                 req,
    6079             :                                                 access_mask,
    6080             :                                                 share_access,
    6081             :                                                 create_disposition,
    6082             :                                                 create_options,
    6083             :                                                 file_attributes,
    6084             :                                                 dirfsp->fsp_name,
    6085             :                                                 smb_fname_atname,
    6086             :                                                 &info,
    6087             :                                                 fsp);
    6088             :                 }
    6089             :         }
    6090             : 
    6091       12965 :         if (!NT_STATUS_IS_OK(status)) {
    6092         899 :                 goto fail;
    6093             :         }
    6094             : 
    6095       12066 :         fsp->fsp_flags.is_fsa = true;
    6096             : 
    6097       12067 :         if ((ea_list != NULL) &&
    6098           1 :             ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN))) {
    6099           1 :                 status = set_ea(conn, fsp, ea_list);
    6100           1 :                 if (!NT_STATUS_IS_OK(status)) {
    6101           0 :                         goto fail;
    6102             :                 }
    6103             :         }
    6104             : 
    6105       13626 :         if (!fsp->fsp_flags.is_directory &&
    6106        1850 :             S_ISDIR(fsp->fsp_name->st.st_ex_mode))
    6107             :         {
    6108           0 :                 status = NT_STATUS_ACCESS_DENIED;
    6109           0 :                 goto fail;
    6110             :         }
    6111             : 
    6112             :         /* Save the requested allocation size. */
    6113       12066 :         if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
    6114        2681 :                 if ((allocation_size > (uint64_t)fsp->fsp_name->st.st_ex_size)
    6115          20 :                     && !(fsp->fsp_flags.is_directory))
    6116             :                 {
    6117          19 :                         fsp->initial_allocation_size = smb_roundup(
    6118          19 :                                 fsp->conn, allocation_size);
    6119          38 :                         if (vfs_allocate_file_space(
    6120          19 :                                     fsp, fsp->initial_allocation_size) == -1) {
    6121           0 :                                 status = NT_STATUS_DISK_FULL;
    6122           0 :                                 goto fail;
    6123             :                         }
    6124             :                 } else {
    6125        2643 :                         fsp->initial_allocation_size = smb_roundup(
    6126        2643 :                                 fsp->conn, (uint64_t)fsp->fsp_name->st.st_ex_size);
    6127             :                 }
    6128             :         } else {
    6129       10642 :                 fsp->initial_allocation_size = 0;
    6130             :         }
    6131             : 
    6132       13420 :         if ((info == FILE_WAS_CREATED) &&
    6133        2544 :             lp_nt_acl_support(SNUM(conn)) &&
    6134        1354 :             !fsp_is_alternate_stream(fsp)) {
    6135        1336 :                 if (sd != NULL) {
    6136             :                         /*
    6137             :                          * According to the MS documentation, the only time the security
    6138             :                          * descriptor is applied to the opened file is iff we *created* the
    6139             :                          * file; an existing file stays the same.
    6140             :                          *
    6141             :                          * Also, it seems (from observation) that you can open the file with
    6142             :                          * any access mask but you can still write the sd. We need to override
    6143             :                          * the granted access before we call set_sd
    6144             :                          * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
    6145             :                          */
    6146             : 
    6147             :                         uint32_t sec_info_sent;
    6148           7 :                         uint32_t saved_access_mask = fsp->access_mask;
    6149             : 
    6150           7 :                         sec_info_sent = get_sec_info(sd);
    6151             : 
    6152           7 :                         fsp->access_mask = FILE_GENERIC_ALL;
    6153             : 
    6154           7 :                         if (sec_info_sent & (SECINFO_OWNER|
    6155             :                                                 SECINFO_GROUP|
    6156             :                                                 SECINFO_DACL|
    6157             :                                                 SECINFO_SACL)) {
    6158           6 :                                 status = set_sd(fsp, sd, sec_info_sent);
    6159             :                         }
    6160             : 
    6161           7 :                         fsp->access_mask = saved_access_mask;
    6162             : 
    6163           7 :                         if (!NT_STATUS_IS_OK(status)) {
    6164           0 :                                 goto fail;
    6165             :                         }
    6166        1329 :                 } else if (lp_inherit_acls(SNUM(conn))) {
    6167             :                         /* Inherit from parent. Errors here are not fatal. */
    6168        1325 :                         status = inherit_new_acl(dirfsp, fsp);
    6169        1325 :                         if (!NT_STATUS_IS_OK(status)) {
    6170           0 :                                 DEBUG(10,("inherit_new_acl: failed for %s with %s\n",
    6171             :                                         fsp_str_dbg(fsp),
    6172             :                                         nt_errstr(status) ));
    6173             :                         }
    6174             :                 }
    6175             :         }
    6176             : 
    6177       12066 :         if ((conn->fs_capabilities & FILE_FILE_COMPRESSION)
    6178           0 :          && (create_options & FILE_NO_COMPRESSION)
    6179           0 :          && (info == FILE_WAS_CREATED)) {
    6180           0 :                 status = SMB_VFS_SET_COMPRESSION(conn, fsp, fsp,
    6181             :                                                  COMPRESSION_FORMAT_NONE);
    6182           0 :                 if (!NT_STATUS_IS_OK(status)) {
    6183           0 :                         DEBUG(1, ("failed to disable compression: %s\n",
    6184             :                                   nt_errstr(status)));
    6185             :                 }
    6186             :         }
    6187             : 
    6188       12066 :         DEBUG(10, ("create_file_unixpath: info=%d\n", info));
    6189             : 
    6190       12066 :         *result = fsp;
    6191       12066 :         if (pinfo != NULL) {
    6192       12002 :                 *pinfo = info;
    6193             :         }
    6194             : 
    6195       12066 :         smb_fname->st = fsp->fsp_name->st;
    6196             : 
    6197       12066 :         TALLOC_FREE(parent_dir_fname);
    6198             : 
    6199       12066 :         return NT_STATUS_OK;
    6200             : 
    6201         911 :  fail:
    6202         911 :         DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
    6203             : 
    6204         911 :         if (fsp != NULL) {
    6205             :                 /*
    6206             :                  * The close_file below will close
    6207             :                  * fsp->base_fsp.
    6208             :                  */
    6209         910 :                 base_fsp = NULL;
    6210         910 :                 close_file_smb(req, fsp, ERROR_CLOSE);
    6211         910 :                 if (free_fsp_on_error) {
    6212         910 :                         file_free(req, fsp);
    6213         910 :                         fsp = NULL;
    6214             :                 }
    6215             :         }
    6216         911 :         if (base_fsp != NULL) {
    6217           0 :                 close_file_free(req, &base_fsp, ERROR_CLOSE);
    6218             :         }
    6219             : 
    6220         911 :         TALLOC_FREE(parent_dir_fname);
    6221             : 
    6222         911 :         return status;
    6223             : }
    6224             : 
    6225       12914 : NTSTATUS create_file_default(connection_struct *conn,
    6226             :                              struct smb_request *req,
    6227             :                              struct files_struct *dirfsp,
    6228             :                              struct smb_filename *smb_fname,
    6229             :                              uint32_t access_mask,
    6230             :                              uint32_t share_access,
    6231             :                              uint32_t create_disposition,
    6232             :                              uint32_t create_options,
    6233             :                              uint32_t file_attributes,
    6234             :                              uint32_t oplock_request,
    6235             :                              const struct smb2_lease *lease,
    6236             :                              uint64_t allocation_size,
    6237             :                              uint32_t private_flags,
    6238             :                              struct security_descriptor *sd,
    6239             :                              struct ea_list *ea_list,
    6240             :                              files_struct **result,
    6241             :                              int *pinfo,
    6242             :                              const struct smb2_create_blobs *in_context_blobs,
    6243             :                              struct smb2_create_blobs *out_context_blobs)
    6244             : {
    6245       12914 :         int info = FILE_WAS_OPENED;
    6246       12914 :         files_struct *fsp = NULL;
    6247             :         NTSTATUS status;
    6248       12914 :         bool stream_name = false;
    6249       12914 :         struct smb2_create_blob *posx = NULL;
    6250             : 
    6251       12914 :         DBG_DEBUG("create_file: access_mask = 0x%x "
    6252             :                   "file_attributes = 0x%x, share_access = 0x%x, "
    6253             :                   "create_disposition = 0x%x create_options = 0x%x "
    6254             :                   "oplock_request = 0x%x "
    6255             :                   "private_flags = 0x%x "
    6256             :                   "ea_list = %p, sd = %p, "
    6257             :                   "fname = %s\n",
    6258             :                   (unsigned int)access_mask,
    6259             :                   (unsigned int)file_attributes,
    6260             :                   (unsigned int)share_access,
    6261             :                   (unsigned int)create_disposition,
    6262             :                   (unsigned int)create_options,
    6263             :                   (unsigned int)oplock_request,
    6264             :                   (unsigned int)private_flags,
    6265             :                   ea_list,
    6266             :                   sd,
    6267             :                   smb_fname_str_dbg(smb_fname));
    6268             : 
    6269       12914 :         if (req != NULL) {
    6270             :                 /*
    6271             :                  * Remember the absolute time of the original request
    6272             :                  * with this mid. We'll use it later to see if this
    6273             :                  * has timed out.
    6274             :                  */
    6275       12898 :                 get_deferred_open_message_state(req, &req->request_time, NULL);
    6276             :         }
    6277             : 
    6278             :         /*
    6279             :          * Check to see if this is a mac fork of some kind.
    6280             :          */
    6281             : 
    6282       12914 :         stream_name = is_ntfs_stream_smb_fname(smb_fname);
    6283       12914 :         if (stream_name) {
    6284             :                 enum FAKE_FILE_TYPE fake_file_type;
    6285             : 
    6286          65 :                 fake_file_type = is_fake_file(smb_fname);
    6287             : 
    6288          65 :                 if (req != NULL && fake_file_type != FAKE_FILE_TYPE_NONE) {
    6289             : 
    6290             :                         /*
    6291             :                          * Here we go! support for changing the disk quotas
    6292             :                          * --metze
    6293             :                          *
    6294             :                          * We need to fake up to open this MAGIC QUOTA file
    6295             :                          * and return a valid FID.
    6296             :                          *
    6297             :                          * w2k close this file directly after openening xp
    6298             :                          * also tries a QUERY_FILE_INFO on the file and then
    6299             :                          * close it
    6300             :                          */
    6301           1 :                         status = open_fake_file(req, conn, req->vuid,
    6302             :                                                 fake_file_type, smb_fname,
    6303             :                                                 access_mask, &fsp);
    6304           1 :                         if (!NT_STATUS_IS_OK(status)) {
    6305           0 :                                 goto fail;
    6306             :                         }
    6307             : 
    6308           1 :                         ZERO_STRUCT(smb_fname->st);
    6309           1 :                         goto done;
    6310             :                 }
    6311             : 
    6312          64 :                 if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
    6313           0 :                         status = NT_STATUS_OBJECT_NAME_INVALID;
    6314           0 :                         goto fail;
    6315             :                 }
    6316             :         }
    6317             : 
    6318       12913 :         if (is_ntfs_default_stream_smb_fname(smb_fname)) {
    6319             :                 int ret;
    6320             :                 /* We have to handle this error here. */
    6321           0 :                 if (create_options & FILE_DIRECTORY_FILE) {
    6322           0 :                         status = NT_STATUS_NOT_A_DIRECTORY;
    6323           0 :                         goto fail;
    6324             :                 }
    6325           0 :                 ret = vfs_stat(conn, smb_fname);
    6326           0 :                 if (ret == 0 && VALID_STAT_OF_DIR(smb_fname->st)) {
    6327           0 :                         status = NT_STATUS_FILE_IS_A_DIRECTORY;
    6328           0 :                         goto fail;
    6329             :                 }
    6330             :         }
    6331             : 
    6332       12913 :         posx = smb2_create_blob_find(
    6333             :                 in_context_blobs, SMB2_CREATE_TAG_POSIX);
    6334       12913 :         if (posx != NULL) {
    6335           0 :                 uint32_t wire_mode_bits = 0;
    6336           0 :                 mode_t mode_bits = 0;
    6337           0 :                 SMB_STRUCT_STAT sbuf = { 0 };
    6338           0 :                 enum perm_type ptype =
    6339             :                         (create_options & FILE_DIRECTORY_FILE) ?
    6340           0 :                         PERM_NEW_DIR : PERM_NEW_FILE;
    6341             : 
    6342           0 :                 if (posx->data.length != 4) {
    6343           0 :                         status = NT_STATUS_INVALID_PARAMETER;
    6344           0 :                         goto fail;
    6345             :                 }
    6346             : 
    6347           0 :                 wire_mode_bits = IVAL(posx->data.data, 0);
    6348           0 :                 status = unix_perms_from_wire(
    6349             :                         conn, &sbuf, wire_mode_bits, ptype, &mode_bits);
    6350           0 :                 if (!NT_STATUS_IS_OK(status)) {
    6351           0 :                         goto fail;
    6352             :                 }
    6353             :                 /*
    6354             :                  * Remove type info from mode, leaving only the
    6355             :                  * permissions and setuid/gid bits.
    6356             :                  */
    6357           0 :                 mode_bits &= ~S_IFMT;
    6358             : 
    6359           0 :                 file_attributes = (FILE_FLAG_POSIX_SEMANTICS | mode_bits);
    6360             :         }
    6361             : 
    6362       12913 :         status = create_file_unixpath(conn,
    6363             :                                       req,
    6364             :                                       dirfsp,
    6365             :                                       smb_fname,
    6366             :                                       access_mask,
    6367             :                                       share_access,
    6368             :                                       create_disposition,
    6369             :                                       create_options,
    6370             :                                       file_attributes,
    6371             :                                       oplock_request,
    6372             :                                       lease,
    6373             :                                       allocation_size,
    6374             :                                       private_flags,
    6375             :                                       sd,
    6376             :                                       ea_list,
    6377             :                                       &fsp,
    6378             :                                       &info);
    6379       12913 :         if (!NT_STATUS_IS_OK(status)) {
    6380         911 :                 goto fail;
    6381             :         }
    6382             : 
    6383       22849 :  done:
    6384       12003 :         DEBUG(10, ("create_file: info=%d\n", info));
    6385             : 
    6386       12003 :         *result = fsp;
    6387       12003 :         if (pinfo != NULL) {
    6388       11987 :                 *pinfo = info;
    6389             :         }
    6390       12003 :         return NT_STATUS_OK;
    6391             : 
    6392         911 :  fail:
    6393         911 :         DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
    6394             : 
    6395         911 :         if (fsp != NULL) {
    6396           0 :                 close_file_free(req, &fsp, ERROR_CLOSE);
    6397             :         }
    6398         911 :         return status;
    6399             : }

Generated by: LCOV version 1.13