Line data Source code
1 : /*
2 : Unix SMB/CIFS Implementation.
3 : DSDB schema syntaxes
4 :
5 : Copyright (C) Stefan Metzmacher <metze@samba.org> 2006
6 : Copyright (C) Simo Sorce 2005
7 : Copyright (C) Andrew Bartlett <abartlet@samba.org> 2008
8 :
9 : This program is free software; you can redistribute it and/or modify
10 : it under the terms of the GNU General Public License as published by
11 : the Free Software Foundation; either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program. If not, see <http://www.gnu.org/licenses/>.
21 :
22 : */
23 : #include "includes.h"
24 : #include "dsdb/samdb/samdb.h"
25 : #include "librpc/gen_ndr/ndr_drsuapi.h"
26 : #include "librpc/gen_ndr/ndr_security.h"
27 : #include "librpc/gen_ndr/ndr_misc.h"
28 : #include <ldb.h>
29 : #include <ldb_errors.h>
30 : #include "system/time.h"
31 : #include "../lib/util/charset/charset.h"
32 : #include "librpc/ndr/libndr.h"
33 : #include "../lib/util/asn1.h"
34 :
35 : #undef strcasecmp
36 :
37 : /**
38 : * Initialize dsdb_syntax_ctx with default values
39 : * for common cases.
40 : */
41 22191527 : void dsdb_syntax_ctx_init(struct dsdb_syntax_ctx *ctx,
42 : struct ldb_context *ldb,
43 : const struct dsdb_schema *schema)
44 : {
45 22191527 : ctx->ldb = ldb;
46 22191527 : ctx->schema = schema;
47 :
48 : /*
49 : * 'true' will keep current behavior,
50 : * i.e. attributeID_id will be returned by default
51 : */
52 22191527 : ctx->is_schema_nc = true;
53 :
54 22191527 : ctx->pfm_remote = NULL;
55 22191527 : }
56 :
57 :
58 : /**
59 : * Returns ATTID for DRS attribute.
60 : *
61 : * ATTID depends on whether we are replicating
62 : * Schema NC or msDs-IntId is set for schemaAttribute
63 : * for the attribute.
64 : */
65 46629124 : uint32_t dsdb_attribute_get_attid(const struct dsdb_attribute *attr,
66 : bool for_schema_nc)
67 : {
68 46629124 : if (!for_schema_nc && attr->msDS_IntId) {
69 3468 : return attr->msDS_IntId;
70 : }
71 :
72 46625656 : return attr->attributeID_id;
73 : }
74 :
75 : /**
76 : * Map an ATTID from remote DC to a local ATTID
77 : * using remote prefixMap
78 : */
79 14969283 : static bool dsdb_syntax_attid_from_remote_attid(const struct dsdb_syntax_ctx *ctx,
80 : TALLOC_CTX *mem_ctx,
81 : uint32_t id_remote,
82 : uint32_t *id_local)
83 : {
84 460685 : WERROR werr;
85 460685 : const char *oid;
86 :
87 : /*
88 : * map remote ATTID to local directly in case
89 : * of no remote prefixMap (during provision for instance)
90 : */
91 14969283 : if (!ctx->pfm_remote) {
92 2997217 : *id_local = id_remote;
93 2997217 : return true;
94 : }
95 :
96 11972066 : werr = dsdb_schema_pfm_oid_from_attid(ctx->pfm_remote, id_remote, mem_ctx, &oid);
97 11972066 : if (!W_ERROR_IS_OK(werr)) {
98 0 : DEBUG(0,("ATTID->OID failed (%s) for: 0x%08X\n", win_errstr(werr), id_remote));
99 0 : return false;
100 : }
101 :
102 11972066 : werr = dsdb_schema_pfm_attid_from_oid(ctx->schema->prefixmap, oid, id_local);
103 11972066 : if (!W_ERROR_IS_OK(werr)) {
104 0 : DEBUG(0,("OID->ATTID failed (%s) for: %s\n", win_errstr(werr), oid));
105 0 : return false;
106 : }
107 :
108 11972066 : return true;
109 : }
110 :
111 0 : static WERROR dsdb_syntax_FOOBAR_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
112 : const struct dsdb_attribute *attr,
113 : const struct drsuapi_DsReplicaAttribute *in,
114 : TALLOC_CTX *mem_ctx,
115 : struct ldb_message_element *out)
116 : {
117 0 : unsigned int i;
118 :
119 0 : out->flags = 0;
120 0 : out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
121 0 : W_ERROR_HAVE_NO_MEMORY(out->name);
122 :
123 0 : out->num_values = in->value_ctr.num_values;
124 0 : out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
125 0 : W_ERROR_HAVE_NO_MEMORY(out->values);
126 :
127 0 : for (i=0; i < out->num_values; i++) {
128 0 : char *str;
129 :
130 0 : if (in->value_ctr.values[i].blob == NULL) {
131 0 : return WERR_FOOBAR;
132 : }
133 :
134 0 : str = talloc_asprintf(out->values, "%s: not implemented",
135 0 : attr->syntax->name);
136 0 : W_ERROR_HAVE_NO_MEMORY(str);
137 :
138 0 : out->values[i] = data_blob_string_const(str);
139 : }
140 :
141 0 : return WERR_OK;
142 : }
143 :
144 0 : static WERROR dsdb_syntax_FOOBAR_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
145 : const struct dsdb_attribute *attr,
146 : const struct ldb_message_element *in,
147 : TALLOC_CTX *mem_ctx,
148 : struct drsuapi_DsReplicaAttribute *out)
149 : {
150 0 : return WERR_FOOBAR;
151 : }
152 :
153 0 : static WERROR dsdb_syntax_FOOBAR_validate_ldb(const struct dsdb_syntax_ctx *ctx,
154 : const struct dsdb_attribute *attr,
155 : const struct ldb_message_element *in)
156 : {
157 0 : return WERR_FOOBAR;
158 : }
159 :
160 2392125 : static WERROR dsdb_syntax_BOOL_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
161 : const struct dsdb_attribute *attr,
162 : const struct drsuapi_DsReplicaAttribute *in,
163 : TALLOC_CTX *mem_ctx,
164 : struct ldb_message_element *out)
165 : {
166 144910 : unsigned int i;
167 :
168 2392125 : out->flags = 0;
169 2392125 : out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
170 2392125 : W_ERROR_HAVE_NO_MEMORY(out->name);
171 :
172 2392125 : out->num_values = in->value_ctr.num_values;
173 2392125 : out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
174 2392125 : W_ERROR_HAVE_NO_MEMORY(out->values);
175 :
176 4770830 : for (i=0; i < out->num_values; i++) {
177 144910 : uint32_t v;
178 144910 : char *str;
179 :
180 2378705 : if (in->value_ctr.values[i].blob == NULL) {
181 0 : return WERR_FOOBAR;
182 : }
183 :
184 2378705 : if (in->value_ctr.values[i].blob->length != 4) {
185 0 : return WERR_FOOBAR;
186 : }
187 :
188 2378705 : v = IVAL(in->value_ctr.values[i].blob->data, 0);
189 :
190 2378705 : if (v != 0) {
191 1854879 : str = talloc_strdup(out->values, "TRUE");
192 1854879 : W_ERROR_HAVE_NO_MEMORY(str);
193 : } else {
194 523826 : str = talloc_strdup(out->values, "FALSE");
195 523826 : W_ERROR_HAVE_NO_MEMORY(str);
196 : }
197 :
198 2378705 : out->values[i] = data_blob_string_const(str);
199 : }
200 :
201 2392125 : return WERR_OK;
202 : }
203 :
204 2070142 : static WERROR dsdb_syntax_BOOL_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
205 : const struct dsdb_attribute *attr,
206 : const struct ldb_message_element *in,
207 : TALLOC_CTX *mem_ctx,
208 : struct drsuapi_DsReplicaAttribute *out)
209 : {
210 144910 : unsigned int i;
211 144910 : DATA_BLOB *blobs;
212 :
213 2070142 : if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
214 0 : return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
215 : }
216 :
217 4140284 : out->attid = dsdb_attribute_get_attid(attr,
218 2070142 : ctx->is_schema_nc);
219 2070142 : out->value_ctr.num_values = in->num_values;
220 2070142 : out->value_ctr.values = talloc_array(mem_ctx,
221 : struct drsuapi_DsAttributeValue,
222 : in->num_values);
223 2070142 : W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
224 :
225 2070142 : blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
226 2070142 : W_ERROR_HAVE_NO_MEMORY(blobs);
227 :
228 4140284 : for (i=0; i < in->num_values; i++) {
229 2070142 : out->value_ctr.values[i].blob = &blobs[i];
230 :
231 2070142 : blobs[i] = data_blob_talloc(blobs, NULL, 4);
232 2070142 : W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
233 :
234 2070142 : if (in->values[i].length >= 4 &&
235 2070142 : strncmp("TRUE", (const char *)in->values[i].data, in->values[i].length) == 0) {
236 1691834 : SIVAL(blobs[i].data, 0, 0x00000001);
237 378308 : } else if (in->values[i].length >= 5 &&
238 378308 : strncmp("FALSE", (const char *)in->values[i].data, in->values[i].length) == 0) {
239 378308 : SIVAL(blobs[i].data, 0, 0x00000000);
240 : } else {
241 0 : return WERR_FOOBAR;
242 : }
243 : }
244 :
245 2070142 : return WERR_OK;
246 : }
247 :
248 968851 : static WERROR dsdb_syntax_BOOL_validate_ldb(const struct dsdb_syntax_ctx *ctx,
249 : const struct dsdb_attribute *attr,
250 : const struct ldb_message_element *in)
251 : {
252 170887 : unsigned int i;
253 :
254 968851 : if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
255 0 : return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
256 : }
257 :
258 1937172 : for (i=0; i < in->num_values; i++) {
259 968321 : if (in->values[i].length == 0) {
260 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
261 : }
262 :
263 968321 : if (in->values[i].length >= 4 &&
264 968321 : strncmp("TRUE",
265 968321 : (const char *)in->values[i].data,
266 797434 : in->values[i].length) == 0) {
267 922283 : continue;
268 : }
269 259503 : if (in->values[i].length >= 5 &&
270 259503 : strncmp("FALSE",
271 259503 : (const char *)in->values[i].data,
272 213465 : in->values[i].length) == 0) {
273 259503 : continue;
274 : }
275 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
276 : }
277 :
278 968851 : return WERR_OK;
279 : }
280 :
281 3152152 : static WERROR dsdb_syntax_INT32_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
282 : const struct dsdb_attribute *attr,
283 : const struct drsuapi_DsReplicaAttribute *in,
284 : TALLOC_CTX *mem_ctx,
285 : struct ldb_message_element *out)
286 : {
287 197252 : unsigned int i;
288 :
289 3152152 : out->flags = 0;
290 3152152 : out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
291 3152152 : W_ERROR_HAVE_NO_MEMORY(out->name);
292 :
293 3152152 : out->num_values = in->value_ctr.num_values;
294 3152152 : out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
295 3152152 : W_ERROR_HAVE_NO_MEMORY(out->values);
296 :
297 6106877 : for (i=0; i < out->num_values; i++) {
298 197252 : int32_t v;
299 197252 : char *str;
300 :
301 2954725 : if (in->value_ctr.values[i].blob == NULL) {
302 0 : return WERR_FOOBAR;
303 : }
304 :
305 2954725 : if (in->value_ctr.values[i].blob->length != 4) {
306 0 : return WERR_FOOBAR;
307 : }
308 :
309 2954725 : v = IVALS(in->value_ctr.values[i].blob->data, 0);
310 :
311 2954725 : str = talloc_asprintf(out->values, "%d", v);
312 2954725 : W_ERROR_HAVE_NO_MEMORY(str);
313 :
314 2954725 : out->values[i] = data_blob_string_const(str);
315 : }
316 :
317 3152152 : return WERR_OK;
318 : }
319 :
320 2457208 : static WERROR dsdb_syntax_INT32_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
321 : const struct dsdb_attribute *attr,
322 : const struct ldb_message_element *in,
323 : TALLOC_CTX *mem_ctx,
324 : struct drsuapi_DsReplicaAttribute *out)
325 : {
326 197252 : unsigned int i;
327 197252 : DATA_BLOB *blobs;
328 :
329 2457208 : if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
330 0 : return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
331 : }
332 :
333 4914416 : out->attid = dsdb_attribute_get_attid(attr,
334 2457208 : ctx->is_schema_nc);
335 2457208 : out->value_ctr.num_values = in->num_values;
336 2457208 : out->value_ctr.values = talloc_array(mem_ctx,
337 : struct drsuapi_DsAttributeValue,
338 : in->num_values);
339 2457208 : W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
340 :
341 2457208 : blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
342 2457208 : W_ERROR_HAVE_NO_MEMORY(blobs);
343 :
344 4914430 : for (i=0; i < in->num_values; i++) {
345 197252 : int32_t v;
346 :
347 2457222 : out->value_ctr.values[i].blob = &blobs[i];
348 :
349 2457222 : blobs[i] = data_blob_talloc(blobs, NULL, 4);
350 2457222 : W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
351 :
352 : /* We've to use "strtoll" here to have the intended overflows.
353 : * Otherwise we may get "LONG_MAX" and the conversion is wrong. */
354 2457222 : v = (int32_t) strtoll((char *)in->values[i].data, NULL, 0);
355 :
356 2457222 : SIVALS(blobs[i].data, 0, v);
357 : }
358 :
359 2457208 : return WERR_OK;
360 : }
361 :
362 1741787 : static WERROR dsdb_syntax_INT32_validate_ldb(const struct dsdb_syntax_ctx *ctx,
363 : const struct dsdb_attribute *attr,
364 : const struct ldb_message_element *in)
365 : {
366 233609 : unsigned int i;
367 :
368 1741787 : if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
369 0 : return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
370 : }
371 :
372 3483544 : for (i=0; i < in->num_values; i++) {
373 233609 : long v;
374 233609 : char buf[sizeof("-2147483648")];
375 1741769 : char *end = NULL;
376 :
377 1741769 : ZERO_STRUCT(buf);
378 1741769 : if (in->values[i].length >= sizeof(buf)) {
379 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
380 : }
381 :
382 1741769 : memcpy(buf, in->values[i].data, in->values[i].length);
383 1741769 : errno = 0;
384 1741769 : v = strtol(buf, &end, 10);
385 1741769 : if (errno != 0) {
386 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
387 : }
388 1741769 : if (end && end[0] != '\0') {
389 12 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
390 : }
391 :
392 1741757 : if (attr->rangeLower) {
393 280418 : if ((int32_t)v < (int32_t)*attr->rangeLower) {
394 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
395 : }
396 : }
397 :
398 1741757 : if (attr->rangeUpper) {
399 95892 : if ((int32_t)v > (int32_t)*attr->rangeUpper) {
400 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
401 : }
402 : }
403 : }
404 :
405 1741775 : return WERR_OK;
406 : }
407 :
408 1116050 : static WERROR dsdb_syntax_INT64_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
409 : const struct dsdb_attribute *attr,
410 : const struct drsuapi_DsReplicaAttribute *in,
411 : TALLOC_CTX *mem_ctx,
412 : struct ldb_message_element *out)
413 : {
414 145454 : unsigned int i;
415 :
416 1116050 : out->flags = 0;
417 1116050 : out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
418 1116050 : W_ERROR_HAVE_NO_MEMORY(out->name);
419 :
420 1116050 : out->num_values = in->value_ctr.num_values;
421 1116050 : out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
422 1116050 : W_ERROR_HAVE_NO_MEMORY(out->values);
423 :
424 2139469 : for (i=0; i < out->num_values; i++) {
425 145454 : int64_t v;
426 145454 : char *str;
427 :
428 1023419 : if (in->value_ctr.values[i].blob == NULL) {
429 0 : return WERR_FOOBAR;
430 : }
431 :
432 1023419 : if (in->value_ctr.values[i].blob->length != 8) {
433 0 : return WERR_FOOBAR;
434 : }
435 :
436 1023419 : v = BVALS(in->value_ctr.values[i].blob->data, 0);
437 :
438 1023419 : str = talloc_asprintf(out->values, "%lld", (long long int)v);
439 1023419 : W_ERROR_HAVE_NO_MEMORY(str);
440 :
441 1023419 : out->values[i] = data_blob_string_const(str);
442 : }
443 :
444 1116050 : return WERR_OK;
445 : }
446 :
447 1026926 : static WERROR dsdb_syntax_INT64_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
448 : const struct dsdb_attribute *attr,
449 : const struct ldb_message_element *in,
450 : TALLOC_CTX *mem_ctx,
451 : struct drsuapi_DsReplicaAttribute *out)
452 : {
453 145454 : unsigned int i;
454 145454 : DATA_BLOB *blobs;
455 :
456 1026926 : if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
457 0 : return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
458 : }
459 :
460 2053852 : out->attid = dsdb_attribute_get_attid(attr,
461 1026926 : ctx->is_schema_nc);
462 1026926 : out->value_ctr.num_values = in->num_values;
463 1026926 : out->value_ctr.values = talloc_array(mem_ctx,
464 : struct drsuapi_DsAttributeValue,
465 : in->num_values);
466 1026926 : W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
467 :
468 1026926 : blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
469 1026926 : W_ERROR_HAVE_NO_MEMORY(blobs);
470 :
471 2053852 : for (i=0; i < in->num_values; i++) {
472 145454 : int64_t v;
473 :
474 1026926 : out->value_ctr.values[i].blob = &blobs[i];
475 :
476 1026926 : blobs[i] = data_blob_talloc(blobs, NULL, 8);
477 1026926 : W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
478 :
479 1026926 : v = strtoll((const char *)in->values[i].data, NULL, 10);
480 :
481 1026926 : SBVALS(blobs[i].data, 0, v);
482 : }
483 :
484 1026926 : return WERR_OK;
485 : }
486 :
487 216781 : static WERROR dsdb_syntax_INT64_validate_ldb(const struct dsdb_syntax_ctx *ctx,
488 : const struct dsdb_attribute *attr,
489 : const struct ldb_message_element *in)
490 : {
491 3204 : unsigned int i;
492 :
493 216781 : if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
494 0 : return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
495 : }
496 :
497 433538 : for (i=0; i < in->num_values; i++) {
498 3204 : long long v;
499 3204 : char buf[sizeof("-9223372036854775808")];
500 216757 : char *end = NULL;
501 :
502 216757 : ZERO_STRUCT(buf);
503 216757 : if (in->values[i].length >= sizeof(buf)) {
504 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
505 : }
506 216757 : memcpy(buf, in->values[i].data, in->values[i].length);
507 :
508 216757 : errno = 0;
509 216757 : v = strtoll(buf, &end, 10);
510 216757 : if (errno != 0) {
511 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
512 : }
513 216757 : if (end && end[0] != '\0') {
514 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
515 : }
516 :
517 216757 : if (attr->rangeLower) {
518 0 : if ((int64_t)v < (int64_t)*attr->rangeLower) {
519 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
520 : }
521 : }
522 :
523 216757 : if (attr->rangeUpper) {
524 161 : if ((int64_t)v > (int64_t)*attr->rangeUpper) {
525 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
526 : }
527 : }
528 : }
529 :
530 216781 : return WERR_OK;
531 : }
532 0 : static WERROR dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
533 : const struct dsdb_attribute *attr,
534 : const struct drsuapi_DsReplicaAttribute *in,
535 : TALLOC_CTX *mem_ctx,
536 : struct ldb_message_element *out)
537 : {
538 0 : unsigned int i;
539 :
540 0 : out->flags = 0;
541 0 : out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
542 0 : W_ERROR_HAVE_NO_MEMORY(out->name);
543 :
544 0 : out->num_values = in->value_ctr.num_values;
545 0 : out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
546 0 : W_ERROR_HAVE_NO_MEMORY(out->values);
547 :
548 0 : for (i=0; i < out->num_values; i++) {
549 0 : NTTIME v;
550 0 : time_t t;
551 0 : char *str;
552 :
553 0 : if (in->value_ctr.values[i].blob == NULL) {
554 0 : return WERR_FOOBAR;
555 : }
556 :
557 0 : if (in->value_ctr.values[i].blob->length != 8) {
558 0 : return WERR_FOOBAR;
559 : }
560 :
561 0 : v = BVAL(in->value_ctr.values[i].blob->data, 0);
562 0 : if (v == 0) {
563 : /* special case for 1601 zero timestamp */
564 0 : out->values[i] = data_blob_string_const("16010101000000.0Z");
565 0 : continue;
566 : }
567 0 : v *= 10000000;
568 0 : t = nt_time_to_unix(v);
569 :
570 : /*
571 : * NOTE: On a w2k3 server you can set a GeneralizedTime string
572 : * via LDAP, but you get back an UTCTime string,
573 : * but via DRSUAPI you get back the NTTIME_1sec value
574 : * that represents the GeneralizedTime value!
575 : *
576 : * So if we store the UTCTime string in our ldb
577 : * we'll loose information!
578 : */
579 0 : str = ldb_timestring_utc(out->values, t);
580 0 : W_ERROR_HAVE_NO_MEMORY(str);
581 0 : out->values[i] = data_blob_string_const(str);
582 : }
583 :
584 0 : return WERR_OK;
585 : }
586 :
587 0 : static WERROR dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
588 : const struct dsdb_attribute *attr,
589 : const struct ldb_message_element *in,
590 : TALLOC_CTX *mem_ctx,
591 : struct drsuapi_DsReplicaAttribute *out)
592 : {
593 0 : unsigned int i;
594 0 : DATA_BLOB *blobs;
595 :
596 0 : if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
597 0 : return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
598 : }
599 :
600 0 : out->attid = dsdb_attribute_get_attid(attr,
601 0 : ctx->is_schema_nc);
602 0 : out->value_ctr.num_values = in->num_values;
603 0 : out->value_ctr.values = talloc_array(mem_ctx,
604 : struct drsuapi_DsAttributeValue,
605 : in->num_values);
606 0 : W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
607 :
608 0 : blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
609 0 : W_ERROR_HAVE_NO_MEMORY(blobs);
610 :
611 0 : for (i=0; i < in->num_values; i++) {
612 0 : NTTIME v;
613 0 : time_t t;
614 :
615 0 : out->value_ctr.values[i].blob = &blobs[i];
616 :
617 0 : blobs[i] = data_blob_talloc(blobs, NULL, 8);
618 0 : W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
619 :
620 0 : if (ldb_val_string_cmp(&in->values[i], "16010101000000.0Z") == 0) {
621 0 : SBVALS(blobs[i].data, 0, 0);
622 0 : continue;
623 : }
624 :
625 0 : t = ldb_string_utc_to_time((const char *)in->values[i].data);
626 0 : unix_to_nt_time(&v, t);
627 0 : v /= 10000000;
628 :
629 0 : SBVAL(blobs[i].data, 0, v);
630 : }
631 :
632 0 : return WERR_OK;
633 : }
634 :
635 0 : static WERROR dsdb_syntax_NTTIME_UTC_validate_ldb(const struct dsdb_syntax_ctx *ctx,
636 : const struct dsdb_attribute *attr,
637 : const struct ldb_message_element *in)
638 : {
639 0 : unsigned int i;
640 :
641 0 : if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
642 0 : return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
643 : }
644 :
645 0 : for (i=0; i < in->num_values; i++) {
646 0 : time_t t;
647 0 : char buf[sizeof("090826075717Z")];
648 :
649 0 : ZERO_STRUCT(buf);
650 0 : if (in->values[i].length >= sizeof(buf)) {
651 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
652 : }
653 0 : memcpy(buf, in->values[i].data, in->values[i].length);
654 :
655 0 : t = ldb_string_utc_to_time(buf);
656 0 : if (t == 0) {
657 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
658 : }
659 :
660 0 : if (attr->rangeLower) {
661 0 : if ((int32_t)t < (int32_t)*attr->rangeLower) {
662 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
663 : }
664 : }
665 :
666 0 : if (attr->rangeUpper) {
667 0 : if ((int32_t)t > (int32_t)*attr->rangeUpper) {
668 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
669 : }
670 : }
671 :
672 : /*
673 : * TODO: verify the comment in the
674 : * dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb() function!
675 : */
676 : }
677 :
678 0 : return WERR_OK;
679 : }
680 :
681 1630865 : static WERROR dsdb_syntax_NTTIME_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
682 : const struct dsdb_attribute *attr,
683 : const struct drsuapi_DsReplicaAttribute *in,
684 : TALLOC_CTX *mem_ctx,
685 : struct ldb_message_element *out)
686 : {
687 144343 : unsigned int i;
688 :
689 1630865 : out->flags = 0;
690 1630865 : out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
691 1630865 : W_ERROR_HAVE_NO_MEMORY(out->name);
692 :
693 1630865 : out->num_values = in->value_ctr.num_values;
694 1630865 : out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
695 1630865 : W_ERROR_HAVE_NO_MEMORY(out->values);
696 :
697 3257876 : for (i=0; i < out->num_values; i++) {
698 144343 : NTTIME v;
699 144343 : time_t t;
700 144343 : char *str;
701 :
702 1627011 : if (in->value_ctr.values[i].blob == NULL) {
703 0 : return WERR_FOOBAR;
704 : }
705 :
706 1627011 : if (in->value_ctr.values[i].blob->length != 8) {
707 0 : return WERR_FOOBAR;
708 : }
709 :
710 1627011 : v = BVAL(in->value_ctr.values[i].blob->data, 0);
711 1627011 : if (v == 0) {
712 : /* special case for 1601 zero timestamp */
713 0 : out->values[i] = data_blob_string_const("16010101000000.0Z");
714 0 : continue;
715 : }
716 1627011 : v *= 10000000;
717 1627011 : t = nt_time_to_unix(v);
718 :
719 1627011 : str = ldb_timestring(out->values, t);
720 1627011 : W_ERROR_HAVE_NO_MEMORY(str);
721 :
722 1627011 : out->values[i] = data_blob_string_const(str);
723 : }
724 :
725 1630865 : return WERR_OK;
726 : }
727 :
728 1557173 : static WERROR dsdb_syntax_NTTIME_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
729 : const struct dsdb_attribute *attr,
730 : const struct ldb_message_element *in,
731 : TALLOC_CTX *mem_ctx,
732 : struct drsuapi_DsReplicaAttribute *out)
733 : {
734 144343 : unsigned int i;
735 144343 : DATA_BLOB *blobs;
736 :
737 1557173 : if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
738 0 : return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
739 : }
740 :
741 3114346 : out->attid = dsdb_attribute_get_attid(attr,
742 1557173 : ctx->is_schema_nc);
743 1557173 : out->value_ctr.num_values = in->num_values;
744 1557173 : out->value_ctr.values = talloc_array(mem_ctx,
745 : struct drsuapi_DsAttributeValue,
746 : in->num_values);
747 1557173 : W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
748 :
749 1557173 : blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
750 1557173 : W_ERROR_HAVE_NO_MEMORY(blobs);
751 :
752 3114346 : for (i=0; i < in->num_values; i++) {
753 144343 : NTTIME v;
754 144343 : time_t t;
755 144343 : int ret;
756 :
757 1557173 : out->value_ctr.values[i].blob = &blobs[i];
758 :
759 1557173 : blobs[i] = data_blob_talloc(blobs, NULL, 8);
760 1557173 : W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
761 :
762 1557173 : if (ldb_val_string_cmp(&in->values[i], "16010101000000.0Z") == 0) {
763 0 : SBVALS(blobs[i].data, 0, 0);
764 0 : continue;
765 : }
766 :
767 1557173 : ret = ldb_val_to_time(&in->values[i], &t);
768 1557173 : if (ret != LDB_SUCCESS) {
769 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
770 : }
771 1557173 : unix_to_nt_time(&v, t);
772 1557173 : v /= 10000000;
773 :
774 1557173 : SBVAL(blobs[i].data, 0, v);
775 : }
776 :
777 1557173 : return WERR_OK;
778 : }
779 :
780 2229 : static WERROR dsdb_syntax_NTTIME_validate_ldb(const struct dsdb_syntax_ctx *ctx,
781 : const struct dsdb_attribute *attr,
782 : const struct ldb_message_element *in)
783 : {
784 1 : unsigned int i;
785 :
786 2229 : if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
787 0 : return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
788 : }
789 :
790 4458 : for (i=0; i < in->num_values; i++) {
791 1 : time_t t;
792 1 : int ret;
793 :
794 2229 : ret = ldb_val_to_time(&in->values[i], &t);
795 2229 : if (ret != LDB_SUCCESS) {
796 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
797 : }
798 :
799 2229 : if (attr->rangeLower) {
800 0 : if ((int32_t)t < (int32_t)*attr->rangeLower) {
801 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
802 : }
803 : }
804 :
805 2229 : if (attr->rangeUpper) {
806 0 : if ((int32_t)t > (int32_t)*attr->rangeUpper) {
807 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
808 : }
809 : }
810 : }
811 :
812 2229 : return WERR_OK;
813 : }
814 :
815 2842080 : static WERROR dsdb_syntax_DATA_BLOB_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
816 : const struct dsdb_attribute *attr,
817 : const struct drsuapi_DsReplicaAttribute *in,
818 : TALLOC_CTX *mem_ctx,
819 : struct ldb_message_element *out)
820 : {
821 166653 : unsigned int i;
822 :
823 2842080 : out->flags = 0;
824 2842080 : out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
825 2842080 : W_ERROR_HAVE_NO_MEMORY(out->name);
826 :
827 2842080 : out->num_values = in->value_ctr.num_values;
828 2842080 : out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
829 2842080 : W_ERROR_HAVE_NO_MEMORY(out->values);
830 :
831 5443563 : for (i=0; i < out->num_values; i++) {
832 2601483 : if (in->value_ctr.values[i].blob == NULL) {
833 0 : return WERR_FOOBAR;
834 : }
835 :
836 2601483 : if (in->value_ctr.values[i].blob->length == 0) {
837 0 : return WERR_FOOBAR;
838 : }
839 :
840 2601483 : out->values[i] = data_blob_dup_talloc(out->values,
841 : *in->value_ctr.values[i].blob);
842 2601483 : W_ERROR_HAVE_NO_MEMORY(out->values[i].data);
843 : }
844 :
845 2842080 : return WERR_OK;
846 : }
847 :
848 2388954 : static WERROR dsdb_syntax_DATA_BLOB_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
849 : const struct dsdb_attribute *attr,
850 : const struct ldb_message_element *in,
851 : TALLOC_CTX *mem_ctx,
852 : struct drsuapi_DsReplicaAttribute *out)
853 : {
854 166653 : unsigned int i;
855 166653 : DATA_BLOB *blobs;
856 :
857 2388954 : if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
858 0 : return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
859 : }
860 :
861 4777908 : out->attid = dsdb_attribute_get_attid(attr,
862 2388954 : ctx->is_schema_nc);
863 2388954 : out->value_ctr.num_values = in->num_values;
864 2388954 : out->value_ctr.values = talloc_array(mem_ctx,
865 : struct drsuapi_DsAttributeValue,
866 : in->num_values);
867 2388954 : W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
868 :
869 2388954 : blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
870 2388954 : W_ERROR_HAVE_NO_MEMORY(blobs);
871 :
872 4782720 : for (i=0; i < in->num_values; i++) {
873 2393766 : out->value_ctr.values[i].blob = &blobs[i];
874 :
875 2393766 : blobs[i] = data_blob_dup_talloc(blobs, in->values[i]);
876 2393766 : W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
877 : }
878 :
879 2388954 : return WERR_OK;
880 : }
881 :
882 1293093 : static WERROR dsdb_syntax_DATA_BLOB_validate_one_val(const struct dsdb_syntax_ctx *ctx,
883 : const struct dsdb_attribute *attr,
884 : const struct ldb_val *val)
885 : {
886 1293093 : if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
887 0 : return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
888 : }
889 :
890 1106511 : if (attr->rangeLower) {
891 1082065 : if ((uint32_t)val->length < (uint32_t)*attr->rangeLower) {
892 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
893 : }
894 : }
895 :
896 1293093 : if (attr->rangeUpper) {
897 1084979 : if ((uint32_t)val->length > (uint32_t)*attr->rangeUpper) {
898 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
899 : }
900 : }
901 :
902 1293093 : return WERR_OK;
903 : }
904 :
905 1416906 : static WERROR dsdb_syntax_DATA_BLOB_validate_ldb(const struct dsdb_syntax_ctx *ctx,
906 : const struct dsdb_attribute *attr,
907 : const struct ldb_message_element *in)
908 : {
909 186800 : unsigned int i;
910 186800 : WERROR status;
911 :
912 1416906 : if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
913 0 : return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
914 : }
915 :
916 2689841 : for (i=0; i < in->num_values; i++) {
917 1272935 : if (in->values[i].length == 0) {
918 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
919 : }
920 :
921 1459517 : status = dsdb_syntax_DATA_BLOB_validate_one_val(ctx,
922 : attr,
923 1272935 : &in->values[i]);
924 1272935 : if (!W_ERROR_IS_OK(status)) {
925 0 : return status;
926 : }
927 : }
928 :
929 1416906 : return WERR_OK;
930 : }
931 :
932 0 : static WERROR _dsdb_syntax_auto_OID_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
933 : const struct dsdb_attribute *attr,
934 : const struct drsuapi_DsReplicaAttribute *in,
935 : TALLOC_CTX *mem_ctx,
936 : struct ldb_message_element *out)
937 : {
938 0 : unsigned int i;
939 :
940 0 : out->flags = 0;
941 0 : out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
942 0 : W_ERROR_HAVE_NO_MEMORY(out->name);
943 :
944 0 : out->num_values = in->value_ctr.num_values;
945 0 : out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
946 0 : W_ERROR_HAVE_NO_MEMORY(out->values);
947 :
948 0 : for (i=0; i < out->num_values; i++) {
949 0 : uint32_t v;
950 0 : const struct dsdb_class *c;
951 0 : const struct dsdb_attribute *a;
952 0 : const char *str = NULL;
953 :
954 0 : if (in->value_ctr.values[i].blob == NULL) {
955 0 : return WERR_FOOBAR;
956 : }
957 :
958 0 : if (in->value_ctr.values[i].blob->length != 4) {
959 0 : return WERR_FOOBAR;
960 : }
961 :
962 0 : v = IVAL(in->value_ctr.values[i].blob->data, 0);
963 :
964 0 : if ((c = dsdb_class_by_governsID_id(ctx->schema, v))) {
965 0 : str = talloc_strdup(out->values, c->lDAPDisplayName);
966 0 : } else if ((a = dsdb_attribute_by_attributeID_id(ctx->schema, v))) {
967 0 : str = talloc_strdup(out->values, a->lDAPDisplayName);
968 : } else {
969 0 : WERROR werr;
970 0 : SMB_ASSERT(ctx->pfm_remote);
971 0 : werr = dsdb_schema_pfm_oid_from_attid(ctx->pfm_remote, v,
972 0 : out->values, &str);
973 0 : W_ERROR_NOT_OK_RETURN(werr);
974 : }
975 0 : W_ERROR_HAVE_NO_MEMORY(str);
976 :
977 : /* the values need to be reversed */
978 0 : out->values[out->num_values - (i + 1)] = data_blob_string_const(str);
979 : }
980 :
981 0 : return WERR_OK;
982 : }
983 :
984 1879441 : static WERROR _dsdb_syntax_OID_obj_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
985 : const struct dsdb_attribute *attr,
986 : const struct drsuapi_DsReplicaAttribute *in,
987 : TALLOC_CTX *mem_ctx,
988 : struct ldb_message_element *out)
989 : {
990 187664 : unsigned int i;
991 :
992 1879441 : out->flags = 0;
993 1879441 : out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
994 1879441 : W_ERROR_HAVE_NO_MEMORY(out->name);
995 :
996 1879441 : out->num_values = in->value_ctr.num_values;
997 1879441 : out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
998 1879441 : W_ERROR_HAVE_NO_MEMORY(out->values);
999 :
1000 5727105 : for (i=0; i < out->num_values; i++) {
1001 357159 : uint32_t v, vo;
1002 357159 : const struct dsdb_class *c;
1003 357159 : const char *str;
1004 :
1005 3847734 : if (in->value_ctr.values[i].blob == NULL) {
1006 0 : return WERR_FOOBAR;
1007 : }
1008 :
1009 3847734 : if (in->value_ctr.values[i].blob->length != 4) {
1010 0 : return WERR_FOOBAR;
1011 : }
1012 :
1013 3847734 : v = IVAL(in->value_ctr.values[i].blob->data, 0);
1014 3847734 : vo = v;
1015 :
1016 : /* convert remote ATTID to local ATTID */
1017 3847734 : if (!dsdb_syntax_attid_from_remote_attid(ctx, mem_ctx, v, &v)) {
1018 0 : DEBUG(1,(__location__ ": Failed to map remote ATTID to local ATTID!\n"));
1019 0 : return WERR_FOOBAR;
1020 : }
1021 :
1022 3847734 : c = dsdb_class_by_governsID_id(ctx->schema, v);
1023 3847734 : if (!c) {
1024 70 : int dbg_level = ctx->schema->resolving_in_progress ? 10 : 0;
1025 70 : DEBUG(dbg_level,(__location__ ": %s unknown local governsID 0x%08X remote 0x%08X%s\n",
1026 : attr->lDAPDisplayName, v, vo,
1027 : ctx->schema->resolving_in_progress ? "resolving in progress" : ""));
1028 70 : return WERR_DS_OBJ_CLASS_NOT_DEFINED;
1029 : }
1030 :
1031 3847664 : str = talloc_strdup(out->values, c->lDAPDisplayName);
1032 3847664 : W_ERROR_HAVE_NO_MEMORY(str);
1033 :
1034 : /* the values need to be reversed */
1035 3847664 : out->values[out->num_values - (i + 1)] = data_blob_string_const(str);
1036 : }
1037 :
1038 1879371 : return WERR_OK;
1039 : }
1040 :
1041 429128 : static WERROR _dsdb_syntax_OID_attr_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
1042 : const struct dsdb_attribute *attr,
1043 : const struct drsuapi_DsReplicaAttribute *in,
1044 : TALLOC_CTX *mem_ctx,
1045 : struct ldb_message_element *out)
1046 : {
1047 61440 : unsigned int i;
1048 :
1049 429128 : out->flags = 0;
1050 429128 : out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1051 429128 : W_ERROR_HAVE_NO_MEMORY(out->name);
1052 :
1053 429128 : out->num_values = in->value_ctr.num_values;
1054 429128 : out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1055 429128 : W_ERROR_HAVE_NO_MEMORY(out->values);
1056 :
1057 1363572 : for (i=0; i < out->num_values; i++) {
1058 103526 : uint32_t v, vo;
1059 103526 : const struct dsdb_attribute *a;
1060 103526 : const char *str;
1061 :
1062 935046 : if (in->value_ctr.values[i].blob == NULL) {
1063 0 : DEBUG(0, ("Attribute has no value\n"));
1064 0 : return WERR_FOOBAR;
1065 : }
1066 :
1067 935046 : if (in->value_ctr.values[i].blob->length != 4) {
1068 0 : DEBUG(0, ("Attribute has a value with 0 length\n"));
1069 0 : return WERR_FOOBAR;
1070 : }
1071 :
1072 935046 : v = IVAL(in->value_ctr.values[i].blob->data, 0);
1073 935046 : vo = v;
1074 :
1075 : /* convert remote ATTID to local ATTID */
1076 935046 : if (!dsdb_syntax_attid_from_remote_attid(ctx, mem_ctx, v, &v)) {
1077 0 : DEBUG(1,(__location__ ": Failed to map remote ATTID to local ATTID!\n"));
1078 0 : return WERR_FOOBAR;
1079 : }
1080 :
1081 935046 : a = dsdb_attribute_by_attributeID_id(ctx->schema, v);
1082 935046 : if (!a) {
1083 602 : int dbg_level = ctx->schema->resolving_in_progress ? 10 : 0;
1084 602 : DEBUG(dbg_level,(__location__ ": %s unknown local attributeID_id 0x%08X remote 0x%08X%s\n",
1085 : attr->lDAPDisplayName, v, vo,
1086 : ctx->schema->resolving_in_progress ? "resolving in progress" : ""));
1087 602 : return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
1088 : }
1089 :
1090 934444 : str = talloc_strdup(out->values, a->lDAPDisplayName);
1091 934444 : W_ERROR_HAVE_NO_MEMORY(str);
1092 :
1093 : /* the values need to be reversed */
1094 934444 : out->values[out->num_values - (i + 1)] = data_blob_string_const(str);
1095 : }
1096 :
1097 428526 : return WERR_OK;
1098 : }
1099 :
1100 1044263 : static WERROR _dsdb_syntax_OID_oid_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
1101 : const struct dsdb_attribute *attr,
1102 : const struct drsuapi_DsReplicaAttribute *in,
1103 : TALLOC_CTX *mem_ctx,
1104 : struct ldb_message_element *out)
1105 : {
1106 99403 : unsigned int i;
1107 99403 : const struct dsdb_schema_prefixmap *prefixmap;
1108 :
1109 1044263 : if (ctx->pfm_remote != NULL) {
1110 492795 : prefixmap = ctx->pfm_remote;
1111 : } else {
1112 551468 : prefixmap = ctx->schema->prefixmap;
1113 : }
1114 1044263 : SMB_ASSERT(prefixmap);
1115 :
1116 1044263 : out->flags = 0;
1117 1044263 : out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1118 1044263 : W_ERROR_HAVE_NO_MEMORY(out->name);
1119 :
1120 1044263 : out->num_values = in->value_ctr.num_values;
1121 1044263 : out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1122 1044263 : W_ERROR_HAVE_NO_MEMORY(out->values);
1123 :
1124 2088526 : for (i=0; i < out->num_values; i++) {
1125 99403 : uint32_t attid;
1126 99403 : WERROR status;
1127 99403 : const char *oid;
1128 :
1129 1044263 : if (in->value_ctr.values[i].blob == NULL) {
1130 0 : return WERR_FOOBAR;
1131 : }
1132 :
1133 1044263 : if (in->value_ctr.values[i].blob->length != 4) {
1134 0 : return WERR_FOOBAR;
1135 : }
1136 :
1137 1044263 : attid = IVAL(in->value_ctr.values[i].blob->data, 0);
1138 :
1139 1044263 : status = dsdb_schema_pfm_oid_from_attid(prefixmap, attid,
1140 1044263 : out->values, &oid);
1141 1044263 : if (!W_ERROR_IS_OK(status)) {
1142 0 : DEBUG(0,(__location__ ": Error: Unknown ATTID 0x%08X\n",
1143 : attid));
1144 0 : return status;
1145 : }
1146 :
1147 1044263 : out->values[i] = data_blob_string_const(oid);
1148 : }
1149 :
1150 1044263 : return WERR_OK;
1151 : }
1152 :
1153 0 : static WERROR _dsdb_syntax_auto_OID_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
1154 : const struct dsdb_attribute *attr,
1155 : const struct ldb_message_element *in,
1156 : TALLOC_CTX *mem_ctx,
1157 : struct drsuapi_DsReplicaAttribute *out)
1158 : {
1159 0 : unsigned int i;
1160 0 : DATA_BLOB *blobs;
1161 :
1162 0 : out->attid= dsdb_attribute_get_attid(attr,
1163 0 : ctx->is_schema_nc);
1164 0 : out->value_ctr.num_values= in->num_values;
1165 0 : out->value_ctr.values= talloc_array(mem_ctx,
1166 : struct drsuapi_DsAttributeValue,
1167 : in->num_values);
1168 0 : W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1169 :
1170 0 : blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1171 0 : W_ERROR_HAVE_NO_MEMORY(blobs);
1172 :
1173 0 : for (i=0; i < in->num_values; i++) {
1174 0 : const struct dsdb_class *obj_class;
1175 0 : const struct dsdb_attribute *obj_attr;
1176 0 : struct ldb_val *v;
1177 :
1178 0 : out->value_ctr.values[i].blob= &blobs[i];
1179 :
1180 0 : blobs[i] = data_blob_talloc(blobs, NULL, 4);
1181 0 : W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
1182 :
1183 : /* in DRS windows puts the classes in the opposite
1184 : order to the order used in ldap */
1185 0 : v = &in->values[(in->num_values-1)-i];
1186 :
1187 0 : if ((obj_class = dsdb_class_by_lDAPDisplayName_ldb_val(ctx->schema, v))) {
1188 0 : SIVAL(blobs[i].data, 0, obj_class->governsID_id);
1189 0 : } else if ((obj_attr = dsdb_attribute_by_lDAPDisplayName_ldb_val(ctx->schema, v))) {
1190 0 : SIVAL(blobs[i].data, 0, obj_attr->attributeID_id);
1191 : } else {
1192 0 : uint32_t attid;
1193 0 : WERROR werr;
1194 0 : werr = dsdb_schema_pfm_attid_from_oid(ctx->schema->prefixmap,
1195 0 : (const char *)v->data,
1196 : &attid);
1197 0 : W_ERROR_NOT_OK_RETURN(werr);
1198 0 : SIVAL(blobs[i].data, 0, attid);
1199 : }
1200 :
1201 : }
1202 :
1203 :
1204 0 : return WERR_OK;
1205 : }
1206 :
1207 1789171 : static WERROR _dsdb_syntax_OID_obj_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
1208 : const struct dsdb_attribute *attr,
1209 : const struct ldb_message_element *in,
1210 : TALLOC_CTX *mem_ctx,
1211 : struct drsuapi_DsReplicaAttribute *out)
1212 : {
1213 187664 : unsigned int i;
1214 187664 : DATA_BLOB *blobs;
1215 :
1216 3578342 : out->attid= dsdb_attribute_get_attid(attr,
1217 1789171 : ctx->is_schema_nc);
1218 1789171 : out->value_ctr.num_values= in->num_values;
1219 1789171 : out->value_ctr.values= talloc_array(mem_ctx,
1220 : struct drsuapi_DsAttributeValue,
1221 : in->num_values);
1222 1789171 : W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1223 :
1224 1789171 : blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1225 1789171 : W_ERROR_HAVE_NO_MEMORY(blobs);
1226 :
1227 5484039 : for (i=0; i < in->num_values; i++) {
1228 357159 : const struct dsdb_class *obj_class;
1229 :
1230 3694892 : out->value_ctr.values[i].blob= &blobs[i];
1231 :
1232 3694892 : blobs[i] = data_blob_talloc(blobs, NULL, 4);
1233 3694892 : W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
1234 :
1235 : /* in DRS windows puts the classes in the opposite
1236 : order to the order used in ldap */
1237 4052051 : obj_class = dsdb_class_by_lDAPDisplayName(ctx->schema,
1238 3694892 : (const char *)in->values[(in->num_values-1)-i].data);
1239 3694892 : if (!obj_class) {
1240 24 : return WERR_FOOBAR;
1241 : }
1242 3694868 : SIVAL(blobs[i].data, 0, obj_class->governsID_id);
1243 : }
1244 :
1245 :
1246 1789147 : return WERR_OK;
1247 : }
1248 :
1249 389007 : static WERROR _dsdb_syntax_OID_attr_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
1250 : const struct dsdb_attribute *attr,
1251 : const struct ldb_message_element *in,
1252 : TALLOC_CTX *mem_ctx,
1253 : struct drsuapi_DsReplicaAttribute *out)
1254 : {
1255 61440 : unsigned int i;
1256 61440 : DATA_BLOB *blobs;
1257 :
1258 778014 : out->attid= dsdb_attribute_get_attid(attr,
1259 389007 : ctx->is_schema_nc);
1260 389007 : out->value_ctr.num_values= in->num_values;
1261 389007 : out->value_ctr.values= talloc_array(mem_ctx,
1262 : struct drsuapi_DsAttributeValue,
1263 : in->num_values);
1264 389007 : W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1265 :
1266 389007 : blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1267 389007 : W_ERROR_HAVE_NO_MEMORY(blobs);
1268 :
1269 1167731 : for (i=0; i < in->num_values; i++) {
1270 103526 : const struct dsdb_attribute *obj_attr;
1271 :
1272 778757 : out->value_ctr.values[i].blob= &blobs[i];
1273 :
1274 778757 : blobs[i] = data_blob_talloc(blobs, NULL, 4);
1275 778757 : W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
1276 :
1277 778757 : obj_attr = dsdb_attribute_by_lDAPDisplayName(ctx->schema, (const char *)in->values[i].data);
1278 778757 : if (!obj_attr) {
1279 33 : DEBUG(0, ("Unable to find attribute %s in the schema\n", (const char *)in->values[i].data));
1280 33 : return WERR_FOOBAR;
1281 : }
1282 778724 : SIVAL(blobs[i].data, 0, obj_attr->attributeID_id);
1283 : }
1284 :
1285 :
1286 388974 : return WERR_OK;
1287 : }
1288 :
1289 812482 : static WERROR _dsdb_syntax_OID_oid_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
1290 : const struct dsdb_attribute *attr,
1291 : const struct ldb_message_element *in,
1292 : TALLOC_CTX *mem_ctx,
1293 : struct drsuapi_DsReplicaAttribute *out)
1294 : {
1295 99403 : unsigned int i;
1296 99403 : DATA_BLOB *blobs;
1297 :
1298 1624964 : out->attid= dsdb_attribute_get_attid(attr,
1299 812482 : ctx->is_schema_nc);
1300 812482 : out->value_ctr.num_values= in->num_values;
1301 812482 : out->value_ctr.values= talloc_array(mem_ctx,
1302 : struct drsuapi_DsAttributeValue,
1303 : in->num_values);
1304 812482 : W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1305 :
1306 812482 : blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1307 812482 : W_ERROR_HAVE_NO_MEMORY(blobs);
1308 :
1309 1624964 : for (i=0; i < in->num_values; i++) {
1310 99403 : uint32_t attid;
1311 99403 : WERROR status;
1312 :
1313 812482 : out->value_ctr.values[i].blob= &blobs[i];
1314 :
1315 812482 : blobs[i] = data_blob_talloc(blobs, NULL, 4);
1316 812482 : W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
1317 :
1318 812482 : status = dsdb_schema_pfm_attid_from_oid(ctx->schema->prefixmap,
1319 812482 : (const char *)in->values[i].data,
1320 : &attid);
1321 812482 : W_ERROR_NOT_OK_RETURN(status);
1322 :
1323 812482 : SIVAL(blobs[i].data, 0, attid);
1324 : }
1325 :
1326 812482 : return WERR_OK;
1327 : }
1328 :
1329 3352832 : static WERROR dsdb_syntax_OID_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
1330 : const struct dsdb_attribute *attr,
1331 : const struct drsuapi_DsReplicaAttribute *in,
1332 : TALLOC_CTX *mem_ctx,
1333 : struct ldb_message_element *out)
1334 : {
1335 348507 : WERROR werr;
1336 :
1337 3352832 : switch (attr->attributeID_id) {
1338 1879441 : case DRSUAPI_ATTID_objectClass:
1339 : case DRSUAPI_ATTID_subClassOf:
1340 : case DRSUAPI_ATTID_auxiliaryClass:
1341 : case DRSUAPI_ATTID_systemAuxiliaryClass:
1342 : case DRSUAPI_ATTID_systemPossSuperiors:
1343 : case DRSUAPI_ATTID_possSuperiors:
1344 1879441 : werr = _dsdb_syntax_OID_obj_drsuapi_to_ldb(ctx, attr, in, mem_ctx, out);
1345 1879441 : break;
1346 429128 : case DRSUAPI_ATTID_systemMustContain:
1347 : case DRSUAPI_ATTID_systemMayContain:
1348 : case DRSUAPI_ATTID_mustContain:
1349 : case DRSUAPI_ATTID_rDNAttId:
1350 : case DRSUAPI_ATTID_transportAddressAttribute:
1351 : case DRSUAPI_ATTID_mayContain:
1352 429128 : werr = _dsdb_syntax_OID_attr_drsuapi_to_ldb(ctx, attr, in, mem_ctx, out);
1353 429128 : break;
1354 1044263 : case DRSUAPI_ATTID_governsID:
1355 : case DRSUAPI_ATTID_attributeID:
1356 : case DRSUAPI_ATTID_attributeSyntax:
1357 1044263 : werr = _dsdb_syntax_OID_oid_drsuapi_to_ldb(ctx, attr, in, mem_ctx, out);
1358 1044263 : break;
1359 0 : default:
1360 0 : DEBUG(0,(__location__ ": Unknown handling for attributeID_id for %s\n",
1361 : attr->lDAPDisplayName));
1362 0 : return _dsdb_syntax_auto_OID_drsuapi_to_ldb(ctx, attr, in, mem_ctx, out);
1363 : }
1364 :
1365 : /* When we are doing the vampire of a schema, we don't want
1366 : * the inability to reference an OID to get in the way.
1367 : * Otherwise, we won't get the new schema with which to
1368 : * understand this */
1369 3352832 : if (!W_ERROR_IS_OK(werr) && ctx->schema->relax_OID_conversions) {
1370 0 : return _dsdb_syntax_OID_oid_drsuapi_to_ldb(ctx, attr, in, mem_ctx, out);
1371 : }
1372 3352832 : return werr;
1373 : }
1374 :
1375 2990660 : static WERROR dsdb_syntax_OID_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
1376 : const struct dsdb_attribute *attr,
1377 : const struct ldb_message_element *in,
1378 : TALLOC_CTX *mem_ctx,
1379 : struct drsuapi_DsReplicaAttribute *out)
1380 : {
1381 2990660 : if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
1382 0 : return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
1383 : }
1384 :
1385 2990660 : switch (attr->attributeID_id) {
1386 1789171 : case DRSUAPI_ATTID_objectClass:
1387 : case DRSUAPI_ATTID_subClassOf:
1388 : case DRSUAPI_ATTID_auxiliaryClass:
1389 : case DRSUAPI_ATTID_systemAuxiliaryClass:
1390 : case DRSUAPI_ATTID_systemPossSuperiors:
1391 : case DRSUAPI_ATTID_possSuperiors:
1392 1789171 : return _dsdb_syntax_OID_obj_ldb_to_drsuapi(ctx, attr, in, mem_ctx, out);
1393 389007 : case DRSUAPI_ATTID_systemMustContain:
1394 : case DRSUAPI_ATTID_systemMayContain:
1395 : case DRSUAPI_ATTID_mustContain:
1396 : case DRSUAPI_ATTID_rDNAttId:
1397 : case DRSUAPI_ATTID_transportAddressAttribute:
1398 : case DRSUAPI_ATTID_mayContain:
1399 389007 : return _dsdb_syntax_OID_attr_ldb_to_drsuapi(ctx, attr, in, mem_ctx, out);
1400 812482 : case DRSUAPI_ATTID_governsID:
1401 : case DRSUAPI_ATTID_attributeID:
1402 : case DRSUAPI_ATTID_attributeSyntax:
1403 812482 : return _dsdb_syntax_OID_oid_ldb_to_drsuapi(ctx, attr, in, mem_ctx, out);
1404 : }
1405 :
1406 0 : DEBUG(0,(__location__ ": Unknown handling for attributeID_id for %s\n",
1407 : attr->lDAPDisplayName));
1408 :
1409 0 : return _dsdb_syntax_auto_OID_ldb_to_drsuapi(ctx, attr, in, mem_ctx, out);
1410 : }
1411 :
1412 402328 : static WERROR _dsdb_syntax_OID_validate_numericoid(const struct dsdb_syntax_ctx *ctx,
1413 : const struct dsdb_attribute *attr,
1414 : const struct ldb_message_element *in)
1415 : {
1416 71874 : unsigned int i;
1417 71874 : TALLOC_CTX *tmp_ctx;
1418 :
1419 402328 : tmp_ctx = talloc_new(ctx->ldb);
1420 402328 : W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1421 :
1422 804656 : for (i=0; i < in->num_values; i++) {
1423 71874 : DATA_BLOB blob;
1424 71874 : char *oid_out;
1425 402328 : const char *oid = (const char*)in->values[i].data;
1426 :
1427 402328 : if (in->values[i].length == 0) {
1428 0 : talloc_free(tmp_ctx);
1429 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1430 : }
1431 :
1432 402328 : if (!ber_write_OID_String(tmp_ctx, &blob, oid)) {
1433 0 : DEBUG(0,("ber_write_OID_String() failed for %s\n", oid));
1434 0 : talloc_free(tmp_ctx);
1435 0 : return WERR_INVALID_PARAMETER;
1436 : }
1437 :
1438 402328 : if (!ber_read_OID_String(tmp_ctx, blob, &oid_out)) {
1439 0 : DEBUG(0,("ber_read_OID_String() failed for %s\n",
1440 : hex_encode_talloc(tmp_ctx, blob.data, blob.length)));
1441 0 : talloc_free(tmp_ctx);
1442 0 : return WERR_INVALID_PARAMETER;
1443 : }
1444 :
1445 402328 : if (strcmp(oid, oid_out) != 0) {
1446 0 : talloc_free(tmp_ctx);
1447 0 : return WERR_INVALID_PARAMETER;
1448 : }
1449 : }
1450 :
1451 402328 : talloc_free(tmp_ctx);
1452 402328 : return WERR_OK;
1453 : }
1454 :
1455 1087122 : static WERROR dsdb_syntax_OID_validate_ldb(const struct dsdb_syntax_ctx *ctx,
1456 : const struct dsdb_attribute *attr,
1457 : const struct ldb_message_element *in)
1458 : {
1459 180527 : WERROR status;
1460 180527 : struct drsuapi_DsReplicaAttribute drs_tmp;
1461 180527 : struct ldb_message_element ldb_tmp;
1462 180527 : TALLOC_CTX *tmp_ctx;
1463 :
1464 1087122 : if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
1465 0 : return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
1466 : }
1467 :
1468 1087122 : switch (attr->attributeID_id) {
1469 402328 : case DRSUAPI_ATTID_governsID:
1470 : case DRSUAPI_ATTID_attributeID:
1471 : case DRSUAPI_ATTID_attributeSyntax:
1472 402328 : return _dsdb_syntax_OID_validate_numericoid(ctx, attr, in);
1473 : }
1474 :
1475 : /*
1476 : * TODO: optimize and verify this code
1477 : */
1478 :
1479 684794 : tmp_ctx = talloc_new(ctx->ldb);
1480 684794 : W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1481 :
1482 684794 : status = dsdb_syntax_OID_ldb_to_drsuapi(ctx,
1483 : attr,
1484 : in,
1485 : tmp_ctx,
1486 : &drs_tmp);
1487 684794 : if (!W_ERROR_IS_OK(status)) {
1488 57 : talloc_free(tmp_ctx);
1489 57 : return status;
1490 : }
1491 :
1492 684737 : status = dsdb_syntax_OID_drsuapi_to_ldb(ctx,
1493 : attr,
1494 : &drs_tmp,
1495 : tmp_ctx,
1496 : &ldb_tmp);
1497 684737 : if (!W_ERROR_IS_OK(status)) {
1498 0 : talloc_free(tmp_ctx);
1499 0 : return status;
1500 : }
1501 :
1502 684737 : talloc_free(tmp_ctx);
1503 684737 : return WERR_OK;
1504 : }
1505 :
1506 5901893 : static WERROR dsdb_syntax_UNICODE_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
1507 : const struct dsdb_attribute *attr,
1508 : const struct drsuapi_DsReplicaAttribute *in,
1509 : TALLOC_CTX *mem_ctx,
1510 : struct ldb_message_element *out)
1511 : {
1512 619467 : unsigned int i;
1513 :
1514 5901893 : out->flags = 0;
1515 5901893 : out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1516 5901893 : W_ERROR_HAVE_NO_MEMORY(out->name);
1517 :
1518 5901893 : out->num_values = in->value_ctr.num_values;
1519 5901893 : out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1520 5901893 : W_ERROR_HAVE_NO_MEMORY(out->values);
1521 :
1522 12968791 : for (i=0; i < out->num_values; i++) {
1523 7066898 : size_t converted_size = 0;
1524 619467 : char *str;
1525 :
1526 7066898 : if (in->value_ctr.values[i].blob == NULL) {
1527 0 : return WERR_FOOBAR;
1528 : }
1529 :
1530 7066898 : if (in->value_ctr.values[i].blob->length == 0) {
1531 0 : return WERR_FOOBAR;
1532 : }
1533 :
1534 7066898 : if (!convert_string_talloc(out->values,
1535 : CH_UTF16, CH_UNIX,
1536 7066898 : in->value_ctr.values[i].blob->data,
1537 6447431 : in->value_ctr.values[i].blob->length,
1538 : &str, &converted_size)) {
1539 0 : return WERR_FOOBAR;
1540 : }
1541 :
1542 7066898 : out->values[i] = data_blob_const(str, converted_size);
1543 : }
1544 :
1545 5901893 : return WERR_OK;
1546 : }
1547 :
1548 5411797 : static WERROR dsdb_syntax_UNICODE_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
1549 : const struct dsdb_attribute *attr,
1550 : const struct ldb_message_element *in,
1551 : TALLOC_CTX *mem_ctx,
1552 : struct drsuapi_DsReplicaAttribute *out)
1553 : {
1554 619467 : unsigned int i;
1555 619467 : DATA_BLOB *blobs;
1556 :
1557 5411797 : if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
1558 0 : return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
1559 : }
1560 :
1561 10823594 : out->attid = dsdb_attribute_get_attid(attr,
1562 5411797 : ctx->is_schema_nc);
1563 5411797 : out->value_ctr.num_values = in->num_values;
1564 5411797 : out->value_ctr.values = talloc_array(mem_ctx,
1565 : struct drsuapi_DsAttributeValue,
1566 : in->num_values);
1567 5411797 : W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1568 :
1569 5411797 : blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1570 5411797 : W_ERROR_HAVE_NO_MEMORY(blobs);
1571 :
1572 12075927 : for (i=0; i < in->num_values; i++) {
1573 6664130 : out->value_ctr.values[i].blob = &blobs[i];
1574 :
1575 6664130 : if (!convert_string_talloc(blobs,
1576 : CH_UNIX, CH_UTF16,
1577 6664130 : in->values[i].data, in->values[i].length,
1578 6664130 : &blobs[i].data, &blobs[i].length)) {
1579 0 : return WERR_FOOBAR;
1580 : }
1581 : }
1582 :
1583 5411797 : return WERR_OK;
1584 : }
1585 :
1586 3285712 : static WERROR dsdb_syntax_UNICODE_validate_one_val(const struct dsdb_syntax_ctx *ctx,
1587 : const struct dsdb_attribute *attr,
1588 : const struct ldb_val *val)
1589 : {
1590 3285712 : void *dst = NULL;
1591 555349 : size_t size;
1592 555349 : bool ok;
1593 :
1594 3285712 : if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
1595 0 : return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
1596 : }
1597 :
1598 3841061 : ok = convert_string_talloc(ctx->ldb,
1599 : CH_UNIX, CH_UTF16,
1600 3285712 : val->data,
1601 3285712 : val->length,
1602 : &dst,
1603 : &size);
1604 3285712 : TALLOC_FREE(dst);
1605 3285712 : if (!ok) {
1606 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1607 : }
1608 :
1609 3285712 : if (attr->rangeLower) {
1610 1078798 : if ((size/2) < *attr->rangeLower) {
1611 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1612 : }
1613 : }
1614 :
1615 3285712 : if (attr->rangeUpper) {
1616 1094547 : if ((size/2) > *attr->rangeUpper) {
1617 3 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1618 : }
1619 : }
1620 :
1621 3285709 : return WERR_OK;
1622 : }
1623 :
1624 1800566 : static WERROR dsdb_syntax_UNICODE_validate_ldb(const struct dsdb_syntax_ctx *ctx,
1625 : const struct dsdb_attribute *attr,
1626 : const struct ldb_message_element *in)
1627 : {
1628 298336 : WERROR status;
1629 298336 : unsigned int i;
1630 :
1631 1800566 : if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
1632 0 : return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
1633 : }
1634 :
1635 5086275 : for (i=0; i < in->num_values; i++) {
1636 3285712 : if (in->values[i].length == 0) {
1637 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1638 : }
1639 :
1640 3285712 : status = dsdb_syntax_UNICODE_validate_one_val(ctx,
1641 : attr,
1642 2730363 : &in->values[i]);
1643 3285712 : if (!W_ERROR_IS_OK(status)) {
1644 3 : return status;
1645 : }
1646 : }
1647 :
1648 1800563 : return WERR_OK;
1649 : }
1650 :
1651 729990 : static WERROR dsdb_syntax_one_DN_drsuapi_to_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
1652 : const struct dsdb_syntax *syntax,
1653 : const DATA_BLOB *in, DATA_BLOB *out)
1654 : {
1655 2 : struct drsuapi_DsReplicaObjectIdentifier3 id3;
1656 2 : enum ndr_err_code ndr_err;
1657 2 : DATA_BLOB guid_blob;
1658 2 : struct ldb_dn *dn;
1659 729990 : TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1660 2 : int ret;
1661 2 : NTSTATUS status;
1662 :
1663 729990 : if (!tmp_ctx) {
1664 0 : W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1665 : }
1666 :
1667 729990 : if (in == NULL) {
1668 0 : talloc_free(tmp_ctx);
1669 0 : return WERR_FOOBAR;
1670 : }
1671 :
1672 729990 : if (in->length == 0) {
1673 0 : talloc_free(tmp_ctx);
1674 0 : return WERR_FOOBAR;
1675 : }
1676 :
1677 :
1678 : /* windows sometimes sends an extra two pad bytes here */
1679 729990 : ndr_err = ndr_pull_struct_blob(in,
1680 : tmp_ctx, &id3,
1681 : (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3);
1682 729990 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1683 0 : status = ndr_map_error2ntstatus(ndr_err);
1684 0 : talloc_free(tmp_ctx);
1685 0 : return ntstatus_to_werror(status);
1686 : }
1687 :
1688 729990 : dn = ldb_dn_new(tmp_ctx, ldb, id3.dn);
1689 729990 : if (!dn) {
1690 0 : talloc_free(tmp_ctx);
1691 : /* If this fails, it must be out of memory, as it does not do much parsing */
1692 0 : W_ERROR_HAVE_NO_MEMORY(dn);
1693 : }
1694 :
1695 729990 : if (!GUID_all_zero(&id3.guid)) {
1696 729130 : status = GUID_to_ndr_blob(&id3.guid, tmp_ctx, &guid_blob);
1697 729130 : if (!NT_STATUS_IS_OK(status)) {
1698 0 : talloc_free(tmp_ctx);
1699 0 : return ntstatus_to_werror(status);
1700 : }
1701 :
1702 729130 : ret = ldb_dn_set_extended_component(dn, "GUID", &guid_blob);
1703 729130 : if (ret != LDB_SUCCESS) {
1704 0 : talloc_free(tmp_ctx);
1705 0 : return WERR_FOOBAR;
1706 : }
1707 729130 : talloc_free(guid_blob.data);
1708 : }
1709 :
1710 729990 : if (id3.__ndr_size_sid) {
1711 1 : DATA_BLOB sid_blob;
1712 24091 : ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, &id3.sid,
1713 : (ndr_push_flags_fn_t)ndr_push_dom_sid);
1714 24091 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1715 0 : status = ndr_map_error2ntstatus(ndr_err);
1716 0 : talloc_free(tmp_ctx);
1717 0 : return ntstatus_to_werror(status);
1718 : }
1719 :
1720 24091 : ret = ldb_dn_set_extended_component(dn, "SID", &sid_blob);
1721 24091 : if (ret != LDB_SUCCESS) {
1722 0 : talloc_free(tmp_ctx);
1723 0 : return WERR_FOOBAR;
1724 : }
1725 : }
1726 :
1727 729990 : *out = data_blob_string_const(ldb_dn_get_extended_linearized(mem_ctx, dn, 1));
1728 729990 : talloc_free(tmp_ctx);
1729 729990 : W_ERROR_HAVE_NO_MEMORY(out->data);
1730 729990 : return WERR_OK;
1731 : }
1732 :
1733 874722 : static WERROR dsdb_syntax_DN_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
1734 : const struct dsdb_attribute *attr,
1735 : const struct drsuapi_DsReplicaAttribute *in,
1736 : TALLOC_CTX *mem_ctx,
1737 : struct ldb_message_element *out)
1738 : {
1739 2 : unsigned int i;
1740 :
1741 874722 : out->flags = 0;
1742 874722 : out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1743 874722 : W_ERROR_HAVE_NO_MEMORY(out->name);
1744 :
1745 874722 : out->num_values = in->value_ctr.num_values;
1746 874722 : out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1747 874722 : W_ERROR_HAVE_NO_MEMORY(out->values);
1748 :
1749 1604712 : for (i=0; i < out->num_values; i++) {
1750 729990 : WERROR status = dsdb_syntax_one_DN_drsuapi_to_ldb(out->values, ctx->ldb, attr->syntax,
1751 729990 : in->value_ctr.values[i].blob,
1752 729990 : &out->values[i]);
1753 729990 : if (!W_ERROR_IS_OK(status)) {
1754 0 : return status;
1755 : }
1756 :
1757 : }
1758 :
1759 874722 : return WERR_OK;
1760 : }
1761 :
1762 614605 : static WERROR dsdb_syntax_DN_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
1763 : const struct dsdb_attribute *attr,
1764 : const struct ldb_message_element *in,
1765 : TALLOC_CTX *mem_ctx,
1766 : struct drsuapi_DsReplicaAttribute *out)
1767 : {
1768 2 : unsigned int i;
1769 2 : DATA_BLOB *blobs;
1770 :
1771 614605 : if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
1772 0 : return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
1773 : }
1774 :
1775 1229210 : out->attid = dsdb_attribute_get_attid(attr,
1776 614605 : ctx->is_schema_nc);
1777 614605 : out->value_ctr.num_values = in->num_values;
1778 614605 : out->value_ctr.values = talloc_array(mem_ctx,
1779 : struct drsuapi_DsAttributeValue,
1780 : in->num_values);
1781 614605 : W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1782 :
1783 614605 : blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1784 614605 : W_ERROR_HAVE_NO_MEMORY(blobs);
1785 :
1786 1230992 : for (i=0; i < in->num_values; i++) {
1787 2 : struct drsuapi_DsReplicaObjectIdentifier3 id3;
1788 2 : enum ndr_err_code ndr_err;
1789 2 : struct ldb_dn *dn;
1790 616387 : TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1791 2 : NTSTATUS status;
1792 :
1793 616387 : W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1794 :
1795 616387 : out->value_ctr.values[i].blob = &blobs[i];
1796 :
1797 616387 : dn = ldb_dn_from_ldb_val(tmp_ctx, ctx->ldb, &in->values[i]);
1798 :
1799 616387 : W_ERROR_HAVE_NO_MEMORY(dn);
1800 :
1801 616387 : ZERO_STRUCT(id3);
1802 :
1803 616387 : status = dsdb_get_extended_dn_guid(dn, &id3.guid, "GUID");
1804 616387 : if (!NT_STATUS_IS_OK(status) &&
1805 820 : !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1806 0 : talloc_free(tmp_ctx);
1807 0 : return ntstatus_to_werror(status);
1808 : }
1809 :
1810 616387 : status = dsdb_get_extended_dn_sid(dn, &id3.sid, "SID");
1811 616387 : if (!NT_STATUS_IS_OK(status) &&
1812 603425 : !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1813 0 : talloc_free(tmp_ctx);
1814 0 : return ntstatus_to_werror(status);
1815 : }
1816 :
1817 616387 : id3.dn = ldb_dn_get_linearized(dn);
1818 :
1819 616387 : ndr_err = ndr_push_struct_blob(&blobs[i], blobs, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
1820 616387 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1821 0 : status = ndr_map_error2ntstatus(ndr_err);
1822 0 : talloc_free(tmp_ctx);
1823 0 : return ntstatus_to_werror(status);
1824 : }
1825 616387 : talloc_free(tmp_ctx);
1826 : }
1827 :
1828 614605 : return WERR_OK;
1829 : }
1830 :
1831 874558 : static WERROR dsdb_syntax_DN_validate_one_val(const struct dsdb_syntax_ctx *ctx,
1832 : const struct dsdb_attribute *attr,
1833 : const struct ldb_val *val,
1834 : TALLOC_CTX *mem_ctx,
1835 : struct dsdb_dn **_dsdb_dn)
1836 : {
1837 104252 : static const char * const extended_list[] = { "GUID", "SID", NULL };
1838 104252 : enum ndr_err_code ndr_err;
1839 104252 : struct GUID guid;
1840 104252 : struct dom_sid sid;
1841 104252 : const DATA_BLOB *sid_blob;
1842 104252 : struct dsdb_dn *dsdb_dn;
1843 104252 : struct ldb_dn *dn;
1844 104252 : char *dn_str;
1845 104252 : struct ldb_dn *dn2;
1846 104252 : char *dn2_str;
1847 104252 : int num_components;
1848 874558 : TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1849 104252 : NTSTATUS status;
1850 :
1851 874558 : W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1852 :
1853 874558 : if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
1854 0 : return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
1855 : }
1856 :
1857 1749116 : dsdb_dn = dsdb_dn_parse(tmp_ctx, ctx->ldb, val,
1858 874558 : attr->syntax->ldap_oid);
1859 874558 : if (!dsdb_dn) {
1860 0 : talloc_free(tmp_ctx);
1861 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1862 : }
1863 874558 : dn = dsdb_dn->dn;
1864 :
1865 874558 : dn2 = ldb_dn_copy(tmp_ctx, dn);
1866 874558 : if (dn == NULL) {
1867 0 : talloc_free(tmp_ctx);
1868 0 : return WERR_NOT_ENOUGH_MEMORY;
1869 : }
1870 :
1871 874558 : num_components = ldb_dn_get_comp_num(dn);
1872 :
1873 874558 : status = dsdb_get_extended_dn_guid(dn, &guid, "GUID");
1874 874558 : if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1875 140718 : num_components++;
1876 733840 : } else if (!NT_STATUS_IS_OK(status)) {
1877 0 : talloc_free(tmp_ctx);
1878 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1879 : }
1880 :
1881 874558 : sid_blob = ldb_dn_get_extended_component(dn, "SID");
1882 874558 : if (sid_blob) {
1883 33440 : num_components++;
1884 33440 : ndr_err = ndr_pull_struct_blob_all(sid_blob,
1885 : tmp_ctx,
1886 : &sid,
1887 : (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1888 33440 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1889 0 : talloc_free(tmp_ctx);
1890 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1891 : }
1892 : }
1893 :
1894 : /* Do not allow links to the RootDSE */
1895 874558 : if (num_components == 0) {
1896 0 : talloc_free(tmp_ctx);
1897 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1898 : }
1899 :
1900 : /*
1901 : * We need to check that only "GUID" and "SID" are
1902 : * specified as extended components, we do that
1903 : * by comparing the dn's after removing all components
1904 : * from one dn and only the allowed subset from the other
1905 : * one.
1906 : */
1907 874558 : ldb_dn_extended_filter(dn, extended_list);
1908 :
1909 874558 : dn_str = ldb_dn_get_extended_linearized(tmp_ctx, dn, 0);
1910 874558 : if (dn_str == NULL) {
1911 0 : talloc_free(tmp_ctx);
1912 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1913 : }
1914 874558 : dn2_str = ldb_dn_get_extended_linearized(tmp_ctx, dn2, 0);
1915 874558 : if (dn2_str == NULL) {
1916 0 : talloc_free(tmp_ctx);
1917 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1918 : }
1919 :
1920 874558 : if (strcmp(dn_str, dn2_str) != 0) {
1921 2 : talloc_free(tmp_ctx);
1922 2 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1923 : }
1924 :
1925 874556 : *_dsdb_dn = talloc_move(mem_ctx, &dsdb_dn);
1926 874556 : talloc_free(tmp_ctx);
1927 874556 : return WERR_OK;
1928 : }
1929 :
1930 846375 : static WERROR dsdb_syntax_DN_validate_ldb(const struct dsdb_syntax_ctx *ctx,
1931 : const struct dsdb_attribute *attr,
1932 : const struct ldb_message_element *in)
1933 : {
1934 102683 : unsigned int i;
1935 :
1936 846375 : if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
1937 0 : return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
1938 : }
1939 :
1940 1700773 : for (i=0; i < in->num_values; i++) {
1941 103594 : WERROR status;
1942 103594 : struct dsdb_dn *dsdb_dn;
1943 854400 : TALLOC_CTX *tmp_ctx = talloc_new(ctx->ldb);
1944 854400 : W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1945 :
1946 854400 : status = dsdb_syntax_DN_validate_one_val(ctx,
1947 : attr,
1948 854400 : &in->values[i],
1949 : tmp_ctx, &dsdb_dn);
1950 854400 : if (!W_ERROR_IS_OK(status)) {
1951 2 : talloc_free(tmp_ctx);
1952 2 : return status;
1953 : }
1954 :
1955 854398 : if (dsdb_dn->dn_format != DSDB_NORMAL_DN) {
1956 0 : talloc_free(tmp_ctx);
1957 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1958 : }
1959 :
1960 854398 : talloc_free(tmp_ctx);
1961 : }
1962 :
1963 846373 : return WERR_OK;
1964 : }
1965 :
1966 7783 : static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
1967 : const struct dsdb_attribute *attr,
1968 : const struct drsuapi_DsReplicaAttribute *in,
1969 : TALLOC_CTX *mem_ctx,
1970 : struct ldb_message_element *out)
1971 : {
1972 3 : unsigned int i;
1973 3 : int ret;
1974 :
1975 7783 : out->flags = 0;
1976 7783 : out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1977 7783 : W_ERROR_HAVE_NO_MEMORY(out->name);
1978 :
1979 7783 : out->num_values = in->value_ctr.num_values;
1980 7783 : out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1981 7783 : W_ERROR_HAVE_NO_MEMORY(out->values);
1982 :
1983 19470 : for (i=0; i < out->num_values; i++) {
1984 3 : struct drsuapi_DsReplicaObjectIdentifier3Binary id3;
1985 3 : enum ndr_err_code ndr_err;
1986 3 : DATA_BLOB guid_blob;
1987 3 : struct ldb_dn *dn;
1988 3 : struct dsdb_dn *dsdb_dn;
1989 3 : NTSTATUS status;
1990 11687 : TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1991 11687 : if (!tmp_ctx) {
1992 0 : W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1993 : }
1994 :
1995 11687 : if (in->value_ctr.values[i].blob == NULL) {
1996 0 : talloc_free(tmp_ctx);
1997 0 : return WERR_FOOBAR;
1998 : }
1999 :
2000 11687 : if (in->value_ctr.values[i].blob->length == 0) {
2001 0 : talloc_free(tmp_ctx);
2002 0 : return WERR_FOOBAR;
2003 : }
2004 :
2005 :
2006 : /* windows sometimes sends an extra two pad bytes here */
2007 11687 : ndr_err = ndr_pull_struct_blob(in->value_ctr.values[i].blob,
2008 : tmp_ctx, &id3,
2009 : (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary);
2010 11687 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2011 0 : status = ndr_map_error2ntstatus(ndr_err);
2012 0 : talloc_free(tmp_ctx);
2013 0 : return ntstatus_to_werror(status);
2014 : }
2015 :
2016 11687 : dn = ldb_dn_new(tmp_ctx, ctx->ldb, id3.dn);
2017 11687 : if (!dn) {
2018 0 : talloc_free(tmp_ctx);
2019 : /* If this fails, it must be out of memory, as it does not do much parsing */
2020 0 : W_ERROR_HAVE_NO_MEMORY(dn);
2021 : }
2022 :
2023 11687 : if (!GUID_all_zero(&id3.guid)) {
2024 11687 : status = GUID_to_ndr_blob(&id3.guid, tmp_ctx, &guid_blob);
2025 11687 : if (!NT_STATUS_IS_OK(status)) {
2026 0 : talloc_free(tmp_ctx);
2027 0 : return ntstatus_to_werror(status);
2028 : }
2029 :
2030 11687 : ret = ldb_dn_set_extended_component(dn, "GUID", &guid_blob);
2031 11687 : if (ret != LDB_SUCCESS) {
2032 0 : talloc_free(tmp_ctx);
2033 0 : return WERR_FOOBAR;
2034 : }
2035 11687 : talloc_free(guid_blob.data);
2036 : }
2037 :
2038 11687 : if (id3.__ndr_size_sid) {
2039 2 : DATA_BLOB sid_blob;
2040 5900 : ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, &id3.sid,
2041 : (ndr_push_flags_fn_t)ndr_push_dom_sid);
2042 5900 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2043 0 : status = ndr_map_error2ntstatus(ndr_err);
2044 0 : talloc_free(tmp_ctx);
2045 0 : return ntstatus_to_werror(status);
2046 : }
2047 :
2048 5900 : ret = ldb_dn_set_extended_component(dn, "SID", &sid_blob);
2049 5900 : if (ret != LDB_SUCCESS) {
2050 0 : talloc_free(tmp_ctx);
2051 0 : return WERR_FOOBAR;
2052 : }
2053 : }
2054 :
2055 : /* set binary stuff */
2056 11687 : dsdb_dn = dsdb_dn_construct(tmp_ctx, dn, id3.binary, attr->syntax->ldap_oid);
2057 11687 : if (!dsdb_dn) {
2058 0 : if (errno == EINVAL) {
2059 : /*
2060 : * This might be Object(OR-Name)
2061 : * failing because of a non empty
2062 : * binary part.
2063 : */
2064 0 : talloc_free(tmp_ctx);
2065 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
2066 : }
2067 0 : talloc_free(tmp_ctx);
2068 0 : W_ERROR_HAVE_NO_MEMORY(dsdb_dn);
2069 : }
2070 11687 : out->values[i] = data_blob_string_const(dsdb_dn_get_extended_linearized(out->values, dsdb_dn, 1));
2071 11687 : talloc_free(tmp_ctx);
2072 11687 : W_ERROR_HAVE_NO_MEMORY(out->values[i].data);
2073 : }
2074 :
2075 7783 : return WERR_OK;
2076 : }
2077 :
2078 4219 : static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
2079 : const struct dsdb_attribute *attr,
2080 : const struct ldb_message_element *in,
2081 : TALLOC_CTX *mem_ctx,
2082 : struct drsuapi_DsReplicaAttribute *out)
2083 : {
2084 3 : unsigned int i;
2085 3 : DATA_BLOB *blobs;
2086 :
2087 4219 : if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
2088 0 : return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
2089 : }
2090 :
2091 8438 : out->attid = dsdb_attribute_get_attid(attr,
2092 4219 : ctx->is_schema_nc);
2093 4219 : out->value_ctr.num_values = in->num_values;
2094 4219 : out->value_ctr.values = talloc_array(mem_ctx,
2095 : struct drsuapi_DsAttributeValue,
2096 : in->num_values);
2097 4219 : W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
2098 :
2099 4219 : blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
2100 4219 : W_ERROR_HAVE_NO_MEMORY(blobs);
2101 :
2102 16161 : for (i=0; i < in->num_values; i++) {
2103 3 : struct drsuapi_DsReplicaObjectIdentifier3Binary id3;
2104 3 : enum ndr_err_code ndr_err;
2105 3 : const DATA_BLOB *sid_blob;
2106 3 : struct dsdb_dn *dsdb_dn;
2107 11942 : TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
2108 3 : NTSTATUS status;
2109 :
2110 11942 : W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
2111 :
2112 11942 : out->value_ctr.values[i].blob = &blobs[i];
2113 :
2114 11942 : dsdb_dn = dsdb_dn_parse(tmp_ctx, ctx->ldb, &in->values[i], attr->syntax->ldap_oid);
2115 :
2116 11942 : if (!dsdb_dn) {
2117 0 : talloc_free(tmp_ctx);
2118 0 : return ntstatus_to_werror(NT_STATUS_INVALID_PARAMETER);
2119 : }
2120 :
2121 11942 : ZERO_STRUCT(id3);
2122 :
2123 11942 : status = dsdb_get_extended_dn_guid(dsdb_dn->dn, &id3.guid, "GUID");
2124 11942 : if (!NT_STATUS_IS_OK(status) &&
2125 0 : !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2126 0 : talloc_free(tmp_ctx);
2127 0 : return ntstatus_to_werror(status);
2128 : }
2129 :
2130 11942 : sid_blob = ldb_dn_get_extended_component(dsdb_dn->dn, "SID");
2131 11942 : if (sid_blob) {
2132 :
2133 2207 : ndr_err = ndr_pull_struct_blob_all(sid_blob,
2134 : tmp_ctx, &id3.sid,
2135 : (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
2136 2207 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2137 0 : status = ndr_map_error2ntstatus(ndr_err);
2138 0 : talloc_free(tmp_ctx);
2139 0 : return ntstatus_to_werror(status);
2140 : }
2141 : }
2142 :
2143 11942 : id3.dn = ldb_dn_get_linearized(dsdb_dn->dn);
2144 :
2145 : /* get binary stuff */
2146 11942 : id3.binary = dsdb_dn->extra_part;
2147 :
2148 11942 : ndr_err = ndr_push_struct_blob(&blobs[i], blobs, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary);
2149 11942 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2150 0 : status = ndr_map_error2ntstatus(ndr_err);
2151 0 : talloc_free(tmp_ctx);
2152 0 : return ntstatus_to_werror(status);
2153 : }
2154 11942 : talloc_free(tmp_ctx);
2155 : }
2156 :
2157 4219 : return WERR_OK;
2158 : }
2159 :
2160 17638 : static WERROR dsdb_syntax_DN_BINARY_validate_ldb(const struct dsdb_syntax_ctx *ctx,
2161 : const struct dsdb_attribute *attr,
2162 : const struct ldb_message_element *in)
2163 : {
2164 209 : unsigned int i;
2165 :
2166 17638 : if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
2167 0 : return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
2168 : }
2169 :
2170 37796 : for (i=0; i < in->num_values; i++) {
2171 658 : WERROR status;
2172 658 : struct dsdb_dn *dsdb_dn;
2173 20158 : TALLOC_CTX *tmp_ctx = talloc_new(ctx->ldb);
2174 20158 : W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
2175 :
2176 20816 : status = dsdb_syntax_DN_validate_one_val(ctx,
2177 : attr,
2178 20158 : &in->values[i],
2179 : tmp_ctx, &dsdb_dn);
2180 20158 : if (!W_ERROR_IS_OK(status)) {
2181 0 : talloc_free(tmp_ctx);
2182 0 : return status;
2183 : }
2184 :
2185 20158 : if (dsdb_dn->dn_format != DSDB_BINARY_DN) {
2186 0 : talloc_free(tmp_ctx);
2187 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
2188 : }
2189 :
2190 20816 : status = dsdb_syntax_DATA_BLOB_validate_one_val(ctx,
2191 : attr,
2192 20158 : &dsdb_dn->extra_part);
2193 20158 : if (!W_ERROR_IS_OK(status)) {
2194 0 : talloc_free(tmp_ctx);
2195 0 : return status;
2196 : }
2197 :
2198 20158 : talloc_free(tmp_ctx);
2199 : }
2200 :
2201 17638 : return WERR_OK;
2202 : }
2203 :
2204 0 : static WERROR dsdb_syntax_DN_STRING_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
2205 : const struct dsdb_attribute *attr,
2206 : const struct drsuapi_DsReplicaAttribute *in,
2207 : TALLOC_CTX *mem_ctx,
2208 : struct ldb_message_element *out)
2209 : {
2210 0 : return dsdb_syntax_DN_BINARY_drsuapi_to_ldb(ctx,
2211 : attr,
2212 : in,
2213 : mem_ctx,
2214 : out);
2215 : }
2216 :
2217 0 : static WERROR dsdb_syntax_DN_STRING_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
2218 : const struct dsdb_attribute *attr,
2219 : const struct ldb_message_element *in,
2220 : TALLOC_CTX *mem_ctx,
2221 : struct drsuapi_DsReplicaAttribute *out)
2222 : {
2223 0 : return dsdb_syntax_DN_BINARY_ldb_to_drsuapi(ctx,
2224 : attr,
2225 : in,
2226 : mem_ctx,
2227 : out);
2228 : }
2229 :
2230 0 : static WERROR dsdb_syntax_DN_STRING_validate_ldb(const struct dsdb_syntax_ctx *ctx,
2231 : const struct dsdb_attribute *attr,
2232 : const struct ldb_message_element *in)
2233 : {
2234 0 : unsigned int i;
2235 :
2236 0 : if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
2237 0 : return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
2238 : }
2239 :
2240 0 : for (i=0; i < in->num_values; i++) {
2241 0 : WERROR status;
2242 0 : struct dsdb_dn *dsdb_dn;
2243 0 : TALLOC_CTX *tmp_ctx = talloc_new(ctx->ldb);
2244 0 : W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
2245 :
2246 0 : status = dsdb_syntax_DN_validate_one_val(ctx,
2247 : attr,
2248 0 : &in->values[i],
2249 : tmp_ctx, &dsdb_dn);
2250 0 : if (!W_ERROR_IS_OK(status)) {
2251 0 : talloc_free(tmp_ctx);
2252 0 : return status;
2253 : }
2254 :
2255 0 : if (dsdb_dn->dn_format != DSDB_STRING_DN) {
2256 0 : talloc_free(tmp_ctx);
2257 0 : return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
2258 : }
2259 :
2260 0 : status = dsdb_syntax_UNICODE_validate_one_val(ctx,
2261 : attr,
2262 0 : &dsdb_dn->extra_part);
2263 0 : if (!W_ERROR_IS_OK(status)) {
2264 0 : talloc_free(tmp_ctx);
2265 0 : return status;
2266 : }
2267 :
2268 0 : talloc_free(tmp_ctx);
2269 : }
2270 :
2271 0 : return WERR_OK;
2272 : }
2273 :
2274 0 : static WERROR dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
2275 : const struct dsdb_attribute *attr,
2276 : const struct drsuapi_DsReplicaAttribute *in,
2277 : TALLOC_CTX *mem_ctx,
2278 : struct ldb_message_element *out)
2279 : {
2280 0 : unsigned int i;
2281 :
2282 0 : out->flags = 0;
2283 0 : out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
2284 0 : W_ERROR_HAVE_NO_MEMORY(out->name);
2285 :
2286 0 : out->num_values = in->value_ctr.num_values;
2287 0 : out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
2288 0 : W_ERROR_HAVE_NO_MEMORY(out->values);
2289 :
2290 0 : for (i=0; i < out->num_values; i++) {
2291 0 : size_t len;
2292 0 : size_t converted_size = 0;
2293 0 : char *str;
2294 :
2295 0 : if (in->value_ctr.values[i].blob == NULL) {
2296 0 : return WERR_FOOBAR;
2297 : }
2298 :
2299 0 : if (in->value_ctr.values[i].blob->length < 4) {
2300 0 : return WERR_FOOBAR;
2301 : }
2302 :
2303 0 : len = IVAL(in->value_ctr.values[i].blob->data, 0);
2304 :
2305 0 : if (len != in->value_ctr.values[i].blob->length) {
2306 0 : return WERR_FOOBAR;
2307 : }
2308 :
2309 0 : if (!convert_string_talloc(out->values, CH_UTF16, CH_UNIX,
2310 0 : in->value_ctr.values[i].blob->data+4,
2311 0 : in->value_ctr.values[i].blob->length-4,
2312 : (void **)&str, &converted_size)) {
2313 0 : return WERR_FOOBAR;
2314 : }
2315 :
2316 0 : out->values[i] = data_blob_string_const(str);
2317 : }
2318 :
2319 0 : return WERR_OK;
2320 : }
2321 :
2322 0 : static WERROR dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
2323 : const struct dsdb_attribute *attr,
2324 : const struct ldb_message_element *in,
2325 : TALLOC_CTX *mem_ctx,
2326 : struct drsuapi_DsReplicaAttribute *out)
2327 : {
2328 0 : unsigned int i;
2329 0 : DATA_BLOB *blobs;
2330 :
2331 0 : if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
2332 0 : return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
2333 : }
2334 :
2335 0 : out->attid = dsdb_attribute_get_attid(attr,
2336 0 : ctx->is_schema_nc);
2337 0 : out->value_ctr.num_values = in->num_values;
2338 0 : out->value_ctr.values = talloc_array(mem_ctx,
2339 : struct drsuapi_DsAttributeValue,
2340 : in->num_values);
2341 0 : W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
2342 :
2343 0 : blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
2344 0 : W_ERROR_HAVE_NO_MEMORY(blobs);
2345 :
2346 0 : for (i=0; i < in->num_values; i++) {
2347 0 : uint8_t *data;
2348 0 : size_t ret;
2349 :
2350 0 : out->value_ctr.values[i].blob = &blobs[i];
2351 :
2352 0 : if (!convert_string_talloc(blobs, CH_UNIX, CH_UTF16,
2353 0 : in->values[i].data,
2354 0 : in->values[i].length,
2355 : (void **)&data, &ret)) {
2356 0 : return WERR_FOOBAR;
2357 : }
2358 :
2359 0 : blobs[i] = data_blob_talloc(blobs, NULL, 4 + ret);
2360 0 : W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
2361 :
2362 0 : SIVAL(blobs[i].data, 0, 4 + ret);
2363 :
2364 0 : if (ret > 0) {
2365 0 : memcpy(blobs[i].data + 4, data, ret);
2366 0 : talloc_free(data);
2367 : }
2368 : }
2369 :
2370 0 : return WERR_OK;
2371 : }
2372 :
2373 0 : static WERROR dsdb_syntax_PRESENTATION_ADDRESS_validate_ldb(const struct dsdb_syntax_ctx *ctx,
2374 : const struct dsdb_attribute *attr,
2375 : const struct ldb_message_element *in)
2376 : {
2377 0 : return dsdb_syntax_UNICODE_validate_ldb(ctx,
2378 : attr,
2379 : in);
2380 : }
2381 :
2382 : #define OMOBJECTCLASS(val) { .length = sizeof(val) - 1, .data = discard_const_p(uint8_t, val) }
2383 :
2384 : static const struct dsdb_syntax dsdb_syntaxes[] = {
2385 : {
2386 : .name = "Boolean",
2387 : .ldap_oid = LDB_SYNTAX_BOOLEAN,
2388 : .oMSyntax = 1,
2389 : .attributeSyntax_oid = "2.5.5.8",
2390 : .drsuapi_to_ldb = dsdb_syntax_BOOL_drsuapi_to_ldb,
2391 : .ldb_to_drsuapi = dsdb_syntax_BOOL_ldb_to_drsuapi,
2392 : .validate_ldb = dsdb_syntax_BOOL_validate_ldb,
2393 : .equality = "booleanMatch",
2394 : .comment = "Boolean",
2395 : .auto_normalise = true
2396 : },{
2397 : .name = "Integer",
2398 : .ldap_oid = LDB_SYNTAX_INTEGER,
2399 : .oMSyntax = 2,
2400 : .attributeSyntax_oid = "2.5.5.9",
2401 : .drsuapi_to_ldb = dsdb_syntax_INT32_drsuapi_to_ldb,
2402 : .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi,
2403 : .validate_ldb = dsdb_syntax_INT32_validate_ldb,
2404 : .equality = "integerMatch",
2405 : .comment = "Integer",
2406 : .ldb_syntax = LDB_SYNTAX_SAMBA_INT32,
2407 : .auto_normalise = true
2408 : },{
2409 : .name = "String(Octet)",
2410 : .ldap_oid = LDB_SYNTAX_OCTET_STRING,
2411 : .oMSyntax = 4,
2412 : .attributeSyntax_oid = "2.5.5.10",
2413 : .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
2414 : .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
2415 : .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb,
2416 : .equality = "octetStringMatch",
2417 : .comment = "Octet String",
2418 : .userParameters = true,
2419 : .ldb_syntax = LDB_SYNTAX_SAMBA_OCTET_STRING
2420 : },{
2421 : .name = "String(Sid)",
2422 : .ldap_oid = LDB_SYNTAX_OCTET_STRING,
2423 : .oMSyntax = 4,
2424 : .attributeSyntax_oid = "2.5.5.17",
2425 : .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
2426 : .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
2427 : .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb,
2428 : .equality = "octetStringMatch",
2429 : .comment = "Octet String - Security Identifier (SID)",
2430 : .ldb_syntax = LDB_SYNTAX_SAMBA_SID
2431 : },{
2432 : .name = "String(Object-Identifier)",
2433 : .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.38",
2434 : .oMSyntax = 6,
2435 : .attributeSyntax_oid = "2.5.5.2",
2436 : .drsuapi_to_ldb = dsdb_syntax_OID_drsuapi_to_ldb,
2437 : .ldb_to_drsuapi = dsdb_syntax_OID_ldb_to_drsuapi,
2438 : .validate_ldb = dsdb_syntax_OID_validate_ldb,
2439 : .equality = "caseIgnoreMatch", /* Would use "objectIdentifierMatch" but most are ldap attribute/class names */
2440 : .comment = "OID String",
2441 : .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING
2442 : },{
2443 : .name = "Enumeration",
2444 : .ldap_oid = LDB_SYNTAX_INTEGER,
2445 : .oMSyntax = 10,
2446 : .attributeSyntax_oid = "2.5.5.9",
2447 : .drsuapi_to_ldb = dsdb_syntax_INT32_drsuapi_to_ldb,
2448 : .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi,
2449 : .validate_ldb = dsdb_syntax_INT32_validate_ldb,
2450 : .ldb_syntax = LDB_SYNTAX_SAMBA_INT32,
2451 : .auto_normalise = true
2452 : },{
2453 : /* not used in w2k3 forest */
2454 : .name = "String(Numeric)",
2455 : .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.36",
2456 : .oMSyntax = 18,
2457 : .attributeSyntax_oid = "2.5.5.6",
2458 : .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
2459 : .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
2460 : .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb,
2461 : .equality = "numericStringMatch",
2462 : .substring = "numericStringSubstringsMatch",
2463 : .comment = "Numeric String",
2464 : .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING,
2465 : },{
2466 : .name = "String(Printable)",
2467 : .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.44",
2468 : .oMSyntax = 19,
2469 : .attributeSyntax_oid = "2.5.5.5",
2470 : .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
2471 : .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
2472 : .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb,
2473 : .ldb_syntax = LDB_SYNTAX_SAMBA_OCTET_STRING,
2474 : },{
2475 : .name = "String(Teletex)",
2476 : .ldap_oid = "1.2.840.113556.1.4.905",
2477 : .oMSyntax = 20,
2478 : .attributeSyntax_oid = "2.5.5.4",
2479 : .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
2480 : .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
2481 : .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb,
2482 : .equality = "caseIgnoreMatch",
2483 : .substring = "caseIgnoreSubstringsMatch",
2484 : .comment = "Case Insensitive String",
2485 : .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING,
2486 : },{
2487 : .name = "String(IA5)",
2488 : .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.26",
2489 : .oMSyntax = 22,
2490 : .attributeSyntax_oid = "2.5.5.5",
2491 : .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
2492 : .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
2493 : .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb,
2494 : .equality = "caseExactIA5Match",
2495 : .comment = "Printable String",
2496 : .ldb_syntax = LDB_SYNTAX_SAMBA_OCTET_STRING,
2497 : },{
2498 : .name = "String(UTC-Time)",
2499 : .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.53",
2500 : .oMSyntax = 23,
2501 : .attributeSyntax_oid = "2.5.5.11",
2502 : .drsuapi_to_ldb = dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb,
2503 : .ldb_to_drsuapi = dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi,
2504 : .validate_ldb = dsdb_syntax_NTTIME_UTC_validate_ldb,
2505 : .equality = "generalizedTimeMatch",
2506 : .comment = "UTC Time",
2507 : .auto_normalise = true
2508 : },{
2509 : .name = "String(Generalized-Time)",
2510 : .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.24",
2511 : .oMSyntax = 24,
2512 : .attributeSyntax_oid = "2.5.5.11",
2513 : .drsuapi_to_ldb = dsdb_syntax_NTTIME_drsuapi_to_ldb,
2514 : .ldb_to_drsuapi = dsdb_syntax_NTTIME_ldb_to_drsuapi,
2515 : .validate_ldb = dsdb_syntax_NTTIME_validate_ldb,
2516 : .equality = "generalizedTimeMatch",
2517 : .comment = "Generalized Time",
2518 : .auto_normalise = true
2519 : },{
2520 : /* not used in w2k3 schema */
2521 : .name = "String(Case Sensitive)",
2522 : .ldap_oid = "1.2.840.113556.1.4.1362",
2523 : .oMSyntax = 27,
2524 : .attributeSyntax_oid = "2.5.5.3",
2525 : .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
2526 : .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
2527 : .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb,
2528 : .equality = "caseExactMatch",
2529 : .substring = "caseExactSubstringsMatch",
2530 : /* TODO (kim): according to LDAP rfc we should be using same comparison
2531 : * as Directory String (LDB_SYNTAX_DIRECTORY_STRING), but case sensitive.
2532 : * But according to ms docs binary compare should do the job:
2533 : * http://msdn.microsoft.com/en-us/library/cc223200(v=PROT.10).aspx */
2534 : .ldb_syntax = LDB_SYNTAX_SAMBA_OCTET_STRING,
2535 : },{
2536 : .name = "String(Unicode)",
2537 : .ldap_oid = LDB_SYNTAX_DIRECTORY_STRING,
2538 : .oMSyntax = 64,
2539 : .attributeSyntax_oid = "2.5.5.12",
2540 : .drsuapi_to_ldb = dsdb_syntax_UNICODE_drsuapi_to_ldb,
2541 : .ldb_to_drsuapi = dsdb_syntax_UNICODE_ldb_to_drsuapi,
2542 : .validate_ldb = dsdb_syntax_UNICODE_validate_ldb,
2543 : .equality = "caseIgnoreMatch",
2544 : .substring = "caseIgnoreSubstringsMatch",
2545 : .comment = "Directory String",
2546 : },{
2547 : .name = "Interval/LargeInteger",
2548 : .ldap_oid = "1.2.840.113556.1.4.906",
2549 : .oMSyntax = 65,
2550 : .attributeSyntax_oid = "2.5.5.16",
2551 : .drsuapi_to_ldb = dsdb_syntax_INT64_drsuapi_to_ldb,
2552 : .ldb_to_drsuapi = dsdb_syntax_INT64_ldb_to_drsuapi,
2553 : .validate_ldb = dsdb_syntax_INT64_validate_ldb,
2554 : .equality = "integerMatch",
2555 : .comment = "Large Integer",
2556 : .ldb_syntax = LDB_SYNTAX_ORDERED_INTEGER,
2557 : .auto_normalise = true
2558 : },{
2559 : .name = "String(NT-Sec-Desc)",
2560 : .ldap_oid = LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR,
2561 : .oMSyntax = 66,
2562 : .attributeSyntax_oid = "2.5.5.15",
2563 : .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
2564 : .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
2565 : .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb,
2566 : },{
2567 : .name = "Object(DS-DN)",
2568 : .ldap_oid = LDB_SYNTAX_DN,
2569 : .oMSyntax = 127,
2570 : .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x4a"),
2571 : .attributeSyntax_oid = "2.5.5.1",
2572 : .drsuapi_to_ldb = dsdb_syntax_DN_drsuapi_to_ldb,
2573 : .ldb_to_drsuapi = dsdb_syntax_DN_ldb_to_drsuapi,
2574 : .validate_ldb = dsdb_syntax_DN_validate_ldb,
2575 : .equality = "distinguishedNameMatch",
2576 : .comment = "Object(DS-DN) == a DN",
2577 : },{
2578 : .name = "Object(DN-Binary)",
2579 : .ldap_oid = DSDB_SYNTAX_BINARY_DN,
2580 : .oMSyntax = 127,
2581 : .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0b"),
2582 : .attributeSyntax_oid = "2.5.5.7",
2583 : .drsuapi_to_ldb = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
2584 : .ldb_to_drsuapi = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
2585 : .validate_ldb = dsdb_syntax_DN_BINARY_validate_ldb,
2586 : .equality = "octetStringMatch",
2587 : .comment = "OctetString: Binary+DN",
2588 : },{
2589 : /* not used in w2k3 schema, but used in Exchange schema*/
2590 : .name = "Object(OR-Name)",
2591 : .ldap_oid = DSDB_SYNTAX_OR_NAME,
2592 : .oMSyntax = 127,
2593 : .oMObjectClass = OMOBJECTCLASS("\x56\x06\x01\x02\x05\x0b\x1D"),
2594 : .attributeSyntax_oid = "2.5.5.7",
2595 : .drsuapi_to_ldb = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
2596 : .ldb_to_drsuapi = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
2597 : .validate_ldb = dsdb_syntax_DN_validate_ldb,
2598 : .equality = "distinguishedNameMatch",
2599 : .ldb_syntax = LDB_SYNTAX_DN,
2600 : },{
2601 : /*
2602 : * TODO: verify if DATA_BLOB is correct here...!
2603 : *
2604 : * repsFrom and repsTo are the only attributes using
2605 : * this attribute syntax, but they're not replicated...
2606 : */
2607 : .name = "Object(Replica-Link)",
2608 : .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.40",
2609 : .oMSyntax = 127,
2610 : .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x06"),
2611 : .attributeSyntax_oid = "2.5.5.10",
2612 : .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
2613 : .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
2614 : .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb,
2615 : },{
2616 : .name = "Object(Presentation-Address)",
2617 : .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.43",
2618 : .oMSyntax = 127,
2619 : .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x5c"),
2620 : .attributeSyntax_oid = "2.5.5.13",
2621 : .drsuapi_to_ldb = dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb,
2622 : .ldb_to_drsuapi = dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi,
2623 : .validate_ldb = dsdb_syntax_PRESENTATION_ADDRESS_validate_ldb,
2624 : .comment = "Presentation Address",
2625 : .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING,
2626 : },{
2627 : /* not used in w2k3 schema */
2628 : .name = "Object(Access-Point)",
2629 : .ldap_oid = DSDB_SYNTAX_ACCESS_POINT,
2630 : .oMSyntax = 127,
2631 : .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x3e"),
2632 : .attributeSyntax_oid = "2.5.5.14",
2633 : .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
2634 : .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
2635 : .validate_ldb = dsdb_syntax_FOOBAR_validate_ldb,
2636 : .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING,
2637 : },{
2638 : /* not used in w2k3 schema */
2639 : .name = "Object(DN-String)",
2640 : .ldap_oid = DSDB_SYNTAX_STRING_DN,
2641 : .oMSyntax = 127,
2642 : .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0c"),
2643 : .attributeSyntax_oid = "2.5.5.14",
2644 : .drsuapi_to_ldb = dsdb_syntax_DN_STRING_drsuapi_to_ldb,
2645 : .ldb_to_drsuapi = dsdb_syntax_DN_STRING_ldb_to_drsuapi,
2646 : .validate_ldb = dsdb_syntax_DN_STRING_validate_ldb,
2647 : .equality = "octetStringMatch",
2648 : .comment = "OctetString: String+DN",
2649 : }
2650 : };
2651 :
2652 184328 : const struct dsdb_syntax *find_syntax_map_by_ad_oid(const char *ad_oid)
2653 : {
2654 32978 : unsigned int i;
2655 1777830 : for (i=0; i < ARRAY_SIZE(dsdb_syntaxes); i++) {
2656 1777830 : if (strcasecmp(ad_oid, dsdb_syntaxes[i].attributeSyntax_oid) == 0) {
2657 184328 : return &dsdb_syntaxes[i];
2658 : }
2659 : }
2660 0 : return NULL;
2661 : }
2662 :
2663 0 : const struct dsdb_syntax *find_syntax_map_by_ad_syntax(int oMSyntax)
2664 : {
2665 0 : unsigned int i;
2666 0 : for (i=0; i < ARRAY_SIZE(dsdb_syntaxes); i++) {
2667 0 : if (oMSyntax == dsdb_syntaxes[i].oMSyntax) {
2668 0 : return &dsdb_syntaxes[i];
2669 : }
2670 : }
2671 0 : return NULL;
2672 : }
2673 :
2674 13 : const struct dsdb_syntax *find_syntax_map_by_standard_oid(const char *standard_oid)
2675 : {
2676 13 : unsigned int i;
2677 205 : for (i=0; i < ARRAY_SIZE(dsdb_syntaxes); i++) {
2678 202 : if (strcasecmp(standard_oid, dsdb_syntaxes[i].ldap_oid) == 0) {
2679 10 : return &dsdb_syntaxes[i];
2680 : }
2681 : }
2682 0 : return NULL;
2683 : }
2684 :
2685 39602309 : const struct dsdb_syntax *dsdb_syntax_for_attribute(const struct dsdb_attribute *attr)
2686 : {
2687 524540 : unsigned int i;
2688 :
2689 386823881 : for (i=0; i < ARRAY_SIZE(dsdb_syntaxes); i++) {
2690 : /*
2691 : * We must pretend that userParameters was declared
2692 : * binary string, so we can store the 'UTF16' (not
2693 : * really string) structure as given over SAMR to samba
2694 : */
2695 386823881 : if (dsdb_syntaxes[i].userParameters &&
2696 30266434 : (strcasecmp(attr->lDAPDisplayName, "userParameters") == 0))
2697 : {
2698 28342 : return &dsdb_syntaxes[i];
2699 : }
2700 386795539 : if (attr->oMSyntax != dsdb_syntaxes[i].oMSyntax) continue;
2701 :
2702 40610496 : if (attr->oMObjectClass.length != dsdb_syntaxes[i].oMObjectClass.length) continue;
2703 :
2704 40003829 : if (attr->oMObjectClass.length) {
2705 75170 : int ret;
2706 5581838 : ret = memcmp(attr->oMObjectClass.data,
2707 5581838 : dsdb_syntaxes[i].oMObjectClass.data,
2708 5506668 : attr->oMObjectClass.length);
2709 5581838 : if (ret != 0) continue;
2710 : }
2711 :
2712 39862119 : if (strcmp(attr->attributeSyntax_oid, dsdb_syntaxes[i].attributeSyntax_oid) != 0) continue;
2713 :
2714 39573967 : return &dsdb_syntaxes[i];
2715 : }
2716 :
2717 0 : return NULL;
2718 : }
2719 :
2720 10187197 : WERROR dsdb_attribute_drsuapi_remote_to_local(const struct dsdb_syntax_ctx *ctx,
2721 : enum drsuapi_DsAttributeId remote_attid_as_enum,
2722 : enum drsuapi_DsAttributeId *local_attid_as_enum,
2723 : const struct dsdb_attribute **_sa)
2724 : {
2725 10187197 : TALLOC_CTX *frame = talloc_stackframe();
2726 0 : const struct dsdb_attribute *sa;
2727 0 : uint32_t attid_local;
2728 0 : bool ok;
2729 :
2730 10187197 : if (ctx->pfm_remote == NULL) {
2731 0 : smb_panic(__location__);
2732 : }
2733 :
2734 10187197 : switch (dsdb_pfm_get_attid_type(remote_attid_as_enum)) {
2735 10186503 : case DSDB_ATTID_TYPE_PFM:
2736 : /* map remote ATTID to local ATTID */
2737 10186503 : ok = dsdb_syntax_attid_from_remote_attid(ctx, frame,
2738 : remote_attid_as_enum,
2739 : &attid_local);
2740 10186503 : if (!ok) {
2741 0 : DEBUG(0,(__location__ ": Can't find local ATTID for 0x%08X\n",
2742 : remote_attid_as_enum));
2743 0 : TALLOC_FREE(frame);
2744 0 : return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
2745 : }
2746 10186503 : break;
2747 694 : case DSDB_ATTID_TYPE_INTID:
2748 : /* use IntId value directly */
2749 694 : attid_local = remote_attid_as_enum;
2750 694 : break;
2751 0 : default:
2752 : /* we should never get here */
2753 0 : DEBUG(0,(__location__ ": Invalid ATTID type passed for conversion - 0x%08X\n",
2754 : remote_attid_as_enum));
2755 0 : TALLOC_FREE(frame);
2756 0 : return WERR_INVALID_PARAMETER;
2757 : }
2758 :
2759 10187197 : sa = dsdb_attribute_by_attributeID_id(ctx->schema, attid_local);
2760 10187197 : if (!sa) {
2761 3 : int dbg_level = ctx->schema->resolving_in_progress ? 10 : 0;
2762 3 : DEBUG(dbg_level,(__location__ ": Unknown local attributeID_id 0x%08X remote 0x%08X%s\n",
2763 : attid_local, remote_attid_as_enum,
2764 : ctx->schema->resolving_in_progress ? "resolving in progress" : ""));
2765 3 : TALLOC_FREE(frame);
2766 3 : return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
2767 : }
2768 :
2769 : /*
2770 : * We return the same class of attid as we were given. That
2771 : * is, we trust the remote server not to use an
2772 : * msDS-IntId value in the schema partition
2773 : */
2774 10187194 : if (local_attid_as_enum != NULL) {
2775 10185375 : *local_attid_as_enum = (enum drsuapi_DsAttributeId)attid_local;
2776 : }
2777 :
2778 10187194 : if (_sa != NULL) {
2779 9647224 : *_sa = sa;
2780 : }
2781 :
2782 10187194 : TALLOC_FREE(frame);
2783 10187194 : return WERR_OK;
2784 : }
2785 :
2786 9646310 : WERROR dsdb_attribute_drsuapi_to_ldb(struct ldb_context *ldb,
2787 : const struct dsdb_schema *schema,
2788 : const struct dsdb_schema_prefixmap *pfm_remote,
2789 : const struct drsuapi_DsReplicaAttribute *in,
2790 : TALLOC_CTX *mem_ctx,
2791 : struct ldb_message_element *out,
2792 : enum drsuapi_DsAttributeId *local_attid_as_enum)
2793 : {
2794 0 : struct dsdb_syntax_ctx syntax_ctx;
2795 9646310 : const struct dsdb_attribute *sa = NULL;
2796 0 : WERROR werr;
2797 :
2798 : /* use default syntax conversion context */
2799 9646310 : dsdb_syntax_ctx_init(&syntax_ctx, ldb, schema);
2800 9646310 : syntax_ctx.pfm_remote = pfm_remote;
2801 :
2802 9646310 : werr = dsdb_attribute_drsuapi_remote_to_local(&syntax_ctx,
2803 9646310 : in->attid,
2804 : local_attid_as_enum,
2805 : &sa);
2806 9646310 : if (!W_ERROR_IS_OK(werr)) {
2807 0 : return werr;
2808 : }
2809 :
2810 9646310 : return sa->syntax->drsuapi_to_ldb(&syntax_ctx, sa, in, mem_ctx, out);
2811 : }
|