2 Unix SMB/CIFS mplementation.
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/>.
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"
35 * Initialize dsdb_syntax_ctx with default values
38 void dsdb_syntax_ctx_init(struct dsdb_syntax_ctx *ctx,
39 struct ldb_context *ldb,
40 const struct dsdb_schema *schema)
47 static WERROR dsdb_syntax_FOOBAR_drsuapi_to_ldb(struct ldb_context *ldb,
48 const struct dsdb_schema *schema,
49 const struct dsdb_attribute *attr,
50 const struct drsuapi_DsReplicaAttribute *in,
52 struct ldb_message_element *out)
57 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
58 W_ERROR_HAVE_NO_MEMORY(out->name);
60 out->num_values = in->value_ctr.num_values;
61 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
62 W_ERROR_HAVE_NO_MEMORY(out->values);
64 for (i=0; i < out->num_values; i++) {
67 if (in->value_ctr.values[i].blob == NULL) {
71 str = talloc_asprintf(out->values, "%s: not implemented",
73 W_ERROR_HAVE_NO_MEMORY(str);
75 out->values[i] = data_blob_string_const(str);
81 static WERROR dsdb_syntax_FOOBAR_ldb_to_drsuapi(struct ldb_context *ldb,
82 const struct dsdb_schema *schema,
83 const struct dsdb_attribute *attr,
84 const struct ldb_message_element *in,
86 struct drsuapi_DsReplicaAttribute *out)
91 static WERROR dsdb_syntax_FOOBAR_validate_ldb(struct ldb_context *ldb,
92 const struct dsdb_schema *schema,
93 const struct dsdb_attribute *attr,
94 const struct ldb_message_element *in)
99 static WERROR dsdb_syntax_BOOL_drsuapi_to_ldb(struct ldb_context *ldb,
100 const struct dsdb_schema *schema,
101 const struct dsdb_attribute *attr,
102 const struct drsuapi_DsReplicaAttribute *in,
104 struct ldb_message_element *out)
109 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
110 W_ERROR_HAVE_NO_MEMORY(out->name);
112 out->num_values = in->value_ctr.num_values;
113 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
114 W_ERROR_HAVE_NO_MEMORY(out->values);
116 for (i=0; i < out->num_values; i++) {
120 if (in->value_ctr.values[i].blob == NULL) {
124 if (in->value_ctr.values[i].blob->length != 4) {
128 v = IVAL(in->value_ctr.values[i].blob->data, 0);
131 str = talloc_strdup(out->values, "TRUE");
132 W_ERROR_HAVE_NO_MEMORY(str);
134 str = talloc_strdup(out->values, "FALSE");
135 W_ERROR_HAVE_NO_MEMORY(str);
138 out->values[i] = data_blob_string_const(str);
144 static WERROR dsdb_syntax_BOOL_ldb_to_drsuapi(struct ldb_context *ldb,
145 const struct dsdb_schema *schema,
146 const struct dsdb_attribute *attr,
147 const struct ldb_message_element *in,
149 struct drsuapi_DsReplicaAttribute *out)
154 if (attr->attributeID_id == 0xFFFFFFFF) {
158 out->attid = attr->attributeID_id;
159 out->value_ctr.num_values = in->num_values;
160 out->value_ctr.values = talloc_array(mem_ctx,
161 struct drsuapi_DsAttributeValue,
163 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
165 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
166 W_ERROR_HAVE_NO_MEMORY(blobs);
168 for (i=0; i < in->num_values; i++) {
169 out->value_ctr.values[i].blob = &blobs[i];
171 blobs[i] = data_blob_talloc(blobs, NULL, 4);
172 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
174 if (strcmp("TRUE", (const char *)in->values[i].data) == 0) {
175 SIVAL(blobs[i].data, 0, 0x00000001);
176 } else if (strcmp("FALSE", (const char *)in->values[i].data) == 0) {
177 SIVAL(blobs[i].data, 0, 0x00000000);
186 static WERROR dsdb_syntax_BOOL_validate_ldb(struct ldb_context *ldb,
187 const struct dsdb_schema *schema,
188 const struct dsdb_attribute *attr,
189 const struct ldb_message_element *in)
193 if (attr->attributeID_id == 0xFFFFFFFF) {
197 for (i=0; i < in->num_values; i++) {
201 (const char *)in->values[i].data,
202 in->values[i].length);
204 (const char *)in->values[i].data,
205 in->values[i].length);
207 if (t != 0 && f != 0) {
208 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
215 static WERROR dsdb_syntax_INT32_drsuapi_to_ldb(struct ldb_context *ldb,
216 const struct dsdb_schema *schema,
217 const struct dsdb_attribute *attr,
218 const struct drsuapi_DsReplicaAttribute *in,
220 struct ldb_message_element *out)
225 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
226 W_ERROR_HAVE_NO_MEMORY(out->name);
228 out->num_values = in->value_ctr.num_values;
229 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
230 W_ERROR_HAVE_NO_MEMORY(out->values);
232 for (i=0; i < out->num_values; i++) {
236 if (in->value_ctr.values[i].blob == NULL) {
240 if (in->value_ctr.values[i].blob->length != 4) {
244 v = IVALS(in->value_ctr.values[i].blob->data, 0);
246 str = talloc_asprintf(out->values, "%d", v);
247 W_ERROR_HAVE_NO_MEMORY(str);
249 out->values[i] = data_blob_string_const(str);
255 static WERROR dsdb_syntax_INT32_ldb_to_drsuapi(struct ldb_context *ldb,
256 const struct dsdb_schema *schema,
257 const struct dsdb_attribute *attr,
258 const struct ldb_message_element *in,
260 struct drsuapi_DsReplicaAttribute *out)
265 if (attr->attributeID_id == 0xFFFFFFFF) {
269 out->attid = attr->attributeID_id;
270 out->value_ctr.num_values = in->num_values;
271 out->value_ctr.values = talloc_array(mem_ctx,
272 struct drsuapi_DsAttributeValue,
274 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
276 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
277 W_ERROR_HAVE_NO_MEMORY(blobs);
279 for (i=0; i < in->num_values; i++) {
282 out->value_ctr.values[i].blob = &blobs[i];
284 blobs[i] = data_blob_talloc(blobs, NULL, 4);
285 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
287 /* We've to use "strtoll" here to have the intended overflows.
288 * Otherwise we may get "LONG_MAX" and the conversion is wrong. */
289 v = (int32_t) strtoll((char *)in->values[i].data, NULL, 0);
291 SIVALS(blobs[i].data, 0, v);
297 static WERROR dsdb_syntax_INT32_validate_ldb(struct ldb_context *ldb,
298 const struct dsdb_schema *schema,
299 const struct dsdb_attribute *attr,
300 const struct ldb_message_element *in)
304 if (attr->attributeID_id == 0xFFFFFFFF) {
308 for (i=0; i < in->num_values; i++) {
310 char buf[sizeof("-2147483648")];
314 if (in->values[i].length >= sizeof(buf)) {
315 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
318 memcpy(buf, in->values[i].data, in->values[i].length);
320 v = strtol(buf, &end, 10);
322 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
324 if (end && end[0] != '\0') {
325 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
328 if (attr->rangeLower) {
329 if ((int32_t)v < (int32_t)*attr->rangeLower) {
330 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
334 if (attr->rangeUpper) {
335 if ((int32_t)v > (int32_t)*attr->rangeUpper) {
336 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
344 static WERROR dsdb_syntax_INT64_drsuapi_to_ldb(struct ldb_context *ldb,
345 const struct dsdb_schema *schema,
346 const struct dsdb_attribute *attr,
347 const struct drsuapi_DsReplicaAttribute *in,
349 struct ldb_message_element *out)
354 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
355 W_ERROR_HAVE_NO_MEMORY(out->name);
357 out->num_values = in->value_ctr.num_values;
358 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
359 W_ERROR_HAVE_NO_MEMORY(out->values);
361 for (i=0; i < out->num_values; i++) {
365 if (in->value_ctr.values[i].blob == NULL) {
369 if (in->value_ctr.values[i].blob->length != 8) {
373 v = BVALS(in->value_ctr.values[i].blob->data, 0);
375 str = talloc_asprintf(out->values, "%lld", (long long int)v);
376 W_ERROR_HAVE_NO_MEMORY(str);
378 out->values[i] = data_blob_string_const(str);
384 static WERROR dsdb_syntax_INT64_ldb_to_drsuapi(struct ldb_context *ldb,
385 const struct dsdb_schema *schema,
386 const struct dsdb_attribute *attr,
387 const struct ldb_message_element *in,
389 struct drsuapi_DsReplicaAttribute *out)
394 if (attr->attributeID_id == 0xFFFFFFFF) {
398 out->attid = attr->attributeID_id;
399 out->value_ctr.num_values = in->num_values;
400 out->value_ctr.values = talloc_array(mem_ctx,
401 struct drsuapi_DsAttributeValue,
403 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
405 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
406 W_ERROR_HAVE_NO_MEMORY(blobs);
408 for (i=0; i < in->num_values; i++) {
411 out->value_ctr.values[i].blob = &blobs[i];
413 blobs[i] = data_blob_talloc(blobs, NULL, 8);
414 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
416 v = strtoll((const char *)in->values[i].data, NULL, 10);
418 SBVALS(blobs[i].data, 0, v);
424 static WERROR dsdb_syntax_INT64_validate_ldb(struct ldb_context *ldb,
425 const struct dsdb_schema *schema,
426 const struct dsdb_attribute *attr,
427 const struct ldb_message_element *in)
431 if (attr->attributeID_id == 0xFFFFFFFF) {
435 for (i=0; i < in->num_values; i++) {
437 char buf[sizeof("-9223372036854775808")];
441 if (in->values[i].length >= sizeof(buf)) {
442 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
444 memcpy(buf, in->values[i].data, in->values[i].length);
447 v = strtoll(buf, &end, 10);
449 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
451 if (end && end[0] != '\0') {
452 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
455 if (attr->rangeLower) {
456 if ((int64_t)v < (int64_t)*attr->rangeLower) {
457 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
461 if (attr->rangeUpper) {
462 if ((int64_t)v > (int64_t)*attr->rangeUpper) {
463 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
470 static WERROR dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb(struct ldb_context *ldb,
471 const struct dsdb_schema *schema,
472 const struct dsdb_attribute *attr,
473 const struct drsuapi_DsReplicaAttribute *in,
475 struct ldb_message_element *out)
480 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
481 W_ERROR_HAVE_NO_MEMORY(out->name);
483 out->num_values = in->value_ctr.num_values;
484 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
485 W_ERROR_HAVE_NO_MEMORY(out->values);
487 for (i=0; i < out->num_values; i++) {
492 if (in->value_ctr.values[i].blob == NULL) {
496 if (in->value_ctr.values[i].blob->length != 8) {
500 v = BVAL(in->value_ctr.values[i].blob->data, 0);
502 t = nt_time_to_unix(v);
505 * NOTE: On a w2k3 server you can set a GeneralizedTime string
506 * via LDAP, but you get back an UTCTime string,
507 * but via DRSUAPI you get back the NTTIME_1sec value
508 * that represents the GeneralizedTime value!
510 * So if we store the UTCTime string in our ldb
511 * we'll loose information!
513 str = ldb_timestring_utc(out->values, t);
514 W_ERROR_HAVE_NO_MEMORY(str);
515 out->values[i] = data_blob_string_const(str);
521 static WERROR dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi(struct ldb_context *ldb,
522 const struct dsdb_schema *schema,
523 const struct dsdb_attribute *attr,
524 const struct ldb_message_element *in,
526 struct drsuapi_DsReplicaAttribute *out)
531 if (attr->attributeID_id == 0xFFFFFFFF) {
535 out->attid = attr->attributeID_id;
536 out->value_ctr.num_values = in->num_values;
537 out->value_ctr.values = talloc_array(mem_ctx,
538 struct drsuapi_DsAttributeValue,
540 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
542 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
543 W_ERROR_HAVE_NO_MEMORY(blobs);
545 for (i=0; i < in->num_values; i++) {
549 out->value_ctr.values[i].blob = &blobs[i];
551 blobs[i] = data_blob_talloc(blobs, NULL, 8);
552 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
554 t = ldb_string_utc_to_time((const char *)in->values[i].data);
555 unix_to_nt_time(&v, t);
558 SBVAL(blobs[i].data, 0, v);
564 static WERROR dsdb_syntax_NTTIME_UTC_validate_ldb(struct ldb_context *ldb,
565 const struct dsdb_schema *schema,
566 const struct dsdb_attribute *attr,
567 const struct ldb_message_element *in)
571 if (attr->attributeID_id == 0xFFFFFFFF) {
575 for (i=0; i < in->num_values; i++) {
577 char buf[sizeof("090826075717Z")];
580 if (in->values[i].length >= sizeof(buf)) {
581 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
583 memcpy(buf, in->values[i].data, in->values[i].length);
586 t = ldb_string_utc_to_time(buf);
588 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
591 if (attr->rangeLower) {
592 if ((int32_t)t < (int32_t)*attr->rangeLower) {
593 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
597 if (attr->rangeUpper) {
598 if ((int32_t)t > (int32_t)*attr->rangeLower) {
599 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
604 * TODO: verify the comment in the
605 * dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb() function!
612 static WERROR dsdb_syntax_NTTIME_drsuapi_to_ldb(struct ldb_context *ldb,
613 const struct dsdb_schema *schema,
614 const struct dsdb_attribute *attr,
615 const struct drsuapi_DsReplicaAttribute *in,
617 struct ldb_message_element *out)
622 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
623 W_ERROR_HAVE_NO_MEMORY(out->name);
625 out->num_values = in->value_ctr.num_values;
626 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
627 W_ERROR_HAVE_NO_MEMORY(out->values);
629 for (i=0; i < out->num_values; i++) {
634 if (in->value_ctr.values[i].blob == NULL) {
638 if (in->value_ctr.values[i].blob->length != 8) {
642 v = BVAL(in->value_ctr.values[i].blob->data, 0);
644 t = nt_time_to_unix(v);
646 str = ldb_timestring(out->values, t);
647 W_ERROR_HAVE_NO_MEMORY(str);
649 out->values[i] = data_blob_string_const(str);
655 static WERROR dsdb_syntax_NTTIME_ldb_to_drsuapi(struct ldb_context *ldb,
656 const struct dsdb_schema *schema,
657 const struct dsdb_attribute *attr,
658 const struct ldb_message_element *in,
660 struct drsuapi_DsReplicaAttribute *out)
665 if (attr->attributeID_id == 0xFFFFFFFF) {
669 out->attid = attr->attributeID_id;
670 out->value_ctr.num_values = in->num_values;
671 out->value_ctr.values = talloc_array(mem_ctx,
672 struct drsuapi_DsAttributeValue,
674 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
676 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
677 W_ERROR_HAVE_NO_MEMORY(blobs);
679 for (i=0; i < in->num_values; i++) {
684 out->value_ctr.values[i].blob = &blobs[i];
686 blobs[i] = data_blob_talloc(blobs, NULL, 8);
687 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
689 ret = ldb_val_to_time(&in->values[i], &t);
690 if (ret != LDB_SUCCESS) {
691 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
693 unix_to_nt_time(&v, t);
696 SBVAL(blobs[i].data, 0, v);
702 static WERROR dsdb_syntax_NTTIME_validate_ldb(struct ldb_context *ldb,
703 const struct dsdb_schema *schema,
704 const struct dsdb_attribute *attr,
705 const struct ldb_message_element *in)
709 if (attr->attributeID_id == 0xFFFFFFFF) {
713 for (i=0; i < in->num_values; i++) {
717 ret = ldb_val_to_time(&in->values[i], &t);
718 if (ret != LDB_SUCCESS) {
719 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
722 if (attr->rangeLower) {
723 if ((int32_t)t < (int32_t)*attr->rangeLower) {
724 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
728 if (attr->rangeUpper) {
729 if ((int32_t)t > (int32_t)*attr->rangeLower) {
730 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
738 static WERROR dsdb_syntax_DATA_BLOB_drsuapi_to_ldb(struct ldb_context *ldb,
739 const struct dsdb_schema *schema,
740 const struct dsdb_attribute *attr,
741 const struct drsuapi_DsReplicaAttribute *in,
743 struct ldb_message_element *out)
748 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
749 W_ERROR_HAVE_NO_MEMORY(out->name);
751 out->num_values = in->value_ctr.num_values;
752 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
753 W_ERROR_HAVE_NO_MEMORY(out->values);
755 for (i=0; i < out->num_values; i++) {
756 if (in->value_ctr.values[i].blob == NULL) {
760 if (in->value_ctr.values[i].blob->length == 0) {
764 out->values[i] = data_blob_dup_talloc(out->values,
765 in->value_ctr.values[i].blob);
766 W_ERROR_HAVE_NO_MEMORY(out->values[i].data);
772 static WERROR dsdb_syntax_DATA_BLOB_ldb_to_drsuapi(struct ldb_context *ldb,
773 const struct dsdb_schema *schema,
774 const struct dsdb_attribute *attr,
775 const struct ldb_message_element *in,
777 struct drsuapi_DsReplicaAttribute *out)
782 if (attr->attributeID_id == 0xFFFFFFFF) {
786 out->attid = attr->attributeID_id;
787 out->value_ctr.num_values = in->num_values;
788 out->value_ctr.values = talloc_array(mem_ctx,
789 struct drsuapi_DsAttributeValue,
791 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
793 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
794 W_ERROR_HAVE_NO_MEMORY(blobs);
796 for (i=0; i < in->num_values; i++) {
797 out->value_ctr.values[i].blob = &blobs[i];
799 blobs[i] = data_blob_dup_talloc(blobs, &in->values[i]);
800 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
806 static WERROR dsdb_syntax_DATA_BLOB_validate_one_val(struct ldb_context *ldb,
807 const struct dsdb_schema *schema,
808 const struct dsdb_attribute *attr,
809 const struct ldb_val *val)
811 if (attr->attributeID_id == 0xFFFFFFFF) {
815 if (attr->rangeLower) {
816 if ((uint32_t)val->length < (uint32_t)*attr->rangeLower) {
817 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
821 if (attr->rangeUpper) {
822 if ((uint32_t)val->length > (uint32_t)*attr->rangeUpper) {
823 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
830 static WERROR dsdb_syntax_DATA_BLOB_validate_ldb(struct ldb_context *ldb,
831 const struct dsdb_schema *schema,
832 const struct dsdb_attribute *attr,
833 const struct ldb_message_element *in)
838 if (attr->attributeID_id == 0xFFFFFFFF) {
842 for (i=0; i < in->num_values; i++) {
843 if (in->values[i].length == 0) {
844 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
847 status = dsdb_syntax_DATA_BLOB_validate_one_val(ldb,
851 if (!W_ERROR_IS_OK(status)) {
859 static WERROR _dsdb_syntax_auto_OID_drsuapi_to_ldb(struct ldb_context *ldb,
860 const struct dsdb_schema *schema,
861 const struct dsdb_attribute *attr,
862 const struct drsuapi_DsReplicaAttribute *in,
864 struct ldb_message_element *out)
869 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
870 W_ERROR_HAVE_NO_MEMORY(out->name);
872 out->num_values = in->value_ctr.num_values;
873 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
874 W_ERROR_HAVE_NO_MEMORY(out->values);
876 for (i=0; i < out->num_values; i++) {
878 const struct dsdb_class *c;
879 const struct dsdb_attribute *a;
880 const char *str = NULL;
882 if (in->value_ctr.values[i].blob == NULL) {
886 if (in->value_ctr.values[i].blob->length != 4) {
890 v = IVAL(in->value_ctr.values[i].blob->data, 0);
892 if ((c = dsdb_class_by_governsID_id(schema, v))) {
893 str = talloc_strdup(out->values, c->lDAPDisplayName);
894 } else if ((a = dsdb_attribute_by_attributeID_id(schema, v))) {
895 str = talloc_strdup(out->values, a->lDAPDisplayName);
898 werr = dsdb_schema_pfm_oid_from_attid(schema->prefixmap, v, out->values, &str);
899 W_ERROR_NOT_OK_RETURN(werr);
901 W_ERROR_HAVE_NO_MEMORY(str);
903 /* the values need to be reversed */
904 out->values[out->num_values - (i + 1)] = data_blob_string_const(str);
910 static WERROR _dsdb_syntax_OID_obj_drsuapi_to_ldb(struct ldb_context *ldb,
911 const struct dsdb_schema *schema,
912 const struct dsdb_attribute *attr,
913 const struct drsuapi_DsReplicaAttribute *in,
915 struct ldb_message_element *out)
920 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
921 W_ERROR_HAVE_NO_MEMORY(out->name);
923 out->num_values = in->value_ctr.num_values;
924 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
925 W_ERROR_HAVE_NO_MEMORY(out->values);
927 for (i=0; i < out->num_values; i++) {
929 const struct dsdb_class *c;
932 if (in->value_ctr.values[i].blob == NULL) {
936 if (in->value_ctr.values[i].blob->length != 4) {
940 v = IVAL(in->value_ctr.values[i].blob->data, 0);
942 c = dsdb_class_by_governsID_id(schema, v);
947 str = talloc_strdup(out->values, c->lDAPDisplayName);
948 W_ERROR_HAVE_NO_MEMORY(str);
950 /* the values need to be reversed */
951 out->values[out->num_values - (i + 1)] = data_blob_string_const(str);
957 static WERROR _dsdb_syntax_OID_attr_drsuapi_to_ldb(struct ldb_context *ldb,
958 const struct dsdb_schema *schema,
959 const struct dsdb_attribute *attr,
960 const struct drsuapi_DsReplicaAttribute *in,
962 struct ldb_message_element *out)
967 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
968 W_ERROR_HAVE_NO_MEMORY(out->name);
970 out->num_values = in->value_ctr.num_values;
971 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
972 W_ERROR_HAVE_NO_MEMORY(out->values);
974 for (i=0; i < out->num_values; i++) {
976 const struct dsdb_attribute *a;
979 if (in->value_ctr.values[i].blob == NULL) {
983 if (in->value_ctr.values[i].blob->length != 4) {
987 v = IVAL(in->value_ctr.values[i].blob->data, 0);
989 a = dsdb_attribute_by_attributeID_id(schema, v);
994 str = talloc_strdup(out->values, a->lDAPDisplayName);
995 W_ERROR_HAVE_NO_MEMORY(str);
997 /* the values need to be reversed */
998 out->values[out->num_values - (i + 1)] = data_blob_string_const(str);
1004 static WERROR _dsdb_syntax_OID_oid_drsuapi_to_ldb(struct ldb_context *ldb,
1005 const struct dsdb_schema *schema,
1006 const struct dsdb_attribute *attr,
1007 const struct drsuapi_DsReplicaAttribute *in,
1008 TALLOC_CTX *mem_ctx,
1009 struct ldb_message_element *out)
1014 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1015 W_ERROR_HAVE_NO_MEMORY(out->name);
1017 out->num_values = in->value_ctr.num_values;
1018 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1019 W_ERROR_HAVE_NO_MEMORY(out->values);
1021 for (i=0; i < out->num_values; i++) {
1026 if (in->value_ctr.values[i].blob == NULL) {
1030 if (in->value_ctr.values[i].blob->length != 4) {
1034 attid = IVAL(in->value_ctr.values[i].blob->data, 0);
1036 status = dsdb_schema_pfm_oid_from_attid(schema->prefixmap, attid, out->values, &oid);
1037 W_ERROR_NOT_OK_RETURN(status);
1039 out->values[i] = data_blob_string_const(oid);
1045 static WERROR _dsdb_syntax_auto_OID_ldb_to_drsuapi(struct ldb_context *ldb,
1046 const struct dsdb_schema *schema,
1047 const struct dsdb_attribute *attr,
1048 const struct ldb_message_element *in,
1049 TALLOC_CTX *mem_ctx,
1050 struct drsuapi_DsReplicaAttribute *out)
1055 out->attid= attr->attributeID_id;
1056 out->value_ctr.num_values= in->num_values;
1057 out->value_ctr.values= talloc_array(mem_ctx,
1058 struct drsuapi_DsAttributeValue,
1060 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1062 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1063 W_ERROR_HAVE_NO_MEMORY(blobs);
1065 for (i=0; i < in->num_values; i++) {
1066 const struct dsdb_class *obj_class;
1067 const struct dsdb_attribute *obj_attr;
1070 out->value_ctr.values[i].blob= &blobs[i];
1072 blobs[i] = data_blob_talloc(blobs, NULL, 4);
1073 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
1075 /* in DRS windows puts the classes in the opposite
1076 order to the order used in ldap */
1077 v = &in->values[(in->num_values-1)-i];
1079 if ((obj_class = dsdb_class_by_lDAPDisplayName_ldb_val(schema, v))) {
1080 SIVAL(blobs[i].data, 0, obj_class->governsID_id);
1081 } else if ((obj_attr = dsdb_attribute_by_lDAPDisplayName_ldb_val(schema, v))) {
1082 SIVAL(blobs[i].data, 0, obj_attr->attributeID_id);
1086 werr = dsdb_schema_pfm_make_attid(schema->prefixmap,
1087 (const char *)v->data,
1089 W_ERROR_NOT_OK_RETURN(werr);
1090 SIVAL(blobs[i].data, 0, attid);
1099 static WERROR _dsdb_syntax_OID_obj_ldb_to_drsuapi(struct ldb_context *ldb,
1100 const struct dsdb_schema *schema,
1101 const struct dsdb_attribute *attr,
1102 const struct ldb_message_element *in,
1103 TALLOC_CTX *mem_ctx,
1104 struct drsuapi_DsReplicaAttribute *out)
1109 out->attid= attr->attributeID_id;
1110 out->value_ctr.num_values= in->num_values;
1111 out->value_ctr.values= talloc_array(mem_ctx,
1112 struct drsuapi_DsAttributeValue,
1114 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1116 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1117 W_ERROR_HAVE_NO_MEMORY(blobs);
1119 for (i=0; i < in->num_values; i++) {
1120 const struct dsdb_class *obj_class;
1122 out->value_ctr.values[i].blob= &blobs[i];
1124 blobs[i] = data_blob_talloc(blobs, NULL, 4);
1125 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
1127 /* in DRS windows puts the classes in the opposite
1128 order to the order used in ldap */
1129 obj_class = dsdb_class_by_lDAPDisplayName(schema,
1130 (const char *)in->values[(in->num_values-1)-i].data);
1134 SIVAL(blobs[i].data, 0, obj_class->governsID_id);
1141 static WERROR _dsdb_syntax_OID_attr_ldb_to_drsuapi(struct ldb_context *ldb,
1142 const struct dsdb_schema *schema,
1143 const struct dsdb_attribute *attr,
1144 const struct ldb_message_element *in,
1145 TALLOC_CTX *mem_ctx,
1146 struct drsuapi_DsReplicaAttribute *out)
1151 out->attid= attr->attributeID_id;
1152 out->value_ctr.num_values= in->num_values;
1153 out->value_ctr.values= talloc_array(mem_ctx,
1154 struct drsuapi_DsAttributeValue,
1156 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1158 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1159 W_ERROR_HAVE_NO_MEMORY(blobs);
1161 for (i=0; i < in->num_values; i++) {
1162 const struct dsdb_attribute *obj_attr;
1164 out->value_ctr.values[i].blob= &blobs[i];
1166 blobs[i] = data_blob_talloc(blobs, NULL, 4);
1167 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
1169 obj_attr = dsdb_attribute_by_lDAPDisplayName(schema, (const char *)in->values[i].data);
1173 SIVAL(blobs[i].data, 0, obj_attr->attributeID_id);
1180 static WERROR _dsdb_syntax_OID_oid_ldb_to_drsuapi(struct ldb_context *ldb,
1181 const struct dsdb_schema *schema,
1182 const struct dsdb_attribute *attr,
1183 const struct ldb_message_element *in,
1184 TALLOC_CTX *mem_ctx,
1185 struct drsuapi_DsReplicaAttribute *out)
1190 out->attid= attr->attributeID_id;
1191 out->value_ctr.num_values= in->num_values;
1192 out->value_ctr.values= talloc_array(mem_ctx,
1193 struct drsuapi_DsAttributeValue,
1195 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1197 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1198 W_ERROR_HAVE_NO_MEMORY(blobs);
1200 for (i=0; i < in->num_values; i++) {
1204 out->value_ctr.values[i].blob= &blobs[i];
1206 blobs[i] = data_blob_talloc(blobs, NULL, 4);
1207 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
1209 status = dsdb_schema_pfm_make_attid(schema->prefixmap,
1210 (const char *)in->values[i].data,
1212 W_ERROR_NOT_OK_RETURN(status);
1214 SIVAL(blobs[i].data, 0, attid);
1220 static WERROR dsdb_syntax_OID_drsuapi_to_ldb(struct ldb_context *ldb,
1221 const struct dsdb_schema *schema,
1222 const struct dsdb_attribute *attr,
1223 const struct drsuapi_DsReplicaAttribute *in,
1224 TALLOC_CTX *mem_ctx,
1225 struct ldb_message_element *out)
1229 switch (attr->attributeID_id) {
1230 case DRSUAPI_ATTRIBUTE_objectClass:
1231 case DRSUAPI_ATTRIBUTE_subClassOf:
1232 case DRSUAPI_ATTRIBUTE_auxiliaryClass:
1233 case DRSUAPI_ATTRIBUTE_systemAuxiliaryClass:
1234 case DRSUAPI_ATTRIBUTE_systemPossSuperiors:
1235 case DRSUAPI_ATTRIBUTE_possSuperiors:
1236 werr = _dsdb_syntax_OID_obj_drsuapi_to_ldb(ldb, schema, attr, in, mem_ctx, out);
1238 case DRSUAPI_ATTRIBUTE_systemMustContain:
1239 case DRSUAPI_ATTRIBUTE_systemMayContain:
1240 case DRSUAPI_ATTRIBUTE_mustContain:
1241 case DRSUAPI_ATTRIBUTE_rDNAttId:
1242 case DRSUAPI_ATTRIBUTE_transportAddressAttribute:
1243 case DRSUAPI_ATTRIBUTE_mayContain:
1244 werr = _dsdb_syntax_OID_attr_drsuapi_to_ldb(ldb, schema, attr, in, mem_ctx, out);
1246 case DRSUAPI_ATTRIBUTE_governsID:
1247 case DRSUAPI_ATTRIBUTE_attributeID:
1248 case DRSUAPI_ATTRIBUTE_attributeSyntax:
1249 werr = _dsdb_syntax_OID_oid_drsuapi_to_ldb(ldb, schema, attr, in, mem_ctx, out);
1252 DEBUG(0,(__location__ ": Unknown handling for attributeID_id for %s\n",
1253 attr->lDAPDisplayName));
1254 return _dsdb_syntax_auto_OID_drsuapi_to_ldb(ldb, schema, attr, in, mem_ctx, out);
1257 /* When we are doing the vampire of a schema, we don't want
1258 * the inablity to reference an OID to get in the way.
1259 * Otherwise, we won't get the new schema with which to
1260 * understand this */
1261 if (!W_ERROR_IS_OK(werr) && schema->relax_OID_conversions) {
1262 return _dsdb_syntax_OID_oid_drsuapi_to_ldb(ldb, schema, attr, in, mem_ctx, out);
1267 static WERROR dsdb_syntax_OID_ldb_to_drsuapi(struct ldb_context *ldb,
1268 const struct dsdb_schema *schema,
1269 const struct dsdb_attribute *attr,
1270 const struct ldb_message_element *in,
1271 TALLOC_CTX *mem_ctx,
1272 struct drsuapi_DsReplicaAttribute *out)
1274 if (attr->attributeID_id == 0xFFFFFFFF) {
1278 switch (attr->attributeID_id) {
1279 case DRSUAPI_ATTRIBUTE_objectClass:
1280 case DRSUAPI_ATTRIBUTE_subClassOf:
1281 case DRSUAPI_ATTRIBUTE_auxiliaryClass:
1282 case DRSUAPI_ATTRIBUTE_systemAuxiliaryClass:
1283 case DRSUAPI_ATTRIBUTE_systemPossSuperiors:
1284 case DRSUAPI_ATTRIBUTE_possSuperiors:
1285 return _dsdb_syntax_OID_obj_ldb_to_drsuapi(ldb, schema, attr, in, mem_ctx, out);
1286 case DRSUAPI_ATTRIBUTE_systemMustContain:
1287 case DRSUAPI_ATTRIBUTE_systemMayContain:
1288 case DRSUAPI_ATTRIBUTE_mustContain:
1289 case DRSUAPI_ATTRIBUTE_rDNAttId:
1290 case DRSUAPI_ATTRIBUTE_transportAddressAttribute:
1291 case DRSUAPI_ATTRIBUTE_mayContain:
1292 return _dsdb_syntax_OID_attr_ldb_to_drsuapi(ldb, schema, attr, in, mem_ctx, out);
1293 case DRSUAPI_ATTRIBUTE_governsID:
1294 case DRSUAPI_ATTRIBUTE_attributeID:
1295 case DRSUAPI_ATTRIBUTE_attributeSyntax:
1296 return _dsdb_syntax_OID_oid_ldb_to_drsuapi(ldb, schema, attr, in, mem_ctx, out);
1299 DEBUG(0,(__location__ ": Unknown handling for attributeID_id for %s\n",
1300 attr->lDAPDisplayName));
1302 return _dsdb_syntax_auto_OID_ldb_to_drsuapi(ldb, schema, attr, in, mem_ctx, out);
1305 static WERROR dsdb_syntax_OID_validate_ldb(struct ldb_context *ldb,
1306 const struct dsdb_schema *schema,
1307 const struct dsdb_attribute *attr,
1308 const struct ldb_message_element *in)
1311 struct drsuapi_DsReplicaAttribute drs_tmp;
1312 struct ldb_message_element ldb_tmp;
1313 TALLOC_CTX *tmp_ctx;
1315 if (attr->attributeID_id == 0xFFFFFFFF) {
1320 * TODO: optimize and verify this code
1323 tmp_ctx = talloc_new(ldb);
1324 if (tmp_ctx == NULL) {
1328 status = dsdb_syntax_OID_ldb_to_drsuapi(ldb,
1334 if (!W_ERROR_IS_OK(status)) {
1335 talloc_free(tmp_ctx);
1339 status = dsdb_syntax_OID_drsuapi_to_ldb(ldb,
1345 if (!W_ERROR_IS_OK(status)) {
1346 talloc_free(tmp_ctx);
1350 talloc_free(tmp_ctx);
1354 static WERROR dsdb_syntax_UNICODE_drsuapi_to_ldb(struct ldb_context *ldb,
1355 const struct dsdb_schema *schema,
1356 const struct dsdb_attribute *attr,
1357 const struct drsuapi_DsReplicaAttribute *in,
1358 TALLOC_CTX *mem_ctx,
1359 struct ldb_message_element *out)
1364 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1365 W_ERROR_HAVE_NO_MEMORY(out->name);
1367 out->num_values = in->value_ctr.num_values;
1368 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1369 W_ERROR_HAVE_NO_MEMORY(out->values);
1371 for (i=0; i < out->num_values; i++) {
1374 if (in->value_ctr.values[i].blob == NULL) {
1378 if (in->value_ctr.values[i].blob->length == 0) {
1382 if (!convert_string_talloc(out->values,
1384 in->value_ctr.values[i].blob->data,
1385 in->value_ctr.values[i].blob->length,
1386 (void **)&str, NULL, false)) {
1390 out->values[i] = data_blob_string_const(str);
1396 static WERROR dsdb_syntax_UNICODE_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)
1406 if (attr->attributeID_id == 0xFFFFFFFF) {
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,
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 out->value_ctr.values[i].blob = &blobs[i];
1423 if (!convert_string_talloc(blobs,
1425 in->values[i].data, in->values[i].length,
1426 (void **)&blobs[i].data, &blobs[i].length, false)) {
1434 static WERROR dsdb_syntax_UNICODE_validate_one_val(struct ldb_context *ldb,
1435 const struct dsdb_schema *schema,
1436 const struct dsdb_attribute *attr,
1437 const struct ldb_val *val)
1443 if (attr->attributeID_id == 0xFFFFFFFF) {
1447 ok = convert_string_talloc(ldb,
1455 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1458 if (attr->rangeLower) {
1459 if ((size/2) < *attr->rangeLower) {
1460 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1464 if (attr->rangeUpper) {
1465 if ((size/2) > *attr->rangeUpper) {
1466 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1473 static WERROR dsdb_syntax_UNICODE_validate_ldb(struct ldb_context *ldb,
1474 const struct dsdb_schema *schema,
1475 const struct dsdb_attribute *attr,
1476 const struct ldb_message_element *in)
1481 if (attr->attributeID_id == 0xFFFFFFFF) {
1485 for (i=0; i < in->num_values; i++) {
1486 if (in->values[i].length == 0) {
1487 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1490 status = dsdb_syntax_UNICODE_validate_one_val(ldb,
1494 if (!W_ERROR_IS_OK(status)) {
1502 WERROR dsdb_syntax_one_DN_drsuapi_to_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
1503 const struct dsdb_syntax *syntax,
1504 const DATA_BLOB *in, DATA_BLOB *out)
1506 struct drsuapi_DsReplicaObjectIdentifier3 id3;
1507 enum ndr_err_code ndr_err;
1508 DATA_BLOB guid_blob;
1510 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1515 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1519 talloc_free(tmp_ctx);
1523 if (in->length == 0) {
1524 talloc_free(tmp_ctx);
1529 /* windows sometimes sends an extra two pad bytes here */
1530 ndr_err = ndr_pull_struct_blob(in,
1532 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3);
1533 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1534 status = ndr_map_error2ntstatus(ndr_err);
1535 talloc_free(tmp_ctx);
1536 return ntstatus_to_werror(status);
1539 dn = ldb_dn_new(tmp_ctx, ldb, id3.dn);
1541 talloc_free(tmp_ctx);
1542 /* If this fails, it must be out of memory, as it does not do much parsing */
1543 W_ERROR_HAVE_NO_MEMORY(dn);
1546 if (!GUID_all_zero(&id3.guid)) {
1547 status = GUID_to_ndr_blob(&id3.guid, tmp_ctx, &guid_blob);
1548 if (!NT_STATUS_IS_OK(status)) {
1549 talloc_free(tmp_ctx);
1550 return ntstatus_to_werror(status);
1553 ret = ldb_dn_set_extended_component(dn, "GUID", &guid_blob);
1554 if (ret != LDB_SUCCESS) {
1555 talloc_free(tmp_ctx);
1558 talloc_free(guid_blob.data);
1561 if (id3.__ndr_size_sid) {
1563 ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, &id3.sid,
1564 (ndr_push_flags_fn_t)ndr_push_dom_sid);
1565 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1566 status = ndr_map_error2ntstatus(ndr_err);
1567 talloc_free(tmp_ctx);
1568 return ntstatus_to_werror(status);
1571 ret = ldb_dn_set_extended_component(dn, "SID", &sid_blob);
1572 if (ret != LDB_SUCCESS) {
1573 talloc_free(tmp_ctx);
1578 *out = data_blob_string_const(ldb_dn_get_extended_linearized(mem_ctx, dn, 1));
1579 talloc_free(tmp_ctx);
1583 static WERROR dsdb_syntax_DN_drsuapi_to_ldb(struct ldb_context *ldb,
1584 const struct dsdb_schema *schema,
1585 const struct dsdb_attribute *attr,
1586 const struct drsuapi_DsReplicaAttribute *in,
1587 TALLOC_CTX *mem_ctx,
1588 struct ldb_message_element *out)
1593 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1594 W_ERROR_HAVE_NO_MEMORY(out->name);
1596 out->num_values = in->value_ctr.num_values;
1597 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1598 W_ERROR_HAVE_NO_MEMORY(out->values);
1600 for (i=0; i < out->num_values; i++) {
1601 WERROR status = dsdb_syntax_one_DN_drsuapi_to_ldb(out->values, ldb, attr->syntax,
1602 in->value_ctr.values[i].blob,
1604 if (!W_ERROR_IS_OK(status)) {
1613 static WERROR dsdb_syntax_DN_ldb_to_drsuapi(struct ldb_context *ldb,
1614 const struct dsdb_schema *schema,
1615 const struct dsdb_attribute *attr,
1616 const struct ldb_message_element *in,
1617 TALLOC_CTX *mem_ctx,
1618 struct drsuapi_DsReplicaAttribute *out)
1623 if (attr->attributeID_id == 0xFFFFFFFF) {
1627 out->attid = attr->attributeID_id;
1628 out->value_ctr.num_values = in->num_values;
1629 out->value_ctr.values = talloc_array(mem_ctx,
1630 struct drsuapi_DsAttributeValue,
1632 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1634 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1635 W_ERROR_HAVE_NO_MEMORY(blobs);
1637 for (i=0; i < in->num_values; i++) {
1638 struct drsuapi_DsReplicaObjectIdentifier3 id3;
1639 enum ndr_err_code ndr_err;
1641 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1644 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1646 out->value_ctr.values[i].blob = &blobs[i];
1648 dn = ldb_dn_from_ldb_val(tmp_ctx, ldb, &in->values[i]);
1650 W_ERROR_HAVE_NO_MEMORY(dn);
1654 status = dsdb_get_extended_dn_guid(dn, &id3.guid, "GUID");
1655 if (!NT_STATUS_IS_OK(status) &&
1656 !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1657 talloc_free(tmp_ctx);
1658 return ntstatus_to_werror(status);
1661 status = dsdb_get_extended_dn_sid(dn, &id3.sid, "SID");
1662 if (!NT_STATUS_IS_OK(status) &&
1663 !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1664 talloc_free(tmp_ctx);
1665 return ntstatus_to_werror(status);
1668 id3.dn = ldb_dn_get_linearized(dn);
1670 ndr_err = ndr_push_struct_blob(&blobs[i], blobs, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
1671 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1672 status = ndr_map_error2ntstatus(ndr_err);
1673 talloc_free(tmp_ctx);
1674 return ntstatus_to_werror(status);
1676 talloc_free(tmp_ctx);
1682 static WERROR dsdb_syntax_DN_validate_one_val(struct ldb_context *ldb,
1683 const struct dsdb_schema *schema,
1684 const struct dsdb_attribute *attr,
1685 const struct ldb_val *val,
1686 TALLOC_CTX *mem_ctx,
1687 struct dsdb_dn **_dsdb_dn)
1689 static const char * const extended_list[] = { "GUID", "SID", NULL };
1690 enum ndr_err_code ndr_err;
1693 const DATA_BLOB *sid_blob;
1694 struct dsdb_dn *dsdb_dn;
1700 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1703 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1705 if (attr->attributeID_id == 0xFFFFFFFF) {
1709 dsdb_dn = dsdb_dn_parse(tmp_ctx, ldb, val,
1710 attr->syntax->ldap_oid);
1712 talloc_free(tmp_ctx);
1713 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1717 dn2 = ldb_dn_copy(tmp_ctx, dn);
1719 talloc_free(tmp_ctx);
1723 num_components = ldb_dn_get_comp_num(dn);
1725 status = dsdb_get_extended_dn_guid(dn, &guid, "GUID");
1726 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1728 } else if (!NT_STATUS_IS_OK(status)) {
1729 talloc_free(tmp_ctx);
1730 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1733 sid_blob = ldb_dn_get_extended_component(dn, "SID");
1736 ndr_err = ndr_pull_struct_blob_all(sid_blob,
1739 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1740 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1741 talloc_free(tmp_ctx);
1742 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1746 /* Do not allow links to the RootDSE */
1747 if (num_components == 0) {
1748 talloc_free(tmp_ctx);
1749 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1753 * We need to check that only "GUID" and "SID" are
1754 * specified as extended components, we do that
1755 * by comparing the dn's after removing all components
1756 * from one dn and only the allowed subset from the other
1759 ldb_dn_extended_filter(dn, extended_list);
1761 dn_str = ldb_dn_get_extended_linearized(tmp_ctx, dn, 0);
1762 if (dn_str == NULL) {
1763 talloc_free(tmp_ctx);
1764 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1766 dn2_str = ldb_dn_get_extended_linearized(tmp_ctx, dn2, 0);
1767 if (dn2_str == NULL) {
1768 talloc_free(tmp_ctx);
1769 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1772 if (strcmp(dn_str, dn2_str) != 0) {
1773 talloc_free(tmp_ctx);
1774 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1777 *_dsdb_dn = talloc_move(mem_ctx, &dsdb_dn);
1778 talloc_free(tmp_ctx);
1782 static WERROR dsdb_syntax_DN_validate_ldb(struct ldb_context *ldb,
1783 const struct dsdb_schema *schema,
1784 const struct dsdb_attribute *attr,
1785 const struct ldb_message_element *in)
1789 if (attr->attributeID_id == 0xFFFFFFFF) {
1793 for (i=0; i < in->num_values; i++) {
1795 struct dsdb_dn *dsdb_dn;
1796 TALLOC_CTX *tmp_ctx = talloc_new(ldb);
1797 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1799 status = dsdb_syntax_DN_validate_one_val(ldb,
1804 if (!W_ERROR_IS_OK(status)) {
1805 talloc_free(tmp_ctx);
1809 if (dsdb_dn->dn_format != DSDB_NORMAL_DN) {
1810 talloc_free(tmp_ctx);
1811 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1814 talloc_free(tmp_ctx);
1820 static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(struct ldb_context *ldb,
1821 const struct dsdb_schema *schema,
1822 const struct dsdb_attribute *attr,
1823 const struct drsuapi_DsReplicaAttribute *in,
1824 TALLOC_CTX *mem_ctx,
1825 struct ldb_message_element *out)
1831 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1832 W_ERROR_HAVE_NO_MEMORY(out->name);
1834 out->num_values = in->value_ctr.num_values;
1835 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1836 W_ERROR_HAVE_NO_MEMORY(out->values);
1838 for (i=0; i < out->num_values; i++) {
1839 struct drsuapi_DsReplicaObjectIdentifier3Binary id3;
1840 enum ndr_err_code ndr_err;
1841 DATA_BLOB guid_blob;
1843 struct dsdb_dn *dsdb_dn;
1845 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1847 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1850 if (in->value_ctr.values[i].blob == NULL) {
1851 talloc_free(tmp_ctx);
1855 if (in->value_ctr.values[i].blob->length == 0) {
1856 talloc_free(tmp_ctx);
1861 /* windows sometimes sends an extra two pad bytes here */
1862 ndr_err = ndr_pull_struct_blob(in->value_ctr.values[i].blob,
1864 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary);
1865 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1866 status = ndr_map_error2ntstatus(ndr_err);
1867 talloc_free(tmp_ctx);
1868 return ntstatus_to_werror(status);
1871 dn = ldb_dn_new(tmp_ctx, ldb, id3.dn);
1873 talloc_free(tmp_ctx);
1874 /* If this fails, it must be out of memory, as it does not do much parsing */
1875 W_ERROR_HAVE_NO_MEMORY(dn);
1878 status = GUID_to_ndr_blob(&id3.guid, tmp_ctx, &guid_blob);
1879 if (!NT_STATUS_IS_OK(status)) {
1880 talloc_free(tmp_ctx);
1881 return ntstatus_to_werror(status);
1884 ret = ldb_dn_set_extended_component(dn, "GUID", &guid_blob);
1885 if (ret != LDB_SUCCESS) {
1886 talloc_free(tmp_ctx);
1890 talloc_free(guid_blob.data);
1892 if (id3.__ndr_size_sid) {
1894 ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, &id3.sid,
1895 (ndr_push_flags_fn_t)ndr_push_dom_sid);
1896 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1897 status = ndr_map_error2ntstatus(ndr_err);
1898 talloc_free(tmp_ctx);
1899 return ntstatus_to_werror(status);
1902 ret = ldb_dn_set_extended_component(dn, "SID", &sid_blob);
1903 if (ret != LDB_SUCCESS) {
1904 talloc_free(tmp_ctx);
1909 /* set binary stuff */
1910 dsdb_dn = dsdb_dn_construct(tmp_ctx, dn, id3.binary, attr->syntax->ldap_oid);
1912 /* If this fails, it must be out of memory, we know the ldap_oid is valid */
1913 talloc_free(tmp_ctx);
1914 W_ERROR_HAVE_NO_MEMORY(dsdb_dn);
1916 out->values[i] = data_blob_string_const(dsdb_dn_get_extended_linearized(out->values, dsdb_dn, 1));
1917 talloc_free(tmp_ctx);
1923 static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(struct ldb_context *ldb,
1924 const struct dsdb_schema *schema,
1925 const struct dsdb_attribute *attr,
1926 const struct ldb_message_element *in,
1927 TALLOC_CTX *mem_ctx,
1928 struct drsuapi_DsReplicaAttribute *out)
1933 if (attr->attributeID_id == 0xFFFFFFFF) {
1937 out->attid = attr->attributeID_id;
1938 out->value_ctr.num_values = in->num_values;
1939 out->value_ctr.values = talloc_array(mem_ctx,
1940 struct drsuapi_DsAttributeValue,
1942 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1944 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1945 W_ERROR_HAVE_NO_MEMORY(blobs);
1947 for (i=0; i < in->num_values; i++) {
1948 struct drsuapi_DsReplicaObjectIdentifier3Binary id3;
1949 enum ndr_err_code ndr_err;
1950 const DATA_BLOB *sid_blob;
1951 struct dsdb_dn *dsdb_dn;
1952 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1955 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1957 out->value_ctr.values[i].blob = &blobs[i];
1959 dsdb_dn = dsdb_dn_parse(tmp_ctx, ldb, &in->values[i], attr->syntax->ldap_oid);
1962 talloc_free(tmp_ctx);
1963 return ntstatus_to_werror(NT_STATUS_INVALID_PARAMETER);
1968 status = dsdb_get_extended_dn_guid(dsdb_dn->dn, &id3.guid, "GUID");
1969 if (!NT_STATUS_IS_OK(status) &&
1970 !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1971 talloc_free(tmp_ctx);
1972 return ntstatus_to_werror(status);
1975 sid_blob = ldb_dn_get_extended_component(dsdb_dn->dn, "SID");
1978 ndr_err = ndr_pull_struct_blob_all(sid_blob,
1980 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1981 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1982 status = ndr_map_error2ntstatus(ndr_err);
1983 talloc_free(tmp_ctx);
1984 return ntstatus_to_werror(status);
1988 id3.dn = ldb_dn_get_linearized(dsdb_dn->dn);
1990 /* get binary stuff */
1991 id3.binary = dsdb_dn->extra_part;
1993 ndr_err = ndr_push_struct_blob(&blobs[i], blobs, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary);
1994 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1995 status = ndr_map_error2ntstatus(ndr_err);
1996 talloc_free(tmp_ctx);
1997 return ntstatus_to_werror(status);
1999 talloc_free(tmp_ctx);
2005 static WERROR dsdb_syntax_DN_BINARY_validate_ldb(struct ldb_context *ldb,
2006 const struct dsdb_schema *schema,
2007 const struct dsdb_attribute *attr,
2008 const struct ldb_message_element *in)
2012 if (attr->attributeID_id == 0xFFFFFFFF) {
2016 for (i=0; i < in->num_values; i++) {
2018 struct dsdb_dn *dsdb_dn;
2019 TALLOC_CTX *tmp_ctx = talloc_new(ldb);
2020 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
2022 status = dsdb_syntax_DN_validate_one_val(ldb,
2027 if (!W_ERROR_IS_OK(status)) {
2028 talloc_free(tmp_ctx);
2032 if (dsdb_dn->dn_format != DSDB_BINARY_DN) {
2033 talloc_free(tmp_ctx);
2034 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
2037 status = dsdb_syntax_DATA_BLOB_validate_one_val(ldb,
2040 &dsdb_dn->extra_part);
2041 if (!W_ERROR_IS_OK(status)) {
2042 talloc_free(tmp_ctx);
2046 talloc_free(tmp_ctx);
2052 static WERROR dsdb_syntax_DN_STRING_drsuapi_to_ldb(struct ldb_context *ldb,
2053 const struct dsdb_schema *schema,
2054 const struct dsdb_attribute *attr,
2055 const struct drsuapi_DsReplicaAttribute *in,
2056 TALLOC_CTX *mem_ctx,
2057 struct ldb_message_element *out)
2059 return dsdb_syntax_DN_BINARY_drsuapi_to_ldb(ldb,
2067 static WERROR dsdb_syntax_DN_STRING_ldb_to_drsuapi(struct ldb_context *ldb,
2068 const struct dsdb_schema *schema,
2069 const struct dsdb_attribute *attr,
2070 const struct ldb_message_element *in,
2071 TALLOC_CTX *mem_ctx,
2072 struct drsuapi_DsReplicaAttribute *out)
2074 return dsdb_syntax_DN_BINARY_ldb_to_drsuapi(ldb,
2082 static WERROR dsdb_syntax_DN_STRING_validate_ldb(struct ldb_context *ldb,
2083 const struct dsdb_schema *schema,
2084 const struct dsdb_attribute *attr,
2085 const struct ldb_message_element *in)
2089 if (attr->attributeID_id == 0xFFFFFFFF) {
2093 for (i=0; i < in->num_values; i++) {
2095 struct dsdb_dn *dsdb_dn;
2096 TALLOC_CTX *tmp_ctx = talloc_new(ldb);
2097 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
2099 status = dsdb_syntax_DN_validate_one_val(ldb,
2104 if (!W_ERROR_IS_OK(status)) {
2105 talloc_free(tmp_ctx);
2109 if (dsdb_dn->dn_format != DSDB_STRING_DN) {
2110 talloc_free(tmp_ctx);
2111 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
2114 status = dsdb_syntax_UNICODE_validate_one_val(ldb,
2117 &dsdb_dn->extra_part);
2118 if (!W_ERROR_IS_OK(status)) {
2119 talloc_free(tmp_ctx);
2123 talloc_free(tmp_ctx);
2129 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb(struct ldb_context *ldb,
2130 const struct dsdb_schema *schema,
2131 const struct dsdb_attribute *attr,
2132 const struct drsuapi_DsReplicaAttribute *in,
2133 TALLOC_CTX *mem_ctx,
2134 struct ldb_message_element *out)
2139 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
2140 W_ERROR_HAVE_NO_MEMORY(out->name);
2142 out->num_values = in->value_ctr.num_values;
2143 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
2144 W_ERROR_HAVE_NO_MEMORY(out->values);
2146 for (i=0; i < out->num_values; i++) {
2150 if (in->value_ctr.values[i].blob == NULL) {
2154 if (in->value_ctr.values[i].blob->length < 4) {
2158 len = IVAL(in->value_ctr.values[i].blob->data, 0);
2160 if (len != in->value_ctr.values[i].blob->length) {
2164 if (!convert_string_talloc(out->values, CH_UTF16, CH_UNIX,
2165 in->value_ctr.values[i].blob->data+4,
2166 in->value_ctr.values[i].blob->length-4,
2167 (void **)&str, NULL, false)) {
2171 out->values[i] = data_blob_string_const(str);
2177 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi(struct ldb_context *ldb,
2178 const struct dsdb_schema *schema,
2179 const struct dsdb_attribute *attr,
2180 const struct ldb_message_element *in,
2181 TALLOC_CTX *mem_ctx,
2182 struct drsuapi_DsReplicaAttribute *out)
2187 if (attr->attributeID_id == 0xFFFFFFFF) {
2191 out->attid = attr->attributeID_id;
2192 out->value_ctr.num_values = in->num_values;
2193 out->value_ctr.values = talloc_array(mem_ctx,
2194 struct drsuapi_DsAttributeValue,
2196 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
2198 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
2199 W_ERROR_HAVE_NO_MEMORY(blobs);
2201 for (i=0; i < in->num_values; i++) {
2205 out->value_ctr.values[i].blob = &blobs[i];
2207 if (!convert_string_talloc(blobs, CH_UNIX, CH_UTF16,
2209 in->values[i].length,
2210 (void **)&data, &ret, false)) {
2214 blobs[i] = data_blob_talloc(blobs, NULL, 4 + ret);
2215 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
2217 SIVAL(blobs[i].data, 0, 4 + ret);
2220 memcpy(blobs[i].data + 4, data, ret);
2228 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_validate_ldb(struct ldb_context *ldb,
2229 const struct dsdb_schema *schema,
2230 const struct dsdb_attribute *attr,
2231 const struct ldb_message_element *in)
2233 return dsdb_syntax_UNICODE_validate_ldb(ldb,
2239 #define OMOBJECTCLASS(val) { .length = sizeof(val) - 1, .data = discard_const_p(uint8_t, val) }
2241 static const struct dsdb_syntax dsdb_syntaxes[] = {
2244 .ldap_oid = LDB_SYNTAX_BOOLEAN,
2246 .attributeSyntax_oid = "2.5.5.8",
2247 .drsuapi_to_ldb = dsdb_syntax_BOOL_drsuapi_to_ldb,
2248 .ldb_to_drsuapi = dsdb_syntax_BOOL_ldb_to_drsuapi,
2249 .validate_ldb = dsdb_syntax_BOOL_validate_ldb,
2250 .equality = "booleanMatch",
2251 .comment = "Boolean"
2254 .ldap_oid = LDB_SYNTAX_INTEGER,
2256 .attributeSyntax_oid = "2.5.5.9",
2257 .drsuapi_to_ldb = dsdb_syntax_INT32_drsuapi_to_ldb,
2258 .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi,
2259 .validate_ldb = dsdb_syntax_INT32_validate_ldb,
2260 .equality = "integerMatch",
2261 .comment = "Integer",
2262 .ldb_syntax = LDB_SYNTAX_SAMBA_INT32
2264 .name = "String(Octet)",
2265 .ldap_oid = LDB_SYNTAX_OCTET_STRING,
2267 .attributeSyntax_oid = "2.5.5.10",
2268 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
2269 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
2270 .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb,
2271 .equality = "octetStringMatch",
2272 .comment = "Octet String",
2274 .name = "String(Sid)",
2275 .ldap_oid = LDB_SYNTAX_OCTET_STRING,
2277 .attributeSyntax_oid = "2.5.5.17",
2278 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
2279 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
2280 .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb,
2281 .equality = "octetStringMatch",
2282 .comment = "Octet String - Security Identifier (SID)",
2283 .ldb_syntax = LDB_SYNTAX_SAMBA_SID
2285 .name = "String(Object-Identifier)",
2286 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.38",
2288 .attributeSyntax_oid = "2.5.5.2",
2289 .drsuapi_to_ldb = dsdb_syntax_OID_drsuapi_to_ldb,
2290 .ldb_to_drsuapi = dsdb_syntax_OID_ldb_to_drsuapi,
2291 .validate_ldb = dsdb_syntax_OID_validate_ldb,
2292 .equality = "caseIgnoreMatch", /* Would use "objectIdentifierMatch" but most are ldap attribute/class names */
2293 .comment = "OID String",
2294 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING
2296 .name = "Enumeration",
2297 .ldap_oid = LDB_SYNTAX_INTEGER,
2299 .attributeSyntax_oid = "2.5.5.9",
2300 .drsuapi_to_ldb = dsdb_syntax_INT32_drsuapi_to_ldb,
2301 .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi,
2302 .validate_ldb = dsdb_syntax_INT32_validate_ldb,
2303 .ldb_syntax = LDB_SYNTAX_SAMBA_INT32
2305 /* not used in w2k3 forest */
2306 .name = "String(Numeric)",
2307 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.36",
2309 .attributeSyntax_oid = "2.5.5.6",
2310 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
2311 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
2312 .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb,
2313 .equality = "numericStringMatch",
2314 .substring = "numericStringSubstringsMatch",
2315 .comment = "Numeric String",
2316 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING,
2318 .name = "String(Printable)",
2319 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.44",
2321 .attributeSyntax_oid = "2.5.5.5",
2322 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
2323 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
2324 .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb,
2325 .ldb_syntax = LDB_SYNTAX_OCTET_STRING,
2327 .name = "String(Teletex)",
2328 .ldap_oid = "1.2.840.113556.1.4.905",
2330 .attributeSyntax_oid = "2.5.5.4",
2331 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
2332 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
2333 .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb,
2334 .equality = "caseIgnoreMatch",
2335 .substring = "caseIgnoreSubstringsMatch",
2336 .comment = "Case Insensitive String",
2337 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING,
2339 .name = "String(IA5)",
2340 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.26",
2342 .attributeSyntax_oid = "2.5.5.5",
2343 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
2344 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
2345 .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb,
2346 .equality = "caseExactIA5Match",
2347 .comment = "Printable String",
2348 .ldb_syntax = LDB_SYNTAX_OCTET_STRING,
2350 .name = "String(UTC-Time)",
2351 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.53",
2353 .attributeSyntax_oid = "2.5.5.11",
2354 .drsuapi_to_ldb = dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb,
2355 .ldb_to_drsuapi = dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi,
2356 .validate_ldb = dsdb_syntax_NTTIME_UTC_validate_ldb,
2357 .equality = "generalizedTimeMatch",
2358 .comment = "UTC Time",
2360 .name = "String(Generalized-Time)",
2361 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.24",
2363 .attributeSyntax_oid = "2.5.5.11",
2364 .drsuapi_to_ldb = dsdb_syntax_NTTIME_drsuapi_to_ldb,
2365 .ldb_to_drsuapi = dsdb_syntax_NTTIME_ldb_to_drsuapi,
2366 .validate_ldb = dsdb_syntax_NTTIME_validate_ldb,
2367 .equality = "generalizedTimeMatch",
2368 .comment = "Generalized Time",
2369 .ldb_syntax = LDB_SYNTAX_UTC_TIME,
2371 /* not used in w2k3 schema */
2372 .name = "String(Case Sensitive)",
2373 .ldap_oid = "1.2.840.113556.1.4.1362",
2375 .attributeSyntax_oid = "2.5.5.3",
2376 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
2377 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
2378 .validate_ldb = dsdb_syntax_FOOBAR_validate_ldb,
2380 .name = "String(Unicode)",
2381 .ldap_oid = LDB_SYNTAX_DIRECTORY_STRING,
2383 .attributeSyntax_oid = "2.5.5.12",
2384 .drsuapi_to_ldb = dsdb_syntax_UNICODE_drsuapi_to_ldb,
2385 .ldb_to_drsuapi = dsdb_syntax_UNICODE_ldb_to_drsuapi,
2386 .validate_ldb = dsdb_syntax_UNICODE_validate_ldb,
2387 .equality = "caseIgnoreMatch",
2388 .substring = "caseIgnoreSubstringsMatch",
2389 .comment = "Directory String",
2391 .name = "Interval/LargeInteger",
2392 .ldap_oid = "1.2.840.113556.1.4.906",
2394 .attributeSyntax_oid = "2.5.5.16",
2395 .drsuapi_to_ldb = dsdb_syntax_INT64_drsuapi_to_ldb,
2396 .ldb_to_drsuapi = dsdb_syntax_INT64_ldb_to_drsuapi,
2397 .validate_ldb = dsdb_syntax_INT64_validate_ldb,
2398 .equality = "integerMatch",
2399 .comment = "Large Integer",
2400 .ldb_syntax = LDB_SYNTAX_INTEGER,
2402 .name = "String(NT-Sec-Desc)",
2403 .ldap_oid = LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR,
2405 .attributeSyntax_oid = "2.5.5.15",
2406 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
2407 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
2408 .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb,
2410 .name = "Object(DS-DN)",
2411 .ldap_oid = LDB_SYNTAX_DN,
2413 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x4a"),
2414 .attributeSyntax_oid = "2.5.5.1",
2415 .drsuapi_to_ldb = dsdb_syntax_DN_drsuapi_to_ldb,
2416 .ldb_to_drsuapi = dsdb_syntax_DN_ldb_to_drsuapi,
2417 .validate_ldb = dsdb_syntax_DN_validate_ldb,
2418 .equality = "distinguishedNameMatch",
2419 .comment = "Object(DS-DN) == a DN",
2421 .name = "Object(DN-Binary)",
2422 .ldap_oid = DSDB_SYNTAX_BINARY_DN,
2424 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0b"),
2425 .attributeSyntax_oid = "2.5.5.7",
2426 .drsuapi_to_ldb = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
2427 .ldb_to_drsuapi = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
2428 .validate_ldb = dsdb_syntax_DN_BINARY_validate_ldb,
2429 .equality = "octetStringMatch",
2430 .comment = "OctetString: Binary+DN",
2432 /* not used in w2k3 schema, but used in Exchange schema*/
2433 .name = "Object(OR-Name)",
2434 .ldap_oid = DSDB_SYNTAX_OR_NAME,
2436 .oMObjectClass = OMOBJECTCLASS("\x56\x06\x01\x02\x05\x0b\x1D"),
2437 .attributeSyntax_oid = "2.5.5.7",
2438 .drsuapi_to_ldb = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
2439 .ldb_to_drsuapi = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
2440 .validate_ldb = dsdb_syntax_DN_BINARY_validate_ldb,
2441 .equality = "caseIgnoreMatch",
2442 .ldb_syntax = LDB_SYNTAX_DN,
2445 * TODO: verify if DATA_BLOB is correct here...!
2447 * repsFrom and repsTo are the only attributes using
2448 * this attribute syntax, but they're not replicated...
2450 .name = "Object(Replica-Link)",
2451 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.40",
2453 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x06"),
2454 .attributeSyntax_oid = "2.5.5.10",
2455 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
2456 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
2457 .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb,
2459 .name = "Object(Presentation-Address)",
2460 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.43",
2462 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x5c"),
2463 .attributeSyntax_oid = "2.5.5.13",
2464 .drsuapi_to_ldb = dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb,
2465 .ldb_to_drsuapi = dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi,
2466 .validate_ldb = dsdb_syntax_PRESENTATION_ADDRESS_validate_ldb,
2467 .comment = "Presentation Address",
2468 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING,
2470 /* not used in w2k3 schema */
2471 .name = "Object(Access-Point)",
2472 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.2",
2474 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x3e"),
2475 .attributeSyntax_oid = "2.5.5.14",
2476 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
2477 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
2478 .validate_ldb = dsdb_syntax_FOOBAR_validate_ldb,
2479 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING,
2481 /* not used in w2k3 schema */
2482 .name = "Object(DN-String)",
2483 .ldap_oid = DSDB_SYNTAX_STRING_DN,
2485 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0c"),
2486 .attributeSyntax_oid = "2.5.5.14",
2487 .drsuapi_to_ldb = dsdb_syntax_DN_STRING_drsuapi_to_ldb,
2488 .ldb_to_drsuapi = dsdb_syntax_DN_STRING_ldb_to_drsuapi,
2489 .validate_ldb = dsdb_syntax_DN_STRING_validate_ldb,
2490 .equality = "octetStringMatch",
2491 .comment = "OctetString: String+DN",
2495 const struct dsdb_syntax *find_syntax_map_by_ad_oid(const char *ad_oid)
2498 for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
2499 if (strcasecmp(ad_oid, dsdb_syntaxes[i].attributeSyntax_oid) == 0) {
2500 return &dsdb_syntaxes[i];
2506 const struct dsdb_syntax *find_syntax_map_by_ad_syntax(int oMSyntax)
2509 for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
2510 if (oMSyntax == dsdb_syntaxes[i].oMSyntax) {
2511 return &dsdb_syntaxes[i];
2517 const struct dsdb_syntax *find_syntax_map_by_standard_oid(const char *standard_oid)
2520 for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
2521 if (strcasecmp(standard_oid, dsdb_syntaxes[i].ldap_oid) == 0) {
2522 return &dsdb_syntaxes[i];
2527 const struct dsdb_syntax *dsdb_syntax_for_attribute(const struct dsdb_attribute *attr)
2531 for (i=0; i < ARRAY_SIZE(dsdb_syntaxes); i++) {
2532 if (attr->oMSyntax != dsdb_syntaxes[i].oMSyntax) continue;
2534 if (attr->oMObjectClass.length != dsdb_syntaxes[i].oMObjectClass.length) continue;
2536 if (attr->oMObjectClass.length) {
2538 ret = memcmp(attr->oMObjectClass.data,
2539 dsdb_syntaxes[i].oMObjectClass.data,
2540 attr->oMObjectClass.length);
2541 if (ret != 0) continue;
2544 if (strcmp(attr->attributeSyntax_oid, dsdb_syntaxes[i].attributeSyntax_oid) != 0) continue;
2546 return &dsdb_syntaxes[i];
2552 WERROR dsdb_attribute_drsuapi_to_ldb(struct ldb_context *ldb,
2553 const struct dsdb_schema *schema,
2554 const struct drsuapi_DsReplicaAttribute *in,
2555 TALLOC_CTX *mem_ctx,
2556 struct ldb_message_element *out)
2558 const struct dsdb_attribute *sa;
2560 sa = dsdb_attribute_by_attributeID_id(schema, in->attid);
2565 return sa->syntax->drsuapi_to_ldb(ldb, schema, sa, in, mem_ctx, out);
2568 WERROR dsdb_attribute_ldb_to_drsuapi(struct ldb_context *ldb,
2569 const struct dsdb_schema *schema,
2570 const struct ldb_message_element *in,
2571 TALLOC_CTX *mem_ctx,
2572 struct drsuapi_DsReplicaAttribute *out)
2574 const struct dsdb_attribute *sa;
2576 sa = dsdb_attribute_by_lDAPDisplayName(schema, in->name);
2581 return sa->syntax->ldb_to_drsuapi(ldb, schema, sa, in, mem_ctx, out);