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,
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, &id3,
902 (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
903 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
904 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
905 return ntstatus_to_werror(status);
912 static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(const struct dsdb_schema *schema,
913 const struct dsdb_attribute *attr,
914 const struct drsuapi_DsReplicaAttribute *in,
916 struct ldb_message_element *out)
921 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
922 W_ERROR_HAVE_NO_MEMORY(out->name);
924 out->num_values = in->value_ctr.num_values;
925 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
926 W_ERROR_HAVE_NO_MEMORY(out->values);
928 for (i=0; i < out->num_values; i++) {
929 struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
932 enum ndr_err_code ndr_err;
934 if (in->value_ctr.values[i].blob == NULL) {
938 if (in->value_ctr.values[i].blob->length == 0) {
942 ndr_err = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob,
944 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary);
945 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
946 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
947 return ntstatus_to_werror(status);
950 /* TODO: handle id3.guid and id3.sid */
951 binary = data_blob_hex_string(out->values, &id3b.binary);
952 W_ERROR_HAVE_NO_MEMORY(binary);
954 str = talloc_asprintf(out->values, "B:%u:%s:%s",
955 (unsigned int)(id3b.binary.length * 2), /* because of 2 hex chars per byte */
958 W_ERROR_HAVE_NO_MEMORY(str);
960 /* TODO: handle id3.guid and id3.sid */
961 out->values[i] = data_blob_string_const(str);
967 static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(const struct dsdb_schema *schema,
968 const struct dsdb_attribute *attr,
969 const struct ldb_message_element *in,
971 struct drsuapi_DsReplicaAttribute *out)
976 if (attr->attributeID_id == 0xFFFFFFFF) {
980 out->attid = attr->attributeID_id;
981 out->value_ctr.num_values = in->num_values;
982 out->value_ctr.values = talloc_array(mem_ctx,
983 struct drsuapi_DsAttributeValue,
985 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
987 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
988 W_ERROR_HAVE_NO_MEMORY(blobs);
990 for (i=0; i < in->num_values; i++) {
991 struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
992 enum ndr_err_code ndr_err;
994 out->value_ctr.values[i].blob = &blobs[i];
996 /* TODO: handle id3b.guid and id3b.sid, id3.binary */
998 id3b.dn = (const char *)in->values[i].data;
999 id3b.binary = data_blob(NULL, 0);
1001 ndr_err = ndr_push_struct_blob(&blobs[i], blobs, &id3b,
1002 (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary);
1003 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1004 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1005 return ntstatus_to_werror(status);
1012 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb(const struct dsdb_schema *schema,
1013 const struct dsdb_attribute *attr,
1014 const struct drsuapi_DsReplicaAttribute *in,
1015 TALLOC_CTX *mem_ctx,
1016 struct ldb_message_element *out)
1021 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1022 W_ERROR_HAVE_NO_MEMORY(out->name);
1024 out->num_values = in->value_ctr.num_values;
1025 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1026 W_ERROR_HAVE_NO_MEMORY(out->values);
1028 for (i=0; i < out->num_values; i++) {
1033 if (in->value_ctr.values[i].blob == NULL) {
1037 if (in->value_ctr.values[i].blob->length < 4) {
1041 len = IVAL(in->value_ctr.values[i].blob->data, 0);
1043 if (len != in->value_ctr.values[i].blob->length) {
1047 ret = convert_string_talloc(out->values, lp_iconv_convenience(global_loadparm), CH_UTF16, CH_UNIX,
1048 in->value_ctr.values[i].blob->data+4,
1049 in->value_ctr.values[i].blob->length-4,
1055 out->values[i] = data_blob_string_const(str);
1061 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi(const struct dsdb_schema *schema,
1062 const struct dsdb_attribute *attr,
1063 const struct ldb_message_element *in,
1064 TALLOC_CTX *mem_ctx,
1065 struct drsuapi_DsReplicaAttribute *out)
1070 if (attr->attributeID_id == 0xFFFFFFFF) {
1074 out->attid = attr->attributeID_id;
1075 out->value_ctr.num_values = in->num_values;
1076 out->value_ctr.values = talloc_array(mem_ctx,
1077 struct drsuapi_DsAttributeValue,
1079 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1081 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1082 W_ERROR_HAVE_NO_MEMORY(blobs);
1084 for (i=0; i < in->num_values; i++) {
1088 out->value_ctr.values[i].blob = &blobs[i];
1090 ret = convert_string_talloc(blobs, lp_iconv_convenience(global_loadparm), CH_UNIX, CH_UTF16,
1092 in->values[i].length,
1098 blobs[i] = data_blob_talloc(blobs, NULL, 4 + ret);
1099 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
1101 SIVAL(blobs[i].data, 0, 4 + ret);
1104 memcpy(blobs[i].data + 4, data, ret);
1113 #define OMOBJECTCLASS(val) { .length = sizeof(val) - 1, .data = discard_const_p(uint8_t, val) }
1115 static const struct dsdb_syntax dsdb_syntaxes[] = {
1118 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.7",
1120 .attributeSyntax_oid = "2.5.5.8",
1121 .drsuapi_to_ldb = dsdb_syntax_BOOL_drsuapi_to_ldb,
1122 .ldb_to_drsuapi = dsdb_syntax_BOOL_ldb_to_drsuapi,
1125 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.27",
1127 .attributeSyntax_oid = "2.5.5.9",
1128 .drsuapi_to_ldb = dsdb_syntax_INT32_drsuapi_to_ldb,
1129 .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi,
1131 .name = "String(Octet)",
1132 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.40",
1134 .attributeSyntax_oid = "2.5.5.10",
1135 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1136 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1138 .name = "String(Sid)",
1139 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.40",
1141 .attributeSyntax_oid = "2.5.5.17",
1142 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1143 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1145 .name = "String(Object-Identifier)",
1146 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.38",
1148 .attributeSyntax_oid = "2.5.5.2",
1149 .drsuapi_to_ldb = dsdb_syntax_OID_drsuapi_to_ldb,
1150 .ldb_to_drsuapi = dsdb_syntax_OID_ldb_to_drsuapi,
1152 .name = "Enumeration",
1153 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.27",
1155 .attributeSyntax_oid = "2.5.5.9",
1156 .drsuapi_to_ldb = dsdb_syntax_INT32_drsuapi_to_ldb,
1157 .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi,
1159 /* not used in w2k3 forest */
1160 .name = "String(Numeric)",
1161 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.36",
1163 .attributeSyntax_oid = "2.5.5.6",
1164 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1165 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1167 .name = "String(Printable)",
1168 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.44",
1170 .attributeSyntax_oid = "2.5.5.5",
1171 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1172 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1174 .name = "String(Teletex)",
1175 .ldap_oid = "1.2.840.113556.1.4.905",
1177 .attributeSyntax_oid = "2.5.5.4",
1178 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1179 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1181 .name = "String(IA5)",
1182 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.26",
1184 .attributeSyntax_oid = "2.5.5.5",
1185 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1186 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1188 .name = "String(UTC-Time)",
1189 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.53",
1191 .attributeSyntax_oid = "2.5.5.11",
1192 .drsuapi_to_ldb = dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb,
1193 .ldb_to_drsuapi = dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi,
1195 .name = "String(Generalized-Time)",
1196 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.24",
1198 .attributeSyntax_oid = "2.5.5.11",
1199 .drsuapi_to_ldb = dsdb_syntax_NTTIME_drsuapi_to_ldb,
1200 .ldb_to_drsuapi = dsdb_syntax_NTTIME_ldb_to_drsuapi,
1202 /* not used in w2k3 schema */
1203 .name = "String(Case Sensitive)",
1204 .ldap_oid = "1.2.840.113556.1.4.1362",
1206 .attributeSyntax_oid = "2.5.5.3",
1207 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1208 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1210 .name = "String(Unicode)",
1211 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.15",
1213 .attributeSyntax_oid = "2.5.5.12",
1214 .drsuapi_to_ldb = dsdb_syntax_UNICODE_drsuapi_to_ldb,
1215 .ldb_to_drsuapi = dsdb_syntax_UNICODE_ldb_to_drsuapi,
1217 .name = "Interval/LargeInteger",
1218 .ldap_oid = "1.2.840.113556.1.4.906",
1220 .attributeSyntax_oid = "2.5.5.16",
1221 .drsuapi_to_ldb = dsdb_syntax_INT64_drsuapi_to_ldb,
1222 .ldb_to_drsuapi = dsdb_syntax_INT64_ldb_to_drsuapi,
1224 .name = "String(NT-Sec-Desc)",
1225 .ldap_oid = "1.2.840.113556.1.4.907",
1227 .attributeSyntax_oid = "2.5.5.15",
1228 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1229 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1231 .name = "Object(DS-DN)",
1232 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.12",
1234 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x4a"),
1235 .attributeSyntax_oid = "2.5.5.1",
1236 .drsuapi_to_ldb = dsdb_syntax_DN_drsuapi_to_ldb,
1237 .ldb_to_drsuapi = dsdb_syntax_DN_ldb_to_drsuapi,
1239 .name = "Object(DN-Binary)",
1240 .ldap_oid = "1.2.840.113556.1.4.903",
1242 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0b"),
1243 .attributeSyntax_oid = "2.5.5.7",
1244 .drsuapi_to_ldb = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
1245 .ldb_to_drsuapi = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
1247 /* not used in w2k3 schema */
1248 .name = "Object(OR-Name)",
1249 .ldap_oid = "1.2.840.113556.1.4.1221",
1251 .oMObjectClass = OMOBJECTCLASS("\x56\x06\x01\x02\x05\x0b\x1D"),
1252 .attributeSyntax_oid = "2.5.5.7",
1253 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1254 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1257 * TODO: verify if DATA_BLOB is correct here...!
1259 * repsFrom and repsTo are the only attributes using
1260 * this attribute syntax, but they're not replicated...
1262 .name = "Object(Replica-Link)",
1263 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.40",
1265 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x06"),
1266 .attributeSyntax_oid = "2.5.5.10",
1267 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1268 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1270 .name = "Object(Presentation-Address)",
1271 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.43",
1273 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x5c"),
1274 .attributeSyntax_oid = "2.5.5.13",
1275 .drsuapi_to_ldb = dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb,
1276 .ldb_to_drsuapi = dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi,
1278 /* not used in w2k3 schema */
1279 .name = "Object(Access-Point)",
1280 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.2",
1282 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x3e"),
1283 .attributeSyntax_oid = "2.5.5.14",
1284 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1285 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1287 /* not used in w2k3 schema */
1288 .name = "Object(DN-String)",
1289 .ldap_oid = "1.2.840.113556.1.4.904",
1291 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0c"),
1292 .attributeSyntax_oid = "2.5.5.14",
1293 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1294 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1298 const struct dsdb_syntax *dsdb_syntax_for_attribute(const struct dsdb_attribute *attr)
1302 for (i=0; i < ARRAY_SIZE(dsdb_syntaxes); i++) {
1303 if (attr->oMSyntax != dsdb_syntaxes[i].oMSyntax) continue;
1305 if (attr->oMObjectClass.length != dsdb_syntaxes[i].oMObjectClass.length) continue;
1307 if (attr->oMObjectClass.length) {
1309 ret = memcmp(attr->oMObjectClass.data,
1310 dsdb_syntaxes[i].oMObjectClass.data,
1311 attr->oMObjectClass.length);
1312 if (ret != 0) continue;
1315 if (strcmp(attr->attributeSyntax_oid, dsdb_syntaxes[i].attributeSyntax_oid) != 0) continue;
1317 return &dsdb_syntaxes[i];
1323 WERROR dsdb_attribute_drsuapi_to_ldb(const struct dsdb_schema *schema,
1324 const struct drsuapi_DsReplicaAttribute *in,
1325 TALLOC_CTX *mem_ctx,
1326 struct ldb_message_element *out)
1328 const struct dsdb_attribute *sa;
1330 sa = dsdb_attribute_by_attributeID_id(schema, in->attid);
1335 return sa->syntax->drsuapi_to_ldb(schema, sa, in, mem_ctx, out);
1338 WERROR dsdb_attribute_ldb_to_drsuapi(const struct dsdb_schema *schema,
1339 const struct ldb_message_element *in,
1340 TALLOC_CTX *mem_ctx,
1341 struct drsuapi_DsReplicaAttribute *out)
1343 const struct dsdb_attribute *sa;
1345 sa = dsdb_attribute_by_lDAPDisplayName(schema, in->name);
1350 return sa->syntax->ldb_to_drsuapi(schema, sa, in, mem_ctx, out);