Merge branch 'master' of ssh://git.samba.org/data/git/samba into extended-dn
[abartlet/samba.git/.git] / source4 / torture / ldb / ldb.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/ldb/proto.h"
32
33 static const char *sid = "S-1-5-21-4177067393-1453636373-93818737";
34 static const char *hex_sid = "01040000000000051500000081FDF8F815BBA456718F9705";
35 static const char *guid = "975ac5fa-35d9-431d-b86a-845bcd34fff9";
36 static const char *guid2 = "{975ac5fa-35d9-431d-b86a-845bcd34fff9}";
37 static const char *hex_guid = "FAC55A97D9351D43B86A845BCD34FFF9";
38
39 static bool torture_ldb_attrs(struct torture_context *torture)
40 {
41         TALLOC_CTX *mem_ctx = talloc_new(torture);
42         struct ldb_context *ldb;
43         const struct ldb_schema_attribute *attr;
44         struct ldb_val string_sid_blob, binary_sid_blob;
45         struct ldb_val string_guid_blob, string_guid_blob2, binary_guid_blob;
46
47         DATA_BLOB sid_blob = strhex_to_data_blob(mem_ctx, hex_sid);
48         DATA_BLOB guid_blob = strhex_to_data_blob(mem_ctx, hex_guid);
49
50         torture_assert(torture, 
51                        ldb = ldb_init(mem_ctx, torture->ev),
52                        "Failed to init ldb");
53
54         torture_assert_int_equal(torture, 
55                                  ldb_register_samba_handlers(ldb), 0, 
56                                  "Failed to register Samba handlers");
57
58         ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
59
60         /* Test SID behaviour */
61         torture_assert(torture, attr = ldb_schema_attribute_by_name(ldb, "objectSid"), 
62                        "Failed to get objectSid schema attribute");
63         
64         string_sid_blob = data_blob_string_const(sid);
65
66         torture_assert_int_equal(torture, 
67                                  attr->syntax->ldif_read_fn(ldb, mem_ctx, 
68                                                             &string_sid_blob, &binary_sid_blob), 0,
69                                  "Failed to parse string SID");
70         
71         torture_assert_data_blob_equal(torture, binary_sid_blob, sid_blob, 
72                                        "Read SID into blob form failed");
73         
74         torture_assert_int_equal(torture, 
75                                  attr->syntax->ldif_read_fn(ldb, mem_ctx, 
76                                                             &sid_blob, &binary_sid_blob), -1,
77                                  "Should have failed to parse binary SID");
78         
79         torture_assert_int_equal(torture, 
80                                  attr->syntax->ldif_write_fn(ldb, mem_ctx, &binary_sid_blob, &string_sid_blob), 0,
81                                  "Failed to parse binary SID");
82         
83         torture_assert_data_blob_equal(torture, 
84                                        string_sid_blob, data_blob_string_const(sid),
85                                        "Write SID into string form failed");
86         
87         torture_assert_int_equal(torture, 
88                                  attr->syntax->comparison_fn(ldb, mem_ctx, &binary_sid_blob, &string_sid_blob), 0,
89                                  "Failed to compare binary and string SID");
90         
91         torture_assert_int_equal(torture, 
92                                  attr->syntax->comparison_fn(ldb, mem_ctx, &string_sid_blob, &binary_sid_blob), 0,
93                                  "Failed to compare string and binary binary SID");
94         
95         torture_assert_int_equal(torture, 
96                                  attr->syntax->comparison_fn(ldb, mem_ctx, &string_sid_blob, &string_sid_blob), 0,
97                                  "Failed to compare string and string SID");
98         
99         torture_assert_int_equal(torture, 
100                                  attr->syntax->comparison_fn(ldb, mem_ctx, &binary_sid_blob, &binary_sid_blob), 0,
101                                  "Failed to compare binary and binary SID");
102         
103         torture_assert(torture, attr->syntax->comparison_fn(ldb, mem_ctx, &guid_blob, &binary_sid_blob) != 0,
104                        "Failed to distinguish binary GUID and binary SID");
105
106
107         /* Test GUID behaviour */
108         torture_assert(torture, attr = ldb_schema_attribute_by_name(ldb, "objectGUID"), 
109                        "Failed to get objectGUID schema attribute");
110         
111         string_guid_blob = data_blob_string_const(guid);
112
113         torture_assert_int_equal(torture, 
114                                  attr->syntax->ldif_read_fn(ldb, mem_ctx, 
115                                                             &string_guid_blob, &binary_guid_blob), 0,
116                                  "Failed to parse string GUID");
117         
118         torture_assert_data_blob_equal(torture, binary_guid_blob, guid_blob, 
119                                        "Read GUID into blob form failed");
120         
121         string_guid_blob2 = data_blob_string_const(guid2);
122         
123         torture_assert_int_equal(torture, 
124                                  attr->syntax->ldif_read_fn(ldb, mem_ctx, 
125                                                             &string_guid_blob2, &binary_guid_blob), 0,
126                                  "Failed to parse string GUID");
127         
128         torture_assert_data_blob_equal(torture, binary_guid_blob, guid_blob, 
129                                        "Read GUID into blob form failed");
130         
131         torture_assert_int_equal(torture, 
132                                  attr->syntax->ldif_read_fn(ldb, mem_ctx, 
133                                                             &guid_blob, &binary_guid_blob), 0,
134                                  "Failed to parse binary GUID");
135         
136         torture_assert_data_blob_equal(torture, binary_guid_blob, guid_blob, 
137                                        "Read GUID into blob form failed");
138         
139         torture_assert_int_equal(torture, 
140                                  attr->syntax->ldif_write_fn(ldb, mem_ctx, &binary_guid_blob, &string_guid_blob), 0,
141                                  "Failed to print binary GUID as string");
142
143         torture_assert_data_blob_equal(torture, string_sid_blob, data_blob_string_const(sid),
144                                        "Write SID into string form failed");
145         
146         torture_assert_int_equal(torture, 
147                                  attr->syntax->comparison_fn(ldb, mem_ctx, &binary_guid_blob, &string_guid_blob), 0,
148                                  "Failed to compare binary and string GUID");
149         
150         torture_assert_int_equal(torture, 
151                                  attr->syntax->comparison_fn(ldb, mem_ctx, &string_guid_blob, &binary_guid_blob), 0,
152                                  "Failed to compare string and binary binary GUID");
153         
154         torture_assert_int_equal(torture, 
155                                  attr->syntax->comparison_fn(ldb, mem_ctx, &string_guid_blob, &string_guid_blob), 0,
156                                  "Failed to compare string and string GUID");
157         
158         torture_assert_int_equal(torture, 
159                                  attr->syntax->comparison_fn(ldb, mem_ctx, &binary_guid_blob, &binary_guid_blob), 0,
160                                  "Failed to compare binary and binary GUID");
161         
162         
163         
164         talloc_free(mem_ctx);
165         return true;
166 }
167
168 static bool torture_ldb_dn_attrs(struct torture_context *torture)
169 {
170         TALLOC_CTX *mem_ctx = talloc_new(torture);
171         struct ldb_context *ldb;
172         const struct ldb_dn_extended_syntax *attr;
173         struct ldb_val string_sid_blob, binary_sid_blob;
174         struct ldb_val string_guid_blob, binary_guid_blob;
175         struct ldb_val hex_sid_blob, hex_guid_blob;
176
177         DATA_BLOB sid_blob = strhex_to_data_blob(mem_ctx, hex_sid);
178         DATA_BLOB guid_blob = strhex_to_data_blob(mem_ctx, hex_guid);
179
180         torture_assert(torture, 
181                        ldb = ldb_init(mem_ctx, torture->ev),
182                        "Failed to init ldb");
183
184         torture_assert_int_equal(torture, 
185                                  ldb_register_samba_handlers(ldb), 0, 
186                                  "Failed to register Samba handlers");
187
188         ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
189
190         /* Test SID behaviour */
191         torture_assert(torture, attr = ldb_dn_extended_syntax_by_name(ldb, "SID"), 
192                        "Failed to get SID DN syntax");
193         
194         string_sid_blob = data_blob_string_const(sid);
195
196         torture_assert_int_equal(torture, 
197                                  attr->read_fn(ldb, mem_ctx, 
198                                                &string_sid_blob, &binary_sid_blob), 0,
199                                  "Failed to parse string SID");
200         
201         torture_assert_data_blob_equal(torture, binary_sid_blob, sid_blob, 
202                                        "Read SID into blob form failed");
203
204         hex_sid_blob = data_blob_string_const(hex_sid);
205         
206         torture_assert_int_equal(torture, 
207                                  attr->read_fn(ldb, mem_ctx, 
208                                                &hex_sid_blob, &binary_sid_blob), 0,
209                                  "Failed to parse HEX SID");
210         
211         torture_assert_data_blob_equal(torture, binary_sid_blob, sid_blob, 
212                                        "Read SID into blob form failed");
213         
214         torture_assert_int_equal(torture, 
215                                  attr->read_fn(ldb, mem_ctx, 
216                                                &sid_blob, &binary_sid_blob), -1,
217                                  "Should have failed to parse binary SID");
218         
219         torture_assert_int_equal(torture, 
220                                  attr->write_hex_fn(ldb, mem_ctx, &sid_blob, &hex_sid_blob), 0,
221                                  "Failed to parse binary SID");
222         
223         torture_assert_data_blob_equal(torture, 
224                                        hex_sid_blob, data_blob_string_const(hex_sid),
225                                        "Write SID into HEX string form failed");
226         
227         torture_assert_int_equal(torture, 
228                                  attr->write_clear_fn(ldb, mem_ctx, &sid_blob, &string_sid_blob), 0,
229                                  "Failed to parse binary SID");
230         
231         torture_assert_data_blob_equal(torture, 
232                                        string_sid_blob, data_blob_string_const(sid),
233                                        "Write SID into clear string form failed");
234         
235
236         /* Test GUID behaviour */
237         torture_assert(torture, attr = ldb_dn_extended_syntax_by_name(ldb, "GUID"), 
238                        "Failed to get GUID DN syntax");
239         
240         string_guid_blob = data_blob_string_const(guid);
241
242         torture_assert_int_equal(torture, 
243                                  attr->read_fn(ldb, mem_ctx, 
244                                                &string_guid_blob, &binary_guid_blob), 0,
245                                  "Failed to parse string GUID");
246         
247         torture_assert_data_blob_equal(torture, binary_guid_blob, guid_blob, 
248                                        "Read GUID into blob form failed");
249         
250         hex_guid_blob = data_blob_string_const(hex_guid);
251         
252         torture_assert_int_equal(torture, 
253                                  attr->read_fn(ldb, mem_ctx, 
254                                                &hex_guid_blob, &binary_guid_blob), 0,
255                                  "Failed to parse HEX GUID");
256         
257         torture_assert_data_blob_equal(torture, binary_guid_blob, guid_blob, 
258                                        "Read GUID into blob form failed");
259         
260         torture_assert_int_equal(torture, 
261                                  attr->read_fn(ldb, mem_ctx, 
262                                                &guid_blob, &binary_guid_blob), -1,
263                                  "Should have failed to parse binary GUID");
264         
265         torture_assert_int_equal(torture, 
266                                  attr->write_hex_fn(ldb, mem_ctx, &guid_blob, &hex_guid_blob), 0,
267                                  "Failed to parse binary GUID");
268         
269         torture_assert_data_blob_equal(torture, 
270                                        hex_guid_blob, data_blob_string_const(hex_guid),
271                                        "Write GUID into HEX string form failed");
272         
273         torture_assert_int_equal(torture, 
274                                  attr->write_clear_fn(ldb, mem_ctx, &guid_blob, &string_guid_blob), 0,
275                                  "Failed to parse binary GUID");
276         
277         torture_assert_data_blob_equal(torture, 
278                                        string_guid_blob, data_blob_string_const(guid),
279                                        "Write GUID into clear string form failed");
280         
281
282
283         talloc_free(mem_ctx);
284         return true;
285 }
286
287 static bool torture_ldb_dn_extended(struct torture_context *torture)
288 {
289         TALLOC_CTX *mem_ctx = talloc_new(torture);
290         struct ldb_context *ldb;
291         struct ldb_dn *dn, *dn2;
292         struct ldb_val string_sid_blob = data_blob_string_const(sid);
293         struct ldb_val string_guid_blob = data_blob_string_const(guid);
294
295         DATA_BLOB sid_blob = strhex_to_data_blob(mem_ctx, hex_sid);
296         DATA_BLOB guid_blob = strhex_to_data_blob(mem_ctx, hex_guid);
297
298         const char *dn_str = "cn=admin,cn=users,dc=samba,dc=org";
299
300         torture_assert(torture, 
301                        ldb = ldb_init(mem_ctx, torture->ev),
302                        "Failed to init ldb");
303
304         torture_assert_int_equal(torture, 
305                                  ldb_register_samba_handlers(ldb), 0, 
306                                  "Failed to register Samba handlers");
307
308         ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
309
310         /* Check behaviour of a normal DN */
311         torture_assert(torture, 
312                        dn = ldb_dn_new(mem_ctx, ldb, dn_str), 
313                        "Failed to create a 'normal' DN");
314
315         torture_assert(torture, 
316                        ldb_dn_validate(dn),
317                        "Failed to validate 'normal' DN");
318
319         torture_assert(torture, ldb_dn_has_extended(dn) == false, 
320                        "Should not find plain DN to be 'extended'");
321
322         torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") == NULL, 
323                        "Should not find an SID on plain DN");
324
325         torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") == NULL, 
326                        "Should not find an GUID on plain DN");
327         
328         torture_assert(torture, ldb_dn_get_extended_component(dn, "WKGUID") == NULL, 
329                        "Should not find an WKGUID on plain DN");
330         
331         /* Now make an extended DN */
332         torture_assert(torture, 
333                        dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>;<SID=%s>;%s",
334                                            guid, sid, dn_str), 
335                        "Failed to create an 'extended' DN");
336
337         torture_assert(torture, 
338                        dn2 = ldb_dn_copy(mem_ctx, dn), 
339                        "Failed to copy the 'extended' DN");
340         talloc_free(dn);
341         dn = dn2;
342
343         torture_assert(torture, 
344                        ldb_dn_validate(dn),
345                        "Failed to validate 'extended' DN");
346
347         torture_assert(torture, ldb_dn_has_extended(dn) == true, 
348                        "Should find extended DN to be 'extended'");
349
350         torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") != NULL, 
351                        "Should find an SID on extended DN");
352
353         torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") != NULL, 
354                        "Should find an GUID on extended DN");
355         
356         torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "SID"), sid_blob, 
357                                        "Extended DN SID incorect");
358
359         torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "GUID"), guid_blob, 
360                                        "Extended DN GUID incorect");
361
362         torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), dn_str, 
363                                  "linearized DN incorrect");
364
365         torture_assert_str_equal(torture, ldb_dn_get_casefold(dn), strupper_talloc(mem_ctx, dn_str), 
366                                  "casefolded DN incorrect");
367
368         torture_assert_str_equal(torture, ldb_dn_get_component_name(dn, 0), "cn", 
369                                  "componet zero incorrect");
370
371         torture_assert_data_blob_equal(torture, *ldb_dn_get_component_val(dn, 0), data_blob_string_const("admin"), 
372                                  "componet zero incorrect");
373
374         torture_assert_str_equal(torture, ldb_dn_extended_linearized(mem_ctx, dn, 1),
375                                  talloc_asprintf(mem_ctx, "<GUID=%s>;<SID=%s>;%s", 
376                                                  guid, sid, dn_str),
377                                  "Clear extended linearized DN incorrect");
378
379         torture_assert_str_equal(torture, ldb_dn_extended_linearized(mem_ctx, dn, 0),
380                                  talloc_asprintf(mem_ctx, "<GUID=%s>;<SID=%s>;%s", 
381                                                  hex_guid, hex_sid, dn_str),
382                                  "HEX extended linearized DN incorrect");
383
384         torture_assert(torture, ldb_dn_remove_child_components(dn, 1) == true,
385                                  "Failed to remove DN child");
386                        
387         torture_assert(torture, ldb_dn_has_extended(dn) == false, 
388                        "Extended DN flag should be cleared after child element removal");
389         
390         torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") == NULL, 
391                        "Should not find an SID on DN");
392
393         torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") == NULL, 
394                        "Should not find an GUID on DN");
395
396
397         /* TODO:  test setting these in the other order, and ensure it still comes out 'GUID first' */
398         torture_assert_int_equal(torture, ldb_dn_set_extended_component(dn, "GUID", &guid_blob), 0, 
399                        "Failed to set a GUID on DN");
400         
401         torture_assert_int_equal(torture, ldb_dn_set_extended_component(dn, "SID", &sid_blob), 0, 
402                        "Failed to set a SID on DN");
403
404         torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "SID"), sid_blob, 
405                                        "Extended DN SID incorect");
406
407         torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "GUID"), guid_blob, 
408                                        "Extended DN GUID incorect");
409
410         torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "cn=users,dc=samba,dc=org", 
411                                  "linearized DN incorrect");
412
413         torture_assert_str_equal(torture, ldb_dn_extended_linearized(mem_ctx, dn, 1),
414                                  talloc_asprintf(mem_ctx, "<GUID=%s>;<SID=%s>;%s", 
415                                                  guid, sid, "cn=users,dc=samba,dc=org"),
416                                  "Clear extended linearized DN incorrect");
417
418         torture_assert_str_equal(torture, ldb_dn_extended_linearized(mem_ctx, dn, 0),
419                                  talloc_asprintf(mem_ctx, "<GUID=%s>;<SID=%s>;%s", 
420                                                  hex_guid, hex_sid, "cn=users,dc=samba,dc=org"),
421                                  "HEX extended linearized DN incorrect");
422
423         /* Now check a 'just GUID' DN (clear format) */
424         torture_assert(torture, 
425                        dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>",
426                                            guid), 
427                        "Failed to create an 'extended' DN");
428
429         torture_assert(torture, 
430                        ldb_dn_validate(dn),
431                        "Failed to validate 'extended' DN");
432
433         torture_assert(torture, ldb_dn_has_extended(dn) == true, 
434                        "Should find extended DN to be 'extended'");
435
436         torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") == NULL, 
437                        "Should not find an SID on this DN");
438
439         torture_assert_int_equal(torture, ldb_dn_get_comp_num(dn), 0, 
440                        "Should not find an 'normal' componet on this DN");
441
442         torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") != NULL, 
443                        "Should find an GUID on this DN");
444         
445         torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "GUID"), guid_blob, 
446                                        "Extended DN GUID incorect");
447
448         torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "", 
449                                  "linearized DN incorrect");
450
451         torture_assert_str_equal(torture, ldb_dn_extended_linearized(mem_ctx, dn, 1),
452                                  talloc_asprintf(mem_ctx, "<GUID=%s>", 
453                                                  guid),
454                                  "Clear extended linearized DN incorrect");
455
456         torture_assert_str_equal(torture, ldb_dn_extended_linearized(mem_ctx, dn, 0),
457                                  talloc_asprintf(mem_ctx, "<GUID=%s>", 
458                                                  hex_guid),
459                                  "HEX extended linearized DN incorrect");
460
461         /* Now check a 'just GUID' DN (HEX format) */
462         torture_assert(torture, 
463                        dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>",
464                                            hex_guid), 
465                        "Failed to create an 'extended' DN");
466
467         torture_assert(torture, 
468                        ldb_dn_validate(dn),
469                        "Failed to validate 'extended' DN");
470
471         torture_assert(torture, ldb_dn_has_extended(dn) == true, 
472                        "Should find extended DN to be 'extended'");
473
474         torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") == NULL, 
475                        "Should not find an SID on this DN");
476
477         torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") != NULL, 
478                        "Should find an GUID on this DN");
479         
480         torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "GUID"), guid_blob, 
481                                        "Extended DN GUID incorect");
482
483         torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "", 
484                                  "linearized DN incorrect");
485
486         /* Now check a 'just SID' DN (clear format) */
487         torture_assert(torture, 
488                        dn = ldb_dn_new_fmt(mem_ctx, ldb, "<SID=%s>",
489                                            sid), 
490                        "Failed to create an 'extended' DN");
491
492         torture_assert(torture, 
493                        ldb_dn_validate(dn),
494                        "Failed to validate 'extended' DN");
495
496         torture_assert(torture, ldb_dn_has_extended(dn) == true, 
497                        "Should find extended DN to be 'extended'");
498
499         torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") == NULL, 
500                        "Should not find an SID on this DN");
501
502         torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") != NULL, 
503                        "Should find an SID on this DN");
504         
505         torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "SID"), sid_blob, 
506                                        "Extended DN SID incorect");
507
508         torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "", 
509                                  "linearized DN incorrect");
510
511         torture_assert_str_equal(torture, ldb_dn_extended_linearized(mem_ctx, dn, 1),
512                                  talloc_asprintf(mem_ctx, "<SID=%s>", 
513                                                  sid),
514                                  "Clear extended linearized DN incorrect");
515
516         torture_assert_str_equal(torture, ldb_dn_extended_linearized(mem_ctx, dn, 0),
517                                  talloc_asprintf(mem_ctx, "<SID=%s>", 
518                                                  hex_sid),
519                                  "HEX extended linearized DN incorrect");
520
521         /* Now check a 'just SID' DN (HEX format) */
522         torture_assert(torture, 
523                        dn = ldb_dn_new_fmt(mem_ctx, ldb, "<SID=%s>",
524                                            hex_sid), 
525                        "Failed to create an 'extended' DN");
526
527         torture_assert(torture, 
528                        ldb_dn_validate(dn),
529                        "Failed to validate 'extended' DN");
530
531         torture_assert(torture, ldb_dn_has_extended(dn) == true, 
532                        "Should find extended DN to be 'extended'");
533
534         torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") == NULL, 
535                        "Should not find an SID on this DN");
536
537         torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") != NULL, 
538                        "Should find an SID on this DN");
539         
540         torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "SID"), sid_blob, 
541                                        "Extended DN SID incorect");
542
543         torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "", 
544                                  "linearized DN incorrect");
545
546         talloc_free(mem_ctx);
547         return true;
548 }
549
550
551 static bool torture_ldb_dn(struct torture_context *torture)
552 {
553         TALLOC_CTX *mem_ctx = talloc_new(torture);
554         struct ldb_context *ldb;
555         struct ldb_dn *dn;
556         struct ldb_dn *child_dn;
557         struct ldb_dn *typo_dn;
558
559         torture_assert(torture, 
560                        ldb = ldb_init(mem_ctx, torture->ev),
561                        "Failed to init ldb");
562
563         torture_assert_int_equal(torture, 
564                                  ldb_register_samba_handlers(ldb), 0, 
565                                  "Failed to register Samba handlers");
566
567         ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
568
569         /* Check behaviour of a normal DN */
570         torture_assert(torture, 
571                        dn = ldb_dn_new(mem_ctx, ldb, NULL), 
572                        "Failed to create a NULL DN");
573
574         torture_assert(torture, 
575                        ldb_dn_validate(dn),
576                        "Failed to validate NULL DN");
577
578         torture_assert(torture, 
579                        ldb_dn_add_base_fmt(dn, "dc=org"), 
580                        "Failed to add base DN");
581
582         torture_assert(torture, 
583                        ldb_dn_add_child_fmt(dn, "dc=samba"), 
584                        "Failed to add base DN");
585
586         torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "dc=samba,dc=org", 
587                                  "linearized DN incorrect");
588
589         torture_assert_str_equal(torture, ldb_dn_extended_linearized(mem_ctx, dn, 0), "dc=samba,dc=org", 
590                                  "extended linearized DN incorrect");
591
592         /* Check child DN comparisons */
593         torture_assert(torture, 
594                        child_dn = ldb_dn_new(mem_ctx, ldb, "CN=users,DC=SAMBA,DC=org"), 
595                        "Failed to create child DN");
596
597         torture_assert(torture, 
598                        ldb_dn_compare(dn, child_dn) != 0,
599                        "Comparison on dc=samba,dc=org and CN=users,DC=SAMBA,DC=org should != 0");
600
601         torture_assert(torture, 
602                        ldb_dn_compare_base(child_dn, dn) != 0,
603                        "Base Comparison of CN=users,DC=SAMBA,DC=org and dc=samba,dc=org should != 0");
604
605         torture_assert(torture, 
606                        ldb_dn_compare_base(dn, child_dn) == 0,
607                        "Base Comparison on dc=samba,dc=org and CN=users,DC=SAMBA,DC=org should == 0");
608
609         /* Check comparisons with a truncated DN */
610         torture_assert(torture, 
611                        typo_dn = ldb_dn_new(mem_ctx, ldb, "c=samba,dc=org"), 
612                        "Failed to create 'typo' DN");
613
614         torture_assert(torture, 
615                        ldb_dn_compare(dn, typo_dn) != 0,
616                        "Comparison on dc=samba,dc=org and c=samba,dc=org should != 0");
617
618         torture_assert(torture, 
619                        ldb_dn_compare_base(typo_dn, dn) != 0,
620                        "Base Comparison of c=samba,dc=org and dc=samba,dc=org should != 0");
621
622         torture_assert(torture, 
623                        ldb_dn_compare_base(dn, typo_dn) != 0,
624                        "Base Comparison on dc=samba,dc=org and c=samba,dc=org should != 0");
625
626         talloc_free(mem_ctx);
627         return true;
628 }
629
630 static bool torture_ldb_dn_invalid_extended(struct torture_context *torture)
631 {
632         TALLOC_CTX *mem_ctx = talloc_new(torture);
633         struct ldb_context *ldb;
634         struct ldb_dn *dn;
635
636         const char *dn_str = "cn=admin,cn=users,dc=samba,dc=org";
637
638         torture_assert(torture, 
639                        ldb = ldb_init(mem_ctx, torture->ev),
640                        "Failed to init ldb");
641
642         torture_assert_int_equal(torture, 
643                                  ldb_register_samba_handlers(ldb), 0, 
644                                  "Failed to register Samba handlers");
645
646         ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
647
648         /* Check behaviour of a normal DN */
649         torture_assert(torture, 
650                        dn = ldb_dn_new(mem_ctx, ldb, "samba,dc=org"), 
651                        "Failed to create a 'normal' invalid DN");
652
653         torture_assert(torture, 
654                        ldb_dn_validate(dn) == false,
655                        "should have failed to validate 'normal' invalid DN");
656
657         /* Now make an extended DN */
658         torture_assert(torture, 
659                        dn = ldb_dn_new_fmt(mem_ctx, ldb, "<PID=%s>;%s",
660                                            sid, dn_str), 
661                        "Failed to create an invalid 'extended' DN");
662
663         torture_assert(torture, 
664                        ldb_dn_validate(dn) == false,
665                        "should have failed to validate 'extended' DN");
666
667         torture_assert(torture, 
668                        dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>%s",
669                                            sid, dn_str), 
670                        "Failed to create an invalid 'extended' DN");
671
672         torture_assert(torture, 
673                        ldb_dn_validate(dn) == false,
674                        "should have failed to validate 'extended' DN");
675
676         torture_assert(torture, 
677                        dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>;",
678                                            sid), 
679                        "Failed to create an invalid 'extended' DN");
680
681         torture_assert(torture, 
682                        ldb_dn_validate(dn) == false,
683                        "should have failed to validate 'extended' DN");
684
685         torture_assert(torture, 
686                        dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>;",
687                                            hex_sid), 
688                        "Failed to create an invalid 'extended' DN");
689
690         torture_assert(torture, 
691                        ldb_dn_validate(dn) == false,
692                        "should have failed to validate 'extended' DN");
693
694         torture_assert(torture, 
695                        dn = ldb_dn_new_fmt(mem_ctx, ldb, "<SID=%s>;",
696                                            hex_guid), 
697                        "Failed to create an invalid 'extended' DN");
698
699         torture_assert(torture, 
700                        ldb_dn_validate(dn) == false,
701                        "should have failed to validate 'extended' DN");
702
703         torture_assert(torture, 
704                        dn = ldb_dn_new_fmt(mem_ctx, ldb, "<SID=%s>;",
705                                            guid), 
706                        "Failed to create an invalid 'extended' DN");
707
708         torture_assert(torture, 
709                        ldb_dn_validate(dn) == false,
710                        "should have failed to validate 'extended' DN");
711
712         torture_assert(torture, 
713                        dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=>"), 
714                        "Failed to create an invalid 'extended' DN");
715
716         torture_assert(torture, 
717                        ldb_dn_validate(dn) == false,
718                        "should have failed to validate 'extended' DN");
719
720         return true;
721 }
722
723 NTSTATUS torture_ldb_init(void)
724 {
725         struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "LDB");
726         torture_suite_add_simple_test(suite, "ATTRS", torture_ldb_attrs);
727         torture_suite_add_simple_test(suite, "DN-ATTRS", torture_ldb_dn_attrs);
728         torture_suite_add_simple_test(suite, "DN-EXTENDED", torture_ldb_dn_extended);
729         torture_suite_add_simple_test(suite, "DN-INVALID-EXTENDED", torture_ldb_dn_invalid_extended);
730         torture_suite_add_simple_test(suite, "DN", torture_ldb_dn);
731
732         suite->description = talloc_strdup(suite, "LDB (samba-specific behaviour) tests");
733
734         torture_register_suite(suite);
735
736         return NT_STATUS_OK;
737 }