Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
12 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source4/lib/ldb/common/attrib_handlers.c

    r414 r745  
    33
    44   Copyright (C) Andrew Tridgell  2005
     5   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2006-2009
    56
    67     ** NOTE! The following LGPL license applies to the ldb
     
    5556{
    5657        char *s, *t;
    57         int l;
     58        size_t l;
    5859
    5960        if (!in || !out || !(in->data)) {
     
    100101}
    101102
     103/* length limited conversion of a ldb_val to a int32_t */
     104static int val_to_int64(const struct ldb_val *in, int64_t *v)
     105{
     106        char *end;
     107        char buf[64];
     108
     109        /* make sure we don't read past the end of the data */
     110        if (in->length > sizeof(buf)-1) {
     111                return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
     112        }
     113        strncpy(buf, (char *)in->data, in->length);
     114        buf[in->length] = 0;
     115
     116        /* We've to use "strtoll" here to have the intended overflows.
     117         * Otherwise we may get "LONG_MAX" and the conversion is wrong. */
     118        *v = (int64_t) strtoll(buf, &end, 0);
     119        if (*end != 0) {
     120                return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
     121        }
     122        return LDB_SUCCESS;
     123}
    102124
    103125
     
    109131                                    const struct ldb_val *in, struct ldb_val *out)
    110132{
    111         char *end;
    112         long long i = strtoll((char *)in->data, &end, 0);
    113         if (*end != 0) {
    114                 return -1;
    115         }
    116         out->data = (uint8_t *)talloc_asprintf(mem_ctx, "%lld", i);
     133        int64_t i;
     134        int ret;
     135
     136        ret = val_to_int64(in, &i);
     137        if (ret != LDB_SUCCESS) {
     138                return ret;
     139        }
     140        out->data = (uint8_t *) talloc_asprintf(mem_ctx, "%lld", (long long)i);
    117141        if (out->data == NULL) {
    118                 return -1;
     142                ldb_oom(ldb);
     143                return LDB_ERR_OPERATIONS_ERROR;
    119144        }
    120145        out->length = strlen((char *)out->data);
     
    128153                                  const struct ldb_val *v1, const struct ldb_val *v2)
    129154{
    130         return strtoll((char *)v1->data, NULL, 0) - strtoll((char *)v2->data, NULL, 0);
     155        int64_t i1=0, i2=0;
     156        val_to_int64(v1, &i1);
     157        val_to_int64(v2, &i2);
     158        if (i1 == i2) return 0;
     159        return i1 > i2? 1 : -1;
    131160}
    132161
     
    241270                talloc_free(b1);
    242271                talloc_free(b2);
    243                 if (memcmp(s1, s2, MIN(n1, n2)) == 0) {
     272                ret = memcmp(s1, s2, MIN(n1, n2));
     273                if (ret == 0) {
    244274                        if (n1 == n2) return 0;
    245275                        if (n1 > n2) {
     
    249279                        }
    250280                }
     281                return ret;
    251282        }
    252283
     
    338369                                  const struct ldb_val *v1, const struct ldb_val *v2)
    339370{
    340         time_t t1, t2;
    341         t1 = ldb_string_to_time((char *)v1->data);
    342         t2 = ldb_string_to_time((char *)v2->data);
    343         return (int)t2 - (int)t1;
     371        time_t t1=0, t2=0;
     372        ldb_val_to_time(v1, &t1);
     373        ldb_val_to_time(v2, &t2);
     374        if (t1 == t2) return 0;
     375        return t1 > t2? 1 : -1;
    344376}
    345377
     
    350382                                    const struct ldb_val *in, struct ldb_val *out)
    351383{
    352         time_t t = ldb_string_to_time((char *)in->data);
     384        time_t t;
     385        int ret;
     386        ret = ldb_val_to_time(in, &t);
     387        if (ret != LDB_SUCCESS) {
     388                return ret;
     389        }
    353390        out->data = (uint8_t *)ldb_timestring(mem_ctx, t);
    354391        if (out->data == NULL) {
    355                 return -1;
     392                ldb_oom(ldb);
     393                return LDB_ERR_OPERATIONS_ERROR;
    356394        }
    357395        out->length = strlen((char *)out->data);
     
    421459                                                            const char *syntax)
    422460{
    423         int i;
     461        unsigned int i;
    424462        unsigned num_handlers = sizeof(ldb_standard_syntaxes)/sizeof(ldb_standard_syntaxes[0]);
    425463        /* TODO: should be replaced with a binary search */
     
    431469        return NULL;
    432470}
     471
     472int ldb_any_comparison(struct ldb_context *ldb, void *mem_ctx,
     473                       ldb_attr_handler_t canonicalise_fn,
     474                       const struct ldb_val *v1,
     475                       const struct ldb_val *v2)
     476{
     477        int ret, ret1, ret2;
     478        struct ldb_val v1_canon, v2_canon;
     479        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     480
     481        /* I could try and bail if tmp_ctx was NULL, but what return
     482         * value would I use?
     483         *
     484         * It seems easier to continue on the NULL context
     485         */
     486        ret1 = canonicalise_fn(ldb, tmp_ctx, v1, &v1_canon);
     487        ret2 = canonicalise_fn(ldb, tmp_ctx, v2, &v2_canon);
     488
     489        if (ret1 == LDB_SUCCESS && ret2 == LDB_SUCCESS) {
     490                ret = ldb_comparison_binary(ldb, mem_ctx, &v1_canon, &v2_canon);
     491        } else {
     492                ret = ldb_comparison_binary(ldb, mem_ctx, v1, v2);
     493        }
     494        talloc_free(tmp_ctx);
     495        return ret;
     496}
  • trunk/server/source4/lib/ldb/common/ldb.c

    r414 r745  
    3535#define TEVENT_DEPRECATED 1
    3636#include "ldb_private.h"
     37#include "ldb.h"
    3738
    3839static int ldb_context_destructor(void *ptr)
     
    9293        struct ldb_context *ldb;
    9394        int ret;
     95        const char *modules_path = getenv("LDB_MODULES_PATH");
     96
     97        if (modules_path == NULL) {
     98                modules_path = LDB_MODULESDIR;
     99        }
     100
     101        ret = ldb_modules_load(modules_path, LDB_VERSION);
     102        if (ret != LDB_SUCCESS) {
     103                return NULL;
     104        }
    94105
    95106        ldb = talloc_zero(mem_ctx, struct ldb_context);
    96         /* FIXME: Hack a new event context so that CMD line utilities work
    97          * until we have them all converted */
     107        /* A new event context so that callers who don't want ldb
     108         * operating on thier global event context can work without
     109         * having to provide their own private one explicitly */
    98110        if (ev_ctx == NULL) {
    99                 ev_ctx = tevent_context_init(talloc_autofree_context());
     111                ev_ctx = tevent_context_init(ldb);
    100112                tevent_set_debug(ev_ctx, ldb_tevent_debug, ldb);
    101113                tevent_loop_allow_nesting(ev_ctx);
     
    103115
    104116        ret = ldb_setup_wellknown_attributes(ldb);
    105         if (ret != 0) {
     117        if (ret != LDB_SUCCESS) {
    106118                talloc_free(ldb);
    107119                return NULL;
     
    218230{
    219231        int ret;
    220         const char *url2;
     232        char *url2;
    221233        /* We seem to need to do this here, or else some utilities don't
    222234         * get ldb backends */
     
    229241                return LDB_ERR_OPERATIONS_ERROR;
    230242        }
    231         ret = ldb_set_opaque(ldb, "ldb_url", talloc_strdup(ldb, url2));
     243        ret = ldb_set_opaque(ldb, "ldb_url", url2);
    232244        if (ret != LDB_SUCCESS) {
    233245                return ret;
    234246        }
    235247
    236         ret = ldb_connect_backend(ldb, url, options, &ldb->modules);
     248        ret = ldb_module_connect_backend(ldb, url, options, &ldb->modules);
    237249        if (ret != LDB_SUCCESS) {
    238250                return ret;
     
    286298}
    287299
     300
     301
     302/*
     303  set an ldb error based on file:line
     304*/
     305int ldb_error_at(struct ldb_context *ldb, int ecode,
     306                 const char *reason, const char *file, int line)
     307{
     308        if (reason == NULL) {
     309                reason = ldb_strerror(ecode);
     310        }
     311        ldb_asprintf_errstring(ldb, "%s at %s:%d", reason, file, line);
     312        return ecode;
     313}
     314
     315
    288316#define FIRST_OP_NOERR(ldb, op) do { \
    289317        module = ldb->modules;                                  \
    290318        while (module && module->ops->op == NULL) module = module->next; \
     319        if ((ldb->flags & LDB_FLG_ENABLE_TRACING) && module) { \
     320                ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_trace_request: (%s)->" #op, \
     321                          module->ops->name);                           \
     322        }                                                               \
    291323} while (0)
    292324
     
    336368                }
    337369        }
     370        if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) {
     371                ldb_debug(module->ldb, LDB_DEBUG_TRACE, "start ldb transaction error: %s",
     372                          ldb_errstring(module->ldb));                         
     373        }
    338374        return status;
    339375}
     
    375411                /* if a module fails the prepare then we need
    376412                   to call the end transaction for everyone */
    377                 FIRST_OP(ldb, end_transaction);
    378                 module->ops->end_transaction(module);
     413                FIRST_OP(ldb, del_transaction);
     414                module->ops->del_transaction(module);
    379415                if (ldb->err_string == NULL) {
    380416                        /* no error string was setup by the backend */
     
    383419                                               ldb_strerror(status),
    384420                                               status);
     421                }
     422                if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) {
     423                        ldb_debug(module->ldb, LDB_DEBUG_TRACE, "prepare commit transaction error: %s",
     424                                  ldb_errstring(module->ldb));                         
    385425                }
    386426        }
     
    433473                                status);
    434474                }
     475                if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) {
     476                        ldb_debug(module->ldb, LDB_DEBUG_TRACE, "commit ldb transaction error: %s",
     477                                  ldb_errstring(module->ldb));                         
     478                }
    435479                /* cancel the transaction */
    436480                FIRST_OP(ldb, del_transaction);
     
    478522                                status);
    479523                }
     524                if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) {
     525                        ldb_debug(module->ldb, LDB_DEBUG_TRACE, "cancel ldb transaction error: %s",
     526                                  ldb_errstring(module->ldb));                         
     527                }
    480528        }
    481529        return status;
    482530}
     531
     532/*
     533  cancel a transaction with no error if no transaction is pending
     534  used when we fork() to clear any parent transactions
     535*/
     536int ldb_transaction_cancel_noerr(struct ldb_context *ldb)
     537{
     538        if (ldb->transaction_active > 0) {
     539                return ldb_transaction_cancel(ldb);
     540        }
     541        return LDB_SUCCESS;
     542}
     543
    483544
    484545/* autostarts a transacion if none active */
     
    633694{
    634695        TALLOC_CTX *tmp_ctx = talloc_new(req);
    635         int i;
     696        unsigned int i;
    636697
    637698        switch (req->operation) {
     
    706767        } else {
    707768                for (i=0; req->controls && req->controls[i]; i++) {
    708                         ldb_debug_add(ldb, " control: %s  crit:%u  data:%s\n",
    709                                       req->controls[i]->oid,
    710                                       req->controls[i]->critical,
    711                                       req->controls[i]->data?"yes":"no");
     769                        if (req->controls[i]->oid) {
     770                                ldb_debug_add(ldb, " control: %s  crit:%u  data:%s\n",
     771                                              req->controls[i]->oid,
     772                                              req->controls[i]->critical,
     773                                              req->controls[i]->data?"yes":"no");
     774                        }
    712775                }
    713776        }
     
    716779
    717780        talloc_free(tmp_ctx);
     781}
     782
     783/*
     784  check that the element flags don't have any internal bits set
     785 */
     786static int ldb_msg_check_element_flags(struct ldb_context *ldb,
     787                                       const struct ldb_message *message)
     788{
     789        unsigned i;
     790        for (i=0; i<message->num_elements; i++) {
     791                if (message->elements[i].flags & LDB_FLAG_INTERNAL_MASK) {
     792                        ldb_asprintf_errstring(ldb, "Invalid element flags 0x%08x on element %s in %s\n",
     793                                               message->elements[i].flags, message->elements[i].name,
     794                                               ldb_dn_get_linearized(message->dn));
     795                        return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
     796                }
     797        }
     798        return LDB_SUCCESS;
    718799}
    719800
     
    743824        switch (req->operation) {
    744825        case LDB_SEARCH:
     826                /* due to "ldb_build_search_req" base DN always != NULL */
     827                if (!ldb_dn_validate(req->op.search.base)) {
     828                        ldb_asprintf_errstring(ldb, "ldb_search: invalid basedn '%s'",
     829                                               ldb_dn_get_linearized(req->op.search.base));
     830                        return LDB_ERR_INVALID_DN_SYNTAX;
     831                }
    745832                FIRST_OP(ldb, search);
    746833                ret = module->ops->search(module, req);
    747834                break;
    748835        case LDB_ADD:
     836                if (!ldb_dn_validate(req->op.add.message->dn)) {
     837                        ldb_asprintf_errstring(ldb, "ldb_add: invalid dn '%s'",
     838                                               ldb_dn_get_linearized(req->op.add.message->dn));
     839                        return LDB_ERR_INVALID_DN_SYNTAX;
     840                }
     841                /*
     842                 * we have to normalize here, as so many places
     843                 * in modules and backends assume we don't have two
     844                 * elements with the same name
     845                 */
     846                ret = ldb_msg_normalize(ldb, req, req->op.add.message,
     847                                        discard_const(&req->op.add.message));
     848                if (ret != LDB_SUCCESS) {
     849                        ldb_oom(ldb);
     850                        return LDB_ERR_OPERATIONS_ERROR;
     851                }
    749852                FIRST_OP(ldb, add);
     853                ret = ldb_msg_check_element_flags(ldb, req->op.add.message);
     854                if (ret != LDB_SUCCESS) {
     855                        return ret;
     856                }
    750857                ret = module->ops->add(module, req);
    751858                break;
    752859        case LDB_MODIFY:
     860                if (!ldb_dn_validate(req->op.mod.message->dn)) {
     861                        ldb_asprintf_errstring(ldb, "ldb_modify: invalid dn '%s'",
     862                                               ldb_dn_get_linearized(req->op.mod.message->dn));
     863                        return LDB_ERR_INVALID_DN_SYNTAX;
     864                }
    753865                FIRST_OP(ldb, modify);
     866                ret = ldb_msg_check_element_flags(ldb, req->op.mod.message);
     867                if (ret != LDB_SUCCESS) {
     868                        return ret;
     869                }
    754870                ret = module->ops->modify(module, req);
    755871                break;
    756872        case LDB_DELETE:
     873                if (!ldb_dn_validate(req->op.del.dn)) {
     874                        ldb_asprintf_errstring(ldb, "ldb_delete: invalid dn '%s'",
     875                                               ldb_dn_get_linearized(req->op.del.dn));
     876                        return LDB_ERR_INVALID_DN_SYNTAX;
     877                }
    757878                FIRST_OP(ldb, del);
    758879                ret = module->ops->del(module, req);
    759880                break;
    760881        case LDB_RENAME:
     882                if (!ldb_dn_validate(req->op.rename.olddn)) {
     883                        ldb_asprintf_errstring(ldb, "ldb_rename: invalid olddn '%s'",
     884                                               ldb_dn_get_linearized(req->op.rename.olddn));
     885                        return LDB_ERR_INVALID_DN_SYNTAX;
     886                }
     887                if (!ldb_dn_validate(req->op.rename.newdn)) {
     888                        ldb_asprintf_errstring(ldb, "ldb_rename: invalid newdn '%s'",
     889                                               ldb_dn_get_linearized(req->op.rename.newdn));
     890                        return LDB_ERR_INVALID_DN_SYNTAX;
     891                }
    761892                FIRST_OP(ldb, rename);
    762893                ret = module->ops->rename(module, req);
     
    794925{
    795926        struct ldb_result *res;
    796         int n;
     927        unsigned int n;
    797928
    798929        res = talloc_get_type(req->context, struct ldb_result);
     
    852983}
    853984
    854 int ldb_op_default_callback(struct ldb_request *req, struct ldb_reply *ares)
    855 {
     985int ldb_modify_default_callback(struct ldb_request *req, struct ldb_reply *ares)
     986{
     987        struct ldb_result *res;
     988        unsigned int n;
    856989        int ret;
     990
     991        res = talloc_get_type(req->context, struct ldb_result);
    857992
    858993        if (!ares) {
     
    8661001        }
    8671002
     1003        switch (ares->type) {
     1004        case LDB_REPLY_REFERRAL:
     1005                if (res->refs) {
     1006                        for (n = 0; res->refs[n]; n++) /*noop*/ ;
     1007                } else {
     1008                        n = 0;
     1009                }
     1010
     1011                res->refs = talloc_realloc(res, res->refs, char *, n + 2);
     1012                if (! res->refs) {
     1013                        return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
     1014                }
     1015
     1016                res->refs[n] = talloc_move(res->refs, &ares->referral);
     1017                res->refs[n + 1] = NULL;
     1018                break;
     1019
     1020        case LDB_REPLY_DONE:
     1021                talloc_free(ares);
     1022                return ldb_request_done(req, LDB_SUCCESS);
     1023        default:
     1024                talloc_free(ares);
     1025                ldb_set_errstring(req->handle->ldb, "Invalid reply type!");
     1026                return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
     1027        }
     1028
     1029        talloc_free(ares);
     1030        return ldb_request_done(req, LDB_SUCCESS);
     1031}
     1032
     1033int ldb_op_default_callback(struct ldb_request *req, struct ldb_reply *ares)
     1034{
     1035        int ret;
     1036
     1037        if (!ares) {
     1038                return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
     1039        }
     1040
     1041        if (ares->error != LDB_SUCCESS) {
     1042                ret = ares->error;
     1043                talloc_free(ares);
     1044                return ldb_request_done(req, ret);
     1045        }
     1046
    8681047        if (ares->type != LDB_REPLY_DONE) {
    8691048                talloc_free(ares);
     
    8781057int ldb_build_search_req_ex(struct ldb_request **ret_req,
    8791058                        struct ldb_context *ldb,
    880                         void *mem_ctx,
     1059                        TALLOC_CTX *mem_ctx,
    8811060                        struct ldb_dn *base,
    8821061                        enum ldb_scope scope,
     
    9281107        if (parent) {
    9291108                req->handle->nesting++;
     1109                req->handle->parent = parent;
     1110                req->handle->flags = parent->handle->flags;
    9301111        }
    9311112
     
    9361117int ldb_build_search_req(struct ldb_request **ret_req,
    9371118                        struct ldb_context *ldb,
    938                         void *mem_ctx,
     1119                        TALLOC_CTX *mem_ctx,
    9391120                        struct ldb_dn *base,
    9401121                        enum ldb_scope scope,
     
    9661147int ldb_build_add_req(struct ldb_request **ret_req,
    9671148                        struct ldb_context *ldb,
    968                         void *mem_ctx,
     1149                        TALLOC_CTX *mem_ctx,
    9691150                        const struct ldb_message *message,
    9701151                        struct ldb_control **controls,
     
    9991180        if (parent) {
    10001181                req->handle->nesting++;
     1182                req->handle->parent = parent;
     1183                req->handle->flags = parent->handle->flags;
    10011184        }
    10021185
     
    10081191int ldb_build_mod_req(struct ldb_request **ret_req,
    10091192                        struct ldb_context *ldb,
    1010                         void *mem_ctx,
     1193                        TALLOC_CTX *mem_ctx,
    10111194                        const struct ldb_message *message,
    10121195                        struct ldb_control **controls,
     
    10411224        if (parent) {
    10421225                req->handle->nesting++;
     1226                req->handle->parent = parent;
     1227                req->handle->flags = parent->handle->flags;
    10431228        }
    10441229
     
    10501235int ldb_build_del_req(struct ldb_request **ret_req,
    10511236                        struct ldb_context *ldb,
    1052                         void *mem_ctx,
     1237                        TALLOC_CTX *mem_ctx,
    10531238                        struct ldb_dn *dn,
    10541239                        struct ldb_control **controls,
     
    10831268        if (parent) {
    10841269                req->handle->nesting++;
     1270                req->handle->parent = parent;
     1271                req->handle->flags = parent->handle->flags;
    10851272        }
    10861273
     
    10921279int ldb_build_rename_req(struct ldb_request **ret_req,
    10931280                        struct ldb_context *ldb,
    1094                         void *mem_ctx,
     1281                        TALLOC_CTX *mem_ctx,
    10951282                        struct ldb_dn *olddn,
    10961283                        struct ldb_dn *newdn,
     
    11271314        if (parent) {
    11281315                req->handle->nesting++;
     1316                req->handle->parent = parent;
     1317                req->handle->flags = parent->handle->flags;
    11291318        }
    11301319
     
    11651354int ldb_build_extended_req(struct ldb_request **ret_req,
    11661355                           struct ldb_context *ldb,
    1167                            void *mem_ctx,
     1356                           TALLOC_CTX *mem_ctx,
    11681357                           const char *oid,
    11691358                           void *data,
     
    12001389        if (parent) {
    12011390                req->handle->nesting++;
     1391                req->handle->parent = parent;
     1392                req->handle->flags = parent->handle->flags;
    12021393        }
    12031394
     
    12921483                                        ldb_search_default_callback,
    12931484                                        NULL);
     1485        ldb_req_set_location(req, "ldb_search");
    12941486
    12951487        if (ret != LDB_SUCCESS) goto done;
     
    13351527                                        ldb_op_default_callback,
    13361528                                        NULL);
     1529        ldb_req_set_location(req, "ldb_add");
    13371530
    13381531        if (ret != LDB_SUCCESS) return ret;
     
    13651558                                        ldb_op_default_callback,
    13661559                                        NULL);
     1560        ldb_req_set_location(req, "ldb_modify");
    13671561
    13681562        if (ret != LDB_SUCCESS) return ret;
     
    13901584                                        ldb_op_default_callback,
    13911585                                        NULL);
     1586        ldb_req_set_location(req, "ldb_delete");
    13921587
    13931588        if (ret != LDB_SUCCESS) return ret;
     
    14161611                                        ldb_op_default_callback,
    14171612                                        NULL);
     1613        ldb_req_set_location(req, "ldb_rename");
    14181614
    14191615        if (ret != LDB_SUCCESS) return ret;
     
    16401836        ldb->flags = flags;
    16411837}
     1838
     1839
     1840/*
     1841  set the location in a ldb request. Used for debugging
     1842 */
     1843void ldb_req_set_location(struct ldb_request *req, const char *location)
     1844{
     1845        if (req && req->handle) {
     1846                req->handle->location = location;
     1847        }
     1848}
     1849
     1850/*
     1851  return the location set with dsdb_req_set_location
     1852 */
     1853const char *ldb_req_location(struct ldb_request *req)
     1854{
     1855        return req->handle->location;
     1856}
     1857
     1858/**
     1859  mark a request as untrusted. This tells the rootdse module to remove
     1860  unregistered controls
     1861 */
     1862void ldb_req_mark_untrusted(struct ldb_request *req)
     1863{
     1864        req->handle->flags |= LDB_HANDLE_FLAG_UNTRUSTED;
     1865}
     1866
     1867/**
     1868  mark a request as trusted.
     1869 */
     1870void ldb_req_mark_trusted(struct ldb_request *req)
     1871{
     1872        req->handle->flags &= ~LDB_HANDLE_FLAG_UNTRUSTED;
     1873}
     1874
     1875/**
     1876   return true is a request is untrusted
     1877 */
     1878bool ldb_req_is_untrusted(struct ldb_request *req)
     1879{
     1880        return (req->handle->flags & LDB_HANDLE_FLAG_UNTRUSTED) != 0;
     1881}
  • trunk/server/source4/lib/ldb/common/ldb_attributes.c

    r414 r745  
    5050                                         const struct ldb_schema_syntax *syntax)
    5151{
    52         int i, n;
     52        unsigned int i, n;
    5353        struct ldb_schema_attribute *a;
    5454
     
    123123        const char *name)
    124124{
    125         int i, e, b = 0, r;
     125        /* for binary search we need signed variables */
     126        unsigned int i, e, b = 0;
     127        int r;
    126128        const struct ldb_schema_attribute *def = &ldb_attribute_default;
    127129
     
    135137        e = ldb->schema.num_attributes - 1;
    136138
    137         while (b <= e) {
    138 
     139        while ((b <= e) && (e != (unsigned int) -1)) {
    139140                i = (b + e) / 2;
    140141
     
    148149                        b = i + 1;
    149150                }
    150 
    151151        }
    152152
     
    180180{
    181181        const struct ldb_schema_attribute *a;
    182         int i;
     182        ptrdiff_t i;
    183183
    184184        a = ldb_schema_attribute_by_name_internal(ldb, name);
     
    233233                { "objectClass", LDB_SYNTAX_OBJECTCLASS }
    234234        };
    235         int i;
     235        unsigned int i;
    236236        int ret;
    237237
     
    255255                               const struct ldb_dn_extended_syntax *syntax)
    256256{
    257         int n;
     257        unsigned int n;
    258258        struct ldb_dn_extended_syntax *a;
    259259
     
    285285                                                                    const char *name)
    286286{
    287         int i;
     287        unsigned int i;
    288288        for (i=0; i < ldb->schema.num_dn_extended_syntax; i++) {
    289289                if (ldb_attr_cmp(ldb->schema.dn_extended_syntax[i].name, name) == 0) {
  • trunk/server/source4/lib/ldb/common/ldb_controls.c

    r414 r745  
    3838struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char *oid)
    3939{
    40         int i;
     40        unsigned int i;
    4141
    4242        if (req->controls != NULL) {
    4343                for (i = 0; req->controls[i]; i++) {
    44                         if (strcmp(oid, req->controls[i]->oid) == 0) {
     44                        if (req->controls[i]->oid && strcmp(oid, req->controls[i]->oid) == 0) {
    4545                                break;
    4646                        }
     
    5757struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid)
    5858{
    59         int i;
     59        unsigned int i;
    6060
    6161        if (rep->controls != NULL) {
    6262                for (i = 0; rep->controls[i]; i++) {
    63                         if (strcmp(oid, rep->controls[i]->oid) == 0) {
     63                        if (rep->controls[i]->oid && strcmp(oid, rep->controls[i]->oid) == 0) {
    6464                                break;
    6565                        }
     
    7272}
    7373
    74 /* saves the current controls list into the "saver" and replace the one in req with a new one excluding
    75 the "exclude" control */
    76 /* returns 0 on error */
    77 int save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver)
     74/*
     75 * Saves the current controls list into the "saver" (can also be NULL) and
     76 * replace the one in "req" with a new one excluding the "exclude" control
     77 * (if it is NULL then the list remains the same)
     78 *
     79 * Returns 0 on error.
     80 */
     81int ldb_save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver)
    7882{
    79         struct ldb_control **lcs;
    80         int i, j;
    81 
    82         *saver = req->controls;
    83         for (i = 0; req->controls[i]; i++);
    84         if (i == 1) {
     83        struct ldb_control **lcs, **lcs_old;
     84        unsigned int i, j;
     85
     86        lcs_old = req->controls;
     87        if (saver != NULL) {
     88                *saver = lcs_old;
     89        }
     90
     91        for (i = 0; req->controls && req->controls[i]; i++);
     92        if (i == 0) {
    8593                req->controls = NULL;
    8694                return 1;
    8795        }
    8896
    89         lcs = talloc_array(req, struct ldb_control *, i);
     97        lcs = talloc_array(req, struct ldb_control *, i + 1);
    9098        if (!lcs) {
    9199                return 0;
    92100        }
    93101
    94         for (i = 0, j = 0; (*saver)[i]; i++) {
    95                 if (exclude == (*saver)[i]) continue;
    96                 lcs[j] = (*saver)[i];
     102        for (i = 0, j = 0; lcs_old[i]; i++) {
     103                if (exclude == lcs_old[i]) continue;
     104                lcs[j] = lcs_old[i];
    97105                j++;
    98106        }
    99107        lcs[j] = NULL;
    100108
    101         req->controls = lcs;
     109        req->controls = talloc_realloc(req, lcs, struct ldb_control *, j + 1);
     110        if (req->controls == NULL) {
     111                return 0;
     112        }
    102113        return 1;
    103114}
    104115
     116/*
     117 * Returns a list of controls, except the one specified with "exclude" (can
     118 * also be NULL).  Included controls become a child of returned list if they
     119 * were children of "controls_in".
     120 *
     121 * Returns NULL on error (OOM) or an empty control list.
     122 */
     123struct ldb_control **ldb_controls_except_specified(struct ldb_control **controls_in,
     124                                               TALLOC_CTX *mem_ctx,
     125                                               struct ldb_control *exclude)
     126{
     127        struct ldb_control **lcs = NULL;
     128        unsigned int i, j, n;
     129
     130        for (i = 0; controls_in && controls_in[i]; i++);
     131        if (i == 0) {
     132                return NULL;
     133        }
     134        n = i;
     135
     136        for (i = 0, j = 0; controls_in && controls_in[i]; i++) {
     137                if (exclude == controls_in[i]) continue;
     138
     139                if (!lcs) {
     140                        /* Allocate here so if we remove the only
     141                         * control, or there were no controls, we
     142                         * don't allocate at all, and just return
     143                         * NULL */
     144                        lcs = talloc_array(mem_ctx, struct ldb_control *,
     145                                           n + 1);
     146                        if (!lcs) {
     147                                return NULL;
     148                        }
     149                }
     150
     151                lcs[j] = controls_in[i];
     152                talloc_reparent(controls_in, lcs, lcs[j]);
     153                j++;
     154        }
     155        if (lcs) {
     156                lcs[j] = NULL;
     157
     158                lcs = talloc_realloc(mem_ctx, lcs, struct ldb_control *, j + 1);
     159        }
     160
     161        return lcs;
     162}
     163
    105164/* check if there's any control marked as critical in the list */
    106165/* return True if any, False if none */
    107 int check_critical_controls(struct ldb_control **controls)
     166int ldb_check_critical_controls(struct ldb_control **controls)
    108167{
    109         int i;
     168        unsigned int i;
    110169
    111170        if (controls == NULL) {
     
    123182
    124183int ldb_request_add_control(struct ldb_request *req, const char *oid, bool critical, void *data)
     184{
     185        unsigned int i, n;
     186        struct ldb_control **ctrls;
     187        struct ldb_control *ctrl;
     188
     189        for (n=0; req->controls && req->controls[n];n++) {
     190                /* having two controls of the same OID makes no sense */
     191                if (req->controls[n]->oid && strcmp(oid, req->controls[n]->oid) == 0) {
     192                        return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
     193                }
     194        }
     195
     196        ctrls = talloc_array(req,
     197                               struct ldb_control *,
     198                               n + 2);
     199        if (!ctrls) return LDB_ERR_OPERATIONS_ERROR;
     200
     201        for (i=0; i<n; i++) {
     202                ctrls[i] = req->controls[i];
     203        }
     204
     205        req->controls = ctrls;
     206        ctrls[n] = NULL;
     207        ctrls[n+1] = NULL;
     208
     209        ctrl = talloc(ctrls, struct ldb_control);
     210        if (!ctrl) return LDB_ERR_OPERATIONS_ERROR;
     211
     212        ctrl->oid       = talloc_strdup(ctrl, oid);
     213        if (!ctrl->oid) return LDB_ERR_OPERATIONS_ERROR;
     214        ctrl->critical  = critical;
     215        ctrl->data      = data;
     216
     217        ctrls[n] = ctrl;
     218        return LDB_SUCCESS;
     219}
     220
     221int ldb_reply_add_control(struct ldb_reply *ares, const char *oid, bool critical, void *data)
    125222{
    126223        unsigned n;
     
    128225        struct ldb_control *ctrl;
    129226
    130         for (n=0; req->controls && req->controls[n];) {
     227        for (n=0; ares->controls && ares->controls[n];) {
    131228                /* having two controls of the same OID makes no sense */
    132                 if (strcmp(oid, req->controls[n]->oid) == 0) {
     229                if (ares->controls[n]->oid && strcmp(oid, ares->controls[n]->oid) == 0) {
    133230                        return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
    134231                }
     
    136233        }
    137234
    138         ctrls = talloc_realloc(req, req->controls,
     235        ctrls = talloc_realloc(ares, ares->controls,
    139236                               struct ldb_control *,
    140237                               n + 2);
    141238        if (!ctrls) return LDB_ERR_OPERATIONS_ERROR;
    142         req->controls = ctrls;
     239        ares->controls = ctrls;
    143240        ctrls[n] = NULL;
    144241        ctrls[n+1] = NULL;
     
    156253}
    157254
    158 /* Parse controls from the format used on the command line and in ejs */
    159 
    160 struct ldb_control **ldb_parse_control_strings(struct ldb_context *ldb, void *mem_ctx, const char **control_strings)
     255/* Add a control to the request, replacing the old one if it is already in the request */
     256int ldb_request_replace_control(struct ldb_request *req, const char *oid, bool critical, void *data)
    161257{
    162         int i;
    163         struct ldb_control **ctrl;
    164 
     258        unsigned int n;
     259        int ret;
     260
     261        ret = ldb_request_add_control(req, oid, critical, data);
     262        if (ret != LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) {
     263                return ret;
     264        }
     265
     266        for (n=0; req->controls[n];n++) {
     267                if (req->controls[n]->oid && strcmp(oid, req->controls[n]->oid) == 0) {
     268                        req->controls[n]->critical = critical;
     269                        req->controls[n]->data = data;
     270                        return LDB_SUCCESS;
     271                }
     272        }
     273
     274        return LDB_ERR_OPERATIONS_ERROR;
     275}
     276
     277/*
     278 * Return a control as string
     279 * the project (ie. name:value1:value2:...:valuen
     280 * The string didn't include the criticity of the critical flag
     281 */
     282char *ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *control)
     283{
     284        char *res = NULL;
     285
     286        if (strcmp(control->oid, LDB_CONTROL_PAGED_RESULTS_OID) == 0) {
     287                struct ldb_paged_control *rep_control = talloc_get_type(control->data, struct ldb_paged_control);
     288                char *cookie;
     289
     290                cookie = ldb_base64_encode(mem_ctx, rep_control->cookie, rep_control->cookie_len);
     291                if (cookie == NULL) {
     292                        return NULL;
     293                }
     294                if (cookie[0] != '\0') {
     295                        res = talloc_asprintf(mem_ctx, "%s:%d:%s",
     296                                                LDB_CONTROL_PAGED_RESULTS_NAME,
     297                                                control->critical,
     298                                                cookie);
     299
     300                        talloc_free(cookie);
     301                } else {
     302                        res = talloc_asprintf(mem_ctx, "%s:%d",
     303                                                LDB_CONTROL_PAGED_RESULTS_NAME,
     304                                                control->critical);
     305                }
     306                return res;
     307        }
     308
     309        if (strcmp(control->oid, LDB_CONTROL_VLV_RESP_OID) == 0) {
     310                struct ldb_vlv_resp_control *rep_control = talloc_get_type(control->data,
     311                                                                struct ldb_vlv_resp_control);
     312
     313                res = talloc_asprintf(mem_ctx, "%s:%d:%d:%d:%d:%d:%s",
     314                                                LDB_CONTROL_VLV_RESP_NAME,
     315                                                control->critical,
     316                                                rep_control->targetPosition,
     317                                                rep_control->contentCount,
     318                                                rep_control->vlv_result,
     319                                                rep_control->ctxid_len,
     320                                                rep_control->contextId);
     321
     322                return res;
     323        }
     324
     325        if (strcmp(control->oid, LDB_CONTROL_SORT_RESP_OID) == 0) {
     326                struct ldb_sort_resp_control *rep_control = talloc_get_type(control->data,
     327                                                                struct ldb_sort_resp_control);
     328
     329                res = talloc_asprintf(mem_ctx, "%s:%d:%d:%s",
     330                                        LDB_CONTROL_SORT_RESP_NAME,
     331                                        control->critical,
     332                                        rep_control->result,
     333                                        rep_control->attr_desc);
     334
     335                return res;
     336        }
     337
     338        if (strcmp(control->oid, LDB_CONTROL_ASQ_OID) == 0) {
     339                struct ldb_asq_control *rep_control = talloc_get_type(control->data,
     340                                                                struct ldb_asq_control);
     341
     342                res = talloc_asprintf(mem_ctx, "%s:%d:%d",
     343                                        LDB_CONTROL_SORT_RESP_NAME,
     344                                        control->critical,
     345                                        rep_control->result);
     346
     347                return res;
     348        }
     349
     350        if (strcmp(control->oid, LDB_CONTROL_DIRSYNC_OID) == 0) {
     351                char *cookie;
     352                struct ldb_dirsync_control *rep_control = talloc_get_type(control->data,
     353                                                                struct ldb_dirsync_control);
     354
     355                cookie = ldb_base64_encode(mem_ctx, rep_control->cookie,
     356                                rep_control->cookie_len);
     357                if (cookie == NULL) {
     358                        return NULL;
     359                }
     360                res = talloc_asprintf(mem_ctx, "%s:%d:%d:%d:%s",
     361                                        LDB_CONTROL_DIRSYNC_NAME,
     362                                        control->critical,
     363                                        rep_control->flags,
     364                                        rep_control->max_attributes,
     365                                        cookie);
     366
     367                talloc_free(cookie);
     368                return res;
     369        }
     370
     371        /*
     372         * From here we don't know the control
     373         */
     374        if (control->data == NULL) {
     375                /*
     376                 * We don't know the control but there is no real data attached to it
     377                 * so we can represent it with local_oid:oid:criticity
     378                 */
     379                res = talloc_asprintf(mem_ctx, "local_oid:%s:%d",
     380                                        control->oid,
     381                                        control->critical);
     382                return res;
     383        }
     384
     385                res = talloc_asprintf(mem_ctx, "unknown oid:%s",
     386                                        control->oid);
     387        return res;
     388}
     389
     390
     391/*
     392 * A little trick to allow to use constants defined in headers rather than
     393 * hardwritten in the file hardwritten in the file
     394 * sizeof will return the \0 char as well so it will take the place of ":" in the
     395 * length of the string
     396 */
     397#define LDB_CONTROL_CMP(control, NAME) strncmp(control, NAME ":", sizeof(NAME))
     398
     399/* Parse one string and return associated control if parsing is successful*/
     400struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *control_strings)
     401{
     402        struct ldb_control *ctrl;
    165403        char *error_string = NULL;
    166404
    167         if (control_strings == NULL || control_strings[0] == NULL)
     405        if (!(ctrl = talloc(mem_ctx, struct ldb_control))) {
     406                ldb_oom(ldb);
    168407                return NULL;
    169 
    170         for (i = 0; control_strings[i]; i++);
    171 
    172         ctrl = talloc_array(mem_ctx, struct ldb_control *, i + 1);
    173 
    174         for (i = 0; control_strings[i]; i++) {
    175                 if (strncmp(control_strings[i], "vlv:", 4) == 0) {
    176                         struct ldb_vlv_req_control *control;
    177                         const char *p;
    178                         char attr[1024];
    179                         char ctxid[1024];
    180                         int crit, bc, ac, os, cc, ret;
    181 
    182                         attr[0] = '\0';
    183                         ctxid[0] = '\0';
    184                         p = &(control_strings[i][4]);
    185                         ret = sscanf(p, "%d:%d:%d:%d:%d:%1023[^$]", &crit, &bc, &ac, &os, &cc, ctxid);
    186                         if (ret < 5) {
    187                                 ret = sscanf(p, "%d:%d:%d:%1023[^:]:%1023[^$]", &crit, &bc, &ac, attr, ctxid);
    188                         }
    189                                
    190                         if ((ret < 4) || (crit < 0) || (crit > 1)) {
    191                                 error_string = talloc_asprintf(mem_ctx, "invalid server_sort control syntax\n");
    192                                 error_string = talloc_asprintf_append(error_string, " syntax: crit(b):bc(n):ac(n):<os(n):cc(n)|attr(s)>[:ctxid(o)]\n");
    193                                 error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number, s = string, o = b64 binary blob");
     408        }
     409
     410        if (LDB_CONTROL_CMP(control_strings,
     411                                LDB_CONTROL_VLV_REQ_NAME) == 0) {
     412                struct ldb_vlv_req_control *control;
     413                const char *p;
     414                char attr[1024];
     415                char ctxid[1024];
     416                int crit, bc, ac, os, cc, ret;
     417
     418                attr[0] = '\0';
     419                ctxid[0] = '\0';
     420                p = &(control_strings[sizeof(LDB_CONTROL_VLV_REQ_NAME)]);
     421                ret = sscanf(p, "%d:%d:%d:%d:%d:%1023[^$]", &crit, &bc, &ac, &os, &cc, ctxid);
     422                if (ret < 5) {
     423                        ret = sscanf(p, "%d:%d:%d:%1023[^:]:%1023[^$]", &crit, &bc, &ac, attr, ctxid);
     424                }
     425                       
     426                if ((ret < 4) || (crit < 0) || (crit > 1)) {
     427                        error_string = talloc_asprintf(mem_ctx, "invalid server_sort control syntax\n");
     428                        error_string = talloc_asprintf_append(error_string, " syntax: crit(b):bc(n):ac(n):<os(n):cc(n)|attr(s)>[:ctxid(o)]\n");
     429                        error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number, s = string, o = b64 binary blob");
     430                        ldb_set_errstring(ldb, error_string);
     431                        talloc_free(error_string);
     432                        return NULL;
     433                }
     434                ctrl->oid = LDB_CONTROL_VLV_REQ_OID;
     435                ctrl->critical = crit;
     436                if (!(control = talloc(ctrl,
     437                                        struct ldb_vlv_req_control))) {
     438                        ldb_oom(ldb);
     439                        return NULL;
     440                }
     441                control->beforeCount = bc;
     442                control->afterCount = ac;
     443                if (attr[0]) {
     444                        control->type = 1;
     445                        control->match.gtOrEq.value = talloc_strdup(control, attr);
     446                        control->match.gtOrEq.value_len = strlen(attr);
     447                } else {
     448                        control->type = 0;
     449                        control->match.byOffset.offset = os;
     450                        control->match.byOffset.contentCount = cc;
     451                }
     452                if (ctxid[0]) {
     453                        control->ctxid_len = ldb_base64_decode(ctxid);
     454                        control->contextId = (char *)talloc_memdup(control, ctxid, control->ctxid_len);
     455                } else {
     456                        control->ctxid_len = 0;
     457                        control->contextId = NULL;
     458                }
     459                ctrl->data = control;
     460
     461                return ctrl;
     462        }
     463
     464        if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DIRSYNC_NAME) == 0) {
     465                struct ldb_dirsync_control *control;
     466                const char *p;
     467                char cookie[1024];
     468                int crit, flags, max_attrs, ret;
     469               
     470                cookie[0] = '\0';
     471                p = &(control_strings[sizeof(LDB_CONTROL_DIRSYNC_NAME)]);
     472                ret = sscanf(p, "%d:%d:%d:%1023[^$]", &crit, &flags, &max_attrs, cookie);
     473
     474                if ((ret < 3) || (crit < 0) || (crit > 1) || (flags < 0) || (max_attrs < 0)) {
     475                        error_string = talloc_asprintf(mem_ctx, "invalid dirsync control syntax\n");
     476                        error_string = talloc_asprintf_append(error_string, " syntax: crit(b):flags(n):max_attrs(n)[:cookie(o)]\n");
     477                        error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number, o = b64 binary blob");
     478                        ldb_set_errstring(ldb, error_string);
     479                        talloc_free(error_string);
     480                        return NULL;
     481                }
     482
     483                /* w2k3 seems to ignore the parameter,
     484                        * but w2k sends a wrong cookie when this value is to small
     485                        * this would cause looping forever, while getting
     486                        * the same data and same cookie forever
     487                        */
     488                if (max_attrs == 0) max_attrs = 0x0FFFFFFF;
     489
     490                ctrl->oid = LDB_CONTROL_DIRSYNC_OID;
     491                ctrl->critical = crit;
     492                control = talloc(ctrl, struct ldb_dirsync_control);
     493                control->flags = flags;
     494                control->max_attributes = max_attrs;
     495                if (*cookie) {
     496                        control->cookie_len = ldb_base64_decode(cookie);
     497                        control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len);
     498                } else {
     499                        control->cookie = NULL;
     500                        control->cookie_len = 0;
     501                }
     502                ctrl->data = control;
     503
     504                return ctrl;
     505        }
     506
     507        if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_ASQ_NAME) == 0) {
     508                struct ldb_asq_control *control;
     509                const char *p;
     510                char attr[256];
     511                int crit, ret;
     512
     513                attr[0] = '\0';
     514                p = &(control_strings[sizeof(LDB_CONTROL_ASQ_NAME)]);
     515                ret = sscanf(p, "%d:%255[^$]", &crit, attr);
     516                if ((ret != 2) || (crit < 0) || (crit > 1) || (attr[0] == '\0')) {
     517                        error_string = talloc_asprintf(mem_ctx, "invalid asq control syntax\n");
     518                        error_string = talloc_asprintf_append(error_string, " syntax: crit(b):attr(s)\n");
     519                        error_string = talloc_asprintf_append(error_string, "   note: b = boolean, s = string");
     520                        ldb_set_errstring(ldb, error_string);
     521                        talloc_free(error_string);
     522                        return NULL;
     523                }
     524
     525                ctrl->oid = LDB_CONTROL_ASQ_OID;
     526                ctrl->critical = crit;
     527                control = talloc(ctrl, struct ldb_asq_control);
     528                control->request = 1;
     529                control->source_attribute = talloc_strdup(control, attr);
     530                control->src_attr_len = strlen(attr);
     531                ctrl->data = control;
     532
     533                return ctrl;
     534        }
     535
     536        if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_EXTENDED_DN_NAME) == 0) {
     537                struct ldb_extended_dn_control *control;
     538                const char *p;
     539                int crit, type, ret;
     540
     541                p = &(control_strings[sizeof(LDB_CONTROL_EXTENDED_DN_NAME)]);
     542                ret = sscanf(p, "%d:%d", &crit, &type);
     543                if ((ret != 2) || (crit < 0) || (crit > 1) || (type < 0) || (type > 1)) {
     544                        ret = sscanf(p, "%d", &crit);
     545                        if ((ret != 1) || (crit < 0) || (crit > 1)) {
     546                                error_string = talloc_asprintf(mem_ctx, "invalid extended_dn control syntax\n");
     547                                error_string = talloc_asprintf_append(error_string, " syntax: crit(b)[:type(i)]\n");
     548                                error_string = talloc_asprintf_append(error_string, "   note: b = boolean\n");
     549                                error_string = talloc_asprintf_append(error_string, "         i = integer\n");
     550                                error_string = talloc_asprintf_append(error_string, "   valid values are: 0 - hexadecimal representation\n");
     551                                error_string = talloc_asprintf_append(error_string, "                     1 - normal string representation");
    194552                                ldb_set_errstring(ldb, error_string);
    195553                                talloc_free(error_string);
    196554                                return NULL;
    197555                        }
    198                         if (!(ctrl[i] = talloc(ctrl, struct ldb_control))) {
    199                                 ldb_oom(ldb);
    200                                 return NULL;
     556                        control = NULL;
     557                } else {
     558                        control = talloc(ctrl, struct ldb_extended_dn_control);
     559                        control->type = type;
     560                }
     561
     562                ctrl->oid = LDB_CONTROL_EXTENDED_DN_OID;
     563                ctrl->critical = crit;
     564                ctrl->data = talloc_steal(ctrl, control);
     565
     566                return ctrl;
     567        }
     568
     569        if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SD_FLAGS_NAME) == 0) {
     570                struct ldb_sd_flags_control *control;
     571                const char *p;
     572                int crit, ret;
     573                unsigned secinfo_flags;
     574
     575                p = &(control_strings[sizeof(LDB_CONTROL_SD_FLAGS_NAME)]);
     576                ret = sscanf(p, "%d:%u", &crit, &secinfo_flags);
     577                if ((ret != 2) || (crit < 0) || (crit > 1) || (secinfo_flags < 0) || (secinfo_flags > 0xF)) {
     578                        error_string = talloc_asprintf(mem_ctx, "invalid sd_flags control syntax\n");
     579                        error_string = talloc_asprintf_append(error_string, " syntax: crit(b):secinfo_flags(n)\n");
     580                        error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number");
     581                        ldb_set_errstring(ldb, error_string);
     582                        talloc_free(error_string);
     583                        return NULL;
     584                }
     585
     586                ctrl->oid = LDB_CONTROL_SD_FLAGS_OID;
     587                ctrl->critical = crit;
     588                control = talloc(ctrl, struct ldb_sd_flags_control);
     589                control->secinfo_flags = secinfo_flags;
     590                ctrl->data = control;
     591
     592                return ctrl;
     593        }
     594
     595        if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SEARCH_OPTIONS_NAME) == 0) {
     596                struct ldb_search_options_control *control;
     597                const char *p;
     598                int crit, ret;
     599                unsigned search_options;
     600
     601                p = &(control_strings[sizeof(LDB_CONTROL_SEARCH_OPTIONS_NAME)]);
     602                ret = sscanf(p, "%d:%u", &crit, &search_options);
     603                if ((ret != 2) || (crit < 0) || (crit > 1) || (search_options < 0) || (search_options > 0xF)) {
     604                        error_string = talloc_asprintf(mem_ctx, "invalid search_options control syntax\n");
     605                        error_string = talloc_asprintf_append(error_string, " syntax: crit(b):search_options(n)\n");
     606                        error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number");
     607                        ldb_set_errstring(ldb, error_string);
     608                        talloc_free(error_string);
     609                        return NULL;
     610                }
     611
     612                ctrl->oid = LDB_CONTROL_SEARCH_OPTIONS_OID;
     613                ctrl->critical = crit;
     614                control = talloc(ctrl, struct ldb_search_options_control);
     615                control->search_options = search_options;
     616                ctrl->data = control;
     617
     618                return ctrl;
     619        }
     620
     621        if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_BYPASS_OPERATIONAL_NAME) == 0) {
     622                const char *p;
     623                int crit, ret;
     624
     625                p = &(control_strings[sizeof(LDB_CONTROL_BYPASS_OPERATIONAL_NAME)]);
     626                ret = sscanf(p, "%d", &crit);
     627                if ((ret != 1) || (crit < 0) || (crit > 1)) {
     628                        error_string = talloc_asprintf(mem_ctx, "invalid bypassopreational control syntax\n");
     629                        error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
     630                        error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
     631                        ldb_set_errstring(ldb, error_string);
     632                        talloc_free(error_string);
     633                        return NULL;
     634                }
     635
     636                ctrl->oid = LDB_CONTROL_BYPASS_OPERATIONAL_OID;
     637                ctrl->critical = crit;
     638                ctrl->data = NULL;
     639
     640                return ctrl;
     641        }
     642
     643        if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_RELAX_NAME) == 0) {
     644                const char *p;
     645                int crit, ret;
     646
     647                p = &(control_strings[sizeof(LDB_CONTROL_RELAX_NAME)]);
     648                ret = sscanf(p, "%d", &crit);
     649                if ((ret != 1) || (crit < 0) || (crit > 1)) {
     650                        error_string = talloc_asprintf(mem_ctx, "invalid relax control syntax\n");
     651                        error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
     652                        error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
     653                        ldb_set_errstring(ldb, error_string);
     654                        talloc_free(error_string);
     655                        return NULL;
     656                }
     657
     658                ctrl->oid = LDB_CONTROL_RELAX_OID;
     659                ctrl->critical = crit;
     660                ctrl->data = NULL;
     661
     662                return ctrl;
     663        }
     664
     665        if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_RECALCULATE_SD_NAME) == 0) {
     666                const char *p;
     667                int crit, ret;
     668
     669                p = &(control_strings[sizeof(LDB_CONTROL_RECALCULATE_SD_NAME)]);
     670                ret = sscanf(p, "%d", &crit);
     671                if ((ret != 1) || (crit < 0) || (crit > 1)) {
     672                        error_string = talloc_asprintf(mem_ctx, "invalid recalculate_sd control syntax\n");
     673                        error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
     674                        error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
     675                        ldb_set_errstring(ldb, error_string);
     676                        talloc_free(error_string);
     677                        return NULL;
     678                }
     679
     680                ctrl->oid = LDB_CONTROL_RECALCULATE_SD_OID;
     681                ctrl->critical = crit;
     682                ctrl->data = NULL;
     683
     684                return ctrl;
     685        }
     686
     687        if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DOMAIN_SCOPE_NAME) == 0) {
     688                const char *p;
     689                int crit, ret;
     690
     691                p = &(control_strings[sizeof(LDB_CONTROL_DOMAIN_SCOPE_NAME)]);
     692                ret = sscanf(p, "%d", &crit);
     693                if ((ret != 1) || (crit < 0) || (crit > 1)) {
     694                        error_string = talloc_asprintf(mem_ctx, "invalid domain_scope control syntax\n");
     695                        error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
     696                        error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
     697                        ldb_set_errstring(ldb, error_string);
     698                        talloc_free(error_string);
     699                        return NULL;
     700                }
     701
     702                ctrl->oid = LDB_CONTROL_DOMAIN_SCOPE_OID;
     703                ctrl->critical = crit;
     704                ctrl->data = NULL;
     705
     706                return ctrl;
     707        }
     708
     709        if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_PAGED_RESULTS_NAME) == 0) {
     710                struct ldb_paged_control *control;
     711                const char *p;
     712                int crit, size, ret;
     713               
     714                p = &(control_strings[sizeof(LDB_CONTROL_PAGED_RESULTS_NAME)]);
     715                ret = sscanf(p, "%d:%d", &crit, &size);
     716                if ((ret != 2) || (crit < 0) || (crit > 1) || (size < 0)) {
     717                        error_string = talloc_asprintf(mem_ctx, "invalid paged_results control syntax\n");
     718                        error_string = talloc_asprintf_append(error_string, " syntax: crit(b):size(n)\n");
     719                        error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number");
     720                        ldb_set_errstring(ldb, error_string);
     721                        talloc_free(error_string);
     722                        return NULL;
     723                }
     724
     725                ctrl->oid = LDB_CONTROL_PAGED_RESULTS_OID;
     726                ctrl->critical = crit;
     727                control = talloc(ctrl, struct ldb_paged_control);
     728                control->size = size;
     729                control->cookie = NULL;
     730                control->cookie_len = 0;
     731                ctrl->data = control;
     732
     733                return ctrl;
     734        }
     735
     736        if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SERVER_SORT_NAME) == 0) {
     737                struct ldb_server_sort_control **control;
     738                const char *p;
     739                char attr[256];
     740                char rule[128];
     741                int crit, rev, ret;
     742
     743                attr[0] = '\0';
     744                rule[0] = '\0';
     745                p = &(control_strings[sizeof(LDB_CONTROL_SERVER_SORT_NAME)]);
     746                ret = sscanf(p, "%d:%d:%255[^:]:%127[^:]", &crit, &rev, attr, rule);
     747                if ((ret < 3) || (crit < 0) || (crit > 1) || (rev < 0 ) || (rev > 1) ||attr[0] == '\0') {
     748                        error_string = talloc_asprintf(mem_ctx, "invalid server_sort control syntax\n");
     749                        error_string = talloc_asprintf_append(error_string, " syntax: crit(b):rev(b):attr(s)[:rule(s)]\n");
     750                        error_string = talloc_asprintf_append(error_string, "   note: b = boolean, s = string");
     751                        ldb_set_errstring(ldb, error_string);
     752                        talloc_free(error_string);
     753                        return NULL;
     754                }
     755                ctrl->oid = LDB_CONTROL_SERVER_SORT_OID;
     756                ctrl->critical = crit;
     757                control = talloc_array(ctrl, struct ldb_server_sort_control *, 2);
     758                control[0] = talloc(control, struct ldb_server_sort_control);
     759                control[0]->attributeName = talloc_strdup(control, attr);
     760                if (rule[0])
     761                        control[0]->orderingRule = talloc_strdup(control, rule);
     762                else
     763                        control[0]->orderingRule = NULL;
     764                control[0]->reverse = rev;
     765                control[1] = NULL;
     766                ctrl->data = control;
     767
     768                return ctrl;
     769        }
     770
     771        if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_NOTIFICATION_NAME) == 0) {
     772                const char *p;
     773                int crit, ret;
     774
     775                p = &(control_strings[sizeof(LDB_CONTROL_NOTIFICATION_NAME)]);
     776                ret = sscanf(p, "%d", &crit);
     777                if ((ret != 1) || (crit < 0) || (crit > 1)) {
     778                        error_string = talloc_asprintf(mem_ctx, "invalid notification control syntax\n");
     779                        error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
     780                        error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
     781                        ldb_set_errstring(ldb, error_string);
     782                        talloc_free(error_string);
     783                        return NULL;
     784                }
     785
     786                ctrl->oid = LDB_CONTROL_NOTIFICATION_OID;
     787                ctrl->critical = crit;
     788                ctrl->data = NULL;
     789
     790                return ctrl;
     791        }
     792
     793        if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_TREE_DELETE_NAME) == 0) {
     794                const char *p;
     795                int crit, ret;
     796
     797                p = &(control_strings[sizeof(LDB_CONTROL_TREE_DELETE_NAME)]);
     798                ret = sscanf(p, "%d", &crit);
     799                if ((ret != 1) || (crit < 0) || (crit > 1)) {
     800                        error_string = talloc_asprintf(mem_ctx, "invalid tree_delete control syntax\n");
     801                        error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
     802                        error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
     803                        ldb_set_errstring(ldb, error_string);
     804                        talloc_free(error_string);
     805                        return NULL;
     806                }
     807
     808                ctrl->oid = LDB_CONTROL_TREE_DELETE_OID;
     809                ctrl->critical = crit;
     810                ctrl->data = NULL;
     811
     812                return ctrl;
     813        }
     814
     815        if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SHOW_DELETED_NAME) == 0) {
     816                const char *p;
     817                int crit, ret;
     818
     819                p = &(control_strings[sizeof(LDB_CONTROL_SHOW_DELETED_NAME)]);
     820                ret = sscanf(p, "%d", &crit);
     821                if ((ret != 1) || (crit < 0) || (crit > 1)) {
     822                        error_string = talloc_asprintf(mem_ctx, "invalid show_deleted control syntax\n");
     823                        error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
     824                        error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
     825                        ldb_set_errstring(ldb, error_string);
     826                        talloc_free(error_string);
     827                        return NULL;
     828                }
     829
     830                ctrl->oid = LDB_CONTROL_SHOW_DELETED_OID;
     831                ctrl->critical = crit;
     832                ctrl->data = NULL;
     833
     834                return ctrl;
     835        }
     836
     837        if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SHOW_DEACTIVATED_LINK_NAME) == 0) {
     838                const char *p;
     839                int crit, ret;
     840
     841                p = &(control_strings[sizeof(LDB_CONTROL_SHOW_DEACTIVATED_LINK_NAME)]);
     842                ret = sscanf(p, "%d", &crit);
     843                if ((ret != 1) || (crit < 0) || (crit > 1)) {
     844                        error_string = talloc_asprintf(mem_ctx, "invalid show_deactivated_link control syntax\n");
     845                        error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
     846                        error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
     847                        ldb_set_errstring(ldb, error_string);
     848                        talloc_free(error_string);
     849                        return NULL;
     850                }
     851
     852                ctrl->oid = LDB_CONTROL_SHOW_DEACTIVATED_LINK_OID;
     853                ctrl->critical = crit;
     854                ctrl->data = NULL;
     855
     856                return ctrl;
     857        }
     858
     859        if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SHOW_RECYCLED_NAME) == 0) {
     860                const char *p;
     861                int crit, ret;
     862
     863                p = &(control_strings[sizeof(LDB_CONTROL_SHOW_RECYCLED_NAME)]);
     864                ret = sscanf(p, "%d", &crit);
     865                if ((ret != 1) || (crit < 0) || (crit > 1)) {
     866                        error_string = talloc_asprintf(mem_ctx, "invalid show_recycled control syntax\n");
     867                        error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
     868                        error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
     869                        ldb_set_errstring(ldb, error_string);
     870                        talloc_free(error_string);
     871                        return NULL;
     872                }
     873
     874                ctrl->oid = LDB_CONTROL_SHOW_RECYCLED_OID;
     875                ctrl->critical = crit;
     876                ctrl->data = NULL;
     877
     878                return ctrl;
     879        }
     880
     881        if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_PERMISSIVE_MODIFY_NAME) == 0) {
     882                const char *p;
     883                int crit, ret;
     884
     885                p = &(control_strings[sizeof(LDB_CONTROL_PERMISSIVE_MODIFY_NAME)]);
     886                ret = sscanf(p, "%d", &crit);
     887                if ((ret != 1) || (crit < 0) || (crit > 1)) {
     888                        error_string = talloc_asprintf(mem_ctx, "invalid permissive_modify control syntax\n");
     889                        error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
     890                        error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
     891                        ldb_set_errstring(ldb, error_string);
     892                        talloc_free(error_string);
     893                        return NULL;
     894                }
     895
     896                ctrl->oid = LDB_CONTROL_PERMISSIVE_MODIFY_OID;
     897                ctrl->critical = crit;
     898                ctrl->data = NULL;
     899
     900                return ctrl;
     901        }
     902
     903        if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_REVEAL_INTERNALS_NAME) == 0) {
     904                const char *p;
     905                int crit, ret;
     906
     907                p = &(control_strings[sizeof(LDB_CONTROL_REVEAL_INTERNALS_NAME)]);
     908                ret = sscanf(p, "%d", &crit);
     909                if ((ret != 1) || (crit < 0) || (crit > 1)) {
     910                        error_string = talloc_asprintf(mem_ctx, "invalid reveal_internals control syntax\n");
     911                        error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
     912                        error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
     913                        ldb_set_errstring(ldb, error_string);
     914                        talloc_free(error_string);
     915                        return NULL;
     916                }
     917
     918                ctrl->oid = LDB_CONTROL_REVEAL_INTERNALS;
     919                ctrl->critical = crit;
     920                ctrl->data = NULL;
     921
     922                return ctrl;
     923        }
     924
     925        if (strncmp(control_strings, "local_oid:", 10) == 0) {
     926                const char *p;
     927                int crit = 0, ret = 0;
     928                char oid[256];
     929
     930                oid[0] = '\0';
     931                p = &(control_strings[10]);
     932                ret = sscanf(p, "%64[^:]:%d", oid, &crit);
     933
     934                if ((ret != 2) || strlen(oid) == 0 || (crit < 0) || (crit > 1)) {
     935                        error_string = talloc_asprintf(mem_ctx, "invalid local_oid control syntax\n");
     936                        error_string = talloc_asprintf_append(error_string, " syntax: oid(s):crit(b)\n");
     937                        error_string = talloc_asprintf_append(error_string, "   note: b = boolean, s = string");
     938                        ldb_set_errstring(ldb, error_string);
     939                        talloc_free(error_string);
     940                        return NULL;
     941                }
     942
     943                ctrl->oid = talloc_strdup(ctrl, oid);
     944                if (!ctrl->oid) {
     945                        ldb_oom(ldb);
     946                        return NULL;
     947                }
     948                ctrl->critical = crit;
     949                ctrl->data = NULL;
     950
     951                return ctrl;
     952        }
     953
     954        if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_RODC_DCPROMO_NAME) == 0) {
     955                const char *p;
     956                int crit, ret;
     957
     958                p = &(control_strings[sizeof(LDB_CONTROL_RODC_DCPROMO_NAME)]);
     959                ret = sscanf(p, "%d", &crit);
     960                if ((ret != 1) || (crit < 0) || (crit > 1)) {
     961                        error_string = talloc_asprintf(mem_ctx, "invalid rodc_join control syntax\n");
     962                        error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
     963                        error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
     964                        ldb_set_errstring(ldb, error_string);
     965                        talloc_free(error_string);
     966                        return NULL;
     967                }
     968
     969                ctrl->oid = LDB_CONTROL_RODC_DCPROMO_OID;
     970                ctrl->critical = crit;
     971                ctrl->data = NULL;
     972
     973                return ctrl;
     974        }
     975
     976        if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_PROVISION_NAME) == 0) {
     977                const char *p;
     978                int crit, ret;
     979
     980                p = &(control_strings[sizeof(LDB_CONTROL_PROVISION_NAME)]);
     981                ret = sscanf(p, "%d", &crit);
     982                if ((ret != 1) || (crit < 0) || (crit > 1)) {
     983                        error_string = talloc_asprintf(mem_ctx, "invalid provision control syntax\n");
     984                        error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
     985                        error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
     986                        ldb_set_errstring(ldb, error_string);
     987                        talloc_free(error_string);
     988                        return NULL;
     989                }
     990
     991                ctrl->oid = LDB_CONTROL_PROVISION_OID;
     992                ctrl->critical = crit;
     993                ctrl->data = NULL;
     994
     995                return ctrl;
     996        }
     997        /*
     998         * When no matching control has been found.
     999         */
     1000        return NULL;
     1001}
     1002
     1003/*
     1004 * A little trick to allow to use constants defined in headers rather than
     1005 * hardwritten in the file hardwritten in the file
     1006 * sizeof will return the \0 char as well so it will take the place of ":" in the
     1007 * length of the string
     1008 */
     1009#define LDB_CONTROL_CMP(control, NAME) strncmp(control, NAME ":", sizeof(NAME))
     1010
     1011/* Parse controls from the format used on the command line and in ejs */
     1012struct ldb_control **ldb_parse_control_strings(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char **control_strings)
     1013{
     1014        unsigned int i;
     1015        struct ldb_control **ctrl;
     1016
     1017        if (control_strings == NULL || control_strings[0] == NULL)
     1018                return NULL;
     1019
     1020        for (i = 0; control_strings[i]; i++);
     1021
     1022        ctrl = talloc_array(mem_ctx, struct ldb_control *, i + 1);
     1023
     1024        ldb_reset_err_string(ldb);
     1025        for (i = 0; control_strings[i]; i++) {
     1026                ctrl[i] = ldb_parse_control_from_string(ldb, ctrl, control_strings[i]);
     1027                if (ctrl[i] == NULL) {
     1028                        if( ldb_errstring == NULL ) {
     1029                                /* no controls matched, throw an error */
     1030                                ldb_asprintf_errstring(ldb, "Invalid control name: '%s'", control_strings[i]);
    2011031                        }
    202                         ctrl[i]->oid = LDB_CONTROL_VLV_REQ_OID;
    203                         ctrl[i]->critical = crit;
    204                         if (!(control = talloc(ctrl[i],
    205                                                struct ldb_vlv_req_control))) {
    206                                 ldb_oom(ldb);
    207                                 return NULL;
    208                         }
    209                         control->beforeCount = bc;
    210                         control->afterCount = ac;
    211                         if (attr[0]) {
    212                                 control->type = 1;
    213                                 control->match.gtOrEq.value = talloc_strdup(control, attr);
    214                                 control->match.gtOrEq.value_len = strlen(attr);
    215                         } else {
    216                                 control->type = 0;
    217                                 control->match.byOffset.offset = os;
    218                                 control->match.byOffset.contentCount = cc;
    219                         }
    220                         if (ctxid[0]) {
    221                                 control->ctxid_len = ldb_base64_decode(ctxid);
    222                                 control->contextId = (char *)talloc_memdup(control, ctxid, control->ctxid_len);
    223                         } else {
    224                                 control->ctxid_len = 0;
    225                                 control->contextId = NULL;
    226                         }
    227                         ctrl[i]->data = control;
    228 
    229                         continue;
    230                 }
    231 
    232                 if (strncmp(control_strings[i], "dirsync:", 8) == 0) {
    233                         struct ldb_dirsync_control *control;
    234                         const char *p;
    235                         char cookie[1024];
    236                         int crit, flags, max_attrs, ret;
    237                        
    238                         cookie[0] = '\0';
    239                         p = &(control_strings[i][8]);
    240                         ret = sscanf(p, "%d:%d:%d:%1023[^$]", &crit, &flags, &max_attrs, cookie);
    241 
    242                         if ((ret < 3) || (crit < 0) || (crit > 1) || (flags < 0) || (max_attrs < 0)) {
    243                                 error_string = talloc_asprintf(mem_ctx, "invalid dirsync control syntax\n");
    244                                 error_string = talloc_asprintf_append(error_string, " syntax: crit(b):flags(n):max_attrs(n)[:cookie(o)]\n");
    245                                 error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number, o = b64 binary blob");
    246                                 ldb_set_errstring(ldb, error_string);
    247                                 talloc_free(error_string);
    248                                 return NULL;
    249                         }
    250 
    251                         /* w2k3 seems to ignore the parameter,
    252                          * but w2k sends a wrong cookie when this value is to small
    253                          * this would cause looping forever, while getting
    254                          * the same data and same cookie forever
    255                          */
    256                         if (max_attrs == 0) max_attrs = 0x0FFFFFFF;
    257 
    258                         ctrl[i] = talloc(ctrl, struct ldb_control);
    259                         ctrl[i]->oid = LDB_CONTROL_DIRSYNC_OID;
    260                         ctrl[i]->critical = crit;
    261                         control = talloc(ctrl[i], struct ldb_dirsync_control);
    262                         control->flags = flags;
    263                         control->max_attributes = max_attrs;
    264                         if (*cookie) {
    265                                 control->cookie_len = ldb_base64_decode(cookie);
    266                                 control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len);
    267                         } else {
    268                                 control->cookie = NULL;
    269                                 control->cookie_len = 0;
    270                         }
    271                         ctrl[i]->data = control;
    272 
    273                         continue;
    274                 }
    275 
    276                 if (strncmp(control_strings[i], "asq:", 4) == 0) {
    277                         struct ldb_asq_control *control;
    278                         const char *p;
    279                         char attr[256];
    280                         int crit, ret;
    281 
    282                         attr[0] = '\0';
    283                         p = &(control_strings[i][4]);
    284                         ret = sscanf(p, "%d:%255[^$]", &crit, attr);
    285                         if ((ret != 2) || (crit < 0) || (crit > 1) || (attr[0] == '\0')) {
    286                                 error_string = talloc_asprintf(mem_ctx, "invalid asq control syntax\n");
    287                                 error_string = talloc_asprintf_append(error_string, " syntax: crit(b):attr(s)\n");
    288                                 error_string = talloc_asprintf_append(error_string, "   note: b = boolean, s = string");
    289                                 ldb_set_errstring(ldb, error_string);
    290                                 talloc_free(error_string);
    291                                 return NULL;
    292                         }
    293 
    294                         ctrl[i] = talloc(ctrl, struct ldb_control);
    295                         if (!ctrl[i]) {
    296                                 ldb_oom(ldb);
    297                                 return NULL;
    298                         }
    299                         ctrl[i]->oid = LDB_CONTROL_ASQ_OID;
    300                         ctrl[i]->critical = crit;
    301                         control = talloc(ctrl[i], struct ldb_asq_control);
    302                         control->request = 1;
    303                         control->source_attribute = talloc_strdup(control, attr);
    304                         control->src_attr_len = strlen(attr);
    305                         ctrl[i]->data = control;
    306 
    307                         continue;
    308                 }
    309 
    310                 if (strncmp(control_strings[i], "extended_dn:", 12) == 0) {
    311                         struct ldb_extended_dn_control *control;
    312                         const char *p;
    313                         int crit, type, ret;
    314 
    315                         p = &(control_strings[i][12]);
    316                         ret = sscanf(p, "%d:%d", &crit, &type);
    317                         if ((ret != 2) || (crit < 0) || (crit > 1) || (type < 0) || (type > 1)) {
    318                                 ret = sscanf(p, "%d", &crit);
    319                                 if ((ret != 1) || (crit < 0) || (crit > 1)) {
    320                                         error_string = talloc_asprintf(mem_ctx, "invalid extended_dn control syntax\n");
    321                                         error_string = talloc_asprintf_append(error_string, " syntax: crit(b)[:type(i)]\n");
    322                                         error_string = talloc_asprintf_append(error_string, "   note: b = boolean\n");
    323                                         error_string = talloc_asprintf_append(error_string, "         i = integer\n");
    324                                         error_string = talloc_asprintf_append(error_string, "   valid values are: 0 - hexadecimal representation\n");
    325                                         error_string = talloc_asprintf_append(error_string, "                     1 - normal string representation");
    326                                         ldb_set_errstring(ldb, error_string);
    327                                         talloc_free(error_string);
    328                                         return NULL;
    329                                 }
    330                                 control = NULL;
    331                         } else {
    332                                 control = talloc(ctrl, struct ldb_extended_dn_control);
    333                                 control->type = type;
    334                         }
    335 
    336                         ctrl[i] = talloc(ctrl, struct ldb_control);
    337                         if (!ctrl[i]) {
    338                                 ldb_oom(ldb);
    339                                 return NULL;
    340                         }
    341                         ctrl[i]->oid = LDB_CONTROL_EXTENDED_DN_OID;
    342                         ctrl[i]->critical = crit;
    343                         ctrl[i]->data = talloc_steal(ctrl[i], control);
    344 
    345                         continue;
    346                 }
    347 
    348                 if (strncmp(control_strings[i], "sd_flags:", 9) == 0) {
    349                         struct ldb_sd_flags_control *control;
    350                         const char *p;
    351                         int crit, ret;
    352                         unsigned secinfo_flags;
    353 
    354                         p = &(control_strings[i][9]);
    355                         ret = sscanf(p, "%d:%u", &crit, &secinfo_flags);
    356                         if ((ret != 2) || (crit < 0) || (crit > 1) || (secinfo_flags < 0) || (secinfo_flags > 0xF)) {
    357                                 error_string = talloc_asprintf(mem_ctx, "invalid sd_flags control syntax\n");
    358                                 error_string = talloc_asprintf_append(error_string, " syntax: crit(b):secinfo_flags(n)\n");
    359                                 error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number");
    360                                 ldb_set_errstring(ldb, error_string);
    361                                 talloc_free(error_string);
    362                                 return NULL;
    363                         }
    364 
    365                         ctrl[i] = talloc(ctrl, struct ldb_control);
    366                         if (!ctrl[i]) {
    367                                 ldb_oom(ldb);
    368                                 return NULL;
    369                         }
    370                         ctrl[i]->oid = LDB_CONTROL_SD_FLAGS_OID;
    371                         ctrl[i]->critical = crit;
    372                         control = talloc(ctrl[i], struct ldb_sd_flags_control);
    373                         control->secinfo_flags = secinfo_flags;
    374                         ctrl[i]->data = control;
    375 
    376                         continue;
    377                 }
    378 
    379                 if (strncmp(control_strings[i], "search_options:", 15) == 0) {
    380                         struct ldb_search_options_control *control;
    381                         const char *p;
    382                         int crit, ret;
    383                         unsigned search_options;
    384 
    385                         p = &(control_strings[i][15]);
    386                         ret = sscanf(p, "%d:%u", &crit, &search_options);
    387                         if ((ret != 2) || (crit < 0) || (crit > 1) || (search_options < 0) || (search_options > 0xF)) {
    388                                 error_string = talloc_asprintf(mem_ctx, "invalid search_options control syntax\n");
    389                                 error_string = talloc_asprintf_append(error_string, " syntax: crit(b):search_options(n)\n");
    390                                 error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number");
    391                                 ldb_set_errstring(ldb, error_string);
    392                                 talloc_free(error_string);
    393                                 return NULL;
    394                         }
    395 
    396                         ctrl[i] = talloc(ctrl, struct ldb_control);
    397                         if (!ctrl[i]) {
    398                                 ldb_oom(ldb);
    399                                 return NULL;
    400                         }
    401                         ctrl[i]->oid = LDB_CONTROL_SEARCH_OPTIONS_OID;
    402                         ctrl[i]->critical = crit;
    403                         control = talloc(ctrl[i], struct ldb_search_options_control);
    404                         control->search_options = search_options;
    405                         ctrl[i]->data = control;
    406 
    407                         continue;
    408                 }
    409 
    410                 if (strncmp(control_strings[i], "domain_scope:", 13) == 0) {
    411                         const char *p;
    412                         int crit, ret;
    413 
    414                         p = &(control_strings[i][13]);
    415                         ret = sscanf(p, "%d", &crit);
    416                         if ((ret != 1) || (crit < 0) || (crit > 1)) {
    417                                 error_string = talloc_asprintf(mem_ctx, "invalid domain_scope control syntax\n");
    418                                 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
    419                                 error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
    420                                 ldb_set_errstring(ldb, error_string);
    421                                 talloc_free(error_string);
    422                                 return NULL;
    423                         }
    424 
    425                         ctrl[i] = talloc(ctrl, struct ldb_control);
    426                         if (!ctrl[i]) {
    427                                 ldb_oom(ldb);
    428                                 return NULL;
    429                         }
    430                         ctrl[i]->oid = LDB_CONTROL_DOMAIN_SCOPE_OID;
    431                         ctrl[i]->critical = crit;
    432                         ctrl[i]->data = NULL;
    433 
    434                         continue;
    435                 }
    436 
    437                 if (strncmp(control_strings[i], "paged_results:", 14) == 0) {
    438                         struct ldb_paged_control *control;
    439                         const char *p;
    440                         int crit, size, ret;
    441                        
    442                         p = &(control_strings[i][14]);
    443                         ret = sscanf(p, "%d:%d", &crit, &size);
    444 
    445                         if ((ret != 2) || (crit < 0) || (crit > 1) || (size < 0)) {
    446                                 error_string = talloc_asprintf(mem_ctx, "invalid paged_results control syntax\n");
    447                                 error_string = talloc_asprintf_append(error_string, " syntax: crit(b):size(n)\n");
    448                                 error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number");
    449                                 ldb_set_errstring(ldb, error_string);
    450                                 talloc_free(error_string);
    451                                 return NULL;
    452                         }
    453 
    454                         ctrl[i] = talloc(ctrl, struct ldb_control);
    455                         if (!ctrl[i]) {
    456                                 ldb_oom(ldb);
    457                                 return NULL;
    458                         }
    459                         ctrl[i]->oid = LDB_CONTROL_PAGED_RESULTS_OID;
    460                         ctrl[i]->critical = crit;
    461                         control = talloc(ctrl[i], struct ldb_paged_control);
    462                         control->size = size;
    463                         control->cookie = NULL;
    464                         control->cookie_len = 0;
    465                         ctrl[i]->data = control;
    466 
    467                         continue;
    468                 }
    469 
    470                 if (strncmp(control_strings[i], "server_sort:", 12) == 0) {
    471                         struct ldb_server_sort_control **control;
    472                         const char *p;
    473                         char attr[256];
    474                         char rule[128];
    475                         int crit, rev, ret;
    476 
    477                         attr[0] = '\0';
    478                         rule[0] = '\0';
    479                         p = &(control_strings[i][12]);
    480                         ret = sscanf(p, "%d:%d:%255[^:]:%127[^:]", &crit, &rev, attr, rule);
    481                         if ((ret < 3) || (crit < 0) || (crit > 1) || (rev < 0 ) || (rev > 1) ||attr[0] == '\0') {
    482                                 error_string = talloc_asprintf(mem_ctx, "invalid server_sort control syntax\n");
    483                                 error_string = talloc_asprintf_append(error_string, " syntax: crit(b):rev(b):attr(s)[:rule(s)]\n");
    484                                 error_string = talloc_asprintf_append(error_string, "   note: b = boolean, s = string");
    485                                 ldb_set_errstring(ldb, error_string);
    486                                 talloc_free(error_string);
    487                                 return NULL;
    488                         }
    489                         ctrl[i] = talloc(ctrl, struct ldb_control);
    490                         if (!ctrl[i]) {
    491                                 ldb_oom(ldb);
    492                                 return NULL;
    493                         }
    494                         ctrl[i]->oid = LDB_CONTROL_SERVER_SORT_OID;
    495                         ctrl[i]->critical = crit;
    496                         control = talloc_array(ctrl[i], struct ldb_server_sort_control *, 2);
    497                         control[0] = talloc(control, struct ldb_server_sort_control);
    498                         control[0]->attributeName = talloc_strdup(control, attr);
    499                         if (rule[0])
    500                                 control[0]->orderingRule = talloc_strdup(control, rule);
    501                         else
    502                                 control[0]->orderingRule = NULL;
    503                         control[0]->reverse = rev;
    504                         control[1] = NULL;
    505                         ctrl[i]->data = control;
    506 
    507                         continue;
    508                 }
    509 
    510                 if (strncmp(control_strings[i], "notification:", 13) == 0) {
    511                         const char *p;
    512                         int crit, ret;
    513 
    514                         p = &(control_strings[i][13]);
    515                         ret = sscanf(p, "%d", &crit);
    516                         if ((ret != 1) || (crit < 0) || (crit > 1)) {
    517                                 error_string = talloc_asprintf(mem_ctx, "invalid notification control syntax\n");
    518                                 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
    519                                 error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
    520                                 ldb_set_errstring(ldb, error_string);
    521                                 talloc_free(error_string);
    522                                 return NULL;
    523                         }
    524 
    525                         ctrl[i] = talloc(ctrl, struct ldb_control);
    526                         if (!ctrl[i]) {
    527                                 ldb_oom(ldb);
    528                                 return NULL;
    529                         }
    530                         ctrl[i]->oid = LDB_CONTROL_NOTIFICATION_OID;
    531                         ctrl[i]->critical = crit;
    532                         ctrl[i]->data = NULL;
    533 
    534                         continue;
    535                 }
    536 
    537                 if (strncmp(control_strings[i], "show_deleted:", 13) == 0) {
    538                         const char *p;
    539                         int crit, ret;
    540 
    541                         p = &(control_strings[i][13]);
    542                         ret = sscanf(p, "%d", &crit);
    543                         if ((ret != 1) || (crit < 0) || (crit > 1)) {
    544                                 error_string = talloc_asprintf(mem_ctx, "invalid show_deleted control syntax\n");
    545                                 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
    546                                 error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
    547                                 ldb_set_errstring(ldb, error_string);
    548                                 talloc_free(error_string);
    549                                 return NULL;
    550                         }
    551 
    552                         ctrl[i] = talloc(ctrl, struct ldb_control);
    553                         if (!ctrl[i]) {
    554                                 ldb_oom(ldb);
    555                                 return NULL;
    556                         }
    557                         ctrl[i]->oid = LDB_CONTROL_SHOW_DELETED_OID;
    558                         ctrl[i]->critical = crit;
    559                         ctrl[i]->data = NULL;
    560 
    561                         continue;
    562                 }
    563 
    564                 if (strncmp(control_strings[i], "show_deactivated_link:", 22) == 0) {
    565                         const char *p;
    566                         int crit, ret;
    567 
    568                         p = &(control_strings[i][22]);
    569                         ret = sscanf(p, "%d", &crit);
    570                         if ((ret != 1) || (crit < 0) || (crit > 1)) {
    571                                 error_string = talloc_asprintf(mem_ctx, "invalid show_deactivated_link control syntax\n");
    572                                 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
    573                                 error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
    574                                 ldb_set_errstring(ldb, error_string);
    575                                 talloc_free(error_string);
    576                                 return NULL;
    577                         }
    578 
    579                         ctrl[i] = talloc(ctrl, struct ldb_control);
    580                         if (!ctrl[i]) {
    581                                 ldb_oom(ldb);
    582                                 return NULL;
    583                         }
    584                         ctrl[i]->oid = LDB_CONTROL_SHOW_DEACTIVATED_LINK_OID;
    585                         ctrl[i]->critical = crit;
    586                         ctrl[i]->data = NULL;
    587 
    588                         continue;
    589                 }
    590 
    591                 if (strncmp(control_strings[i], "show_recycled:", 14) == 0) {
    592                         const char *p;
    593                         int crit, ret;
    594 
    595                         p = &(control_strings[i][14]);
    596                         ret = sscanf(p, "%d", &crit);
    597                         if ((ret != 1) || (crit < 0) || (crit > 1)) {
    598                                 error_string = talloc_asprintf(mem_ctx, "invalid show_recycled control syntax\n");
    599                                 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
    600                                 error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
    601                                 ldb_set_errstring(ldb, error_string);
    602                                 talloc_free(error_string);
    603                                 return NULL;
    604                         }
    605 
    606                         ctrl[i] = talloc(ctrl, struct ldb_control);
    607                         if (!ctrl[i]) {
    608                                 ldb_oom(ldb);
    609                                 return NULL;
    610                         }
    611                         ctrl[i]->oid = LDB_CONTROL_SHOW_RECYCLED_OID;
    612                         ctrl[i]->critical = crit;
    613                         ctrl[i]->data = NULL;
    614 
    615                         continue;
    616                 }
    617 
    618                 if (strncmp(control_strings[i], "permissive_modify:", 18) == 0) {
    619                         const char *p;
    620                         int crit, ret;
    621 
    622                         p = &(control_strings[i][18]);
    623                         ret = sscanf(p, "%d", &crit);
    624                         if ((ret != 1) || (crit < 0) || (crit > 1)) {
    625                                 error_string = talloc_asprintf(mem_ctx, "invalid permissive_modify control syntax\n");
    626                                 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
    627                                 error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
    628                                 ldb_set_errstring(ldb, error_string);
    629                                 talloc_free(error_string);
    630                                 return NULL;
    631                         }
    632 
    633                         ctrl[i] = talloc(ctrl, struct ldb_control);
    634                         if (!ctrl[i]) {
    635                                 ldb_oom(ldb);
    636                                 return NULL;
    637                         }
    638                         ctrl[i]->oid = LDB_CONTROL_PERMISSIVE_MODIFY_OID;
    639                         ctrl[i]->critical = crit;
    640                         ctrl[i]->data = NULL;
    641 
    642                         continue;
    643                 }
    644 
    645                 /* no controls matched, throw an error */
    646                 ldb_asprintf_errstring(ldb, "Invalid control name: '%s'", control_strings[i]);
    647                 return NULL;
     1032                        talloc_free(ctrl);
     1033                        return NULL;
     1034                }
    6481035        }
    6491036
  • trunk/server/source4/lib/ldb/common/ldb_dn.c

    r414 r745  
    8080};
    8181
     82/* it is helpful to be able to break on this in gdb */
     83static void ldb_dn_mark_invalid(struct ldb_dn *dn)
     84{
     85        dn->invalid = true;
     86}
     87
    8288/* strdn may be NULL */
    83 struct ldb_dn *ldb_dn_from_ldb_val(void *mem_ctx,
     89struct ldb_dn *ldb_dn_from_ldb_val(TALLOC_CTX *mem_ctx,
    8490                                   struct ldb_context *ldb,
    8591                                   const struct ldb_val *strdn)
     
    9096
    9197        if (strdn && strdn->data
    92             && (strlen((const char*)strdn->data) != strdn->length)) {
     98            && (strnlen((const char*)strdn->data, strdn->length) != strdn->length)) {
    9399                /* The RDN must not contain a character with value 0x0 */
    94100                return NULL;
     
    98104        LDB_DN_NULL_FAILED(dn);
    99105
    100         dn->ldb = ldb;
     106        dn->ldb = talloc_get_type(ldb, struct ldb_context);
     107        if (dn->ldb == NULL) {
     108                /* the caller probably got the arguments to
     109                   ldb_dn_new() mixed up */
     110                talloc_free(dn);
     111                return NULL;
     112        }
    101113
    102114        if (strdn->data && strdn->length) {
     
    143155
    144156/* strdn may be NULL */
    145 struct ldb_dn *ldb_dn_new(void *mem_ctx,
     157struct ldb_dn *ldb_dn_new(TALLOC_CTX *mem_ctx,
    146158                          struct ldb_context *ldb,
    147159                          const char *strdn)
    148160{
    149161        struct ldb_val blob;
    150         blob.data = strdn;
     162        blob.data = discard_const_p(uint8_t, strdn);
    151163        blob.length = strdn ? strlen(strdn) : 0;
    152164        return ldb_dn_from_ldb_val(mem_ctx, ldb, &blob);
    153165}
    154166
    155 struct ldb_dn *ldb_dn_new_fmt(void *mem_ctx,
     167struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *mem_ctx,
    156168                              struct ldb_context *ldb,
    157169                              const char *new_fmt, ...)
     
    175187}
    176188
     189/* see RFC2253 section 2.4 */
    177190static int ldb_dn_escape_internal(char *dst, const char *src, int len)
    178191{
    179192        const char *p, *s;
    180193        char *d;
    181         int l;
     194        size_t l;
    182195
    183196        p = s = src;
     
    185198
    186199        while (p - src < len) {
    187 
    188                 p += strcspn(p, ",=\n+<>#;\\\"");
     200                p += strcspn(p, ",=\n\r+<>#;\\\" ");
    189201
    190202                if (p - src == len) /* found no escapable chars */
     
    194206                memcpy(d, s, p - s);
    195207                d += (p - s); /* move to current position */
    196 
    197                 if (*p) { /* it is a normal escapable character */
     208               
     209                switch (*p) {
     210                case ' ':
     211                        if (p == src || (p-src)==(len-1)) {
     212                                /* if at the beginning or end
     213                                 * of the string then escape */
     214                                *d++ = '\\';
     215                                *d++ = *p++;                                     
     216                        } else {
     217                                /* otherwise don't escape */
     218                                *d++ = *p++;
     219                        }
     220                        break;
     221
     222                case '#':
     223                        /* despite the RFC, windows escapes a #
     224                           anywhere in the string */
     225                case ',':
     226                case '+':
     227                case '"':
     228                case '\\':
     229                case '<':
     230                case '>':
     231                case '?':
     232                        /* these must be escaped using \c form */
    198233                        *d++ = '\\';
    199234                        *d++ = *p++;
    200                 } else { /* we have a zero byte in the string */
    201                         strncpy(d, "\00", 3); /* escape the zero */
    202                         d += 3;
    203                         p++; /* skip the zero */
     235                        break;
     236
     237                default: {
     238                        /* any others get \XX form */
     239                        unsigned char v;
     240                        const char *hexbytes = "0123456789ABCDEF";
     241                        v = *(const unsigned char *)p;
     242                        *d++ = '\\';
     243                        *d++ = hexbytes[v>>4];
     244                        *d++ = hexbytes[v&0xF];
     245                        p++;
     246                        break;
     247                }
    204248                }
    205249                s = p; /* move forward */
     
    214258}
    215259
    216 char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value)
     260char *ldb_dn_escape_value(TALLOC_CTX *mem_ctx, struct ldb_val value)
    217261{
    218262        char *dst;
     
    245289{
    246290        char *p, *ex_name, *ex_value, *data, *d, *dt, *t;
    247         bool trim = false;
    248         bool in_extended = false;
     291        bool trim = true;
     292        bool in_extended = true;
    249293        bool in_ex_name = false;
    250294        bool in_ex_value = false;
     
    254298        bool is_oid = false;
    255299        bool escape = false;
    256         unsigned x;
    257         int l, ret;
     300        unsigned int x;
     301        size_t l;
     302        int ret;
    258303        char *parse_dn;
     304        bool is_index;
    259305
    260306        if ( ! dn || dn->invalid) return false;
     
    274320        }
    275321
    276         /* The RDN size must be less than 255 characters */
    277         if (strlen(parse_dn) > 255) {
    278                 return false;
    279         }
     322        is_index = (strncmp(parse_dn, "DN=@INDEX:", 10) == 0);
    280323
    281324        /* Empty DNs */
     
    289332        }
    290333
    291         /* make sure we free this if alloced previously before replacing */
    292         talloc_free(dn->components);
    293 
    294         talloc_free(dn->ext_components);
    295         dn->ext_components = NULL;
     334        /* make sure we free this if allocated previously before replacing */
     335        LDB_FREE(dn->components);
     336        dn->comp_num = 0;
     337
     338        LDB_FREE(dn->ext_components);
     339        dn->ext_comp_num = 0;
    296340
    297341        /* in the common case we have 3 or more components */
     
    301345                return false;
    302346        }
    303         dn->comp_num = 0;
    304347
    305348        /* Components data space is allocated here once */
     
    310353
    311354        p = parse_dn;
    312         in_extended = true;
    313         in_ex_name = false;
    314         in_ex_value = false;
    315         trim = true;
    316355        t = NULL;
    317356        d = dt = data;
     
    384423                                                          &ex_val, &dn->ext_components[dn->ext_comp_num].value);
    385424                                if (ret != LDB_SUCCESS) {
    386                                         dn->invalid = true;
     425                                        ldb_dn_mark_invalid(dn);
    387426                                        goto failed;
    388427                                }
     
    399438                                        continue;
    400439                                } else {
    401                                         dn->invalid = true;
     440                                        ldb_dn_mark_invalid(dn);
    402441                                        goto failed;
    403442                                }
     
    419458                                if (!isascii(*p)) {
    420459                                        /* attr names must be ascii only */
    421                                         dn->invalid = true;
     460                                        ldb_dn_mark_invalid(dn);
    422461                                        goto failed;
    423462                                }
     
    429468                                        /* not a digit nor an alpha,
    430469                                         * invalid attribute name */
    431                                         dn->invalid = true;
     470                                        ldb_dn_mark_invalid(dn);
    432471                                        goto failed;
    433472                                }
     
    448487                        if (trim && (*p != '=')) {
    449488                                /* spaces/tabs are not allowed */
    450                                 dn->invalid = true;
     489                                ldb_dn_mark_invalid(dn);
    451490                                goto failed;
    452491                        }
     
    477516                        if (!isascii(*p)) {
    478517                                /* attr names must be ascii only */
    479                                 dn->invalid = true;
     518                                ldb_dn_mark_invalid(dn);
    480519                                goto failed;
    481520                        }
     
    484523                                /* not a digit nor a dot,
    485524                                 * invalid attribute oid */
    486                                 dn->invalid = true;
     525                                ldb_dn_mark_invalid(dn);
    487526                                goto failed;
    488527                        } else
    489528                        if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) {
    490529                                /* not ALPHA, DIGIT or HYPHEN */
    491                                 dn->invalid = true;
     530                                ldb_dn_mark_invalid(dn);
    492531                                goto failed;
    493532                        }
     
    579618                                continue;
    580619
     620                        case '+':
    581621                        case '=':
    582                         case '\n':
    583                         case '+':
     622                                /* to main compatibility with earlier
     623                                versions of ldb indexing, we have to
     624                                accept the base64 encoded binary index
     625                                values, which contain a '+' or '='
     626                                which should normally be escaped */
     627                                if (is_index) {
     628                                        if ( t ) t = NULL;
     629                                        *d++ = *p++;
     630                                        l++;
     631                                        break;
     632                                }
     633                                /* fall through */
     634                        case '\"':
    584635                        case '<':
    585636                        case '>':
    586                         case '#':
    587637                        case ';':
    588                         case '\"':
    589638                                /* a string with not escaped specials is invalid (tested) */
    590639                                if ( ! escape) {
    591                                         dn->invalid = true;
     640                                        ldb_dn_mark_invalid(dn);
    592641                                        goto failed;
    593642                                }
     
    616665                        default:
    617666                                if (escape) {
    618                                         if (sscanf(p, "%02x", &x) != 1) {
    619                                                 /* invalid escaping sequence */
    620                                                 dn->invalid = true;
    621                                                 goto failed;
     667                                        if (isxdigit(p[0]) && isxdigit(p[1])) {
     668                                                if (sscanf(p, "%02x", &x) != 1) {
     669                                                        /* invalid escaping sequence */
     670                                                        ldb_dn_mark_invalid(dn);
     671                                                        goto failed;
     672                                                }
     673                                                p += 2;
     674                                                *d++ = (unsigned char)x;
     675                                        } else {
     676                                                *d++ = *p++;
    622677                                        }
     678
    623679                                        escape = false;
    624 
    625                                         p += 2;
    626                                         *d++ = (unsigned char)x;
    627680                                        l++;
    628 
    629681                                        if ( t ) t = NULL;
    630682                                        break;
     
    648700        if (in_attr || in_quote) {
    649701                /* invalid dn */
    650                 dn->invalid = true;
     702                ldb_dn_mark_invalid(dn);
    651703                goto failed;
    652704        }
     
    674726
    675727failed:
     728        LDB_FREE(dn->components); /* "data" is implicitly free'd */
    676729        dn->comp_num = 0;
    677         talloc_free(dn->components);
     730        LDB_FREE(dn->ext_components);
     731        dn->ext_comp_num = 0;
     732
    678733        return false;
    679734}
     
    686741const char *ldb_dn_get_linearized(struct ldb_dn *dn)
    687742{
    688         int i, len;
     743        unsigned int i;
     744        size_t len;
    689745        char *d, *n;
    690746
     
    694750
    695751        if ( ! dn->components) {
    696                 dn->invalid = true;
     752                ldb_dn_mark_invalid(dn);
    697753                return NULL;
    698754        }
     
    741797}
    742798
    743 char *ldb_dn_get_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode)
     799static int ldb_dn_extended_component_compare(const void *p1, const void *p2)
     800{
     801        const struct ldb_dn_ext_component *ec1 = (const struct ldb_dn_ext_component *)p1;
     802        const struct ldb_dn_ext_component *ec2 = (const struct ldb_dn_ext_component *)p2;
     803        return strcmp(ec1->name, ec2->name);
     804}
     805
     806char *ldb_dn_get_extended_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int mode)
    744807{
    745808        const char *linearized = ldb_dn_get_linearized(dn);
    746         char *p;
    747         int i;
     809        char *p = NULL;
     810        unsigned int i;
    748811
    749812        if (!linearized) {
     
    758821                return NULL;
    759822        }
     823
     824        /* sort the extended components by name. The idea is to make
     825         * the resulting DNs consistent, plus to ensure that we put
     826         * 'DELETED' first, so it can be very quickly recognised
     827         */
     828        TYPESAFE_QSORT(dn->ext_components, dn->ext_comp_num,
     829                       ldb_dn_extended_component_compare);
    760830
    761831        for (i = 0; i < dn->ext_comp_num; i++) {
     
    767837
    768838                ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
     839                if (!ext_syntax) {
     840                        return NULL;
     841                }
    769842
    770843                if (mode == 1) {
     
    783856
    784857                if (i == 0) {
    785                         p = talloc_asprintf(mem_ctx, "<%s=%s>",
    786                                                         name, val.data);
     858                        p = talloc_asprintf(mem_ctx, "<%s=%s>", 
     859                                            name, val.data);
    787860                } else {
    788                         p = talloc_asprintf_append(p, ";<%s=%s>",
    789                                                         name, val.data);
     861                        p = talloc_asprintf_append_buffer(p, ";<%s=%s>",
     862                                                          name, val.data);
    790863                }
    791864
     
    798871
    799872        if (dn->ext_comp_num && *linearized) {
    800                 p = talloc_asprintf_append(p, ";%s", linearized);
     873                p = talloc_asprintf_append_buffer(p, ";%s", linearized);
    801874        }
    802875
     
    808881}
    809882
    810 
    811 
    812 char *ldb_dn_alloc_linearized(void *mem_ctx, struct ldb_dn *dn)
     883/*
     884  filter out all but an acceptable list of extended DN components
     885 */
     886void ldb_dn_extended_filter(struct ldb_dn *dn, const char * const *accept_list)
     887{
     888        unsigned int i;
     889        for (i=0; i<dn->ext_comp_num; i++) {
     890                if (!ldb_attr_in_list(accept_list, dn->ext_components[i].name)) {
     891                        memmove(&dn->ext_components[i],
     892                                &dn->ext_components[i+1],
     893                                (dn->ext_comp_num-(i+1))*sizeof(dn->ext_components[0]));
     894                        dn->ext_comp_num--;
     895                        i--;
     896                }
     897        }
     898        LDB_FREE(dn->ext_linearized);
     899}
     900
     901
     902char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
    813903{
    814904        return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
     
    822912static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
    823913{
    824         int i, ret;
     914        unsigned int i;
     915        int ret;
    825916
    826917        if ( ! dn || dn->invalid) return false;
     
    867958const char *ldb_dn_get_casefold(struct ldb_dn *dn)
    868959{
    869         int i, len;
     960        unsigned int i;
     961        size_t len;
    870962        char *d, *n;
    871963
     
    9241016}
    9251017
    926 char *ldb_dn_alloc_casefold(void *mem_ctx, struct ldb_dn *dn)
     1018char *ldb_dn_alloc_casefold(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
    9271019{
    9281020        return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn));
     
    9371029{
    9381030        int ret;
    939         int n_base, n_dn;
     1031        unsigned int n_base, n_dn;
    9401032
    9411033        if ( ! base || base->invalid) return 1;
     
    9731065        }
    9741066
    975         if (dn->comp_num == 0) {
     1067        if ((dn->comp_num == 0) || (base->comp_num == 0)) {
    9761068                if (dn->special && base->special) {
    9771069                        return strcmp(base->linearized, dn->linearized);
     
    9881080        n_dn = dn->comp_num - 1;
    9891081
    990         while (n_base >= 0) {
     1082        while (n_base != (unsigned int) -1) {
    9911083                char *b_name = base->components[n_base].cf_name;
    9921084                char *dn_name = dn->components[n_dn].cf_name;
     
    10231115int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
    10241116{
    1025         int i, ret;
     1117        unsigned int i;
     1118        int ret;
    10261119
    10271120        if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) {
     
    10941187
    10951188static struct ldb_dn_component ldb_dn_copy_component(
    1096                                                 void *mem_ctx,
     1189                                                TALLOC_CTX *mem_ctx,
    10971190                                                struct ldb_dn_component *src)
    10981191{
     
    11401233
    11411234static struct ldb_dn_ext_component ldb_dn_ext_copy_component(
    1142                                                 void *mem_ctx,
     1235                                                TALLOC_CTX *mem_ctx,
    11431236                                                struct ldb_dn_ext_component *src)
    11441237{
     
    11651258}
    11661259
    1167 struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
     1260struct ldb_dn *ldb_dn_copy(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
    11681261{
    11691262        struct ldb_dn *new_dn;
     
    11811274
    11821275        if (dn->components) {
    1183                 int i;
     1276                unsigned int i;
    11841277
    11851278                new_dn->components =
     
    12041297
    12051298        if (dn->ext_components) {
    1206                 int i;
     1299                unsigned int i;
    12071300
    12081301                new_dn->ext_components =
     
    12701363
    12711364        if (dn->components) {
    1272                 int i;
     1365                unsigned int i;
    12731366
    12741367                if ( ! ldb_dn_validate(base)) {
     
    12881381                                                dn->comp_num + base->comp_num);
    12891382                if ( ! dn->components) {
    1290                         dn->invalid = true;
     1383                        ldb_dn_mark_invalid(dn);
    12911384                        return false;
    12921385                }
     
    12971390                                                        &base->components[i]);
    12981391                        if (dn->components[dn->comp_num].value.data == NULL) {
    1299                                 dn->invalid = true;
     1392                                ldb_dn_mark_invalid(dn);
    13001393                                return false;
    13011394                        }
     
    13281421                }
    13291422                if ( ! t) {
    1330                         dn->invalid = true;
     1423                        ldb_dn_mark_invalid(dn);
    13311424                        return false;
    13321425                }
     
    13371430        /* Wipe the ext_linearized DN,
    13381431         * the GUID and SID are almost certainly no longer valid */
    1339         if (dn->ext_linearized) {
    1340                 LDB_FREE(dn->ext_linearized);
    1341         }
    1342 
     1432        LDB_FREE(dn->ext_linearized);
    13431433        LDB_FREE(dn->ext_components);
    13441434        dn->ext_comp_num = 0;
     1435
    13451436        return true;
    13461437}
     
    13941485
    13951486        if (dn->components) {
    1396                 int n, i, j;
     1487                unsigned int n;
     1488                unsigned int i, j;
     1489
     1490                if (dn->comp_num == 0) {
     1491                        return false;
     1492                }
    13971493
    13981494                if ( ! ldb_dn_validate(child)) {
     
    14141510                                                n);
    14151511                if ( ! dn->components) {
    1416                         dn->invalid = true;
     1512                        ldb_dn_mark_invalid(dn);
    14171513                        return false;
    14181514                }
    14191515
    1420                 for (i = dn->comp_num - 1, j = n - 1; i >= 0; i--, j--) {
     1516                for (i = dn->comp_num - 1, j = n - 1; i != (unsigned int) -1;
     1517                     i--, j--) {
    14211518                        dn->components[j] = dn->components[i];
    14221519                }
     
    14271524                                                        &child->components[i]);
    14281525                        if (dn->components[i].value.data == NULL) {
    1429                                 dn->invalid = true;
     1526                                ldb_dn_mark_invalid(dn);
    14301527                                return false;
    14311528                        }
     
    14421539
    14431540        if (dn->linearized) {
     1541                if (dn->linearized[0] == '\0') {
     1542                        return false;
     1543                }
    14441544
    14451545                s = ldb_dn_get_linearized(child);
     
    14501550                t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
    14511551                if ( ! t) {
    1452                         dn->invalid = true;
     1552                        ldb_dn_mark_invalid(dn);
    14531553                        return false;
    14541554                }
     
    14601560         * the GUID and SID are almost certainly no longer valid */
    14611561        LDB_FREE(dn->ext_linearized);
    1462 
    14631562        LDB_FREE(dn->ext_components);
    14641563        dn->ext_comp_num = 0;
     
    15021601bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
    15031602{
    1504         int i;
     1603        unsigned int i;
    15051604
    15061605        if ( ! ldb_dn_validate(dn)) {
     
    15131612
    15141613        /* free components */
    1515         for (i = num; i > 0; i--) {
    1516                 LDB_FREE(dn->components[dn->comp_num - i].name);
    1517                 LDB_FREE(dn->components[dn->comp_num - i].value.data);
    1518                 LDB_FREE(dn->components[dn->comp_num - i].cf_name);
    1519                 LDB_FREE(dn->components[dn->comp_num - i].cf_value.data);
     1614        for (i = dn->comp_num - num; i < dn->comp_num; i++) {
     1615                LDB_FREE(dn->components[i].name);
     1616                LDB_FREE(dn->components[i].value.data);
     1617                LDB_FREE(dn->components[i].cf_name);
     1618                LDB_FREE(dn->components[i].cf_value.data);
    15201619        }
    15211620
     
    15361635         * the GUID and SID are almost certainly no longer valid */
    15371636        LDB_FREE(dn->ext_linearized);
    1538 
    15391637        LDB_FREE(dn->ext_components);
    15401638        dn->ext_comp_num = 0;
     
    15451643bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
    15461644{
    1547         int i, j;
     1645        unsigned int i, j;
    15481646
    15491647        if ( ! ldb_dn_validate(dn)) {
     
    15811679         * the GUID and SID are almost certainly no longer valid */
    15821680        LDB_FREE(dn->ext_linearized);
    1583 
    15841681        LDB_FREE(dn->ext_components);
    15851682        dn->ext_comp_num = 0;
     1683
    15861684        return true;
    15871685}
    15881686
    1589 struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, struct ldb_dn *dn)
     1687struct ldb_dn *ldb_dn_get_parent(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
    15901688{
    15911689        struct ldb_dn *new_dn;
     
    16011699        }
    16021700
    1603         /* Wipe the ext_linearized DN,
    1604          * the GUID and SID are almost certainly no longer valid */
    1605         LDB_FREE(dn->ext_linearized);
    1606 
    1607         LDB_FREE(dn->ext_components);
    1608         dn->ext_comp_num = 0;
    16091701        return new_dn;
    16101702}
     
    16191711
    16201712*/
    1621 static char *ldb_dn_canonical(void *mem_ctx, struct ldb_dn *dn, int ex_format) {
    1622         int i;
     1713static char *ldb_dn_canonical(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int ex_format) {
     1714        unsigned int i;
    16231715        TALLOC_CTX *tmpctx;
    16241716        char *cracked = NULL;
     
    16321724
    16331725        /* Walk backwards down the DN, grabbing 'dc' components at first */
    1634         for (i = dn->comp_num - 1 ; i >= 0; i--) {
     1726        for (i = dn->comp_num - 1; i != (unsigned int) -1; i--) {
    16351727                if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
    16361728                        break;
     
    16511743
    16521744        /* Only domain components?  Finish here */
    1653         if (i < 0) {
     1745        if (i == (unsigned int) -1) {
    16541746                cracked = talloc_strdup_append_buffer(cracked, format);
    16551747                talloc_steal(mem_ctx, cracked);
     
    16791771
    16801772/* Wrapper functions for the above, for the two different string formats */
    1681 char *ldb_dn_canonical_string(void *mem_ctx, struct ldb_dn *dn) {
     1773char *ldb_dn_canonical_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) {
    16821774        return ldb_dn_canonical(mem_ctx, dn, 0);
    16831775
    16841776}
    16851777
    1686 char *ldb_dn_canonical_ex_string(void *mem_ctx, struct ldb_dn *dn) {
     1778char *ldb_dn_canonical_ex_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) {
    16871779        return ldb_dn_canonical(mem_ctx, dn, 1);
    16881780}
     
    16941786        }
    16951787        return dn->comp_num;
     1788}
     1789
     1790int ldb_dn_get_extended_comp_num(struct ldb_dn *dn)
     1791{
     1792        if ( ! ldb_dn_validate(dn)) {
     1793                return -1;
     1794        }
     1795        return dn->ext_comp_num;
    16961796}
    16971797
     
    17651865
    17661866        if (dn->valid_case) {
    1767                 int i;
     1867                unsigned int i;
    17681868                for (i = 0; i < dn->comp_num; i++) {
    17691869                        LDB_FREE(dn->components[i].cf_name);
     
    17781878         * the GUID and SID are almost certainly no longer valid */
    17791879        LDB_FREE(dn->ext_linearized);
    1780 
     1880        LDB_FREE(dn->ext_components);
    17811881        dn->ext_comp_num = 0;
    1782         LDB_FREE(dn->ext_components);
     1882
    17831883        return LDB_SUCCESS;
    17841884}
     
    17871887                                                    const char *name)
    17881888{
    1789         int i;
     1889        unsigned int i;
    17901890        if ( ! ldb_dn_validate(dn)) {
    17911891                return NULL;
     
    18031903{
    18041904        struct ldb_dn_ext_component *p;
    1805         int i;
     1905        unsigned int i;
     1906        struct ldb_val v2;
    18061907
    18071908        if ( ! ldb_dn_validate(dn)) {
    18081909                return LDB_ERR_OTHER;
     1910        }
     1911
     1912        if (!ldb_dn_extended_syntax_by_name(dn->ldb, name)) {
     1913                /* We don't know how to handle this type of thing */
     1914                return LDB_ERR_INVALID_DN_SYNTAX;
    18091915        }
    18101916
     
    18191925                                if (!dn->ext_components[i].name ||
    18201926                                    !dn->ext_components[i].value.data) {
    1821                                         dn->invalid = true;
     1927                                        ldb_dn_mark_invalid(dn);
    18221928                                        return LDB_ERR_OPERATIONS_ERROR;
    18231929                                }
    1824 
    18251930                        } else {
    18261931                                if (i != (dn->ext_comp_num - 1)) {
     
    18371942                                                   dn->ext_comp_num);
    18381943                                if (!dn->ext_components) {
    1839                                         dn->invalid = true;
     1944                                        ldb_dn_mark_invalid(dn);
    18401945                                        return LDB_ERR_OPERATIONS_ERROR;
    18411946                                }
    1842                                 return LDB_SUCCESS;
    1843                         }
    1844                 }
    1845         }
     1947                        }
     1948                        LDB_FREE(dn->ext_linearized);
     1949
     1950                        return LDB_SUCCESS;
     1951                }
     1952        }
     1953
     1954        if (val == NULL) {
     1955                /* removing a value that doesn't exist is not an error */
     1956                return LDB_SUCCESS;
     1957        }
     1958
     1959        v2 = *val;
    18461960
    18471961        p = dn->ext_components
     
    18511965                                 dn->ext_comp_num + 1);
    18521966        if (!dn->ext_components) {
    1853                 dn->invalid = true;
     1967                ldb_dn_mark_invalid(dn);
    18541968                return LDB_ERR_OPERATIONS_ERROR;
    18551969        }
    18561970
    1857         p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, val);
     1971        p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, &v2);
    18581972        p[dn->ext_comp_num].name = talloc_strdup(p, name);
    18591973
    18601974        if (!dn->ext_components[i].name || !dn->ext_components[i].value.data) {
    1861                 dn->invalid = true;
     1975                ldb_dn_mark_invalid(dn);
    18621976                return LDB_ERR_OPERATIONS_ERROR;
    18631977        }
     
    18651979        dn->ext_comp_num++;
    18661980
     1981        LDB_FREE(dn->ext_linearized);
     1982
    18671983        return LDB_SUCCESS;
    18681984}
     
    18701986void ldb_dn_remove_extended_components(struct ldb_dn *dn)
    18711987{
     1988        LDB_FREE(dn->ext_linearized);
     1989        LDB_FREE(dn->ext_components);
    18721990        dn->ext_comp_num = 0;
    1873         LDB_FREE(dn->ext_components);
    18741991}
    18751992
     
    19062023        return false;
    19072024}
     2025
     2026/*
     2027  this updates dn->components, taking the components from ref_dn.
     2028  This is used by code that wants to update the DN path of a DN
     2029  while not impacting on the extended DN components
     2030 */
     2031int ldb_dn_update_components(struct ldb_dn *dn, const struct ldb_dn *ref_dn)
     2032{
     2033        dn->components = talloc_realloc(dn, dn->components,
     2034                                        struct ldb_dn_component, ref_dn->comp_num);
     2035        if (!dn->components) {
     2036                return LDB_ERR_OPERATIONS_ERROR;
     2037        }
     2038        memcpy(dn->components, ref_dn->components,
     2039               sizeof(struct ldb_dn_component)*ref_dn->comp_num);
     2040        dn->comp_num = ref_dn->comp_num;
     2041
     2042        LDB_FREE(dn->casefold);
     2043        LDB_FREE(dn->linearized);
     2044        LDB_FREE(dn->ext_linearized);
     2045
     2046        return LDB_SUCCESS;
     2047}
     2048
     2049/*
     2050  minimise a DN. The caller must pass in a validated DN.
     2051
     2052  If the DN has an extended component then only the first extended
     2053  component is kept, the DN string is stripped.
     2054
     2055  The existing dn is modified
     2056 */
     2057bool ldb_dn_minimise(struct ldb_dn *dn)
     2058{
     2059        unsigned int i;
     2060
     2061        if (!ldb_dn_validate(dn)) {
     2062                return false;
     2063        }
     2064        if (dn->ext_comp_num == 0) {
     2065                return true;
     2066        }
     2067
     2068        /* free components */
     2069        for (i = 0; i < dn->comp_num; i++) {
     2070                LDB_FREE(dn->components[i].name);
     2071                LDB_FREE(dn->components[i].value.data);
     2072                LDB_FREE(dn->components[i].cf_name);
     2073                LDB_FREE(dn->components[i].cf_value.data);
     2074        }
     2075        dn->comp_num = 0;
     2076        dn->valid_case = false;
     2077
     2078        LDB_FREE(dn->casefold);
     2079        LDB_FREE(dn->linearized);
     2080
     2081        /* note that we don't free dn->components as this there are
     2082         * several places in ldb_dn.c that rely on it being non-NULL
     2083         * for an exploded DN
     2084         */
     2085
     2086        for (i = 1; i < dn->ext_comp_num; i++) {
     2087                LDB_FREE(dn->ext_components[i].name);
     2088                LDB_FREE(dn->ext_components[i].value.data);
     2089        }
     2090        dn->ext_comp_num = 1;
     2091
     2092        dn->ext_components = talloc_realloc(dn, dn->ext_components, struct ldb_dn_ext_component, 1);
     2093        if (dn->ext_components == NULL) {
     2094                ldb_dn_mark_invalid(dn);
     2095                return false;
     2096        }
     2097
     2098        LDB_FREE(dn->ext_linearized);
     2099
     2100        return true;
     2101}
  • trunk/server/source4/lib/ldb/common/ldb_ldif.c

    r414 r745  
    4242 
    4343*/
    44 static int ldb_read_data_file(void *mem_ctx, struct ldb_val *value)
     44static int ldb_read_data_file(TALLOC_CTX *mem_ctx, struct ldb_val *value)
    4545{
    4646        struct stat statbuf;
     
    151151  caller frees
    152152*/
    153 char *ldb_base64_encode(void *mem_ctx, const char *buf, int len)
     153char *ldb_base64_encode(TALLOC_CTX *mem_ctx, const char *buf, int len)
    154154{
    155155        const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
     
    191191        uint8_t *p = val->data;
    192192
    193         if (ldb->flags & LDB_FLG_SHOW_BINARY) {
    194                 return 0;
    195         }
    196 
    197193        if (val->length == 0) {
    198194                return 0;
     
    220216                        const char *buf, size_t length, int start_pos)
    221217{
    222         unsigned int i;
     218        size_t i;
    223219        int total=0, ret;
    224220
     
    334330                for (j=0;j<msg->elements[i].num_values;j++) {
    335331                        struct ldb_val v;
     332                        bool use_b64_encode;
    336333                        ret = a->syntax->ldif_write_fn(ldb, mem_ctx, &msg->elements[i].values[j], &v);
    337334                        if (ret != LDB_SUCCESS) {
    338335                                v = msg->elements[i].values[j];
    339336                        }
    340                         if (ret != LDB_SUCCESS || ldb_should_b64_encode(ldb, &v)) {
     337                        use_b64_encode = !(ldb->flags & LDB_FLG_SHOW_BINARY)
     338                                        && ldb_should_b64_encode(ldb, &v);
     339                        if (ret != LDB_SUCCESS || use_b64_encode) {
    341340                                ret = fprintf_fn(private_data, "%s:: ",
    342341                                                 msg->elements[i].name);
     
    374373        CHECK_RET;
    375374
     375        talloc_free(mem_ctx);
     376
    376377        return total;
    377378}
     
    448449
    449450/* simple ldif attribute parser */
    450 static int next_attr(void *mem_ctx, char **s, const char **attr, struct ldb_val *value)
     451static int next_attr(TALLOC_CTX *mem_ctx, char **s, const char **attr, struct ldb_val *value)
    451452{
    452453        char *p;
     
    509510                int len = ldb_read_data_file(mem_ctx, value);
    510511                if (len == -1) {
    511                         /* an error occured hile trying to retrieve the file */
     512                        /* an error occurred while trying to retrieve the file */
    512513                        return -1;
    513514                }
  • trunk/server/source4/lib/ldb/common/ldb_match.c

    r414 r745  
    8282                             const struct ldb_message *msg,
    8383                             const struct ldb_parse_tree *tree,
    84                              enum ldb_scope scope)
    85 {
     84                             enum ldb_scope scope, bool *matched)
     85{
     86        const struct ldb_schema_attribute *a;
     87        struct ldb_message_element *el;
     88
    8689        if (ldb_attr_dn(tree->u.present.attr) == 0) {
    87                 return 1;
    88         }
    89 
    90         if (ldb_msg_find_element(msg, tree->u.present.attr)) {
    91                 return 1;
    92         }
    93 
    94         return 0;
     90                *matched = true;
     91                return LDB_SUCCESS;
     92        }
     93
     94        el = ldb_msg_find_element(msg, tree->u.present.attr);
     95        if (el == NULL) {
     96                *matched = false;
     97                return LDB_SUCCESS;
     98        }
     99
     100        a = ldb_schema_attribute_by_name(ldb, el->name);
     101        if (!a) {
     102                return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
     103        }
     104
     105        if (a->syntax->operator_fn) {
     106                unsigned int i;
     107                for (i = 0; i < el->num_values; i++) {
     108                        int ret = a->syntax->operator_fn(ldb, LDB_OP_PRESENT, a, &el->values[i], NULL, matched);
     109                        if (ret != LDB_SUCCESS) return ret;
     110                        if (*matched) return LDB_SUCCESS;
     111                }
     112                *matched = false;
     113                return LDB_SUCCESS;
     114        }
     115
     116        *matched = true;
     117        return LDB_SUCCESS;
    95118}
    96119
     
    99122                                const struct ldb_parse_tree *tree,
    100123                                enum ldb_scope scope,
    101                                 enum ldb_parse_op comp_op)
     124                                enum ldb_parse_op comp_op, bool *matched)
    102125{
    103126        unsigned int i;
    104127        struct ldb_message_element *el;
    105128        const struct ldb_schema_attribute *a;
    106         int ret;
    107129
    108130        /* FIXME: APPROX comparison not handled yet */
    109         if (comp_op == LDB_OP_APPROX) return 0;
     131        if (comp_op == LDB_OP_APPROX) {
     132                return LDB_ERR_INAPPROPRIATE_MATCHING;
     133        }
    110134
    111135        el = ldb_msg_find_element(msg, tree->u.comparison.attr);
    112136        if (el == NULL) {
    113                 return 0;
     137                *matched = false;
     138                return LDB_SUCCESS;
    114139        }
    115140
    116141        a = ldb_schema_attribute_by_name(ldb, el->name);
     142        if (!a) {
     143                return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
     144        }
    117145
    118146        for (i = 0; i < el->num_values; i++) {
    119                 ret = a->syntax->comparison_fn(ldb, ldb, &el->values[i], &tree->u.comparison.value);
    120 
    121                 if (ret == 0) {
    122                         return 1;
    123                 }
    124                 if (ret > 0 && comp_op == LDB_OP_GREATER) {
    125                         return 1;
    126                 }
    127                 if (ret < 0 && comp_op == LDB_OP_LESS) {
    128                         return 1;
    129                 }
    130         }
    131 
    132         return 0;
     147                if (a->syntax->operator_fn) {
     148                        int ret;
     149                        ret = a->syntax->operator_fn(ldb, comp_op, a, &el->values[i], &tree->u.comparison.value, matched);
     150                        if (ret != LDB_SUCCESS) return ret;
     151                        if (*matched) return LDB_SUCCESS;
     152                } else {
     153                        int ret = a->syntax->comparison_fn(ldb, ldb, &el->values[i], &tree->u.comparison.value);
     154
     155                        if (ret == 0) {
     156                                *matched = true;
     157                                return LDB_SUCCESS;
     158                        }
     159                        if (ret > 0 && comp_op == LDB_OP_GREATER) {
     160                                *matched = true;
     161                                return LDB_SUCCESS;
     162                        }
     163                        if (ret < 0 && comp_op == LDB_OP_LESS) {
     164                                *matched = true;
     165                                return LDB_SUCCESS;
     166                        }
     167                }
     168        }
     169
     170        *matched = false;
     171        return LDB_SUCCESS;
    133172}
    134173
     
    139178                              const struct ldb_message *msg,
    140179                              const struct ldb_parse_tree *tree,
    141                               enum ldb_scope scope)
     180                              enum ldb_scope scope,
     181                              bool *matched)
    142182{
    143183        unsigned int i;
     
    150190                valuedn = ldb_dn_from_ldb_val(ldb, ldb, &tree->u.equality.value);
    151191                if (valuedn == NULL) {
    152                         return 0;
     192                        return LDB_ERR_INVALID_DN_SYNTAX;
    153193                }
    154194
     
    157197                talloc_free(valuedn);
    158198
    159                 if (ret == 0) return 1;
    160                 return 0;
     199                *matched = (ret == 0);
     200                return LDB_SUCCESS;
    161201        }
    162202
     
    165205        el = ldb_msg_find_element(msg, tree->u.equality.attr);
    166206        if (el == NULL) {
    167                 return 0;
     207                *matched = false;
     208                return LDB_SUCCESS;
    168209        }
    169210
    170211        a = ldb_schema_attribute_by_name(ldb, el->name);
     212        if (a == NULL) {
     213                return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
     214        }
    171215
    172216        for (i=0;i<el->num_values;i++) {
    173                 if (a->syntax->comparison_fn(ldb, ldb, &tree->u.equality.value,
    174                                              &el->values[i]) == 0) {
    175                         return 1;
    176                 }
    177         }
    178 
    179         return 0;
     217                if (a->syntax->operator_fn) {
     218                        ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a,
     219                                                     &tree->u.equality.value, &el->values[i], matched);
     220                        if (ret != LDB_SUCCESS) return ret;
     221                        if (*matched) return LDB_SUCCESS;
     222                } else {
     223                        if (a->syntax->comparison_fn(ldb, ldb, &tree->u.equality.value,
     224                                                     &el->values[i]) == 0) {
     225                                *matched = true;
     226                                return LDB_SUCCESS;
     227                        }
     228                }
     229        }
     230
     231        *matched = false;
     232        return LDB_SUCCESS;
    180233}
    181234
    182235static int ldb_wildcard_compare(struct ldb_context *ldb,
    183236                                const struct ldb_parse_tree *tree,
    184                                 const struct ldb_val value)
     237                                const struct ldb_val value, bool *matched)
    185238{
    186239        const struct ldb_schema_attribute *a;
     
    190243        char *p, *g;
    191244        uint8_t *save_p = NULL;
    192         int c = 0;
     245        unsigned int c = 0;
    193246
    194247        a = ldb_schema_attribute_by_name(ldb, tree->u.substring.attr);
    195 
    196         if(a->syntax->canonicalise_fn(ldb, ldb, &value, &val) != 0)
    197                 return -1;
     248        if (!a) {
     249                return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
     250        }
     251
     252        if (a->syntax->canonicalise_fn(ldb, ldb, &value, &val) != 0) {
     253                return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
     254        }
    198255
    199256        save_p = val.data;
     
    203260
    204261                chunk = tree->u.substring.chunks[c];
    205                 if(a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto failed;
     262                if (a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto mismatch;
    206263
    207264                /* This deals with wildcard prefix searches on binary attributes (eg objectGUID) */
    208265                if (cnk.length > val.length) {
    209                         goto failed;
    210                 }
    211                 if (memcmp((char *)val.data, (char *)cnk.data, cnk.length) != 0) goto failed;
     266                        goto mismatch;
     267                }
     268                if (memcmp((char *)val.data, (char *)cnk.data, cnk.length) != 0) goto mismatch;
    212269                val.length -= cnk.length;
    213270                val.data += cnk.length;
     
    220277
    221278                chunk = tree->u.substring.chunks[c];
    222                 if(a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto failed;
     279                if(a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto mismatch;
    223280
    224281                /* FIXME: case of embedded nulls */
    225282                p = strstr((char *)val.data, (char *)cnk.data);
    226                 if (p == NULL) goto failed;
     283                if (p == NULL) goto mismatch;
    227284                if ( (! tree->u.substring.chunks[c + 1]) && (! tree->u.substring.end_with_wildcard) ) {
    228285                        do { /* greedy */
     
    238295        }
    239296
    240         if ( (! tree->u.substring.end_with_wildcard) && (*(val.data) != 0) ) goto failed; /* last chunk have not reached end of string */
     297        /* last chunk may not have reached end of string */
     298        if ( (! tree->u.substring.end_with_wildcard) && (*(val.data) != 0) ) goto mismatch;
    241299        talloc_free(save_p);
    242         return 1;
    243 
    244 failed:
     300        *matched = true;
     301        return LDB_SUCCESS;
     302
     303mismatch:
     304        *matched = false;
    245305        talloc_free(save_p);
    246306        talloc_free(cnk.data);
    247         return 0;
     307        return LDB_SUCCESS;
    248308}
    249309
     
    254314                               const struct ldb_message *msg,
    255315                               const struct ldb_parse_tree *tree,
    256                                enum ldb_scope scope)
     316                               enum ldb_scope scope, bool *matched)
    257317{
    258318        unsigned int i;
     
    261321        el = ldb_msg_find_element(msg, tree->u.substring.attr);
    262322        if (el == NULL) {
    263                 return 0;
     323                *matched = false;
     324                return LDB_SUCCESS;
    264325        }
    265326
    266327        for (i = 0; i < el->num_values; i++) {
    267                 if (ldb_wildcard_compare(ldb, tree, el->values[i]) == 1) {
    268                         return 1;
    269                 }
    270         }
    271 
    272         return 0;
     328                int ret;
     329                ret = ldb_wildcard_compare(ldb, tree, el->values[i], matched);
     330                if (ret != LDB_SUCCESS) return ret;
     331                if (*matched) return LDB_SUCCESS;
     332        }
     333
     334        *matched = false;
     335        return LDB_SUCCESS;
    273336}
    274337
     
    277340  bitwise-and comparator
    278341*/
    279 static int ldb_comparator_and(const struct ldb_val *v1, const struct ldb_val *v2)
     342static int ldb_comparator_bitmask(const char *oid, const struct ldb_val *v1, const struct ldb_val *v2,
     343                                  bool *matched)
    280344{
    281345        uint64_t i1, i2;
    282         i1 = strtoull((char *)v1->data, NULL, 0);
    283         i2 = strtoull((char *)v2->data, NULL, 0);
    284         return ((i1 & i2) == i2);
    285 }
    286 
    287 /*
    288   bitwise-or comparator
    289 */
    290 static int ldb_comparator_or(const struct ldb_val *v1, const struct ldb_val *v2)
    291 {
    292         uint64_t i1, i2;
    293         i1 = strtoull((char *)v1->data, NULL, 0);
    294         i2 = strtoull((char *)v2->data, NULL, 0);
    295         return ((i1 & i2) != 0);
     346        char ibuf[100];
     347        char *endptr = NULL;
     348
     349        if (v1->length >= sizeof(ibuf)-1) {
     350                return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
     351        }
     352        memcpy(ibuf, (char *)v1->data, v1->length);
     353        ibuf[v1->length] = 0;
     354        i1 = strtoull(ibuf, &endptr, 0);
     355        if (endptr != NULL) {
     356                if (endptr == ibuf || *endptr != 0) {
     357                        return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
     358                }
     359        }
     360
     361        if (v2->length >= sizeof(ibuf)-1) {
     362                return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
     363        }
     364        endptr = NULL;
     365        memcpy(ibuf, (char *)v2->data, v2->length);
     366        ibuf[v2->length] = 0;
     367        i2 = strtoull(ibuf, &endptr, 0);
     368        if (endptr != NULL) {
     369                if (endptr == ibuf || *endptr != 0) {
     370                        return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
     371                }
     372        }
     373        if (strcmp(LDB_OID_COMPARATOR_AND, oid) == 0) {
     374                *matched = ((i1 & i2) == i2);
     375        } else if (strcmp(LDB_OID_COMPARATOR_OR, oid) == 0) {
     376                *matched = ((i1 & i2) != 0);
     377        } else {
     378                return LDB_ERR_INAPPROPRIATE_MATCHING;
     379        }
     380        return LDB_SUCCESS;
    296381}
    297382
     
    303388                              const struct ldb_message *msg,
    304389                              const struct ldb_parse_tree *tree,
    305                               enum ldb_scope scope)
    306 {
    307         int i;
     390                              enum ldb_scope scope, bool *matched)
     391{
     392        unsigned int i;
    308393        const struct {
    309394                const char *oid;
    310                 int (*comparator)(const struct ldb_val *, const struct ldb_val *);
     395                int (*comparator)(const char *, const struct ldb_val *, const struct ldb_val *, bool *);
    311396        } rules[] = {
    312                 { LDB_OID_COMPARATOR_AND, ldb_comparator_and},
    313                 { LDB_OID_COMPARATOR_OR, ldb_comparator_or}
     397                { LDB_OID_COMPARATOR_AND, ldb_comparator_bitmask},
     398                { LDB_OID_COMPARATOR_OR, ldb_comparator_bitmask}
    314399        };
    315         int (*comp)(const struct ldb_val *, const struct ldb_val *) = NULL;
     400        int (*comp)(const char *,const struct ldb_val *, const struct ldb_val *, bool *) = NULL;
    316401        struct ldb_message_element *el;
    317402
    318403        if (tree->u.extended.dnAttributes) {
    319                 ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: dnAttributes extended match not supported yet");
    320                 return -1;
     404                /* FIXME: We really need to find out what this ":dn" part in
     405                 * an extended match means and how to handle it. For now print
     406                 * only a warning to have s3 winbind and other tools working
     407                 * against us. - Matthias */
     408                ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb: dnAttributes extended match not supported yet");
    321409        }
    322410        if (tree->u.extended.rule_id == NULL) {
    323411                ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: no-rule extended matches not supported yet");
    324                 return -1;
     412                return LDB_ERR_INAPPROPRIATE_MATCHING;
    325413        }
    326414        if (tree->u.extended.attr == NULL) {
    327415                ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: no-attribute extended matches not supported yet");
    328                 return -1;
     416                return LDB_ERR_INAPPROPRIATE_MATCHING;
    329417        }
    330418
     
    338426                ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: unknown extended rule_id %s",
    339427                          tree->u.extended.rule_id);
    340                 return -1;
     428                return LDB_ERR_INAPPROPRIATE_MATCHING;
    341429        }
    342430
     
    344432        el = ldb_msg_find_element(msg, tree->u.extended.attr);
    345433        if (el == NULL) {
    346                 return 0;
     434                *matched = false;
     435                return LDB_SUCCESS;
    347436        }
    348437
    349438        for (i=0;i<el->num_values;i++) {
    350                 int ret = comp(&el->values[i], &tree->u.extended.value);
    351                 if (ret == -1 || ret == 1) return ret;
    352         }
    353 
    354         return 0;
     439                int ret = comp(tree->u.extended.rule_id, &el->values[i], &tree->u.extended.value, matched);
     440                if (ret != LDB_SUCCESS) return ret;
     441                if (*matched) return LDB_SUCCESS;
     442        }
     443
     444        *matched = false;
     445        return LDB_SUCCESS;
    355446}
    356447
     
    366457                             const struct ldb_message *msg,
    367458                             const struct ldb_parse_tree *tree,
    368                              enum ldb_scope scope)
     459                             enum ldb_scope scope, bool *matched)
    369460{
    370461        unsigned int i;
    371         int v;
     462        int ret;
     463
     464        *matched = false;
    372465
    373466        switch (tree->operation) {
    374467        case LDB_OP_AND:
    375468                for (i=0;i<tree->u.list.num_elements;i++) {
    376                         v = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope);
    377                         if (!v) return 0;
    378                 }
    379                 return 1;
     469                        ret = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope, matched);
     470                        if (ret != LDB_SUCCESS) return ret;
     471                        if (!*matched) return LDB_SUCCESS;
     472                }
     473                *matched = true;
     474                return LDB_SUCCESS;
    380475
    381476        case LDB_OP_OR:
    382477                for (i=0;i<tree->u.list.num_elements;i++) {
    383                         v = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope);
    384                         if (v) return 1;
    385                 }
    386                 return 0;
     478                        ret = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope, matched);
     479                        if (ret != LDB_SUCCESS) return ret;
     480                        if (*matched) return LDB_SUCCESS;
     481                }
     482                *matched = false;
     483                return LDB_SUCCESS;
    387484
    388485        case LDB_OP_NOT:
    389                 return ! ldb_match_message(ldb, msg, tree->u.isnot.child, scope);
     486                ret = ldb_match_message(ldb, msg, tree->u.isnot.child, scope, matched);
     487                if (ret != LDB_SUCCESS) return ret;
     488                *matched = ! *matched;
     489                return LDB_SUCCESS;
    390490
    391491        case LDB_OP_EQUALITY:
    392                 return ldb_match_equality(ldb, msg, tree, scope);
     492                return ldb_match_equality(ldb, msg, tree, scope, matched);
    393493
    394494        case LDB_OP_SUBSTRING:
    395                 return ldb_match_substring(ldb, msg, tree, scope);
     495                return ldb_match_substring(ldb, msg, tree, scope, matched);
    396496
    397497        case LDB_OP_GREATER:
    398                 return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_GREATER);
     498                return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_GREATER, matched);
    399499
    400500        case LDB_OP_LESS:
    401                 return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_LESS);
     501                return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_LESS, matched);
    402502
    403503        case LDB_OP_PRESENT:
    404                 return ldb_match_present(ldb, msg, tree, scope);
     504                return ldb_match_present(ldb, msg, tree, scope, matched);
    405505
    406506        case LDB_OP_APPROX:
    407                 return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_APPROX);
     507                return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_APPROX, matched);
    408508
    409509        case LDB_OP_EXTENDED:
    410                 return ldb_match_extended(ldb, msg, tree, scope);
    411 
    412         }
    413 
    414         return 0;
     510                return ldb_match_extended(ldb, msg, tree, scope, matched);
     511        }
     512
     513        return LDB_ERR_INAPPROPRIATE_MATCHING;
    415514}
    416515
     
    421520                  enum ldb_scope scope)
    422521{
     522        bool matched;
     523        int ret;
     524
    423525        if ( ! ldb_match_scope(ldb, base, msg->dn, scope) ) {
    424526                return 0;
    425527        }
    426528
    427         return ldb_match_message(ldb, msg, tree, scope);
    428 }
     529        ret = ldb_match_message(ldb, msg, tree, scope, &matched);
     530        if (ret != LDB_SUCCESS) {
     531                /* to match the old API, we need to consider this a
     532                   failure to match */
     533                return 0;
     534        }
     535        return matched?1:0;
     536}
     537
     538int ldb_match_msg_error(struct ldb_context *ldb,
     539                        const struct ldb_message *msg,
     540                        const struct ldb_parse_tree *tree,
     541                        struct ldb_dn *base,
     542                        enum ldb_scope scope,
     543                        bool *matched)
     544{
     545        if ( ! ldb_match_scope(ldb, base, msg->dn, scope) ) {
     546                *matched = false;
     547                return LDB_SUCCESS;
     548        }
     549
     550        return ldb_match_message(ldb, msg, tree, scope, matched);
     551}
     552
     553int ldb_match_msg_objectclass(const struct ldb_message *msg,
     554                              const char *objectclass)
     555{
     556        unsigned int i;
     557        struct ldb_message_element *el = ldb_msg_find_element(msg, "objectClass");
     558        if (!el) {
     559                return 0;
     560        }
     561        for (i=0; i < el->num_values; i++) {
     562                if (ldb_attr_cmp((const char *)el->values[i].data, objectclass) == 0) {
     563                        return 1;
     564                }
     565        }
     566        return 0;
     567}
     568
     569
     570                             
  • trunk/server/source4/lib/ldb/common/ldb_modules.c

    r414 r745  
    3434#include "ldb_private.h"
    3535#include "dlinklist.h"
    36 
    37 #define LDB_MODULE_PREFIX       "modules:"
    38 #define LDB_MODULE_PREFIX_LEN   8
    39 
    40 static void *ldb_dso_load_symbol(struct ldb_context *ldb, const char *name,
    41                                  const char *symbol);
    42 
    43 void ldb_set_modules_dir(struct ldb_context *ldb, const char *path)
    44 {
    45         talloc_free(ldb->modules_dir);
    46         ldb->modules_dir = talloc_strdup(ldb, path);
    47 }
     36#include "system/dir.h"
    4837
    4938static char *ldb_modules_strdup_no_spaces(TALLOC_CTX *mem_ctx, const char *string)
    5039{
    51         int i, len;
     40        size_t i, len;
    5241        char *trimmed;
    5342
     
    8069        const char **m;
    8170        char *modstr, *p;
    82         int i;
     71        unsigned int i;
    8372
    8473        /* spaces not admitted */
     
    9685        }
    9786        talloc_steal(modules, modstr);
     87
     88        if (modstr[0] == '\0') {
     89                modules[0] = NULL;
     90                m = (const char **)modules;
     91                return m;
     92        }
    9893
    9994        i = 0;
     
    131126} *registered_modules = NULL;
    132127
    133 static const struct ldb_builtins {
    134         const struct ldb_backend_ops *backend_ops;
    135         const struct ldb_module_ops *module_ops;
    136 } builtins[];
    137 
    138 static ldb_connect_fn ldb_find_backend(const char *url)
     128static struct backends_list_entry *ldb_find_backend(const char *url_prefix)
    139129{
    140130        struct backends_list_entry *backend;
    141         int i;
    142 
    143         for (i = 0; builtins[i].backend_ops || builtins[i].module_ops; i++) {
    144                 if (builtins[i].backend_ops == NULL) continue;
    145 
    146                 if (strncmp(builtins[i].backend_ops->name, url,
    147                             strlen(builtins[i].backend_ops->name)) == 0) {
    148                         return builtins[i].backend_ops->connect_fn;
    149                 }
    150         }
    151131
    152132        for (backend = ldb_backends; backend; backend = backend->next) {
    153                 if (strncmp(backend->ops->name, url,
    154                             strlen(backend->ops->name)) == 0) {
    155                         return backend->ops->connect_fn;
     133                if (strcmp(backend->ops->name, url_prefix) == 0) {
     134                        return backend;
    156135                }
    157136        }
     
    161140
    162141/*
    163  register a new ldb backend
     142  register a new ldb backend
     143
     144  if override is true, then override any existing backend for this prefix
    164145*/
    165 int ldb_register_backend(const char *url_prefix, ldb_connect_fn connectfn)
    166 {
    167         struct ldb_backend_ops *backend;
    168         struct backends_list_entry *entry;
    169 
    170         backend = talloc(talloc_autofree_context(), struct ldb_backend_ops);
    171         if (!backend) return LDB_ERR_OPERATIONS_ERROR;
    172 
    173         entry = talloc(talloc_autofree_context(), struct backends_list_entry);
    174         if (!entry) {
    175                 talloc_free(backend);
    176                 return LDB_ERR_OPERATIONS_ERROR;
    177         }
    178 
    179         if (ldb_find_backend(url_prefix)) {
    180                 return LDB_SUCCESS;
    181         }
    182 
    183         /* Maybe check for duplicity here later on? */
    184 
    185         backend->name = talloc_strdup(backend, url_prefix);
    186         backend->connect_fn = connectfn;
    187         entry->ops = backend;
    188         DLIST_ADD(ldb_backends, entry);
     146int ldb_register_backend(const char *url_prefix, ldb_connect_fn connectfn, bool override)
     147{
     148        struct backends_list_entry *be;
     149
     150        be = ldb_find_backend(url_prefix);
     151        if (be) {
     152                if (!override) {
     153                        return LDB_SUCCESS;
     154                }
     155        } else {
     156                be = talloc_zero(ldb_backends, struct backends_list_entry);
     157                if (!be) {
     158                        return LDB_ERR_OPERATIONS_ERROR;
     159                }
     160                be->ops = talloc_zero(be, struct ldb_backend_ops);
     161                if (!be->ops) {
     162                        talloc_free(be);
     163                        return LDB_ERR_OPERATIONS_ERROR;
     164                }
     165                DLIST_ADD_END(ldb_backends, be, struct backends_list_entry);
     166        }
     167
     168        be->ops->name = url_prefix;
     169        be->ops->connect_fn = connectfn;
    189170
    190171        return LDB_SUCCESS;
     
    205186   module may wish to direct certain requests at a particular backend.
    206187*/
    207 int ldb_connect_backend(struct ldb_context *ldb,
    208                         const char *url,
    209                         const char *options[],
    210                         struct ldb_module **backend_module)
     188int ldb_module_connect_backend(struct ldb_context *ldb,
     189                               const char *url,
     190                               const char *options[],
     191                               struct ldb_module **backend_module)
    211192{
    212193        int ret;
    213194        char *backend;
    214         ldb_connect_fn fn;
     195        struct backends_list_entry *be;
    215196
    216197        if (strchr(url, ':') != NULL) {
     
    221202        }
    222203
    223         fn = ldb_find_backend(backend);
    224 
    225         if (fn == NULL) {
    226                 struct ldb_backend_ops *ops;
    227                 char *symbol_name = talloc_asprintf(ldb, "ldb_%s_backend_ops", backend);
    228                 if (symbol_name == NULL) {
    229                         return LDB_ERR_OPERATIONS_ERROR;
    230                 }
    231                 ops = ldb_dso_load_symbol(ldb, backend, symbol_name);
    232                 if (ops != NULL) {
    233                         fn = ops->connect_fn;
    234                 }
    235                 talloc_free(symbol_name);
    236         }
     204        be = ldb_find_backend(backend);
    237205
    238206        talloc_free(backend);
    239207
    240         if (fn == NULL) {
     208        if (be == NULL) {
    241209                ldb_debug(ldb, LDB_DEBUG_FATAL,
    242                           "Unable to find backend for '%s'", url);
     210                          "Unable to find backend for '%s' - do you need to set LDB_MODULES_PATH?", url);
    243211                return LDB_ERR_OTHER;
    244212        }
    245213
    246         ret = fn(ldb, url, ldb->flags, options, backend_module);
     214        ret = be->ops->connect_fn(ldb, url, ldb->flags, options, backend_module);
    247215
    248216        if (ret != LDB_SUCCESS) {
    249217                ldb_debug(ldb, LDB_DEBUG_ERROR,
    250                           "Failed to connect to '%s'", url);
     218                          "Failed to connect to '%s' with backend '%s'", url, be->ops->name);
    251219                return ret;
    252220        }
     
    254222}
    255223
     224static struct ldb_hooks {
     225        struct ldb_hooks *next, *prev;
     226        ldb_hook_fn hook_fn;
     227} *ldb_hooks;
     228
     229/*
     230  register a ldb hook function
     231 */
     232int ldb_register_hook(ldb_hook_fn hook_fn)
     233{
     234        struct ldb_hooks *lc;
     235        lc = talloc_zero(ldb_hooks, struct ldb_hooks);
     236        if (lc == NULL) {
     237                return LDB_ERR_OPERATIONS_ERROR;
     238        }
     239        lc->hook_fn = hook_fn;
     240        DLIST_ADD_END(ldb_hooks, lc, struct ldb_hooks);
     241        return LDB_SUCCESS;
     242}
     243
     244/*
     245  call ldb hooks of a given type
     246 */
     247int ldb_modules_hook(struct ldb_context *ldb, enum ldb_module_hook_type t)
     248{
     249        struct ldb_hooks *lc;
     250        for (lc = ldb_hooks; lc; lc=lc->next) {
     251                int ret = lc->hook_fn(ldb, t);
     252                if (ret != LDB_SUCCESS) {
     253                        return ret;
     254                }
     255        }
     256        return LDB_SUCCESS;
     257}
     258
     259
    256260static const struct ldb_module_ops *ldb_find_module_ops(const char *name)
    257261{
    258262        struct ops_list_entry *e;
    259         int i;
    260 
    261         for (i = 0; builtins[i].backend_ops || builtins[i].module_ops; i++) {
    262                 if (builtins[i].module_ops == NULL) continue;
    263 
    264                 if (strcmp(builtins[i].module_ops->name, name) == 0)
    265                         return builtins[i].module_ops;
    266         }
    267263
    268264        for (e = registered_modules; e; e = e->next) {
     
    277273int ldb_register_module(const struct ldb_module_ops *ops)
    278274{
    279         struct ops_list_entry *entry = talloc(talloc_autofree_context(), struct ops_list_entry);
     275        struct ops_list_entry *entry;
    280276
    281277        if (ldb_find_module_ops(ops->name) != NULL)
    282                 return -1;
    283 
     278                return LDB_ERR_ENTRY_ALREADY_EXISTS;
     279
     280        entry = talloc(talloc_autofree_context(), struct ops_list_entry);
    284281        if (entry == NULL)
    285282                return -1;
     
    292289}
    293290
    294 static void *ldb_dso_load_symbol(struct ldb_context *ldb, const char *name,
    295                                  const char *symbol)
    296 {
    297         char *path;
    298         void *handle;
    299         void *sym;
    300 
    301         if (ldb->modules_dir == NULL)
    302                 return NULL;
    303 
    304         path = talloc_asprintf(ldb, "%s/%s.%s", ldb->modules_dir, name,
    305                                SHLIBEXT);
    306 
    307         ldb_debug(ldb, LDB_DEBUG_TRACE, "trying to load %s from %s", name, path);
    308 
    309         handle = dlopen(path, RTLD_NOW);
    310         if (handle == NULL) {
    311                 ldb_debug(ldb, LDB_DEBUG_WARNING, "unable to load %s from %s: %s", name, path, dlerror());
    312                 return NULL;
    313         }
    314 
    315         sym = (int (*)(void))dlsym(handle, symbol);
    316 
    317         if (sym == NULL) {
    318                 ldb_debug(ldb, LDB_DEBUG_ERROR, "no symbol `%s' found in %s: %s", symbol, path, dlerror());
    319                 return NULL;
    320         }
    321 
    322         talloc_free(path);
    323 
    324         return sym;
    325 }
    326 
    327 int ldb_load_modules_list(struct ldb_context *ldb, const char **module_list, struct ldb_module *backend, struct ldb_module **out)
     291/*
     292  load a list of modules
     293 */
     294int ldb_module_load_list(struct ldb_context *ldb, const char **module_list,
     295                         struct ldb_module *backend, struct ldb_module **out)
    328296{
    329297        struct ldb_module *module;
    330         int i;
     298        unsigned int i;
    331299
    332300        module = backend;
    333301
    334         for (i = 0; module_list[i] != NULL; i++) {
     302        for (i = 0; module_list && module_list[i] != NULL; i++) {
    335303                struct ldb_module *current;
    336304                const struct ldb_module_ops *ops;
     
    341309
    342310                ops = ldb_find_module_ops(module_list[i]);
     311
    343312                if (ops == NULL) {
    344                         char *symbol_name = talloc_asprintf(ldb, "ldb_%s_module_ops",
    345                                                                                                 module_list[i]);
    346                         if (symbol_name == NULL) {
    347                                 return LDB_ERR_OPERATIONS_ERROR;
    348                         }
    349                         ops = ldb_dso_load_symbol(ldb, module_list[i], symbol_name);
    350                         talloc_free(symbol_name);
    351                 }
    352 
    353                 if (ops == NULL) {
    354                         ldb_debug(ldb, LDB_DEBUG_WARNING, "WARNING: Module [%s] not found",
     313                        ldb_debug(ldb, LDB_DEBUG_FATAL, "WARNING: Module [%s] not found - do you need to set LDB_MODULES_PATH?",
    355314                                  module_list[i]);
    356                         continue;
     315                        return LDB_ERR_OPERATIONS_ERROR;
    357316                }
    358317
     
    372331}
    373332
    374 int ldb_init_module_chain(struct ldb_context *ldb, struct ldb_module *module)
     333/*
     334  initialise a chain of modules
     335 */
     336int ldb_module_init_chain(struct ldb_context *ldb, struct ldb_module *module)
    375337{
    376338        while (module && module->ops->init_context == NULL)
     
    383345                int ret = module->ops->init_context(module);
    384346                if (ret != LDB_SUCCESS) {
    385                         ldb_debug(ldb, LDB_DEBUG_FATAL, "module %s initialization failed", module->ops->name);
     347                        ldb_debug(ldb, LDB_DEBUG_FATAL, "module %s initialization failed : %s",
     348                                  module->ops->name, ldb_strerror(ret));
    386349                        return ret;
    387350                }
     
    393356int ldb_load_modules(struct ldb_context *ldb, const char *options[])
    394357{
     358        const char *modules_string;
    395359        const char **modules = NULL;
    396         int i;
    397360        int ret;
    398361        TALLOC_CTX *mem_ctx = talloc_new(ldb);
     
    405368        /* check if we have a custom module list passd as ldb option */
    406369        if (options) {
    407                 for (i = 0; options[i] != NULL; i++) {
    408                         if (strncmp(options[i], LDB_MODULE_PREFIX, LDB_MODULE_PREFIX_LEN) == 0) {
    409                                 modules = ldb_modules_list_from_string(ldb, mem_ctx, &options[i][LDB_MODULE_PREFIX_LEN]);
    410                         }
     370                modules_string = ldb_options_find(ldb, options, "modules");
     371                if (modules_string) {
     372                        modules = ldb_modules_list_from_string(ldb, mem_ctx, modules_string);
    411373                }
    412374        }
     
    454416
    455417        if (modules != NULL) {
    456                 ret = ldb_load_modules_list(ldb, modules, ldb->modules, &ldb->modules);
     418                ret = ldb_module_load_list(ldb, modules, ldb->modules, &ldb->modules);
    457419                if (ret != LDB_SUCCESS) {
    458420                        talloc_free(mem_ctx);
     
    463425        }
    464426
    465         ret = ldb_init_module_chain(ldb, ldb->modules);
     427        ret = ldb_module_init_chain(ldb, ldb->modules);
    466428        talloc_free(mem_ctx);
    467429        return ret;
     
    476438        module = module->next; \
    477439        while (module && module->ops->op == NULL) module = module->next; \
     440        if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { \
     441                ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_trace_next_request: (%s)->" #op, \
     442                          module->ops->name);                           \
     443        }                                                               \
    478444} while (0)
    479445
     
    516482{
    517483        return module->ldb;
     484}
     485
     486const struct ldb_module_ops *ldb_module_get_ops(struct ldb_module *module)
     487{
     488        return module->ops;
    518489}
    519490
     
    592563                 * corner for module developers to cut themselves on
    593564                 */
    594                 ldb_module_done(request, NULL, NULL, ret);
     565                ret = ldb_module_done(request, NULL, NULL, ret);
    595566        }
    596567        return ret;
     
    601572        module = module->next;
    602573
    603         return ldb_init_module_chain(module->ldb, module);
     574        return ldb_module_init_chain(module->ldb, module);
    604575}
    605576
    606577int ldb_next_start_trans(struct ldb_module *module)
    607578{
     579        int ret;
    608580        FIND_OP(module, start_transaction);
    609         return module->ops->start_transaction(module);
     581        ret = module->ops->start_transaction(module);
     582        if (ret == LDB_SUCCESS) {
     583                return ret;
     584        }
     585        if (!ldb_errstring(module->ldb)) {
     586                /* Set a default error string, to place the blame somewhere */
     587                ldb_asprintf_errstring(module->ldb, "start_trans error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret);
     588        }
     589        if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) {
     590                ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_start_trans error: %s",
     591                          ldb_errstring(module->ldb));                         
     592        }
     593        return ret;
    610594}
    611595
    612596int ldb_next_end_trans(struct ldb_module *module)
    613597{
     598        int ret;
    614599        FIND_OP(module, end_transaction);
    615         return module->ops->end_transaction(module);
     600        ret = module->ops->end_transaction(module);
     601        if (ret == LDB_SUCCESS) {
     602                return ret;
     603        }
     604        if (!ldb_errstring(module->ldb)) {
     605                /* Set a default error string, to place the blame somewhere */
     606                ldb_asprintf_errstring(module->ldb, "end_trans error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret);
     607        }
     608        if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) {
     609                ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_end_trans error: %s",
     610                          ldb_errstring(module->ldb));                         
     611        }
     612        return ret;
    616613}
    617614
    618615int ldb_next_prepare_commit(struct ldb_module *module)
    619616{
     617        int ret;
    620618        FIND_OP_NOERR(module, prepare_commit);
    621619        if (module == NULL) {
     
    624622                return LDB_SUCCESS;
    625623        }
    626         return module->ops->prepare_commit(module);
     624        ret = module->ops->prepare_commit(module);
     625        if (ret == LDB_SUCCESS) {
     626                return ret;
     627        }
     628        if (!ldb_errstring(module->ldb)) {
     629                /* Set a default error string, to place the blame somewhere */
     630                ldb_asprintf_errstring(module->ldb, "prepare_commit error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret);
     631        }
     632        if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) {
     633                ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_prepare_commit error: %s",
     634                          ldb_errstring(module->ldb));                         
     635        }
     636        return ret;
    627637}
    628638
    629639int ldb_next_del_trans(struct ldb_module *module)
    630640{
     641        int ret;
    631642        FIND_OP(module, del_transaction);
    632         return module->ops->del_transaction(module);
     643        ret = module->ops->del_transaction(module);
     644        if (ret == LDB_SUCCESS) {
     645                return ret;
     646        }
     647        if (!ldb_errstring(module->ldb)) {
     648                /* Set a default error string, to place the blame somewhere */
     649                ldb_asprintf_errstring(module->ldb, "del_trans error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret);
     650        }
     651        if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) {
     652                ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_del_trans error: %s",
     653                          ldb_errstring(module->ldb));                         
     654        }
     655        return ret;
    633656}
    634657
     
    647670        h->ldb = ldb;
    648671        h->flags = 0;
     672        h->location = NULL;
     673        h->parent = NULL;
    649674
    650675        return h;
     
    729754 *      ctrls: controls to send in the reply (must be a talloc pointer, steal)
    730755 *      response: results for extended request (steal)
    731  *      error: LDB_SUCCESS for a succesful return
     756 *      error: LDB_SUCCESS for a successful return
    732757 *             any other ldb error otherwise
    733758 */
     
    763788        }
    764789
    765         req->callback(req, ares);
    766         return error;
     790        return req->callback(req, ares);
    767791}
    768792
    769793/* to be used *only* in modules init functions.
    770  * this function i synchronous and will register
     794 * this function is synchronous and will register
    771795 * the requested OID in the rootdse module if present
    772796 * otherwise it will return an error */
     
    801825}
    802826
    803 #ifndef STATIC_LIBLDB_MODULES
    804 
    805 #ifdef HAVE_LDB_LDAP
    806 #define LDAP_BACKEND LDB_BACKEND(ldap), LDB_BACKEND(ldapi), LDB_BACKEND(ldaps),
    807 #else
    808 #define LDAP_BACKEND
     827static int ldb_modules_load_dir(const char *modules_dir, const char *version);
     828
     829
     830/*
     831  load one module. A static list of loaded module inode numbers is
     832  used to prevent a module being loaded twice
     833
     834  dlopen() is used on the module, and dlsym() is then used to look for
     835  a ldb_init_module() function. If present, that function is called
     836  with the ldb version number as an argument.
     837
     838  The ldb_init_module() function will typically call
     839  ldb_register_module() and ldb_register_backend() to register a
     840  module or backend, but it may also be used to register command line
     841  handling functions, ldif handlers or any other local
     842  modififications.
     843
     844  The ldb_init_module() function does not get a ldb_context passed in,
     845  as modules will be used for multiple ldb context handles. The call
     846  from the first ldb_init() is just a convenient way to ensure it is
     847  called early enough.
     848 */
     849static int ldb_modules_load_path(const char *path, const char *version)
     850{
     851        void *handle;
     852        int (*init_fn)(const char *);
     853        int ret;
     854        struct stat st;
     855        static struct loaded {
     856                struct loaded *next, *prev;
     857                ino_t st_ino;
     858                dev_t st_dev;
     859        } *loaded;
     860        struct loaded *le;
     861        int dlopen_flags;
     862
     863        ret = stat(path, &st);
     864        if (ret != 0) {
     865                fprintf(stderr, "ldb: unable to stat module %s : %s\n", path, strerror(errno));
     866                return LDB_ERR_UNAVAILABLE;
     867        }
     868
     869        for (le=loaded; le; le=le->next) {
     870                if (le->st_ino == st.st_ino &&
     871                    le->st_dev == st.st_dev) {
     872                        /* its already loaded */
     873                        return LDB_SUCCESS;
     874                }
     875        }
     876
     877        le = talloc(loaded, struct loaded);
     878        if (le == NULL) {
     879                fprintf(stderr, "ldb: unable to allocated loaded entry\n");
     880                return LDB_ERR_UNAVAILABLE;
     881        }
     882
     883        le->st_ino = st.st_ino;
     884        le->st_dev = st.st_dev;
     885
     886        DLIST_ADD_END(loaded, le, struct loaded);
     887
     888        /* if it is a directory, recurse */
     889        if (S_ISDIR(st.st_mode)) {
     890                return ldb_modules_load_dir(path, version);
     891        }
     892
     893        dlopen_flags = RTLD_NOW;
     894#ifdef RTLD_DEEPBIND
     895        /* use deepbind if possible, to avoid issues with different
     896           system library varients, for example ldb modules may be linked
     897           against Heimdal while the application may use MIT kerberos
     898
     899           See the dlopen manpage for details
     900        */
     901        dlopen_flags |= RTLD_DEEPBIND;
    809902#endif
    810903
    811 #ifdef HAVE_LDB_SQLITE3
    812 #define SQLITE3_BACKEND LDB_BACKEND(sqlite3),
    813 #else
    814 #define SQLITE3_BACKEND
    815 #endif
    816 
    817 #define STATIC_LIBLDB_MODULES \
    818         LDB_BACKEND(tdb),       \
    819         LDAP_BACKEND    \
    820         SQLITE3_BACKEND \
    821         LDB_MODULE(rdn_name),   \
    822         LDB_MODULE(paged_results),      \
    823         LDB_MODULE(server_sort),                \
    824         LDB_MODULE(asq), \
    825         NULL
    826 #endif
    827 
    828 /*
    829  * this is a bit hacked, as STATIC_LIBLDB_MODULES contains ','
    830  * between the elements and we want to autogenerate the
    831  * extern struct declarations, so we do some hacks and let the
    832  * ',' appear in an unused function prototype.
    833  */
    834 #undef NULL
    835 #define NULL LDB_MODULE(NULL),
    836 
    837 #define LDB_BACKEND(name) \
    838         int); \
    839         extern const struct ldb_backend_ops ldb_ ## name ## _backend_ops;\
    840         extern void ldb_noop ## name (int
    841 #define LDB_MODULE(name) \
    842         int); \
    843         extern const struct ldb_module_ops ldb_ ## name ## _module_ops;\
    844         extern void ldb_noop ## name (int
    845 
    846 extern void ldb_start_noop(int,
    847 STATIC_LIBLDB_MODULES
    848 int);
    849 
    850 #undef NULL
    851 #define NULL { \
    852         .backend_ops = (void *)0, \
    853         .module_ops = (void *)0 \
    854 }
    855 
    856 #undef LDB_BACKEND
    857 #define LDB_BACKEND(name) { \
    858         .backend_ops = &ldb_ ## name ## _backend_ops, \
    859         .module_ops = (void *)0 \
    860 }
    861 #undef LDB_MODULE
    862 #define LDB_MODULE(name) { \
    863         .backend_ops = (void *)0, \
    864         .module_ops = &ldb_ ## name ## _module_ops \
    865 }
    866 
    867 static const struct ldb_builtins builtins[] = {
    868         STATIC_LIBLDB_MODULES
    869 };
     904        handle = dlopen(path, dlopen_flags);
     905        if (handle == NULL) {
     906                fprintf(stderr, "ldb: unable to dlopen %s : %s\n", path, dlerror());
     907                return LDB_SUCCESS;
     908        }
     909
     910        init_fn = dlsym(handle, "ldb_init_module");
     911        if (init_fn == NULL) {
     912                /* ignore it, it could be an old-style
     913                 * module. Once we've converted all modules we
     914                 * could consider this an error */
     915                dlclose(handle);
     916                return LDB_SUCCESS;
     917        }
     918
     919        ret = init_fn(version);
     920        if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
     921                /* the module is already registered - ignore this, as
     922                 * it can happen if LDB_MODULES_PATH points at both
     923                 * the build and install directory
     924                 */
     925                ret = LDB_SUCCESS;
     926        }
     927        return ret;
     928}
     929
     930static int qsort_string(const char **s1, const char **s2)
     931{
     932        return strcmp(*s1, *s2);
     933}
     934
     935
     936/*
     937  load all modules from the given ldb modules directory. This is run once
     938  during the first ldb_init() call.
     939
     940  Modules are loaded in alphabetical order to ensure that any module
     941  load ordering dependencies are reproducible. Modules should avoid
     942  relying on load order
     943 */
     944static int ldb_modules_load_dir(const char *modules_dir, const char *version)
     945{
     946        DIR *dir;
     947        struct dirent *de;
     948        const char **modlist = NULL;
     949        TALLOC_CTX *tmp_ctx = talloc_new(NULL);
     950        unsigned i, num_modules = 0;
     951
     952        dir = opendir(modules_dir);
     953        if (dir == NULL) {
     954                if (errno == ENOENT) {
     955                        talloc_free(tmp_ctx);
     956                        /* we don't have any modules */
     957                        return LDB_SUCCESS;
     958                }
     959                talloc_free(tmp_ctx);
     960                fprintf(stderr, "ldb: unable to open modules directory '%s' - %s\n",
     961                        modules_dir, strerror(errno));
     962                return LDB_ERR_UNAVAILABLE;
     963        }
     964
     965
     966        while ((de = readdir(dir))) {
     967                if (ISDOT(de->d_name) || ISDOTDOT(de->d_name))
     968                        continue;
     969
     970                modlist = talloc_realloc(tmp_ctx, modlist, const char *, num_modules+1);
     971                if (modlist == NULL) {
     972                        talloc_free(tmp_ctx);
     973                        closedir(dir);
     974                        fprintf(stderr, "ldb: unable to allocate modules list\n");
     975                        return LDB_ERR_UNAVAILABLE;
     976                }
     977                modlist[num_modules] = talloc_asprintf(modlist, "%s/%s", modules_dir, de->d_name);
     978                if (modlist[num_modules] == NULL) {
     979                        talloc_free(tmp_ctx);
     980                        closedir(dir);
     981                        fprintf(stderr, "ldb: unable to allocate module list entry\n");
     982                        return LDB_ERR_UNAVAILABLE;
     983                }
     984                num_modules++;
     985        }
     986
     987        closedir(dir);
     988
     989        /* sort the directory, so we get consistent load ordering */
     990        TYPESAFE_QSORT(modlist, num_modules, qsort_string);
     991
     992        for (i=0; i<num_modules; i++) {
     993                int ret = ldb_modules_load_path(modlist[i], version);
     994                if (ret != LDB_SUCCESS) {
     995                        fprintf(stderr, "ldb: failed to initialise module %s : %s\n",
     996                                modlist[i], ldb_strerror(ret));
     997                        talloc_free(tmp_ctx);
     998                        return ret;
     999                }
     1000        }
     1001
     1002        talloc_free(tmp_ctx);
     1003
     1004        return LDB_SUCCESS;
     1005}
     1006
     1007/*
     1008   load any additional modules from the given directory
     1009*/
     1010void ldb_set_modules_dir(struct ldb_context *ldb, const char *path)
     1011{
     1012        int ret = ldb_modules_load_path(path, LDB_VERSION);
     1013        if (ret != LDB_SUCCESS) {
     1014                ldb_asprintf_errstring(ldb, "Failed to load modules from: %s\n", path);
     1015        }
     1016}
     1017
     1018
     1019/*
     1020  load all modules static (builtin) modules
     1021 */
     1022static int ldb_modules_load_static(const char *version)
     1023{
     1024        static bool initialised;
     1025#define _MODULE_PROTO(init) extern int init(const char *);
     1026        STATIC_ldb_MODULES_PROTO;
     1027        const ldb_module_init_fn static_init_functions[] = { STATIC_ldb_MODULES };
     1028        unsigned i;
     1029
     1030        if (initialised) {
     1031                return LDB_SUCCESS;
     1032        }
     1033        initialised = true;
     1034
     1035        for (i=0; static_init_functions[i]; i++) {
     1036                int ret = static_init_functions[i](version);
     1037                if (ret != LDB_SUCCESS) {
     1038                        return ret;
     1039                }
     1040        }
     1041        return LDB_SUCCESS;
     1042}
     1043
     1044/*
     1045  load all modules from the given ldb modules path, colon
     1046  separated.
     1047
     1048  modules are loaded recursively for all subdirectories in the paths
     1049 */
     1050int ldb_modules_load(const char *modules_path, const char *version)
     1051{
     1052        char *tok, *path, *tok_ptr=NULL;
     1053        int ret;
     1054
     1055        ret = ldb_modules_load_static(version);
     1056        if (ret != LDB_SUCCESS) {
     1057                return ret;
     1058        }
     1059
     1060        path = talloc_strdup(NULL, modules_path);
     1061        if (path == NULL) {
     1062                fprintf(stderr, "ldb: failed to allocate modules_path\n");
     1063                return LDB_ERR_UNAVAILABLE;
     1064        }
     1065
     1066        for (tok=strtok_r(path, ":", &tok_ptr);
     1067             tok;
     1068             tok=strtok_r(NULL, ":", &tok_ptr)) {
     1069                ret = ldb_modules_load_path(tok, version);
     1070                if (ret != LDB_SUCCESS) {
     1071                        talloc_free(path);
     1072                        return ret;
     1073                }
     1074        }
     1075        talloc_free(path);
     1076
     1077        return LDB_SUCCESS;
     1078}
     1079
     1080
     1081/*
     1082  return a string representation of the calling chain for the given
     1083  ldb request
     1084 */
     1085char *ldb_module_call_chain(struct ldb_request *req, TALLOC_CTX *mem_ctx)
     1086{
     1087        char *ret;
     1088        int i=0;
     1089
     1090        ret = talloc_strdup(mem_ctx, "");
     1091        if (ret == NULL) {
     1092                return NULL;
     1093        }
     1094
     1095        while (req && req->handle) {
     1096                char *s = talloc_asprintf_append_buffer(ret, "req[%u] %p  : %s\n",
     1097                                                        i++, req, ldb_req_location(req));
     1098                if (s == NULL) {
     1099                        talloc_free(ret);
     1100                        return NULL;
     1101                }
     1102                ret = s;
     1103                req = req->handle->parent;
     1104        }
     1105        return ret;
     1106}
     1107
     1108
     1109/*
     1110  return the next module in the chain
     1111 */
     1112struct ldb_module *ldb_module_next(struct ldb_module *module)
     1113{
     1114        return module->next;
     1115}
     1116
     1117/*
     1118  set the next module in the module chain
     1119 */
     1120void ldb_module_set_next(struct ldb_module *module, struct ldb_module *next)
     1121{
     1122        module->next = next;
     1123}
     1124
     1125
     1126/*
     1127  get the popt_options pointer in the ldb structure. This allows a ldb
     1128  module to change the command line parsing
     1129 */
     1130struct poptOption **ldb_module_popt_options(struct ldb_context *ldb)
     1131{
     1132        return &ldb->popt_options;
     1133}
     1134
     1135
     1136/*
     1137  return the current ldb flags LDB_FLG_*
     1138 */
     1139uint32_t ldb_module_flags(struct ldb_context *ldb)
     1140{
     1141        return ldb->flags;
     1142}
  • trunk/server/source4/lib/ldb/common/ldb_msg.c

    r414 r745  
    3737  create a new ldb_message in a given memory context (NULL for top level)
    3838*/
    39 struct ldb_message *ldb_msg_new(void *mem_ctx)
     39struct ldb_message *ldb_msg_new(TALLOC_CTX *mem_ctx)
    4040{
    4141        return talloc_zero(mem_ctx, struct ldb_message);
     
    6464{
    6565        if (v1->length != v2->length) return 0;
    66 
     66        if (v1->data == v2->data) return 1;
    6767        if (v1->length == 0) return 1;
    6868
     
    9393  duplicate a ldb_val structure
    9494*/
    95 struct ldb_val ldb_val_dup(void *mem_ctx, const struct ldb_val *v)
     95struct ldb_val ldb_val_dup(TALLOC_CTX *mem_ctx, const struct ldb_val *v)
    9696{
    9797        struct ldb_val v2;
     
    115115}
    116116
    117 /*
    118   add an empty element to a message
    119 */
    120 int ldb_msg_add_empty(  struct ldb_message *msg,
    121                         const char *attr_name,
    122                         int flags,
    123                         struct ldb_message_element **return_el)
     117/**
     118 * Adds new empty element to msg->elements
     119 */
     120static int _ldb_msg_add_el(struct ldb_message *msg,
     121                           struct ldb_message_element **return_el)
    124122{
    125123        struct ldb_message_element *els;
    126124
    127         els = talloc_realloc(msg, msg->elements,
    128                              struct ldb_message_element, msg->num_elements+1);
     125        /*
     126         * TODO: Find out a way to assert on input parameters.
     127         * msg and return_el must be valid
     128         */
     129
     130        els = talloc_realloc(msg, msg->elements,
     131                             struct ldb_message_element, msg->num_elements + 1);
    129132        if (!els) {
    130133                errno = ENOMEM;
     
    132135        }
    133136
    134         els[msg->num_elements].values = NULL;
    135         els[msg->num_elements].num_values = 0;
    136         els[msg->num_elements].flags = flags;
    137         els[msg->num_elements].name = talloc_strdup(els, attr_name);
    138         if (!els[msg->num_elements].name) {
     137        ZERO_STRUCT(els[msg->num_elements]);
     138
     139        msg->elements = els;
     140        msg->num_elements++;
     141
     142        *return_el = &els[msg->num_elements-1];
     143
     144        return LDB_SUCCESS;
     145}
     146
     147/**
     148 * Add an empty element with a given name to a message
     149 */
     150int ldb_msg_add_empty(struct ldb_message *msg,
     151                      const char *attr_name,
     152                      int flags,
     153                      struct ldb_message_element **return_el)
     154{
     155        int ret;
     156        struct ldb_message_element *el;
     157
     158        ret = _ldb_msg_add_el(msg, &el);
     159        if (ret != LDB_SUCCESS) {
     160                return ret;
     161        }
     162
     163        /* initialize newly added element */
     164        el->flags = flags;
     165        el->name = talloc_strdup(msg->elements, attr_name);
     166        if (!el->name) {
    139167                errno = ENOMEM;
    140168                return LDB_ERR_OPERATIONS_ERROR;
    141169        }
    142170
    143         msg->elements = els;
    144         msg->num_elements++;
    145 
    146171        if (return_el) {
    147                 *return_el = &els[msg->num_elements-1];
     172                *return_el = el;
    148173        }
    149174
     
    151176}
    152177
    153 /*
    154   add an empty element to a message
    155 */
     178/**
     179 * Adds an element to a message.
     180 *
     181 * NOTE: Ownership of ldb_message_element fields
     182 *       is NOT transferred. Thus, if *el pointer
     183 *       is invalidated for some reason, this will
     184 *       corrupt *msg contents also
     185 */
    156186int ldb_msg_add(struct ldb_message *msg,
    157187                const struct ldb_message_element *el,
    158188                int flags)
    159189{
     190        int ret;
     191        struct ldb_message_element *el_new;
    160192        /* We have to copy this, just in case *el is a pointer into
    161193         * what ldb_msg_add_empty() is about to realloc() */
    162194        struct ldb_message_element el_copy = *el;
    163         if (ldb_msg_add_empty(msg, el->name, flags, NULL) != 0) {
    164                 return LDB_ERR_OPERATIONS_ERROR;
    165         }
    166 
    167         msg->elements[msg->num_elements-1] = el_copy;
    168         msg->elements[msg->num_elements-1].flags = flags;
     195
     196        ret = _ldb_msg_add_el(msg, &el_new);
     197        if (ret != LDB_SUCCESS) {
     198                return ret;
     199        }
     200
     201        el_new->flags      = flags;
     202        el_new->name       = el_copy.name;
     203        el_new->num_values = el_copy.num_values;
     204        el_new->values     = el_copy.values;
    169205
    170206        return LDB_SUCCESS;
     
    191227        }
    192228
    193         vals = talloc_realloc(msg, el->values, struct ldb_val, el->num_values+1);
     229        vals = talloc_realloc(msg->elements, el->values, struct ldb_val,
     230                              el->num_values+1);
    194231        if (!vals) {
    195232                errno = ENOMEM;
     
    238275
    239276        if (val.length == 0) {
    240                 /* allow empty strings as non-existant attributes */
     277                /* allow empty strings as non-existent attributes */
    241278                return LDB_SUCCESS;
    242279        }
     
    256293        val.length = strlen(str);
    257294
     295        if (val.length == 0) {
     296                /* allow empty strings as non-existent attributes */
     297                return LDB_SUCCESS;
     298        }
     299
    258300        return ldb_msg_add_steal_value(msg, attr_name, &val);
     301}
     302
     303/*
     304  add a DN element to a message
     305  WARNING: this uses the linearized string from the dn, and does not
     306  copy the string.
     307*/
     308int ldb_msg_add_linearized_dn(struct ldb_message *msg, const char *attr_name,
     309                              struct ldb_dn *dn)
     310{
     311        char *str = ldb_dn_alloc_linearized(msg, dn);
     312
     313        if (str == NULL) {
     314                /* we don't want to have unknown DNs added */
     315                return LDB_ERR_OPERATIONS_ERROR;
     316        }
     317
     318        return ldb_msg_add_steal_string(msg, attr_name, str);
    259319}
    260320
     
    283343/*
    284344  compare two ldb_message_element structures
    285   assumes case senistive comparison
     345  assumes case sensitive comparison
    286346*/
    287347int ldb_msg_element_compare(struct ldb_message_element *el1,
     
    342402                                       unsigned int default_value)
    343403{
     404        unsigned int ret;
    344405        const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name);
    345406        if (!v || !v->data) {
    346407                return default_value;
    347408        }
     409
     410        /* in LDAP there're only int32_t values */
     411        errno = 0;
     412        ret = strtol((const char *)v->data, NULL, 0);
     413        if (errno == 0) {
     414                return ret;
     415        }
     416
    348417        return strtoul((const char *)v->data, NULL, 0);
    349418}
     
    364433                                     uint64_t default_value)
    365434{
     435        uint64_t ret;
    366436        const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name);
    367437        if (!v || !v->data) {
    368438                return default_value;
    369439        }
     440
     441        /* in LDAP there're only int64_t values */
     442        errno = 0;
     443        ret = strtoll((const char *)v->data, NULL, 0);
     444        if (errno == 0) {
     445                return ret;
     446        }
     447
    370448        return strtoull((const char *)v->data, NULL, 0);
    371449}
     
    411489
    412490struct ldb_dn *ldb_msg_find_attr_as_dn(struct ldb_context *ldb,
    413                                        void *mem_ctx,
     491                                       TALLOC_CTX *mem_ctx,
    414492                                       const struct ldb_message *msg,
    415493                                       const char *attr_name)
     
    435513void ldb_msg_sort_elements(struct ldb_message *msg)
    436514{
    437         qsort(msg->elements, msg->num_elements, sizeof(struct ldb_message_element),
    438               (comparison_fn_t)ldb_msg_element_compare_name);
     515        TYPESAFE_QSORT(msg->elements, msg->num_elements,
     516                       ldb_msg_element_compare_name);
    439517}
    440518
     
    447525{
    448526        struct ldb_message *msg2;
    449         int i;
     527        unsigned int i;
    450528
    451529        msg2 = talloc(mem_ctx, struct ldb_message);
     
    477555{
    478556        struct ldb_message *msg2;
    479         int i, j;
     557        unsigned int i, j;
    480558
    481559        msg2 = ldb_msg_copy_shallow(mem_ctx, msg);
     
    507585
    508586
    509 /*
    510   canonicalise a message, merging elements of the same name
    511 */
     587/**
     588 * Canonicalize a message, merging elements of the same name
     589 */
    512590struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb,
    513591                                         const struct ldb_message *msg)
    514592{
    515         int i;
     593        int ret;
    516594        struct ldb_message *msg2;
    517595
    518         msg2 = ldb_msg_copy(ldb, msg);
    519         if (msg2 == NULL) return NULL;
     596        /*
     597         * Preserve previous behavior and allocate
     598         * *msg2 into *ldb context
     599         */
     600        ret = ldb_msg_normalize(ldb, ldb, msg, &msg2);
     601        if (ret != LDB_SUCCESS) {
     602                return NULL;
     603        }
     604
     605        return msg2;
     606}
     607
     608/**
     609 * Canonicalize a message, merging elements of the same name
     610 */
     611int ldb_msg_normalize(struct ldb_context *ldb,
     612                      TALLOC_CTX *mem_ctx,
     613                      const struct ldb_message *msg,
     614                      struct ldb_message **_msg_out)
     615{
     616        unsigned int i;
     617        struct ldb_message *msg2;
     618
     619        msg2 = ldb_msg_copy(mem_ctx, msg);
     620        if (msg2 == NULL) {
     621                return LDB_ERR_OPERATIONS_ERROR;
     622        }
    520623
    521624        ldb_msg_sort_elements(msg2);
    522625
    523         for (i=1;i<msg2->num_elements;i++) {
     626        for (i=1; i < msg2->num_elements; i++) {
    524627                struct ldb_message_element *el1 = &msg2->elements[i-1];
    525628                struct ldb_message_element *el2 = &msg2->elements[i];
     629
    526630                if (ldb_msg_element_compare_name(el1, el2) == 0) {
    527                         el1->values = talloc_realloc(msg2->elements, el1->values, struct ldb_val,
    528                                                        el1->num_values + el2->num_values);
    529                         if (el1->values == NULL) {
    530                                 return NULL;
     631                        el1->values = talloc_realloc(msg2->elements,
     632                                                     el1->values, struct ldb_val,
     633                                                     el1->num_values + el2->num_values);
     634                        if (el1->num_values + el2->num_values > 0 && el1->values == NULL) {
     635                                talloc_free(msg2);
     636                                return LDB_ERR_OPERATIONS_ERROR;
    531637                        }
    532638                        memcpy(el1->values + el1->num_values,
     
    535641                        el1->num_values += el2->num_values;
    536642                        talloc_free(discard_const_p(char, el2->name));
    537                         if (i+1<msg2->num_elements) {
    538                                 memmove(el2, el2+1, sizeof(struct ldb_message_element) * 
     643                        if ((i+1) < msg2->num_elements) {
     644                                memmove(el2, el2+1, sizeof(struct ldb_message_element) *
    539645                                        (msg2->num_elements - (i+1)));
    540646                        }
     
    544650        }
    545651
    546         return msg2;
    547 }
    548 
    549 
    550 /*
    551   return a ldb_message representing the differences between msg1 and msg2. If you
    552   then use this in a ldb_modify() call it can be used to save edits to a message
    553 */
     652        *_msg_out = msg2;
     653        return LDB_SUCCESS;
     654}
     655
     656
     657/**
     658 * return a ldb_message representing the differences between msg1 and msg2.
     659 * If you then use this in a ldb_modify() call,
     660 * it can be used to save edits to a message
     661 */
    554662struct ldb_message *ldb_msg_diff(struct ldb_context *ldb,
    555663                                 struct ldb_message *msg1,
    556664                                 struct ldb_message *msg2)
    557665{
     666        int ldb_ret;
     667        struct ldb_message *mod;
     668
     669        ldb_ret = ldb_msg_difference(ldb, ldb, msg1, msg2, &mod);
     670        if (ldb_ret != LDB_SUCCESS) {
     671                return NULL;
     672        }
     673
     674        return mod;
     675}
     676
     677/**
     678 * return a ldb_message representing the differences between msg1 and msg2.
     679 * If you then use this in a ldb_modify() call it can be used to save edits to a message
     680 *
     681 * Result message is constructed as follows:
     682 * - LDB_FLAG_MOD_ADD     - elements found only in msg2
     683 * - LDB_FLAG_MOD_REPLACE - elements in msg2 that have different value in msg1
     684 *                          Value for msg2 element is used
     685 * - LDB_FLAG_MOD_DELETE  - elements found only in msg2
     686 *
     687 * @return LDB_SUCCESS or LDB_ERR_OPERATIONS_ERROR
     688 */
     689int ldb_msg_difference(struct ldb_context *ldb,
     690                       TALLOC_CTX *mem_ctx,
     691                       struct ldb_message *msg1,
     692                       struct ldb_message *msg2,
     693                       struct ldb_message **_msg_out)
     694{
     695        int ldb_res;
     696        unsigned int i;
    558697        struct ldb_message *mod;
    559698        struct ldb_message_element *el;
    560         unsigned int i;
    561 
    562         mod = ldb_msg_new(ldb);
     699        TALLOC_CTX *temp_ctx;
     700
     701        temp_ctx = talloc_new(mem_ctx);
     702        if (!temp_ctx) {
     703                return LDB_ERR_OPERATIONS_ERROR;
     704        }
     705
     706        mod = ldb_msg_new(temp_ctx);
     707        if (mod == NULL) {
     708                goto failed;
     709        }
    563710
    564711        mod->dn = msg1->dn;
     
    566713        mod->elements = NULL;
    567714
    568         msg2 = ldb_msg_canonicalize(ldb, msg2);
    569         if (msg2 == NULL) {
    570                 return NULL;
    571         }
    572        
    573         /* look in msg2 to find elements that need to be added
    574            or modified */
     715        /*
     716         * Canonicalize *msg2 so we have no repeated elements
     717         * Resulting message is allocated in *mod's mem context,
     718         * as we are going to move some elements from *msg2 to
     719         * *mod object later
     720         */
     721        ldb_res = ldb_msg_normalize(ldb, mod, msg2, &msg2);
     722        if (ldb_res != LDB_SUCCESS) {
     723                goto failed;
     724        }
     725
     726        /* look in msg2 to find elements that need to be added or modified */
    575727        for (i=0;i<msg2->num_elements;i++) {
    576728                el = ldb_msg_find_element(msg1, msg2->elements[i].name);
     
    580732                }
    581733
    582                 if (ldb_msg_add(mod,
    583                                 &msg2->elements[i],
    584                                 el?LDB_FLAG_MOD_REPLACE:LDB_FLAG_MOD_ADD) != 0) {
    585                         return NULL;
     734                ldb_res = ldb_msg_add(mod,
     735                                      &msg2->elements[i],
     736                                      el ? LDB_FLAG_MOD_REPLACE : LDB_FLAG_MOD_ADD);
     737                if (ldb_res != LDB_SUCCESS) {
     738                        goto failed;
    586739                }
    587740        }
     
    590743        for (i=0;i<msg1->num_elements;i++) {
    591744                el = ldb_msg_find_element(msg2, msg1->elements[i].name);
    592                 if (!el) {
    593                         if (ldb_msg_add_empty(mod,
    594                                               msg1->elements[i].name,
    595                                               LDB_FLAG_MOD_DELETE, NULL) != 0) {
    596                                 return NULL;
     745                if (el == NULL) {
     746                        ldb_res = ldb_msg_add_empty(mod,
     747                                                    msg1->elements[i].name,
     748                                                    LDB_FLAG_MOD_DELETE, NULL);
     749                        if (ldb_res != LDB_SUCCESS) {
     750                                goto failed;
    597751                        }
    598752                }
    599753        }
    600754
    601         return mod;
    602 }
     755        /* steal resulting message into supplied context */
     756        talloc_steal(mem_ctx, mod);
     757        *_msg_out = mod;
     758
     759        talloc_free(temp_ctx);
     760        return LDB_SUCCESS;
     761
     762failed:
     763        talloc_free(temp_ctx);
     764        return LDB_ERR_OPERATIONS_ERROR;
     765}
     766
    603767
    604768int ldb_msg_sanity_check(struct ldb_context *ldb,
    605769                         const struct ldb_message *msg)
    606770{
    607         int i, j;
     771        unsigned int i, j;
    608772
    609773        /* basic check on DN */
     
    643807{
    644808        const char **ret;
    645         int i;
     809        unsigned int i;
     810
    646811        for (i=0;attrs && attrs[i];i++) /* noop */ ;
    647812        ret = talloc_array(mem_ctx, const char *, i+1);
     
    664829{
    665830        const char **ret;
    666         int i;
     831        unsigned int i;
    667832        bool found = false;
     833
    668834        for (i=0;attrs && attrs[i];i++) {
    669835                if (ldb_attr_cmp(attrs[i], new_attr) == 0) {
     
    692858int ldb_attr_in_list(const char * const *attrs, const char *attr)
    693859{
    694         int i;
     860        unsigned int i;
    695861        for (i=0;attrs && attrs[i];i++) {
    696862                if (ldb_attr_cmp(attrs[i], attr) == 0) {
     
    725891{
    726892        struct ldb_message_element *el = ldb_msg_find_element(msg, attr);
     893        int ret;
     894
    727895        if (el == NULL) {
    728896                return LDB_SUCCESS;
    729897        }
    730         if (ldb_msg_add(msg, el, 0) != 0) {
    731                 return LDB_ERR_OPERATIONS_ERROR;
     898        ret = ldb_msg_add(msg, el, 0);
     899        if (ret != LDB_SUCCESS) {
     900                return ret;
    732901        }
    733902        return ldb_msg_rename_attr(msg, attr, replace);
     
    739908void ldb_msg_remove_element(struct ldb_message *msg, struct ldb_message_element *el)
    740909{
    741         int n = (el - msg->elements);
     910        ptrdiff_t n = (el - msg->elements);
    742911        if (n >= msg->num_elements) {
    743912                /* should we abort() here? */
     
    756925void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr)
    757926{
    758         struct ldb_message_element *el = ldb_msg_find_element(msg, attr);
    759         if (el) {
     927        struct ldb_message_element *el;
     928
     929        while ((el = ldb_msg_find_element(msg, attr)) != NULL) {
    760930                ldb_msg_remove_element(msg, el);
    761931        }
     
    803973       
    804974        memset(&tm, 0, sizeof(tm));
    805         if (sscanf(s, "%04u%02u%02u%02u%02u%02u",
     975        if (sscanf(s, "%04u%02u%02u%02u%02u%02u.0Z",
    806976                   &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
    807977                   &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
     
    812982       
    813983        return timegm(&tm);
     984}
     985
     986/*
     987  convert a LDAP GeneralizedTime string in ldb_val format to a
     988  time_t.
     989*/
     990int ldb_val_to_time(const struct ldb_val *v, time_t *t)
     991{
     992        struct tm tm;
     993
     994        if (v == NULL || !v->data || v->length < 17) {
     995                return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
     996        }
     997
     998        memset(&tm, 0, sizeof(tm));
     999
     1000        if (sscanf((char *)v->data, "%04u%02u%02u%02u%02u%02u.0Z",
     1001                   &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
     1002                   &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
     1003                return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
     1004        }
     1005        tm.tm_year -= 1900;
     1006        tm.tm_mon -= 1;
     1007
     1008        *t = timegm(&tm);
     1009
     1010        return LDB_SUCCESS;
    8141011}
    8151012
     
    8551052       
    8561053        memset(&tm, 0, sizeof(tm));
    857         if (sscanf(s, "%02u%02u%02u%02u%02u%02u",
     1054        if (sscanf(s, "%02u%02u%02u%02u%02u%02uZ",
    8581055                   &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
    8591056                   &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
     
    8741071void ldb_dump_results(struct ldb_context *ldb, struct ldb_result *result, FILE *f)
    8751072{
    876         int i;
     1073        unsigned int i;
    8771074
    8781075        for (i = 0; i < result->count; i++) {
     
    8851082}
    8861083
    887 int ldb_msg_check_string_attribute(const struct ldb_message *msg, const char *name, const char *value)
     1084/*
     1085  checks for a string attribute. Returns "1" on match and otherwise "0".
     1086*/
     1087int ldb_msg_check_string_attribute(const struct ldb_message *msg,
     1088                                   const char *name, const char *value)
    8881089{
    8891090        struct ldb_message_element *el;
     
    8911092       
    8921093        el = ldb_msg_find_element(msg, name);
    893         if (el == NULL)
     1094        if (el == NULL) {
    8941095                return 0;
     1096        }
    8951097
    8961098        val.data = discard_const_p(uint8_t, value);
    8971099        val.length = strlen(value);
    8981100
    899         if (ldb_msg_find_val(el, &val))
     1101        if (ldb_msg_find_val(el, &val)) {
    9001102                return 1;
     1103        }
    9011104
    9021105        return 0;
    9031106}
     1107
  • trunk/server/source4/lib/ldb/common/ldb_parse.c

    r414 r745  
    4343#include "ldb_private.h"
    4444#include "system/locale.h"
     45
     46static int ldb_parse_hex2char(const char *x)
     47{
     48        if (isxdigit(x[0]) && isxdigit(x[1])) {
     49                const char h1 = x[0], h2 = x[1];
     50                int c = 0;
     51
     52                if (h1 >= 'a') c = h1 - (int)'a' + 10;
     53                else if (h1 >= 'A') c = h1 - (int)'A' + 10;
     54                else if (h1 >= '0') c = h1 - (int)'0';
     55                c = c << 4;
     56                if (h2 >= 'a') c += h2 - (int)'a' + 10;
     57                else if (h2 >= 'A') c += h2 - (int)'A' + 10;
     58                else if (h2 >= '0') c += h2 - (int)'0';
     59
     60                return c;
     61        }
     62
     63        return -1;
     64}
    4565
    4666/*
     
    6080   Used in LDAP filters.
    6181*/
    62 struct ldb_val ldb_binary_decode(void *mem_ctx, const char *str)
    63 {
    64         int i, j;
     82struct ldb_val ldb_binary_decode(TALLOC_CTX *mem_ctx, const char *str)
     83{
     84        size_t i, j;
    6585        struct ldb_val ret;
    66         int slen = str?strlen(str):0;
     86        size_t slen = str?strlen(str):0;
    6787
    6888        ret.data = (uint8_t *)talloc_size(mem_ctx, slen+1);
     
    7292        for (i=j=0;i<slen;i++) {
    7393                if (str[i] == '\\') {
    74                         unsigned c;
    75                         if (sscanf(&str[i+1], "%02X", &c) != 1) {
     94                        int c;
     95
     96                        c = ldb_parse_hex2char(&str[i+1]);
     97                        if (c == -1) {
    7698                                talloc_free(ret.data);
    7799                                memset(&ret, 0, sizeof(ret));
     
    95117   non-printable or '\' characters
    96118*/
    97 char *ldb_binary_encode(void *mem_ctx, struct ldb_val val)
    98 {
    99         int i;
     119char *ldb_binary_encode(TALLOC_CTX *mem_ctx, struct ldb_val val)
     120{
     121        size_t i;
    100122        char *ret;
    101         int len = val.length;
     123        size_t len = val.length;
    102124        unsigned char *buf = val.data;
    103125
     
    130152   in escaping user data in ldap filters.
    131153*/
    132 char *ldb_binary_encode_string(void *mem_ctx, const char *string)
     154char *ldb_binary_encode_string(TALLOC_CTX *mem_ctx, const char *string)
    133155{
    134156        struct ldb_val val;
     157        if (string == NULL) {
     158                return NULL;
     159        }
    135160        val.data = discard_const_p(uint8_t, string);
    136161        val.length = strlen(string);
     
    160185   chunks separated by wildcards that makes the value portion of the filter
    161186*/
    162 static struct ldb_val **ldb_wildcard_decode(void *mem_ctx, const char *string)
     187static struct ldb_val **ldb_wildcard_decode(TALLOC_CTX *mem_ctx, const char *string)
    163188{
    164189        struct ldb_val **ret = NULL;
    165         int val = 0;
     190        unsigned int val = 0;
    166191        char *wc, *str;
    167192
     
    200225}
    201226
    202 static struct ldb_parse_tree *ldb_parse_filter(void *mem_ctx, const char **s);
     227static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, const char **s);
    203228
    204229
     
    254279}
    255280
    256 static enum ldb_parse_op ldb_parse_filtertype(void *mem_ctx, char **type, char **value, const char **s)
     281static enum ldb_parse_op ldb_parse_filtertype(TALLOC_CTX *mem_ctx, char **type, char **value, const char **s)
    257282{
    258283        enum ldb_parse_op filter = 0;
     
    352377  <simple> ::= <attributetype> <filtertype> <attributevalue>
    353378*/
    354 static struct ldb_parse_tree *ldb_parse_simple(void *mem_ctx, const char **s)
     379static struct ldb_parse_tree *ldb_parse_simple(TALLOC_CTX *mem_ctx, const char **s)
    355380{
    356381        char *attr, *value;
     
    467492  <filterlist> ::= <filter> | <filter> <filterlist>
    468493*/
    469 static struct ldb_parse_tree *ldb_parse_filterlist(void *mem_ctx, const char **s)
     494static struct ldb_parse_tree *ldb_parse_filterlist(TALLOC_CTX *mem_ctx, const char **s)
    470495{
    471496        struct ldb_parse_tree *ret, *next;
     
    535560  <not> ::= '!' <filter>
    536561*/
    537 static struct ldb_parse_tree *ldb_parse_not(void *mem_ctx, const char **s)
     562static struct ldb_parse_tree *ldb_parse_not(TALLOC_CTX *mem_ctx, const char **s)
    538563{
    539564        struct ldb_parse_tree *ret;
     
    567592  <filtercomp> ::= <and> | <or> | <not> | <simple>
    568593*/
    569 static struct ldb_parse_tree *ldb_parse_filtercomp(void *mem_ctx, const char **s)
     594static struct ldb_parse_tree *ldb_parse_filtercomp(TALLOC_CTX *mem_ctx, const char **s)
    570595{
    571596        struct ldb_parse_tree *ret;
     
    604629  <filter> ::= '(' <filtercomp> ')'
    605630*/
    606 static struct ldb_parse_tree *ldb_parse_filter(void *mem_ctx, const char **s)
     631static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, const char **s)
    607632{
    608633        struct ldb_parse_tree *ret;
     
    636661  expression ::= <simple> | <filter>
    637662*/
    638 struct ldb_parse_tree *ldb_parse_tree(void *mem_ctx, const char *s)
     663struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s)
    639664{
    640665        if (s == NULL || *s == 0) {
     
    655680  construct a ldap parse filter given a parse tree
    656681*/
    657 char *ldb_filter_from_tree(void *mem_ctx, struct ldb_parse_tree *tree)
     682char *ldb_filter_from_tree(TALLOC_CTX *mem_ctx, const struct ldb_parse_tree *tree)
    658683{
    659684        char *s, *s2, *ret;
    660         int i;
     685        unsigned int i;
    661686
    662687        if (tree == NULL) {
     
    774799
    775800/*
    776   replace any occurances of an attribute name in the parse tree with a
     801  replace any occurrences of an attribute name in the parse tree with a
    777802  new name
    778803*/
     
    781806                                 const char *replace)
    782807{
    783         int i;
     808        unsigned int i;
    784809        switch (tree->operation) {
    785810        case LDB_OP_AND:
     
    827852                                                   const struct ldb_parse_tree *ot)
    828853{
    829         int i;
     854        unsigned int i;
    830855        struct ldb_parse_tree *nt;
    831856
  • trunk/server/source4/lib/ldb/common/ldb_utf8.c

    r414 r745  
    5454  NOTE: does not handle UTF8
    5555*/
    56 char *ldb_casefold_default(void *context, void *mem_ctx, const char *s, size_t n)
     56char *ldb_casefold_default(void *context, TALLOC_CTX *mem_ctx, const char *s, size_t n)
    5757{
    58         int i;
     58        size_t i;
    5959        char *ret = talloc_strndup(mem_ctx, s, n);
    6060        if (!s) {
     
    7373}
    7474
    75 char *ldb_casefold(struct ldb_context *ldb, void *mem_ctx, const char *s, size_t n)
     75char *ldb_casefold(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *s, size_t n)
    7676{
    7777        return ldb->utf8_fns.casefold(ldb->utf8_fns.context, mem_ctx, s, n);
     
    8585int ldb_valid_attr_name(const char *s)
    8686{
    87         int i;
     87        size_t i;
    8888
    8989        if (!s || !s[0])
     
    110110}
    111111
    112 char *ldb_attr_casefold(void *mem_ctx, const char *s)
     112char *ldb_attr_casefold(TALLOC_CTX *mem_ctx, const char *s)
    113113{
    114         int i;
     114        size_t i;
    115115        char *ret = talloc_strdup(mem_ctx, s);
    116116        if (!ret) {
Note: See TracChangeset for help on using the changeset viewer.