2 Unix SMB/CIFS mplementation.
5 Copyright (C) Stefan Metzmacher <metze@samba.org> 2006
6 Copyright (C) Simo Sorce 2005
7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2008
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "dsdb/samdb/samdb.h"
25 #include "librpc/gen_ndr/ndr_drsuapi.h"
26 #include "librpc/gen_ndr/ndr_security.h"
27 #include "librpc/gen_ndr/ndr_misc.h"
28 #include "lib/ldb/include/ldb.h"
29 #include "lib/ldb/include/ldb_errors.h"
30 #include "system/time.h"
31 #include "../lib/util/charset/charset.h"
32 #include "librpc/ndr/libndr.h"
34 static WERROR dsdb_syntax_FOOBAR_drsuapi_to_ldb(struct ldb_context *ldb,
35 const struct dsdb_schema *schema,
36 const struct dsdb_attribute *attr,
37 const struct drsuapi_DsReplicaAttribute *in,
39 struct ldb_message_element *out)
44 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
45 W_ERROR_HAVE_NO_MEMORY(out->name);
47 out->num_values = in->value_ctr.num_values;
48 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
49 W_ERROR_HAVE_NO_MEMORY(out->values);
51 for (i=0; i < out->num_values; i++) {
54 if (in->value_ctr.values[i].blob == NULL) {
58 str = talloc_asprintf(out->values, "%s: not implemented",
60 W_ERROR_HAVE_NO_MEMORY(str);
62 out->values[i] = data_blob_string_const(str);
68 static WERROR dsdb_syntax_FOOBAR_ldb_to_drsuapi(struct ldb_context *ldb,
69 const struct dsdb_schema *schema,
70 const struct dsdb_attribute *attr,
71 const struct ldb_message_element *in,
73 struct drsuapi_DsReplicaAttribute *out)
78 static WERROR dsdb_syntax_FOOBAR_validate_ldb(struct ldb_context *ldb,
79 const struct dsdb_schema *schema,
80 const struct dsdb_attribute *attr,
81 const struct ldb_message_element *in)
86 static WERROR dsdb_syntax_ALLOW_validate_ldb(struct ldb_context *ldb,
87 const struct dsdb_schema *schema,
88 const struct dsdb_attribute *attr,
89 const struct ldb_message_element *in)
91 if (attr->attributeID_id == 0xFFFFFFFF) {
98 static WERROR dsdb_syntax_BOOL_drsuapi_to_ldb(struct ldb_context *ldb,
99 const struct dsdb_schema *schema,
100 const struct dsdb_attribute *attr,
101 const struct drsuapi_DsReplicaAttribute *in,
103 struct ldb_message_element *out)
108 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
109 W_ERROR_HAVE_NO_MEMORY(out->name);
111 out->num_values = in->value_ctr.num_values;
112 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
113 W_ERROR_HAVE_NO_MEMORY(out->values);
115 for (i=0; i < out->num_values; i++) {
119 if (in->value_ctr.values[i].blob == NULL) {
123 if (in->value_ctr.values[i].blob->length != 4) {
127 v = IVAL(in->value_ctr.values[i].blob->data, 0);
130 str = talloc_strdup(out->values, "TRUE");
131 W_ERROR_HAVE_NO_MEMORY(str);
133 str = talloc_strdup(out->values, "FALSE");
134 W_ERROR_HAVE_NO_MEMORY(str);
137 out->values[i] = data_blob_string_const(str);
143 static WERROR dsdb_syntax_BOOL_ldb_to_drsuapi(struct ldb_context *ldb,
144 const struct dsdb_schema *schema,
145 const struct dsdb_attribute *attr,
146 const struct ldb_message_element *in,
148 struct drsuapi_DsReplicaAttribute *out)
153 if (attr->attributeID_id == 0xFFFFFFFF) {
157 out->attid = attr->attributeID_id;
158 out->value_ctr.num_values = in->num_values;
159 out->value_ctr.values = talloc_array(mem_ctx,
160 struct drsuapi_DsAttributeValue,
162 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
164 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
165 W_ERROR_HAVE_NO_MEMORY(blobs);
167 for (i=0; i < in->num_values; i++) {
168 out->value_ctr.values[i].blob = &blobs[i];
170 blobs[i] = data_blob_talloc(blobs, NULL, 4);
171 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
173 if (strcmp("TRUE", (const char *)in->values[i].data) == 0) {
174 SIVAL(blobs[i].data, 0, 0x00000001);
175 } else if (strcmp("FALSE", (const char *)in->values[i].data) == 0) {
176 SIVAL(blobs[i].data, 0, 0x00000000);
185 static WERROR dsdb_syntax_INT32_drsuapi_to_ldb(struct ldb_context *ldb,
186 const struct dsdb_schema *schema,
187 const struct dsdb_attribute *attr,
188 const struct drsuapi_DsReplicaAttribute *in,
190 struct ldb_message_element *out)
195 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
196 W_ERROR_HAVE_NO_MEMORY(out->name);
198 out->num_values = in->value_ctr.num_values;
199 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
200 W_ERROR_HAVE_NO_MEMORY(out->values);
202 for (i=0; i < out->num_values; i++) {
206 if (in->value_ctr.values[i].blob == NULL) {
210 if (in->value_ctr.values[i].blob->length != 4) {
214 v = IVALS(in->value_ctr.values[i].blob->data, 0);
216 str = talloc_asprintf(out->values, "%d", v);
217 W_ERROR_HAVE_NO_MEMORY(str);
219 out->values[i] = data_blob_string_const(str);
225 static WERROR dsdb_syntax_INT32_ldb_to_drsuapi(struct ldb_context *ldb,
226 const struct dsdb_schema *schema,
227 const struct dsdb_attribute *attr,
228 const struct ldb_message_element *in,
230 struct drsuapi_DsReplicaAttribute *out)
235 if (attr->attributeID_id == 0xFFFFFFFF) {
239 out->attid = attr->attributeID_id;
240 out->value_ctr.num_values = in->num_values;
241 out->value_ctr.values = talloc_array(mem_ctx,
242 struct drsuapi_DsAttributeValue,
244 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
246 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
247 W_ERROR_HAVE_NO_MEMORY(blobs);
249 for (i=0; i < in->num_values; i++) {
252 out->value_ctr.values[i].blob = &blobs[i];
254 blobs[i] = data_blob_talloc(blobs, NULL, 4);
255 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
257 /* We've to use "strtoll" here to have the intended overflows.
258 * Otherwise we may get "LONG_MAX" and the conversion is wrong. */
259 v = (int32_t) strtoll((char *)in->values[i].data, NULL, 0);
261 SIVALS(blobs[i].data, 0, v);
267 static WERROR dsdb_syntax_INT64_drsuapi_to_ldb(struct ldb_context *ldb,
268 const struct dsdb_schema *schema,
269 const struct dsdb_attribute *attr,
270 const struct drsuapi_DsReplicaAttribute *in,
272 struct ldb_message_element *out)
277 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
278 W_ERROR_HAVE_NO_MEMORY(out->name);
280 out->num_values = in->value_ctr.num_values;
281 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
282 W_ERROR_HAVE_NO_MEMORY(out->values);
284 for (i=0; i < out->num_values; i++) {
288 if (in->value_ctr.values[i].blob == NULL) {
292 if (in->value_ctr.values[i].blob->length != 8) {
296 v = BVALS(in->value_ctr.values[i].blob->data, 0);
298 str = talloc_asprintf(out->values, "%lld", (long long int)v);
299 W_ERROR_HAVE_NO_MEMORY(str);
301 out->values[i] = data_blob_string_const(str);
307 static WERROR dsdb_syntax_INT64_ldb_to_drsuapi(struct ldb_context *ldb,
308 const struct dsdb_schema *schema,
309 const struct dsdb_attribute *attr,
310 const struct ldb_message_element *in,
312 struct drsuapi_DsReplicaAttribute *out)
317 if (attr->attributeID_id == 0xFFFFFFFF) {
321 out->attid = attr->attributeID_id;
322 out->value_ctr.num_values = in->num_values;
323 out->value_ctr.values = talloc_array(mem_ctx,
324 struct drsuapi_DsAttributeValue,
326 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
328 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
329 W_ERROR_HAVE_NO_MEMORY(blobs);
331 for (i=0; i < in->num_values; i++) {
334 out->value_ctr.values[i].blob = &blobs[i];
336 blobs[i] = data_blob_talloc(blobs, NULL, 8);
337 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
339 v = strtoll((const char *)in->values[i].data, NULL, 10);
341 SBVALS(blobs[i].data, 0, v);
347 static WERROR dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb(struct ldb_context *ldb,
348 const struct dsdb_schema *schema,
349 const struct dsdb_attribute *attr,
350 const struct drsuapi_DsReplicaAttribute *in,
352 struct ldb_message_element *out)
357 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
358 W_ERROR_HAVE_NO_MEMORY(out->name);
360 out->num_values = in->value_ctr.num_values;
361 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
362 W_ERROR_HAVE_NO_MEMORY(out->values);
364 for (i=0; i < out->num_values; i++) {
369 if (in->value_ctr.values[i].blob == NULL) {
373 if (in->value_ctr.values[i].blob->length != 8) {
377 v = BVAL(in->value_ctr.values[i].blob->data, 0);
379 t = nt_time_to_unix(v);
382 * NOTE: On a w2k3 server you can set a GeneralizedTime string
383 * via LDAP, but you get back an UTCTime string,
384 * but via DRSUAPI you get back the NTTIME_1sec value
385 * that represents the GeneralizedTime value!
387 * So if we store the UTCTime string in our ldb
388 * we'll loose information!
390 str = ldb_timestring_utc(out->values, t);
391 W_ERROR_HAVE_NO_MEMORY(str);
392 out->values[i] = data_blob_string_const(str);
398 static WERROR dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi(struct ldb_context *ldb,
399 const struct dsdb_schema *schema,
400 const struct dsdb_attribute *attr,
401 const struct ldb_message_element *in,
403 struct drsuapi_DsReplicaAttribute *out)
408 if (attr->attributeID_id == 0xFFFFFFFF) {
412 out->attid = attr->attributeID_id;
413 out->value_ctr.num_values = in->num_values;
414 out->value_ctr.values = talloc_array(mem_ctx,
415 struct drsuapi_DsAttributeValue,
417 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
419 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
420 W_ERROR_HAVE_NO_MEMORY(blobs);
422 for (i=0; i < in->num_values; i++) {
426 out->value_ctr.values[i].blob = &blobs[i];
428 blobs[i] = data_blob_talloc(blobs, NULL, 8);
429 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
431 t = ldb_string_utc_to_time((const char *)in->values[i].data);
432 unix_to_nt_time(&v, t);
435 SBVAL(blobs[i].data, 0, v);
441 static WERROR dsdb_syntax_NTTIME_drsuapi_to_ldb(struct ldb_context *ldb,
442 const struct dsdb_schema *schema,
443 const struct dsdb_attribute *attr,
444 const struct drsuapi_DsReplicaAttribute *in,
446 struct ldb_message_element *out)
451 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
452 W_ERROR_HAVE_NO_MEMORY(out->name);
454 out->num_values = in->value_ctr.num_values;
455 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
456 W_ERROR_HAVE_NO_MEMORY(out->values);
458 for (i=0; i < out->num_values; i++) {
463 if (in->value_ctr.values[i].blob == NULL) {
467 if (in->value_ctr.values[i].blob->length != 8) {
471 v = BVAL(in->value_ctr.values[i].blob->data, 0);
473 t = nt_time_to_unix(v);
475 str = ldb_timestring(out->values, t);
476 W_ERROR_HAVE_NO_MEMORY(str);
478 out->values[i] = data_blob_string_const(str);
484 static WERROR dsdb_syntax_NTTIME_ldb_to_drsuapi(struct ldb_context *ldb,
485 const struct dsdb_schema *schema,
486 const struct dsdb_attribute *attr,
487 const struct ldb_message_element *in,
489 struct drsuapi_DsReplicaAttribute *out)
494 if (attr->attributeID_id == 0xFFFFFFFF) {
498 out->attid = attr->attributeID_id;
499 out->value_ctr.num_values = in->num_values;
500 out->value_ctr.values = talloc_array(mem_ctx,
501 struct drsuapi_DsAttributeValue,
503 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
505 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
506 W_ERROR_HAVE_NO_MEMORY(blobs);
508 for (i=0; i < in->num_values; i++) {
513 out->value_ctr.values[i].blob = &blobs[i];
515 blobs[i] = data_blob_talloc(blobs, NULL, 8);
516 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
518 ret = ldb_val_to_time(&in->values[i], &t);
519 if (ret != LDB_SUCCESS) {
520 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
522 unix_to_nt_time(&v, t);
525 SBVAL(blobs[i].data, 0, v);
531 static WERROR dsdb_syntax_DATA_BLOB_drsuapi_to_ldb(struct ldb_context *ldb,
532 const struct dsdb_schema *schema,
533 const struct dsdb_attribute *attr,
534 const struct drsuapi_DsReplicaAttribute *in,
536 struct ldb_message_element *out)
541 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
542 W_ERROR_HAVE_NO_MEMORY(out->name);
544 out->num_values = in->value_ctr.num_values;
545 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
546 W_ERROR_HAVE_NO_MEMORY(out->values);
548 for (i=0; i < out->num_values; i++) {
549 if (in->value_ctr.values[i].blob == NULL) {
553 if (in->value_ctr.values[i].blob->length == 0) {
557 out->values[i] = data_blob_dup_talloc(out->values,
558 in->value_ctr.values[i].blob);
559 W_ERROR_HAVE_NO_MEMORY(out->values[i].data);
565 static WERROR dsdb_syntax_DATA_BLOB_ldb_to_drsuapi(struct ldb_context *ldb,
566 const struct dsdb_schema *schema,
567 const struct dsdb_attribute *attr,
568 const struct ldb_message_element *in,
570 struct drsuapi_DsReplicaAttribute *out)
575 if (attr->attributeID_id == 0xFFFFFFFF) {
579 out->attid = attr->attributeID_id;
580 out->value_ctr.num_values = in->num_values;
581 out->value_ctr.values = talloc_array(mem_ctx,
582 struct drsuapi_DsAttributeValue,
584 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
586 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
587 W_ERROR_HAVE_NO_MEMORY(blobs);
589 for (i=0; i < in->num_values; i++) {
590 out->value_ctr.values[i].blob = &blobs[i];
592 blobs[i] = data_blob_dup_talloc(blobs, &in->values[i]);
593 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
599 static WERROR _dsdb_syntax_auto_OID_drsuapi_to_ldb(struct ldb_context *ldb,
600 const struct dsdb_schema *schema,
601 const struct dsdb_attribute *attr,
602 const struct drsuapi_DsReplicaAttribute *in,
604 struct ldb_message_element *out)
609 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
610 W_ERROR_HAVE_NO_MEMORY(out->name);
612 out->num_values = in->value_ctr.num_values;
613 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
614 W_ERROR_HAVE_NO_MEMORY(out->values);
616 for (i=0; i < out->num_values; i++) {
618 const struct dsdb_class *c;
619 const struct dsdb_attribute *a;
620 const char *str = NULL;
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 if ((c = dsdb_class_by_governsID_id(schema, v))) {
633 str = talloc_strdup(out->values, c->lDAPDisplayName);
634 } else if ((a = dsdb_attribute_by_attributeID_id(schema, v))) {
635 str = talloc_strdup(out->values, a->lDAPDisplayName);
638 werr = dsdb_schema_pfm_oid_from_attid(schema->prefixmap, v, out->values, &str);
639 W_ERROR_NOT_OK_RETURN(werr);
641 W_ERROR_HAVE_NO_MEMORY(str);
643 /* the values need to be reversed */
644 out->values[out->num_values - (i + 1)] = data_blob_string_const(str);
650 static WERROR _dsdb_syntax_OID_obj_drsuapi_to_ldb(struct ldb_context *ldb,
651 const struct dsdb_schema *schema,
652 const struct dsdb_attribute *attr,
653 const struct drsuapi_DsReplicaAttribute *in,
655 struct ldb_message_element *out)
660 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
661 W_ERROR_HAVE_NO_MEMORY(out->name);
663 out->num_values = in->value_ctr.num_values;
664 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
665 W_ERROR_HAVE_NO_MEMORY(out->values);
667 for (i=0; i < out->num_values; i++) {
669 const struct dsdb_class *c;
672 if (in->value_ctr.values[i].blob == NULL) {
676 if (in->value_ctr.values[i].blob->length != 4) {
680 v = IVAL(in->value_ctr.values[i].blob->data, 0);
682 c = dsdb_class_by_governsID_id(schema, v);
687 str = talloc_strdup(out->values, c->lDAPDisplayName);
688 W_ERROR_HAVE_NO_MEMORY(str);
690 /* the values need to be reversed */
691 out->values[out->num_values - (i + 1)] = data_blob_string_const(str);
697 static WERROR _dsdb_syntax_OID_attr_drsuapi_to_ldb(struct ldb_context *ldb,
698 const struct dsdb_schema *schema,
699 const struct dsdb_attribute *attr,
700 const struct drsuapi_DsReplicaAttribute *in,
702 struct ldb_message_element *out)
707 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
708 W_ERROR_HAVE_NO_MEMORY(out->name);
710 out->num_values = in->value_ctr.num_values;
711 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
712 W_ERROR_HAVE_NO_MEMORY(out->values);
714 for (i=0; i < out->num_values; i++) {
716 const struct dsdb_attribute *a;
719 if (in->value_ctr.values[i].blob == NULL) {
723 if (in->value_ctr.values[i].blob->length != 4) {
727 v = IVAL(in->value_ctr.values[i].blob->data, 0);
729 a = dsdb_attribute_by_attributeID_id(schema, v);
734 str = talloc_strdup(out->values, a->lDAPDisplayName);
735 W_ERROR_HAVE_NO_MEMORY(str);
737 /* the values need to be reversed */
738 out->values[out->num_values - (i + 1)] = data_blob_string_const(str);
744 static WERROR _dsdb_syntax_OID_oid_drsuapi_to_ldb(struct ldb_context *ldb,
745 const struct dsdb_schema *schema,
746 const struct dsdb_attribute *attr,
747 const struct drsuapi_DsReplicaAttribute *in,
749 struct ldb_message_element *out)
754 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
755 W_ERROR_HAVE_NO_MEMORY(out->name);
757 out->num_values = in->value_ctr.num_values;
758 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
759 W_ERROR_HAVE_NO_MEMORY(out->values);
761 for (i=0; i < out->num_values; i++) {
766 if (in->value_ctr.values[i].blob == NULL) {
770 if (in->value_ctr.values[i].blob->length != 4) {
774 attid = IVAL(in->value_ctr.values[i].blob->data, 0);
776 status = dsdb_schema_pfm_oid_from_attid(schema->prefixmap, attid, out->values, &oid);
777 W_ERROR_NOT_OK_RETURN(status);
779 out->values[i] = data_blob_string_const(oid);
785 static WERROR _dsdb_syntax_auto_OID_ldb_to_drsuapi(struct ldb_context *ldb,
786 const struct dsdb_schema *schema,
787 const struct dsdb_attribute *attr,
788 const struct ldb_message_element *in,
790 struct drsuapi_DsReplicaAttribute *out)
795 out->attid= attr->attributeID_id;
796 out->value_ctr.num_values= in->num_values;
797 out->value_ctr.values= talloc_array(mem_ctx,
798 struct drsuapi_DsAttributeValue,
800 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
802 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
803 W_ERROR_HAVE_NO_MEMORY(blobs);
805 for (i=0; i < in->num_values; i++) {
806 const struct dsdb_class *obj_class;
807 const struct dsdb_attribute *obj_attr;
810 out->value_ctr.values[i].blob= &blobs[i];
812 blobs[i] = data_blob_talloc(blobs, NULL, 4);
813 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
815 /* in DRS windows puts the classes in the opposite
816 order to the order used in ldap */
817 v = &in->values[(in->num_values-1)-i];
819 if ((obj_class = dsdb_class_by_lDAPDisplayName_ldb_val(schema, v))) {
820 SIVAL(blobs[i].data, 0, obj_class->governsID_id);
821 } else if ((obj_attr = dsdb_attribute_by_lDAPDisplayName_ldb_val(schema, v))) {
822 SIVAL(blobs[i].data, 0, obj_attr->attributeID_id);
826 werr = dsdb_schema_pfm_make_attid(schema->prefixmap,
827 (const char *)v->data,
829 W_ERROR_NOT_OK_RETURN(werr);
830 SIVAL(blobs[i].data, 0, attid);
839 static WERROR _dsdb_syntax_OID_obj_ldb_to_drsuapi(struct ldb_context *ldb,
840 const struct dsdb_schema *schema,
841 const struct dsdb_attribute *attr,
842 const struct ldb_message_element *in,
844 struct drsuapi_DsReplicaAttribute *out)
849 out->attid= attr->attributeID_id;
850 out->value_ctr.num_values= in->num_values;
851 out->value_ctr.values= talloc_array(mem_ctx,
852 struct drsuapi_DsAttributeValue,
854 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
856 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
857 W_ERROR_HAVE_NO_MEMORY(blobs);
859 for (i=0; i < in->num_values; i++) {
860 const struct dsdb_class *obj_class;
862 out->value_ctr.values[i].blob= &blobs[i];
864 blobs[i] = data_blob_talloc(blobs, NULL, 4);
865 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
867 /* in DRS windows puts the classes in the opposite
868 order to the order used in ldap */
869 obj_class = dsdb_class_by_lDAPDisplayName(schema,
870 (const char *)in->values[(in->num_values-1)-i].data);
874 SIVAL(blobs[i].data, 0, obj_class->governsID_id);
881 static WERROR _dsdb_syntax_OID_attr_ldb_to_drsuapi(struct ldb_context *ldb,
882 const struct dsdb_schema *schema,
883 const struct dsdb_attribute *attr,
884 const struct ldb_message_element *in,
886 struct drsuapi_DsReplicaAttribute *out)
891 out->attid= attr->attributeID_id;
892 out->value_ctr.num_values= in->num_values;
893 out->value_ctr.values= talloc_array(mem_ctx,
894 struct drsuapi_DsAttributeValue,
896 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
898 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
899 W_ERROR_HAVE_NO_MEMORY(blobs);
901 for (i=0; i < in->num_values; i++) {
902 const struct dsdb_attribute *obj_attr;
904 out->value_ctr.values[i].blob= &blobs[i];
906 blobs[i] = data_blob_talloc(blobs, NULL, 4);
907 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
909 obj_attr = dsdb_attribute_by_lDAPDisplayName(schema, (const char *)in->values[i].data);
913 SIVAL(blobs[i].data, 0, obj_attr->attributeID_id);
920 static WERROR _dsdb_syntax_OID_oid_ldb_to_drsuapi(struct ldb_context *ldb,
921 const struct dsdb_schema *schema,
922 const struct dsdb_attribute *attr,
923 const struct ldb_message_element *in,
925 struct drsuapi_DsReplicaAttribute *out)
930 out->attid= attr->attributeID_id;
931 out->value_ctr.num_values= in->num_values;
932 out->value_ctr.values= talloc_array(mem_ctx,
933 struct drsuapi_DsAttributeValue,
935 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
937 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
938 W_ERROR_HAVE_NO_MEMORY(blobs);
940 for (i=0; i < in->num_values; i++) {
944 out->value_ctr.values[i].blob= &blobs[i];
946 blobs[i] = data_blob_talloc(blobs, NULL, 4);
947 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
949 status = dsdb_schema_pfm_make_attid(schema->prefixmap,
950 (const char *)in->values[i].data,
952 W_ERROR_NOT_OK_RETURN(status);
954 SIVAL(blobs[i].data, 0, attid);
960 static WERROR dsdb_syntax_OID_drsuapi_to_ldb(struct ldb_context *ldb,
961 const struct dsdb_schema *schema,
962 const struct dsdb_attribute *attr,
963 const struct drsuapi_DsReplicaAttribute *in,
965 struct ldb_message_element *out)
967 switch (attr->attributeID_id) {
968 case DRSUAPI_ATTRIBUTE_objectClass:
969 case DRSUAPI_ATTRIBUTE_subClassOf:
970 case DRSUAPI_ATTRIBUTE_auxiliaryClass:
971 case DRSUAPI_ATTRIBUTE_systemAuxiliaryClass:
972 case DRSUAPI_ATTRIBUTE_systemPossSuperiors:
973 case DRSUAPI_ATTRIBUTE_possSuperiors:
974 return _dsdb_syntax_OID_obj_drsuapi_to_ldb(ldb, schema, attr, in, mem_ctx, out);
975 case DRSUAPI_ATTRIBUTE_systemMustContain:
976 case DRSUAPI_ATTRIBUTE_systemMayContain:
977 case DRSUAPI_ATTRIBUTE_mustContain:
978 case DRSUAPI_ATTRIBUTE_rDNAttId:
979 case DRSUAPI_ATTRIBUTE_transportAddressAttribute:
980 case DRSUAPI_ATTRIBUTE_mayContain:
981 return _dsdb_syntax_OID_attr_drsuapi_to_ldb(ldb, schema, attr, in, mem_ctx, out);
982 case DRSUAPI_ATTRIBUTE_governsID:
983 case DRSUAPI_ATTRIBUTE_attributeID:
984 case DRSUAPI_ATTRIBUTE_attributeSyntax:
985 return _dsdb_syntax_OID_oid_drsuapi_to_ldb(ldb, schema, attr, in, mem_ctx, out);
988 DEBUG(0,(__location__ ": Unknown handling for attributeID_id for %s\n",
989 attr->lDAPDisplayName));
990 return _dsdb_syntax_auto_OID_drsuapi_to_ldb(ldb, schema, attr, in, mem_ctx, out);
993 static WERROR dsdb_syntax_OID_ldb_to_drsuapi(struct ldb_context *ldb,
994 const struct dsdb_schema *schema,
995 const struct dsdb_attribute *attr,
996 const struct ldb_message_element *in,
998 struct drsuapi_DsReplicaAttribute *out)
1000 if (attr->attributeID_id == 0xFFFFFFFF) {
1004 switch (attr->attributeID_id) {
1005 case DRSUAPI_ATTRIBUTE_objectClass:
1006 case DRSUAPI_ATTRIBUTE_subClassOf:
1007 case DRSUAPI_ATTRIBUTE_auxiliaryClass:
1008 case DRSUAPI_ATTRIBUTE_systemAuxiliaryClass:
1009 case DRSUAPI_ATTRIBUTE_systemPossSuperiors:
1010 case DRSUAPI_ATTRIBUTE_possSuperiors:
1011 return _dsdb_syntax_OID_obj_ldb_to_drsuapi(ldb, schema, attr, in, mem_ctx, out);
1012 case DRSUAPI_ATTRIBUTE_systemMustContain:
1013 case DRSUAPI_ATTRIBUTE_systemMayContain:
1014 case DRSUAPI_ATTRIBUTE_mustContain:
1015 case DRSUAPI_ATTRIBUTE_rDNAttId:
1016 case DRSUAPI_ATTRIBUTE_transportAddressAttribute:
1017 case DRSUAPI_ATTRIBUTE_mayContain:
1018 return _dsdb_syntax_OID_attr_ldb_to_drsuapi(ldb, schema, attr, in, mem_ctx, out);
1019 case DRSUAPI_ATTRIBUTE_governsID:
1020 case DRSUAPI_ATTRIBUTE_attributeID:
1021 case DRSUAPI_ATTRIBUTE_attributeSyntax:
1022 return _dsdb_syntax_OID_oid_ldb_to_drsuapi(ldb, schema, attr, in, mem_ctx, out);
1025 DEBUG(0,(__location__ ": Unknown handling for attributeID_id for %s\n",
1026 attr->lDAPDisplayName));
1028 return _dsdb_syntax_auto_OID_ldb_to_drsuapi(ldb, schema, attr, in, mem_ctx, out);
1031 static WERROR dsdb_syntax_UNICODE_drsuapi_to_ldb(struct ldb_context *ldb,
1032 const struct dsdb_schema *schema,
1033 const struct dsdb_attribute *attr,
1034 const struct drsuapi_DsReplicaAttribute *in,
1035 TALLOC_CTX *mem_ctx,
1036 struct ldb_message_element *out)
1041 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1042 W_ERROR_HAVE_NO_MEMORY(out->name);
1044 out->num_values = in->value_ctr.num_values;
1045 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1046 W_ERROR_HAVE_NO_MEMORY(out->values);
1048 for (i=0; i < out->num_values; i++) {
1051 if (in->value_ctr.values[i].blob == NULL) {
1055 if (in->value_ctr.values[i].blob->length == 0) {
1059 if (!convert_string_talloc_convenience(out->values,
1060 schema->iconv_convenience,
1062 in->value_ctr.values[i].blob->data,
1063 in->value_ctr.values[i].blob->length,
1064 (void **)&str, NULL, false)) {
1068 out->values[i] = data_blob_string_const(str);
1074 static WERROR dsdb_syntax_UNICODE_ldb_to_drsuapi(struct ldb_context *ldb,
1075 const struct dsdb_schema *schema,
1076 const struct dsdb_attribute *attr,
1077 const struct ldb_message_element *in,
1078 TALLOC_CTX *mem_ctx,
1079 struct drsuapi_DsReplicaAttribute *out)
1084 if (attr->attributeID_id == 0xFFFFFFFF) {
1088 out->attid = attr->attributeID_id;
1089 out->value_ctr.num_values = in->num_values;
1090 out->value_ctr.values = talloc_array(mem_ctx,
1091 struct drsuapi_DsAttributeValue,
1093 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1095 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1096 W_ERROR_HAVE_NO_MEMORY(blobs);
1098 for (i=0; i < in->num_values; i++) {
1099 out->value_ctr.values[i].blob = &blobs[i];
1101 if (!convert_string_talloc_convenience(blobs,
1102 schema->iconv_convenience, CH_UNIX, CH_UTF16,
1103 in->values[i].data, in->values[i].length,
1104 (void **)&blobs[i].data, &blobs[i].length, false)) {
1113 WERROR dsdb_syntax_one_DN_drsuapi_to_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
1114 const struct dsdb_syntax *syntax,
1115 struct smb_iconv_convenience *iconv_convenience,
1116 const DATA_BLOB *in, DATA_BLOB *out)
1118 struct drsuapi_DsReplicaObjectIdentifier3 id3;
1119 enum ndr_err_code ndr_err;
1120 DATA_BLOB guid_blob;
1122 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1127 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1131 talloc_free(tmp_ctx);
1135 if (in->length == 0) {
1136 talloc_free(tmp_ctx);
1141 /* windows sometimes sends an extra two pad bytes here */
1142 ndr_err = ndr_pull_struct_blob(in,
1143 tmp_ctx, iconv_convenience, &id3,
1144 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3);
1145 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1146 status = ndr_map_error2ntstatus(ndr_err);
1147 talloc_free(tmp_ctx);
1148 return ntstatus_to_werror(status);
1151 dn = ldb_dn_new(tmp_ctx, ldb, id3.dn);
1153 talloc_free(tmp_ctx);
1154 /* If this fails, it must be out of memory, as it does not do much parsing */
1155 W_ERROR_HAVE_NO_MEMORY(dn);
1158 if (!GUID_all_zero(&id3.guid)) {
1159 status = GUID_to_ndr_blob(&id3.guid, tmp_ctx, &guid_blob);
1160 if (!NT_STATUS_IS_OK(status)) {
1161 talloc_free(tmp_ctx);
1162 return ntstatus_to_werror(status);
1165 ret = ldb_dn_set_extended_component(dn, "GUID", &guid_blob);
1166 if (ret != LDB_SUCCESS) {
1167 talloc_free(tmp_ctx);
1170 talloc_free(guid_blob.data);
1173 if (id3.__ndr_size_sid) {
1175 ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, iconv_convenience, &id3.sid,
1176 (ndr_push_flags_fn_t)ndr_push_dom_sid);
1177 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1178 status = ndr_map_error2ntstatus(ndr_err);
1179 talloc_free(tmp_ctx);
1180 return ntstatus_to_werror(status);
1183 ret = ldb_dn_set_extended_component(dn, "SID", &sid_blob);
1184 if (ret != LDB_SUCCESS) {
1185 talloc_free(tmp_ctx);
1190 *out = data_blob_string_const(ldb_dn_get_extended_linearized(mem_ctx, dn, 1));
1191 talloc_free(tmp_ctx);
1195 static WERROR dsdb_syntax_DN_drsuapi_to_ldb(struct ldb_context *ldb,
1196 const struct dsdb_schema *schema,
1197 const struct dsdb_attribute *attr,
1198 const struct drsuapi_DsReplicaAttribute *in,
1199 TALLOC_CTX *mem_ctx,
1200 struct ldb_message_element *out)
1205 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1206 W_ERROR_HAVE_NO_MEMORY(out->name);
1208 out->num_values = in->value_ctr.num_values;
1209 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1210 W_ERROR_HAVE_NO_MEMORY(out->values);
1212 for (i=0; i < out->num_values; i++) {
1213 WERROR status = dsdb_syntax_one_DN_drsuapi_to_ldb(out->values, ldb, attr->syntax,
1214 schema->iconv_convenience,
1215 in->value_ctr.values[i].blob,
1217 if (!W_ERROR_IS_OK(status)) {
1226 static WERROR dsdb_syntax_DN_ldb_to_drsuapi(struct ldb_context *ldb,
1227 const struct dsdb_schema *schema,
1228 const struct dsdb_attribute *attr,
1229 const struct ldb_message_element *in,
1230 TALLOC_CTX *mem_ctx,
1231 struct drsuapi_DsReplicaAttribute *out)
1236 if (attr->attributeID_id == 0xFFFFFFFF) {
1240 out->attid = attr->attributeID_id;
1241 out->value_ctr.num_values = in->num_values;
1242 out->value_ctr.values = talloc_array(mem_ctx,
1243 struct drsuapi_DsAttributeValue,
1245 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1247 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1248 W_ERROR_HAVE_NO_MEMORY(blobs);
1250 for (i=0; i < in->num_values; i++) {
1251 struct drsuapi_DsReplicaObjectIdentifier3 id3;
1252 enum ndr_err_code ndr_err;
1253 const DATA_BLOB *sid_blob;
1255 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1258 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1260 out->value_ctr.values[i].blob = &blobs[i];
1262 dn = ldb_dn_from_ldb_val(tmp_ctx, ldb, &in->values[i]);
1264 W_ERROR_HAVE_NO_MEMORY(dn);
1268 status = dsdb_get_extended_dn_guid(dn, &id3.guid, "GUID");
1269 if (!NT_STATUS_IS_OK(status) &&
1270 !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1271 talloc_free(tmp_ctx);
1272 return ntstatus_to_werror(status);
1275 sid_blob = ldb_dn_get_extended_component(dn, "SID");
1278 ndr_err = ndr_pull_struct_blob_all(sid_blob,
1279 tmp_ctx, schema->iconv_convenience, &id3.sid,
1280 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1281 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1282 status = ndr_map_error2ntstatus(ndr_err);
1283 talloc_free(tmp_ctx);
1284 return ntstatus_to_werror(status);
1288 id3.dn = ldb_dn_get_linearized(dn);
1290 ndr_err = ndr_push_struct_blob(&blobs[i], blobs, schema->iconv_convenience, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
1291 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1292 status = ndr_map_error2ntstatus(ndr_err);
1293 talloc_free(tmp_ctx);
1294 return ntstatus_to_werror(status);
1296 talloc_free(tmp_ctx);
1304 static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(struct ldb_context *ldb,
1305 const struct dsdb_schema *schema,
1306 const struct dsdb_attribute *attr,
1307 const struct drsuapi_DsReplicaAttribute *in,
1308 TALLOC_CTX *mem_ctx,
1309 struct ldb_message_element *out)
1315 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1316 W_ERROR_HAVE_NO_MEMORY(out->name);
1318 out->num_values = in->value_ctr.num_values;
1319 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1320 W_ERROR_HAVE_NO_MEMORY(out->values);
1322 for (i=0; i < out->num_values; i++) {
1323 struct drsuapi_DsReplicaObjectIdentifier3Binary id3;
1324 enum ndr_err_code ndr_err;
1325 DATA_BLOB guid_blob;
1327 struct dsdb_dn *dsdb_dn;
1329 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1331 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1334 if (in->value_ctr.values[i].blob == NULL) {
1335 talloc_free(tmp_ctx);
1339 if (in->value_ctr.values[i].blob->length == 0) {
1340 talloc_free(tmp_ctx);
1345 /* windows sometimes sends an extra two pad bytes here */
1346 ndr_err = ndr_pull_struct_blob(in->value_ctr.values[i].blob,
1347 tmp_ctx, schema->iconv_convenience, &id3,
1348 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary);
1349 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1350 status = ndr_map_error2ntstatus(ndr_err);
1351 talloc_free(tmp_ctx);
1352 return ntstatus_to_werror(status);
1355 dn = ldb_dn_new(tmp_ctx, ldb, id3.dn);
1357 talloc_free(tmp_ctx);
1358 /* If this fails, it must be out of memory, as it does not do much parsing */
1359 W_ERROR_HAVE_NO_MEMORY(dn);
1362 status = GUID_to_ndr_blob(&id3.guid, tmp_ctx, &guid_blob);
1363 if (!NT_STATUS_IS_OK(status)) {
1364 talloc_free(tmp_ctx);
1365 return ntstatus_to_werror(status);
1368 ret = ldb_dn_set_extended_component(dn, "GUID", &guid_blob);
1369 if (ret != LDB_SUCCESS) {
1370 talloc_free(tmp_ctx);
1374 talloc_free(guid_blob.data);
1376 if (id3.__ndr_size_sid) {
1378 ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, schema->iconv_convenience, &id3.sid,
1379 (ndr_push_flags_fn_t)ndr_push_dom_sid);
1380 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1381 status = ndr_map_error2ntstatus(ndr_err);
1382 talloc_free(tmp_ctx);
1383 return ntstatus_to_werror(status);
1386 ret = ldb_dn_set_extended_component(dn, "SID", &sid_blob);
1387 if (ret != LDB_SUCCESS) {
1388 talloc_free(tmp_ctx);
1393 /* set binary stuff */
1394 dsdb_dn = dsdb_dn_construct(tmp_ctx, dn, id3.binary, attr->syntax->ldap_oid);
1396 /* If this fails, it must be out of memory, we know the ldap_oid is valid */
1397 talloc_free(tmp_ctx);
1398 W_ERROR_HAVE_NO_MEMORY(dsdb_dn);
1400 out->values[i] = data_blob_string_const(dsdb_dn_get_extended_linearized(out->values, dsdb_dn, 1));
1401 talloc_free(tmp_ctx);
1407 static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(struct ldb_context *ldb,
1408 const struct dsdb_schema *schema,
1409 const struct dsdb_attribute *attr,
1410 const struct ldb_message_element *in,
1411 TALLOC_CTX *mem_ctx,
1412 struct drsuapi_DsReplicaAttribute *out)
1417 if (attr->attributeID_id == 0xFFFFFFFF) {
1421 out->attid = attr->attributeID_id;
1422 out->value_ctr.num_values = in->num_values;
1423 out->value_ctr.values = talloc_array(mem_ctx,
1424 struct drsuapi_DsAttributeValue,
1426 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1428 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1429 W_ERROR_HAVE_NO_MEMORY(blobs);
1431 for (i=0; i < in->num_values; i++) {
1432 struct drsuapi_DsReplicaObjectIdentifier3Binary id3;
1433 enum ndr_err_code ndr_err;
1434 const DATA_BLOB *sid_blob;
1435 struct dsdb_dn *dsdb_dn;
1436 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1439 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1441 out->value_ctr.values[i].blob = &blobs[i];
1443 dsdb_dn = dsdb_dn_parse(tmp_ctx, ldb, &in->values[i], attr->syntax->ldap_oid);
1446 talloc_free(tmp_ctx);
1447 return ntstatus_to_werror(NT_STATUS_INVALID_PARAMETER);
1452 status = dsdb_get_extended_dn_guid(dsdb_dn->dn, &id3.guid, "GUID");
1453 if (!NT_STATUS_IS_OK(status) &&
1454 !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1455 talloc_free(tmp_ctx);
1456 return ntstatus_to_werror(status);
1459 sid_blob = ldb_dn_get_extended_component(dsdb_dn->dn, "SID");
1462 ndr_err = ndr_pull_struct_blob_all(sid_blob,
1463 tmp_ctx, schema->iconv_convenience, &id3.sid,
1464 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1465 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1466 status = ndr_map_error2ntstatus(ndr_err);
1467 talloc_free(tmp_ctx);
1468 return ntstatus_to_werror(status);
1472 id3.dn = ldb_dn_get_linearized(dsdb_dn->dn);
1474 /* get binary stuff */
1475 id3.binary = dsdb_dn->extra_part;
1477 ndr_err = ndr_push_struct_blob(&blobs[i], blobs, schema->iconv_convenience, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary);
1478 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1479 status = ndr_map_error2ntstatus(ndr_err);
1480 talloc_free(tmp_ctx);
1481 return ntstatus_to_werror(status);
1483 talloc_free(tmp_ctx);
1489 static WERROR dsdb_syntax_DN_STRING_drsuapi_to_ldb(struct ldb_context *ldb,
1490 const struct dsdb_schema *schema,
1491 const struct dsdb_attribute *attr,
1492 const struct drsuapi_DsReplicaAttribute *in,
1493 TALLOC_CTX *mem_ctx,
1494 struct ldb_message_element *out)
1496 return dsdb_syntax_DN_BINARY_drsuapi_to_ldb(ldb,
1504 static WERROR dsdb_syntax_DN_STRING_ldb_to_drsuapi(struct ldb_context *ldb,
1505 const struct dsdb_schema *schema,
1506 const struct dsdb_attribute *attr,
1507 const struct ldb_message_element *in,
1508 TALLOC_CTX *mem_ctx,
1509 struct drsuapi_DsReplicaAttribute *out)
1511 return dsdb_syntax_DN_BINARY_ldb_to_drsuapi(ldb,
1519 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb(struct ldb_context *ldb,
1520 const struct dsdb_schema *schema,
1521 const struct dsdb_attribute *attr,
1522 const struct drsuapi_DsReplicaAttribute *in,
1523 TALLOC_CTX *mem_ctx,
1524 struct ldb_message_element *out)
1529 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1530 W_ERROR_HAVE_NO_MEMORY(out->name);
1532 out->num_values = in->value_ctr.num_values;
1533 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1534 W_ERROR_HAVE_NO_MEMORY(out->values);
1536 for (i=0; i < out->num_values; i++) {
1540 if (in->value_ctr.values[i].blob == NULL) {
1544 if (in->value_ctr.values[i].blob->length < 4) {
1548 len = IVAL(in->value_ctr.values[i].blob->data, 0);
1550 if (len != in->value_ctr.values[i].blob->length) {
1554 if (!convert_string_talloc_convenience(out->values, schema->iconv_convenience, CH_UTF16, CH_UNIX,
1555 in->value_ctr.values[i].blob->data+4,
1556 in->value_ctr.values[i].blob->length-4,
1557 (void **)&str, NULL, false)) {
1561 out->values[i] = data_blob_string_const(str);
1567 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi(struct ldb_context *ldb,
1568 const struct dsdb_schema *schema,
1569 const struct dsdb_attribute *attr,
1570 const struct ldb_message_element *in,
1571 TALLOC_CTX *mem_ctx,
1572 struct drsuapi_DsReplicaAttribute *out)
1577 if (attr->attributeID_id == 0xFFFFFFFF) {
1581 out->attid = attr->attributeID_id;
1582 out->value_ctr.num_values = in->num_values;
1583 out->value_ctr.values = talloc_array(mem_ctx,
1584 struct drsuapi_DsAttributeValue,
1586 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1588 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1589 W_ERROR_HAVE_NO_MEMORY(blobs);
1591 for (i=0; i < in->num_values; i++) {
1595 out->value_ctr.values[i].blob = &blobs[i];
1597 if (!convert_string_talloc_convenience(blobs, schema->iconv_convenience, CH_UNIX, CH_UTF16,
1599 in->values[i].length,
1600 (void **)&data, &ret, false)) {
1604 blobs[i] = data_blob_talloc(blobs, NULL, 4 + ret);
1605 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
1607 SIVAL(blobs[i].data, 0, 4 + ret);
1610 memcpy(blobs[i].data + 4, data, ret);
1618 #define OMOBJECTCLASS(val) { .length = sizeof(val) - 1, .data = discard_const_p(uint8_t, val) }
1620 static const struct dsdb_syntax dsdb_syntaxes[] = {
1623 .ldap_oid = LDB_SYNTAX_BOOLEAN,
1625 .attributeSyntax_oid = "2.5.5.8",
1626 .drsuapi_to_ldb = dsdb_syntax_BOOL_drsuapi_to_ldb,
1627 .ldb_to_drsuapi = dsdb_syntax_BOOL_ldb_to_drsuapi,
1628 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1629 .equality = "booleanMatch",
1630 .comment = "Boolean"
1633 .ldap_oid = LDB_SYNTAX_INTEGER,
1635 .attributeSyntax_oid = "2.5.5.9",
1636 .drsuapi_to_ldb = dsdb_syntax_INT32_drsuapi_to_ldb,
1637 .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi,
1638 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1639 .equality = "integerMatch",
1640 .comment = "Integer",
1641 .ldb_syntax = LDB_SYNTAX_SAMBA_INT32
1643 .name = "String(Octet)",
1644 .ldap_oid = LDB_SYNTAX_OCTET_STRING,
1646 .attributeSyntax_oid = "2.5.5.10",
1647 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1648 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1649 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1650 .equality = "octetStringMatch",
1651 .comment = "Octet String",
1653 .name = "String(Sid)",
1654 .ldap_oid = LDB_SYNTAX_OCTET_STRING,
1656 .attributeSyntax_oid = "2.5.5.17",
1657 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1658 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1659 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1660 .equality = "octetStringMatch",
1661 .comment = "Octet String - Security Identifier (SID)",
1662 .ldb_syntax = LDB_SYNTAX_SAMBA_SID
1664 .name = "String(Object-Identifier)",
1665 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.38",
1667 .attributeSyntax_oid = "2.5.5.2",
1668 .drsuapi_to_ldb = dsdb_syntax_OID_drsuapi_to_ldb,
1669 .ldb_to_drsuapi = dsdb_syntax_OID_ldb_to_drsuapi,
1670 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1671 .equality = "caseIgnoreMatch", /* Would use "objectIdentifierMatch" but most are ldap attribute/class names */
1672 .comment = "OID String",
1673 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING
1675 .name = "Enumeration",
1676 .ldap_oid = LDB_SYNTAX_INTEGER,
1678 .attributeSyntax_oid = "2.5.5.9",
1679 .drsuapi_to_ldb = dsdb_syntax_INT32_drsuapi_to_ldb,
1680 .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi,
1681 .validate_ldb = dsdb_syntax_INT32_validate_ldb,
1682 .ldb_syntax = LDB_SYNTAX_SAMBA_INT32
1684 /* not used in w2k3 forest */
1685 .name = "String(Numeric)",
1686 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.36",
1688 .attributeSyntax_oid = "2.5.5.6",
1689 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1690 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1691 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1692 .equality = "numericStringMatch",
1693 .substring = "numericStringSubstringsMatch",
1694 .comment = "Numeric String",
1695 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING,
1697 .name = "String(Printable)",
1698 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.44",
1700 .attributeSyntax_oid = "2.5.5.5",
1701 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1702 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1703 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1704 .ldb_syntax = LDB_SYNTAX_OCTET_STRING,
1706 .name = "String(Teletex)",
1707 .ldap_oid = "1.2.840.113556.1.4.905",
1709 .attributeSyntax_oid = "2.5.5.4",
1710 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1711 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1712 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1713 .equality = "caseIgnoreMatch",
1714 .substring = "caseIgnoreSubstringsMatch",
1715 .comment = "Case Insensitive String",
1716 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING,
1718 .name = "String(IA5)",
1719 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.26",
1721 .attributeSyntax_oid = "2.5.5.5",
1722 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1723 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1724 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1725 .equality = "caseExactIA5Match",
1726 .comment = "Printable String",
1727 .ldb_syntax = LDB_SYNTAX_OCTET_STRING,
1729 .name = "String(UTC-Time)",
1730 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.53",
1732 .attributeSyntax_oid = "2.5.5.11",
1733 .drsuapi_to_ldb = dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb,
1734 .ldb_to_drsuapi = dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi,
1735 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1736 .equality = "generalizedTimeMatch",
1737 .comment = "UTC Time",
1739 .name = "String(Generalized-Time)",
1740 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.24",
1742 .attributeSyntax_oid = "2.5.5.11",
1743 .drsuapi_to_ldb = dsdb_syntax_NTTIME_drsuapi_to_ldb,
1744 .ldb_to_drsuapi = dsdb_syntax_NTTIME_ldb_to_drsuapi,
1745 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1746 .equality = "generalizedTimeMatch",
1747 .comment = "Generalized Time",
1748 .ldb_syntax = LDB_SYNTAX_UTC_TIME,
1750 /* not used in w2k3 schema */
1751 .name = "String(Case Sensitive)",
1752 .ldap_oid = "1.2.840.113556.1.4.1362",
1754 .attributeSyntax_oid = "2.5.5.3",
1755 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1756 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1757 .validate_ldb = dsdb_syntax_FOOBAR_validate_ldb,
1759 .name = "String(Unicode)",
1760 .ldap_oid = LDB_SYNTAX_DIRECTORY_STRING,
1762 .attributeSyntax_oid = "2.5.5.12",
1763 .drsuapi_to_ldb = dsdb_syntax_UNICODE_drsuapi_to_ldb,
1764 .ldb_to_drsuapi = dsdb_syntax_UNICODE_ldb_to_drsuapi,
1765 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1766 .equality = "caseIgnoreMatch",
1767 .substring = "caseIgnoreSubstringsMatch",
1768 .comment = "Directory String",
1770 .name = "Interval/LargeInteger",
1771 .ldap_oid = "1.2.840.113556.1.4.906",
1773 .attributeSyntax_oid = "2.5.5.16",
1774 .drsuapi_to_ldb = dsdb_syntax_INT64_drsuapi_to_ldb,
1775 .ldb_to_drsuapi = dsdb_syntax_INT64_ldb_to_drsuapi,
1776 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1777 .equality = "integerMatch",
1778 .comment = "Large Integer",
1779 .ldb_syntax = LDB_SYNTAX_INTEGER,
1781 .name = "String(NT-Sec-Desc)",
1782 .ldap_oid = LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR,
1784 .attributeSyntax_oid = "2.5.5.15",
1785 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1786 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1787 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1789 .name = "Object(DS-DN)",
1790 .ldap_oid = LDB_SYNTAX_DN,
1792 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x4a"),
1793 .attributeSyntax_oid = "2.5.5.1",
1794 .drsuapi_to_ldb = dsdb_syntax_DN_drsuapi_to_ldb,
1795 .ldb_to_drsuapi = dsdb_syntax_DN_ldb_to_drsuapi,
1796 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1797 .equality = "distinguishedNameMatch",
1798 .comment = "Object(DS-DN) == a DN",
1800 .name = "Object(DN-Binary)",
1801 .ldap_oid = DSDB_SYNTAX_BINARY_DN,
1803 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0b"),
1804 .attributeSyntax_oid = "2.5.5.7",
1805 .drsuapi_to_ldb = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
1806 .ldb_to_drsuapi = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
1807 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1808 .equality = "octetStringMatch",
1809 .comment = "OctetString: Binary+DN",
1811 /* not used in w2k3 schema, but used in Exchange schema*/
1812 .name = "Object(OR-Name)",
1813 .ldap_oid = DSDB_SYNTAX_OR_NAME,
1815 .oMObjectClass = OMOBJECTCLASS("\x56\x06\x01\x02\x05\x0b\x1D"),
1816 .attributeSyntax_oid = "2.5.5.7",
1817 .drsuapi_to_ldb = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
1818 .ldb_to_drsuapi = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
1819 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1820 .equality = "caseIgnoreMatch",
1821 .ldb_syntax = LDB_SYNTAX_DN,
1824 * TODO: verify if DATA_BLOB is correct here...!
1826 * repsFrom and repsTo are the only attributes using
1827 * this attribute syntax, but they're not replicated...
1829 .name = "Object(Replica-Link)",
1830 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.40",
1832 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x06"),
1833 .attributeSyntax_oid = "2.5.5.10",
1834 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1835 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1836 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1838 .name = "Object(Presentation-Address)",
1839 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.43",
1841 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x5c"),
1842 .attributeSyntax_oid = "2.5.5.13",
1843 .drsuapi_to_ldb = dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb,
1844 .ldb_to_drsuapi = dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi,
1845 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1846 .comment = "Presentation Address",
1847 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING,
1849 /* not used in w2k3 schema */
1850 .name = "Object(Access-Point)",
1851 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.2",
1853 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x3e"),
1854 .attributeSyntax_oid = "2.5.5.14",
1855 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1856 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1857 .validate_ldb = dsdb_syntax_FOOBAR_validate_ldb,
1858 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING,
1860 /* not used in w2k3 schema */
1861 .name = "Object(DN-String)",
1862 .ldap_oid = DSDB_SYNTAX_STRING_DN,
1864 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0c"),
1865 .attributeSyntax_oid = "2.5.5.14",
1866 .drsuapi_to_ldb = dsdb_syntax_DN_STRING_drsuapi_to_ldb,
1867 .ldb_to_drsuapi = dsdb_syntax_DN_STRING_ldb_to_drsuapi,
1868 .validate_ldb = dsdb_syntax_ALLOW_validate_ldb,
1869 .equality = "octetStringMatch",
1870 .comment = "OctetString: String+DN",
1874 const struct dsdb_syntax *find_syntax_map_by_ad_oid(const char *ad_oid)
1877 for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
1878 if (strcasecmp(ad_oid, dsdb_syntaxes[i].attributeSyntax_oid) == 0) {
1879 return &dsdb_syntaxes[i];
1885 const struct dsdb_syntax *find_syntax_map_by_ad_syntax(int oMSyntax)
1888 for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
1889 if (oMSyntax == dsdb_syntaxes[i].oMSyntax) {
1890 return &dsdb_syntaxes[i];
1896 const struct dsdb_syntax *find_syntax_map_by_standard_oid(const char *standard_oid)
1899 for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
1900 if (strcasecmp(standard_oid, dsdb_syntaxes[i].ldap_oid) == 0) {
1901 return &dsdb_syntaxes[i];
1906 const struct dsdb_syntax *dsdb_syntax_for_attribute(const struct dsdb_attribute *attr)
1910 for (i=0; i < ARRAY_SIZE(dsdb_syntaxes); i++) {
1911 if (attr->oMSyntax != dsdb_syntaxes[i].oMSyntax) continue;
1913 if (attr->oMObjectClass.length != dsdb_syntaxes[i].oMObjectClass.length) continue;
1915 if (attr->oMObjectClass.length) {
1917 ret = memcmp(attr->oMObjectClass.data,
1918 dsdb_syntaxes[i].oMObjectClass.data,
1919 attr->oMObjectClass.length);
1920 if (ret != 0) continue;
1923 if (strcmp(attr->attributeSyntax_oid, dsdb_syntaxes[i].attributeSyntax_oid) != 0) continue;
1925 return &dsdb_syntaxes[i];
1931 WERROR dsdb_attribute_drsuapi_to_ldb(struct ldb_context *ldb,
1932 const struct dsdb_schema *schema,
1933 const struct drsuapi_DsReplicaAttribute *in,
1934 TALLOC_CTX *mem_ctx,
1935 struct ldb_message_element *out)
1937 const struct dsdb_attribute *sa;
1939 sa = dsdb_attribute_by_attributeID_id(schema, in->attid);
1944 return sa->syntax->drsuapi_to_ldb(ldb, schema, sa, in, mem_ctx, out);
1947 WERROR dsdb_attribute_ldb_to_drsuapi(struct ldb_context *ldb,
1948 const struct dsdb_schema *schema,
1949 const struct ldb_message_element *in,
1950 TALLOC_CTX *mem_ctx,
1951 struct drsuapi_DsReplicaAttribute *out)
1953 const struct dsdb_attribute *sa;
1955 sa = dsdb_attribute_by_lDAPDisplayName(schema, in->name);
1960 return sa->syntax->ldb_to_drsuapi(ldb, schema, sa, in, mem_ctx, out);
1963 WERROR dsdb_attribute_validate_ldb(struct ldb_context *ldb,
1964 const struct dsdb_schema *schema,
1965 const struct ldb_message_element *in)
1967 const struct dsdb_attribute *sa;
1969 sa = dsdb_attribute_by_lDAPDisplayName(schema, in->name);
1971 return WERR_DS_ATTRIBUTE_TYPE_UNDEFINED;
1974 return sa->syntax->validate_ldb(ldb, schema, sa, in);