s4:dsdb Break up 'parse a DN from DRSUAPI' into a subfunction
[ira/wip.git] / source4 / dsdb / schema / schema_syntax.c
index fe6d129787f6c5d4cfbd437b9d3256d3cf601438..edf5df8aa9b14ff971bad616ffe53f1010513d8d 100644 (file)
@@ -3,10 +3,12 @@
    DSDB schema syntaxes
    
    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,
@@ -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,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,
@@ -113,7 +120,8 @@ static WERROR dsdb_syntax_BOOL_drsuapi_to_ldb(const struct dsdb_schema *schema,
        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,
@@ -154,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,
@@ -193,7 +202,8 @@ static WERROR dsdb_syntax_INT32_drsuapi_to_ldb(const struct dsdb_schema *schema,
        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,7 +234,9 @@ static WERROR dsdb_syntax_INT32_ldb_to_drsuapi(const struct dsdb_schema *schema,
                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);
        }
@@ -232,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 +275,7 @@ static WERROR dsdb_syntax_INT64_drsuapi_to_ldb(const struct dsdb_schema *schema,
 
                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);
@@ -271,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,
@@ -310,7 +324,8 @@ 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_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,
@@ -360,7 +375,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,
@@ -402,7 +418,8 @@ 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_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,
@@ -444,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,
@@ -486,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,
@@ -519,7 +538,8 @@ static WERROR dsdb_syntax_DATA_BLOB_drsuapi_to_ldb(const struct dsdb_schema *sch
        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,
@@ -552,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,
@@ -598,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,
@@ -615,9 +684,9 @@ static WERROR _dsdb_syntax_OID_oid_drsuapi_to_ldb(const struct dsdb_schema *sche
        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.values[i].blob == NULL) {
                        return WERR_FOOBAR;
@@ -627,18 +696,137 @@ static WERROR _dsdb_syntax_OID_oid_drsuapi_to_ldb(const struct dsdb_schema *sche
                        return WERR_FOOBAR;
                }
 
-               v = IVAL(in->value_ctr.values[i].blob->data, 0);
+               attid = IVAL(in->value_ctr.values[i].blob->data, 0);
 
-               status = dsdb_map_int2oid(schema, v, out->values, &str);
+               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,
@@ -648,11 +836,20 @@ 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;
@@ -692,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,
@@ -707,10 +905,20 @@ 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;
@@ -739,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,
@@ -756,7 +965,6 @@ static WERROR dsdb_syntax_UNICODE_drsuapi_to_ldb(const struct dsdb_schema *schem
        W_ERROR_HAVE_NO_MEMORY(out->values);
 
        for (i=0; i < out->num_values; i++) {
-               ssize_t ret;
                char *str;
 
                if (in->value_ctr.values[i].blob == NULL) {
@@ -767,11 +975,12 @@ static WERROR dsdb_syntax_UNICODE_drsuapi_to_ldb(const struct dsdb_schema *schem
                        return WERR_FOOBAR;
                }
 
-               ret = convert_string_talloc(out->values, CH_UTF16, CH_UNIX,
+               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);
-               if (ret == -1) {
+                                           (void **)&str, NULL, false)) {
                        return WERR_FOOBAR;
                }
 
@@ -781,7 +990,8 @@ static WERROR dsdb_syntax_UNICODE_drsuapi_to_ldb(const struct dsdb_schema *schem
        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,
@@ -805,24 +1015,104 @@ static WERROR dsdb_syntax_UNICODE_ldb_to_drsuapi(const struct dsdb_schema *schem
        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];
 
-               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_FOOBAR;
+               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;
                }
-               blobs[i].length = ret;
        }
 
        return WERR_OK;
 }
 
-static WERROR dsdb_syntax_DN_drsuapi_to_ldb(const struct dsdb_schema *schema,
+
+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,
@@ -839,32 +1129,21 @@ static WERROR dsdb_syntax_DN_drsuapi_to_ldb(const struct dsdb_schema *schema,
        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.values[i].blob == NULL) {
-                       return WERR_FOOBAR;
-               }
-
-               if (in->value_ctr.values[i].blob->length == 0) {
-                       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;
                }
-
-               status = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob,
-                                                 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,
@@ -888,32 +1167,72 @@ static WERROR dsdb_syntax_DN_ldb_to_drsuapi(const struct dsdb_schema *schema,
        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 *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];
 
-               /* TODO: handle id3.guid and id3.sid */
+               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);
-               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)) {
+               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(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);
@@ -924,44 +1243,93 @@ static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(const struct dsdb_schema *sch
        W_ERROR_HAVE_NO_MEMORY(out->values);
 
        for (i=0; i < out->num_values; i++) {
-               struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
-               char *binary;
-               char *str;
-               NTSTATUS status;
+               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;
                }
 
-               status = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob,
-                                                 out->values, &id3b,
-                                                 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary);
-               if (!NT_STATUS_IS_OK(status)) {
+               
+               /* 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);
                }
 
-               /* TODO: handle id3.guid and id3.sid */
-               binary = data_blob_hex_string(out->values, &id3b.binary);
-               W_ERROR_HAVE_NO_MEMORY(binary);
+               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);
+               }
 
-               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);
+               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);
+               }
 
