s4:dsdb/schema: add dsdb_syntax_NTTIME_UTC_validate_ldb()
[Samba/fernandojvsilva.git] / source4 / dsdb / schema / schema_syntax.c
blob3805df64635dff91d4ea0c22a0c51dcdda7014e5
1 /*
2 Unix SMB/CIFS mplementation.
3 DSDB schema syntaxes
5 Copyright (C) Stefan Metzmacher <metze@samba.org> 2006
6 Copyright (C) Simo Sorce 2005
7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2008
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.
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.
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/>.
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 "lib/ldb/include/ldb.h"
29 #include "lib/ldb/include/ldb_errors.h"
30 #include "system/time.h"
31 #include "../lib/util/charset/charset.h"
32 #include "librpc/ndr/libndr.h"
34 static WERROR dsdb_syntax_FOOBAR_drsuapi_to_ldb(struct ldb_context *ldb,
35 const struct dsdb_schema *schema,
36 const struct dsdb_attribute *attr,
37 const struct drsuapi_DsReplicaAttribute *in,
38 TALLOC_CTX *mem_ctx,
39 struct ldb_message_element *out)
41 uint32_t i;
43 out->flags = 0;
44 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
45 W_ERROR_HAVE_NO_MEMORY(out->name);
47 out->num_values = in->value_ctr.num_values;
48 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
49 W_ERROR_HAVE_NO_MEMORY(out->values);
51 for (i=0; i < out->num_values; i++) {
52 char *str;
54 if (in->value_ctr.values[i].blob == NULL) {
55 return WERR_FOOBAR;
58 str = talloc_asprintf(out->values, "%s: not implemented",
59 attr->syntax->name);
60 W_ERROR_HAVE_NO_MEMORY(str);
62 out->values[i] = data_blob_string_const(str);
65 return WERR_OK;
68 static WERROR dsdb_syntax_FOOBAR_ldb_to_drsuapi(struct ldb_context *ldb,
69 const struct dsdb_schema *schema,
70 const struct dsdb_attribute *attr,
71 const struct ldb_message_element *in,
72 TALLOC_CTX *mem_ctx,
73 struct drsuapi_DsReplicaAttribute *out)
75 return WERR_FOOBAR;
78 static WERROR dsdb_syntax_FOOBAR_validate_ldb(struct ldb_context *ldb,
79 const struct dsdb_schema *schema,
80 const struct dsdb_attribute *attr,
81 const struct ldb_message_element *in)
83 return WERR_FOOBAR;
86 static WERROR dsdb_syntax_ALLOW_validate_ldb(struct ldb_context *ldb,
87 const struct dsdb_schema *schema,
88 const struct dsdb_attribute *attr,
89 const struct ldb_message_element *in)
91 if (attr->attributeID_id == 0xFFFFFFFF) {
92 return WERR_FOOBAR;
95 return WERR_OK;
98 static WERROR dsdb_syntax_BOOL_drsuapi_to_ldb(struct ldb_context *ldb,
99 const struct dsdb_schema *schema,
100 const struct dsdb_attribute *attr,
101 const struct drsuapi_DsReplicaAttribute *in,
102 TALLOC_CTX *mem_ctx,
103 struct ldb_message_element *out)
105 uint32_t i;
107 out->flags = 0;
108 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
109 W_ERROR_HAVE_NO_MEMORY(out->name);
111 out->num_values = in->value_ctr.num_values;
112 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
113 W_ERROR_HAVE_NO_MEMORY(out->values);
115 for (i=0; i < out->num_values; i++) {
116 uint32_t v;
117 char *str;
119 if (in->value_ctr.values[i].blob == NULL) {
120 return WERR_FOOBAR;
123 if (in->value_ctr.values[i].blob->length != 4) {
124 return WERR_FOOBAR;
127 v = IVAL(in->value_ctr.values[i].blob->data, 0);
129 if (v != 0) {
130 str = talloc_strdup(out->values, "TRUE");
131 W_ERROR_HAVE_NO_MEMORY(str);
132 } else {
133 str = talloc_strdup(out->values, "FALSE");
134 W_ERROR_HAVE_NO_MEMORY(str);
137 out->values[i] = data_blob_string_const(str);
140 return WERR_OK;
143 static WERROR dsdb_syntax_BOOL_ldb_to_drsuapi(struct ldb_context *ldb,
144 const struct dsdb_schema *schema,
145 const struct dsdb_attribute *attr,
146 const struct ldb_message_element *in,
147 TALLOC_CTX *mem_ctx,
148 struct drsuapi_DsReplicaAttribute *out)
150 uint32_t i;
151 DATA_BLOB *blobs;
153 if (attr->attributeID_id == 0xFFFFFFFF) {
154 return WERR_FOOBAR;
157 out->attid = attr->attributeID_id;
158 out->value_ctr.num_values = in->num_values;
159 out->value_ctr.values = talloc_array(mem_ctx,
160 struct drsuapi_DsAttributeValue,
161 in->num_values);
162 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
164 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
165 W_ERROR_HAVE_NO_MEMORY(blobs);
167 for (i=0; i < in->num_values; i++) {
168 out->value_ctr.values[i].blob = &blobs[i];
170 blobs[i] = data_blob_talloc(blobs, NULL, 4);
171 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
173 if (strcmp("TRUE", (const char *)in->values[i].data) == 0) {
174 SIVAL(blobs[i].data, 0, 0x00000001);
175 } else if (strcmp("FALSE", (const char *)in->values[i].data) == 0) {
176 SIVAL(blobs[i].data, 0, 0x00000000);
177 } else {
178 return WERR_FOOBAR;
182 return WERR_OK;
185 static WERROR dsdb_syntax_BOOL_validate_ldb(struct ldb_context *ldb,
186 const struct dsdb_schema *schema,
187 const struct dsdb_attribute *attr,
188 const struct ldb_message_element *in)
190 uint32_t i;
192 if (attr->attributeID_id == 0xFFFFFFFF) {
193 return WERR_FOOBAR;
196 for (i=0; i < in->num_values; i++) {
197 int t, f;
199 t = strncmp("TRUE",
200 (const char *)in->values[i].data,
201 in->values[i].length);
202 f = strncmp("FALSE",
203 (const char *)in->values[i].data,
204 in->values[i].length);
206 if (t != 0 && f != 0) {
207 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
211 return WERR_OK;
214 static WERROR dsdb_syntax_INT32_drsuapi_to_ldb(struct ldb_context *ldb,
215 const struct dsdb_schema *schema,
216 const struct dsdb_attribute *attr,
217 const struct drsuapi_DsReplicaAttribute *in,
218 TALLOC_CTX *mem_ctx,
219 struct ldb_message_element *out)
221 uint32_t i;
223 out->flags = 0;
224 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
225 W_ERROR_HAVE_NO_MEMORY(out->name);
227 out->num_values = in->value_ctr.num_values;
228 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
229 W_ERROR_HAVE_NO_MEMORY(out->values);
231 for (i=0; i < out->num_values; i++) {
232 int32_t v;
233 char *str;
235 if (in->value_ctr.values[i].blob == NULL) {
236 return WERR_FOOBAR;
239 if (in->value_ctr.values[i].blob->length != 4) {
240 return WERR_FOOBAR;
243 v = IVALS(in->value_ctr.values[i].blob->data, 0);
245 str = talloc_asprintf(out->values, "%d", v);
246 W_ERROR_HAVE_NO_MEMORY(str);
248 out->values[i] = data_blob_string_const(str);
251 return WERR_OK;
254 static WERROR dsdb_syntax_INT32_ldb_to_drsuapi(struct ldb_context *ldb,
255 const struct dsdb_schema *schema,
256 const struct dsdb_attribute *attr,
257 const struct ldb_message_element *in,
258 TALLOC_CTX *mem_ctx,
259 struct drsuapi_DsReplicaAttribute *out)
261 uint32_t i;
262 DATA_BLOB *blobs;
264 if (attr->attributeID_id == 0xFFFFFFFF) {
265 return WERR_FOOBAR;
268 out->attid = attr->attributeID_id;
269 out->value_ctr.num_values = in->num_values;
270 out->value_ctr.values = talloc_array(mem_ctx,
271 struct drsuapi_DsAttributeValue,
272 in->num_values);
273 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
275 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
276 W_ERROR_HAVE_NO_MEMORY(blobs);
278 for (i=0; i < in->num_values; i++) {
279 int32_t v;
281 out->value_ctr.values[i].blob = &blobs[i];
283 blobs[i] = data_blob_talloc(blobs, NULL, 4);
284 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
286 /* We've to use "strtoll" here to have the intended overflows.
287 * Otherwise we may get "LONG_MAX" and the conversion is wrong. */
288 v = (int32_t) strtoll((char *)in->values[i].data, NULL, 0);
290 SIVALS(blobs[i].data, 0, v);
293 return WERR_OK;
296 static WERROR dsdb_syntax_INT32_validate_ldb(struct ldb_context *ldb,
297 const struct dsdb_schema *schema,
298 const struct dsdb_attribute *attr,
299 const struct ldb_message_element *in)
301 uint32_t i;
303 if (attr->attributeID_id == 0xFFFFFFFF) {
304 return WERR_FOOBAR;
307 for (i=0; i < in->num_values; i++) {
308 long v;
309 char buf[sizeof("-2147483648")];
310 char *end = NULL;
312 ZERO_STRUCT(buf);
313 if (in->values[i].length >= sizeof(buf)) {
314 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
317 memcpy(buf, in->values[i].data, in->values[i].length);
318 errno = 0;
319 v = strtol(buf, &end, 10);
320 if (errno != 0) {
321 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
323 if (end && end[0] != '\0') {
324 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
327 if (attr->rangeLower) {
328 if ((int32_t)v < (int32_t)*attr->rangeLower) {
329 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
333 if (attr->rangeUpper) {
334 if ((int32_t)v > (int32_t)*attr->rangeUpper) {
335 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
340 return WERR_OK;
343 static WERROR dsdb_syntax_INT64_drsuapi_to_ldb(struct ldb_context *ldb,
344 const struct dsdb_schema *schema,
345 const struct dsdb_attribute *attr,
346 const struct drsuapi_DsReplicaAttribute *in,
347 TALLOC_CTX *mem_ctx,
348 struct ldb_message_element *out)
350 uint32_t i;
352 out->flags = 0;
353 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
354 W_ERROR_HAVE_NO_MEMORY(out->name);
356 out->num_values = in->value_ctr.num_values;
357 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
358 W_ERROR_HAVE_NO_MEMORY(out->values);
360 for (i=0; i < out->num_values; i++) {
361 int64_t v;
362 char *str;
364 if (in->value_ctr.values[i].blob == NULL) {
365 return WERR_FOOBAR;
368 if (in->value_ctr.values[i].blob->length != 8) {
369 return WERR_FOOBAR;
372 v = BVALS(in->value_ctr.values[i].blob->data, 0);
374 str = talloc_asprintf(out->values, "%lld", (long long int)v);
375 W_ERROR_HAVE_NO_MEMORY(str);
377 out->values[i] = data_blob_string_const(str);
380 return WERR_OK;
383 static WERROR dsdb_syntax_INT64_ldb_to_drsuapi(struct ldb_context *ldb,
384 const struct dsdb_schema *schema,
385 const struct dsdb_attribute *attr,
386 const struct ldb_message_element *in,
387 TALLOC_CTX *mem_ctx,
388 struct drsuapi_DsReplicaAttribute *out)
390 uint32_t i;
391 DATA_BLOB *blobs;
393 if (attr->attributeID_id == 0xFFFFFFFF) {
394 return WERR_FOOBAR;
397 out->attid = attr->attributeID_id;
398 out->value_ctr.num_values = in->num_values;
399 out->value_ctr.values = talloc_array(mem_ctx,
400 struct drsuapi_DsAttributeValue,
401 in->num_values);
402 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
404 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
405 W_ERROR_HAVE_NO_MEMORY(blobs);
407 for (i=0; i < in->num_values; i++) {
408 int64_t v;
410 out->value_ctr.values[i].blob = &blobs[i];
412 blobs[i] = data_blob_talloc(blobs, NULL, 8);
413 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
415 v = strtoll((const char *)in->values[i].data, NULL, 10);
417 SBVALS(blobs[i].data, 0, v);
420 return WERR_OK;
423 static WERROR dsdb_syntax_INT64_validate_ldb(struct ldb_context *ldb,
424 const struct dsdb_schema *schema,
425 const struct dsdb_attribute *attr,
426 const struct ldb_message_element *in)
428 uint32_t i;
430 if (attr->attributeID_id == 0xFFFFFFFF) {
431 return WERR_FOOBAR;
434 for (i=0; i < in->num_values; i++) {
435 long long v;
436 char buf[sizeof("-9223372036854775808")];
437 char *end = NULL;
439 ZERO_STRUCT(buf);
440 if (in->values[i].length >= sizeof(buf)) {
441 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
443 memcpy(buf, in->values[i].data, in->values[i].length);
445 errno = 0;
446 v = strtoll(buf, &end, 10);
447 if (errno != 0) {
448 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
450 if (end && end[0] != '\0') {
451 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
454 if (attr->rangeLower) {
455 if ((int64_t)v < (int64_t)*attr->rangeLower) {
456 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
460 if (attr->rangeUpper) {
461 if ((int64_t)v > (int64_t)*attr->rangeUpper) {
462 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
467 return WERR_OK;
469 static WERROR dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb(struct ldb_context *ldb,
470 const struct dsdb_schema *schema,
471 const struct dsdb_attribute *attr,
472 const struct drsuapi_DsReplicaAttribute *in,
473 TALLOC_CTX *mem_ctx,
474 struct ldb_message_element *out)
476 uint32_t i;
478 out->flags = 0;
479 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
480 W_ERROR_HAVE_NO_MEMORY(out->name);
482 out->num_values = in->value_ctr.num_values;
483 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
484 W_ERROR_HAVE_NO_MEMORY(out->values);
486 for (i=0; i < out->num_values; i++) {
487 NTTIME v;
488 time_t t;
489 char *str;
491 if (in->value_ctr.values[i].blob == NULL) {
492 return WERR_FOOBAR;
495 if (in->value_ctr.values[i].blob->length != 8) {
496 return WERR_FOOBAR;
499 v = BVAL(in->value_ctr.values[i].blob->data, 0);
500 v *= 10000000;
501 t = nt_time_to_unix(v);
504 * NOTE: On a w2k3 server you can set a GeneralizedTime string
505 * via LDAP, but you get back an UTCTime string,
506 * but via DRSUAPI you get back the NTTIME_1sec value
507 * that represents the GeneralizedTime value!
509 * So if we store the UTCTime string in our ldb
510 * we'll loose information!
512 str = ldb_timestring_utc(out->values, t);
513 W_ERROR_HAVE_NO_MEMORY(str);
514 out->values[i] = data_blob_string_const(str);
517 return WERR_OK;
520 static WERROR dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi(struct ldb_context *ldb,
521 const struct dsdb_schema *schema,
522 const struct dsdb_attribute *attr,
523 const struct ldb_message_element *in,
524 TALLOC_CTX *mem_ctx,
525 struct drsuapi_DsReplicaAttribute *out)
527 uint32_t i;
528 DATA_BLOB *blobs;
530 if (attr->attributeID_id == 0xFFFFFFFF) {
531 return WERR_FOOBAR;
534 out->attid = attr->attributeID_id;
535 out->value_ctr.num_values = in->num_values;
536 out->value_ctr.values = talloc_array(mem_ctx,
537 struct drsuapi_DsAttributeValue,
538 in->num_values);
539 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
541 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
542 W_ERROR_HAVE_NO_MEMORY(blobs);
544 for (i=0; i < in->num_values; i++) {
545 NTTIME v;
546 time_t t;
548 out->value_ctr.values[i].blob = &blobs[i];
550 blobs[i] = data_blob_talloc(blobs, NULL, 8);
551 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
553 t = ldb_string_utc_to_time((const char *)in->values[i].data);
554 unix_to_nt_time(&v, t);
555 v /= 10000000;
557 SBVAL(blobs[i].data, 0, v);
560 return WERR_OK;
563 static WERROR dsdb_syntax_NTTIME_UTC_validate_ldb(struct ldb_context *ldb,
564 const struct dsdb_schema *schema,
565 const struct dsdb_attribute *attr,
566 const struct ldb_message_element *in)
568 uint32_t i;
570 if (attr->attributeID_id == 0xFFFFFFFF) {
571 return WERR_FOOBAR;
574 for (i=0; i < in->num_values; i++) {
575 time_t t;
576 char buf[sizeof("090826075717Z")];
578 ZERO_STRUCT(buf);
579 if (in->values[i].length >= sizeof(buf)) {
580 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
582 memcpy(buf, in->values[i].data, in->values[i].length);
584 errno = 0;
585 t = ldb_string_utc_to_time(buf);
586 if (errno != 0) {
587 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
590 if (attr->rangeLower) {
591 if ((int32_t)t < (int32_t)*attr->rangeLower) {
592 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
596 if (attr->rangeUpper) {
597 if ((int32_t)t > (int32_t)*attr->rangeLower) {
598 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
603 * TODO: verify the comment in the
604 * dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb() function!
608 return WERR_OK;
611 static WERROR dsdb_syntax_NTTIME_drsuapi_to_ldb(struct ldb_context *ldb,
612 const struct dsdb_schema *schema,
613 const struct dsdb_attribute *attr,
614 const struct drsuapi_DsReplicaAttribute *in,
615 TALLOC_CTX *mem_ctx,
616 struct ldb_message_element *out)
618 uint32_t i;
620 out->flags = 0;
621 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
622 W_ERROR_HAVE_NO_MEMORY(out->name);
624 out->num_values = in->value_ctr.num_values;
625 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
626 W_ERROR_HAVE_NO_MEMORY(out->values);
628 for (i=0; i < out->num_values; i++) {
629 NTTIME v;
630 time_t t;
631 char *str;
633 if (in->value_ctr.values[i].blob == NULL) {
634 return WERR_FOOBAR;
637 if (in->value_ctr.values[i].blob->length != 8) {
638 return WERR_FOOBAR;
641 v = BVAL(in->value_ctr.values[i].blob->data, 0);
642 v *= 10000000;
643 t = nt_time_to_unix(v);
645 str = ldb_timestring(out->values, t);
646 W_ERROR_HAVE_NO_MEMORY(str);
648 out->values[i] = data_blob_string_const(str);
651 return WERR_OK;
654 static WERROR dsdb_syntax_NTTIME_ldb_to_drsuapi(struct ldb_context *ldb,
655 const struct dsdb_schema *schema,
656 const struct dsdb_attribute *attr,
657 const struct ldb_message_element *in,
658 TALLOC_CTX *mem_ctx,
659 struct drsuapi_DsReplicaAttribute *out)
661 uint32_t i;
662 DATA_BLOB *blobs;
664 if (attr->attributeID_id == 0xFFFFFFFF) {
665 return WERR_FOOBAR;
668 out->attid = attr->attributeID_id;
669 out->value_ctr.num_values = in->num_values;
670 out->value_ctr.values = talloc_array(mem_ctx,
671 struct drsuapi_DsAttributeValue,
672 in->num_values);
673 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
675 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
676 W_ERROR_HAVE_NO_MEMORY(blobs);
678 for (i=0; i < in->num_values; i++) {
679 NTTIME v;
680 time_t t;
681 int ret;
683 out->value_ctr.values[i].blob = &blobs[i];
685 blobs[i] = data_blob_talloc(blobs, NULL, 8);
686 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
688 ret = ldb_val_to_time(&in->values[i], &t);
689 if (ret != LDB_SUCCESS) {
690 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
692 unix_to_nt_time(&v, t);
693 v /= 10000000;
695 SBVAL(blobs[i].data, 0, v);
698 return WERR_OK;
701 static WERROR dsdb_syntax_DATA_BLOB_drsuapi_to_ldb(struct ldb_context *ldb,
702 const struct dsdb_schema *schema,
703 const struct dsdb_attribute *attr,
704 const struct drsuapi_DsReplicaAttribute *in,
705 TALLOC_CTX *mem_ctx,
706 struct ldb_message_element *out)
708 uint32_t i;
710 out->flags = 0;
711 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
712 W_ERROR_HAVE_NO_MEMORY(out->name);
714 out->num_values = in->value_ctr.num_values;
715 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
716 W_ERROR_HAVE_NO_MEMORY(out->values);
718 for (i=0; i < out->num_values; i++) {
719 if (in->value_ctr.values[i].blob == NULL) {
720 return WERR_FOOBAR;
723 if (in->value_ctr.values[i].blob->length == 0) {
724 return WERR_FOOBAR;
727 out->values[i] = data_blob_dup_talloc(out->values,
728 in->value_ctr.values[i].blob);
729 W_ERROR_HAVE_NO_MEMORY(out->values[i].data);
732 return WERR_OK;
735 static WERROR dsdb_syntax_DATA_BLOB_ldb_to_drsuapi(struct ldb_context *ldb,
736 const struct dsdb_schema *schema,
737 const struct dsdb_attribute *attr,
738 const struct ldb_message_element *in,
739 TALLOC_CTX *mem_ctx,
740 struct drsuapi_DsReplicaAttribute *out)
742 uint32_t i;
743 DATA_BLOB *blobs;
745 if (attr->attributeID_id == 0xFFFFFFFF) {
746 return WERR_FOOBAR;
749 out->attid = attr->attributeID_id;
750 out->value_ctr.num_values = in->num_values;
751 out->value_ctr.values = talloc_array(mem_ctx,
752 struct drsuapi_DsAttributeValue,
753 in->num_values);
754 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
756 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
757 W_ERROR_HAVE_NO_MEMORY(blobs);
759 for (i=0; i < in->num_values; i++) {
760 out->value_ctr.values[i].blob = &blobs[i];
762 blobs[i] = data_blob_dup_talloc(blobs, &in->values[i]);
763 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
766 return WERR_OK;
769 static WERROR _dsdb_syntax_auto_OID_drsuapi_to_ldb(struct ldb_context *ldb,
770 const struct dsdb_schema *schema,
771 const struct dsdb_attribute *attr,
772 const struct drsuapi_DsReplicaAttribute *in,
773 TALLOC_CTX *mem_ctx,
774 struct ldb_message_element *out)
776 uint32_t i;
778 out->flags = 0;
779 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
780 W_ERROR_HAVE_NO_MEMORY(out->name);
782 out->num_values = in->value_ctr.num_values;
783 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
784 W_ERROR_HAVE_NO_MEMORY(out->values);
786 for (i=0; i < out->num_values; i++) {
787 uint32_t v;
788 const struct dsdb_class *c;
789 const struct dsdb_attribute *a;
790 const char *str = NULL;
792 if (in->value_ctr.values[i].blob == NULL) {
793 return WERR_FOOBAR;
796 if (in->value_ctr.values[i].blob->length != 4) {
797 return WERR_FOOBAR;
800 v = IVAL(in->value_ctr.values[i].blob->data, 0);
802 if ((c = dsdb_class_by_governsID_id(schema, v))) {
803 str = talloc_strdup(out->values, c->lDAPDisplayName);
804 } else if ((a = dsdb_attribute_by_attributeID_id(schema, v))) {
805 str = talloc_strdup(out->values, a->lDAPDisplayName);
806 } else {
807 WERROR werr;
808 werr = dsdb_schema_pfm_oid_from_attid(schema->prefixmap, v, out->values, &str);
809 W_ERROR_NOT_OK_RETURN(werr);
811 W_ERROR_HAVE_NO_MEMORY(str);
813 /* the values need to be reversed */
814 out->values[out->num_values - (i + 1)] = data_blob_string_const(str);
817 return WERR_OK;
820 static WERROR _dsdb_syntax_OID_obj_drsuapi_to_ldb(struct ldb_context *ldb,
821 const struct dsdb_schema *schema,
822 const struct dsdb_attribute *attr,
823 const struct drsuapi_DsReplicaAttribute *in,
824 TALLOC_CTX *mem_ctx,
825 struct ldb_message_element *out)
827 uint32_t i;
829 out->flags = 0;
830 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
831 W_ERROR_HAVE_NO_MEMORY(out->name);
833 out->num_values = in->value_ctr.num_values;
834 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
835 W_ERROR_HAVE_NO_MEMORY(out->values);
837 for (i=0; i < out->num_values; i++) {
838 uint32_t v;
839 const struct dsdb_class *c;
840 const char *str;
842 if (in->value_ctr.values[i].blob == NULL) {
843 return WERR_FOOBAR;
846 if (in->value_ctr.values[i].blob->length != 4) {
847 return WERR_FOOBAR;
850 v = IVAL(in->value_ctr.values[i].blob->data, 0);
852 c = dsdb_class_by_governsID_id(schema, v);
853 if (!c) {
854 return WERR_FOOBAR;
857 str = talloc_strdup(out->values, c->lDAPDisplayName);
858 W_ERROR_HAVE_NO_MEMORY(str);
860 /* the values need to be reversed */
861 out->values[out->num_values - (i + 1)] = data_blob_string_const(str);
864 return WERR_OK;
867 static WERROR _dsdb_syntax_OID_attr_drsuapi_to_ldb(struct ldb_context *ldb,
868 const struct dsdb_schema *schema,
869 const struct dsdb_attribute *attr,
870 const struct drsuapi_DsReplicaAttribute *in,
871 TALLOC_CTX *mem_ctx,
872 struct ldb_message_element *out)
874 uint32_t i;
876 out->flags = 0;
877 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
878 W_ERROR_HAVE_NO_MEMORY(out->name);
880 out->num_values = in->value_ctr.num_values;
881 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
882 W_ERROR_HAVE_NO_MEMORY(out->values);
884 for (i=0; i < out->num_values; i++) {
885 uint32_t v;
886 const struct dsdb_attribute *a;
887 const char *str;
889 if (in->value_ctr.values[i].blob == NULL) {
890 return WERR_FOOBAR;
893 if (in->value_ctr.values[i].blob->length != 4) {
894 return WERR_FOOBAR;
897 v = IVAL(in->value_ctr.values[i].blob->data, 0);
899 a = dsdb_attribute_by_attributeID_id(schema, v);
900 if (!a) {
901 return WERR_FOOBAR;
904 str = talloc_strdup(out->values, a->lDAPDisplayName);
905 W_ERROR_HAVE_NO_MEMORY(str);
907 /* the values need to be reversed */
908 out->values[out->num_values - (i + 1)] = data_blob_string_const(str);
911 return WERR_OK;
914 static WERROR _dsdb_syntax_OID_oid_drsuapi_to_ldb(struct ldb_context *ldb,
915 const struct dsdb_schema *schema,
916 const struct dsdb_attribute *attr,
917 const struct drsuapi_DsReplicaAttribute *in,
918 TALLOC_CTX *mem_ctx,
919 struct ldb_message_element *out)
921 uint32_t i;
923 out->flags = 0;
924 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
925 W_ERROR_HAVE_NO_MEMORY(out->name);
927 out->num_values = in->value_ctr.num_values;
928 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
929 W_ERROR_HAVE_NO_MEMORY(out->values);
931 for (i=0; i < out->num_values; i++) {
932 uint32_t attid;
933 WERROR status;
934 const char *oid;
936 if (in->value_ctr.values[i].blob == NULL) {
937 return WERR_FOOBAR;
940 if (in->value_ctr.values[i].blob->length != 4) {
941 return WERR_FOOBAR;
944 attid = IVAL(in->value_ctr.values[i].blob->data, 0);
946 status = dsdb_schema_pfm_oid_from_attid(schema->prefixmap, attid, out->values, &oid);
947 W_ERROR_NOT_OK_RETURN(status);
949 out->values[i] = data_blob_string_const(oid);
952 return WERR_OK;
955 static WERROR _dsdb_syntax_auto_OID_ldb_to_drsuapi(struct ldb_context *ldb,
956 const struct dsdb_schema *schema,
957 const struct dsdb_attribute *attr,
958 const struct ldb_message_element *in,
959 TALLOC_CTX *mem_ctx,
960 struct drsuapi_DsReplicaAttribute *out)
962 uint32_t i;
963 DATA_BLOB *blobs;
965 out->attid= attr->attributeID_id;
966 out->value_ctr.num_values= in->num_values;
967 out->value_ctr.values= talloc_array(mem_ctx,
968 struct drsuapi_DsAttributeValue,
969 in->num_values);
970 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
972 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
973 W_ERROR_HAVE_NO_MEMORY(blobs);
975 for (i=0; i < in->num_values; i++) {
976 const struct dsdb_class *obj_class;
977 const struct dsdb_attribute *obj_attr;
978 struct ldb_val *v;
980 out->value_ctr.values[i].blob= &blobs[i];
982 blobs[i] = data_blob_talloc(blobs, NULL, 4);
983 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
985 /* in DRS windows puts the classes in the opposite
986 order to the order used in ldap */
987 v = &in->values[(in->num_values-1)-i];
989 if ((obj_class = dsdb_class_by_lDAPDisplayName_ldb_val(schema, v))) {
990 SIVAL(blobs[i].data, 0, obj_class->governsID_id);
991 } else if ((obj_attr = dsdb_attribute_by_lDAPDisplayName_ldb_val(schema, v))) {
992 SIVAL(blobs[i].data, 0, obj_attr->attributeID_id);
993 } else {
994 uint32_t attid;
995 WERROR werr;
996 werr = dsdb_schema_pfm_make_attid(schema->prefixmap,
997 (const char *)v->data,
998 &attid);
999 W_ERROR_NOT_OK_RETURN(werr);
1000 SIVAL(blobs[i].data, 0, attid);
1006 return WERR_OK;
1009 static WERROR _dsdb_syntax_OID_obj_ldb_to_drsuapi(struct ldb_context *ldb,
1010 const struct dsdb_schema *schema,
1011 const struct dsdb_attribute *attr,
1012 const struct ldb_message_element *in,
1013 TALLOC_CTX *mem_ctx,
1014 struct drsuapi_DsReplicaAttribute *out)
1016 uint32_t i;
1017 DATA_BLOB *blobs;
1019 out->attid= attr->attributeID_id;
1020 out->value_ctr.num_values= in->num_values;
1021 out->value_ctr.values= talloc_array(mem_ctx,
1022 struct drsuapi_DsAttributeValue,
1023 in->num_values);
1024 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1026 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1027 W_ERROR_HAVE_NO_MEMORY(blobs);
1029 for (i=0; i < in->num_values; i++) {
1030 const struct dsdb_class *obj_class;
1032 out->value_ctr.values[i].blob= &blobs[i];
1034 blobs[i] = data_blob_talloc(blobs, NULL, 4);
1035 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
1037 /* in DRS windows puts the classes in the opposite
1038 order to the order used in ldap */
1039 obj_class = dsdb_class_by_lDAPDisplayName(schema,
1040 (const char *)in->values[(in->num_values-1)-i].data);
1041 if (!obj_class) {
1042 return WERR_FOOBAR;
1044 SIVAL(blobs[i].data, 0, obj_class->governsID_id);
1048 return WERR_OK;
1051 static WERROR _dsdb_syntax_OID_attr_ldb_to_drsuapi(struct ldb_context *ldb,
1052 const struct dsdb_schema *schema,
1053 const struct dsdb_attribute *attr,
1054 const struct ldb_message_element *in,
1055 TALLOC_CTX *mem_ctx,
1056 struct drsuapi_DsReplicaAttribute *out)
1058 uint32_t i;
1059 DATA_BLOB *blobs;
1061 out->attid= attr->attributeID_id;
1062 out->value_ctr.num_values= in->num_values;
1063 out->value_ctr.values= talloc_array(mem_ctx,
1064 struct drsuapi_DsAttributeValue,
1065 in->num_values);
1066 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1068 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1069 W_ERROR_HAVE_NO_MEMORY(blobs);
1071 for (i=0; i < in->num_values; i++) {
1072 const struct dsdb_attribute *obj_attr;
1074 out->value_ctr.values[i].blob= &blobs[i];
1076 blobs[i] = data_blob_talloc(blobs, NULL, 4);
1077 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
1079 obj_attr = dsdb_attribute_by_lDAPDisplayName(schema, (const char *)in->values[i].data);
1080 if (!obj_attr) {
1081 return WERR_FOOBAR;
1083 SIVAL(blobs[i].data, 0, obj_attr->attributeID_id);
1087 return WERR_OK;
1090 static WERROR _dsdb_syntax_OID_oid_ldb_to_drsuapi(struct ldb_context *ldb,
1091 const struct dsdb_schema *schema,
1092 const struct dsdb_attribute *attr,
1093 const struct ldb_message_element *in,
1094 TALLOC_CTX *mem_ctx,
1095 struct drsuapi_DsReplicaAttribute *out)
1097 uint32_t i;
1098 DATA_BLOB *blobs;
1100 out->attid= attr->attributeID_id;
1101 out->value_ctr.num_values= in->num_values;
1102 out->value_ctr.values= talloc_array(mem_ctx,
1103 struct drsuapi_DsAttributeValue,
1104 in->num_values);
1105 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1107 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1108 W_ERROR_HAVE_NO_MEMORY(blobs);
1110 for (i=0; i < in->num_values; i++) {
1111 uint32_t attid;
1112 WERROR status;
1114 out->value_ctr.values[i].blob= &blobs[i];
1116 blobs[i] = data_blob_talloc(blobs, NULL, 4);
1117 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
1119 status = dsdb_schema_pfm_make_attid(schema->prefixmap,
1120 (const char *)in->values[i].data,
1121 &attid);
1122 W_ERROR_NOT_OK_RETURN(status);
1124 SIVAL(blobs[i].data, 0, attid);
1127 return WERR_OK;
1130 static WERROR dsdb_syntax_OID_drsuapi_to_ldb(struct ldb_context *ldb,
1131 const struct dsdb_schema *schema,
1132 const struct dsdb_attribute *attr,
1133 const struct drsuapi_DsReplicaAttribute *in,
1134 TALLOC_CTX *mem_ctx,
1135 struct ldb_message_element *out)
1137 switch (attr->attributeID_id) {
1138 case DRSUAPI_ATTRIBUTE_objectClass:
1139 case DRSUAPI_ATTRIBUTE_subClassOf:
1140 case DRSUAPI_ATTRIBUTE_auxiliaryClass:
1141 case DRSUAPI_ATTRIBUTE_systemAuxiliaryClass:
1142 case DRSUAPI_ATTRIBUTE_systemPossSuperiors:
1143 case DRSUAPI_ATTRIBUTE_possSuperiors:
1144 return _dsdb_syntax_OID_obj_drsuapi_to_ldb(ldb, schema, attr, in, mem_ctx, out);
1145 case DRSUAPI_ATTRIBUTE_systemMustContain:
1146 case DRSUAPI_ATTRIBUTE_systemMayContain:
1147 case DRSUAPI_ATTRIBUTE_mustContain:
1148 case DRSUAPI_ATTRIBUTE_rDNAttId:
1149 case DRSUAPI_ATTRIBUTE_transportAddressAttribute:
1150 case DRSUAPI_ATTRIBUTE_mayContain:
1151 return _dsdb_syntax_OID_attr_drsuapi_to_ldb(ldb, schema, attr, in, mem_ctx, out);
1152 case DRSUAPI_ATTRIBUTE_governsID:
1153 case DRSUAPI_ATTRIBUTE_attributeID:
1154 case DRSUAPI_ATTRIBUTE_attributeSyntax:
1155 return _dsdb_syntax_OID_oid_drsuapi_to_ldb(ldb, schema, attr, in, mem_ctx, out);
1158 DEBUG(0,(__location__ ": Unknown handling for attributeID_id for %s\n",
1159 attr->lDAPDisplayName));
1160 return _dsdb_syntax_auto_OID_drsuapi_to_ldb(ldb, schema, attr, in, mem_ctx, out);
1163 static WERROR dsdb_syntax_OID_ldb_to_drsuapi(struct ldb_context *ldb,
1164 const struct dsdb_schema *schema,
1165 const struct dsdb_attribute *attr,
1166 const struct ldb_message_element *in,
1167 TALLOC_CTX *mem_ctx,
1168 struct drsuapi_DsReplicaAttribute *out)
1170 if (attr->attributeID_id == 0xFFFFFFFF) {
1171 return WERR_FOOBAR;
1174 switch (attr->attributeID_id) {
1175 case DRSUAPI_ATTRIBUTE_objectClass:
1176 case DRSUAPI_ATTRIBUTE_subClassOf:
1177 case DRSUAPI_ATTRIBUTE_auxiliaryClass:
1178 case DRSUAPI_ATTRIBUTE_systemAuxiliaryClass:
1179 case DRSUAPI_ATTRIBUTE_systemPossSuperiors:
1180 case DRSUAPI_ATTRIBUTE_possSuperiors:
1181 return _dsdb_syntax_OID_obj_ldb_to_drsuapi(ldb, schema, attr, in, mem_ctx, out);
1182 case DRSUAPI_ATTRIBUTE_systemMustContain:
1183 case DRSUAPI_ATTRIBUTE_systemMayContain:
1184 case DRSUAPI_ATTRIBUTE_mustContain:
1185 case DRSUAPI_ATTRIBUTE_rDNAttId:
1186 case DRSUAPI_ATTRIBUTE_transportAddressAttribute:
1187 case DRSUAPI_ATTRIBUTE_mayContain:
1188 return _dsdb_syntax_OID_attr_ldb_to_drsuapi(ldb, schema, attr, in, mem_ctx, out);
1189 case DRSUAPI_ATTRIBUTE_governsID:
1190 case DRSUAPI_ATTRIBUTE_attributeID:
1191 case DRSUAPI_ATTRIBUTE_attributeSyntax:
1192 return _dsdb_syntax_OID_oid_ldb_to_drsuapi(ldb, schema, attr, in, mem_ctx, out);
1195 DEBUG(0,(__location__ ": Unknown handling for attributeID_id for %s\n",
1196 attr->lDAPDisplayName));
1198 return _dsdb_syntax_auto_OID_ldb_to_drsuapi(ldb, schema, attr, in, mem_ctx, out);
1201 static WERROR dsdb_syntax_UNICODE_drsuapi_to_ldb(struct ldb_context *ldb,
1202 const struct dsdb_schema *schema,
1203 const struct dsdb_attribute *attr,
1204 const struct drsuapi_DsReplicaAttribute *in,
1205 TALLOC_CTX *mem_ctx,
1206 struct ldb_message_element *out)
1208 uint32_t i;
1210 out->flags = 0;
1211 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1212 W_ERROR_HAVE_NO_MEMORY(out->name);
1214 out->num_values = in->value_ctr.num_values;
1215 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1216 W_ERROR_HAVE_NO_MEMORY(out->values);
1218 for (i=0; i < out->num_values; i++) {
1219 char *str;
1221 if (in->value_ctr.values[i].blob == NULL) {
1222 return WERR_FOOBAR;
1225 if (in->value_ctr.values[i].blob->length == 0) {
1226 return WERR_FOOBAR;
1229 if (!convert_string_talloc_convenience(out->values,
1230 schema->iconv_convenience,
1231 CH_UTF16, CH_UNIX,
1232 in->value_ctr.values[i].blob->data,
1233 in->value_ctr.values[i].blob->length,
1234 (void **)&str, NULL, false)) {
1235 return WERR_FOOBAR;
1238 out->values[i] = data_blob_string_const(str);
1241 return WERR_OK;
1244 static WERROR dsdb_syntax_UNICODE_ldb_to_drsuapi(struct ldb_context *ldb,
1245 const struct dsdb_schema *schema,
1246 const struct dsdb_attribute *attr,
1247 const struct ldb_message_element *in,
1248 TALLOC_CTX *mem_ctx,
1249 struct drsuapi_DsReplicaAttribute *out)
1251 uint32_t i;
1252 DATA_BLOB *blobs;
1254 if (attr->attributeID_id == 0xFFFFFFFF) {
1255 return WERR_FOOBAR;
1258 out->attid = attr->attributeID_id;
1259 out->value_ctr.num_values = in->num_values;
1260 out->value_ctr.values = talloc_array(mem_ctx,
1261 struct drsuapi_DsAttributeValue,
1262 in->num_values);
1263 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1265 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1266 W_ERROR_HAVE_NO_MEMORY(blobs);
1268 for (i=0; i < in->num_values; i++) {
1269 out->value_ctr.values[i].blob = &blobs[i];
1271 if (!convert_string_talloc_convenience(blobs,
1272 schema->iconv_convenience, CH_UNIX, CH_UTF16,
1273 in->values[i].data, in->values[i].length,
1274 (void **)&blobs[i].data, &blobs[i].length, false)) {
1275 return WERR_FOOBAR;
1279 return WERR_OK;
1283 WERROR dsdb_syntax_one_DN_drsuapi_to_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
1284 const struct dsdb_syntax *syntax,
1285 struct smb_iconv_convenience *iconv_convenience,
1286 const DATA_BLOB *in, DATA_BLOB *out)
1288 struct drsuapi_DsReplicaObjectIdentifier3 id3;
1289 enum ndr_err_code ndr_err;
1290 DATA_BLOB guid_blob;
1291 struct ldb_dn *dn;
1292 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1293 int ret;
1294 NTSTATUS status;
1296 if (!tmp_ctx) {
1297 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1300 if (in == NULL) {
1301 talloc_free(tmp_ctx);
1302 return WERR_FOOBAR;
1305 if (in->length == 0) {
1306 talloc_free(tmp_ctx);
1307 return WERR_FOOBAR;
1311 /* windows sometimes sends an extra two pad bytes here */
1312 ndr_err = ndr_pull_struct_blob(in,
1313 tmp_ctx, iconv_convenience, &id3,
1314 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3);
1315 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1316 status = ndr_map_error2ntstatus(ndr_err);
1317 talloc_free(tmp_ctx);
1318 return ntstatus_to_werror(status);
1321 dn = ldb_dn_new(tmp_ctx, ldb, id3.dn);
1322 if (!dn) {
1323 talloc_free(tmp_ctx);
1324 /* If this fails, it must be out of memory, as it does not do much parsing */
1325 W_ERROR_HAVE_NO_MEMORY(dn);
1328 if (!GUID_all_zero(&id3.guid)) {
1329 status = GUID_to_ndr_blob(&id3.guid, tmp_ctx, &guid_blob);
1330 if (!NT_STATUS_IS_OK(status)) {
1331 talloc_free(tmp_ctx);
1332 return ntstatus_to_werror(status);
1335 ret = ldb_dn_set_extended_component(dn, "GUID", &guid_blob);
1336 if (ret != LDB_SUCCESS) {
1337 talloc_free(tmp_ctx);
1338 return WERR_FOOBAR;
1340 talloc_free(guid_blob.data);
1343 if (id3.__ndr_size_sid) {
1344 DATA_BLOB sid_blob;
1345 ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, iconv_convenience, &id3.sid,
1346 (ndr_push_flags_fn_t)ndr_push_dom_sid);
1347 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1348 status = ndr_map_error2ntstatus(ndr_err);
1349 talloc_free(tmp_ctx);
1350 return ntstatus_to_werror(status);
1353 ret = ldb_dn_set_extended_component(dn, "SID", &sid_blob);
1354 if (ret != LDB_SUCCESS) {
1355 talloc_free(tmp_ctx);
1356 return WERR_FOOBAR;
1360 *out = data_blob_string_const(ldb_dn_get_extended_linearized(mem_ctx, dn, 1));
1361 talloc_free(tmp_ctx);
1362 return WERR_OK;
1365 static WERROR dsdb_syntax_DN_drsuapi_to_ldb(struct ldb_context *ldb,
1366 const struct dsdb_schema *schema,
1367 const struct dsdb_attribute *attr,
1368 const struct drsuapi_DsReplicaAttribute *in,
1369 TALLOC_CTX *mem_ctx,
1370 struct ldb_message_element *out)
1372 uint32_t i;
1374 out->flags = 0;
1375 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1376 W_ERROR_HAVE_NO_MEMORY(out->name);
1378 out->num_values = in->value_ctr.num_values;
1379 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1380 W_ERROR_HAVE_NO_MEMORY(out->values);
1382 for (i=0; i < out->num_values; i++) {
1383 WERROR status = dsdb_syntax_one_DN_drsuapi_to_ldb(out->values, ldb, attr->syntax,
1384 schema->iconv_convenience,
1385 in->value_ctr.values[i].blob,
1386 &out->values[i]);
1387 if (!W_ERROR_IS_OK(status)) {
1388 return status;
1393 return WERR_OK;
1396 static WERROR dsdb_syntax_DN_ldb_to_drsuapi(struct ldb_context *ldb,
1397 const struct dsdb_schema *schema,
1398 const struct dsdb_attribute *attr,
1399 const struct ldb_message_element *in,
1400 TALLOC_CTX *mem_ctx,
1401 struct drsuapi_DsReplicaAttribute *out)
1403 uint32_t i;
1404 DATA_BLOB *blobs;
1406 if (attr->attributeID_id == 0xFFFFFFFF) {
1407 return WERR_FOOBAR;
1410 out->attid = attr->attributeID_id;
1411 out->value_ctr.num_values = in->num_values;
1412 out->value_ctr.values = talloc_array(mem_ctx,
1413 struct drsuapi_DsAttributeValue,
1414 in->num_values);
1415 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1417 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1418 W_ERROR_HAVE_NO_MEMORY(blobs);
1420 for (i=0; i < in->num_values; i++) {
1421 struct drsuapi_DsReplicaObjectIdentifier3 id3;
1422 enum ndr_err_code ndr_err;
1423 const DATA_BLOB *sid_blob;
1424 struct ldb_dn *dn;
1425 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1426 NTSTATUS status;
1428 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1430 out->value_ctr.values[i].blob = &blobs[i];
1432 dn = ldb_dn_from_ldb_val(tmp_ctx, ldb, &in->values[i]);
1434 W_ERROR_HAVE_NO_MEMORY(dn);
1436 ZERO_STRUCT(id3);
1438 status = dsdb_get_extended_dn_guid(dn, &id3.guid, "GUID");
1439 if (!NT_STATUS_IS_OK(status) &&
1440 !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1441 talloc_free(tmp_ctx);
1442 return ntstatus_to_werror(status);
1445 sid_blob = ldb_dn_get_extended_component(dn, "SID");
1446 if (sid_blob) {
1448 ndr_err = ndr_pull_struct_blob_all(sid_blob,
1449 tmp_ctx, schema->iconv_convenience, &id3.sid,
1450 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1451 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1452 status = ndr_map_error2ntstatus(ndr_err);
1453 talloc_free(tmp_ctx);
1454 return ntstatus_to_werror(status);
1458 id3.dn = ldb_dn_get_linearized(dn);
1460 ndr_err = ndr_push_struct_blob(&blobs[i], blobs, schema->iconv_convenience, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
1461 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1462 status = ndr_map_error2ntstatus(ndr_err);
1463 talloc_free(tmp_ctx);
1464 return ntstatus_to_werror(status);
1466 talloc_free(tmp_ctx);
1469 return WERR_OK;
1474 static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(struct ldb_context *ldb,
1475 const struct dsdb_schema *schema,
1476 const struct dsdb_attribute *attr,
1477 const struct drsuapi_DsReplicaAttribute *in,
1478 TALLOC_CTX *mem_ctx,
1479 struct ldb_message_element *out)
1481 uint32_t i;
1482 int ret;
1484 out->flags = 0;
1485 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1486 W_ERROR_HAVE_NO_MEMORY(out->name);
1488 out->num_values = in->value_ctr.num_values;
1489 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1490 W_ERROR_HAVE_NO_MEMORY(out->values);
1492 for (i=0; i < out->num_values; i++) {
1493 struct drsuapi_DsReplicaObjectIdentifier3Binary id3;
1494 enum ndr_err_code ndr_err;
1495 DATA_BLOB guid_blob;
1496 struct ldb_dn *dn;
1497 struct dsdb_dn *dsdb_dn;
1498 NTSTATUS status;
1499 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1500 if (!tmp_ctx) {
1501 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1504 if (in->value_ctr.values[i].blob == NULL) {
1505 talloc_free(tmp_ctx);
1506 return WERR_FOOBAR;
1509 if (in->value_ctr.values[i].blob->length == 0) {
1510 talloc_free(tmp_ctx);
1511 return WERR_FOOBAR;
1515 /* windows sometimes sends an extra two pad bytes here */
1516 ndr_err = ndr_pull_struct_blob(in->value_ctr.values[i].blob,
1517 tmp_ctx, schema->iconv_convenience, &id3,
1518 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary);
1519 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1520 status = ndr_map_error2ntstatus(ndr_err);
1521 talloc_free(tmp_ctx);
1522 return ntstatus_to_werror(status);
1525 dn = ldb_dn_new(tmp_ctx, ldb, id3.dn);
1526 if (!dn) {
1527 talloc_free(tmp_ctx);
1528 /* If this fails, it must be out of memory, as it does not do much parsing */
1529 W_ERROR_HAVE_NO_MEMORY(dn);
1532 status = GUID_to_ndr_blob(&id3.guid, tmp_ctx, &guid_blob);
1533 if (!NT_STATUS_IS_OK(status)) {
1534 talloc_free(tmp_ctx);
1535 return ntstatus_to_werror(status);
1538 ret = ldb_dn_set_extended_component(dn, "GUID", &guid_blob);
1539 if (ret != LDB_SUCCESS) {
1540 talloc_free(tmp_ctx);
1541 return WERR_FOOBAR;
1544 talloc_free(guid_blob.data);
1546 if (id3.__ndr_size_sid) {
1547 DATA_BLOB sid_blob;
1548 ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, schema->iconv_convenience, &id3.sid,
1549 (ndr_push_flags_fn_t)ndr_push_dom_sid);
1550 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1551 status = ndr_map_error2ntstatus(ndr_err);
1552 talloc_free(tmp_ctx);
1553 return ntstatus_to_werror(status);
1556 ret = ldb_dn_set_extended_component(dn, "SID", &sid_blob);
1557 if (ret != LDB_SUCCESS) {
1558 talloc_free(tmp_ctx);
1559 return WERR_FOOBAR;
1563 /* set binary stuff */
1564 dsdb_dn = dsdb_dn_construct(tmp_ctx, dn, id3.binary, attr->syntax->ldap_oid);
1565 if (!dsdb_dn) {
1566 /* If this fails, it must be out of memory, we know the ldap_oid is valid */
1567 talloc_free(tmp_ctx);
1568 W_ERROR_HAVE_NO_MEMORY(dsdb_dn);
1570 out->values[i] = data_blob_string_const(dsdb_dn_get_extended_linearized(out->values, dsdb_dn, 1));
1571 talloc_free(tmp_ctx);
1574 return WERR_OK;
1577 static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(struct ldb_context *ldb,
1578 const struct dsdb_schema *schema,
1579 const struct dsdb_attribute *attr,
1580 const struct ldb_message_element *in,
1581 TALLOC_CTX *mem_ctx,
1582 struct drsuapi_DsReplicaAttribute *out)
1584 uint32_t i;
1585 DATA_BLOB *blobs;
1587 if (attr->attributeID_id == 0xFFFFFFFF) {
1588 return WERR_FOOBAR;
1591 out->attid = attr->attributeID_id;
1592 out->value_ctr.num_values = in->num_values;
1593 out->value_ctr.values = talloc_array(mem_ctx,
1594 struct drsuapi_DsAttributeValue,
1595 in->num_values);
1596 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1598 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1599 W_ERROR_HAVE_NO_MEMORY(blobs);
1601 for (i=0; i < in->num_values; i++) {
1602 struct drsuapi_DsReplicaObjectIdentifier3Binary id3;
1603 enum ndr_err_code ndr_err;
1604 const DATA_BLOB *sid_blob;
1605 struct dsdb_dn *dsdb_dn;
1606 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1607 NTSTATUS status;
1609 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1611 out->value_ctr.values[i].blob = &blobs[i];
1613 dsdb_dn = dsdb_dn_parse(tmp_ctx, ldb, &in->values[i], attr->syntax->ldap_oid);
1615 if (!dsdb_dn) {
1616 talloc_free(tmp_ctx);
1617 return ntstatus_to_werror(NT_STATUS_INVALID_PARAMETER);
1620 ZERO_STRUCT(id3);
1622 status = dsdb_get_extended_dn_guid(dsdb_dn->dn, &id3.guid, "GUID");
1623 if (!NT_STATUS_IS_OK(status) &&
1624 !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1625 talloc_free(tmp_ctx);
1626 return ntstatus_to_werror(status);
1629 sid_blob = ldb_dn_get_extended_component(dsdb_dn->dn, "SID");
1630 if (sid_blob) {
1632 ndr_err = ndr_pull_struct_blob_all(sid_blob,
1633 tmp_ctx, schema->iconv_convenience, &id3.sid,
1634 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1635 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1636 status = ndr_map_error2ntstatus(ndr_err);
1637 talloc_free(tmp_ctx);
1638 return ntstatus_to_werror(status);
1642 id3.dn = ldb_dn_get_linearized(dsdb_dn->dn);
1644 /* get binary stuff */
1645 id3.binary = dsdb_dn->extra_part;
1647 ndr_err = ndr_push_struct_blob(&blobs[i], blobs, schema->iconv_convenience, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary);
1648 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1649 status = ndr_map_error2ntstatus(ndr_err);
1650 talloc_free(tmp_ctx);
1651 return ntstatus_to_werror(status);
1653 talloc_free(tmp_ctx);
1656 return WERR_OK;
1659 static WERROR dsdb_syntax_DN_STRING_drsuapi_to_ldb(struct ldb_context *ldb,
1660 const struct dsdb_schema *schema,
1661 const struct dsdb_attribute *attr,
1662 const struct drsuapi_DsReplicaAttribute *in,
1663 TALLOC_CTX *mem_ctx,
1664 struct ldb_message_element *out)
1666 return dsdb_syntax_DN_BINARY_drsuapi_to_ldb(ldb,
1667 schema,
1668 attr,
1670 mem_ctx,
1671 out);
1674 static WERROR dsdb_syntax_DN_STRING_ldb_to_drsuapi(struct ldb_context *ldb,
1675 const struct dsdb_schema *schema,
1676 const struct dsdb_attribute *attr,
1677 const struct ldb_message_element *in,
1678 TALLOC_CTX *mem_ctx,
1679 struct drsuapi_DsReplicaAttribute *out)
1681 return dsdb_syntax_DN_BINARY_ldb_to_drsuapi(ldb,
1682 schema,
1683 attr,
1685 mem_ctx,
1686 out);
1689 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb(struct ldb_context *ldb,
1690 const struct dsdb_schema *schema,
1691 const struct dsdb_attribute *attr,
1692 const struct drsuapi_DsReplicaAttribute *in,
1693 TALLOC_CTX *mem_ctx,
1694 struct ldb_message_element *out)
1696 uint32_t i;
1698 out->flags = 0;
1699 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1700 W_ERROR_HAVE_NO_MEMORY(out->name);
1702 out->num_values = in->value_ctr.num_values;
1703 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1704 W_ERROR_HAVE_NO_MEMORY(out->values);
1706 for (i=0; i < out->num_values; i++) {
1707 uint32_t len;
1708 char *str;
1710 if (in->value_ctr.values[i].blob == NULL) {
1711 return WERR_FOOBAR;
1714 if (in->value_ctr.values[i].blob->length < 4) {
1715 return WERR_FOOBAR;
1718 len = IVAL(in->value_ctr.values[i].blob->data, 0);
1720 if (len != in->value_ctr.values[i].blob->length) {
1721 return WERR_FOOBAR;
1724 if (!convert_string_talloc_convenience(out->values, schema->iconv_convenience, CH_UTF16, CH_UNIX,
1725 in->value_ctr.values[i].blob->data+4,
1726 in->value_ctr.values[i].blob->length-4,
1727 (void **)&str, NULL, false)) {
1728 return WERR_FOOBAR;
1731 out->values[i] = data_blob_string_const(str);
1734 return WERR_OK;
1737 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi(struct ldb_context *ldb,
1738 const struct dsdb_schema *schema,
1739 const struct dsdb_attribute *attr,
1740 const struct ldb_message_element *in,
1741 TALLOC_CTX *mem_ctx,
1742 struct drsuapi_DsReplicaAttribute *out)
1744 uint32_t i;
1745 DATA_BLOB *blobs;
1747 if (attr->attributeID_id == 0xFFFFFFFF) {
1748 return WERR_FOOBAR;
1751 out->attid = attr->attributeID_id;
1752 out->value_ctr.num_values = in->num_values;
1753 out->value_ctr.values = talloc_array(mem_ctx,
1754 struct drsuapi_DsAttributeValue,
1755 in->num_values);
1756 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1758 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1759 W_ERROR_HAVE_NO_MEMORY(blobs);
1761 for (i=0; i < in->num_values; i++) {
1762 uint8_t *data;
1763 size_t ret;
1765 out->value_ctr.values[i].blob = &blobs[i];
1767 if (!convert_string_talloc_convenience(blobs, schema->iconv_convenience, CH_UNIX, CH_UTF16,
1768 in->values[i].data,
1769 in->values[i].length,
1770 (void **)&data, &ret, false)) {
1771 return WERR_FOOBAR;
1774 blobs[i] = data_blob_talloc(blobs, NULL, 4 + ret);
1775 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
1777 SIVAL(blobs[i].data, 0, 4 + ret);
1779 if (ret > 0) {
1780 memcpy(blobs[i].data + 4, data, ret);
1781 talloc_free(data);
1785 return WERR_OK;
1788 #define OMOBJECTCLASS(val) { .length = sizeof(val) - 1, .data = discard_const_p(uint8_t, val) }
1790 static const struct dsdb_syntax dsdb_syntaxes[] = {
1792 .name = "Boolean",
1793 .ldap_oid = LDB_SYNTAX_BOOLEAN,
1794 .oMSyntax = 1,
1795 .attributeSyntax_oid = "2.5.5.8",
1796 .drsuapi_to_ldb = dsdb_syntax_BOOL_drsuapi_to_ldb,
1797 .ldb_to_drsuapi = dsdb_syntax_BOOL_ldb_to_drsuapi,
1798 .validate_ldb = dsdb_syntax_BOOL_validate_ldb,
1799 .equality = "booleanMatch",
1800 .comment = "Boolean"
1802 .name = "Integer",
1803 .ldap_oid = LDB_SYNTAX_INTEGER,
1804 .oMSyntax = 2,
1805 .attributeSyntax_oid = "2.5.5.9",
1806 .drsuapi_to_ldb = dsdb_syntax_INT32_drsuapi_to_ldb,
1807 .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi,
1808 .validate_ldb = dsdb_syntax_INT32_validate_ldb,
1809 .equality = "integerMatch",
1810 .comment = "Integer",
1811 .ldb_syntax = LDB_SYNTAX_SAMBA_INT32
1813 .name = "String(Octet)",
1814 .ldap_oid = LDB_SYNTAX_OCTET_STRING,
1815 .oMSyntax = 4,
1816 .attributeSyntax_oid = "2.5.5.10",
1817 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1818 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1819 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1820 .equality = "octetStringMatch",
1821 .comment = "Octet String",
1823 .name = "String(Sid)",
1824 .ldap_oid = LDB_SYNTAX_OCTET_STRING,
1825 .oMSyntax = 4,
1826 .attributeSyntax_oid = "2.5.5.17",
1827 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1828 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1829 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1830 .equality = "octetStringMatch",
1831 .comment = "Octet String - Security Identifier (SID)",
1832 .ldb_syntax = LDB_SYNTAX_SAMBA_SID
1834 .name = "String(Object-Identifier)",
1835 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.38",
1836 .oMSyntax = 6,
1837 .attributeSyntax_oid = "2.5.5.2",
1838 .drsuapi_to_ldb = dsdb_syntax_OID_drsuapi_to_ldb,
1839 .ldb_to_drsuapi = dsdb_syntax_OID_ldb_to_drsuapi,
1840 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1841 .equality = "caseIgnoreMatch", /* Would use "objectIdentifierMatch" but most are ldap attribute/class names */
1842 .comment = "OID String",
1843 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING
1845 .name = "Enumeration",
1846 .ldap_oid = LDB_SYNTAX_INTEGER,
1847 .oMSyntax = 10,
1848 .attributeSyntax_oid = "2.5.5.9",
1849 .drsuapi_to_ldb = dsdb_syntax_INT32_drsuapi_to_ldb,
1850 .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi,
1851 .validate_ldb = dsdb_syntax_INT32_validate_ldb,
1852 .ldb_syntax = LDB_SYNTAX_SAMBA_INT32
1854 /* not used in w2k3 forest */
1855 .name = "String(Numeric)",
1856 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.36",
1857 .oMSyntax = 18,
1858 .attributeSyntax_oid = "2.5.5.6",
1859 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1860 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1861 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1862 .equality = "numericStringMatch",
1863 .substring = "numericStringSubstringsMatch",
1864 .comment = "Numeric String",
1865 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING,
1867 .name = "String(Printable)",
1868 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.44",
1869 .oMSyntax = 19,
1870 .attributeSyntax_oid = "2.5.5.5",
1871 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1872 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1873 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1874 .ldb_syntax = LDB_SYNTAX_OCTET_STRING,
1876 .name = "String(Teletex)",
1877 .ldap_oid = "1.2.840.113556.1.4.905",
1878 .oMSyntax = 20,
1879 .attributeSyntax_oid = "2.5.5.4",
1880 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1881 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1882 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1883 .equality = "caseIgnoreMatch",
1884 .substring = "caseIgnoreSubstringsMatch",
1885 .comment = "Case Insensitive String",
1886 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING,
1888 .name = "String(IA5)",
1889 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.26",
1890 .oMSyntax = 22,
1891 .attributeSyntax_oid = "2.5.5.5",
1892 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1893 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1894 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1895 .equality = "caseExactIA5Match",
1896 .comment = "Printable String",
1897 .ldb_syntax = LDB_SYNTAX_OCTET_STRING,
1899 .name = "String(UTC-Time)",
1900 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.53",
1901 .oMSyntax = 23,
1902 .attributeSyntax_oid = "2.5.5.11",
1903 .drsuapi_to_ldb = dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb,
1904 .ldb_to_drsuapi = dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi,
1905 .validate_ldb = dsdb_syntax_NTTIME_UTC_validate_ldb,
1906 .equality = "generalizedTimeMatch",
1907 .comment = "UTC Time",
1909 .name = "String(Generalized-Time)",
1910 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.24",
1911 .oMSyntax = 24,
1912 .attributeSyntax_oid = "2.5.5.11",
1913 .drsuapi_to_ldb = dsdb_syntax_NTTIME_drsuapi_to_ldb,
1914 .ldb_to_drsuapi = dsdb_syntax_NTTIME_ldb_to_drsuapi,
1915 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1916 .equality = "generalizedTimeMatch",
1917 .comment = "Generalized Time",
1918 .ldb_syntax = LDB_SYNTAX_UTC_TIME,
1920 /* not used in w2k3 schema */
1921 .name = "String(Case Sensitive)",
1922 .ldap_oid = "1.2.840.113556.1.4.1362",
1923 .oMSyntax = 27,
1924 .attributeSyntax_oid = "2.5.5.3",
1925 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1926 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1927 .validate_ldb = dsdb_syntax_FOOBAR_validate_ldb,
1929 .name = "String(Unicode)",
1930 .ldap_oid = LDB_SYNTAX_DIRECTORY_STRING,
1931 .oMSyntax = 64,
1932 .attributeSyntax_oid = "2.5.5.12",
1933 .drsuapi_to_ldb = dsdb_syntax_UNICODE_drsuapi_to_ldb,
1934 .ldb_to_drsuapi = dsdb_syntax_UNICODE_ldb_to_drsuapi,
1935 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1936 .equality = "caseIgnoreMatch",
1937 .substring = "caseIgnoreSubstringsMatch",
1938 .comment = "Directory String",
1940 .name = "Interval/LargeInteger",
1941 .ldap_oid = "1.2.840.113556.1.4.906",
1942 .oMSyntax = 65,
1943 .attributeSyntax_oid = "2.5.5.16",
1944 .drsuapi_to_ldb = dsdb_syntax_INT64_drsuapi_to_ldb,
1945 .ldb_to_drsuapi = dsdb_syntax_INT64_ldb_to_drsuapi,
1946 .validate_ldb = dsdb_syntax_INT64_validate_ldb,
1947 .equality = "integerMatch",
1948 .comment = "Large Integer",
1949 .ldb_syntax = LDB_SYNTAX_INTEGER,
1951 .name = "String(NT-Sec-Desc)",
1952 .ldap_oid = LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR,
1953 .oMSyntax = 66,
1954 .attributeSyntax_oid = "2.5.5.15",
1955 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1956 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1957 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1959 .name = "Object(DS-DN)",
1960 .ldap_oid = LDB_SYNTAX_DN,
1961 .oMSyntax = 127,
1962 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x4a"),
1963 .attributeSyntax_oid = "2.5.5.1",
1964 .drsuapi_to_ldb = dsdb_syntax_DN_drsuapi_to_ldb,
1965 .ldb_to_drsuapi = dsdb_syntax_DN_ldb_to_drsuapi,
1966 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1967 .equality = "distinguishedNameMatch",
1968 .comment = "Object(DS-DN) == a DN",
1970 .name = "Object(DN-Binary)",
1971 .ldap_oid = DSDB_SYNTAX_BINARY_DN,
1972 .oMSyntax = 127,
1973 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0b"),
1974 .attributeSyntax_oid = "2.5.5.7",
1975 .drsuapi_to_ldb = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
1976 .ldb_to_drsuapi = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
1977 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1978 .equality = "octetStringMatch",
1979 .comment = "OctetString: Binary+DN",
1981 /* not used in w2k3 schema, but used in Exchange schema*/
1982 .name = "Object(OR-Name)",
1983 .ldap_oid = DSDB_SYNTAX_OR_NAME,
1984 .oMSyntax = 127,
1985 .oMObjectClass = OMOBJECTCLASS("\x56\x06\x01\x02\x05\x0b\x1D"),
1986 .attributeSyntax_oid = "2.5.5.7",
1987 .drsuapi_to_ldb = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
1988 .ldb_to_drsuapi = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
1989 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1990 .equality = "caseIgnoreMatch",
1991 .ldb_syntax = LDB_SYNTAX_DN,
1994 * TODO: verify if DATA_BLOB is correct here...!
1996 * repsFrom and repsTo are the only attributes using
1997 * this attribute syntax, but they're not replicated...
1999 .name = "Object(Replica-Link)",
2000 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.40",
2001 .oMSyntax = 127,
2002 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x06"),
2003 .attributeSyntax_oid = "2.5.5.10",
2004 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
2005 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
2006 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
2008 .name = "Object(Presentation-Address)",
2009 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.43",
2010 .oMSyntax = 127,
2011 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x5c"),
2012 .attributeSyntax_oid = "2.5.5.13",
2013 .drsuapi_to_ldb = dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb,
2014 .ldb_to_drsuapi = dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi,
2015 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
2016 .comment = "Presentation Address",
2017 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING,
2019 /* not used in w2k3 schema */
2020 .name = "Object(Access-Point)",
2021 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.2",
2022 .oMSyntax = 127,
2023 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x3e"),
2024 .attributeSyntax_oid = "2.5.5.14",
2025 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
2026 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
2027 .validate_ldb = dsdb_syntax_FOOBAR_validate_ldb,
2028 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING,
2030 /* not used in w2k3 schema */
2031 .name = "Object(DN-String)",
2032 .ldap_oid = DSDB_SYNTAX_STRING_DN,
2033 .oMSyntax = 127,
2034 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0c"),
2035 .attributeSyntax_oid = "2.5.5.14",
2036 .drsuapi_to_ldb = dsdb_syntax_DN_STRING_drsuapi_to_ldb,
2037 .ldb_to_drsuapi = dsdb_syntax_DN_STRING_ldb_to_drsuapi,
2038 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
2039 .equality = "octetStringMatch",
2040 .comment = "OctetString: String+DN",
2044 const struct dsdb_syntax *find_syntax_map_by_ad_oid(const char *ad_oid)
2046 int i;
2047 for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
2048 if (strcasecmp(ad_oid, dsdb_syntaxes[i].attributeSyntax_oid) == 0) {
2049 return &dsdb_syntaxes[i];
2052 return NULL;
2055 const struct dsdb_syntax *find_syntax_map_by_ad_syntax(int oMSyntax)
2057 int i;
2058 for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
2059 if (oMSyntax == dsdb_syntaxes[i].oMSyntax) {
2060 return &dsdb_syntaxes[i];
2063 return NULL;
2066 const struct dsdb_syntax *find_syntax_map_by_standard_oid(const char *standard_oid)
2068 int i;
2069 for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
2070 if (strcasecmp(standard_oid, dsdb_syntaxes[i].ldap_oid) == 0) {
2071 return &dsdb_syntaxes[i];
2074 return NULL;
2076 const struct dsdb_syntax *dsdb_syntax_for_attribute(const struct dsdb_attribute *attr)
2078 uint32_t i;
2080 for (i=0; i < ARRAY_SIZE(dsdb_syntaxes); i++) {
2081 if (attr->oMSyntax != dsdb_syntaxes[i].oMSyntax) continue;
2083 if (attr->oMObjectClass.length != dsdb_syntaxes[i].oMObjectClass.length) continue;
2085 if (attr->oMObjectClass.length) {
2086 int ret;
2087 ret = memcmp(attr->oMObjectClass.data,
2088 dsdb_syntaxes[i].oMObjectClass.data,
2089 attr->oMObjectClass.length);
2090 if (ret != 0) continue;
2093 if (strcmp(attr->attributeSyntax_oid, dsdb_syntaxes[i].attributeSyntax_oid) != 0) continue;
2095 return &dsdb_syntaxes[i];
2098 return NULL;
2101 WERROR dsdb_attribute_drsuapi_to_ldb(struct ldb_context *ldb,
2102 const struct dsdb_schema *schema,
2103 const struct drsuapi_DsReplicaAttribute *in,
2104 TALLOC_CTX *mem_ctx,
2105 struct ldb_message_element *out)
2107 const struct dsdb_attribute *sa;
2109 sa = dsdb_attribute_by_attributeID_id(schema, in->attid);
2110 if (!sa) {
2111 return WERR_FOOBAR;
2114 return sa->syntax->drsuapi_to_ldb(ldb, schema, sa, in, mem_ctx, out);
2117 WERROR dsdb_attribute_ldb_to_drsuapi(struct ldb_context *ldb,
2118 const struct dsdb_schema *schema,
2119 const struct ldb_message_element *in,
2120 TALLOC_CTX *mem_ctx,
2121 struct drsuapi_DsReplicaAttribute *out)
2123 const struct dsdb_attribute *sa;
2125 sa = dsdb_attribute_by_lDAPDisplayName(schema, in->name);
2126 if (!sa) {
2127 return WERR_FOOBAR;
2130 return sa->syntax->ldb_to_drsuapi(ldb, schema, sa, in, mem_ctx, out);
2133 WERROR dsdb_attribute_validate_ldb(struct ldb_context *ldb,
2134 const struct dsdb_schema *schema,
2135 const struct ldb_message_element *in)
2137 const struct dsdb_attribute *sa;
2139 sa = dsdb_attribute_by_lDAPDisplayName(schema, in->name);
2140 if (!sa) {
2141 return WERR_DS_ATTRIBUTE_TYPE_UNDEFINED;
2144 return sa->syntax->validate_ldb(ldb, schema, sa, in);