d4016b87703b580a338956671ecca20913419592
[abartlet/samba.git/.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 2 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, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "smb.h"
25 #include "libcli/smb2/smb2.h"
26 #include "libcli/smb2/smb2_calls.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.flags       = SMB2_CLOSE_FLAGS_FULL_INFORMATION;
39         io.in.handle   = handle;
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 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         
75         if (lp_parm_bool(-1, "torture", "dangerous", False)) {
76                 data = data_blob_talloc(tree, NULL, 160000);
77         } else {
78                 data = data_blob_talloc(tree, NULL, 120000);
79         }
80         for (i=0;i<data.length;i++) {
81                 data.data[i] = i;
82         }
83
84         ZERO_STRUCT(w);
85         w.in.offset      = 0;
86         w.in.handle      = handle;
87         w.in.data        = data;
88
89         status = smb2_write(tree, &w);
90         if (!NT_STATUS_IS_OK(status)) {
91                 printf("write failed - %s\n", nt_errstr(status));
92                 return status;
93         }
94
95         torture_smb2_all_info(tree, handle);
96
97         status = smb2_write(tree, &w);
98         if (!NT_STATUS_IS_OK(status)) {
99                 printf("write failed - %s\n", nt_errstr(status));
100                 return status;
101         }
102
103         torture_smb2_all_info(tree, handle);
104
105         ZERO_STRUCT(f);
106         f.in.handle      = handle;
107
108         status = smb2_flush(tree, &f);
109         if (!NT_STATUS_IS_OK(status)) {
110                 printf("flush failed - %s\n", nt_errstr(status));
111                 return status;
112         }
113
114         ZERO_STRUCT(r);
115         r.in.length      = data.length;
116         r.in.offset      = 0;
117         r.in.handle      = handle;
118
119         status = smb2_read(tree, tree, &r);
120         if (!NT_STATUS_IS_OK(status)) {
121                 printf("read failed - %s\n", nt_errstr(status));
122                 return status;
123         }
124
125         if (data.length != r.out.data.length ||
126             memcmp(data.data, r.out.data.data, data.length) != 0) {
127                 printf("read data mismatch\n");
128                 return NT_STATUS_NET_WRITE_FAULT;
129         }
130
131         return status;
132 }
133
134
135 /*
136   send a create
137 */
138 static struct smb2_handle torture_smb2_create(struct smb2_tree *tree, 
139                                               const char *fname)
140 {
141         struct smb2_create io;
142         NTSTATUS status;
143         TALLOC_CTX *tmp_ctx = talloc_new(tree);
144
145         ZERO_STRUCT(io);
146         io.in.oplock_flags = 0;
147         io.in.access_mask = SEC_RIGHTS_FILE_ALL;
148         io.in.file_attr   = FILE_ATTRIBUTE_NORMAL;
149         io.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
150         io.in.share_access = 
151                 NTCREATEX_SHARE_ACCESS_DELETE|
152                 NTCREATEX_SHARE_ACCESS_READ|
153                 NTCREATEX_SHARE_ACCESS_WRITE;
154         io.in.create_options = NTCREATEX_OPTIONS_WRITE_THROUGH;
155         io.in.fname = fname;
156
157         status = smb2_create(tree, tmp_ctx, &io);
158         if (!NT_STATUS_IS_OK(status)) {
159                 printf("create1 failed - %s\n", nt_errstr(status));
160                 return io.out.handle;
161         }
162
163         if (DEBUGLVL(1)) {
164                 printf("Open gave:\n");
165                 printf("oplock_flags    = 0x%x\n", io.out.oplock_flags);
166                 printf("create_action   = 0x%x\n", io.out.create_action);
167                 printf("create_time     = %s\n", nt_time_string(tmp_ctx, io.out.create_time));
168                 printf("access_time     = %s\n", nt_time_string(tmp_ctx, io.out.access_time));
169                 printf("write_time      = %s\n", nt_time_string(tmp_ctx, io.out.write_time));
170                 printf("change_time     = %s\n", nt_time_string(tmp_ctx, io.out.change_time));
171                 printf("alloc_size      = %lld\n", (long long)io.out.alloc_size);
172                 printf("size            = %lld\n", (long long)io.out.size);
173                 printf("file_attr       = 0x%x\n", io.out.file_attr);
174                 printf("handle          = %016llx%016llx\n", 
175                        (long long)io.out.handle.data[0], 
176                        (long long)io.out.handle.data[1]);
177         }
178
179         talloc_free(tmp_ctx);
180         
181         return io.out.handle;
182 }
183
184
185 /* 
186    basic testing of SMB2 connection calls
187 */
188 BOOL torture_smb2_connect(void)
189 {
190         TALLOC_CTX *mem_ctx = talloc_new(NULL);
191         struct smb2_tree *tree;
192         struct smb2_handle h1, h2;
193         NTSTATUS status;
194
195         if (!torture_smb2_connection(mem_ctx, &tree)) {
196                 return False;
197         }
198
199         h1 = torture_smb2_create(tree, "test9.dat");
200         h2 = torture_smb2_create(tree, "test9.dat");
201         torture_smb2_write(tree, h1);
202         torture_smb2_close(tree, h1);
203         torture_smb2_close(tree, h2);
204
205         status = smb2_tdis(tree);
206         if (!NT_STATUS_IS_OK(status)) {
207                 printf("tdis failed - %s\n", nt_errstr(status));
208                 return False;
209         }
210
211         status = smb2_tdis(tree);
212         if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
213                 printf("tdis should have disabled session - %s\n", nt_errstr(status));
214                 return False;
215         }
216
217         status = smb2_logoff(tree->session);
218         if (!NT_STATUS_IS_OK(status)) {
219                 printf("Logoff failed - %s\n", nt_errstr(status));
220                 return False;
221         }
222
223         status = smb2_logoff(tree->session);
224         if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
225                 printf("Logoff should have disabled session - %s\n", nt_errstr(status));
226                 return False;
227         }
228
229         status = smb2_keepalive(tree->session->transport);
230         if (!NT_STATUS_IS_OK(status)) {
231                 printf("keepalive failed? - %s\n", nt_errstr(status));
232                 return False;
233         }
234
235         talloc_free(mem_ctx);
236
237         return True;
238 }