r11755: added names for all of the SMB2 qfs info levels (they all map exactly
[gd/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("\tunknown1:       0x%x\n", io.all_info.unknown1);
52         d_printf("\talloc_size:     %llu\n", (uint64_t)io.all_info.alloc_size);
53         d_printf("\tsize:           %llu\n", (uint64_t)io.all_info.size);
54         d_printf("\tnlink:          %u\n", io.all_info.nlink);
55         d_printf("\tdelete_pending: %u\n", io.all_info.delete_pending);
56         d_printf("\tdirectory:      %u\n", io.all_info.directory);
57         d_printf("\tfile_id:        %llu\n", io.all_info.file_id);
58         d_printf("\tea_size:        %u\n", io.all_info.ea_size);
59         d_printf("\taccess_mask:    0x%08x\n", io.all_info.access_mask);
60         d_printf("\tunknown5:       0x%llx\n", io.all_info.unknown5);
61         d_printf("\tunknown6:       0x%llx\n", io.all_info.unknown6);
62         d_printf("\tfname:          '%s'\n", io.all_info.fname);
63
64         /* short name, if any */
65         status = smb2_getinfo_level(tree, tmp_ctx, handle, 
66                                     SMB2_GETINFO_FILE_SHORT_INFO, &io);
67         if (NT_STATUS_IS_OK(status)) {
68                 d_printf("\tshort name:     '%s'\n", io.short_info.short_name);
69         }
70
71         /* the EAs, if any */
72         status = smb2_getinfo_level(tree, tmp_ctx, handle, 
73                                     SMB2_GETINFO_FILE_ALL_EAS, &io);
74         if (NT_STATUS_IS_OK(status)) {
75                 int i;
76                 for (i=0;i<io.all_eas.num_eas;i++) {
77                         d_printf("\tEA[%d] flags=%d len=%d '%s'\n", i,
78                                  io.all_eas.eas[i].flags,
79                                  (int)io.all_eas.eas[i].value.length,
80                                  io.all_eas.eas[i].name.s);
81                 }
82         }
83
84         /* streams, if available */
85         status = smb2_getinfo_level(tree, tmp_ctx, handle, 
86                                     SMB2_GETINFO_FILE_STREAM_INFO, &io);
87         if (NT_STATUS_IS_OK(status)) {
88                 int i;
89                 for (i=0;i<io.stream_info.num_streams;i++) {
90                         d_printf("\tstream %d:\n", i);
91                         d_printf("\t\tsize       %ld\n", 
92                                  (long)io.stream_info.streams[i].size);
93                         d_printf("\t\talloc size %ld\n", 
94                                  (long)io.stream_info.streams[i].alloc_size);
95                         d_printf("\t\tname       %s\n", io.stream_info.streams[i].stream_name.s);
96                 }
97         }       
98
99         talloc_free(tmp_ctx);   
100 }
101
102
103 /*
104   open a smb2 connection
105 */
106 BOOL torture_smb2_connection(TALLOC_CTX *mem_ctx, struct smb2_tree **tree)
107 {
108         NTSTATUS status;
109         const char *host = lp_parm_string(-1, "torture", "host");
110         const char *share = lp_parm_string(-1, "torture", "share");
111         struct cli_credentials *credentials = cmdline_credentials;
112
113         status = smb2_connect(mem_ctx, host, share, credentials, tree, 
114                               event_context_find(mem_ctx));
115         if (!NT_STATUS_IS_OK(status)) {
116                 printf("Failed to connect to SMB2 share \\\\%s\\%s - %s\n",
117                        host, share, nt_errstr(status));
118                 return False;
119         }
120         return True;
121 }
122
123
124 /*
125   create and return a handle to a test file
126 */
127 NTSTATUS torture_smb2_testfile(struct smb2_tree *tree, const char *fname, 
128                                struct smb2_handle *handle)
129 {
130         struct smb2_create io;
131         struct smb2_read r;
132         NTSTATUS status;
133
134         ZERO_STRUCT(io);
135         io.in.oplock_flags = 0;
136         io.in.access_mask = SEC_RIGHTS_FILE_ALL;
137         io.in.file_attr   = FILE_ATTRIBUTE_NORMAL;
138         io.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
139         io.in.share_access = 
140                 NTCREATEX_SHARE_ACCESS_DELETE|
141                 NTCREATEX_SHARE_ACCESS_READ|
142                 NTCREATEX_SHARE_ACCESS_WRITE;
143         io.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
144         io.in.fname = fname;
145         io.in.blob  = data_blob(NULL, 0);
146
147         status = smb2_create(tree, tree, &io);
148         NT_STATUS_NOT_OK_RETURN(status);
149
150         *handle = io.out.handle;
151
152         ZERO_STRUCT(r);
153         r.in.length      = 5;
154         r.in.offset      = 0;
155         r.in.handle      = *handle;
156
157         smb2_read(tree, tree, &r);
158
159         return NT_STATUS_OK;
160 }
161
162 /*
163   create and return a handle to a test directory
164 */
165 NTSTATUS torture_smb2_testdir(struct smb2_tree *tree, const char *fname, 
166                               struct smb2_handle *handle)
167 {
168         struct smb2_create io;
169         NTSTATUS status;
170
171         ZERO_STRUCT(io);
172         io.in.oplock_flags = 0;
173         io.in.access_mask = SEC_RIGHTS_DIR_ALL;
174         io.in.file_attr   = FILE_ATTRIBUTE_DIRECTORY;
175         io.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
176         io.in.share_access = NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE;
177         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
178         io.in.fname = fname;
179         io.in.blob  = data_blob(NULL, 0);
180
181         status = smb2_create(tree, tree, &io);
182         NT_STATUS_NOT_OK_RETURN(status);
183
184         *handle = io.out.handle;
185
186         return NT_STATUS_OK;
187 }
188
189
190 /*
191   create a complex file using the old SMB protocol, to make it easier to 
192   find fields in SMB2 getinfo levels
193 */
194 BOOL torture_setup_complex_file(const char *fname)
195 {
196         struct smbcli_state *cli;
197         int fnum;
198
199         if (!torture_open_connection(&cli)) {
200                 return False;
201         }
202
203         fnum = create_complex_file(cli, cli, fname);
204
205         if (DEBUGLVL(1)) {
206                 torture_all_info(cli->tree, fname);
207         }
208         
209         talloc_free(cli);
210         return fnum != -1;
211 }
212
213 /*
214   create a complex directory using the old SMB protocol, to make it easier to 
215   find fields in SMB2 getinfo levels
216 */
217 BOOL torture_setup_complex_dir(const char *dname)
218 {
219         struct smbcli_state *cli;
220         int fnum;
221
222         if (!torture_open_connection(&cli)) {
223                 return False;
224         }
225
226         fnum = create_complex_dir(cli, cli, dname);
227
228         if (DEBUGLVL(1)) {
229                 torture_all_info(cli->tree, dname);
230         }
231         
232         talloc_free(cli);
233         return fnum != -1;
234 }