Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : Test DSDB syntax 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 : #include "param/provision.h"
33 :
34 :
35 : struct torture_dsdb_syntax {
36 : struct ldb_context *ldb;
37 : struct dsdb_schema *schema;
38 : };
39 :
40 10 : DATA_BLOB hexstr_to_data_blob(TALLOC_CTX *mem_ctx, const char *string)
41 : {
42 10 : DATA_BLOB binary = data_blob_talloc(mem_ctx, NULL, strlen(string)/2);
43 10 : binary.length = strhex_to_str((char *)binary.data, binary.length, string, strlen(string));
44 10 : return binary;
45 : }
46 :
47 1 : static bool torture_syntax_add_OR_Name(struct torture_context *tctx,
48 : struct ldb_context *ldb,
49 : struct dsdb_schema *schema)
50 : {
51 1 : WERROR werr;
52 1 : int ldb_res;
53 1 : struct ldb_ldif *ldif;
54 1 : const char *ldif_str = "dn: CN=ms-Exch-Auth-Orig,CN=Schema,CN=Configuration,DC=kma-exch,DC=devel\n"
55 : "changetype: add\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"
60 : "linkID: 110\n"
61 : "showInAdvancedViewOnly: TRUE\n"
62 : "adminDisplayName: ms-Exch-Auth-Orig\n"
63 : "oMObjectClass:: VgYBAgULHQ==\n"
64 : "adminDescription: ms-Exch-Auth-Orig\n"
65 : "oMSyntax: 127\n"
66 : "searchFlags: 16\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";
73 :
74 1 : ldif = ldb_ldif_read_string(ldb, &ldif_str);
75 1 : torture_assert(tctx, ldif, "Failed to parse LDIF for authOrig");
76 :
77 1 : werr = dsdb_set_attribute_from_ldb(ldb, schema, ldif->msg);
78 1 : ldb_ldif_read_free(ldb, ldif);
79 1 : torture_assert_werr_ok(tctx, werr, "dsdb_set_attribute_from_ldb() failed!");
80 :
81 1 : ldb_res = dsdb_set_schema(ldb, schema, SCHEMA_WRITE);
82 1 : torture_assert_int_equal(tctx, ldb_res, LDB_SUCCESS, "dsdb_set_schema() failed");
83 :
84 0 : return true;
85 : };
86 :
87 10 : static bool torture_test_syntax(struct torture_context *torture,
88 : struct torture_dsdb_syntax *priv,
89 : const char *oid,
90 : const char *attr_string,
91 : const char *ldb_str,
92 : const char *drs_str)
93 : {
94 10 : TALLOC_CTX *tmp_ctx = talloc_new(torture);
95 10 : DATA_BLOB drs_binary = hexstr_to_data_blob(tmp_ctx, drs_str);
96 10 : DATA_BLOB ldb_blob = data_blob_string_const(ldb_str);
97 10 : struct drsuapi_DsReplicaAttribute drs, drs2;
98 10 : struct drsuapi_DsAttributeValue val;
99 10 : const struct dsdb_syntax *syntax;
100 10 : const struct dsdb_attribute *attr;
101 10 : struct ldb_message_element el;
102 10 : struct ldb_context *ldb = priv->ldb;
103 10 : struct dsdb_schema *schema = priv->schema;
104 10 : struct dsdb_syntax_ctx syntax_ctx;
105 :
106 : /* use default syntax conversion context */
107 10 : dsdb_syntax_ctx_init(&syntax_ctx, ldb, schema);
108 :
109 10 : drs.value_ctr.num_values = 1;
110 10 : drs.value_ctr.values = &val;
111 10 : val.blob = &drs_binary;
112 :
113 10 : torture_assert(torture, syntax = find_syntax_map_by_standard_oid(oid), "Failed to find syntax handler");
114 10 : torture_assert(torture, attr = dsdb_attribute_by_lDAPDisplayName(schema, attr_string), "Failed to find attribute handler");
115 10 : torture_assert_str_equal(torture, attr->syntax->name, syntax->name, "Syntax from schema not as expected");
116 :
117 :
118 10 : torture_assert_werr_ok(torture, syntax->drsuapi_to_ldb(&syntax_ctx, attr, &drs, tmp_ctx, &el), "Failed to convert from DRS to ldb format");
119 :
120 10 : torture_assert_data_blob_equal(torture, el.values[0], ldb_blob, "Incorrect conversion from DRS to ldb format");
121 :
122 10 : torture_assert_werr_ok(torture, syntax->validate_ldb(&syntax_ctx, attr, &el), "Failed to validate ldb format");
123 :
124 10 : torture_assert_werr_ok(torture, syntax->ldb_to_drsuapi(&syntax_ctx, attr, &el, tmp_ctx, &drs2), "Failed to convert from ldb to DRS format");
125 :
126 10 : torture_assert(torture, drs2.value_ctr.values[0].blob, "No blob returned from conversion");
127 :
128 10 : torture_assert_data_blob_equal(torture, *drs2.value_ctr.values[0].blob, drs_binary, "Incorrect conversion from ldb to DRS format");
129 0 : return true;
130 : }
131 :
132 1 : static bool torture_dsdb_drs_DN_BINARY(struct torture_context *torture, struct torture_dsdb_syntax *priv)
133 : {
134 1 : bool ret;
135 1 : const char *ldb_str = "B:32:A9D1CA15768811D1ADED00C04FD8D5CD:<GUID=a8378c29-6319-45b3-b216-6a3108452d6c>;CN=Users,DC=ad,DC=ruth,DC=abartlet,DC=net";
136 1 : const char *drs_str = "8C00000000000000298C37A81963B345B2166A3108452D6C000000000000000000000000000000000000000000000000000000002900000043004E003D00550073006500720073002C00440043003D00610064002C00440043003D0072007500740068002C00440043003D00610062006100720074006C00650074002C00440043003D006E0065007400000014000000A9D1CA15768811D1ADED00C04FD8D5CD";
137 1 : 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 1 : const char *drs_str2 = "7A000000180000000852472B8031D44AB6BBA26CFB44AC50010400000000000515000000C68AB9DBABB440B9344D706C0000000020000000440043003D00610064002C00440043003D0072007500740068002C00440043003D00610062006100720074006C00650074002C00440043003D006E0065007400000000000800000000000002";
139 1 : ret = torture_test_syntax(torture, priv, DSDB_SYNTAX_BINARY_DN, "wellKnownObjects", ldb_str, drs_str);
140 1 : if (!ret) return false;
141 1 : return torture_test_syntax(torture, priv, DSDB_SYNTAX_BINARY_DN, "msDS-HasInstantiatedNCs", ldb_str2, drs_str2);
142 : }
143 :
144 1 : static bool torture_dsdb_drs_DN(struct torture_context *torture, struct torture_dsdb_syntax *priv)
145 : {
146 1 : const char *ldb_str = "<GUID=fbee08fd-6f75-4bd4-af3f-e4f063a6379e>;OU=Domain Controllers,DC=ad,DC=naomi,DC=abartlet,DC=net";
147 1 : const char *drs_str = "A800000000000000FD08EEFB756FD44BAF3FE4F063A6379E00000000000000000000000000000000000000000000000000000000370000004F0055003D0044006F006D00610069006E00200043006F006E00740072006F006C006C006500720073002C00440043003D00610064002C00440043003D006E0061006F006D0069002C00440043003D00610062006100720074006C00650074002C00440043003D006E00650074000000";
148 1 : if (!torture_test_syntax(torture, priv, LDB_SYNTAX_DN, "lastKnownParent", ldb_str, drs_str)) {
149 0 : return false;
150 : }
151 :
152 : /* extended_dn with GUID and SID in it */
153 1 : 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 1 : drs_str = "960000001C000000167DCC23A03D3A4F99210AD60A99230F0105000000000005150000009CA04DCC46A0A763E4B37BA4F40100002E00000043004E003D00410064006D0069006E006900730074007200610074006F0072002C0043004E003D00550073006500720073002C00440043003D006B006D0061002D0065007800630068002C00440043003D0064006500760065006C000000";
155 1 : return torture_test_syntax(torture, priv, LDB_SYNTAX_DN, "lastKnownParent", ldb_str, drs_str);
156 : }
157 :
158 1 : static bool torture_dsdb_drs_OR_Name(struct torture_context *torture, struct torture_dsdb_syntax *priv)
159 : {
160 1 : 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 1 : const char *drs_str = "960000001C000000167DCC23A03D3A4F99210AD60A99230F0105000000000005150000009CA04DCC46A0A763E4B37BA4F40100002E00000043004E003D00410064006D0069006E006900730074007200610074006F0072002C0043004E003D00550073006500720073002C00440043003D006B006D0061002D0065007800630068002C00440043003D0064006500760065006C000000000004000000";
162 1 : return torture_test_syntax(torture, priv, DSDB_SYNTAX_OR_NAME, "authOrig", ldb_str, drs_str);
163 : }
164 :
165 1 : static bool torture_dsdb_drs_INT32(struct torture_context *torture, struct torture_dsdb_syntax *priv)
166 : {
167 1 : const char *ldb_str = "532480";
168 1 : const char *drs_str = "00200800";
169 1 : return torture_test_syntax(torture, priv, LDB_SYNTAX_INTEGER, "userAccountControl", ldb_str, drs_str);
170 : }
171 :
172 1 : static bool torture_dsdb_drs_INT64(struct torture_context *torture, struct torture_dsdb_syntax *priv)
173 : {
174 1 : const char *ldb_str = "129022979538281250";
175 1 : const char *drs_str = "22E33D5FB761CA01";
176 1 : return torture_test_syntax(torture, priv, "1.2.840.113556.1.4.906", "pwdLastSet", ldb_str, drs_str);
177 : }
178 :
179 1 : static bool torture_dsdb_drs_NTTIME(struct torture_context *torture, struct torture_dsdb_syntax *priv)
180 : {
181 1 : const char *ldb_str = "20091109003446.0Z";
182 1 : const char *drs_str = "A6F4070103000000";
183 1 : return torture_test_syntax(torture, priv, "1.3.6.1.4.1.1466.115.121.1.24", "whenCreated", ldb_str, drs_str);
184 : }
185 :
186 1 : static bool torture_dsdb_drs_BOOL(struct torture_context *torture, struct torture_dsdb_syntax *priv)
187 : {
188 1 : const char *ldb_str = "TRUE";
189 1 : const char *drs_str = "01000000";
190 1 : return torture_test_syntax(torture, priv, LDB_SYNTAX_BOOLEAN, "isDeleted", ldb_str, drs_str);
191 : }
192 :
193 1 : static bool torture_dsdb_drs_UNICODE(struct torture_context *torture, struct torture_dsdb_syntax *priv)
194 : {
195 1 : const char *ldb_str = "primaryTelexNumber,Numéro de télex";
196 1 : const char *drs_str = "7000720069006D00610072007900540065006C00650078004E0075006D006200650072002C004E0075006D00E90072006F0020006400650020007400E9006C0065007800";
197 1 : return torture_test_syntax(torture, priv, LDB_SYNTAX_DIRECTORY_STRING, "attributeDisplayNames", ldb_str, drs_str);
198 : }
199 :
200 : /*
201 : * DSDB-SYNTAX fixture setup/teardown handlers implementation
202 : */
203 1 : static bool torture_dsdb_syntax_tcase_setup(struct torture_context *tctx, void **data)
204 : {
205 1 : struct torture_dsdb_syntax *priv;
206 :
207 1 : priv = talloc_zero(tctx, struct torture_dsdb_syntax);
208 1 : torture_assert(tctx, priv, "No memory");
209 :
210 1 : priv->ldb = provision_get_schema(priv, tctx->lp_ctx, NULL, NULL);
211 1 : torture_assert(tctx, priv->ldb, "Failed to load schema from disk");
212 :
213 1 : priv->schema = dsdb_get_schema(priv->ldb, NULL);
214 1 : torture_assert(tctx, priv->schema, "Failed to fetch schema");
215 :
216 : /* add 'authOrig' attribute with OR-Name syntax to schema */
217 1 : if (!torture_syntax_add_OR_Name(tctx, priv->ldb, priv->schema)) {
218 0 : return false;
219 : }
220 :
221 1 : *data = priv;
222 1 : return true;
223 : }
224 :
225 1 : static bool torture_dsdb_syntax_tcase_teardown(struct torture_context *tctx, void *data)
226 : {
227 1 : struct torture_dsdb_syntax *priv;
228 :
229 1 : priv = talloc_get_type_abort(data, struct torture_dsdb_syntax);
230 1 : talloc_unlink(priv, priv->ldb);
231 1 : talloc_free(priv);
232 :
233 1 : return true;
234 : }
235 :
236 : /**
237 : * DSDB-SYNTAX test suite creation
238 : */
239 2354 : struct torture_suite *torture_dsdb_syntax(TALLOC_CTX *mem_ctx)
240 : {
241 125 : typedef bool (*pfn_run)(struct torture_context *, void *);
242 :
243 125 : struct torture_tcase *tc;
244 2354 : struct torture_suite *suite = torture_suite_create(mem_ctx, "dsdb.syntax");
245 :
246 2354 : if (suite == NULL) {
247 0 : return NULL;
248 : }
249 :
250 2354 : tc = torture_suite_add_tcase(suite, "tc");
251 2354 : if (!tc) {
252 0 : return NULL;
253 : }
254 :
255 2354 : torture_tcase_set_fixture(tc,
256 : torture_dsdb_syntax_tcase_setup,
257 : torture_dsdb_syntax_tcase_teardown);
258 :
259 2354 : torture_tcase_add_simple_test(tc, "DN-BINARY", (pfn_run)torture_dsdb_drs_DN_BINARY);
260 2354 : torture_tcase_add_simple_test(tc, "DN", (pfn_run)torture_dsdb_drs_DN);
261 2354 : torture_tcase_add_simple_test(tc, "OR-Name", (pfn_run)torture_dsdb_drs_OR_Name);
262 2354 : torture_tcase_add_simple_test(tc, "INT32", (pfn_run)torture_dsdb_drs_INT32);
263 2354 : torture_tcase_add_simple_test(tc, "INT64", (pfn_run)torture_dsdb_drs_INT64);
264 2354 : torture_tcase_add_simple_test(tc, "NTTIME", (pfn_run)torture_dsdb_drs_NTTIME);
265 2354 : torture_tcase_add_simple_test(tc, "BOOL", (pfn_run)torture_dsdb_drs_BOOL);
266 2354 : torture_tcase_add_simple_test(tc, "UNICODE", (pfn_run)torture_dsdb_drs_UNICODE);
267 :
268 2354 : suite->description = talloc_strdup(suite, "DSDB syntax tests");
269 :
270 2354 : return suite;
271 : }
|