LCOV - code coverage report
Current view: top level - source3/smbd - open.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 2036 2531 80.4 %
Date: 2024-05-31 13:13:24 Functions: 74 76 97.4 %

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

Generated by: LCOV version 1.14