s4:dsdb Break up 'parse a DN from DRSUAPI' into a subfunction
[ira/wip.git] / source4 / dsdb / schema / schema_syntax.c
index 9abe13b9608521c41abaeed1788b62ebd6ffc706..edf5df8aa9b14ff971bad616ffe53f1010513d8d 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/drsuapi.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,
@@ -38,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;
                }
 
@@ -59,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,
@@ -68,7 +75,8 @@ 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_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,
@@ -76,18 +84,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);
 
@@ -95,15 +96,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");
@@ -119,7 +120,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,
@@ -132,18 +134,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);
@@ -160,7 +162,8 @@ 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_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,
@@ -168,23 +171,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);
 
@@ -192,15 +183,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);
@@ -211,7 +202,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,
@@ -224,12 +216,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);
@@ -237,12 +229,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);
        }
@@ -250,7 +244,8 @@ 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_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,
@@ -262,7 +257,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);
 
@@ -270,17 +265,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);
@@ -289,7 +284,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,
@@ -302,12 +298,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);
@@ -315,7 +311,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);
@@ -328,7 +324,102 @@ static WERROR dsdb_syntax_INT64_ldb_to_drsuapi(const struct dsdb_schema *schema,
        return WERR_OK;
 }
 
-static WERROR dsdb_syntax_NTTIME_drsuapi_to_ldb(const struct dsdb_schema *schema,
+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,
+                                                   struct ldb_message_element *out)
+{
+       uint32_t i;
+
+       out->flags      = 0;
+       out->name       = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
+       W_ERROR_HAVE_NO_MEMORY(out->name);
+
+       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++) {
+               NTTIME v;
+               time_t t;
+               char *str;
+
+               if (in->value_ctr.values[i].blob == NULL) {
+                       return WERR_FOOBAR;
+               }
+
+               if (in->value_ctr.values[i].blob->length != 8) {
+                       return WERR_FOOBAR;
+               }
+
+               v = BVAL(in->value_ctr.values[i].blob->data, 0);
+               v *= 10000000;
+               t = nt_time_to_unix(v);
+
+               /* 
+                * NOTE: On a w2k3 server you can set a GeneralizedTime string
+                *       via LDAP, but you get back an UTCTime string,
+                *       but via DRSUAPI you get back the NTTIME_1sec value
+                *       that represents the GeneralizedTime value!
+                *
+                *       So if we store the UTCTime string in our ldb
+                *       we'll loose information!
+                */
+               str = ldb_timestring_utc(out->values, t); 
+               W_ERROR_HAVE_NO_MEMORY(str);
+               out->values[i] = data_blob_string_const(str);
+       }
+
+       return WERR_OK;
+}
+
+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,
+                                                   struct drsuapi_DsReplicaAttribute *out)
+{
+       uint32_t i;
+       DATA_BLOB *blobs;
+
+       if (attr->attributeID_id == 0xFFFFFFFF) {
+               return WERR_FOOBAR;
+       }
+
+       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++) {
+               NTTIME v;
+               time_t t;
+
+               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_utc_to_time((const char *)in->values[i].data);
+               unix_to_nt_time(&v, t);
+               v /= 10000000;
+
+               SBVAL(blobs[i].data, 0, v);
+       }
+
+       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,
@@ -340,7 +431,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);
 
@@ -349,15 +440,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);
 
@@ -370,7 +461,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,
@@ -383,12 +475,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);
@@ -397,13 +489,14 @@ static WERROR dsdb_syntax_NTTIME_ldb_to_drsuapi(const struct dsdb_schema *schema
                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);
 
                t = ldb_string_to_time((const char *)in->values[i].data);
                unix_to_nt_time(&v, t);
+               v /= 10000000;
 
                SBVAL(blobs[i].data, 0, v);
        }
@@ -411,7 +504,8 @@ 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_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,
@@ -419,38 +513,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,
@@ -463,18 +552,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);
@@ -483,7 +572,8 @@ 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,
+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,
@@ -495,7 +585,7 @@ 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);
 
