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 "lib/ldb/include/ldb.h"
27 #include "system/time.h"
28 #include "../lib/util/charset/charset.h"
29 #include "librpc/ndr/libndr.h"
30 #include "param/param.h"
32 static WERROR dsdb_syntax_FOOBAR_drsuapi_to_ldb(const struct dsdb_schema *schema,
33 const struct dsdb_attribute *attr,
34 const struct drsuapi_DsReplicaAttribute *in,
36 struct ldb_message_element *out)
41 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
42 W_ERROR_HAVE_NO_MEMORY(out->name);
44 out->num_values = in->value_ctr.num_values;
45 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
46 W_ERROR_HAVE_NO_MEMORY(out->values);
48 for (i=0; i < out->num_values; i++) {
51 if (in->value_ctr.values[i].blob == NULL) {
55 str = talloc_asprintf(out->values, "%s: not implemented",
57 W_ERROR_HAVE_NO_MEMORY(str);
59 out->values[i] = data_blob_string_const(str);
65 static WERROR dsdb_syntax_FOOBAR_ldb_to_drsuapi(const struct dsdb_schema *schema,
66 const struct dsdb_attribute *attr,
67 const struct ldb_message_element *in,
69 struct drsuapi_DsReplicaAttribute *out)
74 static WERROR dsdb_syntax_BOOL_drsuapi_to_ldb(const struct dsdb_schema *schema,
75 const struct dsdb_attribute *attr,
76 const struct drsuapi_DsReplicaAttribute *in,
78 struct ldb_message_element *out)
83 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
84 W_ERROR_HAVE_NO_MEMORY(out->name);
86 out->num_values = in->value_ctr.num_values;
87 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
88 W_ERROR_HAVE_NO_MEMORY(out->values);
90 for (i=0; i < out->num_values; i++) {
94 if (in->value_ctr.values[i].blob == NULL) {
98 if (in->value_ctr.values[i].blob->length != 4) {
102 v = IVAL(in->value_ctr.values[i].blob->data, 0);
105 str = talloc_strdup(out->values, "TRUE");
106 W_ERROR_HAVE_NO_MEMORY(str);
108 str = talloc_strdup(out->values, "FALSE");
109 W_ERROR_HAVE_NO_MEMORY(str);
112 out->values[i] = data_blob_string_const(str);
118 static WERROR dsdb_syntax_BOOL_ldb_to_drsuapi(const struct dsdb_schema *schema,
119 const struct dsdb_attribute *attr,
120 const struct ldb_message_element *in,
122 struct drsuapi_DsReplicaAttribute *out)
127 if (attr->attributeID_id == 0xFFFFFFFF) {
131 out->attid = attr->attributeID_id;
132 out->value_ctr.num_values = in->num_values;
133 out->value_ctr.values = talloc_array(mem_ctx,
134 struct drsuapi_DsAttributeValue,
136 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
138 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
139 W_ERROR_HAVE_NO_MEMORY(blobs);
141 for (i=0; i < in->num_values; i++) {
142 out->value_ctr.values[i].blob = &blobs[i];
144 blobs[i] = data_blob_talloc(blobs, NULL, 4);
145 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
147 if (strcmp("TRUE", (const char *)in->values[i].data) == 0) {
148 SIVAL(blobs[i].data, 0, 0x00000001);
149 } else if (strcmp("FALSE", (const char *)in->values[i].data) == 0) {
150 SIVAL(blobs[i].data, 0, 0x00000000);
159 static WERROR dsdb_syntax_INT32_drsuapi_to_ldb(const struct dsdb_schema *schema,
160 const struct dsdb_attribute *attr,
161 const struct drsuapi_DsReplicaAttribute *in,
163 struct ldb_message_element *out)
168 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
169 W_ERROR_HAVE_NO_MEMORY(out->name);
171 out->num_values = in->value_ctr.num_values;
172 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
173 W_ERROR_HAVE_NO_MEMORY(out->values);
175 for (i=0; i < out->num_values; i++) {
179 if (in->value_ctr.values[i].blob == NULL) {
183 if (in->value_ctr.values[i].blob->length != 4) {
187 v = IVALS(in->value_ctr.values[i].blob->data, 0);
189 str = talloc_asprintf(out->values, "%d", v);
190 W_ERROR_HAVE_NO_MEMORY(str);
192 out->values[i] = data_blob_string_const(str);
198 static WERROR dsdb_syntax_INT32_ldb_to_drsuapi(const struct dsdb_schema *schema,
199 const struct dsdb_attribute *attr,
200 const struct ldb_message_element *in,
202 struct drsuapi_DsReplicaAttribute *out)
207 if (attr->attributeID_id == 0xFFFFFFFF) {
211 out->attid = attr->attributeID_id;
212 out->value_ctr.num_values = in->num_values;
213 out->value_ctr.values = talloc_array(mem_ctx,
214 struct drsuapi_DsAttributeValue,
216 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
218 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
219 W_ERROR_HAVE_NO_MEMORY(blobs);
221 for (i=0; i < in->num_values; i++) {
224 out->value_ctr.values[i].blob = &blobs[i];
226 blobs[i] = data_blob_talloc(blobs, NULL, 4);
227 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
229 v = strtol((const char *)in->values[i].data, NULL, 10);
231 SIVALS(blobs[i].data, 0, v);
237 static WERROR dsdb_syntax_INT64_drsuapi_to_ldb(const struct dsdb_schema *schema,
238 const struct dsdb_attribute *attr,
239 const struct drsuapi_DsReplicaAttribute *in,
241 struct ldb_message_element *out)
246 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
247 W_ERROR_HAVE_NO_MEMORY(out->name);
249 out->num_values = in->value_ctr.num_values;
250 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
251 W_ERROR_HAVE_NO_MEMORY(out->values);
253 for (i=0; i < out->num_values; i++) {
257 if (in->value_ctr.values[i].blob == NULL) {
261 if (in->value_ctr.values[i].blob->length != 8) {
265 v = BVALS(in->value_ctr.values[i].blob->data, 0);
267 str = talloc_asprintf(out->values, "%lld", (long long int)v);
268 W_ERROR_HAVE_NO_MEMORY(str);
270 out->values[i] = data_blob_string_const(str);
276 static WERROR dsdb_syntax_INT64_ldb_to_drsuapi(const struct dsdb_schema *schema,
277 const struct dsdb_attribute *attr,
278 const struct ldb_message_element *in,
280 struct drsuapi_DsReplicaAttribute *out)
285 if (attr->attributeID_id == 0xFFFFFFFF) {
289 out->attid = attr->attributeID_id;
290 out->value_ctr.num_values = in->num_values;
291 out->value_ctr.values = talloc_array(mem_ctx,
292 struct drsuapi_DsAttributeValue,
294 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
296 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
297 W_ERROR_HAVE_NO_MEMORY(blobs);
299 for (i=0; i < in->num_values; i++) {
302 out->value_ctr.values[i].blob = &blobs[i];
304 blobs[i] = data_blob_talloc(blobs, NULL, 8);
305 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
307 v = strtoll((const char *)in->values[i].data, NULL, 10);
309 SBVALS(blobs[i].data, 0, v);
315 static WERROR dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb(const struct dsdb_schema *schema,
316 const struct dsdb_attribute *attr,
317 const struct drsuapi_DsReplicaAttribute *in,
319 struct ldb_message_element *out)
324 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
325 W_ERROR_HAVE_NO_MEMORY(out->name);
327 out->num_values = in->value_ctr.num_values;
328 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
329 W_ERROR_HAVE_NO_MEMORY(out->values);
331 for (i=0; i < out->num_values; i++) {
336 if (in->value_ctr.values[i].blob == NULL) {
340 if (in->value_ctr.values[i].blob->length != 8) {
344 v = BVAL(in->value_ctr.values[i].blob->data, 0);
346 t = nt_time_to_unix(v);
349 * NOTE: On a w2k3 server you can set a GeneralizedTime string
350 * via LDAP, but you get back an UTCTime string,
351 * but via DRSUAPI you get back the NTTIME_1sec value
352 * that represents the GeneralizedTime value!
354 * So if we store the UTCTime string in our ldb
355 * we'll loose information!
357 str = ldb_timestring_utc(out->values, t);
358 W_ERROR_HAVE_NO_MEMORY(str);
359 out->values[i] = data_blob_string_const(str);
365 static WERROR dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi(const struct dsdb_schema *schema,
366 const struct dsdb_attribute *attr,
367 const struct ldb_message_element *in,
369 struct drsuapi_DsReplicaAttribute *out)
374 if (attr->attributeID_id == 0xFFFFFFFF) {
378 out->attid = attr->attributeID_id;
379 out->value_ctr.num_values = in->num_values;
380 out->value_ctr.values = talloc_array(mem_ctx,
381 struct drsuapi_DsAttributeValue,
383 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
385 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
386 W_ERROR_HAVE_NO_MEMORY(blobs);
388 for (i=0; i < in->num_values; i++) {
392 out->value_ctr.values[i].blob = &blobs[i];
394 blobs[i] = data_blob_talloc(blobs, NULL, 8);
395 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
397 t = ldb_string_utc_to_time((const char *)in->values[i].data);
398 unix_to_nt_time(&v, t);
401 SBVAL(blobs[i].data, 0, v);
407 static WERROR dsdb_syntax_NTTIME_drsuapi_to_ldb(const struct dsdb_schema *schema,
408 const struct dsdb_attribute *attr,
409 const struct drsuapi_DsReplicaAttribute *in,
411 struct ldb_message_element *out)
416 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
417 W_ERROR_HAVE_NO_MEMORY(out->name);
419 out->num_values = in->value_ctr.num_values;
420 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
421 W_ERROR_HAVE_NO_MEMORY(out->values);
423 for (i=0; i < out->num_values; i++) {
428 if (in->value_ctr.values[i].blob == NULL) {
432 if (in->value_ctr.values[i].blob->length != 8) {
436 v = BVAL(in->value_ctr.values[i].blob->data, 0);
438 t = nt_time_to_unix(v);
440 str = ldb_timestring(out->values, t);
441 W_ERROR_HAVE_NO_MEMORY(str);
443 out->values[i] = data_blob_string_const(str);
449 static WERROR dsdb_syntax_NTTIME_ldb_to_drsuapi(const struct dsdb_schema *schema,
450 const struct dsdb_attribute *attr,
451 const struct ldb_message_element *in,
453 struct drsuapi_DsReplicaAttribute *out)
458 if (attr->attributeID_id == 0xFFFFFFFF) {
462 out->attid = attr->attributeID_id;
463 out->value_ctr.num_values = in->num_values;
464 out->value_ctr.values = talloc_array(mem_ctx,
465 struct drsuapi_DsAttributeValue,
467 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
469 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
470 W_ERROR_HAVE_NO_MEMORY(blobs);
472 for (i=0; i < in->num_values; i++) {
476 out->value_ctr.values[i].blob = &blobs[i];
478 blobs[i] = data_blob_talloc(blobs, NULL, 8);
479 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
481 t = ldb_string_to_time((const char *)in->values[i].data);
482 unix_to_nt_time(&v, t);
485 SBVAL(blobs[i].data, 0, v);
491 static WERROR dsdb_syntax_DATA_BLOB_drsuapi_to_ldb(const struct dsdb_schema *schema,
492 const struct dsdb_attribute *attr,
493 const struct drsuapi_DsReplicaAttribute *in,
495 struct ldb_message_element *out)
500 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
501 W_ERROR_HAVE_NO_MEMORY(out->name);
503 out->num_values = in->value_ctr.num_values;
504 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
505 W_ERROR_HAVE_NO_MEMORY(out->values);
507 for (i=0; i < out->num_values; i++) {
508 if (in->value_ctr.values[i].blob == NULL) {
512 if (in->value_ctr.values[i].blob->length == 0) {
516 out->values[i] = data_blob_dup_talloc(out->values,
517 in->value_ctr.values[i].blob);
518 W_ERROR_HAVE_NO_MEMORY(out->values[i].data);
524 static WERROR dsdb_syntax_DATA_BLOB_ldb_to_drsuapi(const struct dsdb_schema *schema,
525 const struct dsdb_attribute *attr,
526 const struct ldb_message_element *in,
528 struct drsuapi_DsReplicaAttribute *out)
533 if (attr->attributeID_id == 0xFFFFFFFF) {
537 out->attid = attr->attributeID_id;
538 out->value_ctr.num_values = in->num_values;
539 out->value_ctr.values = talloc_array(mem_ctx,
540 struct drsuapi_DsAttributeValue,
542 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
544 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
545 W_ERROR_HAVE_NO_MEMORY(blobs);
547 for (i=0; i < in->num_values; i++) {
548 out->value_ctr.values[i].blob = &blobs[i];
550 blobs[i] = data_blob_dup_talloc(blobs, &in->values[i]);
551 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
557 static WERROR _dsdb_syntax_OID_obj_drsuapi_to_ldb(const struct dsdb_schema *schema,
558 const struct dsdb_attribute *attr,
559 const struct drsuapi_DsReplicaAttribute *in,
561 struct ldb_message_element *out)
566 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
567 W_ERROR_HAVE_NO_MEMORY(out->name);
569 out->num_values = in->value_ctr.num_values;
570 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
571 W_ERROR_HAVE_NO_MEMORY(out->values);
573 for (i=0; i < out->num_values; i++) {
575 const struct dsdb_class *c;
578 if (in->value_ctr.values[i].blob == NULL) {
582 if (in->value_ctr.values[i].blob->length != 4) {
586 v = IVAL(in->value_ctr.values[i].blob->data, 0);
588 c = dsdb_class_by_governsID_id(schema, v);
593 str = talloc_strdup(out->values, c->lDAPDisplayName);
594 W_ERROR_HAVE_NO_MEMORY(str);
596 /* the values need to be reversed */
597 out->values[out->num_values - (i + 1)] = data_blob_string_const(str);
603 static WERROR _dsdb_syntax_OID_oid_drsuapi_to_ldb(const struct dsdb_schema *schema,
604 const struct dsdb_attribute *attr,
605 const struct drsuapi_DsReplicaAttribute *in,
607 struct ldb_message_element *out)
612 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
613 W_ERROR_HAVE_NO_MEMORY(out->name);
615 out->num_values = in->value_ctr.num_values;
616 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
617 W_ERROR_HAVE_NO_MEMORY(out->values);
619 for (i=0; i < out->num_values; i++) {
624 if (in->value_ctr.values[i].blob == NULL) {
628 if (in->value_ctr.values[i].blob->length != 4) {
632 v = IVAL(in->value_ctr.values[i].blob->data, 0);
634 status = dsdb_map_int2oid(schema, v, out->values, &str);
635 W_ERROR_NOT_OK_RETURN(status);
637 out->values[i] = data_blob_string_const(str);
643 static WERROR dsdb_syntax_OID_drsuapi_to_ldb(const struct dsdb_schema *schema,
644 const struct dsdb_attribute *attr,
645 const struct drsuapi_DsReplicaAttribute *in,
647 struct ldb_message_element *out)
651 switch (attr->attributeID_id) {
652 case DRSUAPI_ATTRIBUTE_objectClass:
653 return _dsdb_syntax_OID_obj_drsuapi_to_ldb(schema, attr, in, mem_ctx, out);
654 case DRSUAPI_ATTRIBUTE_governsID:
655 case DRSUAPI_ATTRIBUTE_attributeID:
656 case DRSUAPI_ATTRIBUTE_attributeSyntax:
657 return _dsdb_syntax_OID_oid_drsuapi_to_ldb(schema, attr, in, mem_ctx, out);
661 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
662 W_ERROR_HAVE_NO_MEMORY(out->name);
664 out->num_values = in->value_ctr.num_values;
665 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
666 W_ERROR_HAVE_NO_MEMORY(out->values);
668 for (i=0; i < out->num_values; i++) {
673 if (in->value_ctr.values[i].blob == NULL) {
677 if (in->value_ctr.values[i].blob->length != 4) {
681 v = IVAL(in->value_ctr.values[i].blob->data, 0);
683 name = dsdb_lDAPDisplayName_by_id(schema, v);
688 str = talloc_strdup(out->values, name);
689 W_ERROR_HAVE_NO_MEMORY(str);
691 out->values[i] = data_blob_string_const(str);
697 static WERROR dsdb_syntax_OID_ldb_to_drsuapi(const struct dsdb_schema *schema,
698 const struct dsdb_attribute *attr,
699 const struct ldb_message_element *in,
701 struct drsuapi_DsReplicaAttribute *out)
706 if (attr->attributeID_id == 0xFFFFFFFF) {
710 switch (attr->attributeID_id) {
711 case DRSUAPI_ATTRIBUTE_objectClass:
712 case DRSUAPI_ATTRIBUTE_governsID:
713 case DRSUAPI_ATTRIBUTE_attributeID:
714 case DRSUAPI_ATTRIBUTE_attributeSyntax:
715 return dsdb_syntax_FOOBAR_ldb_to_drsuapi(schema, attr, in, mem_ctx, out);
718 out->attid = attr->attributeID_id;
719 out->value_ctr.num_values = in->num_values;
720 out->value_ctr.values = talloc_array(mem_ctx,
721 struct drsuapi_DsAttributeValue,
723 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
725 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
726 W_ERROR_HAVE_NO_MEMORY(blobs);
728 for (i=0; i < in->num_values; i++) {
731 out->value_ctr.values[i].blob = &blobs[i];
733 blobs[i] = data_blob_talloc(blobs, NULL, 4);
734 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
736 v = strtol((const char *)in->values[i].data, NULL, 10);
738 SIVAL(blobs[i].data, 0, v);
744 static WERROR dsdb_syntax_UNICODE_drsuapi_to_ldb(const struct dsdb_schema *schema,
745 const struct dsdb_attribute *attr,
746 const struct drsuapi_DsReplicaAttribute *in,
748 struct ldb_message_element *out)
753 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
754 W_ERROR_HAVE_NO_MEMORY(out->name);
756 out->num_values = in->value_ctr.num_values;
757 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
758 W_ERROR_HAVE_NO_MEMORY(out->values);
760 for (i=0; i < out->num_values; i++) {
764 if (in->value_ctr.values[i].blob == NULL) {
768 if (in->value_ctr.values[i].blob->length == 0) {
772 ret = convert_string_talloc_convenience(out->values,
773 schema->iconv_convenience,
775 in->value_ctr.values[i].blob->data,
776 in->value_ctr.values[i].blob->length,
782 out->values[i] = data_blob_string_const(str);
788 static WERROR dsdb_syntax_UNICODE_ldb_to_drsuapi(const struct dsdb_schema *schema,
789 const struct dsdb_attribute *attr,
790 const struct ldb_message_element *in,
792 struct drsuapi_DsReplicaAttribute *out)
797 if (attr->attributeID_id == 0xFFFFFFFF) {
801 out->attid = attr->attributeID_id;
802 out->value_ctr.num_values = in->num_values;
803 out->value_ctr.values = talloc_array(mem_ctx,
804 struct drsuapi_DsAttributeValue,
806 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
808 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
809 W_ERROR_HAVE_NO_MEMORY(blobs);
811 for (i=0; i < in->num_values; i++) {
814 out->value_ctr.values[i].blob = &blobs[i];
816 ret = convert_string_talloc_convenience(blobs, schema->iconv_convenience, CH_UNIX, CH_UTF16,
818 in->values[i].length,
819 (void **)&blobs[i].data);
823 blobs[i].length = ret;
829 static WERROR dsdb_syntax_DN_drsuapi_to_ldb(const struct dsdb_schema *schema,
830 const struct dsdb_attribute *attr,
831 const struct drsuapi_DsReplicaAttribute *in,
833 struct ldb_message_element *out)
838 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
839 W_ERROR_HAVE_NO_MEMORY(out->name);
841 out->num_values = in->value_ctr.num_values;
842 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
843 W_ERROR_HAVE_NO_MEMORY(out->values);
845 for (i=0; i < out->num_values; i++) {
846 struct drsuapi_DsReplicaObjectIdentifier3 id3;
847 enum ndr_err_code ndr_err;
849 if (in->value_ctr.values[i].blob == NULL) {
853 if (in->value_ctr.values[i].blob->length == 0) {
857 ndr_err = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob,
858 out->values, schema->iconv_convenience, &id3,
859 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3);
860 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
861 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
862 return ntstatus_to_werror(status);
865 /* TODO: handle id3.guid and id3.sid */
866 out->values[i] = data_blob_string_const(id3.dn);
872 static WERROR dsdb_syntax_DN_ldb_to_drsuapi(const struct dsdb_schema *schema,
873 const struct dsdb_attribute *attr,
874 const struct ldb_message_element *in,
876 struct drsuapi_DsReplicaAttribute *out)
881 if (attr->attributeID_id == 0xFFFFFFFF) {
885 out->attid = attr->attributeID_id;
886 out->value_ctr.num_values = in->num_values;
887 out->value_ctr.values = talloc_array(mem_ctx,
888 struct drsuapi_DsAttributeValue,
890 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
892 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
893 W_ERROR_HAVE_NO_MEMORY(blobs);
895 for (i=0; i < in->num_values; i++) {
896 struct drsuapi_DsReplicaObjectIdentifier3 id3;
897 enum ndr_err_code ndr_err;
899 out->value_ctr.values[i].blob = &blobs[i];
901 /* TODO: handle id3.guid and id3.sid */
903 id3.dn = (const char *)in->values[i].data;
905 ndr_err = ndr_push_struct_blob(&blobs[i], blobs, schema->iconv_convenience, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
906 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
907 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
908 return ntstatus_to_werror(status);
915 static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(const struct dsdb_schema *schema,
916 const struct dsdb_attribute *attr,
917 const struct drsuapi_DsReplicaAttribute *in,
919 struct ldb_message_element *out)
924 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
925 W_ERROR_HAVE_NO_MEMORY(out->name);
927 out->num_values = in->value_ctr.num_values;
928 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
929 W_ERROR_HAVE_NO_MEMORY(out->values);
931 for (i=0; i < out->num_values; i++) {
932 struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
935 enum ndr_err_code ndr_err;
937 if (in->value_ctr.values[i].blob == NULL) {
941 if (in->value_ctr.values[i].blob->length == 0) {
945 ndr_err = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob,
946 out->values, schema->iconv_convenience, &id3b,
947 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary);
948 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
949 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
950 return ntstatus_to_werror(status);
953 /* TODO: handle id3.guid and id3.sid */
954 binary = data_blob_hex_string(out->values, &id3b.binary);
955 W_ERROR_HAVE_NO_MEMORY(binary);
957 str = talloc_asprintf(out->values, "B:%u:%s:%s",
958 (unsigned int)(id3b.binary.length * 2), /* because of 2 hex chars per byte */
961 W_ERROR_HAVE_NO_MEMORY(str);
963 /* TODO: handle id3.guid and id3.sid */
964 out->values[i] = data_blob_string_const(str);
970 static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(const struct dsdb_schema *schema,
971 const struct dsdb_attribute *attr,
972 const struct ldb_message_element *in,
974 struct drsuapi_DsReplicaAttribute *out)
979 if (attr->attributeID_id == 0xFFFFFFFF) {
983 out->attid = attr->attributeID_id;
984 out->value_ctr.num_values = in->num_values;
985 out->value_ctr.values = talloc_array(mem_ctx,
986 struct drsuapi_DsAttributeValue,
988 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
990 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
991 W_ERROR_HAVE_NO_MEMORY(blobs);
993 for (i=0; i < in->num_values; i++) {
994 struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
995 enum ndr_err_code ndr_err;
997 out->value_ctr.values[i].blob = &blobs[i];
999 /* TODO: handle id3b.guid and id3b.sid, id3.binary */
1001 id3b.dn = (const char *)in->values[i].data;
1002 id3b.binary = data_blob(NULL, 0);
1004 ndr_err = ndr_push_struct_blob(&blobs[i], blobs, schema->iconv_convenience, &id3b,
1005 (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary);
1006 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1007 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1008 return ntstatus_to_werror(status);
1015 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb(const struct dsdb_schema *schema,
1016 const struct dsdb_attribute *attr,
1017 const struct drsuapi_DsReplicaAttribute *in,
1018 TALLOC_CTX *mem_ctx,
1019 struct ldb_message_element *out)
1024 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1025 W_ERROR_HAVE_NO_MEMORY(out->name);
1027 out->num_values = in->value_ctr.num_values;
1028 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1029 W_ERROR_HAVE_NO_MEMORY(out->values);
1031 for (i=0; i < out->num_values; i++) {
1036 if (in->value_ctr.values[i].blob == NULL) {
1040 if (in->value_ctr.values[i].blob->length < 4) {
1044 len = IVAL(in->value_ctr.values[i].blob->data, 0);
1046 if (len != in->value_ctr.values[i].blob->length) {
1050 ret = convert_string_talloc_convenience(out->values, schema->iconv_convenience, CH_UTF16, CH_UNIX,
1051 in->value_ctr.values[i].blob->data+4,
1052 in->value_ctr.values[i].blob->length-4,
1058 out->values[i] = data_blob_string_const(str);
1064 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi(const struct dsdb_schema *schema,
1065 const struct dsdb_attribute *attr,
1066 const struct ldb_message_element *in,
1067 TALLOC_CTX *mem_ctx,
1068 struct drsuapi_DsReplicaAttribute *out)
1073 if (attr->attributeID_id == 0xFFFFFFFF) {
1077 out->attid = attr->attributeID_id;
1078 out->value_ctr.num_values = in->num_values;
1079 out->value_ctr.values = talloc_array(mem_ctx,
1080 struct drsuapi_DsAttributeValue,
1082 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1084 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1085 W_ERROR_HAVE_NO_MEMORY(blobs);
1087 for (i=0; i < in->num_values; i++) {
1091 out->value_ctr.values[i].blob = &blobs[i];
1093 ret = convert_string_talloc_convenience(blobs, schema->iconv_convenience, CH_UNIX, CH_UTF16,
1095 in->values[i].length,
1101 blobs[i] = data_blob_talloc(blobs, NULL, 4 + ret);
1102 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
1104 SIVAL(blobs[i].data, 0, 4 + ret);
1107 memcpy(blobs[i].data + 4, data, ret);
1115 #define OMOBJECTCLASS(val) { .length = sizeof(val) - 1, .data = discard_const_p(uint8_t, val) }
1117 static const struct dsdb_syntax dsdb_syntaxes[] = {
1120 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.7",
1122 .attributeSyntax_oid = "2.5.5.8",
1123 .drsuapi_to_ldb = dsdb_syntax_BOOL_drsuapi_to_ldb,
1124 .ldb_to_drsuapi = dsdb_syntax_BOOL_ldb_to_drsuapi,
1125 .equality = "booleanMatch",
1126 .comment = "Boolean"
1129 .ldap_oid = LDB_SYNTAX_INTEGER,
1131 .attributeSyntax_oid = "2.5.5.9",
1132 .drsuapi_to_ldb = dsdb_syntax_INT32_drsuapi_to_ldb,
1133 .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi,
1134 .equality = "integerMatch",
1135 .comment = "Integer",
1137 .name = "String(Octet)",
1138 .ldap_oid = LDB_SYNTAX_OCTET_STRING,
1140 .attributeSyntax_oid = "2.5.5.10",
1141 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1142 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1143 .equality = "octetStringMatch",
1144 .comment = "Octet String",
1146 .name = "String(Sid)",
1147 .ldap_oid = LDB_SYNTAX_OCTET_STRING,
1149 .attributeSyntax_oid = "2.5.5.17",
1150 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1151 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1152 .equality = "octetStringMatch",
1153 .comment = "Octet String - Security Identifier (SID)",
1154 .ldb_syntax = LDB_SYNTAX_SAMBA_SID
1156 .name = "String(Object-Identifier)",
1157 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.38",
1159 .attributeSyntax_oid = "2.5.5.2",
1160 .drsuapi_to_ldb = dsdb_syntax_OID_drsuapi_to_ldb,
1161 .ldb_to_drsuapi = dsdb_syntax_OID_ldb_to_drsuapi,
1162 .equality = "caseIgnoreMatch", /* Would use "objectIdentifierMatch" but most are ldap attribute/class names */
1163 .comment = "OID String",
1164 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING
1166 .name = "Enumeration",
1167 .ldap_oid = LDB_SYNTAX_INTEGER,
1169 .attributeSyntax_oid = "2.5.5.9",
1170 .drsuapi_to_ldb = dsdb_syntax_INT32_drsuapi_to_ldb,
1171 .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi,
1173 /* not used in w2k3 forest */
1174 .name = "String(Numeric)",
1175 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.36",
1177 .attributeSyntax_oid = "2.5.5.6",
1178 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1179 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1180 .equality = "numericStringMatch",
1181 .substring = "numericStringSubstringsMatch",
1182 .comment = "Numeric String"
1184 .name = "String(Printable)",
1185 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.44",
1187 .attributeSyntax_oid = "2.5.5.5",
1188 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1189 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1191 .name = "String(Teletex)",
1192 .ldap_oid = "1.2.840.113556.1.4.905",
1194 .attributeSyntax_oid = "2.5.5.4",
1195 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1196 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1197 .equality = "caseIgnoreMatch",
1198 .substring = "caseIgnoreSubstringsMatch",
1199 .comment = "Case Insensitive String",
1200 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING,
1202 .name = "String(IA5)",
1203 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.26",
1205 .attributeSyntax_oid = "2.5.5.5",
1206 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1207 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1208 .equality = "caseExactIA5Match",
1209 .comment = "Printable String"
1211 .name = "String(UTC-Time)",
1212 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.53",
1214 .attributeSyntax_oid = "2.5.5.11",
1215 .drsuapi_to_ldb = dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb,
1216 .ldb_to_drsuapi = dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi,
1217 .equality = "generalizedTimeMatch",
1218 .comment = "UTC Time",
1220 .name = "String(Generalized-Time)",
1221 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.24",
1223 .attributeSyntax_oid = "2.5.5.11",
1224 .drsuapi_to_ldb = dsdb_syntax_NTTIME_drsuapi_to_ldb,
1225 .ldb_to_drsuapi = dsdb_syntax_NTTIME_ldb_to_drsuapi,
1226 .equality = "generalizedTimeMatch",
1227 .comment = "Generalized Time",
1228 .ldb_syntax = LDB_SYNTAX_UTC_TIME,
1230 /* not used in w2k3 schema */
1231 .name = "String(Case Sensitive)",
1232 .ldap_oid = "1.2.840.113556.1.4.1362",
1234 .attributeSyntax_oid = "2.5.5.3",
1235 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1236 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1238 .name = "String(Unicode)",
1239 .ldap_oid = LDB_SYNTAX_DIRECTORY_STRING,
1241 .attributeSyntax_oid = "2.5.5.12",
1242 .drsuapi_to_ldb = dsdb_syntax_UNICODE_drsuapi_to_ldb,
1243 .ldb_to_drsuapi = dsdb_syntax_UNICODE_ldb_to_drsuapi,
1244 .equality = "caseIgnoreMatch",
1245 .substring = "caseIgnoreSubstringsMatch",
1246 .comment = "Directory String",
1248 .name = "Interval/LargeInteger",
1249 .ldap_oid = "1.2.840.113556.1.4.906",
1251 .attributeSyntax_oid = "2.5.5.16",
1252 .drsuapi_to_ldb = dsdb_syntax_INT64_drsuapi_to_ldb,
1253 .ldb_to_drsuapi = dsdb_syntax_INT64_ldb_to_drsuapi,
1254 .equality = "integerMatch",
1255 .comment = "Large Integer",
1256 .ldb_syntax = LDB_SYNTAX_INTEGER,
1258 .name = "String(NT-Sec-Desc)",
1259 .ldap_oid = LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR,
1261 .attributeSyntax_oid = "2.5.5.15",
1262 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1263 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1265 .name = "Object(DS-DN)",
1266 .ldap_oid = LDB_SYNTAX_DN,
1268 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x4a"),
1269 .attributeSyntax_oid = "2.5.5.1",
1270 .drsuapi_to_ldb = dsdb_syntax_DN_drsuapi_to_ldb,
1271 .ldb_to_drsuapi = dsdb_syntax_DN_ldb_to_drsuapi,
1272 .equality = "distinguishedNameMatch",
1273 .comment = "Object(DS-DN) == a DN",
1275 .name = "Object(DN-Binary)",
1276 .ldap_oid = "1.2.840.113556.1.4.903",
1278 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0b"),
1279 .attributeSyntax_oid = "2.5.5.7",
1280 .drsuapi_to_ldb = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
1281 .ldb_to_drsuapi = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
1282 .equality = "distinguishedNameMatch",
1283 .comment = "OctetString: Binary+DN",
1284 .ldb_syntax = LDB_SYNTAX_DN,
1286 /* not used in w2k3 schema */
1287 .name = "Object(OR-Name)",
1288 .ldap_oid = "1.2.840.113556.1.4.1221",
1290 .oMObjectClass = OMOBJECTCLASS("\x56\x06\x01\x02\x05\x0b\x1D"),
1291 .attributeSyntax_oid = "2.5.5.7",
1292 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1293 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1296 * TODO: verify if DATA_BLOB is correct here...!
1298 * repsFrom and repsTo are the only attributes using
1299 * this attribute syntax, but they're not replicated...
1301 .name = "Object(Replica-Link)",
1302 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.40",
1304 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x06"),
1305 .attributeSyntax_oid = "2.5.5.10",
1306 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1307 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1309 .name = "Object(Presentation-Address)",
1310 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.43",
1312 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x5c"),
1313 .attributeSyntax_oid = "2.5.5.13",
1314 .drsuapi_to_ldb = dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb,
1315 .ldb_to_drsuapi = dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi,
1316 .comment = "Presentation Address"
1318 /* not used in w2k3 schema */
1319 .name = "Object(Access-Point)",
1320 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.2",
1322 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x3e"),
1323 .attributeSyntax_oid = "2.5.5.14",
1324 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1325 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1326 .equality = "distinguishedNameMatch",
1327 .comment = "OctetString: String+DN",
1328 .ldb_syntax = LDB_SYNTAX_DN,
1330 /* not used in w2k3 schema */
1331 .name = "Object(DN-String)",
1332 .ldap_oid = "1.2.840.113556.1.4.904",
1334 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0c"),
1335 .attributeSyntax_oid = "2.5.5.14",
1336 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1337 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1338 .ldb_syntax = LDB_SYNTAX_DN,
1342 const struct dsdb_syntax *find_syntax_map_by_ad_oid(const char *ad_oid)
1345 for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
1346 if (strcasecmp(ad_oid, dsdb_syntaxes[i].attributeSyntax_oid) == 0) {
1347 return &dsdb_syntaxes[i];
1353 const struct dsdb_syntax *find_syntax_map_by_ad_syntax(int oMSyntax)
1356 for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
1357 if (oMSyntax == dsdb_syntaxes[i].oMSyntax) {
1358 return &dsdb_syntaxes[i];
1364 const struct dsdb_syntax *find_syntax_map_by_standard_oid(const char *standard_oid)
1367 for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
1368 if (strcasecmp(standard_oid, dsdb_syntaxes[i].ldap_oid) == 0) {
1369 return &dsdb_syntaxes[i];
1374 const struct dsdb_syntax *dsdb_syntax_for_attribute(const struct dsdb_attribute *attr)
1378 for (i=0; i < ARRAY_SIZE(dsdb_syntaxes); i++) {
1379 if (attr->oMSyntax != dsdb_syntaxes[i].oMSyntax) continue;
1381 if (attr->oMObjectClass.length != dsdb_syntaxes[i].oMObjectClass.length) continue;
1383 if (attr->oMObjectClass.length) {
1385 ret = memcmp(attr->oMObjectClass.data,
1386 dsdb_syntaxes[i].oMObjectClass.data,
1387 attr->oMObjectClass.length);
1388 if (ret != 0) continue;
1391 if (strcmp(attr->attributeSyntax_oid, dsdb_syntaxes[i].attributeSyntax_oid) != 0) continue;
1393 return &dsdb_syntaxes[i];
1399 WERROR dsdb_attribute_drsuapi_to_ldb(const struct dsdb_schema *schema,
1400 const struct drsuapi_DsReplicaAttribute *in,
1401 TALLOC_CTX *mem_ctx,
1402 struct ldb_message_element *out)
1404 const struct dsdb_attribute *sa;
1406 sa = dsdb_attribute_by_attributeID_id(schema, in->attid);
1411 return sa->syntax->drsuapi_to_ldb(schema, sa, in, mem_ctx, out);
1414 WERROR dsdb_attribute_ldb_to_drsuapi(const struct dsdb_schema *schema,
1415 const struct ldb_message_element *in,
1416 TALLOC_CTX *mem_ctx,
1417 struct drsuapi_DsReplicaAttribute *out)
1419 const struct dsdb_attribute *sa;
1421 sa = dsdb_attribute_by_lDAPDisplayName(schema, in->name);
1426 return sa->syntax->ldb_to_drsuapi(schema, sa, in, mem_ctx, out);