Imported Upstream version 4.3.6
[abartlet/samba-debian.git] / source4 / torture / smb2 / connect.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    test suite for SMB2 connection operations
5
6    Copyright (C) Andrew Tridgell 2005
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "libcli/smb2/smb2.h"
24 #include "libcli/smb2/smb2_calls.h"
25 #include "torture/torture.h"
26 #include "torture/smb2/proto.h"
27
28 /*
29   send a close
30 */
31 static NTSTATUS torture_smb2_close(struct smb2_tree *tree, struct smb2_handle handle)
32 {
33         struct smb2_close io;
34         NTSTATUS status;
35         TALLOC_CTX *tmp_ctx = talloc_new(tree);
36
37         ZERO_STRUCT(io);
38         io.in.file.handle       = handle;
39         io.in.flags             = SMB2_CLOSE_FLAGS_FULL_INFORMATION;
40         status = smb2_close(tree, &io);
41         if (!NT_STATUS_IS_OK(status)) {
42                 printf("close failed - %s\n", nt_errstr(status));
43                 return status;
44         }
45
46         if (DEBUGLVL(1)) {
47                 printf("Close gave:\n");
48                 printf("create_time     = %s\n", nt_time_string(tmp_ctx, io.out.create_time));
49                 printf("access_time     = %s\n", nt_time_string(tmp_ctx, io.out.access_time));
50                 printf("write_time      = %s\n", nt_time_string(tmp_ctx, io.out.write_time));
51                 printf("change_time     = %s\n", nt_time_string(tmp_ctx, io.out.change_time));
52                 printf("alloc_size      = %lld\n", (long long)io.out.alloc_size);
53                 printf("size            = %lld\n", (long long)io.out.size);
54                 printf("file_attr       = 0x%x\n", io.out.file_attr);
55         }
56
57         talloc_free(tmp_ctx);
58         
59         return status;
60 }
61
62
63 /*
64   test writing
65 */
66 static NTSTATUS torture_smb2_write(struct torture_context *tctx, struct smb2_tree *tree, struct smb2_handle handle)
67 {
68         struct smb2_write w;
69         struct smb2_read r;
70         struct smb2_flush f;
71         NTSTATUS status;
72         DATA_BLOB data;
73         int i;
74         uint32_t size = torture_setting_int(tctx, "smb2maxwrite", 64*1024);
75         
76         data = data_blob_talloc(tree, NULL, size);
77         if (size != data.length) {
78                 printf("data_blob_talloc(%u) failed\n", (unsigned int)size);
79                 return NT_STATUS_NO_MEMORY;
80         }
81
82         for (i=0;i<data.length;i++) {
83                 data.data[i] = i;
84         }
85
86         ZERO_STRUCT(w);
87         w.in.file.handle = handle;
88         w.in.offset      = 0;
89         w.in.data        = data;
90
91         status = smb2_write(tree, &w);
92         if (!NT_STATUS_IS_OK(status)) {
93                 printf("write failed - %s\n", nt_errstr(status));
94                 return status;
95         }
96
97         torture_smb2_all_info(tree, handle);
98
99         status = smb2_write(tree, &w);
100         if (!NT_STATUS_IS_OK(status)) {
101                 printf("write failed - %s\n", nt_errstr(status));
102                 return status;
103         }
104
105         torture_smb2_all_info(tree, handle);
106
107         ZERO_STRUCT(f);
108         f.in.file.handle = handle;
109
110         status = smb2_flush(tree, &f);
111         if (!NT_STATUS_IS_OK(status)) {
112                 printf("flush failed - %s\n", nt_errstr(status));
113                 return status;
114         }
115
116         ZERO_STRUCT(r);
117         r.in.file.handle = handle;
118         r.in.length      = data.length;
119         r.in.offset      = 0;
120
121         status = smb2_read(tree, tree, &r);
122         if (!NT_STATUS_IS_OK(status)) {
123                 printf("read failed - %s\n", nt_errstr(status));
124                 return status;
125         }
126
127         if (data.length != r.out.data.length ||
128             memcmp(data.data, r.out.data.data, data.length) != 0) {
129                 printf("read data mismatch\n");
130                 return NT_STATUS_NET_WRITE_FAULT;
131         }
132
133         return status;
134 }
135
136
137 /*
138   send a create
139 */
140 static struct smb2_handle torture_smb2_createfile(struct smb2_tree *tree, 
141                                               const char *fname)
142 {
143         struct smb2_create io;
144         NTSTATUS status;
145         TALLOC_CTX *tmp_ctx = talloc_new(tree);
146
147         ZERO_STRUCT(io);
148         io.in.oplock_level = 0;
149         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
150         io.in.file_attributes   = FILE_ATTRIBUTE_NORMAL;
151         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
152         io.in.share_access = 
153                 NTCREATEX_SHARE_ACCESS_DELETE|
154                 NTCREATEX_SHARE_ACCESS_READ|
155                 NTCREATEX_SHARE_ACCESS_WRITE;
156         io.in.create_options = NTCREATEX_OPTIONS_WRITE_THROUGH;
157         io.in.fname = fname;
158
159         status = smb2_create(tree, tmp_ctx, &io);
160         if (!NT_STATUS_IS_OK(status)) {
161                 printf("create1 failed - %s\n", nt_errstr(status));
162                 return io.out.file.handle;
163         }
164
165         if (DEBUGLVL(1)) {
166                 printf("Open gave:\n");
167                 printf("oplock_flags    = 0x%x\n", io.out.oplock_level);
168                 printf("create_action   = 0x%x\n", io.out.create_action);
169                 printf("create_time     = %s\n", nt_time_string(tmp_ctx, io.out.create_time));
170                 printf("access_time     = %s\n", nt_time_string(tmp_ctx, io.out.access_time));
171                 printf("write_time      = %s\n", nt_time_string(tmp_ctx, io.out.write_time));
172                 printf("change_time     = %s\n", nt_time_string(tmp_ctx, io.out.change_time));
173                 printf("alloc_size      = %lld\n", (long long)io.out.alloc_size);
174                 printf("size            = %lld\n", (long long)io.out.size);
175                 printf("file_attr       = 0x%x\n", io.out.file_attr);
176                 printf("handle          = %016llx%016llx\n", 
177                        (long long)io.out.file.handle.data[0], 
178                        (long long)io.out.file.handle.data[1]);
179         }
180
181         talloc_free(tmp_ctx);
182         
183         return io.out.file.handle;
184 }
185
186
187 /* 
188    basic testing of SMB2 connection calls
189 */
190 bool torture_smb2_connect(struct torture_context *torture)
191 {
192         TALLOC_CTX *mem_ctx = talloc_new(NULL);
193         struct smb2_tree *tree;
194         struct smb2_request *req;
195         struct smb2_handle h1, h2;
196         NTSTATUS status;
197
198         if (!torture_smb2_connection(torture, &tree)) {
199                 return false;
200         }
201
202         smb2_util_unlink(tree, "test9.dat");
203
204         h1 = torture_smb2_createfile(tree, "test9.dat");
205         h2 = torture_smb2_createfile(tree, "test9.dat");
206         status = torture_smb2_write(torture, tree, h1);
207         if (!NT_STATUS_IS_OK(status)) {
208                 printf("Write failed - %s\n", nt_errstr(status));
209                 return false;
210         }
211         status = torture_smb2_close(tree, h1);
212         if (!NT_STATUS_IS_OK(status)) {
213                 printf("Close failed - %s\n", nt_errstr(status));
214                 return false;
215         }
216         status = torture_smb2_close(tree, h2);
217         if (!NT_STATUS_IS_OK(status)) {
218                 printf("Close failed - %s\n", nt_errstr(status));
219                 return false;
220         }
221
222         status = smb2_util_close(tree, h1);
223         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
224                 printf("close should have closed the handle - %s\n", nt_errstr(status));
225                 return false;
226         }
227
228         status = smb2_tdis(tree);
229         if (!NT_STATUS_IS_OK(status)) {
230                 printf("tdis failed - %s\n", nt_errstr(status));
231                 return false;
232         }
233
234         status = smb2_tdis(tree);
235         if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
236                 printf("tdis should have disabled session - %s\n", nt_errstr(status));
237                 return false;
238         }
239
240         status = smb2_logoff(tree->session);
241         if (!NT_STATUS_IS_OK(status)) {
242                 printf("Logoff failed - %s\n", nt_errstr(status));
243                 return false;
244         }
245
246         req = smb2_logoff_send(tree->session);
247         if (!req) {
248                 printf("smb2_logoff_send() failed\n");
249                 return false;
250         }
251
252         req->session = NULL;
253
254         status = smb2_logoff_recv(req);
255         if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
256                 printf("Logoff should have disabled session - %s\n", nt_errstr(status));
257                 return false;
258         }
259
260         status = smb2_keepalive(tree->session->transport);
261         if (!NT_STATUS_IS_OK(status)) {
262                 printf("keepalive failed? - %s\n", nt_errstr(status));
263                 return false;
264         }
265
266         talloc_free(mem_ctx);
267
268         return true;
269 }