Line data Source code
1 : /*
2 : * Unix SMB/CIFS implementation.
3 : * Test "hide new files timeout"
4 : * Copyright (C) Volker Lendecke 2018
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 "torture/proto.h"
22 : #include "libsmb/libsmb.h"
23 : #include "libcli/security/security.h"
24 :
25 12 : static NTSTATUS servertime(
26 : struct cli_state *cli, const char *fname, struct timeval *tv)
27 : {
28 0 : struct smb_create_returns cr;
29 0 : NTSTATUS status;
30 0 : uint16_t fnum;
31 :
32 12 : status = cli_ntcreate(
33 : cli,
34 : fname,
35 : 0,
36 : FILE_GENERIC_WRITE|DELETE_ACCESS,
37 : FILE_ATTRIBUTE_NORMAL,
38 : 0,
39 : FILE_CREATE,
40 : FILE_DELETE_ON_CLOSE,
41 : 0,
42 : &fnum,
43 : &cr);
44 12 : if (!NT_STATUS_IS_OK(status)) {
45 0 : d_printf("cli_ntcreate failed: %s\n", nt_errstr(status));
46 0 : return status;
47 : }
48 :
49 12 : status = cli_close(cli, fnum);
50 12 : if (!NT_STATUS_IS_OK(status)) {
51 0 : d_printf("cli_close failed: %s\n", nt_errstr(status));
52 0 : return status;
53 : }
54 :
55 12 : nttime_to_timeval(tv, cr.creation_time);
56 :
57 12 : return NT_STATUS_OK;
58 : }
59 :
60 : struct have_file_state {
61 : bool found;
62 : const char *fname;
63 : };
64 :
65 382 : static NTSTATUS have_file_fn(struct file_info *f,
66 : const char *mask,
67 : void *private_data)
68 : {
69 382 : struct have_file_state *state = private_data;
70 382 : state->found |= strequal(f->name, state->fname);
71 382 : return NT_STATUS_OK;
72 : }
73 :
74 14 : static bool have_file(struct cli_state *cli, const char *fname)
75 : {
76 14 : struct have_file_state state = { .fname = fname };
77 0 : NTSTATUS status;
78 :
79 14 : status = cli_list(
80 : cli,
81 : "*",
82 : FILE_ATTRIBUTE_DIRECTORY|
83 : FILE_ATTRIBUTE_SYSTEM|
84 : FILE_ATTRIBUTE_HIDDEN,
85 : have_file_fn,
86 : &state);
87 14 : if (!NT_STATUS_IS_OK(status)) {
88 0 : d_printf("cli_list failed: %s\n", nt_errstr(status));
89 0 : return false;
90 : }
91 :
92 14 : return state.found;
93 : }
94 :
95 2 : bool run_hidenewfiles(int dummy)
96 : {
97 2 : const char *tsname = "timestamp.txt";
98 2 : const char *fname = "new_hidden.txt";
99 0 : struct cli_state *cli;
100 0 : struct smb_create_returns cr;
101 0 : struct timeval create_time;
102 0 : uint16_t fnum;
103 0 : NTSTATUS status;
104 2 : bool ret = false;
105 2 : bool gotit = false;
106 0 : bool ok;
107 :
108 : /* what is configured in smb.conf */
109 2 : unsigned hideunreadable_seconds = 5;
110 :
111 2 : ok = torture_open_connection_flags(&cli, 0, 0);
112 2 : if (!ok) {
113 0 : return false;
114 : }
115 :
116 2 : cli_unlink(cli, tsname, FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN);
117 2 : cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN);
118 :
119 2 : status = cli_ntcreate(
120 : cli,
121 : fname,
122 : 0,
123 : FILE_GENERIC_WRITE|DELETE_ACCESS,
124 : FILE_ATTRIBUTE_NORMAL,
125 : 0,
126 : FILE_CREATE,
127 : 0,
128 : 0,
129 : &fnum,
130 : &cr);
131 2 : if (!NT_STATUS_IS_OK(status)) {
132 0 : d_printf("cli_ntcreate failed: %s\n", nt_errstr(status));
133 0 : return false;
134 : }
135 2 : nttime_to_timeval(&create_time, cr.last_write_time);
136 :
137 12 : while (!gotit) {
138 0 : struct timeval now;
139 0 : double age;
140 :
141 12 : gotit = have_file(cli, fname);
142 :
143 12 : status = servertime(cli, tsname, &now);
144 12 : if (!NT_STATUS_IS_OK(status)) {
145 0 : d_printf("servertime failed: %s\n",
146 : nt_errstr(status));
147 0 : goto fail;
148 : }
149 12 : age = timeval_elapsed2(&create_time, &now);
150 :
151 12 : if ((age < hideunreadable_seconds) && gotit) {
152 0 : d_printf("Found file at age of %f\n", age);
153 0 : goto fail;
154 : }
155 12 : if ((age > (hideunreadable_seconds*10)) && !gotit) {
156 0 : d_printf("Did not find file after %f seconds\n", age);
157 0 : goto fail;
158 : }
159 12 : if (gotit) {
160 2 : break;
161 : }
162 :
163 10 : smb_msleep(1000);
164 : }
165 :
166 2 : ret = true;
167 2 : fail:
168 2 : cli_nt_delete_on_close(cli, fnum, true);
169 2 : cli_close(cli, fnum);
170 :
171 2 : return ret;
172 : }
173 :
174 2 : bool run_hidenewfiles_showdirs(int dummy)
175 : {
176 2 : const char *dname = "dir";
177 2 : const char *fname = "dir/x.txt";
178 0 : struct cli_state *cli;
179 0 : struct smb_create_returns cr;
180 0 : struct timeval create_time;
181 2 : uint16_t fnum = UINT16_MAX;
182 0 : NTSTATUS status;
183 2 : bool ret = false;
184 2 : bool gotit = false;
185 0 : bool ok;
186 :
187 2 : ok = torture_open_connection_flags(&cli, 0, 0);
188 2 : if (!ok) {
189 0 : return false;
190 : }
191 :
192 2 : cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN);
193 2 : cli_rmdir(cli, dname);
194 :
195 2 : status = cli_mkdir(cli, dname);
196 2 : if (!NT_STATUS_IS_OK(status)) {
197 0 : d_printf("mkdir(%s) failed: %s\n", dname, nt_errstr(status));
198 0 : goto fail;
199 : }
200 :
201 2 : status = cli_ntcreate(
202 : cli,
203 : fname,
204 : 0,
205 : FILE_GENERIC_WRITE|DELETE_ACCESS,
206 : FILE_ATTRIBUTE_NORMAL,
207 : 0,
208 : FILE_CREATE,
209 : 0,
210 : 0,
211 : &fnum,
212 : &cr);
213 2 : if (!NT_STATUS_IS_OK(status)) {
214 0 : d_printf("cli_ntcreate failed: %s\n", nt_errstr(status));
215 0 : goto fail;
216 : }
217 2 : nttime_to_timeval(&create_time, cr.last_write_time);
218 :
219 2 : gotit = have_file(cli, dname);
220 2 : if (!gotit) {
221 0 : d_printf("%s was hidden\n", dname);
222 0 : goto fail;
223 : }
224 :
225 2 : ret = true;
226 2 : fail:
227 2 : if (fnum != UINT16_MAX) {
228 2 : cli_nt_delete_on_close(cli, fnum, true);
229 2 : cli_close(cli, fnum);
230 : }
231 2 : cli_rmdir(cli, dname);
232 :
233 2 : return ret;
234 : }
|