1 /*
2  * Unix SMB/CIFS implementation.
3  * Test pthreadpool_tevent
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 
servertime(struct cli_state * cli,const char * fname,struct timeval * tv)25 static NTSTATUS servertime(
26 	struct cli_state *cli, const char *fname, struct timeval *tv)
27 {
28 	struct smb_create_returns cr;
29 	NTSTATUS status;
30 	uint16_t fnum;
31 
32 	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 	if (!NT_STATUS_IS_OK(status)) {
45 		d_printf("cli_ntcreate failed: %s\n", nt_errstr(status));
46 		return status;
47 	}
48 
49 	status = cli_close(cli, fnum);
50 	if (!NT_STATUS_IS_OK(status)) {
51 		d_printf("cli_close failed: %s\n", nt_errstr(status));
52 		return status;
53 	}
54 
55 	nttime_to_timeval(tv, cr.creation_time);
56 
57 	return NT_STATUS_OK;
58 }
59 
60 struct have_file_state {
61 	bool found;
62 	const char *fname;
63 };
64 
have_file_fn(const char * mntpoint,struct file_info * f,const char * mask,void * private_data)65 static NTSTATUS have_file_fn(const char *mntpoint,
66 			     struct file_info *f,
67 			     const char *mask,
68 			     void *private_data)
69 {
70 	struct have_file_state *state = private_data;
71 	state->found |= strequal(f->name, state->fname);
72 	return NT_STATUS_OK;
73 }
74 
have_file(struct cli_state * cli,const char * fname)75 static bool have_file(struct cli_state *cli, const char *fname)
76 {
77 	struct have_file_state state = { .fname = fname };
78 	NTSTATUS status;
79 
80 	status = cli_list(
81 		cli,
82 		"*.*",
83 		FILE_ATTRIBUTE_DIRECTORY|
84 		FILE_ATTRIBUTE_SYSTEM|
85 		FILE_ATTRIBUTE_HIDDEN,
86 		have_file_fn,
87 		&state);
88 	if (!NT_STATUS_IS_OK(status)) {
89 		d_printf("cli_list failed: %s\n", nt_errstr(status));
90 		return false;
91 	}
92 
93 	return state.found;
94 }
95 
run_hidenewfiles(int dummy)96 bool run_hidenewfiles(int dummy)
97 {
98 	const char *tsname = "timestamp.txt";
99 	const char *fname = "new_hidden.txt";
100 	struct cli_state *cli;
101 	struct smb_create_returns cr;
102 	struct timeval create_time;
103 	uint16_t fnum;
104 	NTSTATUS status;
105 	bool ret = false;
106 	bool gotit = false;
107 	bool ok;
108 
109 	/* what is configure in smb.conf */
110 	unsigned hideunreadable_seconds = 5;
111 
112 	ok = torture_open_connection(&cli, 0);
113 	if (!ok) {
114 		return false;
115 	}
116 
117 	cli_unlink(cli, tsname, FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN);
118 	cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN);
119 
120 	status = cli_ntcreate(
121 		cli,
122 		fname,
123 		0,
124 		FILE_GENERIC_WRITE|DELETE_ACCESS,
125 		FILE_ATTRIBUTE_NORMAL,
126 		0,
127 		FILE_CREATE,
128 		0,
129 		0,
130 		&fnum,
131 		&cr);
132 	if (!NT_STATUS_IS_OK(status)) {
133 		d_printf("cli_ntcreate failed: %s\n", nt_errstr(status));
134 		return false;
135 	}
136 	nttime_to_timeval(&create_time, cr.last_write_time);
137 
138 	while (!gotit) {
139 		struct timeval now;
140 		double age;
141 
142 		gotit = have_file(cli, fname);
143 
144 		status = servertime(cli, tsname, &now);
145 		if (!NT_STATUS_IS_OK(status)) {
146 			d_printf("servertime failed: %s\n",
147 				 nt_errstr(status));
148 			goto fail;
149 		}
150 		age = timeval_elapsed2(&create_time, &now);
151 
152 		if ((age < hideunreadable_seconds) && gotit) {
153 			d_printf("Found file at age of %f\n", age);
154 			goto fail;
155 		}
156 		if ((age > (hideunreadable_seconds*10)) && !gotit) {
157 			d_printf("Did not find file after %f seconds\n", age);
158 			goto fail;
159 		}
160 		if (gotit) {
161 			break;
162 		}
163 
164 		smb_msleep(1000);
165 	}
166 
167 	ret = true;
168 fail:
169 	cli_nt_delete_on_close(cli, fnum, true);
170 	cli_close(cli, fnum);
171 
172 	return ret;
173 }
174