Line data Source code
1 : /*
2 : * VFS module to disallow writes for older files
3 : *
4 : * Copyright (C) 2013, Volker Lendecke
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 "system/filesys.h"
23 : #include "libcli/security/security.h"
24 :
25 0 : static NTSTATUS vfs_worm_create_file(vfs_handle_struct *handle,
26 : struct smb_request *req,
27 : struct files_struct *dirfsp,
28 : struct smb_filename *smb_fname,
29 : uint32_t access_mask,
30 : uint32_t share_access,
31 : uint32_t create_disposition,
32 : uint32_t create_options,
33 : uint32_t file_attributes,
34 : uint32_t oplock_request,
35 : const struct smb2_lease *lease,
36 : uint64_t allocation_size,
37 : uint32_t private_flags,
38 : struct security_descriptor *sd,
39 : struct ea_list *ea_list,
40 : files_struct **result,
41 : int *pinfo,
42 : const struct smb2_create_blobs *in_context_blobs,
43 : struct smb2_create_blobs *out_context_blobs)
44 : {
45 0 : bool readonly = false;
46 0 : const uint32_t write_access_flags =
47 : FILE_WRITE_DATA | FILE_APPEND_DATA |
48 : FILE_WRITE_ATTRIBUTES | DELETE_ACCESS |
49 : WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS;
50 : NTSTATUS status;
51 :
52 0 : if (VALID_STAT(smb_fname->st)) {
53 : double age;
54 0 : age = timespec_elapsed(&smb_fname->st.st_ex_ctime);
55 0 : if (age > lp_parm_int(SNUM(handle->conn), "worm",
56 : "grace_period", 3600)) {
57 0 : readonly = true;
58 : }
59 : }
60 :
61 0 : if (readonly && (access_mask & write_access_flags)) {
62 0 : return NT_STATUS_ACCESS_DENIED;
63 : }
64 :
65 0 : status = SMB_VFS_NEXT_CREATE_FILE(
66 : handle, req, dirfsp, smb_fname, access_mask,
67 : share_access, create_disposition, create_options,
68 : file_attributes, oplock_request, lease, allocation_size,
69 : private_flags, sd, ea_list, result, pinfo,
70 : in_context_blobs, out_context_blobs);
71 0 : if (!NT_STATUS_IS_OK(status)) {
72 0 : return status;
73 : }
74 :
75 : /*
76 : * Access via MAXIMUM_ALLOWED_ACCESS?
77 : */
78 0 : if (readonly && ((*result)->access_mask & write_access_flags)) {
79 0 : close_file_free(req, result, NORMAL_CLOSE);
80 0 : return NT_STATUS_ACCESS_DENIED;
81 : }
82 0 : return NT_STATUS_OK;
83 : }
84 :
85 : static struct vfs_fn_pointers vfs_worm_fns = {
86 : .create_file_fn = vfs_worm_create_file,
87 : };
88 :
89 : static_decl_vfs;
90 26 : NTSTATUS vfs_worm_init(TALLOC_CTX *ctx)
91 : {
92 : NTSTATUS ret;
93 :
94 26 : ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "worm",
95 : &vfs_worm_fns);
96 26 : if (!NT_STATUS_IS_OK(ret)) {
97 0 : return ret;
98 : }
99 :
100 26 : return ret;
101 : }
|