Ignore:
Timestamp:
Nov 14, 2012, 12:59:34 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to 3.6.0

Location:
vendor/current/source4/dsdb/schema
Files:
7 added
8 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source4/dsdb/schema/schema.h

    r414 r740  
    2323#define _DSDB_SCHEMA_H
    2424
     25#include "prefixmap.h"
     26
    2527struct dsdb_attribute;
    2628struct dsdb_class;
    2729struct dsdb_schema;
     30struct dsdb_dn;
     31
     32struct dsdb_syntax_ctx {
     33        struct ldb_context *ldb;
     34        const struct dsdb_schema *schema;
     35
     36        /* set when converting objects under Schema NC */
     37        bool is_schema_nc;
     38
     39        /* remote prefixMap to be used for drsuapi_to_ldb conversions */
     40        const struct dsdb_schema_prefixmap *pfm_remote;
     41};
     42
    2843
    2944struct dsdb_syntax {
     
    3853        const char *ldb_syntax;
    3954
    40         WERROR (*drsuapi_to_ldb)(struct ldb_context *ldb,
    41                                  const struct dsdb_schema *schema,
     55        WERROR (*drsuapi_to_ldb)(const struct dsdb_syntax_ctx *ctx,
    4256                                 const struct dsdb_attribute *attr,
    4357                                 const struct drsuapi_DsReplicaAttribute *in,
    4458                                 TALLOC_CTX *mem_ctx,
    4559                                 struct ldb_message_element *out);
    46         WERROR (*ldb_to_drsuapi)(struct ldb_context *ldb,
    47                                  const struct dsdb_schema *schema,
     60        WERROR (*ldb_to_drsuapi)(const struct dsdb_syntax_ctx *ctx,
    4861                                 const struct dsdb_attribute *attr,
    4962                                 const struct ldb_message_element *in,
    5063                                 TALLOC_CTX *mem_ctx,
    5164                                 struct drsuapi_DsReplicaAttribute *out);
     65        WERROR (*validate_ldb)(const struct dsdb_syntax_ctx *ctx,
     66                               const struct dsdb_attribute *attr,
     67                               const struct ldb_message_element *in);
    5268};
    5369
     
    6177        struct GUID schemaIDGUID;
    6278        uint32_t mAPIID;
     79        uint32_t msDS_IntId;
    6380
    6481        struct GUID attributeSecurityGUID;
     82        struct GUID objectGUID;
    6583
    6684        uint32_t searchFlags;
     
    103121        uint32_t governsID_id;
    104122        struct GUID schemaIDGUID;
     123        struct GUID objectGUID;
    105124
    106125        uint32_t objectClassCategory;
     
    120139        const char **mayContain;
    121140        const char **possibleInferiors;
     141        const char **systemPossibleInferiors;
    122142
    123143        const char *defaultSecurityDescriptor;
     
    134154        bool systemOnly;
    135155
    136         char **supclasses;
    137         char **subclasses;
    138         char **subclasses_direct;
    139         char **posssuperiors;
     156        const char **supclasses;
     157        const char **subclasses;
     158        const char **subclasses_direct;
     159        const char **posssuperiors;
    140160        uint32_t subClassOf_id;
    141161        uint32_t *systemAuxiliaryClass_ids;
     
    156176};
    157177
    158 struct dsdb_schema_oid_prefix {
    159         uint32_t id;
    160         const char *oid;
    161         size_t oid_len;
    162 };
     178/**
     179 * data stored in schemaInfo attribute
     180 */
     181struct dsdb_schema_info {
     182        uint32_t        revision;
     183        struct GUID     invocation_id;
     184};
     185
    163186
    164187struct dsdb_schema {
    165         uint32_t num_prefixes;
    166         struct dsdb_schema_oid_prefix *prefixes;
     188        struct ldb_dn *base_dn;
     189
     190        struct dsdb_schema_prefixmap *prefixmap;
    167191
    168192        /*
     
    176200        const char *schema_info;
    177201
     202        /* We can also tell the schema version from the USN on the partition */
     203        uint64_t loaded_usn;
     204
    178205        struct dsdb_attribute *attributes;
    179206        struct dsdb_class *classes;
     
    193220        struct dsdb_attribute **attributes_by_attributeID_oid;
    194221        struct dsdb_attribute **attributes_by_linkID;
     222        uint32_t num_int_id_attr;
     223        struct dsdb_attribute **attributes_by_msDS_IntId;
    195224
    196225        struct {
     
    199228        } fsmo;
    200229
    201         struct smb_iconv_convenience *iconv_convenience;
     230        /* Was this schema loaded from ldb (if so, then we will reload it when we detect a change in ldb) */
     231        struct ldb_module *loaded_from_module;
     232        struct dsdb_schema *(*refresh_fn)(struct ldb_module *module, struct dsdb_schema *schema, bool is_global_schema);
     233        bool refresh_in_progress;
     234        /* an 'opaque' sequence number that the reload function may also wish to use */
     235        uint64_t reload_seq_number;
     236
     237        /* Should the syntax handlers in this case handle all incoming OIDs automatically, assigning them as an OID if no text name is known? */
     238        bool relax_OID_conversions;
    202239};
    203240
  • vendor/current/source4/dsdb/schema/schema_convert_to_ol.c

    r414 r740  
    6363                        .values = &objectclass_name_as_ldb_val
    6464                };
    65                 int j;
    66                 int attr_idx;
     65                unsigned int j;
     66                unsigned int attr_idx;
    6767               
    6868                if (!mem_ctx) {
     
    8888                        if (strcasecmp(name, attr_map[j].old_attr) == 0) {
    8989                                name =  attr_map[j].new_attr;
     90                                break;
     91                        }
     92                }
     93               
     94                /* We might have been asked to remap this subClassOf, due to a conflict */
     95                for (j=0; subClassOf && attr_map && attr_map[j].old_attr; j++) {
     96                        if (strcasecmp(subClassOf, attr_map[j].old_attr) == 0) {
     97                                subClassOf =  attr_map[j].new_attr;
    9098                                break;
    9199                        }
     
    176184        char *out;
    177185        const char **attrs_skip = NULL;
    178         int num_skip = 0;
     186        unsigned int num_skip = 0;
    179187        struct oid_map *oid_map = NULL;
    180         int num_oid_maps = 0;
     188        unsigned int num_oid_maps = 0;
    181189        struct attr_map *attr_map = NULL;
    182         int num_attr_maps = 0; 
     190        unsigned int num_attr_maps = 0;
    183191        struct dsdb_attribute *attribute;
    184192        struct dsdb_schema *schema;
     
    254262        }
    255263
    256         schema = dsdb_get_schema(ldb);
     264        schema = dsdb_get_schema(ldb, mem_ctx);
    257265        if (!schema) {
    258266                DEBUG(0, ("No schema on ldb to convert!\n"));
     
    277285
    278286                char *schema_entry = NULL;
    279                 int j;
     287                unsigned int j;
    280288
    281289                /* We have been asked to skip some attributes/objectClasses */
  • vendor/current/source4/dsdb/schema/schema_description.c

    r414 r740  
    178178#define APPEND_ATTRS(attributes)                                \
    179179        do {                                                            \
    180                 int k;                                                  \
     180                unsigned int k;                                         \
    181181                for (k=0; attributes && attributes[k]; k++) {           \
    182182                        const char *attr_name = attributes[k];          \
     
    343343                                     const struct dsdb_schema *schema)
    344344{
    345         int i;
     345        unsigned int i;
    346346        char *schema_description;
    347347        const char **aux_class_list = NULL;
  • vendor/current/source4/dsdb/schema/schema_inferiors.c

    r414 r740  
    11/*
    2    Unix SMB/CIFS mplementation.
     2   Unix SMB/CIFS implementation.
    33
    44   implement possibleInferiors calculation
     
    3535  create the SUPCLASSES() list
    3636 */
    37 static char **schema_supclasses(struct dsdb_schema *schema, struct dsdb_class *schema_class)
    38 {
    39         char **list;
     37static const char **schema_supclasses(const struct dsdb_schema *schema,
     38                                      struct dsdb_class *schema_class)
     39{
     40        const char **list;
    4041
    4142        if (schema_class->supclasses) {
     
    4344        }
    4445
    45         list = str_list_make_empty(schema_class);
     46        list = const_str_list(str_list_make_empty(schema_class));
    4647        if (list == NULL) {
    4748                DEBUG(0,(__location__ " out of memory\n"));
     
    4950        }
    5051
    51         /* Cope with 'top SUP top', ie top is subClassOf top */
     52        /* Cope with 'top SUP top', i.e. top is subClassOf top */
    5253        if (schema_class->subClassOf &&
    5354            strcmp(schema_class->lDAPDisplayName, schema_class->subClassOf) == 0) {
     
    5758
    5859        if (schema_class->subClassOf) {
     60                const struct dsdb_class *schema_class2 = dsdb_class_by_lDAPDisplayName(schema, schema_class->subClassOf);
    5961                const char **list2;
    60                 list = str_list_add_const(list, schema_class->subClassOf);
    61 
    62                 list2 = schema_supclasses(schema, 
    63                                           discard_const_p(struct dsdb_class,
    64                                                           dsdb_class_by_lDAPDisplayName(schema,
    65                                                                                         schema_class->subClassOf)));
     62                list = str_list_add_const(list, schema_class->subClassOf);
     63
     64                list2 = schema_supclasses(schema, discard_const_p(struct dsdb_class, schema_class2));
    6665                list = str_list_append_const(list, list2);
    6766        }
    6867
    6968        schema_class->supclasses = str_list_unique(list);
    70        
    71         return list;
     69
     70        return schema_class->supclasses;
    7271}
    7372
     
    7675  matches SUBCLASSES() python function
    7776 */
    78 static char **schema_subclasses(struct dsdb_schema *schema, TALLOC_CTX *mem_ctx, char **oclist)
    79 {
    80         char **list = str_list_make_empty(mem_ctx);
    81         int i;
     77static const char **schema_subclasses(const struct dsdb_schema *schema,
     78                                      TALLOC_CTX *mem_ctx,
     79                                      const char **oclist)
     80{
     81        const char **list = const_str_list(str_list_make_empty(mem_ctx));
     82        unsigned int i;
    8283
    8384        for (i=0; oclist && oclist[i]; i++) {
    84                 struct dsdb_class *schema_class = dsdb_class_by_lDAPDisplayName(schema, oclist[i]);
     85                const struct dsdb_class *schema_class = dsdb_class_by_lDAPDisplayName(schema, oclist[i]);
    8586                if (!schema_class) {
    8687                        DEBUG(0, ("ERROR: Unable to locate subClass: '%s'\n", oclist[i]));
     
    9697   equivalent of the POSSSUPERIORS() python function
    9798 */
    98 static char **schema_posssuperiors(struct dsdb_schema *schema,
    99                                   struct dsdb_class *schema_class)
     99static const char **schema_posssuperiors(const struct dsdb_schema *schema,
     100                                        struct dsdb_class *schema_class)
    100101{
    101102        if (schema_class->posssuperiors == NULL) {
    102                 char **list2 = str_list_make_empty(schema_class);
    103                 char **list3;
    104                 int i;
     103                const char **list2 = const_str_list(str_list_make_empty(schema_class));
     104                const char **list3;
     105                unsigned int i;
    105106
    106107                list2 = str_list_append_const(list2, schema_class->systemPossSuperiors);
     
    108109                list3 = schema_supclasses(schema, schema_class);
    109110                for (i=0; list3 && list3[i]; i++) {
    110                         struct dsdb_class *class2 = dsdb_class_by_lDAPDisplayName(schema, list3[i]);
     111                        const struct dsdb_class *class2 = dsdb_class_by_lDAPDisplayName(schema, list3[i]);
    111112                        if (!class2) {
    112113                                DEBUG(0, ("ERROR: Unable to locate supClass: '%s'\n", list3[i]));
    113114                                continue;
    114115                        }
    115                         list2 = str_list_append_const(list2, schema_posssuperiors(schema, class2));
     116                        list2 = str_list_append_const(list2, schema_posssuperiors(schema,
     117                                discard_const_p(struct dsdb_class, class2)));
    116118                }
    117119                list2 = str_list_append_const(list2, schema_subclasses(schema, list2, list2));
     
    123125}
    124126
    125 static char **schema_subclasses_recurse(struct dsdb_schema *schema, struct dsdb_class *schema_class)
    126 {
    127         char **list = str_list_copy_const(schema_class, schema_class->subclasses_direct);
    128         int i;
     127static const char **schema_subclasses_recurse(const struct dsdb_schema *schema,
     128                                              struct dsdb_class *schema_class)
     129{
     130        const char **list = str_list_copy_const(schema_class, schema_class->subclasses_direct);
     131        unsigned int i;
    129132        for (i=0;list && list[i]; i++) {
    130                 struct dsdb_class *schema_class2 = dsdb_class_by_lDAPDisplayName(schema, list[i]);
     133                const struct dsdb_class *schema_class2 = dsdb_class_by_lDAPDisplayName(schema, list[i]);
    131134                if (schema_class != schema_class2) {
    132                         list = str_list_append_const(list, schema_subclasses_recurse(schema, schema_class2));
     135                        list = str_list_append_const(list, schema_subclasses_recurse(schema,
     136                                discard_const_p(struct dsdb_class, schema_class2)));
    133137                }
    134138        }
     
    138142/* Walk down the subClass tree, setting a higher index as we go down
    139143 * each level.  top is 1, subclasses of top are 2, etc */
    140 void schema_subclasses_order_recurse(struct dsdb_schema *schema, struct dsdb_class *schema_class, int order)
     144void schema_subclasses_order_recurse(const struct dsdb_schema *schema,
     145                                     struct dsdb_class *schema_class,
     146                                     const int order)
    141147{
    142148        const char **list = schema_class->subclasses_direct;
    143         int i;
     149        unsigned int i;
    144150        schema_class->subClass_order = order;
    145151        for (i=0;list && list[i]; i++) {
    146                 struct dsdb_class *schema_class2 = dsdb_class_by_lDAPDisplayName(schema, list[i]);
    147                 schema_subclasses_order_recurse(schema, schema_class2, order+1);
     152                const struct dsdb_class *schema_class2 = dsdb_class_by_lDAPDisplayName(schema, list[i]);
     153                schema_subclasses_order_recurse(schema, discard_const_p(struct dsdb_class, schema_class2), order+1);
    148154        }
    149155        return;
    150156}
    151157
    152 static void schema_create_subclasses(struct dsdb_schema *schema)
    153 {
    154         struct dsdb_class *schema_class;
     158static int schema_create_subclasses(const struct dsdb_schema *schema)
     159{
     160        struct dsdb_class *schema_class, *top;
    155161
    156162        for (schema_class=schema->classes; schema_class; schema_class=schema_class->next) {
    157                 struct dsdb_class *schema_class2 = dsdb_class_by_lDAPDisplayName(schema, schema_class->subClassOf);
     163                struct dsdb_class *schema_class2 = discard_const_p(struct dsdb_class,
     164                        dsdb_class_by_lDAPDisplayName(schema, schema_class->subClassOf));
    158165                if (schema_class2 == NULL) {
    159                         DEBUG(0,("ERROR: no subClassOf for '%s'\n", schema_class->lDAPDisplayName));
    160                         continue;
     166                        DEBUG(0,("ERROR: no subClassOf '%s' for '%s'\n",
     167                                 schema_class->subClassOf,
     168                                 schema_class->lDAPDisplayName));
     169                        return LDB_ERR_OPERATIONS_ERROR;
    161170                }
    162171                if (schema_class2 && schema_class != schema_class2) {
    163172                        if (schema_class2->subclasses_direct == NULL) {
    164                                 schema_class2->subclasses_direct = str_list_make_empty(schema_class2);
    165                         }
    166                         schema_class2->subclasses_direct = str_list_add_const(schema_class2->subclasses_direct,
    167                                                                         schema_class->lDAPDisplayName);
     173                                schema_class2->subclasses_direct = const_str_list(str_list_make_empty(schema_class2));
     174                                if (!schema_class2->subclasses_direct) {
     175                                        return LDB_ERR_OPERATIONS_ERROR;
     176                                }
     177                        }
     178                        schema_class2->subclasses_direct = str_list_add_const(schema_class2->subclasses_direct,
     179                                                schema_class->lDAPDisplayName);
    168180                }
    169181        }
     
    172184                schema_class->subclasses = str_list_unique(schema_subclasses_recurse(schema, schema_class));
    173185
    174                 /* Initilise the subClass order, to ensure we can't have uninitilised sort on the subClass hirarchy */
     186                /* Initialize the subClass order, to ensure we can't have uninitialized sort on the subClass hierarchy */
    175187                schema_class->subClass_order = 0;
    176188        }
    177189
    178         schema_subclasses_order_recurse(schema, dsdb_class_by_lDAPDisplayName(schema, "top"), 1);
    179 }
    180 
    181 static void schema_fill_possible_inferiors(struct dsdb_schema *schema, struct dsdb_class *schema_class)
     190        top = discard_const_p(struct dsdb_class, dsdb_class_by_lDAPDisplayName(schema, "top"));
     191        if (!top) {
     192                DEBUG(0,("ERROR: no 'top' class in loaded schema\n"));
     193                return LDB_ERR_OPERATIONS_ERROR;
     194        }
     195
     196        schema_subclasses_order_recurse(schema, top, 1);
     197        return LDB_SUCCESS;
     198}
     199
     200static void schema_fill_possible_inferiors(const struct dsdb_schema *schema,
     201                                           struct dsdb_class *schema_class)
    182202{
    183203        struct dsdb_class *c2;
    184204
    185205        for (c2=schema->classes; c2; c2=c2->next) {
    186                 char **superiors = schema_posssuperiors(schema, c2);
     206                const char **superiors = schema_posssuperiors(schema, c2);
    187207                if (c2->systemOnly == false
    188208                    && c2->objectClassCategory != 2
     
    190210                    && str_list_check(superiors, schema_class->lDAPDisplayName)) {
    191211                        if (schema_class->possibleInferiors == NULL) {
    192                                 schema_class->possibleInferiors = str_list_make_empty(schema_class);
     212                                schema_class->possibleInferiors = const_str_list(str_list_make_empty(schema_class));
    193213                        }
    194214                        schema_class->possibleInferiors = str_list_add_const(schema_class->possibleInferiors,
    195                                                                        c2->lDAPDisplayName);
     215                                                        c2->lDAPDisplayName);
    196216                }
    197217        }
     
    199219}
    200220
     221static void schema_fill_system_possible_inferiors(const struct dsdb_schema *schema,
     222                                                  struct dsdb_class *schema_class)
     223{
     224        struct dsdb_class *c2;
     225
     226        for (c2=schema->classes; c2; c2=c2->next) {
     227                const char **superiors = schema_posssuperiors(schema, c2);
     228                if (c2->objectClassCategory != 2
     229                    && c2->objectClassCategory != 3
     230                    && str_list_check(superiors, schema_class->lDAPDisplayName)) {
     231                        if (schema_class->systemPossibleInferiors == NULL) {
     232                                schema_class->systemPossibleInferiors = const_str_list(str_list_make_empty(schema_class));
     233                        }
     234                        schema_class->systemPossibleInferiors = str_list_add_const(schema_class->systemPossibleInferiors,
     235                                                        c2->lDAPDisplayName);
     236                }
     237        }
     238        schema_class->systemPossibleInferiors = str_list_unique(schema_class->systemPossibleInferiors);
     239}
     240
    201241/*
    202242  fill in a string class name from a governs_ID
    203243 */
    204 static void schema_fill_from_class_one(struct dsdb_schema *schema, struct dsdb_class *c,
    205                                     const char **s, uint32_t id)
     244static void schema_fill_from_class_one(const struct dsdb_schema *schema,
     245                                       const struct dsdb_class *c,
     246                                       const char **s,
     247                                       const uint32_t id)
    206248{
    207249        if (*s == NULL && id != 0) {
    208                 struct dsdb_class *c2 = dsdb_class_by_governsID_id(schema, id);
     250                const struct dsdb_class *c2 =
     251                                        dsdb_class_by_governsID_id(schema, id);
    209252                if (c2) {
    210253                        *s = c2->lDAPDisplayName;
     
    216259  fill in a list of string class names from a governs_ID list
    217260 */
    218 static void schema_fill_from_class_list(struct dsdb_schema *schema, struct dsdb_class *c,
    219                                      const char ***s, uint32_t *ids)
     261static void schema_fill_from_class_list(const struct dsdb_schema *schema,
     262                                        const struct dsdb_class *c,
     263                                        const char ***s,
     264                                        const uint32_t *ids)
    220265{
    221266        if (*s == NULL && ids != NULL) {
    222                 int i;
     267                unsigned int i;
    223268                for (i=0;ids[i];i++) ;
    224269                *s = talloc_array(c, const char *, i+1);
    225270                for (i=0;ids[i];i++) {
    226                         struct dsdb_class *c2 = dsdb_class_by_governsID_id(schema, ids[i]);
     271                        const struct dsdb_class *c2 =
     272                                dsdb_class_by_governsID_id(schema, ids[i]);
    227273                        if (c2) {
    228274                                (*s)[i] = c2->lDAPDisplayName;
     
    238284  fill in a list of string attribute names from a attributeID list
    239285 */
    240 static void schema_fill_from_attribute_list(struct dsdb_schema *schema, struct dsdb_class *c,
    241                                             const char ***s, uint32_t *ids)
     286static void schema_fill_from_attribute_list(const struct dsdb_schema *schema,
     287                                            const struct dsdb_class *c,
     288                                            const char ***s,
     289                                            const uint32_t *ids)
    242290{
    243291        if (*s == NULL && ids != NULL) {
    244                 int i;
     292                unsigned int i;
    245293                for (i=0;ids[i];i++) ;
    246294                *s = talloc_array(c, const char *, i+1);
    247295                for (i=0;ids[i];i++) {
    248                         struct dsdb_attribute *a = dsdb_attribute_by_attributeID_id(schema, ids[i]);
     296                        const struct dsdb_attribute *a =
     297                                dsdb_attribute_by_attributeID_id(schema, ids[i]);
    249298                        if (a) {
    250299                                (*s)[i] = a->lDAPDisplayName;
     
    260309  if the schema came from DRS then some attributes will be setup as IDs
    261310 */
    262 static void schema_fill_from_ids(struct dsdb_schema *schema)
     311static void schema_fill_from_ids(const struct dsdb_schema *schema)
    263312{
    264313        struct dsdb_class *c;
     
    276325}
    277326
    278 void schema_fill_constructed(struct dsdb_schema *schema)
    279 {
     327int schema_fill_constructed(const struct dsdb_schema *schema)
     328{
     329        int ret;
    280330        struct dsdb_class *schema_class;
    281331
    282332        schema_fill_from_ids(schema);
    283333
    284         schema_create_subclasses(schema);
     334        ret = schema_create_subclasses(schema);
     335        if (ret != LDB_SUCCESS) {
     336                return ret;
     337        }
    285338
    286339        for (schema_class=schema->classes; schema_class; schema_class=schema_class->next) {
    287340                schema_fill_possible_inferiors(schema, schema_class);
     341                schema_fill_system_possible_inferiors(schema, schema_class);
    288342        }
    289343
     
    299353                schema_class->posssuperiors = NULL;
    300354        }
    301 }
     355
     356        return LDB_SUCCESS;
     357}
  • vendor/current/source4/dsdb/schema/schema_init.c

    r414 r740  
    2323#include "includes.h"
    2424#include "dsdb/samdb/samdb.h"
    25 #include "lib/ldb/include/ldb_errors.h"
     25#include "dsdb/common/util.h"
     26#include <ldb_errors.h>
    2627#include "../lib/util/dlinklist.h"
    2728#include "librpc/gen_ndr/ndr_misc.h"
     
    2930#include "librpc/gen_ndr/ndr_drsblobs.h"
    3031#include "param/param.h"
    31 #include "lib/ldb/include/ldb_module.h"
    32 
    33 struct dsdb_schema *dsdb_new_schema(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience)
     32#include <ldb_module.h>
     33#include "../lib/util/asn1.h"
     34
     35
     36struct dsdb_schema *dsdb_new_schema(TALLOC_CTX *mem_ctx)
    3437{
    3538        struct dsdb_schema *schema = talloc_zero(mem_ctx, struct dsdb_schema);
     
    3841        }
    3942
    40         schema->iconv_convenience = iconv_convenience;
    4143        return schema;
    4244}
    4345
    44 
    45 WERROR dsdb_load_oid_mappings_drsuapi(struct dsdb_schema *schema, const struct drsuapi_DsReplicaOIDMapping_Ctr *ctr)
    46 {
    47         uint32_t i,j;
    48 
    49         schema->prefixes = talloc_array(schema, struct dsdb_schema_oid_prefix, ctr->num_mappings);
    50         W_ERROR_HAVE_NO_MEMORY(schema->prefixes);
    51 
    52         for (i=0, j=0; i < ctr->num_mappings; i++) {
    53                 if (ctr->mappings[i].oid.oid == NULL) {
    54                         return WERR_INVALID_PARAM;
     46struct dsdb_schema *dsdb_schema_copy_shallow(TALLOC_CTX *mem_ctx,
     47                                             struct ldb_context *ldb,
     48                                             const struct dsdb_schema *schema)
     49{
     50        int ret;
     51        struct dsdb_class *cls;
     52        struct dsdb_attribute *attr;
     53        struct dsdb_schema *schema_copy;
     54
     55        schema_copy = dsdb_new_schema(mem_ctx);
     56        if (!schema_copy) {
     57                return NULL;
     58        }
     59
     60        /* schema base_dn */
     61        schema_copy->base_dn = ldb_dn_copy(schema_copy, schema->base_dn);
     62        if (!schema_copy->base_dn) {
     63                goto failed;
     64        }
     65
     66        /* copy prexiMap & schemaInfo */
     67        schema_copy->prefixmap = dsdb_schema_pfm_copy_shallow(schema_copy,
     68                                                              schema->prefixmap);
     69        if (!schema_copy->prefixmap) {
     70                goto failed;
     71        }
     72
     73        schema_copy->schema_info = talloc_strdup(schema_copy, schema->schema_info);
     74
     75        /* copy classes and attributes*/
     76        for (cls = schema->classes; cls; cls = cls->next) {
     77                struct dsdb_class *class_copy = talloc_memdup(schema_copy,
     78                                                              cls, sizeof(*cls));
     79                if (!class_copy) {
     80                        goto failed;
    5581                }
    56 
    57                 if (strncasecmp(ctr->mappings[i].oid.oid, "ff", 2) == 0) {
    58                         if (ctr->mappings[i].id_prefix != 0) {
    59                                 return WERR_INVALID_PARAM;
    60                         }
    61 
    62                         /* the magic value should be in the last array member */
    63                         if (i != (ctr->num_mappings - 1)) {
    64                                 return WERR_INVALID_PARAM;
    65                         }
    66 
    67                         if (ctr->mappings[i].oid.__ndr_size != 21) {
    68                                 return WERR_INVALID_PARAM;
    69                         }
    70 
    71                         schema->schema_info = talloc_strdup(schema, ctr->mappings[i].oid.oid);
    72                         W_ERROR_HAVE_NO_MEMORY(schema->schema_info);
    73                 } else {
    74                         /* the last array member should contain the magic value not a oid */
    75                         if (i == (ctr->num_mappings - 1)) {
    76                                 return WERR_INVALID_PARAM;
    77                         }
    78 
    79                         schema->prefixes[j].id  = ctr->mappings[i].id_prefix<<16;
    80                         schema->prefixes[j].oid = talloc_asprintf(schema->prefixes, "%s.",
    81                                                                   ctr->mappings[i].oid.oid);
    82                         W_ERROR_HAVE_NO_MEMORY(schema->prefixes[j].oid);
    83                         schema->prefixes[j].oid_len = strlen(schema->prefixes[j].oid);
    84                         j++;
     82                DLIST_ADD(schema_copy->classes, class_copy);
     83        }
     84        schema_copy->num_classes = schema->num_classes;
     85
     86        for (attr = schema->attributes; attr; attr = attr->next) {
     87                struct dsdb_attribute *a_copy = talloc_memdup(schema_copy,
     88                                                              attr, sizeof(*attr));
     89                if (!a_copy) {
     90                        goto failed;
    8591                }
    86         }
    87 
    88         schema->num_prefixes = j;
     92                DLIST_ADD(schema_copy->attributes, a_copy);
     93        }
     94        schema_copy->num_attributes = schema->num_attributes;
     95
     96        /* rebuild indexes */
     97        ret = dsdb_setup_sorted_accessors(ldb, schema_copy);
     98        if (ret != LDB_SUCCESS) {
     99                goto failed;
     100        }
     101
     102        /* leave reload_seq_number = 0 so it will be refresh ASAP */
     103        schema_copy->refresh_fn = schema->refresh_fn;
     104        schema_copy->loaded_from_module = schema->loaded_from_module;
     105
     106        return schema_copy;
     107
     108failed:
     109        talloc_free(schema_copy);
     110        return NULL;
     111}
     112
     113
     114WERROR dsdb_load_prefixmap_from_drsuapi(struct dsdb_schema *schema,
     115                                        const struct drsuapi_DsReplicaOIDMapping_Ctr *ctr)
     116{
     117        WERROR werr;
     118        const char *schema_info;
     119        struct dsdb_schema_prefixmap *pfm;
     120
     121        werr = dsdb_schema_pfm_from_drsuapi_pfm(ctr, true, schema, &pfm, &schema_info);
     122        W_ERROR_NOT_OK_RETURN(werr);
     123
     124        /* set loaded prefixMap */
     125        talloc_free(schema->prefixmap);
     126        schema->prefixmap = pfm;
     127
     128        talloc_free(discard_const(schema->schema_info));
     129        schema->schema_info = schema_info;
     130
    89131        return WERR_OK;
     132}
     133
     134static WERROR _dsdb_prefixmap_from_ldb_val(const struct ldb_val *pfm_ldb_val,
     135                                           TALLOC_CTX *mem_ctx,
     136                                           struct dsdb_schema_prefixmap **_pfm)
     137{
     138        WERROR werr;
     139        enum ndr_err_code ndr_err;
     140        struct prefixMapBlob pfm_blob;
     141
     142        TALLOC_CTX *temp_ctx = talloc_new(mem_ctx);
     143        W_ERROR_HAVE_NO_MEMORY(temp_ctx);
     144
     145        ndr_err = ndr_pull_struct_blob(pfm_ldb_val, temp_ctx,
     146                                &pfm_blob,
     147                                (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob);
     148        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     149                NTSTATUS nt_status = ndr_map_error2ntstatus(ndr_err);
     150                DEBUG(0,("_dsdb_prefixmap_from_ldb_val: Failed to parse prefixmap of length %u: %s\n",
     151                         (unsigned int)pfm_ldb_val->length, ndr_map_error2string(ndr_err)));
     152                talloc_free(temp_ctx);
     153                return ntstatus_to_werror(nt_status);
     154        }
     155
     156        if (pfm_blob.version != PREFIX_MAP_VERSION_DSDB) {
     157                DEBUG(0,("_dsdb_prefixmap_from_ldb_val: pfm_blob->version %u incorrect\n", (unsigned int)pfm_blob.version));
     158                talloc_free(temp_ctx);
     159                return WERR_VERSION_PARSE_ERROR;
     160        }
     161
     162        /* call the drsuapi version */
     163        werr = dsdb_schema_pfm_from_drsuapi_pfm(&pfm_blob.ctr.dsdb, false, mem_ctx, _pfm, NULL);
     164        if (!W_ERROR_IS_OK(werr)) {
     165                DEBUG(0, (__location__ " dsdb_schema_pfm_from_drsuapi_pfm failed: %s\n", win_errstr(werr)));
     166                talloc_free(temp_ctx);
     167                return werr;
     168        }
     169
     170        talloc_free(temp_ctx);
     171
     172        return werr;
    90173}
    91174
     
    94177                                  const struct ldb_val *schemaInfo)
    95178{
    96         WERROR status;
    97         enum ndr_err_code ndr_err;
    98         struct prefixMapBlob pfm;
    99         char *schema_info;
    100 
    101         TALLOC_CTX *mem_ctx = talloc_new(schema);
     179        WERROR werr;
     180        const char *schema_info;
     181        struct dsdb_schema_prefixmap *pfm;
     182        TALLOC_CTX *mem_ctx;
     183
     184        /* verify schemaInfo blob is valid one */
     185        if (!dsdb_schema_info_blob_is_valid(schemaInfo)) {
     186                DEBUG(0,(__location__": dsdb_schema_info_blob_is_valid() failed.\n"));
     187                return WERR_INVALID_PARAMETER;
     188        }
     189
     190        mem_ctx = talloc_new(schema);
    102191        W_ERROR_HAVE_NO_MEMORY(mem_ctx);
    103        
    104         ndr_err = ndr_pull_struct_blob(prefixMap, mem_ctx, schema->iconv_convenience, &pfm, (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob);
    105         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    106                 NTSTATUS nt_status = ndr_map_error2ntstatus(ndr_err);
     192
     193        /* fetch prefixMap */
     194        werr = _dsdb_prefixmap_from_ldb_val(prefixMap,
     195                                            mem_ctx, &pfm);
     196        if (!W_ERROR_IS_OK(werr)) {
     197                DEBUG(0, (__location__ " _dsdb_prefixmap_from_ldb_val failed: %s\n", win_errstr(werr)));
    107198                talloc_free(mem_ctx);
    108                 return ntstatus_to_werror(nt_status);
    109         }
    110 
    111         if (pfm.version != PREFIX_MAP_VERSION_DSDB) {
     199                return werr;
     200        }
     201
     202        /* decode schema_info */
     203        schema_info = hex_encode_talloc(mem_ctx,
     204                                        schemaInfo->data,
     205                                        schemaInfo->length);
     206        if (!schema_info) {
    112207                talloc_free(mem_ctx);
    113                 return WERR_FOOBAR;
    114         }
    115 
    116         if (schemaInfo->length != 21 && schemaInfo->data[0] == 0xFF) {
    117                 talloc_free(mem_ctx);
    118                 return WERR_FOOBAR;
    119         }
    120 
    121         /* append the schema info as last element */
    122         pfm.ctr.dsdb.num_mappings++;
    123         pfm.ctr.dsdb.mappings = talloc_realloc(mem_ctx, pfm.ctr.dsdb.mappings,
    124                                                struct drsuapi_DsReplicaOIDMapping,
    125                                                pfm.ctr.dsdb.num_mappings);
    126         W_ERROR_HAVE_NO_MEMORY(pfm.ctr.dsdb.mappings);
    127 
    128         schema_info = data_blob_hex_string(pfm.ctr.dsdb.mappings, schemaInfo);
    129         W_ERROR_HAVE_NO_MEMORY(schema_info);
    130 
    131         pfm.ctr.dsdb.mappings[pfm.ctr.dsdb.num_mappings - 1].id_prefix          = 0;   
    132         pfm.ctr.dsdb.mappings[pfm.ctr.dsdb.num_mappings - 1].oid.__ndr_size     = schemaInfo->length;
    133         pfm.ctr.dsdb.mappings[pfm.ctr.dsdb.num_mappings - 1].oid.oid            = schema_info;
    134 
    135         /* call the drsuapi version */
    136         status = dsdb_load_oid_mappings_drsuapi(schema, &pfm.ctr.dsdb);
     208                return WERR_NOMEM;
     209        }
     210
     211        /* store prefixMap and schema_info into cached Schema */
     212        talloc_free(schema->prefixmap);
     213        schema->prefixmap = talloc_steal(schema, pfm);
     214
     215        talloc_free(discard_const(schema->schema_info));
     216        schema->schema_info = talloc_steal(schema, schema_info);
     217
     218        /* clean up locally allocated mem */
    137219        talloc_free(mem_ctx);
    138 
    139         W_ERROR_NOT_OK_RETURN(status);
    140220
    141221        return WERR_OK;
     
    147227                                     struct drsuapi_DsReplicaOIDMapping_Ctr **_ctr)
    148228{
    149         struct drsuapi_DsReplicaOIDMapping_Ctr *ctr;
    150         uint32_t i;
    151 
    152         ctr = talloc(mem_ctx, struct drsuapi_DsReplicaOIDMapping_Ctr);
    153         W_ERROR_HAVE_NO_MEMORY(ctr);
    154 
    155         ctr->num_mappings       = schema->num_prefixes;
    156         if (include_schema_info) ctr->num_mappings++;
    157         ctr->mappings = talloc_array(schema, struct drsuapi_DsReplicaOIDMapping, ctr->num_mappings);
    158         W_ERROR_HAVE_NO_MEMORY(ctr->mappings);
    159 
    160         for (i=0; i < schema->num_prefixes; i++) {
    161                 ctr->mappings[i].id_prefix      = schema->prefixes[i].id>>16;
    162                 ctr->mappings[i].oid.oid        = talloc_strndup(ctr->mappings,
    163                                                                  schema->prefixes[i].oid,
    164                                                                  schema->prefixes[i].oid_len - 1);
    165                 W_ERROR_HAVE_NO_MEMORY(ctr->mappings[i].oid.oid);
    166         }
    167 
    168         if (include_schema_info) {
    169                 ctr->mappings[i].id_prefix      = 0;
    170                 ctr->mappings[i].oid.oid        = talloc_strdup(ctr->mappings,
    171                                                                 schema->schema_info);
    172                 W_ERROR_HAVE_NO_MEMORY(ctr->mappings[i].oid.oid);
    173         }
    174 
    175         *_ctr = ctr;
     229        return dsdb_drsuapi_pfm_from_schema_pfm(schema->prefixmap,
     230                                                include_schema_info ? schema->schema_info : NULL,
     231                                                mem_ctx, _ctr);
     232}
     233
     234WERROR dsdb_get_drsuapi_prefixmap_as_blob(const struct drsuapi_DsReplicaOIDMapping_Ctr *ctr,
     235                                          TALLOC_CTX *mem_ctx,
     236                                          struct ldb_val *prefixMap)
     237{
     238        struct prefixMapBlob pfm;
     239        enum ndr_err_code ndr_err;
     240        pfm.version     = PREFIX_MAP_VERSION_DSDB;
     241        pfm.reserved    = 0;
     242        pfm.ctr.dsdb    = *ctr;
     243
     244        ndr_err = ndr_push_struct_blob(prefixMap, mem_ctx, &pfm,
     245                                        (ndr_push_flags_fn_t)ndr_push_prefixMapBlob);
     246        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     247                NTSTATUS nt_status = ndr_map_error2ntstatus(ndr_err);
     248                return ntstatus_to_werror(nt_status);
     249        }
    176250        return WERR_OK;
    177251}
     
    183257{
    184258        WERROR status;
    185         enum ndr_err_code ndr_err;
    186259        struct drsuapi_DsReplicaOIDMapping_Ctr *ctr;
    187         struct prefixMapBlob pfm;
    188260
    189261        status = dsdb_get_oid_mappings_drsuapi(schema, false, mem_ctx, &ctr);
    190262        W_ERROR_NOT_OK_RETURN(status);
    191263
    192         pfm.version     = PREFIX_MAP_VERSION_DSDB;
    193         pfm.reserved    = 0;
    194         pfm.ctr.dsdb    = *ctr;
    195 
    196         ndr_err = ndr_push_struct_blob(prefixMap, mem_ctx, schema->iconv_convenience, &pfm, (ndr_push_flags_fn_t)ndr_push_prefixMapBlob);
     264        status = dsdb_get_drsuapi_prefixmap_as_blob(ctr, mem_ctx, prefixMap);
    197265        talloc_free(ctr);
    198         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    199                 NTSTATUS nt_status = ndr_map_error2ntstatus(ndr_err);
    200                 return ntstatus_to_werror(nt_status);
    201         }
     266        W_ERROR_NOT_OK_RETURN(status);
    202267
    203268        *schemaInfo = strhex_to_data_blob(mem_ctx, schema->schema_info);
     
    207272}
    208273
    209 WERROR dsdb_verify_oid_mappings_drsuapi(const struct dsdb_schema *schema, const struct drsuapi_DsReplicaOIDMapping_Ctr *ctr)
    210 {
    211         uint32_t i,j;
    212 
    213         for (i=0; i < ctr->num_mappings; i++) {
    214                 if (ctr->mappings[i].oid.oid == NULL) {
    215                         return WERR_INVALID_PARAM;
    216                 }
    217 
    218                 if (strncasecmp(ctr->mappings[i].oid.oid, "ff", 2) == 0) {
    219                         if (ctr->mappings[i].id_prefix != 0) {
    220                                 return WERR_INVALID_PARAM;
    221                         }
    222 
    223                         /* the magic value should be in the last array member */
    224                         if (i != (ctr->num_mappings - 1)) {
    225                                 return WERR_INVALID_PARAM;
    226                         }
    227 
    228                         if (ctr->mappings[i].oid.__ndr_size != 21) {
    229                                 return WERR_INVALID_PARAM;
    230                         }
    231 
    232                         if (strcasecmp(schema->schema_info, ctr->mappings[i].oid.oid) != 0) {
    233                                 return WERR_DS_DRA_SCHEMA_MISMATCH;
    234                         }
    235                 } else {
    236                         /* the last array member should contain the magic value not a oid */
    237                         if (i == (ctr->num_mappings - 1)) {
    238                                 return WERR_INVALID_PARAM;
    239                         }
    240 
    241                         for (j=0; j < schema->num_prefixes; j++) {
    242                                 size_t oid_len;
    243                                 if (schema->prefixes[j].id != (ctr->mappings[i].id_prefix<<16)) {
    244                                         continue;
    245                                 }
    246 
    247                                 oid_len = strlen(ctr->mappings[i].oid.oid);
    248 
    249                                 if (oid_len != (schema->prefixes[j].oid_len - 1)) {
    250                                         return WERR_DS_DRA_SCHEMA_MISMATCH;
    251                                 }
    252 
    253                                 if (strncmp(ctr->mappings[i].oid.oid, schema->prefixes[j].oid, oid_len) != 0) {
    254                                         return WERR_DS_DRA_SCHEMA_MISMATCH;                             
    255                                 }
    256 
    257                                 break;
    258                         }
    259 
    260                         if (j == schema->num_prefixes) {
    261                                 return WERR_DS_DRA_SCHEMA_MISMATCH;                             
    262                         }
    263                 }
    264         }
    265 
    266         return WERR_OK;
    267 }
    268 
    269 WERROR dsdb_map_oid2int(const struct dsdb_schema *schema, const char *in, uint32_t *out)
    270 {
    271         return dsdb_find_prefix_for_oid(schema->num_prefixes, schema->prefixes, in, out);
    272 }
    273 
    274 
    275 WERROR dsdb_map_int2oid(const struct dsdb_schema *schema, uint32_t in, TALLOC_CTX *mem_ctx, const char **out)
    276 {
    277         uint32_t i;
    278 
    279         for (i=0; i < schema->num_prefixes; i++) {
    280                 const char *val;
    281                 if (schema->prefixes[i].id != (in & 0xFFFF0000)) {
    282                         continue;
    283                 }
    284 
    285                 val = talloc_asprintf(mem_ctx, "%s%u",
    286                                       schema->prefixes[i].oid,
    287                                       in & 0xFFFF);
    288                 W_ERROR_HAVE_NO_MEMORY(val);
    289 
    290                 *out = val;
    291                 return WERR_OK;
    292         }
    293 
    294         return WERR_DS_NO_MSDS_INTID;
    295 }
    296274
    297275/*
     
    301279{
    302280        WERROR status;
    303         uint32_t num_prefixes;
    304         struct dsdb_schema_oid_prefix *prefixes;
     281        uint32_t attid;
    305282        TALLOC_CTX *mem_ctx;
    306         uint32_t out;
     283        struct dsdb_schema_prefixmap *pfm;
    307284
    308285        mem_ctx = talloc_new(ldb);
     
    310287
    311288        /* Read prefixes from disk*/
    312         status = dsdb_read_prefixes_from_ldb( mem_ctx, ldb, &num_prefixes, &prefixes );
     289        status = dsdb_read_prefixes_from_ldb(ldb, mem_ctx, &pfm);
    313290        if (!W_ERROR_IS_OK(status)) {
    314291                DEBUG(0,("dsdb_create_prefix_mapping: dsdb_read_prefixes_from_ldb: %s\n",
     
    319296
    320297        /* Check if there is a prefix for the oid in the prefixes array*/
    321         status = dsdb_find_prefix_for_oid( num_prefixes, prefixes, full_oid, &out );
     298        status = dsdb_schema_pfm_find_oid(pfm, full_oid, NULL);
    322299        if (W_ERROR_IS_OK(status)) {
    323300                /* prefix found*/
    324301                talloc_free(mem_ctx);
    325302                return status;
    326         } else if (!W_ERROR_EQUAL(WERR_DS_NO_MSDS_INTID, status)) {
     303        } else if (!W_ERROR_EQUAL(status, WERR_NOT_FOUND)) {
    327304                /* error */
    328305                DEBUG(0,("dsdb_create_prefix_mapping: dsdb_find_prefix_for_oid: %s\n",
     
    333310
    334311        /* Create the new mapping for the prefix of full_oid */
    335         status = dsdb_prefix_map_update(mem_ctx, &num_prefixes, &prefixes, full_oid);
     312        status = dsdb_schema_pfm_make_attid(pfm, full_oid, &attid);
    336313        if (!W_ERROR_IS_OK(status)) {
    337                 DEBUG(0,("dsdb_create_prefix_mapping: dsdb_prefix_map_update: %s\n",
     314                DEBUG(0,("dsdb_create_prefix_mapping: dsdb_schema_pfm_make_attid: %s\n",
    338315                        win_errstr(status)));
    339316                talloc_free(mem_ctx);
     
    341318        }
    342319
    343         talloc_free(schema->prefixes);
    344         schema->prefixes = talloc_steal(schema, prefixes);
    345         schema->num_prefixes = num_prefixes;
     320        talloc_unlink(schema, schema->prefixmap);
     321        schema->prefixmap = talloc_steal(schema, pfm);
    346322
    347323        /* Update prefixMap in ldb*/
     
    355331
    356332        DEBUG(2,(__location__ " Added prefixMap %s - now have %u prefixes\n",
    357                  full_oid, num_prefixes));
     333                 full_oid, schema->prefixmap->length));
    358334
    359335        talloc_free(mem_ctx);
     
    361337}
    362338
    363 WERROR dsdb_prefix_map_update(TALLOC_CTX *mem_ctx, uint32_t *num_prefixes, struct dsdb_schema_oid_prefix **prefixes, const char *oid)
    364 {
    365         uint32_t new_num_prefixes, index_new_prefix, new_entry_id;
    366         const char* lastDotOffset;
    367         size_t size;
    368        
    369         new_num_prefixes = *num_prefixes + 1;
    370         index_new_prefix = *num_prefixes;
    371 
    372         /*
    373          * this is the algorithm we use to create new mappings for now
    374          *
    375          * TODO: find what algorithm windows use
    376          */
    377         new_entry_id = (*num_prefixes)<<16;
    378 
    379         /* Extract the prefix from the oid*/
    380         lastDotOffset = strrchr(oid, '.');
    381         if (lastDotOffset == NULL) {
    382                 DEBUG(0,("dsdb_prefix_map_update: failed to find the last dot\n"));
    383                 return WERR_NOT_FOUND;
    384         }
    385 
    386         /* Calculate the size of the remainig string that should be the prefix of it */
    387         size = strlen(oid) - strlen(lastDotOffset);
    388         if (size <= 0) {
    389                 DEBUG(0,("dsdb_prefix_map_update: size of the remaining string invalid\n"));
    390                 return WERR_FOOBAR;
    391         }
    392         /* Add one because we need to copy the dot */
    393         size += 1;
    394 
    395         /* Create a spot in the prefixMap for one more prefix*/
    396         (*prefixes) = talloc_realloc(mem_ctx, *prefixes, struct dsdb_schema_oid_prefix, new_num_prefixes);
    397         W_ERROR_HAVE_NO_MEMORY(*prefixes);
    398 
    399         /* Add the new prefix entry*/
    400         (*prefixes)[index_new_prefix].id = new_entry_id;
    401         (*prefixes)[index_new_prefix].oid = talloc_strndup(mem_ctx, oid, size);
    402         (*prefixes)[index_new_prefix].oid_len = strlen((*prefixes)[index_new_prefix].oid);
    403 
    404         /* Increase num_prefixes because new prefix has been added */
    405         ++(*num_prefixes);
    406 
    407         return WERR_OK;
    408 }
    409 
    410 WERROR dsdb_find_prefix_for_oid(uint32_t num_prefixes, const struct dsdb_schema_oid_prefix *prefixes, const char *in, uint32_t *out)
    411 {
    412         uint32_t i;
    413 
    414         for (i=0; i < num_prefixes; i++) {
    415                 const char *val_str;
    416                 char *end_str;
    417                 unsigned val;
    418 
    419                 if (strncmp(prefixes[i].oid, in, prefixes[i].oid_len) != 0) {
    420                         continue;
    421                 }
    422 
    423                 val_str = in + prefixes[i].oid_len;
    424                 end_str = NULL;
    425                 errno = 0;
    426 
    427                 if (val_str[0] == '\0') {
    428                         return WERR_INVALID_PARAM;
    429                 }
    430 
    431                 /* two '.' chars are invalid */
    432                 if (val_str[0] == '.') {
    433                         return WERR_INVALID_PARAM;
    434                 }
    435 
    436                 val = strtoul(val_str, &end_str, 10);
    437                 if (end_str[0] == '.' && end_str[1] != '\0') {
    438                         /*
    439                          * if it's a '.' and not the last char
    440                          * then maybe an other mapping apply
    441                          */
    442                         continue;
    443                 } else if (end_str[0] != '\0') {
    444                         return WERR_INVALID_PARAM;
    445                 } else if (val > 0xFFFF) {
    446                         return WERR_INVALID_PARAM;
    447                 }
    448 
    449                 *out = prefixes[i].id | val;
    450                 return WERR_OK;
    451         }
    452 
    453         DEBUG(5,(__location__ " Failed to find oid %s - have %u prefixes\n", in, num_prefixes));
    454 
    455         return WERR_DS_NO_MSDS_INTID;
    456 }
    457339
    458340WERROR dsdb_write_prefixes_from_schema_to_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
    459                                                      const struct dsdb_schema *schema)
    460 {
    461         struct ldb_message *msg = ldb_msg_new(mem_ctx);
     341                                              const struct dsdb_schema *schema)
     342{
     343        WERROR status;
     344        int ldb_ret;
     345        struct ldb_message *msg;
    462346        struct ldb_dn *schema_dn;
    463         struct prefixMapBlob pm;
     347        struct prefixMapBlob pfm_blob;
    464348        struct ldb_val ndr_blob;
    465349        enum ndr_err_code ndr_err;
    466         uint32_t i;
    467         int ret;
    468 
    469         if (!msg) {
    470                 return WERR_NOMEM;
    471         }
    472        
    473         schema_dn = samdb_schema_dn(ldb);
     350        TALLOC_CTX *temp_ctx;
     351        struct drsuapi_DsReplicaOIDMapping_Ctr *ctr;
     352
     353        schema_dn = ldb_get_schema_basedn(ldb);
    474354        if (!schema_dn) {
    475                 DEBUG(0,("dsdb_write_prefixes_from_schema_to_ldb: no schema dn present\n"));   
     355                DEBUG(0,("dsdb_write_prefixes_from_schema_to_ldb: no schema dn present\n"));
    476356                return WERR_FOOBAR;
    477357        }
    478358
    479         pm.version                      = PREFIX_MAP_VERSION_DSDB;
    480         pm.ctr.dsdb.num_mappings        = schema->num_prefixes;
    481         pm.ctr.dsdb.mappings            = talloc_array(msg,
    482                                                 struct drsuapi_DsReplicaOIDMapping,
    483                                                 pm.ctr.dsdb.num_mappings);
    484         if (!pm.ctr.dsdb.mappings) {
    485                 talloc_free(msg);
    486                 return WERR_NOMEM;
    487         }
    488 
    489         for (i=0; i < schema->num_prefixes; i++) {
    490                 pm.ctr.dsdb.mappings[i].id_prefix = schema->prefixes[i].id>>16;
    491                 pm.ctr.dsdb.mappings[i].oid.oid = talloc_strdup(pm.ctr.dsdb.mappings, schema->prefixes[i].oid);
    492         }
    493 
    494         ndr_err = ndr_push_struct_blob(&ndr_blob, msg,
    495                                        lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
    496                                        &pm,
     359        temp_ctx = talloc_new(mem_ctx);
     360        W_ERROR_HAVE_NO_MEMORY(temp_ctx);
     361
     362        /* convert schema_prefixMap to prefixMap blob */
     363        status = dsdb_get_oid_mappings_drsuapi(schema, false, temp_ctx, &ctr);
     364        if (!W_ERROR_IS_OK(status)) {
     365                talloc_free(temp_ctx);
     366                return status;
     367        }
     368
     369        pfm_blob.version        = PREFIX_MAP_VERSION_DSDB;
     370        pfm_blob.ctr.dsdb       = *ctr;
     371
     372        ndr_err = ndr_push_struct_blob(&ndr_blob, temp_ctx,
     373                                       &pfm_blob,
    497374                                       (ndr_push_flags_fn_t)ndr_push_prefixMapBlob);
    498375        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    499                 talloc_free(msg);
     376                talloc_free(temp_ctx);
    500377                return WERR_FOOBAR;
    501378        }
    502379 
     380        /* write serialized prefixMap into LDB */
     381        msg = ldb_msg_new(temp_ctx);
     382        if (!msg) {
     383                talloc_free(temp_ctx);
     384                return WERR_NOMEM;
     385        }
     386
    503387        msg->dn = schema_dn;
    504         ret = ldb_msg_add_value(msg, "prefixMap", &ndr_blob, NULL);
    505         if (ret != 0) {
    506                 talloc_free(msg);
     388        ldb_ret = ldb_msg_add_value(msg, "prefixMap", &ndr_blob, NULL);
     389        if (ldb_ret != 0) {
     390                talloc_free(temp_ctx);
    507391                DEBUG(0,("dsdb_write_prefixes_from_schema_to_ldb: ldb_msg_add_value failed\n"));       
    508392                return WERR_NOMEM;
    509393        }
    510394 
    511         ret = samdb_replace( ldb, msg, msg );
    512         talloc_free(msg);
    513 
    514         if (ret != 0) {
    515                 DEBUG(0,("dsdb_write_prefixes_from_schema_to_ldb: samdb_replace failed\n"));   
     395        ldb_ret = dsdb_replace(ldb, msg, DSDB_FLAG_AS_SYSTEM);
     396
     397        talloc_free(temp_ctx);
     398
     399        if (ldb_ret != 0) {
     400                DEBUG(0,("dsdb_write_prefixes_from_schema_to_ldb: dsdb_replace failed\n"));
    516401                return WERR_FOOBAR;
    517402        }
     
    520405}
    521406
    522 WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, uint32_t* num_prefixes, struct dsdb_schema_oid_prefix **prefixes)
    523 {
    524         struct prefixMapBlob *blob;
    525         enum ndr_err_code ndr_err;
    526         uint32_t i;
     407WERROR dsdb_read_prefixes_from_ldb(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct dsdb_schema_prefixmap **_pfm)
     408{
     409        WERROR werr;
     410        int ldb_ret;
    527411        const struct ldb_val *prefix_val;
    528412        struct ldb_dn *schema_dn;
    529         struct ldb_result *schema_res;
    530         int ret;   
     413        struct ldb_result *schema_res = NULL;
    531414        static const char *schema_attrs[] = {
    532415                "prefixMap",
     
    534417        };
    535418
    536         schema_dn = samdb_schema_dn(ldb);
     419        schema_dn = ldb_get_schema_basedn(ldb);
    537420        if (!schema_dn) {
    538421                DEBUG(0,("dsdb_read_prefixes_from_ldb: no schema dn present\n"));
     
    540423        }
    541424
    542         ret = ldb_search(ldb, mem_ctx, &schema_res, schema_dn, LDB_SCOPE_BASE, schema_attrs, NULL);
    543         if (ret == LDB_ERR_NO_SUCH_OBJECT) {
     425        ldb_ret = ldb_search(ldb, mem_ctx, &schema_res, schema_dn, LDB_SCOPE_BASE, schema_attrs, NULL);
     426        if (ldb_ret == LDB_ERR_NO_SUCH_OBJECT) {
    544427                DEBUG(0,("dsdb_read_prefixes_from_ldb: no prefix map present\n"));
    545428                talloc_free(schema_res);
    546429                return WERR_FOOBAR;
    547         } else if (ret != LDB_SUCCESS) {
     430        } else if (ldb_ret != LDB_SUCCESS) {
    548431                DEBUG(0,("dsdb_read_prefixes_from_ldb: failed to search the schema head\n"));
    549432                talloc_free(schema_res);
     
    558441        }
    559442
    560         blob = talloc(mem_ctx, struct prefixMapBlob);
    561         W_ERROR_HAVE_NO_MEMORY(blob);
    562 
    563         ndr_err = ndr_pull_struct_blob(prefix_val, blob,
    564                                            lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
    565                                            blob,
    566                                            (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob);
    567         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    568                 DEBUG(0,("dsdb_read_prefixes_from_ldb: ndr_pull_struct_blob failed\n"));
    569                 talloc_free(blob);
    570                 talloc_free(schema_res);
    571                 return WERR_FOOBAR;
    572         }
    573 
     443        werr = _dsdb_prefixmap_from_ldb_val(prefix_val,
     444                                            mem_ctx,
     445                                            _pfm);
    574446        talloc_free(schema_res);
    575 
    576         if (blob->version != PREFIX_MAP_VERSION_DSDB) {
    577                 DEBUG(0,("dsdb_read_prefixes_from_ldb: blob->version incorect\n"));
    578                 talloc_free(blob);
    579                 return WERR_FOOBAR;
    580         }
    581        
    582         *num_prefixes = blob->ctr.dsdb.num_mappings;
    583         *prefixes = talloc_array(mem_ctx, struct dsdb_schema_oid_prefix, *num_prefixes);
    584         if(!(*prefixes)) {
    585                 talloc_free(blob);
    586                 return WERR_NOMEM;
    587         }
    588         for (i=0; i < blob->ctr.dsdb.num_mappings; i++) {
    589                 char *oid;
    590                 (*prefixes)[i].id = blob->ctr.dsdb.mappings[i].id_prefix<<16;
    591                 oid = talloc_strdup(mem_ctx, blob->ctr.dsdb.mappings[i].oid.oid);
    592                 (*prefixes)[i].oid = talloc_asprintf_append(oid, ".");
    593                 (*prefixes)[i].oid_len = strlen((*prefixes)[i].oid);
    594         }
    595 
    596         talloc_free(blob);
     447        W_ERROR_NOT_OK_RETURN(werr);
     448
    597449        return WERR_OK;
    598450}
     
    604456static bool dsdb_schema_unique_attribute(const char *attr)
    605457{
    606         const char *attrs[] = { "objectGUID", "objectSID" , NULL };
    607         int i;
     458        const char *attrs[] = { "objectGUID", "objectSid" , NULL };
     459        unsigned int i;
    608460        for (i=0;attrs[i];i++) {
    609461                if (strcasecmp(attr, attrs[i]) == 0) {
     
    638490
    639491        if (s == NULL) {
    640                 return LDB_ERR_OPERATIONS_ERROR;               
     492                return ldb_operr(ldb);
    641493        }
    642494
    643495        attr->ldb_schema_attribute = a = talloc(attr, struct ldb_schema_attribute);
    644496        if (attr->ldb_schema_attribute == NULL) {
    645                 ldb_oom(ldb);
    646                 return LDB_ERR_OPERATIONS_ERROR;
     497                return ldb_oom(ldb);
    647498        }
    648499
     
    667518        if (get_string_val == NULL) { \
    668519                if (strict) {                                     \
    669                         d_printf("%s: %s == NULL\n", __location__, attr); \
     520                        d_printf("%s: %s == NULL in %s\n", __location__, attr, ldb_dn_get_linearized(msg->dn)); \
    670521                        return WERR_INVALID_PARAM;                      \
    671522                } else {                                                \
     
    683534} while (0)
    684535
    685 #define GET_STRING_LIST_LDB(msg, attr, mem_ctx, p, elem, strict) do {   \
     536#define GET_STRING_LIST_LDB(msg, attr, mem_ctx, p, elem) do {   \
    686537        int get_string_list_counter;                                    \
    687538        struct ldb_message_element *get_string_list_el = ldb_msg_find_element(msg, attr); \
    688         if (get_string_list_el == NULL) {                               \
    689                 if (strict) {                                           \
    690                         d_printf("%s: %s == NULL\n", __location__, attr); \
    691                         return WERR_INVALID_PARAM;                      \
    692                 } else {                                                \
    693                         (p)->elem = NULL;                               \
    694                         break;                                          \
    695                 }                                                       \
     539        /* We may get empty attributes over the replication channel */  \
     540        if (get_string_list_el == NULL || get_string_list_el->num_values == 0) {                                \
     541                (p)->elem = NULL;                                       \
     542                break;                                                  \
    696543        }                                                               \
    697544        (p)->elem = talloc_array(mem_ctx, const char *, get_string_list_el->num_values + 1); \
     
    713560#define GET_BOOL_LDB(msg, attr, p, elem, strict) do { \
    714561        const char *str; \
    715         str = samdb_result_string(msg, attr, NULL);\
     562        str = ldb_msg_find_attr_as_string(msg, attr, NULL);\
    716563        if (str == NULL) { \
    717564                if (strict) { \
     
    732579
    733580#define GET_UINT32_LDB(msg, attr, p, elem) do { \
    734         (p)->elem = samdb_result_uint(msg, attr, 0);\
     581        (p)->elem = ldb_msg_find_attr_as_uint(msg, attr, 0);\
    735582} while (0)
    736583
    737 #define GET_UINT32_PTR_LDB(msg, attr, p, elem) do { \
    738         uint64_t _v = samdb_result_uint64(msg, attr, UINT64_MAX);\
     584#define GET_UINT32_PTR_LDB(msg, attr, mem_ctx, p, elem) do {            \
     585        uint64_t _v = ldb_msg_find_attr_as_uint64(msg, attr, UINT64_MAX);\
    739586        if (_v == UINT64_MAX) { \
    740587                (p)->elem = NULL; \
     
    769616
    770617WERROR dsdb_attribute_from_ldb(struct ldb_context *ldb,
    771                                const struct dsdb_schema *schema,
    772                                struct ldb_message *msg,
    773                                TALLOC_CTX *mem_ctx,
    774                                struct dsdb_attribute *attr)
     618                               struct dsdb_schema *schema,
     619                               struct ldb_message *msg)
    775620{
    776621        WERROR status;
    777 
    778         GET_STRING_LDB(msg, "cn", mem_ctx, attr, cn, false);
    779         GET_STRING_LDB(msg, "lDAPDisplayName", mem_ctx, attr, lDAPDisplayName, true);
    780         GET_STRING_LDB(msg, "attributeID", mem_ctx, attr, attributeID_oid, true);
    781         if (schema->num_prefixes == 0) {
     622        struct dsdb_attribute *attr = talloc_zero(schema, struct dsdb_attribute);
     623        if (!attr) {
     624                return WERR_NOMEM;
     625        }
     626
     627        GET_STRING_LDB(msg, "cn", attr, attr, cn, false);
     628        GET_STRING_LDB(msg, "lDAPDisplayName", attr, attr, lDAPDisplayName, true);
     629        GET_STRING_LDB(msg, "attributeID", attr, attr, attributeID_oid, true);
     630        if (!schema->prefixmap || schema->prefixmap->length == 0) {
    782631                /* set an invalid value */
    783                 attr->attributeID_id = 0xFFFFFFFF;
     632                attr->attributeID_id = DRSUAPI_ATTID_INVALID;
    784633        } else {
    785                 status = dsdb_map_oid2int(schema, attr->attributeID_oid, &attr->attributeID_id);
     634                status = dsdb_schema_pfm_make_attid(schema->prefixmap,
     635                                                    attr->attributeID_oid,
     636                                                    &attr->attributeID_id);
    786637                if (!W_ERROR_IS_OK(status)) {
    787638                        DEBUG(0,("%s: '%s': unable to map attributeID %s: %s\n",
     
    791642                }
    792643        }
     644        /* fetch msDS-IntId to be used in resolving ATTRTYP values */
     645        GET_UINT32_LDB(msg, "msDS-IntId", attr, msDS_IntId);
     646
    793647        GET_GUID_LDB(msg, "schemaIDGUID", attr, schemaIDGUID);
    794648        GET_UINT32_LDB(msg, "mAPIID", attr, mAPIID);
    795649
    796650        GET_GUID_LDB(msg, "attributeSecurityGUID", attr, attributeSecurityGUID);
     651
     652        GET_GUID_LDB(msg, "objectGUID", attr, objectGUID);
    797653
    798654        GET_UINT32_LDB(msg, "searchFlags", attr, searchFlags);
     
    801657        GET_UINT32_LDB(msg, "linkID", attr, linkID);
    802658
    803         GET_STRING_LDB(msg, "attributeSyntax", mem_ctx, attr, attributeSyntax_oid, true);
    804         if (schema->num_prefixes == 0) {
     659        GET_STRING_LDB(msg, "attributeSyntax", attr, attr, attributeSyntax_oid, true);
     660        if (!schema->prefixmap || schema->prefixmap->length == 0) {
    805661                /* set an invalid value */
    806                 attr->attributeSyntax_id = 0xFFFFFFFF;
     662                attr->attributeSyntax_id = DRSUAPI_ATTID_INVALID;
    807663        } else {
    808                 status = dsdb_map_oid2int(schema, attr->attributeSyntax_oid, &attr->attributeSyntax_id);
     664                status = dsdb_schema_pfm_attid_from_oid(schema->prefixmap,
     665                                                        attr->attributeSyntax_oid,
     666                                                        &attr->attributeSyntax_id);
    809667                if (!W_ERROR_IS_OK(status)) {
    810668                        DEBUG(0,("%s: '%s': unable to map attributeSyntax_ %s: %s\n",
     
    815673        }
    816674        GET_UINT32_LDB(msg, "oMSyntax", attr, oMSyntax);
    817         GET_BLOB_LDB(msg, "oMObjectClass", mem_ctx, attr, oMObjectClass);
     675        GET_BLOB_LDB(msg, "oMObjectClass", attr, attr, oMObjectClass);
    818676
    819677        GET_BOOL_LDB(msg, "isSingleValued", attr, isSingleValued, true);
    820         GET_UINT32_PTR_LDB(msg, "rangeLower", attr, rangeLower);
    821         GET_UINT32_PTR_LDB(msg, "rangeUpper", attr, rangeUpper);
     678        GET_UINT32_PTR_LDB(msg, "rangeLower", attr, attr, rangeLower);
     679        GET_UINT32_PTR_LDB(msg, "rangeUpper", attr, attr, rangeUpper);
    822680        GET_BOOL_LDB(msg, "extendedCharsAllowed", attr, extendedCharsAllowed, false);
    823681
    824682        GET_UINT32_LDB(msg, "schemaFlagsEx", attr, schemaFlagsEx);
    825         GET_BLOB_LDB(msg, "msDs-Schema-Extensions", mem_ctx, attr, msDs_Schema_Extensions);
     683        GET_BLOB_LDB(msg, "msDs-Schema-Extensions", attr, attr, msDs_Schema_Extensions);
    826684
    827685        GET_BOOL_LDB(msg, "showInAdvancedViewOnly", attr, showInAdvancedViewOnly, false);
    828         GET_STRING_LDB(msg, "adminDisplayName", mem_ctx, attr, adminDisplayName, false);
    829         GET_STRING_LDB(msg, "adminDescription", mem_ctx, attr, adminDescription, false);
    830         GET_STRING_LDB(msg, "classDisplayName", mem_ctx, attr, classDisplayName, false);
     686        GET_STRING_LDB(msg, "adminDisplayName", attr, attr, adminDisplayName, false);
     687        GET_STRING_LDB(msg, "adminDescription", attr, attr, adminDescription, false);
     688        GET_STRING_LDB(msg, "classDisplayName", attr, attr, classDisplayName, false);
    831689        GET_BOOL_LDB(msg, "isEphemeral", attr, isEphemeral, false);
    832690        GET_BOOL_LDB(msg, "isDefunct", attr, isDefunct, false);
     
    835693        attr->syntax = dsdb_syntax_for_attribute(attr);
    836694        if (!attr->syntax) {
     695                DEBUG(0,(__location__ ": Unknown schema syntax for %s\n",
     696                         attr->lDAPDisplayName));
    837697                return WERR_DS_ATT_SCHEMA_REQ_SYNTAX;
    838698        }
    839699
    840700        if (dsdb_schema_setup_ldb_schema_attribute(ldb, attr) != LDB_SUCCESS) {
     701                DEBUG(0,(__location__ ": Unknown schema syntax for %s - ldb_syntax: %s, ldap_oid: %s\n",
     702                         attr->lDAPDisplayName,
     703                         attr->syntax->ldb_syntax,
     704                         attr->syntax->ldap_oid));
    841705                return WERR_DS_ATT_SCHEMA_REQ_SYNTAX;
    842706        }
    843707
     708        DLIST_ADD(schema->attributes, attr);
    844709        return WERR_OK;
    845710}
    846711
    847 WERROR dsdb_class_from_ldb(const struct dsdb_schema *schema,
    848                            struct ldb_message *msg,
    849                            TALLOC_CTX *mem_ctx,
    850                            struct dsdb_class *obj)
     712WERROR dsdb_class_from_ldb(struct dsdb_schema *schema,
     713                           struct ldb_message *msg)
    851714{
    852715        WERROR status;
    853 
    854         GET_STRING_LDB(msg, "cn", mem_ctx, obj, cn, false);
    855         GET_STRING_LDB(msg, "lDAPDisplayName", mem_ctx, obj, lDAPDisplayName, true);
    856         GET_STRING_LDB(msg, "governsID", mem_ctx, obj, governsID_oid, true);
    857         if (schema->num_prefixes == 0) {
     716        struct dsdb_class *obj = talloc_zero(schema, struct dsdb_class);
     717        if (!obj) {
     718                return WERR_NOMEM;
     719        }
     720        GET_STRING_LDB(msg, "cn", obj, obj, cn, false);
     721        GET_STRING_LDB(msg, "lDAPDisplayName", obj, obj, lDAPDisplayName, true);
     722        GET_STRING_LDB(msg, "governsID", obj, obj, governsID_oid, true);
     723        if (!schema->prefixmap || schema->prefixmap->length == 0) {
    858724                /* set an invalid value */
    859                 obj->governsID_id = 0xFFFFFFFF;
     725                obj->governsID_id = DRSUAPI_ATTID_INVALID;
    860726        } else {
    861                 status = dsdb_map_oid2int(schema, obj->governsID_oid, &obj->governsID_id);
     727                status = dsdb_schema_pfm_make_attid(schema->prefixmap,
     728                                                    obj->governsID_oid,
     729                                                    &obj->governsID_id);
    862730                if (!W_ERROR_IS_OK(status)) {
    863731                        DEBUG(0,("%s: '%s': unable to map governsID %s: %s\n",
     
    868736        }
    869737        GET_GUID_LDB(msg, "schemaIDGUID", obj, schemaIDGUID);
     738        GET_GUID_LDB(msg, "objectGUID", obj, objectGUID);
    870739
    871740        GET_UINT32_LDB(msg, "objectClassCategory", obj, objectClassCategory);
    872         GET_STRING_LDB(msg, "rDNAttID", mem_ctx, obj, rDNAttID, false);
    873         GET_STRING_LDB(msg, "defaultObjectCategory", mem_ctx, obj, defaultObjectCategory, true);
     741        GET_STRING_LDB(msg, "rDNAttID", obj, obj, rDNAttID, false);
     742        GET_STRING_LDB(msg, "defaultObjectCategory", obj, obj, defaultObjectCategory, true);
    874743 
    875         GET_STRING_LDB(msg, "subClassOf", mem_ctx, obj, subClassOf, true);
    876 
    877         GET_STRING_LIST_LDB(msg, "systemAuxiliaryClass", mem_ctx, obj, systemAuxiliaryClass, false);
    878         GET_STRING_LIST_LDB(msg, "auxiliaryClass", mem_ctx, obj, auxiliaryClass, false);
    879 
    880         GET_STRING_LIST_LDB(msg, "systemMustContain", mem_ctx, obj, systemMustContain, false);
    881         GET_STRING_LIST_LDB(msg, "systemMayContain", mem_ctx, obj, systemMayContain, false);
    882         GET_STRING_LIST_LDB(msg, "mustContain", mem_ctx, obj, mustContain, false);
    883         GET_STRING_LIST_LDB(msg, "mayContain", mem_ctx, obj, mayContain, false);
    884 
    885         GET_STRING_LIST_LDB(msg, "systemPossSuperiors", mem_ctx, obj, systemPossSuperiors, false);
    886         GET_STRING_LIST_LDB(msg, "possSuperiors", mem_ctx, obj, possSuperiors, false);
    887 
    888         GET_STRING_LDB(msg, "defaultSecurityDescriptor", mem_ctx, obj, defaultSecurityDescriptor, false);
     744        GET_STRING_LDB(msg, "subClassOf", obj, obj, subClassOf, true);
     745
     746        GET_STRING_LIST_LDB(msg, "systemAuxiliaryClass", obj, obj, systemAuxiliaryClass);
     747        GET_STRING_LIST_LDB(msg, "auxiliaryClass", obj, obj, auxiliaryClass);
     748
     749        GET_STRING_LIST_LDB(msg, "systemMustContain", obj, obj, systemMustContain);
     750        GET_STRING_LIST_LDB(msg, "systemMayContain", obj, obj, systemMayContain);
     751        GET_STRING_LIST_LDB(msg, "mustContain", obj, obj, mustContain);
     752        GET_STRING_LIST_LDB(msg, "mayContain", obj, obj, mayContain);
     753
     754        GET_STRING_LIST_LDB(msg, "systemPossSuperiors", obj, obj, systemPossSuperiors);
     755        GET_STRING_LIST_LDB(msg, "possSuperiors", obj, obj, possSuperiors);
     756
     757        GET_STRING_LDB(msg, "defaultSecurityDescriptor", obj, obj, defaultSecurityDescriptor, false);
    889758
    890759        GET_UINT32_LDB(msg, "schemaFlagsEx", obj, schemaFlagsEx);
    891         GET_BLOB_LDB(msg, "msDs-Schema-Extensions", mem_ctx, obj, msDs_Schema_Extensions);
     760        GET_BLOB_LDB(msg, "msDs-Schema-Extensions", obj, obj, msDs_Schema_Extensions);
    892761
    893762        GET_BOOL_LDB(msg, "showInAdvancedViewOnly", obj, showInAdvancedViewOnly, false);
    894         GET_STRING_LDB(msg, "adminDisplayName", mem_ctx, obj, adminDisplayName, false);
    895         GET_STRING_LDB(msg, "adminDescription", mem_ctx, obj, adminDescription, false);
    896         GET_STRING_LDB(msg, "classDisplayName", mem_ctx, obj, classDisplayName, false);
     763        GET_STRING_LDB(msg, "adminDisplayName", obj, obj, adminDisplayName, false);
     764        GET_STRING_LDB(msg, "adminDescription", obj, obj, adminDescription, false);
     765        GET_STRING_LDB(msg, "classDisplayName", obj, obj, classDisplayName, false);
    897766        GET_BOOL_LDB(msg, "defaultHidingValue", obj, defaultHidingValue, false);
    898767        GET_BOOL_LDB(msg, "isDefunct", obj, isDefunct, false);
    899768        GET_BOOL_LDB(msg, "systemOnly", obj, systemOnly, false);
    900769
     770        DLIST_ADD(schema->classes, obj);
    901771        return WERR_OK;
    902772}
     
    907777 Create a DSDB schema from the ldb results provided.  This is called
    908778 directly when the schema is provisioned from an on-disk LDIF file, or
    909  from dsdb_schema_from_schema_dn below
     779 from dsdb_schema_from_schema_dn in schema_fsmo
    910780*/
    911781
    912782int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
    913                                  struct smb_iconv_convenience *iconv_convenience,
    914783                                 struct ldb_result *schema_res,
    915784                                 struct ldb_result *attrs_res, struct ldb_result *objectclass_res,
     
    918787{
    919788        WERROR status;
    920         uint32_t i;
     789        unsigned int i;
    921790        const struct ldb_val *prefix_val;
    922791        const struct ldb_val *info_val;
     
    924793        struct dsdb_schema *schema;
    925794
    926         schema = dsdb_new_schema(mem_ctx, iconv_convenience);
     795        schema = dsdb_new_schema(mem_ctx);
    927796        if (!schema) {
    928797                dsdb_oom(error_string, mem_ctx);
    929                 return LDB_ERR_OPERATIONS_ERROR;
    930         }
     798                return ldb_operr(ldb);
     799        }
     800
     801        schema->base_dn = talloc_steal(schema, schema_res->msgs[0]->dn);
    931802
    932803        prefix_val = ldb_msg_find_ldb_val(schema_res->msgs[0], "prefixMap");
     
    939810        info_val = ldb_msg_find_ldb_val(schema_res->msgs[0], "schemaInfo");
    940811        if (!info_val) {
    941                 info_val_default = strhex_to_data_blob(mem_ctx, "FF0000000000000000000000000000000000000000");
    942                 if (!info_val_default.data) {
    943                         dsdb_oom(error_string, mem_ctx);
    944                         return LDB_ERR_OPERATIONS_ERROR;
     812                status = dsdb_schema_info_blob_new(mem_ctx, &info_val_default);
     813                if (!W_ERROR_IS_OK(status)) {
     814                        *error_string = talloc_asprintf(mem_ctx,
     815                                                        "schema_fsmo_init: dsdb_schema_info_blob_new() failed - %s",
     816                                                        win_errstr(status));
     817                        DEBUG(0,(__location__ ": %s\n", *error_string));
     818                        return ldb_operr(ldb);
    945819                }
    946820                info_val = &info_val_default;
     
    957831
    958832        for (i=0; i < attrs_res->count; i++) {
    959                 struct dsdb_attribute *sa;
    960 
    961                 sa = talloc_zero(schema, struct dsdb_attribute);
    962                 if (!sa) {
    963                         dsdb_oom(error_string, mem_ctx);
    964                         return LDB_ERR_OPERATIONS_ERROR;
    965                 }
    966 
    967                 status = dsdb_attribute_from_ldb(ldb, schema, attrs_res->msgs[i], sa, sa);
     833                status = dsdb_attribute_from_ldb(ldb, schema, attrs_res->msgs[i]);
    968834                if (!W_ERROR_IS_OK(status)) {
    969835                        *error_string = talloc_asprintf(mem_ctx,
     
    974840                        return LDB_ERR_CONSTRAINT_VIOLATION;
    975841                }
    976 
    977                 DLIST_ADD(schema->attributes, sa);
    978842        }
    979843
    980844        for (i=0; i < objectclass_res->count; i++) {
    981                 struct dsdb_class *sc;
    982 
    983                 sc = talloc_zero(schema, struct dsdb_class);
    984                 if (!sc) {
    985                         dsdb_oom(error_string, mem_ctx);
    986                         return LDB_ERR_OPERATIONS_ERROR;
    987                 }
    988 
    989                 status = dsdb_class_from_ldb(schema, objectclass_res->msgs[i], sc, sc);
     845                status = dsdb_class_from_ldb(schema, objectclass_res->msgs[i]);
    990846                if (!W_ERROR_IS_OK(status)) {
    991847                        *error_string = talloc_asprintf(mem_ctx,
     
    996852                        return LDB_ERR_CONSTRAINT_VIOLATION;
    997853                }
    998 
    999                 DLIST_ADD(schema->classes, sc);
    1000854        }
    1001855
     
    1013867        return LDB_SUCCESS;
    1014868}
    1015 
    1016 /*
    1017   Given an LDB, and the DN, return a populated schema
    1018 */
    1019 
    1020 int dsdb_schema_from_schema_dn(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
    1021                                struct smb_iconv_convenience *iconv_convenience,
    1022                                struct ldb_dn *schema_dn,
    1023                                struct dsdb_schema **schema,
    1024                                char **error_string_out)
    1025 {
    1026         TALLOC_CTX *tmp_ctx;
    1027         char *error_string;
    1028         int ret;
    1029 
    1030         struct ldb_result *schema_res;
    1031         struct ldb_result *a_res;
    1032         struct ldb_result *c_res;
    1033         static const char *schema_attrs[] = {
    1034                 "prefixMap",
    1035                 "schemaInfo",
    1036                 "fSMORoleOwner",
    1037                 NULL
    1038         };
    1039         unsigned flags;
    1040 
    1041         tmp_ctx = talloc_new(mem_ctx);
    1042         if (!tmp_ctx) {
    1043                 dsdb_oom(error_string_out, mem_ctx);
    1044                 return LDB_ERR_OPERATIONS_ERROR;
    1045         }
    1046 
    1047         /* we don't want to trace the schema load */
    1048         flags = ldb_get_flags(ldb);
    1049         ldb_set_flags(ldb, flags & ~LDB_FLG_ENABLE_TRACING);
    1050 
    1051         /*
    1052          * setup the prefix mappings and schema info
    1053          */
    1054         ret = ldb_search(ldb, tmp_ctx, &schema_res,
    1055                          schema_dn, LDB_SCOPE_BASE, schema_attrs, NULL);
    1056         if (ret == LDB_ERR_NO_SUCH_OBJECT) {
    1057                 goto failed;
    1058         } else if (ret != LDB_SUCCESS) {
    1059                 *error_string_out = talloc_asprintf(mem_ctx,
    1060                                        "dsdb_schema: failed to search the schema head: %s",
    1061                                        ldb_errstring(ldb));
    1062                 goto failed;
    1063         }
    1064         if (schema_res->count != 1) {
    1065                 *error_string_out = talloc_asprintf(mem_ctx,
    1066                               "dsdb_schema: [%u] schema heads found on a base search",
    1067                               schema_res->count);
    1068                 goto failed;
    1069         }
    1070 
    1071         /*
    1072          * load the attribute definitions
    1073          */
    1074         ret = ldb_search(ldb, tmp_ctx, &a_res,
    1075                          schema_dn, LDB_SCOPE_ONELEVEL, NULL,
    1076                          "(objectClass=attributeSchema)");
    1077         if (ret != LDB_SUCCESS) {
    1078                 *error_string_out = talloc_asprintf(mem_ctx,
    1079                                        "dsdb_schema: failed to search attributeSchema objects: %s",
    1080                                        ldb_errstring(ldb));
    1081                 goto failed;
    1082         }
    1083 
    1084         /*
    1085          * load the objectClass definitions
    1086          */
    1087         ret = ldb_search(ldb, tmp_ctx, &c_res,
    1088                          schema_dn, LDB_SCOPE_ONELEVEL, NULL,
    1089                          "(objectClass=classSchema)");
    1090         if (ret != LDB_SUCCESS) {
    1091                 *error_string_out = talloc_asprintf(mem_ctx,
    1092                                        "dsdb_schema: failed to search attributeSchema objects: %s",
    1093                                        ldb_errstring(ldb));
    1094                 goto failed;
    1095         }
    1096 
    1097         ret = dsdb_schema_from_ldb_results(tmp_ctx, ldb,
    1098                                            lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
    1099                                            schema_res, a_res, c_res, schema, &error_string);
    1100         if (ret != LDB_SUCCESS) {
    1101                 *error_string_out = talloc_asprintf(mem_ctx,
    1102                                                     "dsdb_schema load failed: %s",
    1103                                                     error_string);
    1104                 goto failed;
    1105         }
    1106         talloc_steal(mem_ctx, *schema);
    1107         talloc_free(tmp_ctx);
    1108 
    1109         if (flags & LDB_FLG_ENABLE_TRACING) {
    1110                 flags = ldb_get_flags(ldb);
    1111                 ldb_set_flags(ldb, flags | LDB_FLG_ENABLE_TRACING);
    1112         }
    1113 
    1114         return LDB_SUCCESS;
    1115 
    1116 failed:
    1117         if (flags & LDB_FLG_ENABLE_TRACING) {
    1118                 flags = ldb_get_flags(ldb);
    1119                 ldb_set_flags(ldb, flags | LDB_FLG_ENABLE_TRACING);
    1120         }
    1121         talloc_free(tmp_ctx);
    1122         return ret;
    1123 }       
    1124 
    1125 
    1126 static const struct {
    1127         const char *name;
    1128         const char *oid;
    1129 } name_mappings[] = {
    1130         { "cn",                                 "2.5.4.3" },
    1131         { "name",                               "1.2.840.113556.1.4.1" },
    1132         { "lDAPDisplayName",                    "1.2.840.113556.1.2.460" },
    1133         { "attributeID",                        "1.2.840.113556.1.2.30" },
    1134         { "schemaIDGUID",                       "1.2.840.113556.1.4.148" },
    1135         { "mAPIID",                             "1.2.840.113556.1.2.49" },
    1136         { "attributeSecurityGUID",              "1.2.840.113556.1.4.149" },
    1137         { "searchFlags",                        "1.2.840.113556.1.2.334" },
    1138         { "systemFlags",                        "1.2.840.113556.1.4.375" },
    1139         { "isMemberOfPartialAttributeSet",      "1.2.840.113556.1.4.639" },
    1140         { "linkID",                             "1.2.840.113556.1.2.50" },
    1141         { "attributeSyntax",                    "1.2.840.113556.1.2.32" },
    1142         { "oMSyntax",                           "1.2.840.113556.1.2.231" },
    1143         { "oMObjectClass",                      "1.2.840.113556.1.2.218" },
    1144         { "isSingleValued",                     "1.2.840.113556.1.2.33" },
    1145         { "rangeLower",                         "1.2.840.113556.1.2.34" },
    1146         { "rangeUpper",                         "1.2.840.113556.1.2.35" },
    1147         { "extendedCharsAllowed",               "1.2.840.113556.1.2.380" },
    1148         { "schemaFlagsEx",                      "1.2.840.113556.1.4.120" },
    1149         { "msDs-Schema-Extensions",             "1.2.840.113556.1.4.1440" },
    1150         { "showInAdvancedViewOnly",             "1.2.840.113556.1.2.169" },
    1151         { "adminDisplayName",                   "1.2.840.113556.1.2.194" },
    1152         { "adminDescription",                   "1.2.840.113556.1.2.226" },
    1153         { "classDisplayName",                   "1.2.840.113556.1.4.610" },
    1154         { "isEphemeral",                        "1.2.840.113556.1.4.1212" },
    1155         { "isDefunct",                          "1.2.840.113556.1.4.661" },
    1156         { "systemOnly",                         "1.2.840.113556.1.4.170" },
    1157         { "governsID",                          "1.2.840.113556.1.2.22" },
    1158         { "objectClassCategory",                "1.2.840.113556.1.2.370" },
    1159         { "rDNAttID",                           "1.2.840.113556.1.2.26" },
    1160         { "defaultObjectCategory",              "1.2.840.113556.1.4.783" },
    1161         { "subClassOf",                         "1.2.840.113556.1.2.21" },
    1162         { "systemAuxiliaryClass",               "1.2.840.113556.1.4.198" },
    1163         { "systemPossSuperiors",                "1.2.840.113556.1.4.195" },
    1164         { "systemMustContain",                  "1.2.840.113556.1.4.197" },
    1165         { "systemMayContain",                   "1.2.840.113556.1.4.196" },
    1166         { "auxiliaryClass",                     "1.2.840.113556.1.2.351" },
    1167         { "possSuperiors",                      "1.2.840.113556.1.2.8" },
    1168         { "mustContain",                        "1.2.840.113556.1.2.24" },
    1169         { "mayContain",                         "1.2.840.113556.1.2.25" },
    1170         { "defaultSecurityDescriptor",          "1.2.840.113556.1.4.224" },
    1171         { "defaultHidingValue",                 "1.2.840.113556.1.4.518" },
    1172 };
    1173 
    1174 static struct drsuapi_DsReplicaAttribute *dsdb_find_object_attr_name(struct dsdb_schema *schema,
    1175                                                                      struct drsuapi_DsReplicaObject *obj,
    1176                                                                      const char *name,
    1177                                                                      uint32_t *idx)
    1178 {
    1179         WERROR status;
    1180         uint32_t i, id;
    1181         const char *oid = NULL;
    1182 
    1183         for(i=0; i < ARRAY_SIZE(name_mappings); i++) {
    1184                 if (strcmp(name_mappings[i].name, name) != 0) continue;
    1185 
    1186                 oid = name_mappings[i].oid;
    1187                 break;
    1188         }
    1189 
    1190         if (!oid) {
    1191                 return NULL;
    1192         }
    1193 
    1194         status = dsdb_map_oid2int(schema, oid, &id);
    1195         if (!W_ERROR_IS_OK(status)) {
    1196                 return NULL;
    1197         }
    1198 
    1199         for (i=0; i < obj->attribute_ctr.num_attributes; i++) {
    1200                 if (obj->attribute_ctr.attributes[i].attid != id) continue;
    1201 
    1202                 if (idx) *idx = i;
    1203                 return &obj->attribute_ctr.attributes[i];
    1204         }
    1205 
    1206         return NULL;
    1207 }
    1208 
    1209 #define GET_STRING_DS(s, r, attr, mem_ctx, p, elem, strict) do { \
    1210         struct drsuapi_DsReplicaAttribute *_a; \
    1211         _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
    1212         if (strict && !_a) { \
    1213                 d_printf("%s: %s == NULL\n", __location__, attr); \
    1214                 return WERR_INVALID_PARAM; \
    1215         } \
    1216         if (strict && _a->value_ctr.num_values != 1) { \
    1217                 d_printf("%s: %s num_values == %u\n", __location__, attr, \
    1218                         _a->value_ctr.num_values); \
    1219                 return WERR_INVALID_PARAM; \
    1220         } \
    1221         if (_a && _a->value_ctr.num_values >= 1) { \
    1222                 size_t _ret; \
    1223                 if (!convert_string_talloc_convenience(mem_ctx, s->iconv_convenience, CH_UTF16, CH_UNIX, \
    1224                                              _a->value_ctr.values[0].blob->data, \
    1225                                              _a->value_ctr.values[0].blob->length, \
    1226                                              (void **)discard_const(&(p)->elem), &_ret, false)) { \
    1227                         DEBUG(0,("%s: invalid data!\n", attr)); \
    1228                         dump_data(0, \
    1229                                      _a->value_ctr.values[0].blob->data, \
    1230                                      _a->value_ctr.values[0].blob->length); \
    1231                         return WERR_FOOBAR; \
    1232                 } \
    1233         } else { \
    1234                 (p)->elem = NULL; \
    1235         } \
    1236 } while (0)
    1237 
    1238 #define GET_UINT32_LIST_DS(s, r, attr, mem_ctx, p, elem) do { \
    1239         int list_counter;                                       \
    1240         struct drsuapi_DsReplicaAttribute *_a; \
    1241         _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
    1242         (p)->elem = _a ? talloc_array(mem_ctx, uint32_t, _a->value_ctr.num_values + 1) : NULL; \
    1243         for (list_counter=0;                                    \
    1244              _a && list_counter < _a->value_ctr.num_values;     \
    1245              list_counter++) {                          \
    1246                 if (_a->value_ctr.values[list_counter].blob->length != 4) { \
    1247                         return WERR_INVALID_PARAM;                      \
    1248                 }                                                       \
    1249                 (p)->elem[list_counter] = IVAL(_a->value_ctr.values[list_counter].blob->data, 0); \
    1250         }                                                               \
    1251         if (_a) (p)->elem[list_counter] = 0;                            \
    1252 } while (0)
    1253 
    1254 #define GET_DN_DS(s, r, attr, mem_ctx, p, elem, strict) do { \
    1255         struct drsuapi_DsReplicaAttribute *_a; \
    1256         _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
    1257         if (strict && !_a) { \
    1258                 d_printf("%s: %s == NULL\n", __location__, attr); \
    1259                 return WERR_INVALID_PARAM; \
    1260         } \
    1261         if (strict && _a->value_ctr.num_values != 1) { \
    1262                 d_printf("%s: %s num_values == %u\n", __location__, attr, \
    1263                         _a->value_ctr.num_values); \
    1264                 return WERR_INVALID_PARAM; \
    1265         } \
    1266         if (strict && !_a->value_ctr.values[0].blob) { \
    1267                 d_printf("%s: %s data == NULL\n", __location__, attr); \
    1268                 return WERR_INVALID_PARAM; \
    1269         } \
    1270         if (_a && _a->value_ctr.num_values >= 1 \
    1271             && _a->value_ctr.values[0].blob) { \
    1272                 struct drsuapi_DsReplicaObjectIdentifier3 _id3; \
    1273                 enum ndr_err_code _ndr_err; \
    1274                 _ndr_err = ndr_pull_struct_blob_all(_a->value_ctr.values[0].blob, \
    1275                                                       mem_ctx, s->iconv_convenience, &_id3,\
    1276                                                       (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3);\
    1277                 if (!NDR_ERR_CODE_IS_SUCCESS(_ndr_err)) { \
    1278                         NTSTATUS _nt_status = ndr_map_error2ntstatus(_ndr_err); \
    1279                         return ntstatus_to_werror(_nt_status); \
    1280                 } \
    1281                 (p)->elem = _id3.dn; \
    1282         } else { \
    1283                 (p)->elem = NULL; \
    1284         } \
    1285 } while (0)
    1286 
    1287 #define GET_BOOL_DS(s, r, attr, p, elem, strict) do { \
    1288         struct drsuapi_DsReplicaAttribute *_a; \
    1289         _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
    1290         if (strict && !_a) { \
    1291                 d_printf("%s: %s == NULL\n", __location__, attr); \
    1292                 return WERR_INVALID_PARAM; \
    1293         } \
    1294         if (strict && _a->value_ctr.num_values != 1) { \
    1295                 d_printf("%s: %s num_values == %u\n", __location__, attr, \
    1296                          (unsigned int)_a->value_ctr.num_values);       \
    1297                 return WERR_INVALID_PARAM; \
    1298         } \
    1299         if (strict && !_a->value_ctr.values[0].blob) { \
    1300                 d_printf("%s: %s data == NULL\n", __location__, attr); \
    1301                 return WERR_INVALID_PARAM; \
    1302         } \
    1303         if (strict && _a->value_ctr.values[0].blob->length != 4) { \
    1304                 d_printf("%s: %s length == %u\n", __location__, attr, \
    1305                          (unsigned int)_a->value_ctr.values[0].blob->length); \
    1306                 return WERR_INVALID_PARAM; \
    1307         } \
    1308         if (_a && _a->value_ctr.num_values >= 1 \
    1309             && _a->value_ctr.values[0].blob \
    1310             && _a->value_ctr.values[0].blob->length == 4) { \
    1311                 (p)->elem = (IVAL(_a->value_ctr.values[0].blob->data,0)?true:false);\
    1312         } else { \
    1313                 (p)->elem = false; \
    1314         } \
    1315 } while (0)
    1316 
    1317 #define GET_UINT32_DS(s, r, attr, p, elem) do { \
    1318         struct drsuapi_DsReplicaAttribute *_a; \
    1319         _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
    1320         if (_a && _a->value_ctr.num_values >= 1 \
    1321             && _a->value_ctr.values[0].blob \
    1322             && _a->value_ctr.values[0].blob->length == 4) { \
    1323                 (p)->elem = IVAL(_a->value_ctr.values[0].blob->data,0);\
    1324         } else { \
    1325                 (p)->elem = 0; \
    1326         } \
    1327 } while (0)
    1328 
    1329 #define GET_UINT32_PTR_DS(s, r, attr, p, elem) do { \
    1330         struct drsuapi_DsReplicaAttribute *_a; \
    1331         _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
    1332         if (_a && _a->value_ctr.num_values >= 1 \
    1333             && _a->value_ctr.values[0].blob \
    1334             && _a->value_ctr.values[0].blob->length == 4) { \
    1335                 (p)->elem = talloc(mem_ctx, uint32_t); \
    1336                 if (!(p)->elem) { \
    1337                         d_printf("%s: talloc failed for %s\n", __location__, attr); \
    1338                         return WERR_NOMEM; \
    1339                 } \
    1340                 *(p)->elem = IVAL(_a->value_ctr.values[0].blob->data,0);\
    1341         } else { \
    1342                 (p)->elem = NULL; \
    1343         } \
    1344 } while (0)
    1345 
    1346 #define GET_GUID_DS(s, r, attr, mem_ctx, p, elem) do { \
    1347         struct drsuapi_DsReplicaAttribute *_a; \
    1348         _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
    1349         if (_a && _a->value_ctr.num_values >= 1 \
    1350             && _a->value_ctr.values[0].blob \
    1351             && _a->value_ctr.values[0].blob->length == 16) { \
    1352                 enum ndr_err_code _ndr_err; \
    1353                 _ndr_err = ndr_pull_struct_blob_all(_a->value_ctr.values[0].blob, \
    1354                                                       mem_ctx, s->iconv_convenience, &(p)->elem, \
    1355                                                       (ndr_pull_flags_fn_t)ndr_pull_GUID); \
    1356                 if (!NDR_ERR_CODE_IS_SUCCESS(_ndr_err)) { \
    1357                         NTSTATUS _nt_status = ndr_map_error2ntstatus(_ndr_err); \
    1358                         return ntstatus_to_werror(_nt_status); \
    1359                 } \
    1360         } else { \
    1361                 ZERO_STRUCT((p)->elem);\
    1362         } \
    1363 } while (0)
    1364 
    1365 #define GET_BLOB_DS(s, r, attr, mem_ctx, p, elem) do { \
    1366         struct drsuapi_DsReplicaAttribute *_a; \
    1367         _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
    1368         if (_a && _a->value_ctr.num_values >= 1 \
    1369             && _a->value_ctr.values[0].blob) { \
    1370                 (p)->elem = *_a->value_ctr.values[0].blob;\
    1371                 talloc_steal(mem_ctx, (p)->elem.data); \
    1372         } else { \
    1373                 ZERO_STRUCT((p)->elem);\
    1374         }\
    1375 } while (0)
    1376 
    1377 WERROR dsdb_attribute_from_drsuapi(struct ldb_context *ldb,
    1378                                    struct dsdb_schema *schema,
    1379                                    struct drsuapi_DsReplicaObject *r,
    1380                                    TALLOC_CTX *mem_ctx,
    1381                                    struct dsdb_attribute *attr)
    1382 {
    1383         WERROR status;
    1384 
    1385         GET_STRING_DS(schema, r, "name", mem_ctx, attr, cn, true);
    1386         GET_STRING_DS(schema, r, "lDAPDisplayName", mem_ctx, attr, lDAPDisplayName, true);
    1387         GET_UINT32_DS(schema, r, "attributeID", attr, attributeID_id);
    1388         status = dsdb_map_int2oid(schema, attr->attributeID_id, mem_ctx, &attr->attributeID_oid);
    1389         if (!W_ERROR_IS_OK(status)) {
    1390                 DEBUG(0,("%s: '%s': unable to map attributeID 0x%08X: %s\n",
    1391                         __location__, attr->lDAPDisplayName, attr->attributeID_id,
    1392                         win_errstr(status)));
    1393                 return status;
    1394         }
    1395         GET_GUID_DS(schema, r, "schemaIDGUID", mem_ctx, attr, schemaIDGUID);
    1396         GET_UINT32_DS(schema, r, "mAPIID", attr, mAPIID);
    1397 
    1398         GET_GUID_DS(schema, r, "attributeSecurityGUID", mem_ctx, attr, attributeSecurityGUID);
    1399 
    1400         GET_UINT32_DS(schema, r, "searchFlags", attr, searchFlags);
    1401         GET_UINT32_DS(schema, r, "systemFlags", attr, systemFlags);
    1402         GET_BOOL_DS(schema, r, "isMemberOfPartialAttributeSet", attr, isMemberOfPartialAttributeSet, false);
    1403         GET_UINT32_DS(schema, r, "linkID", attr, linkID);
    1404 
    1405         GET_UINT32_DS(schema, r, "attributeSyntax", attr, attributeSyntax_id);
    1406         status = dsdb_map_int2oid(schema, attr->attributeSyntax_id, mem_ctx, &attr->attributeSyntax_oid);
    1407         if (!W_ERROR_IS_OK(status)) {
    1408                 DEBUG(0,("%s: '%s': unable to map attributeSyntax 0x%08X: %s\n",
    1409                         __location__, attr->lDAPDisplayName, attr->attributeSyntax_id,
    1410                         win_errstr(status)));
    1411                 return status;
    1412         }
    1413         GET_UINT32_DS(schema, r, "oMSyntax", attr, oMSyntax);
    1414         GET_BLOB_DS(schema, r, "oMObjectClass", mem_ctx, attr, oMObjectClass);
    1415 
    1416         GET_BOOL_DS(schema, r, "isSingleValued", attr, isSingleValued, true);
    1417         GET_UINT32_PTR_DS(schema, r, "rangeLower", attr, rangeLower);
    1418         GET_UINT32_PTR_DS(schema, r, "rangeUpper", attr, rangeUpper);
    1419         GET_BOOL_DS(schema, r, "extendedCharsAllowed", attr, extendedCharsAllowed, false);
    1420 
    1421         GET_UINT32_DS(schema, r, "schemaFlagsEx", attr, schemaFlagsEx);
    1422         GET_BLOB_DS(schema, r, "msDs-Schema-Extensions", mem_ctx, attr, msDs_Schema_Extensions);
    1423 
    1424         GET_BOOL_DS(schema, r, "showInAdvancedViewOnly", attr, showInAdvancedViewOnly, false);
    1425         GET_STRING_DS(schema, r, "adminDisplayName", mem_ctx, attr, adminDisplayName, false);
    1426         GET_STRING_DS(schema, r, "adminDescription", mem_ctx, attr, adminDescription, false);
    1427         GET_STRING_DS(schema, r, "classDisplayName", mem_ctx, attr, classDisplayName, false);
    1428         GET_BOOL_DS(schema, r, "isEphemeral", attr, isEphemeral, false);
    1429         GET_BOOL_DS(schema, r, "isDefunct", attr, isDefunct, false);
    1430         GET_BOOL_DS(schema, r, "systemOnly", attr, systemOnly, false);
    1431 
    1432         attr->syntax = dsdb_syntax_for_attribute(attr);
    1433         if (!attr->syntax) {
    1434                 return WERR_DS_ATT_SCHEMA_REQ_SYNTAX;
    1435         }
    1436 
    1437         if (dsdb_schema_setup_ldb_schema_attribute(ldb, attr) != LDB_SUCCESS) {
    1438                 return WERR_DS_ATT_SCHEMA_REQ_SYNTAX;
    1439         }
    1440 
    1441         return WERR_OK;
    1442 }
    1443 
    1444 WERROR dsdb_class_from_drsuapi(struct dsdb_schema *schema,
    1445                                struct drsuapi_DsReplicaObject *r,
    1446                                TALLOC_CTX *mem_ctx,
    1447                                struct dsdb_class *obj)
    1448 {
    1449         WERROR status;
    1450 
    1451         GET_STRING_DS(schema, r, "name", mem_ctx, obj, cn, true);
    1452         GET_STRING_DS(schema, r, "lDAPDisplayName", mem_ctx, obj, lDAPDisplayName, true);
    1453         GET_UINT32_DS(schema, r, "governsID", obj, governsID_id);
    1454         status = dsdb_map_int2oid(schema, obj->governsID_id, mem_ctx, &obj->governsID_oid);
    1455         if (!W_ERROR_IS_OK(status)) {
    1456                 DEBUG(0,("%s: '%s': unable to map governsID 0x%08X: %s\n",
    1457                         __location__, obj->lDAPDisplayName, obj->governsID_id,
    1458                         win_errstr(status)));
    1459                 return status;
    1460         }
    1461         GET_GUID_DS(schema, r, "schemaIDGUID", mem_ctx, obj, schemaIDGUID);
    1462 
    1463         GET_UINT32_DS(schema, r, "objectClassCategory", obj, objectClassCategory);
    1464         GET_STRING_DS(schema, r, "rDNAttID", mem_ctx, obj, rDNAttID, false);
    1465         GET_DN_DS(schema, r, "defaultObjectCategory", mem_ctx, obj, defaultObjectCategory, true);
    1466 
    1467         GET_UINT32_DS(schema, r, "subClassOf", obj, subClassOf_id);
    1468 
    1469         GET_UINT32_LIST_DS(schema, r, "systemAuxiliaryClass", mem_ctx, obj, systemAuxiliaryClass_ids);
    1470         GET_UINT32_LIST_DS(schema, r, "auxiliaryClass", mem_ctx, obj, auxiliaryClass_ids);
    1471 
    1472         GET_UINT32_LIST_DS(schema, r, "systemMustContain", mem_ctx, obj, systemMustContain_ids);
    1473         GET_UINT32_LIST_DS(schema, r, "systemMayContain", mem_ctx, obj, systemMayContain_ids);
    1474         GET_UINT32_LIST_DS(schema, r, "mustContain", mem_ctx, obj, mustContain_ids);
    1475         GET_UINT32_LIST_DS(schema, r, "mayContain", mem_ctx, obj, mayContain_ids);
    1476 
    1477         GET_UINT32_LIST_DS(schema, r, "systemPossSuperiors", mem_ctx, obj, systemPossSuperiors_ids);
    1478         GET_UINT32_LIST_DS(schema, r, "possSuperiors", mem_ctx, obj, possSuperiors_ids);
    1479 
    1480         GET_STRING_DS(schema, r, "defaultSecurityDescriptor", mem_ctx, obj, defaultSecurityDescriptor, false);
    1481 
    1482         GET_UINT32_DS(schema, r, "schemaFlagsEx", obj, schemaFlagsEx);
    1483         GET_BLOB_DS(schema, r, "msDs-Schema-Extensions", mem_ctx, obj, msDs_Schema_Extensions);
    1484 
    1485         GET_BOOL_DS(schema, r, "showInAdvancedViewOnly", obj, showInAdvancedViewOnly, false);
    1486         GET_STRING_DS(schema, r, "adminDisplayName", mem_ctx, obj, adminDisplayName, false);
    1487         GET_STRING_DS(schema, r, "adminDescription", mem_ctx, obj, adminDescription, false);
    1488         GET_STRING_DS(schema, r, "classDisplayName", mem_ctx, obj, classDisplayName, false);
    1489         GET_BOOL_DS(schema, r, "defaultHidingValue", obj, defaultHidingValue, false);
    1490         GET_BOOL_DS(schema, r, "isDefunct", obj, isDefunct, false);
    1491         GET_BOOL_DS(schema, r, "systemOnly", obj, systemOnly, false);
    1492 
    1493         return WERR_OK;
    1494 }
    1495 
  • vendor/current/source4/dsdb/schema/schema_query.c

    r414 r740  
    2323#include "includes.h"
    2424#include "dsdb/samdb/samdb.h"
    25 
    26 /* a binary array search, where the array is an array of pointers to structures,
    27    and we want to find a match for 'target' on 'field' in those structures.
    28 
    29    Inputs:
    30       array:          base pointer to an array of structures
    31       arrray_size:    number of elements in the array
    32       field:          the name of the field in the structure we are keying off
    33       target:         the field value we are looking for
    34       comparison_fn:  the comparison function
    35       result:         where the result of the search is put
    36 
    37    if the element is found, then 'result' is set to point to the found array element. If not,
    38    then 'result' is set to NULL.
    39 
    40    The array is assumed to be sorted by the same comparison_fn as the
    41    search (with, for example, qsort)
    42  */
    43 #define BINARY_ARRAY_SEARCH(array, array_size, field, target, comparison_fn, result) do { \
    44         int32_t _b, _e; \
    45         (result) = NULL; \
    46         for (_b = 0, _e = (array_size)-1; _b <= _e; ) { \
    47                 int32_t _i = (_b+_e)/2; \
    48                 int _r = comparison_fn(target, array[_i]->field); \
    49                 if (_r == 0) { (result) = array[_i]; break; } \
    50                 if (_r < 0) _e = _i - 1; else _b = _i + 1; \
    51         } } while (0)
    52 
     25#include "lib/util/binsearch.h"
     26#include "lib/util/tsort.h"
    5327
    5428static const char **dsdb_full_attribute_list_internal(TALLOC_CTX *mem_ctx,
     
    5933static int uint32_cmp(uint32_t c1, uint32_t c2)
    6034{
    61         return c1 - c2;
     35        if (c1 == c2) return 0;
     36        return c1 > c2 ? 1 : -1;
    6237}
    6338
     
    6641        int ret = strncasecmp((const char *)target->data, str, target->length);
    6742        if (ret == 0) {
    68                 return (target->length - strlen(str));
     43                size_t len = strlen(str);
     44                if (target->length > len) {
     45                        if (target->data[len] == 0) {
     46                                return 0;
     47                        }
     48                        return 1;
     49                }
     50                return (target->length - len);
    6951        }
    7052        return ret;
     
    8264        if (id == 0xFFFFFFFF) return NULL;
    8365
    84         BINARY_ARRAY_SEARCH(schema->attributes_by_attributeID_id,
    85                             schema->num_attributes, attributeID_id, id, uint32_cmp, c);
     66        /* check for msDS-IntId type attribute */
     67        if (dsdb_pfm_get_attid_type(id) == DSDB_ATTID_TYPE_INTID) {
     68                BINARY_ARRAY_SEARCH_P(schema->attributes_by_msDS_IntId,
     69                                      schema->num_int_id_attr, msDS_IntId, id, uint32_cmp, c);
     70                return c;
     71        }
     72
     73        BINARY_ARRAY_SEARCH_P(schema->attributes_by_attributeID_id,
     74                              schema->num_attributes, attributeID_id, id, uint32_cmp, c);
    8675        return c;
    8776}
     
    9483        if (!oid) return NULL;
    9584
    96         BINARY_ARRAY_SEARCH(schema->attributes_by_attributeID_oid,
    97                             schema->num_attributes, attributeID_oid, oid, strcasecmp, c);
     85        BINARY_ARRAY_SEARCH_P(schema->attributes_by_attributeID_oid,
     86                              schema->num_attributes, attributeID_oid, oid, strcasecmp, c);
    9887        return c;
    9988}
     
    10695        if (!name) return NULL;
    10796
    108         BINARY_ARRAY_SEARCH(schema->attributes_by_lDAPDisplayName,
    109                             schema->num_attributes, lDAPDisplayName, name, strcasecmp, c);
    110         return c;
     97        BINARY_ARRAY_SEARCH_P(schema->attributes_by_lDAPDisplayName,
     98                              schema->num_attributes, lDAPDisplayName, name, strcasecmp, c);
     99        return c;
     100}
     101
     102const struct dsdb_attribute *dsdb_attribute_by_lDAPDisplayName_ldb_val(const struct dsdb_schema *schema,
     103                                                                       const struct ldb_val *name)
     104{
     105        struct dsdb_attribute *a;
     106
     107        if (!name) return NULL;
     108
     109        BINARY_ARRAY_SEARCH_P(schema->attributes_by_lDAPDisplayName,
     110                              schema->num_attributes, lDAPDisplayName, name, strcasecmp_with_ldb_val, a);
     111        return a;
    111112}
    112113
     
    116117        struct dsdb_attribute *c;
    117118
    118         BINARY_ARRAY_SEARCH(schema->attributes_by_linkID,
    119                             schema->num_attributes, linkID, linkID, uint32_cmp, c);
     119        BINARY_ARRAY_SEARCH_P(schema->attributes_by_linkID,
     120                              schema->num_attributes, linkID, linkID, uint32_cmp, c);
    120121        return c;
    121122}
     
    132133        if (id == 0xFFFFFFFF) return NULL;
    133134
    134         BINARY_ARRAY_SEARCH(schema->classes_by_governsID_id,
    135                             schema->num_classes, governsID_id, id, uint32_cmp, c);
     135        BINARY_ARRAY_SEARCH_P(schema->classes_by_governsID_id,
     136                              schema->num_classes, governsID_id, id, uint32_cmp, c);
    136137        return c;
    137138}
     
    142143        struct dsdb_class *c;
    143144        if (!oid) return NULL;
    144         BINARY_ARRAY_SEARCH(schema->classes_by_governsID_oid,
    145                             schema->num_classes, governsID_oid, oid, strcasecmp, c);
     145        BINARY_ARRAY_SEARCH_P(schema->classes_by_governsID_oid,
     146                              schema->num_classes, governsID_oid, oid, strcasecmp, c);
    146147        return c;
    147148}
     
    152153        struct dsdb_class *c;
    153154        if (!name) return NULL;
    154         BINARY_ARRAY_SEARCH(schema->classes_by_lDAPDisplayName,
    155                             schema->num_classes, lDAPDisplayName, name, strcasecmp, c);
     155        BINARY_ARRAY_SEARCH_P(schema->classes_by_lDAPDisplayName,
     156                              schema->num_classes, lDAPDisplayName, name, strcasecmp, c);
    156157        return c;
    157158}
     
    162163        struct dsdb_class *c;
    163164        if (!name) return NULL;
    164         BINARY_ARRAY_SEARCH(schema->classes_by_lDAPDisplayName,
    165                             schema->num_classes, lDAPDisplayName, name, strcasecmp_with_ldb_val, c);
     165        BINARY_ARRAY_SEARCH_P(schema->classes_by_lDAPDisplayName,
     166                              schema->num_classes, lDAPDisplayName, name, strcasecmp_with_ldb_val, c);
    166167        return c;
    167168}
     
    172173        struct dsdb_class *c;
    173174        if (!cn) return NULL;
    174         BINARY_ARRAY_SEARCH(schema->classes_by_cn,
    175                             schema->num_classes, cn, cn, strcasecmp, c);
     175        BINARY_ARRAY_SEARCH_P(schema->classes_by_cn,
     176                              schema->num_classes, cn, cn, strcasecmp, c);
    176177        return c;
    177178}
     
    182183        struct dsdb_class *c;
    183184        if (!cn) return NULL;
    184         BINARY_ARRAY_SEARCH(schema->classes_by_cn,
    185                             schema->num_classes, cn, cn, strcasecmp_with_ldb_val, c);
     185        BINARY_ARRAY_SEARCH_P(schema->classes_by_cn,
     186                              schema->num_classes, cn, cn, strcasecmp_with_ldb_val, c);
    186187        return c;
    187188}
     
    217218        const char **attr_list = NULL;
    218219        struct dsdb_attribute *cur;
    219         int i = 0;
     220        unsigned int i = 0;
    220221        for (cur = schema->attributes; cur; cur = cur->next) {
    221222                if (cur->linkID == 0) continue;
     
    237238{
    238239        const char **ret_attrs;
    239         int i;
     240        unsigned int i;
    240241        size_t new_len, orig_len = str_list_length(attrs);
    241242        if (!new_attrs) {
     
    337338                                                      enum dsdb_attr_list_query query)
    338339{
    339         int i;
     340        unsigned int i;
    340341        const char **attr_list = NULL;
    341342
     
    364365                                                         enum dsdb_attr_list_query query)
    365366{
    366         int i;
     367        unsigned int i;
    367368        const char **attr_list = NULL;
    368369
     
    378379}
    379380
     381static int qsort_string(const char **s1, const char **s2)
     382{
     383        return strcasecmp(*s1, *s2);
     384}
     385
    380386/* Helper function to remove duplicates from the attribute list to be returned */
    381387static const char **dedup_attr_list(const char **attr_list)
     
    384390        /* Remove duplicates */
    385391        if (new_len > 1) {
    386                 int i;
    387                 qsort(attr_list, new_len,
    388                       sizeof(*attr_list),
    389                       (comparison_fn_t)strcasecmp);
    390                
    391                 for (i=1 ; i < new_len; i++) {
     392                size_t i;
     393                TYPESAFE_QSORT(attr_list, new_len, qsort_string);
     394               
     395                for (i=1; i < new_len; i++) {
    392396                        const char **val1 = &attr_list[i-1];
    393397                        const char **val2 = &attr_list[i];
    394398                        if (ldb_attr_cmp(*val1, *val2) == 0) {
    395399                                memmove(val1, val2, (new_len - i) * sizeof( *attr_list));
     400                                attr_list[new_len-1] = NULL;
    396401                                new_len--;
    397402                                i--;
     
    420425/* Return the schemaIDGUID of a class */
    421426
    422 const struct GUID * class_schemaid_guid_by_lDAPDisplayName(const struct dsdb_schema *schema,
    423                                                            const char *name)
     427const struct GUID *class_schemaid_guid_by_lDAPDisplayName(const struct dsdb_schema *schema,
     428                                                          const char *name)
    424429{
    425430        const struct dsdb_class *object_class = dsdb_class_by_lDAPDisplayName(schema, name);
     
    429434        return &object_class->schemaIDGUID;
    430435}
     436
     437const struct GUID *attribute_schemaid_guid_by_lDAPDisplayName(const struct dsdb_schema *schema,
     438                                                              const char *name)
     439{
     440        const struct dsdb_attribute *attr = dsdb_attribute_by_lDAPDisplayName(schema, name);
     441        if (!attr)
     442                return NULL;
     443
     444        return &attr->schemaIDGUID;
     445}
  • vendor/current/source4/dsdb/schema/schema_set.c

    r414 r740  
    1 /* 
    2    Unix SMB/CIFS mplementation.
     1/*
     2   Unix SMB/CIFS implementation.
    33   DSDB schema header
    4    
     4
    55   Copyright (C) Stefan Metzmacher <metze@samba.org> 2006-2007
    66   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2006-2008
     
    1010   the Free Software Foundation; either version 3 of the License, or
    1111   (at your option) any later version.
    12    
     12
    1313   This program is distributed in the hope that it will be useful,
    1414   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1515   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1616   GNU General Public License for more details.
    17    
     17
    1818   You should have received a copy of the GNU General Public License
    1919   along with this program.  If not, see <http://www.gnu.org/licenses/>.
    20    
     20
    2121*/
    2222
     
    2424#include "lib/util/dlinklist.h"
    2525#include "dsdb/samdb/samdb.h"
    26 #include "lib/ldb/include/ldb_module.h"
     26#include <ldb_module.h>
    2727#include "param/param.h"
     28#include "librpc/ndr/libndr.h"
     29#include "librpc/gen_ndr/ndr_misc.h"
     30#include "lib/util/tsort.h"
    2831
    2932/*
    3033  override the name to attribute handler function
    3134 */
    32 const struct ldb_schema_attribute *dsdb_attribute_handler_override(struct ldb_context *ldb, 
     35const struct ldb_schema_attribute *dsdb_attribute_handler_override(struct ldb_context *ldb,
    3336                                                                   void *private_data,
    3437                                                                   const char *name)
     
    6366        mem_ctx = talloc_new(ldb);
    6467        if (!mem_ctx) {
    65                 return LDB_ERR_OPERATIONS_ERROR;
     68                return ldb_oom(ldb);
    6669        }
    6770
     
    8184                goto op_error;
    8285        }
    83         msg_idx->dn = ldb_dn_new(msg, ldb, "@INDEXLIST");
     86        msg_idx->dn = ldb_dn_new(msg_idx, ldb, "@INDEXLIST");
    8487        if (!msg_idx->dn) {
    8588                ldb_oom(ldb);
     
    9497        for (attr = schema->attributes; attr; attr = attr->next) {
    9598                const char *syntax = attr->syntax->ldb_syntax;
    96                
     99
    97100                if (!syntax) {
    98101                        syntax = attr->syntax->ldap_oid;
    99102                }
    100103
    101                 /* Write out a rough approximation of the schema as an @ATTRIBUTES value, for bootstrapping */
     104                /*
     105                 * Write out a rough approximation of the schema
     106                 * as an @ATTRIBUTES value, for bootstrapping
     107                 */
    102108                if (strcmp(syntax, LDB_SYNTAX_INTEGER) == 0) {
    103109                        ret = ldb_msg_add_string(msg, attr->lDAPDisplayName, "INTEGER");
    104110                } else if (strcmp(syntax, LDB_SYNTAX_DIRECTORY_STRING) == 0) {
    105111                        ret = ldb_msg_add_string(msg, attr->lDAPDisplayName, "CASE_INSENSITIVE");
    106                 } 
     112                }
    107113                if (ret != LDB_SUCCESS) {
    108114                        break;
     
    122128        }
    123129
    124         /* Try to avoid churning the attributes too much - we only want to do this if they have changed */
    125         ret = ldb_search(ldb, mem_ctx, &res, msg->dn, LDB_SCOPE_BASE, NULL, "dn=%s", ldb_dn_get_linearized(msg->dn));
     130        /*
     131         * Try to avoid churning the attributes too much,
     132         * we only want to do this if they have changed
     133         */
     134        ret = ldb_search(ldb, mem_ctx, &res, msg->dn, LDB_SCOPE_BASE, NULL,
     135                         NULL);
    126136        if (ret == LDB_ERR_NO_SUCH_OBJECT) {
    127137                ret = ldb_add(ldb, msg);
     
    133143                /* Annoyingly added to our search results */
    134144                ldb_msg_remove_attr(res->msgs[0], "distinguishedName");
    135                
    136                 mod_msg = ldb_msg_diff(ldb, res->msgs[0], msg);
     145
     146                ret = ldb_msg_difference(ldb, mem_ctx,
     147                                         res->msgs[0], msg, &mod_msg);
     148                if (ret != LDB_SUCCESS) {
     149                        goto op_error;
     150                }
    137151                if (mod_msg->num_elements > 0) {
    138                         ret = samdb_replace(ldb, mem_ctx, mod_msg);
    139                 }
    140         }
    141 
    142         if (ret == LDB_ERR_OPERATIONS_ERROR || ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) {
    143                 /* We might be on a read-only DB */
     152                        ret = dsdb_replace(ldb, mod_msg, 0);
     153                }
     154                talloc_free(mod_msg);
     155        }
     156
     157        if (ret == LDB_ERR_OPERATIONS_ERROR || ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS || ret == LDB_ERR_INVALID_DN_SYNTAX) {
     158                /* We might be on a read-only DB or LDAP */
    144159                ret = LDB_SUCCESS;
    145160        }
     
    149164        }
    150165
    151         /* Now write out the indexs, as found in the schema (if they have changed) */
    152 
    153         ret = ldb_search(ldb, mem_ctx, &res_idx, msg_idx->dn, LDB_SCOPE_BASE, NULL, "dn=%s", ldb_dn_get_linearized(msg_idx->dn));
     166        /* Now write out the indexes, as found in the schema (if they have changed) */
     167
     168        ret = ldb_search(ldb, mem_ctx, &res_idx, msg_idx->dn, LDB_SCOPE_BASE,
     169                         NULL, NULL);
    154170        if (ret == LDB_ERR_NO_SUCH_OBJECT) {
    155171                ret = ldb_add(ldb, msg_idx);
     
    162178                ldb_msg_remove_attr(res_idx->msgs[0], "distinguishedName");
    163179
    164                 mod_msg = ldb_msg_diff(ldb, res_idx->msgs[0], msg_idx);
     180                ret = ldb_msg_difference(ldb, mem_ctx,
     181                                         res_idx->msgs[0], msg_idx, &mod_msg);
     182                if (ret != LDB_SUCCESS) {
     183                        goto op_error;
     184                }
    165185                if (mod_msg->num_elements > 0) {
    166                         ret = samdb_replace(ldb, mem_ctx, mod_msg);
    167                 }
    168         }
    169         if (ret == LDB_ERR_OPERATIONS_ERROR || ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) {
     186                        ret = dsdb_replace(ldb, mod_msg, 0);
     187                }
     188                talloc_free(mod_msg);
     189        }
     190        if (ret == LDB_ERR_OPERATIONS_ERROR || ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS || ret == LDB_ERR_INVALID_DN_SYNTAX) {
    170191                /* We might be on a read-only DB */
    171192                ret = LDB_SUCCESS;
     
    176197op_error:
    177198        talloc_free(mem_ctx);
    178         return LDB_ERR_OPERATIONS_ERROR;
     199        return ldb_operr(ldb);
     200}
     201
     202static int uint32_cmp(uint32_t c1, uint32_t c2)
     203{
     204        if (c1 == c2) return 0;
     205        return c1 > c2 ? 1 : -1;
    179206}
    180207
     
    185212static int dsdb_compare_class_by_governsID_id(struct dsdb_class **c1, struct dsdb_class **c2)
    186213{
    187         return (*c1)->governsID_id - (*c2)->governsID_id;
     214        return uint32_cmp((*c1)->governsID_id, (*c2)->governsID_id);
    188215}
    189216static int dsdb_compare_class_by_governsID_oid(struct dsdb_class **c1, struct dsdb_class **c2)
     
    202229static int dsdb_compare_attribute_by_attributeID_id(struct dsdb_attribute **a1, struct dsdb_attribute **a2)
    203230{
    204         return (*a1)->attributeID_id - (*a2)->attributeID_id;
     231        return uint32_cmp((*a1)->attributeID_id, (*a2)->attributeID_id);
     232}
     233static int dsdb_compare_attribute_by_msDS_IntId(struct dsdb_attribute **a1, struct dsdb_attribute **a2)
     234{
     235        return uint32_cmp((*a1)->msDS_IntId, (*a2)->msDS_IntId);
    205236}
    206237static int dsdb_compare_attribute_by_attributeID_oid(struct dsdb_attribute **a1, struct dsdb_attribute **a2)
     
    210241static int dsdb_compare_attribute_by_linkID(struct dsdb_attribute **a1, struct dsdb_attribute **a2)
    211242{
    212         return (*a1)->linkID - (*a2)->linkID;
     243        return uint32_cmp((*a1)->linkID, (*a2)->linkID);
     244}
     245
     246/**
     247 * Clean up Classes and Attributes accessor arrays
     248 */
     249static void dsdb_sorted_accessors_free(struct dsdb_schema *schema)
     250{
     251        /* free classes accessors */
     252        TALLOC_FREE(schema->classes_by_lDAPDisplayName);
     253        TALLOC_FREE(schema->classes_by_governsID_id);
     254        TALLOC_FREE(schema->classes_by_governsID_oid);
     255        TALLOC_FREE(schema->classes_by_cn);
     256        /* free attribute accessors */
     257        TALLOC_FREE(schema->attributes_by_lDAPDisplayName);
     258        TALLOC_FREE(schema->attributes_by_attributeID_id);
     259        TALLOC_FREE(schema->attributes_by_msDS_IntId);
     260        TALLOC_FREE(schema->attributes_by_attributeID_oid);
     261        TALLOC_FREE(schema->attributes_by_linkID);
    213262}
    214263
     
    216265  create the sorted accessor arrays for the schema
    217266 */
    218 static int dsdb_setup_sorted_accessors(struct ldb_context *ldb,
    219                                        struct dsdb_schema *schema)
     267int dsdb_setup_sorted_accessors(struct ldb_context *ldb,
     268                                struct dsdb_schema *schema)
    220269{
    221270        struct dsdb_class *cur;
    222271        struct dsdb_attribute *a;
    223         uint32_t i;
    224 
    225         talloc_free(schema->classes_by_lDAPDisplayName);
    226         talloc_free(schema->classes_by_governsID_id);
    227         talloc_free(schema->classes_by_governsID_oid);
    228         talloc_free(schema->classes_by_cn);
     272        unsigned int i;
     273        unsigned int num_int_id;
     274
     275        /* free all caches */
     276        dsdb_sorted_accessors_free(schema);
    229277
    230278        /* count the classes */
     
    252300
    253301        /* sort the arrays */
    254         qsort(schema->classes_by_lDAPDisplayName, schema->num_classes,
    255               sizeof(struct dsdb_class *), QSORT_CAST dsdb_compare_class_by_lDAPDisplayName);
    256         qsort(schema->classes_by_governsID_id, schema->num_classes,
    257               sizeof(struct dsdb_class *), QSORT_CAST dsdb_compare_class_by_governsID_id);
    258         qsort(schema->classes_by_governsID_oid, schema->num_classes,
    259               sizeof(struct dsdb_class *), QSORT_CAST dsdb_compare_class_by_governsID_oid);
    260         qsort(schema->classes_by_cn, schema->num_classes,
    261               sizeof(struct dsdb_class *), QSORT_CAST dsdb_compare_class_by_cn);
     302        TYPESAFE_QSORT(schema->classes_by_lDAPDisplayName, schema->num_classes, dsdb_compare_class_by_lDAPDisplayName);
     303        TYPESAFE_QSORT(schema->classes_by_governsID_id, schema->num_classes, dsdb_compare_class_by_governsID_id);
     304        TYPESAFE_QSORT(schema->classes_by_governsID_oid, schema->num_classes, dsdb_compare_class_by_governsID_oid);
     305        TYPESAFE_QSORT(schema->classes_by_cn, schema->num_classes, dsdb_compare_class_by_cn);
    262306
    263307        /* now build the attribute accessor arrays */
    264         talloc_free(schema->attributes_by_lDAPDisplayName);
    265         talloc_free(schema->attributes_by_attributeID_id);
    266         talloc_free(schema->attributes_by_attributeID_oid);
    267         talloc_free(schema->attributes_by_linkID);
    268 
    269         /* count the attributes */
    270         for (i=0, a=schema->attributes; a; i++, a=a->next) /* noop */ ;
     308
     309        /* count the attributes
     310         * and attributes with msDS-IntId set */
     311        num_int_id = 0;
     312        for (i=0, a=schema->attributes; a; i++, a=a->next) {
     313                if (a->msDS_IntId != 0) {
     314                        num_int_id++;
     315                }
     316        }
    271317        schema->num_attributes = i;
     318        schema->num_int_id_attr = num_int_id;
    272319
    273320        /* setup attributes_by_* */
    274321        schema->attributes_by_lDAPDisplayName = talloc_array(schema, struct dsdb_attribute *, i);
    275322        schema->attributes_by_attributeID_id    = talloc_array(schema, struct dsdb_attribute *, i);
     323        schema->attributes_by_msDS_IntId        = talloc_array(schema,
     324                                                               struct dsdb_attribute *, num_int_id);
    276325        schema->attributes_by_attributeID_oid   = talloc_array(schema, struct dsdb_attribute *, i);
    277326        schema->attributes_by_linkID              = talloc_array(schema, struct dsdb_attribute *, i);
    278327        if (schema->attributes_by_lDAPDisplayName == NULL ||
    279328            schema->attributes_by_attributeID_id == NULL ||
     329            schema->attributes_by_msDS_IntId == NULL ||
    280330            schema->attributes_by_attributeID_oid == NULL ||
    281331            schema->attributes_by_linkID == NULL) {
     
    283333        }
    284334
     335        num_int_id = 0;
    285336        for (i=0, a=schema->attributes; a; i++, a=a->next) {
    286337                schema->attributes_by_lDAPDisplayName[i] = a;
     
    288339                schema->attributes_by_attributeID_oid[i]   = a;
    289340                schema->attributes_by_linkID[i]          = a;
    290         }
     341                /* append attr-by-msDS-IntId values */
     342                if (a->msDS_IntId != 0) {
     343                        schema->attributes_by_msDS_IntId[num_int_id] = a;
     344                        num_int_id++;
     345                }
     346        }
     347        SMB_ASSERT(num_int_id == schema->num_int_id_attr);
    291348
    292349        /* sort the arrays */
    293         qsort(schema->attributes_by_lDAPDisplayName, schema->num_attributes,
    294               sizeof(struct dsdb_attribute *), QSORT_CAST dsdb_compare_attribute_by_lDAPDisplayName);
    295         qsort(schema->attributes_by_attributeID_id, schema->num_attributes,
    296               sizeof(struct dsdb_attribute *), QSORT_CAST dsdb_compare_attribute_by_attributeID_id);
    297         qsort(schema->attributes_by_attributeID_oid, schema->num_attributes,
    298               sizeof(struct dsdb_attribute *), QSORT_CAST dsdb_compare_attribute_by_attributeID_oid);
    299         qsort(schema->attributes_by_linkID, schema->num_attributes,
    300               sizeof(struct dsdb_attribute *), QSORT_CAST dsdb_compare_attribute_by_linkID);
     350        TYPESAFE_QSORT(schema->attributes_by_lDAPDisplayName, schema->num_attributes, dsdb_compare_attribute_by_lDAPDisplayName);
     351        TYPESAFE_QSORT(schema->attributes_by_attributeID_id, schema->num_attributes, dsdb_compare_attribute_by_attributeID_id);
     352        TYPESAFE_QSORT(schema->attributes_by_msDS_IntId, schema->num_int_id_attr, dsdb_compare_attribute_by_msDS_IntId);
     353        TYPESAFE_QSORT(schema->attributes_by_attributeID_oid, schema->num_attributes, dsdb_compare_attribute_by_attributeID_oid);
     354        TYPESAFE_QSORT(schema->attributes_by_linkID, schema->num_attributes, dsdb_compare_attribute_by_linkID);
    301355
    302356        return LDB_SUCCESS;
    303357
    304358failed:
    305         schema->classes_by_lDAPDisplayName = NULL;
    306         schema->classes_by_governsID_id = NULL;
    307         schema->classes_by_governsID_oid = NULL;
    308         schema->classes_by_cn = NULL;
    309         schema->attributes_by_lDAPDisplayName = NULL;
    310         schema->attributes_by_attributeID_id = NULL;
    311         schema->attributes_by_attributeID_oid = NULL;
    312         schema->attributes_by_linkID = NULL;
    313         ldb_oom(ldb);
    314         return LDB_ERR_OPERATIONS_ERROR;
     359        dsdb_sorted_accessors_free(schema);
     360        return ldb_oom(ldb);
    315361}
    316362
     
    327373         * objectClass lists efficiently) */
    328374
    329         /* Walk the list of scheam classes */
    330        
     375        /* Walk the list of schema classes */
     376
    331377        /*  Create a 'total possible superiors' on each class */
    332378        return LDB_SUCCESS;
     
    334380
    335381/**
    336  * Attach the schema to an opaque pointer on the ldb, so ldb modules
    337  * can find it
    338  */
    339 
     382 * Attach the schema to an opaque pointer on the ldb,
     383 * so ldb modules can find it
     384 */
    340385int dsdb_set_schema(struct ldb_context *ldb, struct dsdb_schema *schema)
    341386{
     387        struct dsdb_schema *old_schema;
    342388        int ret;
    343389
     
    347393        }
    348394
    349         schema_fill_constructed(schema);
     395        ret = schema_fill_constructed(schema);
     396        if (ret != LDB_SUCCESS) {
     397                return ret;
     398        }
     399
     400        old_schema = ldb_get_opaque(ldb, "dsdb_schema");
    350401
    351402        ret = ldb_set_opaque(ldb, "dsdb_schema", schema);
     403        if (ret != LDB_SUCCESS) {
     404                return ret;
     405        }
     406
     407        /* Remove the reference to the schema we just overwrote - if there was
     408         * none, NULL is harmless here */
     409        if (old_schema != schema) {
     410                talloc_unlink(ldb, old_schema);
     411                talloc_steal(ldb, schema);
     412        }
     413
     414        ret = ldb_set_opaque(ldb, "dsdb_use_global_schema", NULL);
    352415        if (ret != LDB_SUCCESS) {
    353416                return ret;
     
    360423        }
    361424
    362         talloc_steal(ldb, schema);
    363 
    364425        return LDB_SUCCESS;
    365426}
     
    377438{
    378439        int ret;
     440        struct dsdb_schema *old_schema;
     441        old_schema = ldb_get_opaque(ldb, "dsdb_schema");
    379442        ret = ldb_set_opaque(ldb, "dsdb_schema", schema);
    380443        if (ret != LDB_SUCCESS) {
     
    382445        }
    383446
    384         /* Set the new attributes based on the new schema */
     447        /* Remove the reference to the schema we just overwrote - if there was
     448         * none, NULL is harmless here */
     449        talloc_unlink(ldb, old_schema);
     450
     451        if (talloc_reference(ldb, schema) == NULL) {
     452                return ldb_oom(ldb);
     453        }
     454
     455        /* Make this ldb use local schema preferably */
     456        ret = ldb_set_opaque(ldb, "dsdb_use_global_schema", NULL);
     457        if (ret != LDB_SUCCESS) {
     458                return ret;
     459        }
     460
    385461        ret = dsdb_schema_set_attributes(ldb, schema, write_attributes);
    386462        if (ret != LDB_SUCCESS) {
     
    388464        }
    389465
    390         /* Keep a reference to this schema, just incase the original copy is replaced */
    391         if (talloc_reference(ldb, schema) == NULL) {
    392                 return LDB_ERR_OPERATIONS_ERROR;
    393         }
    394 
    395466        return LDB_SUCCESS;
    396467}
     
    401472int dsdb_set_global_schema(struct ldb_context *ldb)
    402473{
     474        int ret;
     475        void *use_global_schema = (void *)1;
    403476        if (!global_schema) {
    404477                return LDB_SUCCESS;
    405478        }
    406 
    407         return dsdb_reference_schema(ldb, global_schema, false /* Don't write attributes, it's expensive */);
     479        ret = ldb_set_opaque(ldb, "dsdb_use_global_schema", use_global_schema);
     480        if (ret != LDB_SUCCESS) {
     481                return ret;
     482        }
     483
     484        /* Set the new attributes based on the new schema */
     485        ret = dsdb_schema_set_attributes(ldb, global_schema, false /* Don't write attributes, it's expensive */);
     486        if (ret == LDB_SUCCESS) {
     487                /* Keep a reference to this schema, just in case the original copy is replaced */
     488                if (talloc_reference(ldb, global_schema) == NULL) {
     489                        return ldb_oom(ldb);
     490                }
     491        }
     492
     493        return ret;
     494}
     495
     496bool dsdb_uses_global_schema(struct ldb_context *ldb)
     497{
     498        return (ldb_get_opaque(ldb, "dsdb_use_global_schema") != NULL);
    408499}
    409500
    410501/**
    411502 * Find the schema object for this ldb
    412  */
    413 
    414 struct dsdb_schema *dsdb_get_schema(struct ldb_context *ldb)
     503 *
     504 * If reference_ctx is not NULL, then talloc_reference onto that context
     505 */
     506
     507struct dsdb_schema *dsdb_get_schema(struct ldb_context *ldb, TALLOC_CTX *reference_ctx)
    415508{
    416509        const void *p;
    417         struct dsdb_schema *schema;
     510        struct dsdb_schema *schema_out;
     511        struct dsdb_schema *schema_in;
     512        bool use_global_schema;
     513        TALLOC_CTX *tmp_ctx = talloc_new(reference_ctx);
     514        if (!tmp_ctx) {
     515                return NULL;
     516        }
    418517
    419518        /* see if we have a cached copy */
    420         p = ldb_get_opaque(ldb, "dsdb_schema");
    421         if (!p) {
    422                 return NULL;
    423         }
    424 
    425         schema = talloc_get_type(p, struct dsdb_schema);
    426         if (!schema) {
    427                 return NULL;
    428         }
    429 
    430         return schema;
     519        use_global_schema = dsdb_uses_global_schema(ldb);
     520        if (use_global_schema) {
     521                schema_in = global_schema;
     522        } else {
     523                p = ldb_get_opaque(ldb, "dsdb_schema");
     524
     525                schema_in = talloc_get_type(p, struct dsdb_schema);
     526                if (!schema_in) {
     527                        talloc_free(tmp_ctx);
     528                        return NULL;
     529                }
     530        }
     531
     532        if (schema_in->refresh_fn && !schema_in->refresh_in_progress) {
     533                if (!talloc_reference(tmp_ctx, schema_in)) {
     534                        /*
     535                         * ensure that the schema_in->refresh_in_progress
     536                         * remains valid for the right amount of time
     537                         */
     538                        talloc_free(tmp_ctx);
     539                        return NULL;
     540                }
     541                schema_in->refresh_in_progress = true;
     542                /* This may change schema, if it needs to reload it from disk */
     543                schema_out = schema_in->refresh_fn(schema_in->loaded_from_module,
     544                                                   schema_in,
     545                                                   use_global_schema);
     546                schema_in->refresh_in_progress = false;
     547        } else {
     548                schema_out = schema_in;
     549        }
     550
     551        /* This removes the extra reference above */
     552        talloc_free(tmp_ctx);
     553        if (!reference_ctx) {
     554                return schema_out;
     555        } else {
     556                return talloc_reference(reference_ctx, schema_out);
     557        }
    431558}
    432559
     
    435562 */
    436563
    437 void dsdb_make_schema_global(struct ldb_context *ldb)
    438 {
    439         struct dsdb_schema *schema = dsdb_get_schema(ldb);
     564void dsdb_make_schema_global(struct ldb_context *ldb, struct dsdb_schema *schema)
     565{
    440566        if (!schema) {
    441567                return;
     
    447573
    448574        /* we want the schema to be around permanently */
    449         talloc_reparent(talloc_parent(schema), talloc_autofree_context(), schema);
    450 
     575        talloc_reparent(ldb, talloc_autofree_context(), schema);
    451576        global_schema = schema;
    452577
     578        /* This calls the talloc_reference() of the global schema back onto the ldb */
    453579        dsdb_set_global_schema(ldb);
    454580}
    455581
     582/**
     583 * When loading the schema from LDIF files, we don't get the extended DNs.
     584 *
     585 * We need to set these up, so that from the moment we start the provision,
     586 * the defaultObjectCategory links are set up correctly.
     587 */
     588int dsdb_schema_fill_extended_dn(struct ldb_context *ldb, struct dsdb_schema *schema)
     589{
     590        struct dsdb_class *cur;
     591        const struct dsdb_class *target_class;
     592        for (cur = schema->classes; cur; cur = cur->next) {
     593                const struct ldb_val *rdn;
     594                struct ldb_val guid;
     595                NTSTATUS status;
     596                struct ldb_dn *dn = ldb_dn_new(NULL, ldb, cur->defaultObjectCategory);
     597
     598                if (!dn) {
     599                        return LDB_ERR_INVALID_DN_SYNTAX;
     600                }
     601                rdn = ldb_dn_get_component_val(dn, 0);
     602                if (!rdn) {
     603                        talloc_free(dn);
     604                        return LDB_ERR_INVALID_DN_SYNTAX;
     605                }
     606                target_class = dsdb_class_by_cn_ldb_val(schema, rdn);
     607                if (!target_class) {
     608                        talloc_free(dn);
     609                        return LDB_ERR_CONSTRAINT_VIOLATION;
     610                }
     611
     612                status = GUID_to_ndr_blob(&target_class->objectGUID, dn, &guid);
     613                if (!NT_STATUS_IS_OK(status)) {
     614                        talloc_free(dn);
     615                        return ldb_operr(ldb);
     616                }
     617                ldb_dn_set_extended_component(dn, "GUID", &guid);
     618
     619                cur->defaultObjectCategory = ldb_dn_get_extended_linearized(cur, dn, 1);
     620                talloc_free(dn);
     621        }
     622        return LDB_SUCCESS;
     623}
     624
     625/**
     626 * Add an element to the schema (attribute or class) from an LDB message
     627 */
     628WERROR dsdb_schema_set_el_from_ldb_msg(struct ldb_context *ldb, struct dsdb_schema *schema,
     629                                       struct ldb_message *msg)
     630{
     631        if (samdb_find_attribute(ldb, msg,
     632                                 "objectclass", "attributeSchema") != NULL) {
     633                return dsdb_attribute_from_ldb(ldb, schema, msg);
     634        } else if (samdb_find_attribute(ldb, msg,
     635                                 "objectclass", "classSchema") != NULL) {
     636                return dsdb_class_from_ldb(schema, msg);
     637        }
     638
     639        /* Don't fail on things not classes or attributes */
     640        return WERR_OK;
     641}
    456642
    457643/**
     
    473659        struct ldb_val info_val_default;
    474660
     661
    475662        mem_ctx = talloc_new(ldb);
    476663        if (!mem_ctx) {
     
    478665        }
    479666
    480         schema = dsdb_new_schema(mem_ctx, lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")));
     667        schema = dsdb_new_schema(mem_ctx);
    481668
    482669        schema->fsmo.we_are_master = true;
     
    496683        talloc_steal(mem_ctx, ldif);
    497684
    498         msg = ldb_msg_canonicalize(ldb, ldif->msg);
    499         if (!msg) {
     685        ret = ldb_msg_normalize(ldb, mem_ctx, ldif->msg, &msg);
     686        if (ret != LDB_SUCCESS) {
    500687                goto nomem;
    501688        }
    502         talloc_steal(mem_ctx, msg);
    503689        talloc_free(ldif);
    504690
     
    511697        info_val = ldb_msg_find_ldb_val(msg, "schemaInfo");
    512698        if (!info_val) {
    513                 info_val_default = strhex_to_data_blob(mem_ctx, "FF0000000000000000000000000000000000000000");
    514                 if (!info_val_default.data) {
    515                         goto nomem;
    516                 }
     699                status = dsdb_schema_info_blob_new(mem_ctx, &info_val_default);
     700                W_ERROR_NOT_OK_GOTO(status, failed);
    517701                info_val = &info_val_default;
    518702        }
     
    520704        status = dsdb_load_oid_mappings_ldb(schema, prefix_val, info_val);
    521705        if (!W_ERROR_IS_OK(status)) {
     706                DEBUG(0,("ERROR: dsdb_load_oid_mappings_ldb() failed with %s\n", win_errstr(status)));
    522707                goto failed;
    523708        }
    524709
    525         /*
    526          * load the attribute and class definitions outof df
    527          */
     710        /* load the attribute and class definitions out of df */
    528711        while ((ldif = ldb_ldif_read_string(ldb, &df))) {
    529                 bool is_sa;
    530                 bool is_sc;
    531 
    532712                talloc_steal(mem_ctx, ldif);
    533713
    534                 msg = ldb_msg_canonicalize(ldb, ldif->msg);
    535                 if (!msg) {
     714                ret = ldb_msg_normalize(ldb, ldif, ldif->msg, &msg);
     715                if (ret != LDB_SUCCESS) {
    536716                        goto nomem;
    537717                }
    538718
    539                 talloc_steal(mem_ctx, msg);
     719                status = dsdb_schema_set_el_from_ldb_msg(ldb, schema, msg);
    540720                talloc_free(ldif);
    541 
    542                 is_sa = ldb_msg_check_string_attribute(msg, "objectClass", "attributeSchema");
    543                 is_sc = ldb_msg_check_string_attribute(msg, "objectClass", "classSchema");
    544 
    545                 if (is_sa) {
    546                         struct dsdb_attribute *sa;
    547 
    548                         sa = talloc_zero(schema, struct dsdb_attribute);
    549                         if (!sa) {
    550                                 goto nomem;
    551                         }
    552 
    553                         status = dsdb_attribute_from_ldb(ldb, schema, msg, sa, sa);
    554                         if (!W_ERROR_IS_OK(status)) {
    555                                 goto failed;
    556                         }
    557 
    558                         DLIST_ADD(schema->attributes, sa);
    559                 } else if (is_sc) {
    560                         struct dsdb_class *sc;
    561 
    562                         sc = talloc_zero(schema, struct dsdb_class);
    563                         if (!sc) {
    564                                 goto nomem;
    565                         }
    566 
    567                         status = dsdb_class_from_ldb(schema, msg, sc, sc);
    568                         if (!W_ERROR_IS_OK(status)) {
    569                                 goto failed;
    570                         }
    571 
    572                         DLIST_ADD(schema->classes, sc);
     721                if (!W_ERROR_IS_OK(status)) {
     722                        goto failed;
    573723                }
    574724        }
    575725
    576726        ret = dsdb_set_schema(ldb, schema);
     727        if (ret != LDB_SUCCESS) {
     728                status = WERR_FOOBAR;
     729                goto failed;
     730        }
     731
     732        ret = dsdb_schema_fill_extended_dn(ldb, schema);
    577733        if (ret != LDB_SUCCESS) {
    578734                status = WERR_FOOBAR;
  • vendor/current/source4/dsdb/schema/schema_syntax.c

    r414 r740  
    1 /* 
     1/*
    22   Unix SMB/CIFS mplementation.
    33   DSDB schema syntaxes
    4    
     4
    55   Copyright (C) Stefan Metzmacher <metze@samba.org> 2006
    66   Copyright (C) Simo Sorce 2005
     
    1111   the Free Software Foundation; either version 3 of the License, or
    1212   (at your option) any later version.
    13    
     13
    1414   This program is distributed in the hope that it will be useful,
    1515   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1616   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1717   GNU General Public License for more details.
    18    
     18
    1919   You should have received a copy of the GNU General Public License
    2020   along with this program.  If not, see <http://www.gnu.org/licenses/>.
    21    
     21
    2222*/
    2323#include "includes.h"
     
    2626#include "librpc/gen_ndr/ndr_security.h"
    2727#include "librpc/gen_ndr/ndr_misc.h"
    28 #include "lib/ldb/include/ldb.h"
    29 #include "lib/ldb/include/ldb_errors.h"
     28#include <ldb.h>
     29#include <ldb_errors.h>
    3030#include "system/time.h"
    3131#include "../lib/util/charset/charset.h"
    3232#include "librpc/ndr/libndr.h"
    33 
    34 static WERROR dsdb_syntax_FOOBAR_drsuapi_to_ldb(struct ldb_context *ldb,
    35                                                 const struct dsdb_schema *schema,
     33#include "../lib/util/asn1.h"
     34
     35/**
     36 * Initialize dsdb_syntax_ctx with default values
     37 * for common cases.
     38 */
     39void dsdb_syntax_ctx_init(struct dsdb_syntax_ctx *ctx,
     40                          struct ldb_context *ldb,
     41                          const struct dsdb_schema *schema)
     42{
     43        ctx->ldb        = ldb;
     44        ctx->schema     = schema;
     45
     46        /*
     47         * 'true' will keep current behavior,
     48         * i.e. attributeID_id will be returned by default
     49         */
     50        ctx->is_schema_nc = true;
     51
     52        ctx->pfm_remote = NULL;
     53}
     54
     55
     56/**
     57 * Returns ATTID for DRS attribute.
     58 *
     59 * ATTID depends on whether we are replicating
     60 * Schema NC or msDs-IntId is set for schemaAttribute
     61 * for the attribute.
     62 */
     63uint32_t dsdb_attribute_get_attid(const struct dsdb_attribute *attr,
     64                                  bool for_schema_nc)
     65{
     66        if (!for_schema_nc && attr->msDS_IntId) {
     67                return attr->msDS_IntId;
     68        }
     69
     70        return attr->attributeID_id;
     71}
     72
     73/**
     74 * Map an ATTID from remote DC to a local ATTID
     75 * using remote prefixMap
     76 */
     77static bool dsdb_syntax_attid_from_remote_attid(const struct dsdb_syntax_ctx *ctx,
     78                                                TALLOC_CTX *mem_ctx,
     79                                                uint32_t id_remote,
     80                                                uint32_t *id_local)
     81{
     82        WERROR werr;
     83        const char *oid;
     84
     85        /*
     86         * map remote ATTID to local directly in case
     87         * of no remote prefixMap (during provision for instance)
     88         */
     89        if (!ctx->pfm_remote) {
     90                *id_local = id_remote;
     91                return true;
     92        }
     93
     94        werr = dsdb_schema_pfm_oid_from_attid(ctx->pfm_remote, id_remote, mem_ctx, &oid);
     95        if (!W_ERROR_IS_OK(werr)) {
     96                DEBUG(0,("ATTID->OID failed (%s) for: 0x%08X\n", win_errstr(werr), id_remote));
     97                return false;
     98        }
     99
     100        werr = dsdb_schema_pfm_make_attid(ctx->schema->prefixmap, oid, id_local);
     101        if (!W_ERROR_IS_OK(werr)) {
     102                DEBUG(0,("OID->ATTID failed (%s) for: %s\n", win_errstr(werr), oid));
     103                return false;
     104        }
     105
     106        return true;
     107}
     108
     109static WERROR dsdb_syntax_FOOBAR_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
    36110                                                const struct dsdb_attribute *attr,
    37111                                                const struct drsuapi_DsReplicaAttribute *in,
     
    39113                                                struct ldb_message_element *out)
    40114{
    41         uint32_t i;
     115        unsigned int i;
    42116
    43117        out->flags      = 0;
     
    66140}
    67141
    68 static WERROR dsdb_syntax_FOOBAR_ldb_to_drsuapi(struct ldb_context *ldb,
    69                                                 const struct dsdb_schema *schema,
     142static WERROR dsdb_syntax_FOOBAR_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
    70143                                                const struct dsdb_attribute *attr,
    71144                                                const struct ldb_message_element *in,
     
    76149}
    77150
    78 static WERROR dsdb_syntax_BOOL_drsuapi_to_ldb(struct ldb_context *ldb,
    79                                               const struct dsdb_schema *schema,
     151static WERROR dsdb_syntax_FOOBAR_validate_ldb(const struct dsdb_syntax_ctx *ctx,
     152                                              const struct dsdb_attribute *attr,
     153                                              const struct ldb_message_element *in)
     154{
     155        return WERR_FOOBAR;
     156}
     157
     158static WERROR dsdb_syntax_BOOL_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
    80159                                              const struct dsdb_attribute *attr,
    81160                                              const struct drsuapi_DsReplicaAttribute *in,
     
    83162                                              struct ldb_message_element *out)
    84163{
    85         uint32_t i;
     164        unsigned int i;
    86165
    87166        out->flags      = 0;
     
    121200}
    122201
    123 static WERROR dsdb_syntax_BOOL_ldb_to_drsuapi(struct ldb_context *ldb,
    124                                               const struct dsdb_schema *schema,
     202static WERROR dsdb_syntax_BOOL_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
    125203                                              const struct dsdb_attribute *attr,
    126204                                              const struct ldb_message_element *in,
     
    128206                                              struct drsuapi_DsReplicaAttribute *out)
    129207{
    130         uint32_t i;
     208        unsigned int i;
    131209        DATA_BLOB *blobs;
    132210
    133         if (attr->attributeID_id == 0xFFFFFFFF) {
    134                 return WERR_FOOBAR;
    135         }
    136 
    137         out->attid                      = attr->attributeID_id;
     211        if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     212                return WERR_FOOBAR;
     213        }
     214
     215        out->attid                      = dsdb_attribute_get_attid(attr,
     216                                                                   ctx->is_schema_nc);
    138217        out->value_ctr.num_values       = in->num_values;
    139218        out->value_ctr.values           = talloc_array(mem_ctx,
     
    163242}
    164243
    165 static WERROR dsdb_syntax_INT32_drsuapi_to_ldb(struct ldb_context *ldb,
    166                                                const struct dsdb_schema *schema,
     244static WERROR dsdb_syntax_BOOL_validate_ldb(const struct dsdb_syntax_ctx *ctx,
     245                                            const struct dsdb_attribute *attr,
     246                                            const struct ldb_message_element *in)
     247{
     248        unsigned int i;
     249
     250        if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     251                return WERR_FOOBAR;
     252        }
     253
     254        for (i=0; i < in->num_values; i++) {
     255                int t, f;
     256
     257                t = strncmp("TRUE",
     258                            (const char *)in->values[i].data,
     259                            in->values[i].length);
     260                f = strncmp("FALSE",
     261                            (const char *)in->values[i].data,
     262                            in->values[i].length);
     263
     264                if (t != 0 && f != 0) {
     265                        return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     266                }
     267        }
     268
     269        return WERR_OK;
     270}
     271
     272static WERROR dsdb_syntax_INT32_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
    167273                                               const struct dsdb_attribute *attr,
    168274                                               const struct drsuapi_DsReplicaAttribute *in,
     
    170276                                               struct ldb_message_element *out)
    171277{
    172         uint32_t i;
     278        unsigned int i;
    173279
    174280        out->flags      = 0;
     
    203309}
    204310
    205 static WERROR dsdb_syntax_INT32_ldb_to_drsuapi(struct ldb_context *ldb,
    206                                                const struct dsdb_schema *schema,
     311static WERROR dsdb_syntax_INT32_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
    207312                                               const struct dsdb_attribute *attr,
    208313                                               const struct ldb_message_element *in,
     
    210315                                               struct drsuapi_DsReplicaAttribute *out)
    211316{
    212         uint32_t i;
     317        unsigned int i;
    213318        DATA_BLOB *blobs;
    214319
    215         if (attr->attributeID_id == 0xFFFFFFFF) {
    216                 return WERR_FOOBAR;
    217         }
    218 
    219         out->attid                      = attr->attributeID_id;
     320        if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     321                return WERR_FOOBAR;
     322        }
     323
     324        out->attid                      = dsdb_attribute_get_attid(attr,
     325                                                                   ctx->is_schema_nc);
    220326        out->value_ctr.num_values       = in->num_values;
    221327        out->value_ctr.values           = talloc_array(mem_ctx,
     
    245351}
    246352
    247 static WERROR dsdb_syntax_INT64_drsuapi_to_ldb(struct ldb_context *ldb,
    248                                                const struct dsdb_schema *schema,
     353static WERROR dsdb_syntax_INT32_validate_ldb(const struct dsdb_syntax_ctx *ctx,
     354                                             const struct dsdb_attribute *attr,
     355                                             const struct ldb_message_element *in)
     356{
     357        unsigned int i;
     358
     359        if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     360                return WERR_FOOBAR;
     361        }
     362
     363        for (i=0; i < in->num_values; i++) {
     364                long v;
     365                char buf[sizeof("-2147483648")];
     366                char *end = NULL;
     367
     368                ZERO_STRUCT(buf);
     369                if (in->values[i].length >= sizeof(buf)) {
     370                        return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     371                }
     372
     373                memcpy(buf, in->values[i].data, in->values[i].length);
     374                errno = 0;
     375                v = strtol(buf, &end, 10);
     376                if (errno != 0) {
     377                        return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     378                }
     379                if (end && end[0] != '\0') {
     380                        return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     381                }
     382
     383                if (attr->rangeLower) {
     384                        if ((int32_t)v < (int32_t)*attr->rangeLower) {
     385                                return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     386                        }
     387                }
     388
     389                if (attr->rangeUpper) {
     390                        if ((int32_t)v > (int32_t)*attr->rangeUpper) {
     391                                return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     392                        }
     393                }
     394        }
     395
     396        return WERR_OK;
     397}
     398
     399static WERROR dsdb_syntax_INT64_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
    249400                                               const struct dsdb_attribute *attr,
    250401                                               const struct drsuapi_DsReplicaAttribute *in,
     
    252403                                               struct ldb_message_element *out)
    253404{
    254         uint32_t i;
     405        unsigned int i;
    255406
    256407        out->flags      = 0;
     
    285436}
    286437
    287 static WERROR dsdb_syntax_INT64_ldb_to_drsuapi(struct ldb_context *ldb,
    288                                                const struct dsdb_schema *schema,
     438static WERROR dsdb_syntax_INT64_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
    289439                                               const struct dsdb_attribute *attr,
    290440                                               const struct ldb_message_element *in,
     
    292442                                               struct drsuapi_DsReplicaAttribute *out)
    293443{
    294         uint32_t i;
     444        unsigned int i;
    295445        DATA_BLOB *blobs;
    296446
    297         if (attr->attributeID_id == 0xFFFFFFFF) {
    298                 return WERR_FOOBAR;
    299         }
    300 
    301         out->attid                      = attr->attributeID_id;
     447        if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     448                return WERR_FOOBAR;
     449        }
     450
     451        out->attid                      = dsdb_attribute_get_attid(attr,
     452                                                                   ctx->is_schema_nc);
    302453        out->value_ctr.num_values       = in->num_values;
    303454        out->value_ctr.values           = talloc_array(mem_ctx,
     
    325476}
    326477
    327 static WERROR dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb(struct ldb_context *ldb,
    328                                                     const struct dsdb_schema *schema,
     478static WERROR dsdb_syntax_INT64_validate_ldb(const struct dsdb_syntax_ctx *ctx,
     479                                             const struct dsdb_attribute *attr,
     480                                             const struct ldb_message_element *in)
     481{
     482        unsigned int i;
     483
     484        if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     485                return WERR_FOOBAR;
     486        }
     487
     488        for (i=0; i < in->num_values; i++) {
     489                long long v;
     490                char buf[sizeof("-9223372036854775808")];
     491                char *end = NULL;
     492
     493                ZERO_STRUCT(buf);
     494                if (in->values[i].length >= sizeof(buf)) {
     495                        return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     496                }
     497                memcpy(buf, in->values[i].data, in->values[i].length);
     498
     499                errno = 0;
     500                v = strtoll(buf, &end, 10);
     501                if (errno != 0) {
     502                        return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     503                }
     504                if (end && end[0] != '\0') {
     505                        return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     506                }
     507
     508                if (attr->rangeLower) {
     509                        if ((int64_t)v < (int64_t)*attr->rangeLower) {
     510                                return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     511                        }
     512                }
     513
     514                if (attr->rangeUpper) {
     515                        if ((int64_t)v > (int64_t)*attr->rangeUpper) {
     516                                return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     517                        }
     518                }
     519        }
     520
     521        return WERR_OK;
     522}
     523static WERROR dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
    329524                                                    const struct dsdb_attribute *attr,
    330525                                                    const struct drsuapi_DsReplicaAttribute *in,
     
    332527                                                    struct ldb_message_element *out)
    333528{
    334         uint32_t i;
     529        unsigned int i;
    335530
    336531        out->flags      = 0;
     
    359554                t = nt_time_to_unix(v);
    360555
    361                 /* 
     556                /*
    362557                 * NOTE: On a w2k3 server you can set a GeneralizedTime string
    363558                 *       via LDAP, but you get back an UTCTime string,
     
    368563                 *       we'll loose information!
    369564                 */
    370                 str = ldb_timestring_utc(out->values, t); 
     565                str = ldb_timestring_utc(out->values, t);
    371566                W_ERROR_HAVE_NO_MEMORY(str);
    372567                out->values[i] = data_blob_string_const(str);
     
    376571}
    377572
    378 static WERROR dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi(struct ldb_context *ldb,
    379                                                     const struct dsdb_schema *schema,
     573static WERROR dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
    380574                                                    const struct dsdb_attribute *attr,
    381575                                                    const struct ldb_message_element *in,
     
    383577                                                    struct drsuapi_DsReplicaAttribute *out)
    384578{
    385         uint32_t i;
     579        unsigned int i;
    386580        DATA_BLOB *blobs;
    387581
    388         if (attr->attributeID_id == 0xFFFFFFFF) {
    389                 return WERR_FOOBAR;
    390         }
    391 
    392         out->attid                      = attr->attributeID_id;
     582        if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     583                return WERR_FOOBAR;
     584        }
     585
     586        out->attid                      = dsdb_attribute_get_attid(attr,
     587                                                                   ctx->is_schema_nc);
    393588        out->value_ctr.num_values       = in->num_values;
    394589        out->value_ctr.values           = talloc_array(mem_ctx,
     
    419614}
    420615
    421 static WERROR dsdb_syntax_NTTIME_drsuapi_to_ldb(struct ldb_context *ldb,
    422                                                 const struct dsdb_schema *schema,
     616static WERROR dsdb_syntax_NTTIME_UTC_validate_ldb(const struct dsdb_syntax_ctx *ctx,
     617                                                  const struct dsdb_attribute *attr,
     618                                                  const struct ldb_message_element *in)
     619{
     620        unsigned int i;
     621
     622        if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     623                return WERR_FOOBAR;
     624        }
     625
     626        for (i=0; i < in->num_values; i++) {
     627                time_t t;
     628                char buf[sizeof("090826075717Z")];
     629
     630                ZERO_STRUCT(buf);
     631                if (in->values[i].length >= sizeof(buf)) {
     632                        return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     633                }
     634                memcpy(buf, in->values[i].data, in->values[i].length);
     635
     636                errno = 0;
     637                t = ldb_string_utc_to_time(buf);
     638                if (errno != 0) {
     639                        return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     640                }
     641
     642                if (attr->rangeLower) {
     643                        if ((int32_t)t < (int32_t)*attr->rangeLower) {
     644                                return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     645                        }
     646                }
     647
     648                if (attr->rangeUpper) {
     649                        if ((int32_t)t > (int32_t)*attr->rangeLower) {
     650                                return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     651                        }
     652                }
     653
     654                /*
     655                 * TODO: verify the comment in the
     656                 * dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb() function!
     657                 */
     658        }
     659
     660        return WERR_OK;
     661}
     662
     663static WERROR dsdb_syntax_NTTIME_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
    423664                                                const struct dsdb_attribute *attr,
    424665                                                const struct drsuapi_DsReplicaAttribute *in,
     
    426667                                                struct ldb_message_element *out)
    427668{
    428         uint32_t i;
     669        unsigned int i;
    429670
    430671        out->flags      = 0;
     
    453694                t = nt_time_to_unix(v);
    454695
    455                 str = ldb_timestring(out->values, t); 
     696                str = ldb_timestring(out->values, t);
    456697                W_ERROR_HAVE_NO_MEMORY(str);
    457698
     
    462703}
    463704
    464 static WERROR dsdb_syntax_NTTIME_ldb_to_drsuapi(struct ldb_context *ldb,
    465                                                 const struct dsdb_schema *schema,
     705static WERROR dsdb_syntax_NTTIME_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
    466706                                                const struct dsdb_attribute *attr,
    467707                                                const struct ldb_message_element *in,
     
    469709                                                struct drsuapi_DsReplicaAttribute *out)
    470710{
    471         uint32_t i;
     711        unsigned int i;
    472712        DATA_BLOB *blobs;
    473713
    474         if (attr->attributeID_id == 0xFFFFFFFF) {
    475                 return WERR_FOOBAR;
    476         }
    477 
    478         out->attid                      = attr->attributeID_id;
     714        if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     715                return WERR_FOOBAR;
     716        }
     717
     718        out->attid                      = dsdb_attribute_get_attid(attr,
     719                                                                   ctx->is_schema_nc);
    479720        out->value_ctr.num_values       = in->num_values;
    480721        out->value_ctr.values           = talloc_array(mem_ctx,
     
    489730                NTTIME v;
    490731                time_t t;
     732                int ret;
    491733
    492734                out->value_ctr.values[i].blob   = &blobs[i];
     
    495737                W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
    496738
    497                 t = ldb_string_to_time((const char *)in->values[i].data);
     739                ret = ldb_val_to_time(&in->values[i], &t);
     740                if (ret != LDB_SUCCESS) {
     741                        return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     742                }
    498743                unix_to_nt_time(&v, t);
    499744                v /= 10000000;
     
    505750}
    506751
    507 static WERROR dsdb_syntax_DATA_BLOB_drsuapi_to_ldb(struct ldb_context *ldb,
    508                                                    const struct dsdb_schema *schema,
     752static WERROR dsdb_syntax_NTTIME_validate_ldb(const struct dsdb_syntax_ctx *ctx,
     753                                              const struct dsdb_attribute *attr,
     754                                              const struct ldb_message_element *in)
     755{
     756        unsigned int i;
     757
     758        if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     759                return WERR_FOOBAR;
     760        }
     761
     762        for (i=0; i < in->num_values; i++) {
     763                time_t t;
     764                int ret;
     765
     766                ret = ldb_val_to_time(&in->values[i], &t);
     767                if (ret != LDB_SUCCESS) {
     768                        return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     769                }
     770
     771                if (attr->rangeLower) {
     772                        if ((int32_t)t < (int32_t)*attr->rangeLower) {
     773                                return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     774                        }
     775                }
     776
     777                if (attr->rangeUpper) {
     778                        if ((int32_t)t > (int32_t)*attr->rangeLower) {
     779                                return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     780                        }
     781                }
     782        }
     783
     784        return WERR_OK;
     785}
     786
     787static WERROR dsdb_syntax_DATA_BLOB_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
    509788                                                   const struct dsdb_attribute *attr,
    510789                                                   const struct drsuapi_DsReplicaAttribute *in,
     
    512791                                                   struct ldb_message_element *out)
    513792{
    514         uint32_t i;
     793        unsigned int i;
    515794
    516795        out->flags      = 0;
     
    539818}
    540819
    541 static WERROR dsdb_syntax_DATA_BLOB_ldb_to_drsuapi(struct ldb_context *ldb,
    542                                                    const struct dsdb_schema *schema,
     820static WERROR dsdb_syntax_DATA_BLOB_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
    543821                                                   const struct dsdb_attribute *attr,
    544822                                                   const struct ldb_message_element *in,
     
    546824                                                   struct drsuapi_DsReplicaAttribute *out)
    547825{
    548         uint32_t i;
     826        unsigned int i;
    549827        DATA_BLOB *blobs;
    550828
    551         if (attr->attributeID_id == 0xFFFFFFFF) {
    552                 return WERR_FOOBAR;
    553         }
    554 
    555         out->attid                      = attr->attributeID_id;
     829        if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     830                return WERR_FOOBAR;
     831        }
     832
     833        out->attid                      = dsdb_attribute_get_attid(attr,
     834                                                                   ctx->is_schema_nc);
    556835        out->value_ctr.num_values       = in->num_values;
    557836        out->value_ctr.values           = talloc_array(mem_ctx,
     
    573852}
    574853
    575 static WERROR _dsdb_syntax_OID_obj_drsuapi_to_ldb(struct ldb_context *ldb,
    576                                                   const struct dsdb_schema *schema,
     854static WERROR dsdb_syntax_DATA_BLOB_validate_one_val(const struct dsdb_syntax_ctx *ctx,
     855                                                     const struct dsdb_attribute *attr,
     856                                                     const struct ldb_val *val)
     857{
     858        if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     859                return WERR_FOOBAR;
     860        }
     861
     862        if (attr->rangeLower) {
     863                if ((uint32_t)val->length < (uint32_t)*attr->rangeLower) {
     864                        return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     865                }
     866        }
     867
     868        if (attr->rangeUpper) {
     869                if ((uint32_t)val->length > (uint32_t)*attr->rangeUpper) {
     870                        return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     871                }
     872        }
     873
     874        return WERR_OK;
     875}
     876
     877static WERROR dsdb_syntax_DATA_BLOB_validate_ldb(const struct dsdb_syntax_ctx *ctx,
     878                                                 const struct dsdb_attribute *attr,
     879                                                 const struct ldb_message_element *in)
     880{
     881        unsigned int i;
     882        WERROR status;
     883
     884        if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     885                return WERR_FOOBAR;
     886        }
     887
     888        for (i=0; i < in->num_values; i++) {
     889                if (in->values[i].length == 0) {
     890                        return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     891                }
     892
     893                status = dsdb_syntax_DATA_BLOB_validate_one_val(ctx,
     894                                                                attr,
     895                                                                &in->values[i]);
     896                if (!W_ERROR_IS_OK(status)) {
     897                        return status;
     898                }
     899        }
     900
     901        return WERR_OK;
     902}
     903
     904static WERROR _dsdb_syntax_auto_OID_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
     905                                                   const struct dsdb_attribute *attr,
     906                                                   const struct drsuapi_DsReplicaAttribute *in,
     907                                                   TALLOC_CTX *mem_ctx,
     908                                                   struct ldb_message_element *out)
     909{
     910        unsigned int i;
     911
     912        out->flags      = 0;
     913        out->name       = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
     914        W_ERROR_HAVE_NO_MEMORY(out->name);
     915
     916        out->num_values = in->value_ctr.num_values;
     917        out->values     = talloc_array(mem_ctx, struct ldb_val, out->num_values);
     918        W_ERROR_HAVE_NO_MEMORY(out->values);
     919
     920        for (i=0; i < out->num_values; i++) {
     921                uint32_t v;
     922                const struct dsdb_class *c;
     923                const struct dsdb_attribute *a;
     924                const char *str = NULL;
     925
     926                if (in->value_ctr.values[i].blob == NULL) {
     927                        return WERR_FOOBAR;
     928                }
     929
     930                if (in->value_ctr.values[i].blob->length != 4) {
     931                        return WERR_FOOBAR;
     932                }
     933
     934                v = IVAL(in->value_ctr.values[i].blob->data, 0);
     935
     936                if ((c = dsdb_class_by_governsID_id(ctx->schema, v))) {
     937                        str = talloc_strdup(out->values, c->lDAPDisplayName);
     938                } else if ((a = dsdb_attribute_by_attributeID_id(ctx->schema, v))) {
     939                        str = talloc_strdup(out->values, a->lDAPDisplayName);
     940                } else {
     941                        WERROR werr;
     942                        SMB_ASSERT(ctx->pfm_remote);
     943                        werr = dsdb_schema_pfm_oid_from_attid(ctx->pfm_remote, v,
     944                                                              out->values, &str);
     945                        W_ERROR_NOT_OK_RETURN(werr);
     946                }
     947                W_ERROR_HAVE_NO_MEMORY(str);
     948
     949                /* the values need to be reversed */
     950                out->values[out->num_values - (i + 1)] = data_blob_string_const(str);
     951        }
     952
     953        return WERR_OK;
     954}
     955
     956static WERROR _dsdb_syntax_OID_obj_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
    577957                                                  const struct dsdb_attribute *attr,
    578958                                                  const struct drsuapi_DsReplicaAttribute *in,
     
    580960                                                  struct ldb_message_element *out)
    581961{
    582         uint32_t i;
     962        unsigned int i;
    583963
    584964        out->flags      = 0;
     
    605985                v = IVAL(in->value_ctr.values[i].blob->data, 0);
    606986
    607                 c = dsdb_class_by_governsID_id(schema, v);
     987                /* convert remote ATTID to local ATTID */
     988                if (!dsdb_syntax_attid_from_remote_attid(ctx, mem_ctx, v, &v)) {
     989                        DEBUG(1,(__location__ ": Failed to map remote ATTID to local ATTID!\n"));
     990                        return WERR_FOOBAR;
     991                }
     992
     993                c = dsdb_class_by_governsID_id(ctx->schema, v);
    608994                if (!c) {
     995                        DEBUG(1,(__location__ ": Unknown governsID 0x%08X\n", v));
    609996                        return WERR_FOOBAR;
    610997                }
     
    6201007}
    6211008
    622 static WERROR _dsdb_syntax_OID_attr_drsuapi_to_ldb(struct ldb_context *ldb,
    623                                                    const struct dsdb_schema *schema,
     1009static WERROR _dsdb_syntax_OID_attr_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
    6241010                                                   const struct dsdb_attribute *attr,
    6251011                                                   const struct drsuapi_DsReplicaAttribute *in,
     
    6271013                                                   struct ldb_message_element *out)
    6281014{
    629         uint32_t i;
     1015        unsigned int i;
    6301016
    6311017        out->flags      = 0;
     
    6521038                v = IVAL(in->value_ctr.values[i].blob->data, 0);
    6531039
    654                 a = dsdb_attribute_by_attributeID_id(schema, v);
     1040                /* convert remote ATTID to local ATTID */
     1041                if (!dsdb_syntax_attid_from_remote_attid(ctx, mem_ctx, v, &v)) {
     1042                        DEBUG(1,(__location__ ": Failed to map remote ATTID to local ATTID!\n"));
     1043                        return WERR_FOOBAR;
     1044                }
     1045
     1046                a = dsdb_attribute_by_attributeID_id(ctx->schema, v);
    6551047                if (!a) {
     1048                        DEBUG(1,(__location__ ": Unknown attributeID_id 0x%08X\n", v));
    6561049                        return WERR_FOOBAR;
    6571050                }
     
    6671060}
    6681061
    669 static WERROR _dsdb_syntax_OID_oid_drsuapi_to_ldb(struct ldb_context *ldb,
    670                                                   const struct dsdb_schema *schema,
     1062static WERROR _dsdb_syntax_OID_oid_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
    6711063                                                  const struct dsdb_attribute *attr,
    6721064                                                  const struct drsuapi_DsReplicaAttribute *in,
     
    6741066                                                  struct ldb_message_element *out)
    6751067{
    676         uint32_t i;
     1068        unsigned int i;
     1069
     1070        SMB_ASSERT(ctx->pfm_remote);
    6771071
    6781072        out->flags      = 0;
     
    6851079
    6861080        for (i=0; i < out->num_values; i++) {
    687                 uint32_t v;
     1081                uint32_t attid;
    6881082                WERROR status;
    689                 const char *str;
     1083                const char *oid;
    6901084
    6911085                if (in->value_ctr.values[i].blob == NULL) {
     
    6971091                }
    6981092
    699                 v = IVAL(in->value_ctr.values[i].blob->data, 0);
    700 
    701                 status = dsdb_map_int2oid(schema, v, out->values, &str);
    702                 W_ERROR_NOT_OK_RETURN(status);
    703 
    704                 out->values[i] = data_blob_string_const(str);
    705         }
    706 
    707         return WERR_OK;
    708 }
    709 
    710 static WERROR _dsdb_syntax_OID_obj_ldb_to_drsuapi(struct ldb_context *ldb,
    711                                                   const struct dsdb_schema *schema,
    712                                                   const struct dsdb_attribute *attr,
    713                                                   const struct ldb_message_element *in,
    714                                                   TALLOC_CTX *mem_ctx,
    715                                                   struct drsuapi_DsReplicaAttribute *out)
    716 {
    717         uint32_t i;
     1093                attid = IVAL(in->value_ctr.values[i].blob->data, 0);
     1094
     1095                status = dsdb_schema_pfm_oid_from_attid(ctx->pfm_remote, attid,
     1096                                                        out->values, &oid);
     1097                if (!W_ERROR_IS_OK(status)) {
     1098                        DEBUG(0,(__location__ ": Error: Unknown ATTID 0x%08X\n",
     1099                                 attid));
     1100                        return status;
     1101                }
     1102
     1103                out->values[i] = data_blob_string_const(oid);
     1104        }
     1105
     1106        return WERR_OK;
     1107}
     1108
     1109static WERROR _dsdb_syntax_auto_OID_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
     1110                                                   const struct dsdb_attribute *attr,
     1111                                                   const struct ldb_message_element *in,
     1112                                                   TALLOC_CTX *mem_ctx,
     1113                                                   struct drsuapi_DsReplicaAttribute *out)
     1114{
     1115        unsigned int i;
    7181116        DATA_BLOB *blobs;
    7191117
    720         out->attid= attr->attributeID_id;
     1118        out->attid= dsdb_attribute_get_attid(attr,
     1119                                             ctx->is_schema_nc);
    7211120        out->value_ctr.num_values= in->num_values;
    7221121        out->value_ctr.values= talloc_array(mem_ctx,
     
    7301129        for (i=0; i < in->num_values; i++) {
    7311130                const struct dsdb_class *obj_class;
     1131                const struct dsdb_attribute *obj_attr;
     1132                struct ldb_val *v;
    7321133
    7331134                out->value_ctr.values[i].blob= &blobs[i];
     
    7361137                W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
    7371138
    738                 obj_class = dsdb_class_by_lDAPDisplayName(schema, (const char *)in->values[i].data);
    739                 if (!obj_class) {
    740                         return WERR_FOOBAR;
    741                 }
    742                 SIVAL(blobs[i].data, 0, obj_class->governsID_id);
     1139                /* in DRS windows puts the classes in the opposite
     1140                   order to the order used in ldap */
     1141                v = &in->values[(in->num_values-1)-i];
     1142
     1143                if ((obj_class = dsdb_class_by_lDAPDisplayName_ldb_val(ctx->schema, v))) {
     1144                        SIVAL(blobs[i].data, 0, obj_class->governsID_id);
     1145                } else if ((obj_attr = dsdb_attribute_by_lDAPDisplayName_ldb_val(ctx->schema, v))) {
     1146                        SIVAL(blobs[i].data, 0, obj_attr->attributeID_id);
     1147                } else {
     1148                        uint32_t attid;
     1149                        WERROR werr;
     1150                        werr = dsdb_schema_pfm_attid_from_oid(ctx->schema->prefixmap,
     1151                                                              (const char *)v->data,
     1152                                                              &attid);
     1153                        W_ERROR_NOT_OK_RETURN(werr);
     1154                        SIVAL(blobs[i].data, 0, attid);
     1155                }
     1156
    7431157        }
    7441158
     
    7471161}
    7481162
    749 static WERROR _dsdb_syntax_OID_attr_ldb_to_drsuapi(struct ldb_context *ldb,
    750                                                    const struct dsdb_schema *schema,
    751                                                    const struct dsdb_attribute *attr,
    752                                                    const struct ldb_message_element *in,
    753                                                    TALLOC_CTX *mem_ctx,
    754                                                    struct drsuapi_DsReplicaAttribute *out)
    755 {
    756         uint32_t i;
     1163static WERROR _dsdb_syntax_OID_obj_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
     1164                                                  const struct dsdb_attribute *attr,
     1165                                                  const struct ldb_message_element *in,
     1166                                                  TALLOC_CTX *mem_ctx,
     1167                                                  struct drsuapi_DsReplicaAttribute *out)
     1168{
     1169        unsigned int i;
    7571170        DATA_BLOB *blobs;
    7581171
    759         out->attid= attr->attributeID_id;
     1172        out->attid= dsdb_attribute_get_attid(attr,
     1173                                             ctx->is_schema_nc);
    7601174        out->value_ctr.num_values= in->num_values;
    7611175        out->value_ctr.values= talloc_array(mem_ctx,
     
    7681182
    7691183        for (i=0; i < in->num_values; i++) {
    770                 const struct dsdb_attribute *obj_attr;
     1184                const struct dsdb_class *obj_class;
    7711185
    7721186                out->value_ctr.values[i].blob= &blobs[i];
     
    7751189                W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
    7761190
    777                 obj_attr = dsdb_attribute_by_lDAPDisplayName(schema, (const char *)in->values[i].data);
     1191                /* in DRS windows puts the classes in the opposite
     1192                   order to the order used in ldap */
     1193                obj_class = dsdb_class_by_lDAPDisplayName(ctx->schema,
     1194                                                          (const char *)in->values[(in->num_values-1)-i].data);
     1195                if (!obj_class) {
     1196                        return WERR_FOOBAR;
     1197                }
     1198                SIVAL(blobs[i].data, 0, obj_class->governsID_id);
     1199        }
     1200
     1201
     1202        return WERR_OK;
     1203}
     1204
     1205static WERROR _dsdb_syntax_OID_attr_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
     1206                                                   const struct dsdb_attribute *attr,
     1207                                                   const struct ldb_message_element *in,
     1208                                                   TALLOC_CTX *mem_ctx,
     1209                                                   struct drsuapi_DsReplicaAttribute *out)
     1210{
     1211        unsigned int i;
     1212        DATA_BLOB *blobs;
     1213
     1214        out->attid= dsdb_attribute_get_attid(attr,
     1215                                             ctx->is_schema_nc);
     1216        out->value_ctr.num_values= in->num_values;
     1217        out->value_ctr.values= talloc_array(mem_ctx,
     1218                                            struct drsuapi_DsAttributeValue,
     1219                                            in->num_values);
     1220        W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
     1221
     1222        blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
     1223        W_ERROR_HAVE_NO_MEMORY(blobs);
     1224
     1225        for (i=0; i < in->num_values; i++) {
     1226                const struct dsdb_attribute *obj_attr;
     1227
     1228                out->value_ctr.values[i].blob= &blobs[i];
     1229
     1230                blobs[i] = data_blob_talloc(blobs, NULL, 4);
     1231                W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
     1232
     1233                obj_attr = dsdb_attribute_by_lDAPDisplayName(ctx->schema, (const char *)in->values[i].data);
    7781234                if (!obj_attr) {
    7791235                        return WERR_FOOBAR;
     
    7861242}
    7871243
    788 static WERROR _dsdb_syntax_OID_oid_ldb_to_drsuapi(struct ldb_context *ldb,
    789                                                   const struct dsdb_schema *schema,
     1244static WERROR _dsdb_syntax_OID_oid_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
    7901245                                                  const struct dsdb_attribute *attr,
    7911246                                                  const struct ldb_message_element *in,
     
    7931248                                                  struct drsuapi_DsReplicaAttribute *out)
    7941249{
    795         uint32_t i;
     1250        unsigned int i;
    7961251        DATA_BLOB *blobs;
    7971252
    798         out->attid= attr->attributeID_id;
     1253        out->attid= dsdb_attribute_get_attid(attr,
     1254                                             ctx->is_schema_nc);
    7991255        out->value_ctr.num_values= in->num_values;
    8001256        out->value_ctr.values= talloc_array(mem_ctx,
     
    8071263
    8081264        for (i=0; i < in->num_values; i++) {
    809                 uint32_t v;
     1265                uint32_t attid;
    8101266                WERROR status;
    8111267
     
    8151271                W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
    8161272
    817                 status = dsdb_map_oid2int(schema,
    818                                           (const char *)in->values[i].data,
    819                                           &v);
     1273                status = dsdb_schema_pfm_attid_from_oid(ctx->schema->prefixmap,
     1274                                                        (const char *)in->values[i].data,
     1275                                                        &attid);
    8201276                W_ERROR_NOT_OK_RETURN(status);
    8211277
    822                 SIVAL(blobs[i].data, 0, v);
    823         }
    824 
    825         return WERR_OK;
    826 }
    827 
    828 static WERROR dsdb_syntax_OID_drsuapi_to_ldb(struct ldb_context *ldb,
    829                                              const struct dsdb_schema *schema,
     1278                SIVAL(blobs[i].data, 0, attid);
     1279        }
     1280
     1281        return WERR_OK;
     1282}
     1283
     1284static WERROR dsdb_syntax_OID_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
    8301285                                             const struct dsdb_attribute *attr,
    8311286                                             const struct drsuapi_DsReplicaAttribute *in,
     
    8331288                                             struct ldb_message_element *out)
    8341289{
    835         uint32_t i;
     1290        WERROR werr;
    8361291
    8371292        switch (attr->attributeID_id) {
    838         case DRSUAPI_ATTRIBUTE_objectClass:
    839         case DRSUAPI_ATTRIBUTE_subClassOf:
    840         case DRSUAPI_ATTRIBUTE_auxiliaryClass:
    841         case DRSUAPI_ATTRIBUTE_systemPossSuperiors:
    842         case DRSUAPI_ATTRIBUTE_possSuperiors:
    843                 return _dsdb_syntax_OID_obj_drsuapi_to_ldb(ldb, schema, attr, in, mem_ctx, out);
    844         case DRSUAPI_ATTRIBUTE_systemMustContain:
    845         case DRSUAPI_ATTRIBUTE_systemMayContain:       
    846         case DRSUAPI_ATTRIBUTE_mustContain:
    847         case DRSUAPI_ATTRIBUTE_mayContain:
    848                 return _dsdb_syntax_OID_attr_drsuapi_to_ldb(ldb, schema, attr, in, mem_ctx, out);
    849         case DRSUAPI_ATTRIBUTE_governsID:
    850         case DRSUAPI_ATTRIBUTE_attributeID:
    851         case DRSUAPI_ATTRIBUTE_attributeSyntax:
    852                 return _dsdb_syntax_OID_oid_drsuapi_to_ldb(ldb, schema, attr, in, mem_ctx, out);
    853         }
    854 
    855         out->flags      = 0;
    856         out->name       = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
    857         W_ERROR_HAVE_NO_MEMORY(out->name);
    858 
    859         out->num_values = in->value_ctr.num_values;
    860         out->values     = talloc_array(mem_ctx, struct ldb_val, out->num_values);
    861         W_ERROR_HAVE_NO_MEMORY(out->values);
    862 
    863         for (i=0; i < out->num_values; i++) {
    864                 uint32_t v;
    865                 const char *name;
    866                 char *str;
    867 
    868                 if (in->value_ctr.values[i].blob == NULL) {
    869                         return WERR_FOOBAR;
    870                 }
    871 
    872                 if (in->value_ctr.values[i].blob->length != 4) {
    873                         return WERR_FOOBAR;
    874                 }
    875 
    876                 v = IVAL(in->value_ctr.values[i].blob->data, 0);
    877 
    878                 name = dsdb_lDAPDisplayName_by_id(schema, v);
    879                 if (!name) {
    880                         return WERR_FOOBAR;
    881                 }
    882 
    883                 str = talloc_strdup(out->values, name);
    884                 W_ERROR_HAVE_NO_MEMORY(str);
    885 
    886                 out->values[i] = data_blob_string_const(str);
    887         }
    888 
    889         return WERR_OK;
    890 }
    891 
    892 static WERROR dsdb_syntax_OID_ldb_to_drsuapi(struct ldb_context *ldb,
    893                                              const struct dsdb_schema *schema,
     1293        case DRSUAPI_ATTID_objectClass:
     1294        case DRSUAPI_ATTID_subClassOf:
     1295        case DRSUAPI_ATTID_auxiliaryClass:
     1296        case DRSUAPI_ATTID_systemAuxiliaryClass:
     1297        case DRSUAPI_ATTID_systemPossSuperiors:
     1298        case DRSUAPI_ATTID_possSuperiors:
     1299                werr = _dsdb_syntax_OID_obj_drsuapi_to_ldb(ctx, attr, in, mem_ctx, out);
     1300                break;
     1301        case DRSUAPI_ATTID_systemMustContain:
     1302        case DRSUAPI_ATTID_systemMayContain:
     1303        case DRSUAPI_ATTID_mustContain:
     1304        case DRSUAPI_ATTID_rDNAttId:
     1305        case DRSUAPI_ATTID_transportAddressAttribute:
     1306        case DRSUAPI_ATTID_mayContain:
     1307                werr = _dsdb_syntax_OID_attr_drsuapi_to_ldb(ctx, attr, in, mem_ctx, out);
     1308                break;
     1309        case DRSUAPI_ATTID_governsID:
     1310        case DRSUAPI_ATTID_attributeID:
     1311        case DRSUAPI_ATTID_attributeSyntax:
     1312                werr = _dsdb_syntax_OID_oid_drsuapi_to_ldb(ctx, attr, in, mem_ctx, out);
     1313                break;
     1314        default:
     1315                DEBUG(0,(__location__ ": Unknown handling for attributeID_id for %s\n",
     1316                         attr->lDAPDisplayName));
     1317                return _dsdb_syntax_auto_OID_drsuapi_to_ldb(ctx, attr, in, mem_ctx, out);
     1318        }
     1319
     1320        /* When we are doing the vampire of a schema, we don't want
     1321         * the inability to reference an OID to get in the way.
     1322         * Otherwise, we won't get the new schema with which to
     1323         * understand this */
     1324        if (!W_ERROR_IS_OK(werr) && ctx->schema->relax_OID_conversions) {
     1325                return _dsdb_syntax_OID_oid_drsuapi_to_ldb(ctx, attr, in, mem_ctx, out);
     1326        }
     1327        return werr;
     1328}
     1329
     1330static WERROR dsdb_syntax_OID_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
    8941331                                             const struct dsdb_attribute *attr,
    8951332                                             const struct ldb_message_element *in,
     
    8971334                                             struct drsuapi_DsReplicaAttribute *out)
    8981335{
    899         uint32_t i;
     1336        if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     1337                return WERR_FOOBAR;
     1338        }
     1339
     1340        switch (attr->attributeID_id) {
     1341        case DRSUAPI_ATTID_objectClass:
     1342        case DRSUAPI_ATTID_subClassOf:
     1343        case DRSUAPI_ATTID_auxiliaryClass:
     1344        case DRSUAPI_ATTID_systemAuxiliaryClass:
     1345        case DRSUAPI_ATTID_systemPossSuperiors:
     1346        case DRSUAPI_ATTID_possSuperiors:
     1347                return _dsdb_syntax_OID_obj_ldb_to_drsuapi(ctx, attr, in, mem_ctx, out);
     1348        case DRSUAPI_ATTID_systemMustContain:
     1349        case DRSUAPI_ATTID_systemMayContain:
     1350        case DRSUAPI_ATTID_mustContain:
     1351        case DRSUAPI_ATTID_rDNAttId:
     1352        case DRSUAPI_ATTID_transportAddressAttribute:
     1353        case DRSUAPI_ATTID_mayContain:
     1354                return _dsdb_syntax_OID_attr_ldb_to_drsuapi(ctx, attr, in, mem_ctx, out);
     1355        case DRSUAPI_ATTID_governsID:
     1356        case DRSUAPI_ATTID_attributeID:
     1357        case DRSUAPI_ATTID_attributeSyntax:
     1358                return _dsdb_syntax_OID_oid_ldb_to_drsuapi(ctx, attr, in, mem_ctx, out);
     1359        }
     1360
     1361        DEBUG(0,(__location__ ": Unknown handling for attributeID_id for %s\n",
     1362                 attr->lDAPDisplayName));
     1363
     1364        return _dsdb_syntax_auto_OID_ldb_to_drsuapi(ctx, attr, in, mem_ctx, out);
     1365}
     1366
     1367static WERROR _dsdb_syntax_OID_validate_numericoid(const struct dsdb_syntax_ctx *ctx,
     1368                                                   const struct dsdb_attribute *attr,
     1369                                                   const struct ldb_message_element *in)
     1370{
     1371        unsigned int i;
     1372        TALLOC_CTX *tmp_ctx;
     1373
     1374        tmp_ctx = talloc_new(ctx->ldb);
     1375        W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
     1376
     1377        for (i=0; i < in->num_values; i++) {
     1378                DATA_BLOB blob;
     1379                char *oid_out;
     1380                const char *oid = (const char*)in->values[i].data;
     1381
     1382                if (!ber_write_OID_String(tmp_ctx, &blob, oid)) {
     1383                        DEBUG(0,("ber_write_OID_String() failed for %s\n", oid));
     1384                        talloc_free(tmp_ctx);
     1385                        return WERR_INVALID_PARAMETER;
     1386                }
     1387
     1388                if (!ber_read_OID_String(tmp_ctx, blob, &oid_out)) {
     1389                        DEBUG(0,("ber_read_OID_String() failed for %s\n",
     1390                                 hex_encode_talloc(tmp_ctx, blob.data, blob.length)));
     1391                        talloc_free(tmp_ctx);
     1392                        return WERR_INVALID_PARAMETER;
     1393                }
     1394
     1395                if (strcmp(oid, oid_out) != 0) {
     1396                        talloc_free(tmp_ctx);
     1397                        return WERR_INVALID_PARAMETER;
     1398                }
     1399        }
     1400
     1401        talloc_free(tmp_ctx);
     1402        return WERR_OK;
     1403}
     1404
     1405static WERROR dsdb_syntax_OID_validate_ldb(const struct dsdb_syntax_ctx *ctx,
     1406                                           const struct dsdb_attribute *attr,
     1407                                           const struct ldb_message_element *in)
     1408{
     1409        WERROR status;
     1410        struct drsuapi_DsReplicaAttribute drs_tmp;
     1411        struct ldb_message_element ldb_tmp;
     1412        TALLOC_CTX *tmp_ctx;
     1413
     1414        if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     1415                return WERR_FOOBAR;
     1416        }
     1417
     1418        switch (attr->attributeID_id) {
     1419        case DRSUAPI_ATTID_governsID:
     1420        case DRSUAPI_ATTID_attributeID:
     1421        case DRSUAPI_ATTID_attributeSyntax:
     1422                return _dsdb_syntax_OID_validate_numericoid(ctx, attr, in);
     1423        }
     1424
     1425        /*
     1426         * TODO: optimize and verify this code
     1427         */
     1428
     1429        tmp_ctx = talloc_new(ctx->ldb);
     1430        W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
     1431
     1432        status = dsdb_syntax_OID_ldb_to_drsuapi(ctx,
     1433                                                attr,
     1434                                                in,
     1435                                                tmp_ctx,
     1436                                                &drs_tmp);
     1437        if (!W_ERROR_IS_OK(status)) {
     1438                talloc_free(tmp_ctx);
     1439                return status;
     1440        }
     1441
     1442        status = dsdb_syntax_OID_drsuapi_to_ldb(ctx,
     1443                                                attr,
     1444                                                &drs_tmp,
     1445                                                tmp_ctx,
     1446                                                &ldb_tmp);
     1447        if (!W_ERROR_IS_OK(status)) {
     1448                talloc_free(tmp_ctx);
     1449                return status;
     1450        }
     1451
     1452        talloc_free(tmp_ctx);
     1453        return WERR_OK;
     1454}
     1455
     1456static WERROR dsdb_syntax_UNICODE_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
     1457                                                 const struct dsdb_attribute *attr,
     1458                                                 const struct drsuapi_DsReplicaAttribute *in,
     1459                                                 TALLOC_CTX *mem_ctx,
     1460                                                 struct ldb_message_element *out)
     1461{
     1462        unsigned int i;
     1463
     1464        out->flags      = 0;
     1465        out->name       = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
     1466        W_ERROR_HAVE_NO_MEMORY(out->name);
     1467
     1468        out->num_values = in->value_ctr.num_values;
     1469        out->values     = talloc_array(mem_ctx, struct ldb_val, out->num_values);
     1470        W_ERROR_HAVE_NO_MEMORY(out->values);
     1471
     1472        for (i=0; i < out->num_values; i++) {
     1473                char *str;
     1474
     1475                if (in->value_ctr.values[i].blob == NULL) {
     1476                        return WERR_FOOBAR;
     1477                }
     1478
     1479                if (in->value_ctr.values[i].blob->length == 0) {
     1480                        return WERR_FOOBAR;
     1481                }
     1482
     1483                if (!convert_string_talloc(out->values,
     1484                                           CH_UTF16, CH_UNIX,
     1485                                           in->value_ctr.values[i].blob->data,
     1486                                           in->value_ctr.values[i].blob->length,
     1487                                           (void **)&str, NULL, false)) {
     1488                        return WERR_FOOBAR;
     1489                }
     1490
     1491                out->values[i] = data_blob_string_const(str);
     1492        }
     1493
     1494        return WERR_OK;
     1495}
     1496
     1497static WERROR dsdb_syntax_UNICODE_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
     1498                                                 const struct dsdb_attribute *attr,
     1499                                                 const struct ldb_message_element *in,
     1500                                                 TALLOC_CTX *mem_ctx,
     1501                                                 struct drsuapi_DsReplicaAttribute *out)
     1502{
     1503        unsigned int i;
    9001504        DATA_BLOB *blobs;
    9011505
    902         if (attr->attributeID_id == 0xFFFFFFFF) {
    903                 return WERR_FOOBAR;
    904         }
    905 
    906         switch (attr->attributeID_id) {
    907         case DRSUAPI_ATTRIBUTE_objectClass:
    908         case DRSUAPI_ATTRIBUTE_subClassOf:
    909         case DRSUAPI_ATTRIBUTE_auxiliaryClass:
    910         case DRSUAPI_ATTRIBUTE_systemPossSuperiors:
    911         case DRSUAPI_ATTRIBUTE_possSuperiors:
    912                 return _dsdb_syntax_OID_obj_ldb_to_drsuapi(ldb, schema, attr, in, mem_ctx, out);
    913         case DRSUAPI_ATTRIBUTE_systemMustContain:
    914         case DRSUAPI_ATTRIBUTE_systemMayContain:       
    915         case DRSUAPI_ATTRIBUTE_mustContain:
    916         case DRSUAPI_ATTRIBUTE_mayContain:
    917                 return _dsdb_syntax_OID_attr_ldb_to_drsuapi(ldb, schema, attr, in, mem_ctx, out);
    918         case DRSUAPI_ATTRIBUTE_governsID:
    919         case DRSUAPI_ATTRIBUTE_attributeID:
    920         case DRSUAPI_ATTRIBUTE_attributeSyntax:
    921                 return _dsdb_syntax_OID_oid_ldb_to_drsuapi(ldb, schema, attr, in, mem_ctx, out);
    922         }
    923 
    924         out->attid                      = attr->attributeID_id;
     1506        if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     1507                return WERR_FOOBAR;
     1508        }
     1509
     1510        out->attid                      = dsdb_attribute_get_attid(attr,
     1511                                                                   ctx->is_schema_nc);
    9251512        out->value_ctr.num_values       = in->num_values;
    9261513        out->value_ctr.values           = talloc_array(mem_ctx,
     
    9331520
    9341521        for (i=0; i < in->num_values; i++) {
    935                 uint32_t v;
    936 
    9371522                out->value_ctr.values[i].blob   = &blobs[i];
    9381523
    939                 blobs[i] = data_blob_talloc(blobs, NULL, 4);
    940                 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
    941 
    942                 v = strtol((const char *)in->values[i].data, NULL, 10);
    943 
    944                 SIVAL(blobs[i].data, 0, v);
    945         }
    946 
    947         return WERR_OK;
    948 }
    949 
    950 static WERROR dsdb_syntax_UNICODE_drsuapi_to_ldb(struct ldb_context *ldb,
    951                                                  const struct dsdb_schema *schema,
    952                                                  const struct dsdb_attribute *attr,
    953                                                  const struct drsuapi_DsReplicaAttribute *in,
    954                                                  TALLOC_CTX *mem_ctx,
    955                                                  struct ldb_message_element *out)
    956 {
    957         uint32_t i;
     1524                if (!convert_string_talloc(blobs,
     1525                                           CH_UNIX, CH_UTF16,
     1526                                           in->values[i].data, in->values[i].length,
     1527                                           (void **)&blobs[i].data, &blobs[i].length, false)) {
     1528                        return WERR_FOOBAR;
     1529                }
     1530        }
     1531
     1532        return WERR_OK;
     1533}
     1534
     1535static WERROR dsdb_syntax_UNICODE_validate_one_val(const struct dsdb_syntax_ctx *ctx,
     1536                                                   const struct dsdb_attribute *attr,
     1537                                                   const struct ldb_val *val)
     1538{
     1539        void *dst = NULL;
     1540        size_t size;
     1541        bool ok;
     1542
     1543        if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     1544                return WERR_FOOBAR;
     1545        }
     1546
     1547        ok = convert_string_talloc(ctx->ldb,
     1548                                   CH_UNIX, CH_UTF16,
     1549                                   val->data,
     1550                                   val->length,
     1551                                   (void **)&dst,
     1552                                   &size, false);
     1553        TALLOC_FREE(dst);
     1554        if (!ok) {
     1555                return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     1556        }
     1557
     1558        if (attr->rangeLower) {
     1559                if ((size/2) < *attr->rangeLower) {
     1560                        return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     1561                }
     1562        }
     1563
     1564        if (attr->rangeUpper) {
     1565                if ((size/2) > *attr->rangeUpper) {
     1566                        return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     1567                }
     1568        }
     1569
     1570        return WERR_OK;
     1571}
     1572
     1573static WERROR dsdb_syntax_UNICODE_validate_ldb(const struct dsdb_syntax_ctx *ctx,
     1574                                               const struct dsdb_attribute *attr,
     1575                                               const struct ldb_message_element *in)
     1576{
     1577        WERROR status;
     1578        unsigned int i;
     1579
     1580        if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     1581                return WERR_FOOBAR;
     1582        }
     1583
     1584        for (i=0; i < in->num_values; i++) {
     1585                if (in->values[i].length == 0) {
     1586                        return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     1587                }
     1588
     1589                status = dsdb_syntax_UNICODE_validate_one_val(ctx,
     1590                                                              attr,
     1591                                                              &in->values[i]);
     1592                if (!W_ERROR_IS_OK(status)) {
     1593                        return status;
     1594                }
     1595        }
     1596
     1597        return WERR_OK;
     1598}
     1599
     1600static WERROR dsdb_syntax_one_DN_drsuapi_to_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
     1601                                                const struct dsdb_syntax *syntax,
     1602                                                const DATA_BLOB *in, DATA_BLOB *out)
     1603{
     1604        struct drsuapi_DsReplicaObjectIdentifier3 id3;
     1605        enum ndr_err_code ndr_err;
     1606        DATA_BLOB guid_blob;
     1607        struct ldb_dn *dn;
     1608        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     1609        int ret;
     1610        NTSTATUS status;
     1611
     1612        if (!tmp_ctx) {
     1613                W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
     1614        }
     1615
     1616        if (in == NULL) {
     1617                talloc_free(tmp_ctx);
     1618                return WERR_FOOBAR;
     1619        }
     1620
     1621        if (in->length == 0) {
     1622                talloc_free(tmp_ctx);
     1623                return WERR_FOOBAR;
     1624        }
     1625
     1626
     1627        /* windows sometimes sends an extra two pad bytes here */
     1628        ndr_err = ndr_pull_struct_blob(in,
     1629                                       tmp_ctx, &id3,
     1630                                       (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3);
     1631        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     1632                status = ndr_map_error2ntstatus(ndr_err);
     1633                talloc_free(tmp_ctx);
     1634                return ntstatus_to_werror(status);
     1635        }
     1636
     1637        dn = ldb_dn_new(tmp_ctx, ldb, id3.dn);
     1638        if (!dn) {
     1639                talloc_free(tmp_ctx);
     1640                /* If this fails, it must be out of memory, as it does not do much parsing */
     1641                W_ERROR_HAVE_NO_MEMORY(dn);
     1642        }
     1643
     1644        if (!GUID_all_zero(&id3.guid)) {
     1645                status = GUID_to_ndr_blob(&id3.guid, tmp_ctx, &guid_blob);
     1646                if (!NT_STATUS_IS_OK(status)) {
     1647                        talloc_free(tmp_ctx);
     1648                        return ntstatus_to_werror(status);
     1649                }
     1650
     1651                ret = ldb_dn_set_extended_component(dn, "GUID", &guid_blob);
     1652                if (ret != LDB_SUCCESS) {
     1653                        talloc_free(tmp_ctx);
     1654                        return WERR_FOOBAR;
     1655                }
     1656                talloc_free(guid_blob.data);
     1657        }
     1658
     1659        if (id3.__ndr_size_sid) {
     1660                DATA_BLOB sid_blob;
     1661                ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, &id3.sid,
     1662                                               (ndr_push_flags_fn_t)ndr_push_dom_sid);
     1663                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     1664                        status = ndr_map_error2ntstatus(ndr_err);
     1665                        talloc_free(tmp_ctx);
     1666                        return ntstatus_to_werror(status);
     1667                }
     1668
     1669                ret = ldb_dn_set_extended_component(dn, "SID", &sid_blob);
     1670                if (ret != LDB_SUCCESS) {
     1671                        talloc_free(tmp_ctx);
     1672                        return WERR_FOOBAR;
     1673                }
     1674        }
     1675
     1676        *out = data_blob_string_const(ldb_dn_get_extended_linearized(mem_ctx, dn, 1));
     1677        talloc_free(tmp_ctx);
     1678        return WERR_OK;
     1679}
     1680
     1681static WERROR dsdb_syntax_DN_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
     1682                                            const struct dsdb_attribute *attr,
     1683                                            const struct drsuapi_DsReplicaAttribute *in,
     1684                                            TALLOC_CTX *mem_ctx,
     1685                                            struct ldb_message_element *out)
     1686{
     1687        unsigned int i;
    9581688
    9591689        out->flags      = 0;
     
    9661696
    9671697        for (i=0; i < out->num_values; i++) {
    968                 char *str;
    969 
    970                 if (in->value_ctr.values[i].blob == NULL) {
    971                         return WERR_FOOBAR;
    972                 }
    973 
    974                 if (in->value_ctr.values[i].blob->length == 0) {
    975                         return WERR_FOOBAR;
    976                 }
    977 
    978                 if (!convert_string_talloc_convenience(out->values,
    979                                                 schema->iconv_convenience,
    980                                                                         CH_UTF16, CH_UNIX,
    981                                             in->value_ctr.values[i].blob->data,
    982                                             in->value_ctr.values[i].blob->length,
    983                                             (void **)&str, NULL, false)) {
    984                         return WERR_FOOBAR;
    985                 }
    986 
    987                 out->values[i] = data_blob_string_const(str);
    988         }
    989 
    990         return WERR_OK;
    991 }
    992 
    993 static WERROR dsdb_syntax_UNICODE_ldb_to_drsuapi(struct ldb_context *ldb,
    994                                                  const struct dsdb_schema *schema,
    995                                                  const struct dsdb_attribute *attr,
    996                                                  const struct ldb_message_element *in,
    997                                                  TALLOC_CTX *mem_ctx,
    998                                                  struct drsuapi_DsReplicaAttribute *out)
    999 {
    1000         uint32_t i;
     1698                WERROR status = dsdb_syntax_one_DN_drsuapi_to_ldb(out->values, ctx->ldb, attr->syntax,
     1699                                                                  in->value_ctr.values[i].blob,
     1700                                                                  &out->values[i]);
     1701                if (!W_ERROR_IS_OK(status)) {
     1702                        return status;
     1703                }
     1704
     1705        }
     1706
     1707        return WERR_OK;
     1708}
     1709
     1710static WERROR dsdb_syntax_DN_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
     1711                                            const struct dsdb_attribute *attr,
     1712                                            const struct ldb_message_element *in,
     1713                                            TALLOC_CTX *mem_ctx,
     1714                                            struct drsuapi_DsReplicaAttribute *out)
     1715{
     1716        unsigned int i;
    10011717        DATA_BLOB *blobs;
    10021718
    1003         if (attr->attributeID_id == 0xFFFFFFFF) {
    1004                 return WERR_FOOBAR;
    1005         }
    1006 
    1007         out->attid                      = attr->attributeID_id;
     1719        if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     1720                return WERR_FOOBAR;
     1721        }
     1722
     1723        out->attid                      = dsdb_attribute_get_attid(attr,
     1724                                                                   ctx->is_schema_nc);
    10081725        out->value_ctr.num_values       = in->num_values;
    10091726        out->value_ctr.values           = talloc_array(mem_ctx,
     
    10161733
    10171734        for (i=0; i < in->num_values; i++) {
     1735                struct drsuapi_DsReplicaObjectIdentifier3 id3;
     1736                enum ndr_err_code ndr_err;
     1737                struct ldb_dn *dn;
     1738                TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     1739                NTSTATUS status;
     1740
     1741                W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
     1742
    10181743                out->value_ctr.values[i].blob   = &blobs[i];
    10191744
    1020                 if (!convert_string_talloc_convenience(blobs,
    1021                         schema->iconv_convenience, CH_UNIX, CH_UTF16,
    1022                         in->values[i].data, in->values[i].length,
    1023                         (void **)&blobs[i].data, &blobs[i].length, false)) {
    1024                                 return WERR_FOOBAR;
    1025                 }
    1026         }
    1027 
    1028         return WERR_OK;
    1029 }
    1030 
    1031 static WERROR dsdb_syntax_DN_drsuapi_to_ldb(struct ldb_context *ldb,
    1032                                             const struct dsdb_schema *schema,
    1033                                             const struct dsdb_attribute *attr,
    1034                                             const struct drsuapi_DsReplicaAttribute *in,
    1035                                             TALLOC_CTX *mem_ctx,
    1036                                             struct ldb_message_element *out)
    1037 {
    1038         uint32_t i;
     1745                dn = ldb_dn_from_ldb_val(tmp_ctx, ctx->ldb, &in->values[i]);
     1746
     1747                W_ERROR_HAVE_NO_MEMORY(dn);
     1748
     1749                ZERO_STRUCT(id3);
     1750
     1751                status = dsdb_get_extended_dn_guid(dn, &id3.guid, "GUID");
     1752                if (!NT_STATUS_IS_OK(status) &&
     1753                    !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
     1754                        talloc_free(tmp_ctx);
     1755                        return ntstatus_to_werror(status);
     1756                }
     1757
     1758                status = dsdb_get_extended_dn_sid(dn, &id3.sid, "SID");
     1759                if (!NT_STATUS_IS_OK(status) &&
     1760                    !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
     1761                        talloc_free(tmp_ctx);
     1762                        return ntstatus_to_werror(status);
     1763                }
     1764
     1765                id3.dn = ldb_dn_get_linearized(dn);
     1766
     1767                ndr_err = ndr_push_struct_blob(&blobs[i], blobs, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
     1768                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     1769                        status = ndr_map_error2ntstatus(ndr_err);
     1770                        talloc_free(tmp_ctx);
     1771                        return ntstatus_to_werror(status);
     1772                }
     1773                talloc_free(tmp_ctx);
     1774        }
     1775
     1776        return WERR_OK;
     1777}
     1778
     1779static WERROR dsdb_syntax_DN_validate_one_val(const struct dsdb_syntax_ctx *ctx,
     1780                                              const struct dsdb_attribute *attr,
     1781                                              const struct ldb_val *val,
     1782                                              TALLOC_CTX *mem_ctx,
     1783                                              struct dsdb_dn **_dsdb_dn)
     1784{
     1785        static const char * const extended_list[] = { "GUID", "SID", NULL };
     1786        enum ndr_err_code ndr_err;
     1787        struct GUID guid;
     1788        struct dom_sid sid;
     1789        const DATA_BLOB *sid_blob;
     1790        struct dsdb_dn *dsdb_dn;
     1791        struct ldb_dn *dn;
     1792        char *dn_str;
     1793        struct ldb_dn *dn2;
     1794        char *dn2_str;
     1795        int num_components;
     1796        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     1797        NTSTATUS status;
     1798
     1799        W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
     1800
     1801        if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     1802                return WERR_FOOBAR;
     1803        }
     1804
     1805        dsdb_dn = dsdb_dn_parse(tmp_ctx, ctx->ldb, val,
     1806                                attr->syntax->ldap_oid);
     1807        if (!dsdb_dn) {
     1808                talloc_free(tmp_ctx);
     1809                return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     1810        }
     1811        dn = dsdb_dn->dn;
     1812
     1813        dn2 = ldb_dn_copy(tmp_ctx, dn);
     1814        if (dn == NULL) {
     1815                talloc_free(tmp_ctx);
     1816                return WERR_NOMEM;
     1817        }
     1818
     1819        num_components = ldb_dn_get_comp_num(dn);
     1820
     1821        status = dsdb_get_extended_dn_guid(dn, &guid, "GUID");
     1822        if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
     1823                num_components++;
     1824        } else if (!NT_STATUS_IS_OK(status)) {
     1825                talloc_free(tmp_ctx);
     1826                return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     1827        }
     1828
     1829        sid_blob = ldb_dn_get_extended_component(dn, "SID");
     1830        if (sid_blob) {
     1831                num_components++;
     1832                ndr_err = ndr_pull_struct_blob_all(sid_blob,
     1833                                                   tmp_ctx,
     1834                                                   &sid,
     1835                                                   (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
     1836                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     1837                        talloc_free(tmp_ctx);
     1838                        return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     1839                }
     1840        }
     1841
     1842        /* Do not allow links to the RootDSE */
     1843        if (num_components == 0) {
     1844                talloc_free(tmp_ctx);
     1845                return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     1846        }
     1847
     1848        /*
     1849         * We need to check that only "GUID" and "SID" are
     1850         * specified as extended components, we do that
     1851         * by comparing the dn's after removing all components
     1852         * from one dn and only the allowed subset from the other
     1853         * one.
     1854         */
     1855        ldb_dn_extended_filter(dn, extended_list);
     1856
     1857        dn_str = ldb_dn_get_extended_linearized(tmp_ctx, dn, 0);
     1858        if (dn_str == NULL) {
     1859                talloc_free(tmp_ctx);
     1860                return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     1861        }
     1862        dn2_str = ldb_dn_get_extended_linearized(tmp_ctx, dn2, 0);
     1863        if (dn2_str == NULL) {
     1864                talloc_free(tmp_ctx);
     1865                return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     1866        }
     1867
     1868        if (strcmp(dn_str, dn2_str) != 0) {
     1869                talloc_free(tmp_ctx);
     1870                return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     1871        }
     1872
     1873        *_dsdb_dn = talloc_move(mem_ctx, &dsdb_dn);
     1874        talloc_free(tmp_ctx);
     1875        return WERR_OK;
     1876}
     1877
     1878static WERROR dsdb_syntax_DN_validate_ldb(const struct dsdb_syntax_ctx *ctx,
     1879                                          const struct dsdb_attribute *attr,
     1880                                          const struct ldb_message_element *in)
     1881{
     1882        unsigned int i;
     1883
     1884        if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     1885                return WERR_FOOBAR;
     1886        }
     1887
     1888        for (i=0; i < in->num_values; i++) {
     1889                WERROR status;
     1890                struct dsdb_dn *dsdb_dn;
     1891                TALLOC_CTX *tmp_ctx = talloc_new(ctx->ldb);
     1892                W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
     1893
     1894                status = dsdb_syntax_DN_validate_one_val(ctx,
     1895                                                         attr,
     1896                                                         &in->values[i],
     1897                                                         tmp_ctx, &dsdb_dn);
     1898                if (!W_ERROR_IS_OK(status)) {
     1899                        talloc_free(tmp_ctx);
     1900                        return status;
     1901                }
     1902
     1903                if (dsdb_dn->dn_format != DSDB_NORMAL_DN) {
     1904                        talloc_free(tmp_ctx);
     1905                        return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     1906                }
     1907
     1908                talloc_free(tmp_ctx);
     1909        }
     1910
     1911        return WERR_OK;
     1912}
     1913
     1914static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
     1915                                                   const struct dsdb_attribute *attr,
     1916                                                   const struct drsuapi_DsReplicaAttribute *in,
     1917                                                   TALLOC_CTX *mem_ctx,
     1918                                                   struct ldb_message_element *out)
     1919{
     1920        unsigned int i;
    10391921        int ret;
    10401922
     
    10481930
    10491931        for (i=0; i < out->num_values; i++) {
    1050                 struct drsuapi_DsReplicaObjectIdentifier3 id3;
     1932                struct drsuapi_DsReplicaObjectIdentifier3Binary id3;
    10511933                enum ndr_err_code ndr_err;
    10521934                DATA_BLOB guid_blob;
    10531935                struct ldb_dn *dn;
     1936                struct dsdb_dn *dsdb_dn;
     1937                NTSTATUS status;
    10541938                TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
    10551939                if (!tmp_ctx) {
     
    10671951                }
    10681952
    1069                
     1953
    10701954                /* windows sometimes sends an extra two pad bytes here */
    10711955                ndr_err = ndr_pull_struct_blob(in->value_ctr.values[i].blob,
    1072                                                tmp_ctx, schema->iconv_convenience, &id3,
    1073                                                (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3);
     1956                                               tmp_ctx, &id3,
     1957                                               (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary);
    10741958                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1075                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
     1959                        status = ndr_map_error2ntstatus(ndr_err);
    10761960                        talloc_free(tmp_ctx);
    10771961                        return ntstatus_to_werror(status);
    10781962                }
    10791963
    1080                 dn = ldb_dn_new(tmp_ctx, ldb, id3.dn);
     1964                dn = ldb_dn_new(tmp_ctx, ctx->ldb, id3.dn);
    10811965                if (!dn) {
    10821966                        talloc_free(tmp_ctx);
     
    10851969                }
    10861970
    1087                 ndr_err = ndr_push_struct_blob(&guid_blob, tmp_ctx, schema->iconv_convenience, &id3.guid,
    1088                                                (ndr_push_flags_fn_t)ndr_push_GUID);
    1089                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1090                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
     1971                status = GUID_to_ndr_blob(&id3.guid, tmp_ctx, &guid_blob);
     1972                if (!NT_STATUS_IS_OK(status)) {
    10911973                        talloc_free(tmp_ctx);
    10921974                        return ntstatus_to_werror(status);
     
    11031985                if (id3.__ndr_size_sid) {
    11041986                        DATA_BLOB sid_blob;
    1105                         ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, schema->iconv_convenience, &id3.sid,
     1987                        ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, &id3.sid,
    11061988                                                       (ndr_push_flags_fn_t)ndr_push_dom_sid);
    11071989                        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1108                                 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
     1990                                status = ndr_map_error2ntstatus(ndr_err);
    11091991                                talloc_free(tmp_ctx);
    11101992                                return ntstatus_to_werror(status);
     
    11182000                }
    11192001
    1120                 out->values[i] = data_blob_string_const(ldb_dn_get_extended_linearized(out->values, dn, 1));
     2002                /* set binary stuff */
     2003                dsdb_dn = dsdb_dn_construct(tmp_ctx, dn, id3.binary, attr->syntax->ldap_oid);
     2004                if (!dsdb_dn) {
     2005                        /* If this fails, it must be out of memory, we know the ldap_oid is valid */
     2006                        talloc_free(tmp_ctx);
     2007                        W_ERROR_HAVE_NO_MEMORY(dsdb_dn);
     2008                }
     2009                out->values[i] = data_blob_string_const(dsdb_dn_get_extended_linearized(out->values, dsdb_dn, 1));
    11212010                talloc_free(tmp_ctx);
    11222011        }
     
    11252014}
    11262015
    1127 static WERROR dsdb_syntax_DN_ldb_to_drsuapi(struct ldb_context *ldb,
    1128                                             const struct dsdb_schema *schema,
    1129                                             const struct dsdb_attribute *attr,
    1130                                             const struct ldb_message_element *in,
    1131                                             TALLOC_CTX *mem_ctx,
    1132                                             struct drsuapi_DsReplicaAttribute *out)
    1133 {
    1134         uint32_t i;
     2016static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
     2017                                                   const struct dsdb_attribute *attr,
     2018                                                   const struct ldb_message_element *in,
     2019                                                   TALLOC_CTX *mem_ctx,
     2020                                                   struct drsuapi_DsReplicaAttribute *out)
     2021{
     2022        unsigned int i;
    11352023        DATA_BLOB *blobs;
    11362024
    1137         if (attr->attributeID_id == 0xFFFFFFFF) {
    1138                 return WERR_FOOBAR;
    1139         }
    1140 
    1141         out->attid                      = attr->attributeID_id;
     2025        if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     2026                return WERR_FOOBAR;
     2027        }
     2028
     2029        out->attid                      = dsdb_attribute_get_attid(attr,
     2030                                                                   ctx->is_schema_nc);
    11422031        out->value_ctr.num_values       = in->num_values;
    11432032        out->value_ctr.values           = talloc_array(mem_ctx,
     
    11502039
    11512040        for (i=0; i < in->num_values; i++) {
    1152                 struct drsuapi_DsReplicaObjectIdentifier3 id3;
     2041                struct drsuapi_DsReplicaObjectIdentifier3Binary id3;
    11532042                enum ndr_err_code ndr_err;
    1154                 const DATA_BLOB *guid_blob, *sid_blob;
    1155                 struct ldb_dn *dn;
     2043                const DATA_BLOB *sid_blob;
     2044                struct dsdb_dn *dsdb_dn;
    11562045                TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     2046                NTSTATUS status;
     2047
    11572048                W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
    11582049
    11592050                out->value_ctr.values[i].blob   = &blobs[i];
    11602051
    1161                 dn = ldb_dn_from_ldb_val(tmp_ctx, ldb, &in->values[i]);
    1162 
    1163                 W_ERROR_HAVE_NO_MEMORY(dn);
    1164 
    1165                 guid_blob = ldb_dn_get_extended_component(dn, "GUID");
     2052                dsdb_dn = dsdb_dn_parse(tmp_ctx, ctx->ldb, &in->values[i], attr->syntax->ldap_oid);
     2053
     2054                if (!dsdb_dn) {
     2055                        talloc_free(tmp_ctx);
     2056                        return ntstatus_to_werror(NT_STATUS_INVALID_PARAMETER);
     2057                }
    11662058
    11672059                ZERO_STRUCT(id3);
    11682060
    1169                 if (guid_blob) {
    1170                         ndr_err = ndr_pull_struct_blob_all(guid_blob,
    1171                                                            tmp_ctx, schema->iconv_convenience, &id3.guid,
    1172                                                            (ndr_pull_flags_fn_t)ndr_pull_GUID);
     2061                status = dsdb_get_extended_dn_guid(dsdb_dn->dn, &id3.guid, "GUID");
     2062                if (!NT_STATUS_IS_OK(status) &&
     2063                    !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
     2064                        talloc_free(tmp_ctx);
     2065                        return ntstatus_to_werror(status);
     2066                }
     2067
     2068                sid_blob = ldb_dn_get_extended_component(dsdb_dn->dn, "SID");
     2069                if (sid_blob) {
     2070
     2071                        ndr_err = ndr_pull_struct_blob_all(sid_blob,
     2072                                                           tmp_ctx, &id3.sid,
     2073                                                           (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
    11732074                        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1174                                 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
     2075                                status = ndr_map_error2ntstatus(ndr_err);
    11752076                                talloc_free(tmp_ctx);
    11762077                                return ntstatus_to_werror(status);
     
    11782079                }
    11792080
    1180                 sid_blob = ldb_dn_get_extended_component(dn, "SID");
    1181                 if (sid_blob) {
    1182                        
    1183                         ndr_err = ndr_pull_struct_blob_all(sid_blob,
    1184                                                            tmp_ctx, schema->iconv_convenience, &id3.sid,
    1185                                                            (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
    1186                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1187                                 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
    1188                                 talloc_free(tmp_ctx);
    1189                                 return ntstatus_to_werror(status);
    1190                         }
    1191                 }
    1192 
    1193                 id3.dn = ldb_dn_get_linearized(dn);
    1194 
    1195                 ndr_err = ndr_push_struct_blob(&blobs[i], blobs, schema->iconv_convenience, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
     2081                id3.dn = ldb_dn_get_linearized(dsdb_dn->dn);
     2082
     2083                /* get binary stuff */
     2084                id3.binary = dsdb_dn->extra_part;
     2085
     2086                ndr_err = ndr_push_struct_blob(&blobs[i], blobs, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary);
    11962087                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1197                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
     2088                        status = ndr_map_error2ntstatus(ndr_err);
    11982089                        talloc_free(tmp_ctx);
    11992090                        return ntstatus_to_werror(status);
     
    12052096}
    12062097
    1207 static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(struct ldb_context *ldb,
    1208                                                    const struct dsdb_schema *schema,
     2098static WERROR dsdb_syntax_DN_BINARY_validate_ldb(const struct dsdb_syntax_ctx *ctx,
     2099                                                 const struct dsdb_attribute *attr,
     2100                                                 const struct ldb_message_element *in)
     2101{
     2102        unsigned int i;
     2103
     2104        if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     2105                return WERR_FOOBAR;
     2106        }
     2107
     2108        for (i=0; i < in->num_values; i++) {
     2109                WERROR status;
     2110                struct dsdb_dn *dsdb_dn;
     2111                TALLOC_CTX *tmp_ctx = talloc_new(ctx->ldb);
     2112                W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
     2113
     2114                status = dsdb_syntax_DN_validate_one_val(ctx,
     2115                                                         attr,
     2116                                                         &in->values[i],
     2117                                                         tmp_ctx, &dsdb_dn);
     2118                if (!W_ERROR_IS_OK(status)) {
     2119                        talloc_free(tmp_ctx);
     2120                        return status;
     2121                }
     2122
     2123                if (dsdb_dn->dn_format != DSDB_BINARY_DN) {
     2124                        talloc_free(tmp_ctx);
     2125                        return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     2126                }
     2127
     2128                status = dsdb_syntax_DATA_BLOB_validate_one_val(ctx,
     2129                                                                attr,
     2130                                                                &dsdb_dn->extra_part);
     2131                if (!W_ERROR_IS_OK(status)) {
     2132                        talloc_free(tmp_ctx);
     2133                        return status;
     2134                }
     2135
     2136                talloc_free(tmp_ctx);
     2137        }
     2138
     2139        return WERR_OK;
     2140}
     2141
     2142static WERROR dsdb_syntax_DN_STRING_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
    12092143                                                   const struct dsdb_attribute *attr,
    12102144                                                   const struct drsuapi_DsReplicaAttribute *in,
     
    12122146                                                   struct ldb_message_element *out)
    12132147{
    1214         uint32_t i;
    1215 
    1216         out->flags      = 0;
    1217         out->name       = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
    1218         W_ERROR_HAVE_NO_MEMORY(out->name);
    1219 
    1220         out->num_values = in->value_ctr.num_values;
    1221         out->values     = talloc_array(mem_ctx, struct ldb_val, out->num_values);
    1222         W_ERROR_HAVE_NO_MEMORY(out->values);
    1223 
    1224         for (i=0; i < out->num_values; i++) {
    1225                 struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
    1226                 char *binary;
    1227                 char *str;
    1228                 enum ndr_err_code ndr_err;
    1229 
    1230                 if (in->value_ctr.values[i].blob == NULL) {
    1231                         return WERR_FOOBAR;
    1232                 }
    1233 
    1234                 if (in->value_ctr.values[i].blob->length == 0) {
    1235                         return WERR_FOOBAR;
    1236                 }
    1237 
    1238                 ndr_err = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob,
    1239                                                    out->values, schema->iconv_convenience, &id3b,
    1240                                                    (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary);
    1241                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1242                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
    1243                         return ntstatus_to_werror(status);
    1244                 }
    1245 
    1246                 /* TODO: handle id3.guid and id3.sid */
    1247                 binary = data_blob_hex_string(out->values, &id3b.binary);
    1248                 W_ERROR_HAVE_NO_MEMORY(binary);
    1249 
    1250                 str = talloc_asprintf(out->values, "B:%u:%s:%s",
    1251                                       (unsigned int)(id3b.binary.length * 2), /* because of 2 hex chars per byte */
    1252                                       binary,
    1253                                       id3b.dn);
    1254                 W_ERROR_HAVE_NO_MEMORY(str);
    1255 
    1256                 /* TODO: handle id3.guid and id3.sid */
    1257                 out->values[i] = data_blob_string_const(str);
    1258         }
    1259 
    1260         return WERR_OK;
    1261 }
    1262 
    1263 static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(struct ldb_context *ldb,
    1264                                                    const struct dsdb_schema *schema,
     2148        return dsdb_syntax_DN_BINARY_drsuapi_to_ldb(ctx,
     2149                                                    attr,
     2150                                                    in,
     2151                                                    mem_ctx,
     2152                                                    out);
     2153}
     2154
     2155static WERROR dsdb_syntax_DN_STRING_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
    12652156                                                   const struct dsdb_attribute *attr,
    12662157                                                   const struct ldb_message_element *in,
     
    12682159                                                   struct drsuapi_DsReplicaAttribute *out)
    12692160{
    1270         uint32_t i;
     2161        return dsdb_syntax_DN_BINARY_ldb_to_drsuapi(ctx,
     2162                                                    attr,
     2163                                                    in,
     2164                                                    mem_ctx,
     2165                                                    out);
     2166}
     2167
     2168static WERROR dsdb_syntax_DN_STRING_validate_ldb(const struct dsdb_syntax_ctx *ctx,
     2169                                                 const struct dsdb_attribute *attr,
     2170                                                 const struct ldb_message_element *in)
     2171{
     2172        unsigned int i;
     2173
     2174        if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     2175                return WERR_FOOBAR;
     2176        }
     2177
     2178        for (i=0; i < in->num_values; i++) {
     2179                WERROR status;
     2180                struct dsdb_dn *dsdb_dn;
     2181                TALLOC_CTX *tmp_ctx = talloc_new(ctx->ldb);
     2182                W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
     2183
     2184                status = dsdb_syntax_DN_validate_one_val(ctx,
     2185                                                         attr,
     2186                                                         &in->values[i],
     2187                                                         tmp_ctx, &dsdb_dn);
     2188                if (!W_ERROR_IS_OK(status)) {
     2189                        talloc_free(tmp_ctx);
     2190                        return status;
     2191                }
     2192
     2193                if (dsdb_dn->dn_format != DSDB_STRING_DN) {
     2194                        talloc_free(tmp_ctx);
     2195                        return WERR_DS_INVALID_ATTRIBUTE_SYNTAX;
     2196                }
     2197
     2198                status = dsdb_syntax_UNICODE_validate_one_val(ctx,
     2199                                                              attr,
     2200                                                              &dsdb_dn->extra_part);
     2201                if (!W_ERROR_IS_OK(status)) {
     2202                        talloc_free(tmp_ctx);
     2203                        return status;
     2204                }
     2205
     2206                talloc_free(tmp_ctx);
     2207        }
     2208
     2209        return WERR_OK;
     2210}
     2211
     2212static WERROR dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx,
     2213                                                              const struct dsdb_attribute *attr,
     2214                                                              const struct drsuapi_DsReplicaAttribute *in,
     2215                                                              TALLOC_CTX *mem_ctx,
     2216                                                              struct ldb_message_element *out)
     2217{
     2218        unsigned int i;
     2219
     2220        out->flags      = 0;
     2221        out->name       = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
     2222        W_ERROR_HAVE_NO_MEMORY(out->name);
     2223
     2224        out->num_values = in->value_ctr.num_values;
     2225        out->values     = talloc_array(mem_ctx, struct ldb_val, out->num_values);
     2226        W_ERROR_HAVE_NO_MEMORY(out->values);
     2227
     2228        for (i=0; i < out->num_values; i++) {
     2229                size_t len;
     2230                char *str;
     2231
     2232                if (in->value_ctr.values[i].blob == NULL) {
     2233                        return WERR_FOOBAR;
     2234                }
     2235
     2236                if (in->value_ctr.values[i].blob->length < 4) {
     2237                        return WERR_FOOBAR;
     2238                }
     2239
     2240                len = IVAL(in->value_ctr.values[i].blob->data, 0);
     2241
     2242                if (len != in->value_ctr.values[i].blob->length) {
     2243                        return WERR_FOOBAR;
     2244                }
     2245
     2246                if (!convert_string_talloc(out->values, CH_UTF16, CH_UNIX,
     2247                                           in->value_ctr.values[i].blob->data+4,
     2248                                           in->value_ctr.values[i].blob->length-4,
     2249                                           (void **)&str, NULL, false)) {
     2250                        return WERR_FOOBAR;
     2251                }
     2252
     2253                out->values[i] = data_blob_string_const(str);
     2254        }
     2255
     2256        return WERR_OK;
     2257}
     2258
     2259static WERROR dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
     2260                                                              const struct dsdb_attribute *attr,
     2261                                                              const struct ldb_message_element *in,
     2262                                                              TALLOC_CTX *mem_ctx,
     2263                                                              struct drsuapi_DsReplicaAttribute *out)
     2264{
     2265        unsigned int i;
    12712266        DATA_BLOB *blobs;
    12722267
    1273         if (attr->attributeID_id == 0xFFFFFFFF) {
    1274                 return WERR_FOOBAR;
    1275         }
    1276 
    1277         out->attid                      = attr->attributeID_id;
     2268        if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) {
     2269                return WERR_FOOBAR;
     2270        }
     2271
     2272        out->attid                      = dsdb_attribute_get_attid(attr,
     2273                                                                   ctx->is_schema_nc);
    12782274        out->value_ctr.num_values       = in->num_values;
    12792275        out->value_ctr.values           = talloc_array(mem_ctx,
     
    12862282
    12872283        for (i=0; i < in->num_values; i++) {
    1288                 struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
    1289                 enum ndr_err_code ndr_err;
    1290 
    1291                 out->value_ctr.values[i].blob   = &blobs[i];
    1292 
    1293                 /* TODO: handle id3b.guid and id3b.sid, id3.binary */
    1294                 ZERO_STRUCT(id3b);
    1295                 id3b.dn         = (const char *)in->values[i].data;
    1296                 id3b.binary     = data_blob(NULL, 0);
    1297 
    1298                 ndr_err = ndr_push_struct_blob(&blobs[i], blobs, schema->iconv_convenience, &id3b,
    1299                                                (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary);
    1300                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1301                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
    1302                         return ntstatus_to_werror(status);
    1303                 }
    1304         }
    1305 
    1306         return WERR_OK;
    1307 }
    1308 
    1309 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb(struct ldb_context *ldb,
    1310                                                               const struct dsdb_schema *schema,
    1311                                                               const struct dsdb_attribute *attr,
    1312                                                               const struct drsuapi_DsReplicaAttribute *in,
    1313                                                               TALLOC_CTX *mem_ctx,
    1314                                                               struct ldb_message_element *out)
    1315 {
    1316         uint32_t i;
    1317 
    1318         out->flags      = 0;
    1319         out->name       = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
    1320         W_ERROR_HAVE_NO_MEMORY(out->name);
    1321 
    1322         out->num_values = in->value_ctr.num_values;
    1323         out->values     = talloc_array(mem_ctx, struct ldb_val, out->num_values);
    1324         W_ERROR_HAVE_NO_MEMORY(out->values);
    1325 
    1326         for (i=0; i < out->num_values; i++) {
    1327                 uint32_t len;
    1328                 char *str;
    1329 
    1330                 if (in->value_ctr.values[i].blob == NULL) {
    1331                         return WERR_FOOBAR;
    1332                 }
    1333 
    1334                 if (in->value_ctr.values[i].blob->length < 4) {
    1335                         return WERR_FOOBAR;
    1336                 }
    1337 
    1338                 len = IVAL(in->value_ctr.values[i].blob->data, 0);
    1339 
    1340                 if (len != in->value_ctr.values[i].blob->length) {
    1341                         return WERR_FOOBAR;
    1342                 }
    1343 
    1344                 if (!convert_string_talloc_convenience(out->values, schema->iconv_convenience, CH_UTF16, CH_UNIX,
    1345                                             in->value_ctr.values[i].blob->data+4,
    1346                                             in->value_ctr.values[i].blob->length-4,
    1347                                             (void **)&str, NULL, false)) {
    1348                         return WERR_FOOBAR;
    1349                 }
    1350 
    1351                 out->values[i] = data_blob_string_const(str);
    1352         }
    1353 
    1354         return WERR_OK;
    1355 }
    1356 
    1357 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi(struct ldb_context *ldb,
    1358                                                               const struct dsdb_schema *schema,
    1359                                                               const struct dsdb_attribute *attr,
    1360                                                               const struct ldb_message_element *in,
    1361                                                               TALLOC_CTX *mem_ctx,
    1362                                                               struct drsuapi_DsReplicaAttribute *out)
    1363 {
    1364         uint32_t i;
    1365         DATA_BLOB *blobs;
    1366 
    1367         if (attr->attributeID_id == 0xFFFFFFFF) {
    1368                 return WERR_FOOBAR;
    1369         }
    1370 
    1371         out->attid                      = attr->attributeID_id;
    1372         out->value_ctr.num_values       = in->num_values;
    1373         out->value_ctr.values           = talloc_array(mem_ctx,
    1374                                                        struct drsuapi_DsAttributeValue,
    1375                                                        in->num_values);
    1376         W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
    1377 
    1378         blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
    1379         W_ERROR_HAVE_NO_MEMORY(blobs);
    1380 
    1381         for (i=0; i < in->num_values; i++) {
    13822284                uint8_t *data;
    13832285                size_t ret;
     
    13852287                out->value_ctr.values[i].blob   = &blobs[i];
    13862288
    1387                 if (!convert_string_talloc_convenience(blobs, schema->iconv_convenience, CH_UNIX, CH_UTF16,
    1388                                             in->values[i].data,
    1389                                             in->values[i].length,
    1390                                             (void **)&data, &ret, false)) {
     2289                if (!convert_string_talloc(blobs, CH_UNIX, CH_UTF16,
     2290                                           in->values[i].data,
     2291                                           in->values[i].length,
     2292                                           (void **)&data, &ret, false)) {
    13912293                        return WERR_FOOBAR;
    13922294                }
     
    14042306
    14052307        return WERR_OK;
     2308}
     2309
     2310static WERROR dsdb_syntax_PRESENTATION_ADDRESS_validate_ldb(const struct dsdb_syntax_ctx *ctx,
     2311                                                            const struct dsdb_attribute *attr,
     2312                                                            const struct ldb_message_element *in)
     2313{
     2314        return dsdb_syntax_UNICODE_validate_ldb(ctx,
     2315                                                attr,
     2316                                                in);
    14062317}
    14072318
     
    14162327                .drsuapi_to_ldb         = dsdb_syntax_BOOL_drsuapi_to_ldb,
    14172328                .ldb_to_drsuapi         = dsdb_syntax_BOOL_ldb_to_drsuapi,
     2329                .validate_ldb           = dsdb_syntax_BOOL_validate_ldb,
    14182330                .equality               = "booleanMatch",
    1419                 .comment                = "Boolean" 
     2331                .comment                = "Boolean"
    14202332        },{
    14212333                .name                   = "Integer",
     
    14252337                .drsuapi_to_ldb         = dsdb_syntax_INT32_drsuapi_to_ldb,
    14262338                .ldb_to_drsuapi         = dsdb_syntax_INT32_ldb_to_drsuapi,
     2339                .validate_ldb           = dsdb_syntax_INT32_validate_ldb,
    14272340                .equality               = "integerMatch",
    14282341                .comment                = "Integer",
     
    14352348                .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
    14362349                .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
     2350                .validate_ldb           = dsdb_syntax_DATA_BLOB_validate_ldb,
    14372351                .equality               = "octetStringMatch",
    14382352                .comment                = "Octet String",
     
    14442358                .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
    14452359                .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
     2360                .validate_ldb           = dsdb_syntax_DATA_BLOB_validate_ldb,
    14462361                .equality               = "octetStringMatch",
    14472362                .comment                = "Octet String - Security Identifier (SID)",
     
    14542369                .drsuapi_to_ldb         = dsdb_syntax_OID_drsuapi_to_ldb,
    14552370                .ldb_to_drsuapi         = dsdb_syntax_OID_ldb_to_drsuapi,
     2371                .validate_ldb           = dsdb_syntax_OID_validate_ldb,
    14562372                .equality               = "caseIgnoreMatch", /* Would use "objectIdentifierMatch" but most are ldap attribute/class names */
    14572373                .comment                = "OID String",
     
    14642380                .drsuapi_to_ldb         = dsdb_syntax_INT32_drsuapi_to_ldb,
    14652381                .ldb_to_drsuapi         = dsdb_syntax_INT32_ldb_to_drsuapi,
     2382                .validate_ldb           = dsdb_syntax_INT32_validate_ldb,
    14662383                .ldb_syntax             = LDB_SYNTAX_SAMBA_INT32
    14672384        },{
     
    14732390                .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
    14742391                .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
     2392                .validate_ldb           = dsdb_syntax_DATA_BLOB_validate_ldb,
    14752393                .equality               = "numericStringMatch",
    14762394                .substring              = "numericStringSubstringsMatch",
     
    14842402                .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
    14852403                .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
     2404                .validate_ldb           = dsdb_syntax_DATA_BLOB_validate_ldb,
    14862405                .ldb_syntax             = LDB_SYNTAX_OCTET_STRING,
    14872406        },{
     
    14922411                .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
    14932412                .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
     2413                .validate_ldb           = dsdb_syntax_DATA_BLOB_validate_ldb,
    14942414                .equality               = "caseIgnoreMatch",
    14952415                .substring              = "caseIgnoreSubstringsMatch",
     
    15032423                .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
    15042424                .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
     2425                .validate_ldb           = dsdb_syntax_DATA_BLOB_validate_ldb,
    15052426                .equality               = "caseExactIA5Match",
    15062427                .comment                = "Printable String",
     
    15132434                .drsuapi_to_ldb         = dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb,
    15142435                .ldb_to_drsuapi         = dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi,
     2436                .validate_ldb           = dsdb_syntax_NTTIME_UTC_validate_ldb,
    15152437                .equality               = "generalizedTimeMatch",
    15162438                .comment                = "UTC Time",
     
    15222444                .drsuapi_to_ldb         = dsdb_syntax_NTTIME_drsuapi_to_ldb,
    15232445                .ldb_to_drsuapi         = dsdb_syntax_NTTIME_ldb_to_drsuapi,
     2446                .validate_ldb           = dsdb_syntax_NTTIME_validate_ldb,
    15242447                .equality               = "generalizedTimeMatch",
    15252448                .comment                = "Generalized Time",
     
    15312454                .oMSyntax               = 27,
    15322455                .attributeSyntax_oid    = "2.5.5.3",
    1533                 .drsuapi_to_ldb         = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
    1534                 .ldb_to_drsuapi         = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
     2456                .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
     2457                .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
     2458                .validate_ldb           = dsdb_syntax_DATA_BLOB_validate_ldb,
     2459                .equality               = "caseExactMatch",
     2460                .substring              = "caseExactSubstringsMatch",
     2461                /* TODO (kim): according to LDAP rfc we should be using same comparison
     2462                 * as Directory String (LDB_SYNTAX_DIRECTORY_STRING), but case sensitive.
     2463                 * But according to ms docs binary compare should do the job:
     2464                 * http://msdn.microsoft.com/en-us/library/cc223200(v=PROT.10).aspx */
     2465                .ldb_syntax             = LDB_SYNTAX_OCTET_STRING,
    15352466        },{
    15362467                .name                   = "String(Unicode)",
     
    15402471                .drsuapi_to_ldb         = dsdb_syntax_UNICODE_drsuapi_to_ldb,
    15412472                .ldb_to_drsuapi         = dsdb_syntax_UNICODE_ldb_to_drsuapi,
     2473                .validate_ldb           = dsdb_syntax_UNICODE_validate_ldb,
    15422474                .equality               = "caseIgnoreMatch",
    15432475                .substring              = "caseIgnoreSubstringsMatch",
     
    15502482                .drsuapi_to_ldb         = dsdb_syntax_INT64_drsuapi_to_ldb,
    15512483                .ldb_to_drsuapi         = dsdb_syntax_INT64_ldb_to_drsuapi,
     2484                .validate_ldb           = dsdb_syntax_INT64_validate_ldb,
    15522485                .equality               = "integerMatch",
    15532486                .comment                = "Large Integer",
     
    15602493                .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
    15612494                .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
     2495                .validate_ldb           = dsdb_syntax_DATA_BLOB_validate_ldb,
    15622496        },{
    15632497                .name                   = "Object(DS-DN)",
     
    15682502                .drsuapi_to_ldb         = dsdb_syntax_DN_drsuapi_to_ldb,
    15692503                .ldb_to_drsuapi         = dsdb_syntax_DN_ldb_to_drsuapi,
     2504                .validate_ldb           = dsdb_syntax_DN_validate_ldb,
    15702505                .equality               = "distinguishedNameMatch",
    15712506                .comment                = "Object(DS-DN) == a DN",
    15722507        },{
    15732508                .name                   = "Object(DN-Binary)",
    1574                 .ldap_oid               = "1.2.840.113556.1.4.903",
     2509                .ldap_oid               = DSDB_SYNTAX_BINARY_DN,
    15752510                .oMSyntax               = 127,
    15762511                .oMObjectClass          = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0b"),
     
    15782513                .drsuapi_to_ldb         = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
    15792514                .ldb_to_drsuapi         = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
     2515                .validate_ldb           = dsdb_syntax_DN_BINARY_validate_ldb,
    15802516                .equality               = "octetStringMatch",
    15812517                .comment                = "OctetString: Binary+DN",
    1582                 .ldb_syntax             = LDB_SYNTAX_OCTET_STRING,
    15832518        },{
    1584         /* not used in w2k3 schema */
     2519        /* not used in w2k3 schema, but used in Exchange schema*/
    15852520                .name                   = "Object(OR-Name)",
    1586                 .ldap_oid               = "1.2.840.113556.1.4.1221",
     2521                .ldap_oid               = DSDB_SYNTAX_OR_NAME,
    15872522                .oMSyntax               = 127,
    15882523                .oMObjectClass          = OMOBJECTCLASS("\x56\x06\x01\x02\x05\x0b\x1D"),
    15892524                .attributeSyntax_oid    = "2.5.5.7",
    1590                 .drsuapi_to_ldb         = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
    1591                 .ldb_to_drsuapi         = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
     2525                .drsuapi_to_ldb         = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
     2526                .ldb_to_drsuapi         = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
     2527                .validate_ldb           = dsdb_syntax_DN_BINARY_validate_ldb,
     2528                .equality               = "caseIgnoreMatch",
     2529                .ldb_syntax             = LDB_SYNTAX_DN,
    15922530        },{
    1593         /* 
     2531        /*
    15942532         * TODO: verify if DATA_BLOB is correct here...!
    15952533         *
    15962534         *       repsFrom and repsTo are the only attributes using
    1597          *       this attribute syntax, but they're not replicated... 
     2535         *       this attribute syntax, but they're not replicated...
    15982536         */
    15992537                .name                   = "Object(Replica-Link)",
     
    16042542                .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
    16052543                .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
     2544                .validate_ldb           = dsdb_syntax_DATA_BLOB_validate_ldb,
    16062545        },{
    16072546                .name                   = "Object(Presentation-Address)",
     
    16122551                .drsuapi_to_ldb         = dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb,
    16132552                .ldb_to_drsuapi         = dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi,
     2553                .validate_ldb           = dsdb_syntax_PRESENTATION_ADDRESS_validate_ldb,
    16142554                .comment                = "Presentation Address",
    16152555                .ldb_syntax             = LDB_SYNTAX_DIRECTORY_STRING,
     
    16232563                .drsuapi_to_ldb         = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
    16242564                .ldb_to_drsuapi         = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
     2565                .validate_ldb           = dsdb_syntax_FOOBAR_validate_ldb,
    16252566                .ldb_syntax             = LDB_SYNTAX_DIRECTORY_STRING,
    16262567        },{
    16272568        /* not used in w2k3 schema */
    16282569                .name                   = "Object(DN-String)",
    1629                 .ldap_oid               = "1.2.840.113556.1.4.904",
     2570                .ldap_oid               = DSDB_SYNTAX_STRING_DN,
    16302571                .oMSyntax               = 127,
    16312572                .oMObjectClass          = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0c"),
    16322573                .attributeSyntax_oid    = "2.5.5.14",
    1633                 .drsuapi_to_ldb         = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
    1634                 .ldb_to_drsuapi         = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
     2574                .drsuapi_to_ldb         = dsdb_syntax_DN_STRING_drsuapi_to_ldb,
     2575                .ldb_to_drsuapi         = dsdb_syntax_DN_STRING_ldb_to_drsuapi,
     2576                .validate_ldb           = dsdb_syntax_DN_STRING_validate_ldb,
    16352577                .equality               = "octetStringMatch",
    16362578                .comment                = "OctetString: String+DN",
    1637                 .ldb_syntax             = LDB_SYNTAX_OCTET_STRING,
    16382579        }
    16392580};
    16402581
    1641 const struct dsdb_syntax *find_syntax_map_by_ad_oid(const char *ad_oid) 
    1642 {
    1643         int i;
     2582const struct dsdb_syntax *find_syntax_map_by_ad_oid(const char *ad_oid)
     2583{
     2584        unsigned int i;
    16442585        for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
    16452586                if (strcasecmp(ad_oid, dsdb_syntaxes[i].attributeSyntax_oid) == 0) {
     
    16502591}
    16512592
    1652 const struct dsdb_syntax *find_syntax_map_by_ad_syntax(int oMSyntax) 
    1653 {
    1654         int i;
     2593const struct dsdb_syntax *find_syntax_map_by_ad_syntax(int oMSyntax)
     2594{
     2595        unsigned int i;
    16552596        for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
    16562597                if (oMSyntax == dsdb_syntaxes[i].oMSyntax) {
     
    16612602}
    16622603
    1663 const struct dsdb_syntax *find_syntax_map_by_standard_oid(const char *standard_oid) 
    1664 {
    1665         int i;
     2604const struct dsdb_syntax *find_syntax_map_by_standard_oid(const char *standard_oid)
     2605{
     2606        unsigned int i;
    16662607        for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
    16672608                if (strcasecmp(standard_oid, dsdb_syntaxes[i].ldap_oid) == 0) {
     
    16712612        return NULL;
    16722613}
     2614
    16732615const struct dsdb_syntax *dsdb_syntax_for_attribute(const struct dsdb_attribute *attr)
    16742616{
    1675         uint32_t i;
     2617        unsigned int i;
    16762618
    16772619        for (i=0; i < ARRAY_SIZE(dsdb_syntaxes); i++) {
     
    16962638}
    16972639
    1698 WERROR dsdb_attribute_drsuapi_to_ldb(struct ldb_context *ldb, 
     2640WERROR dsdb_attribute_drsuapi_to_ldb(struct ldb_context *ldb,
    16992641                                     const struct dsdb_schema *schema,
     2642                                     const struct dsdb_schema_prefixmap *pfm_remote,
    17002643                                     const struct drsuapi_DsReplicaAttribute *in,
    17012644                                     TALLOC_CTX *mem_ctx,
     
    17032646{
    17042647        const struct dsdb_attribute *sa;
    1705 
    1706         sa = dsdb_attribute_by_attributeID_id(schema, in->attid);
     2648        struct dsdb_syntax_ctx syntax_ctx;
     2649        uint32_t attid_local;
     2650
     2651        /* use default syntax conversion context */
     2652        dsdb_syntax_ctx_init(&syntax_ctx, ldb, schema);
     2653        syntax_ctx.pfm_remote = pfm_remote;
     2654
     2655        switch (dsdb_pfm_get_attid_type(in->attid)) {
     2656        case DSDB_ATTID_TYPE_PFM:
     2657                /* map remote ATTID to local ATTID */
     2658                if (!dsdb_syntax_attid_from_remote_attid(&syntax_ctx, mem_ctx, in->attid, &attid_local)) {
     2659                        DEBUG(0,(__location__ ": Can't find local ATTID for 0x%08X\n",
     2660                                 in->attid));
     2661                        return WERR_FOOBAR;
     2662                }
     2663                break;
     2664        case DSDB_ATTID_TYPE_INTID:
     2665                /* use IntId value directly */
     2666                attid_local = in->attid;
     2667                break;
     2668        default:
     2669                /* we should never get here */
     2670                DEBUG(0,(__location__ ": Invalid ATTID type passed for conversion - 0x%08X\n",
     2671                         in->attid));
     2672                return WERR_INVALID_PARAMETER;
     2673        }
     2674
     2675        sa = dsdb_attribute_by_attributeID_id(schema, attid_local);
    17072676        if (!sa) {
    1708                 return WERR_FOOBAR;
    1709         }
    1710 
    1711         return sa->syntax->drsuapi_to_ldb(ldb, schema, sa, in, mem_ctx, out);
    1712 }
    1713 
    1714 WERROR dsdb_attribute_ldb_to_drsuapi(struct ldb_context *ldb,
     2677                DEBUG(1,(__location__ ": Unknown attributeID_id 0x%08X\n", in->attid));
     2678                return WERR_FOOBAR;
     2679        }
     2680
     2681        return sa->syntax->drsuapi_to_ldb(&syntax_ctx, sa, in, mem_ctx, out);
     2682}
     2683
     2684WERROR dsdb_attribute_ldb_to_drsuapi(struct ldb_context *ldb,
    17152685                                     const struct dsdb_schema *schema,
    17162686                                     const struct ldb_message_element *in,
     
    17192689{
    17202690        const struct dsdb_attribute *sa;
     2691        struct dsdb_syntax_ctx syntax_ctx;
    17212692
    17222693        sa = dsdb_attribute_by_lDAPDisplayName(schema, in->name);
     
    17252696        }
    17262697
    1727         return sa->syntax->ldb_to_drsuapi(ldb, schema, sa, in, mem_ctx, out);
    1728 }
     2698        /* use default syntax conversion context */
     2699        dsdb_syntax_ctx_init(&syntax_ctx, ldb, schema);
     2700
     2701        return sa->syntax->ldb_to_drsuapi(&syntax_ctx, sa, in, mem_ctx, out);
     2702}
     2703
Note: See TracChangeset for help on using the changeset viewer.