-               /* TODO: handle id3.guid and id3.sid */
-               out->values[i] = data_blob_string_const(str);
+               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(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,
@@ -985,27 +1353,71 @@ static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(const struct dsdb_schema *sch
        W_ERROR_HAVE_NO_MEMORY(blobs);
 
        for (i=0; i < in->num_values; i++) {
-               NTSTATUS status;
-               struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
+               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];
 
-               /* 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);
+               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");
 
-               status = ndr_push_struct_blob(&blobs[i], blobs, &id3b,
-                                             (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary);
-               if (!NT_STATUS_IS_OK(status)) {
+               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;
 }
 
-static WERROR dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb(const struct dsdb_schema *schema,
+
+
+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,
@@ -1023,7 +1435,6 @@ static WERROR dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb(const struct dsdb_
 
        for (i=0; i < out->num_values; i++) {
                uint32_t len;
-               ssize_t ret;
                char *str;
 
                if (in->value_ctr.values[i].blob == NULL) {
@@ -1040,11 +1451,10 @@ static WERROR dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb(const struct dsdb_
                        return WERR_FOOBAR;
                }
 
-               ret = convert_string_talloc(out->values, CH_UTF16, CH_UNIX,
+               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);
-               if (ret == -1) {
+                                           (void **)&str, NULL, false)) {
                        return WERR_FOOBAR;
                }
 
@@ -1054,7 +1464,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,
@@ -1079,15 +1490,14 @@ static WERROR dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi(const struct dsdb_
 
        for (i=0; i < in->num_values; i++) {
                uint8_t *data;
-               ssize_t ret;
+               size_t ret;
 
                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;
                }
 
@@ -1105,38 +1515,47 @@ 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,
+               .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",
@@ -1144,13 +1563,17 @@ 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)",
@@ -1159,6 +1582,10 @@ 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,
+               .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",
@@ -1166,6 +1593,7 @@ 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,
+               .ldb_syntax             = LDB_SYNTAX_OCTET_STRING,
        },{
                .name                   = "String(Teletex)",
                .ldap_oid               = "1.2.840.113556.1.4.905",
@@ -1173,6 +1601,10 @@ 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,
+               .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",
@@ -1180,6 +1612,9 @@ 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,
+               .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",
@@ -1187,6 +1622,8 @@ 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,
+               .equality               = "generalizedTimeMatch",
+               .comment                = "UTC Time",
        },{
                .name                   = "String(Generalized-Time)",
                .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.24",
@@ -1194,6 +1631,9 @@ 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 schema */
                .name                   = "String(Case Sensitive)",
@@ -1204,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",
@@ -1216,29 +1659,36 @@ 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_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_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 schema */
                .name                   = "Object(OR-Name)",
@@ -1270,6 +1720,8 @@ 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,
+               .comment                = "Presentation Address",
+               .ldb_syntax             = LDB_SYNTAX_DIRECTORY_STRING,
        },{
        /* not used in w2k3 schema */
                .name                   = "Object(Access-Point)",
@@ -1279,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 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;
@@ -1316,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)
@@ -1328,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)
@@ -1343,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);
 }