LCOV - code coverage report
Current view: top level - source4/dsdb/schema - schema_syntax.c (source / functions) Hit Total Coverage
Test: coverage report for master 70ed9daf Lines: 845 1288 65.6 %
Date: 2024-01-11 09:59:51 Functions: 46 61 75.4 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS Implementation.
       3             :    DSDB schema syntaxes
       4             : 
       5             :    Copyright (C) Stefan Metzmacher <metze@samba.org> 2006
       6             :    Copyright (C) Simo Sorce 2005
       7             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2008
       8             : 
       9             :    This program is free software; you can redistribute it and/or modify
      10             :    it under the terms of the GNU General Public License as published by
      11             :    the Free Software Foundation; either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    This program is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : 
      22             : */
      23             : #include "includes.h"
      24             : #include "dsdb/samdb/samdb.h"
      25             : #include "librpc/gen_ndr/ndr_drsuapi.h"
      26             : #include "librpc/gen_ndr/ndr_security.h"
      27             : #include "librpc/gen_ndr/ndr_misc.h"
      28             : #include <ldb.h>
      29             : #include <ldb_errors.h>
      30             : #include "system/time.h"
      31             : #include "../lib/util/charset/charset.h"
      32             : #include "librpc/ndr/libndr.h"
      33             : #include "../lib/util/asn1.h"
      34             : 
      35             : #undef strcasecmp
      36             : 
      37             : /**
      38             :  * Initialize dsdb_syntax_ctx with default values
      39             :  * for common cases.
      40             :  */
      41    22167535 : void dsdb_syntax_ctx_init(struct dsdb_syntax_ctx *ctx,
      42             :                           struct ldb_context *ldb,
      43             :                           const struct dsdb_schema *schema)
      44             : {
      45    22167535 :         ctx->ldb     = ldb;
      46    22167535 :         ctx->schema  = schema;
      47             : 
      48             :         /*
      49             :          * 'true' will keep current behavior,
      50             :          * i.e. attributeID_id will be returned by default
      51             :          */
      52    22167535 :         ctx->is_schema_nc = true;
      53             : 
      54    22167535 :         ctx->pfm_remote = NULL;
      55    22167535 : }
      56             : 
      57             : 
      58             : /**
      59             :  * Returns ATTID for DRS attribute.
      60             :  *
      61             :  * ATTID depends on whether we are replicating
      62             :  * Schema NC or msDs-IntId is set for schemaAttribute
      63             :  * for the attribute.
      64             :  */
      65    46581249 : uint32_t dsdb_attribute_get_attid(const struct dsdb_attribute *attr,
      66             :                                   bool for_schema_nc)
      67             : {
      68    46581249 :         if (!for_schema_nc && attr->msDS_IntId) {
      69        3527 :                 return attr->msDS_IntId;
      70             :         }
      71             : 
      72    46577722 :         return attr->attributeID_id;
      73             : }
      74             : 
      75             : /**
      76             :  * Map an ATTID from remote DC to a local ATTID
      77             :  * using remote prefixMap
      78             :  */
      79    14986978 : static bool dsdb_syntax_attid_from_remote_attid(const struct dsdb_syntax_ctx *ctx,
      80             :                                                 TALLOC_CTX *mem_ctx,
      81             :                                                 uint32_t id_remote,
      82             :                                                 uint32_t *id_local)
      83             : {
      84      460639 :         WERROR werr;
      85      460639 :         const char *oid;
      86             : 
      87             :         /*
      88             :          * map remote ATTID to local directly in case
      89             :          * of no remote prefixMap (during provision for instance)
      90             :          */
      91    14986978 :         if (!ctx->pfm_remote) {
      92     2993950 :                 *id_local = id_remote;
      93     2993950 :                 return true;
      94             :         }
      95             : 
      96    11993028 :         werr = dsdb_schema_pfm_oid_from_attid(ctx->pfm_remote, id_remote, mem_ctx, &oid);
      97    11993028 :         if (!W_ERROR_IS_OK(werr)) {
      98           0 :                 DEBUG(0,("ATTID->OID failed (%s) for: 0x%08X\n", win_errstr(werr), id_remote));
      99           0 :                 return false;
     100             :         }
     101             : 
     102    11993028 :         werr = dsdb_schema_pfm_attid_from_oid(ctx->schema->prefixmap, oid, id_local);
     103    11993028 :         if (!W_ERROR_IS_OK(werr)) {
     104           0 :                 DEBUG(0,("OID->ATTID failed (%s) for: %s\n", win_errstr(werr), oid));
     105           0 :                 return false;
     106             :         }
     107             : 
     108    11993028 :         return true;
     109             : }
     110             : 
     111           0 : static WERROR dsdb_syntax_FOOBAR_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
     112             :                                                 const struct dsdb_attribute *attr,
     113             :                                                 const struct drsuapi_DsReplicaAttribute *in,
     114             :                                                 TALLOC_CTX *mem_ctx,
     115             :                                                 struct ldb_message_element *out)
     116             : {
     117           0 :         unsigned int i;
     118             : 
     119           0 :         out->flags   = 0;
     120           0 :         out->name    = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
     121           0 :         W_ERROR_HAVE_NO_MEMORY(out->name);
     122             : 
     123           0 :         out->num_values      = in->value_ctr.num_values;
     124           0 :         out->values  = talloc_array(mem_ctx, struct ldb_val, out->num_values);
     125           0 :         W_ERROR_HAVE_NO_MEMORY(out->values);
     126             : 
     127           0 :         for (i=0; i < out->num_values; i++) {
     128           0 :                 char *str;
     129             : 
     130           0 :                 if (in->value_ctr.values[i].blob == NULL) {
     131           0 :                         return WERR_FOOBAR;
     132             :                 }
     133             : 
     134           0 :                 str = talloc_asprintf(out->values, "%s: not implemented",
     135           0 :                                       attr->syntax->name);
     136           0 :                 W_ERROR_HAVE_NO_MEMORY(str);
     137             : 
     138           0 :                 out->values[i] = data_blob_string_const(str);
     139             :         }
     140             : 
     141           0 :         return WERR_OK;
     142             : }
     143             : 
     144           0 : static WERROR dsdb_syntax_FOOBAR_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
     145             :                                                 const struct dsdb_attribute *attr,
     146             :                                                 const struct ldb_message_element *in,
     147             :                                                 TALLOC_CTX *mem_ctx,
     148             :                                                 struct drsuapi_DsReplicaAttribute *out)
     149             : {
     150           0 :         return WERR_FOOBAR;
     151             : }
     152             : 
     153           0 : static WERROR dsdb_syntax_FOOBAR_validate_ldb(const struct dsdb_syntax_ctx *ctx,
     154             :                                               const struct dsdb_attribute *attr,
     155             :                                               const struct ldb_message_element *in)
     156             : {
     157           0 :         return WERR_FOOBAR;
     158             : }
     159             : 
     160     2391641 : static WERROR dsdb_syntax_BOOL_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
     161             :                                               const struct dsdb_attribute *attr,
     162             :                                               const struct drsuapi_DsReplicaAttribute *in,
     163             :                                               TALLOC_CTX *mem_ctx,
     164             :                                               struct ldb_message_element *out)
     165             : {
     166      144909 :         unsigned int i;
     167             : 
     168     2391641 :         out->flags   = 0;
     169     2391641 :         out->name    = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
     170     2391641 :         W_ERROR_HAVE_NO_MEMORY(out->name);
     171             : 
     172     2391641 :         out->num_values      = in->value_ctr.num_values;
     173     2391641 :         out->values  = talloc_array(mem_ctx, struct ldb_val, out->num_values);
     174     2391641 :         W_ERROR_HAVE_NO_MEMORY(out->values);
     175             : 
     176     4770273 :         for (i=0; i < out->num_values; i++) {
     177      144909 :                 uint32_t v;
     178      144909 :                 char *str;
     179             : 
     180     2378632 :                 if (in->value_ctr.values[i].blob == NULL) {
     181           0 :                         return WERR_FOOBAR;
     182             :                 }
     183             : 
     184     2378632 :                 if (in->value_ctr.values[i].blob->length != 4) {
     185           0 :                         return WERR_FOOBAR;
     186             :                 }
     187             : 
     188     2378632 :                 v = IVAL(in->value_ctr.values[i].blob->data, 0);
     189             : 
     190     2378632 :                 if (v != 0) {
     191     1854807 :                         str = talloc_strdup(out->values, "TRUE");
     192     1854807 :                         W_ERROR_HAVE_NO_MEMORY(str);
     193             :                 } else {
     194      523825 :                         str = talloc_strdup(out->values, "FALSE");
     195      523825 :                         W_ERROR_HAVE_NO_MEMORY(str);
     196             :                 }
     197             : 
     198     2378632 :                 out->values[i] = data_blob_string_const(str);
     199             :         }
     200             : 
     201     2391641 :         return WERR_OK;
     202             : }
     203             : 
     204     2069981 : static WERROR dsdb_syntax_BOOL_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
     205             :                                               const struct dsdb_attribute *attr,
     206             :                                               const struct ldb_message_element *in,
     207             :                                               TALLOC_CTX *mem_ctx,
     208             :                                               struct drsuapi_DsReplicaAttribute *out)
     209             : {
     210      144909 :         unsigned int i;
     211      144909 :         DATA_BLOB *blobs;
     212             : 
     213     2069981 :         if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     214           0 :                 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
     215             :         }
     216             : 
     217     4139962 :         out->attid                   = dsdb_attribute_get_attid(attr,
     218     2069981 :                                                                    ctx->is_schema_nc);
     219     2069981 :         out->value_ctr.num_values    = in->num_values;
     220     2069981 :         out->value_ctr.values                = talloc_array(mem_ctx,
     221             :                                                        struct drsuapi_DsAttributeValue,
     222             :                                                        in->num_values);
     223     2069981 :         W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
     224             : 
     225     2069981 :         blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
     226     2069981 :         W_ERROR_HAVE_NO_MEMORY(blobs);
     227             : 
     228     4139962 :         for (i=0; i < in->num_values; i++) {
     229     2069981 :                 out->value_ctr.values[i].blob        = &blobs[i];
     230             : 
     231     2069981 :                 blobs[i] = data_blob_talloc(blobs, NULL, 4);
     232     2069981 :                 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
     233             : 
     234     2069981 :                 if (in->values[i].length >= 4 &&
     235     2069981 :                     strncmp("TRUE", (const char *)in->values[i].data, in->values[i].length) == 0) {
     236     1691674 :                         SIVAL(blobs[i].data, 0, 0x00000001);
     237      378307 :                 } else if (in->values[i].length >= 5 &&
     238      378307 :                            strncmp("FALSE", (const char *)in->values[i].data, in->values[i].length) == 0) {
     239      378307 :                         SIVAL(blobs[i].data, 0, 0x00000000);
     240             :                 } else {
     241           0 :                         return WERR_FOOBAR;
     242             :                 }
     243             :         }
     244             : 
     245     2069981 :         return WERR_OK;
     246             : }
     247             : 
     248      968618 : static WERROR dsdb_syntax_BOOL_validate_ldb(const struct dsdb_syntax_ctx *ctx,
     249             :                                             const struct dsdb_attribute *attr,
     250             :                                             const struct ldb_message_element *in)
     251             : {
     252      170865 :         unsigned int i;
     253             : 
     254      968618 :         if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     255           0 :                 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
     256             :         }
     257             : 
     258     1936706 :         for (i=0; i < in->num_values; i++) {
     259      968088 :                 if (in->values[i].length == 0) {
     260           0 :                         return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     261             :                 }
     262             : 
     263      968088 :                 if (in->values[i].length >= 4 &&
     264      968088 :                     strncmp("TRUE",
     265      968088 :                             (const char *)in->values[i].data,
     266      797223 :                             in->values[i].length) == 0) {
     267      922050 :                         continue;
     268             :                 }
     269      259423 :                 if (in->values[i].length >= 5 &&
     270      259423 :                     strncmp("FALSE",
     271      259423 :                             (const char *)in->values[i].data,
     272      213385 :                             in->values[i].length) == 0) {
     273      259423 :                         continue;
     274             :                 }
     275           0 :                 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     276             :         }
     277             : 
     278      968618 :         return WERR_OK;
     279             : }
     280             : 
     281     3147969 : static WERROR dsdb_syntax_INT32_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
     282             :                                                const struct dsdb_attribute *attr,
     283             :                                                const struct drsuapi_DsReplicaAttribute *in,
     284             :                                                TALLOC_CTX *mem_ctx,
     285             :                                                struct ldb_message_element *out)
     286             : {
     287      197248 :         unsigned int i;
     288             : 
     289     3147969 :         out->flags   = 0;
     290     3147969 :         out->name    = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
     291     3147969 :         W_ERROR_HAVE_NO_MEMORY(out->name);
     292             : 
     293     3147969 :         out->num_values      = in->value_ctr.num_values;
     294     3147969 :         out->values  = talloc_array(mem_ctx, struct ldb_val, out->num_values);
     295     3147969 :         W_ERROR_HAVE_NO_MEMORY(out->values);
     296             : 
     297     6101070 :         for (i=0; i < out->num_values; i++) {
     298      197248 :                 int32_t v;
     299      197248 :                 char *str;
     300             : 
     301     2953101 :                 if (in->value_ctr.values[i].blob == NULL) {
     302           0 :                         return WERR_FOOBAR;
     303             :                 }
     304             : 
     305     2953101 :                 if (in->value_ctr.values[i].blob->length != 4) {
     306           0 :                         return WERR_FOOBAR;
     307             :                 }
     308             : 
     309     2953101 :                 v = IVALS(in->value_ctr.values[i].blob->data, 0);
     310             : 
     311     2953101 :                 str = talloc_asprintf(out->values, "%d", v);
     312     2953101 :                 W_ERROR_HAVE_NO_MEMORY(str);
     313             : 
     314     2953101 :                 out->values[i] = data_blob_string_const(str);
     315             :         }
     316             : 
     317     3147969 :         return WERR_OK;
     318             : }
     319             : 
     320     2455479 : static WERROR dsdb_syntax_INT32_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
     321             :                                                const struct dsdb_attribute *attr,
     322             :                                                const struct ldb_message_element *in,
     323             :                                                TALLOC_CTX *mem_ctx,
     324             :                                                struct drsuapi_DsReplicaAttribute *out)
     325             : {
     326      197248 :         unsigned int i;
     327      197248 :         DATA_BLOB *blobs;
     328             : 
     329     2455479 :         if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     330           0 :                 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
     331             :         }
     332             : 
     333     4910958 :         out->attid                   = dsdb_attribute_get_attid(attr,
     334     2455479 :                                                                    ctx->is_schema_nc);
     335     2455479 :         out->value_ctr.num_values    = in->num_values;
     336     2455479 :         out->value_ctr.values                = talloc_array(mem_ctx,
     337             :                                                        struct drsuapi_DsAttributeValue,
     338             :                                                        in->num_values);
     339     2455479 :         W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
     340             : 
     341     2455479 :         blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
     342     2455479 :         W_ERROR_HAVE_NO_MEMORY(blobs);
     343             : 
     344     4910972 :         for (i=0; i < in->num_values; i++) {
     345      197248 :                 int32_t v;
     346             : 
     347     2455493 :                 out->value_ctr.values[i].blob        = &blobs[i];
     348             : 
     349     2455493 :                 blobs[i] = data_blob_talloc(blobs, NULL, 4);
     350     2455493 :                 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
     351             : 
     352             :                 /* We've to use "strtoll" here to have the intended overflows.
     353             :                  * Otherwise we may get "LONG_MAX" and the conversion is wrong. */
     354     2455493 :                 v = (int32_t) strtoll((char *)in->values[i].data, NULL, 0);
     355             : 
     356     2455493 :                 SIVALS(blobs[i].data, 0, v);
     357             :         }
     358             : 
     359     2455479 :         return WERR_OK;
     360             : }
     361             : 
     362     1737575 : static WERROR dsdb_syntax_INT32_validate_ldb(const struct dsdb_syntax_ctx *ctx,
     363             :                                              const struct dsdb_attribute *attr,
     364             :                                              const struct ldb_message_element *in)
     365             : {
     366      233521 :         unsigned int i;
     367             : 
     368     1737575 :         if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     369           0 :                 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
     370             :         }
     371             : 
     372     3475122 :         for (i=0; i < in->num_values; i++) {
     373      233521 :                 long v;
     374      233521 :                 char buf[sizeof("-2147483648")];
     375     1737559 :                 char *end = NULL;
     376             : 
     377     1737559 :                 ZERO_STRUCT(buf);
     378     1737559 :                 if (in->values[i].length >= sizeof(buf)) {
     379           0 :                         return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     380             :                 }
     381             : 
     382     1737559 :                 memcpy(buf, in->values[i].data, in->values[i].length);
     383     1737559 :                 errno = 0;
     384     1737559 :                 v = strtol(buf, &end, 10);
     385     1737559 :                 if (errno != 0) {
     386           0 :                         return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     387             :                 }
     388     1737559 :                 if (end && end[0] != '\0') {
     389          12 :                         return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     390             :                 }
     391             : 
     392     1737547 :                 if (attr->rangeLower) {
     393      279874 :                         if ((int32_t)v < (int32_t)*attr->rangeLower) {
     394           0 :                                 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     395             :                         }
     396             :                 }
     397             : 
     398     1737547 :                 if (attr->rangeUpper) {
     399       95348 :                         if ((int32_t)v > (int32_t)*attr->rangeUpper) {
     400           0 :                                 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     401             :                         }
     402             :                 }
     403             :         }
     404             : 
     405     1737563 :         return WERR_OK;
     406             : }
     407             : 
     408     1113661 : static WERROR dsdb_syntax_INT64_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
     409             :                                                const struct dsdb_attribute *attr,
     410             :                                                const struct drsuapi_DsReplicaAttribute *in,
     411             :                                                TALLOC_CTX *mem_ctx,
     412             :                                                struct ldb_message_element *out)
     413             : {
     414      145450 :         unsigned int i;
     415             : 
     416     1113661 :         out->flags   = 0;
     417     1113661 :         out->name    = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
     418     1113661 :         W_ERROR_HAVE_NO_MEMORY(out->name);
     419             : 
     420     1113661 :         out->num_values      = in->value_ctr.num_values;
     421     1113661 :         out->values  = talloc_array(mem_ctx, struct ldb_val, out->num_values);
     422     1113661 :         W_ERROR_HAVE_NO_MEMORY(out->values);
     423             : 
     424     2136106 :         for (i=0; i < out->num_values; i++) {
     425      145450 :                 int64_t v;
     426      145450 :                 char *str;
     427             : 
     428     1022445 :                 if (in->value_ctr.values[i].blob == NULL) {
     429           0 :                         return WERR_FOOBAR;
     430             :                 }
     431             : 
     432     1022445 :                 if (in->value_ctr.values[i].blob->length != 8) {
     433           0 :                         return WERR_FOOBAR;
     434             :                 }
     435             : 
     436     1022445 :                 v = BVALS(in->value_ctr.values[i].blob->data, 0);
     437             : 
     438     1022445 :                 str = talloc_asprintf(out->values, "%lld", (long long int)v);
     439     1022445 :                 W_ERROR_HAVE_NO_MEMORY(str);
     440             : 
     441     1022445 :                 out->values[i] = data_blob_string_const(str);
     442             :         }
     443             : 
     444     1113661 :         return WERR_OK;
     445             : }
     446             : 
     447     1025940 : static WERROR dsdb_syntax_INT64_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
     448             :                                                const struct dsdb_attribute *attr,
     449             :                                                const struct ldb_message_element *in,
     450             :                                                TALLOC_CTX *mem_ctx,
     451             :                                                struct drsuapi_DsReplicaAttribute *out)
     452             : {
     453      145450 :         unsigned int i;
     454      145450 :         DATA_BLOB *blobs;
     455             : 
     456     1025940 :         if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     457           0 :                 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
     458             :         }
     459             : 
     460     2051880 :         out->attid                   = dsdb_attribute_get_attid(attr,
     461     1025940 :                                                                    ctx->is_schema_nc);
     462     1025940 :         out->value_ctr.num_values    = in->num_values;
     463     1025940 :         out->value_ctr.values                = talloc_array(mem_ctx,
     464             :                                                        struct drsuapi_DsAttributeValue,
     465             :                                                        in->num_values);
     466     1025940 :         W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
     467             : 
     468     1025940 :         blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
     469     1025940 :         W_ERROR_HAVE_NO_MEMORY(blobs);
     470             : 
     471     2051880 :         for (i=0; i < in->num_values; i++) {
     472      145450 :                 int64_t v;
     473             : 
     474     1025940 :                 out->value_ctr.values[i].blob        = &blobs[i];
     475             : 
     476     1025940 :                 blobs[i] = data_blob_talloc(blobs, NULL, 8);
     477     1025940 :                 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
     478             : 
     479     1025940 :                 v = strtoll((const char *)in->values[i].data, NULL, 10);
     480             : 
     481     1025940 :                 SBVALS(blobs[i].data, 0, v);
     482             :         }
     483             : 
     484     1025940 :         return WERR_OK;
     485             : }
     486             : 
     487      214475 : static WERROR dsdb_syntax_INT64_validate_ldb(const struct dsdb_syntax_ctx *ctx,
     488             :                                              const struct dsdb_attribute *attr,
     489             :                                              const struct ldb_message_element *in)
     490             : {
     491        3160 :         unsigned int i;
     492             : 
     493      214475 :         if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     494           0 :                 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
     495             :         }
     496             : 
     497      428926 :         for (i=0; i < in->num_values; i++) {
     498        3160 :                 long long v;
     499        3160 :                 char buf[sizeof("-9223372036854775808")];
     500      214451 :                 char *end = NULL;
     501             : 
     502      214451 :                 ZERO_STRUCT(buf);
     503      214451 :                 if (in->values[i].length >= sizeof(buf)) {
     504           0 :                         return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     505             :                 }
     506      214451 :                 memcpy(buf, in->values[i].data, in->values[i].length);
     507             : 
     508      214451 :                 errno = 0;
     509      214451 :                 v = strtoll(buf, &end, 10);
     510      214451 :                 if (errno != 0) {
     511           0 :                         return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     512             :                 }
     513      214451 :                 if (end && end[0] != '\0') {
     514           0 :                         return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     515             :                 }
     516             : 
     517      214451 :                 if (attr->rangeLower) {
     518           0 :                         if ((int64_t)v < (int64_t)*attr->rangeLower) {
     519           0 :                                 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     520             :                         }
     521             :                 }
     522             : 
     523      214451 :                 if (attr->rangeUpper) {
     524         161 :                         if ((int64_t)v > (int64_t)*attr->rangeUpper) {
     525           0 :                                 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     526             :                         }
     527             :                 }
     528             :         }
     529             : 
     530      214475 :         return WERR_OK;
     531             : }
     532           0 : static WERROR dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
     533             :                                                     const struct dsdb_attribute *attr,
     534             :                                                     const struct drsuapi_DsReplicaAttribute *in,
     535             :                                                     TALLOC_CTX *mem_ctx,
     536             :                                                     struct ldb_message_element *out)
     537             : {
     538           0 :         unsigned int i;
     539             : 
     540           0 :         out->flags   = 0;
     541           0 :         out->name    = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
     542           0 :         W_ERROR_HAVE_NO_MEMORY(out->name);
     543             : 
     544           0 :         out->num_values      = in->value_ctr.num_values;
     545           0 :         out->values  = talloc_array(mem_ctx, struct ldb_val, out->num_values);
     546           0 :         W_ERROR_HAVE_NO_MEMORY(out->values);
     547             : 
     548           0 :         for (i=0; i < out->num_values; i++) {
     549           0 :                 NTTIME v;
     550           0 :                 time_t t;
     551           0 :                 char *str;
     552             : 
     553           0 :                 if (in->value_ctr.values[i].blob == NULL) {
     554           0 :                         return WERR_FOOBAR;
     555             :                 }
     556             : 
     557           0 :                 if (in->value_ctr.values[i].blob->length != 8) {
     558           0 :                         return WERR_FOOBAR;
     559             :                 }
     560             : 
     561           0 :                 v = BVAL(in->value_ctr.values[i].blob->data, 0);
     562           0 :                 if (v == 0) {
     563             :                         /* special case for 1601 zero timestamp */
     564           0 :                         out->values[i] = data_blob_string_const("16010101000000.0Z");
     565           0 :                         continue;
     566             :                 }
     567           0 :                 v *= 10000000;
     568           0 :                 t = nt_time_to_unix(v);
     569             : 
     570             :                 /*
     571             :                  * NOTE: On a w2k3 server you can set a GeneralizedTime string
     572             :                  *       via LDAP, but you get back an UTCTime string,
     573             :                  *       but via DRSUAPI you get back the NTTIME_1sec value
     574             :                  *       that represents the GeneralizedTime value!
     575             :                  *
     576             :                  *       So if we store the UTCTime string in our ldb
     577             :                  *       we'll loose information!
     578             :                  */
     579           0 :                 str = ldb_timestring_utc(out->values, t);
     580           0 :                 W_ERROR_HAVE_NO_MEMORY(str);
     581           0 :                 out->values[i] = data_blob_string_const(str);
     582             :         }
     583             : 
     584           0 :         return WERR_OK;
     585             : }
     586             : 
     587           0 : static WERROR dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
     588             :                                                     const struct dsdb_attribute *attr,
     589             :                                                     const struct ldb_message_element *in,
     590             :                                                     TALLOC_CTX *mem_ctx,
     591             :                                                     struct drsuapi_DsReplicaAttribute *out)
     592             : {
     593           0 :         unsigned int i;
     594           0 :         DATA_BLOB *blobs;
     595             : 
     596           0 :         if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     597           0 :                 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
     598             :         }
     599             : 
     600           0 :         out->attid                   = dsdb_attribute_get_attid(attr,
     601           0 :                                                                    ctx->is_schema_nc);
     602           0 :         out->value_ctr.num_values    = in->num_values;
     603           0 :         out->value_ctr.values                = talloc_array(mem_ctx,
     604             :                                                        struct drsuapi_DsAttributeValue,
     605             :                                                        in->num_values);
     606           0 :         W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
     607             : 
     608           0 :         blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
     609           0 :         W_ERROR_HAVE_NO_MEMORY(blobs);
     610             : 
     611           0 :         for (i=0; i < in->num_values; i++) {
     612           0 :                 NTTIME v;
     613           0 :                 time_t t;
     614             : 
     615           0 :                 out->value_ctr.values[i].blob        = &blobs[i];
     616             : 
     617           0 :                 blobs[i] = data_blob_talloc(blobs, NULL, 8);
     618           0 :                 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
     619             : 
     620           0 :                 if (ldb_val_string_cmp(&in->values[i], "16010101000000.0Z") == 0) {
     621           0 :                         SBVALS(blobs[i].data, 0, 0);
     622           0 :                         continue;
     623             :                 }
     624             : 
     625           0 :                 t = ldb_string_utc_to_time((const char *)in->values[i].data);
     626           0 :                 unix_to_nt_time(&v, t);
     627           0 :                 v /= 10000000;
     628             : 
     629           0 :                 SBVAL(blobs[i].data, 0, v);
     630             :         }
     631             : 
     632           0 :         return WERR_OK;
     633             : }
     634             : 
     635           0 : static WERROR dsdb_syntax_NTTIME_UTC_validate_ldb(const struct dsdb_syntax_ctx *ctx,
     636             :                                                   const struct dsdb_attribute *attr,
     637             :                                                   const struct ldb_message_element *in)
     638             : {
     639           0 :         unsigned int i;
     640             : 
     641           0 :         if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     642           0 :                 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
     643             :         }
     644             : 
     645           0 :         for (i=0; i < in->num_values; i++) {
     646           0 :                 time_t t;
     647           0 :                 char buf[sizeof("090826075717Z")];
     648             : 
     649           0 :                 ZERO_STRUCT(buf);
     650           0 :                 if (in->values[i].length >= sizeof(buf)) {
     651           0 :                         return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     652             :                 }
     653           0 :                 memcpy(buf, in->values[i].data, in->values[i].length);
     654             : 
     655           0 :                 t = ldb_string_utc_to_time(buf);
     656           0 :                 if (t == 0) {
     657           0 :                         return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     658             :                 }
     659             : 
     660           0 :                 if (attr->rangeLower) {
     661           0 :                         if ((int32_t)t < (int32_t)*attr->rangeLower) {
     662           0 :                                 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     663             :                         }
     664             :                 }
     665             : 
     666           0 :                 if (attr->rangeUpper) {
     667           0 :                         if ((int32_t)t > (int32_t)*attr->rangeUpper) {
     668           0 :                                 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     669             :                         }
     670             :                 }
     671             : 
     672             :                 /*
     673             :                  * TODO: verify the comment in the
     674             :                  * dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb() function!
     675             :                  */
     676             :         }
     677             : 
     678           0 :         return WERR_OK;
     679             : }
     680             : 
     681     1628909 : static WERROR dsdb_syntax_NTTIME_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
     682             :                                                 const struct dsdb_attribute *attr,
     683             :                                                 const struct drsuapi_DsReplicaAttribute *in,
     684             :                                                 TALLOC_CTX *mem_ctx,
     685             :                                                 struct ldb_message_element *out)
     686             : {
     687      144341 :         unsigned int i;
     688             : 
     689     1628909 :         out->flags   = 0;
     690     1628909 :         out->name    = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
     691     1628909 :         W_ERROR_HAVE_NO_MEMORY(out->name);
     692             : 
     693     1628909 :         out->num_values      = in->value_ctr.num_values;
     694     1628909 :         out->values  = talloc_array(mem_ctx, struct ldb_val, out->num_values);
     695     1628909 :         W_ERROR_HAVE_NO_MEMORY(out->values);
     696             : 
     697     3253964 :         for (i=0; i < out->num_values; i++) {
     698      144341 :                 NTTIME v;
     699      144341 :                 time_t t;
     700      144341 :                 char *str;
     701             : 
     702     1625055 :                 if (in->value_ctr.values[i].blob == NULL) {
     703           0 :                         return WERR_FOOBAR;
     704             :                 }
     705             : 
     706     1625055 :                 if (in->value_ctr.values[i].blob->length != 8) {
     707           0 :                         return WERR_FOOBAR;
     708             :                 }
     709             : 
     710     1625055 :                 v = BVAL(in->value_ctr.values[i].blob->data, 0);
     711     1625055 :                 if (v == 0) {
     712             :                         /* special case for 1601 zero timestamp */
     713           0 :                         out->values[i] = data_blob_string_const("16010101000000.0Z");
     714           0 :                         continue;
     715             :                 }
     716     1625055 :                 v *= 10000000;
     717     1625055 :                 t = nt_time_to_unix(v);
     718             : 
     719     1625055 :                 str = ldb_timestring(out->values, t);
     720     1625055 :                 W_ERROR_HAVE_NO_MEMORY(str);
     721             : 
     722     1625055 :                 out->values[i] = data_blob_string_const(str);
     723             :         }
     724             : 
     725     1628909 :         return WERR_OK;
     726             : }
     727             : 
     728     1555179 : static WERROR dsdb_syntax_NTTIME_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
     729             :                                                 const struct dsdb_attribute *attr,
     730             :                                                 const struct ldb_message_element *in,
     731             :                                                 TALLOC_CTX *mem_ctx,
     732             :                                                 struct drsuapi_DsReplicaAttribute *out)
     733             : {
     734      144341 :         unsigned int i;
     735      144341 :         DATA_BLOB *blobs;
     736             : 
     737     1555179 :         if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     738           0 :                 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
     739             :         }
     740             : 
     741     3110358 :         out->attid                   = dsdb_attribute_get_attid(attr,
     742     1555179 :                                                                    ctx->is_schema_nc);
     743     1555179 :         out->value_ctr.num_values    = in->num_values;
     744     1555179 :         out->value_ctr.values                = talloc_array(mem_ctx,
     745             :                                                        struct drsuapi_DsAttributeValue,
     746             :                                                        in->num_values);
     747     1555179 :         W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
     748             : 
     749     1555179 :         blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
     750     1555179 :         W_ERROR_HAVE_NO_MEMORY(blobs);
     751             : 
     752     3110358 :         for (i=0; i < in->num_values; i++) {
     753      144341 :                 NTTIME v;
     754      144341 :                 time_t t;
     755      144341 :                 int ret;
     756             : 
     757     1555179 :                 out->value_ctr.values[i].blob        = &blobs[i];
     758             : 
     759     1555179 :                 blobs[i] = data_blob_talloc(blobs, NULL, 8);
     760     1555179 :                 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
     761             : 
     762     1555179 :                 if (ldb_val_string_cmp(&in->values[i], "16010101000000.0Z") == 0) {
     763           0 :                         SBVALS(blobs[i].data, 0, 0);
     764           0 :                         continue;
     765             :                 }
     766             : 
     767     1555179 :                 ret = ldb_val_to_time(&in->values[i], &t);
     768     1555179 :                 if (ret != LDB_SUCCESS) {
     769           0 :                         return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     770             :                 }
     771     1555179 :                 unix_to_nt_time(&v, t);
     772     1555179 :                 v /= 10000000;
     773             : 
     774     1555179 :                 SBVAL(blobs[i].data, 0, v);
     775             :         }
     776             : 
     777     1555179 :         return WERR_OK;
     778             : }
     779             : 
     780        2229 : static WERROR dsdb_syntax_NTTIME_validate_ldb(const struct dsdb_syntax_ctx *ctx,
     781             :                                               const struct dsdb_attribute *attr,
     782             :                                               const struct ldb_message_element *in)
     783             : {
     784           1 :         unsigned int i;
     785             : 
     786        2229 :         if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     787           0 :                 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
     788             :         }
     789             : 
     790        4458 :         for (i=0; i < in->num_values; i++) {
     791           1 :                 time_t t;
     792           1 :                 int ret;
     793             : 
     794        2229 :                 ret = ldb_val_to_time(&in->values[i], &t);
     795        2229 :                 if (ret != LDB_SUCCESS) {
     796           0 :                         return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     797             :                 }
     798             : 
     799        2229 :                 if (attr->rangeLower) {
     800           0 :                         if ((int32_t)t < (int32_t)*attr->rangeLower) {
     801           0 :                                 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     802             :                         }
     803             :                 }
     804             : 
     805        2229 :                 if (attr->rangeUpper) {
     806           0 :                         if ((int32_t)t > (int32_t)*attr->rangeUpper) {
     807           0 :                                 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     808             :                         }
     809             :                 }
     810             :         }
     811             : 
     812        2229 :         return WERR_OK;
     813             : }
     814             : 
     815     2835066 : static WERROR dsdb_syntax_DATA_BLOB_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
     816             :                                                    const struct dsdb_attribute *attr,
     817             :                                                    const struct drsuapi_DsReplicaAttribute *in,
     818             :                                                    TALLOC_CTX *mem_ctx,
     819             :                                                    struct ldb_message_element *out)
     820             : {
     821      166648 :         unsigned int i;
     822             : 
     823     2835066 :         out->flags   = 0;
     824     2835066 :         out->name    = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
     825     2835066 :         W_ERROR_HAVE_NO_MEMORY(out->name);
     826             : 
     827     2835066 :         out->num_values      = in->value_ctr.num_values;
     828     2835066 :         out->values  = talloc_array(mem_ctx, struct ldb_val, out->num_values);
     829     2835066 :         W_ERROR_HAVE_NO_MEMORY(out->values);
     830             : 
     831     5432844 :         for (i=0; i < out->num_values; i++) {
     832     2597778 :                 if (in->value_ctr.values[i].blob == NULL) {
     833           0 :                         return WERR_FOOBAR;
     834             :                 }
     835             : 
     836     2597778 :                 if (in->value_ctr.values[i].blob->length == 0) {
     837           0 :                         return WERR_FOOBAR;
     838             :                 }
     839             : 
     840     2597778 :                 out->values[i] = data_blob_dup_talloc(out->values,
     841             :                                                       *in->value_ctr.values[i].blob);
     842     2597778 :                 W_ERROR_HAVE_NO_MEMORY(out->values[i].data);
     843             :         }
     844             : 
     845     2835066 :         return WERR_OK;
     846             : }
     847             : 
     848     2384705 : static WERROR dsdb_syntax_DATA_BLOB_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
     849             :                                                    const struct dsdb_attribute *attr,
     850             :                                                    const struct ldb_message_element *in,
     851             :                                                    TALLOC_CTX *mem_ctx,
     852             :                                                    struct drsuapi_DsReplicaAttribute *out)
     853             : {
     854      166648 :         unsigned int i;
     855      166648 :         DATA_BLOB *blobs;
     856             : 
     857     2384705 :         if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     858           0 :                 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
     859             :         }
     860             : 
     861     4769410 :         out->attid                   = dsdb_attribute_get_attid(attr,
     862     2384705 :                                                                    ctx->is_schema_nc);
     863     2384705 :         out->value_ctr.num_values    = in->num_values;
     864     2384705 :         out->value_ctr.values                = talloc_array(mem_ctx,
     865             :                                                        struct drsuapi_DsAttributeValue,
     866             :                                                        in->num_values);
     867     2384705 :         W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
     868             : 
     869     2384705 :         blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
     870     2384705 :         W_ERROR_HAVE_NO_MEMORY(blobs);
     871             : 
     872     4774260 :         for (i=0; i < in->num_values; i++) {
     873     2389555 :                 out->value_ctr.values[i].blob        = &blobs[i];
     874             : 
     875     2389555 :                 blobs[i] = data_blob_dup_talloc(blobs, in->values[i]);
     876     2389555 :                 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
     877             :         }
     878             : 
     879     2384705 :         return WERR_OK;
     880             : }
     881             : 
     882     1300179 : static WERROR dsdb_syntax_DATA_BLOB_validate_one_val(const struct dsdb_syntax_ctx *ctx,
     883             :                                                      const struct dsdb_attribute *attr,
     884             :                                                      const struct ldb_val *val)
     885             : {
     886     1300179 :         if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     887           0 :                 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
     888             :         }
     889             : 
     890     1113685 :         if (attr->rangeLower) {
     891     1081249 :                 if ((uint32_t)val->length < (uint32_t)*attr->rangeLower) {
     892           0 :                         return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     893             :                 }
     894             :         }
     895             : 
     896     1300179 :         if (attr->rangeUpper) {
     897     1083604 :                 if ((uint32_t)val->length > (uint32_t)*attr->rangeUpper) {
     898           0 :                         return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     899             :                 }
     900             :         }
     901             : 
     902     1300179 :         return WERR_OK;
     903             : }
     904             : 
     905     1415174 : static WERROR dsdb_syntax_DATA_BLOB_validate_ldb(const struct dsdb_syntax_ctx *ctx,
     906             :                                                  const struct dsdb_attribute *attr,
     907             :                                                  const struct ldb_message_element *in)
     908             : {
     909      186712 :         unsigned int i;
     910      186712 :         WERROR status;
     911             : 
     912     1415174 :         if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     913           0 :                 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
     914             :         }
     915             : 
     916     2695895 :         for (i=0; i < in->num_values; i++) {
     917     1280721 :                 if (in->values[i].length == 0) {
     918           0 :                         return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     919             :                 }
     920             : 
     921     1467215 :                 status = dsdb_syntax_DATA_BLOB_validate_one_val(ctx,
     922             :                                                                 attr,
     923     1280721 :                                                                 &in->values[i]);
     924     1280721 :                 if (!W_ERROR_IS_OK(status)) {
     925           0 :                         return status;
     926             :                 }
     927             :         }
     928             : 
     929     1415174 :         return WERR_OK;
     930             : }
     931             : 
     932           0 : static WERROR _dsdb_syntax_auto_OID_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
     933             :                                                    const struct dsdb_attribute *attr,
     934             :                                                    const struct drsuapi_DsReplicaAttribute *in,
     935             :                                                    TALLOC_CTX *mem_ctx,
     936             :                                                    struct ldb_message_element *out)
     937             : {
     938           0 :         unsigned int i;
     939             : 
     940           0 :         out->flags   = 0;
     941           0 :         out->name    = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
     942           0 :         W_ERROR_HAVE_NO_MEMORY(out->name);
     943             : 
     944           0 :         out->num_values      = in->value_ctr.num_values;
     945           0 :         out->values  = talloc_array(mem_ctx, struct ldb_val, out->num_values);
     946           0 :         W_ERROR_HAVE_NO_MEMORY(out->values);
     947             : 
     948           0 :         for (i=0; i < out->num_values; i++) {
     949           0 :                 uint32_t v;
     950           0 :                 const struct dsdb_class *c;
     951           0 :                 const struct dsdb_attribute *a;
     952           0 :                 const char *str = NULL;
     953             : 
     954           0 :                 if (in->value_ctr.values[i].blob == NULL) {
     955           0 :                         return WERR_FOOBAR;
     956             :                 }
     957             : 
     958           0 :                 if (in->value_ctr.values[i].blob->length != 4) {
     959           0 :                         return WERR_FOOBAR;
     960             :                 }
     961             : 
     962           0 :                 v = IVAL(in->value_ctr.values[i].blob->data, 0);
     963             : 
     964           0 :                 if ((c = dsdb_class_by_governsID_id(ctx->schema, v))) {
     965           0 :                         str = talloc_strdup(out->values, c->lDAPDisplayName);
     966           0 :                 } else if ((a = dsdb_attribute_by_attributeID_id(ctx->schema, v))) {
     967           0 :                         str = talloc_strdup(out->values, a->lDAPDisplayName);
     968             :                 } else {
     969           0 :                         WERROR werr;
     970           0 :                         SMB_ASSERT(ctx->pfm_remote);
     971           0 :                         werr = dsdb_schema_pfm_oid_from_attid(ctx->pfm_remote, v,
     972           0 :                                                               out->values, &str);
     973           0 :                         W_ERROR_NOT_OK_RETURN(werr);
     974             :                 }
     975           0 :                 W_ERROR_HAVE_NO_MEMORY(str);
     976             : 
     977             :                 /* the values need to be reversed */
     978           0 :                 out->values[out->num_values - (i + 1)] = data_blob_string_const(str);
     979             :         }
     980             : 
     981           0 :         return WERR_OK;
     982             : }
     983             : 
     984     1877474 : static WERROR _dsdb_syntax_OID_obj_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
     985             :                                                   const struct dsdb_attribute *attr,
     986             :                                                   const struct drsuapi_DsReplicaAttribute *in,
     987             :                                                   TALLOC_CTX *mem_ctx,
     988             :                                                   struct ldb_message_element *out)
     989             : {
     990      187641 :         unsigned int i;
     991             : 
     992     1877474 :         out->flags   = 0;
     993     1877474 :         out->name    = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
     994     1877474 :         W_ERROR_HAVE_NO_MEMORY(out->name);
     995             : 
     996     1877474 :         out->num_values      = in->value_ctr.num_values;
     997     1877474 :         out->values  = talloc_array(mem_ctx, struct ldb_val, out->num_values);
     998     1877474 :         W_ERROR_HAVE_NO_MEMORY(out->values);
     999             : 
    1000     5718357 :         for (i=0; i < out->num_values; i++) {
    1001      357113 :                 uint32_t v, vo;
    1002      357113 :                 const struct dsdb_class *c;
    1003      357113 :                 const char *str;
    1004             : 
    1005     3840953 :                 if (in->value_ctr.values[i].blob == NULL) {
    1006           0 :                         return WERR_FOOBAR;
    1007             :                 }
    1008             : 
    1009     3840953 :                 if (in->value_ctr.values[i].blob->length != 4) {
    1010           0 :                         return WERR_FOOBAR;
    1011             :                 }
    1012             : 
    1013     3840953 :                 v = IVAL(in->value_ctr.values[i].blob->data, 0);
    1014     3840953 :                 vo = v;
    1015             : 
    1016             :                 /* convert remote ATTID to local ATTID */
    1017     3840953 :                 if (!dsdb_syntax_attid_from_remote_attid(ctx, mem_ctx, v, &v)) {
    1018           0 :                         DEBUG(1,(__location__ ": Failed to map remote ATTID to local ATTID!\n"));
    1019           0 :                         return WERR_FOOBAR;
    1020             :                 }
    1021             : 
    1022     3840953 :                 c = dsdb_class_by_governsID_id(ctx->schema, v);
    1023     3840953 :                 if (!c) {
    1024          70 :                         int dbg_level = ctx->schema->resolving_in_progress ? 10 : 0;
    1025          70 :                         DEBUG(dbg_level,(__location__ ": %s unknown local governsID 0x%08X remote 0x%08X%s\n",
    1026             :                               attr->lDAPDisplayName, v, vo,
    1027             :                               ctx->schema->resolving_in_progress ? "resolving in progress" : ""));
    1028          70 :                         return WERR_DS_OBJ_CLASS_NOT_DEFINED;
    1029             :                 }
    1030             : 
    1031     3840883 :                 str = talloc_strdup(out->values, c->lDAPDisplayName);
    1032     3840883 :                 W_ERROR_HAVE_NO_MEMORY(str);
    1033             : 
    1034             :                 /* the values need to be reversed */
    1035     3840883 :                 out->values[out->num_values - (i + 1)] = data_blob_string_const(str);
    1036             :         }
    1037             : 
    1038     1877404 :         return WERR_OK;
    1039             : }
    1040             : 
    1041      429128 : static WERROR _dsdb_syntax_OID_attr_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
    1042             :                                                    const struct dsdb_attribute *attr,
    1043             :                                                    const struct drsuapi_DsReplicaAttribute *in,
    1044             :                                                    TALLOC_CTX *mem_ctx,
    1045             :                                                    struct ldb_message_element *out)
    1046             : {
    1047       61440 :         unsigned int i;
    1048             : 
    1049      429128 :         out->flags   = 0;
    1050      429128 :         out->name    = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
    1051      429128 :         W_ERROR_HAVE_NO_MEMORY(out->name);
    1052             : 
    1053      429128 :         out->num_values      = in->value_ctr.num_values;
    1054      429128 :         out->values  = talloc_array(mem_ctx, struct ldb_val, out->num_values);
    1055      429128 :         W_ERROR_HAVE_NO_MEMORY(out->values);
    1056             : 
    1057     1363572 :         for (i=0; i < out->num_values; i++) {
    1058      103526 :                 uint32_t v, vo;
    1059      103526 :                 const struct dsdb_attribute *a;
    1060      103526 :                 const char *str;
    1061             : 
    1062      935046 :                 if (in->value_ctr.values[i].blob == NULL) {
    1063           0 :                         DEBUG(0, ("Attribute has no value\n"));
    1064           0 :                         return WERR_FOOBAR;
    1065             :                 }
    1066             : 
    1067      935046 :                 if (in->value_ctr.values[i].blob->length != 4) {
    1068           0 :                         DEBUG(0, ("Attribute has a value with 0 length\n"));
    1069           0 :                         return WERR_FOOBAR;
    1070             :                 }
    1071             : 
    1072      935046 :                 v = IVAL(in->value_ctr.values[i].blob->data, 0);
    1073      935046 :                 vo = v;
    1074             : 
    1075             :                 /* convert remote ATTID to local ATTID */
    1076      935046 :                 if (!dsdb_syntax_attid_from_remote_attid(ctx, mem_ctx, v, &v)) {
    1077           0 :                         DEBUG(1,(__location__ ": Failed to map remote ATTID to local ATTID!\n"));
    1078           0 :                         return WERR_FOOBAR;
    1079             :                 }
    1080             : 
    1081      935046 :                 a = dsdb_attribute_by_attributeID_id(ctx->schema, v);
    1082      935046 :                 if (!a) {
    1083         602 :                         int dbg_level = ctx->schema->resolving_in_progress ? 10 : 0;
    1084         602 :                         DEBUG(dbg_level,(__location__ ": %s unknown local attributeID_id 0x%08X remote 0x%08X%s\n",
    1085             :                               attr->lDAPDisplayName, v, vo,
    1086             :                               ctx->schema->resolving_in_progress ? "resolving in progress" : ""));
    1087         602 :                         return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
    1088             :                 }
    1089             : 
    1090      934444 :                 str = talloc_strdup(out->values, a->lDAPDisplayName);
    1091      934444 :                 W_ERROR_HAVE_NO_MEMORY(str);
    1092             : 
    1093             :                 /* the values need to be reversed */
    1094      934444 :                 out->values[out->num_values - (i + 1)] = data_blob_string_const(str);
    1095             :         }
    1096             : 
    1097      428526 :         return WERR_OK;
    1098             : }
    1099             : 
    1100     1044263 : static WERROR _dsdb_syntax_OID_oid_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
    1101             :                                                   const struct dsdb_attribute *attr,
    1102             :                                                   const struct drsuapi_DsReplicaAttribute *in,
    1103             :                                                   TALLOC_CTX *mem_ctx,
    1104             :                                                   struct ldb_message_element *out)
    1105             : {
    1106       99403 :         unsigned int i;
    1107       99403 :         const struct dsdb_schema_prefixmap *prefixmap;
    1108             : 
    1109     1044263 :         if (ctx->pfm_remote != NULL) {
    1110      492795 :                 prefixmap = ctx->pfm_remote;
    1111             :         } else {
    1112      551468 :                 prefixmap = ctx->schema->prefixmap;
    1113             :         }
    1114     1044263 :         SMB_ASSERT(prefixmap);
    1115             : 
    1116     1044263 :         out->flags   = 0;
    1117     1044263 :         out->name    = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
    1118     1044263 :         W_ERROR_HAVE_NO_MEMORY(out->name);
    1119             : 
    1120     1044263 :         out->num_values      = in->value_ctr.num_values;
    1121     1044263 :         out->values  = talloc_array(mem_ctx, struct ldb_val, out->num_values);
    1122     1044263 :         W_ERROR_HAVE_NO_MEMORY(out->values);
    1123             : 
    1124     2088526 :         for (i=0; i < out->num_values; i++) {
    1125       99403 :                 uint32_t attid;
    1126       99403 :                 WERROR status;
    1127       99403 :                 const char *oid;
    1128             : 
    1129     1044263 :                 if (in->value_ctr.values[i].blob == NULL) {
    1130           0 :                         return WERR_FOOBAR;
    1131             :                 }
    1132             : 
    1133     1044263 :                 if (in->value_ctr.values[i].blob->length != 4) {
    1134           0 :                         return WERR_FOOBAR;
    1135             :                 }
    1136             : 
    1137     1044263 :                 attid = IVAL(in->value_ctr.values[i].blob->data, 0);
    1138             : 
    1139     1044263 :                 status = dsdb_schema_pfm_oid_from_attid(prefixmap, attid,
    1140     1044263 :                                                         out->values, &oid);
    1141     1044263 :                 if (!W_ERROR_IS_OK(status)) {
    1142           0 :                         DEBUG(0,(__location__ ": Error: Unknown ATTID 0x%08X\n",
    1143             :                                  attid));
    1144           0 :                         return status;
    1145             :                 }
    1146             : 
    1147     1044263 :                 out->values[i] = data_blob_string_const(oid);
    1148             :         }
    1149             : 
    1150     1044263 :         return WERR_OK;
    1151             : }
    1152             : 
    1153           0 : static WERROR _dsdb_syntax_auto_OID_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
    1154             :                                                    const struct dsdb_attribute *attr,
    1155             :                                                    const struct ldb_message_element *in,
    1156             :                                                    TALLOC_CTX *mem_ctx,
    1157             :                                                    struct drsuapi_DsReplicaAttribute *out)
    1158             : {
    1159           0 :         unsigned int i;
    1160           0 :         DATA_BLOB *blobs;
    1161             : 
    1162           0 :         out->attid= dsdb_attribute_get_attid(attr,
    1163           0 :                                              ctx->is_schema_nc);
    1164           0 :         out->value_ctr.num_values= in->num_values;
    1165           0 :         out->value_ctr.values= talloc_array(mem_ctx,
    1166             :                                             struct drsuapi_DsAttributeValue,
    1167             :                                             in->num_values);
    1168           0 :         W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
    1169             : 
    1170           0 :         blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
    1171           0 :         W_ERROR_HAVE_NO_MEMORY(blobs);
    1172             : 
    1173           0 :         for (i=0; i < in->num_values; i++) {
    1174           0 :                 const struct dsdb_class *obj_class;
    1175           0 :                 const struct dsdb_attribute *obj_attr;
    1176           0 :                 struct ldb_val *v;
    1177             : 
    1178           0 :                 out->value_ctr.values[i].blob= &blobs[i];
    1179             : 
    1180           0 :                 blobs[i] = data_blob_talloc(blobs, NULL, 4);
    1181           0 :                 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
    1182             : 
    1183             :                 /* in DRS windows puts the classes in the opposite
    1184             :                    order to the order used in ldap */
    1185           0 :                 v = &in->values[(in->num_values-1)-i];
    1186             : 
    1187           0 :                 if ((obj_class = dsdb_class_by_lDAPDisplayName_ldb_val(ctx->schema, v))) {
    1188           0 :                         SIVAL(blobs[i].data, 0, obj_class->governsID_id);
    1189           0 :                 } else if ((obj_attr = dsdb_attribute_by_lDAPDisplayName_ldb_val(ctx->schema, v))) {
    1190           0 :                         SIVAL(blobs[i].data, 0, obj_attr->attributeID_id);
    1191             :                 } else {
    1192           0 :                         uint32_t attid;
    1193           0 :                         WERROR werr;
    1194           0 :                         werr = dsdb_schema_pfm_attid_from_oid(ctx->schema->prefixmap,
    1195           0 :                                                               (const char *)v->data,
    1196             :                                                               &attid);
    1197           0 :                         W_ERROR_NOT_OK_RETURN(werr);
    1198           0 :                         SIVAL(blobs[i].data, 0, attid);
    1199             :                 }
    1200             : 
    1201             :         }
    1202             : 
    1203             : 
    1204           0 :         return WERR_OK;
    1205             : }
    1206             : 
    1207     1787166 : static WERROR _dsdb_syntax_OID_obj_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
    1208             :                                                   const struct dsdb_attribute *attr,
    1209             :                                                   const struct ldb_message_element *in,
    1210             :                                                   TALLOC_CTX *mem_ctx,
    1211             :                                                   struct drsuapi_DsReplicaAttribute *out)
    1212             : {
    1213      187641 :         unsigned int i;
    1214      187641 :         DATA_BLOB *blobs;
    1215             : 
    1216     3574332 :         out->attid= dsdb_attribute_get_attid(attr,
    1217     1787166 :                                              ctx->is_schema_nc);
    1218     1787166 :         out->value_ctr.num_values= in->num_values;
    1219     1787166 :         out->value_ctr.values= talloc_array(mem_ctx,
    1220             :                                             struct drsuapi_DsAttributeValue,
    1221             :                                             in->num_values);
    1222     1787166 :         W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
    1223             : 
    1224     1787166 :         blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
    1225     1787166 :         W_ERROR_HAVE_NO_MEMORY(blobs);
    1226             : 
    1227     5475103 :         for (i=0; i < in->num_values; i++) {
    1228      357113 :                 const struct dsdb_class *obj_class;
    1229             : 
    1230     3687961 :                 out->value_ctr.values[i].blob= &blobs[i];
    1231             : 
    1232     3687961 :                 blobs[i] = data_blob_talloc(blobs, NULL, 4);
    1233     3687961 :                 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
    1234             : 
    1235             :                 /* in DRS windows puts the classes in the opposite
    1236             :                    order to the order used in ldap */
    1237     4045074 :                 obj_class = dsdb_class_by_lDAPDisplayName(ctx->schema,
    1238     3687961 :                                                           (const char *)in->values[(in->num_values-1)-i].data);
    1239     3687961 :                 if (!obj_class) {
    1240          24 :                         return WERR_FOOBAR;
    1241             :                 }
    1242     3687937 :                 SIVAL(blobs[i].data, 0, obj_class->governsID_id);
    1243             :         }
    1244             : 
    1245             : 
    1246     1787142 :         return WERR_OK;
    1247             : }
    1248             : 
    1249      389007 : static WERROR _dsdb_syntax_OID_attr_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
    1250             :                                                    const struct dsdb_attribute *attr,
    1251             :                                                    const struct ldb_message_element *in,
    1252             :                                                    TALLOC_CTX *mem_ctx,
    1253             :                                                    struct drsuapi_DsReplicaAttribute *out)
    1254             : {
    1255       61440 :         unsigned int i;
    1256       61440 :         DATA_BLOB *blobs;
    1257             : 
    1258      778014 :         out->attid= dsdb_attribute_get_attid(attr,
    1259      389007 :                                              ctx->is_schema_nc);
    1260      389007 :         out->value_ctr.num_values= in->num_values;
    1261      389007 :         out->value_ctr.values= talloc_array(mem_ctx,
    1262             :                                             struct drsuapi_DsAttributeValue,
    1263             :                                             in->num_values);
    1264      389007 :         W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
    1265             : 
    1266      389007 :         blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
    1267      389007 :         W_ERROR_HAVE_NO_MEMORY(blobs);
    1268             : 
    1269     1167731 :         for (i=0; i < in->num_values; i++) {
    1270      103526 :                 const struct dsdb_attribute *obj_attr;
    1271             : 
    1272      778757 :                 out->value_ctr.values[i].blob= &blobs[i];
    1273             : 
    1274      778757 :                 blobs[i] = data_blob_talloc(blobs, NULL, 4);
    1275      778757 :                 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
    1276             : 
    1277      778757 :                 obj_attr = dsdb_attribute_by_lDAPDisplayName(ctx->schema, (const char *)in->values[i].data);
    1278      778757 :                 if (!obj_attr) {
    1279          33 :                         DEBUG(0, ("Unable to find attribute %s in the schema\n", (const char *)in->values[i].data));
    1280          33 :                         return WERR_FOOBAR;
    1281             :                 }
    1282      778724 :                 SIVAL(blobs[i].data, 0, obj_attr->attributeID_id);
    1283             :         }
    1284             : 
    1285             : 
    1286      388974 :         return WERR_OK;
    1287             : }
    1288             : 
    1289      812482 : static WERROR _dsdb_syntax_OID_oid_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
    1290             :                                                   const struct dsdb_attribute *attr,
    1291             :                                                   const struct ldb_message_element *in,
    1292             :                                                   TALLOC_CTX *mem_ctx,
    1293             :                                                   struct drsuapi_DsReplicaAttribute *out)
    1294             : {
    1295       99403 :         unsigned int i;
    1296       99403 :         DATA_BLOB *blobs;
    1297             : 
    1298     1624964 :         out->attid= dsdb_attribute_get_attid(attr,
    1299      812482 :                                              ctx->is_schema_nc);
    1300      812482 :         out->value_ctr.num_values= in->num_values;
    1301      812482 :         out->value_ctr.values= talloc_array(mem_ctx,
    1302             :                                             struct drsuapi_DsAttributeValue,
    1303             :                                             in->num_values);
    1304      812482 :         W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
    1305             : 
    1306      812482 :         blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
    1307      812482 :         W_ERROR_HAVE_NO_MEMORY(blobs);
    1308             : 
    1309     1624964 :         for (i=0; i < in->num_values; i++) {
    1310       99403 :                 uint32_t attid;
    1311       99403 :                 WERROR status;
    1312             : 
    1313      812482 :                 out->value_ctr.values[i].blob= &blobs[i];
    1314             : 
    1315      812482 :                 blobs[i] = data_blob_talloc(blobs, NULL, 4);
    1316      812482 :                 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
    1317             : 
    1318      812482 :                 status = dsdb_schema_pfm_attid_from_oid(ctx->schema->prefixmap,
    1319      812482 :                                                         (const char *)in->values[i].data,
    1320             :                                                         &attid);
    1321      812482 :                 W_ERROR_NOT_OK_RETURN(status);
    1322             : 
    1323      812482 :                 SIVAL(blobs[i].data, 0, attid);
    1324             :         }
    1325             : 
    1326      812482 :         return WERR_OK;
    1327             : }
    1328             : 
    1329     3350865 : static WERROR dsdb_syntax_OID_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
    1330             :                                              const struct dsdb_attribute *attr,
    1331             :                                              const struct drsuapi_DsReplicaAttribute *in,
    1332             :                                              TALLOC_CTX *mem_ctx,
    1333             :                                              struct ldb_message_element *out)
    1334             : {
    1335      348484 :         WERROR werr;
    1336             : 
    1337     3350865 :         switch (attr->attributeID_id) {
    1338     1877474 :         case DRSUAPI_ATTID_objectClass:
    1339             :         case DRSUAPI_ATTID_subClassOf:
    1340             :         case DRSUAPI_ATTID_auxiliaryClass:
    1341             :         case DRSUAPI_ATTID_systemAuxiliaryClass:
    1342             :         case DRSUAPI_ATTID_systemPossSuperiors:
    1343             :         case DRSUAPI_ATTID_possSuperiors:
    1344     1877474 :                 werr = _dsdb_syntax_OID_obj_drsuapi_to_ldb(ctx, attr, in, mem_ctx, out);
    1345     1877474 :                 break;
    1346      429128 :         case DRSUAPI_ATTID_systemMustContain:
    1347             :         case DRSUAPI_ATTID_systemMayContain:
    1348             :         case DRSUAPI_ATTID_mustContain:
    1349             :         case DRSUAPI_ATTID_rDNAttId:
    1350             :         case DRSUAPI_ATTID_transportAddressAttribute:
    1351             :         case DRSUAPI_ATTID_mayContain:
    1352      429128 :                 werr = _dsdb_syntax_OID_attr_drsuapi_to_ldb(ctx, attr, in, mem_ctx, out);
    1353      429128 :                 break;
    1354     1044263 :         case DRSUAPI_ATTID_governsID:
    1355             :         case DRSUAPI_ATTID_attributeID:
    1356             :         case DRSUAPI_ATTID_attributeSyntax:
    1357     1044263 :                 werr = _dsdb_syntax_OID_oid_drsuapi_to_ldb(ctx, attr, in, mem_ctx, out);
    1358     1044263 :                 break;
    1359           0 :         default:
    1360           0 :                 DEBUG(0,(__location__ ": Unknown handling for attributeID_id for %s\n",
    1361             :                          attr->lDAPDisplayName));
    1362           0 :                 return _dsdb_syntax_auto_OID_drsuapi_to_ldb(ctx, attr, in, mem_ctx, out);
    1363             :         }
    1364             : 
    1365             :         /* When we are doing the vampire of a schema, we don't want
    1366             :          * the inability to reference an OID to get in the way.
    1367             :          * Otherwise, we won't get the new schema with which to
    1368             :          * understand this */
    1369     3350865 :         if (!W_ERROR_IS_OK(werr) && ctx->schema->relax_OID_conversions) {
    1370           0 :                 return _dsdb_syntax_OID_oid_drsuapi_to_ldb(ctx, attr, in, mem_ctx, out);
    1371             :         }
    1372     3350865 :         return werr;
    1373             : }
    1374             : 
    1375     2988655 : static WERROR dsdb_syntax_OID_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
    1376             :                                              const struct dsdb_attribute *attr,
    1377             :                                              const struct ldb_message_element *in,
    1378             :                                              TALLOC_CTX *mem_ctx,
    1379             :                                              struct drsuapi_DsReplicaAttribute *out)
    1380             : {
    1381     2988655 :         if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
    1382           0 :                 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
    1383             :         }
    1384             : 
    1385     2988655 :         switch (attr->attributeID_id) {
    1386     1787166 :         case DRSUAPI_ATTID_objectClass:
    1387             :         case DRSUAPI_ATTID_subClassOf:
    1388             :         case DRSUAPI_ATTID_auxiliaryClass:
    1389             :         case DRSUAPI_ATTID_systemAuxiliaryClass:
    1390             :         case DRSUAPI_ATTID_systemPossSuperiors:
    1391             :         case DRSUAPI_ATTID_possSuperiors:
    1392     1787166 :                 return _dsdb_syntax_OID_obj_ldb_to_drsuapi(ctx, attr, in, mem_ctx, out);
    1393      389007 :         case DRSUAPI_ATTID_systemMustContain:
    1394             :         case DRSUAPI_ATTID_systemMayContain:
    1395             :         case DRSUAPI_ATTID_mustContain:
    1396             :         case DRSUAPI_ATTID_rDNAttId:
    1397             :         case DRSUAPI_ATTID_transportAddressAttribute:
    1398             :         case DRSUAPI_ATTID_mayContain:
    1399      389007 :                 return _dsdb_syntax_OID_attr_ldb_to_drsuapi(ctx, attr, in, mem_ctx, out);
    1400      812482 :         case DRSUAPI_ATTID_governsID:
    1401             :         case DRSUAPI_ATTID_attributeID:
    1402             :         case DRSUAPI_ATTID_attributeSyntax:
    1403      812482 :                 return _dsdb_syntax_OID_oid_ldb_to_drsuapi(ctx, attr, in, mem_ctx, out);
    1404             :         }
    1405             : 
    1406           0 :         DEBUG(0,(__location__ ": Unknown handling for attributeID_id for %s\n",
    1407             :                  attr->lDAPDisplayName));
    1408             : 
    1409           0 :         return _dsdb_syntax_auto_OID_ldb_to_drsuapi(ctx, attr, in, mem_ctx, out);
    1410             : }
    1411             : 
    1412      402328 : static WERROR _dsdb_syntax_OID_validate_numericoid(const struct dsdb_syntax_ctx *ctx,
    1413             :                                                    const struct dsdb_attribute *attr,
    1414             :                                                    const struct ldb_message_element *in)
    1415             : {
    1416       71874 :         unsigned int i;
    1417       71874 :         TALLOC_CTX *tmp_ctx;
    1418             : 
    1419      402328 :         tmp_ctx = talloc_new(ctx->ldb);
    1420      402328 :         W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
    1421             : 
    1422      804656 :         for (i=0; i < in->num_values; i++) {
    1423       71874 :                 DATA_BLOB blob;
    1424       71874 :                 char *oid_out;
    1425      402328 :                 const char *oid = (const char*)in->values[i].data;
    1426             : 
    1427      402328 :                 if (in->values[i].length == 0) {
    1428           0 :                         talloc_free(tmp_ctx);
    1429           0 :                         return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
    1430             :                 }
    1431             : 
    1432      402328 :                 if (!ber_write_OID_String(tmp_ctx, &blob, oid)) {
    1433           0 :                         DEBUG(0,("ber_write_OID_String() failed for %s\n", oid));
    1434           0 :                         talloc_free(tmp_ctx);
    1435           0 :                         return WERR_INVALID_PARAMETER;
    1436             :                 }
    1437             : 
    1438      402328 :                 if (!ber_read_OID_String(tmp_ctx, blob, &oid_out)) {
    1439           0 :                         DEBUG(0,("ber_read_OID_String() failed for %s\n",
    1440             :                                  hex_encode_talloc(tmp_ctx, blob.data, blob.length)));
    1441           0 :                         talloc_free(tmp_ctx);
    1442           0 :                         return WERR_INVALID_PARAMETER;
    1443             :                 }
    1444             : 
    1445      402328 :                 if (strcmp(oid, oid_out) != 0) {
    1446           0 :                         talloc_free(tmp_ctx);
    1447           0 :                         return WERR_INVALID_PARAMETER;
    1448             :                 }
    1449             :         }
    1450             : 
    1451      402328 :         talloc_free(tmp_ctx);
    1452      402328 :         return WERR_OK;
    1453             : }
    1454             : 
    1455     1086702 : static WERROR dsdb_syntax_OID_validate_ldb(const struct dsdb_syntax_ctx *ctx,
    1456             :                                            const struct dsdb_attribute *attr,
    1457             :                                            const struct ldb_message_element *in)
    1458             : {
    1459      180505 :         WERROR status;
    1460      180505 :         struct drsuapi_DsReplicaAttribute drs_tmp;
    1461      180505 :         struct ldb_message_element ldb_tmp;
    1462      180505 :         TALLOC_CTX *tmp_ctx;
    1463             : 
    1464     1086702 :         if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
    1465           0 :                 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
    1466             :         }
    1467             : 
    1468     1086702 :         switch (attr->attributeID_id) {
    1469      402328 :         case DRSUAPI_ATTID_governsID:
    1470             :         case DRSUAPI_ATTID_attributeID:
    1471             :         case DRSUAPI_ATTID_attributeSyntax:
    1472      402328 :                 return _dsdb_syntax_OID_validate_numericoid(ctx, attr, in);
    1473             :         }
    1474             : 
    1475             :         /*
    1476             :          * TODO: optimize and verify this code
    1477             :          */
    1478             : 
    1479      684374 :         tmp_ctx = talloc_new(ctx->ldb);
    1480      684374 :         W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
    1481             : 
    1482      684374 :         status = dsdb_syntax_OID_ldb_to_drsuapi(ctx,
    1483             :                                                 attr,
    1484             :                                                 in,
    1485             :                                                 tmp_ctx,
    1486             :                                                 &drs_tmp);
    1487      684374 :         if (!W_ERROR_IS_OK(status)) {
    1488          57 :                 talloc_free(tmp_ctx);
    1489          57 :                 return status;
    1490             :         }
    1491             : 
    1492      684317 :         status = dsdb_syntax_OID_drsuapi_to_ldb(ctx,
    1493             :                                                 attr,
    1494             :                                                 &drs_tmp,
    1495             :                                                 tmp_ctx,
    1496             :                                                 &ldb_tmp);
    1497      684317 :         if (!W_ERROR_IS_OK(status)) {
    1498           0 :                 talloc_free(tmp_ctx);
    1499           0 :                 return status;
    1500             :         }
    1501             : 
    1502      684317 :         talloc_free(tmp_ctx);
    1503      684317 :         return WERR_OK;
    1504             : }
    1505             : 
    1506     5899826 : static WERROR dsdb_syntax_UNICODE_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
    1507             :                                                  const struct dsdb_attribute *attr,
    1508             :                                                  const struct drsuapi_DsReplicaAttribute *in,
    1509             :                                                  TALLOC_CTX *mem_ctx,
    1510             :                                                  struct ldb_message_element *out)
    1511             : {
    1512      619463 :         unsigned int i;
    1513             : 
    1514     5899826 :         out->flags   = 0;
    1515     5899826 :         out->name    = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
    1516     5899826 :         W_ERROR_HAVE_NO_MEMORY(out->name);
    1517             : 
    1518     5899826 :         out->num_values      = in->value_ctr.num_values;
    1519     5899826 :         out->values  = talloc_array(mem_ctx, struct ldb_val, out->num_values);
    1520     5899826 :         W_ERROR_HAVE_NO_MEMORY(out->values);
    1521             : 
    1522    12964410 :         for (i=0; i < out->num_values; i++) {
    1523     7064584 :                 size_t converted_size = 0;
    1524      619463 :                 char *str;
    1525             : 
    1526     7064584 :                 if (in->value_ctr.values[i].blob == NULL) {
    1527           0 :                         return WERR_FOOBAR;
    1528             :                 }
    1529             : 
    1530     7064584 :                 if (in->value_ctr.values[i].blob->length == 0) {
    1531           0 :                         return WERR_FOOBAR;
    1532             :                 }
    1533             : 
    1534     7064584 :                 if (!convert_string_talloc(out->values,
    1535             :                                            CH_UTF16, CH_UNIX,
    1536     7064584 :                                            in->value_ctr.values[i].blob->data,
    1537     6445121 :                                            in->value_ctr.values[i].blob->length,
    1538             :                                            &str, &converted_size)) {
    1539           0 :                         return WERR_FOOBAR;
    1540             :                 }
    1541             : 
    1542     7064584 :                 out->values[i] = data_blob_const(str, converted_size);
    1543             :         }
    1544             : 
    1545     5899826 :         return WERR_OK;
    1546             : }
    1547             : 
    1548     5409395 : static WERROR dsdb_syntax_UNICODE_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
    1549             :                                                  const struct dsdb_attribute *attr,
    1550             :                                                  const struct ldb_message_element *in,
    1551             :                                                  TALLOC_CTX *mem_ctx,
    1552             :                                                  struct drsuapi_DsReplicaAttribute *out)
    1553             : {
    1554      619463 :         unsigned int i;
    1555      619463 :         DATA_BLOB *blobs;
    1556             : 
    1557     5409395 :         if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
    1558           0 :                 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
    1559             :         }
    1560             : 
    1561    10818790 :         out->attid                   = dsdb_attribute_get_attid(attr,
    1562     5409395 :                                                                    ctx->is_schema_nc);
    1563     5409395 :         out->value_ctr.num_values    = in->num_values;
    1564     5409395 :         out->value_ctr.values                = talloc_array(mem_ctx,
    1565             :                                                        struct drsuapi_DsAttributeValue,
    1566             :                                                        in->num_values);
    1567     5409395 :         W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
    1568             : 
    1569     5409395 :         blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
    1570     5409395 :         W_ERROR_HAVE_NO_MEMORY(blobs);
    1571             : 
    1572    12071123 :         for (i=0; i < in->num_values; i++) {
    1573     6661728 :                 out->value_ctr.values[i].blob        = &blobs[i];
    1574             : 
    1575     6661728 :                 if (!convert_string_talloc(blobs,
    1576             :                                            CH_UNIX, CH_UTF16,
    1577     6661728 :                                            in->values[i].data, in->values[i].length,
    1578     6661728 :                                            &blobs[i].data, &blobs[i].length)) {
    1579           0 :                         return WERR_FOOBAR;
    1580             :                 }
    1581             :         }
    1582             : 
    1583     5409395 :         return WERR_OK;
    1584             : }
    1585             : 
    1586     3284352 : static WERROR dsdb_syntax_UNICODE_validate_one_val(const struct dsdb_syntax_ctx *ctx,
    1587             :                                                    const struct dsdb_attribute *attr,
    1588             :                                                    const struct ldb_val *val)
    1589             : {
    1590     3284352 :         void *dst = NULL;
    1591      555305 :         size_t size;
    1592      555305 :         bool ok;
    1593             : 
    1594     3284352 :         if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
    1595           0 :                 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
    1596             :         }
    1597             : 
    1598     3839657 :         ok = convert_string_talloc(ctx->ldb,
    1599             :                                    CH_UNIX, CH_UTF16,
    1600     3284352 :                                    val->data,
    1601     3284352 :                                    val->length,
    1602             :                                    &dst,
    1603             :                                    &size);
    1604     3284352 :         TALLOC_FREE(dst);
    1605     3284352 :         if (!ok) {
    1606           0 :                 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
    1607             :         }
    1608             : 
    1609     3284352 :         if (attr->rangeLower) {
    1610     1077970 :                 if ((size/2) < *attr->rangeLower) {
    1611           0 :                         return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
    1612             :                 }
    1613             :         }
    1614             : 
    1615     3284352 :         if (attr->rangeUpper) {
    1616     1093333 :                 if ((size/2) > *attr->rangeUpper) {
    1617           3 :                         return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
    1618             :                 }
    1619             :         }
    1620             : 
    1621     3284349 :         return WERR_OK;
    1622             : }
    1623             : 
    1624     1799202 : static WERROR dsdb_syntax_UNICODE_validate_ldb(const struct dsdb_syntax_ctx *ctx,
    1625             :                                                const struct dsdb_attribute *attr,
    1626             :                                                const struct ldb_message_element *in)
    1627             : {
    1628      298292 :         WERROR status;
    1629      298292 :         unsigned int i;
    1630             : 
    1631     1799202 :         if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
    1632           0 :                 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
    1633             :         }
    1634             : 
    1635     5083551 :         for (i=0; i < in->num_values; i++) {
    1636     3284352 :                 if (in->values[i].length == 0) {
    1637           0 :                         return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
    1638             :                 }
    1639             : 
    1640     3284352 :                 status = dsdb_syntax_UNICODE_validate_one_val(ctx,
    1641             :                                                               attr,
    1642     2729047 :                                                               &in->values[i]);
    1643     3284352 :                 if (!W_ERROR_IS_OK(status)) {
    1644           3 :                         return status;
    1645             :                 }
    1646             :         }
    1647             : 
    1648     1799199 :         return WERR_OK;
    1649             : }
    1650             : 
    1651      730415 : static WERROR dsdb_syntax_one_DN_drsuapi_to_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
    1652             :                                                 const struct dsdb_syntax *syntax,
    1653             :                                                 const DATA_BLOB *in, DATA_BLOB *out)
    1654             : {
    1655           2 :         struct drsuapi_DsReplicaObjectIdentifier3 id3;
    1656           2 :         enum ndr_err_code ndr_err;
    1657           2 :         DATA_BLOB guid_blob;
    1658           2 :         struct ldb_dn *dn;
    1659      730415 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
    1660           2 :         int ret;
    1661           2 :         NTSTATUS status;
    1662             : 
    1663      730415 :         if (!tmp_ctx) {
    1664           0 :                 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
    1665             :         }
    1666             : 
    1667      730415 :         if (in == NULL) {
    1668           0 :                 talloc_free(tmp_ctx);
    1669           0 :                 return WERR_FOOBAR;
    1670             :         }
    1671             : 
    1672      730415 :         if (in->length == 0) {
    1673           0 :                 talloc_free(tmp_ctx);
    1674           0 :                 return WERR_FOOBAR;
    1675             :         }
    1676             : 
    1677             : 
    1678             :         /* windows sometimes sends an extra two pad bytes here */
    1679      730415 :         ndr_err = ndr_pull_struct_blob(in,
    1680             :                                        tmp_ctx, &id3,
    1681             :                                        (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3);
    1682      730415 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1683           0 :                 status = ndr_map_error2ntstatus(ndr_err);
    1684           0 :                 talloc_free(tmp_ctx);
    1685           0 :                 return ntstatus_to_werror(status);
    1686             :         }
    1687             : 
    1688      730415 :         dn = ldb_dn_new(tmp_ctx, ldb, id3.dn);
    1689      730415 :         if (!dn) {
    1690           0 :                 talloc_free(tmp_ctx);
    1691             :                 /* If this fails, it must be out of memory, as it does not do much parsing */
    1692           0 :                 W_ERROR_HAVE_NO_MEMORY(dn);
    1693             :         }
    1694             : 
    1695      730415 :         if (!GUID_all_zero(&id3.guid)) {
    1696      729555 :                 status = GUID_to_ndr_blob(&id3.guid, tmp_ctx, &guid_blob);
    1697      729555 :                 if (!NT_STATUS_IS_OK(status)) {
    1698           0 :                         talloc_free(tmp_ctx);
    1699           0 :                         return ntstatus_to_werror(status);
    1700             :                 }
    1701             : 
    1702      729555 :                 ret = ldb_dn_set_extended_component(dn, "GUID", &guid_blob);
    1703      729555 :                 if (ret != LDB_SUCCESS) {
    1704           0 :                         talloc_free(tmp_ctx);
    1705           0 :                         return WERR_FOOBAR;
    1706             :                 }
    1707      729555 :                 talloc_free(guid_blob.data);
    1708             :         }
    1709             : 
    1710      730415 :         if (id3.__ndr_size_sid) {
    1711           1 :                 DATA_BLOB sid_blob;
    1712       24084 :                 ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, &id3.sid,
    1713             :                                                (ndr_push_flags_fn_t)ndr_push_dom_sid);
    1714       24084 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1715           0 :                         status = ndr_map_error2ntstatus(ndr_err);
    1716           0 :                         talloc_free(tmp_ctx);
    1717           0 :                         return ntstatus_to_werror(status);
    1718             :                 }
    1719             : 
    1720       24084 :                 ret = ldb_dn_set_extended_component(dn, "SID", &sid_blob);
    1721       24084 :                 if (ret != LDB_SUCCESS) {
    1722           0 :                         talloc_free(tmp_ctx);
    1723           0 :                         return WERR_FOOBAR;
    1724             :                 }
    1725             :         }
    1726             : 
    1727      730415 :         *out = data_blob_string_const(ldb_dn_get_extended_linearized(mem_ctx, dn, 1));
    1728      730415 :         talloc_free(tmp_ctx);
    1729      730415 :         W_ERROR_HAVE_NO_MEMORY(out->data);
    1730      730415 :         return WERR_OK;
    1731             : }
    1732             : 
    1733      875638 : static WERROR dsdb_syntax_DN_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
    1734             :                                             const struct dsdb_attribute *attr,
    1735             :                                             const struct drsuapi_DsReplicaAttribute *in,
    1736             :                                             TALLOC_CTX *mem_ctx,
    1737             :                                             struct ldb_message_element *out)
    1738             : {
    1739           2 :         unsigned int i;
    1740             : 
    1741      875638 :         out->flags   = 0;
    1742      875638 :         out->name    = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
    1743      875638 :         W_ERROR_HAVE_NO_MEMORY(out->name);
    1744             : 
    1745      875638 :         out->num_values      = in->value_ctr.num_values;
    1746      875638 :         out->values  = talloc_array(mem_ctx, struct ldb_val, out->num_values);
    1747      875638 :         W_ERROR_HAVE_NO_MEMORY(out->values);
    1748             : 
    1749     1606053 :         for (i=0; i < out->num_values; i++) {
    1750      730415 :                 WERROR status = dsdb_syntax_one_DN_drsuapi_to_ldb(out->values, ctx->ldb, attr->syntax,
    1751      730415 :                                                                   in->value_ctr.values[i].blob,
    1752      730415 :                                                                   &out->values[i]);
    1753      730415 :                 if (!W_ERROR_IS_OK(status)) {
    1754           0 :                         return status;
    1755             :                 }
    1756             : 
    1757             :         }
    1758             : 
    1759      875638 :         return WERR_OK;
    1760             : }
    1761             : 
    1762      615044 : static WERROR dsdb_syntax_DN_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
    1763             :                                             const struct dsdb_attribute *attr,
    1764             :                                             const struct ldb_message_element *in,
    1765             :                                             TALLOC_CTX *mem_ctx,
    1766             :                                             struct drsuapi_DsReplicaAttribute *out)
    1767             : {
    1768           2 :         unsigned int i;
    1769           2 :         DATA_BLOB *blobs;
    1770             : 
    1771      615044 :         if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
    1772           0 :                 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
    1773             :         }
    1774             : 
    1775     1230088 :         out->attid                   = dsdb_attribute_get_attid(attr,
    1776      615044 :                                                                    ctx->is_schema_nc);
    1777      615044 :         out->value_ctr.num_values    = in->num_values;
    1778      615044 :         out->value_ctr.values                = talloc_array(mem_ctx,
    1779             :                                                        struct drsuapi_DsAttributeValue,
    1780             :                                                        in->num_values);
    1781      615044 :         W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
    1782             : 
    1783      615044 :         blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
    1784      615044 :         W_ERROR_HAVE_NO_MEMORY(blobs);
    1785             : 
    1786     1231870 :         for (i=0; i < in->num_values; i++) {
    1787           2 :                 struct drsuapi_DsReplicaObjectIdentifier3 id3;
    1788           2 :                 enum ndr_err_code ndr_err;
    1789           2 :                 struct ldb_dn *dn;
    1790      616826 :                 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
    1791           2 :                 NTSTATUS status;
    1792             : 
    1793      616826 :                 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
    1794             : 
    1795      616826 :                 out->value_ctr.values[i].blob        = &blobs[i];
    1796             : 
    1797      616826 :                 dn = ldb_dn_from_ldb_val(tmp_ctx, ctx->ldb, &in->values[i]);
    1798             : 
    1799      616826 :                 W_ERROR_HAVE_NO_MEMORY(dn);
    1800             : 
    1801      616826 :                 ZERO_STRUCT(id3);
    1802             : 
    1803      616826 :                 status = dsdb_get_extended_dn_guid(dn, &id3.guid, "GUID");
    1804      616826 :                 if (!NT_STATUS_IS_OK(status) &&
    1805         820 :                     !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    1806           0 :                         talloc_free(tmp_ctx);
    1807           0 :                         return ntstatus_to_werror(status);
    1808             :                 }
    1809             : 
    1810      616826 :                 status = dsdb_get_extended_dn_sid(dn, &id3.sid, "SID");
    1811      616826 :                 if (!NT_STATUS_IS_OK(status) &&
    1812      603957 :                     !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    1813           0 :                         talloc_free(tmp_ctx);
    1814           0 :                         return ntstatus_to_werror(status);
    1815             :                 }
    1816             : 
    1817      616826 :                 id3.dn = ldb_dn_get_linearized(dn);
    1818             : 
    1819      616826 :                 ndr_err = ndr_push_struct_blob(&blobs[i], blobs, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
    1820      616826 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1821           0 :                         status = ndr_map_error2ntstatus(ndr_err);
    1822           0 :                         talloc_free(tmp_ctx);
    1823           0 :                         return ntstatus_to_werror(status);
    1824             :                 }
    1825      616826 :                 talloc_free(tmp_ctx);
    1826             :         }
    1827             : 
    1828      615044 :         return WERR_OK;
    1829             : }
    1830             : 
    1831      873256 : static WERROR dsdb_syntax_DN_validate_one_val(const struct dsdb_syntax_ctx *ctx,
    1832             :                                               const struct dsdb_attribute *attr,
    1833             :                                               const struct ldb_val *val,
    1834             :                                               TALLOC_CTX *mem_ctx,
    1835             :                                               struct dsdb_dn **_dsdb_dn)
    1836             : {
    1837      104208 :         static const char * const extended_list[] = { "GUID", "SID", NULL };
    1838      104208 :         enum ndr_err_code ndr_err;
    1839      104208 :         struct GUID guid;
    1840      104208 :         struct dom_sid sid;
    1841      104208 :         const DATA_BLOB *sid_blob;
    1842      104208 :         struct dsdb_dn *dsdb_dn;
    1843      104208 :         struct ldb_dn *dn;
    1844      104208 :         char *dn_str;
    1845      104208 :         struct ldb_dn *dn2;
    1846      104208 :         char *dn2_str;
    1847      104208 :         int num_components;
    1848      873256 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
    1849      104208 :         NTSTATUS status;
    1850             : 
    1851      873256 :         W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
    1852             : 
    1853      873256 :         if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
    1854           0 :                 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
    1855             :         }
    1856             : 
    1857     1746512 :         dsdb_dn = dsdb_dn_parse(tmp_ctx, ctx->ldb, val,
    1858      873256 :                                 attr->syntax->ldap_oid);
    1859      873256 :         if (!dsdb_dn) {
    1860           0 :                 talloc_free(tmp_ctx);
    1861           0 :                 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
    1862             :         }
    1863      873256 :         dn = dsdb_dn->dn;
    1864             : 
    1865      873256 :         dn2 = ldb_dn_copy(tmp_ctx, dn);
    1866      873256 :         if (dn == NULL) {
    1867           0 :                 talloc_free(tmp_ctx);
    1868           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    1869             :         }
    1870             : 
    1871      873256 :         num_components = ldb_dn_get_comp_num(dn);
    1872             : 
    1873      873256 :         status = dsdb_get_extended_dn_guid(dn, &guid, "GUID");
    1874      873256 :         if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    1875      140691 :                 num_components++;
    1876      732565 :         } else if (!NT_STATUS_IS_OK(status)) {
    1877           0 :                 talloc_free(tmp_ctx);
    1878           0 :                 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
    1879             :         }
    1880             : 
    1881      873256 :         sid_blob = ldb_dn_get_extended_component(dn, "SID");
    1882      873256 :         if (sid_blob) {
    1883       32623 :                 num_components++;
    1884       32623 :                 ndr_err = ndr_pull_struct_blob_all(sid_blob,
    1885             :                                                    tmp_ctx,
    1886             :                                                    &sid,
    1887             :                                                    (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
    1888       32623 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1889           0 :                         talloc_free(tmp_ctx);
    1890           0 :                         return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
    1891             :                 }
    1892             :         }
    1893             : 
    1894             :         /* Do not allow links to the RootDSE */
    1895      873256 :         if (num_components == 0) {
    1896           0 :                 talloc_free(tmp_ctx);
    1897           0 :                 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
    1898             :         }
    1899             : 
    1900             :         /*
    1901             :          * We need to check that only "GUID" and "SID" are
    1902             :          * specified as extended components, we do that
    1903             :          * by comparing the dn's after removing all components
    1904             :          * from one dn and only the allowed subset from the other
    1905             :          * one.
    1906             :          */
    1907      873256 :         ldb_dn_extended_filter(dn, extended_list);
    1908             : 
    1909      873256 :         dn_str = ldb_dn_get_extended_linearized(tmp_ctx, dn, 0);
    1910      873256 :         if (dn_str == NULL) {
    1911           0 :                 talloc_free(tmp_ctx);
    1912           0 :                 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
    1913             :         }
    1914      873256 :         dn2_str = ldb_dn_get_extended_linearized(tmp_ctx, dn2, 0);
    1915      873256 :         if (dn2_str == NULL) {
    1916           0 :                 talloc_free(tmp_ctx);
    1917           0 :                 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
    1918             :         }
    1919             : 
    1920      873256 :         if (strcmp(dn_str, dn2_str) != 0) {
    1921           2 :                 talloc_free(tmp_ctx);
    1922           2 :                 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
    1923             :         }
    1924             : 
    1925      873254 :         *_dsdb_dn = talloc_move(mem_ctx, &dsdb_dn);
    1926      873254 :         talloc_free(tmp_ctx);
    1927      873254 :         return WERR_OK;
    1928             : }
    1929             : 
    1930      845773 : static WERROR dsdb_syntax_DN_validate_ldb(const struct dsdb_syntax_ctx *ctx,
    1931             :                                           const struct dsdb_attribute *attr,
    1932             :                                           const struct ldb_message_element *in)
    1933             : {
    1934      102639 :         unsigned int i;
    1935             : 
    1936      845773 :         if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
    1937           0 :                 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
    1938             :         }
    1939             : 
    1940     1699569 :         for (i=0; i < in->num_values; i++) {
    1941      103550 :                 WERROR status;
    1942      103550 :                 struct dsdb_dn *dsdb_dn;
    1943      853798 :                 TALLOC_CTX *tmp_ctx = talloc_new(ctx->ldb);
    1944      853798 :                 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
    1945             : 
    1946      853798 :                 status = dsdb_syntax_DN_validate_one_val(ctx,
    1947             :                                                          attr,
    1948      853798 :                                                          &in->values[i],
    1949             :                                                          tmp_ctx, &dsdb_dn);
    1950      853798 :                 if (!W_ERROR_IS_OK(status)) {
    1951           2 :                         talloc_free(tmp_ctx);
    1952           2 :                         return status;
    1953             :                 }
    1954             : 
    1955      853796 :                 if (dsdb_dn->dn_format != DSDB_NORMAL_DN) {
    1956           0 :                         talloc_free(tmp_ctx);
    1957           0 :                         return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
    1958             :                 }
    1959             : 
    1960      853796 :                 talloc_free(tmp_ctx);
    1961             :         }
    1962             : 
    1963      845771 :         return WERR_OK;
    1964             : }
    1965             : 
    1966        7880 : static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
    1967             :                                                    const struct dsdb_attribute *attr,
    1968             :                                                    const struct drsuapi_DsReplicaAttribute *in,
    1969             :                                                    TALLOC_CTX *mem_ctx,
    1970             :                                                    struct ldb_message_element *out)
    1971             : {
    1972           3 :         unsigned int i;
    1973           3 :         int ret;
    1974             : 
    1975        7880 :         out->flags   = 0;
    1976        7880 :         out->name    = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
    1977        7880 :         W_ERROR_HAVE_NO_MEMORY(out->name);
    1978             : 
    1979        7880 :         out->num_values      = in->value_ctr.num_values;
    1980        7880 :         out->values  = talloc_array(mem_ctx, struct ldb_val, out->num_values);
    1981        7880 :         W_ERROR_HAVE_NO_MEMORY(out->values);
    1982             : 
    1983       19674 :         for (i=0; i < out->num_values; i++) {
    1984           3 :                 struct drsuapi_DsReplicaObjectIdentifier3Binary id3;
    1985           3 :                 enum ndr_err_code ndr_err;
    1986           3 :                 DATA_BLOB guid_blob;
    1987           3 :                 struct ldb_dn *dn;
    1988           3 :                 struct dsdb_dn *dsdb_dn;
    1989           3 :                 NTSTATUS status;
    1990       11794 :                 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
    1991       11794 :                 if (!tmp_ctx) {
    1992           0 :                         W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
    1993             :                 }
    1994             : 
    1995       11794 :                 if (in->value_ctr.values[i].blob == NULL) {
    1996           0 :                         talloc_free(tmp_ctx);
    1997           0 :                         return WERR_FOOBAR;
    1998             :                 }
    1999             : 
    2000       11794 :                 if (in->value_ctr.values[i].blob->length == 0) {
    2001           0 :                         talloc_free(tmp_ctx);
    2002           0 :                         return WERR_FOOBAR;
    2003             :                 }
    2004             : 
    2005             : 
    2006             :                 /* windows sometimes sends an extra two pad bytes here */
    2007       11794 :                 ndr_err = ndr_pull_struct_blob(in->value_ctr.values[i].blob,
    2008             :                                                tmp_ctx, &id3,
    2009             :                                                (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary);
    2010       11794 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    2011           0 :                         status = ndr_map_error2ntstatus(ndr_err);
    2012           0 :                         talloc_free(tmp_ctx);
    2013           0 :                         return ntstatus_to_werror(status);
    2014             :                 }
    2015             : 
    2016       11794 :                 dn = ldb_dn_new(tmp_ctx, ctx->ldb, id3.dn);
    2017       11794 :                 if (!dn) {
    2018           0 :                         talloc_free(tmp_ctx);
    2019             :                         /* If this fails, it must be out of memory, as it does not do much parsing */
    2020           0 :                         W_ERROR_HAVE_NO_MEMORY(dn);
    2021             :                 }
    2022             : 
    2023       11794 :                 if (!GUID_all_zero(&id3.guid)) {
    2024       11794 :                         status = GUID_to_ndr_blob(&id3.guid, tmp_ctx, &guid_blob);
    2025       11794 :                         if (!NT_STATUS_IS_OK(status)) {
    2026           0 :                                 talloc_free(tmp_ctx);
    2027           0 :                                 return ntstatus_to_werror(status);
    2028             :                         }
    2029             : 
    2030       11794 :                         ret = ldb_dn_set_extended_component(dn, "GUID", &guid_blob);
    2031       11794 :                         if (ret != LDB_SUCCESS) {
    2032           0 :                                 talloc_free(tmp_ctx);
    2033           0 :                                 return WERR_FOOBAR;
    2034             :                         }
    2035       11794 :                         talloc_free(guid_blob.data);
    2036             :                 }
    2037             : 
    2038       11794 :                 if (id3.__ndr_size_sid) {
    2039           2 :                         DATA_BLOB sid_blob;
    2040        5921 :                         ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, &id3.sid,
    2041             :                                                        (ndr_push_flags_fn_t)ndr_push_dom_sid);
    2042        5921 :                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    2043           0 :                                 status = ndr_map_error2ntstatus(ndr_err);
    2044           0 :                                 talloc_free(tmp_ctx);
    2045           0 :                                 return ntstatus_to_werror(status);
    2046             :                         }
    2047             : 
    2048        5921 :                         ret = ldb_dn_set_extended_component(dn, "SID", &sid_blob);
    2049        5921 :                         if (ret != LDB_SUCCESS) {
    2050           0 :                                 talloc_free(tmp_ctx);
    2051           0 :                                 return WERR_FOOBAR;
    2052             :                         }
    2053             :                 }
    2054             : 
    2055             :                 /* set binary stuff */
    2056       11794 :                 dsdb_dn = dsdb_dn_construct(tmp_ctx, dn, id3.binary, attr->syntax->ldap_oid);
    2057       11794 :                 if (!dsdb_dn) {
    2058           0 :                         if (errno == EINVAL) {
    2059             :                                 /*
    2060             :                                  * This might be Object(OR-Name)
    2061             :                                  * failing because of a non empty
    2062             :                                  * binary part.
    2063             :                                  */
    2064           0 :                                 talloc_free(tmp_ctx);
    2065           0 :                                 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
    2066             :                         }
    2067           0 :                         talloc_free(tmp_ctx);
    2068           0 :                         W_ERROR_HAVE_NO_MEMORY(dsdb_dn);
    2069             :                 }
    2070       11794 :                 out->values[i] = data_blob_string_const(dsdb_dn_get_extended_linearized(out->values, dsdb_dn, 1));
    2071       11794 :                 talloc_free(tmp_ctx);
    2072       11794 :                 W_ERROR_HAVE_NO_MEMORY(out->values[i].data);
    2073             :         }
    2074             : 
    2075        7880 :         return WERR_OK;
    2076             : }
    2077             : 
    2078        4221 : static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
    2079             :                                                    const struct dsdb_attribute *attr,
    2080             :                                                    const struct ldb_message_element *in,
    2081             :                                                    TALLOC_CTX *mem_ctx,
    2082             :                                                    struct drsuapi_DsReplicaAttribute *out)
    2083             : {
    2084           3 :         unsigned int i;
    2085           3 :         DATA_BLOB *blobs;
    2086             : 
    2087        4221 :         if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
    2088           0 :                 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
    2089             :         }
    2090             : 
    2091        8442 :         out->attid                   = dsdb_attribute_get_attid(attr,
    2092        4221 :                                                                    ctx->is_schema_nc);
    2093        4221 :         out->value_ctr.num_values    = in->num_values;
    2094        4221 :         out->value_ctr.values                = talloc_array(mem_ctx,
    2095             :                                                        struct drsuapi_DsAttributeValue,
    2096             :                                                        in->num_values);
    2097        4221 :         W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
    2098             : 
    2099        4221 :         blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
    2100        4221 :         W_ERROR_HAVE_NO_MEMORY(blobs);
    2101             : 
    2102       16175 :         for (i=0; i < in->num_values; i++) {
    2103           3 :                 struct drsuapi_DsReplicaObjectIdentifier3Binary id3;
    2104           3 :                 enum ndr_err_code ndr_err;
    2105           3 :                 const DATA_BLOB *sid_blob;
    2106           3 :                 struct dsdb_dn *dsdb_dn;
    2107       11954 :                 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
    2108           3 :                 NTSTATUS status;
    2109             : 
    2110       11954 :                 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
    2111             : 
    2112       11954 :                 out->value_ctr.values[i].blob        = &blobs[i];
    2113             : 
    2114       11954 :                 dsdb_dn = dsdb_dn_parse(tmp_ctx, ctx->ldb, &in->values[i], attr->syntax->ldap_oid);
    2115             : 
    2116       11954 :                 if (!dsdb_dn) {
    2117           0 :                         talloc_free(tmp_ctx);
    2118           0 :                         return ntstatus_to_werror(NT_STATUS_INVALID_PARAMETER);
    2119             :                 }
    2120             : 
    2121       11954 :                 ZERO_STRUCT(id3);
    2122             : 
    2123       11954 :                 status = dsdb_get_extended_dn_guid(dsdb_dn->dn, &id3.guid, "GUID");
    2124       11954 :                 if (!NT_STATUS_IS_OK(status) &&
    2125           0 :                     !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    2126           0 :                         talloc_free(tmp_ctx);
    2127           0 :                         return ntstatus_to_werror(status);
    2128             :                 }
    2129             : 
    2130       11954 :                 sid_blob = ldb_dn_get_extended_component(dsdb_dn->dn, "SID");
    2131       11954 :                 if (sid_blob) {
    2132             : 
    2133        2205 :                         ndr_err = ndr_pull_struct_blob_all(sid_blob,
    2134             :                                                            tmp_ctx, &id3.sid,
    2135             :                                                            (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
    2136        2205 :                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    2137           0 :                                 status = ndr_map_error2ntstatus(ndr_err);
    2138           0 :                                 talloc_free(tmp_ctx);
    2139           0 :                                 return ntstatus_to_werror(status);
    2140             :                         }
    2141             :                 }
    2142             : 
    2143       11954 :                 id3.dn = ldb_dn_get_linearized(dsdb_dn->dn);
    2144             : 
    2145             :                 /* get binary stuff */
    2146       11954 :                 id3.binary = dsdb_dn->extra_part;
    2147             : 
    2148       11954 :                 ndr_err = ndr_push_struct_blob(&blobs[i], blobs, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary);
    2149       11954 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    2150           0 :                         status = ndr_map_error2ntstatus(ndr_err);
    2151           0 :                         talloc_free(tmp_ctx);
    2152           0 :                         return ntstatus_to_werror(status);
    2153             :                 }
    2154       11954 :                 talloc_free(tmp_ctx);
    2155             :         }
    2156             : 
    2157        4221 :         return WERR_OK;
    2158             : }
    2159             : 
    2160       16938 : static WERROR dsdb_syntax_DN_BINARY_validate_ldb(const struct dsdb_syntax_ctx *ctx,
    2161             :                                                  const struct dsdb_attribute *attr,
    2162             :                                                  const struct ldb_message_element *in)
    2163             : {
    2164         209 :         unsigned int i;
    2165             : 
    2166       16938 :         if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
    2167           0 :                 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
    2168             :         }
    2169             : 
    2170       36396 :         for (i=0; i < in->num_values; i++) {
    2171         658 :                 WERROR status;
    2172         658 :                 struct dsdb_dn *dsdb_dn;
    2173       19458 :                 TALLOC_CTX *tmp_ctx = talloc_new(ctx->ldb);
    2174       19458 :                 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
    2175             : 
    2176       20116 :                 status = dsdb_syntax_DN_validate_one_val(ctx,
    2177             :                                                          attr,
    2178       19458 :                                                          &in->values[i],
    2179             :                                                          tmp_ctx, &dsdb_dn);
    2180       19458 :                 if (!W_ERROR_IS_OK(status)) {
    2181           0 :                         talloc_free(tmp_ctx);
    2182           0 :                         return status;
    2183             :                 }
    2184             : 
    2185       19458 :                 if (dsdb_dn->dn_format != DSDB_BINARY_DN) {
    2186           0 :                         talloc_free(tmp_ctx);
    2187           0 :                         return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
    2188             :                 }
    2189             : 
    2190       20116 :                 status = dsdb_syntax_DATA_BLOB_validate_one_val(ctx,
    2191             :                                                                 attr,
    2192       19458 :                                                                 &dsdb_dn->extra_part);
    2193       19458 :                 if (!W_ERROR_IS_OK(status)) {
    2194           0 :                         talloc_free(tmp_ctx);
    2195           0 :                         return status;
    2196             :                 }
    2197             : 
    2198       19458 :                 talloc_free(tmp_ctx);
    2199             :         }
    2200             : 
    2201       16938 :         return WERR_OK;
    2202             : }
    2203             : 
    2204           0 : static WERROR dsdb_syntax_DN_STRING_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
    2205             :                                                    const struct dsdb_attribute *attr,
    2206             :                                                    const struct drsuapi_DsReplicaAttribute *in,
    2207             :                                                    TALLOC_CTX *mem_ctx,
    2208             :                                                    struct ldb_message_element *out)
    2209             : {
    2210           0 :         return dsdb_syntax_DN_BINARY_drsuapi_to_ldb(ctx,
    2211             :                                                     attr,
    2212             :                                                     in,
    2213             :                                                     mem_ctx,
    2214             :                                                     out);
    2215             : }
    2216             : 
    2217           0 : static WERROR dsdb_syntax_DN_STRING_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
    2218             :                                                    const struct dsdb_attribute *attr,
    2219             :                                                    const struct ldb_message_element *in,
    2220             :                                                    TALLOC_CTX *mem_ctx,
    2221             :                                                    struct drsuapi_DsReplicaAttribute *out)
    2222             : {
    2223           0 :         return dsdb_syntax_DN_BINARY_ldb_to_drsuapi(ctx,
    2224             :                                                     attr,
    2225             :                                                     in,
    2226             :                                                     mem_ctx,
    2227             :                                                     out);
    2228             : }
    2229             : 
    2230           0 : static WERROR dsdb_syntax_DN_STRING_validate_ldb(const struct dsdb_syntax_ctx *ctx,
    2231             :                                                  const struct dsdb_attribute *attr,
    2232             :                                                  const struct ldb_message_element *in)
    2233             : {
    2234           0 :         unsigned int i;
    2235             : 
    2236           0 :         if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
    2237           0 :                 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
    2238             :         }
    2239             : 
    2240           0 :         for (i=0; i < in->num_values; i++) {
    2241           0 :                 WERROR status;
    2242           0 :                 struct dsdb_dn *dsdb_dn;
    2243           0 :                 TALLOC_CTX *tmp_ctx = talloc_new(ctx->ldb);
    2244           0 :                 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
    2245             : 
    2246           0 :                 status = dsdb_syntax_DN_validate_one_val(ctx,
    2247             :                                                          attr,
    2248           0 :                                                          &in->values[i],
    2249             :                                                          tmp_ctx, &dsdb_dn);
    2250           0 :                 if (!W_ERROR_IS_OK(status)) {
    2251           0 :                         talloc_free(tmp_ctx);
    2252           0 :                         return status;
    2253             :                 }
    2254             : 
    2255           0 :                 if (dsdb_dn->dn_format != DSDB_STRING_DN) {
    2256           0 :                         talloc_free(tmp_ctx);
    2257           0 :                         return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
    2258             :                 }
    2259             : 
    2260           0 :                 status = dsdb_syntax_UNICODE_validate_one_val(ctx,
    2261             :                                                               attr,
    2262           0 :                                                               &dsdb_dn->extra_part);
    2263           0 :                 if (!W_ERROR_IS_OK(status)) {
    2264           0 :                         talloc_free(tmp_ctx);
    2265           0 :                         return status;
    2266             :                 }
    2267             : 
    2268           0 :                 talloc_free(tmp_ctx);
    2269             :         }
    2270             : 
    2271           0 :         return WERR_OK;
    2272             : }
    2273             : 
    2274           0 : static WERROR dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
    2275             :                                                               const struct dsdb_attribute *attr,
    2276             :                                                               const struct drsuapi_DsReplicaAttribute *in,
    2277             :                                                               TALLOC_CTX *mem_ctx,
    2278             :                                                               struct ldb_message_element *out)
    2279             : {
    2280           0 :         unsigned int i;
    2281             : 
    2282           0 :         out->flags   = 0;
    2283           0 :         out->name    = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
    2284           0 :         W_ERROR_HAVE_NO_MEMORY(out->name);
    2285             : 
    2286           0 :         out->num_values      = in->value_ctr.num_values;
    2287           0 :         out->values  = talloc_array(mem_ctx, struct ldb_val, out->num_values);
    2288           0 :         W_ERROR_HAVE_NO_MEMORY(out->values);
    2289             : 
    2290           0 :         for (i=0; i < out->num_values; i++) {
    2291           0 :                 size_t len;
    2292           0 :                 size_t converted_size = 0;
    2293           0 :                 char *str;
    2294             : 
    2295           0 :                 if (in->value_ctr.values[i].blob == NULL) {
    2296           0 :                         return WERR_FOOBAR;
    2297             :                 }
    2298             : 
    2299           0 :                 if (in->value_ctr.values[i].blob->length < 4) {
    2300           0 :                         return WERR_FOOBAR;
    2301             :                 }
    2302             : 
    2303           0 :                 len = IVAL(in->value_ctr.values[i].blob->data, 0);
    2304             : 
    2305           0 :                 if (len != in->value_ctr.values[i].blob->length) {
    2306           0 :                         return WERR_FOOBAR;
    2307             :                 }
    2308             : 
    2309           0 :                 if (!convert_string_talloc(out->values, CH_UTF16, CH_UNIX,
    2310           0 :                                            in->value_ctr.values[i].blob->data+4,
    2311           0 :                                            in->value_ctr.values[i].blob->length-4,
    2312             :                                            (void **)&str, &converted_size)) {
    2313           0 :                         return WERR_FOOBAR;
    2314             :                 }
    2315             : 
    2316           0 :                 out->values[i] = data_blob_string_const(str);
    2317             :         }
    2318             : 
    2319           0 :         return WERR_OK;
    2320             : }
    2321             : 
    2322           0 : static WERROR dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
    2323             :                                                               const struct dsdb_attribute *attr,
    2324             :                                                               const struct ldb_message_element *in,
    2325             :                                                               TALLOC_CTX *mem_ctx,
    2326             :                                                               struct drsuapi_DsReplicaAttribute *out)
    2327             : {
    2328           0 :         unsigned int i;
    2329           0 :         DATA_BLOB *blobs;
    2330             : 
    2331           0 :         if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
    2332           0 :                 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
    2333             :         }
    2334             : 
    2335           0 :         out->attid                   = dsdb_attribute_get_attid(attr,
    2336           0 :                                                                    ctx->is_schema_nc);
    2337           0 :         out->value_ctr.num_values    = in->num_values;
    2338           0 :         out->value_ctr.values                = talloc_array(mem_ctx,
    2339             :                                                        struct drsuapi_DsAttributeValue,
    2340             :                                                        in->num_values);
    2341           0 :         W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
    2342             : 
    2343           0 :         blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
    2344           0 :         W_ERROR_HAVE_NO_MEMORY(blobs);
    2345             : 
    2346           0 :         for (i=0; i < in->num_values; i++) {
    2347           0 :                 uint8_t *data;
    2348           0 :                 size_t ret;
    2349             : 
    2350           0 :                 out->value_ctr.values[i].blob        = &blobs[i];
    2351             : 
    2352           0 :                 if (!convert_string_talloc(blobs, CH_UNIX, CH_UTF16,
    2353           0 :                                            in->values[i].data,
    2354           0 :                                            in->values[i].length,
    2355             :                                            (void **)&data, &ret)) {
    2356           0 :                         return WERR_FOOBAR;
    2357             :                 }
    2358             : 
    2359           0 :                 blobs[i] = data_blob_talloc(blobs, NULL, 4 + ret);
    2360           0 :                 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
    2361             : 
    2362           0 :                 SIVAL(blobs[i].data, 0, 4 + ret);
    2363             : 
    2364           0 :                 if (ret > 0) {
    2365           0 :                         memcpy(blobs[i].data + 4, data, ret);
    2366           0 :                         talloc_free(data);
    2367             :                 }
    2368             :         }
    2369             : 
    2370           0 :         return WERR_OK;
    2371             : }
    2372             : 
    2373           0 : static WERROR dsdb_syntax_PRESENTATION_ADDRESS_validate_ldb(const struct dsdb_syntax_ctx *ctx,
    2374             :                                                             const struct dsdb_attribute *attr,
    2375             :                                                             const struct ldb_message_element *in)
    2376             : {
    2377           0 :         return dsdb_syntax_UNICODE_validate_ldb(ctx,
    2378             :                                                 attr,
    2379             :                                                 in);
    2380             : }
    2381             : 
    2382             : #define OMOBJECTCLASS(val) { .length = sizeof(val) - 1, .data = discard_const_p(uint8_t, val) }
    2383             : 
    2384             : static const struct dsdb_syntax dsdb_syntaxes[] = {
    2385             :         {
    2386             :                 .name                   = "Boolean",
    2387             :                 .ldap_oid               = LDB_SYNTAX_BOOLEAN,
    2388             :                 .oMSyntax               = 1,
    2389             :                 .attributeSyntax_oid    = "2.5.5.8",
    2390             :                 .drsuapi_to_ldb         = dsdb_syntax_BOOL_drsuapi_to_ldb,
    2391             :                 .ldb_to_drsuapi         = dsdb_syntax_BOOL_ldb_to_drsuapi,
    2392             :                 .validate_ldb           = dsdb_syntax_BOOL_validate_ldb,
    2393             :                 .equality               = "booleanMatch",
    2394             :                 .comment                = "Boolean",
    2395             :                 .auto_normalise         = true
    2396             :         },{
    2397             :                 .name                   = "Integer",
    2398             :                 .ldap_oid               = LDB_SYNTAX_INTEGER,
    2399             :                 .oMSyntax               = 2,
    2400             :                 .attributeSyntax_oid    = "2.5.5.9",
    2401             :                 .drsuapi_to_ldb         = dsdb_syntax_INT32_drsuapi_to_ldb,
    2402             :                 .ldb_to_drsuapi         = dsdb_syntax_INT32_ldb_to_drsuapi,
    2403             :                 .validate_ldb           = dsdb_syntax_INT32_validate_ldb,
    2404             :                 .equality               = "integerMatch",
    2405             :                 .comment                = "Integer",
    2406             :                 .ldb_syntax             = LDB_SYNTAX_SAMBA_INT32,
    2407             :                 .auto_normalise         = true
    2408             :         },{
    2409             :                 .name                   = "String(Octet)",
    2410             :                 .ldap_oid               = LDB_SYNTAX_OCTET_STRING,
    2411             :                 .oMSyntax               = 4,
    2412             :                 .attributeSyntax_oid    = "2.5.5.10",
    2413             :                 .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
    2414             :                 .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
    2415             :                 .validate_ldb           = dsdb_syntax_DATA_BLOB_validate_ldb,
    2416             :                 .equality               = "octetStringMatch",
    2417             :                 .comment                = "Octet String",
    2418             :                 .userParameters         = true,
    2419             :                 .ldb_syntax             = LDB_SYNTAX_SAMBA_OCTET_STRING
    2420             :         },{
    2421             :                 .name                   = "String(Sid)",
    2422             :                 .ldap_oid               = LDB_SYNTAX_OCTET_STRING,
    2423             :                 .oMSyntax               = 4,
    2424             :                 .attributeSyntax_oid    = "2.5.5.17",
    2425             :                 .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
    2426             :                 .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
    2427             :                 .validate_ldb           = dsdb_syntax_DATA_BLOB_validate_ldb,
    2428             :                 .equality               = "octetStringMatch",
    2429             :                 .comment                = "Octet String - Security Identifier (SID)",
    2430             :                 .ldb_syntax             = LDB_SYNTAX_SAMBA_SID
    2431             :         },{
    2432             :                 .name                   = "String(Object-Identifier)",
    2433             :                 .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.38",
    2434             :                 .oMSyntax               = 6,
    2435             :                 .attributeSyntax_oid    = "2.5.5.2",
    2436             :                 .drsuapi_to_ldb         = dsdb_syntax_OID_drsuapi_to_ldb,
    2437             :                 .ldb_to_drsuapi         = dsdb_syntax_OID_ldb_to_drsuapi,
    2438             :                 .validate_ldb           = dsdb_syntax_OID_validate_ldb,
    2439             :                 .equality               = "caseIgnoreMatch", /* Would use "objectIdentifierMatch" but most are ldap attribute/class names */
    2440             :                 .comment                = "OID String",
    2441             :                 .ldb_syntax             = LDB_SYNTAX_DIRECTORY_STRING
    2442             :         },{
    2443             :                 .name                   = "Enumeration",
    2444             :                 .ldap_oid               = LDB_SYNTAX_INTEGER,
    2445             :                 .oMSyntax               = 10,
    2446             :                 .attributeSyntax_oid    = "2.5.5.9",
    2447             :                 .drsuapi_to_ldb         = dsdb_syntax_INT32_drsuapi_to_ldb,
    2448             :                 .ldb_to_drsuapi         = dsdb_syntax_INT32_ldb_to_drsuapi,
    2449             :                 .validate_ldb           = dsdb_syntax_INT32_validate_ldb,
    2450             :                 .ldb_syntax             = LDB_SYNTAX_SAMBA_INT32,
    2451             :                 .auto_normalise         = true
    2452             :         },{
    2453             :         /* not used in w2k3 forest */
    2454             :                 .name                   = "String(Numeric)",
    2455             :                 .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.36",
    2456             :                 .oMSyntax               = 18,
    2457             :                 .attributeSyntax_oid    = "2.5.5.6",
    2458             :                 .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
    2459             :                 .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
    2460             :                 .validate_ldb           = dsdb_syntax_DATA_BLOB_validate_ldb,
    2461             :                 .equality               = "numericStringMatch",
    2462             :                 .substring              = "numericStringSubstringsMatch",
    2463             :                 .comment                = "Numeric String",
    2464             :                 .ldb_syntax             = LDB_SYNTAX_DIRECTORY_STRING,
    2465             :         },{
    2466             :                 .name                   = "String(Printable)",
    2467             :                 .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.44",
    2468             :                 .oMSyntax               = 19,
    2469             :                 .attributeSyntax_oid    = "2.5.5.5",
    2470             :                 .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
    2471             :                 .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
    2472             :                 .validate_ldb           = dsdb_syntax_DATA_BLOB_validate_ldb,
    2473             :                 .ldb_syntax             = LDB_SYNTAX_SAMBA_OCTET_STRING,
    2474             :         },{
    2475             :                 .name                   = "String(Teletex)",
    2476             :                 .ldap_oid               = "1.2.840.113556.1.4.905",
    2477             :                 .oMSyntax               = 20,
    2478             :                 .attributeSyntax_oid    = "2.5.5.4",
    2479             :                 .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
    2480             :                 .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
    2481             :                 .validate_ldb           = dsdb_syntax_DATA_BLOB_validate_ldb,
    2482             :                 .equality               = "caseIgnoreMatch",
    2483             :                 .substring              = "caseIgnoreSubstringsMatch",
    2484             :                 .comment                = "Case Insensitive String",
    2485             :                 .ldb_syntax             = LDB_SYNTAX_DIRECTORY_STRING,
    2486             :         },{
    2487             :                 .name                   = "String(IA5)",
    2488             :                 .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.26",
    2489             :                 .oMSyntax               = 22,
    2490             :                 .attributeSyntax_oid    = "2.5.5.5",
    2491             :                 .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
    2492             :                 .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
    2493             :                 .validate_ldb           = dsdb_syntax_DATA_BLOB_validate_ldb,
    2494             :                 .equality               = "caseExactIA5Match",
    2495             :                 .comment                = "Printable String",
    2496             :                 .ldb_syntax             = LDB_SYNTAX_SAMBA_OCTET_STRING,
    2497             :         },{
    2498             :                 .name                   = "String(UTC-Time)",
    2499             :                 .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.53",
    2500             :                 .oMSyntax               = 23,
    2501             :                 .attributeSyntax_oid    = "2.5.5.11",
    2502             :                 .drsuapi_to_ldb         = dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb,
    2503             :                 .ldb_to_drsuapi         = dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi,
    2504             :                 .validate_ldb           = dsdb_syntax_NTTIME_UTC_validate_ldb,
    2505             :                 .equality               = "generalizedTimeMatch",
    2506             :                 .comment                = "UTC Time",
    2507             :                 .auto_normalise         = true
    2508             :         },{
    2509             :                 .name                   = "String(Generalized-Time)",
    2510             :                 .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.24",
    2511             :                 .oMSyntax               = 24,
    2512             :                 .attributeSyntax_oid    = "2.5.5.11",
    2513             :                 .drsuapi_to_ldb         = dsdb_syntax_NTTIME_drsuapi_to_ldb,
    2514             :                 .ldb_to_drsuapi         = dsdb_syntax_NTTIME_ldb_to_drsuapi,
    2515             :                 .validate_ldb           = dsdb_syntax_NTTIME_validate_ldb,
    2516             :                 .equality               = "generalizedTimeMatch",
    2517             :                 .comment                = "Generalized Time",
    2518             :                 .auto_normalise         = true
    2519             :         },{
    2520             :         /* not used in w2k3 schema */
    2521             :                 .name                   = "String(Case Sensitive)",
    2522             :                 .ldap_oid               = "1.2.840.113556.1.4.1362",
    2523             :                 .oMSyntax               = 27,
    2524             :                 .attributeSyntax_oid    = "2.5.5.3",
    2525             :                 .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
    2526             :                 .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
    2527             :                 .validate_ldb           = dsdb_syntax_DATA_BLOB_validate_ldb,
    2528             :                 .equality               = "caseExactMatch",
    2529             :                 .substring              = "caseExactSubstringsMatch",
    2530             :                 /* TODO (kim): according to LDAP rfc we should be using same comparison
    2531             :                  * as Directory String (LDB_SYNTAX_DIRECTORY_STRING), but case sensitive.
    2532             :                  * But according to ms docs binary compare should do the job:
    2533             :                  * http://msdn.microsoft.com/en-us/library/cc223200(v=PROT.10).aspx */
    2534             :                 .ldb_syntax             = LDB_SYNTAX_SAMBA_OCTET_STRING,
    2535             :         },{
    2536             :                 .name                   = "String(Unicode)",
    2537             :                 .ldap_oid               = LDB_SYNTAX_DIRECTORY_STRING,
    2538             :                 .oMSyntax               = 64,
    2539             :                 .attributeSyntax_oid    = "2.5.5.12",
    2540             :                 .drsuapi_to_ldb         = dsdb_syntax_UNICODE_drsuapi_to_ldb,
    2541             :                 .ldb_to_drsuapi         = dsdb_syntax_UNICODE_ldb_to_drsuapi,
    2542             :                 .validate_ldb           = dsdb_syntax_UNICODE_validate_ldb,
    2543             :                 .equality               = "caseIgnoreMatch",
    2544             :                 .substring              = "caseIgnoreSubstringsMatch",
    2545             :                 .comment                = "Directory String",
    2546             :         },{
    2547             :                 .name                   = "Interval/LargeInteger",
    2548             :                 .ldap_oid               = "1.2.840.113556.1.4.906",
    2549             :                 .oMSyntax               = 65,
    2550             :                 .attributeSyntax_oid    = "2.5.5.16",
    2551             :                 .drsuapi_to_ldb         = dsdb_syntax_INT64_drsuapi_to_ldb,
    2552             :                 .ldb_to_drsuapi         = dsdb_syntax_INT64_ldb_to_drsuapi,
    2553             :                 .validate_ldb           = dsdb_syntax_INT64_validate_ldb,
    2554             :                 .equality               = "integerMatch",
    2555             :                 .comment                = "Large Integer",
    2556             :                 .ldb_syntax             = LDB_SYNTAX_ORDERED_INTEGER,
    2557             :                 .auto_normalise         = true
    2558             :         },{
    2559             :                 .name                   = "String(NT-Sec-Desc)",
    2560             :                 .ldap_oid               = LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR,
    2561             :                 .oMSyntax               = 66,
    2562             :                 .attributeSyntax_oid    = "2.5.5.15",
    2563             :                 .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
    2564             :                 .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
    2565             :                 .validate_ldb           = dsdb_syntax_DATA_BLOB_validate_ldb,
    2566             :         },{
    2567             :                 .name                   = "Object(DS-DN)",
    2568             :                 .ldap_oid               = LDB_SYNTAX_DN,
    2569             :                 .oMSyntax               = 127,
    2570             :                 .oMObjectClass          = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x4a"),
    2571             :                 .attributeSyntax_oid    = "2.5.5.1",
    2572             :                 .drsuapi_to_ldb         = dsdb_syntax_DN_drsuapi_to_ldb,
    2573             :                 .ldb_to_drsuapi         = dsdb_syntax_DN_ldb_to_drsuapi,
    2574             :                 .validate_ldb           = dsdb_syntax_DN_validate_ldb,
    2575             :                 .equality               = "distinguishedNameMatch",
    2576             :                 .comment                = "Object(DS-DN) == a DN",
    2577             :         },{
    2578             :                 .name                   = "Object(DN-Binary)",
    2579             :                 .ldap_oid               = DSDB_SYNTAX_BINARY_DN,
    2580             :                 .oMSyntax               = 127,
    2581             :                 .oMObjectClass          = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0b"),
    2582             :                 .attributeSyntax_oid    = "2.5.5.7",
    2583             :                 .drsuapi_to_ldb         = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
    2584             :                 .ldb_to_drsuapi         = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
    2585             :                 .validate_ldb           = dsdb_syntax_DN_BINARY_validate_ldb,
    2586             :                 .equality               = "octetStringMatch",
    2587             :                 .comment                = "OctetString: Binary+DN",
    2588             :         },{
    2589             :         /* not used in w2k3 schema, but used in Exchange schema*/
    2590             :                 .name                   = "Object(OR-Name)",
    2591             :                 .ldap_oid               = DSDB_SYNTAX_OR_NAME,
    2592             :                 .oMSyntax               = 127,
    2593             :                 .oMObjectClass          = OMOBJECTCLASS("\x56\x06\x01\x02\x05\x0b\x1D"),
    2594             :                 .attributeSyntax_oid    = "2.5.5.7",
    2595             :                 .drsuapi_to_ldb         = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
    2596             :                 .ldb_to_drsuapi         = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
    2597             :                 .validate_ldb           = dsdb_syntax_DN_validate_ldb,
    2598             :                 .equality               = "distinguishedNameMatch",
    2599             :                 .ldb_syntax             = LDB_SYNTAX_DN,
    2600             :         },{
    2601             :         /*
    2602             :          * TODO: verify if DATA_BLOB is correct here...!
    2603             :          *
    2604             :          *       repsFrom and repsTo are the only attributes using
    2605             :          *       this attribute syntax, but they're not replicated...
    2606             :          */
    2607             :                 .name                   = "Object(Replica-Link)",
    2608             :                 .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.40",
    2609             :                 .oMSyntax               = 127,
    2610             :                 .oMObjectClass          = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x06"),
    2611             :                 .attributeSyntax_oid    = "2.5.5.10",
    2612             :                 .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
    2613             :                 .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
    2614             :                 .validate_ldb           = dsdb_syntax_DATA_BLOB_validate_ldb,
    2615             :         },{
    2616             :                 .name                   = "Object(Presentation-Address)",
    2617             :                 .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.43",
    2618             :                 .oMSyntax               = 127,
    2619             :                 .oMObjectClass          = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x5c"),
    2620             :                 .attributeSyntax_oid    = "2.5.5.13",
    2621             :                 .drsuapi_to_ldb         = dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb,
    2622             :                 .ldb_to_drsuapi         = dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi,
    2623             :                 .validate_ldb           = dsdb_syntax_PRESENTATION_ADDRESS_validate_ldb,
    2624             :                 .comment                = "Presentation Address",
    2625             :                 .ldb_syntax             = LDB_SYNTAX_DIRECTORY_STRING,
    2626             :         },{
    2627             :         /* not used in w2k3 schema */
    2628             :                 .name                   = "Object(Access-Point)",
    2629             :                 .ldap_oid               = DSDB_SYNTAX_ACCESS_POINT,
    2630             :                 .oMSyntax               = 127,
    2631             :                 .oMObjectClass          = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x3e"),
    2632             :                 .attributeSyntax_oid    = "2.5.5.14",
    2633             :                 .drsuapi_to_ldb         = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
    2634             :                 .ldb_to_drsuapi         = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
    2635             :                 .validate_ldb           = dsdb_syntax_FOOBAR_validate_ldb,
    2636             :                 .ldb_syntax             = LDB_SYNTAX_DIRECTORY_STRING,
    2637             :         },{
    2638             :         /* not used in w2k3 schema */
    2639             :                 .name                   = "Object(DN-String)",
    2640             :                 .ldap_oid               = DSDB_SYNTAX_STRING_DN,
    2641             :                 .oMSyntax               = 127,
    2642             :                 .oMObjectClass          = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0c"),
    2643             :                 .attributeSyntax_oid    = "2.5.5.14",
    2644             :                 .drsuapi_to_ldb         = dsdb_syntax_DN_STRING_drsuapi_to_ldb,
    2645             :                 .ldb_to_drsuapi         = dsdb_syntax_DN_STRING_ldb_to_drsuapi,
    2646             :                 .validate_ldb           = dsdb_syntax_DN_STRING_validate_ldb,
    2647             :                 .equality               = "octetStringMatch",
    2648             :                 .comment                = "OctetString: String+DN",
    2649             :         }
    2650             : };
    2651             : 
    2652      184328 : const struct dsdb_syntax *find_syntax_map_by_ad_oid(const char *ad_oid)
    2653             : {
    2654       32978 :         unsigned int i;
    2655     1777830 :         for (i=0; i < ARRAY_SIZE(dsdb_syntaxes); i++) {
    2656     1777830 :                 if (strcasecmp(ad_oid, dsdb_syntaxes[i].attributeSyntax_oid) == 0) {
    2657      184328 :                         return &dsdb_syntaxes[i];
    2658             :                 }
    2659             :         }
    2660           0 :         return NULL;
    2661             : }
    2662             : 
    2663           0 : const struct dsdb_syntax *find_syntax_map_by_ad_syntax(int oMSyntax)
    2664             : {
    2665           0 :         unsigned int i;
    2666           0 :         for (i=0; i < ARRAY_SIZE(dsdb_syntaxes); i++) {
    2667           0 :                 if (oMSyntax == dsdb_syntaxes[i].oMSyntax) {
    2668           0 :                         return &dsdb_syntaxes[i];
    2669             :                 }
    2670             :         }
    2671           0 :         return NULL;
    2672             : }
    2673             : 
    2674          13 : const struct dsdb_syntax *find_syntax_map_by_standard_oid(const char *standard_oid)
    2675             : {
    2676          13 :         unsigned int i;
    2677         205 :         for (i=0; i < ARRAY_SIZE(dsdb_syntaxes); i++) {
    2678         202 :                 if (strcasecmp(standard_oid, dsdb_syntaxes[i].ldap_oid) == 0) {
    2679          10 :                         return &dsdb_syntaxes[i];
    2680             :                 }
    2681             :         }
    2682           0 :         return NULL;
    2683             : }
    2684             : 
    2685    39112674 : const struct dsdb_syntax *dsdb_syntax_for_attribute(const struct dsdb_attribute *attr)
    2686             : {
    2687      524540 :         unsigned int i;
    2688             : 
    2689   382051870 :         for (i=0; i < ARRAY_SIZE(dsdb_syntaxes); i++) {
    2690             :                 /*
    2691             :                  * We must pretend that userParameters was declared
    2692             :                  * binary string, so we can store the 'UTF16' (not
    2693             :                  * really string) structure as given over SAMR to samba
    2694             :                  */
    2695   382051870 :                 if (dsdb_syntaxes[i].userParameters &&
    2696    29892119 :                     (strcasecmp(attr->lDAPDisplayName, "userParameters") == 0))
    2697             :                 {
    2698       28012 :                         return &dsdb_syntaxes[i];
    2699             :                 }
    2700   382023858 :                 if (attr->oMSyntax != dsdb_syntaxes[i].oMSyntax) continue;
    2701             : 
    2702    40108460 :                 if (attr->oMObjectClass.length != dsdb_syntaxes[i].oMObjectClass.length) continue;
    2703             : 
    2704    39509004 :                 if (attr->oMObjectClass.length) {
    2705       75170 :                         int ret;
    2706     5510371 :                         ret = memcmp(attr->oMObjectClass.data,
    2707     5510371 :                                      dsdb_syntaxes[i].oMObjectClass.data,
    2708     5435201 :                                      attr->oMObjectClass.length);
    2709     5510371 :                         if (ret != 0) continue;
    2710             :                 }
    2711             : 
    2712    39368944 :                 if (strcmp(attr->attributeSyntax_oid, dsdb_syntaxes[i].attributeSyntax_oid) != 0) continue;
    2713             : 
    2714    39084662 :                 return &dsdb_syntaxes[i];
    2715             :         }
    2716             : 
    2717           0 :         return NULL;
    2718             : }
    2719             : 
    2720    10211715 : WERROR dsdb_attribute_drsuapi_remote_to_local(const struct dsdb_syntax_ctx *ctx,
    2721             :                                               enum drsuapi_DsAttributeId remote_attid_as_enum,
    2722             :                                               enum drsuapi_DsAttributeId *local_attid_as_enum,
    2723             :                                               const struct dsdb_attribute **_sa)
    2724             : {
    2725    10211715 :         TALLOC_CTX *frame = talloc_stackframe();
    2726           0 :         const struct dsdb_attribute *sa;
    2727           0 :         uint32_t attid_local;
    2728           0 :         bool ok;
    2729             : 
    2730    10211715 :         if (ctx->pfm_remote == NULL) {
    2731           0 :                 smb_panic(__location__);
    2732             :         }
    2733             : 
    2734    10211715 :         switch (dsdb_pfm_get_attid_type(remote_attid_as_enum)) {
    2735    10210979 :         case DSDB_ATTID_TYPE_PFM:
    2736             :                 /* map remote ATTID to local ATTID */
    2737    10210979 :                 ok = dsdb_syntax_attid_from_remote_attid(ctx, frame,
    2738             :                                                          remote_attid_as_enum,
    2739             :                                                          &attid_local);
    2740    10210979 :                 if (!ok) {
    2741           0 :                         DEBUG(0,(__location__ ": Can't find local ATTID for 0x%08X\n",
    2742             :                                  remote_attid_as_enum));
    2743           0 :                         TALLOC_FREE(frame);
    2744           0 :                         return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
    2745             :                 }
    2746    10210979 :                 break;
    2747         736 :         case DSDB_ATTID_TYPE_INTID:
    2748             :                 /* use IntId value directly */
    2749         736 :                 attid_local = remote_attid_as_enum;
    2750         736 :                 break;
    2751           0 :         default:
    2752             :                 /* we should never get here */
    2753           0 :                 DEBUG(0,(__location__ ": Invalid ATTID type passed for conversion - 0x%08X\n",
    2754             :                          remote_attid_as_enum));
    2755           0 :                 TALLOC_FREE(frame);
    2756           0 :                 return WERR_INVALID_PARAMETER;
    2757             :         }
    2758             : 
    2759    10211715 :         sa = dsdb_attribute_by_attributeID_id(ctx->schema, attid_local);
    2760    10211715 :         if (!sa) {
    2761           3 :                 int dbg_level = ctx->schema->resolving_in_progress ? 10 : 0;
    2762           3 :                 DEBUG(dbg_level,(__location__ ": Unknown local attributeID_id 0x%08X remote 0x%08X%s\n",
    2763             :                       attid_local, remote_attid_as_enum,
    2764             :                       ctx->schema->resolving_in_progress ? "resolving in progress" : ""));
    2765           3 :                 TALLOC_FREE(frame);
    2766           3 :                 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
    2767             :         }
    2768             : 
    2769             :         /*
    2770             :          * We return the same class of attid as we were given.  That
    2771             :          * is, we trust the remote server not to use an
    2772             :          * msDS-IntId value in the schema partition
    2773             :          */
    2774    10211712 :         if (local_attid_as_enum != NULL) {
    2775    10209833 :                 *local_attid_as_enum = (enum drsuapi_DsAttributeId)attid_local;
    2776             :         }
    2777             : 
    2778    10211712 :         if (_sa != NULL) {
    2779     9636166 :                 *_sa = sa;
    2780             :         }
    2781             : 
    2782    10211712 :         TALLOC_FREE(frame);
    2783    10211712 :         return WERR_OK;
    2784             : }
    2785             : 
    2786     9635192 : WERROR dsdb_attribute_drsuapi_to_ldb(struct ldb_context *ldb,
    2787             :                                      const struct dsdb_schema *schema,
    2788             :                                      const struct dsdb_schema_prefixmap *pfm_remote,
    2789             :                                      const struct drsuapi_DsReplicaAttribute *in,
    2790             :                                      TALLOC_CTX *mem_ctx,
    2791             :                                      struct ldb_message_element *out,
    2792             :                                      enum drsuapi_DsAttributeId *local_attid_as_enum)
    2793             : {
    2794           0 :         struct dsdb_syntax_ctx syntax_ctx;
    2795     9635192 :         const struct dsdb_attribute *sa = NULL;
    2796           0 :         WERROR werr;
    2797             : 
    2798             :         /* use default syntax conversion context */
    2799     9635192 :         dsdb_syntax_ctx_init(&syntax_ctx, ldb, schema);
    2800     9635192 :         syntax_ctx.pfm_remote = pfm_remote;
    2801             : 
    2802     9635192 :         werr = dsdb_attribute_drsuapi_remote_to_local(&syntax_ctx,
    2803     9635192 :                                                       in->attid,
    2804             :                                                       local_attid_as_enum,
    2805             :                                                       &sa);
    2806     9635192 :         if (!W_ERROR_IS_OK(werr)) {
    2807           0 :                 return werr;
    2808             :         }
    2809             : 
    2810     9635192 :         return sa->syntax->drsuapi_to_ldb(&syntax_ctx, sa, in, mem_ctx, out);
    2811             : }

Generated by: LCOV version 1.14