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"
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,
39 struct ldb_message_element *out)
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++) {
54 if (in->value_ctr.values[i].blob == NULL) {
58 str = talloc_asprintf(out->values, "%s: not implemented",
60 W_ERROR_HAVE_NO_MEMORY(str);
62 out->values[i] = data_blob_string_const(str);
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,
73 struct drsuapi_DsReplicaAttribute *out)
78 static WERROR dsdb_syntax_BOOL_drsuapi_to_ldb(struct ldb_context *ldb,
79 const struct dsdb_schema *schema,
80 const struct dsdb_attribute *attr,
81 const struct drsuapi_DsReplicaAttribute *in,
83 struct ldb_message_element *out)
88 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
89 W_ERROR_HAVE_NO_MEMORY(out->name);
91 out->num_values = in->value_ctr.num_values;
92 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
93 W_ERROR_HAVE_NO_MEMORY(out->values);
95 for (i=0; i < out->num_values; i++) {
99 if (in->value_ctr.values[i].blob == NULL) {
103 if (in->value_ctr.values[i].blob->length != 4) {
107 v = IVAL(in->value_ctr.values[i].blob->data, 0);
110 str = talloc_strdup(out->values, "TRUE");
111 W_ERROR_HAVE_NO_MEMORY(str);
113 str = talloc_strdup(out->values, "FALSE");
114 W_ERROR_HAVE_NO_MEMORY(str);
117 out->values[i] = data_blob_string_const(str);
123 static WERROR dsdb_syntax_BOOL_ldb_to_drsuapi(struct ldb_context *ldb,
124 const struct dsdb_schema *schema,
125 const struct dsdb_attribute *attr,
126 const struct ldb_message_element *in,
128 struct drsuapi_DsReplicaAttribute *out)
133 if (attr->attributeID_id == 0xFFFFFFFF) {
137 out->attid = attr->attributeID_id;
138 out->value_ctr.num_values = in->num_values;
139 out->value_ctr.values = talloc_array(mem_ctx,
140 struct drsuapi_DsAttributeValue,
142 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
144 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
145 W_ERROR_HAVE_NO_MEMORY(blobs);
147 for (i=0; i < in->num_values; i++) {
148 out->value_ctr.values[i].blob = &blobs[i];
150 blobs[i] = data_blob_talloc(blobs, NULL, 4);
151 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
153 if (strcmp("TRUE", (const char *)in->values[i].data) == 0) {
154 SIVAL(blobs[i].data, 0, 0x00000001);
155 } else if (strcmp("FALSE", (const char *)in->values[i].data) == 0) {
156 SIVAL(blobs[i].data, 0, 0x00000000);
165 static WERROR dsdb_syntax_INT32_drsuapi_to_ldb(struct ldb_context *ldb,
166 const struct dsdb_schema *schema,
167 const struct dsdb_attribute *attr,
168 const struct drsuapi_DsReplicaAttribute *in,
170 struct ldb_message_element *out)
175 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
176 W_ERROR_HAVE_NO_MEMORY(out->name);
178 out->num_values = in->value_ctr.num_values;
179 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
180 W_ERROR_HAVE_NO_MEMORY(out->values);
182 for (i=0; i < out->num_values; i++) {
186 if (in->value_ctr.values[i].blob == NULL) {
190 if (in->value_ctr.values[i].blob->length != 4) {
194 v = IVALS(in->value_ctr.values[i].blob->data, 0);
196 str = talloc_asprintf(out->values, "%d", v);
197 W_ERROR_HAVE_NO_MEMORY(str);
199 out->values[i] = data_blob_string_const(str);
205 static WERROR dsdb_syntax_INT32_ldb_to_drsuapi(struct ldb_context *ldb,
206 const struct dsdb_schema *schema,
207 const struct dsdb_attribute *attr,
208 const struct ldb_message_element *in,
210 struct drsuapi_DsReplicaAttribute *out)
215 if (attr->attributeID_id == 0xFFFFFFFF) {
219 out->attid = attr->attributeID_id;
220 out->value_ctr.num_values = in->num_values;
221 out->value_ctr.values = talloc_array(mem_ctx,
222 struct drsuapi_DsAttributeValue,
224 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
226 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
227 W_ERROR_HAVE_NO_MEMORY(blobs);
229 for (i=0; i < in->num_values; i++) {
232 out->value_ctr.values[i].blob = &blobs[i];
234 blobs[i] = data_blob_talloc(blobs, NULL, 4);
235 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
237 v = strtol((const char *)in->values[i].data, NULL, 10);
239 SIVALS(blobs[i].data, 0, v);
245 static WERROR dsdb_syntax_INT64_drsuapi_to_ldb(struct ldb_context *ldb,
246 const struct dsdb_schema *schema,
247 const struct dsdb_attribute *attr,
248 const struct drsuapi_DsReplicaAttribute *in,
250 struct ldb_message_element *out)
255 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
256 W_ERROR_HAVE_NO_MEMORY(out->name);
258 out->num_values = in->value_ctr.num_values;
259 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
260 W_ERROR_HAVE_NO_MEMORY(out->values);
262 for (i=0; i < out->num_values; i++) {
266 if (in->value_ctr.values[i].blob == NULL) {
270 if (in->value_ctr.values[i].blob->length != 8) {
274 v = BVALS(in->value_ctr.values[i].blob->data, 0);
276 str = talloc_asprintf(out->values, "%lld", (long long int)v);
277 W_ERROR_HAVE_NO_MEMORY(str);
279 out->values[i] = data_blob_string_const(str);
285 static WERROR dsdb_syntax_INT64_ldb_to_drsuapi(struct ldb_context *ldb,
286 const struct dsdb_schema *schema,
287 const struct dsdb_attribute *attr,
288 const struct ldb_message_element *in,
290 struct drsuapi_DsReplicaAttribute *out)
295 if (attr->attributeID_id == 0xFFFFFFFF) {
299 out->attid = attr->attributeID_id;
300 out->value_ctr.num_values = in->num_values;
301 out->value_ctr.values = talloc_array(mem_ctx,
302 struct drsuapi_DsAttributeValue,
304 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
306 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
307 W_ERROR_HAVE_NO_MEMORY(blobs);
309 for (i=0; i < in->num_values; i++) {
312 out->value_ctr.values[i].blob = &blobs[i];
314 blobs[i] = data_blob_talloc(blobs, NULL, 8);
315 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
317 v = strtoll((const char *)in->values[i].data, NULL, 10);
319 SBVALS(blobs[i].data, 0, v);
325 static WERROR dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb(struct ldb_context *ldb,
326 const struct dsdb_schema *schema,
327 const struct dsdb_attribute *attr,
328 const struct drsuapi_DsReplicaAttribute *in,
330 struct ldb_message_element *out)
335 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
336 W_ERROR_HAVE_NO_MEMORY(out->name);
338 out->num_values = in->value_ctr.num_values;
339 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
340 W_ERROR_HAVE_NO_MEMORY(out->values);
342 for (i=0; i < out->num_values; i++) {
347 if (in->value_ctr.values[i].blob == NULL) {
351 if (in->value_ctr.values[i].blob->length != 8) {
355 v = BVAL(in->value_ctr.values[i].blob->data, 0);
357 t = nt_time_to_unix(v);
360 * NOTE: On a w2k3 server you can set a GeneralizedTime string
361 * via LDAP, but you get back an UTCTime string,
362 * but via DRSUAPI you get back the NTTIME_1sec value
363 * that represents the GeneralizedTime value!
365 * So if we store the UTCTime string in our ldb
366 * we'll loose information!
368 str = ldb_timestring_utc(out->values, t);
369 W_ERROR_HAVE_NO_MEMORY(str);
370 out->values[i] = data_blob_string_const(str);
376 static WERROR dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi(struct ldb_context *ldb,
377 const struct dsdb_schema *schema,
378 const struct dsdb_attribute *attr,
379 const struct ldb_message_element *in,
381 struct drsuapi_DsReplicaAttribute *out)
386 if (attr->attributeID_id == 0xFFFFFFFF) {
390 out->attid = attr->attributeID_id;
391 out->value_ctr.num_values = in->num_values;
392 out->value_ctr.values = talloc_array(mem_ctx,
393 struct drsuapi_DsAttributeValue,
395 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
397 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
398 W_ERROR_HAVE_NO_MEMORY(blobs);
400 for (i=0; i < in->num_values; i++) {
404 out->value_ctr.values[i].blob = &blobs[i];
406 blobs[i] = data_blob_talloc(blobs, NULL, 8);
407 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
409 t = ldb_string_utc_to_time((const char *)in->values[i].data);
410 unix_to_nt_time(&v, t);
413 SBVAL(blobs[i].data, 0, v);
419 static WERROR dsdb_syntax_NTTIME_drsuapi_to_ldb(struct ldb_context *ldb,
420 const struct dsdb_schema *schema,
421 const struct dsdb_attribute *attr,
422 const struct drsuapi_DsReplicaAttribute *in,
424 struct ldb_message_element *out)
429 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
430 W_ERROR_HAVE_NO_MEMORY(out->name);
432 out->num_values = in->value_ctr.num_values;
433 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
434 W_ERROR_HAVE_NO_MEMORY(out->values);
436 for (i=0; i < out->num_values; i++) {
441 if (in->value_ctr.values[i].blob == NULL) {
445 if (in->value_ctr.values[i].blob->length != 8) {
449 v = BVAL(in->value_ctr.values[i].blob->data, 0);
451 t = nt_time_to_unix(v);
453 str = ldb_timestring(out->values, t);
454 W_ERROR_HAVE_NO_MEMORY(str);
456 out->values[i] = data_blob_string_const(str);
462 static WERROR dsdb_syntax_NTTIME_ldb_to_drsuapi(struct ldb_context *ldb,
463 const struct dsdb_schema *schema,
464 const struct dsdb_attribute *attr,
465 const struct ldb_message_element *in,
467 struct drsuapi_DsReplicaAttribute *out)
472 if (attr->attributeID_id == 0xFFFFFFFF) {
476 out->attid = attr->attributeID_id;
477 out->value_ctr.num_values = in->num_values;
478 out->value_ctr.values = talloc_array(mem_ctx,
479 struct drsuapi_DsAttributeValue,
481 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
483 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
484 W_ERROR_HAVE_NO_MEMORY(blobs);
486 for (i=0; i < in->num_values; i++) {
490 out->value_ctr.values[i].blob = &blobs[i];
492 blobs[i] = data_blob_talloc(blobs, NULL, 8);
493 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
495 t = ldb_string_to_time((const char *)in->values[i].data);
496 unix_to_nt_time(&v, t);
499 SBVAL(blobs[i].data, 0, v);
505 static WERROR dsdb_syntax_DATA_BLOB_drsuapi_to_ldb(struct ldb_context *ldb,
506 const struct dsdb_schema *schema,
507 const struct dsdb_attribute *attr,
508 const struct drsuapi_DsReplicaAttribute *in,
510 struct ldb_message_element *out)
515 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
516 W_ERROR_HAVE_NO_MEMORY(out->name);
518 out->num_values = in->value_ctr.num_values;
519 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
520 W_ERROR_HAVE_NO_MEMORY(out->values);
522 for (i=0; i < out->num_values; i++) {
523 if (in->value_ctr.values[i].blob == NULL) {
527 if (in->value_ctr.values[i].blob->length == 0) {
531 out->values[i] = data_blob_dup_talloc(out->values,
532 in->value_ctr.values[i].blob);
533 W_ERROR_HAVE_NO_MEMORY(out->values[i].data);
539 static WERROR dsdb_syntax_DATA_BLOB_ldb_to_drsuapi(struct ldb_context *ldb,
540 const struct dsdb_schema *schema,
541 const struct dsdb_attribute *attr,
542 const struct ldb_message_element *in,
544 struct drsuapi_DsReplicaAttribute *out)
549 if (attr->attributeID_id == 0xFFFFFFFF) {
553 out->attid = attr->attributeID_id;
554 out->value_ctr.num_values = in->num_values;
555 out->value_ctr.values = talloc_array(mem_ctx,
556 struct drsuapi_DsAttributeValue,
558 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
560 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
561 W_ERROR_HAVE_NO_MEMORY(blobs);
563 for (i=0; i < in->num_values; i++) {
564 out->value_ctr.values[i].blob = &blobs[i];
566 blobs[i] = data_blob_dup_talloc(blobs, &in->values[i]);
567 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
573 static WERROR _dsdb_syntax_OID_obj_drsuapi_to_ldb(struct ldb_context *ldb,
574 const struct dsdb_schema *schema,
575 const struct dsdb_attribute *attr,
576 const struct drsuapi_DsReplicaAttribute *in,
578 struct ldb_message_element *out)
583 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
584 W_ERROR_HAVE_NO_MEMORY(out->name);
586 out->num_values = in->value_ctr.num_values;
587 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
588 W_ERROR_HAVE_NO_MEMORY(out->values);
590 for (i=0; i < out->num_values; i++) {
592 const struct dsdb_class *c;
595 if (in->value_ctr.values[i].blob == NULL) {
599 if (in->value_ctr.values[i].blob->length != 4) {
603 v = IVAL(in->value_ctr.values[i].blob->data, 0);
605 c = dsdb_class_by_governsID_id(schema, v);
610 str = talloc_strdup(out->values, c->lDAPDisplayName);
611 W_ERROR_HAVE_NO_MEMORY(str);
613 /* the values need to be reversed */
614 out->values[out->num_values - (i + 1)] = data_blob_string_const(str);
620 static WERROR _dsdb_syntax_OID_oid_drsuapi_to_ldb(struct ldb_context *ldb,
621 const struct dsdb_schema *schema,
622 const struct dsdb_attribute *attr,
623 const struct drsuapi_DsReplicaAttribute *in,
625 struct ldb_message_element *out)
630 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
631 W_ERROR_HAVE_NO_MEMORY(out->name);
633 out->num_values = in->value_ctr.num_values;
634 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
635 W_ERROR_HAVE_NO_MEMORY(out->values);
637 for (i=0; i < out->num_values; i++) {
642 if (in->value_ctr.values[i].blob == NULL) {
646 if (in->value_ctr.values[i].blob->length != 4) {
650 v = IVAL(in->value_ctr.values[i].blob->data, 0);
652 status = dsdb_map_int2oid(schema, v, out->values, &str);
653 W_ERROR_NOT_OK_RETURN(status);
655 out->values[i] = data_blob_string_const(str);
661 static WERROR dsdb_syntax_OID_drsuapi_to_ldb(struct ldb_context *ldb,
662 const struct dsdb_schema *schema,
663 const struct dsdb_attribute *attr,
664 const struct drsuapi_DsReplicaAttribute *in,
666 struct ldb_message_element *out)
670 switch (attr->attributeID_id) {
671 case DRSUAPI_ATTRIBUTE_objectClass:
672 return _dsdb_syntax_OID_obj_drsuapi_to_ldb(ldb, schema, attr, in, mem_ctx, out);
673 case DRSUAPI_ATTRIBUTE_governsID:
674 case DRSUAPI_ATTRIBUTE_attributeID:
675 case DRSUAPI_ATTRIBUTE_attributeSyntax:
676 return _dsdb_syntax_OID_oid_drsuapi_to_ldb(ldb, schema, attr, in, mem_ctx, out);
680 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
681 W_ERROR_HAVE_NO_MEMORY(out->name);
683 out->num_values = in->value_ctr.num_values;
684 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
685 W_ERROR_HAVE_NO_MEMORY(out->values);
687 for (i=0; i < out->num_values; i++) {
692 if (in->value_ctr.values[i].blob == NULL) {
696 if (in->value_ctr.values[i].blob->length != 4) {
700 v = IVAL(in->value_ctr.values[i].blob->data, 0);
702 name = dsdb_lDAPDisplayName_by_id(schema, v);
707 str = talloc_strdup(out->values, name);
708 W_ERROR_HAVE_NO_MEMORY(str);
710 out->values[i] = data_blob_string_const(str);
716 static WERROR dsdb_syntax_OID_ldb_to_drsuapi(struct ldb_context *ldb,
717 const struct dsdb_schema *schema,
718 const struct dsdb_attribute *attr,
719 const struct ldb_message_element *in,
721 struct drsuapi_DsReplicaAttribute *out)
726 if (attr->attributeID_id == 0xFFFFFFFF) {
730 switch (attr->attributeID_id) {
731 case DRSUAPI_ATTRIBUTE_objectClass:
732 case DRSUAPI_ATTRIBUTE_governsID:
733 case DRSUAPI_ATTRIBUTE_attributeID:
734 case DRSUAPI_ATTRIBUTE_attributeSyntax:
735 return dsdb_syntax_FOOBAR_ldb_to_drsuapi(ldb, schema, attr, in, mem_ctx, out);
738 out->attid = attr->attributeID_id;
739 out->value_ctr.num_values = in->num_values;
740 out->value_ctr.values = talloc_array(mem_ctx,
741 struct drsuapi_DsAttributeValue,
743 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
745 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
746 W_ERROR_HAVE_NO_MEMORY(blobs);
748 for (i=0; i < in->num_values; i++) {
751 out->value_ctr.values[i].blob = &blobs[i];
753 blobs[i] = data_blob_talloc(blobs, NULL, 4);
754 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
756 v = strtol((const char *)in->values[i].data, NULL, 10);
758 SIVAL(blobs[i].data, 0, v);
764 static WERROR dsdb_syntax_UNICODE_drsuapi_to_ldb(struct ldb_context *ldb,
765 const struct dsdb_schema *schema,
766 const struct dsdb_attribute *attr,
767 const struct drsuapi_DsReplicaAttribute *in,
769 struct ldb_message_element *out)
774 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
775 W_ERROR_HAVE_NO_MEMORY(out->name);
777 out->num_values = in->value_ctr.num_values;
778 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
779 W_ERROR_HAVE_NO_MEMORY(out->values);
781 for (i=0; i < out->num_values; i++) {
784 if (in->value_ctr.values[i].blob == NULL) {
788 if (in->value_ctr.values[i].blob->length == 0) {
792 if (!convert_string_talloc_convenience(out->values,
793 schema->iconv_convenience,
795 in->value_ctr.values[i].blob->data,
796 in->value_ctr.values[i].blob->length,
797 (void **)&str, NULL, false)) {
801 out->values[i] = data_blob_string_const(str);
807 static WERROR dsdb_syntax_UNICODE_ldb_to_drsuapi(struct ldb_context *ldb,
808 const struct dsdb_schema *schema,
809 const struct dsdb_attribute *attr,
810 const struct ldb_message_element *in,
812 struct drsuapi_DsReplicaAttribute *out)
817 if (attr->attributeID_id == 0xFFFFFFFF) {
821 out->attid = attr->attributeID_id;
822 out->value_ctr.num_values = in->num_values;
823 out->value_ctr.values = talloc_array(mem_ctx,
824 struct drsuapi_DsAttributeValue,
826 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
828 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
829 W_ERROR_HAVE_NO_MEMORY(blobs);
831 for (i=0; i < in->num_values; i++) {
834 out->value_ctr.values[i].blob = &blobs[i];
836 if (!convert_string_talloc_convenience(blobs, schema->iconv_convenience, CH_UNIX, CH_UTF16,
838 in->values[i].length,
839 (void **)&blobs[i].data, NULL, false)) {
842 blobs[i].length = ret;
848 static WERROR dsdb_syntax_DN_drsuapi_to_ldb(struct ldb_context *ldb,
849 const struct dsdb_schema *schema,
850 const struct dsdb_attribute *attr,
851 const struct drsuapi_DsReplicaAttribute *in,
853 struct ldb_message_element *out)
859 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
860 W_ERROR_HAVE_NO_MEMORY(out->name);
862 out->num_values = in->value_ctr.num_values;
863 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
864 W_ERROR_HAVE_NO_MEMORY(out->values);
866 for (i=0; i < out->num_values; i++) {
867 struct drsuapi_DsReplicaObjectIdentifier3 id3;
868 enum ndr_err_code ndr_err;
871 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
873 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
876 if (in->value_ctr.values[i].blob == NULL) {
877 talloc_free(tmp_ctx);
881 if (in->value_ctr.values[i].blob->length == 0) {
882 talloc_free(tmp_ctx);
888 ndr_err = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob,
889 tmp_ctx, schema->iconv_convenience, &id3,
890 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3);
891 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
892 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
893 talloc_free(tmp_ctx);
894 return ntstatus_to_werror(status);
897 dn = ldb_dn_new(tmp_ctx, ldb, id3.dn);
899 talloc_free(tmp_ctx);
900 /* If this fails, it must be out of memory, as it does not do much parsing */
901 W_ERROR_HAVE_NO_MEMORY(dn);
904 ndr_err = ndr_push_struct_blob(&guid_blob, tmp_ctx, schema->iconv_convenience, &id3.guid,
905 (ndr_push_flags_fn_t)ndr_push_GUID);
906 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
907 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
908 talloc_free(tmp_ctx);
909 return ntstatus_to_werror(status);
912 ret = ldb_dn_set_extended_component(dn, "GUID", &guid_blob);
913 if (ret != LDB_SUCCESS) {
914 talloc_free(tmp_ctx);
918 talloc_free(guid_blob.data);
920 if (id3.__ndr_size_sid) {
922 ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, schema->iconv_convenience, &id3.sid,
923 (ndr_push_flags_fn_t)ndr_push_dom_sid);
924 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
925 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
926 talloc_free(tmp_ctx);
927 return ntstatus_to_werror(status);
930 ret = ldb_dn_set_extended_component(dn, "SID", &sid_blob);
931 if (ret != LDB_SUCCESS) {
932 talloc_free(tmp_ctx);
937 out->values[i] = data_blob_string_const(ldb_dn_get_extended_linearized(out->values, dn, 1));
938 talloc_free(tmp_ctx);
944 static WERROR dsdb_syntax_DN_ldb_to_drsuapi(struct ldb_context *ldb,
945 const struct dsdb_schema *schema,
946 const struct dsdb_attribute *attr,
947 const struct ldb_message_element *in,
949 struct drsuapi_DsReplicaAttribute *out)
954 if (attr->attributeID_id == 0xFFFFFFFF) {
958 out->attid = attr->attributeID_id;
959 out->value_ctr.num_values = in->num_values;
960 out->value_ctr.values = talloc_array(mem_ctx,
961 struct drsuapi_DsAttributeValue,
963 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
965 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
966 W_ERROR_HAVE_NO_MEMORY(blobs);
968 for (i=0; i < in->num_values; i++) {
969 struct drsuapi_DsReplicaObjectIdentifier3 id3;
970 enum ndr_err_code ndr_err;
971 const DATA_BLOB *guid_blob, *sid_blob;
973 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
974 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
976 out->value_ctr.values[i].blob = &blobs[i];
978 dn = ldb_dn_from_ldb_val(tmp_ctx, ldb, &in->values[i]);
980 W_ERROR_HAVE_NO_MEMORY(dn);
982 guid_blob = ldb_dn_get_extended_component(dn, "GUID");
987 ndr_err = ndr_pull_struct_blob_all(guid_blob,
988 tmp_ctx, schema->iconv_convenience, &id3.guid,
989 (ndr_pull_flags_fn_t)ndr_pull_GUID);
990 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
991 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
992 talloc_free(tmp_ctx);
993 return ntstatus_to_werror(status);
997 sid_blob = ldb_dn_get_extended_component(dn, "SID");
1000 ndr_err = ndr_pull_struct_blob_all(sid_blob,
1001 tmp_ctx, schema->iconv_convenience, &id3.sid,
1002 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1003 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1004 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1005 talloc_free(tmp_ctx);
1006 return ntstatus_to_werror(status);
1010 id3.dn = ldb_dn_get_linearized(dn);
1012 ndr_err = ndr_push_struct_blob(&blobs[i], blobs, schema->iconv_convenience, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
1013 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1014 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1015 talloc_free(tmp_ctx);
1016 return ntstatus_to_werror(status);
1018 talloc_free(tmp_ctx);
1024 static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(struct ldb_context *ldb,
1025 const struct dsdb_schema *schema,
1026 const struct dsdb_attribute *attr,
1027 const struct drsuapi_DsReplicaAttribute *in,
1028 TALLOC_CTX *mem_ctx,
1029 struct ldb_message_element *out)
1034 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1035 W_ERROR_HAVE_NO_MEMORY(out->name);
1037 out->num_values = in->value_ctr.num_values;
1038 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1039 W_ERROR_HAVE_NO_MEMORY(out->values);
1041 for (i=0; i < out->num_values; i++) {
1042 struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
1045 enum ndr_err_code ndr_err;
1047 if (in->value_ctr.values[i].blob == NULL) {
1051 if (in->value_ctr.values[i].blob->length == 0) {
1055 ndr_err = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob,
1056 out->values, schema->iconv_convenience, &id3b,
1057 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary);
1058 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1059 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1060 return ntstatus_to_werror(status);
1063 /* TODO: handle id3.guid and id3.sid */
1064 binary = data_blob_hex_string(out->values, &id3b.binary);
1065 W_ERROR_HAVE_NO_MEMORY(binary);
1067 str = talloc_asprintf(out->values, "B:%u:%s:%s",
1068 (unsigned int)(id3b.binary.length * 2), /* because of 2 hex chars per byte */
1071 W_ERROR_HAVE_NO_MEMORY(str);
1073 /* TODO: handle id3.guid and id3.sid */
1074 out->values[i] = data_blob_string_const(str);
1080 static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(struct ldb_context *ldb,
1081 const struct dsdb_schema *schema,
1082 const struct dsdb_attribute *attr,
1083 const struct ldb_message_element *in,
1084 TALLOC_CTX *mem_ctx,
1085 struct drsuapi_DsReplicaAttribute *out)
1090 if (attr->attributeID_id == 0xFFFFFFFF) {
1094 out->attid = attr->attributeID_id;
1095 out->value_ctr.num_values = in->num_values;
1096 out->value_ctr.values = talloc_array(mem_ctx,
1097 struct drsuapi_DsAttributeValue,
1099 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1101 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1102 W_ERROR_HAVE_NO_MEMORY(blobs);
1104 for (i=0; i < in->num_values; i++) {
1105 struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
1106 enum ndr_err_code ndr_err;
1108 out->value_ctr.values[i].blob = &blobs[i];
1110 /* TODO: handle id3b.guid and id3b.sid, id3.binary */
1112 id3b.dn = (const char *)in->values[i].data;
1113 id3b.binary = data_blob(NULL, 0);
1115 ndr_err = ndr_push_struct_blob(&blobs[i], blobs, schema->iconv_convenience, &id3b,
1116 (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary);
1117 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1118 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1119 return ntstatus_to_werror(status);
1126 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb(struct ldb_context *ldb,
1127 const struct dsdb_schema *schema,
1128 const struct dsdb_attribute *attr,
1129 const struct drsuapi_DsReplicaAttribute *in,
1130 TALLOC_CTX *mem_ctx,
1131 struct ldb_message_element *out)
1136 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1137 W_ERROR_HAVE_NO_MEMORY(out->name);
1139 out->num_values = in->value_ctr.num_values;
1140 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1141 W_ERROR_HAVE_NO_MEMORY(out->values);
1143 for (i=0; i < out->num_values; i++) {
1147 if (in->value_ctr.values[i].blob == NULL) {
1151 if (in->value_ctr.values[i].blob->length < 4) {
1155 len = IVAL(in->value_ctr.values[i].blob->data, 0);
1157 if (len != in->value_ctr.values[i].blob->length) {
1161 if (!convert_string_talloc_convenience(out->values, schema->iconv_convenience, CH_UTF16, CH_UNIX,
1162 in->value_ctr.values[i].blob->data+4,
1163 in->value_ctr.values[i].blob->length-4,
1164 (void **)&str, NULL, false)) {
1168 out->values[i] = data_blob_string_const(str);
1174 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi(struct ldb_context *ldb,
1175 const struct dsdb_schema *schema,
1176 const struct dsdb_attribute *attr,
1177 const struct ldb_message_element *in,
1178 TALLOC_CTX *mem_ctx,
1179 struct drsuapi_DsReplicaAttribute *out)
1184 if (attr->attributeID_id == 0xFFFFFFFF) {
1188 out->attid = attr->attributeID_id;
1189 out->value_ctr.num_values = in->num_values;
1190 out->value_ctr.values = talloc_array(mem_ctx,
1191 struct drsuapi_DsAttributeValue,
1193 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1195 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1196 W_ERROR_HAVE_NO_MEMORY(blobs);
1198 for (i=0; i < in->num_values; i++) {
1202 out->value_ctr.values[i].blob = &blobs[i];
1204 if (!convert_string_talloc_convenience(blobs, schema->iconv_convenience, CH_UNIX, CH_UTF16,
1206 in->values[i].length,
1207 (void **)&data, &ret, false)) {
1211 blobs[i] = data_blob_talloc(blobs, NULL, 4 + ret);
1212 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
1214 SIVAL(blobs[i].data, 0, 4 + ret);
1217 memcpy(blobs[i].data + 4, data, ret);
1225 #define OMOBJECTCLASS(val) { .length = sizeof(val) - 1, .data = discard_const_p(uint8_t, val) }
1227 static const struct dsdb_syntax dsdb_syntaxes[] = {
1230 .ldap_oid = LDB_SYNTAX_BOOLEAN,
1232 .attributeSyntax_oid = "2.5.5.8",
1233 .drsuapi_to_ldb = dsdb_syntax_BOOL_drsuapi_to_ldb,
1234 .ldb_to_drsuapi = dsdb_syntax_BOOL_ldb_to_drsuapi,
1235 .equality = "booleanMatch",
1236 .comment = "Boolean"
1239 .ldap_oid = LDB_SYNTAX_INTEGER,
1241 .attributeSyntax_oid = "2.5.5.9",
1242 .drsuapi_to_ldb = dsdb_syntax_INT32_drsuapi_to_ldb,
1243 .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi,
1244 .equality = "integerMatch",
1245 .comment = "Integer",
1247 .name = "String(Octet)",
1248 .ldap_oid = LDB_SYNTAX_OCTET_STRING,
1250 .attributeSyntax_oid = "2.5.5.10",
1251 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1252 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1253 .equality = "octetStringMatch",
1254 .comment = "Octet String",
1256 .name = "String(Sid)",
1257 .ldap_oid = LDB_SYNTAX_OCTET_STRING,
1259 .attributeSyntax_oid = "2.5.5.17",
1260 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1261 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1262 .equality = "octetStringMatch",
1263 .comment = "Octet String - Security Identifier (SID)",
1264 .ldb_syntax = LDB_SYNTAX_SAMBA_SID
1266 .name = "String(Object-Identifier)",
1267 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.38",
1269 .attributeSyntax_oid = "2.5.5.2",
1270 .drsuapi_to_ldb = dsdb_syntax_OID_drsuapi_to_ldb,
1271 .ldb_to_drsuapi = dsdb_syntax_OID_ldb_to_drsuapi,
1272 .equality = "caseIgnoreMatch", /* Would use "objectIdentifierMatch" but most are ldap attribute/class names */
1273 .comment = "OID String",
1274 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING
1276 .name = "Enumeration",
1277 .ldap_oid = LDB_SYNTAX_INTEGER,
1279 .attributeSyntax_oid = "2.5.5.9",
1280 .drsuapi_to_ldb = dsdb_syntax_INT32_drsuapi_to_ldb,
1281 .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi,
1283 /* not used in w2k3 forest */
1284 .name = "String(Numeric)",
1285 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.36",
1287 .attributeSyntax_oid = "2.5.5.6",
1288 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1289 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1290 .equality = "numericStringMatch",
1291 .substring = "numericStringSubstringsMatch",
1292 .comment = "Numeric String",
1293 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING,
1295 .name = "String(Printable)",
1296 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.44",
1298 .attributeSyntax_oid = "2.5.5.5",
1299 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1300 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1301 .ldb_syntax = LDB_SYNTAX_OCTET_STRING,
1303 .name = "String(Teletex)",
1304 .ldap_oid = "1.2.840.113556.1.4.905",
1306 .attributeSyntax_oid = "2.5.5.4",
1307 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1308 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1309 .equality = "caseIgnoreMatch",
1310 .substring = "caseIgnoreSubstringsMatch",
1311 .comment = "Case Insensitive String",
1312 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING,
1314 .name = "String(IA5)",
1315 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.26",
1317 .attributeSyntax_oid = "2.5.5.5",
1318 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1319 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1320 .equality = "caseExactIA5Match",
1321 .comment = "Printable String",
1322 .ldb_syntax = LDB_SYNTAX_OCTET_STRING,
1324 .name = "String(UTC-Time)",
1325 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.53",
1327 .attributeSyntax_oid = "2.5.5.11",
1328 .drsuapi_to_ldb = dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb,
1329 .ldb_to_drsuapi = dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi,
1330 .equality = "generalizedTimeMatch",
1331 .comment = "UTC Time",
1333 .name = "String(Generalized-Time)",
1334 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.24",
1336 .attributeSyntax_oid = "2.5.5.11",
1337 .drsuapi_to_ldb = dsdb_syntax_NTTIME_drsuapi_to_ldb,
1338 .ldb_to_drsuapi = dsdb_syntax_NTTIME_ldb_to_drsuapi,
1339 .equality = "generalizedTimeMatch",
1340 .comment = "Generalized Time",
1341 .ldb_syntax = LDB_SYNTAX_UTC_TIME,
1343 /* not used in w2k3 schema */
1344 .name = "String(Case Sensitive)",
1345 .ldap_oid = "1.2.840.113556.1.4.1362",
1347 .attributeSyntax_oid = "2.5.5.3",
1348 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1349 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1351 .name = "String(Unicode)",
1352 .ldap_oid = LDB_SYNTAX_DIRECTORY_STRING,
1354 .attributeSyntax_oid = "2.5.5.12",
1355 .drsuapi_to_ldb = dsdb_syntax_UNICODE_drsuapi_to_ldb,
1356 .ldb_to_drsuapi = dsdb_syntax_UNICODE_ldb_to_drsuapi,
1357 .equality = "caseIgnoreMatch",
1358 .substring = "caseIgnoreSubstringsMatch",
1359 .comment = "Directory String",
1361 .name = "Interval/LargeInteger",
1362 .ldap_oid = "1.2.840.113556.1.4.906",
1364 .attributeSyntax_oid = "2.5.5.16",
1365 .drsuapi_to_ldb = dsdb_syntax_INT64_drsuapi_to_ldb,
1366 .ldb_to_drsuapi = dsdb_syntax_INT64_ldb_to_drsuapi,
1367 .equality = "integerMatch",
1368 .comment = "Large Integer",
1369 .ldb_syntax = LDB_SYNTAX_INTEGER,
1371 .name = "String(NT-Sec-Desc)",
1372 .ldap_oid = LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR,
1374 .attributeSyntax_oid = "2.5.5.15",
1375 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1376 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1378 .name = "Object(DS-DN)",
1379 .ldap_oid = LDB_SYNTAX_DN,
1381 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x4a"),
1382 .attributeSyntax_oid = "2.5.5.1",
1383 .drsuapi_to_ldb = dsdb_syntax_DN_drsuapi_to_ldb,
1384 .ldb_to_drsuapi = dsdb_syntax_DN_ldb_to_drsuapi,
1385 .equality = "distinguishedNameMatch",
1386 .comment = "Object(DS-DN) == a DN",
1388 .name = "Object(DN-Binary)",
1389 .ldap_oid = "1.2.840.113556.1.4.903",
1391 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0b"),
1392 .attributeSyntax_oid = "2.5.5.7",
1393 .drsuapi_to_ldb = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
1394 .ldb_to_drsuapi = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
1395 .equality = "octetStringMatch",
1396 .comment = "OctetString: Binary+DN",
1397 .ldb_syntax = LDB_SYNTAX_OCTET_STRING,
1399 /* not used in w2k3 schema */
1400 .name = "Object(OR-Name)",
1401 .ldap_oid = "1.2.840.113556.1.4.1221",
1403 .oMObjectClass = OMOBJECTCLASS("\x56\x06\x01\x02\x05\x0b\x1D"),
1404 .attributeSyntax_oid = "2.5.5.7",
1405 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1406 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1409 * TODO: verify if DATA_BLOB is correct here...!
1411 * repsFrom and repsTo are the only attributes using
1412 * this attribute syntax, but they're not replicated...
1414 .name = "Object(Replica-Link)",
1415 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.40",
1417 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x06"),
1418 .attributeSyntax_oid = "2.5.5.10",
1419 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1420 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1422 .name = "Object(Presentation-Address)",
1423 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.43",
1425 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x5c"),
1426 .attributeSyntax_oid = "2.5.5.13",
1427 .drsuapi_to_ldb = dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb,
1428 .ldb_to_drsuapi = dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi,
1429 .comment = "Presentation Address",
1430 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING,
1432 /* not used in w2k3 schema */
1433 .name = "Object(Access-Point)",
1434 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.2",
1436 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x3e"),
1437 .attributeSyntax_oid = "2.5.5.14",
1438 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1439 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1440 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING,
1442 /* not used in w2k3 schema */
1443 .name = "Object(DN-String)",
1444 .ldap_oid = "1.2.840.113556.1.4.904",
1446 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0c"),
1447 .attributeSyntax_oid = "2.5.5.14",
1448 .drsuapi_to_ldb = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
1449 .ldb_to_drsuapi = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
1450 .equality = "octetStringMatch",
1451 .comment = "OctetString: String+DN",
1452 .ldb_syntax = LDB_SYNTAX_OCTET_STRING,
1456 const struct dsdb_syntax *find_syntax_map_by_ad_oid(const char *ad_oid)
1459 for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
1460 if (strcasecmp(ad_oid, dsdb_syntaxes[i].attributeSyntax_oid) == 0) {
1461 return &dsdb_syntaxes[i];
1467 const struct dsdb_syntax *find_syntax_map_by_ad_syntax(int oMSyntax)
1470 for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
1471 if (oMSyntax == dsdb_syntaxes[i].oMSyntax) {
1472 return &dsdb_syntaxes[i];
1478 const struct dsdb_syntax *find_syntax_map_by_standard_oid(const char *standard_oid)
1481 for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
1482 if (strcasecmp(standard_oid, dsdb_syntaxes[i].ldap_oid) == 0) {
1483 return &dsdb_syntaxes[i];
1488 const struct dsdb_syntax *dsdb_syntax_for_attribute(const struct dsdb_attribute *attr)
1492 for (i=0; i < ARRAY_SIZE(dsdb_syntaxes); i++) {
1493 if (attr->oMSyntax != dsdb_syntaxes[i].oMSyntax) continue;
1495 if (attr->oMObjectClass.length != dsdb_syntaxes[i].oMObjectClass.length) continue;
1497 if (attr->oMObjectClass.length) {
1499 ret = memcmp(attr->oMObjectClass.data,
1500 dsdb_syntaxes[i].oMObjectClass.data,
1501 attr->oMObjectClass.length);
1502 if (ret != 0) continue;
1505 if (strcmp(attr->attributeSyntax_oid, dsdb_syntaxes[i].attributeSyntax_oid) != 0) continue;
1507 return &dsdb_syntaxes[i];
1513 WERROR dsdb_attribute_drsuapi_to_ldb(struct ldb_context *ldb,
1514 const struct dsdb_schema *schema,
1515 const struct drsuapi_DsReplicaAttribute *in,
1516 TALLOC_CTX *mem_ctx,
1517 struct ldb_message_element *out)
1519 const struct dsdb_attribute *sa;
1521 sa = dsdb_attribute_by_attributeID_id(schema, in->attid);
1526 return sa->syntax->drsuapi_to_ldb(ldb, schema, sa, in, mem_ctx, out);
1529 WERROR dsdb_attribute_ldb_to_drsuapi(struct ldb_context *ldb,
1530 const struct dsdb_schema *schema,
1531 const struct ldb_message_element *in,
1532 TALLOC_CTX *mem_ctx,
1533 struct drsuapi_DsReplicaAttribute *out)
1535 const struct dsdb_attribute *sa;
1537 sa = dsdb_attribute_by_lDAPDisplayName(schema, in->name);
1542 return sa->syntax->ldb_to_drsuapi(ldb, schema, sa, in, mem_ctx, out);