LCOV - code coverage report
Current view: top level - source3/smbd - open.c (source / functions) Hit Total Coverage
Test: coverage report for master 6248eab5 Lines: 1829 2283 80.1 %
Date: 2021-08-25 13:27:56 Functions: 72 80 90.0 %

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

Generated by: LCOV version 1.13