LCOV - code coverage report
Current view: top level - source3/smbd - smb1_utils.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 13 60 21.7 %
Date: 2024-06-13 04:01:37 Functions: 1 3 33.3 %

          Line data    Source code
       1             : /*
       2             :  * Unix SMB/CIFS implementation.
       3             :  * Util functions valid in the SMB1 server
       4             :  *
       5             :  * Copyright (C) Volker Lendecke 2019
       6             :  * Copyright by the authors of the functions moved here eventually
       7             :  *
       8             :  * This program is free software; you can redistribute it and/or modify
       9             :  * it under the terms of the GNU General Public License as published by
      10             :  * the Free Software Foundation; either version 3 of the License, or
      11             :  * (at your option) any later version.
      12             :  *
      13             :  * This program is distributed in the hope that it will be useful,
      14             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :  * GNU General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU General Public License
      19             :  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             :  */
      21             : 
      22             : #include "includes.h"
      23             : #include "smbd/smbd.h"
      24             : #include "smbd/globals.h"
      25             : #include "libcli/security/security.h"
      26             : #include "lib/util/sys_rw_data.h"
      27             : #include "smbd/fd_handle.h"
      28             : 
      29             : /****************************************************************************
      30             :  Special FCB or DOS processing in the case of a sharing violation.
      31             :  Try and find a duplicated file handle.
      32             : ****************************************************************************/
      33             : 
      34           0 : struct files_struct *fcb_or_dos_open(
      35             :         struct smb_request *req,
      36             :         const struct smb_filename *smb_fname,
      37             :         uint32_t access_mask,
      38             :         uint32_t create_options,
      39             :         uint32_t private_flags)
      40             : {
      41           0 :         struct connection_struct *conn = req->conn;
      42           0 :         struct file_id id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
      43           0 :         struct files_struct *fsp = NULL, *new_fsp = NULL;
      44             :         NTSTATUS status;
      45             : 
      46           0 :         if ((private_flags &
      47             :              (NTCREATEX_FLAG_DENY_DOS|
      48             :               NTCREATEX_FLAG_DENY_FCB))
      49             :             == 0) {
      50           0 :                 return NULL;
      51             :         }
      52             : 
      53           0 :         for(fsp = file_find_di_first(conn->sconn, id, true);
      54           0 :             fsp != NULL;
      55           0 :             fsp = file_find_di_next(fsp, true)) {
      56             : 
      57           0 :                 DBG_DEBUG("Checking file %s, fd = %d, vuid = %"PRIu64", "
      58             :                           "file_pid = %"PRIu16", "
      59             :                           "private_options = 0x%"PRIx32", "
      60             :                           "access_mask = 0x%"PRIx32"\n",
      61             :                           fsp_str_dbg(fsp),
      62             :                           fsp_get_pathref_fd(fsp),
      63             :                           fsp->vuid,
      64             :                           fsp->file_pid,
      65             :                           fh_get_private_options(fsp->fh),
      66             :                           fsp->access_mask);
      67             : 
      68           0 :                 if (fsp_get_pathref_fd(fsp) != -1 &&
      69           0 :                     fsp->vuid == req->vuid &&
      70           0 :                     fsp->file_pid == req->smbpid &&
      71           0 :                     (fh_get_private_options(fsp->fh) &
      72             :                      (NTCREATEX_FLAG_DENY_DOS |
      73           0 :                       NTCREATEX_FLAG_DENY_FCB)) &&
      74           0 :                     (fsp->access_mask & FILE_WRITE_DATA) &&
      75           0 :                     strequal(fsp->fsp_name->base_name, smb_fname->base_name) &&
      76           0 :                     strequal(fsp->fsp_name->stream_name,
      77           0 :                              smb_fname->stream_name)) {
      78           0 :                         DBG_DEBUG("file match\n");
      79           0 :                         break;
      80             :                 }
      81             :         }
      82             : 
      83           0 :         if (fsp == NULL) {
      84           0 :                 return NULL;
      85             :         }
      86             : 
      87             :         /* quite an insane set of semantics ... */
      88           0 :         if (is_executable(smb_fname->base_name) &&
      89           0 :             (fh_get_private_options(fsp->fh) & NTCREATEX_FLAG_DENY_DOS)) {
      90           0 :                 DBG_DEBUG("file fail due to is_executable.\n");
      91           0 :                 return NULL;
      92             :         }
      93             : 
      94           0 :         status = file_new(req, conn, &new_fsp);
      95           0 :         if (!NT_STATUS_IS_OK(status)) {
      96           0 :                 DBG_DEBUG("file_new failed: %s\n", nt_errstr(status));
      97           0 :                 return NULL;
      98             :         }
      99             : 
     100           0 :         status = dup_file_fsp(fsp, access_mask, new_fsp);
     101             : 
     102           0 :         if (!NT_STATUS_IS_OK(status)) {
     103           0 :                 DBG_DEBUG("dup_file_fsp failed: %s\n", nt_errstr(status));
     104           0 :                 file_free(req, new_fsp);
     105           0 :                 return NULL;
     106             :         }
     107             : 
     108           0 :         return new_fsp;
     109             : }
     110             : 
     111             : /****************************************************************************
     112             :  Send a keepalive packet (rfc1002).
     113             : ****************************************************************************/
     114             : 
     115           0 : bool send_keepalive(int client)
     116             : {
     117             :         unsigned char buf[4];
     118             : 
     119           0 :         buf[0] = NBSSkeepalive;
     120           0 :         buf[1] = buf[2] = buf[3] = 0;
     121             : 
     122           0 :         return(write_data(client,(char *)buf,4) == 4);
     123             : }
     124             : 
     125             : /*******************************************************************
     126             :  Add a string to the end of a smb_buf, adjusting bcc and smb_len.
     127             :  Return the bytes added
     128             : ********************************************************************/
     129             : 
     130         164 : ssize_t message_push_string(uint8_t **outbuf, const char *str, int flags)
     131             : {
     132         164 :         size_t buf_size = smb_len(*outbuf) + 4;
     133             :         size_t grow_size;
     134         164 :         size_t result = 0;
     135             :         uint8_t *tmp;
     136             :         NTSTATUS status;
     137             : 
     138             :         /*
     139             :          * We need to over-allocate, now knowing what srvstr_push will
     140             :          * actually use. This is very generous by incorporating potential
     141             :          * padding, the terminating 0 and at most 4 chars per UTF-16 code
     142             :          * point.
     143             :          */
     144         164 :         grow_size = (strlen(str) + 2) * 4;
     145             : 
     146         164 :         if (!(tmp = talloc_realloc(NULL, *outbuf, uint8_t,
     147             :                                          buf_size + grow_size))) {
     148           0 :                 DEBUG(0, ("talloc failed\n"));
     149           0 :                 return -1;
     150             :         }
     151             : 
     152         164 :         status = srvstr_push((char *)tmp, SVAL(tmp, smb_flg2),
     153             :                              tmp + buf_size, str, grow_size, flags, &result);
     154             : 
     155         164 :         if (!NT_STATUS_IS_OK(status)) {
     156           0 :                 DEBUG(0, ("srvstr_push failed\n"));
     157           0 :                 return -1;
     158             :         }
     159             : 
     160             :         /*
     161             :          * Ensure we clear out the extra data we have
     162             :          * grown the buffer by, but not written to.
     163             :          */
     164         164 :         if (buf_size + result < buf_size) {
     165           0 :                 return -1;
     166             :         }
     167         164 :         if (grow_size < result) {
     168           0 :                 return -1;
     169             :         }
     170             : 
     171         164 :         memset(tmp + buf_size + result, '\0', grow_size - result);
     172             : 
     173         164 :         set_message_bcc((char *)tmp, smb_buflen(tmp) + result);
     174             : 
     175         164 :         *outbuf = tmp;
     176             : 
     177         164 :         return result;
     178             : }

Generated by: LCOV version 1.13