@@ -504,11 +594,15 @@ static WERROR _dsdb_syntax_OID_obj_drsuapi_to_ldb(const struct dsdb_schema *sche
                const struct dsdb_class *c;
                const char *str;
 
-               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;
+               if (in->value_ctr.values[i].blob->length != 4) {
+                       return WERR_FOOBAR;
+               }
+
+               v = IVAL(in->value_ctr.values[i].blob->data, 0);
 
                c = dsdb_class_by_governsID_id(schema, v);
                if (!c) {
@@ -525,7 +619,55 @@ 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_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;
+
+       out->flags      = 0;
+       out->name       = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
+       W_ERROR_HAVE_NO_MEMORY(out->name);
+
+       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_attribute *a;
+               const char *str;
+
+               if (in->value_ctr.values[i].blob == NULL) {
+                       return WERR_FOOBAR;
+               }
+
+               if (in->value_ctr.values[i].blob->length != 4) {
+                       return WERR_FOOBAR;
+               }
+
+               v = IVAL(in->value_ctr.values[i].blob->data, 0);
+
+               a = dsdb_attribute_by_attributeID_id(schema, v);
+               if (!a) {
+                       return WERR_FOOBAR;
+               }
+
+               str = talloc_strdup(out->values, a->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_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,
@@ -537,31 +679,154 @@ 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;
+               uint32_t attid;
                WERROR status;
-               const char *str;
+               const char *oid;
 
-               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);
+               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(str);
+               out->values[i] = data_blob_string_const(oid);
+       }
+
+       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);
+
+               obj_class = dsdb_class_by_lDAPDisplayName(schema, (const char *)in->values[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 attid;
+               WERROR status;
+
+               out->value_ctr.values[i].blob= &blobs[i];
+
+               blobs[i] = data_blob_talloc(blobs, NULL, 4);
+               W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
+
+               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, attid);
        }
 
        return WERR_OK;
 }
 
