examples:winexe: embed Samba version as exe timestamp
[samba.git] / source4 / torture / raw / close.c
1 /* 
2    Unix SMB/CIFS implementation.
3    RAW_CLOSE_* individual 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 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/torture.h"
22 #include "system/time.h"
23 #include "libcli/raw/libcliraw.h"
24 #include "libcli/raw/raw_proto.h"
25 #include "libcli/libcli.h"
26 #include "torture/util.h"
27 #include "torture/raw/proto.h"
28
29 /**
30  * basic testing of all RAW_CLOSE_* calls 
31 */
32 bool torture_raw_close(struct torture_context *torture,
33                        struct smbcli_state *cli)
34 {
35         bool ret = true;
36         union smb_close io;
37         union smb_flush io_flush;
38         int fnum;
39         const char *fname = "\\torture_close.txt";
40         time_t basetime = (time(NULL) + 3*86400) & ~1;
41         union smb_fileinfo finfo, finfo2;
42         NTSTATUS status;
43
44 #define REOPEN do { \
45         fnum = create_complex_file(cli, torture, fname); \
46         if (fnum == -1) { \
47                 printf("(%d) Failed to create %s\n", __LINE__, fname); \
48                 ret = false; \
49                 goto done; \
50         }} while (0)
51
52 #define CHECK_STATUS(status, correct) do { \
53         if (!NT_STATUS_EQUAL(status, correct)) { \
54                 printf("(%d) Incorrect status %s - should be %s\n", \
55                        __LINE__, nt_errstr(status), nt_errstr(correct)); \
56                 ret = false; \
57                 goto done; \
58         }} while (0)
59
60         REOPEN;
61
62         io.close.level = RAW_CLOSE_CLOSE;
63         io.close.in.file.fnum = fnum;
64         io.close.in.write_time = basetime;
65         status = smb_raw_close(cli->tree, &io);
66         CHECK_STATUS(status, NT_STATUS_OK);
67
68         status = smb_raw_close(cli->tree, &io);
69         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
70         
71         printf("Testing close.in.write_time\n");
72
73         /* the file should have the write time set */
74         finfo.generic.level = RAW_FILEINFO_ALL_INFO;
75         finfo.generic.in.file.path = fname;
76         status = smb_raw_pathinfo(cli->tree, torture, &finfo);
77         CHECK_STATUS(status, NT_STATUS_OK);
78
79         if (basetime != nt_time_to_unix(finfo.all_info.out.write_time)) {
80                 printf("Incorrect write time on file - %s - %s\n",
81                        timestring(torture, basetime), 
82                        nt_time_string(torture, finfo.all_info.out.write_time));
83                 dump_all_info(torture, &finfo);
84                 ret = false;
85         }
86
87         printf("Testing other times\n");
88
89         /* none of the other times should be set to that time */
90         if (nt_time_equal(&finfo.all_info.out.write_time, 
91                           &finfo.all_info.out.access_time) ||
92             nt_time_equal(&finfo.all_info.out.write_time, 
93                           &finfo.all_info.out.create_time) ||
94             nt_time_equal(&finfo.all_info.out.write_time, 
95                           &finfo.all_info.out.change_time)) {
96                 printf("Incorrect times after close - only write time should be set\n");
97                 dump_all_info(torture, &finfo);
98
99                 if (!torture_setting_bool(torture, "samba3", false)) {
100                         /*
101                          * In Samba3 as of 3.0.23d we don't yet support all
102                          * file times, so don't mark this as a critical
103                          * failure
104                          */
105                         ret = false;
106                 }
107         }
108             
109
110         smbcli_unlink(cli->tree, fname);
111         REOPEN;
112
113         finfo2.generic.level = RAW_FILEINFO_ALL_INFO;
114         finfo2.generic.in.file.path = fname;
115         status = smb_raw_pathinfo(cli->tree, torture, &finfo2);
116         CHECK_STATUS(status, NT_STATUS_OK);
117
118         io.close.level = RAW_CLOSE_CLOSE;
119         io.close.in.file.fnum = fnum;
120         io.close.in.write_time = 0;
121         status = smb_raw_close(cli->tree, &io);
122         CHECK_STATUS(status, NT_STATUS_OK);
123
124         /* the file should have the write time set equal to access time */
125         finfo.generic.level = RAW_FILEINFO_ALL_INFO;
126         finfo.generic.in.file.path = fname;
127         status = smb_raw_pathinfo(cli->tree, torture, &finfo);
128         CHECK_STATUS(status, NT_STATUS_OK);
129
130         if (!nt_time_equal(&finfo.all_info.out.write_time, 
131                            &finfo2.all_info.out.write_time)) {
132                 printf("Incorrect write time on file - 0 time should be ignored\n");
133                 dump_all_info(torture, &finfo);
134                 ret = false;
135         }
136
137         printf("Testing splclose\n");
138
139         /* check splclose on a file */
140         REOPEN;
141         io.splclose.level = RAW_CLOSE_SPLCLOSE;
142         io.splclose.in.file.fnum = fnum;
143         status = smb_raw_close(cli->tree, &io);
144         CHECK_STATUS(status, NT_STATUS_DOS(ERRSRV, ERRerror));
145
146         printf("Testing flush\n");
147         smbcli_close(cli->tree, fnum);
148
149         io_flush.flush.level            = RAW_FLUSH_FLUSH;
150         io_flush.flush.in.file.fnum     = fnum;
151         status = smb_raw_flush(cli->tree, &io_flush);
152         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
153
154         io_flush.flush_all.level        = RAW_FLUSH_ALL;
155         status = smb_raw_flush(cli->tree, &io_flush);
156         CHECK_STATUS(status, NT_STATUS_OK);
157
158         REOPEN;
159
160         io_flush.flush.level            = RAW_FLUSH_FLUSH;
161         io_flush.flush.in.file.fnum     = fnum;
162         status = smb_raw_flush(cli->tree, &io_flush);
163         CHECK_STATUS(status, NT_STATUS_OK);
164
165         printf("Testing SMBexit\n");
166         smb_raw_exit(cli->session);
167
168         io_flush.flush.level            = RAW_FLUSH_FLUSH;
169         io_flush.flush.in.file.fnum     = fnum;
170         status = smb_raw_flush(cli->tree, &io_flush);
171         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
172         
173
174 done:
175         smbcli_close(cli->tree, fnum);
176         smbcli_unlink(cli->tree, fname);
177         return ret;
178 }