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