-static WERROR dsdb_syntax_OID_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,
@@ -571,18 +836,27 @@ static WERROR dsdb_syntax_OID_drsuapi_to_ldb(const struct dsdb_schema *schema,
 
        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_subClassOf:
+       case DRSUAPI_ATTRIBUTE_auxiliaryClass:
+       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_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(schema, attr, in, mem_ctx, out);
+               return _dsdb_syntax_OID_oid_drsuapi_to_ldb(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);
 
@@ -591,15 +865,15 @@ static WERROR dsdb_syntax_OID_drsuapi_to_ldb(const struct dsdb_schema *schema,
                const char *name;
                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) {
@@ -615,7 +889,8 @@ static WERROR dsdb_syntax_OID_drsuapi_to_ldb(const struct dsdb_schema *schema,
        return WERR_OK;
 }
 
-static WERROR dsdb_syntax_OID_ldb_to_drsuapi(const struct dsdb_schema *schema,
+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,
@@ -630,18 +905,28 @@ static WERROR dsdb_syntax_OID_ldb_to_drsuapi(const struct dsdb_schema *schema,
 
        switch (attr->attributeID_id) {
        case DRSUAPI_ATTRIBUTE_objectClass:
+       case DRSUAPI_ATTRIBUTE_subClassOf:
+       case DRSUAPI_ATTRIBUTE_auxiliaryClass:
+       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_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_FOOBAR_ldb_to_drsuapi(schema, attr, in, mem_ctx, out);
+               return _dsdb_syntax_OID_oid_ldb_to_drsuapi(ldb, schema, attr, in, mem_ctx, out);
        }
 
-       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);
@@ -649,7 +934,7 @@ static WERROR dsdb_syntax_OID_ldb_to_drsuapi(const struct dsdb_schema *schema,
        for (i=0; i < in->num_values; i++) {
                uint32_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);
@@ -662,7 +947,8 @@ static WERROR dsdb_syntax_OID_ldb_to_drsuapi(const struct dsdb_schema *schema,
        return WERR_OK;
 }
 
-static WERROR dsdb_syntax_UNICODE_drsuapi_to_ldb(const struct dsdb_schema *schema,
+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,
@@ -670,42 +956,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;
                }
 
@@ -715,7 +990,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,
@@ -728,29 +1004,512 @@ 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++) {
+               out->value_ctr.values[i].blob   = &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;
+               }
+       }
+
+       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;
+
+       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)) {
+               NTSTATUS 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);
+       }
+       
+       ndr_err = ndr_push_struct_blob(&guid_blob, tmp_ctx, iconv_convenience, &id3.guid,
+                                      (ndr_push_flags_fn_t)ndr_push_GUID);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
+               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;
+       }
+       
+       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)) {
+                       NTSTATUS 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(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;
+
+       out->flags      = 0;
+       out->name       = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
+       W_ERROR_HAVE_NO_MEMORY(out->name);
+
+       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++) {
+               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;
+               }
+                                                 
+       }
+
+       return WERR_OK;
+}
+
+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,
+                                           struct drsuapi_DsReplicaAttribute *out)
+{
+       uint32_t i;
+       DATA_BLOB *blobs;
+
+       if (attr->attributeID_id == 0xFFFFFFFF) {
+               return WERR_FOOBAR;
+       }
+
+       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;
+               struct drsuapi_DsReplicaObjectIdentifier3 id3;
+               enum ndr_err_code ndr_err;
+               const DATA_BLOB *guid_blob, *sid_blob;
+               struct ldb_dn *dn;
+               TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+               W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
+
+               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);
+
+               guid_blob = ldb_dn_get_extended_component(dn, "GUID");
+
+               ZERO_STRUCT(id3);
+
+               if (guid_blob) {
+                       ndr_err = ndr_pull_struct_blob_all(guid_blob, 
+                                                          tmp_ctx, schema->iconv_convenience, &id3.guid,
+                                                          (ndr_pull_flags_fn_t)ndr_pull_GUID);
+                       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                               NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
+                               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)) {
+                               NTSTATUS 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)) {
+                       NTSTATUS 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(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.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 id3;
+               enum ndr_err_code ndr_err;
+               DATA_BLOB guid_blob;
+               struct ldb_dn *dn;
+               struct dsdb_dn *dsdb_dn;
+               TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+               if (!tmp_ctx) {
+                       W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
+               }
+
+               if (in->value_ctr.values[i].blob == NULL) {
+                       talloc_free(tmp_ctx);
+                       return WERR_FOOBAR;
+               }
+
+               if (in->value_ctr.values[i].blob->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->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)) {
+                       NTSTATUS 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);
+               }
+
+               ndr_err = ndr_push_struct_blob(&guid_blob, tmp_ctx, schema->iconv_convenience, &id3.guid,
+                                              (ndr_push_flags_fn_t)ndr_push_GUID);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
+                       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;
+               }
+
+               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)) {
+                               NTSTATUS 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;
+                       }
+               }
+
+               /* 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(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;
+
+       if (attr->attributeID_id == 0xFFFFFFFF) {
+               return WERR_FOOBAR;
+       }
+
+       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 *guid_blob, *sid_blob;
+               struct dsdb_dn *dsdb_dn;
+               TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+               W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
+
+               out->value_ctr.values[i].blob   = &blobs[i];
+
+               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);
+               }
+
+               guid_blob = ldb_dn_get_extended_component(dsdb_dn->dn, "GUID");
+
+               ZERO_STRUCT(id3);
+
+               if (guid_blob) {
+                       ndr_err = ndr_pull_struct_blob_all(guid_blob, 
+                                                          tmp_ctx, schema->iconv_convenience, &id3.guid,
+                                                          (ndr_pull_flags_fn_t)ndr_pull_GUID);
+                       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                               NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
+                               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)) {
+                               NTSTATUS 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)) {
+                       NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
+                       talloc_free(tmp_ctx);
+                       return ntstatus_to_werror(status);
+               }
+               talloc_free(tmp_ctx);
+       }
+
+       return WERR_OK;
+}
+
 
-               out->value_ctr.data_blob.values[i].data = &blobs[i];
 
-               ret = convert_string_talloc(blobs, CH_UNIX, CH_UTF16,
+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,
+                                                             struct ldb_message_element *out)
+{
+       uint32_t i;
+
+       out->flags      = 0;
+       out->name       = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
+       W_ERROR_HAVE_NO_MEMORY(out->name);
+
+       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;
+               char *str;
+
+               if (in->value_ctr.values[i].blob == NULL) {
+                       return WERR_FOOBAR;
+               }
+
+               if (in->value_ctr.values[i].blob->length < 4) {
+                       return WERR_FOOBAR;
+               }
+
+               len = IVAL(in->value_ctr.values[i].blob->data, 0);
+
+               if (len != in->value_ctr.values[i].blob->length) {
+                       return WERR_FOOBAR;
+               }
+
+               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;
+               }
+
+               out->values[i] = data_blob_string_const(str);
+       }
+
+       return WERR_OK;
+}
+
+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,
+                                                             struct drsuapi_DsReplicaAttribute *out)
+{
+       uint32_t i;
+       DATA_BLOB *blobs;
+
+       if (attr->attributeID_id == 0xFFFFFFFF) {
+               return WERR_FOOBAR;
+       }
+
+       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;
+               size_t ret;
+
+               out->value_ctr.values[i].blob   = &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);
-               if (ret == -1) {
+                                           (void **)&data, &ret, false)) {
                        return WERR_FOOBAR;
                }
-               blobs[i].length = ret;
+
+               blobs[i] = data_blob_talloc(blobs, NULL, 4 + ret);
+               W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
+
+               SIVAL(blobs[i].data, 0, 4 + ret);
+
+               if (ret > 0) {
+                       memcpy(blobs[i].data + 4, data, ret);
+                       talloc_free(data);
+               }
        }
 
        return WERR_OK;
@@ -761,32 +1520,42 @@ static WERROR dsdb_syntax_UNICODE_ldb_to_drsuapi(const struct dsdb_schema *schem
 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,
+               .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,
+               .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,
+               .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,
+               .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",
@@ -794,53 +1563,67 @@ 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,
+               .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,
+               .ldb_syntax             = LDB_SYNTAX_SAMBA_INT32
        },{
        /* not used in w2k3 forest */
                .name                   = "String(Numeric)",
                .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.36",
                .oMSyntax               = 18,
                .attributeSyntax_oid    = "2.5.5.6",
