s4-ldb: changed the DN checks for \n to warnings
[ira/wip.git] / source4 / dsdb / common / tests / dsdb_dn.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    Test LDB attribute functions
5
6    Copyright (C) Andrew Bartlet <abartlet@samba.org> 2008
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 "lib/events/events.h"
24 #include "lib/ldb/include/ldb.h"
25 #include "lib/ldb/include/ldb_errors.h"
26 #include "lib/ldb-samba/ldif_handlers.h"
27 #include "ldb_wrap.h"
28 #include "dsdb/samdb/samdb.h"
29 #include "param/param.h"
30 #include "torture/smbtorture.h"
31 #include "torture/local/proto.h"
32
33 #define DSDB_DN_TEST_SID "S-1-5-21-4177067393-1453636373-93818737"
34
35 static bool torture_dsdb_dn_attrs(struct torture_context *torture)
36 {
37         TALLOC_CTX *mem_ctx = talloc_new(torture);
38         struct ldb_context *ldb;
39         const struct ldb_schema_syntax *syntax;
40         struct ldb_val dn1, dn2, dn3;
41
42         torture_assert(torture, 
43                        ldb = ldb_init(mem_ctx, torture->ev),
44                        "Failed to init ldb");
45
46         torture_assert_int_equal(torture, 
47                                  ldb_register_samba_handlers(ldb), 0, 
48                                  "Failed to register Samba handlers");
49
50         ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
51
52         /* Test DN+Binary behaviour */
53         torture_assert(torture, syntax = ldb_samba_syntax_by_name(ldb, DSDB_SYNTAX_BINARY_DN), 
54                        "Failed to get DN+Binary schema attribute");
55         /* Test compare with different case of HEX string */
56         dn1 = data_blob_string_const("B:6:abcdef:dc=samba,dc=org");
57         dn2 = data_blob_string_const("B:6:ABCDef:dc=samba,dc=org");
58         torture_assert_int_equal(torture, 
59                                  syntax->comparison_fn(ldb, mem_ctx, &dn1, &dn2), 0,
60                                  "Failed to compare different case of binary in DN+Binary");
61         torture_assert_int_equal(torture, 
62                                  syntax->canonicalise_fn(ldb, mem_ctx, &dn1, &dn3), 0,
63                                  "Failed to canonicalise DN+Binary");
64         torture_assert_data_blob_equal(torture, dn3, data_blob_string_const("B:6:ABCDEF:DC=SAMBA,DC=ORG"), 
65                                        "Failed to canonicalise DN+Binary");
66         /* Test compare with different case of DN */
67         dn1 = data_blob_string_const("B:6:abcdef:dc=samba,dc=org");
68         dn2 = data_blob_string_const("B:6:abcdef:dc=SAMBa,dc=ORg");
69         torture_assert_int_equal(torture, 
70                                  syntax->comparison_fn(ldb, mem_ctx, &dn1, &dn2), 0,
71                                  "Failed to compare different case of DN in DN+Binary");
72         
73         /* Test compare (false) with binary and non-binary prefix */
74         dn1 = data_blob_string_const("B:6:abcdef:dc=samba,dc=org");
75         dn2 = data_blob_string_const("dc=samba,dc=org");
76         torture_assert(torture, 
77                        syntax->comparison_fn(ldb, mem_ctx, &dn1, &dn2) != 0,
78                        "compare of binary+dn an dn should have failed");
79
80         /* Test DN+String behaviour */
81         torture_assert(torture, syntax = ldb_samba_syntax_by_name(ldb, DSDB_SYNTAX_STRING_DN), 
82                        "Failed to get DN+String schema attribute");
83         
84         /* Test compare with different case of string */
85         dn1 = data_blob_string_const("S:8:hihohiho:dc=samba,dc=org");
86         dn2 = data_blob_string_const("S:8:HIHOHIHO:dc=samba,dc=org");
87         torture_assert(torture, 
88                        syntax->comparison_fn(ldb, mem_ctx, &dn1, &dn2) != 0,
89                        "compare of string+dn an different case of string+dn should have failed");
90
91         /* Test compare with different case of DN */
92         dn1 = data_blob_string_const("S:8:hihohiho:dc=samba,dc=org");
93         dn2 = data_blob_string_const("S:8:hihohiho:dc=SAMBA,dc=org");
94         torture_assert_int_equal(torture, 
95                                  syntax->comparison_fn(ldb, mem_ctx, &dn1, &dn2), 0,
96                                  "Failed to compare different case of DN in DN+String");
97         torture_assert_int_equal(torture, 
98                                  syntax->canonicalise_fn(ldb, mem_ctx, &dn1, &dn3), 0,
99                                  "Failed to canonicalise DN+String");
100         torture_assert_data_blob_equal(torture, dn3, data_blob_string_const("S:8:hihohiho:DC=SAMBA,DC=ORG"), 
101                                        "Failed to canonicalise DN+String");
102
103         /* Test compare (false) with string and non-string prefix */
104         dn1 = data_blob_string_const("S:6:abcdef:dc=samba,dc=org");
105         dn2 = data_blob_string_const("dc=samba,dc=org");
106         torture_assert(torture, 
107                        syntax->comparison_fn(ldb, mem_ctx, &dn1, &dn2) != 0,
108                        "compare of string+dn an dn should have failed");
109
110         talloc_free(mem_ctx);
111         return true;
112 }
113
114 static bool torture_dsdb_dn_valid(struct torture_context *torture)
115 {
116         TALLOC_CTX *mem_ctx = talloc_new(torture);
117         struct ldb_context *ldb;
118         struct ldb_dn *dn;
119         struct dsdb_dn *dsdb_dn;
120
121         struct ldb_val val;
122
123         DATA_BLOB abcd_blob = data_blob_talloc(mem_ctx, "\xa\xb\xc\xd", 4);
124
125         torture_assert(torture, 
126                        ldb = ldb_init(mem_ctx, torture->ev),
127                        "Failed to init ldb");
128
129         torture_assert_int_equal(torture, 
130                                  ldb_register_samba_handlers(ldb), 0, 
131                                  "Failed to register Samba handlers");
132
133         ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
134
135         /* Check behaviour of a normal DN */
136         torture_assert(torture, 
137                        dn = ldb_dn_new(mem_ctx, ldb, NULL), 
138                        "Failed to create a NULL DN");
139         torture_assert(torture, 
140                        ldb_dn_validate(dn),
141                        "Failed to validate NULL DN");
142         torture_assert(torture, 
143                        ldb_dn_add_base_fmt(dn, "dc=org"), 
144                        "Failed to add base DN");
145         torture_assert(torture, 
146                        ldb_dn_add_child_fmt(dn, "dc=samba"), 
147                        "Failed to add base DN");
148         torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "dc=samba,dc=org", 
149                                  "linearized DN incorrect");
150         torture_assert(torture, dsdb_dn =  dsdb_dn_construct(mem_ctx, dn, data_blob_null, LDB_SYNTAX_DN), 
151                 "Failed to build dsdb dn");
152         torture_assert_str_equal(torture, dsdb_dn_get_extended_linearized(mem_ctx, dsdb_dn, 0), "dc=samba,dc=org", 
153                                  "extended linearized DN incorrect");
154         torture_assert_str_equal(torture, dsdb_dn_get_linearized(mem_ctx, dsdb_dn), "dc=samba,dc=org", 
155                                  "linearized DN incorrect");
156         torture_assert_str_equal(torture, dsdb_dn_get_casefold(mem_ctx, dsdb_dn), "DC=SAMBA,DC=ORG", 
157                                  "casefold DN incorrect");
158
159
160         /* Test constructing a binary DN */
161         torture_assert(torture, dsdb_dn = dsdb_dn_construct(mem_ctx, dn, abcd_blob, DSDB_SYNTAX_BINARY_DN), 
162                        "Failed to build binary dsdb dn");
163         torture_assert_str_equal(torture, dsdb_dn_get_extended_linearized(mem_ctx, dsdb_dn, 0), "B:8:0A0B0C0D:dc=samba,dc=org", 
164                                  "extended linearized DN incorrect");
165         torture_assert_str_equal(torture, dsdb_dn_get_linearized(mem_ctx, dsdb_dn), "B:8:0A0B0C0D:dc=samba,dc=org", 
166                                  "linearized DN incorrect");
167         torture_assert_str_equal(torture, dsdb_dn_get_casefold(mem_ctx, dsdb_dn), "B:8:0A0B0C0D:DC=SAMBA,DC=ORG", 
168                                  "casefold DN incorrect");
169         torture_assert_int_equal(torture, dsdb_dn->extra_part.length, 4, "length of extra-part should be 2");
170                 
171
172         /* Test constructing a string DN */
173         torture_assert(torture, dsdb_dn =  dsdb_dn_construct(mem_ctx, dn, data_blob_talloc(mem_ctx, "hello", 5), DSDB_SYNTAX_STRING_DN),
174                        "Failed to build string dsdb dn");
175         torture_assert_str_equal(torture, dsdb_dn_get_extended_linearized(mem_ctx, dsdb_dn, 0), "S:5:hello:dc=samba,dc=org", 
176                                  "extended linearized DN incorrect");
177         torture_assert_str_equal(torture, dsdb_dn_get_linearized(mem_ctx, dsdb_dn), "S:5:hello:dc=samba,dc=org", 
178                                  "linearized DN incorrect");
179         torture_assert_str_equal(torture, dsdb_dn_get_casefold(mem_ctx, dsdb_dn), "S:5:hello:DC=SAMBA,DC=ORG", 
180                                  "casefold DN incorrect");
181         torture_assert_int_equal(torture, dsdb_dn->extra_part.length, 5, "length of extra-part should be 5");
182
183
184         /* Test compose of binary+DN */
185         val = data_blob_string_const("B:0::CN=Zer0,DC=SAMBA,DC=org");
186         torture_assert(torture,
187                        dsdb_dn = dsdb_dn_parse(mem_ctx, ldb, &val,
188                                      DSDB_SYNTAX_BINARY_DN),
189                        "Failed to create a DN with a zero binary part in it");
190         torture_assert_int_equal(torture, dsdb_dn->extra_part.length, 0, "length of extra-part should be 0");
191         torture_assert_str_equal(torture, dsdb_dn_get_extended_linearized(mem_ctx, dsdb_dn, 0), "B:0::CN=Zer0,DC=SAMBA,DC=org", 
192                                  "extended linearized DN incorrect");
193         torture_assert_str_equal(torture, dsdb_dn_get_linearized(mem_ctx, dsdb_dn), "B:0::CN=Zer0,DC=SAMBA,DC=org", 
194                                  "linearized DN incorrect");
195         torture_assert_str_equal(torture, dsdb_dn_get_casefold(mem_ctx, dsdb_dn), "B:0::CN=ZER0,DC=SAMBA,DC=ORG", 
196                                  "casefold DN incorrect");
197
198         /* Test parse of binary DN */
199         val = data_blob_string_const("B:8:abcdabcd:CN=4,DC=Samba,DC=org");
200         torture_assert(torture,
201                        dsdb_dn = dsdb_dn_parse(mem_ctx, ldb, &val,
202                                      DSDB_SYNTAX_BINARY_DN),
203                        "Failed to create a DN with a binary part in it");
204         torture_assert_int_equal(torture, dsdb_dn->extra_part.length, 4, "length of extra-part should be 4");
205
206         torture_assert_str_equal(torture, dsdb_dn_get_extended_linearized(mem_ctx, dsdb_dn, 0), "B:8:ABCDABCD:CN=4,DC=Samba,DC=org", 
207                                  "extended linearized DN incorrect");
208         torture_assert_str_equal(torture, dsdb_dn_get_linearized(mem_ctx, dsdb_dn), "B:8:ABCDABCD:CN=4,DC=Samba,DC=org", 
209                                  "linearized DN incorrect");
210         torture_assert_str_equal(torture, dsdb_dn_get_casefold(mem_ctx, dsdb_dn), "B:8:ABCDABCD:CN=4,DC=SAMBA,DC=ORG", 
211                                  "casefold DN incorrect");
212
213         /* Test parse of string+DN */
214         val = data_blob_string_const("S:8:Goodbye!:CN=S,DC=Samba,DC=org");
215         torture_assert(torture,
216                        dsdb_dn = dsdb_dn_parse(mem_ctx, ldb, &val,
217                                      DSDB_SYNTAX_STRING_DN),
218                        "Failed to create a DN with a string part in it");
219         torture_assert_int_equal(torture, dsdb_dn->extra_part.length, 8, "length of extra-part should be 8");
220         torture_assert_str_equal(torture, dsdb_dn_get_extended_linearized(mem_ctx, dsdb_dn, 0), "S:8:Goodbye!:CN=S,DC=Samba,DC=org", 
221                                  "extended linearized DN incorrect");
222
223         /* Test that the linearised DN is the postfix of the lineairsed dsdb_dn */
224         torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dsdb_dn->dn, 0), "CN=S,DC=Samba,DC=org", 
225                                  "extended linearized DN incorrect");
226         torture_assert_str_equal(torture, dsdb_dn_get_linearized(mem_ctx, dsdb_dn), "S:8:Goodbye!:CN=S,DC=Samba,DC=org", 
227                                  "linearized DN incorrect");
228         torture_assert_str_equal(torture, ldb_dn_get_linearized(dsdb_dn->dn), "CN=S,DC=Samba,DC=org", 
229                                  "linearized DN incorrect");
230         torture_assert_str_equal(torture, dsdb_dn_get_casefold(mem_ctx, dsdb_dn), "S:8:Goodbye!:CN=S,DC=SAMBA,DC=ORG", 
231                                  "casefold DN incorrect");
232
233         /* Test that the casefold DN is the postfix of the casefolded dsdb_dn */
234         torture_assert_str_equal(torture, ldb_dn_get_casefold(dsdb_dn->dn), "CN=S,DC=SAMBA,DC=ORG", 
235                                  "casefold DN incorrect");
236
237         talloc_free(mem_ctx);
238         return true;
239 }
240
241 static bool torture_dsdb_dn_invalid(struct torture_context *torture)
242 {
243         TALLOC_CTX *mem_ctx = talloc_new(torture);
244         struct ldb_context *ldb;
245         struct ldb_val val;
246
247         torture_assert(torture, 
248                        ldb = ldb_init(mem_ctx, torture->ev),
249                        "Failed to init ldb");
250
251         torture_assert_int_equal(torture, 
252                                  ldb_register_samba_handlers(ldb), 0, 
253                                  "Failed to register Samba handlers");
254
255         ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
256
257         /* Check behaviour of a normal DN */
258         val = data_blob_string_const("samba,dc=org");
259         torture_assert(torture, 
260                        dsdb_dn_parse(mem_ctx, ldb, &val, LDB_SYNTAX_DN) == NULL, 
261                        "Should have failed to create a 'normal' invalid DN");
262
263         /* Test invalid binary DNs */
264         val = data_blob_string_const("B:5:AB:dc=samba,dc=org");
265         torture_assert(torture, 
266                        dsdb_dn_parse(mem_ctx, ldb, &val,
267                                      DSDB_SYNTAX_BINARY_DN) == NULL, 
268                        "Should have Failed to create an invalid 'binary' DN");
269         val = data_blob_string_const("B:5:ABCDEFG:dc=samba,dc=org");
270         torture_assert(torture, 
271                        dsdb_dn_parse(mem_ctx, ldb, &val,
272                                      DSDB_SYNTAX_BINARY_DN) == NULL, 
273                        "Should have Failed to create an invalid 'binary' DN");
274         val = data_blob_string_const("B:10:AB:dc=samba,dc=org");
275         torture_assert(torture, 
276                        dsdb_dn_parse(mem_ctx, ldb, &val,
277                                      DSDB_SYNTAX_BINARY_DN) == NULL, 
278                        "Should have Failed to create an invalid 'binary' DN");
279         val = data_blob_string_const("B:4:0xAB:dc=samba,dc=org");
280         torture_assert(torture, 
281                        dsdb_dn_parse(mem_ctx, ldb, &val,
282                                      DSDB_SYNTAX_BINARY_DN) == NULL, 
283                        "Should have Failed to create an invalid 0x preifx 'binary' DN");
284         val = data_blob_string_const("B:2:0xAB:dc=samba,dc=org");
285         torture_assert(torture, 
286                        dsdb_dn_parse(mem_ctx, ldb, &val,
287                                      DSDB_SYNTAX_BINARY_DN) == NULL, 
288                        "Should have Failed to create an invalid 0x preifx 'binary' DN");
289         val = data_blob_string_const("B:10:XXXXXXXXXX:dc=samba,dc=org");
290         torture_assert(torture, 
291                        dsdb_dn_parse(mem_ctx, ldb, &val,
292                                      DSDB_SYNTAX_BINARY_DN) == NULL, 
293                        "Should have Failed to create an invalid 'binary' DN");
294
295         val = data_blob_string_const("B:60::dc=samba,dc=org");
296         torture_assert(torture, 
297                        dsdb_dn_parse(mem_ctx, ldb, &val,
298                                      DSDB_SYNTAX_BINARY_DN) == NULL, 
299                        "Should have Failed to create an invalid 'binary' DN");
300
301         /* Test invalid string DNs */
302         val = data_blob_string_const("S:5:hi:dc=samba,dc=org");
303         torture_assert(torture, 
304                        dsdb_dn_parse(mem_ctx, ldb, &val,
305                                      DSDB_SYNTAX_STRING_DN) == NULL, 
306                        "Should have Failed to create an invalid 'string' DN");
307         val = data_blob_string_const("S:5:hihohiho:dc=samba,dc=org");
308         torture_assert(torture, 
309                        dsdb_dn_parse(mem_ctx, ldb, &val,
310                                      DSDB_SYNTAX_STRING_DN) == NULL, 
311                        "Should have Failed to create an invalid 'string' DN");
312
313         val = data_blob_string_const("<SID=" DSDB_DN_TEST_SID">;dc=samba,dc=org");
314         torture_assert(torture, 
315                        dsdb_dn_parse(mem_ctx, ldb, &val, DSDB_SYNTAX_BINARY_DN) == NULL, 
316                        "Should have failed to create an 'extended' DN marked as a binary DN");
317
318         /* Check DN based on MS-ADTS:3.1.1.5.1.2 Naming Constraints*/
319         val = data_blob_string_const("CN=New\nLine,DC=SAMBA,DC=org");
320
321         /* changed to a warning until we understand the DEL: DNs */
322         if (dsdb_dn_parse(mem_ctx, ldb, &val, LDB_SYNTAX_DN) != NULL) {
323                 torture_warning(torture,
324                                 "Should have Failed to create a DN with 0xA in it");
325         }
326
327         val = data_blob_string_const("B:4:ABAB:CN=New\nLine,DC=SAMBA,DC=org");
328         torture_assert(torture,
329                        dsdb_dn_parse(mem_ctx, ldb, &val, LDB_SYNTAX_DN) == NULL,
330                        "Should have Failed to create a DN with 0xA in it");
331
332         val = data_blob_const("CN=Zer\0,DC=SAMBA,DC=org", 23);
333         torture_assert(torture,
334                        dsdb_dn_parse(mem_ctx, ldb, &val, LDB_SYNTAX_DN) == NULL,
335                        "Should have Failed to create a DN with 0x0 in it");
336
337         val = data_blob_const("B:4:ABAB:CN=Zer\0,DC=SAMBA,DC=org", 23+9);
338         torture_assert(torture,
339                        dsdb_dn_parse(mem_ctx, ldb, &val, DSDB_SYNTAX_BINARY_DN) == NULL,
340                        "Should have Failed to create a DN with 0x0 in it");
341
342         return true;
343 }
344
345 struct torture_suite *torture_dsdb_dn(TALLOC_CTX *mem_ctx)
346 {
347         struct torture_suite *suite = torture_suite_create(mem_ctx, "DSDB-DN");
348
349         if (suite == NULL) {
350                 return NULL;
351         }
352
353         torture_suite_add_simple_test(suite, "VALID", torture_dsdb_dn_valid);
354         torture_suite_add_simple_test(suite, "INVALID", torture_dsdb_dn_invalid);
355         torture_suite_add_simple_test(suite, "ATTRS", torture_dsdb_dn_attrs);
356
357         suite->description = talloc_strdup(suite, "DSDB DN tests");
358
359         return suite;
360 }