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 : }
|