Coverage Report

Created: 2026-04-01 06:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/source3/smbd/fake_file.c
Line
Count
Source
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
static struct fake_file_handle *init_fake_file_handle(enum FAKE_FILE_TYPE type)
44
0
{
45
0
  struct fake_file_handle *fh = NULL;
46
0
  int i;
47
48
0
  for (i=0; fake_files[i].name!=NULL; i++) {
49
0
    if (fake_files[i].type==type) {
50
0
      break;
51
0
    }
52
0
  }
53
54
0
  if (fake_files[i].name == NULL) {
55
0
    return NULL;
56
0
  }
57
58
0
  DEBUG(5,("init_fake_file_handle: for [%s]\n",fake_files[i].name));
59
60
0
  fh = talloc(NULL, struct fake_file_handle);
61
0
  if (fh == NULL) {
62
0
    DEBUG(0,("TALLOC_ZERO() failed.\n"));
63
0
    return NULL;
64
0
  }
65
66
0
  fh->type = type;
67
68
0
  if (fake_files[i].init_pd) {
69
0
    fh->private_data = fake_files[i].init_pd(fh);
70
0
  }
71
0
  return fh;
72
0
}
73
74
/****************************************************************************
75
 Does this name match a fake filename ?
76
****************************************************************************/
77
78
enum FAKE_FILE_TYPE is_fake_file_path(const char *path)
79
0
{
80
0
  int i;
81
82
0
  if (!path) {
83
0
    return FAKE_FILE_TYPE_NONE;
84
0
  }
85
86
0
  for (i=0;fake_files[i].name!=NULL;i++) {
87
0
    if (strncmp(path,fake_files[i].name,strlen(fake_files[i].name))==0) {
88
0
      DEBUG(5,("is_fake_file: [%s] is a fake file\n",path));
89
0
      return fake_files[i].type;
90
0
    }
91
0
  }
92
93
0
  return FAKE_FILE_TYPE_NONE;
94
0
}
95
96
enum FAKE_FILE_TYPE is_fake_file(const struct smb_filename *smb_fname)
97
0
{
98
0
  char *fname = NULL;
99
0
  NTSTATUS status;
100
0
  enum FAKE_FILE_TYPE ret;
101
102
0
  if (!smb_fname) {
103
0
    return FAKE_FILE_TYPE_NONE;
104
0
  }
105
106
0
  status = get_full_smb_filename(talloc_tos(), smb_fname, &fname);
107
0
  if (!NT_STATUS_IS_OK(status)) {
108
0
    return FAKE_FILE_TYPE_NONE;
109
0
  }
110
111
0
  ret = is_fake_file_path(fname);
112
113
0
  TALLOC_FREE(fname);
114
115
0
  return ret;
116
0
}
117
118
uint32_t dosmode_from_fake_filehandle(const struct fake_file_handle *ffh)
119
0
{
120
0
  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
0
  }
125
126
  /* This is what Windows 2016 returns */
127
0
  return FILE_ATTRIBUTE_HIDDEN
128
0
    | FILE_ATTRIBUTE_SYSTEM
129
0
    | FILE_ATTRIBUTE_DIRECTORY
130
0
    | FILE_ATTRIBUTE_ARCHIVE;
131
0
}
132
133
/****************************************************************************
134
 Open a fake quota file with a share mode.
135
****************************************************************************/
136
137
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
0
{
144
0
  const struct loadparm_substitution *lp_sub =
145
0
    loadparm_s3_global_substitution();
146
0
  files_struct *fsp = NULL;
147
0
  NTSTATUS status;
148
0
  bool ok;
149
150
  /* access check */
151
0
  if (geteuid() != sec_initial_uid()) {
152
0
    DBG_NOTICE("access_denied to service[%s] file[%s] user[%s]\n",
153
0
         lp_servicename(talloc_tos(), lp_sub, SNUM(conn)),
154
0
         smb_fname_str_dbg(smb_fname),
155
0
         conn->session_info->unix_info->unix_name);
156
0
    return NT_STATUS_ACCESS_DENIED;
157
158
0
  }
159
160
0
  status = file_new(req, conn, &fsp);
161
0
  if(!NT_STATUS_IS_OK(status)) {
162
0
    return status;
163
0
  }
164
165
0
  DBG_INFO("fname = %s, %s, access_mask = 0x%"PRIx32"\n",
166
0
     smb_fname_str_dbg(smb_fname),
167
0
     fsp_fnum_dbg(fsp),
168
0
     access_mask);
169
170
0
  fsp->conn = conn;
171
0
  fsp_set_fd(fsp, -1);
172
0
  fsp->vuid = current_vuid;
173
0
  fh_set_pos(fsp->fh, -1);
174
0
  fsp->fsp_flags.can_lock = false; /* Should this be true ? - No, JRA */
175
0
  fsp->access_mask = access_mask;
176
0
  ok = fsp_set_smb_fname(fsp, smb_fname);
177
0
  if (!ok) {
178
0
    file_free(req, fsp);
179
0
    return NT_STATUS_NO_MEMORY;
180
0
  }
181
182
0
  fsp->fake_file_handle = init_fake_file_handle(fake_file_type);
183
184
0
  if (fsp->fake_file_handle==NULL) {
185
0
    file_free(req, fsp);
186
0
    return NT_STATUS_NO_MEMORY;
187
0
  }
188
189
0
  status = smbd_calculate_access_mask_fsp(conn->cwd_fsp,
190
0
          fsp,
191
0
          false,
192
0
          access_mask,
193
0
          &access_mask);
194
0
  if (!NT_STATUS_IS_OK(status)) {
195
0
    DBG_DEBUG("smbd_calculate_access_mask_fsp "
196
0
      "on service[%s] file[%s] returned %s\n",
197
0
      lp_servicename(talloc_tos(), lp_sub, SNUM(conn)),
198
0
      smb_fname_str_dbg(smb_fname),
199
0
      nt_errstr(status));
200
0
    file_free(req, fsp);
201
0
    return status;
202
0
  }
203
204
0
  *result = fsp;
205
0
  return NT_STATUS_OK;
206
0
}
207
208
NTSTATUS close_fake_file(struct smb_request *req, files_struct *fsp)
209
0
{
210
  /*
211
   * Nothing to do, fake files don't hold any resources
212
   */
213
0
  return NT_STATUS_OK;
214
0
}