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

Generated by: LCOV version 1.14