r12694: Move some headers to the directory of the subsystem they belong to.
[gd/samba-autobuild/.git] / source4 / torture / basic / charset.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    SMB torture tester - charset test routines
5
6    Copyright (C) Andrew Tridgell 2001
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 "torture/torture.h"
25 #include "libcli/raw/libcliraw.h"
26 #include "libcli/libcli.h"
27
28 #define BASEDIR "\\chartest\\"
29
30 /* 
31    open a file using a set of unicode code points for the name
32
33    the prefix BASEDIR is added before the name
34 */
35 static NTSTATUS unicode_open(struct smbcli_tree *tree,
36                              TALLOC_CTX *mem_ctx,
37                              uint32_t open_disposition, 
38                              const uint32_t *u_name, 
39                              size_t u_name_len)
40 {
41         union smb_open io;
42         char *fname, *fname2=NULL, *ucs_name;
43         int i;
44         NTSTATUS status;
45
46         ucs_name = talloc_size(mem_ctx, (1+u_name_len)*2);
47         if (!ucs_name) {
48                 printf("Failed to create UCS2 Name - talloc() failure\n");
49                 return NT_STATUS_NO_MEMORY;
50         }
51
52         for (i=0;i<u_name_len;i++) {
53                 SSVAL(ucs_name, i*2, u_name[i]);
54         }
55         SSVAL(ucs_name, i*2, 0);
56
57         i = convert_string_talloc(ucs_name, CH_UTF16, CH_UNIX, ucs_name, (1+u_name_len)*2, (void **)&fname);
58         if (i == -1) {
59                 printf("Failed to convert UCS2 Name into unix - convert_string_talloc() failure\n");
60                 talloc_free(ucs_name);
61                 return NT_STATUS_NO_MEMORY;
62         }
63
64         fname2 = talloc_asprintf(ucs_name, "%s%s", BASEDIR, fname);
65         if (!fname2) {
66                 talloc_free(ucs_name);
67                 return NT_STATUS_NO_MEMORY;
68         }
69
70         io.generic.level = RAW_OPEN_NTCREATEX;
71         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
72         io.ntcreatex.in.root_fid = 0;
73         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
74         io.ntcreatex.in.alloc_size = 0;
75         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
76         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
77         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
78         io.ntcreatex.in.create_options = 0;
79         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
80         io.ntcreatex.in.security_flags = 0;
81         io.ntcreatex.in.fname = fname2;
82         io.ntcreatex.in.open_disposition = open_disposition;
83
84         status = smb_raw_open(tree, mem_ctx, &io);
85
86         talloc_free(ucs_name);
87
88         return status;
89 }
90
91
92 /*
93   see if the server recognises composed characters
94 */
95 static BOOL test_composed(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
96 {
97         const uint32_t name1[] = {0x61, 0x308};
98         const uint32_t name2[] = {0xe4};
99         NTSTATUS status1, status2;
100
101         printf("Testing composite character (a umlaut)\n");
102         
103         status1 = unicode_open(cli->tree, mem_ctx, NTCREATEX_DISP_CREATE, name1, 2);
104         if (!NT_STATUS_IS_OK(status1)) {
105                 printf("Failed to create composed name - %s\n",
106                        nt_errstr(status1));
107                 return False;
108         }
109
110         status2 = unicode_open(cli->tree, mem_ctx, NTCREATEX_DISP_CREATE, name2, 1);
111
112         if (!NT_STATUS_IS_OK(status2)) {
113                 printf("Failed to create accented character - %s\n",
114                        nt_errstr(status2));
115                 return False;
116         }
117
118         return True;
119 }
120
121 /*
122   see if the server recognises a naked diacritical
123 */
124 static BOOL test_diacritical(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
125 {
126         const uint32_t name1[] = {0x308};
127         const uint32_t name2[] = {0x308, 0x308};
128         NTSTATUS status1, status2;
129
130         printf("Testing naked diacritical (umlaut)\n");
131         
132         status1 = unicode_open(cli->tree, mem_ctx, NTCREATEX_DISP_CREATE, name1, 1);
133
134         if (!NT_STATUS_IS_OK(status1)) {
135                 printf("Failed to create naked diacritical - %s\n",
136                        nt_errstr(status1));
137                 return False;
138         }
139
140         /* try a double diacritical */
141         status2 = unicode_open(cli->tree, mem_ctx, NTCREATEX_DISP_CREATE, name2, 2);
142
143         if (!NT_STATUS_IS_OK(status2)) {
144                 printf("Failed to create double naked diacritical - %s\n",
145                        nt_errstr(status2));
146                 return False;
147         }
148
149         return True;
150 }
151
152 /*
153   see if the server recognises a partial surrogate pair
154 */
155 static BOOL test_surrogate(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
156 {
157         const uint32_t name1[] = {0xd800};
158         const uint32_t name2[] = {0xdc00};
159         const uint32_t name3[] = {0xd800, 0xdc00};
160         NTSTATUS status;
161
162         printf("Testing partial surrogate\n");
163
164         status = unicode_open(cli->tree, mem_ctx, NTCREATEX_DISP_CREATE, name1, 1);
165
166         if (!NT_STATUS_IS_OK(status)) {
167                 printf("Failed to create partial surrogate 1 - %s\n",
168                        nt_errstr(status));
169                 return False;
170         }
171
172         status = unicode_open(cli->tree, mem_ctx, NTCREATEX_DISP_CREATE, name2, 1);
173
174         if (!NT_STATUS_IS_OK(status)) {
175                 printf("Failed to create partial surrogate 2 - %s\n",
176                        nt_errstr(status));
177                 return False;
178         }
179
180         status = unicode_open(cli->tree, mem_ctx, NTCREATEX_DISP_CREATE, name3, 2);
181
182         if (!NT_STATUS_IS_OK(status)) {
183                 printf("Failed to create full surrogate - %s\n",
184                        nt_errstr(status));
185                 return False;
186         }
187
188         return True;
189 }
190
191 /*
192   see if the server recognises wide-a characters
193 */
194 static BOOL test_widea(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
195 {
196         const uint32_t name1[] = {'a'};
197         const uint32_t name2[] = {0xff41};
198         const uint32_t name3[] = {0xff21};
199         NTSTATUS status;
200
201         printf("Testing wide-a\n");
202         
203         status = unicode_open(cli->tree, mem_ctx, NTCREATEX_DISP_CREATE, name1, 1);
204
205         if (!NT_STATUS_IS_OK(status)) {
206                 printf("Failed to create 'a' - %s\n",
207                        nt_errstr(status));
208                 return False;
209         }
210
211         status = unicode_open(cli->tree, mem_ctx, NTCREATEX_DISP_CREATE, name2, 1);
212
213         if (!NT_STATUS_IS_OK(status)) {
214                 printf("Failed to create wide-a - %s\n",
215                        nt_errstr(status));
216                 return False;
217         }
218
219         status = unicode_open(cli->tree, mem_ctx, NTCREATEX_DISP_CREATE, name3, 1);
220
221         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
222                 printf("Expected %s creating wide-A - %s\n",
223                        nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION),
224                        nt_errstr(status));
225                 return False;
226         }
227
228         return True;
229 }
230
231 BOOL torture_charset(void)
232 {
233         static struct smbcli_state *cli;
234         BOOL ret = True;
235         TALLOC_CTX *mem_ctx;
236
237         mem_ctx = talloc_init("torture_charset");
238
239         if (!torture_open_connection(&cli)) {
240                 return False;
241         }
242
243         printf("Starting charset tests\n");
244
245         if (!torture_setup_dir(cli, BASEDIR)) {
246                 return False;
247         }
248
249         if (!test_composed(cli, mem_ctx)) {
250                 ret = False;
251         }
252
253         if (!test_diacritical(cli, mem_ctx)) {
254                 ret = False;
255         }
256
257         if (!test_surrogate(cli, mem_ctx)) {
258                 ret = False;
259         }
260
261         if (!test_widea(cli, mem_ctx)) {
262                 ret = False;
263         }
264
265         return ret;
266 }