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