-               .drsuapi_to_ldb         = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
-               .ldb_to_drsuapi         = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
+               .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
+               .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
+               .equality               = "numericStringMatch",
+               .substring              = "numericStringSubstringsMatch",
+               .comment                = "Numeric String",
+               .ldb_syntax             = LDB_SYNTAX_DIRECTORY_STRING,
        },{
-       /* not used in w2k3 forest */
                .name                   = "String(Printable)",
                .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.44",
                .oMSyntax               = 19,
                .attributeSyntax_oid    = "2.5.5.5",
-               .drsuapi_to_ldb         = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
-               .ldb_to_drsuapi         = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
+               .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
+               .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
+               .ldb_syntax             = LDB_SYNTAX_OCTET_STRING,
        },{
-       /* not used in w2k3 forest */
                .name                   = "String(Teletex)",
                .ldap_oid               = "1.2.840.113556.1.4.905",
                .oMSyntax               = 20,
                .attributeSyntax_oid    = "2.5.5.4",
-               .drsuapi_to_ldb         = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
-               .ldb_to_drsuapi         = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
+               .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
+               .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
+               .equality               = "caseIgnoreMatch",
+               .substring              = "caseIgnoreSubstringsMatch",
+               .comment                = "Case Insensitive String",
+               .ldb_syntax             = LDB_SYNTAX_DIRECTORY_STRING,
        },{
-       /* not used in w2k3 forest */
                .name                   = "String(IA5)",
                .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.26",
                .oMSyntax               = 22,
                .attributeSyntax_oid    = "2.5.5.5",
-               .drsuapi_to_ldb         = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
-               .ldb_to_drsuapi         = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
+               .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
+               .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
+               .equality               = "caseExactIA5Match",
+               .comment                = "Printable String",
+               .ldb_syntax             = LDB_SYNTAX_OCTET_STRING,
        },{
-       /* not used in w2k3 forest */
                .name                   = "String(UTC-Time)",
                .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.53",
                .oMSyntax               = 23,
                .attributeSyntax_oid    = "2.5.5.11",
-               .drsuapi_to_ldb         = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
-               .ldb_to_drsuapi         = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
+               .drsuapi_to_ldb         = dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb,
+               .ldb_to_drsuapi         = dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi,
+               .equality               = "generalizedTimeMatch",
+               .comment                = "UTC Time",
        },{
                .name                   = "String(Generalized-Time)",
                .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.24",
@@ -848,8 +1631,11 @@ 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,
+               .equality               = "generalizedTimeMatch",
+               .comment                = "Generalized Time",
+               .ldb_syntax             = LDB_SYNTAX_UTC_TIME,
        },{
-       /* not used in w2k3 forest */
+       /* not used in w2k3 schema */
                .name                   = "String(Case Sensitive)",
                .ldap_oid               = "1.2.840.113556.1.4.1362",
                .oMSyntax               = 27,
@@ -858,11 +1644,14 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .ldb_to_drsuapi         = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
        },{
                .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,
+               .equality               = "caseIgnoreMatch",
+               .substring              = "caseIgnoreSubstringsMatch",
+               .comment                = "Directory String",
        },{
                .name                   = "Interval/LargeInteger",
                .ldap_oid               = "1.2.840.113556.1.4.906",
@@ -870,31 +1659,38 @@ 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,
+               .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,
        },{
                .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_FOOBAR_drsuapi_to_ldb,
-               .ldb_to_drsuapi         = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
+               .drsuapi_to_ldb         = dsdb_syntax_DN_drsuapi_to_ldb,
+               .ldb_to_drsuapi         = dsdb_syntax_DN_ldb_to_drsuapi,
+               .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_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,
+               .equality               = "octetStringMatch",
+               .comment                = "OctetString: Binary+DN",
        },{
-       /* not used in w2k3 forest */
+       /* not used in w2k3 schema */
                .name                   = "Object(OR-Name)",
                .ldap_oid               = "1.2.840.113556.1.4.1221",
                .oMSyntax               = 127,
@@ -903,6 +1699,12 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .drsuapi_to_ldb         = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
        },{
+       /* 
+        * TODO: verify if DATA_BLOB is correct here...!
+        *
+        *       repsFrom and repsTo are the only attributes using
+        *       this attribute syntax, but they're not replicated... 
+        */
                .name                   = "Object(Replica-Link)",
                .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.40",
                .oMSyntax               = 127,
@@ -911,16 +1713,17 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
        },{
-       /* not used in w2k3 forest */
+               .name                   = "Object(Presentation-Address)",
                .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.43",
                .oMSyntax               = 127,
                .oMObjectClass          = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x5c"),
                .attributeSyntax_oid    = "2.5.5.13",
-               .name                   = "Object(Presentation-Address)",
-               .drsuapi_to_ldb         = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
-               .ldb_to_drsuapi         = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
+               .drsuapi_to_ldb         = dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb,
+               .ldb_to_drsuapi         = dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi,
+               .comment                = "Presentation Address",
+               .ldb_syntax             = LDB_SYNTAX_DIRECTORY_STRING,
        },{
-       /* not used in w2k3 forest */
+       /* not used in w2k3 schema */
                .name                   = "Object(Access-Point)",
                .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.2",
                .oMSyntax               = 127,
@@ -928,18 +1731,53 @@ 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,
+               .ldb_syntax             = LDB_SYNTAX_DIRECTORY_STRING,
        },{
-       /* not used in w2k3 forest */
+       /* 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_BINARY_drsuapi_to_ldb,
+               .ldb_to_drsuapi         = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
+               .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;
@@ -965,7 +1803,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)
@@ -977,10 +1816,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)
@@ -992,5 +1832,5 @@ 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);
 }