r8058: added testing of delete on close for files and directories
[kai/samba.git] / source4 / torture / raw / unlink.c
1 /* 
2    Unix SMB/CIFS implementation.
3    unlink test suite
4    Copyright (C) Andrew Tridgell 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 2 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, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22 #include "system/filesys.h"
23
24 #define CHECK_STATUS(status, correct) do { \
25         if (!NT_STATUS_EQUAL(status, correct)) { \
26                 printf("(%s) Incorrect status %s - should be %s\n", \
27                        __location__, nt_errstr(status), nt_errstr(correct)); \
28                 ret = False; \
29                 goto done; \
30         }} while (0)
31
32 #define BASEDIR "\\testunlink"
33
34 /*
35   test unlink ops
36 */
37 static BOOL test_unlink(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
38 {
39         struct smb_unlink io;
40         NTSTATUS status;
41         BOOL ret = True;
42         const char *fname = BASEDIR "\\test.txt";
43
44         if (!torture_setup_dir(cli, BASEDIR)) {
45                 return False;
46         }
47
48         printf("Trying non-existant file\n");
49         io.in.pattern = fname;
50         io.in.attrib = 0;
51         status = smb_raw_unlink(cli->tree, &io);
52         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
53
54         smbcli_close(cli->tree, smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE));
55
56         io.in.pattern = fname;
57         io.in.attrib = 0;
58         status = smb_raw_unlink(cli->tree, &io);
59         CHECK_STATUS(status, NT_STATUS_OK);
60
61         printf("Trying a hidden file\n");
62         smbcli_close(cli->tree, smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE));
63         torture_set_file_attribute(cli->tree, fname, FILE_ATTRIBUTE_HIDDEN);
64
65         io.in.pattern = fname;
66         io.in.attrib = 0;
67         status = smb_raw_unlink(cli->tree, &io);
68         CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE);
69
70         io.in.pattern = fname;
71         io.in.attrib = FILE_ATTRIBUTE_HIDDEN;
72         status = smb_raw_unlink(cli->tree, &io);
73         CHECK_STATUS(status, NT_STATUS_OK);
74
75         io.in.pattern = fname;
76         io.in.attrib = FILE_ATTRIBUTE_HIDDEN;
77         status = smb_raw_unlink(cli->tree, &io);
78         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
79
80         printf("Trying a directory\n");
81         io.in.pattern = BASEDIR;
82         io.in.attrib = 0;
83         status = smb_raw_unlink(cli->tree, &io);
84         CHECK_STATUS(status, NT_STATUS_FILE_IS_A_DIRECTORY);
85
86         io.in.pattern = BASEDIR;
87         io.in.attrib = FILE_ATTRIBUTE_DIRECTORY;
88         status = smb_raw_unlink(cli->tree, &io);
89         CHECK_STATUS(status, NT_STATUS_FILE_IS_A_DIRECTORY);
90
91         printf("Trying a bad path\n");
92         io.in.pattern = "..";
93         io.in.attrib = 0;
94         status = smb_raw_unlink(cli->tree, &io);
95         CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
96
97         io.in.pattern = "\\..";
98         io.in.attrib = 0;
99         status = smb_raw_unlink(cli->tree, &io);
100         CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
101
102         io.in.pattern = BASEDIR "\\..\\..";
103         io.in.attrib = 0;
104         status = smb_raw_unlink(cli->tree, &io);
105         CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
106
107         io.in.pattern = BASEDIR "\\..";
108         io.in.attrib = 0;
109         status = smb_raw_unlink(cli->tree, &io);
110         CHECK_STATUS(status, NT_STATUS_FILE_IS_A_DIRECTORY);
111
112         printf("Trying wildcards\n");
113         smbcli_close(cli->tree, smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE));
114         io.in.pattern = BASEDIR "\\t*.t";
115         io.in.attrib = 0;
116         status = smb_raw_unlink(cli->tree, &io);
117         CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE);
118
119         io.in.pattern = BASEDIR "\\z*";
120         io.in.attrib = 0;
121         status = smb_raw_unlink(cli->tree, &io);
122         CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE);
123
124         io.in.pattern = BASEDIR "\\z*";
125         io.in.attrib = FILE_ATTRIBUTE_DIRECTORY;
126         status = smb_raw_unlink(cli->tree, &io);
127         CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE);
128
129         io.in.pattern = BASEDIR "\\*";
130         io.in.attrib = FILE_ATTRIBUTE_DIRECTORY;
131         status = smb_raw_unlink(cli->tree, &io);
132         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
133
134         io.in.pattern = BASEDIR "\\?";
135         io.in.attrib = FILE_ATTRIBUTE_DIRECTORY;
136         status = smb_raw_unlink(cli->tree, &io);
137         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
138
139         io.in.pattern = BASEDIR "\\t*";
140         io.in.attrib = FILE_ATTRIBUTE_DIRECTORY;
141         status = smb_raw_unlink(cli->tree, &io);
142         CHECK_STATUS(status, NT_STATUS_OK);
143
144         smbcli_close(cli->tree, smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE));
145
146         io.in.pattern = BASEDIR "\\*.dat";
147         io.in.attrib = FILE_ATTRIBUTE_DIRECTORY;
148         status = smb_raw_unlink(cli->tree, &io);
149         CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE);
150
151         io.in.pattern = BASEDIR "\\*.tx?";
152         io.in.attrib = 0;
153         status = smb_raw_unlink(cli->tree, &io);
154         CHECK_STATUS(status, NT_STATUS_OK);
155
156         status = smb_raw_unlink(cli->tree, &io);
157         CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE);
158
159
160 done:
161         smb_raw_exit(cli->session);
162         smbcli_deltree(cli->tree, BASEDIR);
163         return ret;
164 }
165
166
167 /*
168   test delete on close 
169 */
170 static BOOL test_delete_on_close(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
171 {
172         struct smb_unlink io;
173         struct smb_rmdir dio;
174         NTSTATUS status;
175         BOOL ret = True;
176         int fnum;
177         const char *fname = BASEDIR "\\test.txt";
178         const char *dname = BASEDIR "\\test.dir";
179         union smb_setfileinfo sfinfo;
180
181         if (!torture_setup_dir(cli, BASEDIR)) {
182                 return False;
183         }
184
185         dio.in.path = dname;
186
187         io.in.pattern = fname;
188         io.in.attrib = 0;
189         status = smb_raw_unlink(cli->tree, &io);
190         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
191
192         printf("Testing with delete_on_close 0\n");
193         fnum = create_complex_file(cli, mem_ctx, fname);
194
195         sfinfo.disposition_info.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
196         sfinfo.disposition_info.file.fnum = fnum;
197         sfinfo.disposition_info.in.delete_on_close = 0;
198         status = smb_raw_setfileinfo(cli->tree, &sfinfo);
199         CHECK_STATUS(status, NT_STATUS_OK);
200
201         smbcli_close(cli->tree, fnum);
202
203         status = smb_raw_unlink(cli->tree, &io);
204         CHECK_STATUS(status, NT_STATUS_OK);
205
206         printf("Testing with delete_on_close 1\n");
207         fnum = create_complex_file(cli, mem_ctx, fname);
208         sfinfo.disposition_info.file.fnum = fnum;
209         sfinfo.disposition_info.in.delete_on_close = 1;
210         status = smb_raw_setfileinfo(cli->tree, &sfinfo);
211         CHECK_STATUS(status, NT_STATUS_OK);
212
213         smbcli_close(cli->tree, fnum);
214
215         status = smb_raw_unlink(cli->tree, &io);
216         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
217
218
219         printf("Testing with directory and delete_on_close 0\n");
220         fnum = create_directory_handle(cli->tree, dname);
221
222         sfinfo.disposition_info.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
223         sfinfo.disposition_info.file.fnum = fnum;
224         sfinfo.disposition_info.in.delete_on_close = 0;
225         status = smb_raw_setfileinfo(cli->tree, &sfinfo);
226         CHECK_STATUS(status, NT_STATUS_OK);
227
228         smbcli_close(cli->tree, fnum);
229
230         status = smb_raw_rmdir(cli->tree, &dio);
231         CHECK_STATUS(status, NT_STATUS_OK);
232
233         printf("Testing with directory delete_on_close 1\n");
234         fnum = create_directory_handle(cli->tree, dname);
235         sfinfo.disposition_info.file.fnum = fnum;
236         sfinfo.disposition_info.in.delete_on_close = 1;
237         status = smb_raw_setfileinfo(cli->tree, &sfinfo);
238         CHECK_STATUS(status, NT_STATUS_OK);
239
240         smbcli_close(cli->tree, fnum);
241
242         status = smb_raw_rmdir(cli->tree, &dio);
243         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
244
245 done:
246         smb_raw_exit(cli->session);
247         smbcli_deltree(cli->tree, BASEDIR);
248         return ret;
249 }
250
251
252 /* 
253    basic testing of unlink calls
254 */
255 BOOL torture_raw_unlink(void)
256 {
257         struct smbcli_state *cli;
258         BOOL ret = True;
259         TALLOC_CTX *mem_ctx;
260
261         if (!torture_open_connection(&cli)) {
262                 return False;
263         }
264
265         mem_ctx = talloc_init("torture_raw_unlink");
266
267         ret &= test_unlink(cli, mem_ctx);
268         ret &= test_delete_on_close(cli, mem_ctx);
269
270         torture_close_connection(cli);
271         talloc_free(mem_ctx);
272         return ret;
273 }