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"
35 * Initialize dsdb_syntax_ctx with default values
38 void dsdb_syntax_ctx_init(struct dsdb_syntax_ctx *ctx,
39 struct ldb_context *ldb,
40 const struct dsdb_schema *schema)
46 * 'true' will keep current behavior,
47 * i.e. attributeID_id will be returned by default
49 ctx->is_schema_nc = true;
54 * Returns ATTID for DRS attribute.
56 * ATTID depends on whether we are replicating
57 * Schema NC or msDs-IntId is set for schemaAttribute
60 static uint32_t dsdb_attribute_get_attid(const struct dsdb_attribute *attr,
63 if (!for_schema_nc && attr->msDS_IntId) {
64 return attr->msDS_IntId;
67 return attr->attributeID_id;
71 static WERROR dsdb_syntax_FOOBAR_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
72 const struct dsdb_attribute *attr,
73 const struct drsuapi_DsReplicaAttribute *in,
75 struct ldb_message_element *out)
80 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
81 W_ERROR_HAVE_NO_MEMORY(out->name);
83 out->num_values = in->value_ctr.num_values;
84 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
85 W_ERROR_HAVE_NO_MEMORY(out->values);
87 for (i=0; i < out->num_values; i++) {
90 if (in->value_ctr.values[i].blob == NULL) {
94 str = talloc_asprintf(out->values, "%s: not implemented",
96 W_ERROR_HAVE_NO_MEMORY(str);
98 out->values[i] = data_blob_string_const(str);
104 static WERROR dsdb_syntax_FOOBAR_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
105 const struct dsdb_attribute *attr,
106 const struct ldb_message_element *in,
108 struct drsuapi_DsReplicaAttribute *out)
113 static WERROR dsdb_syntax_FOOBAR_validate_ldb(const struct dsdb_syntax_ctx *ctx,
114 const struct dsdb_attribute *attr,
115 const struct ldb_message_element *in)
120 static WERROR dsdb_syntax_BOOL_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
121 const struct dsdb_attribute *attr,
122 const struct drsuapi_DsReplicaAttribute *in,
124 struct ldb_message_element *out)
129 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
130 W_ERROR_HAVE_NO_MEMORY(out->name);
132 out->num_values = in->value_ctr.num_values;
133 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
134 W_ERROR_HAVE_NO_MEMORY(out->values);
136 for (i=0; i < out->num_values; i++) {
140 if (in->value_ctr.values[i].blob == NULL) {
144 if (in->value_ctr.values[i].blob->length != 4) {
148 v = IVAL(in->value_ctr.values[i].blob->data, 0);
151 str = talloc_strdup(out->values, "TRUE");
152 W_ERROR_HAVE_NO_MEMORY(str);
154 str = talloc_strdup(out->values, "FALSE");
155 W_ERROR_HAVE_NO_MEMORY(str);
158 out->values[i] = data_blob_string_const(str);
164 static WERROR dsdb_syntax_BOOL_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
165 const struct dsdb_attribute *attr,
166 const struct ldb_message_element *in,
168 struct drsuapi_DsReplicaAttribute *out)
173 if (attr->attributeID_id == 0xFFFFFFFF) {
177 out->attid = dsdb_attribute_get_attid(attr,
179 out->value_ctr.num_values = in->num_values;
180 out->value_ctr.values = talloc_array(mem_ctx,
181 struct drsuapi_DsAttributeValue,
183 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
185 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
186 W_ERROR_HAVE_NO_MEMORY(blobs);
188 for (i=0; i < in->num_values; i++) {
189 out->value_ctr.values[i].blob = &blobs[i];
191 blobs[i] = data_blob_talloc(blobs, NULL, 4);
192 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
194 if (strcmp("TRUE", (const char *)in->values[i].data) == 0) {
195 SIVAL(blobs[i].data, 0, 0x00000001);
196 } else if (strcmp("FALSE", (const char *)in->values[i].data) == 0) {
197 SIVAL(blobs[i].data, 0, 0x00000000);
206 static WERROR dsdb_syntax_BOOL_validate_ldb(const struct dsdb_syntax_ctx *ctx,
207 const struct dsdb_attribute *attr,
208 const struct ldb_message_element *in)
212 if (attr->attributeID_id == 0xFFFFFFFF) {
216 for (i=0; i < in->num_values; i++) {
220 (const char *)in->values[i].data,
221 in->values[i].length);
223 (const char *)in->values[i].data,
224 in->values[i].length);
226 if (t != 0 && f != 0) {
227 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
234 static WERROR dsdb_syntax_INT32_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
235 const struct dsdb_attribute *attr,
236 const struct drsuapi_DsReplicaAttribute *in,
238 struct ldb_message_element *out)
243 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
244 W_ERROR_HAVE_NO_MEMORY(out->name);
246 out->num_values = in->value_ctr.num_values;
247 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
248 W_ERROR_HAVE_NO_MEMORY(out->values);
250 for (i=0; i < out->num_values; i++) {
254 if (in->value_ctr.values[i].blob == NULL) {
258 if (in->value_ctr.values[i].blob->length != 4) {
262 v = IVALS(in->value_ctr.values[i].blob->data, 0);
264 str = talloc_asprintf(out->values, "%d", v);
265 W_ERROR_HAVE_NO_MEMORY(str);
267 out->values[i] = data_blob_string_const(str);
273 static WERROR dsdb_syntax_INT32_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
274 const struct dsdb_attribute *attr,
275 const struct ldb_message_element *in,
277 struct drsuapi_DsReplicaAttribute *out)
282 if (attr->attributeID_id == 0xFFFFFFFF) {
286 out->attid = dsdb_attribute_get_attid(attr,
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, 4);
303 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
305 /* We've to use "strtoll" here to have the intended overflows.
306 * Otherwise we may get "LONG_MAX" and the conversion is wrong. */
307 v = (int32_t) strtoll((char *)in->values[i].data, NULL, 0);
309 SIVALS(blobs[i].data, 0, v);
315 static WERROR dsdb_syntax_INT32_validate_ldb(const struct dsdb_syntax_ctx *ctx,
316 const struct dsdb_attribute *attr,
317 const struct ldb_message_element *in)
321 if (attr->attributeID_id == 0xFFFFFFFF) {
325 for (i=0; i < in->num_values; i++) {
327 char buf[sizeof("-2147483648")];
331 if (in->values[i].length >= sizeof(buf)) {
332 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
335 memcpy(buf, in->values[i].data, in->values[i].length);
337 v = strtol(buf, &end, 10);
339 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
341 if (end && end[0] != '\0') {
342 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
345 if (attr->rangeLower) {
346 if ((int32_t)v < (int32_t)*attr->rangeLower) {
347 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
351 if (attr->rangeUpper) {
352 if ((int32_t)v > (int32_t)*attr->rangeUpper) {
353 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
361 static WERROR dsdb_syntax_INT64_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
362 const struct dsdb_attribute *attr,
363 const struct drsuapi_DsReplicaAttribute *in,
365 struct ldb_message_element *out)
370 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
371 W_ERROR_HAVE_NO_MEMORY(out->name);
373 out->num_values = in->value_ctr.num_values;
374 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
375 W_ERROR_HAVE_NO_MEMORY(out->values);
377 for (i=0; i < out->num_values; i++) {
381 if (in->value_ctr.values[i].blob == NULL) {
385 if (in->value_ctr.values[i].blob->length != 8) {
389 v = BVALS(in->value_ctr.values[i].blob->data, 0);
391 str = talloc_asprintf(out->values, "%lld", (long long int)v);
392 W_ERROR_HAVE_NO_MEMORY(str);
394 out->values[i] = data_blob_string_const(str);
400 static WERROR dsdb_syntax_INT64_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
401 const struct dsdb_attribute *attr,
402 const struct ldb_message_element *in,
404 struct drsuapi_DsReplicaAttribute *out)
409 if (attr->attributeID_id == 0xFFFFFFFF) {
413 out->attid = dsdb_attribute_get_attid(attr,
415 out->value_ctr.num_values = in->num_values;
416 out->value_ctr.values = talloc_array(mem_ctx,
417 struct drsuapi_DsAttributeValue,
419 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
421 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
422 W_ERROR_HAVE_NO_MEMORY(blobs);
424 for (i=0; i < in->num_values; i++) {
427 out->value_ctr.values[i].blob = &blobs[i];
429 blobs[i] = data_blob_talloc(blobs, NULL, 8);
430 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
432 v = strtoll((const char *)in->values[i].data, NULL, 10);
434 SBVALS(blobs[i].data, 0, v);
440 static WERROR dsdb_syntax_INT64_validate_ldb(const struct dsdb_syntax_ctx *ctx,
441 const struct dsdb_attribute *attr,
442 const struct ldb_message_element *in)
446 if (attr->attributeID_id == 0xFFFFFFFF) {
450 for (i=0; i < in->num_values; i++) {
452 char buf[sizeof("-9223372036854775808")];
456 if (in->values[i].length >= sizeof(buf)) {
457 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
459 memcpy(buf, in->values[i].data, in->values[i].length);
462 v = strtoll(buf, &end, 10);
464 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
466 if (end && end[0] != '\0') {
467 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
470 if (attr->rangeLower) {
471 if ((int64_t)v < (int64_t)*attr->rangeLower) {
472 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
476 if (attr->rangeUpper) {
477 if ((int64_t)v > (int64_t)*attr->rangeUpper) {
478 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
485 static WERROR dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
486 const struct dsdb_attribute *attr,
487 const struct drsuapi_DsReplicaAttribute *in,
489 struct ldb_message_element *out)
494 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
495 W_ERROR_HAVE_NO_MEMORY(out->name);
497 out->num_values = in->value_ctr.num_values;
498 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
499 W_ERROR_HAVE_NO_MEMORY(out->values);
501 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 != 8) {
514 v = BVAL(in->value_ctr.values[i].blob->data, 0);
516 t = nt_time_to_unix(v);
519 * NOTE: On a w2k3 server you can set a GeneralizedTime string
520 * via LDAP, but you get back an UTCTime string,
521 * but via DRSUAPI you get back the NTTIME_1sec value
522 * that represents the GeneralizedTime value!
524 * So if we store the UTCTime string in our ldb
525 * we'll loose information!
527 str = ldb_timestring_utc(out->values, t);
528 W_ERROR_HAVE_NO_MEMORY(str);
529 out->values[i] = data_blob_string_const(str);
535 static WERROR dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
536 const struct dsdb_attribute *attr,
537 const struct ldb_message_element *in,
539 struct drsuapi_DsReplicaAttribute *out)
544 if (attr->attributeID_id == 0xFFFFFFFF) {
548 out->attid = dsdb_attribute_get_attid(attr,
550 out->value_ctr.num_values = in->num_values;
551 out->value_ctr.values = talloc_array(mem_ctx,
552 struct drsuapi_DsAttributeValue,
554 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
556 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
557 W_ERROR_HAVE_NO_MEMORY(blobs);
559 for (i=0; i < in->num_values; i++) {
563 out->value_ctr.values[i].blob = &blobs[i];
565 blobs[i] = data_blob_talloc(blobs, NULL, 8);
566 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
568 t = ldb_string_utc_to_time((const char *)in->values[i].data);
569 unix_to_nt_time(&v, t);
572 SBVAL(blobs[i].data, 0, v);
578 static WERROR dsdb_syntax_NTTIME_UTC_validate_ldb(const struct dsdb_syntax_ctx *ctx,
579 const struct dsdb_attribute *attr,
580 const struct ldb_message_element *in)
584 if (attr->attributeID_id == 0xFFFFFFFF) {
588 for (i=0; i < in->num_values; i++) {
590 char buf[sizeof("090826075717Z")];
593 if (in->values[i].length >= sizeof(buf)) {
594 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
596 memcpy(buf, in->values[i].data, in->values[i].length);
599 t = ldb_string_utc_to_time(buf);
601 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
604 if (attr->rangeLower) {
605 if ((int32_t)t < (int32_t)*attr->rangeLower) {
606 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
610 if (attr->rangeUpper) {
611 if ((int32_t)t > (int32_t)*attr->rangeLower) {
612 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
617 * TODO: verify the comment in the
618 * dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb() function!
625 static WERROR dsdb_syntax_NTTIME_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
626 const struct dsdb_attribute *attr,
627 const struct drsuapi_DsReplicaAttribute *in,
629 struct ldb_message_element *out)
634 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
635 W_ERROR_HAVE_NO_MEMORY(out->name);
637 out->num_values = in->value_ctr.num_values;
638 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
639 W_ERROR_HAVE_NO_MEMORY(out->values);
641 for (i=0; i < out->num_values; i++) {
646 if (in->value_ctr.values[i].blob == NULL) {
650 if (in->value_ctr.values[i].blob->length != 8) {
654 v = BVAL(in->value_ctr.values[i].blob->data, 0);
656 t = nt_time_to_unix(v);
658 str = ldb_timestring(out->values, t);
659 W_ERROR_HAVE_NO_MEMORY(str);
661 out->values[i] = data_blob_string_const(str);
667 static WERROR dsdb_syntax_NTTIME_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
668 const struct dsdb_attribute *attr,
669 const struct ldb_message_element *in,
671 struct drsuapi_DsReplicaAttribute *out)
676 if (attr->attributeID_id == 0xFFFFFFFF) {
680 out->attid = dsdb_attribute_get_attid(attr,
682 out->value_ctr.num_values = in->num_values;
683 out->value_ctr.values = talloc_array(mem_ctx,
684 struct drsuapi_DsAttributeValue,
686 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
688 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
689 W_ERROR_HAVE_NO_MEMORY(blobs);
691 for (i=0; i < in->num_values; i++) {
696 out->value_ctr.values[i].blob = &blobs[i];
698 blobs[i] = data_blob_talloc(blobs, NULL, 8);
699 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
701 ret = ldb_val_to_time(&in->values[i], &t);
702 if (ret != LDB_SUCCESS) {
703 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
705 unix_to_nt_time(&v, t);
708 SBVAL(blobs[i].data, 0, v);
714 static WERROR dsdb_syntax_NTTIME_validate_ldb(const struct dsdb_syntax_ctx *ctx,
715 const struct dsdb_attribute *attr,
716 const struct ldb_message_element *in)
720 if (attr->attributeID_id == 0xFFFFFFFF) {
724 for (i=0; i < in->num_values; i++) {
728 ret = ldb_val_to_time(&in->values[i], &t);
729 if (ret != LDB_SUCCESS) {
730 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
733 if (attr->rangeLower) {
734 if ((int32_t)t < (int32_t)*attr->rangeLower) {
735 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
739 if (attr->rangeUpper) {
740 if ((int32_t)t > (int32_t)*attr->rangeLower) {
741 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
749 static WERROR dsdb_syntax_DATA_BLOB_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
750 const struct dsdb_attribute *attr,
751 const struct drsuapi_DsReplicaAttribute *in,
753 struct ldb_message_element *out)
758 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
759 W_ERROR_HAVE_NO_MEMORY(out->name);
761 out->num_values = in->value_ctr.num_values;
762 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
763 W_ERROR_HAVE_NO_MEMORY(out->values);
765 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 == 0) {
774 out->values[i] = data_blob_dup_talloc(out->values,
775 in->value_ctr.values[i].blob);
776 W_ERROR_HAVE_NO_MEMORY(out->values[i].data);
782 static WERROR dsdb_syntax_DATA_BLOB_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
783 const struct dsdb_attribute *attr,
784 const struct ldb_message_element *in,
786 struct drsuapi_DsReplicaAttribute *out)
791 if (attr->attributeID_id == 0xFFFFFFFF) {
795 out->attid = dsdb_attribute_get_attid(attr,
797 out->value_ctr.num_values = in->num_values;
798 out->value_ctr.values = talloc_array(mem_ctx,
799 struct drsuapi_DsAttributeValue,
801 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
803 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
804 W_ERROR_HAVE_NO_MEMORY(blobs);
806 for (i=0; i < in->num_values; i++) {
807 out->value_ctr.values[i].blob = &blobs[i];
809 blobs[i] = data_blob_dup_talloc(blobs, &in->values[i]);
810 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
816 static WERROR dsdb_syntax_DATA_BLOB_validate_one_val(const struct dsdb_syntax_ctx *ctx,
817 const struct dsdb_attribute *attr,
818 const struct ldb_val *val)
820 if (attr->attributeID_id == 0xFFFFFFFF) {
824 if (attr->rangeLower) {
825 if ((uint32_t)val->length < (uint32_t)*attr->rangeLower) {
826 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
830 if (attr->rangeUpper) {
831 if ((uint32_t)val->length > (uint32_t)*attr->rangeUpper) {
832 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
839 static WERROR dsdb_syntax_DATA_BLOB_validate_ldb(const struct dsdb_syntax_ctx *ctx,
840 const struct dsdb_attribute *attr,
841 const struct ldb_message_element *in)
846 if (attr->attributeID_id == 0xFFFFFFFF) {
850 for (i=0; i < in->num_values; i++) {
851 if (in->values[i].length == 0) {
852 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
855 status = dsdb_syntax_DATA_BLOB_validate_one_val(ctx,
858 if (!W_ERROR_IS_OK(status)) {
866 static WERROR _dsdb_syntax_auto_OID_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
867 const struct dsdb_attribute *attr,
868 const struct drsuapi_DsReplicaAttribute *in,
870 struct ldb_message_element *out)
875 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
876 W_ERROR_HAVE_NO_MEMORY(out->name);
878 out->num_values = in->value_ctr.num_values;
879 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
880 W_ERROR_HAVE_NO_MEMORY(out->values);
882 for (i=0; i < out->num_values; i++) {
884 const struct dsdb_class *c;
885 const struct dsdb_attribute *a;
886 const char *str = NULL;
888 if (in->value_ctr.values[i].blob == NULL) {
892 if (in->value_ctr.values[i].blob->length != 4) {
896 v = IVAL(in->value_ctr.values[i].blob->data, 0);
898 if ((c = dsdb_class_by_governsID_id(ctx->schema, v))) {
899 str = talloc_strdup(out->values, c->lDAPDisplayName);
900 } else if ((a = dsdb_attribute_by_attributeID_id(ctx->schema, v))) {
901 str = talloc_strdup(out->values, a->lDAPDisplayName);
904 werr = dsdb_schema_pfm_oid_from_attid(ctx->schema->prefixmap, v, out->values, &str);
905 W_ERROR_NOT_OK_RETURN(werr);
907 W_ERROR_HAVE_NO_MEMORY(str);
909 /* the values need to be reversed */
910 out->values[out->num_values - (i + 1)] = data_blob_string_const(str);
916 static WERROR _dsdb_syntax_OID_obj_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
917 const struct dsdb_attribute *attr,
918 const struct drsuapi_DsReplicaAttribute *in,
920 struct ldb_message_element *out)
925 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
926 W_ERROR_HAVE_NO_MEMORY(out->name);
928 out->num_values = in->value_ctr.num_values;
929 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
930 W_ERROR_HAVE_NO_MEMORY(out->values);
932 for (i=0; i < out->num_values; i++) {
934 const struct dsdb_class *c;
937 if (in->value_ctr.values[i].blob == NULL) {
941 if (in->value_ctr.values[i].blob->length != 4) {
945 v = IVAL(in->value_ctr.values[i].blob->data, 0);
947 c = dsdb_class_by_governsID_id(ctx->schema, v);
952 str = talloc_strdup(out->values, c->lDAPDisplayName);
953 W_ERROR_HAVE_NO_MEMORY(str);
955 /* the values need to be reversed */
956 out->values[out->num_values - (i + 1)] = data_blob_string_const(str);
962 static WERROR _dsdb_syntax_OID_attr_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
963 const struct dsdb_attribute *attr,
964 const struct drsuapi_DsReplicaAttribute *in,
966 struct ldb_message_element *out)
971 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
972 W_ERROR_HAVE_NO_MEMORY(out->name);
974 out->num_values = in->value_ctr.num_values;
975 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
976 W_ERROR_HAVE_NO_MEMORY(out->values);
978 for (i=0; i < out->num_values; i++) {
980 const struct dsdb_attribute *a;
983 if (in->value_ctr.values[i].blob == NULL) {
987 if (in->value_ctr.values[i].blob->length != 4) {
991 v = IVAL(in->value_ctr.values[i].blob->data, 0);
993 a = dsdb_attribute_by_attributeID_id(ctx->schema, v);
998 str = talloc_strdup(out->values, a->lDAPDisplayName);
999 W_ERROR_HAVE_NO_MEMORY(str);
1001 /* the values need to be reversed */
1002 out->values[out->num_values - (i + 1)] = data_blob_string_const(str);
1008 static WERROR _dsdb_syntax_OID_oid_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
1009 const struct dsdb_attribute *attr,
1010 const struct drsuapi_DsReplicaAttribute *in,
1011 TALLOC_CTX *mem_ctx,
1012 struct ldb_message_element *out)
1017 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1018 W_ERROR_HAVE_NO_MEMORY(out->name);
1020 out->num_values = in->value_ctr.num_values;
1021 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1022 W_ERROR_HAVE_NO_MEMORY(out->values);
1024 for (i=0; i < out->num_values; i++) {
1029 if (in->value_ctr.values[i].blob == NULL) {
1033 if (in->value_ctr.values[i].blob->length != 4) {
1037 attid = IVAL(in->value_ctr.values[i].blob->data, 0);
1039 status = dsdb_schema_pfm_oid_from_attid(ctx->schema->prefixmap, attid, out->values, &oid);
1040 W_ERROR_NOT_OK_RETURN(status);
1042 out->values[i] = data_blob_string_const(oid);
1048 static WERROR _dsdb_syntax_auto_OID_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
1049 const struct dsdb_attribute *attr,
1050 const struct ldb_message_element *in,
1051 TALLOC_CTX *mem_ctx,
1052 struct drsuapi_DsReplicaAttribute *out)
1057 out->attid= dsdb_attribute_get_attid(attr,
1059 out->value_ctr.num_values= in->num_values;
1060 out->value_ctr.values= talloc_array(mem_ctx,
1061 struct drsuapi_DsAttributeValue,
1063 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1065 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1066 W_ERROR_HAVE_NO_MEMORY(blobs);
1068 for (i=0; i < in->num_values; i++) {
1069 const struct dsdb_class *obj_class;
1070 const struct dsdb_attribute *obj_attr;
1073 out->value_ctr.values[i].blob= &blobs[i];
1075 blobs[i] = data_blob_talloc(blobs, NULL, 4);
1076 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
1078 /* in DRS windows puts the classes in the opposite
1079 order to the order used in ldap */
1080 v = &in->values[(in->num_values-1)-i];
1082 if ((obj_class = dsdb_class_by_lDAPDisplayName_ldb_val(ctx->schema, v))) {
1083 SIVAL(blobs[i].data, 0, obj_class->governsID_id);
1084 } else if ((obj_attr = dsdb_attribute_by_lDAPDisplayName_ldb_val(ctx->schema, v))) {
1085 SIVAL(blobs[i].data, 0, obj_attr->attributeID_id);
1089 werr = dsdb_schema_pfm_make_attid(ctx->schema->prefixmap,
1090 (const char *)v->data,
1092 W_ERROR_NOT_OK_RETURN(werr);
1093 SIVAL(blobs[i].data, 0, attid);
1102 static WERROR _dsdb_syntax_OID_obj_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
1103 const struct dsdb_attribute *attr,
1104 const struct ldb_message_element *in,
1105 TALLOC_CTX *mem_ctx,
1106 struct drsuapi_DsReplicaAttribute *out)
1111 out->attid= dsdb_attribute_get_attid(attr,
1113 out->value_ctr.num_values= in->num_values;
1114 out->value_ctr.values= talloc_array(mem_ctx,
1115 struct drsuapi_DsAttributeValue,
1117 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1119 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1120 W_ERROR_HAVE_NO_MEMORY(blobs);
1122 for (i=0; i < in->num_values; i++) {
1123 const struct dsdb_class *obj_class;
1125 out->value_ctr.values[i].blob= &blobs[i];
1127 blobs[i] = data_blob_talloc(blobs, NULL, 4);
1128 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
1130 /* in DRS windows puts the classes in the opposite
1131 order to the order used in ldap */
1132 obj_class = dsdb_class_by_lDAPDisplayName(ctx->schema,
1133 (const char *)in->values[(in->num_values-1)-i].data);
1137 SIVAL(blobs[i].data, 0, obj_class->governsID_id);
1144 static WERROR _dsdb_syntax_OID_attr_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
1145 const struct dsdb_attribute *attr,
1146 const struct ldb_message_element *in,
1147 TALLOC_CTX *mem_ctx,
1148 struct drsuapi_DsReplicaAttribute *out)
1153 out->attid= dsdb_attribute_get_attid(attr,
1155 out->value_ctr.num_values= in->num_values;
1156 out->value_ctr.values= talloc_array(mem_ctx,
1157 struct drsuapi_DsAttributeValue,
1159 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1161 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1162 W_ERROR_HAVE_NO_MEMORY(blobs);
1164 for (i=0; i < in->num_values; i++) {
1165 const struct dsdb_attribute *obj_attr;
1167 out->value_ctr.values[i].blob= &blobs[i];
1169 blobs[i] = data_blob_talloc(blobs, NULL, 4);
1170 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
1172 obj_attr = dsdb_attribute_by_lDAPDisplayName(ctx->schema, (const char *)in->values[i].data);
1176 SIVAL(blobs[i].data, 0, obj_attr->attributeID_id);
1183 static WERROR _dsdb_syntax_OID_oid_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
1184 const struct dsdb_attribute *attr,
1185 const struct ldb_message_element *in,
1186 TALLOC_CTX *mem_ctx,
1187 struct drsuapi_DsReplicaAttribute *out)
1192 out->attid= dsdb_attribute_get_attid(attr,
1194 out->value_ctr.num_values= in->num_values;
1195 out->value_ctr.values= talloc_array(mem_ctx,
1196 struct drsuapi_DsAttributeValue,
1198 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1200 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1201 W_ERROR_HAVE_NO_MEMORY(blobs);
1203 for (i=0; i < in->num_values; i++) {
1207 out->value_ctr.values[i].blob= &blobs[i];
1209 blobs[i] = data_blob_talloc(blobs, NULL, 4);
1210 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
1212 status = dsdb_schema_pfm_make_attid(ctx->schema->prefixmap,
1213 (const char *)in->values[i].data,
1215 W_ERROR_NOT_OK_RETURN(status);
1217 SIVAL(blobs[i].data, 0, attid);
1223 static WERROR dsdb_syntax_OID_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
1224 const struct dsdb_attribute *attr,
1225 const struct drsuapi_DsReplicaAttribute *in,
1226 TALLOC_CTX *mem_ctx,
1227 struct ldb_message_element *out)
1231 switch (attr->attributeID_id) {
1232 case DRSUAPI_ATTRIBUTE_objectClass:
1233 case DRSUAPI_ATTRIBUTE_subClassOf:
1234 case DRSUAPI_ATTRIBUTE_auxiliaryClass:
1235 case DRSUAPI_ATTRIBUTE_systemAuxiliaryClass:
1236 case DRSUAPI_ATTRIBUTE_systemPossSuperiors:
1237 case DRSUAPI_ATTRIBUTE_possSuperiors:
1238 werr = _dsdb_syntax_OID_obj_drsuapi_to_ldb(ctx, attr, in, mem_ctx, out);
1240 case DRSUAPI_ATTRIBUTE_systemMustContain:
1241 case DRSUAPI_ATTRIBUTE_systemMayContain:
1242 case DRSUAPI_ATTRIBUTE_mustContain:
1243 case DRSUAPI_ATTRIBUTE_rDNAttId:
1244 case DRSUAPI_ATTRIBUTE_transportAddressAttribute:
1245 case DRSUAPI_ATTRIBUTE_mayContain:
1246 werr = _dsdb_syntax_OID_attr_drsuapi_to_ldb(ctx, attr, in, mem_ctx, out);
1248 case DRSUAPI_ATTRIBUTE_governsID:
1249 case DRSUAPI_ATTRIBUTE_attributeID:
1250 case DRSUAPI_ATTRIBUTE_attributeSyntax:
1251 werr = _dsdb_syntax_OID_oid_drsuapi_to_ldb(ctx, attr, in, mem_ctx, out);
1254 DEBUG(0,(__location__ ": Unknown handling for attributeID_id for %s\n",
1255 attr->lDAPDisplayName));
1256 return _dsdb_syntax_auto_OID_drsuapi_to_ldb(ctx, attr, in, mem_ctx, out);
1259 /* When we are doing the vampire of a schema, we don't want
1260 * the inability to reference an OID to get in the way.
1261 * Otherwise, we won't get the new schema with which to
1262 * understand this */
1263 if (!W_ERROR_IS_OK(werr) && ctx->schema->relax_OID_conversions) {
1264 return _dsdb_syntax_OID_oid_drsuapi_to_ldb(ctx, attr, in, mem_ctx, out);
1269 static WERROR dsdb_syntax_OID_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
1270 const struct dsdb_attribute *attr,
1271 const struct ldb_message_element *in,
1272 TALLOC_CTX *mem_ctx,
1273 struct drsuapi_DsReplicaAttribute *out)
1275 if (attr->attributeID_id == 0xFFFFFFFF) {
1279 switch (attr->attributeID_id) {
1280 case DRSUAPI_ATTRIBUTE_objectClass:
1281 case DRSUAPI_ATTRIBUTE_subClassOf:
1282 case DRSUAPI_ATTRIBUTE_auxiliaryClass:
1283 case DRSUAPI_ATTRIBUTE_systemAuxiliaryClass:
1284 case DRSUAPI_ATTRIBUTE_systemPossSuperiors:
1285 case DRSUAPI_ATTRIBUTE_possSuperiors:
1286 return _dsdb_syntax_OID_obj_ldb_to_drsuapi(ctx, attr, in, mem_ctx, out);
1287 case DRSUAPI_ATTRIBUTE_systemMustContain:
1288 case DRSUAPI_ATTRIBUTE_systemMayContain:
1289 case DRSUAPI_ATTRIBUTE_mustContain:
1290 case DRSUAPI_ATTRIBUTE_rDNAttId:
1291 case DRSUAPI_ATTRIBUTE_transportAddressAttribute:
1292 case DRSUAPI_ATTRIBUTE_mayContain:
1293 return _dsdb_syntax_OID_attr_ldb_to_drsuapi(ctx, attr, in, mem_ctx, out);
1294 case DRSUAPI_ATTRIBUTE_governsID:
1295 case DRSUAPI_ATTRIBUTE_attributeID:
1296 case DRSUAPI_ATTRIBUTE_attributeSyntax:
1297 return _dsdb_syntax_OID_oid_ldb_to_drsuapi(ctx, attr, in, mem_ctx, out);
1300 DEBUG(0,(__location__ ": Unknown handling for attributeID_id for %s\n",
1301 attr->lDAPDisplayName));
1303 return _dsdb_syntax_auto_OID_ldb_to_drsuapi(ctx, attr, in, mem_ctx, out);
1306 static WERROR dsdb_syntax_OID_validate_ldb(const struct dsdb_syntax_ctx *ctx,
1307 const struct dsdb_attribute *attr,
1308 const struct ldb_message_element *in)
1311 struct drsuapi_DsReplicaAttribute drs_tmp;
1312 struct ldb_message_element ldb_tmp;
1313 TALLOC_CTX *tmp_ctx;
1315 if (attr->attributeID_id == 0xFFFFFFFF) {
1320 * TODO: optimize and verify this code
1323 tmp_ctx = talloc_new(ctx->ldb);
1324 if (tmp_ctx == NULL) {
1328 status = dsdb_syntax_OID_ldb_to_drsuapi(ctx,
1333 if (!W_ERROR_IS_OK(status)) {
1334 talloc_free(tmp_ctx);
1338 status = dsdb_syntax_OID_drsuapi_to_ldb(ctx,
1343 if (!W_ERROR_IS_OK(status)) {
1344 talloc_free(tmp_ctx);
1348 talloc_free(tmp_ctx);
1352 static WERROR dsdb_syntax_UNICODE_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
1353 const struct dsdb_attribute *attr,
1354 const struct drsuapi_DsReplicaAttribute *in,
1355 TALLOC_CTX *mem_ctx,
1356 struct ldb_message_element *out)
1361 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1362 W_ERROR_HAVE_NO_MEMORY(out->name);
1364 out->num_values = in->value_ctr.num_values;
1365 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1366 W_ERROR_HAVE_NO_MEMORY(out->values);
1368 for (i=0; i < out->num_values; i++) {
1371 if (in->value_ctr.values[i].blob == NULL) {
1375 if (in->value_ctr.values[i].blob->length == 0) {
1379 if (!convert_string_talloc(out->values,
1381 in->value_ctr.values[i].blob->data,
1382 in->value_ctr.values[i].blob->length,
1383 (void **)&str, NULL, false)) {
1387 out->values[i] = data_blob_string_const(str);
1393 static WERROR dsdb_syntax_UNICODE_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
1394 const struct dsdb_attribute *attr,
1395 const struct ldb_message_element *in,
1396 TALLOC_CTX *mem_ctx,
1397 struct drsuapi_DsReplicaAttribute *out)
1402 if (attr->attributeID_id == 0xFFFFFFFF) {
1406 out->attid = dsdb_attribute_get_attid(attr,
1408 out->value_ctr.num_values = in->num_values;
1409 out->value_ctr.values = talloc_array(mem_ctx,
1410 struct drsuapi_DsAttributeValue,
1412 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1414 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1415 W_ERROR_HAVE_NO_MEMORY(blobs);
1417 for (i=0; i < in->num_values; i++) {
1418 out->value_ctr.values[i].blob = &blobs[i];
1420 if (!convert_string_talloc(blobs,
1422 in->values[i].data, in->values[i].length,
1423 (void **)&blobs[i].data, &blobs[i].length, false)) {
1431 static WERROR dsdb_syntax_UNICODE_validate_one_val(const struct dsdb_syntax_ctx *ctx,
1432 const struct dsdb_attribute *attr,
1433 const struct ldb_val *val)
1439 if (attr->attributeID_id == 0xFFFFFFFF) {
1443 ok = convert_string_talloc(ctx->ldb,
1451 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1454 if (attr->rangeLower) {
1455 if ((size/2) < *attr->rangeLower) {
1456 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1460 if (attr->rangeUpper) {
1461 if ((size/2) > *attr->rangeUpper) {
1462 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1469 static WERROR dsdb_syntax_UNICODE_validate_ldb(const struct dsdb_syntax_ctx *ctx,
1470 const struct dsdb_attribute *attr,
1471 const struct ldb_message_element *in)
1476 if (attr->attributeID_id == 0xFFFFFFFF) {
1480 for (i=0; i < in->num_values; i++) {
1481 if (in->values[i].length == 0) {
1482 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1485 status = dsdb_syntax_UNICODE_validate_one_val(ctx,
1488 if (!W_ERROR_IS_OK(status)) {
1496 static WERROR dsdb_syntax_one_DN_drsuapi_to_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
1497 const struct dsdb_syntax *syntax,
1498 const DATA_BLOB *in, DATA_BLOB *out)
1500 struct drsuapi_DsReplicaObjectIdentifier3 id3;
1501 enum ndr_err_code ndr_err;
1502 DATA_BLOB guid_blob;
1504 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1509 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1513 talloc_free(tmp_ctx);
1517 if (in->length == 0) {
1518 talloc_free(tmp_ctx);
1523 /* windows sometimes sends an extra two pad bytes here */
1524 ndr_err = ndr_pull_struct_blob(in,
1526 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3);
1527 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1528 status = ndr_map_error2ntstatus(ndr_err);
1529 talloc_free(tmp_ctx);
1530 return ntstatus_to_werror(status);
1533 dn = ldb_dn_new(tmp_ctx, ldb, id3.dn);
1535 talloc_free(tmp_ctx);
1536 /* If this fails, it must be out of memory, as it does not do much parsing */
1537 W_ERROR_HAVE_NO_MEMORY(dn);
1540 if (!GUID_all_zero(&id3.guid)) {
1541 status = GUID_to_ndr_blob(&id3.guid, tmp_ctx, &guid_blob);
1542 if (!NT_STATUS_IS_OK(status)) {
1543 talloc_free(tmp_ctx);
1544 return ntstatus_to_werror(status);
1547 ret = ldb_dn_set_extended_component(dn, "GUID", &guid_blob);
1548 if (ret != LDB_SUCCESS) {
1549 talloc_free(tmp_ctx);
1552 talloc_free(guid_blob.data);
1555 if (id3.__ndr_size_sid) {
1557 ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, &id3.sid,
1558 (ndr_push_flags_fn_t)ndr_push_dom_sid);
1559 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1560 status = ndr_map_error2ntstatus(ndr_err);
1561 talloc_free(tmp_ctx);
1562 return ntstatus_to_werror(status);
1565 ret = ldb_dn_set_extended_component(dn, "SID", &sid_blob);
1566 if (ret != LDB_SUCCESS) {
1567 talloc_free(tmp_ctx);
1572 *out = data_blob_string_const(ldb_dn_get_extended_linearized(mem_ctx, dn, 1));
1573 talloc_free(tmp_ctx);
1577 static WERROR dsdb_syntax_DN_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
1578 const struct dsdb_attribute *attr,
1579 const struct drsuapi_DsReplicaAttribute *in,
1580 TALLOC_CTX *mem_ctx,
1581 struct ldb_message_element *out)
1586 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1587 W_ERROR_HAVE_NO_MEMORY(out->name);
1589 out->num_values = in->value_ctr.num_values;
1590 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1591 W_ERROR_HAVE_NO_MEMORY(out->values);
1593 for (i=0; i < out->num_values; i++) {
1594 WERROR status = dsdb_syntax_one_DN_drsuapi_to_ldb(out->values, ctx->ldb, attr->syntax,
1595 in->value_ctr.values[i].blob,
1597 if (!W_ERROR_IS_OK(status)) {
1606 static WERROR dsdb_syntax_DN_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
1607 const struct dsdb_attribute *attr,
1608 const struct ldb_message_element *in,
1609 TALLOC_CTX *mem_ctx,
1610 struct drsuapi_DsReplicaAttribute *out)
1615 if (attr->attributeID_id == 0xFFFFFFFF) {
1619 out->attid = dsdb_attribute_get_attid(attr,
1621 out->value_ctr.num_values = in->num_values;
1622 out->value_ctr.values = talloc_array(mem_ctx,
1623 struct drsuapi_DsAttributeValue,
1625 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1627 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1628 W_ERROR_HAVE_NO_MEMORY(blobs);
1630 for (i=0; i < in->num_values; i++) {
1631 struct drsuapi_DsReplicaObjectIdentifier3 id3;
1632 enum ndr_err_code ndr_err;
1634 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1637 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1639 out->value_ctr.values[i].blob = &blobs[i];
1641 dn = ldb_dn_from_ldb_val(tmp_ctx, ctx->ldb, &in->values[i]);
1643 W_ERROR_HAVE_NO_MEMORY(dn);
1647 status = dsdb_get_extended_dn_guid(dn, &id3.guid, "GUID");
1648 if (!NT_STATUS_IS_OK(status) &&
1649 !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1650 talloc_free(tmp_ctx);
1651 return ntstatus_to_werror(status);
1654 status = dsdb_get_extended_dn_sid(dn, &id3.sid, "SID");
1655 if (!NT_STATUS_IS_OK(status) &&
1656 !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1657 talloc_free(tmp_ctx);
1658 return ntstatus_to_werror(status);
1661 id3.dn = ldb_dn_get_linearized(dn);
1663 ndr_err = ndr_push_struct_blob(&blobs[i], blobs, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
1664 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1665 status = ndr_map_error2ntstatus(ndr_err);
1666 talloc_free(tmp_ctx);
1667 return ntstatus_to_werror(status);
1669 talloc_free(tmp_ctx);
1675 static WERROR dsdb_syntax_DN_validate_one_val(const struct dsdb_syntax_ctx *ctx,
1676 const struct dsdb_attribute *attr,
1677 const struct ldb_val *val,
1678 TALLOC_CTX *mem_ctx,
1679 struct dsdb_dn **_dsdb_dn)
1681 static const char * const extended_list[] = { "GUID", "SID", NULL };
1682 enum ndr_err_code ndr_err;
1685 const DATA_BLOB *sid_blob;
1686 struct dsdb_dn *dsdb_dn;
1692 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1695 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1697 if (attr->attributeID_id == 0xFFFFFFFF) {
1701 dsdb_dn = dsdb_dn_parse(tmp_ctx, ctx->ldb, val,
1702 attr->syntax->ldap_oid);
1704 talloc_free(tmp_ctx);
1705 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1709 dn2 = ldb_dn_copy(tmp_ctx, dn);
1711 talloc_free(tmp_ctx);
1715 num_components = ldb_dn_get_comp_num(dn);
1717 status = dsdb_get_extended_dn_guid(dn, &guid, "GUID");
1718 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1720 } else if (!NT_STATUS_IS_OK(status)) {
1721 talloc_free(tmp_ctx);
1722 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1725 sid_blob = ldb_dn_get_extended_component(dn, "SID");
1728 ndr_err = ndr_pull_struct_blob_all(sid_blob,
1731 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1732 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1733 talloc_free(tmp_ctx);
1734 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1738 /* Do not allow links to the RootDSE */
1739 if (num_components == 0) {
1740 talloc_free(tmp_ctx);
1741 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1745 * We need to check that only "GUID" and "SID" are
1746 * specified as extended components, we do that
1747 * by comparing the dn's after removing all components
1748 * from one dn and only the allowed subset from the other
1751 ldb_dn_extended_filter(dn, extended_list);
1753 dn_str = ldb_dn_get_extended_linearized(tmp_ctx, dn, 0);
1754 if (dn_str == NULL) {
1755 talloc_free(tmp_ctx);
1756 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1758 dn2_str = ldb_dn_get_extended_linearized(tmp_ctx, dn2, 0);
1759 if (dn2_str == NULL) {
1760 talloc_free(tmp_ctx);
1761 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1764 if (strcmp(dn_str, dn2_str) != 0) {
1765 talloc_free(tmp_ctx);
1766 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1769 *_dsdb_dn = talloc_move(mem_ctx, &dsdb_dn);
1770 talloc_free(tmp_ctx);
1774 static WERROR dsdb_syntax_DN_validate_ldb(const struct dsdb_syntax_ctx *ctx,
1775 const struct dsdb_attribute *attr,
1776 const struct ldb_message_element *in)
1780 if (attr->attributeID_id == 0xFFFFFFFF) {
1784 for (i=0; i < in->num_values; i++) {
1786 struct dsdb_dn *dsdb_dn;
1787 TALLOC_CTX *tmp_ctx = talloc_new(ctx->ldb);
1788 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1790 status = dsdb_syntax_DN_validate_one_val(ctx,
1794 if (!W_ERROR_IS_OK(status)) {
1795 talloc_free(tmp_ctx);
1799 if (dsdb_dn->dn_format != DSDB_NORMAL_DN) {
1800 talloc_free(tmp_ctx);
1801 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
1804 talloc_free(tmp_ctx);
1810 static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
1811 const struct dsdb_attribute *attr,
1812 const struct drsuapi_DsReplicaAttribute *in,
1813 TALLOC_CTX *mem_ctx,
1814 struct ldb_message_element *out)
1820 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1821 W_ERROR_HAVE_NO_MEMORY(out->name);
1823 out->num_values = in->value_ctr.num_values;
1824 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1825 W_ERROR_HAVE_NO_MEMORY(out->values);
1827 for (i=0; i < out->num_values; i++) {
1828 struct drsuapi_DsReplicaObjectIdentifier3Binary id3;
1829 enum ndr_err_code ndr_err;
1830 DATA_BLOB guid_blob;
1832 struct dsdb_dn *dsdb_dn;
1834 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1836 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1839 if (in->value_ctr.values[i].blob == NULL) {
1840 talloc_free(tmp_ctx);
1844 if (in->value_ctr.values[i].blob->length == 0) {
1845 talloc_free(tmp_ctx);
1850 /* windows sometimes sends an extra two pad bytes here */
1851 ndr_err = ndr_pull_struct_blob(in->value_ctr.values[i].blob,
1853 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary);
1854 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1855 status = ndr_map_error2ntstatus(ndr_err);
1856 talloc_free(tmp_ctx);
1857 return ntstatus_to_werror(status);
1860 dn = ldb_dn_new(tmp_ctx, ctx->ldb, id3.dn);
1862 talloc_free(tmp_ctx);
1863 /* If this fails, it must be out of memory, as it does not do much parsing */
1864 W_ERROR_HAVE_NO_MEMORY(dn);
1867 status = GUID_to_ndr_blob(&id3.guid, tmp_ctx, &guid_blob);
1868 if (!NT_STATUS_IS_OK(status)) {
1869 talloc_free(tmp_ctx);
1870 return ntstatus_to_werror(status);
1873 ret = ldb_dn_set_extended_component(dn, "GUID", &guid_blob);
1874 if (ret != LDB_SUCCESS) {
1875 talloc_free(tmp_ctx);
1879 talloc_free(guid_blob.data);
1881 if (id3.__ndr_size_sid) {
1883 ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, &id3.sid,
1884 (ndr_push_flags_fn_t)ndr_push_dom_sid);
1885 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1886 status = ndr_map_error2ntstatus(ndr_err);
1887 talloc_free(tmp_ctx);
1888 return ntstatus_to_werror(status);
1891 ret = ldb_dn_set_extended_component(dn, "SID", &sid_blob);
1892 if (ret != LDB_SUCCESS) {
1893 talloc_free(tmp_ctx);
1898 /* set binary stuff */
1899 dsdb_dn = dsdb_dn_construct(tmp_ctx, dn, id3.binary, attr->syntax->ldap_oid);
1901 /* If this fails, it must be out of memory, we know the ldap_oid is valid */
1902 talloc_free(tmp_ctx);
1903 W_ERROR_HAVE_NO_MEMORY(dsdb_dn);
1905 out->values[i] = data_blob_string_const(dsdb_dn_get_extended_linearized(out->values, dsdb_dn, 1));
1906 talloc_free(tmp_ctx);
1912 static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
1913 const struct dsdb_attribute *attr,
1914 const struct ldb_message_element *in,
1915 TALLOC_CTX *mem_ctx,
1916 struct drsuapi_DsReplicaAttribute *out)
1921 if (attr->attributeID_id == 0xFFFFFFFF) {
1925 out->attid = dsdb_attribute_get_attid(attr,
1927 out->value_ctr.num_values = in->num_values;
1928 out->value_ctr.values = talloc_array(mem_ctx,
1929 struct drsuapi_DsAttributeValue,
1931 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1933 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1934 W_ERROR_HAVE_NO_MEMORY(blobs);
1936 for (i=0; i < in->num_values; i++) {
1937 struct drsuapi_DsReplicaObjectIdentifier3Binary id3;
1938 enum ndr_err_code ndr_err;
1939 const DATA_BLOB *sid_blob;
1940 struct dsdb_dn *dsdb_dn;
1941 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1944 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1946 out->value_ctr.values[i].blob = &blobs[i];
1948 dsdb_dn = dsdb_dn_parse(tmp_ctx, ctx->ldb, &in->values[i], attr->syntax->ldap_oid);
1951 talloc_free(tmp_ctx);
1952 return ntstatus_to_werror(NT_STATUS_INVALID_PARAMETER);
1957 status = dsdb_get_extended_dn_guid(dsdb_dn->dn, &id3.guid, "GUID");
1958 if (!NT_STATUS_IS_OK(status) &&
1959 !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1960 talloc_free(tmp_ctx);
1961 return ntstatus_to_werror(status);
1964 sid_blob = ldb_dn_get_extended_component(dsdb_dn->dn, "SID");
1967 ndr_err = ndr_pull_struct_blob_all(sid_blob,
1969 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1970 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1971 status = ndr_map_error2ntstatus(ndr_err);
1972 talloc_free(tmp_ctx);
1973 return ntstatus_to_werror(status);
1977 id3.dn = ldb_dn_get_linearized(dsdb_dn->dn);
1979 /* get binary stuff */
1980 id3.binary = dsdb_dn->extra_part;
1982 ndr_err = ndr_push_struct_blob(&blobs[i], blobs, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary);
1983 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1984 status = ndr_map_error2ntstatus(ndr_err);
1985 talloc_free(tmp_ctx);
1986 return ntstatus_to_werror(status);
1988 talloc_free(tmp_ctx);
1994 static WERROR dsdb_syntax_DN_BINARY_validate_ldb(const struct dsdb_syntax_ctx *ctx,
1995 const struct dsdb_attribute *attr,
1996 const struct ldb_message_element *in)
2000 if (attr->attributeID_id == 0xFFFFFFFF) {
2004 for (i=0; i < in->num_values; i++) {
2006 struct dsdb_dn *dsdb_dn;
2007 TALLOC_CTX *tmp_ctx = talloc_new(ctx->ldb);
2008 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
2010 status = dsdb_syntax_DN_validate_one_val(ctx,
2014 if (!W_ERROR_IS_OK(status)) {
2015 talloc_free(tmp_ctx);
2019 if (dsdb_dn->dn_format != DSDB_BINARY_DN) {
2020 talloc_free(tmp_ctx);
2021 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
2024 status = dsdb_syntax_DATA_BLOB_validate_one_val(ctx,
2026 &dsdb_dn->extra_part);
2027 if (!W_ERROR_IS_OK(status)) {
2028 talloc_free(tmp_ctx);
2032 talloc_free(tmp_ctx);
2038 static WERROR dsdb_syntax_DN_STRING_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
2039 const struct dsdb_attribute *attr,
2040 const struct drsuapi_DsReplicaAttribute *in,
2041 TALLOC_CTX *mem_ctx,
2042 struct ldb_message_element *out)
2044 return dsdb_syntax_DN_BINARY_drsuapi_to_ldb(ctx,
2051 static WERROR dsdb_syntax_DN_STRING_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
2052 const struct dsdb_attribute *attr,
2053 const struct ldb_message_element *in,
2054 TALLOC_CTX *mem_ctx,
2055 struct drsuapi_DsReplicaAttribute *out)
2057 return dsdb_syntax_DN_BINARY_ldb_to_drsuapi(ctx,
2064 static WERROR dsdb_syntax_DN_STRING_validate_ldb(const struct dsdb_syntax_ctx *ctx,
2065 const struct dsdb_attribute *attr,
2066 const struct ldb_message_element *in)
2070 if (attr->attributeID_id == 0xFFFFFFFF) {
2074 for (i=0; i < in->num_values; i++) {
2076 struct dsdb_dn *dsdb_dn;
2077 TALLOC_CTX *tmp_ctx = talloc_new(ctx->ldb);
2078 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
2080 status = dsdb_syntax_DN_validate_one_val(ctx,
2084 if (!W_ERROR_IS_OK(status)) {
2085 talloc_free(tmp_ctx);
2089 if (dsdb_dn->dn_format != DSDB_STRING_DN) {
2090 talloc_free(tmp_ctx);
2091 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
2094 status = dsdb_syntax_UNICODE_validate_one_val(ctx,
2096 &dsdb_dn->extra_part);
2097 if (!W_ERROR_IS_OK(status)) {
2098 talloc_free(tmp_ctx);
2102 talloc_free(tmp_ctx);
2108 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
2109 const struct dsdb_attribute *attr,
2110 const struct drsuapi_DsReplicaAttribute *in,
2111 TALLOC_CTX *mem_ctx,
2112 struct ldb_message_element *out)
2117 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
2118 W_ERROR_HAVE_NO_MEMORY(out->name);
2120 out->num_values = in->value_ctr.num_values;
2121 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
2122 W_ERROR_HAVE_NO_MEMORY(out->values);
2124 for (i=0; i < out->num_values; i++) {
2128 if (in->value_ctr.values[i].blob == NULL) {
2132 if (in->value_ctr.values[i].blob->length < 4) {
2136 len = IVAL(in->value_ctr.values[i].blob->data, 0);
2138 if (len != in->value_ctr.values[i].blob->length) {
2142 if (!convert_string_talloc(out->values, CH_UTF16, CH_UNIX,
2143 in->value_ctr.values[i].blob->data+4,
2144 in->value_ctr.values[i].blob->length-4,
2145 (void **)&str, NULL, false)) {
2149 out->values[i] = data_blob_string_const(str);
2155 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
2156 const struct dsdb_attribute *attr,
2157 const struct ldb_message_element *in,
2158 TALLOC_CTX *mem_ctx,
2159 struct drsuapi_DsReplicaAttribute *out)
2164 if (attr->attributeID_id == 0xFFFFFFFF) {
2168 out->attid = dsdb_attribute_get_attid(attr,
2170 out->value_ctr.num_values = in->num_values;
2171 out->value_ctr.values = talloc_array(mem_ctx,
2172 struct drsuapi_DsAttributeValue,
2174 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
2176 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
2177 W_ERROR_HAVE_NO_MEMORY(blobs);
2179 for (i=0; i < in->num_values; i++) {
2183 out->value_ctr.values[i].blob = &blobs[i];
2185 if (!convert_string_talloc(blobs, CH_UNIX, CH_UTF16,
2187 in->values[i].length,
2188 (void **)&data, &ret, false)) {
2192 blobs[i] = data_blob_talloc(blobs, NULL, 4 + ret);
2193 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
2195 SIVAL(blobs[i].data, 0, 4 + ret);
2198 memcpy(blobs[i].data + 4, data, ret);
2206 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_validate_ldb(const struct dsdb_syntax_ctx *ctx,
2207 const struct dsdb_attribute *attr,
2208 const struct ldb_message_element *in)
2210 return dsdb_syntax_UNICODE_validate_ldb(ctx,
2215 #define OMOBJECTCLASS(val) { .length = sizeof(val) - 1, .data = discard_const_p(uint8_t, val) }
2217 static const struct dsdb_syntax dsdb_syntaxes[] = {
2220 .ldap_oid = LDB_SYNTAX_BOOLEAN,
2222 .attributeSyntax_oid = "2.5.5.8",
2223 .drsuapi_to_ldb = dsdb_syntax_BOOL_drsuapi_to_ldb,
2224 .ldb_to_drsuapi = dsdb_syntax_BOOL_ldb_to_drsuapi,
2225 .validate_ldb = dsdb_syntax_BOOL_validate_ldb,
2226 .equality = "booleanMatch",
2227 .comment = "Boolean"
2230 .ldap_oid = LDB_SYNTAX_INTEGER,
2232 .attributeSyntax_oid = "2.5.5.9",
2233 .drsuapi_to_ldb = dsdb_syntax_INT32_drsuapi_to_ldb,
2234 .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi,
2235 .validate_ldb = dsdb_syntax_INT32_validate_ldb,
2236 .equality = "integerMatch",
2237 .comment = "Integer",
2238 .ldb_syntax = LDB_SYNTAX_SAMBA_INT32
2240 .name = "String(Octet)",
2241 .ldap_oid = LDB_SYNTAX_OCTET_STRING,
2243 .attributeSyntax_oid = "2.5.5.10",
2244 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
2245 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
2246 .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb,
2247 .equality = "octetStringMatch",
2248 .comment = "Octet String",
2250 .name = "String(Sid)",
2251 .ldap_oid = LDB_SYNTAX_OCTET_STRING,
2253 .attributeSyntax_oid = "2.5.5.17",
2254 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
2255 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
2256 .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb,
2257 .equality = "octetStringMatch",
2258 .comment = "Octet String - Security Identifier (SID)",
2259 .ldb_syntax = LDB_SYNTAX_SAMBA_SID
2261 .name = "String(Object-Identifier)",
2262 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.38",
2264 .attributeSyntax_oid = "2.5.5.2",
2265 .drsuapi_to_ldb = dsdb_syntax_OID_drsuapi_to_ldb,
2266 .ldb_to_drsuapi = dsdb_syntax_OID_ldb_to_drsuapi,
2267 .validate_ldb = dsdb_syntax_OID_validate_ldb,
2268 .equality = "caseIgnoreMatch", /* Would use "objectIdentifierMatch" but most are ldap attribute/class names */
2269 .comment = "OID String",
2270 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING
2272 .name = "Enumeration",
2273 .ldap_oid = LDB_SYNTAX_INTEGER,
2275 .attributeSyntax_oid = "2.5.5.9",
2276 .drsuapi_to_ldb = dsdb_syntax_INT32_drsuapi_to_ldb,
2277 .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi,
2278 .validate_ldb = dsdb_syntax_INT32_validate_ldb,
2279 .ldb_syntax = LDB_SYNTAX_SAMBA_INT32
2281 /* not used in w2k3 forest */
2282 .name = "String(Numeric)",
2283 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.36",
2285 .attributeSyntax_oid = "2.5.5.6",
2286 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
2287 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
2288 .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb,
2289 .equality = "numericStringMatch",
2290 .substring = "numericStringSubstringsMatch",
2291 .comment = "Numeric String",
2292 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING,
2294 .name = "String(Printable)",
2295 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.44",
2297 .attributeSyntax_oid = "2.5.5.5",
2298 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
2299 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
2300 .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb,
2301 .ldb_syntax = LDB_SYNTAX_OCTET_STRING,
2303 .name = "String(Teletex)",
2304 .ldap_oid = "1.2.840.113556.1.4.905",
2306 .attributeSyntax_oid = "2.5.5.4",
2307 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
2308 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
2309 .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb,
2310 .equality = "caseIgnoreMatch",
2311 .substring = "caseIgnoreSubstringsMatch",
2312 .comment = "Case Insensitive String",
2313 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING,
2315 .name = "String(IA5)",
2316 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.26",
2318 .attributeSyntax_oid = "2.5.5.5",
2319 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
2320 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
2321 .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb,
2322 .equality = "caseExactIA5Match",
2323 .comment = "Printable String",
2324 .ldb_syntax = LDB_SYNTAX_OCTET_STRING,
2326 .name = "String(UTC-Time)",
2327 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.53",
2329 .attributeSyntax_oid = "2.5.5.11",
2330 .drsuapi_to_ldb = dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb,
2331 .ldb_to_drsuapi = dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi,
2332 .validate_ldb = dsdb_syntax_NTTIME_UTC_validate_ldb,
2333 .equality = "generalizedTimeMatch",
2334 .comment = "UTC Time",
2336 .name = "String(Generalized-Time)",
2337 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.24",
2339 .attributeSyntax_oid = "2.5.5.11",
2340 .drsuapi_to_ldb = dsdb_syntax_NTTIME_drsuapi_to_ldb,
2341 .ldb_to_drsuapi = dsdb_syntax_NTTIME_ldb_to_drsuapi,
2342 .validate_ldb = dsdb_syntax_NTTIME_validate_ldb,
2343 .equality = "generalizedTimeMatch",
2344 .comment = "Generalized Time",
2345 .ldb_syntax = LDB_SYNTAX_UTC_TIME,
2347 /* not used in w2k3 schema */
2348 .name = "String(Case Sensitive)",
2349 .ldap_oid = "1.2.840.113556.1.4.1362",
2351 .attributeSyntax_oid = "2.5.5.3",
2352 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
2353 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
2354 .validate_ldb = dsdb_syntax_FOOBAR_validate_ldb,
2356 .name = "String(Unicode)",
2357 .ldap_oid = LDB_SYNTAX_DIRECTORY_STRING,
2359 .attributeSyntax_oid = "2.5.5.12",
2360 .drsuapi_to_ldb = dsdb_syntax_UNICODE_drsuapi_to_ldb,
2361 .ldb_to_drsuapi = dsdb_syntax_UNICODE_ldb_to_drsuapi,
2362 .validate_ldb = dsdb_syntax_UNICODE_validate_ldb,
2363 .equality = "caseIgnoreMatch",
2364 .substring = "caseIgnoreSubstringsMatch",
2365 .comment = "Directory String",
2367 .name = "Interval/LargeInteger",
2368 .ldap_oid = "1.2.840.113556.1.4.906",
2370 .attributeSyntax_oid = "2.5.5.16",
2371 .drsuapi_to_ldb = dsdb_syntax_INT64_drsuapi_to_ldb,
2372 .ldb_to_drsuapi = dsdb_syntax_INT64_ldb_to_drsuapi,
2373 .validate_ldb = dsdb_syntax_INT64_validate_ldb,
2374 .equality = "integerMatch",
2375 .comment = "Large Integer",
2376 .ldb_syntax = LDB_SYNTAX_INTEGER,
2378 .name = "String(NT-Sec-Desc)",
2379 .ldap_oid = LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR,
2381 .attributeSyntax_oid = "2.5.5.15",
2382 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
2383 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
2384 .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb,
2386 .name = "Object(DS-DN)",
2387 .ldap_oid = LDB_SYNTAX_DN,
2389 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x4a"),
2390 .attributeSyntax_oid = "2.5.5.1",
2391 .drsuapi_to_ldb = dsdb_syntax_DN_drsuapi_to_ldb,
2392 .ldb_to_drsuapi = dsdb_syntax_DN_ldb_to_drsuapi,
2393 .validate_ldb = dsdb_syntax_DN_validate_ldb,
2394 .equality = "distinguishedNameMatch",
2395 .comment = "Object(DS-DN) == a DN",
2397 .name = "Object(DN-Binary)",
2398 .ldap_oid = DSDB_SYNTAX_BINARY_DN,
2400 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0b"),
2401 .attributeSyntax_oid = "2.5.5.7",
2402 .drsuapi_to_ldb = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
2403 .ldb_to_drsuapi = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
2404 .validate_ldb = dsdb_syntax_DN_BINARY_validate_ldb,
2405 .equality = "octetStringMatch",
2406 .comment = "OctetString: Binary+DN",
2408 /* not used in w2k3 schema, but used in Exchange schema*/
2409 .name = "Object(OR-Name)",
2410 .ldap_oid = DSDB_SYNTAX_OR_NAME,
2412 .oMObjectClass = OMOBJECTCLASS("\x56\x06\x01\x02\x05\x0b\x1D"),
2413 .attributeSyntax_oid = "2.5.5.7",
2414 .drsuapi_to_ldb = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
2415 .ldb_to_drsuapi = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
2416 .validate_ldb = dsdb_syntax_DN_BINARY_validate_ldb,
2417 .equality = "caseIgnoreMatch",
2418 .ldb_syntax = LDB_SYNTAX_DN,
2421 * TODO: verify if DATA_BLOB is correct here...!
2423 * repsFrom and repsTo are the only attributes using
2424 * this attribute syntax, but they're not replicated...
2426 .name = "Object(Replica-Link)",
2427 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.40",
2429 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x06"),
2430 .attributeSyntax_oid = "2.5.5.10",
2431 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
2432 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
2433 .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb,
2435 .name = "Object(Presentation-Address)",
2436 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.43",
2438 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x5c"),
2439 .attributeSyntax_oid = "2.5.5.13",
2440 .drsuapi_to_ldb = dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb,
2441 .ldb_to_drsuapi = dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi,
2442 .validate_ldb = dsdb_syntax_PRESENTATION_ADDRESS_validate_ldb,
2443 .comment = "Presentation Address",
2444 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING,
2446 /* not used in w2k3 schema */
2447 .name = "Object(Access-Point)",
2448 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.2",
2450 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x3e"),
2451 .attributeSyntax_oid = "2.5.5.14",
2452 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
2453 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
2454 .validate_ldb = dsdb_syntax_FOOBAR_validate_ldb,
2455 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING,
2457 /* not used in w2k3 schema */
2458 .name = "Object(DN-String)",
2459 .ldap_oid = DSDB_SYNTAX_STRING_DN,
2461 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0c"),
2462 .attributeSyntax_oid = "2.5.5.14",
2463 .drsuapi_to_ldb = dsdb_syntax_DN_STRING_drsuapi_to_ldb,
2464 .ldb_to_drsuapi = dsdb_syntax_DN_STRING_ldb_to_drsuapi,
2465 .validate_ldb = dsdb_syntax_DN_STRING_validate_ldb,
2466 .equality = "octetStringMatch",
2467 .comment = "OctetString: String+DN",
2471 const struct dsdb_syntax *find_syntax_map_by_ad_oid(const char *ad_oid)
2474 for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
2475 if (strcasecmp(ad_oid, dsdb_syntaxes[i].attributeSyntax_oid) == 0) {
2476 return &dsdb_syntaxes[i];
2482 const struct dsdb_syntax *find_syntax_map_by_ad_syntax(int oMSyntax)
2485 for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
2486 if (oMSyntax == dsdb_syntaxes[i].oMSyntax) {
2487 return &dsdb_syntaxes[i];
2493 const struct dsdb_syntax *find_syntax_map_by_standard_oid(const char *standard_oid)
2496 for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
2497 if (strcasecmp(standard_oid, dsdb_syntaxes[i].ldap_oid) == 0) {
2498 return &dsdb_syntaxes[i];
2504 const struct dsdb_syntax *dsdb_syntax_for_attribute(const struct dsdb_attribute *attr)
2508 for (i=0; i < ARRAY_SIZE(dsdb_syntaxes); i++) {
2509 if (attr->oMSyntax != dsdb_syntaxes[i].oMSyntax) continue;
2511 if (attr->oMObjectClass.length != dsdb_syntaxes[i].oMObjectClass.length) continue;
2513 if (attr->oMObjectClass.length) {
2515 ret = memcmp(attr->oMObjectClass.data,
2516 dsdb_syntaxes[i].oMObjectClass.data,
2517 attr->oMObjectClass.length);
2518 if (ret != 0) continue;
2521 if (strcmp(attr->attributeSyntax_oid, dsdb_syntaxes[i].attributeSyntax_oid) != 0) continue;
2523 return &dsdb_syntaxes[i];
2529 WERROR dsdb_attribute_drsuapi_to_ldb(struct ldb_context *ldb,
2530 const struct dsdb_schema *schema,
2531 const struct drsuapi_DsReplicaAttribute *in,
2532 TALLOC_CTX *mem_ctx,
2533 struct ldb_message_element *out)
2535 const struct dsdb_attribute *sa;
2536 struct dsdb_syntax_ctx syntax_ctx;
2538 sa = dsdb_attribute_by_attributeID_id(schema, in->attid);
2543 /* use default syntax conversion context */
2544 dsdb_syntax_ctx_init(&syntax_ctx, ldb, schema);
2546 return sa->syntax->drsuapi_to_ldb(&syntax_ctx, sa, in, mem_ctx, out);
2549 WERROR dsdb_attribute_ldb_to_drsuapi(struct ldb_context *ldb,
2550 const struct dsdb_schema *schema,
2551 const struct ldb_message_element *in,
2552 TALLOC_CTX *mem_ctx,
2553 struct drsuapi_DsReplicaAttribute *out)
2555 const struct dsdb_attribute *sa;
2556 struct dsdb_syntax_ctx syntax_ctx;
2558 sa = dsdb_attribute_by_lDAPDisplayName(schema, in->name);
2563 /* use default syntax conversion context */
2564 dsdb_syntax_ctx_init(&syntax_ctx, ldb, schema);
2566 return sa->syntax->ldb_to_drsuapi(&syntax_ctx, sa, in, mem_ctx, out);