s4:dsdb/schema: add dsdb_syntax_NTTIME_validate_ldb()
[ira/wip.git] / source4 / dsdb / schema / schema_syntax.c
index d37045168321e7c6e15e5aa9f71cd594e94a244c..6dc334e736a29f34407572c876a568f430bd19d3 100644 (file)
@@ -2,11 +2,13 @@
    Unix SMB/CIFS mplementation.
    DSDB schema syntaxes
    
-   Copyright (C) Stefan Metzmacher 2006
-    
+   Copyright (C) Stefan Metzmacher <metze@samba.org> 2006
+   Copyright (C) Simo Sorce 2005
+   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2008
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
 */
 #include "includes.h"
 #include "dsdb/samdb/samdb.h"
 #include "librpc/gen_ndr/ndr_drsuapi.h"
+#include "librpc/gen_ndr/ndr_security.h"
+#include "librpc/gen_ndr/ndr_misc.h"
 #include "lib/ldb/include/ldb.h"
+#include "lib/ldb/include/ldb_errors.h"
 #include "system/time.h"
-#include "lib/charset/charset.h"
+#include "../lib/util/charset/charset.h"
 #include "librpc/ndr/libndr.h"
 
-static WERROR dsdb_syntax_FOOBAR_drsuapi_to_ldb(const struct dsdb_schema *schema,
+static WERROR dsdb_syntax_FOOBAR_drsuapi_to_ldb(struct ldb_context *ldb, 
+                                               const struct dsdb_schema *schema,
                                                const struct dsdb_attribute *attr,
                                                const struct drsuapi_DsReplicaAttribute *in,
                                                TALLOC_CTX *mem_ctx,
@@ -39,14 +44,14 @@ static WERROR dsdb_syntax_FOOBAR_drsuapi_to_ldb(const struct dsdb_schema *schema
        out->name       = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
        W_ERROR_HAVE_NO_MEMORY(out->name);
 
-       out->num_values = in->value_ctr.data_blob.num_values;
+       out->num_values = in->value_ctr.num_values;
        out->values     = talloc_array(mem_ctx, struct ldb_val, out->num_values);
        W_ERROR_HAVE_NO_MEMORY(out->values);
 
        for (i=0; i < out->num_values; i++) {
                char *str;
 
-               if (in->value_ctr.data_blob.values[i].data == NULL) {
+               if (in->value_ctr.values[i].blob == NULL) {
                        return WERR_FOOBAR;
                }
 
@@ -60,7 +65,8 @@ static WERROR dsdb_syntax_FOOBAR_drsuapi_to_ldb(const struct dsdb_schema *schema
        return WERR_OK;
 }
 
-static WERROR dsdb_syntax_FOOBAR_ldb_to_drsuapi(const struct dsdb_schema *schema,
+static WERROR dsdb_syntax_FOOBAR_ldb_to_drsuapi(struct ldb_context *ldb, 
+                                               const struct dsdb_schema *schema,
                                                const struct dsdb_attribute *attr,
                                                const struct ldb_message_element *in,
                                                TALLOC_CTX *mem_ctx,
@@ -69,7 +75,28 @@ static WERROR dsdb_syntax_FOOBAR_ldb_to_drsuapi(const struct dsdb_schema *schema
        return WERR_FOOBAR;
 }
 
-static WERROR dsdb_syntax_BOOL_drsuapi_to_ldb(const struct dsdb_schema *schema,
+static WERROR dsdb_syntax_FOOBAR_validate_ldb(struct ldb_context *ldb,
+                                             const struct dsdb_schema *schema,
+                                             const struct dsdb_attribute *attr,
+                                             const struct ldb_message_element *in)
+{
+       return WERR_FOOBAR;
+}
+
+static WERROR dsdb_syntax_ALLOW_validate_ldb(struct ldb_context *ldb,
+                                            const struct dsdb_schema *schema,
+                                            const struct dsdb_attribute *attr,
+                                            const struct ldb_message_element *in)
+{
+       if (attr->attributeID_id == 0xFFFFFFFF) {
+               return WERR_FOOBAR;
+       }
+
+       return WERR_OK;
+}
+
+static WERROR dsdb_syntax_BOOL_drsuapi_to_ldb(struct ldb_context *ldb, 
+                                             const struct dsdb_schema *schema,
                                              const struct dsdb_attribute *attr,
                                              const struct drsuapi_DsReplicaAttribute *in,
                                              TALLOC_CTX *mem_ctx,
@@ -77,18 +104,11 @@ static WERROR dsdb_syntax_BOOL_drsuapi_to_ldb(const struct dsdb_schema *schema,
 {
        uint32_t i;
 
-switch (attr->attributeID_id) {
-case DRSUAPI_ATTRIBUTE_isSingleValued:
-case DRSUAPI_ATTRIBUTE_showInAdvancedViewOnly:
-case DRSUAPI_ATTRIBUTE_isMemberOfPartialAttributeSet:
-       return dsdb_syntax_FOOBAR_drsuapi_to_ldb(schema,attr, in, mem_ctx, out);
-}
-
        out->flags      = 0;
        out->name       = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
        W_ERROR_HAVE_NO_MEMORY(out->name);
 
-       out->num_values = in->value_ctr.data_blob.num_values;
+       out->num_values = in->value_ctr.num_values;
        out->values     = talloc_array(mem_ctx, struct ldb_val, out->num_values);
        W_ERROR_HAVE_NO_MEMORY(out->values);
 
@@ -96,15 +116,15 @@ case DRSUAPI_ATTRIBUTE_isMemberOfPartialAttributeSet:
                uint32_t v;
                char *str;
 
-               if (in->value_ctr.data_blob.values[i].data == NULL) {
+               if (in->value_ctr.values[i].blob == NULL) {
                        return WERR_FOOBAR;
                }
 
-               if (in->value_ctr.data_blob.values[i].data->length != 4) {
+               if (in->value_ctr.values[i].blob->length != 4) {
                        return WERR_FOOBAR;
                }
 
-               v = IVAL(in->value_ctr.data_blob.values[i].data->data, 0);
+               v = IVAL(in->value_ctr.values[i].blob->data, 0);
 
                if (v != 0) {
                        str = talloc_strdup(out->values, "TRUE");
@@ -120,7 +140,8 @@ case DRSUAPI_ATTRIBUTE_isMemberOfPartialAttributeSet:
        return WERR_OK;
 }
 
-static WERROR dsdb_syntax_BOOL_ldb_to_drsuapi(const struct dsdb_schema *schema,
+static WERROR dsdb_syntax_BOOL_ldb_to_drsuapi(struct ldb_context *ldb, 
+                                             const struct dsdb_schema *schema,
                                              const struct dsdb_attribute *attr,
                                              const struct ldb_message_element *in,
                                              TALLOC_CTX *mem_ctx,
@@ -133,18 +154,18 @@ static WERROR dsdb_syntax_BOOL_ldb_to_drsuapi(const struct dsdb_schema *schema,
                return WERR_FOOBAR;
        }
 
-       out->attid                              = attr->attributeID_id;
-       out->value_ctr.data_blob.num_values     = in->num_values;
-       out->value_ctr.data_blob.values         = talloc_array(mem_ctx,
-                                                              struct drsuapi_DsAttributeValueDataBlob,
-                                                              in->num_values);
-       W_ERROR_HAVE_NO_MEMORY(out->value_ctr.data_blob.values);
+       out->attid                      = attr->attributeID_id;
+       out->value_ctr.num_values       = in->num_values;
+       out->value_ctr.values           = talloc_array(mem_ctx,
+                                                      struct drsuapi_DsAttributeValue,
+                                                      in->num_values);
+       W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
 
        blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
        W_ERROR_HAVE_NO_MEMORY(blobs);
 
        for (i=0; i < in->num_values; i++) {
-               out->value_ctr.data_blob.values[i].data = &blobs[i];
+               out->value_ctr.values[i].blob   = &blobs[i];
 
                blobs[i] = data_blob_talloc(blobs, NULL, 4);
                W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
@@ -161,7 +182,37 @@ static WERROR dsdb_syntax_BOOL_ldb_to_drsuapi(const struct dsdb_schema *schema,
        return WERR_OK;
 }
 
-static WERROR dsdb_syntax_INT32_drsuapi_to_ldb(const struct dsdb_schema *schema,
+static WERROR dsdb_syntax_BOOL_validate_ldb(struct ldb_context *ldb,
+                                           const struct dsdb_schema *schema,
+                                           const struct dsdb_attribute *attr,
+                                           const struct ldb_message_element *in)
+{
+       uint32_t i;
+
+       if (attr->attributeID_id == 0xFFFFFFFF) {
+               return WERR_FOOBAR;
+       }
+
+       for (i=0; i < in->num_values; i++) {
+               int t, f;
+
+               t = strncmp("TRUE",
+                           (const char *)in->values[i].data,
+                           in->values[i].length);
+               f = strncmp("FALSE",
+                           (const char *)in->values[i].data,
+                           in->values[i].length);
+
+               if (t != 0 && f != 0) {
+                       return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
+               }
+       }
+
+       return WERR_OK;
+}
+
+static WERROR dsdb_syntax_INT32_drsuapi_to_ldb(struct ldb_context *ldb, 
+                                              const struct dsdb_schema *schema,
                                               const struct dsdb_attribute *attr,
                                               const struct drsuapi_DsReplicaAttribute *in,
                                               TALLOC_CTX *mem_ctx,
@@ -169,23 +220,11 @@ static WERROR dsdb_syntax_INT32_drsuapi_to_ldb(const struct dsdb_schema *schema,
 {
        uint32_t i;
 
-switch (attr->attributeID_id) {
-case DRSUAPI_ATTRIBUTE_instanceType:
-case DRSUAPI_ATTRIBUTE_rangeLower:
-case DRSUAPI_ATTRIBUTE_rangeUpper:
-case DRSUAPI_ATTRIBUTE_objectVersion:
-case DRSUAPI_ATTRIBUTE_oMSyntax:
-case DRSUAPI_ATTRIBUTE_searchFlags:
-case DRSUAPI_ATTRIBUTE_systemFlags:
-case DRSUAPI_ATTRIBUTE_msDS_Behavior_Version:
-       return dsdb_syntax_FOOBAR_drsuapi_to_ldb(schema,attr, in, mem_ctx, out);
-}
-
        out->flags      = 0;
        out->name       = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
        W_ERROR_HAVE_NO_MEMORY(out->name);
 
-       out->num_values = in->value_ctr.data_blob.num_values;
+       out->num_values = in->value_ctr.num_values;
        out->values     = talloc_array(mem_ctx, struct ldb_val, out->num_values);
        W_ERROR_HAVE_NO_MEMORY(out->values);
 
@@ -193,15 +232,15 @@ case DRSUAPI_ATTRIBUTE_msDS_Behavior_Version:
                int32_t v;
                char *str;
 
-               if (in->value_ctr.data_blob.values[i].data == NULL) {
+               if (in->value_ctr.values[i].blob == NULL) {
                        return WERR_FOOBAR;
                }
 
-               if (in->value_ctr.data_blob.values[i].data->length != 4) {
+               if (in->value_ctr.values[i].blob->length != 4) {
                        return WERR_FOOBAR;
                }
 
-               v = IVALS(in->value_ctr.data_blob.values[i].data->data, 0);
+               v = IVALS(in->value_ctr.values[i].blob->data, 0);
 
                str = talloc_asprintf(out->values, "%d", v);
                W_ERROR_HAVE_NO_MEMORY(str);
@@ -212,7 +251,8 @@ case DRSUAPI_ATTRIBUTE_msDS_Behavior_Version:
        return WERR_OK;
 }
 
-static WERROR dsdb_syntax_INT32_ldb_to_drsuapi(const struct dsdb_schema *schema,
+static WERROR dsdb_syntax_INT32_ldb_to_drsuapi(struct ldb_context *ldb, 
+                                              const struct dsdb_schema *schema,
                                               const struct dsdb_attribute *attr,
                                               const struct ldb_message_element *in,
                                               TALLOC_CTX *mem_ctx,
@@ -225,12 +265,12 @@ static WERROR dsdb_syntax_INT32_ldb_to_drsuapi(const struct dsdb_schema *schema,
                return WERR_FOOBAR;
        }
 
-       out->attid                              = attr->attributeID_id;
-       out->value_ctr.data_blob.num_values     = in->num_values;
-       out->value_ctr.data_blob.values         = talloc_array(mem_ctx,
-                                                              struct drsuapi_DsAttributeValueDataBlob,
-                                                              in->num_values);
-       W_ERROR_HAVE_NO_MEMORY(out->value_ctr.data_blob.values);
+       out->attid                      = attr->attributeID_id;
+       out->value_ctr.num_values       = in->num_values;
+       out->value_ctr.values           = talloc_array(mem_ctx,
+                                                      struct drsuapi_DsAttributeValue,
+                                                      in->num_values);
+       W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
 
        blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
        W_ERROR_HAVE_NO_MEMORY(blobs);
@@ -238,12 +278,14 @@ static WERROR dsdb_syntax_INT32_ldb_to_drsuapi(const struct dsdb_schema *schema,
        for (i=0; i < in->num_values; i++) {
                int32_t v;
 
-               out->value_ctr.data_blob.values[i].data = &blobs[i];
+               out->value_ctr.values[i].blob   = &blobs[i];
 
                blobs[i] = data_blob_talloc(blobs, NULL, 4);
                W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
 
-               v = strtol((const char *)in->values[i].data, NULL, 10);
+               /* We've to use "strtoll" here to have the intended overflows.
+                * Otherwise we may get "LONG_MAX" and the conversion is wrong. */
+               v = (int32_t) strtoll((char *)in->values[i].data, NULL, 0);
 
                SIVALS(blobs[i].data, 0, v);
        }
@@ -251,7 +293,55 @@ static WERROR dsdb_syntax_INT32_ldb_to_drsuapi(const struct dsdb_schema *schema,
        return WERR_OK;
 }
 
-static WERROR dsdb_syntax_INT64_drsuapi_to_ldb(const struct dsdb_schema *schema,
+static WERROR dsdb_syntax_INT32_validate_ldb(struct ldb_context *ldb,
+                                            const struct dsdb_schema *schema,
+                                            const struct dsdb_attribute *attr,
+                                            const struct ldb_message_element *in)
+{
+       uint32_t i;
+
+       if (attr->attributeID_id == 0xFFFFFFFF) {
+               return WERR_FOOBAR;
+       }
+
+       for (i=0; i < in->num_values; i++) {
+               long v;
+               char buf[sizeof("-2147483648")];
+               char *end = NULL;
+
+               ZERO_STRUCT(buf);
+               if (in->values[i].length >= sizeof(buf)) {
+                       return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
+               }
+
+               memcpy(buf, in->values[i].data, in->values[i].length);
+               errno = 0;
+               v = strtol(buf, &end, 10);
+               if (errno != 0) {
+                       return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
+               }
+               if (end && end[0] != '\0') {
+                       return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
+               }
+
+               if (attr->rangeLower) {
+                       if ((int32_t)v < (int32_t)*attr->rangeLower) {
+                               return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
+                       }
+               }
+
+               if (attr->rangeUpper) {
+                       if ((int32_t)v > (int32_t)*attr->rangeUpper) {
+                               return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
+                       }
+               }
+       }
+
+       return WERR_OK;
+}
+
+static WERROR dsdb_syntax_INT64_drsuapi_to_ldb(struct ldb_context *ldb, 
+                                              const struct dsdb_schema *schema,
                                               const struct dsdb_attribute *attr,
                                               const struct drsuapi_DsReplicaAttribute *in,
                                               TALLOC_CTX *mem_ctx,
@@ -263,7 +353,7 @@ static WERROR dsdb_syntax_INT64_drsuapi_to_ldb(const struct dsdb_schema *schema,
        out->name       = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
        W_ERROR_HAVE_NO_MEMORY(out->name);
 
-       out->num_values = in->value_ctr.data_blob.num_values;
+       out->num_values = in->value_ctr.num_values;
        out->values     = talloc_array(mem_ctx, struct ldb_val, out->num_values);
        W_ERROR_HAVE_NO_MEMORY(out->values);
 
@@ -271,17 +361,17 @@ static WERROR dsdb_syntax_INT64_drsuapi_to_ldb(const struct dsdb_schema *schema,
                int64_t v;
                char *str;
 
-               if (in->value_ctr.data_blob.values[i].data == NULL) {
+               if (in->value_ctr.values[i].blob == NULL) {
                        return WERR_FOOBAR;
                }
 
-               if (in->value_ctr.data_blob.values[i].data->length != 8) {
+               if (in->value_ctr.values[i].blob->length != 8) {
                        return WERR_FOOBAR;
                }
 
-               v = BVALS(in->value_ctr.data_blob.values[i].data->data, 0);
+               v = BVALS(in->value_ctr.values[i].blob->data, 0);
 
-               str = talloc_asprintf(out->values, "%lld", v);
+               str = talloc_asprintf(out->values, "%lld", (long long int)v);
                W_ERROR_HAVE_NO_MEMORY(str);
 
                out->values[i] = data_blob_string_const(str);
@@ -290,7 +380,8 @@ static WERROR dsdb_syntax_INT64_drsuapi_to_ldb(const struct dsdb_schema *schema,
        return WERR_OK;
 }
 
-static WERROR dsdb_syntax_INT64_ldb_to_drsuapi(const struct dsdb_schema *schema,
+static WERROR dsdb_syntax_INT64_ldb_to_drsuapi(struct ldb_context *ldb, 
+                                              const struct dsdb_schema *schema,
                                               const struct dsdb_attribute *attr,
                                               const struct ldb_message_element *in,
                                               TALLOC_CTX *mem_ctx,
@@ -303,12 +394,12 @@ static WERROR dsdb_syntax_INT64_ldb_to_drsuapi(const struct dsdb_schema *schema,
                return WERR_FOOBAR;
        }
 
-       out->attid                              = attr->attributeID_id;
-       out->value_ctr.data_blob.num_values     = in->num_values;
-       out->value_ctr.data_blob.values         = talloc_array(mem_ctx,
-                                                              struct drsuapi_DsAttributeValueDataBlob,
-                                                              in->num_values);
-       W_ERROR_HAVE_NO_MEMORY(out->value_ctr.data_blob.values);
+       out->attid                      = attr->attributeID_id;
+       out->value_ctr.num_values       = in->num_values;
+       out->value_ctr.values           = talloc_array(mem_ctx,
+                                                      struct drsuapi_DsAttributeValue,
+                                                      in->num_values);
+       W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
 
        blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
        W_ERROR_HAVE_NO_MEMORY(blobs);
@@ -316,7 +407,7 @@ static WERROR dsdb_syntax_INT64_ldb_to_drsuapi(const struct dsdb_schema *schema,
        for (i=0; i < in->num_values; i++) {
                int64_t v;
 
-               out->value_ctr.data_blob.values[i].data = &blobs[i];
+               out->value_ctr.values[i].blob   = &blobs[i];
 
                blobs[i] = data_blob_talloc(blobs, NULL, 8);
                W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
@@ -329,7 +420,54 @@ static WERROR dsdb_syntax_INT64_ldb_to_drsuapi(const struct dsdb_schema *schema,
        return WERR_OK;
 }
 
-static WERROR dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb(const struct dsdb_schema *schema,
+static WERROR dsdb_syntax_INT64_validate_ldb(struct ldb_context *ldb,
+                                            const struct dsdb_schema *schema,
+                                            const struct dsdb_attribute *attr,
+                                            const struct ldb_message_element *in)
+{
+       uint32_t i;
+
+       if (attr->attributeID_id == 0xFFFFFFFF) {
+               return WERR_FOOBAR;
+       }
+
+       for (i=0; i < in->num_values; i++) {
+               long long v;
+               char buf[sizeof("-9223372036854775808")];
+               char *end = NULL;
+
+               ZERO_STRUCT(buf);
+               if (in->values[i].length >= sizeof(buf)) {
+                       return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
+               }
+               memcpy(buf, in->values[i].data, in->values[i].length);
+
+               errno = 0;
+               v = strtoll(buf, &end, 10);
+               if (errno != 0) {
+                       return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
+               }
+               if (end && end[0] != '\0') {
+                       return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
+               }
+
+               if (attr->rangeLower) {
+                       if ((int64_t)v < (int64_t)*attr->rangeLower) {
+                               return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
+                       }
+               }
+
+               if (attr->rangeUpper) {
+                       if ((int64_t)v > (int64_t)*attr->rangeUpper) {
+                               return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
+                       }
+               }
+       }
+
+       return WERR_OK;
+}
+static WERROR dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb(struct ldb_context *ldb, 
+                                                   const struct dsdb_schema *schema,
                                                    const struct dsdb_attribute *attr,
                                                    const struct drsuapi_DsReplicaAttribute *in,
                                                    TALLOC_CTX *mem_ctx,
@@ -341,7 +479,7 @@ static WERROR dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb(const struct dsdb_schema *sc
        out->name       = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
        W_ERROR_HAVE_NO_MEMORY(out->name);
 
-       out->num_values = in->value_ctr.data_blob.num_values;
+       out->num_values = in->value_ctr.num_values;
        out->values     = talloc_array(mem_ctx, struct ldb_val, out->num_values);
        W_ERROR_HAVE_NO_MEMORY(out->values);
 
@@ -350,15 +488,15 @@ static WERROR dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb(const struct dsdb_schema *sc
                time_t t;
                char *str;
 
-               if (in->value_ctr.data_blob.values[i].data == NULL) {
+               if (in->value_ctr.values[i].blob == NULL) {
                        return WERR_FOOBAR;
                }
 
-               if (in->value_ctr.data_blob.values[i].data->length != 8) {
+               if (in->value_ctr.values[i].blob->length != 8) {
                        return WERR_FOOBAR;
                }
 
-               v = BVAL(in->value_ctr.data_blob.values[i].data->data, 0);
+               v = BVAL(in->value_ctr.values[i].blob->data, 0);
                v *= 10000000;
                t = nt_time_to_unix(v);
 
@@ -379,7 +517,8 @@ static WERROR dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb(const struct dsdb_schema *sc
        return WERR_OK;
 }
 
-static WERROR dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi(const struct dsdb_schema *schema,
+static WERROR dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi(struct ldb_context *ldb, 
+                                                   const struct dsdb_schema *schema,
                                                    const struct dsdb_attribute *attr,
                                                    const struct ldb_message_element *in,
                                                    TALLOC_CTX *mem_ctx,
@@ -392,12 +531,12 @@ static WERROR dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi(const struct dsdb_schema *sc
                return WERR_FOOBAR;
        }
 
-       out->attid                              = attr->attributeID_id;
-       out->value_ctr.data_blob.num_values     = in->num_values;
-       out->value_ctr.data_blob.values         = talloc_array(mem_ctx,
-                                                              struct drsuapi_DsAttributeValueDataBlob,
-                                                              in->num_values);
-       W_ERROR_HAVE_NO_MEMORY(out->value_ctr.data_blob.values);
+       out->attid                      = attr->attributeID_id;
+       out->value_ctr.num_values       = in->num_values;
+       out->value_ctr.values           = talloc_array(mem_ctx,
+                                                      struct drsuapi_DsAttributeValue,
+                                                      in->num_values);
+       W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
 
        blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
        W_ERROR_HAVE_NO_MEMORY(blobs);
@@ -406,7 +545,7 @@ static WERROR dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi(const struct dsdb_schema *sc
                NTTIME v;
                time_t t;
 
-               out->value_ctr.data_blob.values[i].data = &blobs[i];
+               out->value_ctr.values[i].blob   = &blobs[i];
 
                blobs[i] = data_blob_talloc(blobs, NULL, 8);
                W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
@@ -421,7 +560,56 @@ static WERROR dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi(const struct dsdb_schema *sc
        return WERR_OK;
 }
 
-static WERROR dsdb_syntax_NTTIME_drsuapi_to_ldb(const struct dsdb_schema *schema,
+static WERROR dsdb_syntax_NTTIME_UTC_validate_ldb(struct ldb_context *ldb,
+                                                 const struct dsdb_schema *schema,
+                                                 const struct dsdb_attribute *attr,
+                                                 const struct ldb_message_element *in)
+{
+       uint32_t i;
+
+       if (attr->attributeID_id == 0xFFFFFFFF) {
+               return WERR_FOOBAR;
+       }
+
+       for (i=0; i < in->num_values; i++) {
+               time_t t;
+               char buf[sizeof("090826075717Z")];
+
+               ZERO_STRUCT(buf);
+               if (in->values[i].length >= sizeof(buf)) {
+                       return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
+               }
+               memcpy(buf, in->values[i].data, in->values[i].length);
+
+               errno = 0;
+               t = ldb_string_utc_to_time(buf);
+               if (errno != 0) {
+                       return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
+               }
+
+               if (attr->rangeLower) {
+                       if ((int32_t)t < (int32_t)*attr->rangeLower) {
+                               return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
+                       }
+               }
+
+               if (attr->rangeUpper) {
+                       if ((int32_t)t > (int32_t)*attr->rangeLower) {
+                               return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
+                       }
+               }
+
+               /*
+                * TODO: verify the comment in the
+                * dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb() function!
+                */
+       }
+
+       return WERR_OK;
+}
+
+static WERROR dsdb_syntax_NTTIME_drsuapi_to_ldb(struct ldb_context *ldb, 
+                                               const struct dsdb_schema *schema,
                                                const struct dsdb_attribute *attr,
                                                const struct drsuapi_DsReplicaAttribute *in,
                                                TALLOC_CTX *mem_ctx,
@@ -433,7 +621,7 @@ static WERROR dsdb_syntax_NTTIME_drsuapi_to_ldb(const struct dsdb_schema *schema
        out->name       = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
        W_ERROR_HAVE_NO_MEMORY(out->name);
 
-       out->num_values = in->value_ctr.data_blob.num_values;
+       out->num_values = in->value_ctr.num_values;
        out->values     = talloc_array(mem_ctx, struct ldb_val, out->num_values);
        W_ERROR_HAVE_NO_MEMORY(out->values);
 
@@ -442,15 +630,15 @@ static WERROR dsdb_syntax_NTTIME_drsuapi_to_ldb(const struct dsdb_schema *schema
                time_t t;
                char *str;
 
-               if (in->value_ctr.data_blob.values[i].data == NULL) {
+               if (in->value_ctr.values[i].blob == NULL) {
                        return WERR_FOOBAR;
                }
 
-               if (in->value_ctr.data_blob.values[i].data->length != 8) {
+               if (in->value_ctr.values[i].blob->length != 8) {
                        return WERR_FOOBAR;
                }
 
-               v = BVAL(in->value_ctr.data_blob.values[i].data->data, 0);
+               v = BVAL(in->value_ctr.values[i].blob->data, 0);
                v *= 10000000;
                t = nt_time_to_unix(v);
 
@@ -463,7 +651,8 @@ static WERROR dsdb_syntax_NTTIME_drsuapi_to_ldb(const struct dsdb_schema *schema
        return WERR_OK;
 }
 
-static WERROR dsdb_syntax_NTTIME_ldb_to_drsuapi(const struct dsdb_schema *schema,
+static WERROR dsdb_syntax_NTTIME_ldb_to_drsuapi(struct ldb_context *ldb, 
+                                               const struct dsdb_schema *schema,
                                                const struct dsdb_attribute *attr,
                                                const struct ldb_message_element *in,
                                                TALLOC_CTX *mem_ctx,
@@ -476,12 +665,12 @@ static WERROR dsdb_syntax_NTTIME_ldb_to_drsuapi(const struct dsdb_schema *schema
                return WERR_FOOBAR;
        }
 
-       out->attid                              = attr->attributeID_id;
-       out->value_ctr.data_blob.num_values     = in->num_values;
-       out->value_ctr.data_blob.values         = talloc_array(mem_ctx,
-                                                              struct drsuapi_DsAttributeValueDataBlob,
-                                                              in->num_values);
-       W_ERROR_HAVE_NO_MEMORY(out->value_ctr.data_blob.values);
+       out->attid                      = attr->attributeID_id;
+       out->value_ctr.num_values       = in->num_values;
+       out->value_ctr.values           = talloc_array(mem_ctx,
+                                                      struct drsuapi_DsAttributeValue,
+                                                      in->num_values);
+       W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
 
        blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
        W_ERROR_HAVE_NO_MEMORY(blobs);
@@ -489,13 +678,17 @@ static WERROR dsdb_syntax_NTTIME_ldb_to_drsuapi(const struct dsdb_schema *schema
        for (i=0; i < in->num_values; i++) {
                NTTIME v;
                time_t t;
+               int ret;
 
-               out->value_ctr.data_blob.values[i].data = &blobs[i];
+               out->value_ctr.values[i].blob   = &blobs[i];
 
                blobs[i] = data_blob_talloc(blobs, NULL, 8);
                W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
 
-               t = ldb_string_to_time((const char *)in->values[i].data);
+               ret = ldb_val_to_time(&in->values[i], &t);
+               if (ret != LDB_SUCCESS) {
+                       return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
+               }
                unix_to_nt_time(&v, t);
                v /= 10000000;
 
@@ -505,7 +698,44 @@ static WERROR dsdb_syntax_NTTIME_ldb_to_drsuapi(const struct dsdb_schema *schema
        return WERR_OK;
 }
 
-static WERROR dsdb_syntax_DATA_BLOB_drsuapi_to_ldb(const struct dsdb_schema *schema,
+static WERROR dsdb_syntax_NTTIME_validate_ldb(struct ldb_context *ldb,
+                                             const struct dsdb_schema *schema,
+                                             const struct dsdb_attribute *attr,
+                                             const struct ldb_message_element *in)
+{
+       uint32_t i;
+
+       if (attr->attributeID_id == 0xFFFFFFFF) {
+               return WERR_FOOBAR;
+       }
+
+       for (i=0; i < in->num_values; i++) {
+               time_t t;
+               int ret;
+
+               ret = ldb_val_to_time(&in->values[i], &t);
+               if (ret != LDB_SUCCESS) {
+                       return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
+               }
+
+               if (attr->rangeLower) {
+                       if ((int32_t)t < (int32_t)*attr->rangeLower) {
+                               return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
+                       }
+               }
+
+               if (attr->rangeUpper) {
+                       if ((int32_t)t > (int32_t)*attr->rangeLower) {
+                               return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
+                       }
+               }
+       }
+
+       return WERR_OK;
+}
+
+static WERROR dsdb_syntax_DATA_BLOB_drsuapi_to_ldb(struct ldb_context *ldb, 
+                                                  const struct dsdb_schema *schema,
                                                   const struct dsdb_attribute *attr,
                                                   const struct drsuapi_DsReplicaAttribute *in,
                                                   TALLOC_CTX *mem_ctx,
@@ -513,38 +743,33 @@ static WERROR dsdb_syntax_DATA_BLOB_drsuapi_to_ldb(const struct dsdb_schema *sch
 {
        uint32_t i;
 
-switch (attr->attributeID_id) {
-case DRSUAPI_ATTRIBUTE_invocationId:
-case DRSUAPI_ATTRIBUTE_schemaIDGUID:
-       return dsdb_syntax_FOOBAR_drsuapi_to_ldb(schema,attr, in, mem_ctx, out);
-}
-
        out->flags      = 0;
        out->name       = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
        W_ERROR_HAVE_NO_MEMORY(out->name);
 
-       out->num_values = in->value_ctr.data_blob.num_values;
+       out->num_values = in->value_ctr.num_values;
        out->values     = talloc_array(mem_ctx, struct ldb_val, out->num_values);
        W_ERROR_HAVE_NO_MEMORY(out->values);
 
        for (i=0; i < out->num_values; i++) {
-               if (in->value_ctr.data_blob.values[i].data == NULL) {
+               if (in->value_ctr.values[i].blob == NULL) {
                        return WERR_FOOBAR;
                }
 
-               if (in->value_ctr.data_blob.values[i].data->length == 0) {
+               if (in->value_ctr.values[i].blob->length == 0) {
                        return WERR_FOOBAR;
                }
 
                out->values[i] = data_blob_dup_talloc(out->values,
-                                                     in->value_ctr.data_blob.values[i].data);
+                                                     in->value_ctr.values[i].blob);
                W_ERROR_HAVE_NO_MEMORY(out->values[i].data);
        }
 
        return WERR_OK;
 }
 
-static WERROR dsdb_syntax_DATA_BLOB_ldb_to_drsuapi(const struct dsdb_schema *schema,
+static WERROR dsdb_syntax_DATA_BLOB_ldb_to_drsuapi(struct ldb_context *ldb, 
+                                                  const struct dsdb_schema *schema,
                                                   const struct dsdb_attribute *attr,
                                                   const struct ldb_message_element *in,
                                                   TALLOC_CTX *mem_ctx,
@@ -557,18 +782,18 @@ static WERROR dsdb_syntax_DATA_BLOB_ldb_to_drsuapi(const struct dsdb_schema *sch
                return WERR_FOOBAR;
        }
 
-       out->attid                              = attr->attributeID_id;
-       out->value_ctr.data_blob.num_values     = in->num_values;
-       out->value_ctr.data_blob.values         = talloc_array(mem_ctx,
-                                                              struct drsuapi_DsAttributeValueDataBlob,
-                                                              in->num_values);
-       W_ERROR_HAVE_NO_MEMORY(out->value_ctr.data_blob.values);
+       out->attid                      = attr->attributeID_id;
+       out->value_ctr.num_values       = in->num_values;
+       out->value_ctr.values           = talloc_array(mem_ctx,
+                                                      struct drsuapi_DsAttributeValue,
+                                                      in->num_values);
+       W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
 
        blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
        W_ERROR_HAVE_NO_MEMORY(blobs);
 
        for (i=0; i < in->num_values; i++) {
-               out->value_ctr.data_blob.values[i].data = &blobs[i];
+               out->value_ctr.values[i].blob   = &blobs[i];
 
                blobs[i] = data_blob_dup_talloc(blobs, &in->values[i]);
                W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
@@ -577,11 +802,12 @@ static WERROR dsdb_syntax_DATA_BLOB_ldb_to_drsuapi(const struct dsdb_schema *sch
        return WERR_OK;
 }
 
-static WERROR _dsdb_syntax_OID_obj_drsuapi_to_ldb(const struct dsdb_schema *schema,
-                                                 const struct dsdb_attribute *attr,
-                                                 const struct drsuapi_DsReplicaAttribute *in,
-                                                 TALLOC_CTX *mem_ctx,
-                                                 struct ldb_message_element *out)
+static WERROR _dsdb_syntax_auto_OID_drsuapi_to_ldb(struct ldb_context *ldb,
+                                                  const struct dsdb_schema *schema,
+                                                  const struct dsdb_attribute *attr,
+                                                  const struct drsuapi_DsReplicaAttribute *in,
+                                                  TALLOC_CTX *mem_ctx,
+                                                  struct ldb_message_element *out)
 {
        uint32_t i;
 
@@ -589,27 +815,35 @@ static WERROR _dsdb_syntax_OID_obj_drsuapi_to_ldb(const struct dsdb_schema *sche
        out->name       = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
        W_ERROR_HAVE_NO_MEMORY(out->name);
 
-       out->num_values = in->value_ctr.data_blob.num_values;
+       out->num_values = in->value_ctr.num_values;
        out->values     = talloc_array(mem_ctx, struct ldb_val, out->num_values);
        W_ERROR_HAVE_NO_MEMORY(out->values);
 
        for (i=0; i < out->num_values; i++) {
                uint32_t v;
                const struct dsdb_class *c;
-               const char *str;
+               const struct dsdb_attribute *a;
+               const char *str = NULL;
 
-               if (in->value_ctr.object_class_id.values[i].objectClassId == NULL) {
+               if (in->value_ctr.values[i].blob == NULL) {
                        return WERR_FOOBAR;
                }
 
-               v = *in->value_ctr.object_class_id.values[i].objectClassId;
-
-               c = dsdb_class_by_governsID_id(schema, v);
-               if (!c) {
+               if (in->value_ctr.values[i].blob->length != 4) {
                        return WERR_FOOBAR;
                }
 
-               str = talloc_strdup(out->values, c->lDAPDisplayName);
+               v = IVAL(in->value_ctr.values[i].blob->data, 0);
+
+               if ((c = dsdb_class_by_governsID_id(schema, v))) {
+                       str = talloc_strdup(out->values, c->lDAPDisplayName);
+               } else if ((a = dsdb_attribute_by_attributeID_id(schema, v))) {
+                       str = talloc_strdup(out->values, a->lDAPDisplayName);
+               } else {
+                       WERROR werr;
+                       werr = dsdb_schema_pfm_oid_from_attid(schema->prefixmap, v, out->values, &str);
+                       W_ERROR_NOT_OK_RETURN(werr);
+               }
                W_ERROR_HAVE_NO_MEMORY(str);
 
                /* the values need to be reversed */
@@ -619,7 +853,8 @@ static WERROR _dsdb_syntax_OID_obj_drsuapi_to_ldb(const struct dsdb_schema *sche
        return WERR_OK;
 }
 
-static WERROR _dsdb_syntax_OID_oid_drsuapi_to_ldb(const struct dsdb_schema *schema,
+static WERROR _dsdb_syntax_OID_obj_drsuapi_to_ldb(struct ldb_context *ldb, 
+                                                 const struct dsdb_schema *schema,
                                                  const struct dsdb_attribute *attr,
                                                  const struct drsuapi_DsReplicaAttribute *in,
                                                  TALLOC_CTX *mem_ctx,
@@ -631,132 +866,376 @@ static WERROR _dsdb_syntax_OID_oid_drsuapi_to_ldb(const struct dsdb_schema *sche
        out->name       = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
        W_ERROR_HAVE_NO_MEMORY(out->name);
 
-       out->num_values = in->value_ctr.data_blob.num_values;
+       out->num_values = in->value_ctr.num_values;
        out->values     = talloc_array(mem_ctx, struct ldb_val, out->num_values);
        W_ERROR_HAVE_NO_MEMORY(out->values);
 
        for (i=0; i < out->num_values; i++) {
                uint32_t v;
-               WERROR status;
+               const struct dsdb_class *c;
                const char *str;
 
-               if (in->value_ctr.oid.values[i].value == NULL) {
+               if (in->value_ctr.values[i].blob == NULL) {
                        return WERR_FOOBAR;
                }
 
-               v = *in->value_ctr.oid.values[i].value;
+               if (in->value_ctr.values[i].blob->length != 4) {
+                       return WERR_FOOBAR;
+               }
 
-               status = dsdb_map_int2oid(schema, v, out->values, &str);
-               W_ERROR_NOT_OK_RETURN(status);
+               v = IVAL(in->value_ctr.values[i].blob->data, 0);
 
-               out->values[i] = data_blob_string_const(str);
+               c = dsdb_class_by_governsID_id(schema, v);
+               if (!c) {
+                       return WERR_FOOBAR;
+               }
+
+               str = talloc_strdup(out->values, c->lDAPDisplayName);
+               W_ERROR_HAVE_NO_MEMORY(str);
+
+               /* the values need to be reversed */
+               out->values[out->num_values - (i + 1)] = data_blob_string_const(str);
        }
 
        return WERR_OK;
 }
 
-static WERROR dsdb_syntax_OID_drsuapi_to_ldb(const struct dsdb_schema *schema,
-                                            const struct dsdb_attribute *attr,
-                                            const struct drsuapi_DsReplicaAttribute *in,
-                                            TALLOC_CTX *mem_ctx,
-                                            struct ldb_message_element *out)
+static WERROR _dsdb_syntax_OID_attr_drsuapi_to_ldb(struct ldb_context *ldb, 
+                                                  const struct dsdb_schema *schema,
+                                                  const struct dsdb_attribute *attr,
+                                                  const struct drsuapi_DsReplicaAttribute *in,
+                                                  TALLOC_CTX *mem_ctx,
+                                                  struct ldb_message_element *out)
 {
        uint32_t i;
 
-       switch (attr->attributeID_id) {
-       case DRSUAPI_ATTRIBUTE_objectClass:
-               return _dsdb_syntax_OID_obj_drsuapi_to_ldb(schema, attr, in, mem_ctx, out);
-       case DRSUAPI_ATTRIBUTE_governsID:
-       case DRSUAPI_ATTRIBUTE_attributeID:
-       case DRSUAPI_ATTRIBUTE_attributeSyntax:
-               return _dsdb_syntax_OID_oid_drsuapi_to_ldb(schema, attr, in, mem_ctx, out);
-       }
-
        out->flags      = 0;
        out->name       = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
        W_ERROR_HAVE_NO_MEMORY(out->name);
 
-       out->num_values = in->value_ctr.data_blob.num_values;
+       out->num_values = in->value_ctr.num_values;
        out->values     = talloc_array(mem_ctx, struct ldb_val, out->num_values);
        W_ERROR_HAVE_NO_MEMORY(out->values);
 
        for (i=0; i < out->num_values; i++) {
                uint32_t v;
-               const char *name;
-               char *str;
+               const struct dsdb_attribute *a;
+               const char *str;
 
-               if (in->value_ctr.data_blob.values[i].data == NULL) {
+               if (in->value_ctr.values[i].blob == NULL) {
                        return WERR_FOOBAR;
                }
 
-               if (in->value_ctr.data_blob.values[i].data->length != 4) {
+               if (in->value_ctr.values[i].blob->length != 4) {
                        return WERR_FOOBAR;
                }
 
-               v = IVAL(in->value_ctr.data_blob.values[i].data->data, 0);
+               v = IVAL(in->value_ctr.values[i].blob->data, 0);
 
-               name = dsdb_lDAPDisplayName_by_id(schema, v);
-               if (!name) {
+               a = dsdb_attribute_by_attributeID_id(schema, v);
+               if (!a) {
                        return WERR_FOOBAR;
                }
 
-               str = talloc_strdup(out->values, name);
+               str = talloc_strdup(out->values, a->lDAPDisplayName);
                W_ERROR_HAVE_NO_MEMORY(str);
 
-               out->values[i] = data_blob_string_const(str);
+               /* the values need to be reversed */
+               out->values[out->num_values - (i + 1)] = data_blob_string_const(str);
        }
 
        return WERR_OK;
 }
 
-static WERROR dsdb_syntax_OID_ldb_to_drsuapi(const struct dsdb_schema *schema,
-                                            const struct dsdb_attribute *attr,
-                                            const struct ldb_message_element *in,
-                                            TALLOC_CTX *mem_ctx,
-                                            struct drsuapi_DsReplicaAttribute *out)
+static WERROR _dsdb_syntax_OID_oid_drsuapi_to_ldb(struct ldb_context *ldb, 
+                                                 const struct dsdb_schema *schema,
+                                                 const struct dsdb_attribute *attr,
+                                                 const struct drsuapi_DsReplicaAttribute *in,
+                                                 TALLOC_CTX *mem_ctx,
+                                                 struct ldb_message_element *out)
 {
        uint32_t i;
-       DATA_BLOB *blobs;
 
-       if (attr->attributeID_id == 0xFFFFFFFF) {
-               return WERR_FOOBAR;
-       }
+       out->flags      = 0;
+       out->name       = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
+       W_ERROR_HAVE_NO_MEMORY(out->name);
 
-       switch (attr->attributeID_id) {
-       case DRSUAPI_ATTRIBUTE_objectClass:
-       case DRSUAPI_ATTRIBUTE_governsID:
-       case DRSUAPI_ATTRIBUTE_attributeID:
-       case DRSUAPI_ATTRIBUTE_attributeSyntax:
-               return dsdb_syntax_FOOBAR_ldb_to_drsuapi(schema, attr, in, mem_ctx, out);
+       out->num_values = in->value_ctr.num_values;
+       out->values     = talloc_array(mem_ctx, struct ldb_val, out->num_values);
+       W_ERROR_HAVE_NO_MEMORY(out->values);
+
+       for (i=0; i < out->num_values; i++) {
+               uint32_t attid;
+               WERROR status;
+               const char *oid;
+
+               if (in->value_ctr.values[i].blob == NULL) {
+                       return WERR_FOOBAR;
+               }
+
+               if (in->value_ctr.values[i].blob->length != 4) {
+                       return WERR_FOOBAR;
+               }
+
+               attid = IVAL(in->value_ctr.values[i].blob->data, 0);
+
+               status = dsdb_schema_pfm_oid_from_attid(schema->prefixmap, attid, out->values, &oid);
+               W_ERROR_NOT_OK_RETURN(status);
+
+               out->values[i] = data_blob_string_const(oid);
        }
 
-       out->attid                              = attr->attributeID_id;
-       out->value_ctr.data_blob.num_values     = in->num_values;
-       out->value_ctr.data_blob.values         = talloc_array(mem_ctx,
-                                                              struct drsuapi_DsAttributeValueDataBlob,
-                                                              in->num_values);
-       W_ERROR_HAVE_NO_MEMORY(out->value_ctr.data_blob.values);
+       return WERR_OK;
+}
+
+static WERROR _dsdb_syntax_auto_OID_ldb_to_drsuapi(struct ldb_context *ldb,
+                                                  const struct dsdb_schema *schema,
+                                                  const struct dsdb_attribute *attr,
+                                                  const struct ldb_message_element *in,
+                                                  TALLOC_CTX *mem_ctx,
+                                                 struct drsuapi_DsReplicaAttribute *out)
+{
+        uint32_t i;
+        DATA_BLOB *blobs;
+
+        out->attid= attr->attributeID_id;
+        out->value_ctr.num_values= in->num_values;
+        out->value_ctr.values= talloc_array(mem_ctx,
+                                            struct drsuapi_DsAttributeValue,
+                                            in->num_values);
+        W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
+
+        blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
+        W_ERROR_HAVE_NO_MEMORY(blobs);
+
+        for (i=0; i < in->num_values; i++) {
+               const struct dsdb_class *obj_class;
+               const struct dsdb_attribute *obj_attr;
+               struct ldb_val *v;
+
+               out->value_ctr.values[i].blob= &blobs[i];
+
+               blobs[i] = data_blob_talloc(blobs, NULL, 4);
+               W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
+
+               /* in DRS windows puts the classes in the opposite
+                  order to the order used in ldap */
+               v = &in->values[(in->num_values-1)-i];
+
+               if ((obj_class = dsdb_class_by_lDAPDisplayName_ldb_val(schema, v))) {
+                       SIVAL(blobs[i].data, 0, obj_class->governsID_id);
+               } else if ((obj_attr = dsdb_attribute_by_lDAPDisplayName_ldb_val(schema, v))) {
+                       SIVAL(blobs[i].data, 0, obj_attr->attributeID_id);
+               } else {
+                       uint32_t attid;
+                       WERROR werr;
+                       werr = dsdb_schema_pfm_make_attid(schema->prefixmap,
+                                                         (const char *)v->data,
+                                                         &attid);
+                       W_ERROR_NOT_OK_RETURN(werr);
+                       SIVAL(blobs[i].data, 0, attid);
+               }
+
+        }
+
+
+        return WERR_OK;
+}
+
+static WERROR _dsdb_syntax_OID_obj_ldb_to_drsuapi(struct ldb_context *ldb,
+                                                 const struct dsdb_schema *schema,
+                                                 const struct dsdb_attribute *attr,
+                                                 const struct ldb_message_element *in,
+                                                 TALLOC_CTX *mem_ctx,
+                                                 struct drsuapi_DsReplicaAttribute *out)
+{
+        uint32_t i;
+        DATA_BLOB *blobs;
+
+        out->attid= attr->attributeID_id;
+        out->value_ctr.num_values= in->num_values;
+        out->value_ctr.values= talloc_array(mem_ctx,
+                                            struct drsuapi_DsAttributeValue,
+                                            in->num_values);
+        W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
+
+        blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
+        W_ERROR_HAVE_NO_MEMORY(blobs);
+
+        for (i=0; i < in->num_values; i++) {
+               const struct dsdb_class *obj_class;
+
+               out->value_ctr.values[i].blob= &blobs[i];
+
+               blobs[i] = data_blob_talloc(blobs, NULL, 4);
+               W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
+
+               /* in DRS windows puts the classes in the opposite
+                  order to the order used in ldap */
+               obj_class = dsdb_class_by_lDAPDisplayName(schema,
+                                                         (const char *)in->values[(in->num_values-1)-i].data);
+               if (!obj_class) {
+                       return WERR_FOOBAR;
+               }
+               SIVAL(blobs[i].data, 0, obj_class->governsID_id);
+        }
+
+
+        return WERR_OK;
+}
+
+static WERROR _dsdb_syntax_OID_attr_ldb_to_drsuapi(struct ldb_context *ldb,
+                                                  const struct dsdb_schema *schema,
+                                                  const struct dsdb_attribute *attr,
+                                                  const struct ldb_message_element *in,
+                                                  TALLOC_CTX *mem_ctx,
+                                                  struct drsuapi_DsReplicaAttribute *out)
+{
+        uint32_t i;
+        DATA_BLOB *blobs;
+
+        out->attid= attr->attributeID_id;
+        out->value_ctr.num_values= in->num_values;
+        out->value_ctr.values= talloc_array(mem_ctx,
+                                            struct drsuapi_DsAttributeValue,
+                                            in->num_values);
+        W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
+
+        blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
+        W_ERROR_HAVE_NO_MEMORY(blobs);
+
+        for (i=0; i < in->num_values; i++) {
+               const struct dsdb_attribute *obj_attr;
+
+               out->value_ctr.values[i].blob= &blobs[i];
+
+               blobs[i] = data_blob_talloc(blobs, NULL, 4);
+               W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
+
+               obj_attr = dsdb_attribute_by_lDAPDisplayName(schema, (const char *)in->values[i].data);
+               if (!obj_attr) {
+                       return WERR_FOOBAR;
+               }
+               SIVAL(blobs[i].data, 0, obj_attr->attributeID_id);
+        }
+
+
+        return WERR_OK;
+}
+
+static WERROR _dsdb_syntax_OID_oid_ldb_to_drsuapi(struct ldb_context *ldb,
+                                                 const struct dsdb_schema *schema,
+                                                 const struct dsdb_attribute *attr,
+                                                 const struct ldb_message_element *in,
+                                                 TALLOC_CTX *mem_ctx,
+                                                 struct drsuapi_DsReplicaAttribute *out)
+{
+       uint32_t i;
+       DATA_BLOB *blobs;
+
+       out->attid= attr->attributeID_id;
+       out->value_ctr.num_values= in->num_values;
+       out->value_ctr.values= talloc_array(mem_ctx,
+                                           struct drsuapi_DsAttributeValue,
+                                           in->num_values);
+       W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
 
        blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
        W_ERROR_HAVE_NO_MEMORY(blobs);
 
        for (i=0; i < in->num_values; i++) {
-               uint32_t v;
+               uint32_t attid;
+               WERROR status;
 
-               out->value_ctr.data_blob.values[i].data = &blobs[i];
+               out->value_ctr.values[i].blob= &blobs[i];
 
                blobs[i] = data_blob_talloc(blobs, NULL, 4);
                W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
 
-               v = strtol((const char *)in->values[i].data, NULL, 10);
+               status = dsdb_schema_pfm_make_attid(schema->prefixmap,
+                                                   (const char *)in->values[i].data,
+                                                   &attid);
+               W_ERROR_NOT_OK_RETURN(status);
 
-               SIVAL(blobs[i].data, 0, v);
+               SIVAL(blobs[i].data, 0, attid);
        }
 
        return WERR_OK;
 }
 
-static WERROR dsdb_syntax_UNICODE_drsuapi_to_ldb(const struct dsdb_schema *schema,
+static WERROR dsdb_syntax_OID_drsuapi_to_ldb(struct ldb_context *ldb, 
+                                            const struct dsdb_schema *schema,
+                                            const struct dsdb_attribute *attr,
+                                            const struct drsuapi_DsReplicaAttribute *in,
+                                            TALLOC_CTX *mem_ctx,
+                                            struct ldb_message_element *out)
+{
+       switch (attr->attributeID_id) {
+       case DRSUAPI_ATTRIBUTE_objectClass:
+       case DRSUAPI_ATTRIBUTE_subClassOf:
+       case DRSUAPI_ATTRIBUTE_auxiliaryClass:
+       case DRSUAPI_ATTRIBUTE_systemAuxiliaryClass:
+       case DRSUAPI_ATTRIBUTE_systemPossSuperiors:
+       case DRSUAPI_ATTRIBUTE_possSuperiors:
+               return _dsdb_syntax_OID_obj_drsuapi_to_ldb(ldb, schema, attr, in, mem_ctx, out);
+       case DRSUAPI_ATTRIBUTE_systemMustContain:
+       case DRSUAPI_ATTRIBUTE_systemMayContain:        
+       case DRSUAPI_ATTRIBUTE_mustContain:
+       case DRSUAPI_ATTRIBUTE_rDNAttId:
+       case DRSUAPI_ATTRIBUTE_transportAddressAttribute:
+       case DRSUAPI_ATTRIBUTE_mayContain:
+               return _dsdb_syntax_OID_attr_drsuapi_to_ldb(ldb, schema, attr, in, mem_ctx, out);
+       case DRSUAPI_ATTRIBUTE_governsID:
+       case DRSUAPI_ATTRIBUTE_attributeID:
+       case DRSUAPI_ATTRIBUTE_attributeSyntax:
+               return _dsdb_syntax_OID_oid_drsuapi_to_ldb(ldb, schema, attr, in, mem_ctx, out);
+       }
+
+       DEBUG(0,(__location__ ": Unknown handling for attributeID_id for %s\n",
+                attr->lDAPDisplayName));
+       return _dsdb_syntax_auto_OID_drsuapi_to_ldb(ldb, schema, attr, in, mem_ctx, out);
+}
+
+static WERROR dsdb_syntax_OID_ldb_to_drsuapi(struct ldb_context *ldb, 
+                                            const struct dsdb_schema *schema,
+                                            const struct dsdb_attribute *attr,
+                                            const struct ldb_message_element *in,
+                                            TALLOC_CTX *mem_ctx,
+                                            struct drsuapi_DsReplicaAttribute *out)
+{
+       if (attr->attributeID_id == 0xFFFFFFFF) {
+               return WERR_FOOBAR;
+       }
+
+       switch (attr->attributeID_id) {
+       case DRSUAPI_ATTRIBUTE_objectClass:
+       case DRSUAPI_ATTRIBUTE_subClassOf:
+       case DRSUAPI_ATTRIBUTE_auxiliaryClass:
+       case DRSUAPI_ATTRIBUTE_systemAuxiliaryClass:
+       case DRSUAPI_ATTRIBUTE_systemPossSuperiors:
+       case DRSUAPI_ATTRIBUTE_possSuperiors:
+               return _dsdb_syntax_OID_obj_ldb_to_drsuapi(ldb, schema, attr, in, mem_ctx, out);
+       case DRSUAPI_ATTRIBUTE_systemMustContain:
+       case DRSUAPI_ATTRIBUTE_systemMayContain:        
+       case DRSUAPI_ATTRIBUTE_mustContain:
+       case DRSUAPI_ATTRIBUTE_rDNAttId:
+       case DRSUAPI_ATTRIBUTE_transportAddressAttribute:
+       case DRSUAPI_ATTRIBUTE_mayContain:
+               return _dsdb_syntax_OID_attr_ldb_to_drsuapi(ldb, schema, attr, in, mem_ctx, out);
+       case DRSUAPI_ATTRIBUTE_governsID:
+       case DRSUAPI_ATTRIBUTE_attributeID:
+       case DRSUAPI_ATTRIBUTE_attributeSyntax:
+               return _dsdb_syntax_OID_oid_ldb_to_drsuapi(ldb, schema, attr, in, mem_ctx, out);
+       }
+
+       DEBUG(0,(__location__ ": Unknown handling for attributeID_id for %s\n",
+                attr->lDAPDisplayName));
+
+       return _dsdb_syntax_auto_OID_ldb_to_drsuapi(ldb, schema, attr, in, mem_ctx, out);
+}
+
+static WERROR dsdb_syntax_UNICODE_drsuapi_to_ldb(struct ldb_context *ldb, 
+                                                const struct dsdb_schema *schema,
                                                 const struct dsdb_attribute *attr,
                                                 const struct drsuapi_DsReplicaAttribute *in,
                                                 TALLOC_CTX *mem_ctx,
@@ -764,42 +1243,31 @@ static WERROR dsdb_syntax_UNICODE_drsuapi_to_ldb(const struct dsdb_schema *schem
 {
        uint32_t i;
 
-switch (attr->attributeID_id) {
-case DRSUAPI_ATTRIBUTE_description:
-case DRSUAPI_ATTRIBUTE_adminDisplayName:
-case DRSUAPI_ATTRIBUTE_adminDescription:
-case DRSUAPI_ATTRIBUTE_lDAPDisplayName:
-case DRSUAPI_ATTRIBUTE_name:
-case DRSUAPI_ATTRIBUTE_sAMAccountName:
-case DRSUAPI_ATTRIBUTE_gPLink:
-       return dsdb_syntax_FOOBAR_drsuapi_to_ldb(schema,attr, in, mem_ctx, out);
-}
-
        out->flags      = 0;
        out->name       = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
        W_ERROR_HAVE_NO_MEMORY(out->name);
 
-       out->num_values = in->value_ctr.data_blob.num_values;
+       out->num_values = in->value_ctr.num_values;
        out->values     = talloc_array(mem_ctx, struct ldb_val, out->num_values);
        W_ERROR_HAVE_NO_MEMORY(out->values);
 
        for (i=0; i < out->num_values; i++) {
-               ssize_t ret;
                char *str;
 
-               if (in->value_ctr.data_blob.values[i].data == NULL) {
+               if (in->value_ctr.values[i].blob == NULL) {
                        return WERR_FOOBAR;
                }
 
-               if (in->value_ctr.data_blob.values[i].data->length == 0) {
+               if (in->value_ctr.values[i].blob->length == 0) {
                        return WERR_FOOBAR;
                }
 
-               ret = convert_string_talloc(out->values, CH_UTF16, CH_UNIX,
-                                           in->value_ctr.data_blob.values[i].data->data,
-                                           in->value_ctr.data_blob.values[i].data->length,
-                                           (void **)&str);
-               if (ret == -1) {
+               if (!convert_string_talloc_convenience(out->values, 
+                                               schema->iconv_convenience, 
+                                                                       CH_UTF16, CH_UNIX,
+                                           in->value_ctr.values[i].blob->data,
+                                           in->value_ctr.values[i].blob->length,
+                                           (void **)&str, NULL, false)) {
                        return WERR_FOOBAR;
                }
 
@@ -809,7 +1277,8 @@ case DRSUAPI_ATTRIBUTE_gPLink:
        return WERR_OK;
 }
 
-static WERROR dsdb_syntax_UNICODE_ldb_to_drsuapi(const struct dsdb_schema *schema,
+static WERROR dsdb_syntax_UNICODE_ldb_to_drsuapi(struct ldb_context *ldb, 
+                                                const struct dsdb_schema *schema,
                                                 const struct dsdb_attribute *attr,
                                                 const struct ldb_message_element *in,
                                                 TALLOC_CTX *mem_ctx,
@@ -822,35 +1291,115 @@ static WERROR dsdb_syntax_UNICODE_ldb_to_drsuapi(const struct dsdb_schema *schem
                return WERR_FOOBAR;
        }
 
-       out->attid                              = attr->attributeID_id;
-       out->value_ctr.data_blob.num_values     = in->num_values;
-       out->value_ctr.data_blob.values         = talloc_array(mem_ctx,
-                                                              struct drsuapi_DsAttributeValueDataBlob,
-                                                              in->num_values);
-       W_ERROR_HAVE_NO_MEMORY(out->value_ctr.data_blob.values);
+       out->attid                      = attr->attributeID_id;
+       out->value_ctr.num_values       = in->num_values;
+       out->value_ctr.values           = talloc_array(mem_ctx,
+                                                      struct drsuapi_DsAttributeValue,
+                                                      in->num_values);
+       W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
 
        blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
        W_ERROR_HAVE_NO_MEMORY(blobs);
 
        for (i=0; i < in->num_values; i++) {
-               ssize_t ret;
+               out->value_ctr.values[i].blob   = &blobs[i];
 
-               out->value_ctr.data_blob.values[i].data = &blobs[i];
+               if (!convert_string_talloc_convenience(blobs,
+                       schema->iconv_convenience, CH_UNIX, CH_UTF16,
+                       in->values[i].data, in->values[i].length,
+                       (void **)&blobs[i].data, &blobs[i].length, false)) {
+                               return WERR_FOOBAR;
+               }
+       }
 
-               ret = convert_string_talloc(blobs, CH_UNIX, CH_UTF16,
-                                           in->values[i].data,
-                                           in->values[i].length,
-                                           (void **)&blobs[i].data);
-               if (ret == -1) {
+       return WERR_OK;
+}
+
+
+WERROR dsdb_syntax_one_DN_drsuapi_to_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, 
+                                        const struct dsdb_syntax *syntax, 
+                                        struct smb_iconv_convenience *iconv_convenience,
+                                        const DATA_BLOB *in, DATA_BLOB *out)
+{
+       struct drsuapi_DsReplicaObjectIdentifier3 id3;
+       enum ndr_err_code ndr_err;
+       DATA_BLOB guid_blob;
+       struct ldb_dn *dn;
+       TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+       int ret;
+       NTSTATUS status;
+
+       if (!tmp_ctx) {
+               W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
+       }
+       
+       if (in == NULL) {
+               talloc_free(tmp_ctx);
+               return WERR_FOOBAR;
+       }
+       
+       if (in->length == 0) {
+               talloc_free(tmp_ctx);
+               return WERR_FOOBAR;
+       }
+       
+       
+       /* windows sometimes sends an extra two pad bytes here */
+       ndr_err = ndr_pull_struct_blob(in,
+                                      tmp_ctx, iconv_convenience, &id3,
+                                      (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               status = ndr_map_error2ntstatus(ndr_err);
+               talloc_free(tmp_ctx);
+               return ntstatus_to_werror(status);
+       }
+       
+       dn = ldb_dn_new(tmp_ctx, ldb, id3.dn);
+       if (!dn) {
+               talloc_free(tmp_ctx);
+               /* If this fails, it must be out of memory, as it does not do much parsing */
+               W_ERROR_HAVE_NO_MEMORY(dn);
+       }
+
+       if (!GUID_all_zero(&id3.guid)) {
+               status = GUID_to_ndr_blob(&id3.guid, tmp_ctx, &guid_blob);
+               if (!NT_STATUS_IS_OK(status)) {
+                       talloc_free(tmp_ctx);
+                       return ntstatus_to_werror(status);
+               }
+       
+               ret = ldb_dn_set_extended_component(dn, "GUID", &guid_blob);
+               if (ret != LDB_SUCCESS) {
+                       talloc_free(tmp_ctx);
                        return WERR_FOOBAR;
                }
-               blobs[i].length = ret;
+               talloc_free(guid_blob.data);
        }
-
+       
+       if (id3.__ndr_size_sid) {
+               DATA_BLOB sid_blob;
+               ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, iconv_convenience, &id3.sid,
+                                              (ndr_push_flags_fn_t)ndr_push_dom_sid);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       status = ndr_map_error2ntstatus(ndr_err);
+                       talloc_free(tmp_ctx);
+                       return ntstatus_to_werror(status);
+               }
+               
+               ret = ldb_dn_set_extended_component(dn, "SID", &sid_blob);
+               if (ret != LDB_SUCCESS) {
+                       talloc_free(tmp_ctx);
+                       return WERR_FOOBAR;
+               }
+       }
+       
+       *out = data_blob_string_const(ldb_dn_get_extended_linearized(mem_ctx, dn, 1));
+       talloc_free(tmp_ctx);
        return WERR_OK;
 }
 
-static WERROR dsdb_syntax_DN_drsuapi_to_ldb(const struct dsdb_schema *schema,
+static WERROR dsdb_syntax_DN_drsuapi_to_ldb(struct ldb_context *ldb, 
+                                           const struct dsdb_schema *schema,
                                            const struct dsdb_attribute *attr,
                                            const struct drsuapi_DsReplicaAttribute *in,
                                            TALLOC_CTX *mem_ctx,
@@ -858,55 +1407,30 @@ static WERROR dsdb_syntax_DN_drsuapi_to_ldb(const struct dsdb_schema *schema,
 {
        uint32_t i;
 
-switch (attr->attributeID_id) {
-case DRSUAPI_ATTRIBUTE_member:
-case DRSUAPI_ATTRIBUTE_objectCategory:
-case DRSUAPI_ATTRIBUTE_hasMasterNCs:
-case DRSUAPI_ATTRIBUTE_dMDLocation:
-case DRSUAPI_ATTRIBUTE_fSMORoleOwner:
-case DRSUAPI_ATTRIBUTE_wellKnownObjects:
-case DRSUAPI_ATTRIBUTE_serverReference:
-case DRSUAPI_ATTRIBUTE_serverReferenceBL:
-case DRSUAPI_ATTRIBUTE_msDS_HasDomainNCs:
-case DRSUAPI_ATTRIBUTE_msDS_hasMasterNCs:
-       return dsdb_syntax_FOOBAR_drsuapi_to_ldb(schema,attr, in, mem_ctx, out);
-}
-
        out->flags      = 0;
        out->name       = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
        W_ERROR_HAVE_NO_MEMORY(out->name);
 
-       out->num_values = in->value_ctr.data_blob.num_values;
+       out->num_values = in->value_ctr.num_values;
        out->values     = talloc_array(mem_ctx, struct ldb_val, out->num_values);
        W_ERROR_HAVE_NO_MEMORY(out->values);
 
        for (i=0; i < out->num_values; i++) {
-               struct drsuapi_DsReplicaObjectIdentifier3 id3;
-               NTSTATUS status;
-
-               if (in->value_ctr.data_blob.values[i].data == NULL) {
-                       return WERR_FOOBAR;
+               WERROR status = dsdb_syntax_one_DN_drsuapi_to_ldb(out->values, ldb, attr->syntax, 
+                                                                 schema->iconv_convenience, 
+                                                                 in->value_ctr.values[i].blob, 
+                                                                 &out->values[i]);
+               if (!W_ERROR_IS_OK(status)) {
+                       return status;
                }
-
-               if (in->value_ctr.data_blob.values[i].data->length == 0) {
-                       return WERR_FOOBAR;
-               }
-
-               status = ndr_pull_struct_blob_all(in->value_ctr.data_blob.values[i].data,
-                                                 out->values, &id3,
-                                                 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3);
-               if (!NT_STATUS_IS_OK(status)) {
-                       return ntstatus_to_werror(status);
-               }
-
-               /* TODO: handle id3.guid and id3.sid */
-               out->values[i] = data_blob_string_const(id3.dn);
+                                                 
        }
 
        return WERR_OK;
 }
 
-static WERROR dsdb_syntax_DN_ldb_to_drsuapi(const struct dsdb_schema *schema,
+static WERROR dsdb_syntax_DN_ldb_to_drsuapi(struct ldb_context *ldb, 
+                                           const struct dsdb_schema *schema,
                                            const struct dsdb_attribute *attr,
                                            const struct ldb_message_element *in,
                                            TALLOC_CTX *mem_ctx,
@@ -919,91 +1443,175 @@ static WERROR dsdb_syntax_DN_ldb_to_drsuapi(const struct dsdb_schema *schema,
                return WERR_FOOBAR;
        }
 
-       out->attid                              = attr->attributeID_id;
-       out->value_ctr.data_blob.num_values     = in->num_values;
-       out->value_ctr.data_blob.values         = talloc_array(mem_ctx,
-                                                              struct drsuapi_DsAttributeValueDataBlob,
-                                                              in->num_values);
-       W_ERROR_HAVE_NO_MEMORY(out->value_ctr.data_blob.values);
+       out->attid                      = attr->attributeID_id;
+       out->value_ctr.num_values       = in->num_values;
+       out->value_ctr.values           = talloc_array(mem_ctx,
+                                                      struct drsuapi_DsAttributeValue,
+                                                      in->num_values);
+       W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
 
        blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
        W_ERROR_HAVE_NO_MEMORY(blobs);
 
        for (i=0; i < in->num_values; i++) {
-               NTSTATUS status;
                struct drsuapi_DsReplicaObjectIdentifier3 id3;
+               enum ndr_err_code ndr_err;
+               const DATA_BLOB *sid_blob;
+               struct ldb_dn *dn;
+               TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+               NTSTATUS status;
+
+               W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
 
-               out->value_ctr.data_blob.values[i].data = &blobs[i];
+               out->value_ctr.values[i].blob   = &blobs[i];
+
+               dn = ldb_dn_from_ldb_val(tmp_ctx, ldb, &in->values[i]);
+
+               W_ERROR_HAVE_NO_MEMORY(dn);
 
-               /* TODO: handle id3.guid and id3.sid */
                ZERO_STRUCT(id3);
-               id3.dn = (const char *)in->values[i].data;
 
-               status = ndr_push_struct_blob(&blobs[i], blobs, &id3,
-                                             (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
-               if (!NT_STATUS_IS_OK(status)) {
+               status = dsdb_get_extended_dn_guid(dn, &id3.guid, "GUID");
+               if (!NT_STATUS_IS_OK(status) &&
+                   !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+                       talloc_free(tmp_ctx);
                        return ntstatus_to_werror(status);
                }
+
+               sid_blob = ldb_dn_get_extended_component(dn, "SID");
+               if (sid_blob) {
+                       
+                       ndr_err = ndr_pull_struct_blob_all(sid_blob, 
+                                                          tmp_ctx, schema->iconv_convenience, &id3.sid,
+                                                          (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
+                       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                               status = ndr_map_error2ntstatus(ndr_err);
+                               talloc_free(tmp_ctx);
+                               return ntstatus_to_werror(status);
+                       }
+               }
+
+               id3.dn = ldb_dn_get_linearized(dn);
+
+               ndr_err = ndr_push_struct_blob(&blobs[i], blobs, schema->iconv_convenience, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       status = ndr_map_error2ntstatus(ndr_err);
+                       talloc_free(tmp_ctx);
+                       return ntstatus_to_werror(status);
+               }
+               talloc_free(tmp_ctx);
        }
 
        return WERR_OK;
 }
 
-static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(const struct dsdb_schema *schema,
+
+
+static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(struct ldb_context *ldb, 
+                                                  const struct dsdb_schema *schema,
                                                   const struct dsdb_attribute *attr,
                                                   const struct drsuapi_DsReplicaAttribute *in,
                                                   TALLOC_CTX *mem_ctx,
                                                   struct ldb_message_element *out)
 {
        uint32_t i;
+       int ret;
 
        out->flags      = 0;
        out->name       = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
        W_ERROR_HAVE_NO_MEMORY(out->name);
 
-       out->num_values = in->value_ctr.data_blob.num_values;
+       out->num_values = in->value_ctr.num_values;
        out->values     = talloc_array(mem_ctx, struct ldb_val, out->num_values);
        W_ERROR_HAVE_NO_MEMORY(out->values);
 
        for (i=0; i < out->num_values; i++) {
-               struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
-               char *binary;
-               char *str;
+               struct drsuapi_DsReplicaObjectIdentifier3Binary id3;
+               enum ndr_err_code ndr_err;
+               DATA_BLOB guid_blob;
+               struct ldb_dn *dn;
+               struct dsdb_dn *dsdb_dn;
                NTSTATUS status;
+               TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+               if (!tmp_ctx) {
+                       W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
+               }
 
-               if (in->value_ctr.data_blob.values[i].data == NULL) {
+               if (in->value_ctr.values[i].blob == NULL) {
+                       talloc_free(tmp_ctx);
                        return WERR_FOOBAR;
                }
 
-               if (in->value_ctr.data_blob.values[i].data->length == 0) {
+               if (in->value_ctr.values[i].blob->length == 0) {
+                       talloc_free(tmp_ctx);
                        return WERR_FOOBAR;
                }
 
-               status = ndr_pull_struct_blob_all(in->value_ctr.data_blob.values[i].data,
-                                                 out->values, &id3b,
-                                                 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary);
+               
+               /* windows sometimes sends an extra two pad bytes here */
+               ndr_err = ndr_pull_struct_blob(in->value_ctr.values[i].blob,
+                                              tmp_ctx, schema->iconv_convenience, &id3,
+                                              (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       status = ndr_map_error2ntstatus(ndr_err);
+                       talloc_free(tmp_ctx);
+                       return ntstatus_to_werror(status);
+               }
+
+               dn = ldb_dn_new(tmp_ctx, ldb, id3.dn);
+               if (!dn) {
+                       talloc_free(tmp_ctx);
+                       /* If this fails, it must be out of memory, as it does not do much parsing */
+                       W_ERROR_HAVE_NO_MEMORY(dn);
+               }
+
+               status = GUID_to_ndr_blob(&id3.guid, tmp_ctx, &guid_blob);
                if (!NT_STATUS_IS_OK(status)) {
+                       talloc_free(tmp_ctx);
                        return ntstatus_to_werror(status);
                }
 
-               /* TODO: handle id3.guid and id3.sid */
-               binary = data_blob_hex_string(out->values, &id3b.binary);
-               W_ERROR_HAVE_NO_MEMORY(binary);
+               ret = ldb_dn_set_extended_component(dn, "GUID", &guid_blob);
+               if (ret != LDB_SUCCESS) {
+                       talloc_free(tmp_ctx);
+                       return WERR_FOOBAR;
+               }
 
-               str = talloc_asprintf(out->values, "B:%u:%s:%s",
-                                     id3b.binary.length * 2, /* because of 2 hex chars per byte */
-                                     binary,
-                                     id3b.dn);
-               W_ERROR_HAVE_NO_MEMORY(str);
+               talloc_free(guid_blob.data);
+
+               if (id3.__ndr_size_sid) {
+                       DATA_BLOB sid_blob;
+                       ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, schema->iconv_convenience, &id3.sid,
+                                                      (ndr_push_flags_fn_t)ndr_push_dom_sid);
+                       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                               status = ndr_map_error2ntstatus(ndr_err);
+                               talloc_free(tmp_ctx);
+                               return ntstatus_to_werror(status);
+                       }
+
+                       ret = ldb_dn_set_extended_component(dn, "SID", &sid_blob);
+                       if (ret != LDB_SUCCESS) {
+                               talloc_free(tmp_ctx);
+                               return WERR_FOOBAR;
+                       }
+               }
 
-               /* TODO: handle id3.guid and id3.sid */
-               out->values[i] = data_blob_string_const(str);
+               /* set binary stuff */
+               dsdb_dn = dsdb_dn_construct(tmp_ctx, dn, id3.binary, attr->syntax->ldap_oid);
+               if (!dsdb_dn) {
+                       /* If this fails, it must be out of memory, we know the ldap_oid is valid */
+                       talloc_free(tmp_ctx);
+                       W_ERROR_HAVE_NO_MEMORY(dsdb_dn);
+               }
+               out->values[i] = data_blob_string_const(dsdb_dn_get_extended_linearized(out->values, dsdb_dn, 1));
+               talloc_free(tmp_ctx);
        }
 
        return WERR_OK;
 }
 
-static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(const struct dsdb_schema *schema,
+static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(struct ldb_context *ldb, 
+                                                  const struct dsdb_schema *schema,
                                                   const struct dsdb_attribute *attr,
                                                   const struct ldb_message_element *in,
                                                   TALLOC_CTX *mem_ctx,
@@ -1016,38 +1624,106 @@ static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(const struct dsdb_schema *sch
                return WERR_FOOBAR;
        }
 
-       out->attid                              = attr->attributeID_id;
-       out->value_ctr.data_blob.num_values     = in->num_values;
-       out->value_ctr.data_blob.values         = talloc_array(mem_ctx,
-                                                              struct drsuapi_DsAttributeValueDataBlob,
-                                                              in->num_values);
-       W_ERROR_HAVE_NO_MEMORY(out->value_ctr.data_blob.values);
+       out->attid                      = attr->attributeID_id;
+       out->value_ctr.num_values       = in->num_values;
+       out->value_ctr.values           = talloc_array(mem_ctx,
+                                                      struct drsuapi_DsAttributeValue,
+                                                      in->num_values);
+       W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
 
        blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
        W_ERROR_HAVE_NO_MEMORY(blobs);
 
        for (i=0; i < in->num_values; i++) {
+               struct drsuapi_DsReplicaObjectIdentifier3Binary id3;
+               enum ndr_err_code ndr_err;
+               const DATA_BLOB *sid_blob;
+               struct dsdb_dn *dsdb_dn;
+               TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
                NTSTATUS status;
-               struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
 
-               out->value_ctr.data_blob.values[i].data = &blobs[i];
+               W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
 
-               /* TODO: handle id3b.guid and id3b.sid, id3.binary */
-               ZERO_STRUCT(id3b);
-               id3b.dn         = (const char *)in->values[i].data;
-               id3b.binary     = data_blob(NULL, 0);
+               out->value_ctr.values[i].blob   = &blobs[i];
 
-               status = ndr_push_struct_blob(&blobs[i], blobs, &id3b,
-                                             (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary);
-               if (!NT_STATUS_IS_OK(status)) {
+               dsdb_dn = dsdb_dn_parse(tmp_ctx, ldb, &in->values[i], attr->syntax->ldap_oid);
+
+               if (!dsdb_dn) {
+                       talloc_free(tmp_ctx);
+                       return ntstatus_to_werror(NT_STATUS_INVALID_PARAMETER);
+               }
+
+               ZERO_STRUCT(id3);
+
+               status = dsdb_get_extended_dn_guid(dsdb_dn->dn, &id3.guid, "GUID");
+               if (!NT_STATUS_IS_OK(status) &&
+                   !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+                       talloc_free(tmp_ctx);
+                       return ntstatus_to_werror(status);
+               }
+
+               sid_blob = ldb_dn_get_extended_component(dsdb_dn->dn, "SID");
+               if (sid_blob) {
+                       
+                       ndr_err = ndr_pull_struct_blob_all(sid_blob, 
+                                                          tmp_ctx, schema->iconv_convenience, &id3.sid,
+                                                          (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
+                       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                               status = ndr_map_error2ntstatus(ndr_err);
+                               talloc_free(tmp_ctx);
+                               return ntstatus_to_werror(status);
+                       }
+               }
+
+               id3.dn = ldb_dn_get_linearized(dsdb_dn->dn);
+
+               /* get binary stuff */
+               id3.binary = dsdb_dn->extra_part;
+
+               ndr_err = ndr_push_struct_blob(&blobs[i], blobs, schema->iconv_convenience, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       status = ndr_map_error2ntstatus(ndr_err);
+                       talloc_free(tmp_ctx);
                        return ntstatus_to_werror(status);
                }
+               talloc_free(tmp_ctx);
        }
 
        return WERR_OK;
 }
 
-static WERROR dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb(const struct dsdb_schema *schema,
+static WERROR dsdb_syntax_DN_STRING_drsuapi_to_ldb(struct ldb_context *ldb,
+                                                  const struct dsdb_schema *schema,
+                                                  const struct dsdb_attribute *attr,
+                                                  const struct drsuapi_DsReplicaAttribute *in,
+                                                  TALLOC_CTX *mem_ctx,
+                                                  struct ldb_message_element *out)
+{
+       return dsdb_syntax_DN_BINARY_drsuapi_to_ldb(ldb,
+                                                   schema,
+                                                   attr,
+                                                   in,
+                                                   mem_ctx,
+                                                   out);
+}
+
+static WERROR dsdb_syntax_DN_STRING_ldb_to_drsuapi(struct ldb_context *ldb,
+                                                  const struct dsdb_schema *schema,
+                                                  const struct dsdb_attribute *attr,
+                                                  const struct ldb_message_element *in,
+                                                  TALLOC_CTX *mem_ctx,
+                                                  struct drsuapi_DsReplicaAttribute *out)
+{
+       return dsdb_syntax_DN_BINARY_ldb_to_drsuapi(ldb,
+                                                   schema,
+                                                   attr,
+                                                   in,
+                                                   mem_ctx,
+                                                   out);
+}
+
+static WERROR dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb(struct ldb_context *ldb, 
+                                                             const struct dsdb_schema *schema,
                                                              const struct dsdb_attribute *attr,
                                                              const struct drsuapi_DsReplicaAttribute *in,
                                                              TALLOC_CTX *mem_ctx,
@@ -1059,34 +1735,32 @@ static WERROR dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb(const struct dsdb_
        out->name       = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
        W_ERROR_HAVE_NO_MEMORY(out->name);
 
-       out->num_values = in->value_ctr.data_blob.num_values;
+       out->num_values = in->value_ctr.num_values;
        out->values     = talloc_array(mem_ctx, struct ldb_val, out->num_values);
        W_ERROR_HAVE_NO_MEMORY(out->values);
 
        for (i=0; i < out->num_values; i++) {
                uint32_t len;
-               ssize_t ret;
                char *str;
 
-               if (in->value_ctr.data_blob.values[i].data == NULL) {
+               if (in->value_ctr.values[i].blob == NULL) {
                        return WERR_FOOBAR;
                }
 
-               if (in->value_ctr.data_blob.values[i].data->length < 4) {
+               if (in->value_ctr.values[i].blob->length < 4) {
                        return WERR_FOOBAR;
                }
 
-               len = IVAL(in->value_ctr.data_blob.values[i].data->data, 0);
+               len = IVAL(in->value_ctr.values[i].blob->data, 0);
 
-               if (len != in->value_ctr.data_blob.values[i].data->length) {
+               if (len != in->value_ctr.values[i].blob->length) {
                        return WERR_FOOBAR;
                }
 
-               ret = convert_string_talloc(out->values, CH_UTF16, CH_UNIX,
-                                           in->value_ctr.data_blob.values[i].data->data+4,
-                                           in->value_ctr.data_blob.values[i].data->length-4,
-                                           (void **)&str);
-               if (ret == -1) {
+               if (!convert_string_talloc_convenience(out->values, schema->iconv_convenience, CH_UTF16, CH_UNIX,
+                                           in->value_ctr.values[i].blob->data+4,
+                                           in->value_ctr.values[i].blob->length-4,
+                                           (void **)&str, NULL, false)) {
                        return WERR_FOOBAR;
                }
 
@@ -1096,7 +1770,8 @@ static WERROR dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb(const struct dsdb_
        return WERR_OK;
 }
 
-static WERROR dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi(const struct dsdb_schema *schema,
+static WERROR dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi(struct ldb_context *ldb, 
+                                                             const struct dsdb_schema *schema,
                                                              const struct dsdb_attribute *attr,
                                                              const struct ldb_message_element *in,
                                                              TALLOC_CTX *mem_ctx,
@@ -1109,27 +1784,26 @@ static WERROR dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi(const struct dsdb_
                return WERR_FOOBAR;
        }
 
-       out->attid                              = attr->attributeID_id;
-       out->value_ctr.data_blob.num_values     = in->num_values;
-       out->value_ctr.data_blob.values         = talloc_array(mem_ctx,
-                                                              struct drsuapi_DsAttributeValueDataBlob,
-                                                              in->num_values);
-       W_ERROR_HAVE_NO_MEMORY(out->value_ctr.data_blob.values);
+       out->attid                      = attr->attributeID_id;
+       out->value_ctr.num_values       = in->num_values;
+       out->value_ctr.values           = talloc_array(mem_ctx,
+                                                      struct drsuapi_DsAttributeValue,
+                                                      in->num_values);
+       W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
 
        blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
        W_ERROR_HAVE_NO_MEMORY(blobs);
 
        for (i=0; i < in->num_values; i++) {
                uint8_t *data;
-               ssize_t ret;
+               size_t ret;
 
-               out->value_ctr.data_blob.values[i].data = &blobs[i];
+               out->value_ctr.values[i].blob   = &blobs[i];
 
-               ret = convert_string_talloc(blobs, CH_UNIX, CH_UTF16,
+               if (!convert_string_talloc_convenience(blobs, schema->iconv_convenience, CH_UNIX, CH_UTF16,
                                            in->values[i].data,
                                            in->values[i].length,
-                                           (void **)&data);
-               if (ret == -1) {
+                                           (void **)&data, &ret, false)) {
                        return WERR_FOOBAR;
                }
 
@@ -1147,38 +1821,51 @@ static WERROR dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi(const struct dsdb_
        return WERR_OK;
 }
 
-
 #define OMOBJECTCLASS(val) { .length = sizeof(val) - 1, .data = discard_const_p(uint8_t, val) }
 
 static const struct dsdb_syntax dsdb_syntaxes[] = {
        {
                .name                   = "Boolean",
-               .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.7",
+               .ldap_oid               = LDB_SYNTAX_BOOLEAN,
                .oMSyntax               = 1,
                .attributeSyntax_oid    = "2.5.5.8",
                .drsuapi_to_ldb         = dsdb_syntax_BOOL_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_BOOL_ldb_to_drsuapi,
+               .validate_ldb           = dsdb_syntax_BOOL_validate_ldb,
+               .equality               = "booleanMatch",
+               .comment                = "Boolean" 
        },{
                .name                   = "Integer",
-               .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.27",
+               .ldap_oid               = LDB_SYNTAX_INTEGER,
                .oMSyntax               = 2,
                .attributeSyntax_oid    = "2.5.5.9",
                .drsuapi_to_ldb         = dsdb_syntax_INT32_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_INT32_ldb_to_drsuapi,
+               .validate_ldb           = dsdb_syntax_INT32_validate_ldb,
+               .equality               = "integerMatch",
+               .comment                = "Integer",
+               .ldb_syntax             = LDB_SYNTAX_SAMBA_INT32
        },{
                .name                   = "String(Octet)",
-               .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.40",
+               .ldap_oid               = LDB_SYNTAX_OCTET_STRING,
                .oMSyntax               = 4,
                .attributeSyntax_oid    = "2.5.5.10",
                .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
+               .validate_ldb           = dsdb_syntax_ALLOW_validate_ldb,
+               .equality               = "octetStringMatch",
+               .comment                = "Octet String",
        },{
                .name                   = "String(Sid)",
-               .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.40",
+               .ldap_oid               = LDB_SYNTAX_OCTET_STRING,
                .oMSyntax               = 4,
                .attributeSyntax_oid    = "2.5.5.17",
                .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
+               .validate_ldb           = dsdb_syntax_ALLOW_validate_ldb,
+               .equality               = "octetStringMatch",
+               .comment                = "Octet String - Security Identifier (SID)",
+               .ldb_syntax             = LDB_SYNTAX_SAMBA_SID
        },{
                .name                   = "String(Object-Identifier)",
                .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.38",
@@ -1186,13 +1873,19 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .attributeSyntax_oid    = "2.5.5.2",
                .drsuapi_to_ldb         = dsdb_syntax_OID_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_OID_ldb_to_drsuapi,
+               .validate_ldb           = dsdb_syntax_ALLOW_validate_ldb,
+               .equality               = "caseIgnoreMatch", /* Would use "objectIdentifierMatch" but most are ldap attribute/class names */
+               .comment                = "OID String",
+               .ldb_syntax             = LDB_SYNTAX_DIRECTORY_STRING
        },{
                .name                   = "Enumeration",
-               .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.27",
+               .ldap_oid               = LDB_SYNTAX_INTEGER,
                .oMSyntax               = 10,
                .attributeSyntax_oid    = "2.5.5.9",
                .drsuapi_to_ldb         = dsdb_syntax_INT32_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_INT32_ldb_to_drsuapi,
+               .validate_ldb           = dsdb_syntax_INT32_validate_ldb,
+               .ldb_syntax             = LDB_SYNTAX_SAMBA_INT32
        },{
        /* not used in w2k3 forest */
                .name                   = "String(Numeric)",
@@ -1201,6 +1894,11 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .attributeSyntax_oid    = "2.5.5.6",
                .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
+               .validate_ldb           = dsdb_syntax_ALLOW_validate_ldb,
+               .equality               = "numericStringMatch",
+               .substring              = "numericStringSubstringsMatch",
+               .comment                = "Numeric String",
+               .ldb_syntax             = LDB_SYNTAX_DIRECTORY_STRING,
        },{
                .name                   = "String(Printable)",
                .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.44",
@@ -1208,6 +1906,8 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .attributeSyntax_oid    = "2.5.5.5",
                .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
+               .validate_ldb           = dsdb_syntax_ALLOW_validate_ldb,
+               .ldb_syntax             = LDB_SYNTAX_OCTET_STRING,
        },{
                .name                   = "String(Teletex)",
                .ldap_oid               = "1.2.840.113556.1.4.905",
@@ -1215,6 +1915,11 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .attributeSyntax_oid    = "2.5.5.4",
                .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
+               .validate_ldb           = dsdb_syntax_ALLOW_validate_ldb,
+               .equality               = "caseIgnoreMatch",
+               .substring              = "caseIgnoreSubstringsMatch",
+               .comment                = "Case Insensitive String",
+               .ldb_syntax             = LDB_SYNTAX_DIRECTORY_STRING,
        },{
                .name                   = "String(IA5)",
                .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.26",
@@ -1222,6 +1927,10 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .attributeSyntax_oid    = "2.5.5.5",
                .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
+               .validate_ldb           = dsdb_syntax_ALLOW_validate_ldb,
+               .equality               = "caseExactIA5Match",
+               .comment                = "Printable String",
+               .ldb_syntax             = LDB_SYNTAX_OCTET_STRING,
        },{
                .name                   = "String(UTC-Time)",
                .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.53",
@@ -1229,6 +1938,9 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .attributeSyntax_oid    = "2.5.5.11",
                .drsuapi_to_ldb         = dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi,
+               .validate_ldb           = dsdb_syntax_NTTIME_UTC_validate_ldb,
+               .equality               = "generalizedTimeMatch",
+               .comment                = "UTC Time",
        },{
                .name                   = "String(Generalized-Time)",
                .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.24",
@@ -1236,6 +1948,10 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .attributeSyntax_oid    = "2.5.5.11",
                .drsuapi_to_ldb         = dsdb_syntax_NTTIME_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_NTTIME_ldb_to_drsuapi,
+               .validate_ldb           = dsdb_syntax_NTTIME_validate_ldb,
+               .equality               = "generalizedTimeMatch",
+               .comment                = "Generalized Time",
+               .ldb_syntax             = LDB_SYNTAX_UTC_TIME,
        },{
        /* not used in w2k3 schema */
                .name                   = "String(Case Sensitive)",
@@ -1244,13 +1960,18 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .attributeSyntax_oid    = "2.5.5.3",
                .drsuapi_to_ldb         = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
+               .validate_ldb           = dsdb_syntax_FOOBAR_validate_ldb,
        },{
                .name                   = "String(Unicode)",
-               .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.15",
+               .ldap_oid               = LDB_SYNTAX_DIRECTORY_STRING,
                .oMSyntax               = 64,
                .attributeSyntax_oid    = "2.5.5.12",
                .drsuapi_to_ldb         = dsdb_syntax_UNICODE_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_UNICODE_ldb_to_drsuapi,
+               .validate_ldb           = dsdb_syntax_ALLOW_validate_ldb,
+               .equality               = "caseIgnoreMatch",
+               .substring              = "caseIgnoreSubstringsMatch",
+               .comment                = "Directory String",
        },{
                .name                   = "Interval/LargeInteger",
                .ldap_oid               = "1.2.840.113556.1.4.906",
@@ -1258,38 +1979,52 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .attributeSyntax_oid    = "2.5.5.16",
                .drsuapi_to_ldb         = dsdb_syntax_INT64_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_INT64_ldb_to_drsuapi,
+               .validate_ldb           = dsdb_syntax_INT64_validate_ldb,
+               .equality               = "integerMatch",
+               .comment                = "Large Integer",
+               .ldb_syntax             = LDB_SYNTAX_INTEGER,
        },{
                .name                   = "String(NT-Sec-Desc)",
-               .ldap_oid               = "1.2.840.113556.1.4.907",
+               .ldap_oid               = LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR,
                .oMSyntax               = 66,
                .attributeSyntax_oid    = "2.5.5.15",
                .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
+               .validate_ldb           = dsdb_syntax_ALLOW_validate_ldb,
        },{
                .name                   = "Object(DS-DN)",
-               .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.12",
+               .ldap_oid               = LDB_SYNTAX_DN,
                .oMSyntax               = 127,
                .oMObjectClass          = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x4a"),
                .attributeSyntax_oid    = "2.5.5.1",
                .drsuapi_to_ldb         = dsdb_syntax_DN_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_DN_ldb_to_drsuapi,
+               .validate_ldb           = dsdb_syntax_ALLOW_validate_ldb,
+               .equality               = "distinguishedNameMatch",
+               .comment                = "Object(DS-DN) == a DN",
        },{
                .name                   = "Object(DN-Binary)",
-               .ldap_oid               = "1.2.840.113556.1.4.903",
+               .ldap_oid               = DSDB_SYNTAX_BINARY_DN,
                .oMSyntax               = 127,
                .oMObjectClass          = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0b"),
                .attributeSyntax_oid    = "2.5.5.7",
                .drsuapi_to_ldb         = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
+               .validate_ldb           = dsdb_syntax_ALLOW_validate_ldb,
+               .equality               = "octetStringMatch",
+               .comment                = "OctetString: Binary+DN",
        },{
-       /* not used in w2k3 schema */
+       /* not used in w2k3 schema, but used in Exchange schema*/
                .name                   = "Object(OR-Name)",
-               .ldap_oid               = "1.2.840.113556.1.4.1221",
+               .ldap_oid               = DSDB_SYNTAX_OR_NAME,
                .oMSyntax               = 127,
                .oMObjectClass          = OMOBJECTCLASS("\x56\x06\x01\x02\x05\x0b\x1D"),
                .attributeSyntax_oid    = "2.5.5.7",
-               .drsuapi_to_ldb         = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
-               .ldb_to_drsuapi         = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
+               .drsuapi_to_ldb         = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
+               .ldb_to_drsuapi         = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
+               .validate_ldb           = dsdb_syntax_ALLOW_validate_ldb,
+               .equality               = "caseIgnoreMatch",
+               .ldb_syntax             = LDB_SYNTAX_DN,
        },{
        /* 
         * TODO: verify if DATA_BLOB is correct here...!
@@ -1304,6 +2039,7 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .attributeSyntax_oid    = "2.5.5.10",
                .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
+               .validate_ldb           = dsdb_syntax_ALLOW_validate_ldb,
        },{
                .name                   = "Object(Presentation-Address)",
                .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.43",
@@ -1312,6 +2048,9 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .attributeSyntax_oid    = "2.5.5.13",
                .drsuapi_to_ldb         = dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi,
+               .validate_ldb           = dsdb_syntax_ALLOW_validate_ldb,
+               .comment                = "Presentation Address",
+               .ldb_syntax             = LDB_SYNTAX_DIRECTORY_STRING,
        },{
        /* not used in w2k3 schema */
                .name                   = "Object(Access-Point)",
@@ -1321,18 +2060,55 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .attributeSyntax_oid    = "2.5.5.14",
                .drsuapi_to_ldb         = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
+               .validate_ldb           = dsdb_syntax_FOOBAR_validate_ldb,
+               .ldb_syntax             = LDB_SYNTAX_DIRECTORY_STRING,
        },{
        /* not used in w2k3 schema */
                .name                   = "Object(DN-String)",
-               .ldap_oid               = "1.2.840.113556.1.4.904",
+               .ldap_oid               = DSDB_SYNTAX_STRING_DN,
                .oMSyntax               = 127,
                .oMObjectClass          = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0c"),
                .attributeSyntax_oid    = "2.5.5.14",
-               .drsuapi_to_ldb         = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
-               .ldb_to_drsuapi         = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
+               .drsuapi_to_ldb         = dsdb_syntax_DN_STRING_drsuapi_to_ldb,
+               .ldb_to_drsuapi         = dsdb_syntax_DN_STRING_ldb_to_drsuapi,
+               .validate_ldb           = dsdb_syntax_ALLOW_validate_ldb,
+               .equality               = "octetStringMatch",
+               .comment                = "OctetString: String+DN",
        }
 };
 
+const struct dsdb_syntax *find_syntax_map_by_ad_oid(const char *ad_oid) 
+{
+       int i;
+       for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
+               if (strcasecmp(ad_oid, dsdb_syntaxes[i].attributeSyntax_oid) == 0) {
+                       return &dsdb_syntaxes[i];
+               }
+       }
+       return NULL;
+}
+
+const struct dsdb_syntax *find_syntax_map_by_ad_syntax(int oMSyntax) 
+{
+       int i;
+       for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
+               if (oMSyntax == dsdb_syntaxes[i].oMSyntax) {
+                       return &dsdb_syntaxes[i];
+               }
+       }
+       return NULL;
+}
+
+const struct dsdb_syntax *find_syntax_map_by_standard_oid(const char *standard_oid) 
+{
+       int i;
+       for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
+               if (strcasecmp(standard_oid, dsdb_syntaxes[i].ldap_oid) == 0) {
+                       return &dsdb_syntaxes[i];
+               }
+       }
+       return NULL;
+}
 const struct dsdb_syntax *dsdb_syntax_for_attribute(const struct dsdb_attribute *attr)
 {
        uint32_t i;
@@ -1358,7 +2134,8 @@ const struct dsdb_syntax *dsdb_syntax_for_attribute(const struct dsdb_attribute
        return NULL;
 }
 
-WERROR dsdb_attribute_drsuapi_to_ldb(const struct dsdb_schema *schema,
+WERROR dsdb_attribute_drsuapi_to_ldb(struct ldb_context *ldb, 
+                                    const struct dsdb_schema *schema,
                                     const struct drsuapi_DsReplicaAttribute *in,
                                     TALLOC_CTX *mem_ctx,
                                     struct ldb_message_element *out)
@@ -1370,10 +2147,11 @@ WERROR dsdb_attribute_drsuapi_to_ldb(const struct dsdb_schema *schema,
                return WERR_FOOBAR;
        }
 
-       return sa->syntax->drsuapi_to_ldb(schema, sa, in, mem_ctx, out);
+       return sa->syntax->drsuapi_to_ldb(ldb, schema, sa, in, mem_ctx, out);
 }
 
-WERROR dsdb_attribute_ldb_to_drsuapi(const struct dsdb_schema *schema,
+WERROR dsdb_attribute_ldb_to_drsuapi(struct ldb_context *ldb, 
+                                    const struct dsdb_schema *schema,
                                     const struct ldb_message_element *in,
                                     TALLOC_CTX *mem_ctx,
                                     struct drsuapi_DsReplicaAttribute *out)
@@ -1385,5 +2163,19 @@ WERROR dsdb_attribute_ldb_to_drsuapi(const struct dsdb_schema *schema,
                return WERR_FOOBAR;
        }
 
-       return sa->syntax->ldb_to_drsuapi(schema, sa, in, mem_ctx, out);
+       return sa->syntax->ldb_to_drsuapi(ldb, schema, sa, in, mem_ctx, out);
+}
+
+WERROR dsdb_attribute_validate_ldb(struct ldb_context *ldb,
+                                  const struct dsdb_schema *schema,
+                                  const struct ldb_message_element *in)
+{
+       const struct dsdb_attribute *sa;
+
+       sa = dsdb_attribute_by_lDAPDisplayName(schema, in->name);
+       if (!sa) {
+               return WERR_DS_ATTRIBUTE_TYPE_UNDEFINED;
+       }
+
+       return sa->syntax->validate_ldb(ldb, schema, sa, in);
 }