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"
28 #include "param/param.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", (long long int)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, lp_iconv_convenience(global_loadparm), 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, lp_iconv_convenience(global_loadparm), 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;
843 enum ndr_err_code ndr_err;
845 if (in->value_ctr.values[i].blob == NULL) {
849 if (in->value_ctr.values[i].blob->length == 0) {
853 ndr_err = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob,
854 out->values, lp_iconv_convenience(global_loadparm), &id3,
855 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3);
856 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
857 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
858 return ntstatus_to_werror(status);
861 /* TODO: handle id3.guid and id3.sid */
862 out->values[i] = data_blob_string_const(id3.dn);
868 static WERROR dsdb_syntax_DN_ldb_to_drsuapi(const struct dsdb_schema *schema,
869 const struct dsdb_attribute *attr,
870 const struct ldb_message_element *in,
872 struct drsuapi_DsReplicaAttribute *out)
877 if (attr->attributeID_id == 0xFFFFFFFF) {
881 out->attid = attr->attributeID_id;
882 out->value_ctr.num_values = in->num_values;
883 out->value_ctr.values = talloc_array(mem_ctx,
884 struct drsuapi_DsAttributeValue,
886 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
888 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
889 W_ERROR_HAVE_NO_MEMORY(blobs);
891 for (i=0; i < in->num_values; i++) {
892 struct drsuapi_DsReplicaObjectIdentifier3 id3;
893 enum ndr_err_code ndr_err;
895 out->value_ctr.values[i].blob = &blobs[i];
897 /* TODO: handle id3.guid and id3.sid */
899 id3.dn = (const char *)in->values[i].data;
901 ndr_err = ndr_push_struct_blob(&blobs[i], blobs, lp_iconv_convenience(global_loadparm), &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
902 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
903 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
904 return ntstatus_to_werror(status);
911 static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(const struct dsdb_schema *schema,
912 const struct dsdb_attribute *attr,
913 const struct drsuapi_DsReplicaAttribute *in,
915 struct ldb_message_element *out)
920 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
921 W_ERROR_HAVE_NO_MEMORY(out->name);
923 out->num_values = in->value_ctr.num_values;
924 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
925 W_ERROR_HAVE_NO_MEMORY(out->values);
927 for (i=0; i < out->num_values; i++) {
928 struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
931 enum ndr_err_code ndr_err;
933 if (in->value_ctr.values[i].blob == NULL) {
937 if (in->value_ctr.values[i].blob->length == 0) {
941 ndr_err = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob,
942 out->values, NULL, &id3b,
943 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary);
944 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
945 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
946 return ntstatus_to_werror(status);
949 /* TODO: handle id3.guid and id3.sid */
950 binary = data_blob_hex_string(out->values, &id3b.binary);
951 W_ERROR_HAVE_NO_MEMORY(binary);
953 str = talloc_asprintf(out->values, "B:%u:%s:%s",
954 (unsigned int)(id3b.binary.length * 2), /* because of 2 hex chars per byte */
957 W_ERROR_HAVE_NO_MEMORY(str);
959 /* TODO: handle id3.guid and id3.sid */
960 out->values[i] = data_blob_string_const(str);
966 static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(const struct dsdb_schema *schema,
967 const struct dsdb_attribute *attr,
968 const struct ldb_message_element *in,
970 struct drsuapi_DsReplicaAttribute *out)
975 if (attr->attributeID_id == 0xFFFFFFFF) {
979 out->attid = attr->attributeID_id;
980 out->value_ctr.num_values = in->num_values;
981 out->value_ctr.values = talloc_array(mem_ctx,
982 struct drsuapi_DsAttributeValue,
984 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
986 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
987 W_ERROR_HAVE_NO_MEMORY(blobs);
989 for (i=0; i < in->num_values; i++) {
990 struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
991 enum ndr_err_code ndr_err;
993 out->value_ctr.values[i].blob = &blobs[i];
995 /* TODO: handle id3b.guid and id3b.sid, id3.binary */
997 id3b.dn = (const char *)in->values[i].data;
998 id3b.binary = data_blob(NULL, 0);
1000 ndr_err = ndr_push_struct_blob(&blobs[i], blobs, NULL, &id3b,
1001 (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary);
1002 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1003 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1004 return ntstatus_to_werror(status);
1011 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb(const struct dsdb_schema *schema,
1012 const struct dsdb_attribute *attr,
1013 const struct drsuapi_DsReplicaAttribute *in,
1014 TALLOC_CTX *mem_ctx,
1015 struct ldb_message_element *out)
1020 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1021 W_ERROR_HAVE_NO_MEMORY(out->name);
1023 out->num_values = in->value_ctr.num_values;
1024 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1025 W_ERROR_HAVE_NO_MEMORY(out->values);
1027 for (i=0; i < out->num_values; i++) {
1032 if (in->value_ctr.values[i].blob == NULL) {
1036 if (in->value_ctr.values[i].blob->length < 4) {
1040 len = IVAL(in->value_ctr.values[i].blob->data, 0);
1042 if (len != in->value_ctr.values[i].blob->length) {
1046 ret = convert_string_talloc(out->values, lp_iconv_convenience(global_loadparm), CH_UTF16, CH_UNIX,
1047 in->value_ctr.values[i].blob->data+4,
1048 in->value_ctr.values[i].blob->length-4,
1054 out->values[i] = data_blob_string_const(str);
1060 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi(const struct dsdb_schema *schema,
1061 const struct dsdb_attribute *attr,
1062 const struct ldb_message_element *in,
1063 TALLOC_CTX *mem_ctx,
1064 struct drsuapi_DsReplicaAttribute *out)
1069 if (attr->attributeID_id == 0xFFFFFFFF) {
1073 out->attid = attr->attributeID_id;
1074 out->value_ctr.num_values = in->num_values;
1075 out->value_ctr.values = talloc_array(mem_ctx,
1076 struct drsuapi_DsAttributeValue,
1078 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1080 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1081 W_ERROR_HAVE_NO_MEMORY(blobs);
1083 for (i=0; i < in->num_values; i++) {
1087 out->value_ctr.values[i].blob = &blobs[i];
1089 ret = convert_string_talloc(blobs, lp_iconv_convenience(global_loadparm), CH_UNIX, CH_UTF16,
1091 in->values[i].length,
1097 blobs[i] = data_blob_talloc(blobs, NULL, 4 + ret);
1098 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
1100 SIVAL(blobs[i].data, 0, 4 + ret);
1103 memcpy(blobs[i].data + 4, data, ret);
1112 #define OMOBJECTCLASS(val) { .length = sizeof(val) - 1, .data = discard_const_p(uint8_t, val) }
1114 static const struct dsdb_syntax dsdb_syntaxes[] = {
1117 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.7",
1119 .attributeSyntax_oid = "2.5.5.8",
1120 .drsuapi_to_ldb = dsdb_syntax_BOOL_drsuapi_to_ldb,
1121 .ldb_to_drsuapi = dsdb_syntax_BOOL_ldb_to_drsuapi,
1124 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.27",
1126 .attributeSyntax_oid = "2.5.5.9",
1127 .drsuapi_to_ldb = dsdb_syntax_INT32_drsuapi_to_ldb,
1128 .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi,
1130 .name = "String(Octet)",
1131 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.40",
1133 .attributeSyntax_oid = "2.5.5.10",
1134 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1135 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1137 .name = "String(Sid)",
1138 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.40",
1140 .attributeSyntax_oid = "2.5.5.17",
1141 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1142 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1144 .name = "String(Object-Identifier)",
1145 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.38",
1147 .attributeSyntax_oid = "2.5.5.2",
1148 .drsuapi_to_ldb = dsdb_syntax_OID_drsuapi_to_ldb,
1149 .ldb_to_drsuapi = dsdb_syntax_OID_ldb_to_drsuapi,
1151 .name = "Enumeration",
1152 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.27",
1154 .attributeSyntax_oid = "2.5.5.9",
1155 .drsuapi_to_ldb = dsdb_syntax_INT32_drsuapi_to_ldb,
1156 .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi,
1158 /* not used in w2k3 forest */
1159 .name = "String(Numeric)",
1160 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.36",
1162 .attributeSyntax_oid = "2.5.5.6",
1163 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1164 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1166 .name = "String(Printable)",
1167 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.44",
1169 .attributeSyntax_oid = "2.5.5.5",
1170 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1171 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1173 .name = "String(Teletex)",
1174 .ldap_oid = "1.2.840.113556.1.4.905",
1176 .attributeSyntax_oid = "2.5.5.4",
1177 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1178 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1180 .name = "String(IA5)",
1181 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.26",
1183 .attributeSyntax_oid = "2.5.5.5",
1184 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1185 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1187 .name = "String(UTC-Time)",
1188 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.53",
1190 .attributeSyntax_oid = "2.5.5.11",
1191 .drsuapi_to_ldb = dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb,
1192 .ldb_to_drsuapi = dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi,
1194 .name = "String(Generalized-Time)",
1195 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.24",
1197 .attributeSyntax_oid = "2.5.5.11",
1198 .drsuapi_to_ldb = dsdb_syntax_NTTIME_drsuapi_to_ldb,
1199 .ldb_to_drsuapi = dsdb_syntax_NTTIME_ldb_to_drsuapi,
1201 /* not used in w2k3 schema */
1202 .name = "String(Case Sensitive)",
1203 .ldap_oid = "1.2.840.113556.1.4.1362",
1205 .attributeSyntax_oid = "2.5.5.3",
1206 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1207 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1209 .name = "String(Unicode)",
1210 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.15",
1212 .attributeSyntax_oid = "2.5.5.12",
1213 .drsuapi_to_ldb = dsdb_syntax_UNICODE_drsuapi_to_ldb,
1214 .ldb_to_drsuapi = dsdb_syntax_UNICODE_ldb_to_drsuapi,
1216 .name = "Interval/LargeInteger",
1217 .ldap_oid = "1.2.840.113556.1.4.906",
1219 .attributeSyntax_oid = "2.5.5.16",
1220 .drsuapi_to_ldb = dsdb_syntax_INT64_drsuapi_to_ldb,
1221 .ldb_to_drsuapi = dsdb_syntax_INT64_ldb_to_drsuapi,
1223 .name = "String(NT-Sec-Desc)",
1224 .ldap_oid = "1.2.840.113556.1.4.907",
1226 .attributeSyntax_oid = "2.5.5.15",
1227 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1228 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1230 .name = "Object(DS-DN)",
1231 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.12",
1233 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x4a"),
1234 .attributeSyntax_oid = "2.5.5.1",
1235 .drsuapi_to_ldb = dsdb_syntax_DN_drsuapi_to_ldb,
1236 .ldb_to_drsuapi = dsdb_syntax_DN_ldb_to_drsuapi,
1238 .name = "Object(DN-Binary)",
1239 .ldap_oid = "1.2.840.113556.1.4.903",
1241 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0b"),
1242 .attributeSyntax_oid = "2.5.5.7",
1243 .drsuapi_to_ldb = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
1244 .ldb_to_drsuapi = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
1246 /* not used in w2k3 schema */
1247 .name = "Object(OR-Name)",
1248 .ldap_oid = "1.2.840.113556.1.4.1221",
1250 .oMObjectClass = OMOBJECTCLASS("\x56\x06\x01\x02\x05\x0b\x1D"),
1251 .attributeSyntax_oid = "2.5.5.7",
1252 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1253 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1256 * TODO: verify if DATA_BLOB is correct here...!
1258 * repsFrom and repsTo are the only attributes using
1259 * this attribute syntax, but they're not replicated...
1261 .name = "Object(Replica-Link)",
1262 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.40",
1264 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x06"),
1265 .attributeSyntax_oid = "2.5.5.10",
1266 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1267 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1269 .name = "Object(Presentation-Address)",
1270 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.43",
1272 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x5c"),
1273 .attributeSyntax_oid = "2.5.5.13",
1274 .drsuapi_to_ldb = dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb,
1275 .ldb_to_drsuapi = dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi,
1277 /* not used in w2k3 schema */
1278 .name = "Object(Access-Point)",
1279 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.2",
1281 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x3e"),
1282 .attributeSyntax_oid = "2.5.5.14",
1283 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1284 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1286 /* not used in w2k3 schema */
1287 .name = "Object(DN-String)",
1288 .ldap_oid = "1.2.840.113556.1.4.904",
1290 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0c"),
1291 .attributeSyntax_oid = "2.5.5.14",
1292 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1293 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1297 const struct dsdb_syntax *dsdb_syntax_for_attribute(const struct dsdb_attribute *attr)
1301 for (i=0; i < ARRAY_SIZE(dsdb_syntaxes); i++) {
1302 if (attr->oMSyntax != dsdb_syntaxes[i].oMSyntax) continue;
1304 if (attr->oMObjectClass.length != dsdb_syntaxes[i].oMObjectClass.length) continue;
1306 if (attr->oMObjectClass.length) {
1308 ret = memcmp(attr->oMObjectClass.data,
1309 dsdb_syntaxes[i].oMObjectClass.data,
1310 attr->oMObjectClass.length);
1311 if (ret != 0) continue;
1314 if (strcmp(attr->attributeSyntax_oid, dsdb_syntaxes[i].attributeSyntax_oid) != 0) continue;
1316 return &dsdb_syntaxes[i];
1322 WERROR dsdb_attribute_drsuapi_to_ldb(const struct dsdb_schema *schema,
1323 const struct drsuapi_DsReplicaAttribute *in,
1324 TALLOC_CTX *mem_ctx,
1325 struct ldb_message_element *out)
1327 const struct dsdb_attribute *sa;
1329 sa = dsdb_attribute_by_attributeID_id(schema, in->attid);
1334 return sa->syntax->drsuapi_to_ldb(schema, sa, in, mem_ctx, out);
1337 WERROR dsdb_attribute_ldb_to_drsuapi(const struct dsdb_schema *schema,
1338 const struct ldb_message_element *in,
1339 TALLOC_CTX *mem_ctx,
1340 struct drsuapi_DsReplicaAttribute *out)
1342 const struct dsdb_attribute *sa;
1344 sa = dsdb_attribute_by_lDAPDisplayName(schema, in->name);
1349 return sa->syntax->ldb_to_drsuapi(schema, sa, in, mem_ctx, out);