2 Unix SMB/CIFS mplementation.
5 Copyright (C) Stefan Metzmacher <metze@samba.org> 2006
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "dsdb/samdb/samdb.h"
23 #include "librpc/gen_ndr/ndr_drsuapi.h"
24 #include "lib/ldb/include/ldb.h"
25 #include "system/time.h"
26 #include "lib/charset/charset.h"
27 #include "librpc/ndr/libndr.h"
29 static WERROR dsdb_syntax_FOOBAR_drsuapi_to_ldb(const struct dsdb_schema *schema,
30 const struct dsdb_attribute *attr,
31 const struct drsuapi_DsReplicaAttribute *in,
33 struct ldb_message_element *out)
38 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
39 W_ERROR_HAVE_NO_MEMORY(out->name);
41 out->num_values = in->value_ctr.num_values;
42 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
43 W_ERROR_HAVE_NO_MEMORY(out->values);
45 for (i=0; i < out->num_values; i++) {
48 if (in->value_ctr.values[i].blob == NULL) {
52 str = talloc_asprintf(out->values, "%s: not implemented",
54 W_ERROR_HAVE_NO_MEMORY(str);
56 out->values[i] = data_blob_string_const(str);
62 static WERROR dsdb_syntax_FOOBAR_ldb_to_drsuapi(const struct dsdb_schema *schema,
63 const struct dsdb_attribute *attr,
64 const struct ldb_message_element *in,
66 struct drsuapi_DsReplicaAttribute *out)
71 static WERROR dsdb_syntax_BOOL_drsuapi_to_ldb(const struct dsdb_schema *schema,
72 const struct dsdb_attribute *attr,
73 const struct drsuapi_DsReplicaAttribute *in,
75 struct ldb_message_element *out)
80 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
81 W_ERROR_HAVE_NO_MEMORY(out->name);
83 out->num_values = in->value_ctr.num_values;
84 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
85 W_ERROR_HAVE_NO_MEMORY(out->values);
87 for (i=0; i < out->num_values; i++) {
91 if (in->value_ctr.values[i].blob == NULL) {
95 if (in->value_ctr.values[i].blob->length != 4) {
99 v = IVAL(in->value_ctr.values[i].blob->data, 0);
102 str = talloc_strdup(out->values, "TRUE");
103 W_ERROR_HAVE_NO_MEMORY(str);
105 str = talloc_strdup(out->values, "FALSE");
106 W_ERROR_HAVE_NO_MEMORY(str);
109 out->values[i] = data_blob_string_const(str);
115 static WERROR dsdb_syntax_BOOL_ldb_to_drsuapi(const struct dsdb_schema *schema,
116 const struct dsdb_attribute *attr,
117 const struct ldb_message_element *in,
119 struct drsuapi_DsReplicaAttribute *out)
124 if (attr->attributeID_id == 0xFFFFFFFF) {
128 out->attid = attr->attributeID_id;
129 out->value_ctr.num_values = in->num_values;
130 out->value_ctr.values = talloc_array(mem_ctx,
131 struct drsuapi_DsAttributeValue,
133 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
135 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
136 W_ERROR_HAVE_NO_MEMORY(blobs);
138 for (i=0; i < in->num_values; i++) {
139 out->value_ctr.values[i].blob = &blobs[i];
141 blobs[i] = data_blob_talloc(blobs, NULL, 4);
142 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
144 if (strcmp("TRUE", (const char *)in->values[i].data) == 0) {
145 SIVAL(blobs[i].data, 0, 0x00000001);
146 } else if (strcmp("FALSE", (const char *)in->values[i].data) == 0) {
147 SIVAL(blobs[i].data, 0, 0x00000000);
156 static WERROR dsdb_syntax_INT32_drsuapi_to_ldb(const struct dsdb_schema *schema,
157 const struct dsdb_attribute *attr,
158 const struct drsuapi_DsReplicaAttribute *in,
160 struct ldb_message_element *out)
165 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
166 W_ERROR_HAVE_NO_MEMORY(out->name);
168 out->num_values = in->value_ctr.num_values;
169 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
170 W_ERROR_HAVE_NO_MEMORY(out->values);
172 for (i=0; i < out->num_values; i++) {
176 if (in->value_ctr.values[i].blob == NULL) {
180 if (in->value_ctr.values[i].blob->length != 4) {
184 v = IVALS(in->value_ctr.values[i].blob->data, 0);
186 str = talloc_asprintf(out->values, "%d", v);
187 W_ERROR_HAVE_NO_MEMORY(str);
189 out->values[i] = data_blob_string_const(str);
195 static WERROR dsdb_syntax_INT32_ldb_to_drsuapi(const struct dsdb_schema *schema,
196 const struct dsdb_attribute *attr,
197 const struct ldb_message_element *in,
199 struct drsuapi_DsReplicaAttribute *out)
204 if (attr->attributeID_id == 0xFFFFFFFF) {
208 out->attid = attr->attributeID_id;
209 out->value_ctr.num_values = in->num_values;
210 out->value_ctr.values = talloc_array(mem_ctx,
211 struct drsuapi_DsAttributeValue,
213 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
215 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
216 W_ERROR_HAVE_NO_MEMORY(blobs);
218 for (i=0; i < in->num_values; i++) {
221 out->value_ctr.values[i].blob = &blobs[i];
223 blobs[i] = data_blob_talloc(blobs, NULL, 4);
224 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
226 v = strtol((const char *)in->values[i].data, NULL, 10);
228 SIVALS(blobs[i].data, 0, v);
234 static WERROR dsdb_syntax_INT64_drsuapi_to_ldb(const struct dsdb_schema *schema,
235 const struct dsdb_attribute *attr,
236 const struct drsuapi_DsReplicaAttribute *in,
238 struct ldb_message_element *out)
243 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
244 W_ERROR_HAVE_NO_MEMORY(out->name);
246 out->num_values = in->value_ctr.num_values;
247 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
248 W_ERROR_HAVE_NO_MEMORY(out->values);
250 for (i=0; i < out->num_values; i++) {
254 if (in->value_ctr.values[i].blob == NULL) {
258 if (in->value_ctr.values[i].blob->length != 8) {
262 v = BVALS(in->value_ctr.values[i].blob->data, 0);
264 str = talloc_asprintf(out->values, "%lld", v);
265 W_ERROR_HAVE_NO_MEMORY(str);
267 out->values[i] = data_blob_string_const(str);
273 static WERROR dsdb_syntax_INT64_ldb_to_drsuapi(const struct dsdb_schema *schema,
274 const struct dsdb_attribute *attr,
275 const struct ldb_message_element *in,
277 struct drsuapi_DsReplicaAttribute *out)
282 if (attr->attributeID_id == 0xFFFFFFFF) {
286 out->attid = attr->attributeID_id;
287 out->value_ctr.num_values = in->num_values;
288 out->value_ctr.values = talloc_array(mem_ctx,
289 struct drsuapi_DsAttributeValue,
291 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
293 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
294 W_ERROR_HAVE_NO_MEMORY(blobs);
296 for (i=0; i < in->num_values; i++) {
299 out->value_ctr.values[i].blob = &blobs[i];
301 blobs[i] = data_blob_talloc(blobs, NULL, 8);
302 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
304 v = strtoll((const char *)in->values[i].data, NULL, 10);
306 SBVALS(blobs[i].data, 0, v);
312 static WERROR dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb(const struct dsdb_schema *schema,
313 const struct dsdb_attribute *attr,
314 const struct drsuapi_DsReplicaAttribute *in,
316 struct ldb_message_element *out)
321 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
322 W_ERROR_HAVE_NO_MEMORY(out->name);
324 out->num_values = in->value_ctr.num_values;
325 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
326 W_ERROR_HAVE_NO_MEMORY(out->values);
328 for (i=0; i < out->num_values; i++) {
333 if (in->value_ctr.values[i].blob == NULL) {
337 if (in->value_ctr.values[i].blob->length != 8) {
341 v = BVAL(in->value_ctr.values[i].blob->data, 0);
343 t = nt_time_to_unix(v);
346 * NOTE: On a w2k3 server you can set a GeneralizedTime string
347 * via LDAP, but you get back an UTCTime string,
348 * but via DRSUAPI you get back the NTTIME_1sec value
349 * that represents the GeneralizedTime value!
351 * So if we store the UTCTime string in our ldb
352 * we'll loose information!
354 str = ldb_timestring_utc(out->values, t);
355 W_ERROR_HAVE_NO_MEMORY(str);
356 out->values[i] = data_blob_string_const(str);
362 static WERROR dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi(const struct dsdb_schema *schema,
363 const struct dsdb_attribute *attr,
364 const struct ldb_message_element *in,
366 struct drsuapi_DsReplicaAttribute *out)
371 if (attr->attributeID_id == 0xFFFFFFFF) {
375 out->attid = attr->attributeID_id;
376 out->value_ctr.num_values = in->num_values;
377 out->value_ctr.values = talloc_array(mem_ctx,
378 struct drsuapi_DsAttributeValue,
380 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
382 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
383 W_ERROR_HAVE_NO_MEMORY(blobs);
385 for (i=0; i < in->num_values; i++) {
389 out->value_ctr.values[i].blob = &blobs[i];
391 blobs[i] = data_blob_talloc(blobs, NULL, 8);
392 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
394 t = ldb_string_utc_to_time((const char *)in->values[i].data);
395 unix_to_nt_time(&v, t);
398 SBVAL(blobs[i].data, 0, v);
404 static WERROR dsdb_syntax_NTTIME_drsuapi_to_ldb(const struct dsdb_schema *schema,
405 const struct dsdb_attribute *attr,
406 const struct drsuapi_DsReplicaAttribute *in,
408 struct ldb_message_element *out)
413 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
414 W_ERROR_HAVE_NO_MEMORY(out->name);
416 out->num_values = in->value_ctr.num_values;
417 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
418 W_ERROR_HAVE_NO_MEMORY(out->values);
420 for (i=0; i < out->num_values; i++) {
425 if (in->value_ctr.values[i].blob == NULL) {
429 if (in->value_ctr.values[i].blob->length != 8) {
433 v = BVAL(in->value_ctr.values[i].blob->data, 0);
435 t = nt_time_to_unix(v);
437 str = ldb_timestring(out->values, t);
438 W_ERROR_HAVE_NO_MEMORY(str);
440 out->values[i] = data_blob_string_const(str);
446 static WERROR dsdb_syntax_NTTIME_ldb_to_drsuapi(const struct dsdb_schema *schema,
447 const struct dsdb_attribute *attr,
448 const struct ldb_message_element *in,
450 struct drsuapi_DsReplicaAttribute *out)
455 if (attr->attributeID_id == 0xFFFFFFFF) {
459 out->attid = attr->attributeID_id;
460 out->value_ctr.num_values = in->num_values;
461 out->value_ctr.values = talloc_array(mem_ctx,
462 struct drsuapi_DsAttributeValue,
464 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
466 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
467 W_ERROR_HAVE_NO_MEMORY(blobs);
469 for (i=0; i < in->num_values; i++) {
473 out->value_ctr.values[i].blob = &blobs[i];
475 blobs[i] = data_blob_talloc(blobs, NULL, 8);
476 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
478 t = ldb_string_to_time((const char *)in->values[i].data);
479 unix_to_nt_time(&v, t);
482 SBVAL(blobs[i].data, 0, v);
488 static WERROR dsdb_syntax_DATA_BLOB_drsuapi_to_ldb(const struct dsdb_schema *schema,
489 const struct dsdb_attribute *attr,
490 const struct drsuapi_DsReplicaAttribute *in,
492 struct ldb_message_element *out)
497 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
498 W_ERROR_HAVE_NO_MEMORY(out->name);
500 out->num_values = in->value_ctr.num_values;
501 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
502 W_ERROR_HAVE_NO_MEMORY(out->values);
504 for (i=0; i < out->num_values; i++) {
505 if (in->value_ctr.values[i].blob == NULL) {
509 if (in->value_ctr.values[i].blob->length == 0) {
513 out->values[i] = data_blob_dup_talloc(out->values,
514 in->value_ctr.values[i].blob);
515 W_ERROR_HAVE_NO_MEMORY(out->values[i].data);
521 static WERROR dsdb_syntax_DATA_BLOB_ldb_to_drsuapi(const struct dsdb_schema *schema,
522 const struct dsdb_attribute *attr,
523 const struct ldb_message_element *in,
525 struct drsuapi_DsReplicaAttribute *out)
530 if (attr->attributeID_id == 0xFFFFFFFF) {
534 out->attid = attr->attributeID_id;
535 out->value_ctr.num_values = in->num_values;
536 out->value_ctr.values = talloc_array(mem_ctx,
537 struct drsuapi_DsAttributeValue,
539 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
541 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
542 W_ERROR_HAVE_NO_MEMORY(blobs);
544 for (i=0; i < in->num_values; i++) {
545 out->value_ctr.values[i].blob = &blobs[i];
547 blobs[i] = data_blob_dup_talloc(blobs, &in->values[i]);
548 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
554 static WERROR _dsdb_syntax_OID_obj_drsuapi_to_ldb(const struct dsdb_schema *schema,
555 const struct dsdb_attribute *attr,
556 const struct drsuapi_DsReplicaAttribute *in,
558 struct ldb_message_element *out)
563 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
564 W_ERROR_HAVE_NO_MEMORY(out->name);
566 out->num_values = in->value_ctr.num_values;
567 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
568 W_ERROR_HAVE_NO_MEMORY(out->values);
570 for (i=0; i < out->num_values; i++) {
572 const struct dsdb_class *c;
575 if (in->value_ctr.values[i].blob == NULL) {
579 if (in->value_ctr.values[i].blob->length != 4) {
583 v = IVAL(in->value_ctr.values[i].blob->data, 0);
585 c = dsdb_class_by_governsID_id(schema, v);
590 str = talloc_strdup(out->values, c->lDAPDisplayName);
591 W_ERROR_HAVE_NO_MEMORY(str);
593 /* the values need to be reversed */
594 out->values[out->num_values - (i + 1)] = data_blob_string_const(str);
600 static WERROR _dsdb_syntax_OID_oid_drsuapi_to_ldb(const struct dsdb_schema *schema,
601 const struct dsdb_attribute *attr,
602 const struct drsuapi_DsReplicaAttribute *in,
604 struct ldb_message_element *out)
609 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
610 W_ERROR_HAVE_NO_MEMORY(out->name);
612 out->num_values = in->value_ctr.num_values;
613 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
614 W_ERROR_HAVE_NO_MEMORY(out->values);
616 for (i=0; i < out->num_values; i++) {
621 if (in->value_ctr.values[i].blob == NULL) {
625 if (in->value_ctr.values[i].blob->length != 4) {
629 v = IVAL(in->value_ctr.values[i].blob->data, 0);
631 status = dsdb_map_int2oid(schema, v, out->values, &str);
632 W_ERROR_NOT_OK_RETURN(status);
634 out->values[i] = data_blob_string_const(str);
640 static WERROR dsdb_syntax_OID_drsuapi_to_ldb(const struct dsdb_schema *schema,
641 const struct dsdb_attribute *attr,
642 const struct drsuapi_DsReplicaAttribute *in,
644 struct ldb_message_element *out)
648 switch (attr->attributeID_id) {
649 case DRSUAPI_ATTRIBUTE_objectClass:
650 return _dsdb_syntax_OID_obj_drsuapi_to_ldb(schema, attr, in, mem_ctx, out);
651 case DRSUAPI_ATTRIBUTE_governsID:
652 case DRSUAPI_ATTRIBUTE_attributeID:
653 case DRSUAPI_ATTRIBUTE_attributeSyntax:
654 return _dsdb_syntax_OID_oid_drsuapi_to_ldb(schema, attr, in, mem_ctx, out);
658 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
659 W_ERROR_HAVE_NO_MEMORY(out->name);
661 out->num_values = in->value_ctr.num_values;
662 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
663 W_ERROR_HAVE_NO_MEMORY(out->values);
665 for (i=0; i < out->num_values; i++) {
670 if (in->value_ctr.values[i].blob == NULL) {
674 if (in->value_ctr.values[i].blob->length != 4) {
678 v = IVAL(in->value_ctr.values[i].blob->data, 0);
680 name = dsdb_lDAPDisplayName_by_id(schema, v);
685 str = talloc_strdup(out->values, name);
686 W_ERROR_HAVE_NO_MEMORY(str);
688 out->values[i] = data_blob_string_const(str);
694 static WERROR dsdb_syntax_OID_ldb_to_drsuapi(const struct dsdb_schema *schema,
695 const struct dsdb_attribute *attr,
696 const struct ldb_message_element *in,
698 struct drsuapi_DsReplicaAttribute *out)
703 if (attr->attributeID_id == 0xFFFFFFFF) {
707 switch (attr->attributeID_id) {
708 case DRSUAPI_ATTRIBUTE_objectClass:
709 case DRSUAPI_ATTRIBUTE_governsID:
710 case DRSUAPI_ATTRIBUTE_attributeID:
711 case DRSUAPI_ATTRIBUTE_attributeSyntax:
712 return dsdb_syntax_FOOBAR_ldb_to_drsuapi(schema, attr, in, mem_ctx, out);
715 out->attid = attr->attributeID_id;
716 out->value_ctr.num_values = in->num_values;
717 out->value_ctr.values = talloc_array(mem_ctx,
718 struct drsuapi_DsAttributeValue,
720 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
722 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
723 W_ERROR_HAVE_NO_MEMORY(blobs);
725 for (i=0; i < in->num_values; i++) {
728 out->value_ctr.values[i].blob = &blobs[i];
730 blobs[i] = data_blob_talloc(blobs, NULL, 4);
731 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
733 v = strtol((const char *)in->values[i].data, NULL, 10);
735 SIVAL(blobs[i].data, 0, v);
741 static WERROR dsdb_syntax_UNICODE_drsuapi_to_ldb(const struct dsdb_schema *schema,
742 const struct dsdb_attribute *attr,
743 const struct drsuapi_DsReplicaAttribute *in,
745 struct ldb_message_element *out)
750 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
751 W_ERROR_HAVE_NO_MEMORY(out->name);
753 out->num_values = in->value_ctr.num_values;
754 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
755 W_ERROR_HAVE_NO_MEMORY(out->values);
757 for (i=0; i < out->num_values; i++) {
761 if (in->value_ctr.values[i].blob == NULL) {
765 if (in->value_ctr.values[i].blob->length == 0) {
769 ret = convert_string_talloc(out->values, CH_UTF16, CH_UNIX,
770 in->value_ctr.values[i].blob->data,
771 in->value_ctr.values[i].blob->length,
777 out->values[i] = data_blob_string_const(str);
783 static WERROR dsdb_syntax_UNICODE_ldb_to_drsuapi(const struct dsdb_schema *schema,
784 const struct dsdb_attribute *attr,
785 const struct ldb_message_element *in,
787 struct drsuapi_DsReplicaAttribute *out)
792 if (attr->attributeID_id == 0xFFFFFFFF) {
796 out->attid = attr->attributeID_id;
797 out->value_ctr.num_values = in->num_values;
798 out->value_ctr.values = talloc_array(mem_ctx,
799 struct drsuapi_DsAttributeValue,
801 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
803 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
804 W_ERROR_HAVE_NO_MEMORY(blobs);
806 for (i=0; i < in->num_values; i++) {
809 out->value_ctr.values[i].blob = &blobs[i];
811 ret = convert_string_talloc(blobs, CH_UNIX, CH_UTF16,
813 in->values[i].length,
814 (void **)&blobs[i].data);
818 blobs[i].length = ret;
824 static WERROR dsdb_syntax_DN_drsuapi_to_ldb(const struct dsdb_schema *schema,
825 const struct dsdb_attribute *attr,
826 const struct drsuapi_DsReplicaAttribute *in,
828 struct ldb_message_element *out)
833 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
834 W_ERROR_HAVE_NO_MEMORY(out->name);
836 out->num_values = in->value_ctr.num_values;
837 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
838 W_ERROR_HAVE_NO_MEMORY(out->values);
840 for (i=0; i < out->num_values; i++) {
841 struct drsuapi_DsReplicaObjectIdentifier3 id3;
844 if (in->value_ctr.values[i].blob == NULL) {
848 if (in->value_ctr.values[i].blob->length == 0) {
852 status = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob,
854 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3);
855 if (!NT_STATUS_IS_OK(status)) {
856 return ntstatus_to_werror(status);
859 /* TODO: handle id3.guid and id3.sid */
860 out->values[i] = data_blob_string_const(id3.dn);
866 static WERROR dsdb_syntax_DN_ldb_to_drsuapi(const struct dsdb_schema *schema,
867 const struct dsdb_attribute *attr,
868 const struct ldb_message_element *in,
870 struct drsuapi_DsReplicaAttribute *out)
875 if (attr->attributeID_id == 0xFFFFFFFF) {
879 out->attid = attr->attributeID_id;
880 out->value_ctr.num_values = in->num_values;
881 out->value_ctr.values = talloc_array(mem_ctx,
882 struct drsuapi_DsAttributeValue,
884 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
886 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
887 W_ERROR_HAVE_NO_MEMORY(blobs);
889 for (i=0; i < in->num_values; i++) {
891 struct drsuapi_DsReplicaObjectIdentifier3 id3;
893 out->value_ctr.values[i].blob = &blobs[i];
895 /* TODO: handle id3.guid and id3.sid */
897 id3.dn = (const char *)in->values[i].data;
899 status = ndr_push_struct_blob(&blobs[i], blobs, &id3,
900 (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
901 if (!NT_STATUS_IS_OK(status)) {
902 return ntstatus_to_werror(status);
909 static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(const struct dsdb_schema *schema,
910 const struct dsdb_attribute *attr,
911 const struct drsuapi_DsReplicaAttribute *in,
913 struct ldb_message_element *out)
918 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
919 W_ERROR_HAVE_NO_MEMORY(out->name);
921 out->num_values = in->value_ctr.num_values;
922 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
923 W_ERROR_HAVE_NO_MEMORY(out->values);
925 for (i=0; i < out->num_values; i++) {
926 struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
931 if (in->value_ctr.values[i].blob == NULL) {
935 if (in->value_ctr.values[i].blob->length == 0) {
939 status = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob,
941 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary);
942 if (!NT_STATUS_IS_OK(status)) {
943 return ntstatus_to_werror(status);
946 /* TODO: handle id3.guid and id3.sid */
947 binary = data_blob_hex_string(out->values, &id3b.binary);
948 W_ERROR_HAVE_NO_MEMORY(binary);
950 str = talloc_asprintf(out->values, "B:%u:%s:%s",
951 id3b.binary.length * 2, /* because of 2 hex chars per byte */
954 W_ERROR_HAVE_NO_MEMORY(str);
956 /* TODO: handle id3.guid and id3.sid */
957 out->values[i] = data_blob_string_const(str);
963 static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(const struct dsdb_schema *schema,
964 const struct dsdb_attribute *attr,
965 const struct ldb_message_element *in,
967 struct drsuapi_DsReplicaAttribute *out)
972 if (attr->attributeID_id == 0xFFFFFFFF) {
976 out->attid = attr->attributeID_id;
977 out->value_ctr.num_values = in->num_values;
978 out->value_ctr.values = talloc_array(mem_ctx,
979 struct drsuapi_DsAttributeValue,
981 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
983 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
984 W_ERROR_HAVE_NO_MEMORY(blobs);
986 for (i=0; i < in->num_values; i++) {
988 struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
990 out->value_ctr.values[i].blob = &blobs[i];
992 /* TODO: handle id3b.guid and id3b.sid, id3.binary */
994 id3b.dn = (const char *)in->values[i].data;
995 id3b.binary = data_blob(NULL, 0);
997 status = ndr_push_struct_blob(&blobs[i], blobs, &id3b,
998 (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary);
999 if (!NT_STATUS_IS_OK(status)) {
1000 return ntstatus_to_werror(status);
1007 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb(const struct dsdb_schema *schema,
1008 const struct dsdb_attribute *attr,
1009 const struct drsuapi_DsReplicaAttribute *in,
1010 TALLOC_CTX *mem_ctx,
1011 struct ldb_message_element *out)
1016 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1017 W_ERROR_HAVE_NO_MEMORY(out->name);
1019 out->num_values = in->value_ctr.num_values;
1020 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1021 W_ERROR_HAVE_NO_MEMORY(out->values);
1023 for (i=0; i < out->num_values; i++) {
1028 if (in->value_ctr.values[i].blob == NULL) {
1032 if (in->value_ctr.values[i].blob->length < 4) {
1036 len = IVAL(in->value_ctr.values[i].blob->data, 0);
1038 if (len != in->value_ctr.values[i].blob->length) {
1042 ret = convert_string_talloc(out->values, CH_UTF16, CH_UNIX,
1043 in->value_ctr.values[i].blob->data+4,
1044 in->value_ctr.values[i].blob->length-4,
1050 out->values[i] = data_blob_string_const(str);
1056 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi(const struct dsdb_schema *schema,
1057 const struct dsdb_attribute *attr,
1058 const struct ldb_message_element *in,
1059 TALLOC_CTX *mem_ctx,
1060 struct drsuapi_DsReplicaAttribute *out)
1065 if (attr->attributeID_id == 0xFFFFFFFF) {
1069 out->attid = attr->attributeID_id;
1070 out->value_ctr.num_values = in->num_values;
1071 out->value_ctr.values = talloc_array(mem_ctx,
1072 struct drsuapi_DsAttributeValue,
1074 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1076 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1077 W_ERROR_HAVE_NO_MEMORY(blobs);
1079 for (i=0; i < in->num_values; i++) {
1083 out->value_ctr.values[i].blob = &blobs[i];
1085 ret = convert_string_talloc(blobs, CH_UNIX, CH_UTF16,
1087 in->values[i].length,
1093 blobs[i] = data_blob_talloc(blobs, NULL, 4 + ret);
1094 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
1096 SIVAL(blobs[i].data, 0, 4 + ret);
1099 memcpy(blobs[i].data + 4, data, ret);
1108 #define OMOBJECTCLASS(val) { .length = sizeof(val) - 1, .data = discard_const_p(uint8_t, val) }
1110 static const struct dsdb_syntax dsdb_syntaxes[] = {
1113 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.7",
1115 .attributeSyntax_oid = "2.5.5.8",
1116 .drsuapi_to_ldb = dsdb_syntax_BOOL_drsuapi_to_ldb,
1117 .ldb_to_drsuapi = dsdb_syntax_BOOL_ldb_to_drsuapi,
1120 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.27",
1122 .attributeSyntax_oid = "2.5.5.9",
1123 .drsuapi_to_ldb = dsdb_syntax_INT32_drsuapi_to_ldb,
1124 .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi,
1126 .name = "String(Octet)",
1127 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.40",
1129 .attributeSyntax_oid = "2.5.5.10",
1130 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1131 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1133 .name = "String(Sid)",
1134 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.40",
1136 .attributeSyntax_oid = "2.5.5.17",
1137 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1138 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1140 .name = "String(Object-Identifier)",
1141 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.38",
1143 .attributeSyntax_oid = "2.5.5.2",
1144 .drsuapi_to_ldb = dsdb_syntax_OID_drsuapi_to_ldb,
1145 .ldb_to_drsuapi = dsdb_syntax_OID_ldb_to_drsuapi,
1147 .name = "Enumeration",
1148 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.27",
1150 .attributeSyntax_oid = "2.5.5.9",
1151 .drsuapi_to_ldb = dsdb_syntax_INT32_drsuapi_to_ldb,
1152 .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi,
1154 /* not used in w2k3 forest */
1155 .name = "String(Numeric)",
1156 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.36",
1158 .attributeSyntax_oid = "2.5.5.6",
1159 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1160 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1162 .name = "String(Printable)",
1163 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.44",
1165 .attributeSyntax_oid = "2.5.5.5",
1166 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1167 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1169 .name = "String(Teletex)",
1170 .ldap_oid = "1.2.840.113556.1.4.905",
1172 .attributeSyntax_oid = "2.5.5.4",
1173 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1174 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1176 .name = "String(IA5)",
1177 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.26",
1179 .attributeSyntax_oid = "2.5.5.5",
1180 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1181 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1183 .name = "String(UTC-Time)",
1184 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.53",
1186 .attributeSyntax_oid = "2.5.5.11",
1187 .drsuapi_to_ldb = dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb,
1188 .ldb_to_drsuapi = dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi,
1190 .name = "String(Generalized-Time)",
1191 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.24",
1193 .attributeSyntax_oid = "2.5.5.11",
1194 .drsuapi_to_ldb = dsdb_syntax_NTTIME_drsuapi_to_ldb,
1195 .ldb_to_drsuapi = dsdb_syntax_NTTIME_ldb_to_drsuapi,
1197 /* not used in w2k3 schema */
1198 .name = "String(Case Sensitive)",
1199 .ldap_oid = "1.2.840.113556.1.4.1362",
1201 .attributeSyntax_oid = "2.5.5.3",
1202 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1203 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1205 .name = "String(Unicode)",
1206 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.15",
1208 .attributeSyntax_oid = "2.5.5.12",
1209 .drsuapi_to_ldb = dsdb_syntax_UNICODE_drsuapi_to_ldb,
1210 .ldb_to_drsuapi = dsdb_syntax_UNICODE_ldb_to_drsuapi,
1212 .name = "Interval/LargeInteger",
1213 .ldap_oid = "1.2.840.113556.1.4.906",
1215 .attributeSyntax_oid = "2.5.5.16",
1216 .drsuapi_to_ldb = dsdb_syntax_INT64_drsuapi_to_ldb,
1217 .ldb_to_drsuapi = dsdb_syntax_INT64_ldb_to_drsuapi,
1219 .name = "String(NT-Sec-Desc)",
1220 .ldap_oid = "1.2.840.113556.1.4.907",
1222 .attributeSyntax_oid = "2.5.5.15",
1223 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1224 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1226 .name = "Object(DS-DN)",
1227 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.12",
1229 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x4a"),
1230 .attributeSyntax_oid = "2.5.5.1",
1231 .drsuapi_to_ldb = dsdb_syntax_DN_drsuapi_to_ldb,
1232 .ldb_to_drsuapi = dsdb_syntax_DN_ldb_to_drsuapi,
1234 .name = "Object(DN-Binary)",
1235 .ldap_oid = "1.2.840.113556.1.4.903",
1237 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0b"),
1238 .attributeSyntax_oid = "2.5.5.7",
1239 .drsuapi_to_ldb = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
1240 .ldb_to_drsuapi = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
1242 /* not used in w2k3 schema */
1243 .name = "Object(OR-Name)",
1244 .ldap_oid = "1.2.840.113556.1.4.1221",
1246 .oMObjectClass = OMOBJECTCLASS("\x56\x06\x01\x02\x05\x0b\x1D"),
1247 .attributeSyntax_oid = "2.5.5.7",
1248 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1249 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1252 * TODO: verify if DATA_BLOB is correct here...!
1254 * repsFrom and repsTo are the only attributes using
1255 * this attribute syntax, but they're not replicated...
1257 .name = "Object(Replica-Link)",
1258 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.40",
1260 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x06"),
1261 .attributeSyntax_oid = "2.5.5.10",
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(Presentation-Address)",
1266 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.43",
1268 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x5c"),
1269 .attributeSyntax_oid = "2.5.5.13",
1270 .drsuapi_to_ldb = dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb,
1271 .ldb_to_drsuapi = dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi,
1273 /* not used in w2k3 schema */
1274 .name = "Object(Access-Point)",
1275 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.2",
1277 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x3e"),
1278 .attributeSyntax_oid = "2.5.5.14",
1279 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1280 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1282 /* not used in w2k3 schema */
1283 .name = "Object(DN-String)",
1284 .ldap_oid = "1.2.840.113556.1.4.904",
1286 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0c"),
1287 .attributeSyntax_oid = "2.5.5.14",
1288 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1289 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1293 const struct dsdb_syntax *dsdb_syntax_for_attribute(const struct dsdb_attribute *attr)
1297 for (i=0; i < ARRAY_SIZE(dsdb_syntaxes); i++) {
1298 if (attr->oMSyntax != dsdb_syntaxes[i].oMSyntax) continue;
1300 if (attr->oMObjectClass.length != dsdb_syntaxes[i].oMObjectClass.length) continue;
1302 if (attr->oMObjectClass.length) {
1304 ret = memcmp(attr->oMObjectClass.data,
1305 dsdb_syntaxes[i].oMObjectClass.data,
1306 attr->oMObjectClass.length);
1307 if (ret != 0) continue;
1310 if (strcmp(attr->attributeSyntax_oid, dsdb_syntaxes[i].attributeSyntax_oid) != 0) continue;
1312 return &dsdb_syntaxes[i];
1318 WERROR dsdb_attribute_drsuapi_to_ldb(const struct dsdb_schema *schema,
1319 const struct drsuapi_DsReplicaAttribute *in,
1320 TALLOC_CTX *mem_ctx,
1321 struct ldb_message_element *out)
1323 const struct dsdb_attribute *sa;
1325 sa = dsdb_attribute_by_attributeID_id(schema, in->attid);
1330 return sa->syntax->drsuapi_to_ldb(schema, sa, in, mem_ctx, out);
1333 WERROR dsdb_attribute_ldb_to_drsuapi(const struct dsdb_schema *schema,
1334 const struct ldb_message_element *in,
1335 TALLOC_CTX *mem_ctx,
1336 struct drsuapi_DsReplicaAttribute *out)
1338 const struct dsdb_attribute *sa;
1340 sa = dsdb_attribute_by_lDAPDisplayName(schema, in->name);
1345 return sa->syntax->ldb_to_drsuapi(schema, sa, in, mem_ctx, out);