LCOV - code coverage report
Current view: top level - source3/smbd - open.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 2043 2538 80.5 %
Date: 2024-04-21 15:09:00 Functions: 74 76 97.4 %

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

Generated by: LCOV version 1.14