2 Unix SMB/CIFS implementation.
4 Test DSDB syntax functions
6 Copyright (C) Andrew Bartlet <abartlet@samba.org> 2008
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.
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.
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/>.
23 #include "lib/events/events.h"
25 #include <ldb_errors.h>
26 #include "lib/ldb-samba/ldif_handlers.h"
28 #include "dsdb/samdb/samdb.h"
29 #include "param/param.h"
30 #include "torture/smbtorture.h"
31 #include "torture/local/proto.h"
32 #include "param/provision.h"
35 struct torture_dsdb_syntax
{
36 struct ldb_context
*ldb
;
37 struct dsdb_schema
*schema
;
40 DATA_BLOB
hexstr_to_data_blob(TALLOC_CTX
*mem_ctx
, const char *string
)
42 DATA_BLOB binary
= data_blob_talloc(mem_ctx
, NULL
, strlen(string
)/2);
43 binary
.length
= strhex_to_str((char *)binary
.data
, binary
.length
, string
, strlen(string
));
47 static bool torture_syntax_add_OR_Name(struct torture_context
*tctx
,
48 struct ldb_context
*ldb
,
49 struct dsdb_schema
*schema
)
53 struct ldb_ldif
*ldif
;
54 const char *ldif_str
= "dn: CN=ms-Exch-Auth-Orig,CN=Schema,CN=Configuration,DC=kma-exch,DC=devel\n"
56 "cn: ms-Exch-Auth-Orig\n"
57 "attributeID: 1.2.840.113556.1.2.129\n"
58 "attributeSyntax: 2.5.5.7\n"
59 "isSingleValued: FALSE\n"
61 "showInAdvancedViewOnly: TRUE\n"
62 "adminDisplayName: ms-Exch-Auth-Orig\n"
63 "oMObjectClass:: VgYBAgULHQ==\n"
64 "adminDescription: ms-Exch-Auth-Orig\n"
67 "lDAPDisplayName: authOrig\n"
68 "name: ms-Exch-Auth-Orig\n"
69 "objectGUID:: 7tqEWktjAUqsZXqsFPQpRg==\n"
70 "schemaIDGUID:: l3PfqOrF0RG7ywCAx2ZwwA==\n"
71 "attributeSecurityGUID:: VAGN5Pi80RGHAgDAT7lgUA==\n"
72 "isMemberOfPartialAttributeSet: TRUE\n";
74 ldif
= ldb_ldif_read_string(ldb
, &ldif_str
);
75 torture_assert(tctx
, ldif
, "Failed to parse LDIF for authOrig");
77 werr
= dsdb_set_attribute_from_ldb(ldb
, schema
, ldif
->msg
);
78 ldb_ldif_read_free(ldb
, ldif
);
79 torture_assert_werr_ok(tctx
, werr
, "dsdb_set_attribute_from_ldb() failed!");
81 ldb_res
= dsdb_set_schema(ldb
, schema
, SCHEMA_WRITE
);
82 torture_assert_int_equal(tctx
, ldb_res
, LDB_SUCCESS
, "dsdb_set_schema() failed");
87 static bool torture_test_syntax(struct torture_context
*torture
,
88 struct torture_dsdb_syntax
*priv
,
90 const char *attr_string
,
94 TALLOC_CTX
*tmp_ctx
= talloc_new(torture
);
95 DATA_BLOB drs_binary
= hexstr_to_data_blob(tmp_ctx
, drs_str
);
96 DATA_BLOB ldb_blob
= data_blob_string_const(ldb_str
);
97 struct drsuapi_DsReplicaAttribute drs
, drs2
;
98 struct drsuapi_DsAttributeValue val
;
99 const struct dsdb_syntax
*syntax
;
100 const struct dsdb_attribute
*attr
;
101 struct ldb_message_element el
;
102 struct ldb_context
*ldb
= priv
->ldb
;
103 struct dsdb_schema
*schema
= priv
->schema
;
104 struct dsdb_syntax_ctx syntax_ctx
;
106 /* use default syntax conversion context */
107 dsdb_syntax_ctx_init(&syntax_ctx
, ldb
, schema
);
109 drs
.value_ctr
.num_values
= 1;
110 drs
.value_ctr
.values
= &val
;
111 val
.blob
= &drs_binary
;
113 torture_assert(torture
, syntax
= find_syntax_map_by_standard_oid(oid
), "Failed to find syntax handler");
114 torture_assert(torture
, attr
= dsdb_attribute_by_lDAPDisplayName(schema
, attr_string
), "Failed to find attribute handler");
115 torture_assert_str_equal(torture
, attr
->syntax
->name
, syntax
->name
, "Syntax from schema not as expected");
118 torture_assert_werr_ok(torture
, syntax
->drsuapi_to_ldb(&syntax_ctx
, attr
, &drs
, tmp_ctx
, &el
), "Failed to convert from DRS to ldb format");
120 torture_assert_data_blob_equal(torture
, el
.values
[0], ldb_blob
, "Incorrect conversion from DRS to ldb format");
122 torture_assert_werr_ok(torture
, syntax
->validate_ldb(&syntax_ctx
, attr
, &el
), "Failed to validate ldb format");
124 torture_assert_werr_ok(torture
, syntax
->ldb_to_drsuapi(&syntax_ctx
, attr
, &el
, tmp_ctx
, &drs2
), "Failed to convert from ldb to DRS format");
126 torture_assert(torture
, drs2
.value_ctr
.values
[0].blob
, "No blob returned from conversion");
128 torture_assert_data_blob_equal(torture
, *drs2
.value_ctr
.values
[0].blob
, drs_binary
, "Incorrect conversion from ldb to DRS format");
132 static bool torture_dsdb_drs_DN_BINARY(struct torture_context
*torture
, struct torture_dsdb_syntax
*priv
)
135 const char *ldb_str
= "B:32:A9D1CA15768811D1ADED00C04FD8D5CD:<GUID=a8378c29-6319-45b3-b216-6a3108452d6c>;CN=Users,DC=ad,DC=ruth,DC=abartlet,DC=net";
136 const char *drs_str
= "8C00000000000000298C37A81963B345B2166A3108452D6C000000000000000000000000000000000000000000000000000000002900000043004E003D00550073006500720073002C00440043003D00610064002C00440043003D0072007500740068002C00440043003D00610062006100720074006C00650074002C00440043003D006E0065007400000014000000A9D1CA15768811D1ADED00C04FD8D5CD";
137 const char *ldb_str2
= "B:8:00000002:<GUID=2b475208-3180-4ad4-b6bb-a26cfb44ac50>;<SID=S-1-5-21-3686369990-3108025515-1819299124>;DC=ad,DC=ruth,DC=abartlet,DC=net";
138 const char *drs_str2
= "7A000000180000000852472B8031D44AB6BBA26CFB44AC50010400000000000515000000C68AB9DBABB440B9344D706C0000000020000000440043003D00610064002C00440043003D0072007500740068002C00440043003D00610062006100720074006C00650074002C00440043003D006E0065007400000000000800000000000002";
139 ret
= torture_test_syntax(torture
, priv
, DSDB_SYNTAX_BINARY_DN
, "wellKnownObjects", ldb_str
, drs_str
);
140 if (!ret
) return false;
141 return torture_test_syntax(torture
, priv
, DSDB_SYNTAX_BINARY_DN
, "msDS-HasInstantiatedNCs", ldb_str2
, drs_str2
);
144 static bool torture_dsdb_drs_DN(struct torture_context
*torture
, struct torture_dsdb_syntax
*priv
)
146 const char *ldb_str
= "<GUID=fbee08fd-6f75-4bd4-af3f-e4f063a6379e>;OU=Domain Controllers,DC=ad,DC=naomi,DC=abartlet,DC=net";
147 const char *drs_str
= "A800000000000000FD08EEFB756FD44BAF3FE4F063A6379E00000000000000000000000000000000000000000000000000000000370000004F0055003D0044006F006D00610069006E00200043006F006E00740072006F006C006C006500720073002C00440043003D00610064002C00440043003D006E0061006F006D0069002C00440043003D00610062006100720074006C00650074002C00440043003D006E00650074000000";
148 if (!torture_test_syntax(torture
, priv
, LDB_SYNTAX_DN
, "lastKnownParent", ldb_str
, drs_str
)) {
152 /* extended_dn with GUID and SID in it */
153 ldb_str
= "<GUID=23cc7d16-3da0-4f3a-9921-0ad60a99230f>;<SID=S-1-5-21-3427639452-1671929926-2759570404-500>;CN=Administrator,CN=Users,DC=kma-exch,DC=devel";
154 drs_str
= "960000001C000000167DCC23A03D3A4F99210AD60A99230F0105000000000005150000009CA04DCC46A0A763E4B37BA4F40100002E00000043004E003D00410064006D0069006E006900730074007200610074006F0072002C0043004E003D00550073006500720073002C00440043003D006B006D0061002D0065007800630068002C00440043003D0064006500760065006C000000";
155 return torture_test_syntax(torture
, priv
, LDB_SYNTAX_DN
, "lastKnownParent", ldb_str
, drs_str
);
158 static bool torture_dsdb_drs_OR_Name(struct torture_context
*torture
, struct torture_dsdb_syntax
*priv
)
160 const char *ldb_str
= "<GUID=23cc7d16-3da0-4f3a-9921-0ad60a99230f>;<SID=S-1-5-21-3427639452-1671929926-2759570404-500>;CN=Administrator,CN=Users,DC=kma-exch,DC=devel";
161 const char *drs_str
= "960000001C000000167DCC23A03D3A4F99210AD60A99230F0105000000000005150000009CA04DCC46A0A763E4B37BA4F40100002E00000043004E003D00410064006D0069006E006900730074007200610074006F0072002C0043004E003D00550073006500720073002C00440043003D006B006D0061002D0065007800630068002C00440043003D0064006500760065006C000000000004000000";
162 return torture_test_syntax(torture
, priv
, DSDB_SYNTAX_OR_NAME
, "authOrig", ldb_str
, drs_str
);
165 static bool torture_dsdb_drs_INT32(struct torture_context
*torture
, struct torture_dsdb_syntax
*priv
)
167 const char *ldb_str
= "532480";
168 const char *drs_str
= "00200800";
169 return torture_test_syntax(torture
, priv
, LDB_SYNTAX_INTEGER
, "userAccountControl", ldb_str
, drs_str
);
172 static bool torture_dsdb_drs_INT64(struct torture_context
*torture
, struct torture_dsdb_syntax
*priv
)
174 const char *ldb_str
= "129022979538281250";
175 const char *drs_str
= "22E33D5FB761CA01";
176 return torture_test_syntax(torture
, priv
, "1.2.840.113556.1.4.906", "pwdLastSet", ldb_str
, drs_str
);
179 static bool torture_dsdb_drs_NTTIME(struct torture_context
*torture
, struct torture_dsdb_syntax
*priv
)
181 const char *ldb_str
= "20091109003446.0Z";
182 const char *drs_str
= "A6F4070103000000";
183 return torture_test_syntax(torture
, priv
, "1.3.6.1.4.1.1466.115.121.1.24", "whenCreated", ldb_str
, drs_str
);
186 static bool torture_dsdb_drs_BOOL(struct torture_context
*torture
, struct torture_dsdb_syntax
*priv
)
188 const char *ldb_str
= "TRUE";
189 const char *drs_str
= "01000000";
190 return torture_test_syntax(torture
, priv
, LDB_SYNTAX_BOOLEAN
, "isDeleted", ldb_str
, drs_str
);
193 static bool torture_dsdb_drs_UNICODE(struct torture_context
*torture
, struct torture_dsdb_syntax
*priv
)
195 const char *ldb_str
= "primaryTelexNumber,Numéro de télex";
196 const char *drs_str
= "7000720069006D00610072007900540065006C00650078004E0075006D006200650072002C004E0075006D00E90072006F0020006400650020007400E9006C0065007800";
197 return torture_test_syntax(torture
, priv
, LDB_SYNTAX_DIRECTORY_STRING
, "attributeDisplayNames", ldb_str
, drs_str
);
201 * DSDB-SYNTAX fixture setup/teardown handlers implementation
203 static bool torture_dsdb_syntax_tcase_setup(struct torture_context
*tctx
, void **data
)
205 struct torture_dsdb_syntax
*priv
;
207 priv
= talloc_zero(tctx
, struct torture_dsdb_syntax
);
208 torture_assert(tctx
, priv
, "No memory");
210 priv
->ldb
= provision_get_schema(priv
, tctx
->lp_ctx
, NULL
, NULL
);
211 torture_assert(tctx
, priv
->ldb
, "Failed to load schema from disk");
213 priv
->schema
= dsdb_get_schema(priv
->ldb
, NULL
);
214 torture_assert(tctx
, priv
->schema
, "Failed to fetch schema");
216 /* add 'authOrig' attribute with OR-Name syntax to schema */
217 if (!torture_syntax_add_OR_Name(tctx
, priv
->ldb
, priv
->schema
)) {
225 static bool torture_dsdb_syntax_tcase_teardown(struct torture_context
*tctx
, void *data
)
227 struct torture_dsdb_syntax
*priv
;
229 priv
= talloc_get_type_abort(data
, struct torture_dsdb_syntax
);
230 talloc_unlink(priv
, priv
->ldb
);
237 * DSDB-SYNTAX test suite creation
239 struct torture_suite
*torture_dsdb_syntax(TALLOC_CTX
*mem_ctx
)
241 typedef bool (*pfn_run
)(struct torture_context
*, void *);
243 struct torture_tcase
*tc
;
244 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "dsdb.syntax");
250 tc
= torture_suite_add_tcase(suite
, "tc");
255 torture_tcase_set_fixture(tc
,
256 torture_dsdb_syntax_tcase_setup
,
257 torture_dsdb_syntax_tcase_teardown
);
259 torture_tcase_add_simple_test(tc
, "DN-BINARY", (pfn_run
)torture_dsdb_drs_DN_BINARY
);
260 torture_tcase_add_simple_test(tc
, "DN", (pfn_run
)torture_dsdb_drs_DN
);
261 torture_tcase_add_simple_test(tc
, "OR-Name", (pfn_run
)torture_dsdb_drs_OR_Name
);
262 torture_tcase_add_simple_test(tc
, "INT32", (pfn_run
)torture_dsdb_drs_INT32
);
263 torture_tcase_add_simple_test(tc
, "INT64", (pfn_run
)torture_dsdb_drs_INT64
);
264 torture_tcase_add_simple_test(tc
, "NTTIME", (pfn_run
)torture_dsdb_drs_NTTIME
);
265 torture_tcase_add_simple_test(tc
, "BOOL", (pfn_run
)torture_dsdb_drs_BOOL
);
266 torture_tcase_add_simple_test(tc
, "UNICODE", (pfn_run
)torture_dsdb_drs_UNICODE
);
268 suite
->description
= talloc_strdup(suite
, "DSDB syntax tests");