LCOV - code coverage report
Current view: top level - source3/smbd - fake_file.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 57 79 72.2 %
Date: 2024-04-21 15:09:00 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    FAKE FILE support, for faking up special files windows want access to
       4             :    Copyright (C) Stefan (metze) Metzmacher      2003
       5             : 
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             : 
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : #include "includes.h"
      21             : #include "smbd/smbd.h"
      22             : #include "smbd/globals.h"
      23             : #include "fake_file.h"
      24             : #include "auth.h"
      25             : 
      26             : struct fake_file_type {
      27             :         const char *name;
      28             :         enum FAKE_FILE_TYPE type;
      29             :         void *(*init_pd)(TALLOC_CTX *mem_ctx);
      30             : };
      31             : 
      32             : static const struct fake_file_type fake_files[] = {
      33             : #ifdef WITH_QUOTAS
      34             :         {FAKE_FILE_NAME_QUOTA_UNIX, FAKE_FILE_TYPE_QUOTA, init_quota_handle},
      35             : #endif /* WITH_QUOTAS */
      36             :         {NULL, FAKE_FILE_TYPE_NONE, NULL}
      37             : };
      38             : 
      39             : /****************************************************************************
      40             :  Create a fake file handle
      41             : ****************************************************************************/
      42             : 
      43          21 : static struct fake_file_handle *init_fake_file_handle(enum FAKE_FILE_TYPE type)
      44             : {
      45          21 :         struct fake_file_handle *fh = NULL;
      46           0 :         int i;
      47             : 
      48          21 :         for (i=0; fake_files[i].name!=NULL; i++) {
      49          21 :                 if (fake_files[i].type==type) {
      50          21 :                         break;
      51             :                 }
      52             :         }
      53             : 
      54          21 :         if (fake_files[i].name == NULL) {
      55           0 :                 return NULL;
      56             :         }
      57             : 
      58          21 :         DEBUG(5,("init_fake_file_handle: for [%s]\n",fake_files[i].name));
      59             : 
      60          21 :         fh = talloc(NULL, struct fake_file_handle);
      61          21 :         if (fh == NULL) {
      62           0 :                 DEBUG(0,("TALLOC_ZERO() failed.\n"));
      63           0 :                 return NULL;
      64             :         }
      65             : 
      66          21 :         fh->type = type;
      67             : 
      68          21 :         if (fake_files[i].init_pd) {
      69          21 :                 fh->private_data = fake_files[i].init_pd(fh);
      70             :         }
      71          21 :         return fh;
      72             : }
      73             : 
      74             : /****************************************************************************
      75             :  Does this name match a fake filename ?
      76             : ****************************************************************************/
      77             : 
      78      699453 : enum FAKE_FILE_TYPE is_fake_file_path(const char *path)
      79             : {
      80       10416 :         int i;
      81             : 
      82      699453 :         if (!path) {
      83           0 :                 return FAKE_FILE_TYPE_NONE;
      84             :         }
      85             : 
      86     1398864 :         for (i=0;fake_files[i].name!=NULL;i++) {
      87      699453 :                 if (strncmp(path,fake_files[i].name,strlen(fake_files[i].name))==0) {
      88          42 :                         DEBUG(5,("is_fake_file: [%s] is a fake file\n",path));
      89          42 :                         return fake_files[i].type;
      90             :                 }
      91             :         }
      92             : 
      93      688995 :         return FAKE_FILE_TYPE_NONE;
      94             : }
      95             : 
      96        8073 : enum FAKE_FILE_TYPE is_fake_file(const struct smb_filename *smb_fname)
      97             : {
      98        8073 :         char *fname = NULL;
      99           3 :         NTSTATUS status;
     100           3 :         enum FAKE_FILE_TYPE ret;
     101             : 
     102        8073 :         if (!smb_fname) {
     103           0 :                 return FAKE_FILE_TYPE_NONE;
     104             :         }
     105             : 
     106        8073 :         status = get_full_smb_filename(talloc_tos(), smb_fname, &fname);
     107        8073 :         if (!NT_STATUS_IS_OK(status)) {
     108           0 :                 return FAKE_FILE_TYPE_NONE;
     109             :         }
     110             : 
     111        8073 :         ret = is_fake_file_path(fname);
     112             : 
     113        8073 :         TALLOC_FREE(fname);
     114             : 
     115        8070 :         return ret;
     116             : }
     117             : 
     118          21 : uint32_t dosmode_from_fake_filehandle(const struct fake_file_handle *ffh)
     119             : {
     120          21 :         if (ffh->type != FAKE_FILE_TYPE_QUOTA) {
     121           0 :                 DBG_ERR("Unexpected fake_file_handle: %d\n", ffh->type);
     122           0 :                 log_stack_trace();
     123           0 :                 return FILE_ATTRIBUTE_NORMAL;
     124             :         }
     125             : 
     126             :         /* This is what Windows 2016 returns */
     127          21 :         return FILE_ATTRIBUTE_HIDDEN
     128             :                 | FILE_ATTRIBUTE_SYSTEM
     129             :                 | FILE_ATTRIBUTE_DIRECTORY
     130             :                 | FILE_ATTRIBUTE_ARCHIVE;
     131             : }
     132             : 
     133             : /****************************************************************************
     134             :  Open a fake quota file with a share mode.
     135             : ****************************************************************************/
     136             : 
     137          21 : NTSTATUS open_fake_file(struct smb_request *req, connection_struct *conn,
     138             :                                 uint64_t current_vuid,
     139             :                                 enum FAKE_FILE_TYPE fake_file_type,
     140             :                                 const struct smb_filename *smb_fname,
     141             :                                 uint32_t access_mask,
     142             :                                 files_struct **result)
     143             : {
     144           0 :         const struct loadparm_substitution *lp_sub =
     145          21 :                 loadparm_s3_global_substitution();
     146          21 :         files_struct *fsp = NULL;
     147           0 :         NTSTATUS status;
     148             : 
     149             :         /* access check */
     150          21 :         if (geteuid() != sec_initial_uid()) {
     151           0 :                 DBG_NOTICE("access_denied to service[%s] file[%s] user[%s]\n",
     152             :                            lp_servicename(talloc_tos(), lp_sub, SNUM(conn)),
     153             :                            smb_fname_str_dbg(smb_fname),
     154             :                            conn->session_info->unix_info->unix_name);
     155           0 :                 return NT_STATUS_ACCESS_DENIED;
     156             : 
     157             :         }
     158             : 
     159          21 :         status = file_new(req, conn, &fsp);
     160          21 :         if(!NT_STATUS_IS_OK(status)) {
     161           0 :                 return status;
     162             :         }
     163             : 
     164          21 :         DBG_INFO("fname = %s, %s, access_mask = 0x%"PRIx32"\n",
     165             :                  smb_fname_str_dbg(smb_fname),
     166             :                  fsp_fnum_dbg(fsp),
     167             :                  access_mask);
     168             : 
     169          21 :         fsp->conn = conn;
     170          21 :         fsp_set_fd(fsp, -1);
     171          21 :         fsp->vuid = current_vuid;
     172          21 :         fh_set_pos(fsp->fh, -1);
     173          21 :         fsp->fsp_flags.can_lock = false; /* Should this be true ? - No, JRA */
     174          21 :         fsp->access_mask = access_mask;
     175          21 :         status = fsp_set_smb_fname(fsp, smb_fname);
     176          21 :         if (!NT_STATUS_IS_OK(status)) {
     177           0 :                 file_free(req, fsp);
     178           0 :                 return NT_STATUS_NO_MEMORY;
     179             :         }
     180             : 
     181          21 :         fsp->fake_file_handle = init_fake_file_handle(fake_file_type);
     182             : 
     183          21 :         if (fsp->fake_file_handle==NULL) {
     184           0 :                 file_free(req, fsp);
     185           0 :                 return NT_STATUS_NO_MEMORY;
     186             :         }
     187             : 
     188          21 :         status = smbd_calculate_access_mask_fsp(conn->cwd_fsp,
     189             :                                         fsp,
     190             :                                         false,
     191             :                                         access_mask,
     192             :                                         &access_mask);
     193          21 :         if (!NT_STATUS_IS_OK(status)) {
     194           0 :                 DBG_DEBUG("smbd_calculate_access_mask_fsp "
     195             :                         "on service[%s] file[%s] returned %s\n",
     196             :                         lp_servicename(talloc_tos(), lp_sub, SNUM(conn)),
     197             :                         smb_fname_str_dbg(smb_fname),
     198             :                         nt_errstr(status));
     199           0 :                 file_free(req, fsp);
     200           0 :                 return status;
     201             :         }
     202             : 
     203          21 :         *result = fsp;
     204          21 :         return NT_STATUS_OK;
     205             : }
     206             : 
     207       16920 : NTSTATUS close_fake_file(struct smb_request *req, files_struct *fsp)
     208             : {
     209             :         /*
     210             :          * Nothing to do, fake files don't hold any resources
     211             :          */
     212       16920 :         return NT_STATUS_OK;
     213             : }

Generated by: LCOV version 1.14