2c3965831aa1f1041d892b8cd9c09f8020c3315a
[bbaumbach/samba-autobuild/.git] / source4 / torture / smb2 / util.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    helper functions for SMB2 test suite
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 "libcli/raw/libcliraw.h"
25 #include "libcli/smb2/smb2.h"
26 #include "libcli/smb2/smb2_calls.h"
27 #include "lib/cmdline/popt_common.h"
28 #include "lib/events/events.h"
29
30 /*
31   show lots of information about a file
32 */
33 void torture_smb2_all_info(struct smb2_tree *tree, struct smb2_handle handle)
34 {
35         NTSTATUS status;
36         TALLOC_CTX *tmp_ctx = talloc_new(tree);
37         union smb2_fileinfo io;
38
39         status = smb2_getinfo_level(tree, tmp_ctx, handle, SMB2_GETINFO_FILE_ALL_INFO, &io);
40         if (!NT_STATUS_IS_OK(status)) {
41                 DEBUG(0,("getinfo failed - %s\n", nt_errstr(status)));
42                 talloc_free(tmp_ctx);
43                 return;
44         }
45
46         d_printf("\tcreate_time:    %s\n", nt_time_string(tmp_ctx, io.all_info.create_time));
47         d_printf("\taccess_time:    %s\n", nt_time_string(tmp_ctx, io.all_info.access_time));
48         d_printf("\twrite_time:     %s\n", nt_time_string(tmp_ctx, io.all_info.write_time));
49         d_printf("\tchange_time:    %s\n", nt_time_string(tmp_ctx, io.all_info.change_time));
50         d_printf("\tattrib:         0x%x\n", io.all_info.file_attr);
51         d_printf("\talloc_size:     %llu\n", (uint64_t)io.all_info.alloc_size);
52         d_printf("\tsize:           %llu\n", (uint64_t)io.all_info.size);
53         d_printf("\tnlink:          %u\n", io.all_info.nlink);
54         d_printf("\tdelete_pending: %u\n", io.all_info.delete_pending);
55         d_printf("\tdirectory:      %u\n", io.all_info.directory);
56         d_printf("\tfile_id:        %llu\n", io.all_info.file_id);
57         d_printf("\tea_size:        %u\n", io.all_info.ea_size);
58         d_printf("\taccess_mask:    0x%08x\n", io.all_info.access_mask);
59         d_printf("\tunknown5:       0x%llx\n", io.all_info.unknown5);
60         d_printf("\tunknown6:       0x%llx\n", io.all_info.unknown6);
61         d_printf("\tfname:          '%s'\n", io.all_info.fname);
62
63         /* the EAs, if any */
64         status = smb2_getinfo_level(tree, tmp_ctx, handle, 
65                                     SMB2_GETINFO_FILE_ALL_EAS, &io);
66         if (NT_STATUS_IS_OK(status)) {
67                 int i;
68                 for (i=0;i<io.all_eas.num_eas;i++) {
69                         d_printf("\tEA[%d] flags=%d len=%d '%s'\n", i,
70                                  io.all_eas.eas[i].flags,
71                                  (int)io.all_eas.eas[i].value.length,
72                                  io.all_eas.eas[i].name.s);
73                 }
74         }
75
76         /* streams, if available */
77         status = smb2_getinfo_level(tree, tmp_ctx, handle, 
78                                     SMB2_GETINFO_FILE_STREAM_INFO, &io);
79         if (NT_STATUS_IS_OK(status)) {
80                 int i;
81                 for (i=0;i<io.stream_info.num_streams;i++) {
82                         d_printf("\tstream %d:\n", i);
83                         d_printf("\t\tsize       %ld\n", 
84                                  (long)io.stream_info.streams[i].size);
85                         d_printf("\t\talloc size %ld\n", 
86                                  (long)io.stream_info.streams[i].alloc_size);
87                         d_printf("\t\tname       %s\n", io.stream_info.streams[i].stream_name.s);
88                 }
89         }       
90
91         talloc_free(tmp_ctx);   
92 }
93
94
95 /*
96   open a smb2 connection
97 */
98 BOOL torture_smb2_connection(TALLOC_CTX *mem_ctx, struct smb2_tree **tree)
99 {
100         NTSTATUS status;
101         const char *host = lp_parm_string(-1, "torture", "host");
102         const char *share = lp_parm_string(-1, "torture", "share");
103         struct cli_credentials *credentials = cmdline_credentials;
104
105         status = smb2_connect(mem_ctx, host, share, credentials, tree, 
106                               event_context_find(mem_ctx));
107         if (!NT_STATUS_IS_OK(status)) {
108                 printf("Failed to connect to SMB2 share \\\\%s\\%s - %s\n",
109                        host, share, nt_errstr(status));
110                 return False;
111         }
112         return True;
113 }
114
115
116 /*
117   create and return a handle to a test file
118 */
119 NTSTATUS torture_smb2_testfile(struct smb2_tree *tree, const char *fname, 
120                                struct smb2_handle *handle)
121 {
122         struct smb2_create io;
123         struct smb2_read r;
124         NTSTATUS status;
125
126         ZERO_STRUCT(io);
127         io.in.oplock_flags = 0;
128         io.in.access_mask = SEC_RIGHTS_FILE_ALL;
129         io.in.file_attr   = FILE_ATTRIBUTE_NORMAL;
130         io.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
131         io.in.share_access = 
132                 NTCREATEX_SHARE_ACCESS_DELETE|
133                 NTCREATEX_SHARE_ACCESS_READ|
134                 NTCREATEX_SHARE_ACCESS_WRITE;
135         io.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
136         io.in.fname = fname;
137         io.in.blob  = data_blob(NULL, 0);
138
139         status = smb2_create(tree, tree, &io);
140         NT_STATUS_NOT_OK_RETURN(status);
141
142         *handle = io.out.handle;
143
144         ZERO_STRUCT(r);
145         r.in.length      = 5;
146         r.in.offset      = 0;
147         r.in.handle      = *handle;
148
149         smb2_read(tree, tree, &r);
150
151         return NT_STATUS_OK;
152 }
153
154 /*
155   create and return a handle to a test directory
156 */
157 NTSTATUS torture_smb2_testdir(struct smb2_tree *tree, const char *fname, 
158                               struct smb2_handle *handle)
159 {
160         struct smb2_create io;
161         NTSTATUS status;
162
163         ZERO_STRUCT(io);
164         io.in.oplock_flags = 0;
165         io.in.access_mask = SEC_RIGHTS_DIR_ALL;
166         io.in.file_attr   = FILE_ATTRIBUTE_DIRECTORY;
167         io.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
168         io.in.share_access = NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE;
169         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
170         io.in.fname = fname;
171         io.in.blob  = data_blob(NULL, 0);
172
173         status = smb2_create(tree, tree, &io);
174         NT_STATUS_NOT_OK_RETURN(status);
175
176         *handle = io.out.handle;
177
178         return NT_STATUS_OK;
179 }
180
181
182 /*
183   create a complex file using the old SMB protocol, to make it easier to 
184   find fields in SMB2 getinfo levels
185 */
186 BOOL torture_setup_complex_file(const char *fname)
187 {
188         struct smbcli_state *cli;
189         int fnum;
190
191         if (!torture_open_connection(&cli)) {
192                 return False;
193         }
194
195         fnum = create_complex_file(cli, cli, fname);
196
197         if (DEBUGLVL(1)) {
198                 torture_all_info(cli->tree, fname);
199         }
200         
201         talloc_free(cli);
202         return fnum != -1;
203 }
204
205 /*
206   create a complex directory using the old SMB protocol, to make it easier to 
207   find fields in SMB2 getinfo levels
208 */
209 BOOL torture_setup_complex_dir(const char *dname)
210 {
211         struct smbcli_state *cli;
212         int fnum;
213
214         if (!torture_open_connection(&cli)) {
215                 return False;
216         }
217
218         fnum = create_complex_dir(cli, cli, dname);
219
220         if (DEBUGLVL(1)) {
221                 torture_all_info(cli->tree, dname);
222         }
223         
224         talloc_free(cli);
225         return fnum != -1;
226 }