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 2 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, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "dsdb/samdb/samdb.h"
24 #include "librpc/gen_ndr/ndr_drsuapi.h"
25 #include "lib/ldb/include/ldb.h"
26 #include "system/time.h"
27 #include "lib/charset/charset.h"
28 #include "librpc/ndr/libndr.h"
30 static WERROR dsdb_syntax_FOOBAR_drsuapi_to_ldb(const struct dsdb_schema *schema,
31 const struct dsdb_attribute *attr,
32 const struct drsuapi_DsReplicaAttribute *in,
34 struct ldb_message_element *out)
39 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
40 W_ERROR_HAVE_NO_MEMORY(out->name);
42 out->num_values = in->value_ctr.num_values;
43 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
44 W_ERROR_HAVE_NO_MEMORY(out->values);
46 for (i=0; i < out->num_values; i++) {
49 if (in->value_ctr.values[i].blob == NULL) {
53 str = talloc_asprintf(out->values, "%s: not implemented",
55 W_ERROR_HAVE_NO_MEMORY(str);
57 out->values[i] = data_blob_string_const(str);
63 static WERROR dsdb_syntax_FOOBAR_ldb_to_drsuapi(const struct dsdb_schema *schema,
64 const struct dsdb_attribute *attr,
65 const struct ldb_message_element *in,
67 struct drsuapi_DsReplicaAttribute *out)
72 static WERROR dsdb_syntax_BOOL_drsuapi_to_ldb(const struct dsdb_schema *schema,
73 const struct dsdb_attribute *attr,
74 const struct drsuapi_DsReplicaAttribute *in,
76 struct ldb_message_element *out)
81 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
82 W_ERROR_HAVE_NO_MEMORY(out->name);
84 out->num_values = in->value_ctr.num_values;
85 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
86 W_ERROR_HAVE_NO_MEMORY(out->values);
88 for (i=0; i < out->num_values; i++) {
92 if (in->value_ctr.values[i].blob == NULL) {
96 if (in->value_ctr.values[i].blob->length != 4) {
100 v = IVAL(in->value_ctr.values[i].blob->data, 0);
103 str = talloc_strdup(out->values, "TRUE");
104 W_ERROR_HAVE_NO_MEMORY(str);
106 str = talloc_strdup(out->values, "FALSE");
107 W_ERROR_HAVE_NO_MEMORY(str);
110 out->values[i] = data_blob_string_const(str);
116 static WERROR dsdb_syntax_BOOL_ldb_to_drsuapi(const struct dsdb_schema *schema,
117 const struct dsdb_attribute *attr,
118 const struct ldb_message_element *in,
120 struct drsuapi_DsReplicaAttribute *out)
125 if (attr->attributeID_id == 0xFFFFFFFF) {
129 out->attid = attr->attributeID_id;
130 out->value_ctr.num_values = in->num_values;
131 out->value_ctr.values = talloc_array(mem_ctx,
132 struct drsuapi_DsAttributeValue,
134 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
136 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
137 W_ERROR_HAVE_NO_MEMORY(blobs);
139 for (i=0; i < in->num_values; i++) {
140 out->value_ctr.values[i].blob = &blobs[i];
142 blobs[i] = data_blob_talloc(blobs, NULL, 4);
143 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
145 if (strcmp("TRUE", (const char *)in->values[i].data) == 0) {
146 SIVAL(blobs[i].data, 0, 0x00000001);
147 } else if (strcmp("FALSE", (const char *)in->values[i].data) == 0) {
148 SIVAL(blobs[i].data, 0, 0x00000000);
157 static WERROR dsdb_syntax_INT32_drsuapi_to_ldb(const struct dsdb_schema *schema,
158 const struct dsdb_attribute *attr,
159 const struct drsuapi_DsReplicaAttribute *in,
161 struct ldb_message_element *out)
166 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
167 W_ERROR_HAVE_NO_MEMORY(out->name);
169 out->num_values = in->value_ctr.num_values;
170 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
171 W_ERROR_HAVE_NO_MEMORY(out->values);
173 for (i=0; i < out->num_values; i++) {
177 if (in->value_ctr.values[i].blob == NULL) {
181 if (in->value_ctr.values[i].blob->length != 4) {
185 v = IVALS(in->value_ctr.values[i].blob->data, 0);
187 str = talloc_asprintf(out->values, "%d", v);
188 W_ERROR_HAVE_NO_MEMORY(str);
190 out->values[i] = data_blob_string_const(str);
196 static WERROR dsdb_syntax_INT32_ldb_to_drsuapi(const struct dsdb_schema *schema,
197 const struct dsdb_attribute *attr,
198 const struct ldb_message_element *in,
200 struct drsuapi_DsReplicaAttribute *out)
205 if (attr->attributeID_id == 0xFFFFFFFF) {
209 out->attid = attr->attributeID_id;
210 out->value_ctr.num_values = in->num_values;
211 out->value_ctr.values = talloc_array(mem_ctx,
212 struct drsuapi_DsAttributeValue,
214 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
216 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
217 W_ERROR_HAVE_NO_MEMORY(blobs);
219 for (i=0; i < in->num_values; i++) {
222 out->value_ctr.values[i].blob = &blobs[i];
224 blobs[i] = data_blob_talloc(blobs, NULL, 4);
225 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
227 v = strtol((const char *)in->values[i].data, NULL, 10);
229 SIVALS(blobs[i].data, 0, v);
235 static WERROR dsdb_syntax_INT64_drsuapi_to_ldb(const struct dsdb_schema *schema,
236 const struct dsdb_attribute *attr,
237 const struct drsuapi_DsReplicaAttribute *in,
239 struct ldb_message_element *out)
244 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
245 W_ERROR_HAVE_NO_MEMORY(out->name);
247 out->num_values = in->value_ctr.num_values;
248 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
249 W_ERROR_HAVE_NO_MEMORY(out->values);
251 for (i=0; i < out->num_values; i++) {
255 if (in->value_ctr.values[i].blob == NULL) {
259 if (in->value_ctr.values[i].blob->length != 8) {
263 v = BVALS(in->value_ctr.values[i].blob->data, 0);
265 str = talloc_asprintf(out->values, "%lld", v);
266 W_ERROR_HAVE_NO_MEMORY(str);
268 out->values[i] = data_blob_string_const(str);
274 static WERROR dsdb_syntax_INT64_ldb_to_drsuapi(const struct dsdb_schema *schema,
275 const struct dsdb_attribute *attr,
276 const struct ldb_message_element *in,
278 struct drsuapi_DsReplicaAttribute *out)
283 if (attr->attributeID_id == 0xFFFFFFFF) {
287 out->attid = attr->attributeID_id;
288 out->value_ctr.num_values = in->num_values;
289 out->value_ctr.values = talloc_array(mem_ctx,
290 struct drsuapi_DsAttributeValue,
292 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
294 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
295 W_ERROR_HAVE_NO_MEMORY(blobs);
297 for (i=0; i < in->num_values; i++) {
300 out->value_ctr.values[i].blob = &blobs[i];
302 blobs[i] = data_blob_talloc(blobs, NULL, 8);
303 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
305 v = strtoll((const char *)in->values[i].data, NULL, 10);
307 SBVALS(blobs[i].data, 0, v);
313 static WERROR dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb(const struct dsdb_schema *schema,
314 const struct dsdb_attribute *attr,
315 const struct drsuapi_DsReplicaAttribute *in,
317 struct ldb_message_element *out)
322 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
323 W_ERROR_HAVE_NO_MEMORY(out->name);
325 out->num_values = in->value_ctr.num_values;
326 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
327 W_ERROR_HAVE_NO_MEMORY(out->values);
329 for (i=0; i < out->num_values; i++) {
334 if (in->value_ctr.values[i].blob == NULL) {
338 if (in->value_ctr.values[i].blob->length != 8) {
342 v = BVAL(in->value_ctr.values[i].blob->data, 0);
344 t = nt_time_to_unix(v);
347 * NOTE: On a w2k3 server you can set a GeneralizedTime string
348 * via LDAP, but you get back an UTCTime string,
349 * but via DRSUAPI you get back the NTTIME_1sec value
350 * that represents the GeneralizedTime value!
352 * So if we store the UTCTime string in our ldb
353 * we'll loose information!
355 str = ldb_timestring_utc(out->values, t);
356 W_ERROR_HAVE_NO_MEMORY(str);
357 out->values[i] = data_blob_string_const(str);
363 static WERROR dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi(const struct dsdb_schema *schema,
364 const struct dsdb_attribute *attr,
365 const struct ldb_message_element *in,
367 struct drsuapi_DsReplicaAttribute *out)
372 if (attr->attributeID_id == 0xFFFFFFFF) {
376 out->attid = attr->attributeID_id;
377 out->value_ctr.num_values = in->num_values;
378 out->value_ctr.values = talloc_array(mem_ctx,
379 struct drsuapi_DsAttributeValue,
381 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
383 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
384 W_ERROR_HAVE_NO_MEMORY(blobs);
386 for (i=0; i < in->num_values; i++) {
390 out->value_ctr.values[i].blob = &blobs[i];
392 blobs[i] = data_blob_talloc(blobs, NULL, 8);
393 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
395 t = ldb_string_utc_to_time((const char *)in->values[i].data);
396 unix_to_nt_time(&v, t);
399 SBVAL(blobs[i].data, 0, v);
405 static WERROR dsdb_syntax_NTTIME_drsuapi_to_ldb(const struct dsdb_schema *schema,
406 const struct dsdb_attribute *attr,
407 const struct drsuapi_DsReplicaAttribute *in,
409 struct ldb_message_element *out)
414 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
415 W_ERROR_HAVE_NO_MEMORY(out->name);
417 out->num_values = in->value_ctr.num_values;
418 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
419 W_ERROR_HAVE_NO_MEMORY(out->values);
421 for (i=0; i < out->num_values; i++) {
426 if (in->value_ctr.values[i].blob == NULL) {
430 if (in->value_ctr.values[i].blob->length != 8) {
434 v = BVAL(in->value_ctr.values[i].blob->data, 0);
436 t = nt_time_to_unix(v);
438 str = ldb_timestring(out->values, t);
439 W_ERROR_HAVE_NO_MEMORY(str);
441 out->values[i] = data_blob_string_const(str);
447 static WERROR dsdb_syntax_NTTIME_ldb_to_drsuapi(const struct dsdb_schema *schema,
448 const struct dsdb_attribute *attr,
449 const struct ldb_message_element *in,
451 struct drsuapi_DsReplicaAttribute *out)
456 if (attr->attributeID_id == 0xFFFFFFFF) {
460 out->attid = attr->attributeID_id;
461 out->value_ctr.num_values = in->num_values;
462 out->value_ctr.values = talloc_array(mem_ctx,
463 struct drsuapi_DsAttributeValue,
465 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
467 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
468 W_ERROR_HAVE_NO_MEMORY(blobs);
470 for (i=0; i < in->num_values; i++) {
474 out->value_ctr.values[i].blob = &blobs[i];
476 blobs[i] = data_blob_talloc(blobs, NULL, 8);
477 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
479 t = ldb_string_to_time((const char *)in->values[i].data);
480 unix_to_nt_time(&v, t);
483 SBVAL(blobs[i].data, 0, v);
489 static WERROR dsdb_syntax_DATA_BLOB_drsuapi_to_ldb(const struct dsdb_schema *schema,
490 const struct dsdb_attribute *attr,
491 const struct drsuapi_DsReplicaAttribute *in,
493 struct ldb_message_element *out)
498 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
499 W_ERROR_HAVE_NO_MEMORY(out->name);
501 out->num_values = in->value_ctr.num_values;
502 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
503 W_ERROR_HAVE_NO_MEMORY(out->values);
505 for (i=0; i < out->num_values; i++) {
506 if (in->value_ctr.values[i].blob == NULL) {
510 if (in->value_ctr.values[i].blob->length == 0) {
514 out->values[i] = data_blob_dup_talloc(out->values,
515 in->value_ctr.values[i].blob);
516 W_ERROR_HAVE_NO_MEMORY(out->values[i].data);
522 static WERROR dsdb_syntax_DATA_BLOB_ldb_to_drsuapi(const struct dsdb_schema *schema,
523 const struct dsdb_attribute *attr,
524 const struct ldb_message_element *in,
526 struct drsuapi_DsReplicaAttribute *out)
531 if (attr->attributeID_id == 0xFFFFFFFF) {
535 out->attid = attr->attributeID_id;
536 out->value_ctr.num_values = in->num_values;
537 out->value_ctr.values = talloc_array(mem_ctx,
538 struct drsuapi_DsAttributeValue,
540 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
542 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
543 W_ERROR_HAVE_NO_MEMORY(blobs);
545 for (i=0; i < in->num_values; i++) {
546 out->value_ctr.values[i].blob = &blobs[i];
548 blobs[i] = data_blob_dup_talloc(blobs, &in->values[i]);
549 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
555 static WERROR _dsdb_syntax_OID_obj_drsuapi_to_ldb(const struct dsdb_schema *schema,
556 const struct dsdb_attribute *attr,
557 const struct drsuapi_DsReplicaAttribute *in,
559 struct ldb_message_element *out)
564 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
565 W_ERROR_HAVE_NO_MEMORY(out->name);
567 out->num_values = in->value_ctr.num_values;
568 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
569 W_ERROR_HAVE_NO_MEMORY(out->values);
571 for (i=0; i < out->num_values; i++) {
573 const struct dsdb_class *c;
576 if (in->value_ctr.values[i].blob == NULL) {
580 if (in->value_ctr.values[i].blob->length != 4) {
584 v = IVAL(in->value_ctr.values[i].blob->data, 0);
586 c = dsdb_class_by_governsID_id(schema, v);
591 str = talloc_strdup(out->values, c->lDAPDisplayName);
592 W_ERROR_HAVE_NO_MEMORY(str);
594 /* the values need to be reversed */
595 out->values[out->num_values - (i + 1)] = data_blob_string_const(str);
601 static WERROR _dsdb_syntax_OID_oid_drsuapi_to_ldb(const struct dsdb_schema *schema,
602 const struct dsdb_attribute *attr,
603 const struct drsuapi_DsReplicaAttribute *in,
605 struct ldb_message_element *out)
610 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
611 W_ERROR_HAVE_NO_MEMORY(out->name);
613 out->num_values = in->value_ctr.num_values;
614 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
615 W_ERROR_HAVE_NO_MEMORY(out->values);
617 for (i=0; i < out->num_values; i++) {
622 if (in->value_ctr.values[i].blob == NULL) {
626 if (in->value_ctr.values[i].blob->length != 4) {
630 v = IVAL(in->value_ctr.values[i].blob->data, 0);
632 status = dsdb_map_int2oid(schema, v, out->values, &str);
633 W_ERROR_NOT_OK_RETURN(status);
635 out->values[i] = data_blob_string_const(str);
641 static WERROR dsdb_syntax_OID_drsuapi_to_ldb(const struct dsdb_schema *schema,
642 const struct dsdb_attribute *attr,
643 const struct drsuapi_DsReplicaAttribute *in,
645 struct ldb_message_element *out)
649 switch (attr->attributeID_id) {
650 case DRSUAPI_ATTRIBUTE_objectClass:
651 return _dsdb_syntax_OID_obj_drsuapi_to_ldb(schema, attr, in, mem_ctx, out);
652 case DRSUAPI_ATTRIBUTE_governsID:
653 case DRSUAPI_ATTRIBUTE_attributeID:
654 case DRSUAPI_ATTRIBUTE_attributeSyntax:
655 return _dsdb_syntax_OID_oid_drsuapi_to_ldb(schema, attr, in, mem_ctx, out);
659 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
660 W_ERROR_HAVE_NO_MEMORY(out->name);
662 out->num_values = in->value_ctr.num_values;
663 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
664 W_ERROR_HAVE_NO_MEMORY(out->values);
666 for (i=0; i < out->num_values; i++) {
671 if (in->value_ctr.values[i].blob == NULL) {
675 if (in->value_ctr.values[i].blob->length != 4) {
679 v = IVAL(in->value_ctr.values[i].blob->data, 0);
681 name = dsdb_lDAPDisplayName_by_id(schema, v);
686 str = talloc_strdup(out->values, name);
687 W_ERROR_HAVE_NO_MEMORY(str);
689 out->values[i] = data_blob_string_const(str);
695 static WERROR dsdb_syntax_OID_ldb_to_drsuapi(const struct dsdb_schema *schema,
696 const struct dsdb_attribute *attr,
697 const struct ldb_message_element *in,
699 struct drsuapi_DsReplicaAttribute *out)
704 if (attr->attributeID_id == 0xFFFFFFFF) {
708 switch (attr->attributeID_id) {
709 case DRSUAPI_ATTRIBUTE_objectClass:
710 case DRSUAPI_ATTRIBUTE_governsID:
711 case DRSUAPI_ATTRIBUTE_attributeID:
712 case DRSUAPI_ATTRIBUTE_attributeSyntax:
713 return dsdb_syntax_FOOBAR_ldb_to_drsuapi(schema, attr, in, mem_ctx, out);
716 out->attid = attr->attributeID_id;
717 out->value_ctr.num_values = in->num_values;
718 out->value_ctr.values = talloc_array(mem_ctx,
719 struct drsuapi_DsAttributeValue,
721 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
723 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
724 W_ERROR_HAVE_NO_MEMORY(blobs);
726 for (i=0; i < in->num_values; i++) {
729 out->value_ctr.values[i].blob = &blobs[i];
731 blobs[i] = data_blob_talloc(blobs, NULL, 4);
732 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
734 v = strtol((const char *)in->values[i].data, NULL, 10);
736 SIVAL(blobs[i].data, 0, v);
742 static WERROR dsdb_syntax_UNICODE_drsuapi_to_ldb(const struct dsdb_schema *schema,
743 const struct dsdb_attribute *attr,
744 const struct drsuapi_DsReplicaAttribute *in,
746 struct ldb_message_element *out)
751 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
752 W_ERROR_HAVE_NO_MEMORY(out->name);
754 out->num_values = in->value_ctr.num_values;
755 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
756 W_ERROR_HAVE_NO_MEMORY(out->values);
758 for (i=0; i < out->num_values; i++) {
762 if (in->value_ctr.values[i].blob == NULL) {
766 if (in->value_ctr.values[i].blob->length == 0) {
770 ret = convert_string_talloc(out->values, CH_UTF16, CH_UNIX,
771 in->value_ctr.values[i].blob->data,
772 in->value_ctr.values[i].blob->length,
778 out->values[i] = data_blob_string_const(str);
784 static WERROR dsdb_syntax_UNICODE_ldb_to_drsuapi(const struct dsdb_schema *schema,
785 const struct dsdb_attribute *attr,
786 const struct ldb_message_element *in,
788 struct drsuapi_DsReplicaAttribute *out)
793 if (attr->attributeID_id == 0xFFFFFFFF) {
797 out->attid = attr->attributeID_id;
798 out->value_ctr.num_values = in->num_values;
799 out->value_ctr.values = talloc_array(mem_ctx,
800 struct drsuapi_DsAttributeValue,
802 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
804 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
805 W_ERROR_HAVE_NO_MEMORY(blobs);
807 for (i=0; i < in->num_values; i++) {
810 out->value_ctr.values[i].blob = &blobs[i];
812 ret = convert_string_talloc(blobs, CH_UNIX, CH_UTF16,
814 in->values[i].length,
815 (void **)&blobs[i].data);
819 blobs[i].length = ret;
825 static WERROR dsdb_syntax_DN_drsuapi_to_ldb(const struct dsdb_schema *schema,
826 const struct dsdb_attribute *attr,
827 const struct drsuapi_DsReplicaAttribute *in,
829 struct ldb_message_element *out)
834 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
835 W_ERROR_HAVE_NO_MEMORY(out->name);
837 out->num_values = in->value_ctr.num_values;
838 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
839 W_ERROR_HAVE_NO_MEMORY(out->values);
841 for (i=0; i < out->num_values; i++) {
842 struct drsuapi_DsReplicaObjectIdentifier3 id3;
845 if (in->value_ctr.values[i].blob == NULL) {
849 if (in->value_ctr.values[i].blob->length == 0) {
853 status = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob,
855 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3);
856 if (!NT_STATUS_IS_OK(status)) {
857 return ntstatus_to_werror(status);
860 /* TODO: handle id3.guid and id3.sid */
861 out->values[i] = data_blob_string_const(id3.dn);
867 static WERROR dsdb_syntax_DN_ldb_to_drsuapi(const struct dsdb_schema *schema,
868 const struct dsdb_attribute *attr,
869 const struct ldb_message_element *in,
871 struct drsuapi_DsReplicaAttribute *out)
876 if (attr->attributeID_id == 0xFFFFFFFF) {
880 out->attid = attr->attributeID_id;
881 out->value_ctr.num_values = in->num_values;
882 out->value_ctr.values = talloc_array(mem_ctx,
883 struct drsuapi_DsAttributeValue,
885 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
887 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
888 W_ERROR_HAVE_NO_MEMORY(blobs);
890 for (i=0; i < in->num_values; i++) {
892 struct drsuapi_DsReplicaObjectIdentifier3 id3;
894 out->value_ctr.values[i].blob = &blobs[i];
896 /* TODO: handle id3.guid and id3.sid */
898 id3.dn = (const char *)in->values[i].data;
900 status = ndr_push_struct_blob(&blobs[i], blobs, &id3,
901 (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
902 if (!NT_STATUS_IS_OK(status)) {
903 return ntstatus_to_werror(status);
910 static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(const struct dsdb_schema *schema,
911 const struct dsdb_attribute *attr,
912 const struct drsuapi_DsReplicaAttribute *in,
914 struct ldb_message_element *out)
919 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
920 W_ERROR_HAVE_NO_MEMORY(out->name);
922 out->num_values = in->value_ctr.num_values;
923 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
924 W_ERROR_HAVE_NO_MEMORY(out->values);
926 for (i=0; i < out->num_values; i++) {
927 struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
932 if (in->value_ctr.values[i].blob == NULL) {
936 if (in->value_ctr.values[i].blob->length == 0) {
940 status = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob,
942 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary);
943 if (!NT_STATUS_IS_OK(status)) {
944 return ntstatus_to_werror(status);
947 /* TODO: handle id3.guid and id3.sid */
948 binary = data_blob_hex_string(out->values, &id3b.binary);
949 W_ERROR_HAVE_NO_MEMORY(binary);
951 str = talloc_asprintf(out->values, "B:%u:%s:%s",
952 id3b.binary.length * 2, /* because of 2 hex chars per byte */
955 W_ERROR_HAVE_NO_MEMORY(str);
957 /* TODO: handle id3.guid and id3.sid */
958 out->values[i] = data_blob_string_const(str);
964 static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(const struct dsdb_schema *schema,
965 const struct dsdb_attribute *attr,
966 const struct ldb_message_element *in,
968 struct drsuapi_DsReplicaAttribute *out)
973 if (attr->attributeID_id == 0xFFFFFFFF) {
977 out->attid = attr->attributeID_id;
978 out->value_ctr.num_values = in->num_values;
979 out->value_ctr.values = talloc_array(mem_ctx,
980 struct drsuapi_DsAttributeValue,
982 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
984 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
985 W_ERROR_HAVE_NO_MEMORY(blobs);
987 for (i=0; i < in->num_values; i++) {
989 struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
991 out->value_ctr.values[i].blob = &blobs[i];
993 /* TODO: handle id3b.guid and id3b.sid, id3.binary */
995 id3b.dn = (const char *)in->values[i].data;
996 id3b.binary = data_blob(NULL, 0);
998 status = ndr_push_struct_blob(&blobs[i], blobs, &id3b,
999 (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary);
1000 if (!NT_STATUS_IS_OK(status)) {
1001 return ntstatus_to_werror(status);
1008 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb(const struct dsdb_schema *schema,
1009 const struct dsdb_attribute *attr,
1010 const struct drsuapi_DsReplicaAttribute *in,
1011 TALLOC_CTX *mem_ctx,
1012 struct ldb_message_element *out)
1017 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1018 W_ERROR_HAVE_NO_MEMORY(out->name);
1020 out->num_values = in->value_ctr.num_values;
1021 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1022 W_ERROR_HAVE_NO_MEMORY(out->values);
1024 for (i=0; i < out->num_values; i++) {
1029 if (in->value_ctr.values[i].blob == NULL) {
1033 if (in->value_ctr.values[i].blob->length < 4) {
1037 len = IVAL(in->value_ctr.values[i].blob->data, 0);
1039 if (len != in->value_ctr.values[i].blob->length) {
1043 ret = convert_string_talloc(out->values, CH_UTF16, CH_UNIX,
1044 in->value_ctr.values[i].blob->data+4,
1045 in->value_ctr.values[i].blob->length-4,
1051 out->values[i] = data_blob_string_const(str);
1057 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi(const struct dsdb_schema *schema,
1058 const struct dsdb_attribute *attr,
1059 const struct ldb_message_element *in,
1060 TALLOC_CTX *mem_ctx,
1061 struct drsuapi_DsReplicaAttribute *out)
1066 if (attr->attributeID_id == 0xFFFFFFFF) {
1070 out->attid = attr->attributeID_id;
1071 out->value_ctr.num_values = in->num_values;
1072 out->value_ctr.values = talloc_array(mem_ctx,
1073 struct drsuapi_DsAttributeValue,
1075 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1077 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1078 W_ERROR_HAVE_NO_MEMORY(blobs);
1080 for (i=0; i < in->num_values; i++) {
1084 out->value_ctr.values[i].blob = &blobs[i];
1086 ret = convert_string_talloc(blobs, CH_UNIX, CH_UTF16,
1088 in->values[i].length,
1094 blobs[i] = data_blob_talloc(blobs, NULL, 4 + ret);
1095 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
1097 SIVAL(blobs[i].data, 0, 4 + ret);
1100 memcpy(blobs[i].data + 4, data, ret);
1109 #define OMOBJECTCLASS(val) { .length = sizeof(val) - 1, .data = discard_const_p(uint8_t, val) }
1111 static const struct dsdb_syntax dsdb_syntaxes[] = {
1114 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.7",
1116 .attributeSyntax_oid = "2.5.5.8",
1117 .drsuapi_to_ldb = dsdb_syntax_BOOL_drsuapi_to_ldb,
1118 .ldb_to_drsuapi = dsdb_syntax_BOOL_ldb_to_drsuapi,
1121 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.27",
1123 .attributeSyntax_oid = "2.5.5.9",
1124 .drsuapi_to_ldb = dsdb_syntax_INT32_drsuapi_to_ldb,
1125 .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi,
1127 .name = "String(Octet)",
1128 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.40",
1130 .attributeSyntax_oid = "2.5.5.10",
1131 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1132 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1134 .name = "String(Sid)",
1135 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.40",
1137 .attributeSyntax_oid = "2.5.5.17",
1138 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1139 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1141 .name = "String(Object-Identifier)",
1142 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.38",
1144 .attributeSyntax_oid = "2.5.5.2",
1145 .drsuapi_to_ldb = dsdb_syntax_OID_drsuapi_to_ldb,
1146 .ldb_to_drsuapi = dsdb_syntax_OID_ldb_to_drsuapi,
1148 .name = "Enumeration",
1149 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.27",
1151 .attributeSyntax_oid = "2.5.5.9",
1152 .drsuapi_to_ldb = dsdb_syntax_INT32_drsuapi_to_ldb,
1153 .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi,
1155 /* not used in w2k3 forest */
1156 .name = "String(Numeric)",
1157 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.36",
1159 .attributeSyntax_oid = "2.5.5.6",
1160 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1161 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1163 .name = "String(Printable)",
1164 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.44",
1166 .attributeSyntax_oid = "2.5.5.5",
1167 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1168 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1170 .name = "String(Teletex)",
1171 .ldap_oid = "1.2.840.113556.1.4.905",
1173 .attributeSyntax_oid = "2.5.5.4",
1174 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1175 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1177 .name = "String(IA5)",
1178 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.26",
1180 .attributeSyntax_oid = "2.5.5.5",
1181 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1182 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1184 .name = "String(UTC-Time)",
1185 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.53",
1187 .attributeSyntax_oid = "2.5.5.11",
1188 .drsuapi_to_ldb = dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb,
1189 .ldb_to_drsuapi = dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi,
1191 .name = "String(Generalized-Time)",
1192 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.24",
1194 .attributeSyntax_oid = "2.5.5.11",
1195 .drsuapi_to_ldb = dsdb_syntax_NTTIME_drsuapi_to_ldb,
1196 .ldb_to_drsuapi = dsdb_syntax_NTTIME_ldb_to_drsuapi,
1198 /* not used in w2k3 schema */
1199 .name = "String(Case Sensitive)",
1200 .ldap_oid = "1.2.840.113556.1.4.1362",
1202 .attributeSyntax_oid = "2.5.5.3",
1203 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1204 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1206 .name = "String(Unicode)",
1207 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.15",
1209 .attributeSyntax_oid = "2.5.5.12",
1210 .drsuapi_to_ldb = dsdb_syntax_UNICODE_drsuapi_to_ldb,
1211 .ldb_to_drsuapi = dsdb_syntax_UNICODE_ldb_to_drsuapi,
1213 .name = "Interval/LargeInteger",
1214 .ldap_oid = "1.2.840.113556.1.4.906",
1216 .attributeSyntax_oid = "2.5.5.16",
1217 .drsuapi_to_ldb = dsdb_syntax_INT64_drsuapi_to_ldb,
1218 .ldb_to_drsuapi = dsdb_syntax_INT64_ldb_to_drsuapi,
1220 .name = "String(NT-Sec-Desc)",
1221 .ldap_oid = "1.2.840.113556.1.4.907",
1223 .attributeSyntax_oid = "2.5.5.15",
1224 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1225 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1227 .name = "Object(DS-DN)",
1228 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.12",
1230 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x4a"),
1231 .attributeSyntax_oid = "2.5.5.1",
1232 .drsuapi_to_ldb = dsdb_syntax_DN_drsuapi_to_ldb,
1233 .ldb_to_drsuapi = dsdb_syntax_DN_ldb_to_drsuapi,
1235 .name = "Object(DN-Binary)",
1236 .ldap_oid = "1.2.840.113556.1.4.903",
1238 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0b"),
1239 .attributeSyntax_oid = "2.5.5.7",
1240 .drsuapi_to_ldb = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
1241 .ldb_to_drsuapi = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
1243 /* not used in w2k3 schema */
1244 .name = "Object(OR-Name)",
1245 .ldap_oid = "1.2.840.113556.1.4.1221",
1247 .oMObjectClass = OMOBJECTCLASS("\x56\x06\x01\x02\x05\x0b\x1D"),
1248 .attributeSyntax_oid = "2.5.5.7",
1249 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1250 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1253 * TODO: verify if DATA_BLOB is correct here...!
1255 * repsFrom and repsTo are the only attributes using
1256 * this attribute syntax, but they're not replicated...
1258 .name = "Object(Replica-Link)",
1259 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.40",
1261 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x06"),
1262 .attributeSyntax_oid = "2.5.5.10",
1263 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1264 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1266 .name = "Object(Presentation-Address)",
1267 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.43",
1269 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x5c"),
1270 .attributeSyntax_oid = "2.5.5.13",
1271 .drsuapi_to_ldb = dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb,
1272 .ldb_to_drsuapi = dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi,
1274 /* not used in w2k3 schema */
1275 .name = "Object(Access-Point)",
1276 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.2",
1278 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x3e"),
1279 .attributeSyntax_oid = "2.5.5.14",
1280 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1281 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1283 /* not used in w2k3 schema */
1284 .name = "Object(DN-String)",
1285 .ldap_oid = "1.2.840.113556.1.4.904",
1287 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0c"),
1288 .attributeSyntax_oid = "2.5.5.14",
1289 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1290 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1294 const struct dsdb_syntax *dsdb_syntax_for_attribute(const struct dsdb_attribute *attr)
1298 for (i=0; i < ARRAY_SIZE(dsdb_syntaxes); i++) {
1299 if (attr->oMSyntax != dsdb_syntaxes[i].oMSyntax) continue;
1301 if (attr->oMObjectClass.length != dsdb_syntaxes[i].oMObjectClass.length) continue;
1303 if (attr->oMObjectClass.length) {
1305 ret = memcmp(attr->oMObjectClass.data,
1306 dsdb_syntaxes[i].oMObjectClass.data,
1307 attr->oMObjectClass.length);
1308 if (ret != 0) continue;
1311 if (strcmp(attr->attributeSyntax_oid, dsdb_syntaxes[i].attributeSyntax_oid) != 0) continue;
1313 return &dsdb_syntaxes[i];
1319 WERROR dsdb_attribute_drsuapi_to_ldb(const struct dsdb_schema *schema,
1320 const struct drsuapi_DsReplicaAttribute *in,
1321 TALLOC_CTX *mem_ctx,
1322 struct ldb_message_element *out)
1324 const struct dsdb_attribute *sa;
1326 sa = dsdb_attribute_by_attributeID_id(schema, in->attid);
1331 return sa->syntax->drsuapi_to_ldb(schema, sa, in, mem_ctx, out);
1334 WERROR dsdb_attribute_ldb_to_drsuapi(const struct dsdb_schema *schema,
1335 const struct ldb_message_element *in,
1336 TALLOC_CTX *mem_ctx,
1337 struct drsuapi_DsReplicaAttribute *out)
1339 const struct dsdb_attribute *sa;
1341 sa = dsdb_attribute_by_lDAPDisplayName(schema, in->name);
1346 return sa->syntax->ldb_to_drsuapi(schema, sa, in, mem_ctx, out);