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

Samba Server: update vendor to 3.6.0

Location:
vendor/current/source4/lib/ldb
Files:
27 added
29 deleted
64 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source4/lib/ldb/common/attrib_handlers.c

    r414 r740  
    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}
  • vendor/current/source4/lib/ldb/common/ldb.c

    r414 r740  
    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}
  • vendor/current/source4/lib/ldb/common/ldb_attributes.c

    r414 r740  
    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) {
  • vendor/current/source4/lib/ldb/common/ldb_controls.c

    r414 r740  
    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
  • vendor/current/source4/lib/ldb/common/ldb_dn.c

    r414 r740  
    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}
  • vendor/current/source4/lib/ldb/common/ldb_ldif.c

    r414 r740  
    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                }
  • vendor/current/source4/lib/ldb/common/ldb_match.c

    r414 r740  
    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                             
  • vendor/current/source4/lib/ldb/common/ldb_modules.c

    r414 r740  
    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}
  • vendor/current/source4/lib/ldb/common/ldb_msg.c

    r414 r740  
    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
  • vendor/current/source4/lib/ldb/common/ldb_parse.c

    r414 r740  
    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
  • vendor/current/source4/lib/ldb/common/ldb_utf8.c

    r414 r740  
    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) {
  • vendor/current/source4/lib/ldb/include/dlinklist.h

    r414 r740  
    22   Unix SMB/CIFS implementation.
    33   some simple double linked list macros
    4    Copyright (C) Andrew Tridgell 1998
     4
     5   Copyright (C) Andrew Tridgell 1998-2010
     6
     7     ** NOTE! The following LGPL license applies to the ldb
     8     ** library. This does NOT imply that all of Samba is released
     9     ** under the LGPL
    510   
    6    This program is free software; you can redistribute it and/or modify
    7    it under the terms of the GNU General Public License as published by
    8    the Free Software Foundation; either version 3 of the License, or
    9    (at your option) any later version.
    10    
    11    This program is distributed in the hope that it will be useful,
     11   This library is free software; you can redistribute it and/or
     12   modify it under the terms of the GNU Lesser General Public
     13   License as published by the Free Software Foundation; either
     14   version 3 of the License, or (at your option) any later version.
     15
     16   This library is distributed in the hope that it will be useful,
    1217   but WITHOUT ANY WARRANTY; without even the implied warranty of
    13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14    GNU General Public License for more details.
    15    
    16    You should have received a copy of the GNU General Public License
    17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
     18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     19   Lesser General Public License for more details.
     20
     21   You should have received a copy of the GNU Lesser General Public
     22   License along with this library; if not, see <http://www.gnu.org/licenses/>.
    1823*/
    1924
     
    2429#define _DLINKLIST_H
    2530
     31/*
     32  February 2010 - changed list format to have a prev pointer from the
     33  list head. This makes DLIST_ADD_END() O(1) even though we only have
     34  one list pointer.
    2635
    27 /* hook into the front of the list */
     36  The scheme is as follows:
     37
     38     1) with no entries in the list:
     39          list_head == NULL
     40
     41     2) with 1 entry in the list:
     42          list_head->next == NULL
     43          list_head->prev == list_head
     44
     45     3) with 2 entries in the list:
     46          list_head->next == element2
     47          list_head->prev == element2
     48          element2->prev == list_head
     49          element2->next == NULL
     50
     51     4) with N entries in the list:
     52          list_head->next == element2
     53          list_head->prev == elementN
     54          elementN->prev == element{N-1}
     55          elementN->next == NULL
     56
     57  This allows us to find the tail of the list by using
     58  list_head->prev, which means we can add to the end of the list in
     59  O(1) time
     60
     61
     62  Note that the 'type' arguments below are no longer needed, but
     63  are kept for now to prevent an incompatible argument change
     64 */
     65
     66
     67/*
     68   add an element at the front of a list
     69*/
    2870#define DLIST_ADD(list, p) \
    2971do { \
    3072        if (!(list)) { \
    31                 (list) = (p); \
    32                 (p)->next = (p)->prev = NULL; \
     73                (p)->prev = (list) = (p); \
     74                (p)->next = NULL; \
    3375        } else { \
     76                (p)->prev = (list)->prev; \
    3477                (list)->prev = (p); \
    3578                (p)->next = (list); \
    36                 (p)->prev = NULL; \
    3779                (list) = (p); \
    38         }\
     80        } \
    3981} while (0)
    4082
    41 /* remove an element from a list - element doesn't have to be in list. */
     83/*
     84   remove an element from a list
     85   Note that the element doesn't have to be in the list. If it
     86   isn't then this is a no-op
     87*/
    4288#define DLIST_REMOVE(list, p) \
    4389do { \
    4490        if ((p) == (list)) { \
     91                if ((p)->next) (p)->next->prev = (p)->prev; \
    4592                (list) = (p)->next; \
    46                 if (list) (list)->prev = NULL; \
     93        } else if ((list) && (p) == (list)->prev) {     \
     94                (p)->prev->next = NULL; \
     95                (list)->prev = (p)->prev; \
    4796        } else { \
    4897                if ((p)->prev) (p)->prev->next = (p)->next; \
    4998                if ((p)->next) (p)->next->prev = (p)->prev; \
    5099        } \
    51         if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
     100        if ((p) != (list)) (p)->next = (p)->prev = NULL;        \
    52101} while (0)
    53102
    54 /* promote an element to the top of the list */
    55 #define DLIST_PROMOTE(list, p) \
     103/*
     104   find the head of the list given any element in it.
     105   Note that this costs O(N), so you should avoid this macro
     106   if at all possible!
     107*/
     108#define DLIST_HEAD(p, result_head) \
    56109do { \
    57           DLIST_REMOVE(list, p); \
    58           DLIST_ADD(list, p); \
    59 } while (0)
     110       (result_head) = (p); \
     111       while (DLIST_PREV(result_head)) (result_head) = (result_head)->prev; \
     112} while(0)
    60113
    61 /* hook into the end of the list - needs the entry type */
    62 #define DLIST_ADD_END(list, p, type) \
    63 do { \
    64                 if (!(list)) { \
    65                         (list) = (p); \
    66                         (p)->next = (p)->prev = NULL; \
    67                 } else { \
    68                         type tmp; \
    69                         for (tmp = (list); tmp->next; tmp = tmp->next) ; \
    70                         tmp->next = (p); \
    71                         (p)->next = NULL; \
    72                         (p)->prev = tmp; \
    73                 } \
    74 } while (0)
     114/* return the last element in the list */
     115#define DLIST_TAIL(list) ((list)?(list)->prev:NULL)
     116
     117/* return the previous element in the list. */
     118#define DLIST_PREV(p) (((p)->prev && (p)->prev->next != NULL)?(p)->prev:NULL)
    75119
    76120/* insert 'p' after the given element 'el' in a list. If el is NULL then
     
    81125                DLIST_ADD(list, p); \
    82126        } else { \
    83                 p->prev = el; \
    84                 p->next = el->next; \
    85                 el->next = p; \
    86                 if (p->next) p->next->prev = p; \
     127                (p)->prev = (el);   \
     128                (p)->next = (el)->next;         \
     129                (el)->next = (p);               \
     130                if ((p)->next) (p)->next->prev = (p);   \
     131                if ((list)->prev == (el)) (list)->prev = (p); \
    87132        }\
    88133} while (0)
    89134
    90 /* demote an element to the end of the list, needs the entry type */
    91 #define DLIST_DEMOTE(list, p, type) \
     135
     136/*
     137   add to the end of a list.
     138   Note that 'type' is ignored
     139*/
     140#define DLIST_ADD_END(list, p, type)                    \
    92141do { \
    93                 DLIST_REMOVE(list, p); \
    94                 DLIST_ADD_END(list, p, type); \
     142        if (!(list)) { \
     143                DLIST_ADD(list, p); \
     144        } else { \
     145                DLIST_ADD_AFTER(list, p, (list)->prev); \
     146        } \
    95147} while (0)
    96148
    97 /* concatenate two lists - putting all elements of the 2nd list at the
    98    end of the first list */
    99 #define DLIST_CONCATENATE(list1, list2, type) \
     149/* promote an element to the from of a list */
     150#define DLIST_PROMOTE(list, p) \
    100151do { \
    101                 if (!(list1)) { \
    102                         (list1) = (list2); \
    103                 } else { \
    104                         type tmp; \
    105                         for (tmp = (list1); tmp->next; tmp = tmp->next) ; \
    106                         tmp->next = (list2); \
    107                         if (list2) { \
    108                                 (list2)->prev = tmp;    \
    109                         } \
     152          DLIST_REMOVE(list, p); \
     153          DLIST_ADD(list, p); \
     154} while (0)
     155
     156/*
     157   demote an element to the end of a list.
     158   Note that 'type' is ignored
     159*/
     160#define DLIST_DEMOTE(list, p, type)                     \
     161do { \
     162        DLIST_REMOVE(list, p); \
     163        DLIST_ADD_END(list, p, NULL);           \
     164} while (0)
     165
     166/*
     167   concatenate two lists - putting all elements of the 2nd list at the
     168   end of the first list.
     169   Note that 'type' is ignored
     170*/
     171#define DLIST_CONCATENATE(list1, list2, type)   \
     172do { \
     173        if (!(list1)) { \
     174                (list1) = (list2); \
     175        } else { \
     176                (list1)->prev->next = (list2); \
     177                if (list2) { \
     178                        void *_tmplist = (void *)(list1)->prev; \
     179                        (list1)->prev = (list2)->prev; \
     180                        (list2)->prev = _tmplist; \
    110181                } \
     182        } \
    111183} while (0)
    112184
  • vendor/current/source4/lib/ldb/include/ldb.h

    r414 r740  
    4848
    4949#include <stdbool.h>
    50 #include "talloc.h"
    51 #include "tevent.h"
    52 #include "ldb_errors.h"
     50#include <talloc.h>
     51#include <tevent.h>
     52#include <ldb_version.h>
     53#include <ldb_errors.h>
    5354
    5455/*
     
    8687#ifndef PRINTF_ATTRIBUTE
    8788#define PRINTF_ATTRIBUTE(a,b)
     89#endif
     90
     91#ifndef _DEPRECATED_
     92#if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 )
     93#define _DEPRECATED_ __attribute__ ((deprecated))
     94#else
     95#define _DEPRECATED_
     96#endif
    8897#endif
    8998/*! \endcond */
     
    103112
    104113/**
     114  use this to extract the mod type from the operation
     115 */
     116#define LDB_FLAG_MOD_TYPE(flags) ((flags) & LDB_FLAG_MOD_MASK)
     117
     118/**
    105119   Flag value used in ldap_modify() to indicate that attributes are
    106120   being added.
     
    125139*/
    126140#define LDB_FLAG_MOD_DELETE  3
     141
     142/**
     143    flag bits on an element usable only by the internal implementation
     144*/
     145#define LDB_FLAG_INTERNAL_MASK 0xFFFFFFF0
    127146
    128147/**
     
    297316
    298317struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s);
    299 char *ldb_filter_from_tree(TALLOC_CTX *mem_ctx, struct ldb_parse_tree *tree);
     318char *ldb_filter_from_tree(TALLOC_CTX *mem_ctx, const struct ldb_parse_tree *tree);
    300319
    301320/**
     
    336355typedef int (*ldb_attr_handler_t)(struct ldb_context *, TALLOC_CTX *mem_ctx, const struct ldb_val *, struct ldb_val *);
    337356typedef int (*ldb_attr_comparison_t)(struct ldb_context *, TALLOC_CTX *mem_ctx, const struct ldb_val *, const struct ldb_val *);
     357struct ldb_schema_attribute;
     358typedef int (*ldb_attr_operator_t)(struct ldb_context *, enum ldb_parse_op operation,
     359                                   const struct ldb_schema_attribute *a,
     360                                   const struct ldb_val *, const struct ldb_val *, bool *matched);
    338361
    339362/*
     
    353376        ldb_attr_handler_t canonicalise_fn;
    354377        ldb_attr_comparison_t comparison_fn;
     378        ldb_attr_operator_t operator_fn;
    355379};
    356380
     
    457481typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque);
    458482
     483/* Individual controls */
     484
     485/**
     486  OID for getting and manipulating attributes from the ldb
     487  without interception in the operational module.
     488  It can be used to access attribute that used to be stored in the sam
     489  and that are now calculated.
     490*/
     491#define LDB_CONTROL_BYPASS_OPERATIONAL_OID "1.3.6.1.4.1.7165.4.3.13"
     492#define LDB_CONTROL_BYPASS_OPERATIONAL_NAME "bypassoperational"
     493
     494/**
     495  OID for recalculate SD control. This control force the
     496  dsdb code to recalculate the SD of the object as if the
     497  object was just created.
     498
     499*/
     500#define LDB_CONTROL_RECALCULATE_SD_OID "1.3.6.1.4.1.7165.4.3.5"
     501#define LDB_CONTROL_RECALCULATE_SD_NAME "recalculate_sd"
     502
     503/**
     504   REVEAL_INTERNALS is used to reveal internal attributes and DN
     505   components which are not normally shown to the user
     506*/
     507#define LDB_CONTROL_REVEAL_INTERNALS "1.3.6.1.4.1.7165.4.3.6"
     508#define LDB_CONTROL_REVEAL_INTERNALS_NAME       "reveal_internals"
     509
     510/**
     511   LDB_CONTROL_AS_SYSTEM is used to skip access checks on operations
     512   that are performed by the system, but with a user's credentials, e.g.
     513   updating prefix map
     514*/
     515#define LDB_CONTROL_AS_SYSTEM_OID "1.3.6.1.4.1.7165.4.3.7"
     516
     517/**
     518   LDB_CONTROL_PROVISION_OID is used to skip some constraint checks. It's is
     519   mainly thought to be used for the provisioning.
     520*/
     521#define LDB_CONTROL_PROVISION_OID "1.3.6.1.4.1.7165.4.3.16"
     522#define LDB_CONTROL_PROVISION_NAME      "provision"
     523
     524/* AD controls */
     525
    459526/**
    460527   OID for the paged results control. This control is included in the
     
    466533*/
    467534#define LDB_CONTROL_PAGED_RESULTS_OID   "1.2.840.113556.1.4.319"
     535#define LDB_CONTROL_PAGED_RESULTS_NAME  "paged_result"
    468536
    469537/**
     
    473541*/
    474542#define LDB_CONTROL_SD_FLAGS_OID        "1.2.840.113556.1.4.801"
     543#define LDB_CONTROL_SD_FLAGS_NAME       "sd_flags"
    475544
    476545/**
     
    480549*/
    481550#define LDB_CONTROL_DOMAIN_SCOPE_OID    "1.2.840.113556.1.4.1339"
     551#define LDB_CONTROL_DOMAIN_SCOPE_NAME   "domain_scope"
    482552
    483553/**
     
    487557*/
    488558#define LDB_CONTROL_SEARCH_OPTIONS_OID  "1.2.840.113556.1.4.1340"
     559#define LDB_CONTROL_SEARCH_OPTIONS_NAME "search_options"
    489560
    490561/**
     
    494565*/
    495566#define LDB_CONTROL_NOTIFICATION_OID    "1.2.840.113556.1.4.528"
     567#define LDB_CONTROL_NOTIFICATION_NAME   "notification"
     568
     569/**
     570   OID for performing subtree deletes
     571
     572   \sa <a href="http://msdn.microsoft.com/en-us/library/aa366991(v=VS.85).aspx">Microsoft documentation of this OID</a>
     573*/
     574#define LDB_CONTROL_TREE_DELETE_OID     "1.2.840.113556.1.4.805"
     575#define LDB_CONTROL_TREE_DELETE_NAME    "tree_delete"
    496576
    497577/**
     
    501581*/
    502582#define LDB_CONTROL_SHOW_DELETED_OID    "1.2.840.113556.1.4.417"
     583#define LDB_CONTROL_SHOW_DELETED_NAME   "show_deleted"
    503584
    504585/**
     
    508589*/
    509590#define LDB_CONTROL_SHOW_RECYCLED_OID         "1.2.840.113556.1.4.2064"
     591#define LDB_CONTROL_SHOW_RECYCLED_NAME  "show_recycled"
    510592
    511593/**
     
    515597*/
    516598#define LDB_CONTROL_SHOW_DEACTIVATED_LINK_OID "1.2.840.113556.1.4.2065"
     599#define LDB_CONTROL_SHOW_DEACTIVATED_LINK_NAME  "show_deactivated_link"
    517600
    518601/**
     
    522605*/
    523606#define LDB_CONTROL_EXTENDED_DN_OID     "1.2.840.113556.1.4.529"
     607#define LDB_CONTROL_EXTENDED_DN_NAME    "extended_dn"
    524608
    525609/**
     
    536620*/
    537621#define LDB_CONTROL_SERVER_SORT_OID     "1.2.840.113556.1.4.473"
     622#define LDB_CONTROL_SERVER_SORT_NAME    "server_sort"
    538623
    539624/**
     
    547632*/
    548633#define LDB_CONTROL_SORT_RESP_OID       "1.2.840.113556.1.4.474"
     634#define LDB_CONTROL_SORT_RESP_NAME      "server_sort_resp"
    549635
    550636/**
     
    555641*/
    556642#define LDB_CONTROL_ASQ_OID             "1.2.840.113556.1.4.1504"
     643#define LDB_CONTROL_ASQ_NAME    "asq"
    557644
    558645/**
     
    563650*/
    564651#define LDB_CONTROL_DIRSYNC_OID         "1.2.840.113556.1.4.841"
     652#define LDB_CONTROL_DIRSYNC_NAME        "dirsync"
    565653
    566654
     
    572660*/
    573661#define LDB_CONTROL_VLV_REQ_OID         "2.16.840.1.113730.3.4.9"
     662#define LDB_CONTROL_VLV_REQ_NAME        "vlv"
    574663
    575664/**
     
    580669*/
    581670#define LDB_CONTROL_VLV_RESP_OID        "2.16.840.1.113730.3.4.10"
     671#define LDB_CONTROL_VLV_RESP_NAME       "vlv_resp"
    582672
    583673/**
     
    588678*/
    589679#define LDB_CONTROL_PERMISSIVE_MODIFY_OID       "1.2.840.113556.1.4.1413"
     680#define LDB_CONTROL_PERMISSIVE_MODIFY_NAME      "permissive_modify"
     681
     682/**
     683    OID to allow the server to be more 'fast and loose' with the data being added. 
     684
     685    \sa <a href="http://msdn.microsoft.com/en-us/library/aa366982(v=VS.85).aspx">Microsoft documentation of this OID</a>
     686*/
     687#define LDB_CONTROL_SERVER_LAZY_COMMIT   "1.2.840.113556.1.4.619"
     688
     689/**
     690   Control for RODC join -see [MS-ADTS] section 3.1.1.3.4.1.23
     691
     692   \sa <a href="">Microsoft documentation of this OID</a>
     693*/
     694#define LDB_CONTROL_RODC_DCPROMO_OID "1.2.840.113556.1.4.1341"
     695#define LDB_CONTROL_RODC_DCPROMO_NAME   "rodc_join"
     696
     697/* Other standardised controls */
     698
     699/**
     700   OID for the allowing client to request temporary relaxed
     701   enforcement of constraints of the x.500 model.
     702
     703   Mainly used for the OpenLDAP backend.
     704
     705   \sa <a href="http://opends.dev.java.net/public/standards/draft-zeilenga-ldap-managedit.txt">draft managedit</a>.
     706*/
     707#define LDB_CONTROL_RELAX_OID "1.3.6.1.4.1.4203.666.5.12"
     708#define LDB_CONTROL_RELAX_NAME  "relax"
     709
     710/* Extended operations */
     711
     712/**
     713   OID for LDAP Extended Operation SEQUENCE_NUMBER
     714
     715   This extended operation is used to retrieve the extended sequence number.
     716*/
     717#define LDB_EXTENDED_SEQUENCE_NUMBER    "1.3.6.1.4.1.7165.4.4.3"
     718
     719/**
     720   OID for LDAP Extended Operation PASSWORD_CHANGE.
     721
     722   This Extended operation is used to allow user password changes by the user
     723   itself.
     724*/
     725#define LDB_EXTENDED_PASSWORD_CHANGE_OID        "1.3.6.1.4.1.4203.1.11.1"
     726
     727
     728/**
     729   OID for LDAP Extended Operation FAST_BIND
     730
     731   This Extended operations is used to perform a fast bind.
     732*/
     733#define LDB_EXTENDED_FAST_BIND_OID      "1.2.840.113556.1.4.1781"
    590734
    591735/**
    592736   OID for LDAP Extended Operation START_TLS.
    593737
    594    This Extended operation is used to start a new TLS
    595    channel on top of a clear text channel.
     738   This Extended operation is used to start a new TLS channel on top of a clear
     739   text channel.
    596740*/
    597741#define LDB_EXTENDED_START_TLS_OID      "1.3.6.1.4.1.1466.20037"
    598742
    599743/**
     744   OID for LDAP Extended Operation DYNAMIC_REFRESH.
     745
     746   This Extended operation is used to create and maintain objects which exist
     747   only a specific time, e.g. when a certain client or a certain person is
     748   logged in. Data refreshes have to be periodically sent in a specific
     749   interval. Otherwise the entry is going to be removed.
    600750*/
    601751#define LDB_EXTENDED_DYNAMIC_OID        "1.3.6.1.4.1.1466.101.119.1"
    602 
    603 /**
    604 */
    605 #define LDB_EXTENDED_FAST_BIND_OID      "1.2.840.113556.1.4.1781"
    606752
    607753struct ldb_sd_flags_control {
     
    736882};
    737883
    738 #define LDB_EXTENDED_SEQUENCE_NUMBER    "1.3.6.1.4.1.7165.4.4.3"
    739 
    740884enum ldb_sequence_type {
    741885        LDB_SEQ_HIGHEST_SEQ,
     
    9641108int ldb_op_default_callback(struct ldb_request *req, struct ldb_reply *ares);
    9651109
     1110int ldb_modify_default_callback(struct ldb_request *req, struct ldb_reply *ares);
    9661111
    9671112/**
     
    11181263
    11191264/**
     1265  replace a ldb_control in a ldb_request
     1266
     1267  \param req the request struct where to add the control
     1268  \param oid the object identifier of the control as string
     1269  \param critical whether the control should be critical or not
     1270  \param data a talloc pointer to the control specific data
     1271
     1272  \return result code (LDB_SUCCESS on success, or a failure code)
     1273*/
     1274int ldb_request_replace_control(struct ldb_request *req, const char *oid, bool critical, void *data);
     1275
     1276/**
    11201277   check if a control with the specified "oid" exist and return it
    11211278  \param req the request struct where to add the control
     
    13091466int ldb_transaction_cancel(struct ldb_context *ldb);
    13101467
     1468/*
     1469  cancel a transaction with no error if no transaction is pending
     1470  used when we fork() to clear any parent transactions
     1471*/
     1472int ldb_transaction_cancel_noerr(struct ldb_context *ldb);
     1473
    13111474
    13121475/**
     
    15511714  \param mode Style of extended DN to return (0 is HEX representation of binary form, 1 is a string form)
    15521715*/
    1553 char *ldb_dn_get_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode);
     1716char *ldb_dn_get_extended_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int mode);
    15541717const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn, const char *name);
    15551718int ldb_dn_set_extended_component(struct ldb_dn *dn, const char *name, const struct ldb_val *val);
    1556 
     1719void ldb_dn_extended_filter(struct ldb_dn *dn, const char * const *accept_list);
    15571720void ldb_dn_remove_extended_components(struct ldb_dn *dn);
    15581721bool ldb_dn_has_extended(struct ldb_dn *dn);
     
    15911754*/
    15921755
    1593 struct ldb_dn *ldb_dn_from_ldb_val(void *mem_ctx, struct ldb_context *ldb, const struct ldb_val *strdn);
     1756struct ldb_dn *ldb_dn_from_ldb_val(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const struct ldb_val *strdn);
    15941757
    15951758/**
     
    16201783char *ldb_dn_canonical_ex_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn);
    16211784int ldb_dn_get_comp_num(struct ldb_dn *dn);
     1785int ldb_dn_get_extended_comp_num(struct ldb_dn *dn);
    16221786const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num);
    16231787const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn, unsigned int num);
     
    16301794bool ldb_dn_check_special(struct ldb_dn *dn, const char *check);
    16311795bool ldb_dn_is_null(struct ldb_dn *dn);
     1796int ldb_dn_update_components(struct ldb_dn *dn, const struct ldb_dn *ref_dn);
    16321797
    16331798
     
    17131878int ldb_msg_add_string(struct ldb_message *msg,
    17141879                       const char *attr_name, const char *str);
     1880int ldb_msg_add_linearized_dn(struct ldb_message *msg, const char *attr_name,
     1881                              struct ldb_dn *dn);
    17151882int ldb_msg_add_fmt(struct ldb_message *msg,
    17161883                    const char *attr_name, const char *fmt, ...) PRINTF_ATTRIBUTE(3,4);
     
    17661933                                 const struct ldb_message *msg);
    17671934
     1935/*
     1936 * ldb_msg_canonicalize() is now depreciated
     1937 * Please use ldb_msg_normalize() instead
     1938 *
     1939 * NOTE: Returned ldb_message object is allocated
     1940 * into *ldb's context. Callers are recommended
     1941 * to steal the returned object into a TALLOC_CTX
     1942 * with short lifetime.
     1943 */
    17681944struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb,
    1769                                          const struct ldb_message *msg);
    1770 
    1771 
     1945                                         const struct ldb_message *msg) _DEPRECATED_;
     1946
     1947int ldb_msg_normalize(struct ldb_context *ldb,
     1948                      TALLOC_CTX *mem_ctx,
     1949                      const struct ldb_message *msg,
     1950                      struct ldb_message **_msg_out);
     1951
     1952
     1953/*
     1954 * ldb_msg_diff() is now depreciated
     1955 * Please use ldb_msg_difference() instead
     1956 *
     1957 * NOTE: Returned ldb_message object is allocated
     1958 * into *ldb's context. Callers are recommended
     1959 * to steal the returned object into a TALLOC_CTX
     1960 * with short lifetime.
     1961 */
    17721962struct ldb_message *ldb_msg_diff(struct ldb_context *ldb,
    17731963                                 struct ldb_message *msg1,
    1774                                  struct ldb_message *msg2);
    1775 
     1964                                 struct ldb_message *msg2) _DEPRECATED_;
     1965
     1966/**
     1967 * return a ldb_message representing the differences between msg1 and msg2.
     1968 * If you then use this in a ldb_modify() call,
     1969 * it can be used to save edits to a message
     1970 *
     1971 * Result message is constructed as follows:
     1972 * - LDB_FLAG_MOD_ADD     - elements found only in msg2
     1973 * - LDB_FLAG_MOD_REPLACE - elements in msg2 that have
     1974 *                          different value in msg1
     1975 *                          Value for msg2 element is used
     1976 * - LDB_FLAG_MOD_DELETE  - elements found only in msg2
     1977 *
     1978 * @return LDB_SUCCESS or LDB_ERR_OPERATIONS_ERROR
     1979 */
     1980int ldb_msg_difference(struct ldb_context *ldb,
     1981                       TALLOC_CTX *mem_ctx,
     1982                       struct ldb_message *msg1,
     1983                       struct ldb_message *msg2,
     1984                       struct ldb_message **_msg_out);
     1985
     1986/**
     1987   Tries to find a certain string attribute in a message
     1988
     1989   \param msg the message to check
     1990   \param name attribute name
     1991   \param value attribute value
     1992
     1993   \return 1 on match and 0 otherwise.
     1994*/
    17761995int ldb_msg_check_string_attribute(const struct ldb_message *msg,
    17771996                                   const char *name,
     
    18802099
    18812100/**
     2101  convert a LDAP GeneralizedTime string in ldb_val format to a
     2102  time_t.
     2103*/
     2104int ldb_val_to_time(const struct ldb_val *v, time_t *t);
     2105
     2106/**
    18822107   Convert a time structure to a string
    18832108
     
    19082133void ldb_qsort (void *const pbase, size_t total_elems, size_t size, void *opaque, ldb_qsort_cmp_fn_t cmp);
    19092134
    1910 
     2135#ifndef discard_const
     2136#define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
     2137#endif
     2138
     2139/*
     2140  a wrapper around ldb_qsort() that ensures the comparison function is
     2141  type safe. This will produce a compilation warning if the types
     2142  don't match
     2143 */
     2144#define LDB_TYPESAFE_QSORT(base, numel, opaque, comparison)     \
     2145do { \
     2146        if (numel > 1) { \
     2147                ldb_qsort(base, numel, sizeof((base)[0]), discard_const(opaque), (ldb_qsort_cmp_fn_t)comparison); \
     2148                comparison(&((base)[0]), &((base)[1]), opaque);         \
     2149        } \
     2150} while (0)
     2151
     2152/* allow ldb to also call TYPESAFE_QSORT() */
     2153#ifndef TYPESAFE_QSORT
     2154#define TYPESAFE_QSORT(base, numel, comparison) \
     2155do { \
     2156        if (numel > 1) { \
     2157                qsort(base, numel, sizeof((base)[0]), (int (*)(const void *, const void *))comparison); \
     2158                comparison(&((base)[0]), &((base)[1])); \
     2159        } \
     2160} while (0)
     2161#endif
     2162
     2163
     2164
     2165/**
     2166   Convert a control into its string representation.
     2167   
     2168   \param mem_ctx TALLOC context to return result on, and to allocate error_string on
     2169   \param control A struct ldb_control to convert
     2170
     2171   \return string representation of the control
     2172*/
     2173char* ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *control);
     2174/**
     2175   Convert a string representing a control into a ldb_control structure
     2176   
     2177   \param ldb LDB context
     2178   \param mem_ctx TALLOC context to return result on, and to allocate error_string on
     2179   \param control_strings A string-formatted control
     2180
     2181   \return a ldb_control element
     2182*/
     2183struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *control_strings);
    19112184/**
    19122185   Convert an array of string represention of a control into an array of ldb_control structures
     
    19292202
    19302203
     2204struct ldb_dn *ldb_dn_binary_from_ldb_val(TALLOC_CTX *mem_ctx,
     2205                                          struct ldb_context *ldb,
     2206                                          const struct ldb_val *strdn);
     2207
     2208int ldb_dn_get_binary(struct ldb_dn *dn, struct ldb_val *val);
     2209int ldb_dn_set_binary(struct ldb_dn *dn, struct ldb_val *val);
     2210
     2211/* debugging functions for ldb requests */
     2212void ldb_req_set_location(struct ldb_request *req, const char *location);
     2213const char *ldb_req_location(struct ldb_request *req);
     2214
     2215/* set the location marker on a request handle - used for debugging */
     2216#define LDB_REQ_SET_LOCATION(req) ldb_req_set_location(req, __location__)
     2217
     2218/*
     2219  minimise a DN. The caller must pass in a validated DN.
     2220
     2221  If the DN has an extended component then only the first extended
     2222  component is kept, the DN string is stripped.
     2223
     2224  The existing dn is modified
     2225 */
     2226bool ldb_dn_minimise(struct ldb_dn *dn);
     2227
    19312228#endif
  • vendor/current/source4/lib/ldb/include/ldb_errors.h

    r414 r740  
    198198
    199199/**
    200    The function referred to an alias which points to a non-existant
     200   The function referred to an alias which points to a non-existent
    201201   object in the database.
    202202*/
  • vendor/current/source4/lib/ldb/include/ldb_handlers.h

    r414 r740  
    3636int ldb_comparison_binary(      struct ldb_context *ldb, void *mem_ctx,
    3737                                const struct ldb_val *v1, const struct ldb_val *v2);
    38 int db_handler_fold(            struct ldb_context *ldb, void *mem_ctx,
    39                                 const struct ldb_val *in, struct ldb_val *out);
    4038int ldb_comparison_fold(        struct ldb_context *ldb, void *mem_ctx,
    4139                                const struct ldb_val *v1, const struct ldb_val *v2);
  • vendor/current/source4/lib/ldb/include/ldb_module.h

    r414 r740  
    3434#define _LDB_MODULE_H_
    3535
    36 #include "ldb.h"
     36#include <ldb.h>
    3737
    3838struct ldb_context;
    3939struct ldb_module;
     40
     41/**
     42   internal flag bits on message elements. Must be within LDB_FLAG_INTERNAL_MASK
     43 */
     44#define LDB_FLAG_INTERNAL_DISABLE_VALIDATION 0x10
     45
     46/* disable any single value checking on this attribute */
     47#define LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK 0x20
     48
     49/* attribute has failed access check and must not be exposed */
     50#define LDB_FLAG_INTERNAL_INACCESSIBLE_ATTRIBUTE 0x40
     51
     52/* force single value checking on this attribute */
     53#define LDB_FLAG_INTERNAL_FORCE_SINGLE_VALUE_CHECK 0x80
     54
    4055
    4156/*
     
    6883void ldb_debug_end(struct ldb_context *ldb, enum ldb_debug_level level);
    6984
    70 #define ldb_oom(ldb) ldb_debug_set(ldb, LDB_DEBUG_FATAL, "ldb out of memory at %s:%d\n", __FILE__, __LINE__)
     85#define ldb_error(ldb, ecode, reason) ldb_error_at(ldb, ecode, reason, __FILE__, __LINE__)
     86
     87#define ldb_oom(ldb) ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, "ldb out of memory")
     88#define ldb_module_oom(module) ldb_oom(ldb_module_get_ctx(module))
     89#define ldb_operr(ldb) ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, "operations error")
    7190
    7291/* The following definitions come from lib/ldb/common/ldb.c  */
     
    99118                                               void *private_data);
    100119
     120/* A useful function to build comparison functions with */
     121int ldb_any_comparison(struct ldb_context *ldb, void *mem_ctx,
     122                       ldb_attr_handler_t canonicalise_fn,
     123                       const struct ldb_val *v1,
     124                       const struct ldb_val *v2);
     125
    101126/* The following definitions come from lib/ldb/common/ldb_controls.c  */
    102 struct ldb_control *get_control_from_list(struct ldb_control **controls, const char *oid);
    103 int save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver);
    104 int check_critical_controls(struct ldb_control **controls);
     127int ldb_save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver);
     128/* Returns a list of controls, except the one specified.  Included
     129 * controls become a child of returned list if they were children of
     130 * controls_in */
     131struct ldb_control **ldb_controls_except_specified(struct ldb_control **controls_in,
     132                                               TALLOC_CTX *mem_ctx,
     133                                               struct ldb_control *exclude);
     134int ldb_check_critical_controls(struct ldb_control **controls);
    105135
    106136/* The following definitions come from lib/ldb/common/ldb_ldif.c  */
     
    114144                  enum ldb_scope scope);
    115145
     146int ldb_match_msg_error(struct ldb_context *ldb,
     147                        const struct ldb_message *msg,
     148                        const struct ldb_parse_tree *tree,
     149                        struct ldb_dn *base,
     150                        enum ldb_scope scope,
     151                        bool *matched);
     152
     153int ldb_match_msg_objectclass(const struct ldb_message *msg,
     154                              const char *objectclass);
     155
    116156/* The following definitions come from lib/ldb/common/ldb_modules.c  */
    117157
     
    125165void *ldb_module_get_private(struct ldb_module *module);
    126166void ldb_module_set_private(struct ldb_module *module, void *private_data);
     167const struct ldb_module_ops *ldb_module_get_ops(struct ldb_module *module);
    127168
    128169int ldb_next_request(struct ldb_module *module, struct ldb_request *request);
     
    136177void ldb_asprintf_errstring(struct ldb_context *ldb, const char *format, ...) PRINTF_ATTRIBUTE(2,3);
    137178void ldb_reset_err_string(struct ldb_context *ldb);
     179int ldb_error_at(struct ldb_context *ldb, int ecode, const char *reason, const char *file, int line);
    138180
    139181const char *ldb_default_modules_dir(void);
     
    152194const char *ldb_default_modules_dir(void);
    153195
    154 int ldb_register_backend(const char *url_prefix, ldb_connect_fn);
     196int ldb_register_backend(const char *url_prefix, ldb_connect_fn, bool);
    155197
    156198struct ldb_handle *ldb_handle_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb);
     
    171213
    172214void ldb_set_default_dns(struct ldb_context *ldb);
     215/**
     216  Add a ldb_control to a ldb_reply
     217
     218  \param ares the reply struct where to add the control
     219  \param oid the object identifier of the control as string
     220  \param critical whether the control should be critical or not
     221  \param data a talloc pointer to the control specific data
     222
     223  \return result code (LDB_SUCCESS on success, or a failure code)
     224*/
     225int ldb_reply_add_control(struct ldb_reply *ares, const char *oid, bool critical, void *data);
     226
     227/**
     228  mark a request as untrusted. This tells the rootdse module to remove
     229  unregistered controls
     230 */
     231void ldb_req_mark_untrusted(struct ldb_request *req);
     232
     233/**
     234  mark a request as trusted.
     235 */
     236void ldb_req_mark_trusted(struct ldb_request *req);
     237
     238/**
     239   return true is a request is untrusted
     240 */
     241bool ldb_req_is_untrusted(struct ldb_request *req);
     242
     243/* load all modules from the given directory */
     244int ldb_modules_load(const char *modules_path, const char *version);
     245
     246/* init functions prototype */
     247typedef int (*ldb_module_init_fn)(const char *);
     248
     249/*
     250  general ldb hook function
     251 */
     252enum ldb_module_hook_type { LDB_MODULE_HOOK_CMDLINE_OPTIONS     = 1,
     253                            LDB_MODULE_HOOK_CMDLINE_PRECONNECT  = 2,
     254                            LDB_MODULE_HOOK_CMDLINE_POSTCONNECT = 3 };
     255
     256typedef int (*ldb_hook_fn)(struct ldb_context *, enum ldb_module_hook_type );
     257
     258/*
     259  register a ldb hook function
     260 */
     261int ldb_register_hook(ldb_hook_fn hook_fn);
     262
     263/*
     264  call ldb hooks of a given type
     265 */
     266int ldb_modules_hook(struct ldb_context *ldb, enum ldb_module_hook_type t);
     267
     268#define LDB_MODULE_CHECK_VERSION(version) do { \
     269 if (strcmp(version, LDB_VERSION) != 0) { \
     270        fprintf(stderr, "ldb: module version mismatch in %s : ldb_version=%s module_version=%s\n", \
     271                        __FILE__, version, LDB_VERSION); \
     272        return LDB_ERR_UNAVAILABLE; \
     273 }} while (0)
     274
     275
     276/*
     277  return a string representation of the calling chain for the given
     278  ldb request
     279 */
     280char *ldb_module_call_chain(struct ldb_request *req, TALLOC_CTX *mem_ctx);
     281
     282/*
     283  return the next module in the chain
     284 */
     285struct ldb_module *ldb_module_next(struct ldb_module *module);
     286
     287/*
     288  set the next module in the module chain
     289 */
     290void ldb_module_set_next(struct ldb_module *module, struct ldb_module *next);
     291
     292/*
     293  load a list of modules
     294 */
     295int ldb_module_load_list(struct ldb_context *ldb, const char **module_list,
     296                         struct ldb_module *backend, struct ldb_module **out);
     297
     298/*
     299  get the popt_options pointer in the ldb structure. This allows a ldb
     300  module to change the command line parsing
     301 */
     302struct poptOption **ldb_module_popt_options(struct ldb_context *ldb);
     303
     304/* modules are called in inverse order on the stack.
     305   Lets place them as an admin would think the right order is.
     306   Modules order is important */
     307const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *string);
     308
     309/*
     310  return the current ldb flags LDB_FLG_*
     311 */
     312uint32_t ldb_module_flags(struct ldb_context *ldb);
     313
     314int ldb_module_connect_backend(struct ldb_context *ldb,
     315                               const char *url,
     316                               const char *options[],
     317                               struct ldb_module **backend_module);
     318
     319/*
     320  initialise a chain of modules
     321 */
     322int ldb_module_init_chain(struct ldb_context *ldb, struct ldb_module *module);
     323
     324/*
     325 * prototype for the init function defined by dynamically loaded modules
     326 */
     327int ldb_init_module(const char *version);
     328
    173329
    174330#endif
  • vendor/current/source4/lib/ldb/include/ldb_private.h

    r414 r740  
    3838#define _LDB_PRIVATE_H_ 1
    3939
    40 #include "ldb_includes.h"
     40#include "replace.h"
     41#include "system/filesys.h"
     42#include "system/time.h"
    4143#include "ldb.h"
    4244#include "ldb_module.h"
     
    4951
    5052#define LDB_HANDLE_FLAG_DONE_CALLED 1
     53/* call is from an untrusted source - eg. over ldap:// */
     54#define LDB_HANDLE_FLAG_UNTRUSTED   2
    5155
    5256struct ldb_handle {
     
    5660        unsigned flags;
    5761        unsigned nesting;
     62
     63        /* used for debugging */
     64        struct ldb_request *parent;
     65        const char *location;
    5866};
    5967
     
    113121        unsigned int create_perms;
    114122
    115         char *modules_dir;
    116 
    117123        struct tevent_context *ev_ctx;
    118124
     
    120126
    121127        char *partial_debug;
     128
     129        struct poptOption *popt_options;
    122130};
    123131
    124132/* The following definitions come from lib/ldb/common/ldb.c  */
    125 
    126 int ldb_connect_backend(struct ldb_context *ldb, const char *url, const char *options[],
    127                         struct ldb_module **backend_module);
    128 
    129133
    130134extern const struct ldb_module_ops ldb_objectclass_module_ops;
     
    158162
    159163/* The following definitions come from lib/ldb/common/ldb_utf8.c */
    160 char *ldb_casefold_default(void *context, void *mem_ctx, const char *s, size_t n);
     164char *ldb_casefold_default(void *context, TALLOC_CTX *mem_ctx, const char *s, size_t n);
    161165
    162166void ldb_dump_results(struct ldb_context *ldb, struct ldb_result *result, FILE *f);
     
    166170
    167171const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *string);
    168 int ldb_load_modules_list(struct ldb_context *ldb, const char **module_list, struct ldb_module *backend, struct ldb_module **out);
    169172int ldb_load_modules(struct ldb_context *ldb, const char *options[]);
    170 int ldb_init_module_chain(struct ldb_context *ldb, struct ldb_module *module);
    171173
    172 struct ldb_val ldb_binary_decode(void *mem_ctx, const char *str);
     174struct ldb_val ldb_binary_decode(TALLOC_CTX *mem_ctx, const char *str);
     175
     176
     177/* The following definitions come from lib/ldb/common/ldb_options.c  */
     178
     179const char *ldb_options_find(struct ldb_context *ldb, const char *options[],
     180                             const char *option_name);
    173181
    174182#endif
  • vendor/current/source4/lib/ldb/ldb.pc.in

    r414 r740  
    1010Requires.private: tdb
    1111Requires: talloc
    12 Libs: -L${libdir} -lldb
     12Libs: @LIB_RPATH@ -L${libdir} -lldb
    1313Libs.private: @LDAP_LIBS@
    1414Cflags: -I${includedir}
  • vendor/current/source4/lib/ldb/ldb_ldap/ldb_ldap.c

    r414 r740  
    3434 *  Modifications:
    3535 *
    36  *  - description: make the module use asyncronous calls
     36 *  - description: make the module use asynchronous calls
    3737 *    date: Feb 2006
    3838 *    author: Simo Sorce
    3939 */
    4040
    41 #include "ldb_includes.h"
     41#include "replace.h"
     42#include "system/filesys.h"
     43#include "system/time.h"
    4244#include "ldb_module.h"
     45#include "ldb_private.h"
    4346
    4447#define LDAP_DEPRECATED 1
     
    118121                                goto failed;
    119122                        }
    120                         mods[num_mods]->mod_vals.modv_bvals[j]->bv_val = el->values[j].data;
     123                        mods[num_mods]->mod_vals.modv_bvals[j]->bv_val = (char *)el->values[j].data;
    121124                        mods[num_mods]->mod_vals.modv_bvals[j]->bv_len = el->values[j].length;
    122125                }
     
    254257
    255258        ret = ldap_search_ext(lldb->ldap, search_base, ldap_scope,
    256                             expression,
    257                             discard_const_p(char *, req->op.search.attrs),
    258                             0,
    259                             NULL,
    260                             NULL,
    261                             &tv,
    262                             LDAP_NO_LIMIT,
    263                             &lldb_ac->msgid);
     259                              expression,
     260                              discard_const_p(char *, req->op.search.attrs),
     261                              0,
     262                              NULL,
     263                              NULL,
     264                              &tv,
     265                              LDAP_NO_LIMIT,
     266                              &lldb_ac->msgid);
    264267
    265268        if (ret != LDAP_SUCCESS) {
     
    283286        int ret;
    284287
    285         ldb_module_get_ctx(module);
     288        ldb = ldb_module_get_ctx(module);
    286289
    287290        ldb_request_set_state(req, LDB_ASYNC_PENDING);
     
    322325        int ret;
    323326
    324         ldb_module_get_ctx(module);
     327        ldb = ldb_module_get_ctx(module);
    325328
    326329        ldb_request_set_state(req, LDB_ASYNC_PENDING);
     
    360363        int ret;
    361364
    362         ldb_module_get_ctx(module);
     365        ldb = ldb_module_get_ctx(module);
    363366
    364367        ldb_request_set_state(req, LDB_ASYNC_PENDING);
     
    387390        struct ldb_module *module = lldb_ac->module;
    388391        struct ldb_request *req = lldb_ac->req;
     392        const char *rdn_name;
     393        const struct ldb_val *rdn_val;
    389394        char *old_dn;
    390         char *newrdn;
     395        char *newrdn;
    391396        char *parentdn;
    392397        int ret;
    393398
    394         ldb_module_get_ctx(module);
     399        ldb = ldb_module_get_ctx(module);
    395400
    396401        ldb_request_set_state(req, LDB_ASYNC_PENDING);
     
    401406        }
    402407
    403         newrdn = talloc_asprintf(lldb_ac, "%s=%s",
    404                                  ldb_dn_get_rdn_name(req->op.rename.newdn),
    405                                  ldb_dn_escape_value(lldb, *(ldb_dn_get_rdn_val(req->op.rename.newdn))));
     408        rdn_name = ldb_dn_get_rdn_name(req->op.rename.newdn);
     409        rdn_val = ldb_dn_get_rdn_val(req->op.rename.newdn);
     410
     411        if ((rdn_name != NULL) && (rdn_val != NULL)) {
     412                newrdn = talloc_asprintf(lldb_ac, "%s=%s", rdn_name,
     413                                         rdn_val->length > 0 ? ldb_dn_escape_value(lldb, *rdn_val) : "");
     414        } else {
     415                newrdn = talloc_strdup(lldb_ac, "");
     416        }
    406417        if (!newrdn) {
    407418                return LDB_ERR_OPERATIONS_ERROR;
     
    445456}
    446457
    447 void lldb_request_done(struct lldb_context *ac,
     458static void lldb_request_done(struct lldb_context *ac,
    448459                        struct ldb_control **ctrls, int error)
    449460{
     
    484495        bool request_done;
    485496        bool lret;
     497        unsigned int i;
    486498        int ret;
    487         int i;
    488499
    489500        ldb = ldb_module_get_ctx(ac->module);
     
    503514                        ldbmsg = ldb_msg_new(ac);
    504515                        if (!ldbmsg) {
     516                                ldb_oom(ldb);
    505517                                ret = LDB_ERR_OPERATIONS_ERROR;
    506518                                break;
     
    509521                        dn = ldap_get_dn(lldb->ldap, msg);
    510522                        if (!dn) {
     523                                ldb_oom(ldb);
    511524                                talloc_free(ldbmsg);
    512525                                ret = LDB_ERR_OPERATIONS_ERROR;
     
    515528                        ldbmsg->dn = ldb_dn_new(ldbmsg, ldb, dn);
    516529                        if ( ! ldb_dn_validate(ldbmsg->dn)) {
     530                                ldb_asprintf_errstring(ldb, "Invalid DN '%s' in reply", dn);
    517531                                talloc_free(ldbmsg);
    518532                                ret = LDB_ERR_OPERATIONS_ERROR;
     533                                ldap_memfree(dn);
    519534                                break;
    520535                        }
     
    540555                        ret = ldb_module_send_entry(ac->req, ldbmsg, NULL /* controls not yet supported */);
    541556                        if (ret != LDB_SUCCESS) {
    542 
     557                                ldb_asprintf_errstring(ldb, "entry send failed: %s",
     558                                                       ldb_errstring(ldb));
    543559                                callback_failed = true;
    544560                        }
     
    550566        case LDAP_RES_SEARCH_REFERENCE:
    551567
    552                 if (ldap_parse_result(lldb->ldap, result, &ret,
    553                                         &matcheddnp, &errmsgp,
    554                                         &referralsp, &serverctrlsp, 0) != LDAP_SUCCESS) {
     568                ret = ldap_parse_reference(lldb->ldap, result,
     569                                           &referralsp, &serverctrlsp, 0);
     570                if (ret != LDAP_SUCCESS) {
     571                        ldb_asprintf_errstring(ldb, "ldap reference parse error: %s : %s",
     572                                               ldap_err2string(ret), errmsgp);
    555573                        ret = LDB_ERR_OPERATIONS_ERROR;
    556                 }
    557                 if (ret != LDB_SUCCESS) {
    558574                        break;
    559575                }
    560576                if (referralsp == NULL) {
     577                        ldb_asprintf_errstring(ldb, "empty ldap referrals list");
    561578                        ret = LDB_ERR_PROTOCOL_ERROR;
    562579                        break;
     
    568585                        ret = ldb_module_send_referral(ac->req, referral);
    569586                        if (ret != LDB_SUCCESS) {
     587                                ldb_asprintf_errstring(ldb, "referral send failed: %s",
     588                                                       ldb_errstring(ldb));
    570589                                callback_failed = true;
    571590                                break;
     
    586605                }
    587606                if (ret != LDB_SUCCESS) {
     607                        ldb_asprintf_errstring(ldb, "ldap parse error for type %d: %s : %s",
     608                                               type, ldap_err2string(ret), errmsgp);
    588609                        break;
    589610                }
     
    598619
    599620        default:
     621                ldb_asprintf_errstring(ldb, "unknown ldap return type: %d", type);
    600622                ret = LDB_ERR_PROTOCOL_ERROR;
    601623                break;
     
    799821        default:
    800822                /* no other op supported */
    801                 ret = LDB_ERR_OPERATIONS_ERROR;
     823                ret = LDB_ERR_PROTOCOL_ERROR;
    802824                break;
    803825        }
     
    846868}
    847869
     870
     871/*
     872  optionally perform a bind
     873 */
     874static int lldb_bind(struct ldb_module *module,
     875                     const char *options[])
     876{
     877        const char *bind_mechanism;
     878        struct lldb_private *lldb;
     879        struct ldb_context *ldb = ldb_module_get_ctx(module);
     880        int ret;
     881
     882        bind_mechanism = ldb_options_find(ldb, options, "bindMech");
     883        if (bind_mechanism == NULL) {
     884                /* no bind wanted */
     885                return LDB_SUCCESS;
     886        }
     887
     888        lldb = talloc_get_type(ldb_module_get_private(module), struct lldb_private);
     889
     890        if (strcmp(bind_mechanism, "simple") == 0) {
     891                const char *bind_id, *bind_secret;
     892
     893                bind_id = ldb_options_find(ldb, options, "bindID");
     894                bind_secret = ldb_options_find(ldb, options, "bindSecret");
     895                if (bind_id == NULL || bind_secret == NULL) {
     896                        ldb_asprintf_errstring(ldb, "simple bind requires bindID and bindSecret");
     897                        return LDB_ERR_OPERATIONS_ERROR;
     898                }
     899
     900                ret = ldap_simple_bind_s(lldb->ldap, bind_id, bind_secret);
     901                if (ret != LDAP_SUCCESS) {
     902                        ldb_asprintf_errstring(ldb, "bind failed: %s", ldap_err2string(ret));
     903                        return ret;
     904                }
     905                return LDB_SUCCESS;
     906        }
     907
     908        ldb_asprintf_errstring(ldb, "bind failed: unknown mechanism %s", bind_mechanism);
     909        return LDB_ERR_INAPPROPRIATE_AUTHENTICATION;
     910}
     911
    848912/*
    849913  connect to the database
     
    861925
    862926        module = ldb_module_new(ldb, ldb, "ldb_ldap backend", &lldb_ops);
    863         if (!module) return -1;
     927        if (!module) return LDB_ERR_OPERATIONS_ERROR;
    864928
    865929        lldb = talloc_zero(module, struct lldb_private);
     
    887951
    888952        *_module = module;
    889         return 0;
     953
     954        ret = lldb_bind(module, options);
     955        if (ret != LDB_SUCCESS) {
     956                goto failed;
     957        }
     958
     959
     960        return LDB_SUCCESS;
    890961
    891962failed:
    892963        talloc_free(module);
    893         return -1;
    894 }
    895 
    896 const struct ldb_backend_ops ldb_ldap_backend_ops = {
    897         .name = "ldap",
    898         .connect_fn = lldb_connect
    899 };
    900 
    901 const struct ldb_backend_ops ldb_ldapi_backend_ops = {
    902         .name = "ldapi",
    903         .connect_fn = lldb_connect
    904 };
    905 
    906 const struct ldb_backend_ops ldb_ldaps_backend_ops = {
    907         .name = "ldaps",
    908         .connect_fn = lldb_connect
    909 };
     964        return LDB_ERR_OPERATIONS_ERROR;
     965}
     966
     967/*
     968  initialise the module
     969 */
     970int ldb_ldap_init(const char *version)
     971{
     972        int ret, i;
     973        const char *names[] = { "ldap", "ldaps", "ldapi", NULL };
     974        LDB_MODULE_CHECK_VERSION(version);
     975        for (i=0; names[i]; i++) {
     976                ret = ldb_register_backend(names[i], lldb_connect, false);
     977                if (ret != LDB_SUCCESS) {
     978                        return ret;
     979                }
     980        }
     981        return LDB_SUCCESS;
     982}
  • vendor/current/source4/lib/ldb/ldb_map/ldb_map.c

    r414 r740  
    3636 */
    3737
    38 #include "ldb_includes.h"
     38#include "replace.h"
     39#include "system/filesys.h"
     40#include "system/time.h"
    3941#include "ldb_map.h"
    4042#include "ldb_map_private.h"
     
    257259static const struct ldb_map_objectclass *map_objectclass_find_local(const struct ldb_map_context *data, const char *name)
    258260{
    259         int i;
     261        unsigned int i;
    260262
    261263        for (i = 0; data->objectclass_maps && data->objectclass_maps[i].local_name; i++) {
     
    271273static const struct ldb_map_objectclass *map_objectclass_find_remote(const struct ldb_map_context *data, const char *name)
    272274{
    273         int i;
     275        unsigned int i;
    274276
    275277        for (i = 0; data->objectclass_maps && data->objectclass_maps[i].remote_name; i++) {
     
    285287const struct ldb_map_attribute *map_attr_find_local(const struct ldb_map_context *data, const char *name)
    286288{
    287         int i;
     289        unsigned int i;
    288290
    289291        for (i = 0; data->attribute_maps[i].local_name; i++) {
     
    306308        const struct ldb_map_attribute *map;
    307309        const struct ldb_map_attribute *wildcard = NULL;
    308         int i, j;
     310        unsigned int i, j;
    309311
    310312        for (i = 0; data->attribute_maps[i].local_name; i++) {
     
    315317
    316318                switch (map->type) {
    317                 case MAP_IGNORE:
     319                case LDB_MAP_IGNORE:
    318320                        break;
    319321
    320                 case MAP_KEEP:
     322                case LDB_MAP_KEEP:
    321323                        if (ldb_attr_cmp(map->local_name, name) == 0) {
    322324                                return map;
     
    324326                        break;
    325327
    326                 case MAP_RENAME:
    327                 case MAP_CONVERT:
     328                case LDB_MAP_RENAME:
     329                case LDB_MAP_CONVERT:
    328330                        if (ldb_attr_cmp(map->u.rename.remote_name, name) == 0) {
    329331                                return map;
     
    331333                        break;
    332334
    333                 case MAP_GENERATE:
     335                case LDB_MAP_GENERATE:
    334336                        for (j = 0; map->u.generate.remote_names && map->u.generate.remote_names[j]; j++) {
    335337                                if (ldb_attr_cmp(map->u.generate.remote_names[j], name) == 0) {
     
    357359                return false;
    358360        }
    359         if (map->type == MAP_IGNORE) {
     361        if (map->type == LDB_MAP_IGNORE) {
    360362                return false;
    361363        }
     
    372374
    373375        switch (map->type) {
    374         case MAP_KEEP:
     376        case LDB_MAP_KEEP:
    375377                return talloc_strdup(mem_ctx, attr);
    376378
    377         case MAP_RENAME:
    378         case MAP_CONVERT:
     379        case LDB_MAP_RENAME:
     380        case LDB_MAP_CONVERT:
    379381                return talloc_strdup(mem_ctx, map->u.rename.remote_name);
    380382
     
    391393        }
    392394
    393         if (map->type == MAP_KEEP) {
     395        if (map->type == LDB_MAP_KEEP) {
    394396                return talloc_strdup(mem_ctx, attr);
    395397        }
     
    403405                    const char ***attrs, const char * const *more_attrs)
    404406{
    405         int i, j, k;
     407        unsigned int i, j, k;
    406408
    407409        for (i = 0; *attrs && (*attrs)[i]; i++) /* noop */ ;
     
    430432                                 const struct ldb_map_attribute *map, const struct ldb_val *val)
    431433{
    432         if (map && (map->type == MAP_CONVERT) && (map->u.convert.convert_local)) {
     434        if (map && (map->type == LDB_MAP_CONVERT) && (map->u.convert.convert_local)) {
    433435                return map->u.convert.convert_local(module, mem_ctx, val);
    434436        }
     
    441443                                  const struct ldb_map_attribute *map, const struct ldb_val *val)
    442444{
    443         if (map && (map->type == MAP_CONVERT) && (map->u.convert.convert_remote)) {
     445        if (map && (map->type == LDB_MAP_CONVERT) && (map->u.convert.convert_remote)) {
    444446                return map->u.convert.convert_remote(module, mem_ctx, val);
    445447        }
     
    494496                /* Unknown attribute - leave this RDN as is and hope the best... */
    495497                if (map == NULL) {
    496                         map_type = MAP_KEEP;
     498                        map_type = LDB_MAP_KEEP;
    497499                } else {
    498500                        map_type = map->type;
     
    500502
    501503                switch (map_type) {
    502                 case MAP_IGNORE:
    503                 case MAP_GENERATE:
     504                case LDB_MAP_IGNORE:
     505                case LDB_MAP_GENERATE:
    504506                        ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
    505                                   "MAP_IGNORE/MAP_GENERATE attribute '%s' "
     507                                  "LDB_MAP_IGNORE/LDB_MAP_GENERATE attribute '%s' "
    506508                                  "used in DN!", ldb_dn_get_component_name(dn, i));
    507509                        goto failed;
    508510
    509                 case MAP_CONVERT:
     511                case LDB_MAP_CONVERT:
    510512                        if (map->u.convert.convert_local == NULL) {
    511513                                ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
     
    515517                        }
    516518                        /* fall through */
    517                 case MAP_KEEP:
    518                 case MAP_RENAME:
     519                case LDB_MAP_KEEP:
     520                case LDB_MAP_RENAME:
    519521                        name = map_attr_map_local(newdn, map, ldb_dn_get_component_name(dn, i));
    520522                        if (name == NULL) goto failed;
     
    569571                /* Unknown attribute - leave this RDN as is and hope the best... */
    570572                if (map == NULL) {
    571                         map_type = MAP_KEEP;
     573                        map_type = LDB_MAP_KEEP;
    572574                } else {
    573575                        map_type = map->type;
     
    575577
    576578                switch (map_type) {
    577                 case MAP_IGNORE:
    578                 case MAP_GENERATE:
     579                case LDB_MAP_IGNORE:
     580                case LDB_MAP_GENERATE:
    579581                        ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
    580                                   "MAP_IGNORE/MAP_GENERATE attribute '%s' "
     582                                  "LDB_MAP_IGNORE/LDB_MAP_GENERATE attribute '%s' "
    581583                                  "used in DN!", ldb_dn_get_component_name(dn, i));
    582584                        goto failed;
    583585
    584                 case MAP_CONVERT:
     586                case LDB_MAP_CONVERT:
    585587                        if (map->u.convert.convert_remote == NULL) {
    586588                                ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
     
    590592                        }
    591593                        /* fall through */
    592                 case MAP_KEEP:
    593                 case MAP_RENAME:
     594                case LDB_MAP_KEEP:
     595                case LDB_MAP_RENAME:
    594596                        name = map_attr_map_remote(newdn, map, ldb_dn_get_component_name(dn, i));
    595597                        if (name == NULL) goto failed;
     
    715717        struct ldb_val val;
    716718        bool found_extensibleObject = false;
    717         int i;
     719        unsigned int i;
    718720
    719721        ldb = ldb_module_get_ctx(module);
     
    790792        struct ldb_message_element *el, *oc;
    791793        struct ldb_val val;
    792         int i;
     794        unsigned int i;
    793795
    794796        ldb = ldb_module_get_ctx(module);
     
    843845static const struct ldb_map_attribute objectclass_convert_map = {
    844846        .local_name = "objectClass",
    845         .type = MAP_CONVERT,
     847        .type = LDB_MAP_CONVERT,
    846848        .u = {
    847849                .convert = {
     
    892894                                        context, callback,
    893895                                        ac->req);
     896        LDB_REQ_SET_LOCATION(req);
    894897        if (ret != LDB_SUCCESS) {
    895898                return NULL;
     
    939942                                context, callback,
    940943                                ac->req);
     944        LDB_REQ_SET_LOCATION(req);
    941945        if (ret != LDB_SUCCESS) {
    942946                goto failed;
     
    958962        {
    959963                .local_name = "dn",
    960                 .type = MAP_CONVERT,
     964                .type = LDB_MAP_CONVERT,
    961965                .u = {
    962966                        .convert = {
     
    974978static const struct ldb_map_attribute objectclass_attribute_map = {
    975979        .local_name = "objectClass",
    976         .type = MAP_GENERATE,
     980        .type = LDB_MAP_GENERATE,
    977981        .convert_operator = map_objectclass_convert_operator,
    978982        .u = {
     
    10441048                         const char * const *wildcard_attributes)
    10451049{
    1046         int i, j, last;
     1050        unsigned int i, j, last;
    10471051        last = 0;
    10481052
  • vendor/current/source4/lib/ldb/ldb_map/ldb_map.h

    r414 r740  
    6060
    6161        enum ldb_map_attr_type {
    62                 MAP_IGNORE, /* Ignore this local attribute. Doesn't exist remotely.  */
    63                 MAP_KEEP,   /* Keep as is. Same name locally and remotely. */
    64                 MAP_RENAME, /* Simply rename the attribute. Name changes, data is the same */
    65                 MAP_CONVERT, /* Rename + convert data */
    66                 MAP_GENERATE /* Use generate function for generating new name/data.
     62                LDB_MAP_IGNORE, /* Ignore this local attribute. Doesn't exist remotely.  */
     63                LDB_MAP_KEEP,   /* Keep as is. Same name locally and remotely. */
     64                LDB_MAP_RENAME, /* Simply rename the attribute. Name changes, data is the same */
     65                LDB_MAP_CONVERT, /* Rename + convert data */
     66                LDB_MAP_GENERATE /* Use generate function for generating new name/data.
    6767                                                Used for generating attributes based on
    6868                                                multiple remote attributes. */
     
    158158                 const char *name);
    159159
    160 int map_add(struct ldb_module *module, struct ldb_request *req);
    161 int map_search(struct ldb_module *module, struct ldb_request *req);
    162 int map_rename(struct ldb_module *module, struct ldb_request *req);
    163 int map_delete(struct ldb_module *module, struct ldb_request *req);
    164 int map_modify(struct ldb_module *module, struct ldb_request *req);
     160int ldb_map_add(struct ldb_module *module, struct ldb_request *req);
     161int ldb_map_search(struct ldb_module *module, struct ldb_request *req);
     162int ldb_map_rename(struct ldb_module *module, struct ldb_request *req);
     163int ldb_map_delete(struct ldb_module *module, struct ldb_request *req);
     164int ldb_map_modify(struct ldb_module *module, struct ldb_request *req);
    165165
    166166#define LDB_MAP_OPS \
    167         .add            = map_add, \
    168         .modify         = map_modify, \
    169         .del            = map_delete, \
    170         .rename         = map_rename, \
    171         .search         = map_search,
     167        .add            = ldb_map_add, \
     168        .modify         = ldb_map_modify, \
     169        .del            = ldb_map_delete, \
     170        .rename         = ldb_map_rename, \
     171        .search         = ldb_map_search,
    172172
    173173#endif /* __LDB_MAP_H__ */
  • vendor/current/source4/lib/ldb/ldb_map/ldb_map_inbound.c

    r414 r740  
    2525*/
    2626
    27 #include "ldb_includes.h"
     27#include "replace.h"
     28#include "system/filesys.h"
     29#include "system/time.h"
    2830#include "ldb_map.h"
    2931#include "ldb_map_private.h"
     
    3739{
    3840        struct ldb_message_element *el;
    39         int i;
     41        unsigned int i;
    4042
    4143        el = talloc_zero(mem_ctx, struct ldb_message_element);
     
    8082
    8183        switch (map->type) {
    82         case MAP_IGNORE:
     84        case LDB_MAP_IGNORE:
    8385                goto local;
    8486
    85         case MAP_CONVERT:
     87        case LDB_MAP_CONVERT:
    8688                if (map->u.convert.convert_local == NULL) {
    8789                        ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: "
     
    9294                }
    9395                /* fall through */
    94         case MAP_KEEP:
    95         case MAP_RENAME:
     96        case LDB_MAP_KEEP:
     97        case LDB_MAP_RENAME:
    9698                el = ldb_msg_el_map_local(module, remote, map, old);
    9799                break;
    98100
    99         case MAP_GENERATE:
     101        case LDB_MAP_GENERATE:
    100102                if (map->u.generate.generate_remote == NULL) {
    101103                        ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: "
     
    142144        const struct ldb_map_context *data = map_get_context(module);
    143145        bool ret;
    144         int i;
     146        unsigned int i;
    145147
    146148        for (i = 0; i < msg->num_elements; i++) {
     
    160162        /* const char * const names[]; */
    161163        struct ldb_context *ldb;
    162         int i, ret;
     164        unsigned int i;
     165        int ret;
    163166
    164167        ldb = ldb_module_get_ctx(module);
     
    357360
    358361/* Add a record. */
    359 int map_add(struct ldb_module *module, struct ldb_request *req)
     362int ldb_map_add(struct ldb_module *module, struct ldb_request *req)
    360363{
    361364        const struct ldb_message *msg = req->op.add.message;
     
    363366        struct map_context *ac;
    364367        struct ldb_message *remote_msg;
    365         const char *dn;
    366368        int ret;
    367369
     
    415417                                ac, map_op_remote_callback,
    416418                                req);
     419        LDB_REQ_SET_LOCATION(ac->remote_req);
    417420        if (ret != LDB_SUCCESS) {
    418421                return LDB_ERR_OPERATIONS_ERROR;
     
    427430        /* Store remote DN in 'IS_MAPPED' */
    428431        /* TODO: use GUIDs here instead */
    429         dn = ldb_dn_alloc_linearized(ac->local_msg, remote_msg->dn);
    430         if (ldb_msg_add_string(ac->local_msg, IS_MAPPED, dn) != 0) {
     432        ret = ldb_msg_add_linearized_dn(ac->local_msg, IS_MAPPED,
     433                                        remote_msg->dn);
     434        if (ret != LDB_SUCCESS) {
    431435                return LDB_ERR_OPERATIONS_ERROR;
    432436        }
     
    451455                                map_op_local_callback,
    452456                                ac->req);
     457        LDB_REQ_SET_LOCATION(local_req);
    453458        if (ret != LDB_SUCCESS) {
    454459                return LDB_ERR_OPERATIONS_ERROR;
     
    462467
    463468/* Modify a record. */
    464 int map_modify(struct ldb_module *module, struct ldb_request *req)
     469int ldb_map_modify(struct ldb_module *module, struct ldb_request *req)
    465470{
    466471        const struct ldb_message *msg = req->op.mod.message;
     
    522527                                ac, map_op_remote_callback,
    523528                                req);
     529        LDB_REQ_SET_LOCATION(ac->remote_req);
    524530        if (ret != LDB_SUCCESS) {
    525531                return LDB_ERR_OPERATIONS_ERROR;
     
    546552        struct ldb_request *local_req;
    547553        struct ldb_context *ldb;
    548         char *dn;
    549554        int ret;
    550555
     
    559564                        return LDB_ERR_OPERATIONS_ERROR;
    560565                }
    561                 dn = ldb_dn_alloc_linearized(ac->local_msg,
    562                                         ac->remote_req->op.mod.message->dn);
    563                 if (ldb_msg_add_string(ac->local_msg, IS_MAPPED, dn) != 0) {
     566                ret = ldb_msg_add_linearized_dn(ac->local_msg, IS_MAPPED,
     567                                                ac->remote_req->op.mod.message->dn);
     568                if (ret != 0) {
    564569                        return LDB_ERR_OPERATIONS_ERROR;
    565570                }
     
    572577                                        map_op_local_callback,
    573578                                        ac->req);
     579                LDB_REQ_SET_LOCATION(local_req);
    574580                if (ret != LDB_SUCCESS) {
    575581                        return LDB_ERR_OPERATIONS_ERROR;
     
    583589                                        map_op_local_callback,
    584590                                        ac->req);
     591                LDB_REQ_SET_LOCATION(local_req);
    585592                if (ret != LDB_SUCCESS) {
    586593                        return LDB_ERR_OPERATIONS_ERROR;
     
    596603
    597604/* Delete a record. */
    598 int map_delete(struct ldb_module *module, struct ldb_request *req)
     605int ldb_map_delete(struct ldb_module *module, struct ldb_request *req)
    599606{
    600607        struct ldb_request *search_req;
     
    629636                                   map_op_remote_callback,
    630637                                   req);
     638        LDB_REQ_SET_LOCATION(ac->remote_req);
    631639        if (ret != LDB_SUCCESS) {
    632640                return LDB_ERR_OPERATIONS_ERROR;
     
    671679                                   map_op_local_callback,
    672680                                   ac->req);
     681        LDB_REQ_SET_LOCATION(local_req);
    673682        if (ret != LDB_SUCCESS) {
    674683                return LDB_ERR_OPERATIONS_ERROR;
     
    682691
    683692/* Rename a record. */
    684 int map_rename(struct ldb_module *module, struct ldb_request *req)
     693int ldb_map_rename(struct ldb_module *module, struct ldb_request *req)
    685694{
    686695        struct ldb_request *search_req;
     
    722731                                   ac, map_op_remote_callback,
    723732                                   req);
     733        LDB_REQ_SET_LOCATION(ac->remote_req);
    724734        if (ret != LDB_SUCCESS) {
    725735                return LDB_ERR_OPERATIONS_ERROR;
     
    765775                                   map_rename_local_callback,
    766776                                   ac->req);
     777        LDB_REQ_SET_LOCATION(local_req);
    767778        if (ret != LDB_SUCCESS) {
    768779                return LDB_ERR_OPERATIONS_ERROR;
  • vendor/current/source4/lib/ldb/ldb_map/ldb_map_outbound.c

    r414 r740  
    2626*/
    2727
    28 #include "ldb_includes.h"
     28#include "replace.h"
     29#include "system/filesys.h"
     30#include "system/time.h"
    2931#include "ldb_map.h"
    3032#include "ldb_map_private.h"
     
    3941        const struct ldb_map_context *data = map_get_context(module);
    4042        const char **result;
    41         int i, last;
     43        unsigned int i, last;
    4244
    4345        if (attrs == NULL)
     
    8284        const struct ldb_map_attribute *map;
    8385        const char *name=NULL;
    84         int i, j, last;
     86        unsigned int i, j, last;
    8587        int ret;
    8688
     
    125127
    126128                switch (map->type) {
    127                 case MAP_IGNORE:
     129                case LDB_MAP_IGNORE:
    128130                        continue;
    129131
    130                 case MAP_KEEP:
     132                case LDB_MAP_KEEP:
    131133                        name = attrs[i];
    132134                        goto named;
    133135
    134                 case MAP_RENAME:
    135                 case MAP_CONVERT:
     136                case LDB_MAP_RENAME:
     137                case LDB_MAP_CONVERT:
    136138                        name = map->u.rename.remote_name;
    137139                        goto named;
    138140
    139                 case MAP_GENERATE:
     141                case LDB_MAP_GENERATE:
    140142                        /* Add all remote names of "generate" attrs */
    141143                        for (j = 0; map->u.generate.remote_names[j]; j++) {
     
    220222                                                         const struct ldb_message_element *old)
    221223{
     224        const struct ldb_map_context *data = map_get_context(module);
     225        const char *local_attr_name = attr_name;
    222226        struct ldb_message_element *el;
    223         int i;
     227        unsigned int i;
    224228
    225229        el = talloc_zero(mem_ctx, struct ldb_message_element);
     
    236240        }
    237241
    238         el->name = talloc_strdup(el, attr_name);
     242        for (i = 0; data->attribute_maps[i].local_name; i++) {
     243                struct ldb_map_attribute *am = &data->attribute_maps[i];
     244                if ((am->type == LDB_MAP_RENAME &&
     245                        !strcmp(am->u.rename.remote_name, attr_name))
     246                    || (am->type == LDB_MAP_CONVERT &&
     247                        !strcmp(am->u.convert.remote_name, attr_name))) {
     248
     249                        local_attr_name = am->local_name;
     250                        break;
     251                }
     252        }
     253
     254        el->name = talloc_strdup(el, local_attr_name);
    239255        if (el->name == NULL) {
    240256                talloc_free(el);
     
    282298
    283299        switch (map->type) {
    284         case MAP_IGNORE:
    285                 break;
    286         case MAP_CONVERT:
     300        case LDB_MAP_IGNORE:
     301                break;
     302        case LDB_MAP_CONVERT:
    287303                remote_name = map->u.convert.remote_name;
    288304                break;
    289         case MAP_KEEP:
     305        case LDB_MAP_KEEP:
    290306                remote_name = attr_name;
    291307                break;
    292         case MAP_RENAME:
     308        case LDB_MAP_RENAME:
    293309                remote_name = map->u.rename.remote_name;
    294310                break;
    295         case MAP_GENERATE:
     311        case LDB_MAP_GENERATE:
    296312                break;
    297313        }
    298314
    299315        switch (map->type) {
    300         case MAP_IGNORE:
     316        case LDB_MAP_IGNORE:
    301317                return LDB_SUCCESS;
    302318
    303         case MAP_CONVERT:
     319        case LDB_MAP_CONVERT:
    304320                if (map->u.convert.convert_remote == NULL) {
    305321                        ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
     
    310326                }
    311327                /* fall through */
    312         case MAP_KEEP:
    313         case MAP_RENAME:
     328        case LDB_MAP_KEEP:
     329        case LDB_MAP_RENAME:
    314330                old = ldb_msg_find_element(remote, remote_name);
    315331                if (old) {
     
    320336                break;
    321337
    322         case MAP_GENERATE:
     338        case LDB_MAP_GENERATE:
    323339                if (map->u.generate.generate_local == NULL) {
    324340                        ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
     
    351367        const struct ldb_map_attribute *map = map_attr_find_local(data, "*");
    352368        struct ldb_message_element *el=NULL;
    353         int i, ret;
     369        unsigned int i;
     370        int ret;
    354371
    355372        /* Perhaps we have a mapping for "*" */
    356         if (map && map->type == MAP_KEEP) {
     373        if (map && map->type == LDB_MAP_KEEP) {
    357374                /* We copy everything over, and hope that anything with a
    358375                   more specific rule is overwritten */
     
    393410static int ldb_msg_merge_local(struct ldb_module *module, struct ldb_message *msg1, struct ldb_message *msg2)
    394411{
    395         int i, ret;
     412        unsigned int i;
     413        int ret;
    396414
    397415        for (i = 0; i < msg2->num_elements; i++) {
     
    409427                                struct ldb_message *remote)
    410428{
    411         int i, ret;
     429        unsigned int i;
     430        int ret;
    412431        const char * const *attrs = ac->all_attrs;
    413432        if (!attrs) {
     
    521540{
    522541        const char **new_attrs;
    523         int i, ret;
     542        unsigned int i;
     543        int ret;
    524544
    525545        if (tree == NULL) {
     
    548568                return 0;
    549569        }
    550 
    551         return -1;
    552570}
    553571
     
    589607static int map_subtree_select_local_list(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree)
    590608{
    591         int i, j, ret=0;
     609        unsigned int i, j;
     610        int ret=0;
    592611
    593612        /* Prepare new tree */
     
    712731static int map_subtree_collect_remote_list(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree)
    713732{
    714         int i, j, ret=0;
     733        unsigned int i, j;
     734        int ret=0;
    715735
    716736        /* Prepare new tree */
     
    773793        **new = *tree;
    774794       
    775         if (map->type == MAP_KEEP) {
     795        if (map->type == LDB_MAP_KEEP) {
    776796                /* Nothing to do here */
    777797                return 0;
     
    815835        }
    816836
    817         if (map->type == MAP_RENAME) {
     837        if (map->type == LDB_MAP_RENAME) {
    818838                /* Nothing more to do here, the attribute has been renamed */
    819839                return 0;
     
    898918        }
    899919
    900         if (map->type == MAP_GENERATE) {
     920        if (map->type == LDB_MAP_GENERATE) {
    901921                ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: "
    902922                          "Skipping attribute '%s': "
     
    10521072        const char * const *attrs;
    10531073        struct ldb_context *ldb;
    1054         int i;
     1074        unsigned int i;
     1075        int ret;
     1076        bool matched;
    10551077
    10561078        ldb = ldb_module_get_ctx(ac->module);
    10571079
    10581080        /* Merged result doesn't match original query, skip */
    1059         if (!ldb_match_msg(ldb, ares->message,
    1060                            ac->req->op.search.tree,
    1061                            ac->req->op.search.base,
    1062                            ac->req->op.search.scope)) {
     1081        ret = ldb_match_msg_error(ldb, ares->message,
     1082                                  ac->req->op.search.tree,
     1083                                  ac->req->op.search.base,
     1084                                  ac->req->op.search.scope,
     1085                                  &matched);
     1086        if (ret != LDB_SUCCESS) return ret;
     1087        if (!matched) {
    10631088                ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_map: "
    10641089                          "Skipping record '%s': "
     
    10901115
    10911116/* Search a record. */
    1092 int map_search(struct ldb_module *module, struct ldb_request *req)
     1117int ldb_map_search(struct ldb_module *module, struct ldb_request *req)
    10931118{
    10941119        struct ldb_parse_tree *remote_tree;
     
    11861211                                      ac, map_remote_search_callback,
    11871212                                      req);
     1213        LDB_REQ_SET_LOCATION(remote_req);
    11881214        if (ret != LDB_SUCCESS) {
    11891215                return LDB_ERR_OPERATIONS_ERROR;
     
    12621288                }
    12631289
    1264                 talloc_free(ares);
     1290                ac->remote_done_ares = talloc_steal(ac, ares);
    12651291
    12661292                ret = map_search_local(ac);
     
    13341360
    13351361        case LDB_REPLY_DONE:
     1362                /* We don't need the local 'ares', but we will use the remote one from below */
    13361363                talloc_free(ares);
    13371364
     
    13721399                 * finish operations for this module */
    13731400                return ldb_module_done(ac->req,
    1374                                         ac->r_current->remote->controls,
    1375                                         ac->r_current->remote->response,
    1376                                         ac->r_current->remote->error);
     1401                                        ac->remote_done_ares->controls,
     1402                                        ac->remote_done_ares->response,
     1403                                        ac->remote_done_ares->error);
    13771404        }
    13781405
  • vendor/current/source4/lib/ldb/ldb_map/ldb_map_private.h

    r414 r740  
    1 #include "ldb_includes.h"
     1#include "replace.h"
     2#include "system/filesys.h"
     3#include "system/time.h"
    24
    35/* A handy macro to report Out of Memory conditions */
     
    3840        struct map_reply *r_list;
    3941        struct map_reply *r_current;
     42
     43        /* The response continaing any controls the remote server gave */
     44        struct ldb_reply *remote_done_ares;
    4045};
    4146
  • vendor/current/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c

    r414 r740  
    256256        char *ret = NULL;
    257257        char *attr;
    258         int i;
     258        unsigned int i;
    259259
    260260        ldb = ldb_module_get_ctx(module);
     
    558558
    559559/*
    560  * This is a bad hack to support ldap style comparisons whithin sqlite.
     560 * This is a bad hack to support ldap style comparisons within sqlite.
    561561 * val is the attribute in the row currently under test
    562562 * func is the desired test "<=" ">=" "~" ":"
     
    668668        struct ldb_message *msg;
    669669        long long eid;
    670         int i, ret;
     670        unsigned int i;
     671        int ret;
    671672
    672673        ac = talloc_get_type(result, struct lsql_context);
     
    687688                 * except the first time */
    688689                if (ac->current_eid != 0) {
    689                         msg = ldb_msg_canonicalize(ldb, msg);
    690                         if (!msg) return SQLITE_ABORT;
     690                        ret = ldb_msg_normalize(ldb, ac->req, msg, &msg);
     691                        if (ret != LDB_SUCCESS) {
     692                                return SQLITE_ABORT;
     693                        }
    691694
    692695                        ret = ldb_module_send_entry(ac->req, msg, NULL);
    693696                        if (ret != LDB_SUCCESS) {
    694697                                ac->callback_failed = true;
     698                                /* free msg object */
     699                                TALLOC_FREE(msg);
    695700                                return SQLITE_ABORT;
    696701                        }
     702
     703                        /* free msg object */
     704                        TALLOC_FREE(msg);
    697705                }
    698706
     
    960968        /* complete the last message if any */
    961969        if (ctx->ares) {
    962                 ctx->ares->message = ldb_msg_canonicalize(ldb, ctx->ares->message);
    963                 if (ctx->ares->message == NULL) {
     970                ret = ldb_msg_normalize(ldb, ctx->ares,
     971                                        ctx->ares->message,
     972                                        &ctx->ares->message);
     973                if (ret != LDB_SUCCESS) {
    964974                        return LDB_ERR_OPERATIONS_ERROR;
    965975                }
     
    987997        char *errmsg;
    988998        char *query;
    989         int i;
     999        unsigned int i;
    9901000        int ret;
    9911001
     
    10441054                const struct ldb_schema_attribute *a;
    10451055                char *attr;
    1046                 int j;
     1056                unsigned int j;
    10471057
    10481058                /* Get a case-folded copy of the attribute name */
     
    10531063
    10541064                a = ldb_schema_attribute_by_name(ldb, el->name);
     1065
     1066                if (el->num_value == 0) {
     1067                        ldb_asprintf_errstring(ldb, "attribute %s on %s specified, but with 0 values (illegal)",
     1068                                               el->name, ldb_dn_get_linearized(msg->dn));
     1069                        return LDB_ERR_CONSTRAINT_VIOLATION;
     1070                }
    10551071
    10561072                /* For each value of the specified attribute name... */
     
    10981114        struct ldb_context *ldb;
    10991115        struct ldb_message *msg = req->op.mod.message;
    1100         long long eid;
     1116        long long eid;
    11011117        char *errmsg;
    1102         int i;
     1118        unsigned int i;
    11031119        int ret;
    11041120
     
    11241140                char *attr;
    11251141                char *mod;
    1126                 int j;
     1142                unsigned int j;
    11271143
    11281144                /* Get a case-folded copy of the attribute name */
     
    11371153
    11381154                case LDB_FLAG_MOD_REPLACE:
     1155
     1156                        for (j=0; j<el->num_values; j++) {
     1157                                if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) {
     1158                                        ldb_asprintf_errstring(ldb, "%s: value #%d provided more than once", el->name, j);
     1159                                        return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
     1160                                }
     1161                        }
    11391162
    11401163                        /* remove all attributes before adding the replacements */
     
    11601183
    11611184                case LDB_FLAG_MOD_ADD:
    1162 #warning "We should throw an error if no value is provided!"
     1185
     1186                        if (el->num_values == 0) {
     1187                                ldb_asprintf_errstring(ldb, "attribute %s on %s specified, but with 0 values (illigal)",
     1188                                                       el->name, ldb_dn_get_linearized(msg->dn));
     1189                                return LDB_ERR_CONSTRAINT_VIOLATION;
     1190                        }
     1191
    11631192                        /* For each value of the specified attribute name... */
    11641193                        for (j = 0; j < el->num_values; j++) {
     
    14921521        default:
    14931522                /* no other op supported */
    1494                 ret = LDB_ERR_UNWILLING_TO_PERFORM;
     1523                ret = LDB_ERR_PROTOCOL_ERROR;
    14951524        }
    14961525
     
    15101539        struct timeval tv;
    15111540
    1512         if (check_critical_controls(req->controls)) {
     1541        if (ldb_check_critical_controls(req->controls)) {
    15131542                return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
    15141543        }
     
    18461875        struct ldb_module *module;
    18471876        struct lsqlite3_private *lsqlite3;
    1848         int i, ret;
     1877        unsigned int i;
     1878        int ret;
    18491879
    18501880        module = ldb_module_new(ldb, ldb, "ldb_sqlite3 backend", &lsqlite3_ops);
    1851         if (!module) return -1;
     1881        if (!module) return LDB_ERR_OPERATIONS_ERROR;
    18521882
    18531883        lsqlite3 = talloc(module, struct lsqlite3_private);
     
    18931923
    18941924        *_module = module;
    1895         return 0;
     1925        return LDB_SUCCESS;
    18961926
    18971927failed:
     
    19001930        }
    19011931        talloc_free(lsqlite3);
    1902         return -1;
    1903 }
    1904 
    1905 const struct ldb_backend_ops ldb_sqlite3_backend_ops = {
    1906         .name = "sqlite3",
    1907         .connect_fn = lsqlite3_connect
    1908 };
     1932        return LDB_ERR_OPERATIONS_ERROR;
     1933}
     1934
     1935int ldb_sqlite3_init(const char *version)
     1936{
     1937        LDB_MODULE_CHECK_VERSION(version);
     1938        return ldb_register_backend("sqlite3", lsqlite3_connect, false);
     1939}
  • vendor/current/source4/lib/ldb/ldb_tdb/ldb_cache.c

    r414 r740  
    6161        struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
    6262        struct ldb_message *msg;
    63         int i;
     63        unsigned int i;
    6464
    6565        ldb = ldb_module_get_ctx(module);
     
    8484static int ltdb_attributes_flags(struct ldb_message_element *el, unsigned *v)
    8585{
    86         int i;
     86        unsigned int i;
    8787        unsigned value = 0;
    8888        for (i=0;i<el->num_values;i++) {
    89                 int j;
     89                unsigned int j;
    9090                for (j=0;ltdb_valid_attr_flags[j].name;j++) {
    9191                        if (strcmp(ltdb_valid_attr_flags[j].name,
     
    113113        struct ldb_message *msg = ltdb->cache->attributes;
    114114        struct ldb_dn *dn;
    115         int i, r;
     115        unsigned int i;
     116        int r;
    116117
    117118        ldb = ldb_module_get_ctx(module);
     
    120121                /* we skip loading the @ATTRIBUTES record when a module is supplying
    121122                   its own attribute handling */
    122                 return LDB_SUCCESS;
     123                return 0;
    123124        }
    124125
     
    203204        ltdb->sequence_number = atof(initial_sequence_number);
    204205
    205         msg = talloc(ltdb, struct ldb_message);
     206        msg = ldb_msg_new(ltdb);
    206207        if (msg == NULL) {
    207208                goto failed;
     
    287288                ltdb->cache = talloc_zero(ltdb, struct ltdb_cache);
    288289                if (ltdb->cache == NULL) goto failed;
    289                 ltdb->cache->indexlist = talloc_zero(ltdb->cache, struct ldb_message);
    290                 ltdb->cache->attributes = talloc_zero(ltdb->cache, struct ldb_message);
     290                ltdb->cache->indexlist = ldb_msg_new(ltdb->cache);
     291                ltdb->cache->attributes = ldb_msg_new(ltdb->cache);
    291292                if (ltdb->cache->indexlist == NULL ||
    292293                    ltdb->cache->attributes == NULL) {
     
    295296        }
    296297
    297         baseinfo = talloc(ltdb->cache, struct ldb_message);
     298        baseinfo = ldb_msg_new(ltdb->cache);
    298299        if (baseinfo == NULL) goto failed;
    299300
    300         baseinfo_dn = ldb_dn_new(module, ldb, LTDB_BASEINFO);
     301        baseinfo_dn = ldb_dn_new(baseinfo, ldb, LTDB_BASEINFO);
    301302        if (baseinfo_dn == NULL) goto failed;
    302303
     
    327328
    328329        /* Read an interpret database options */
    329         options = talloc(ltdb->cache, struct ldb_message);
     330        options = ldb_msg_new(ltdb->cache);
    330331        if (options == NULL) goto failed;
    331332
     
    348349        memset(&ltdb->cache->last_attribute, 0, sizeof(ltdb->cache->last_attribute));
    349350
    350         ltdb_attributes_unload(module);
    351 
    352351        talloc_free(ltdb->cache->indexlist);
    353 
    354         ltdb->cache->indexlist = talloc_zero(ltdb->cache, struct ldb_message);
    355         ltdb->cache->attributes = talloc_zero(ltdb->cache, struct ldb_message);
     352        ltdb_attributes_unload(module); /* calls internally "talloc_free" */
     353
     354        ltdb->cache->indexlist = ldb_msg_new(ltdb->cache);
     355        ltdb->cache->attributes = ldb_msg_new(ltdb->cache);
    356356        if (ltdb->cache->indexlist == NULL ||
    357357            ltdb->cache->attributes == NULL) {
    358358                goto failed;
    359359        }
     360        ltdb->cache->one_level_indexes = false;
     361        ltdb->cache->attribute_indexes = false;
    360362           
    361363        indexlist_dn = ldb_dn_new(module, ldb, LTDB_INDEXLIST);
     
    367369        }
    368370
     371        if (ldb_msg_find_element(ltdb->cache->indexlist, LTDB_IDXONE) != NULL) {
     372                ltdb->cache->one_level_indexes = true;
     373        }
     374        if (ldb_msg_find_element(ltdb->cache->indexlist, LTDB_IDXATTR) != NULL) {
     375                ltdb->cache->attribute_indexes = true;
     376        }
     377
    369378        if (ltdb_attributes_load(module) == -1) {
    370379                goto failed;
     
    374383        talloc_free(options);
    375384        talloc_free(baseinfo);
    376         talloc_free(baseinfo_dn);
    377385        talloc_free(indexlist_dn);
    378386        return 0;
     
    381389        talloc_free(options);
    382390        talloc_free(baseinfo);
    383         talloc_free(baseinfo_dn);
    384391        talloc_free(indexlist_dn);
    385392        return -1;
     
    405412        ldb = ldb_module_get_ctx(module);
    406413
    407         msg = talloc(ltdb, struct ldb_message);
     414        msg = ldb_msg_new(ltdb);
    408415        if (msg == NULL) {
    409416                errno = ENOMEM;
     
    413420        s = talloc_asprintf(msg, "%llu", ltdb->sequence_number+1);
    414421        if (!s) {
     422                talloc_free(msg);
    415423                errno = ENOMEM;
    416424                return LDB_ERR_OPERATIONS_ERROR;
     
    449457        s = ldb_timestring(msg, t);
    450458        if (s == NULL) {
     459                talloc_free(msg);
    451460                return LDB_ERR_OPERATIONS_ERROR;
    452461        }
     
    455464        val_time.length = strlen(s);
    456465
    457         ret = ltdb_modify_internal(module, msg);
     466        ret = ltdb_modify_internal(module, msg, NULL);
    458467
    459468        talloc_free(msg);
     
    472481int ltdb_check_at_attributes_values(const struct ldb_val *value)
    473482{
    474         int i;
     483        unsigned int i;
    475484
    476485        for (i = 0; ltdb_valid_attr_flags[i].name != NULL; i++) {
  • vendor/current/source4/lib/ldb/ldb_tdb/ldb_index.c

    r414 r740  
    22   ldb database library
    33
    4    Copyright (C) Andrew Tridgell  2004
     4   Copyright (C) Andrew Tridgell  2004-2009
    55
    66     ** NOTE! The following LGPL license applies to the ldb
     
    3333
    3434#include "ldb_tdb.h"
    35 #include "dlinklist.h"
    36 
    37 /*
    38   the idxptr code is a bit unusual. The way it works is to replace
    39   @IDX elements in records during a transaction with @IDXPTR
    40   elements. The @IDXPTR elements don't contain the actual index entry
    41   values, but contain a pointer to a linked list of values.
    42 
    43   This means we are storing pointers in a database, which is normally
    44   not allowed, but in this case we are storing them only for the
    45   duration of a transaction, and re-writing them into the normal @IDX
    46   format at the end of the transaction. That means no other processes
    47   are ever exposed to the @IDXPTR values.
    48 
    49   The advantage is that the linked list doesn't cause huge
    50   fragmentation during a transaction. Without the @IDXPTR method we
    51   often ended up with a ldb that was between 10x and 100x larger then
    52   it needs to be due to massive fragmentation caused by re-writing
    53   @INDEX records many times during indexing.
    54  */
    55 struct ldb_index_pointer {
    56         struct ldb_index_pointer *next, *prev;
    57         struct ldb_val value;
     35
     36struct dn_list {
     37        unsigned int count;
     38        struct ldb_val *dn;
    5839};
    5940
    6041struct ltdb_idxptr {
    61         int num_dns;
    62         const char **dn_list;
    63         bool repack;
     42        struct tdb_context *itdb;
     43        int error;
    6444};
    6545
    66 /*
    67   add to the list of DNs that need to be fixed on transaction end
    68  */
    69 static int ltdb_idxptr_add(struct ldb_module *module, const struct ldb_message *msg)
    70 {
    71         void *data = ldb_module_get_private(module);
    72         struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
    73         ltdb->idxptr->dn_list = talloc_realloc(ltdb->idxptr, ltdb->idxptr->dn_list,
    74                                                const char *, ltdb->idxptr->num_dns+1);
    75         if (ltdb->idxptr->dn_list == NULL) {
    76                 ltdb->idxptr->num_dns = 0;
    77                 return LDB_ERR_OPERATIONS_ERROR;
    78         }
    79         ltdb->idxptr->dn_list[ltdb->idxptr->num_dns] =
    80                 talloc_strdup(ltdb->idxptr->dn_list, ldb_dn_get_linearized(msg->dn));
    81         if (ltdb->idxptr->dn_list[ltdb->idxptr->num_dns] == NULL) {
    82                 return LDB_ERR_OPERATIONS_ERROR;
    83         }
    84         ltdb->idxptr->num_dns++;
    85         return LDB_SUCCESS;
    86 }
    87 
    88 /* free an idxptr record */
    89 static int ltdb_free_idxptr(struct ldb_module *module, struct ldb_message_element *el)
    90 {
    91         struct ldb_val val;
    92         struct ldb_index_pointer *ptr;
    93 
    94         if (el->num_values != 1) {
    95                 return LDB_ERR_OPERATIONS_ERROR;
    96         }
    97 
    98         val = el->values[0];
    99         if (val.length != sizeof(void *)) {
    100                 return LDB_ERR_OPERATIONS_ERROR;
    101         }
    102 
    103         ptr = *(struct ldb_index_pointer **)val.data;
    104         if (talloc_get_type(ptr, struct ldb_index_pointer) != ptr) {
    105                 return LDB_ERR_OPERATIONS_ERROR;
    106         }
    107 
    108         while (ptr) {
    109                 struct ldb_index_pointer *tmp = ptr;
    110                 DLIST_REMOVE(ptr, ptr);
    111                 talloc_free(tmp);
    112         }
    113 
    114         return LDB_SUCCESS;
    115 }
    116 
    117 
    118 /* convert from the IDXPTR format to a ldb_message_element format */
    119 static int ltdb_convert_from_idxptr(struct ldb_module *module, struct ldb_message_element *el)
    120 {
    121         struct ldb_val val;
    122         struct ldb_index_pointer *ptr, *tmp;
    123         int i;
    124         struct ldb_val *val2;
    125 
    126         if (el->num_values != 1) {
    127                 return LDB_ERR_OPERATIONS_ERROR;
    128         }
    129 
    130         val = el->values[0];
    131         if (val.length != sizeof(void *)) {
    132                 return LDB_ERR_OPERATIONS_ERROR;
    133         }
    134 
    135         ptr = *(struct ldb_index_pointer **)val.data;
    136         if (talloc_get_type(ptr, struct ldb_index_pointer) != ptr) {
    137                 return LDB_ERR_OPERATIONS_ERROR;
    138         }
    139 
    140         /* count the length of the list */
    141         for (i=0, tmp = ptr; tmp; tmp=tmp->next) {
    142                 i++;
    143         }
    144 
    145         /* allocate the new values array */
    146         val2 = talloc_realloc(NULL, el->values, struct ldb_val, i);
    147         if (val2 == NULL) {
    148                 return LDB_ERR_OPERATIONS_ERROR;
    149         }
    150         el->values = val2;
    151         el->num_values = i;
    152 
    153         /* populate the values array */
    154         for (i=0, tmp = ptr; tmp; tmp=tmp->next, i++) {
    155                 el->values[i].length = tmp->value.length;
    156                 /* we need to over-allocate here as there are still some places
    157                    in ldb that rely on null termination. */
    158                 el->values[i].data = talloc_size(el->values, tmp->value.length+1);
    159                 if (el->values[i].data == NULL) {
    160                         return LDB_ERR_OPERATIONS_ERROR;
    161                 }
    162                 memcpy(el->values[i].data, tmp->value.data, tmp->value.length);
    163                 el->values[i].data[tmp->value.length] = 0;
    164         }
    165 
    166         /* update the name */
    167         el->name = LTDB_IDX;
    168 
    169         return LDB_SUCCESS;
    170 }
    171 
    172 
    173 /* convert to the IDXPTR format from a ldb_message_element format */
    174 static int ltdb_convert_to_idxptr(struct ldb_module *module, struct ldb_message_element *el)
    175 {
    176         struct ldb_index_pointer *ptr, *tmp;
    177         int i;
    178         struct ldb_val *val2;
    179         void *data = ldb_module_get_private(module);
    180         struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
    181 
    182         ptr = NULL;
    183 
    184         for (i=0;i<el->num_values;i++) {
    185                 tmp = talloc(ltdb->idxptr, struct ldb_index_pointer);
    186                 if (tmp == NULL) {
    187                         return LDB_ERR_OPERATIONS_ERROR;
    188                 }
    189                 tmp->value = el->values[i];
    190                 tmp->value.data = talloc_memdup(tmp, tmp->value.data, tmp->value.length);
    191                 if (tmp->value.data == NULL) {
    192                         return LDB_ERR_OPERATIONS_ERROR;
    193                 }
    194                 DLIST_ADD(ptr, tmp);
    195         }
    196 
    197         /* allocate the new values array */
    198         val2 = talloc_realloc(NULL, el->values, struct ldb_val, 1);
    199         if (val2 == NULL) {
    200                 return LDB_ERR_OPERATIONS_ERROR;
    201         }
    202         el->values = val2;
    203         el->num_values = 1;
    204 
    205         el->values[0].data = talloc_memdup(el->values, &ptr, sizeof(ptr));
    206         el->values[0].length = sizeof(ptr);
    207 
    208         /* update the name */
    209         el->name = LTDB_IDXPTR;
    210 
    211         return LDB_SUCCESS;
    212 }
    213 
     46/* we put a @IDXVERSION attribute on index entries. This
     47   allows us to tell if it was written by an older version
     48*/
     49#define LTDB_INDEXING_VERSION 2
    21450
    21551/* enable the idxptr mode when transactions start */
    21652int ltdb_index_transaction_start(struct ldb_module *module)
    21753{
    218         void *data = ldb_module_get_private(module);
    219         struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
    220         ltdb->idxptr = talloc_zero(module, struct ltdb_idxptr);
     54        struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
     55        ltdb->idxptr = talloc_zero(ltdb, struct ltdb_idxptr);
    22156        return LDB_SUCCESS;
    22257}
    22358
    224 /*
    225   a wrapper around ltdb_search_dn1() which translates pointer based index records
    226   and maps them into normal ldb message structures
    227  */
    228 static int ltdb_search_dn1_index(struct ldb_module *module,
    229                                 struct ldb_dn *dn, struct ldb_message *msg)
    230 {
    231         int ret, i;
     59/* compare two DN entries in a dn_list. Take account of possible
     60 * differences in string termination */
     61static int dn_list_cmp(const struct ldb_val *v1, const struct ldb_val *v2)
     62{
     63        if (v1->length > v2->length && v1->data[v2->length] != 0) {
     64                return -1;
     65        }
     66        if (v1->length < v2->length && v2->data[v1->length] != 0) {
     67                return 1;
     68        }
     69        return strncmp((char *)v1->data, (char *)v2->data, v1->length);
     70}
     71
     72
     73/*
     74  find a entry in a dn_list, using a ldb_val. Uses a case sensitive
     75  comparison with the dn returns -1 if not found
     76 */
     77static int ltdb_dn_list_find_val(const struct dn_list *list, const struct ldb_val *v)
     78{
     79        unsigned int i;
     80        for (i=0; i<list->count; i++) {
     81                if (dn_list_cmp(&list->dn[i], v) == 0) return i;
     82        }
     83        return -1;
     84}
     85
     86/*
     87  find a entry in a dn_list. Uses a case sensitive comparison with the dn
     88  returns -1 if not found
     89 */
     90static int ltdb_dn_list_find_str(struct dn_list *list, const char *dn)
     91{
     92        struct ldb_val v;
     93        v.data = discard_const_p(unsigned char, dn);
     94        v.length = strlen(dn);
     95        return ltdb_dn_list_find_val(list, &v);
     96}
     97
     98/*
     99  this is effectively a cast function, but with lots of paranoia
     100  checks and also copes with CPUs that are fussy about pointer
     101  alignment
     102 */
     103static struct dn_list *ltdb_index_idxptr(struct ldb_module *module, TDB_DATA rec, bool check_parent)
     104{
     105        struct dn_list *list;
     106        if (rec.dsize != sizeof(void *)) {
     107                ldb_asprintf_errstring(ldb_module_get_ctx(module),
     108                                       "Bad data size for idxptr %u", (unsigned)rec.dsize);
     109                return NULL;
     110        }
     111        /* note that we can't just use a cast here, as rec.dptr may
     112           not be aligned sufficiently for a pointer. A cast would cause
     113           platforms like some ARM CPUs to crash */
     114        memcpy(&list, rec.dptr, sizeof(void *));
     115        list = talloc_get_type(list, struct dn_list);
     116        if (list == NULL) {
     117                ldb_asprintf_errstring(ldb_module_get_ctx(module),
     118                                       "Bad type '%s' for idxptr",
     119                                       talloc_get_name(list));
     120                return NULL;
     121        }
     122        if (check_parent && list->dn && talloc_parent(list->dn) != list) {
     123                ldb_asprintf_errstring(ldb_module_get_ctx(module),
     124                                       "Bad parent '%s' for idxptr",
     125                                       talloc_get_name(talloc_parent(list->dn)));
     126                return NULL;
     127        }
     128        return list;
     129}
     130
     131/*
     132  return the @IDX list in an index entry for a dn as a
     133  struct dn_list
     134 */
     135static int ltdb_dn_list_load(struct ldb_module *module,
     136                             struct ldb_dn *dn, struct dn_list *list)
     137{
     138        struct ldb_message *msg;
     139        int ret;
     140        struct ldb_message_element *el;
     141        struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
     142        TDB_DATA rec;
     143        struct dn_list *list2;
     144        TDB_DATA key;
     145
     146        list->dn = NULL;
     147        list->count = 0;
     148
     149        /* see if we have any in-memory index entries */
     150        if (ltdb->idxptr == NULL ||
     151            ltdb->idxptr->itdb == NULL) {
     152                goto normal_index;
     153        }
     154
     155        key.dptr = discard_const_p(unsigned char, ldb_dn_get_linearized(dn));
     156        key.dsize = strlen((char *)key.dptr);
     157
     158        rec = tdb_fetch(ltdb->idxptr->itdb, key);
     159        if (rec.dptr == NULL) {
     160                goto normal_index;
     161        }
     162
     163        /* we've found an in-memory index entry */
     164        list2 = ltdb_index_idxptr(module, rec, true);
     165        if (list2 == NULL) {
     166                free(rec.dptr);
     167                return LDB_ERR_OPERATIONS_ERROR;
     168        }
     169        free(rec.dptr);
     170
     171        *list = *list2;
     172        return LDB_SUCCESS;
     173
     174normal_index:
     175        msg = ldb_msg_new(list);
     176        if (msg == NULL) {
     177                return LDB_ERR_OPERATIONS_ERROR;
     178        }
     179
    232180        ret = ltdb_search_dn1(module, dn, msg);
    233181        if (ret != LDB_SUCCESS) {
     182                talloc_free(msg);
    234183                return ret;
    235184        }
    236185
    237         /* if this isn't a @INDEX record then don't munge it */
    238         if (strncmp(ldb_dn_get_linearized(msg->dn), LTDB_INDEX ":", strlen(LTDB_INDEX) + 1) != 0) {
    239                 return LDB_ERR_OPERATIONS_ERROR;
    240         }
    241 
    242         for (i=0;i<msg->num_elements;i++) {
    243                 struct ldb_message_element *el = &msg->elements[i];
    244                 if (strcmp(el->name, LTDB_IDXPTR) == 0) {
    245                         ret = ltdb_convert_from_idxptr(module, el);
    246                         if (ret != LDB_SUCCESS) {
    247                                 return ret;
    248                         }
    249                 }
    250         }
    251 
    252         return ret;
    253 }
    254 
    255 
    256 
    257 /*
    258   fixup the idxptr for one DN
    259  */
    260 static int ltdb_idxptr_fix_dn(struct ldb_module *module, const char *strdn)
    261 {
    262         struct ldb_context *ldb;
    263         struct ldb_dn *dn;
    264         struct ldb_message *msg = ldb_msg_new(module);
     186        /* TODO: check indexing version number */
     187
     188        el = ldb_msg_find_element(msg, LTDB_IDX);
     189        if (!el) {
     190                talloc_free(msg);
     191                return LDB_SUCCESS;
     192        }
     193
     194        /* we avoid copying the strings by stealing the list */
     195        list->dn = talloc_steal(list, el->values);
     196        list->count = el->num_values;
     197
     198        return LDB_SUCCESS;
     199}
     200
     201
     202/*
     203  save a dn_list into a full @IDX style record
     204 */
     205static int ltdb_dn_list_store_full(struct ldb_module *module, struct ldb_dn *dn,
     206                                   struct dn_list *list)
     207{
     208        struct ldb_message *msg;
    265209        int ret;
    266210
    267         ldb = ldb_module_get_ctx(module);
    268 
    269         dn = ldb_dn_new(msg, ldb, strdn);
    270         if (ltdb_search_dn1_index(module, dn, msg) == LDB_SUCCESS) {
    271                 ret = ltdb_store(module, msg, TDB_REPLACE);
    272         }
     211        if (list->count == 0) {
     212                ret = ltdb_delete_noindex(module, dn);
     213                if (ret == LDB_ERR_NO_SUCH_OBJECT) {
     214                        return LDB_SUCCESS;
     215                }
     216                return ret;
     217        }
     218
     219        msg = ldb_msg_new(module);
     220        if (!msg) {
     221                return ldb_module_oom(module);
     222        }
     223
     224        ret = ldb_msg_add_fmt(msg, LTDB_IDXVERSION, "%u", LTDB_INDEXING_VERSION);
     225        if (ret != LDB_SUCCESS) {
     226                talloc_free(msg);
     227                return ldb_module_oom(module);
     228        }
     229
     230        msg->dn = dn;
     231        if (list->count > 0) {
     232                struct ldb_message_element *el;
     233
     234                ret = ldb_msg_add_empty(msg, LTDB_IDX, LDB_FLAG_MOD_ADD, &el);
     235                if (ret != LDB_SUCCESS) {
     236                        talloc_free(msg);
     237                        return ldb_module_oom(module);
     238                }
     239                el->values = list->dn;
     240                el->num_values = list->count;
     241        }
     242
     243        ret = ltdb_store(module, msg, TDB_REPLACE);
    273244        talloc_free(msg);
    274245        return ret;
    275246}
    276247
     248/*
     249  save a dn_list into the database, in either @IDX or internal format
     250 */
     251static int ltdb_dn_list_store(struct ldb_module *module, struct ldb_dn *dn,
     252                              struct dn_list *list)
     253{
     254        struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
     255        TDB_DATA rec, key;
     256        int ret;
     257        struct dn_list *list2;
     258
     259        if (ltdb->idxptr == NULL) {
     260                return ltdb_dn_list_store_full(module, dn, list);
     261        }
     262
     263        if (ltdb->idxptr->itdb == NULL) {
     264                ltdb->idxptr->itdb = tdb_open(NULL, 1000, TDB_INTERNAL, O_RDWR, 0);
     265                if (ltdb->idxptr->itdb == NULL) {
     266                        return LDB_ERR_OPERATIONS_ERROR;
     267                }
     268        }
     269
     270        key.dptr = discard_const_p(unsigned char, ldb_dn_get_linearized(dn));
     271        key.dsize = strlen((char *)key.dptr);
     272
     273        rec = tdb_fetch(ltdb->idxptr->itdb, key);
     274        if (rec.dptr != NULL) {
     275                list2 = ltdb_index_idxptr(module, rec, false);
     276                if (list2 == NULL) {
     277                        free(rec.dptr);
     278                        return LDB_ERR_OPERATIONS_ERROR;
     279                }
     280                free(rec.dptr);
     281                list2->dn = talloc_steal(list2, list->dn);
     282                list2->count = list->count;
     283                return LDB_SUCCESS;
     284        }
     285
     286        list2 = talloc(ltdb->idxptr, struct dn_list);
     287        if (list2 == NULL) {
     288                return LDB_ERR_OPERATIONS_ERROR;
     289        }
     290        list2->dn = talloc_steal(list2, list->dn);
     291        list2->count = list->count;
     292
     293        rec.dptr = (uint8_t *)&list2;
     294        rec.dsize = sizeof(void *);
     295
     296        ret = tdb_store(ltdb->idxptr->itdb, key, rec, TDB_INSERT);
     297        if (ret == -1) {
     298                return ltdb_err_map(tdb_error(ltdb->idxptr->itdb));
     299        }
     300        return LDB_SUCCESS;
     301}
     302
     303/*
     304  traverse function for storing the in-memory index entries on disk
     305 */
     306static int ltdb_index_traverse_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state)
     307{
     308        struct ldb_module *module = state;
     309        struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
     310        struct ldb_dn *dn;
     311        struct ldb_context *ldb = ldb_module_get_ctx(module);
     312        struct ldb_val v;
     313        struct dn_list *list;
     314
     315        list = ltdb_index_idxptr(module, data, true);
     316        if (list == NULL) {
     317                ltdb->idxptr->error = LDB_ERR_OPERATIONS_ERROR;
     318                return -1;
     319        }
     320
     321        v.data = key.dptr;
     322        v.length = strnlen((char *)key.dptr, key.dsize);
     323
     324        dn = ldb_dn_from_ldb_val(module, ldb, &v);
     325        if (dn == NULL) {
     326                ldb_asprintf_errstring(ldb, "Failed to parse index key %*.*s as an LDB DN", (int)v.length, (int)v.length, (const char *)v.data);
     327                ltdb->idxptr->error = LDB_ERR_OPERATIONS_ERROR;
     328                return -1;
     329        }
     330
     331        ltdb->idxptr->error = ltdb_dn_list_store_full(module, dn, list);
     332        talloc_free(dn);
     333        if (ltdb->idxptr->error != 0) {
     334                return -1;
     335        }
     336        return 0;
     337}
     338
    277339/* cleanup the idxptr mode when transaction commits */
    278340int ltdb_index_transaction_commit(struct ldb_module *module)
    279341{
    280         int i;
    281         void *data = ldb_module_get_private(module);
    282         struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
    283 
    284         /* fix all the DNs that we have modified */
    285         if (ltdb->idxptr) {
    286                 for (i=0;i<ltdb->idxptr->num_dns;i++) {
    287                         ltdb_idxptr_fix_dn(module, ltdb->idxptr->dn_list[i]);
    288                 }
    289 
    290                 if (ltdb->idxptr->repack) {
    291                         tdb_repack(ltdb->tdb);
    292                 }
    293         }
    294 
     342        struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
     343        int ret;
     344
     345        struct ldb_context *ldb = ldb_module_get_ctx(module);
     346
     347        ldb_reset_err_string(ldb);
     348
     349        if (ltdb->idxptr->itdb) {
     350                tdb_traverse(ltdb->idxptr->itdb, ltdb_index_traverse_store, module);
     351                tdb_close(ltdb->idxptr->itdb);
     352        }
     353
     354        ret = ltdb->idxptr->error;
     355        if (ret != LDB_SUCCESS) {
     356                if (!ldb_errstring(ldb)) {
     357                        ldb_set_errstring(ldb, ldb_strerror(ret));
     358                }
     359                ldb_asprintf_errstring(ldb, "Failed to store index records in transaction commit: %s", ldb_errstring(ldb));
     360        }
     361
     362        talloc_free(ltdb->idxptr);
     363        ltdb->idxptr = NULL;
     364        return ret;
     365}
     366
     367/* cleanup the idxptr mode when transaction cancels */
     368int ltdb_index_transaction_cancel(struct ldb_module *module)
     369{
     370        struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
     371        if (ltdb->idxptr && ltdb->idxptr->itdb) {
     372                tdb_close(ltdb->idxptr->itdb);
     373        }
    295374        talloc_free(ltdb->idxptr);
    296375        ltdb->idxptr = NULL;
     
    298377}
    299378
    300 /* cleanup the idxptr mode when transaction cancels */
    301 int ltdb_index_transaction_cancel(struct ldb_module *module)
    302 {
    303         void *data = ldb_module_get_private(module);
    304         struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
    305         talloc_free(ltdb->idxptr);
    306         ltdb->idxptr = NULL;
    307         return LDB_SUCCESS;
    308 }
    309 
    310 
    311 
    312 /* a wrapper around ltdb_store() for the index code which
    313    stores in IDXPTR format when idxptr mode is enabled
    314 
    315    WARNING: This modifies the msg which is passed in
    316 */
    317 int ltdb_store_idxptr(struct ldb_module *module, const struct ldb_message *msg, int flgs)
    318 {
    319         void *data = ldb_module_get_private(module);
    320         struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
    321         int ret;
    322 
    323         if (ltdb->idxptr) {
    324                 int i;
    325                 struct ldb_message *msg2 = ldb_msg_new(module);
    326 
    327                 /* free any old pointer */
    328                 ret = ltdb_search_dn1(module, msg->dn, msg2);
    329                 if (ret == 0) {
    330                         for (i=0;i<msg2->num_elements;i++) {
    331                                 struct ldb_message_element *el = &msg2->elements[i];
    332                                 if (strcmp(el->name, LTDB_IDXPTR) == 0) {
    333                                         ret = ltdb_free_idxptr(module, el);
    334                                         if (ret != LDB_SUCCESS) {
    335                                                 return ret;
    336                                         }
    337                                 }
    338                         }
    339                 }
    340                 talloc_free(msg2);
    341 
    342                 for (i=0;i<msg->num_elements;i++) {
    343                         struct ldb_message_element *el = &msg->elements[i];
    344                         if (strcmp(el->name, LTDB_IDX) == 0) {
    345                                 ret = ltdb_convert_to_idxptr(module, el);
    346                                 if (ret != LDB_SUCCESS) {
    347                                         return ret;
    348                                 }
    349                         }
    350                 }
    351 
    352                 if (ltdb_idxptr_add(module, msg) != 0) {
    353                         return LDB_ERR_OPERATIONS_ERROR;
    354                 }
    355         }
    356 
    357         ret = ltdb_store(module, msg, flgs);
    358         return ret;
    359 }
    360 
    361 
    362 /*
    363   find an element in a list, using the given comparison function and
    364   assuming that the list is already sorted using comp_fn
    365 
    366   return -1 if not found, or the index of the first occurance of needle if found
    367 */
    368 static int ldb_list_find(const void *needle,
    369                          const void *base, size_t nmemb, size_t size,
    370                          comparison_fn_t comp_fn)
    371 {
    372         const char *base_p = (const char *)base;
    373         size_t min_i, max_i, test_i;
    374 
    375         if (nmemb == 0) {
    376                 return -1;
    377         }
    378 
    379         min_i = 0;
    380         max_i = nmemb-1;
    381 
    382         while (min_i < max_i) {
    383                 int r;
    384 
    385                 test_i = (min_i + max_i) / 2;
    386                 /* the following cast looks strange, but is
    387                  correct. The key to understanding it is that base_p
    388                  is a pointer to an array of pointers, so we have to
    389                  dereference it after casting to void **. The strange
    390                  const in the middle gives us the right type of pointer
    391                  after the dereference  (tridge) */
    392                 r = comp_fn(needle, *(void * const *)(base_p + (size * test_i)));
    393                 if (r == 0) {
    394                         /* scan back for first element */
    395                         while (test_i > 0 &&
    396                                comp_fn(needle, *(void * const *)(base_p + (size * (test_i-1)))) == 0) {
    397                                 test_i--;
    398                         }
    399                         return test_i;
    400                 }
    401                 if (r < 0) {
    402                         if (test_i == 0) {
    403                                 return -1;
    404                         }
    405                         max_i = test_i - 1;
    406                 }
    407                 if (r > 0) {
    408                         min_i = test_i + 1;
    409                 }
    410         }
    411 
    412         if (comp_fn(needle, *(void * const *)(base_p + (size * min_i))) == 0) {
    413                 return min_i;
    414         }
    415 
    416         return -1;
    417 }
    418 
    419 struct dn_list {
    420         unsigned int count;
    421         char **dn;
    422 };
    423379
    424380/*
    425381  return the dn key to be used for an index
    426   caller frees
     382  the caller is responsible for freeing
    427383*/
    428384static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb,
     
    458414        if (ldb_should_b64_encode(ldb, &v)) {
    459415                char *vstr = ldb_base64_encode(ldb, (char *)v.data, v.length);
    460                 if (!vstr) return NULL;
     416                if (!vstr) {
     417                        talloc_free(attr_folded);
     418                        return NULL;
     419                }
    461420                ret = ldb_dn_new_fmt(ldb, ldb, "%s:%s::%s", LTDB_INDEX, attr_folded, vstr);
    462421                talloc_free(vstr);
     
    476435  see if a attribute value is in the list of indexed attributes
    477436*/
    478 static int ldb_msg_find_idx(const struct ldb_message *msg, const char *attr,
    479                             unsigned int *v_idx, const char *key)
    480 {
    481         unsigned int i, j;
    482         for (i=0;i<msg->num_elements;i++) {
    483                 if (ldb_attr_cmp(msg->elements[i].name, key) == 0) {
    484                         const struct ldb_message_element *el = &msg->elements[i];
    485 
    486                         if (attr == NULL) {
    487                                 /* in this case we are just looking to see if key is present,
    488                                    we are not spearching for a specific index */
    489                                 return 0;
    490                         }
    491 
    492                         for (j=0;j<el->num_values;j++) {
    493                                 if (ldb_attr_cmp((char *)el->values[j].data, attr) == 0) {
    494                                         if (v_idx) {
    495                                                 *v_idx = j;
    496                                         }
    497                                         return i;
    498                                 }
    499                         }
    500                 }
    501         }
    502         return -1;
    503 }
    504 
    505 /* used in sorting dn lists */
    506 static int list_cmp(const char **s1, const char **s2)
    507 {
    508         return strcmp(*s1, *s2);
    509 }
    510 
    511 /*
    512   return a list of dn's that might match a simple indexed search or
     437static bool ltdb_is_indexed(const struct ldb_message *index_list, const char *attr)
     438{
     439        unsigned int i;
     440        struct ldb_message_element *el;
     441
     442        el = ldb_msg_find_element(index_list, LTDB_IDXATTR);
     443        if (el == NULL) {
     444                return false;
     445        }
     446
     447        /* TODO: this is too expensive! At least use a binary search */
     448        for (i=0; i<el->num_values; i++) {
     449                if (ldb_attr_cmp((char *)el->values[i].data, attr) == 0) {
     450                        return true;
     451                }
     452        }
     453        return false;
     454}
     455
     456/*
     457  in the following logic functions, the return value is treated as
     458  follows:
     459
     460     LDB_SUCCESS: we found some matching index values
     461
     462     LDB_ERR_NO_SUCH_OBJECT: we know for sure that no object matches
     463
     464     LDB_ERR_OPERATIONS_ERROR: indexing could not answer the call,
     465                               we'll need a full search
     466 */
     467
     468/*
     469  return a list of dn's that might match a simple indexed search (an
     470  equality search only)
    513471 */
    514472static int ltdb_index_dn_simple(struct ldb_module *module,
     
    520478        struct ldb_dn *dn;
    521479        int ret;
    522         unsigned int i, j;
    523         struct ldb_message *msg;
    524480
    525481        ldb = ldb_module_get_ctx(module);
     
    530486        /* if the attribute isn't in the list of indexed attributes then
    531487           this node needs a full search */
    532         if (ldb_msg_find_idx(index_list, tree->u.equality.attr, NULL, LTDB_IDXATTR) == -1) {
     488        if (!ltdb_is_indexed(index_list, tree->u.equality.attr)) {
    533489                return LDB_ERR_OPERATIONS_ERROR;
    534490        }
     
    539495        if (!dn) return LDB_ERR_OPERATIONS_ERROR;
    540496
    541         msg = talloc(list, struct ldb_message);
    542         if (msg == NULL) {
    543                 return LDB_ERR_OPERATIONS_ERROR;
    544         }
    545 
    546         ret = ltdb_search_dn1_index(module, dn, msg);
     497        ret = ltdb_dn_list_load(module, dn, list);
    547498        talloc_free(dn);
    548         if (ret != LDB_SUCCESS) {
    549                 return ret;
    550         }
    551 
    552         for (i=0;i<msg->num_elements;i++) {
    553                 struct ldb_message_element *el;
    554 
    555                 if (strcmp(msg->elements[i].name, LTDB_IDX) != 0) {
    556                         continue;
    557                 }
    558 
    559                 el = &msg->elements[i];
    560 
    561                 list->dn = talloc_array(list, char *, el->num_values);
    562                 if (!list->dn) {
    563                         talloc_free(msg);
    564                         return LDB_ERR_OPERATIONS_ERROR;
    565                 }
    566 
    567                 for (j=0;j<el->num_values;j++) {
    568                         list->dn[list->count] =
    569                                 talloc_strdup(list->dn, (char *)el->values[j].data);
    570                         if (!list->dn[list->count]) {
    571                                 talloc_free(msg);
    572                                 return LDB_ERR_OPERATIONS_ERROR;
    573                         }
    574                         list->count++;
    575                 }
    576         }
    577 
    578         talloc_free(msg);
    579 
    580         if (list->count > 1) {
    581                 qsort(list->dn, list->count, sizeof(char *), (comparison_fn_t) list_cmp);
    582         }
    583 
    584         return LDB_SUCCESS;
    585 }
    586 
    587 
    588 static int list_union(struct ldb_context *, struct dn_list *, const struct dn_list *);
     499        return ret;
     500}
     501
     502
     503static bool list_union(struct ldb_context *, struct dn_list *, const struct dn_list *);
    589504
    590505/*
     
    596511                              struct dn_list *list)
    597512{
    598         struct ldb_context *ldb;
    599         ldb = ldb_module_get_ctx(module);
    600 
    601513        if (ldb_attr_dn(tree->u.equality.attr) == 0) {
    602                 list->dn = talloc_array(list, char *, 1);
     514                list->dn = talloc_array(list, struct ldb_val, 1);
    603515                if (list->dn == NULL) {
    604                         ldb_oom(ldb);
     516                        ldb_module_oom(module);
    605517                        return LDB_ERR_OPERATIONS_ERROR;
    606518                }
    607                 list->dn[0] = talloc_strdup(list->dn, (char *)tree->u.equality.value.data);
    608                 if (list->dn[0] == NULL) {
    609                         ldb_oom(ldb);
    610                         return LDB_ERR_OPERATIONS_ERROR;
    611                 }
     519                list->dn[0] = tree->u.equality.value;
    612520                list->count = 1;
    613521                return LDB_SUCCESS;
     
    620528  list intersection
    621529  list = list & list2
    622   relies on the lists being sorted
    623 */
    624 static int list_intersect(struct ldb_context *ldb,
    625                           struct dn_list *list, const struct dn_list *list2)
     530*/
     531static bool list_intersect(struct ldb_context *ldb,
     532                           struct dn_list *list, const struct dn_list *list2)
    626533{
    627534        struct dn_list *list3;
    628535        unsigned int i;
    629536
    630         if (list->count == 0 || list2->count == 0) {
     537        if (list->count == 0) {
    631538                /* 0 & X == 0 */
    632                 return LDB_ERR_NO_SUCH_OBJECT;
    633         }
    634 
    635         list3 = talloc(ldb, struct dn_list);
     539                return true;
     540        }
     541        if (list2->count == 0) {
     542                /* X & 0 == 0 */
     543                list->count = 0;
     544                list->dn = NULL;
     545                return true;
     546        }
     547
     548        /* the indexing code is allowed to return a longer list than
     549           what really matches, as all results are filtered by the
     550           full expression at the end - this shortcut avoids a lot of
     551           work in some cases */
     552        if (list->count < 2 && list2->count > 10) {
     553                return true;
     554        }
     555        if (list2->count < 2 && list->count > 10) {
     556                list->count = list2->count;
     557                list->dn = list2->dn;
     558                /* note that list2 may not be the parent of list2->dn,
     559                   as list2->dn may be owned by ltdb->idxptr. In that
     560                   case we expect this reparent call to fail, which is
     561                   OK */
     562                talloc_reparent(list2, list, list2->dn);
     563                return true;
     564        }
     565
     566        list3 = talloc_zero(list, struct dn_list);
    636567        if (list3 == NULL) {
    637                 return LDB_ERR_OPERATIONS_ERROR;
    638         }
    639 
    640         list3->dn = talloc_array(list3, char *, list->count);
     568                return false;
     569        }
     570
     571        list3->dn = talloc_array(list3, struct ldb_val, list->count);
    641572        if (!list3->dn) {
    642573                talloc_free(list3);
    643                 return LDB_ERR_OPERATIONS_ERROR;
     574                return false;
    644575        }
    645576        list3->count = 0;
    646577
    647578        for (i=0;i<list->count;i++) {
    648                 if (ldb_list_find(list->dn[i], list2->dn, list2->count,
    649                               sizeof(char *), (comparison_fn_t)strcmp) != -1) {
    650                         list3->dn[list3->count] = talloc_move(list3->dn, &list->dn[i]);
     579                if (ltdb_dn_list_find_val(list2, &list->dn[i]) != -1) {
     580                        list3->dn[list3->count] = list->dn[i];
    651581                        list3->count++;
    652                 } else {
    653                         talloc_free(list->dn[i]);
    654                 }
    655         }
    656 
    657         talloc_free(list->dn);
    658         list->dn = talloc_move(list, &list3->dn);
     582                }
     583        }
     584
     585        list->dn = talloc_steal(list, list3->dn);
    659586        list->count = list3->count;
    660587        talloc_free(list3);
    661588
    662         return LDB_ERR_NO_SUCH_OBJECT;
     589        return true;
    663590}
    664591
     
    667594  list union
    668595  list = list | list2
    669   relies on the lists being sorted
    670 */
    671 static int list_union(struct ldb_context *ldb,
    672                       struct dn_list *list, const struct dn_list *list2)
    673 {
    674         unsigned int i;
    675         char **d;
    676         unsigned int count = list->count;
    677 
    678         if (list->count == 0 && list2->count == 0) {
    679                 /* 0 | 0 == 0 */
    680                 return LDB_ERR_NO_SUCH_OBJECT;
    681         }
    682 
    683         d = talloc_realloc(list, list->dn, char *, list->count + list2->count);
    684         if (!d) {
    685                 return LDB_ERR_OPERATIONS_ERROR;
    686         }
    687         list->dn = d;
    688 
    689         for (i=0;i<list2->count;i++) {
    690                 if (ldb_list_find(list2->dn[i], list->dn, count,
    691                               sizeof(char *), (comparison_fn_t)strcmp) == -1) {
    692                         list->dn[list->count] = talloc_strdup(list->dn, list2->dn[i]);
    693                         if (!list->dn[list->count]) {
    694                                 return LDB_ERR_OPERATIONS_ERROR;
    695                         }
    696                         list->count++;
    697                 }
    698         }
    699 
    700         if (list->count != count) {
    701                 qsort(list->dn, list->count, sizeof(char *), (comparison_fn_t)list_cmp);
    702         }
    703 
    704         return LDB_ERR_NO_SUCH_OBJECT;
     596*/
     597static bool list_union(struct ldb_context *ldb,
     598                       struct dn_list *list, const struct dn_list *list2)
     599{
     600        struct ldb_val *dn3;
     601
     602        if (list2->count == 0) {
     603                /* X | 0 == X */
     604                return true;
     605        }
     606
     607        if (list->count == 0) {
     608                /* 0 | X == X */
     609                list->count = list2->count;
     610                list->dn = list2->dn;
     611                /* note that list2 may not be the parent of list2->dn,
     612                   as list2->dn may be owned by ltdb->idxptr. In that
     613                   case we expect this reparent call to fail, which is
     614                   OK */
     615                talloc_reparent(list2, list, list2->dn);
     616                return true;
     617        }
     618
     619        dn3 = talloc_array(list, struct ldb_val, list->count + list2->count);
     620        if (!dn3) {
     621                ldb_oom(ldb);
     622                return false;
     623        }
     624
     625        /* we allow for duplicates here, and get rid of them later */
     626        memcpy(dn3, list->dn, sizeof(list->dn[0])*list->count);
     627        memcpy(dn3+list->count, list2->dn, sizeof(list2->dn[0])*list2->count);
     628
     629        list->dn = dn3;
     630        list->count += list2->count;
     631
     632        return true;
    705633}
    706634
     
    712640
    713641/*
    714   OR two index results
     642  process an OR list (a union)
    715643 */
    716644static int ltdb_index_dn_or(struct ldb_module *module,
     
    721649        struct ldb_context *ldb;
    722650        unsigned int i;
    723         int ret;
    724651
    725652        ldb = ldb_module_get_ctx(module);
    726653
    727         ret = LDB_ERR_OPERATIONS_ERROR;
    728654        list->dn = NULL;
    729655        list->count = 0;
    730656
    731         for (i=0;i<tree->u.list.num_elements;i++) {
     657        for (i=0; i<tree->u.list.num_elements; i++) {
    732658                struct dn_list *list2;
    733                 int v;
    734 
    735                 list2 = talloc(module, struct dn_list);
     659                int ret;
     660
     661                list2 = talloc_zero(list, struct dn_list);
    736662                if (list2 == NULL) {
    737663                        return LDB_ERR_OPERATIONS_ERROR;
    738664                }
    739665
    740                 v = ltdb_index_dn(module, tree->u.list.elements[i], index_list, list2);
    741 
    742                 if (v == LDB_ERR_NO_SUCH_OBJECT) {
    743                         /* 0 || X == X */
    744                         if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) {
    745                                 ret = v;
    746                         }
     666                ret = ltdb_index_dn(module, tree->u.list.elements[i], index_list, list2);
     667
     668                if (ret == LDB_ERR_NO_SUCH_OBJECT) {
     669                        /* X || 0 == X */
    747670                        talloc_free(list2);
    748671                        continue;
    749672                }
    750673
    751                 if (v != LDB_SUCCESS && v != LDB_ERR_NO_SUCH_OBJECT) {
    752                         /* 1 || X == 1 */
    753                         talloc_free(list->dn);
     674                if (ret != LDB_SUCCESS) {
     675                        /* X || * == * */
    754676                        talloc_free(list2);
    755                         return v;
    756                 }
    757 
    758                 if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) {
    759                         ret = LDB_SUCCESS;
    760                         list->dn = talloc_move(list, &list2->dn);
    761                         list->count = list2->count;
    762                 } else {
    763                         if (list_union(ldb, list, list2) == -1) {
    764                                 talloc_free(list2);
    765                                 return LDB_ERR_OPERATIONS_ERROR;
    766                         }
    767                         ret = LDB_SUCCESS;
    768                 }
    769                 talloc_free(list2);
     677                        return ret;
     678                }
     679
     680                if (!list_union(ldb, list, list2)) {
     681                        talloc_free(list2);
     682                        return LDB_ERR_OPERATIONS_ERROR;
     683                }
    770684        }
    771685
     
    774688        }
    775689
    776         return ret;
     690        return LDB_SUCCESS;
    777691}
    778692
     
    810724
    811725/*
    812   AND two index results
     726  process an AND expression (intersection)
    813727 */
    814728static int ltdb_index_dn_and(struct ldb_module *module,
     
    819733        struct ldb_context *ldb;
    820734        unsigned int i;
    821         int ret, pass;
     735        bool found;
    822736
    823737        ldb = ldb_module_get_ctx(module);
    824738
    825         ret = LDB_ERR_OPERATIONS_ERROR;
    826739        list->dn = NULL;
    827740        list->count = 0;
    828741
    829         for (pass=0;pass<=1;pass++) {
    830                 /* in the first pass we only look for unique simple
    831                    equality tests, in the hope of avoiding having to look
    832                    at any others */
    833                 bool only_unique = pass==0?true:false;
    834 
    835                 for (i=0;i<tree->u.list.num_elements;i++) {
    836                         struct dn_list *list2;
    837                         int v;
    838                         bool is_unique = false;
    839                         const struct ldb_parse_tree *subtree = tree->u.list.elements[i];
    840 
    841                         if (subtree->operation == LDB_OP_EQUALITY &&
    842                             ltdb_index_unique(ldb, subtree->u.equality.attr)) {
    843                                 is_unique = true;
    844                         }
    845                         if (is_unique != only_unique) continue;
     742        /* in the first pass we only look for unique simple
     743           equality tests, in the hope of avoiding having to look
     744           at any others */
     745        for (i=0; i<tree->u.list.num_elements; i++) {
     746                const struct ldb_parse_tree *subtree = tree->u.list.elements[i];
     747                int ret;
     748
     749                if (subtree->operation != LDB_OP_EQUALITY ||
     750                    !ltdb_index_unique(ldb, subtree->u.equality.attr)) {
     751                        continue;
     752                }
     753               
     754                ret = ltdb_index_dn(module, subtree, index_list, list);
     755                if (ret == LDB_ERR_NO_SUCH_OBJECT) {
     756                        /* 0 && X == 0 */
     757                        return LDB_ERR_NO_SUCH_OBJECT;
     758                }
     759                if (ret == LDB_SUCCESS) {
     760                        /* a unique index match means we can
     761                         * stop. Note that we don't care if we return
     762                         * a few too many objects, due to later
     763                         * filtering */
     764                        return LDB_SUCCESS;
     765                }
     766        }       
     767
     768        /* now do a full intersection */
     769        found = false;
     770
     771        for (i=0; i<tree->u.list.num_elements; i++) {
     772                const struct ldb_parse_tree *subtree = tree->u.list.elements[i];
     773                struct dn_list *list2;
     774                int ret;
     775
     776                list2 = talloc_zero(list, struct dn_list);
     777                if (list2 == NULL) {
     778                        return ldb_module_oom(module);
     779                }
    846780                       
    847                         list2 = talloc(module, struct dn_list);
    848                         if (list2 == NULL) {
    849                                 return LDB_ERR_OPERATIONS_ERROR;
    850                         }
     781                ret = ltdb_index_dn(module, subtree, index_list, list2);
     782
     783                if (ret == LDB_ERR_NO_SUCH_OBJECT) {
     784                        /* X && 0 == 0 */
     785                        list->dn = NULL;
     786                        list->count = 0;
     787                        talloc_free(list2);
     788                        return LDB_ERR_NO_SUCH_OBJECT;
     789                }
     790               
     791                if (ret != LDB_SUCCESS) {
     792                        /* this didn't adding anything */
     793                        talloc_free(list2);
     794                        continue;
     795                }
     796
     797                if (!found) {
     798                        talloc_reparent(list2, list, list->dn);
     799                        list->dn = list2->dn;
     800                        list->count = list2->count;
     801                        found = true;
     802                } else if (!list_intersect(ldb, list, list2)) {
     803                        talloc_free(list2);
     804                        return LDB_ERR_OPERATIONS_ERROR;
     805                }
    851806                       
    852                         v = ltdb_index_dn(module, subtree, index_list, list2);
    853 
    854                         if (v == LDB_ERR_NO_SUCH_OBJECT) {
    855                                 /* 0 && X == 0 */
    856                                 talloc_free(list->dn);
    857                                 talloc_free(list2);
    858                                 return LDB_ERR_NO_SUCH_OBJECT;
    859                         }
     807                if (list->count == 0) {
     808                        list->dn = NULL;
     809                        return LDB_ERR_NO_SUCH_OBJECT;
     810                }
    860811                       
    861                         if (v != LDB_SUCCESS && v != LDB_ERR_NO_SUCH_OBJECT) {
    862                                 talloc_free(list2);
    863                                 continue;
    864                         }
    865                        
    866                         if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) {
    867                                 ret = LDB_SUCCESS;
    868                                 talloc_free(list->dn);
    869                                 list->dn = talloc_move(list, &list2->dn);
    870                                 list->count = list2->count;
    871                         } else {
    872                                 if (list_intersect(ldb, list, list2) == -1) {
    873                                         talloc_free(list2);
    874                                         return LDB_ERR_OPERATIONS_ERROR;
    875                                 }
    876                         }
    877                        
    878                         talloc_free(list2);
    879                        
    880                         if (list->count == 0) {
    881                                 talloc_free(list->dn);
    882                                 return LDB_ERR_NO_SUCH_OBJECT;
    883                         }
    884                        
    885                         if (list->count == 1) {
    886                                 /* it isn't worth loading the next part of the tree */
    887                                 return ret;
    888                         }
     812                if (list->count < 2) {
     813                        /* it isn't worth loading the next part of the tree */
     814                        return LDB_SUCCESS;
    889815                }
    890816        }       
    891         return ret;
     817
     818        if (!found) {
     819                /* none of the attributes were indexed */
     820                return LDB_ERR_OPERATIONS_ERROR;
     821        }
     822
     823        return LDB_SUCCESS;
    892824}
    893825       
    894826/*
    895   AND index results and ONE level special index
     827  return a list of matching objects using a one-level index
    896828 */
    897829static int ltdb_index_dn_one(struct ldb_module *module,
     
    900832{
    901833        struct ldb_context *ldb;
    902         struct dn_list *list2;
    903         struct ldb_message *msg;
    904834        struct ldb_dn *key;
    905835        struct ldb_val val;
    906         unsigned int i, j;
    907836        int ret;
    908837
    909838        ldb = ldb_module_get_ctx(module);
    910839
    911         list2 = talloc_zero(module, struct dn_list);
    912         if (list2 == NULL) {
    913                 return LDB_ERR_OPERATIONS_ERROR;
    914         }
    915 
    916         /* the attribute is indexed. Pull the list of DNs that match the
    917            search criterion */
     840        /* work out the index key from the parent DN */
    918841        val.data = (uint8_t *)((uintptr_t)ldb_dn_get_casefold(parent_dn));
    919842        val.length = strlen((char *)val.data);
    920843        key = ltdb_index_key(ldb, LTDB_IDXONE, &val, NULL);
    921844        if (!key) {
    922                 talloc_free(list2);
    923                 return LDB_ERR_OPERATIONS_ERROR;
    924         }
    925 
    926         msg = talloc(list2, struct ldb_message);
    927         if (msg == NULL) {
    928                 talloc_free(list2);
    929                 return LDB_ERR_OPERATIONS_ERROR;
    930         }
    931 
    932         ret = ltdb_search_dn1_index(module, key, msg);
     845                ldb_oom(ldb);
     846                return LDB_ERR_OPERATIONS_ERROR;
     847        }
     848
     849        ret = ltdb_dn_list_load(module, key, list);
    933850        talloc_free(key);
    934851        if (ret != LDB_SUCCESS) {
     
    936853        }
    937854
    938         for (i = 0; i < msg->num_elements; i++) {
    939                 struct ldb_message_element *el;
    940 
    941                 if (strcmp(msg->elements[i].name, LTDB_IDX) != 0) {
    942                         continue;
    943                 }
    944 
    945                 el = &msg->elements[i];
    946 
    947                 list2->dn = talloc_array(list2, char *, el->num_values);
    948                 if (!list2->dn) {
    949                         talloc_free(list2);
    950                         return LDB_ERR_OPERATIONS_ERROR;
    951                 }
    952 
    953                 for (j = 0; j < el->num_values; j++) {
    954                         list2->dn[list2->count] = talloc_strdup(list2->dn, (char *)el->values[j].data);
    955                         if (!list2->dn[list2->count]) {
    956                                 talloc_free(list2);
    957                                 return LDB_ERR_OPERATIONS_ERROR;
    958                         }
    959                         list2->count++;
    960                 }
    961         }
    962 
    963         if (list2->count == 0) {
    964                 talloc_free(list2);
     855        if (list->count == 0) {
    965856                return LDB_ERR_NO_SUCH_OBJECT;
    966857        }
    967 
    968         if (list2->count > 1) {
    969                 qsort(list2->dn, list2->count, sizeof(char *), (comparison_fn_t) list_cmp);
    970         }
    971 
    972         if (list->count > 0) {
    973                 if (list_intersect(ldb, list, list2) == -1) {
    974                         talloc_free(list2);
    975                         return LDB_ERR_OPERATIONS_ERROR;
    976                 }
    977 
    978                 if (list->count == 0) {
    979                         talloc_free(list->dn);
    980                         talloc_free(list2);
    981                         return LDB_ERR_NO_SUCH_OBJECT;
    982                 }
    983         } else {
    984                 list->dn = talloc_move(list, &list2->dn);
    985                 list->count = list2->count;
    986         }
    987 
    988         talloc_free(list2);
    989858
    990859        return LDB_SUCCESS;
     
    1050919                struct ldb_dn *dn;
    1051920                int ret;
     921                bool matched;
    1052922
    1053923                msg = ldb_msg_new(ac);
     
    1056926                }
    1057927
    1058                 dn = ldb_dn_new(msg, ldb, dn_list->dn[i]);
     928                dn = ldb_dn_from_ldb_val(msg, ldb, &dn_list->dn[i]);
    1059929                if (dn == NULL) {
    1060930                        talloc_free(msg);
     
    1076946                }
    1077947
    1078                 if (!ldb_match_msg(ldb, msg,
    1079                                    ac->tree, ac->base, ac->scope)) {
     948                ret = ldb_match_msg_error(ldb, msg,
     949                                          ac->tree, ac->base, ac->scope, &matched);
     950                if (ret != LDB_SUCCESS) {
     951                        talloc_free(msg);
     952                        return ret;
     953                }
     954                if (!matched) {
    1080955                        talloc_free(msg);
    1081956                        continue;
     
    1092967                ret = ldb_module_send_entry(ac->req, msg, NULL);
    1093968                if (ret != LDB_SUCCESS) {
     969                        /* Regardless of success or failure, the msg
     970                         * is the callbacks responsiblity, and should
     971                         * not be talloc_free()'ed */
    1094972                        ac->request_terminated = true;
    1095973                        return ret;
     
    1100978
    1101979        return LDB_SUCCESS;
     980}
     981
     982/*
     983  remove any duplicated entries in a indexed result
     984 */
     985static void ltdb_dn_list_remove_duplicates(struct dn_list *list)
     986{
     987        unsigned int i, new_count;
     988
     989        if (list->count < 2) {
     990                return;
     991        }
     992
     993        TYPESAFE_QSORT(list->dn, list->count, dn_list_cmp);
     994
     995        new_count = 1;
     996        for (i=1; i<list->count; i++) {
     997                if (dn_list_cmp(&list->dn[i], &list->dn[new_count-1]) != 0) {
     998                        if (new_count != i) {
     999                                list->dn[new_count] = list->dn[i];
     1000                        }
     1001                        new_count++;
     1002                }
     1003        }
     1004       
     1005        list->count = new_count;
    11021006}
    11031007
     
    11091013int ltdb_search_indexed(struct ltdb_context *ac, uint32_t *match_count)
    11101014{
    1111         struct ldb_context *ldb;
    1112         void *data = ldb_module_get_private(ac->module);
    1113         struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
     1015        struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(ac->module), struct ltdb_private);
    11141016        struct dn_list *dn_list;
    1115         int ret, idxattr, idxone;
    1116 
    1117         ldb = ldb_module_get_ctx(ac->module);
    1118 
    1119         idxattr = idxone = 0;
    1120         ret = ldb_msg_find_idx(ltdb->cache->indexlist, NULL, NULL, LTDB_IDXATTR);
    1121         if (ret == 0 ) {
    1122                 idxattr = 1;
    1123         }
    1124 
    1125         /* We do one level indexing only if requested */
    1126         ret = ldb_msg_find_idx(ltdb->cache->indexlist, NULL, NULL, LTDB_IDXONE);
    1127         if (ret == 0 ) {
    1128                 idxone = 1;
    1129         }
    1130 
    1131         if ((ac->scope == LDB_SCOPE_ONELEVEL && (idxattr+idxone == 0)) ||
    1132             (ac->scope == LDB_SCOPE_SUBTREE && idxattr == 0)) {
    1133                 /* no indexes? must do full search */
    1134                 return LDB_ERR_OPERATIONS_ERROR;
    1135         }
    1136 
    1137         ret = LDB_ERR_OPERATIONS_ERROR;
     1017        int ret;
     1018
     1019        /* see if indexing is enabled */
     1020        if (!ltdb->cache->attribute_indexes &&
     1021            !ltdb->cache->one_level_indexes &&
     1022            ac->scope != LDB_SCOPE_BASE) {
     1023                /* fallback to a full search */
     1024                return LDB_ERR_OPERATIONS_ERROR;
     1025        }
    11381026
    11391027        dn_list = talloc_zero(ac, struct dn_list);
    11401028        if (dn_list == NULL) {
    1141                 return LDB_ERR_OPERATIONS_ERROR;
    1142         }
    1143 
    1144         if (ac->scope == LDB_SCOPE_BASE) {
    1145                 /* with BASE searches only one DN can match */
    1146                 dn_list->dn = talloc_array(dn_list, char *, 1);
     1029                return ldb_module_oom(ac->module);
     1030        }
     1031
     1032        switch (ac->scope) {
     1033        case LDB_SCOPE_BASE:
     1034                dn_list->dn = talloc_array(dn_list, struct ldb_val, 1);
    11471035                if (dn_list->dn == NULL) {
    1148                         ldb_oom(ldb);
     1036                        talloc_free(dn_list);
     1037                        return ldb_module_oom(ac->module);
     1038                }
     1039                dn_list->dn[0].data = discard_const_p(unsigned char, ldb_dn_get_linearized(ac->base));
     1040                if (dn_list->dn[0].data == NULL) {
     1041                        talloc_free(dn_list);
     1042                        return ldb_module_oom(ac->module);
     1043                }
     1044                dn_list->dn[0].length = strlen((char *)dn_list->dn[0].data);
     1045                dn_list->count = 1;
     1046                break;         
     1047
     1048        case LDB_SCOPE_ONELEVEL:
     1049                if (!ltdb->cache->one_level_indexes) {
     1050                        talloc_free(dn_list);
    11491051                        return LDB_ERR_OPERATIONS_ERROR;
    11501052                }
    1151                 dn_list->dn[0] = ldb_dn_alloc_linearized(dn_list, ac->base);
    1152                 if (dn_list->dn[0] == NULL) {
    1153                         ldb_oom(ldb);
     1053                ret = ltdb_index_dn_one(ac->module, ac->base, dn_list);
     1054                if (ret != LDB_SUCCESS) {
     1055                        talloc_free(dn_list);
     1056                        return ret;
     1057                }
     1058                break;
     1059
     1060        case LDB_SCOPE_SUBTREE:
     1061        case LDB_SCOPE_DEFAULT:
     1062                if (!ltdb->cache->attribute_indexes) {
     1063                        talloc_free(dn_list);
    11541064                        return LDB_ERR_OPERATIONS_ERROR;
    11551065                }
    1156                 dn_list->count = 1;
    1157                 ret = LDB_SUCCESS;
    1158         }
    1159 
    1160         if (ac->scope != LDB_SCOPE_BASE && idxattr == 1) {
    11611066                ret = ltdb_index_dn(ac->module, ac->tree, ltdb->cache->indexlist, dn_list);
    1162         }
    1163 
    1164         if (ret == LDB_ERR_OPERATIONS_ERROR &&
    1165             ac->scope == LDB_SCOPE_ONELEVEL && idxone == 1) {
    1166                 ret = ltdb_index_dn_one(ac->module, ac->base, dn_list);
    1167         }
    1168 
    1169         if (ret == LDB_SUCCESS) {
    1170                 /* we've got a candidate list - now filter by the full tree
    1171                    and extract the needed attributes */
    1172                 ret = ltdb_index_filter(dn_list, ac, match_count);
    1173         }
    1174 
     1067                if (ret != LDB_SUCCESS) {
     1068                        talloc_free(dn_list);
     1069                        return ret;
     1070                }
     1071                ltdb_dn_list_remove_duplicates(dn_list);
     1072                break;
     1073        }
     1074
     1075        ret = ltdb_index_filter(dn_list, ac, match_count);
    11751076        talloc_free(dn_list);
    1176 
    11771077        return ret;
    1178 }
    1179 
    1180 /*
    1181   add a index element where this is the first indexed DN for this value
    1182 */
    1183 static int ltdb_index_add1_new(struct ldb_context *ldb,
    1184                                struct ldb_message *msg,
    1185                                const char *dn)
    1186 {
    1187         struct ldb_message_element *el;
    1188 
    1189         /* add another entry */
    1190         el = talloc_realloc(msg, msg->elements,
    1191                                struct ldb_message_element, msg->num_elements+1);
    1192         if (!el) {
    1193                 return LDB_ERR_OPERATIONS_ERROR;
    1194         }
    1195 
    1196         msg->elements = el;
    1197         msg->elements[msg->num_elements].name = talloc_strdup(msg->elements, LTDB_IDX);
    1198         if (!msg->elements[msg->num_elements].name) {
    1199                 return LDB_ERR_OPERATIONS_ERROR;
    1200         }
    1201         msg->elements[msg->num_elements].num_values = 0;
    1202         msg->elements[msg->num_elements].values = talloc(msg->elements, struct ldb_val);
    1203         if (!msg->elements[msg->num_elements].values) {
    1204                 return LDB_ERR_OPERATIONS_ERROR;
    1205         }
    1206         msg->elements[msg->num_elements].values[0].length = strlen(dn);
    1207         msg->elements[msg->num_elements].values[0].data = discard_const_p(uint8_t, dn);
    1208         msg->elements[msg->num_elements].num_values = 1;
    1209         msg->num_elements++;
    1210 
    1211         return LDB_SUCCESS;
    1212 }
    1213 
    1214 
    1215 /*
    1216   add a index element where this is not the first indexed DN for this
    1217   value
    1218 */
    1219 static int ltdb_index_add1_add(struct ldb_context *ldb,
    1220                                struct ldb_message *msg,
    1221                                int idx,
    1222                                const char *dn,
    1223                                const struct ldb_schema_attribute *a)
    1224 {
    1225         struct ldb_val *v2;
    1226         unsigned int i;
    1227 
    1228         /* for multi-valued attributes we can end up with repeats */
    1229         for (i=0;i<msg->elements[idx].num_values;i++) {
    1230                 if (strcmp(dn, (char *)msg->elements[idx].values[i].data) == 0) {
    1231                         return LDB_SUCCESS;
    1232                 }
    1233         }
    1234 
    1235         if (a->flags & LDB_ATTR_FLAG_UNIQUE_INDEX) {
    1236                 return LDB_ERR_ENTRY_ALREADY_EXISTS;
    1237         }
    1238 
    1239         v2 = talloc_realloc(msg->elements, msg->elements[idx].values,
    1240                               struct ldb_val,
    1241                               msg->elements[idx].num_values+1);
    1242         if (!v2) {
    1243                 return LDB_ERR_OPERATIONS_ERROR;
    1244         }
    1245         msg->elements[idx].values = v2;
    1246 
    1247         msg->elements[idx].values[msg->elements[idx].num_values].length = strlen(dn);
    1248         msg->elements[idx].values[msg->elements[idx].num_values].data = discard_const_p(uint8_t, dn);
    1249         msg->elements[idx].num_values++;
    1250 
    1251         return LDB_SUCCESS;
    12521078}
    12531079
     
    12591085{
    12601086        struct ldb_context *ldb;
    1261         struct ldb_message *msg;
    12621087        struct ldb_dn *dn_key;
    12631088        int ret;
    1264         unsigned int i;
    12651089        const struct ldb_schema_attribute *a;
     1090        struct dn_list *list;
     1091        unsigned alloc_len;
    12661092
    12671093        ldb = ldb_module_get_ctx(module);
    12681094
    1269         msg = talloc(module, struct ldb_message);
    1270         if (msg == NULL) {
    1271                 errno = ENOMEM;
     1095        list = talloc_zero(module, struct dn_list);
     1096        if (list == NULL) {
    12721097                return LDB_ERR_OPERATIONS_ERROR;
    12731098        }
     
    12751100        dn_key = ltdb_index_key(ldb, el->name, &el->values[v_idx], &a);
    12761101        if (!dn_key) {
    1277                 talloc_free(msg);
    1278                 return LDB_ERR_OPERATIONS_ERROR;
    1279         }
    1280         talloc_steal(msg, dn_key);
    1281 
    1282         ret = ltdb_search_dn1_index(module, dn_key, msg);
     1102                talloc_free(list);
     1103                return LDB_ERR_OPERATIONS_ERROR;
     1104        }
     1105        talloc_steal(list, dn_key);
     1106
     1107        ret = ltdb_dn_list_load(module, dn_key, list);
    12831108        if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) {
    1284                 talloc_free(msg);
     1109                talloc_free(list);
    12851110                return ret;
    12861111        }
    12871112
    1288         if (ret == LDB_ERR_NO_SUCH_OBJECT) {
    1289                 msg->dn = dn_key;
    1290                 msg->num_elements = 0;
    1291                 msg->elements = NULL;
    1292         }
    1293 
    1294         for (i=0;i<msg->num_elements;i++) {
    1295                 if (strcmp(LTDB_IDX, msg->elements[i].name) == 0) {
    1296                         break;
    1297                 }
    1298         }
    1299 
    1300         if (i == msg->num_elements) {
    1301                 ret = ltdb_index_add1_new(ldb, msg, dn);
    1302         } else {
    1303                 ret = ltdb_index_add1_add(ldb, msg, i, dn, a);
    1304         }
    1305 
    1306         if (ret == LDB_SUCCESS) {
    1307                 ret = ltdb_store_idxptr(module, msg, TDB_REPLACE);
    1308         }
    1309 
    1310         talloc_free(msg);
     1113        if (ltdb_dn_list_find_str(list, dn) != -1) {
     1114                talloc_free(list);
     1115                return LDB_SUCCESS;
     1116        }
     1117
     1118        if (list->count > 0 &&
     1119            a->flags & LDB_ATTR_FLAG_UNIQUE_INDEX) {
     1120                talloc_free(list);
     1121                ldb_asprintf_errstring(ldb, __location__ ": unique index violation on %s in %s",
     1122                                       el->name, dn);
     1123                return LDB_ERR_ENTRY_ALREADY_EXISTS;           
     1124        }
     1125
     1126        /* overallocate the list a bit, to reduce the number of
     1127         * realloc trigered copies */   
     1128        alloc_len = ((list->count+1)+7) & ~7;
     1129        list->dn = talloc_realloc(list, list->dn, struct ldb_val, alloc_len);
     1130        if (list->dn == NULL) {
     1131                talloc_free(list);
     1132                return LDB_ERR_OPERATIONS_ERROR;
     1133        }
     1134        list->dn[list->count].data = (uint8_t *)talloc_strdup(list->dn, dn);
     1135        list->dn[list->count].length = strlen(dn);
     1136        list->count++;
     1137
     1138        ret = ltdb_dn_list_store(module, dn_key, list);
     1139
     1140        talloc_free(list);
    13111141
    13121142        return ret;
    13131143}
    13141144
    1315 static int ltdb_index_add0(struct ldb_module *module, const char *dn,
    1316                            struct ldb_message_element *elements, int num_el)
    1317 {
    1318         void *data = ldb_module_get_private(module);
    1319         struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
    1320         int ret;
    1321         unsigned int i, j;
     1145/*
     1146  add index entries for one elements in a message
     1147 */
     1148static int ltdb_index_add_el(struct ldb_module *module, const char *dn,
     1149                             struct ldb_message_element *el)
     1150{
     1151        unsigned int i;
     1152        for (i = 0; i < el->num_values; i++) {
     1153                int ret = ltdb_index_add1(module, dn, el, i);
     1154                if (ret != LDB_SUCCESS) {
     1155                        return ret;
     1156                }
     1157        }
     1158
     1159        return LDB_SUCCESS;
     1160}
     1161
     1162/*
     1163  add index entries for all elements in a message
     1164 */
     1165static int ltdb_index_add_all(struct ldb_module *module, const char *dn,
     1166                              struct ldb_message_element *elements, int num_el)
     1167{
     1168        struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
     1169        unsigned int i;
    13221170
    13231171        if (dn[0] == '@') {
     
    13311179
    13321180        for (i = 0; i < num_el; i++) {
    1333                 ret = ldb_msg_find_idx(ltdb->cache->indexlist, elements[i].name,
    1334                                        NULL, LTDB_IDXATTR);
    1335                 if (ret == -1) {
     1181                int ret;
     1182                if (!ltdb_is_indexed(ltdb->cache->indexlist, elements[i].name)) {
    13361183                        continue;
    13371184                }
    1338                 for (j = 0; j < elements[i].num_values; j++) {
    1339                         ret = ltdb_index_add1(module, dn, &elements[i], j);
    1340                         if (ret != LDB_SUCCESS) {
    1341                                 return ret;
    1342                         }
     1185                ret = ltdb_index_add_el(module, dn, &elements[i]);
     1186                if (ret != LDB_SUCCESS) {
     1187                        struct ldb_context *ldb = ldb_module_get_ctx(module);
     1188                        ldb_asprintf_errstring(ldb,
     1189                                               __location__ ": Failed to re-index %s in %s - %s",
     1190                                               elements[i].name, dn, ldb_errstring(ldb));
     1191                        return ret;
    13431192                }
    13441193        }
     
    13471196}
    13481197
    1349 /*
    1350   add the index entries for a new record
    1351 */
    1352 int ltdb_index_add(struct ldb_module *module, const struct ldb_message *msg)
    1353 {
    1354         const char *dn;
    1355         int ret;
    1356 
    1357         dn = ldb_dn_get_linearized(msg->dn);
    1358         if (dn == NULL) {
    1359                 return LDB_ERR_OPERATIONS_ERROR;
    1360         }
    1361 
    1362         ret = ltdb_index_add0(module, dn, msg->elements, msg->num_elements);
    1363 
    1364         return ret;
    1365 }
    1366 
    1367 
    1368 /*
    1369   delete an index entry for one message element
    1370 */
    1371 int ltdb_index_del_value(struct ldb_module *module, const char *dn,
    1372                          struct ldb_message_element *el, int v_idx)
    1373 {
    1374         struct ldb_context *ldb;
    1375         struct ldb_message *msg;
    1376         struct ldb_dn *dn_key;
    1377         int ret, i;
    1378         unsigned int j;
    1379 
    1380         ldb = ldb_module_get_ctx(module);
    1381 
    1382         if (dn[0] == '@') {
    1383                 return LDB_SUCCESS;
    1384         }
    1385 
    1386         dn_key = ltdb_index_key(ldb, el->name, &el->values[v_idx], NULL);
    1387         if (!dn_key) {
    1388                 return LDB_ERR_OPERATIONS_ERROR;
    1389         }
    1390 
    1391         msg = talloc(dn_key, struct ldb_message);
    1392         if (msg == NULL) {
    1393                 talloc_free(dn_key);
    1394                 return LDB_ERR_OPERATIONS_ERROR;
    1395         }
    1396 
    1397         ret = ltdb_search_dn1_index(module, dn_key, msg);
    1398         if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) {
    1399                 talloc_free(dn_key);
    1400                 return ret;
    1401         }
    1402 
    1403         if (ret == LDB_ERR_NO_SUCH_OBJECT) {
    1404                 /* it wasn't indexed. Did we have an earlier error? If we did then
    1405                    its gone now */
    1406                 talloc_free(dn_key);
    1407                 return LDB_SUCCESS;
    1408         }
    1409 
    1410         i = ldb_msg_find_idx(msg, dn, &j, LTDB_IDX);
    1411         if (i == -1) {
    1412                 struct ldb_ldif ldif;
    1413                 char *ldif_string;
    1414                 ldif.changetype = LDB_CHANGETYPE_NONE;
    1415                 ldif.msg = msg;
    1416                 ldif_string = ldb_ldif_write_string(ldb, NULL, &ldif);
    1417                 ldb_debug(ldb, LDB_DEBUG_ERROR,
    1418                           "ERROR: dn %s not found in %s", dn,
    1419                           ldif_string);
    1420                 talloc_free(ldif_string);
    1421                 /* it ain't there. hmmm */
    1422                 talloc_free(dn_key);
    1423                 return LDB_SUCCESS;
    1424         }
    1425 
    1426         if (j != msg->elements[i].num_values - 1) {
    1427                 memmove(&msg->elements[i].values[j],
    1428                         &msg->elements[i].values[j+1],
    1429                         (msg->elements[i].num_values-(j+1)) *
    1430                         sizeof(msg->elements[i].values[0]));
    1431         }
    1432         msg->elements[i].num_values--;
    1433 
    1434         if (msg->elements[i].num_values == 0) {
    1435                 ret = ltdb_delete_noindex(module, dn_key);
    1436         } else {
    1437                 ret = ltdb_store_idxptr(module, msg, TDB_REPLACE);
    1438         }
    1439 
    1440         talloc_free(dn_key);
    1441 
    1442         return ret;
    1443 }
    1444 
    1445 /*
    1446   delete the index entries for a record
    1447   return -1 on failure
    1448 */
    1449 int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg)
    1450 {
    1451         void *data = ldb_module_get_private(module);
    1452         struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
    1453         int ret;
    1454         const char *dn;
    1455         unsigned int i, j;
    1456 
    1457         /* find the list of indexed fields */
    1458         if (ltdb->cache->indexlist->num_elements == 0) {
    1459                 /* no indexed fields */
    1460                 return LDB_SUCCESS;
    1461         }
    1462 
    1463         if (ldb_dn_is_special(msg->dn)) {
    1464                 return LDB_SUCCESS;
    1465         }
    1466 
    1467         dn = ldb_dn_get_linearized(msg->dn);
    1468         if (dn == NULL) {
    1469                 return LDB_ERR_OPERATIONS_ERROR;
    1470         }
    1471 
    1472         for (i = 0; i < msg->num_elements; i++) {
    1473                 ret = ldb_msg_find_idx(ltdb->cache->indexlist, msg->elements[i].name,
    1474                                        NULL, LTDB_IDXATTR);
    1475                 if (ret == -1) {
    1476                         continue;
    1477                 }
    1478                 for (j = 0; j < msg->elements[i].num_values; j++) {
    1479                         ret = ltdb_index_del_value(module, dn, &msg->elements[i], j);
    1480                         if (ret != LDB_SUCCESS) {
    1481                                 return ret;
    1482                         }
    1483                 }
    1484         }
    1485 
    1486         return LDB_SUCCESS;
    1487 }
    1488 
    1489 /*
    1490   handle special index for one level searches
    1491 */
    1492 int ltdb_index_one(struct ldb_module *module, const struct ldb_message *msg, int add)
    1493 {
    1494         void *data = ldb_module_get_private(module);
    1495         struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
     1198
     1199/*
     1200  insert a one level index for a message
     1201*/
     1202static int ltdb_index_onelevel(struct ldb_module *module, const struct ldb_message *msg, int add)
     1203{
     1204        struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
    14961205        struct ldb_message_element el;
    14971206        struct ldb_val val;
     
    15001209        int ret;
    15011210
    1502         if (ldb_dn_is_special(msg->dn)) {
    1503                 return LDB_SUCCESS;
    1504         }
    1505 
    15061211        /* We index for ONE Level only if requested */
    1507         ret = ldb_msg_find_idx(ltdb->cache->indexlist, NULL, NULL, LTDB_IDXONE);
    1508         if (ret != 0) {
     1212        if (!ltdb->cache->one_level_indexes) {
    15091213                return LDB_SUCCESS;
    15101214        }
     
    15351239                ret = ltdb_index_add1(module, dn, &el, 0);
    15361240        } else { /* delete */
    1537                 ret = ltdb_index_del_value(module, dn, &el, 0);
     1241                ret = ltdb_index_del_value(module, msg->dn, &el, 0);
    15381242        }
    15391243
     
    15431247}
    15441248
     1249/*
     1250  add the index entries for a new element in a record
     1251  The caller guarantees that these element values are not yet indexed
     1252*/
     1253int ltdb_index_add_element(struct ldb_module *module, struct ldb_dn *dn,
     1254                           struct ldb_message_element *el)
     1255{
     1256        struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
     1257        if (ldb_dn_is_special(dn)) {
     1258                return LDB_SUCCESS;
     1259        }
     1260        if (!ltdb_is_indexed(ltdb->cache->indexlist, el->name)) {
     1261                return LDB_SUCCESS;
     1262        }
     1263        return ltdb_index_add_el(module, ldb_dn_get_linearized(dn), el);
     1264}
     1265
     1266/*
     1267  add the index entries for a new record
     1268*/
     1269int ltdb_index_add_new(struct ldb_module *module, const struct ldb_message *msg)
     1270{
     1271        const char *dn;
     1272        int ret;
     1273
     1274        if (ldb_dn_is_special(msg->dn)) {
     1275                return LDB_SUCCESS;
     1276        }
     1277
     1278        dn = ldb_dn_get_linearized(msg->dn);
     1279        if (dn == NULL) {
     1280                return LDB_ERR_OPERATIONS_ERROR;
     1281        }
     1282
     1283        ret = ltdb_index_add_all(module, dn, msg->elements, msg->num_elements);
     1284        if (ret != LDB_SUCCESS) {
     1285                return ret;
     1286        }
     1287
     1288        return ltdb_index_onelevel(module, msg, 1);
     1289}
     1290
     1291
     1292/*
     1293  delete an index entry for one message element
     1294*/
     1295int ltdb_index_del_value(struct ldb_module *module, struct ldb_dn *dn,
     1296                         struct ldb_message_element *el, unsigned int v_idx)
     1297{
     1298        struct ldb_context *ldb;
     1299        struct ldb_dn *dn_key;
     1300        const char *dn_str;
     1301        int ret, i;
     1302        unsigned int j;
     1303        struct dn_list *list;
     1304
     1305        ldb = ldb_module_get_ctx(module);
     1306
     1307        dn_str = ldb_dn_get_linearized(dn);
     1308        if (dn_str == NULL) {
     1309                return LDB_ERR_OPERATIONS_ERROR;
     1310        }
     1311
     1312        if (dn_str[0] == '@') {
     1313                return LDB_SUCCESS;
     1314        }
     1315
     1316        dn_key = ltdb_index_key(ldb, el->name, &el->values[v_idx], NULL);
     1317        if (!dn_key) {
     1318                return LDB_ERR_OPERATIONS_ERROR;
     1319        }
     1320
     1321        list = talloc_zero(dn_key, struct dn_list);
     1322        if (list == NULL) {
     1323                talloc_free(dn_key);
     1324                return LDB_ERR_OPERATIONS_ERROR;
     1325        }
     1326
     1327        ret = ltdb_dn_list_load(module, dn_key, list);
     1328        if (ret == LDB_ERR_NO_SUCH_OBJECT) {
     1329                /* it wasn't indexed. Did we have an earlier error? If we did then
     1330                   its gone now */
     1331                talloc_free(dn_key);
     1332                return LDB_SUCCESS;
     1333        }
     1334
     1335        if (ret != LDB_SUCCESS) {
     1336                talloc_free(dn_key);
     1337                return ret;
     1338        }
     1339
     1340        i = ltdb_dn_list_find_str(list, dn_str);
     1341        if (i == -1) {
     1342                /* nothing to delete */
     1343                talloc_free(dn_key);
     1344                return LDB_SUCCESS;             
     1345        }
     1346
     1347        j = (unsigned int) i;
     1348        if (j != list->count - 1) {
     1349                memmove(&list->dn[j], &list->dn[j+1], sizeof(list->dn[0])*(list->count - (j+1)));
     1350        }
     1351        list->count--;
     1352        list->dn = talloc_realloc(list, list->dn, struct ldb_val, list->count);
     1353
     1354        ret = ltdb_dn_list_store(module, dn_key, list);
     1355
     1356        talloc_free(dn_key);
     1357
     1358        return ret;
     1359}
     1360
     1361/*
     1362  delete the index entries for a element
     1363  return -1 on failure
     1364*/
     1365int ltdb_index_del_element(struct ldb_module *module, struct ldb_dn *dn,
     1366                           struct ldb_message_element *el)
     1367{
     1368        struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
     1369        const char *dn_str;
     1370        int ret;
     1371        unsigned int i;
     1372
     1373        if (!ltdb->cache->attribute_indexes) {
     1374                /* no indexed fields */
     1375                return LDB_SUCCESS;
     1376        }
     1377
     1378        dn_str = ldb_dn_get_linearized(dn);
     1379        if (dn_str == NULL) {
     1380                return LDB_ERR_OPERATIONS_ERROR;
     1381        }
     1382
     1383        if (dn_str[0] == '@') {
     1384                return LDB_SUCCESS;
     1385        }
     1386
     1387        if (!ltdb_is_indexed(ltdb->cache->indexlist, el->name)) {
     1388                return LDB_SUCCESS;
     1389        }
     1390        for (i = 0; i < el->num_values; i++) {
     1391                ret = ltdb_index_del_value(module, dn, el, i);
     1392                if (ret != LDB_SUCCESS) {
     1393                        return ret;
     1394                }
     1395        }
     1396
     1397        return LDB_SUCCESS;
     1398}
     1399
     1400/*
     1401  delete the index entries for a record
     1402  return -1 on failure
     1403*/
     1404int ltdb_index_delete(struct ldb_module *module, const struct ldb_message *msg)
     1405{
     1406        struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
     1407        int ret;
     1408        unsigned int i;
     1409
     1410        if (ldb_dn_is_special(msg->dn)) {
     1411                return LDB_SUCCESS;
     1412        }
     1413
     1414        ret = ltdb_index_onelevel(module, msg, 0);
     1415        if (ret != LDB_SUCCESS) {
     1416                return ret;
     1417        }
     1418
     1419        if (!ltdb->cache->attribute_indexes) {
     1420                /* no indexed fields */
     1421                return LDB_SUCCESS;
     1422        }
     1423
     1424        for (i = 0; i < msg->num_elements; i++) {
     1425                ret = ltdb_index_del_element(module, msg->dn, &msg->elements[i]);
     1426                if (ret != LDB_SUCCESS) {
     1427                        return ret;
     1428                }
     1429        }
     1430
     1431        return LDB_SUCCESS;
     1432}
     1433
    15451434
    15461435/*
     
    15491438static int delete_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state)
    15501439{
    1551         const char *dn = "DN=" LTDB_INDEX ":";
    1552         if (strncmp((char *)key.dptr, dn, strlen(dn)) == 0) {
    1553                 return tdb_delete(tdb, key);
    1554         }
     1440        struct ldb_module *module = state;
     1441        struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
     1442        const char *dnstr = "DN=" LTDB_INDEX ":";
     1443        struct dn_list list;
     1444        struct ldb_dn *dn;
     1445        struct ldb_val v;
     1446        int ret;
     1447
     1448        if (strncmp((char *)key.dptr, dnstr, strlen(dnstr)) != 0) {
     1449                return 0;
     1450        }
     1451        /* we need to put a empty list in the internal tdb for this
     1452         * index entry */
     1453        list.dn = NULL;
     1454        list.count = 0;
     1455
     1456        /* the offset of 3 is to remove the DN= prefix. */
     1457        v.data = key.dptr + 3;
     1458        v.length = strnlen((char *)key.dptr, key.dsize) - 3;
     1459
     1460        dn = ldb_dn_from_ldb_val(ltdb, ldb_module_get_ctx(module), &v);
     1461        ret = ltdb_dn_list_store(module, dn, &list);
     1462        if (ret != LDB_SUCCESS) {
     1463                ldb_asprintf_errstring(ldb_module_get_ctx(module),
     1464                                       "Unable to store null index for %s\n",
     1465                                                ldb_dn_get_linearized(dn));
     1466                talloc_free(dn);
     1467                return -1;
     1468        }
     1469        talloc_free(dn);
    15551470        return 0;
    15561471}
    15571472
     1473struct ltdb_reindex_context {
     1474        struct ldb_module *module;
     1475        int error;
     1476};
     1477
    15581478/*
    15591479  traversal function that adds @INDEX records during a re index
     
    15621482{
    15631483        struct ldb_context *ldb;
    1564         struct ldb_module *module = (struct ldb_module *)state;
     1484        struct ltdb_reindex_context *ctx = (struct ltdb_reindex_context *)state;
     1485        struct ldb_module *module = ctx->module;
    15651486        struct ldb_message *msg;
    15661487        const char *dn = NULL;
     
    15751496        }
    15761497
    1577         msg = talloc(module, struct ldb_message);
     1498        msg = ldb_msg_new(module);
    15781499        if (msg == NULL) {
    15791500                return -1;
     
    15831504        if (ret != 0) {
    15841505                ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %s\n",
    1585                           ldb_dn_get_linearized(msg->dn));
     1506                                                ldb_dn_get_linearized(msg->dn));
    15861507                talloc_free(msg);
    15871508                return -1;
     
    15941515                /* probably a corrupt record ... darn */
    15951516                ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid DN in re_index: %s",
    1596                                                         ldb_dn_get_linearized(msg->dn));
     1517                                                ldb_dn_get_linearized(msg->dn));
    15971518                talloc_free(msg);
    15981519                return 0;
     
    16101531        }
    16111532
    1612         ret = ltdb_index_one(module, msg, 1);
    1613         if (ret == LDB_SUCCESS) {
    1614                 ret = ltdb_index_add0(module, dn, msg->elements, msg->num_elements);
    1615         } else {
     1533        ret = ltdb_index_onelevel(module, msg, 1);
     1534        if (ret != LDB_SUCCESS) {
    16161535                ldb_debug(ldb, LDB_DEBUG_ERROR,
    1617                         "Adding special ONE LEVEL index failed (%s)!",
    1618                         ldb_dn_get_linearized(msg->dn));
     1536                          "Adding special ONE LEVEL index failed (%s)!",
     1537                                                ldb_dn_get_linearized(msg->dn));
     1538                talloc_free(msg);
     1539                return -1;
     1540        }
     1541
     1542        ret = ltdb_index_add_all(module, dn, msg->elements, msg->num_elements);
     1543
     1544        if (ret != LDB_SUCCESS) {
     1545                ctx->error = ret;
     1546                talloc_free(msg);
     1547                return -1;
    16191548        }
    16201549
    16211550        talloc_free(msg);
    16221551
    1623         if (ret != LDB_SUCCESS) return -1;
    1624 
    16251552        return 0;
    16261553}
     
    16311558int ltdb_reindex(struct ldb_module *module)
    16321559{
    1633         void *data = ldb_module_get_private(module);
    1634         struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
     1560        struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
    16351561        int ret;
     1562        struct ltdb_reindex_context ctx;
    16361563
    16371564        if (ltdb_cache_reload(module) != 0) {
     
    16391566        }
    16401567
    1641         /* first traverse the database deleting any @INDEX records */
    1642         ret = tdb_traverse(ltdb->tdb, delete_index, NULL);
     1568        /* first traverse the database deleting any @INDEX records by
     1569         * putting NULL entries in the in-memory tdb
     1570         */
     1571        ret = tdb_traverse(ltdb->tdb, delete_index, module);
    16431572        if (ret == -1) {
    16441573                return LDB_ERR_OPERATIONS_ERROR;
     
    16501579        }
    16511580
     1581        ctx.module = module;
     1582        ctx.error = 0;
     1583
    16521584        /* now traverse adding any indexes for normal LDB records */
    1653         ret = tdb_traverse(ltdb->tdb, re_index, module);
     1585        ret = tdb_traverse(ltdb->tdb, re_index, &ctx);
    16541586        if (ret == -1) {
    1655                 return LDB_ERR_OPERATIONS_ERROR;
    1656         }
    1657 
    1658         if (ltdb->idxptr) {
    1659                 ltdb->idxptr->repack = true;
     1587                struct ldb_context *ldb = ldb_module_get_ctx(module);
     1588                ldb_asprintf_errstring(ldb, "reindexing traverse failed: %s", ldb_errstring(ldb));
     1589                return LDB_ERR_OPERATIONS_ERROR;
     1590        }
     1591
     1592        if (ctx.error != LDB_SUCCESS) {
     1593                struct ldb_context *ldb = ldb_module_get_ctx(module);
     1594                ldb_asprintf_errstring(ldb, "reindexing failed: %s", ldb_errstring(ldb));
     1595                return ctx.error;
    16601596        }
    16611597
  • vendor/current/source4/lib/ldb/ldb_tdb/ldb_pack.c

    r414 r740  
    5959{
    6060        if (el->num_values == 0) return 0;
    61 
    62         if (ldb_attr_cmp(el->name, "dn") == 0) return 0;
    6361
    6462        if (ldb_attr_cmp(el->name, "distinguishedName") == 0) return 0;
     
    209207
    210208        if (message->num_elements == 0) {
    211                 message->elements = NULL;
    212209                return 0;
    213210        }
  • vendor/current/source4/lib/ldb/ldb_tdb/ldb_search.c

    r414 r740  
    7979
    8080        elnew->num_values = el->num_values;
     81        elnew->flags = el->flags;
    8182
    8283        ret->num_elements++;
     
    9899        el.num_values = 1;
    99100        el.values = &val;
     101        el.flags = 0;
    100102        val.data = (uint8_t *)ldb_dn_alloc_linearized(msg, msg->dn);
    101103        val.length = strlen((char *)val.data);
     
    146148{
    147149        struct ldb_message *ret;
    148         int i;
     150        unsigned int i;
    149151
    150152        ret = talloc(mem_ctx, struct ldb_message);
     
    326328int ltdb_filter_attrs(struct ldb_message *msg, const char * const *attrs)
    327329{
    328         int i, keep_all = 0;
     330        unsigned int i;
     331        int keep_all = 0;
     332        struct ldb_message_element *el2;
     333        uint32_t num_elements;
    329334
    330335        if (attrs) {
     
    353358        }
    354359
     360        el2 = talloc_array(msg, struct ldb_message_element, msg->num_elements);
     361        if (el2 == NULL) {
     362                return -1;
     363        }
     364        num_elements = 0;
     365
    355366        for (i = 0; i < msg->num_elements; i++) {
    356                 int j, found;
     367                unsigned int j;
     368                int found = 0;
    357369               
    358                 for (j = 0, found = 0; attrs[j]; j++) {
     370                for (j = 0; attrs[j]; j++) {
    359371                        if (ldb_attr_cmp(msg->elements[i].name, attrs[j]) == 0) {
    360372                                found = 1;
     
    363375                }
    364376
    365                 if (!found) {
    366                         ldb_msg_remove_attr(msg, msg->elements[i].name);
    367                         i--;
    368                 }
    369         }
     377                if (found) {
     378                        el2[num_elements] = msg->elements[i];
     379                        talloc_steal(el2, el2[num_elements].name);
     380                        talloc_steal(el2, el2[num_elements].values);
     381                        num_elements++;
     382                }
     383        }
     384
     385        talloc_free(msg->elements);
     386        msg->elements = talloc_realloc(msg, el2, struct ldb_message_element, msg->num_elements);
     387        if (msg->elements == NULL) {
     388                return -1;
     389        }
     390        msg->num_elements = num_elements;
    370391
    371392        return 0;
     
    381402        struct ldb_message *msg;
    382403        int ret;
     404        bool matched;
    383405
    384406        ac = talloc_get_type(state, struct ltdb_context);
     
    412434
    413435        /* see if it matches the given expression */
    414         if (!ldb_match_msg(ldb, msg,
    415                            ac->tree, ac->base, ac->scope)) {
     436        ret = ldb_match_msg_error(ldb, msg,
     437                                  ac->tree, ac->base, ac->scope, &matched);
     438        if (ret != LDB_SUCCESS) {
     439                talloc_free(msg);
     440                return -1;
     441        }
     442        if (!matched) {
    416443                talloc_free(msg);
    417444                return 0;
     
    552579                if ( ! ctx->request_terminated && ret != LDB_SUCCESS) {
    553580                        /* Not indexed, so we need to do a full scan */
    554 #if 0
    555                         /* useful for debugging when slow performance
    556                          * is caused by unindexed searches */
    557                         char *expression = ldb_filter_from_tree(ctx, ctx->tree);
    558                         printf("FULL SEARCH: %s\n", expression);
    559                         talloc_free(expression);
    560 #endif
     581                        if (ltdb->warn_unindexed) {
     582                                /* useful for debugging when slow performance
     583                                 * is caused by unindexed searches */
     584                                char *expression = ldb_filter_from_tree(ctx, ctx->tree);
     585                                ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb FULL SEARCH: %s SCOPE: %s DN: %s\n",
     586                                                        expression,
     587                                                        req->op.search.scope==LDB_SCOPE_BASE?"base":
     588                                                        req->op.search.scope==LDB_SCOPE_ONELEVEL?"one":
     589                                                        req->op.search.scope==LDB_SCOPE_SUBTREE?"sub":"UNKNOWN",
     590                                                        ldb_dn_get_linearized(req->op.search.base));
     591
     592                                talloc_free(expression);
     593                        }
    561594                        if (match_count != 0) {
    562595                                /* the indexing code gave an error
     
    568601                                 * duplicate entries
    569602                                 */
     603                                ltdb_unlock_read(module);
    570604                                return LDB_ERR_OPERATIONS_ERROR;
    571605                        }
  • vendor/current/source4/lib/ldb/ldb_tdb/ldb_tdb.c

    r414 r740  
    22   ldb database library
    33
    4    Copyright (C) Andrew Tridgell  2004
    5    Copyright (C) Stefan Metzmacher  2004
    6    Copyright (C) Simo Sorce       2006-2008
    7 
     4   Copyright (C) Andrew Tridgell 2004
     5   Copyright (C) Stefan Metzmacher 2004
     6   Copyright (C) Simo Sorce 2006-2008
     7   Copyright (C) Matthias Dieter Wallnöfer 2009-2010
    88
    99     ** NOTE! The following LGPL license applies to the ldb
     
    3737 *  Modifications:
    3838 *
    39  *  - description: make the module use asyncronous calls
     39 *  - description: make the module use asynchronous calls
    4040 *    date: Feb 2006
    4141 *    Author: Simo Sorce
     
    4444 *    date: Jan 2008
    4545 *    Author: Simo Sorce
     46 *
     47 *  - description: fix up memory leaks and small bugs
     48 *    date: Oct 2009
     49 *    Author: Matthias Dieter Wallnöfer
    4650 */
    4751
     
    5256  map a tdb error code to a ldb error code
    5357*/
    54 static int ltdb_err_map(enum TDB_ERROR tdb_code)
     58int ltdb_err_map(enum TDB_ERROR tdb_code)
    5559{
    5660        switch (tdb_code) {
     
    7478        case TDB_ERR_RDONLY:
    7579                return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
     80        default:
     81                break;
    7682        }
    7783        return LDB_ERR_OTHER;
     
    8591        void *data = ldb_module_get_private(module);
    8692        struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
    87         if (ltdb->in_transaction == 0) {
    88                 return tdb_lockall_read(ltdb->tdb);
    89         }
    90         return 0;
     93        int ret = 0;
     94
     95        if (ltdb->in_transaction == 0 &&
     96            ltdb->read_lock_count == 0) {
     97                ret = tdb_lockall_read(ltdb->tdb);
     98        }
     99        if (ret == 0) {
     100                ltdb->read_lock_count++;
     101        }
     102        return ret;
    91103}
    92104
     
    98110        void *data = ldb_module_get_private(module);
    99111        struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
    100         if (ltdb->in_transaction == 0) {
     112        if (ltdb->in_transaction == 0 && ltdb->read_lock_count == 1) {
    101113                return tdb_unlockall_read(ltdb->tdb);
    102114        }
     115        ltdb->read_lock_count--;
    103116        return 0;
    104117}
     
    163176*/
    164177static int ltdb_check_special_dn(struct ldb_module *module,
    165                           const struct ldb_message *msg)
     178                                const struct ldb_message *msg)
    166179{
    167180        struct ldb_context *ldb = ldb_module_get_ctx(module);
    168         int i, j;
     181        unsigned int i, j;
    169182
    170183        if (! ldb_dn_is_special(msg->dn) ||
    171184            ! ldb_dn_check_special(msg->dn, LTDB_ATTRIBUTES)) {
    172                 return 0;
     185                return LDB_SUCCESS;
    173186        }
    174187
     
    176189        /* should we check that we deny multivalued attributes ? */
    177190        for (i = 0; i < msg->num_elements; i++) {
     191                if (ldb_attr_cmp(msg->elements[i].name, "distinguishedName") == 0) continue;
     192
    178193                for (j = 0; j < msg->elements[i].num_values; j++) {
    179194                        if (ltdb_check_at_attributes_values(&msg->elements[i].values[j]) != 0) {
     
    184199        }
    185200
    186         return 0;
     201        return LDB_SUCCESS;
    187202}
    188203
     
    195210{
    196211        int ret = LDB_SUCCESS;
     212        struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
     213
     214        /* only allow modifies inside a transaction, otherwise the
     215         * ldb is unsafe */
     216        if (ltdb->in_transaction == 0) {
     217                ldb_set_errstring(ldb_module_get_ctx(module), "ltdb modify without transaction");
     218                return LDB_ERR_OPERATIONS_ERROR;
     219        }
    197220
    198221        if (ldb_dn_is_special(dn) &&
     
    202225        }
    203226
     227        /* If the modify was to a normal record, or any special except @BASEINFO, update the seq number */
    204228        if (ret == LDB_SUCCESS &&
    205229            !(ldb_dn_is_special(dn) &&
     
    208232        }
    209233
     234        /* If the modify was to @OPTIONS, reload the cache */
     235        if (ret == LDB_SUCCESS &&
     236            ldb_dn_is_special(dn) &&
     237            (ldb_dn_check_special(dn, LTDB_OPTIONS)) ) {
     238                ret = ltdb_cache_reload(module);
     239        }
     240
    210241        return ret;
    211242}
     
    219250        struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
    220251        TDB_DATA tdb_key, tdb_data;
    221         int ret;
     252        int ret = LDB_SUCCESS;
    222253
    223254        tdb_key = ltdb_key(module, msg->dn);
    224         if (!tdb_key.dptr) {
     255        if (tdb_key.dptr == NULL) {
    225256                return LDB_ERR_OTHER;
    226257        }
     
    238269        }
    239270
    240         ret = ltdb_index_add(module, msg);
    241         if (ret != LDB_SUCCESS) {
    242                 tdb_delete(ltdb->tdb, tdb_key);
    243         }
    244 
    245271done:
    246272        talloc_free(tdb_key.dptr);
     
    251277
    252278
     279/*
     280  check if a attribute is a single valued, for a given element
     281 */
     282static bool ldb_tdb_single_valued(const struct ldb_schema_attribute *a,
     283                                  struct ldb_message_element *el)
     284{
     285        if (!a) return false;
     286        if (el != NULL) {
     287                if (el->flags & LDB_FLAG_INTERNAL_FORCE_SINGLE_VALUE_CHECK) {
     288                        /* override from a ldb module, for example
     289                           used for the description field, which is
     290                           marked multi-valued in the schema but which
     291                           should not actually accept multiple
     292                           values */
     293                        return true;
     294                }
     295                if (el->flags & LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK) {
     296                        /* override from a ldb module, for example used for
     297                           deleted linked attribute entries */
     298                        return false;
     299                }
     300        }
     301        if (a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
     302                return true;
     303        }
     304        return false;
     305}
     306
    253307static int ltdb_add_internal(struct ldb_module *module,
    254308                             const struct ldb_message *msg)
    255309{
    256310        struct ldb_context *ldb = ldb_module_get_ctx(module);
    257         int ret, i;
    258 
    259         ret = ltdb_check_special_dn(module, msg);
    260         if (ret != LDB_SUCCESS) {
    261                 return ret;
    262         }
    263 
    264         if (ltdb_cache_load(module) != 0) {
    265                 return LDB_ERR_OPERATIONS_ERROR;
    266         }
     311        int ret = LDB_SUCCESS;
     312        unsigned int i;
    267313
    268314        for (i=0;i<msg->num_elements;i++) {
     
    271317
    272318                if (el->num_values == 0) {
    273                         ldb_asprintf_errstring(ldb, "attribute %s on %s specified, but with 0 values (illegal)",
     319                        ldb_asprintf_errstring(ldb, "attribute '%s' on '%s' specified, but with 0 values (illegal)",
    274320                                               el->name, ldb_dn_get_linearized(msg->dn));
    275321                        return LDB_ERR_CONSTRAINT_VIOLATION;
    276322                }
    277                 if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
    278                         if (el->num_values > 1) {
    279                                 ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s speicified more than once",
    280                                                        el->name, ldb_dn_get_linearized(msg->dn));
    281                                 return LDB_ERR_CONSTRAINT_VIOLATION;
    282                         }
     323                if (el->num_values > 1 && ldb_tdb_single_valued(a, el)) {
     324                        ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once",
     325                                               el->name, ldb_dn_get_linearized(msg->dn));
     326                        return LDB_ERR_CONSTRAINT_VIOLATION;
    283327                }
    284328        }
    285329
    286330        ret = ltdb_store(module, msg, TDB_INSERT);
    287 
    288         if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
    289                 ldb_asprintf_errstring(ldb,
    290                                         "Entry %s already exists",
    291                                         ldb_dn_get_linearized(msg->dn));
     331        if (ret != LDB_SUCCESS) {
     332                if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
     333                        ldb_asprintf_errstring(ldb,
     334                                               "Entry %s already exists",
     335                                               ldb_dn_get_linearized(msg->dn));
     336                }
    292337                return ret;
    293338        }
    294339
    295         if (ret == LDB_SUCCESS) {
    296                 ret = ltdb_index_one(module, msg, 1);
    297                 if (ret != LDB_SUCCESS) {
    298                         return ret;
    299                 }
    300 
    301                 ret = ltdb_modified(module, msg->dn);
    302                 if (ret != LDB_SUCCESS) {
    303                         return ret;
    304                 }
    305         }
     340        ret = ltdb_index_add_new(module, msg);
     341        if (ret != LDB_SUCCESS) {
     342                return ret;
     343        }
     344
     345        ret = ltdb_modified(module, msg->dn);
    306346
    307347        return ret;
     
    315355        struct ldb_module *module = ctx->module;
    316356        struct ldb_request *req = ctx->req;
    317         int tret;
     357        int ret = LDB_SUCCESS;
     358
     359        ret = ltdb_check_special_dn(module, req->op.add.message);
     360        if (ret != LDB_SUCCESS) {
     361                return ret;
     362        }
    318363
    319364        ldb_request_set_state(req, LDB_ASYNC_PENDING);
    320365
    321         tret = ltdb_add_internal(module, req->op.add.message);
    322         if (tret != LDB_SUCCESS) {
    323                 return tret;
    324         }
    325 
    326         return LDB_SUCCESS;
     366        if (ltdb_cache_load(module) != 0) {
     367                return LDB_ERR_OPERATIONS_ERROR;
     368        }
     369
     370        ret = ltdb_add_internal(module, req->op.add.message);
     371
     372        return ret;
    327373}
    328374
     
    356402{
    357403        struct ldb_message *msg;
    358         int ret;
    359 
    360         msg = talloc(module, struct ldb_message);
     404        int ret = LDB_SUCCESS;
     405
     406        msg = ldb_msg_new(module);
    361407        if (msg == NULL) {
    362408                return LDB_ERR_OPERATIONS_ERROR;
     
    376422        }
    377423
    378         /* remove one level attribute */
    379         ret = ltdb_index_one(module, msg, 0);
    380         if (ret != LDB_SUCCESS) {
    381                 goto done;
    382         }
    383 
    384424        /* remove any indexed attributes */
    385         ret = ltdb_index_del(module, msg);
     425        ret = ltdb_index_delete(module, msg);
    386426        if (ret != LDB_SUCCESS) {
    387427                goto done;
     
    405445        struct ldb_module *module = ctx->module;
    406446        struct ldb_request *req = ctx->req;
    407         int tret;
     447        int ret = LDB_SUCCESS;
    408448
    409449        ldb_request_set_state(req, LDB_ASYNC_PENDING);
     
    413453        }
    414454
    415         tret = ltdb_delete_internal(module, req->op.del.dn);
    416         if (tret != LDB_SUCCESS) {
    417                 return tret;
    418         }
    419 
    420         return LDB_SUCCESS;
     455        ret = ltdb_delete_internal(module, req->op.del.dn);
     456
     457        return ret;
    421458}
    422459
     
    447484  returns 0 on success, -1 on failure (and sets errno)
    448485*/
    449 static int msg_add_element(struct ldb_context *ldb,
    450                            struct ldb_message *msg,
    451                            struct ldb_message_element *el)
     486static int ltdb_msg_add_element(struct ldb_context *ldb,
     487                                struct ldb_message *msg,
     488                                struct ldb_message_element *el)
    452489{
    453490        struct ldb_message_element *e2;
    454491        unsigned int i;
     492
     493        if (el->num_values == 0) {
     494                /* nothing to do here - we don't add empty elements */
     495                return 0;
     496        }
    455497
    456498        e2 = talloc_realloc(msg, msg->elements, struct ldb_message_element,
     
    467509        e2->name = el->name;
    468510        e2->flags = el->flags;
    469         e2->values = NULL;
    470         if (el->num_values != 0) {
    471                 e2->values = talloc_array(msg->elements,
    472                                           struct ldb_val, el->num_values);
    473                 if (!e2->values) {
    474                         errno = ENOMEM;
    475                         return -1;
    476                 }
     511        e2->values = talloc_array(msg->elements,
     512                                  struct ldb_val, el->num_values);
     513        if (!e2->values) {
     514                errno = ENOMEM;
     515                return -1;
    477516        }
    478517        for (i=0;i<el->num_values;i++) {
     
    481520        e2->num_values = el->num_values;
    482521
    483         msg->num_elements++;
     522        ++msg->num_elements;
    484523
    485524        return 0;
     
    493532                                struct ldb_message *msg, const char *name)
    494533{
    495         const char *dn;
    496         unsigned int i, j;
    497 
    498         dn = ldb_dn_get_linearized(msg->dn);
    499         if (dn == NULL) {
    500                 return -1;
    501         }
    502 
    503         for (i=0;i<msg->num_elements;i++) {
    504                 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
    505                         for (j=0;j<msg->elements[i].num_values;j++) {
    506                                 ltdb_index_del_value(module, dn,
    507                                                      &msg->elements[i], j);
    508                         }
    509                         talloc_free(msg->elements[i].values);
    510                         if (msg->num_elements > (i+1)) {
    511                                 memmove(&msg->elements[i],
    512                                         &msg->elements[i+1],
    513                                         sizeof(struct ldb_message_element)*
    514                                         (msg->num_elements - (i+1)));
    515                         }
    516                         msg->num_elements--;
    517                         i--;
    518                         msg->elements = talloc_realloc(msg, msg->elements,
    519                                                         struct ldb_message_element,
    520                                                         msg->num_elements);
    521                 }
    522         }
    523 
    524         return 0;
     534        unsigned int i;
     535        int ret;
     536        struct ldb_message_element *el;
     537
     538        el = ldb_msg_find_element(msg, name);
     539        if (el == NULL) {
     540                return LDB_ERR_NO_SUCH_ATTRIBUTE;
     541        }
     542        i = el - msg->elements;
     543
     544        ret = ltdb_index_del_element(module, msg->dn, el);
     545        if (ret != LDB_SUCCESS) {
     546                return ret;
     547        }
     548
     549        talloc_free(el->values);
     550        if (msg->num_elements > (i+1)) {
     551                memmove(el, el+1, sizeof(*el) * (msg->num_elements - (i+1)));
     552        }
     553        msg->num_elements--;
     554        msg->elements = talloc_realloc(msg, msg->elements,
     555                                       struct ldb_message_element,
     556                                       msg->num_elements);
     557        return LDB_SUCCESS;
    525558}
    526559
     
    528561  delete all elements matching an attribute name/value
    529562
    530   return 0 on success, -1 on failure
     563  return LDB Error on failure
    531564*/
    532565static int msg_delete_element(struct ldb_module *module,
     
    537570        struct ldb_context *ldb = ldb_module_get_ctx(module);
    538571        unsigned int i;
    539         int found;
     572        int found, ret;
    540573        struct ldb_message_element *el;
    541574        const struct ldb_schema_attribute *a;
     
    543576        found = find_element(msg, name);
    544577        if (found == -1) {
    545                 return -1;
    546         }
    547 
    548         el = &msg->elements[found];
     578                return LDB_ERR_NO_SUCH_ATTRIBUTE;
     579        }
     580
     581        i = (unsigned int) found;
     582        el = &(msg->elements[i]);
    549583
    550584        a = ldb_schema_attribute_by_name(ldb, el->name);
    551585
    552586        for (i=0;i<el->num_values;i++) {
    553                 if (a->syntax->comparison_fn(ldb, ldb,
    554                                                 &el->values[i], val) == 0) {
     587                bool matched;
     588                if (a->syntax->operator_fn) {
     589                        ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a,
     590                                                     &el->values[i], val, &matched);
     591                        if (ret != LDB_SUCCESS) return ret;
     592                } else {
     593                        matched = (a->syntax->comparison_fn(ldb, ldb,
     594                                                            &el->values[i], val) == 0);
     595                }
     596                if (matched) {
     597                        if (el->num_values == 1) {
     598                                return msg_delete_attribute(module, ldb, msg, name);
     599                        }
     600
     601                        ret = ltdb_index_del_value(module, msg->dn, el, i);
     602                        if (ret != LDB_SUCCESS) {
     603                                return ret;
     604                        }
     605
    555606                        if (i<el->num_values-1) {
    556607                                memmove(&el->values[i], &el->values[i+1],
     
    559610                        }
    560611                        el->num_values--;
    561                         if (el->num_values == 0) {
    562                                 return msg_delete_attribute(module, ldb,
    563                                                             msg, name);
    564                         }
    565                         return 0;
     612
     613                        /* per definition we find in a canonicalised message an
     614                           attribute value only once. So we are finished here */
     615                        return LDB_SUCCESS;
    566616                }
    567617        }
    568618
    569         return -1;
     619        /* Not found */
     620        return LDB_ERR_NO_SUCH_ATTRIBUTE;
    570621}
    571622
     
    577628  get away with it, but if we ever have really large attribute lists
    578629  then we'll need to look at this again
     630
     631  'req' is optional, and is used to specify controls if supplied
    579632*/
    580633int ltdb_modify_internal(struct ldb_module *module,
    581                          const struct ldb_message *msg)
     634                         const struct ldb_message *msg,
     635                         struct ldb_request *req)
    582636{
    583637        struct ldb_context *ldb = ldb_module_get_ctx(module);
     
    586640        TDB_DATA tdb_key, tdb_data;
    587641        struct ldb_message *msg2;
    588         unsigned i, j;
    589         int ret, idx;
     642        unsigned int i, j, k;
     643        int ret = LDB_SUCCESS, idx;
     644        struct ldb_control *control_permissive = NULL;
     645
     646        if (req) {
     647                control_permissive = ldb_request_get_control(req,
     648                                        LDB_CONTROL_PERMISSIVE_MODIFY_OID);
     649        }
    590650
    591651        tdb_key = ltdb_key(module, msg->dn);
     
    600660        }
    601661
    602         msg2 = talloc(tdb_key.dptr, struct ldb_message);
     662        msg2 = ldb_msg_new(tdb_key.dptr);
    603663        if (msg2 == NULL) {
    604                 talloc_free(tdb_key.dptr);
    605                 return LDB_ERR_OTHER;
     664                free(tdb_data.dptr);
     665                ret = LDB_ERR_OTHER;
     666                goto done;
    606667        }
    607668
    608669        ret = ltdb_unpack_data(module, &tdb_data, msg2);
     670        free(tdb_data.dptr);
    609671        if (ret == -1) {
    610672                ret = LDB_ERR_OTHER;
    611                 goto failed;
     673                goto done;
    612674        }
    613675
     
    616678        }
    617679
    618         for (i=0;i<msg->num_elements;i++) {
    619                 struct ldb_message_element *el = &msg->elements[i];
    620                 struct ldb_message_element *el2;
     680        for (i=0; i<msg->num_elements; i++) {
     681                struct ldb_message_element *el = &msg->elements[i], *el2;
    621682                struct ldb_val *vals;
     683                const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name);
    622684                const char *dn;
    623                 const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name);
     685
    624686                switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
    625 
    626687                case LDB_FLAG_MOD_ADD:
    627                        
    628                         /* add this element to the message. fail if it
    629                            already exists */
     688
     689                        if (el->num_values == 0) {
     690                                ldb_asprintf_errstring(ldb,
     691                                                       "attribute '%s': attribute on '%s' specified, but with 0 values (illegal)",
     692                                                       el->name, ldb_dn_get_linearized(msg2->dn));
     693                                ret = LDB_ERR_CONSTRAINT_VIOLATION;
     694                                goto done;
     695                        }
     696
     697                        /* make a copy of the array so that a permissive
     698                         * control can remove duplicates without changing the
     699                         * original values, but do not copy data as we do not
     700                         * need to keep it around once the operation is
     701                         * finished */
     702                        if (control_permissive) {
     703                                el = talloc(msg2, struct ldb_message_element);
     704                                if (!el) {
     705                                        ret = LDB_ERR_OTHER;
     706                                        goto done;
     707                                }
     708                                *el = msg->elements[i];
     709                                el->values = talloc_array(el, struct ldb_val, el->num_values);
     710                                if (el->values == NULL) {
     711                                        ret = LDB_ERR_OTHER;
     712                                        goto done;
     713                                }
     714                                for (j = 0; j < el->num_values; j++) {
     715                                        el->values[j] = msg->elements[i].values[j];
     716                                }
     717                        }
     718
     719                        if (el->num_values > 1 && ldb_tdb_single_valued(a, el)) {
     720                                ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once",
     721                                                       el->name, ldb_dn_get_linearized(msg2->dn));
     722                                ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
     723                                goto done;
     724                        }
     725
     726                        /* Checks if element already exists */
    630727                        idx = find_element(msg2, el->name);
    631 
    632                         if (el->num_values == 0) {
    633                                 ldb_asprintf_errstring(ldb, "attribute %s on %s speicified, but with 0 values (illigal)",
    634                                                   el->name, ldb_dn_get_linearized(msg->dn));
    635                                 return LDB_ERR_CONSTRAINT_VIOLATION;
    636                         }
    637728                        if (idx == -1) {
    638                                 if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
    639                                         if (el->num_values > 1) {
    640                                                 ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s speicified more than once",
    641                                                                el->name, ldb_dn_get_linearized(msg->dn));
    642                                                 return LDB_ERR_CONSTRAINT_VIOLATION;
     729                                if (ltdb_msg_add_element(ldb, msg2, el) != 0) {
     730                                        ret = LDB_ERR_OTHER;
     731                                        goto done;
     732                                }
     733                                ret = ltdb_index_add_element(module, msg2->dn,
     734                                                             el);
     735                                if (ret != LDB_SUCCESS) {
     736                                        goto done;
     737                                }
     738                        } else {
     739                                j = (unsigned int) idx;
     740                                el2 = &(msg2->elements[j]);
     741
     742                                /* We cannot add another value on a existing one
     743                                   if the attribute is single-valued */
     744                                if (ldb_tdb_single_valued(a, el)) {
     745                                        ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once",
     746                                                               el->name, ldb_dn_get_linearized(msg2->dn));
     747                                        ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
     748                                        goto done;
     749                                }
     750
     751                                /* Check that values don't exist yet on multi-
     752                                   valued attributes or aren't provided twice */
     753                                for (j = 0; j < el->num_values; j++) {
     754                                        if (ldb_msg_find_val(el2, &el->values[j]) != NULL) {
     755                                                if (control_permissive) {
     756                                                        /* remove this one as if it was never added */
     757                                                        el->num_values--;
     758                                                        for (k = j; k < el->num_values; k++) {
     759                                                                el->values[k] = el->values[k + 1];
     760                                                        }
     761                                                        j--; /* rewind */
     762
     763                                                        continue;
     764                                                }
     765
     766                                                ldb_asprintf_errstring(ldb,
     767                                                                       "attribute '%s': value #%u on '%s' already exists",
     768                                                                       el->name, j, ldb_dn_get_linearized(msg2->dn));
     769                                                ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
     770                                                goto done;
     771                                        }
     772                                        if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) {
     773                                                ldb_asprintf_errstring(ldb,
     774                                                                       "attribute '%s': value #%u on '%s' provided more than once",
     775                                                                       el->name, j, ldb_dn_get_linearized(msg2->dn));
     776                                                ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
     777                                                goto done;
    643778                                        }
    644779                                }
    645                                 if (msg_add_element(ldb, msg2, el) != 0) {
     780
     781                                /* Now combine existing and new values to a new
     782                                   attribute record */
     783                                vals = talloc_realloc(msg2->elements,
     784                                                      el2->values, struct ldb_val,
     785                                                      el2->num_values + el->num_values);
     786                                if (vals == NULL) {
     787                                        ldb_oom(ldb);
    646788                                        ret = LDB_ERR_OTHER;
    647                                         goto failed;
     789                                        goto done;
    648790                                }
    649                                 continue;
    650                         }
    651 
    652                         /* If this is an add, then if it already
    653                          * exists in the object, then we violoate the
    654                          * single-value rule */
    655                         if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
    656                                 return LDB_ERR_CONSTRAINT_VIOLATION;
    657                         }
    658 
    659                         el2 = &msg2->elements[idx];
    660 
    661                         /* An attribute with this name already exists,
    662                          * add all values if they don't already exist
    663                          * (check both the other elements to be added,
    664                          * and those already in the db). */
    665 
    666                         for (j=0;j<el->num_values;j++) {
    667                                 if (ldb_msg_find_val(el2, &el->values[j])) {
    668                                         ldb_asprintf_errstring(ldb, "%s: value #%d already exists", el->name, j);
    669                                         ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
    670                                         goto failed;
     791
     792                                for (j=0; j<el->num_values; j++) {
     793                                        vals[el2->num_values + j] =
     794                                                ldb_val_dup(vals, &el->values[j]);
    671795                                }
    672                                 if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) {
    673                                         ldb_asprintf_errstring(ldb, "%s: value #%d provided more than once", el->name, j);
    674                                         ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
    675                                         goto failed;
     796
     797                                el2->values = vals;
     798                                el2->num_values += el->num_values;
     799
     800                                ret = ltdb_index_add_element(module, msg2->dn, el);
     801                                if (ret != LDB_SUCCESS) {
     802                                        goto done;
    676803                                }
    677804                        }
    678805
    679                         vals = talloc_realloc(msg2->elements, el2->values, struct ldb_val,
    680                                                 el2->num_values + el->num_values);
    681 
    682                         if (vals == NULL) {
    683                                 ret = LDB_ERR_OTHER;
    684                                 goto failed;
     806                        break;
     807
     808                case LDB_FLAG_MOD_REPLACE:
     809
     810                        if (el->num_values > 1 && ldb_tdb_single_valued(a, el)) {
     811                                ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once",
     812                                                       el->name, ldb_dn_get_linearized(msg2->dn));
     813                                ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
     814                                goto done;
    685815                        }
    686816
    687                         for (j=0;j<el->num_values;j++) {
    688                                 vals[el2->num_values + j] =
    689                                         ldb_val_dup(vals, &el->values[j]);
    690                         }
    691 
    692                         el2->values = vals;
    693                         el2->num_values += el->num_values;
    694 
    695                         break;
    696 
    697                 case LDB_FLAG_MOD_REPLACE:
    698                         if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
    699                                 if (el->num_values > 1) {
    700                                         ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s speicified more than once",
    701                                                                el->name, ldb_dn_get_linearized(msg->dn));
    702                                         return LDB_ERR_CONSTRAINT_VIOLATION;
     817                        /* TODO: This is O(n^2) - replace with more efficient check */
     818                        for (j=0; j<el->num_values; j++) {
     819                                if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) {
     820                                        ldb_asprintf_errstring(ldb,
     821                                                               "attribute '%s': value #%u on '%s' provided more than once",
     822                                                               el->name, j, ldb_dn_get_linearized(msg2->dn));
     823                                        ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
     824                                        goto done;
    703825                                }
    704826                        }
    705                         /* replace all elements of this attribute name with the elements
    706                            listed. The attribute not existing is not an error */
    707                         msg_delete_attribute(module, ldb, msg2, el->name);
    708 
    709                         for (j=0;j<el->num_values;j++) {
    710                                 if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) {
    711                                         ldb_asprintf_errstring(ldb, "%s: value #%d provided more than once", el->name, j);
    712                                         ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
    713                                         goto failed;
     827
     828                        /* Checks if element already exists */
     829                        idx = find_element(msg2, el->name);
     830                        if (idx != -1) {
     831                                j = (unsigned int) idx;
     832                                el2 = &(msg2->elements[j]);
     833                                if (ldb_msg_element_compare(el, el2) == 0) {
     834                                        /* we are replacing with the same values */
     835                                        continue;
     836                                }
     837                       
     838                                /* Delete the attribute if it exists in the DB */
     839                                if (msg_delete_attribute(module, ldb, msg2,
     840                                                         el->name) != 0) {
     841                                        ret = LDB_ERR_OTHER;
     842                                        goto done;
    714843                                }
    715844                        }
    716845
    717                         /* add the replacement element, if not empty */
    718                         if (el->num_values != 0 &&
    719                             msg_add_element(ldb, msg2, el) != 0) {
     846                        /* Recreate it with the new values */
     847                        if (ltdb_msg_add_element(ldb, msg2, el) != 0) {
    720848                                ret = LDB_ERR_OTHER;
    721                                 goto failed;
     849                                goto done;
    722850                        }
     851
     852                        ret = ltdb_index_add_element(module, msg2->dn, el);
     853                        if (ret != LDB_SUCCESS) {
     854                                goto done;
     855                        }
     856
    723857                        break;
    724858
    725859                case LDB_FLAG_MOD_DELETE:
    726 
    727                         dn = ldb_dn_get_linearized(msg->dn);
     860                        dn = ldb_dn_get_linearized(msg2->dn);
    728861                        if (dn == NULL) {
    729862                                ret = LDB_ERR_OTHER;
    730                                 goto failed;
     863                                goto done;
    731864                        }
    732865
    733                         /* we could be being asked to delete all
    734                            values or just some values */
    735866                        if (msg->elements[i].num_values == 0) {
    736                                 if (msg_delete_attribute(module, ldb, msg2,
    737                                                          msg->elements[i].name) != 0) {
    738                                         ldb_asprintf_errstring(ldb, "No such attribute: %s for delete on %s", msg->elements[i].name, dn);
    739                                         ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
    740                                         goto failed;
     867                                /* Delete the whole attribute */
     868                                ret = msg_delete_attribute(module, ldb, msg2,
     869                                                           msg->elements[i].name);
     870                                if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE &&
     871                                    control_permissive) {
     872                                        ret = LDB_SUCCESS;
     873                                } else {
     874                                        ldb_asprintf_errstring(ldb,
     875                                                               "attribute '%s': no such attribute for delete on '%s'",
     876                                                               msg->elements[i].name, dn);
    741877                                }
    742                                 break;
    743                         }
    744                         for (j=0;j<msg->elements[i].num_values;j++) {
    745                                 if (msg_delete_element(module,
    746                                                        msg2,
    747                                                        msg->elements[i].name,
    748                                                        &msg->elements[i].values[j]) != 0) {
    749                                         ldb_asprintf_errstring(ldb, "No matching attribute value when deleting attribute: %s on %s", msg->elements[i].name, dn);
    750                                         ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
    751                                         goto failed;
     878                                if (ret != LDB_SUCCESS) {
     879                                        goto done;
    752880                                }
    753                                 ret = ltdb_index_del_value(module, dn, &msg->elements[i], j);
    754                                 if (ret != LDB_SUCCESS) {
    755                                         goto failed;
     881                        } else {
     882                                /* Delete specified values from an attribute */
     883                                for (j=0; j < msg->elements[i].num_values; j++) {
     884                                        ret = msg_delete_element(module,
     885                                                                 msg2,
     886                                                                 msg->elements[i].name,
     887                                                                 &msg->elements[i].values[j]);
     888                                        if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE &&
     889                                            control_permissive) {
     890                                                ret = LDB_SUCCESS;
     891                                        } else {
     892                                                ldb_asprintf_errstring(ldb,
     893                                                                       "attribute '%s': no matching attribute value while deleting attribute on '%s'",
     894                                                                       msg->elements[i].name, dn);
     895                                        }
     896                                        if (ret != LDB_SUCCESS) {
     897                                                goto done;
     898                                        }
    756899                                }
    757900                        }
     
    759902                default:
    760903                        ldb_asprintf_errstring(ldb,
    761                                 "Invalid ldb_modify flags on %s: 0x%x",
    762                                 msg->elements[i].name,
    763                                 msg->elements[i].flags & LDB_FLAG_MOD_MASK);
     904                                               "attribute '%s': invalid modify flags on '%s': 0x%x",
     905                                               msg->elements[i].name, ldb_dn_get_linearized(msg->dn),
     906                                               msg->elements[i].flags & LDB_FLAG_MOD_MASK);
    764907                        ret = LDB_ERR_PROTOCOL_ERROR;
    765                         goto failed;
     908                        goto done;
    766909                }
    767910        }
    768911
    769         /* we've made all the mods
    770          * save the modified record back into the database */
    771912        ret = ltdb_store(module, msg2, TDB_MODIFY);
    772913        if (ret != LDB_SUCCESS) {
    773                 goto failed;
    774         }
    775 
    776         ret = ltdb_modified(module, msg->dn);
     914                goto done;
     915        }
     916
     917        ret = ltdb_modified(module, msg2->dn);
    777918        if (ret != LDB_SUCCESS) {
    778                 goto failed;
    779         }
    780 
     919                goto done;
     920        }
     921
     922done:
    781923        talloc_free(tdb_key.dptr);
    782         free(tdb_data.dptr);
    783         return ret;
    784 
    785 failed:
    786         talloc_free(tdb_key.dptr);
    787         free(tdb_data.dptr);
    788924        return ret;
    789925}
     
    796932        struct ldb_module *module = ctx->module;
    797933        struct ldb_request *req = ctx->req;
    798         int tret;
     934        int ret = LDB_SUCCESS;
     935
     936        ret = ltdb_check_special_dn(module, req->op.mod.message);
     937        if (ret != LDB_SUCCESS) {
     938                return ret;
     939        }
    799940
    800941        ldb_request_set_state(req, LDB_ASYNC_PENDING);
    801942
    802         tret = ltdb_check_special_dn(module, req->op.mod.message);
    803         if (tret != LDB_SUCCESS) {
    804                 return tret;
    805         }
    806 
    807943        if (ltdb_cache_load(module) != 0) {
    808944                return LDB_ERR_OPERATIONS_ERROR;
    809945        }
    810946
    811         tret = ltdb_modify_internal(module, req->op.mod.message);
    812         if (tret != LDB_SUCCESS) {
    813                 return tret;
    814         }
    815 
    816         return LDB_SUCCESS;
     947        ret = ltdb_modify_internal(module, req->op.mod.message, req);
     948
     949        return ret;
    817950}
    818951
     
    825958        struct ldb_request *req = ctx->req;
    826959        struct ldb_message *msg;
    827         int tret;
     960        int ret = LDB_SUCCESS;
    828961
    829962        ldb_request_set_state(req, LDB_ASYNC_PENDING);
     
    833966        }
    834967
    835         msg = talloc(ctx, struct ldb_message);
     968        msg = ldb_msg_new(ctx);
    836969        if (msg == NULL) {
    837970                return LDB_ERR_OPERATIONS_ERROR;
     
    840973        /* in case any attribute of the message was indexed, we need
    841974           to fetch the old record */
    842         tret = ltdb_search_dn1(module, req->op.rename.olddn, msg);
    843         if (tret != LDB_SUCCESS) {
     975        ret = ltdb_search_dn1(module, req->op.rename.olddn, msg);
     976        if (ret != LDB_SUCCESS) {
    844977                /* not finding the old record is an error */
    845                 return tret;
    846         }
    847 
    848         msg->dn = ldb_dn_copy(msg, req->op.rename.newdn);
    849         if (!msg->dn) {
    850                 return LDB_ERR_OPERATIONS_ERROR;
     978                return ret;
    851979        }
    852980
     
    855983         * atomic
    856984         */
    857         tret = ltdb_delete_internal(module, req->op.rename.olddn);
    858         if (tret != LDB_SUCCESS) {
    859                 return tret;
    860         }
    861 
    862         tret = ltdb_add_internal(module, msg);
    863         if (tret != LDB_SUCCESS) {
    864                 return tret;
    865         }
    866 
    867         return LDB_SUCCESS;
     985        ret = ltdb_delete_internal(module, msg->dn);
     986        if (ret != LDB_SUCCESS) {
     987                return ret;
     988        }
     989
     990        msg->dn = ldb_dn_copy(msg, req->op.rename.newdn);
     991        if (msg->dn == NULL) {
     992                return LDB_ERR_OPERATIONS_ERROR;
     993        }
     994
     995        ret = ltdb_add_internal(module, msg);
     996
     997        return ret;
    868998}
    869999
     
    9591089        struct ldb_module *module = ctx->module;
    9601090        struct ldb_request *req = ctx->req;
    961         TALLOC_CTX *tmp_ctx;
     1091        TALLOC_CTX *tmp_ctx = NULL;
    9621092        struct ldb_seqnum_request *seq;
    9631093        struct ldb_seqnum_result *res;
     
    9651095        struct ldb_dn *dn;
    9661096        const char *date;
    967         int ret;
     1097        int ret = LDB_SUCCESS;
    9681098
    9691099        ldb = ldb_module_get_ctx(module);
     
    9861116                goto done;
    9871117        }
     1118
    9881119        tmp_ctx = talloc_new(req);
    9891120        if (tmp_ctx == NULL) {
     
    9931124
    9941125        dn = ldb_dn_new(tmp_ctx, ldb, LTDB_BASEINFO);
    995 
    996         msg = talloc(tmp_ctx, struct ldb_message);
     1126        if (dn == NULL) {
     1127                ret = LDB_ERR_OPERATIONS_ERROR;
     1128                goto done;
     1129        }
     1130
     1131        msg = ldb_msg_new(tmp_ctx);
    9971132        if (msg == NULL) {
    9981133                ret = LDB_ERR_OPERATIONS_ERROR;
     
    10311166        (*ext)->oid = LDB_EXTENDED_SEQUENCE_NUMBER;
    10321167        (*ext)->data = talloc_steal(*ext, res);
    1033 
    1034         ret = LDB_SUCCESS;
    10351168
    10361169done:
     
    11671300        default:
    11681301                /* no other op supported */
    1169                 ret = LDB_ERR_UNWILLING_TO_PERFORM;
     1302                ret = LDB_ERR_PROTOCOL_ERROR;
    11701303        }
    11711304
     
    11971330                               struct ldb_request *req)
    11981331{
     1332        struct ldb_control *control_permissive;
    11991333        struct ldb_context *ldb;
    12001334        struct tevent_context *ev;
     
    12021336        struct tevent_timer *te;
    12031337        struct timeval tv;
    1204 
    1205         if (check_critical_controls(req->controls)) {
    1206                 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
    1207         }
     1338        unsigned int i;
    12081339
    12091340        ldb = ldb_module_get_ctx(module);
     1341
     1342        control_permissive = ldb_request_get_control(req,
     1343                                        LDB_CONTROL_PERMISSIVE_MODIFY_OID);
     1344
     1345        for (i = 0; req->controls && req->controls[i]; i++) {
     1346                if (req->controls[i]->critical &&
     1347                    req->controls[i] != control_permissive) {
     1348                        ldb_asprintf_errstring(ldb, "Unsupported critical extension %s",
     1349                                               req->controls[i]->oid);
     1350                        return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
     1351                }
     1352        }
    12101353
    12111354        if (req->starttime == 0 || req->timeout == 0) {
     
    12181361        ac = talloc_zero(ldb, struct ltdb_context);
    12191362        if (ac == NULL) {
    1220                 ldb_set_errstring(ldb, "Out of Memory");
     1363                ldb_oom(ldb);
    12211364                return LDB_ERR_OPERATIONS_ERROR;
    12221365        }
     
    12541397}
    12551398
     1399static int ltdb_init_rootdse(struct ldb_module *module)
     1400{
     1401        struct ldb_context *ldb;
     1402        int ret;
     1403
     1404        ldb = ldb_module_get_ctx(module);
     1405
     1406        ret = ldb_mod_register_control(module,
     1407                                       LDB_CONTROL_PERMISSIVE_MODIFY_OID);
     1408        /* ignore errors on this - we expect it for non-sam databases */
     1409
     1410        /* there can be no module beyond the backend, just return */
     1411        return LDB_SUCCESS;
     1412}
     1413
    12561414static const struct ldb_module_ops ltdb_ops = {
    12571415        .name              = "tdb",
     1416        .init_context      = ltdb_init_rootdse,
    12581417        .search            = ltdb_handle_request,
    12591418        .add               = ltdb_handle_request,
     
    12851444                        ldb_debug(ldb, LDB_DEBUG_ERROR,
    12861445                                  "Invalid tdb URL '%s'", url);
    1287                         return -1;
     1446                        return LDB_ERR_OPERATIONS_ERROR;
    12881447                }
    12891448                path = url+6;
     
    13131472        if (!ltdb) {
    13141473                ldb_oom(ldb);
    1315                 return -1;
     1474                return LDB_ERR_OPERATIONS_ERROR;
    13161475        }
    13171476
     
    13241483                          "Unable to open tdb '%s'", path);
    13251484                talloc_free(ltdb);
    1326                 return -1;
     1485                return LDB_ERR_OPERATIONS_ERROR;
     1486        }
     1487
     1488        if (getenv("LDB_WARN_UNINDEXED")) {
     1489                ltdb->warn_unindexed = true;
    13271490        }
    13281491
     
    13321495        if (!module) {
    13331496                talloc_free(ltdb);
    1334                 return -1;
     1497                return LDB_ERR_OPERATIONS_ERROR;
    13351498        }
    13361499        ldb_module_set_private(module, ltdb);
     1500        talloc_steal(module, ltdb);
    13371501
    13381502        if (ltdb_cache_load(module) != 0) {
    13391503                talloc_free(module);
    13401504                talloc_free(ltdb);
    1341                 return -1;
     1505                return LDB_ERR_OPERATIONS_ERROR;
    13421506        }
    13431507
    13441508        *_module = module;
    1345         return 0;
    1346 }
    1347 
    1348 const struct ldb_backend_ops ldb_tdb_backend_ops = {
    1349         .name = "tdb",
    1350         .connect_fn = ltdb_connect
    1351 };
     1509        return LDB_SUCCESS;
     1510}
     1511
     1512int ldb_tdb_init(const char *version)
     1513{
     1514        LDB_MODULE_CHECK_VERSION(version);
     1515        return ldb_register_backend("tdb", ltdb_connect, false);
     1516}
  • vendor/current/source4/lib/ldb/ldb_tdb/ldb_tdb.h

    r414 r740  
    1 #include "ldb_includes.h"
     1#include "replace.h"
     2#include "system/filesys.h"
     3#include "system/time.h"
    24#include "tdb.h"
    35#include "ldb_module.h"
     
    1820                struct ldb_message *indexlist;
    1921                struct ldb_message *attributes;
     22                bool one_level_indexes;
     23                bool attribute_indexes;
    2024
    2125                struct {
     
    3034        struct ltdb_idxptr *idxptr;
    3135        bool prepared_commit;
     36        int read_lock_count;
     37
     38        bool warn_unindexed;
    3239};
    3340
     
    5966#define LTDB_INDEXLIST  "@INDEXLIST"
    6067#define LTDB_IDX        "@IDX"
    61 #define LTDB_IDXPTR     "@IDXPTR"
     68#define LTDB_IDXVERSION "@IDXVERSION"
    6269#define LTDB_IDXATTR    "@IDXATTR"
    6370#define LTDB_IDXONE     "@IDXONE"
     
    8491
    8592int ltdb_search_indexed(struct ltdb_context *ctx, uint32_t *);
    86 int ltdb_index_add(struct ldb_module *module, const struct ldb_message *msg);
    87 int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg);
    88 int ltdb_index_one(struct ldb_module *module, const struct ldb_message *msg, int add);
     93int ltdb_index_add_new(struct ldb_module *module, const struct ldb_message *msg);
     94int ltdb_index_delete(struct ldb_module *module, const struct ldb_message *msg);
     95int ltdb_index_del_element(struct ldb_module *module, struct ldb_dn *dn,
     96                           struct ldb_message_element *el);
     97int ltdb_index_add_element(struct ldb_module *module, struct ldb_dn *dn,
     98                           struct ldb_message_element *el);
     99int ltdb_index_del_value(struct ldb_module *module, struct ldb_dn *dn,
     100                         struct ldb_message_element *el, unsigned int v_idx);
    89101int ltdb_reindex(struct ldb_module *module);
    90102int ltdb_index_transaction_start(struct ldb_module *module);
     
    123135struct TDB_DATA ltdb_key(struct ldb_module *module, struct ldb_dn *dn);
    124136int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs);
     137int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg, struct ldb_request *req);
    125138int ltdb_delete_noindex(struct ldb_module *module, struct ldb_dn *dn);
    126 int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg);
    127 
    128 int ltdb_index_del_value(struct ldb_module *module, const char *dn,
    129                          struct ldb_message_element *el, int v_idx);
     139int ltdb_err_map(enum TDB_ERROR tdb_code);
    130140
    131141struct tdb_context *ltdb_wrap_open(TALLOC_CTX *mem_ctx,
  • vendor/current/source4/lib/ldb/ldb_tdb/ldb_tdb_wrap.c

    r414 r740  
    2323
    2424#include "ldb_tdb.h"
     25#include "dlinklist.h"
    2526
    2627/*
     
    4344{
    4445        tdb_close(w->tdb);
    45         if (w->next) {
    46                 w->next->prev = w->prev;
    47         }
    48         if (w->prev) {
    49                 w->prev->next = w->next;
    50         }
    51         if (w == tdb_list) {
    52                 tdb_list = w->next;
    53         }
     46        DLIST_REMOVE(tdb_list, w);
    5447        return 0;
    5548}                               
     
    144137        talloc_set_destructor(w, ltdb_wrap_destructor);
    145138
    146         w->next = tdb_list;
    147         w->prev = NULL;
    148         if (tdb_list) {
    149                 tdb_list->prev = w;
    150         }
    151         tdb_list = w;
     139        DLIST_ADD(tdb_list, w);
    152140       
    153141        return w->tdb;
  • vendor/current/source4/lib/ldb/man/ldbadd.1.xml

    r414 r740  
    2828        <title>DESCRIPTION</title>
    2929
    30         <para>ldbadd adds records to an ldb(7) database. It reads
     30        <para>ldbadd adds records to an ldb(3) database. It reads
    3131                the ldif(5) files specified on the command line and adds
    3232                the records from these files to the LDB database, which is specified
     
    5353                        <term>-H &lt;ldb-url&gt;</term>
    5454                        <listitem><para>
    55                                 LDB URL to connect to. See ldb(7) for details.
     55                                LDB URL to connect to. See ldb(3) for details.
    5656                        </para></listitem>
    5757                </varlistentry>
     
    8282        <title>SEE ALSO</title>
    8383
    84         <para>ldb(7), ldbmodify, ldbdel, ldif(5)</para>
     84        <para>ldb(3), ldbmodify, ldbdel, ldif(5)</para>
    8585
    8686</refsect1>
  • vendor/current/source4/lib/ldb/man/ldbdel.1.xml

    r414 r740  
    2727        <title>DESCRIPTION</title>
    2828
    29         <para>ldbdel deletes records from an ldb(7) database.
     29        <para>ldbdel deletes records from an ldb(3) database.
    3030                It deletes the records identified by the dn's specified
    3131                on the command-line. </para>
     
    5151                        <term>-H &lt;ldb-url&gt;</term>
    5252                        <listitem><para>
    53                                 LDB URL to connect to. See ldb(7) for details.
     53                                LDB URL to connect to. See ldb(3) for details.
    5454                        </para></listitem>
    5555                </varlistentry>
     
    8080        <title>SEE ALSO</title>
    8181
    82         <para>ldb(7), ldbmodify, ldbadd, ldif(5)</para>
     82        <para>ldb(3), ldbmodify, ldbadd, ldif(5)</para>
    8383
    8484</refsect1>
  • vendor/current/source4/lib/ldb/man/ldbedit.1.xml

    r414 r740  
    173173        <title>SEE ALSO</title>
    174174       
    175         <para>ldb(7), ldbmodify(1), ldbdel(1), ldif(5), vi(1)</para>
     175        <para>ldb(3), ldbmodify(1), ldbdel(1), ldif(5), vi(1)</para>
    176176
    177177    </refsect1>
  • vendor/current/source4/lib/ldb/man/ldbmodify.1.xml

    r414 r740  
    4343                        <term>-H &lt;ldb-url&gt;</term>
    4444                        <listitem><para>
    45                                 LDB URL to connect to. See ldb(7) for details.
     45                                LDB URL to connect to. See ldb(3) for details.
    4646                        </para></listitem>
    4747                </varlistentry>
     
    7070        <title>SEE ALSO</title>
    7171
    72         <para>ldb(7), ldbedit</para>
     72        <para>ldb(3), ldbedit</para>
    7373
    7474</refsect1>
  • vendor/current/source4/lib/ldb/man/ldbrename.1.xml

    r414 r740  
    4949                        <term>-H &lt;ldb-url&gt;</term>
    5050                        <listitem><para>
    51                                 LDB URL to connect to. See ldb(7) for details.
     51                                LDB URL to connect to. See ldb(3) for details.
    5252                        </para></listitem>
    5353                </varlistentry>
     
    8484        <title>SEE ALSO</title>
    8585
    86         <para>ldb(7), ldbmodify, ldbdel, ldif(5)</para>
     86        <para>ldb(3), ldbmodify, ldbdel, ldif(5)</para>
    8787
    8888</refsect1>
  • vendor/current/source4/lib/ldb/man/ldbsearch.1.xml

    r414 r740  
    5252                        <term>-H &lt;ldb-url&gt;</term>
    5353                        <listitem><para>
    54                                 LDB URL to connect to. See ldb(7) for details.
     54                                LDB URL to connect to. See ldb(3) for details.
    5555                        </para></listitem>
    5656                </varlistentry>
     
    9696        <title>SEE ALSO</title>
    9797
    98         <para>ldb(7), ldbedit(1)</para>
     98        <para>ldb(3), ldbedit(1)</para>
    9999
    100100</refsect1>
  • vendor/current/source4/lib/ldb/modules/asq.c

    r414 r740  
    3333 */
    3434
     35#include "replace.h"
     36#include "system/filesys.h"
     37#include "system/time.h"
    3538#include "ldb_module.h"
    3639
     
    5659
    5760        struct ldb_request **reqs;
    58         int num_reqs;
    59         int cur_req;
     61        unsigned int num_reqs;
     62        unsigned int cur_req;
    6063
    6164        struct ldb_control **controls;
     
    8689{
    8790        struct ldb_asq_control *asq;
    88         int i;
     91        unsigned int i;
    8992
    9093        if (ac->controls) {
     
    238241                                        ac->req);
    239242        if (ret != LDB_SUCCESS) {
    240                 return LDB_ERR_OPERATIONS_ERROR;
     243                return ret;
    241244        }
    242245
     
    251254        struct ldb_dn *dn;
    252255        struct ldb_message_element *el;
    253         int ret, i;
     256        unsigned int i;
     257        int ret;
    254258
    255259        if (ac->base_res == NULL) {
     
    293297                                                ac->req);
    294298                if (ret != LDB_SUCCESS) {
    295                         return LDB_ERR_OPERATIONS_ERROR;
     299                        return ret;
    296300                }
    297301
    298302                /* remove the ASQ control itself */
    299303                control = ldb_request_get_control(ac->req, LDB_CONTROL_ASQ_OID);
    300                 if (!save_controls(control, ac->reqs[i], &saved_controls)) {
     304                if (!ldb_save_controls(control, ac->reqs[i], &saved_controls)) {
    301305                        return LDB_ERR_OPERATIONS_ERROR;
    302306                }
     
    400404}
    401405
    402 const struct ldb_module_ops ldb_asq_module_ops = {
     406static const struct ldb_module_ops ldb_asq_module_ops = {
    403407        .name              = "asq",
    404408        .search            = asq_search,
    405409        .init_context      = asq_init
    406410};
     411
     412int ldb_asq_init(const char *version)
     413{
     414        LDB_MODULE_CHECK_VERSION(version);
     415        return ldb_register_module(&ldb_asq_module_ops);
     416}
  • vendor/current/source4/lib/ldb/modules/paged_results.c

    r414 r740  
    3333 */
    3434
    35 #include "ldb_includes.h"
     35#include "replace.h"
     36#include "system/filesys.h"
     37#include "system/time.h"
    3638#include "ldb_module.h"
    3739
     
    6668
    6769struct private_data {
    68 
    69         int next_free_id;
     70        unsigned int next_free_id;
    7071        struct results_store *store;
    7172       
     
    9697{
    9798        struct results_store *newr;
    98         int new_id = priv->next_free_id++;
     99        unsigned int new_id = priv->next_free_id++;
    99100
    100101        /* TODO: we should have a limit on the number of
     
    141142        struct ldb_paged_control *paged;
    142143        struct message_store *msg;
    143         int i, num_ctrls, ret;
     144        unsigned int i, num_ctrls;
     145        int ret;
    144146
    145147        if (ac->store == NULL) {
     
    327329        ac->req = req;
    328330        ac->size = paged_ctrl->size;
     331        if (ac->size < 0) {
     332                /* apparently some clients send more than 2^31. This
     333                   violates the ldap standard, but we need to cope */
     334                ac->size = 0x7FFFFFFF;
     335        }
    329336
    330337        /* check if it is a continuation search the store */
     
    348355                                                paged_search_callback,
    349356                                                req);
     357                if (ret != LDB_SUCCESS) {
     358                        return ret;
     359                }
    350360
    351361                /* save it locally and remove it from the list */
    352362                /* we do not need to replace them later as we
    353363                 * are keeping the original req intact */
    354                 if (!save_controls(control, search_req, &saved_controls)) {
     364                if (!ldb_save_controls(control, search_req, &saved_controls)) {
    355365                        return LDB_ERR_OPERATIONS_ERROR;
    356366                }
     
    416426}
    417427
    418 const struct ldb_module_ops ldb_paged_results_module_ops = {
     428static const struct ldb_module_ops ldb_paged_results_module_ops = {
    419429        .name           = "paged_results",
    420430        .search         = paged_search,
    421431        .init_context   = paged_request_init
    422432};
     433
     434int ldb_paged_results_init(const char *version)
     435{
     436        LDB_MODULE_CHECK_VERSION(version);
     437        return ldb_register_module(&ldb_paged_results_module_ops);
     438}
  • vendor/current/source4/lib/ldb/modules/paged_searches.c

    r414 r740  
    3434 */
    3535
    36 #include "includes.h"
     36#include "replace.h"
     37#include "system/filesys.h"
     38#include "system/time.h"
    3739#include "ldb_module.h"
    3840
     
    5355
    5456        char **saved_referrals;
    55         int num_referrals;
     57        unsigned int num_referrals;
    5658
    5759        struct ldb_request *down_req;
     
    7981                        return LDB_ERR_OPERATIONS_ERROR;
    8082                } else {
    81                         /* No cookie recived yet, valid to just return the full data set */
     83                        /* No cookie received yet, valid to just return the full data set */
    8284
    8385                        /* we are done */
     
    133135        struct ldb_reply *ares;
    134136        int ret;
    135         int i;
     137        unsigned int i;
    136138
    137139        for (i = 0; i < ac->num_referrals; i++) {
     
    271273                                        ps_callback,
    272274                                        ac->req);
     275        LDB_REQ_SET_LOCATION(ac->down_req);
    273276        if (ret != LDB_SUCCESS) {
    274277                return ret;
     
    352355                                   data, check_supported_paged,
    353356                                   NULL);
     357        LDB_REQ_SET_LOCATION(req);
    354358        if (ret != LDB_SUCCESS) {
    355359                return ret;
     
    370374}
    371375
    372 _PUBLIC_ const struct ldb_module_ops ldb_paged_searches_module_ops = {
     376static const struct ldb_module_ops ldb_paged_searches_module_ops = {
    373377        .name           = "paged_searches",
    374378        .search         = ps_search,
    375379        .init_context   = ps_init
    376380};
     381
     382int ldb_paged_searches_init(const char *version)
     383{
     384        LDB_MODULE_CHECK_VERSION(version);
     385        return ldb_register_module(&ldb_paged_searches_module_ops);
     386}
  • vendor/current/source4/lib/ldb/modules/rdn_name.c

    r414 r740  
    22   ldb database library
    33
    4    Copyright (C) Andrew Bartlett 2005
     4   Copyright (C) Andrew Bartlett 2005-2009
    55   Copyright (C) Simo Sorce 2006-2008
    66
     
    3737 */
    3838
    39 #include "ldb_includes.h"
     39#include "replace.h"
     40#include "system/filesys.h"
     41#include "system/time.h"
    4042#include "ldb_module.h"
    4143
    4244struct rename_context {
    43 
    4445        struct ldb_module *module;
    4546        struct ldb_request *req;
     
    4748        struct ldb_reply *ares;
    4849};
    49 
    50 static struct ldb_message_element *rdn_name_find_attribute(const struct ldb_message *msg, const char *name)
    51 {
    52         int i;
    53 
    54         for (i = 0; i < msg->num_elements; i++) {
    55                 if (ldb_attr_cmp(name, msg->elements[i].name) == 0) {
    56                         return &msg->elements[i];
    57                 }
    58         }
    59 
    60         return NULL;
    61 }
    6250
    6351static int rdn_name_add_callback(struct ldb_request *req,
     
    7260                                        LDB_ERR_OPERATIONS_ERROR);
    7361        }
     62
     63        if (ares->type == LDB_REPLY_REFERRAL) {
     64                return ldb_module_send_referral(ac->req, ares->referral);
     65        }
     66
    7467        if (ares->error != LDB_SUCCESS) {
    7568                return ldb_module_done(ac->req, ares->controls,
     
    9588        const struct ldb_schema_attribute *a;
    9689        const char *rdn_name;
     90        const struct ldb_val *rdn_val_p;
    9791        struct ldb_val rdn_val;
    98         int i, ret;
     92        unsigned int i;
     93        int ret;
    9994
    10095        ldb = ldb_module_get_ctx(module);
    101         ldb_debug(ldb, LDB_DEBUG_TRACE, "rdn_name_add_record");
    10296
    10397        /* do not manipulate our control entries */
     
    121115        rdn_name = ldb_dn_get_rdn_name(msg->dn);
    122116        if (rdn_name == NULL) {
    123                 talloc_free(ac);
    124117                return LDB_ERR_OPERATIONS_ERROR;
    125118        }
    126119       
    127         rdn_val = ldb_val_dup(msg, ldb_dn_get_rdn_val(msg->dn));
    128        
    129         /* Perhaps someone above us tried to set this? */
    130         if ((attribute = rdn_name_find_attribute(msg, "name")) != NULL ) {
    131                 attribute->num_values = 0;
    132         }
    133 
    134         if (ldb_msg_add_value(msg, "name", &rdn_val, NULL) != 0) {
    135                 talloc_free(ac);
    136                 return LDB_ERR_OPERATIONS_ERROR;
    137         }
    138 
    139         attribute = rdn_name_find_attribute(msg, rdn_name);
    140 
     120        rdn_val_p = ldb_dn_get_rdn_val(msg->dn);
     121        if (rdn_val_p == NULL) {
     122                return LDB_ERR_OPERATIONS_ERROR;
     123        }
     124        if (rdn_val_p->length == 0) {
     125                ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!",
     126                                       ldb_dn_get_linearized(req->op.add.message->dn));
     127                return LDB_ERR_INVALID_DN_SYNTAX;
     128        }
     129        rdn_val = ldb_val_dup(msg, rdn_val_p);
     130
     131        /* Perhaps someone above us tried to set this? Then ignore it */
     132        ldb_msg_remove_attr(msg, "name");
     133
     134        ret = ldb_msg_add_value(msg, "name", &rdn_val, NULL);
     135        if (ret != LDB_SUCCESS) {
     136                return ret;
     137        }
     138
     139        a = ldb_schema_attribute_by_name(ldb, rdn_name);
     140        if (a == NULL) {
     141                return LDB_ERR_OPERATIONS_ERROR;
     142        }
     143
     144        attribute = ldb_msg_find_element(msg, rdn_name);
    141145        if (!attribute) {
    142                 if (ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL) != 0) {
    143                         talloc_free(ac);
    144                         return LDB_ERR_OPERATIONS_ERROR;
     146                /* add entry with normalised RDN information if possible */
     147                if (a->name != NULL) {
     148                        ret = ldb_msg_add_value(msg, a->name, &rdn_val, NULL);
     149                } else {
     150                        ret = ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL);
     151                }
     152                if (ret != LDB_SUCCESS) {
     153                        return ret;
    145154                }
    146155        } else {
    147                 a = ldb_schema_attribute_by_name(ldb, rdn_name);
    148 
     156                /* normalise attribute name if possible */
     157                if (a->name != NULL) {
     158                        attribute->name = a->name;
     159                }
     160                /* normalise attribute value */
    149161                for (i = 0; i < attribute->num_values; i++) {
    150                         ret = a->syntax->comparison_fn(ldb, msg,
    151                                         &rdn_val, &attribute->values[i]);
    152                         if (ret == 0) {
     162                        bool matched;
     163                        if (a->syntax->operator_fn) {
     164                                ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a,
     165                                                             &rdn_val, &attribute->values[i], &matched);
     166                                if (ret != LDB_SUCCESS) return ret;
     167                        } else {
     168                                matched = (a->syntax->comparison_fn(ldb, msg,
     169                                                                    &rdn_val, &attribute->values[i]) == 0);
     170                        }
     171                        if (matched) {
    153172                                /* overwrite so it matches in case */
    154173                                attribute->values[i] = rdn_val;
     
    157176                }
    158177                if (i == attribute->num_values) {
    159                         char *rdn_errstring = talloc_asprintf(ac, "RDN mismatch on %s: %s (%.*s) should match one of:",
    160                                                           ldb_dn_get_linearized(msg->dn), rdn_name,
    161                                                           (int)rdn_val.length, (const char *)rdn_val.data);
     178                        char *rdn_errstring = talloc_asprintf(ac,
     179                                "RDN mismatch on %s: %s (%.*s) should match one of:",
     180                                ldb_dn_get_linearized(msg->dn), rdn_name,
     181                                (int)rdn_val.length, (const char *)rdn_val.data);
    162182                        for (i = 0; i < attribute->num_values; i++) {
    163                                 rdn_errstring = talloc_asprintf_append(rdn_errstring, " (%.*s)",
    164                                                                        (int)attribute->values[i].length,
    165                                                                        (const char *)attribute->values[i].data);
     183                                rdn_errstring = talloc_asprintf_append(
     184                                        rdn_errstring, " (%.*s)",
     185                                        (int)attribute->values[i].length,
     186                                        (const char *)attribute->values[i].data);
    166187                        }
    167                         ldb_debug_set(ldb, LDB_DEBUG_FATAL, "%s", rdn_errstring);
    168                         talloc_free(ac);
     188                        ldb_set_errstring(ldb, rdn_errstring);
    169189                        /* Match AD's error here */
    170190                        return LDB_ERR_INVALID_DN_SYNTAX;
     
    197217                                        LDB_ERR_OPERATIONS_ERROR);
    198218        }
     219
     220        if (ares->type == LDB_REPLY_REFERRAL) {
     221                return ldb_module_send_referral(ac->req, ares->referral);
     222        }
     223
    199224        if (ares->error != LDB_SUCCESS) {
    200225                return ldb_module_done(ac->req, ares->controls,
     
    219244        struct ldb_request *mod_req;
    220245        const char *rdn_name;
     246        const struct ldb_val *rdn_val_p;
    221247        struct ldb_val rdn_val;
    222248        struct ldb_message *msg;
     
    229255                goto error;
    230256        }
     257
     258        if (ares->type == LDB_REPLY_REFERRAL) {
     259                return ldb_module_send_referral(ac->req, ares->referral);
     260        }
     261
    231262        if (ares->error != LDB_SUCCESS) {
    232263                return ldb_module_done(ac->req, ares->controls,
     
    250281                goto error;
    251282        }
     283
    252284        rdn_name = ldb_dn_get_rdn_name(ac->req->op.rename.newdn);
    253285        if (rdn_name == NULL) {
    254286                goto error;
    255287        }
    256        
    257         rdn_val = ldb_val_dup(msg, ldb_dn_get_rdn_val(ac->req->op.rename.newdn));
    258        
     288
     289        rdn_val_p = ldb_dn_get_rdn_val(msg->dn);
     290        if (rdn_val_p == NULL) {
     291                goto error;
     292        }
     293        if (rdn_val_p->length == 0) {
     294                ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!",
     295                                       ldb_dn_get_linearized(req->op.rename.olddn));
     296                return ldb_module_done(ac->req, NULL, NULL,
     297                                       LDB_ERR_NAMING_VIOLATION);
     298        }
     299        rdn_val = ldb_val_dup(msg, rdn_val_p);
     300
    259301        if (ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_REPLACE, NULL) != 0) {
    260302                goto error;
     
    279321        talloc_steal(mod_req, msg);
    280322
    281         /* do the mod call */
    282         return ldb_request(ldb, mod_req);
     323        /* go on with the call chain */
     324        return ldb_next_request(ac->module, mod_req);
    283325
    284326error:
    285         return ldb_module_done(ac->req, NULL, NULL,
    286                                                 LDB_ERR_OPERATIONS_ERROR);
     327        return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR);
    287328}
    288329
     
    295336
    296337        ldb = ldb_module_get_ctx(module);
    297         ldb_debug(ldb, LDB_DEBUG_TRACE, "rdn_name_rename");
    298338
    299339        /* do not manipulate our control entries */
     
    321361
    322362        if (ret != LDB_SUCCESS) {
    323                 return LDB_ERR_OPERATIONS_ERROR;
     363                return ret;
    324364        }
    325365
     
    328368}
    329369
    330 const struct ldb_module_ops ldb_rdn_name_module_ops = {
     370static int rdn_name_modify(struct ldb_module *module, struct ldb_request *req)
     371{
     372        struct ldb_context *ldb;
     373        const struct ldb_val *rdn_val_p;
     374
     375        ldb = ldb_module_get_ctx(module);
     376
     377        /* do not manipulate our control entries */
     378        if (ldb_dn_is_special(req->op.mod.message->dn)) {
     379                return ldb_next_request(module, req);
     380        }
     381
     382        rdn_val_p = ldb_dn_get_rdn_val(req->op.mod.message->dn);
     383        if (rdn_val_p == NULL) {
     384                return LDB_ERR_OPERATIONS_ERROR;
     385        }
     386        if (rdn_val_p->length == 0) {
     387                ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!",
     388                                       ldb_dn_get_linearized(req->op.mod.message->dn));
     389                return LDB_ERR_INVALID_DN_SYNTAX;
     390        }
     391
     392        if (ldb_msg_find_element(req->op.mod.message, "distinguishedName")) {
     393                ldb_asprintf_errstring(ldb, "Modify of 'distinguishedName' on %s not permitted, must use 'rename' operation instead",
     394                                       ldb_dn_get_linearized(req->op.mod.message->dn));
     395                return LDB_ERR_CONSTRAINT_VIOLATION;
     396        }
     397
     398        if (ldb_msg_find_element(req->op.mod.message, "name")) {
     399                ldb_asprintf_errstring(ldb, "Modify of 'name' on %s not permitted, must use 'rename' operation instead",
     400                                       ldb_dn_get_linearized(req->op.mod.message->dn));
     401                return LDB_ERR_NOT_ALLOWED_ON_RDN;
     402        }
     403
     404        if (ldb_msg_find_element(req->op.mod.message, ldb_dn_get_rdn_name(req->op.mod.message->dn))) {
     405                ldb_asprintf_errstring(ldb, "Modify of RDN '%s' on %s not permitted, must use 'rename' operation instead",
     406                                       ldb_dn_get_rdn_name(req->op.mod.message->dn), ldb_dn_get_linearized(req->op.mod.message->dn));
     407                return LDB_ERR_NOT_ALLOWED_ON_RDN;
     408        }
     409
     410        /* All OK, they kept their fingers out of the special attributes */
     411        return ldb_next_request(module, req);
     412}
     413
     414static int rdn_name_search(struct ldb_module *module, struct ldb_request *req)
     415{
     416        struct ldb_context *ldb;
     417        const char *rdn_name;
     418        const struct ldb_val *rdn_val_p;
     419
     420        ldb = ldb_module_get_ctx(module);
     421
     422        /* do not manipulate our control entries */
     423        if (ldb_dn_is_special(req->op.search.base)) {
     424                return ldb_next_request(module, req);
     425        }
     426
     427        rdn_name = ldb_dn_get_rdn_name(req->op.search.base);
     428        rdn_val_p = ldb_dn_get_rdn_val(req->op.search.base);
     429        if ((rdn_name != NULL) && (rdn_val_p == NULL)) {
     430                return LDB_ERR_OPERATIONS_ERROR;
     431        }
     432        if ((rdn_val_p != NULL) && (rdn_val_p->length == 0)) {
     433                ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!",
     434                                       ldb_dn_get_linearized(req->op.search.base));
     435                return LDB_ERR_INVALID_DN_SYNTAX;
     436        }
     437
     438        return ldb_next_request(module, req);
     439}
     440
     441static const struct ldb_module_ops ldb_rdn_name_module_ops = {
    331442        .name              = "rdn_name",
    332443        .add               = rdn_name_add,
     444        .modify            = rdn_name_modify,
    333445        .rename            = rdn_name_rename,
     446        .search            = rdn_name_search
    334447};
     448
     449int ldb_rdn_name_init(const char *version)
     450{
     451        LDB_MODULE_CHECK_VERSION(version);
     452        return ldb_register_module(&ldb_rdn_name_module_ops);
     453}
  • vendor/current/source4/lib/ldb/modules/skel.c

    r414 r740  
    1 /* 
     1/*
    22   ldb database library
    33
     
    77     ** library. This does NOT imply that all of Samba is released
    88     ** under the LGPL
    9    
     9
    1010   This library is free software; you can redistribute it and/or
    1111   modify it under the terms of the GNU Lesser General Public
     
    3232 */
    3333
     34#include "replace.h"
     35#include "system/filesys.h"
     36#include "system/time.h"
    3437#include "ldb_module.h"
    3538
     
    124127}
    125128
    126 const struct ldb_module_ops ldb_skel_module_ops = {
     129static const struct ldb_module_ops ldb_skel_module_ops = {
    127130        .name              = "skel",
    128131        .init_context      = skel_init,
     
    137140        .del_transaction   = skel_del_trans,
    138141};
     142
     143int ldb_skel_init(const char *version)
     144{
     145        LDB_MODULE_CHECK_VERSION(version);
     146        return ldb_register_module(&ldb_skel_module_ops);
     147}
  • vendor/current/source4/lib/ldb/modules/sort.c

    r414 r740  
    3232 */
    3333
     34#include "replace.h"
     35#include "system/filesys.h"
     36#include "system/time.h"
    3437#include "ldb_module.h"
    3538
     
    4548        struct ldb_module *module;
    4649
    47         char *attributeName;
    48         char *orderingRule;
     50        const char *attributeName;
     51        const char *orderingRule;
    4952        int reverse;
    5053
     
    5255        struct ldb_message **msgs;
    5356        char **referrals;
    54         int num_msgs;
    55         int num_refs;
     57        unsigned int num_msgs;
     58        unsigned int num_refs;
    5659
    5760        const struct ldb_schema_attribute *a;
     
    6366        struct ldb_control **controls;
    6467        struct ldb_sort_resp_control *resp;
    65         int i;
     68        unsigned int i;
    6669
    6770        if (*ctrls) {
     
    138141        struct ldb_context *ldb;
    139142        struct ldb_reply *ares;
    140         int i, ret;
     143        unsigned int i;
     144        int ret;
    141145
    142146        ldb = ldb_module_get_ctx(ac->module);
     
    145149        ac->sort_result = 0;
    146150
    147         ldb_qsort(ac->msgs, ac->num_msgs,
    148                   sizeof(struct ldb_message *),
    149                   ac, (ldb_qsort_cmp_fn_t)sort_compare);
     151        LDB_TYPESAFE_QSORT(ac->msgs, ac->num_msgs, ac, sort_compare);
    150152
    151153        if (ac->sort_result != LDB_SUCCESS) {
     
    316318                                        req);
    317319        if (ret != LDB_SUCCESS) {
    318                 return LDB_ERR_OPERATIONS_ERROR;
     320                return ret;
    319321        }
    320322
     
    322324        /* we do not need to replace them later as we
    323325         * are keeping the original req intact */
    324         if (!save_controls(control, down_req, &saved_controls)) {
     326        if (!ldb_save_controls(control, down_req, &saved_controls)) {
    325327                return LDB_ERR_OPERATIONS_ERROR;
    326328        }
     
    346348}
    347349
    348 const struct ldb_module_ops ldb_server_sort_module_ops = {
     350static const struct ldb_module_ops ldb_server_sort_module_ops = {
    349351        .name              = "server_sort",
    350352        .search            = server_sort_search,
    351353        .init_context      = server_sort_init
    352354};
     355
     356int ldb_server_sort_init(const char *version)
     357{
     358        LDB_MODULE_CHECK_VERSION(version);
     359        return ldb_register_module(&ldb_server_sort_module_ops);
     360}
  • vendor/current/source4/lib/ldb/nssldb/ldb-nss.c

    r414 r740  
    192192        size_t bufpos;
    193193        size_t lsize;
    194         int i;
     194        unsigned int i;
    195195
    196196        bufpos = 0;
     
    281281{
    282282        NSS_STATUS ret;
    283         int i;
     283        unsigned int i;
    284284
    285285        for (i = 0; i < grlist->count; i++) {
  • vendor/current/source4/lib/ldb/pyldb.c

    r414 r740  
    66   Copyright (C) 2005,2006 Tim Potter <tpot@samba.org>
    77   Copyright (C) 2006 Simo Sorce <idra@samba.org>
    8    Copyright (C) 2007-2009 Jelmer Vernooij <jelmer@samba.org>
    9    Copyright (C) 2009 Matthias Dieter Wallnöfer
    10 
    11         ** NOTE! The following LGPL license applies to the ldb
    12         ** library. This does NOT imply that all of Samba is released
    13         ** under the LGPL
     8   Copyright (C) 2007-2010 Jelmer Vernooij <jelmer@samba.org>
     9   Copyright (C) 2009-2010 Matthias Dieter Wallnöfer
     10
     11    ** NOTE! The following LGPL license applies to the ldb
     12    ** library. This does NOT imply that all of Samba is released
     13    ** under the LGPL
    1414
    1515   This library is free software; you can redistribute it and/or
     
    2727*/
    2828
    29 #include "replace.h"
     29#include <Python.h>
     30#include <pytalloc.h>
    3031#include "ldb_private.h"
    31 #include <Python.h>
    3232#include "pyldb.h"
     33
     34void initldb(void);
     35static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg);
     36static PyObject *PyExc_LdbError;
     37
     38staticforward PyTypeObject PyLdbControl;
     39staticforward PyTypeObject PyLdbResult;
     40staticforward PyTypeObject PyLdbMessage;
     41staticforward PyTypeObject PyLdbModule;
     42staticforward PyTypeObject PyLdbDn;
     43staticforward PyTypeObject PyLdb;
     44staticforward PyTypeObject PyLdbMessageElement;
     45staticforward PyTypeObject PyLdbTree;
     46static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx);
     47static PyObject *PyLdbModule_FromModule(struct ldb_module *mod);
     48static struct ldb_message_element *PyObject_AsMessageElement(
     49                                                      TALLOC_CTX *mem_ctx,
     50                                                      PyObject *set_obj,
     51                                                      int flags,
     52                                                      const char *attr_name);
    3353
    3454/* There's no Py_ssize_t in 2.4, apparently */
     
    4363#endif
    4464
     65#define SIGN(a) (((a) == 0)?0:((a) < 0?-1:1))
     66
     67
     68
     69static PyObject *py_ldb_control_str(PyLdbControlObject *self)
     70{
     71        if (self->data != NULL) {
     72                char* control = ldb_control_to_string(self->mem_ctx, self->data);
     73                if (control == NULL) {
     74                        PyErr_NoMemory();
     75                        return NULL;
     76                }
     77                return PyString_FromString(control);
     78        } else {
     79                return PyString_FromFormat("ldb control");
     80        }
     81}
     82
     83static void py_ldb_control_dealloc(PyLdbControlObject *self)
     84{
     85        if (self->mem_ctx != NULL) {
     86                talloc_free(self->mem_ctx);
     87        }
     88        self->ob_type->tp_free(self);
     89}
     90
     91static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self)
     92{
     93        return PyString_FromString(self->data->oid);
     94}
     95
     96static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self)
     97{
     98        return PyBool_FromLong(self->data->critical);
     99}
     100
     101static PyObject *py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure)
     102{
     103        if (PyObject_IsTrue(value)) {
     104                self->data->critical = true;
     105        } else {
     106                self->data->critical = false;
     107        }
     108        return 0;
     109}
     110
     111static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
     112{
     113        char *data = NULL;
     114        const char *array[2];
     115        const char * const kwnames[] = { "ldb", "data", NULL };
     116        struct ldb_control *parsed_controls;
     117        PyLdbControlObject *ret;
     118        PyObject *py_ldb;
     119        TALLOC_CTX *mem_ctx;
     120        struct ldb_context *ldb_ctx;
     121
     122        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
     123                                         discard_const_p(char *, kwnames),
     124                                         &py_ldb, &data))
     125                return NULL;
     126
     127        mem_ctx = talloc_new(NULL);
     128        if (mem_ctx == NULL) {
     129                PyErr_NoMemory();
     130                return NULL;
     131        }
     132
     133        ldb_ctx = PyLdb_AsLdbContext(py_ldb);
     134        parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data);
     135
     136        if (!parsed_controls) {
     137                talloc_free(mem_ctx);
     138                PyErr_SetString(PyExc_ValueError, "unable to parse control string");
     139                return NULL;
     140        }
     141
     142        ret = PyObject_New(PyLdbControlObject, type);
     143        if (ret == NULL) {
     144                PyErr_NoMemory();
     145                talloc_free(mem_ctx);
     146                return NULL;
     147        }
     148
     149        ret->mem_ctx = mem_ctx;
     150
     151        ret->data = talloc_steal(mem_ctx, parsed_controls);
     152        if (ret->data == NULL) {
     153                Py_DECREF(ret);
     154                PyErr_NoMemory();
     155                talloc_free(mem_ctx);
     156                return NULL;
     157        }
     158
     159        return (PyObject *)ret;
     160}
     161
     162static PyGetSetDef py_ldb_control_getset[] = {
     163        { discard_const_p(char, "oid"), (getter)py_ldb_control_get_oid, NULL, NULL },
     164        { discard_const_p(char, "critical"), (getter)py_ldb_control_get_critical, (setter)py_ldb_control_set_critical, NULL },
     165        { NULL }
     166};
     167
     168static PyTypeObject PyLdbControl = {
     169        .tp_name = "ldb.control",
     170        .tp_dealloc = (destructor)py_ldb_control_dealloc,
     171        .tp_getattro = PyObject_GenericGetAttr,
     172        .tp_basicsize = sizeof(PyLdbControlObject),
     173        .tp_getset = py_ldb_control_getset,
     174        .tp_doc = "LDB control.",
     175        .tp_str = (reprfunc)py_ldb_control_str,
     176        .tp_new = py_ldb_control_new,
     177        .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
     178};
     179
    45180static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
    46181{
     
    49184
    50185        PyErr_SetObject(error,
    51                                         Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
    52                                   ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
    53 }
    54 
    55 static PyObject *PyExc_LdbError;
    56 
    57 PyAPI_DATA(PyTypeObject) PyLdbMessage;
    58 PyAPI_DATA(PyTypeObject) PyLdbModule;
    59 PyAPI_DATA(PyTypeObject) PyLdbDn;
    60 PyAPI_DATA(PyTypeObject) PyLdb;
    61 PyAPI_DATA(PyTypeObject) PyLdbMessageElement;
    62 PyAPI_DATA(PyTypeObject) PyLdbTree;
    63 
    64 static PyObject *PyObject_FromLdbValue(struct ldb_context *ldb_ctx,
    65                                                            struct ldb_message_element *el,
    66                                                            struct ldb_val *val)
    67 {
    68         struct ldb_val new_val;
    69         TALLOC_CTX *mem_ctx = talloc_new(NULL);
    70         PyObject *ret;
    71 
    72         new_val = *val;
    73 
    74         ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
    75 
    76         talloc_free(mem_ctx);
    77 
    78         return ret;
     186                        Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
     187                                      ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
     188}
     189
     190static PyObject *PyObject_FromLdbValue(struct ldb_val *val)
     191{
     192        return PyString_FromStringAndSize((const char *)val->data, val->length);
    79193}
    80194
    81195/**
    82  * Obtain a ldb DN from a Python object.
     196 * Create a Python object from a ldb_result.
    83197 *
    84  * @param mem_ctx Memory context
    85  * @param object Python object
    86  * @param ldb_ctx LDB context
    87  * @return Whether or not the conversion succeeded
     198 * @param result LDB result to convert
     199 * @return Python object with converted result (a list object)
    88200 */
    89 bool PyObject_AsDn(TALLOC_CTX *mem_ctx, PyObject *object,
    90                    struct ldb_context *ldb_ctx, struct ldb_dn **dn)
    91 {
    92         struct ldb_dn *odn;
    93 
    94         if (ldb_ctx != NULL && PyString_Check(object)) {
    95                 odn = ldb_dn_new(mem_ctx, ldb_ctx, PyString_AsString(object));
    96                 *dn = odn;
    97                 return true;
    98         }
    99 
    100         if (PyLdbDn_Check(object)) {
    101                 *dn = PyLdbDn_AsDn(object);
    102                 return true;
    103         }
    104 
    105         PyErr_SetString(PyExc_TypeError, "Expected DN");
    106         return false;
     201static PyObject *PyLdbControl_FromControl(struct ldb_control *control)
     202{
     203        TALLOC_CTX *ctl_ctx = talloc_new(NULL);
     204        PyLdbControlObject *ctrl;
     205        if (ctl_ctx == NULL) {
     206                PyErr_NoMemory();
     207                return NULL;
     208        }
     209
     210        ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0);
     211        if (ctrl == NULL) {
     212                PyErr_NoMemory();
     213                return NULL;
     214        }
     215        ctrl->mem_ctx = ctl_ctx;
     216        ctrl->data = talloc_steal(ctrl->mem_ctx, control);
     217        if (ctrl->data == NULL) {
     218                Py_DECREF(ctrl);
     219                PyErr_NoMemory();
     220                return NULL;
     221        }
     222        return (PyObject*) ctrl;
    107223}
    108224
     
    115231static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
    116232{
    117         PyObject *ret;
    118         int i;
     233        PyLdbResultObject *ret;
     234        PyObject *list, *controls, *referals;
     235        Py_ssize_t i;
     236
    119237        if (result == NULL) {
    120238                Py_RETURN_NONE;
    121         }
    122         ret = PyList_New(result->count);
     239        }
     240
     241        ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0);
     242        if (ret == NULL) {
     243                PyErr_NoMemory();
     244                return NULL;
     245        }
     246
     247        list = PyList_New(result->count);
     248        if (list == NULL) {
     249                PyErr_NoMemory();
     250                Py_DECREF(ret);
     251                return NULL;
     252        }
     253
    123254        for (i = 0; i < result->count; i++) {
    124                 PyList_SetItem(ret, i, PyLdbMessage_FromMessage(result->msgs[i])
    125                 );
    126         }
    127         return ret;
     255                PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i]));
     256        }
     257
     258        ret->mem_ctx = talloc_new(NULL);
     259        if (ret->mem_ctx == NULL) {
     260                Py_DECREF(list);
     261                Py_DECREF(ret);
     262                PyErr_NoMemory();
     263                return NULL;
     264        }
     265
     266        ret->msgs = list;
     267
     268        if (result->controls) {
     269                controls = PyList_New(1);
     270                if (controls == NULL) {
     271                        Py_DECREF(ret);
     272                        PyErr_NoMemory();
     273                        return NULL;
     274                }
     275                for (i=0; result->controls[i]; i++) {
     276                        PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]);
     277                        if (ctrl == NULL) {
     278                                Py_DECREF(ret);
     279                                Py_DECREF(controls);
     280                                PyErr_NoMemory();
     281                                return NULL;
     282                        }
     283                        PyList_SetItem(controls, i, ctrl);
     284                }
     285        } else {
     286                /*
     287                 * No controls so we keep an empty list
     288                 */
     289                controls = PyList_New(0);
     290                if (controls == NULL) {
     291                        Py_DECREF(ret);
     292                        PyErr_NoMemory();
     293                        return NULL;
     294                }
     295        }
     296
     297        ret->controls = controls;
     298
     299        i = 0;
     300
     301        while (result->refs && result->refs[i]) {
     302                i++;
     303        }
     304
     305        referals = PyList_New(i);
     306        if (referals == NULL) {
     307                Py_DECREF(ret);
     308                PyErr_NoMemory();
     309                return NULL;
     310        }
     311
     312        for (i = 0;result->refs && result->refs[i]; i++) {
     313                PyList_SetItem(referals, i, PyString_FromString(result->refs[i]));
     314        }
     315        ret->referals = referals;
     316        return (PyObject *)ret;
    128317}
    129318
     
    137326 */
    138327static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx,
    139                                                                                            PyObject *obj)
     328                                               PyObject *obj)
    140329{
    141330        struct ldb_result *res;
    142         int i;
     331        Py_ssize_t i;
    143332
    144333        if (obj == Py_None)
     
    296485                "S.canonical_ex_str() -> string\n"
    297486                "Canonical version of this DN (like a posix path, with terminating newline)." },
    298         { "check_special", (PyCFunction)py_ldb_dn_is_special, METH_VARARGS,
    299                 NULL },
    300487        { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
    301488                "S.parent() -> dn\n"
     
    308495                "Add a base DN to this DN." },
    309496        { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
    310                 NULL },
     497                "S.check_special(name) -> bool\n\n"
     498                "Check if name is a special DN name"},
    311499        { NULL }
    312500};
     
    366554
    367555        ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
    368 
    369         if (ret == NULL || !ldb_dn_validate(ret)) {
     556        if (!ldb_dn_validate(ret)) {
    370557                talloc_free(mem_ctx);
    371558                PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
     
    384571}
    385572
    386 PyObject *PyLdbDn_FromDn(struct ldb_dn *dn)
    387 {
    388         PyLdbDnObject *py_ret;
    389 
    390         if (dn == NULL) {
    391                 Py_RETURN_NONE;
    392         }
    393 
    394         py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
    395         if (py_ret == NULL) {
    396                 PyErr_NoMemory();
    397                 return NULL;
    398         }
    399         py_ret->mem_ctx = talloc_new(NULL);
    400         py_ret->dn = talloc_reference(py_ret->mem_ctx, dn);
    401         return (PyObject *)py_ret;
    402 }
    403 
    404573static void py_ldb_dn_dealloc(PyLdbDnObject *self)
    405574{
    406575        talloc_free(self->mem_ctx);
    407         self->ob_type->tp_free(self);
    408 }
    409 
    410 PyTypeObject PyLdbDn = {
    411         .tp_name = "Dn",
     576        PyObject_Del(self);
     577}
     578
     579static PyTypeObject PyLdbDn = {
     580        .tp_name = "ldb.Dn",
    412581        .tp_methods = py_ldb_dn_methods,
    413582        .tp_str = (reprfunc)py_ldb_dn_get_linearized,
     
    418587        .tp_new = py_ldb_dn_new,
    419588        .tp_dealloc = (destructor)py_ldb_dn_dealloc,
    420         .tp_basicsize = sizeof(PyLdbObject),
     589        .tp_basicsize = sizeof(PyLdbDnObject),
    421590        .tp_flags = Py_TPFLAGS_DEFAULT,
    422591};
     
    475644{
    476645        PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_commit(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
     646        Py_RETURN_NONE;
     647}
     648
     649static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self)
     650{
     651        PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_prepare_commit(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
    477652        Py_RETURN_NONE;
    478653}
     
    529704
    530705static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list,
    531                                                                                 const char *paramname)
     706                                        const char *paramname)
    532707{
    533708        const char **ret;
    534         int i;
     709        Py_ssize_t i;
    535710        if (!PyList_Check(list)) {
    536711                PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
     
    538713        }
    539714        ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
     715        if (ret == NULL) {
     716                PyErr_NoMemory();
     717                return NULL;
     718        }
     719
    540720        for (i = 0; i < PyList_Size(list); i++) {
    541721                PyObject *item = PyList_GetItem(list, i);
     
    545725                }
    546726                ret[i] = talloc_strndup(ret, PyString_AsString(item),
    547                                                            PyString_Size(item));
     727                                        PyString_Size(item));
    548728        }
    549729        ret[i] = NULL;
     
    642822{
    643823        PyObject *py_msg;
    644         int ret;
    645         if (!PyArg_ParseTuple(args, "O", &py_msg))
    646                 return NULL;
    647 
    648         if (!PyLdbMessage_Check(py_msg)) {
    649                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
    650                 return NULL;
    651         }
    652 
    653         ret = ldb_modify(PyLdb_AsLdbContext(self), PyLdbMessage_AsMessage(py_msg));
    654         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
    655 
    656         Py_RETURN_NONE;
    657 }
    658 
    659 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args)
    660 {
    661         PyObject *py_msg;
    662         int ret;
    663         Py_ssize_t dict_pos, msg_pos;
    664         struct ldb_message_element *msgel;
    665         struct ldb_message *msg;
     824        PyObject *py_controls = Py_None;
    666825        struct ldb_context *ldb_ctx;
    667826        struct ldb_request *req;
    668         PyObject *key, *value;
    669         PyObject *py_controls = Py_None;
     827        struct ldb_control **parsed_controls;
     828        struct ldb_message *msg;
     829        int ret;
    670830        TALLOC_CTX *mem_ctx;
    671         struct ldb_control **parsed_controls;
    672 
    673         if (!PyArg_ParseTuple(args, "O|O", &py_msg, &py_controls ))
    674                 return NULL;
     831
     832        if (!PyArg_ParseTuple(args, "O|O", &py_msg, &py_controls))
     833                return NULL;
     834
     835        mem_ctx = talloc_new(NULL);
     836        if (mem_ctx == NULL) {
     837                PyErr_NoMemory();
     838                return NULL;
     839        }
    675840        ldb_ctx = PyLdb_AsLdbContext(self);
    676841
    677         mem_ctx = talloc_new(NULL);
    678842        if (py_controls == Py_None) {
    679843                parsed_controls = NULL;
    680844        } else {
    681                 const char **controls = PyList_AsStringList(ldb_ctx, py_controls, "controls");
    682                 parsed_controls = ldb_parse_control_strings(ldb_ctx, ldb_ctx, controls);
     845                const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
     846                parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
    683847                talloc_free(controls);
    684848        }
    685         if (PyDict_Check(py_msg)) {
    686                 PyObject *dn_value = PyDict_GetItemString(py_msg, "dn");
    687                 msg = ldb_msg_new(mem_ctx);
    688                 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_msg));
    689                 msg_pos = dict_pos = 0;
    690                 if (dn_value) {
    691                         if (!PyObject_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
    692                                 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
    693                                 talloc_free(mem_ctx);
    694                                 return NULL;
    695                         }
    696                         if (msg->dn == NULL) {
    697                                 PyErr_SetString(PyExc_TypeError, "dn set but not found");
    698                                 talloc_free(mem_ctx);
    699                                 return NULL;
    700                         }
    701                 }
    702 
    703                 while (PyDict_Next(py_msg, &dict_pos, &key, &value)) {
    704                         char *key_str = PyString_AsString(key);
    705                         if (strcmp(key_str, "dn") != 0) {
    706                                 msgel = PyObject_AsMessageElement(msg->elements, value, 0, key_str);
    707                                 if (msgel == NULL) {
    708                                         PyErr_SetString(PyExc_TypeError, "unable to import element");
    709                                         talloc_free(mem_ctx);
    710                                         return NULL;
    711                                 }
    712                                 memcpy(&msg->elements[msg_pos], msgel, sizeof(*msgel));
    713                                 msg_pos++;
    714                         }
    715                 }
    716 
    717                 if (msg->dn == NULL) {
    718                         PyErr_SetString(PyExc_TypeError, "no dn set");
    719                         talloc_free(mem_ctx);
    720                         return NULL;
    721                 }
    722 
    723                 msg->num_elements = msg_pos;
    724         } else {
    725                 msg = PyLdbMessage_AsMessage(py_msg);
    726         }
    727        
     849
     850        if (!PyLdbMessage_Check(py_msg)) {
     851                PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
     852                talloc_free(mem_ctx);
     853                return NULL;
     854        }
     855        msg = PyLdbMessage_AsMessage(py_msg);
     856
    728857        ret = ldb_msg_sanity_check(ldb_ctx, msg);
    729         if (ret != LDB_SUCCESS) {
    730                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
     858        if (ret != LDB_SUCCESS) {
     859                PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
    731860                talloc_free(mem_ctx);
    732861                return NULL;
    733         }
    734 
    735         ret = ldb_build_add_req(&req, ldb_ctx, ldb_ctx,
    736                                         msg,
    737                                         parsed_controls,
    738                                         NULL,
    739                                         ldb_op_default_callback,
    740                                         NULL);
    741 
     862        }
     863
     864        ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
     865                                NULL, ldb_op_default_callback, NULL);
    742866        if (ret != LDB_SUCCESS) {
    743867                PyErr_SetString(PyExc_TypeError, "failed to build request");
     
    746870        }
    747871
    748         /* do request and autostart a transaction */
     872        /* do request and autostart a transaction */
    749873        /* Then let's LDB handle the message error in case of pb as they are meaningful */
    750874
    751         ret = ldb_transaction_start(ldb_ctx);
    752         if (ret != LDB_SUCCESS) {
    753                 talloc_free(req);
     875        ret = ldb_transaction_start(ldb_ctx);
     876        if (ret != LDB_SUCCESS) {
    754877                talloc_free(mem_ctx);
    755                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
    756         }
    757 
    758         ret = ldb_request(ldb_ctx, req);
    759         if (ret == LDB_SUCCESS) {
    760                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
    761         }
    762 
     878                PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
     879        }
     880
     881        ret = ldb_request(ldb_ctx, req);
    763882        if (ret == LDB_SUCCESS) {
    764                 ret = ldb_transaction_commit(ldb_ctx);
    765         } else {
    766                 ldb_transaction_cancel(ldb_ctx);
     883                        ret = ldb_wait(req->handle, LDB_WAIT_ALL);
     884        }
     885
     886        if (ret == LDB_SUCCESS) {
     887                ret = ldb_transaction_commit(ldb_ctx);
     888        } else {
     889                ldb_transaction_cancel(ldb_ctx);
    767890                if (ldb_ctx->err_string == NULL) {
    768891                        /* no error string was setup by the backend */
     
    770893                }
    771894        }
    772         talloc_free(req);
     895
    773896        talloc_free(mem_ctx);
    774         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
     897        PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
     898
     899        Py_RETURN_NONE;
     900}
     901
     902
     903/**
     904 * Obtain a ldb message from a Python Dictionary object.
     905 *
     906 * @param mem_ctx Memory context
     907 * @param py_obj Python Dictionary object
     908 * @param ldb_ctx LDB context
     909 * @param mod_flags Flags to be set on every message element
     910 * @return ldb_message on success or NULL on failure
     911 */
     912static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
     913                                            PyObject *py_obj,
     914                                            struct ldb_context *ldb_ctx,
     915                                            unsigned int mod_flags)
     916{
     917        struct ldb_message *msg;
     918        unsigned int msg_pos = 0;
     919        Py_ssize_t dict_pos = 0;
     920        PyObject *key, *value;
     921        struct ldb_message_element *msg_el;
     922        PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
     923
     924        msg = ldb_msg_new(mem_ctx);
     925        msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
     926
     927        if (dn_value) {
     928                if (!PyObject_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
     929                        PyErr_SetString(PyExc_TypeError, "unable to import dn object");
     930                        return NULL;
     931                }
     932                if (msg->dn == NULL) {
     933                        PyErr_SetString(PyExc_TypeError, "dn set but not found");
     934                        return NULL;
     935                }
     936        } else {
     937                PyErr_SetString(PyExc_TypeError, "no dn set");
     938                return NULL;
     939        }
     940
     941        while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
     942                char *key_str = PyString_AsString(key);
     943                if (strcmp(key_str, "dn") != 0) {
     944                        msg_el = PyObject_AsMessageElement(msg->elements, value,
     945                                                           mod_flags, key_str);
     946                        if (msg_el == NULL) {
     947                                PyErr_SetString(PyExc_TypeError, "unable to import element");
     948                                return NULL;
     949                        }
     950                        memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
     951                        msg_pos++;
     952                }
     953        }
     954
     955        msg->num_elements = msg_pos;
     956
     957        return msg;
     958}
     959
     960static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args)
     961{
     962        PyObject *py_obj;
     963        int ret;
     964        struct ldb_context *ldb_ctx;
     965        struct ldb_request *req;
     966        struct ldb_message *msg = NULL;
     967        PyObject *py_controls = Py_None;
     968        TALLOC_CTX *mem_ctx;
     969        struct ldb_control **parsed_controls;
     970
     971        if (!PyArg_ParseTuple(args, "O|O", &py_obj, &py_controls ))
     972                return NULL;
     973
     974        mem_ctx = talloc_new(NULL);
     975        if (mem_ctx == NULL) {
     976                PyErr_NoMemory();
     977                return NULL;
     978        }
     979        ldb_ctx = PyLdb_AsLdbContext(self);
     980
     981        if (py_controls == Py_None) {
     982                parsed_controls = NULL;
     983        } else {
     984                const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
     985                parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
     986                talloc_free(controls);
     987        }
     988
     989        if (PyLdbMessage_Check(py_obj)) {
     990                msg = PyLdbMessage_AsMessage(py_obj);
     991        } else if (PyDict_Check(py_obj)) {
     992                msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
     993        } else {
     994                PyErr_SetString(PyExc_TypeError,
     995                                "Dictionary or LdbMessage object expected!");
     996        }
     997
     998        if (!msg) {
     999                /* we should have a PyErr already set */
     1000                talloc_free(mem_ctx);
     1001                return NULL;
     1002        }
     1003
     1004        ret = ldb_msg_sanity_check(ldb_ctx, msg);
     1005        if (ret != LDB_SUCCESS) {
     1006                PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
     1007                talloc_free(mem_ctx);
     1008                return NULL;
     1009        }
     1010
     1011        ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
     1012                                NULL, ldb_op_default_callback, NULL);
     1013        if (ret != LDB_SUCCESS) {
     1014                PyErr_SetString(PyExc_TypeError, "failed to build request");
     1015                talloc_free(mem_ctx);
     1016                return NULL;
     1017        }
     1018
     1019        /* do request and autostart a transaction */
     1020        /* Then let's LDB handle the message error in case of pb as they are meaningful */
     1021
     1022        ret = ldb_transaction_start(ldb_ctx);
     1023        if (ret != LDB_SUCCESS) {
     1024                talloc_free(mem_ctx);
     1025                PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
     1026        }
     1027
     1028        ret = ldb_request(ldb_ctx, req);
     1029        if (ret == LDB_SUCCESS) {
     1030                        ret = ldb_wait(req->handle, LDB_WAIT_ALL);
     1031        }
     1032
     1033        if (ret == LDB_SUCCESS) {
     1034                        ret = ldb_transaction_commit(ldb_ctx);
     1035        } else {
     1036                ldb_transaction_cancel(ldb_ctx);
     1037                if (ldb_ctx->err_string == NULL) {
     1038                        /* no error string was setup by the backend */
     1039                        ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret);
     1040                }
     1041        }
     1042
     1043        talloc_free(mem_ctx);
     1044        PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
    7751045
    7761046        Py_RETURN_NONE;
     
    7821052        struct ldb_dn *dn;
    7831053        int ret;
    784         struct ldb_context *ldb;
    785         if (!PyArg_ParseTuple(args, "O", &py_dn))
    786                 return NULL;
    787 
    788         ldb = PyLdb_AsLdbContext(self);
    789 
    790         if (!PyObject_AsDn(NULL, py_dn, ldb, &dn))
    791                 return NULL;
    792 
    793         ret = ldb_delete(ldb, dn);
    794         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
     1054        struct ldb_context *ldb_ctx;
     1055        struct ldb_request *req;
     1056        PyObject *py_controls = Py_None;
     1057        TALLOC_CTX *mem_ctx;
     1058        struct ldb_control **parsed_controls;
     1059
     1060        if (!PyArg_ParseTuple(args, "O|O", &py_dn, &py_controls))
     1061                return NULL;
     1062
     1063        mem_ctx = talloc_new(NULL);
     1064        if (mem_ctx == NULL) {
     1065                PyErr_NoMemory();
     1066                return NULL;
     1067        }
     1068        ldb_ctx = PyLdb_AsLdbContext(self);
     1069
     1070        if (py_controls == Py_None) {
     1071                parsed_controls = NULL;
     1072        } else {
     1073                const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
     1074                parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
     1075                talloc_free(controls);
     1076        }
     1077
     1078        if (!PyObject_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
     1079                talloc_free(mem_ctx);
     1080                return NULL;
     1081        }
     1082
     1083        ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
     1084                                NULL, ldb_op_default_callback, NULL);
     1085        if (ret != LDB_SUCCESS) {
     1086                PyErr_SetString(PyExc_TypeError, "failed to build request");
     1087                talloc_free(mem_ctx);
     1088                return NULL;
     1089        }
     1090
     1091        /* do request and autostart a transaction */
     1092        /* Then let's LDB handle the message error in case of pb as they are meaningful */
     1093
     1094        ret = ldb_transaction_start(ldb_ctx);
     1095        if (ret != LDB_SUCCESS) {
     1096                talloc_free(mem_ctx);
     1097                PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
     1098        }
     1099
     1100        ret = ldb_request(ldb_ctx, req);
     1101        if (ret == LDB_SUCCESS) {
     1102                ret = ldb_wait(req->handle, LDB_WAIT_ALL);
     1103        }
     1104
     1105        if (ret == LDB_SUCCESS) {
     1106                ret = ldb_transaction_commit(ldb_ctx);
     1107        } else {
     1108                ldb_transaction_cancel(ldb_ctx);
     1109                if (ldb_ctx->err_string == NULL) {
     1110                        /* no error string was setup by the backend */
     1111                        ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret);
     1112                }
     1113        }
     1114
     1115        talloc_free(mem_ctx);
     1116        PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
    7951117
    7961118        Py_RETURN_NONE;
     
    8041126        struct ldb_context *ldb;
    8051127        TALLOC_CTX *mem_ctx;
    806         if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
    807                 return NULL;
     1128        PyObject *py_controls = Py_None;
     1129        struct ldb_control **parsed_controls;
     1130        struct ldb_context *ldb_ctx;
     1131        struct ldb_request *req;
     1132
     1133        ldb_ctx = PyLdb_AsLdbContext(self);
     1134
     1135        if (!PyArg_ParseTuple(args, "OO|O", &py_dn1, &py_dn2, &py_controls))
     1136                return NULL;
     1137
    8081138
    8091139        mem_ctx = talloc_new(NULL);
     
    8131143        }
    8141144        ldb = PyLdb_AsLdbContext(self);
     1145
     1146        if (py_controls == Py_None) {
     1147                parsed_controls = NULL;
     1148        } else {
     1149                const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
     1150                parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
     1151                talloc_free(controls);
     1152        }
     1153
     1154
    8151155        if (!PyObject_AsDn(mem_ctx, py_dn1, ldb, &dn1)) {
    8161156                talloc_free(mem_ctx);
     
    8231163        }
    8241164
    825         ret = ldb_rename(ldb, dn1, dn2);
     1165        ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
     1166                                NULL, ldb_op_default_callback, NULL);
     1167        if (ret != LDB_SUCCESS) {
     1168                PyErr_SetString(PyExc_TypeError, "failed to build request");
     1169                talloc_free(mem_ctx);
     1170                return NULL;
     1171        }
     1172
     1173        /* do request and autostart a transaction */
     1174        /* Then let's LDB handle the message error in case of pb as they are meaningful */
     1175
     1176        ret = ldb_transaction_start(ldb_ctx);
     1177        if (ret != LDB_SUCCESS) {
     1178                talloc_free(mem_ctx);
     1179                PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
     1180        }
     1181
     1182        ret = ldb_request(ldb_ctx, req);
     1183        if (ret == LDB_SUCCESS) {
     1184                ret = ldb_wait(req->handle, LDB_WAIT_ALL);
     1185        }
     1186
     1187        if (ret == LDB_SUCCESS) {
     1188                ret = ldb_transaction_commit(ldb_ctx);
     1189        } else {
     1190                ldb_transaction_cancel(ldb_ctx);
     1191                if (ldb_ctx->err_string == NULL) {
     1192                        /* no error string was setup by the backend */
     1193                        ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret);
     1194                }
     1195        }
     1196
    8261197        talloc_free(mem_ctx);
    827         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
     1198        PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
    8281199
    8291200        Py_RETURN_NONE;
     
    8691240
    8701241
    871 static PyObject *py_ldb_write_ldif(PyLdbMessageObject *self, PyObject *args)
     1242static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
    8721243{
    8731244        int changetype;
     
    9381309static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
    9391310{
     1311        int ldb_ret;
    9401312        PyObject *py_msg_old;
    9411313        PyObject *py_msg_new;
    9421314        struct ldb_message *diff;
     1315        struct ldb_context *ldb;
    9431316        PyObject *py_ret;
    9441317
     
    9561329        }
    9571330
    958         diff = ldb_msg_diff(PyLdb_AsLdbContext(self), PyLdbMessage_AsMessage(py_msg_old), PyLdbMessage_AsMessage(py_msg_new));
    959         if (diff == NULL)
    960                 return NULL;
     1331        ldb = PyLdb_AsLdbContext(self);
     1332        ldb_ret = ldb_msg_difference(ldb, ldb,
     1333                                     PyLdbMessage_AsMessage(py_msg_old),
     1334                                     PyLdbMessage_AsMessage(py_msg_new),
     1335                                     &diff);
     1336        if (ldb_ret != LDB_SUCCESS) {
     1337                PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
     1338                return NULL;
     1339        }
    9611340
    9621341        py_ret = PyLdbMessage_FromMessage(diff);
     1342
     1343        talloc_unlink(ldb, diff);
    9631344
    9641345        return py_ret;
     
    10041385{
    10051386        PyObject *py_base = Py_None;
    1006         enum ldb_scope scope = LDB_SCOPE_DEFAULT;
     1387        int scope = LDB_SCOPE_DEFAULT;
    10071388        char *expr = NULL;
    10081389        PyObject *py_attrs = Py_None;
     
    10171398        struct ldb_dn *base;
    10181399        PyObject *py_ret;
    1019 
     1400        TALLOC_CTX *mem_ctx;
     1401
     1402        /* type "int" rather than "enum" for "scope" is intentional */
    10201403        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
    10211404                                         discard_const_p(char *, kwnames),
     
    10231406                return NULL;
    10241407
     1408
     1409        mem_ctx = talloc_new(NULL);
     1410        if (mem_ctx == NULL) {
     1411                PyErr_NoMemory();
     1412                return NULL;
     1413        }
    10251414        ldb_ctx = PyLdb_AsLdbContext(self);
    10261415
     
    10281417                attrs = NULL;
    10291418        } else {
    1030                 attrs = PyList_AsStringList(NULL, py_attrs, "attrs");
    1031                 if (attrs == NULL)
     1419                attrs = PyList_AsStringList(mem_ctx, py_attrs, "attrs");
     1420                if (attrs == NULL) {
     1421                        talloc_free(mem_ctx);
    10321422                        return NULL;
     1423                }
    10331424        }
    10341425
     
    10451436                parsed_controls = NULL;
    10461437        } else {
    1047                 const char **controls = PyList_AsStringList(ldb_ctx, py_controls, "controls");
    1048                 parsed_controls = ldb_parse_control_strings(ldb_ctx, ldb_ctx, controls);
     1438                const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
     1439                parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
    10491440                talloc_free(controls);
    10501441        }
    10511442
    1052         res = talloc_zero(ldb_ctx, struct ldb_result);
     1443        res = talloc_zero(mem_ctx, struct ldb_result);
    10531444        if (res == NULL) {
    10541445                PyErr_NoMemory();
    1055                 talloc_free(attrs);
    1056                 return NULL;
    1057         }
    1058 
    1059         ret = ldb_build_search_req(&req, ldb_ctx, ldb_ctx,
     1446                talloc_free(mem_ctx);
     1447                return NULL;
     1448        }
     1449
     1450        ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
    10601451                                   base,
    10611452                                   scope,
     
    10671458                                   NULL);
    10681459
     1460        if (ret != LDB_SUCCESS) {
     1461                talloc_free(mem_ctx);
     1462                PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
     1463                return NULL;
     1464        }
     1465
    10691466        talloc_steal(req, attrs);
    1070 
    1071         if (ret != LDB_SUCCESS) {
    1072                 talloc_free(res);
    1073                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
    1074                 return NULL;
    1075         }
    10761467
    10771468        ret = ldb_request(ldb_ctx, req);
     
    10811472        }
    10821473
    1083         talloc_free(req);
    1084 
    10851474        if (ret != LDB_SUCCESS) {
    1086                 talloc_free(res);
     1475                talloc_free(mem_ctx);
    10871476                PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
    10881477                return NULL;
     
    10911480        py_ret = PyLdbResult_FromResult(res);
    10921481
    1093         talloc_free(res);
     1482        talloc_free(mem_ctx);
    10941483
    10951484        return py_ret;
     
    11421531}
    11431532
     1533static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
     1534{
     1535        struct ldb_context *ldb = PyLdb_AsLdbContext(self);
     1536        int type, ret;
     1537        uint64_t value;
     1538
     1539        if (!PyArg_ParseTuple(args, "i", &type))
     1540                return NULL;
     1541
     1542        /* FIXME: More interpretation */
     1543
     1544        ret = ldb_sequence_number(ldb, type, &value);
     1545
     1546        if (ret != LDB_SUCCESS) {
     1547                PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
     1548                return NULL;
     1549        }
     1550        return PyLong_FromLongLong(value);
     1551}
    11441552static PyMethodDef py_ldb_methods[] = {
    11451553        { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
     
    11561564                "S.transaction_start() -> None\n"
    11571565                "Start a new transaction." },
     1566        { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
     1567                "S.transaction_prepare_commit() -> None\n"
     1568                "prepare to commit a new transaction (2-stage commit)." },
    11581569        { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
    11591570                "S.transaction_commit() -> None\n"
     
    12251636                "S.modules() -> list\n"
    12261637                "Return the list of modules on this LDB connection " },
     1638        { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
     1639                "S.sequence_number(type) -> value\n"
     1640                "Return the value of the sequence according to the requested type" },
    12271641        { NULL },
    12281642};
    12291643
    1230 PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
     1644static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
    12311645{
    12321646        PyLdbModuleObject *ret;
     
    12571671        struct ldb_dn *dn;
    12581672        struct ldb_result *result;
     1673        unsigned int count;
    12591674        int ret;
    1260         int count;
    1261 
    1262         if (!PyObject_AsDn(ldb_ctx, obj, ldb_ctx, &dn))
     1675
     1676        if (!PyObject_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
    12631677                return -1;
    1264 
    1265         ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL, NULL);
     1678        }
     1679
     1680        ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
     1681                         NULL);
    12661682        if (ret != LDB_SUCCESS) {
    12671683                PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
     
    12731689        talloc_free(result);
    12741690
     1691        if (count > 1) {
     1692                PyErr_Format(PyExc_RuntimeError,
     1693                             "Searching for [%s] dn gave %u results!",
     1694                             ldb_dn_get_linearized(dn),
     1695                             count);
     1696                return -1;
     1697        }
     1698
    12751699        return count;
    12761700}
     
    12801704};
    12811705
    1282 PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
     1706static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
    12831707{
    12841708        PyLdbObject *ret;
     
    13001724}
    13011725
    1302 PyTypeObject PyLdb = {
    1303         .tp_name = "Ldb",
     1726static PyTypeObject PyLdb = {
     1727        .tp_name = "ldb.Ldb",
    13041728        .tp_methods = py_ldb_methods,
    13051729        .tp_repr = (reprfunc)py_ldb_repr,
     
    13151739};
    13161740
     1741static void py_ldb_result_dealloc(PyLdbResultObject *self)
     1742{
     1743        talloc_free(self->mem_ctx);
     1744        Py_DECREF(self->msgs);
     1745        Py_DECREF(self->referals);
     1746        Py_DECREF(self->controls);
     1747        self->ob_type->tp_free(self);
     1748}
     1749
     1750static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
     1751{
     1752        Py_INCREF(self->msgs);
     1753        return self->msgs;
     1754}
     1755
     1756static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
     1757{
     1758        Py_INCREF(self->controls);
     1759        return self->controls;
     1760}
     1761
     1762static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
     1763{
     1764        Py_INCREF(self->referals);
     1765        return self->referals;
     1766}
     1767
     1768static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
     1769{
     1770        Py_ssize_t size;
     1771        if (self->msgs == NULL) {
     1772                PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
     1773                return NULL;
     1774        }
     1775        size = PyList_Size(self->msgs);
     1776        return PyInt_FromLong(size);
     1777}
     1778
     1779static PyGetSetDef py_ldb_result_getset[] = {
     1780        { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL },
     1781        { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL },
     1782        { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL },
     1783        { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL },
     1784        { NULL }
     1785};
     1786
     1787static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
     1788{
     1789        return PyObject_GetIter(self->msgs);
     1790}
     1791
     1792static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
     1793{
     1794        return PySequence_Size(self->msgs);
     1795}
     1796
     1797static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
     1798{
     1799        return PySequence_GetItem(self->msgs, idx);
     1800}
     1801
     1802static PySequenceMethods py_ldb_result_seq = {
     1803        .sq_length = (lenfunc)py_ldb_result_len,
     1804        .sq_item = (ssizeargfunc)py_ldb_result_find,
     1805};
     1806
     1807static PyObject *py_ldb_result_repr(PyLdbObject *self)
     1808{
     1809        return PyString_FromFormat("<ldb result>");
     1810}
     1811
     1812
     1813static PyTypeObject PyLdbResult = {
     1814        .tp_name = "ldb.Result",
     1815        .tp_repr = (reprfunc)py_ldb_result_repr,
     1816        .tp_dealloc = (destructor)py_ldb_result_dealloc,
     1817        .tp_iter = (getiterfunc)py_ldb_result_iter,
     1818        .tp_getset = py_ldb_result_getset,
     1819        .tp_getattro = PyObject_GenericGetAttr,
     1820        .tp_basicsize = sizeof(PyLdbResultObject),
     1821        .tp_as_sequence = &py_ldb_result_seq,
     1822        .tp_doc = "LDB result.",
     1823        .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
     1824};
     1825
    13171826static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
    13181827{
     
    13521861        const char * const*attrs;
    13531862
     1863        /* type "int" rather than "enum" for "scope" is intentional */
    13541864        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OiOO",
    13551865                                         discard_const_p(char *, kwnames),
     
    14902000{
    14912001        talloc_free(self->mem_ctx);
    1492         self->ob_type->tp_free(self);
    1493 }
    1494 
    1495 PyTypeObject PyLdbModule = {
    1496         .tp_name = "LdbModule",
     2002        PyObject_Del(self);
     2003}
     2004
     2005static PyTypeObject PyLdbModule = {
     2006        .tp_name = "ldb.LdbModule",
    14972007        .tp_methods = py_ldb_module_methods,
    14982008        .tp_repr = (reprfunc)py_ldb_module_repr,
     
    15182028 * @return New ldb_message_element, allocated as child of mem_ctx
    15192029 */
    1520 struct ldb_message_element *PyObject_AsMessageElement(TALLOC_CTX *mem_ctx,
    1521                                                                                            PyObject *set_obj, int flags,
    1522                                                                                            const char *attr_name)
     2030static struct ldb_message_element *PyObject_AsMessageElement(
     2031                                                      TALLOC_CTX *mem_ctx,
     2032                                                      PyObject *set_obj,
     2033                                                      int flags,
     2034                                                      const char *attr_name)
    15232035{
    15242036        struct ldb_message_element *me;
    15252037
    1526         if (PyLdbMessageElement_Check(set_obj))
    1527                 return talloc_reference(mem_ctx,
    1528                                                                 PyLdbMessageElement_AsMessageElement(set_obj));
     2038        if (PyLdbMessageElement_Check(set_obj)) {
     2039                PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
     2040                /* We have to talloc_reference() the memory context, not the pointer
     2041                 * which may not actually be it's own context */
     2042                if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
     2043                        return PyLdbMessageElement_AsMessageElement(set_obj);
     2044                }
     2045                return NULL;
     2046        }
    15292047
    15302048        me = talloc(mem_ctx, struct ldb_message_element);
     2049        if (me == NULL) {
     2050                PyErr_NoMemory();
     2051                return NULL;
     2052        }
    15312053
    15322054        me->name = talloc_strdup(me, attr_name);
     
    15372059                me->values[0].length = PyString_Size(set_obj);
    15382060                me->values[0].data = talloc_memdup(me,
    1539                         (uint8_t *)PyString_AsString(set_obj), me->values[0].length);
     2061                        (uint8_t *)PyString_AsString(set_obj), me->values[0].length+1);
    15402062        } else if (PySequence_Check(set_obj)) {
    1541                 int i;
     2063                Py_ssize_t i;
    15422064                me->num_values = PySequence_Size(set_obj);
    15432065                me->values = talloc_array(me, struct ldb_val, me->num_values);
    15442066                for (i = 0; i < me->num_values; i++) {
    15452067                        PyObject *obj = PySequence_GetItem(set_obj, i);
     2068                        if (!PyString_Check(obj)) {
     2069                                PyErr_Format(PyExc_TypeError,
     2070                                             "Expected string as element %zd in list", i);
     2071                                talloc_free(me);
     2072                                return NULL;
     2073                        }
    15462074
    15472075                        me->values[i].length = PyString_Size(obj);
    15482076                        me->values[i].data = talloc_memdup(me,
    1549                                 (uint8_t *)PyString_AsString(obj), me->values[i].length);
     2077                                (uint8_t *)PyString_AsString(obj), me->values[i].length+1);
    15502078                }
    15512079        } else {
     
    15582086
    15592087
    1560 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx, 
    1561                                                                  struct ldb_message_element *me)
    1562 {
    1563         int i;
     2088static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
     2089                                        struct ldb_message_element *me)
     2090{
     2091        Py_ssize_t i;
    15642092        PyObject *result;
    15652093
     
    15692097        for (i = 0; i < me->num_values; i++) {
    15702098                PyList_SetItem(result, i,
    1571                         PyObject_FromLdbValue(ldb_ctx, me, &me->values[i]));
     2099                        PyObject_FromLdbValue(&me->values[i]));
    15722100        }
    15732101
     
    15772105static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
    15782106{
    1579         int i;
    1580         if (!PyArg_ParseTuple(args, "i", &i))
    1581                 return NULL;
    1582         if (i < 0 || i >= PyLdbMessageElement_AsMessageElement(self)->num_values)
     2107        unsigned int i;
     2108        if (!PyArg_ParseTuple(args, "I", &i))
     2109                return NULL;
     2110        if (i >= PyLdbMessageElement_AsMessageElement(self)->num_values)
    15832111                Py_RETURN_NONE;
    15842112
    1585         return PyObject_FromLdbValue(NULL, PyLdbMessageElement_AsMessageElement(self),
    1586                                                                  &(PyLdbMessageElement_AsMessageElement(self)->values[i]));
     2113        return PyObject_FromLdbValue(&(PyLdbMessageElement_AsMessageElement(self)->values[i]));
    15872114}
    15882115
    15892116static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
    15902117{
    1591         struct ldb_message_element *el;
    1592 
    1593         el = PyLdbMessageElement_AsMessageElement(self);
     2118        struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
    15942119        return PyInt_FromLong(el->flags);
    15952120}
     
    16362161static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other)
    16372162{
    1638         return ldb_msg_element_compare(PyLdbMessageElement_AsMessageElement(self),
    1639                                                                    PyLdbMessageElement_AsMessageElement(other));
     2163        int ret = ldb_msg_element_compare(PyLdbMessageElement_AsMessageElement(self),
     2164                                                                          PyLdbMessageElement_AsMessageElement(other));
     2165        return SIGN(ret);
    16402166}
    16412167
     
    16452171}
    16462172
    1647 PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
     2173static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
    16482174{
    16492175        PyLdbMessageElementObject *ret;
    1650         ret = (PyLdbMessageElementObject *)PyLdbMessageElement.tp_alloc(&PyLdbMessageElement, 0);
     2176        ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
    16512177        if (ret == NULL) {
    16522178                PyErr_NoMemory();
     
    16842210
    16852211        el = talloc_zero(mem_ctx, struct ldb_message_element);
     2212        if (el == NULL) {
     2213                PyErr_NoMemory();
     2214                talloc_free(mem_ctx);
     2215                return NULL;
     2216        }
    16862217
    16872218        if (py_elements != NULL) {
    1688                 int i;
     2219                Py_ssize_t i;
    16892220                if (PyString_Check(py_elements)) {
    16902221                        el->num_values = 1;
    16912222                        el->values = talloc_array(el, struct ldb_val, 1);
     2223                        if (el->values == NULL) {
     2224                                talloc_free(mem_ctx);
     2225                                PyErr_NoMemory();
     2226                                return NULL;
     2227                        }
    16922228                        el->values[0].length = PyString_Size(py_elements);
    1693                         el->values[0].data = talloc_memdup(el,
    1694                                 (uint8_t *)PyString_AsString(py_elements), el->values[0].length);
     2229                        el->values[0].data = talloc_memdup(el->values,
     2230                                (uint8_t *)PyString_AsString(py_elements), el->values[0].length+1);
    16952231                } else if (PySequence_Check(py_elements)) {
    16962232                        el->num_values = PySequence_Size(py_elements);
    16972233                        el->values = talloc_array(el, struct ldb_val, el->num_values);
     2234                        if (el->values == NULL) {
     2235                                talloc_free(mem_ctx);
     2236                                PyErr_NoMemory();
     2237                                return NULL;
     2238                        }
    16982239                        for (i = 0; i < el->num_values; i++) {
    16992240                                PyObject *item = PySequence_GetItem(py_elements, i);
     2241                                if (item == NULL) {
     2242                                        talloc_free(mem_ctx);
     2243                                        return NULL;
     2244                                }
    17002245                                if (!PyString_Check(item)) {
    17012246                                        PyErr_Format(PyExc_TypeError,
    1702                                                         "Expected string as element %d in list",
    1703                                                         i);
     2247                                                     "Expected string as element %zd in list", i);
    17042248                                        talloc_free(mem_ctx);
    17052249                                        return NULL;
    17062250                                }
    17072251                                el->values[i].length = PyString_Size(item);
    1708                                 el->values[i].data = talloc_memdup(el, 
    1709                                         (uint8_t *)PyString_AsString(item), el->values[i].length);
     2252                                el->values[i].data = talloc_memdup(el,
     2253                                        (uint8_t *)PyString_AsString(item), el->values[i].length+1);
    17102254                        }
    17112255                } else {
     
    17202264        el->name = talloc_strdup(el, name);
    17212265
    1722         ret = (PyLdbMessageElementObject *)PyLdbMessageElement.tp_alloc(&PyLdbMessageElement, 0);
     2266        ret = PyObject_New(PyLdbMessageElementObject, type);
    17232267        if (ret == NULL) {
    1724                 PyErr_NoMemory();
    17252268                talloc_free(mem_ctx);
    17262269                return NULL;
     
    17352278{
    17362279        char *element_str = NULL;
    1737         int i;
     2280        Py_ssize_t i;
    17382281        struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
    17392282        PyObject *ret;
     
    17472290        }
    17482291
    1749         ret = PyString_FromFormat("MessageElement([%s])", element_str);
    1750 
    1751         talloc_free(element_str);
     2292        if (element_str != NULL) {
     2293                ret = PyString_FromFormat("MessageElement([%s])", element_str);
     2294                talloc_free(element_str);
     2295        } else {
     2296                ret = PyString_FromString("MessageElement([])");
     2297        }
    17522298
    17532299        return ret;
     
    17602306        if (el->num_values == 1)
    17612307                return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
    1762         else 
     2308        else
    17632309                Py_RETURN_NONE;
    17642310}
     
    17672313{
    17682314        talloc_free(self->mem_ctx);
    1769         self->ob_type->tp_free(self);
    1770 }
    1771 
    1772 PyTypeObject PyLdbMessageElement = {
    1773         .tp_name = "MessageElement",
     2315        PyObject_Del(self);
     2316}
     2317
     2318static PyTypeObject PyLdbMessageElement = {
     2319        .tp_name = "ldb.MessageElement",
    17742320        .tp_basicsize = sizeof(PyLdbMessageElementObject),
    17752321        .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
     
    17842330};
    17852331
     2332
     2333static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
     2334{
     2335        PyObject *py_ldb;
     2336        PyObject *py_dict;
     2337        PyObject *py_ret;
     2338        struct ldb_message *msg;
     2339        struct ldb_context *ldb_ctx;
     2340        unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
     2341
     2342        if (!PyArg_ParseTuple(args, "O!O!|I",
     2343                              &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
     2344                              &mod_flags)) {
     2345                return NULL;
     2346        }
     2347
     2348        /* mask only flags we are going to use */
     2349        mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
     2350        if (!mod_flags) {
     2351                PyErr_SetString(PyExc_ValueError,
     2352                                "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
     2353                                " expected as mod_flag value");
     2354                return NULL;
     2355        }
     2356
     2357        ldb_ctx = PyLdb_AsLdbContext(py_ldb);
     2358
     2359        msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
     2360        if (!msg) {
     2361                return NULL;
     2362        }
     2363
     2364        py_ret = PyLdbMessage_FromMessage(msg);
     2365
     2366        talloc_unlink(ldb_ctx, msg);
     2367
     2368        return py_ret;
     2369}
     2370
    17862371static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
    17872372{
     
    17982383{
    17992384        struct ldb_message *msg = PyLdbMessage_AsMessage(self);
    1800         int i, j = 0;
     2385        Py_ssize_t i, j = 0;
    18012386        PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
    18022387        if (msg->dn != NULL) {
     
    18272412                return NULL;
    18282413        }
    1829         return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg);
     2414        return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
    18302415}
    18312416
     
    18582443{
    18592444        struct ldb_message *msg = PyLdbMessage_AsMessage(self);
    1860         int i, j;
     2445        Py_ssize_t i, j = 0;
    18612446        PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
    1862         j = 0;
    18632447        if (msg->dn != NULL) {
    18642448                PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", PyLdbDn_FromDn(msg->dn)));
     
    18662450        }
    18672451        for (i = 0; i < msg->num_elements; i++, j++) {
    1868                 PyList_SetItem(l, j, Py_BuildValue("(sO)", msg->elements[i].name, PyLdbMessageElement_FromMessageElement(&msg->elements[i], self->msg)));
     2452                PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
     2453                PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
     2454                PyList_SetItem(l, j, value);
    18692455        }
    18702456        return l;
    18712457}
    18722458
    1873 static PyMethodDef py_ldb_msg_methods[] = {
    1874         { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, NULL },
    1875         { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS, NULL },
     2459static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
     2460{
     2461        struct ldb_message *msg = PyLdbMessage_AsMessage(self);
     2462        Py_ssize_t i = 0;
     2463        PyObject *l = PyList_New(msg->num_elements);
     2464        for (i = 0; i < msg->num_elements; i++) {
     2465                PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
     2466        }
     2467        return l;
     2468}
     2469
     2470static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
     2471{
     2472        struct ldb_message *msg = PyLdbMessage_AsMessage(self);
     2473        PyLdbMessageElementObject *py_element;
     2474        int ret;
     2475        struct ldb_message_element *el;
     2476
     2477        if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
     2478                return NULL;
     2479
     2480        el = talloc_reference(msg, py_element->el);
     2481        if (el == NULL) {
     2482                PyErr_NoMemory();
     2483                return NULL;
     2484        }
     2485
     2486        ret = ldb_msg_add(msg, el, el->flags);
     2487        PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
     2488
     2489        Py_RETURN_NONE;
     2490}
     2491
     2492static PyMethodDef py_ldb_msg_methods[] = {
     2493        { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
     2494                "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
     2495                "Class method to create ldb.Message object from Dictionary.\n"
     2496                "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
     2497        { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
     2498                "S.keys() -> list\n\n"
     2499                "Return sequence of all attribute names." },
     2500        { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
     2501                "S.remove(name)\n\n"
     2502                "Remove all entries for attributes with the specified name."},
    18762503        { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS, NULL },
    18772504        { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
     2505        { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
     2506        { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
     2507                "S.append(element)\n\n"
     2508                "Add an element to this message." },
    18782509        { NULL },
    18792510};
     
    18972528                return -1;
    18982529        }
    1899        
     2530
    19002531        attr_name = PyString_AsString(name);
    19012532        if (value == NULL) {
     
    19042535        } else {
    19052536                struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
    1906                                                                                         value, 0, attr_name);
     2537                                                                           value, 0, attr_name);
    19072538                if (el == NULL)
    19082539                        return -1;
     
    19712602}
    19722603
    1973 PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
     2604static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
    19742605{
    19752606        PyLdbMessageObject *ret;
     
    20212652{
    20222653        talloc_free(self->mem_ctx);
    2023         self->ob_type->tp_free(self);
    2024 }
    2025 
    2026 PyTypeObject PyLdbMessage = {
    2027         .tp_name = "Message",
     2654        PyObject_Del(self);
     2655}
     2656
     2657static int py_ldb_msg_compare(PyLdbMessageObject *py_msg1,
     2658                              PyLdbMessageObject *py_msg2)
     2659{
     2660        struct ldb_message *msg1 = PyLdbMessage_AsMessage(py_msg1),
     2661                           *msg2 = PyLdbMessage_AsMessage(py_msg2);
     2662        unsigned int i;
     2663        int ret;
     2664
     2665        if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
     2666                ret = ldb_dn_compare(msg1->dn, msg2->dn);
     2667                if (ret != 0) {
     2668                        return SIGN(ret);
     2669                }
     2670        }
     2671
     2672        ret = msg1->num_elements - msg2->num_elements;
     2673        if (ret != 0) {
     2674                return SIGN(ret);
     2675        }
     2676
     2677        for (i = 0; i < msg1->num_elements; i++) {
     2678                ret = ldb_msg_element_compare_name(&msg1->elements[i],
     2679                                                   &msg2->elements[i]);
     2680                if (ret != 0) {
     2681                        return SIGN(ret);
     2682                }
     2683
     2684                ret = ldb_msg_element_compare(&msg1->elements[i],
     2685                                              &msg2->elements[i]);
     2686                if (ret != 0) {
     2687                        return SIGN(ret);
     2688                }
     2689        }
     2690
     2691        return 0;
     2692}
     2693
     2694static PyTypeObject PyLdbMessage = {
     2695        .tp_name = "ldb.Message",
    20282696        .tp_methods = py_ldb_msg_methods,
    20292697        .tp_getset = py_ldb_msg_getset,
     
    20352703        .tp_flags = Py_TPFLAGS_DEFAULT,
    20362704        .tp_iter = (getiterfunc)py_ldb_msg_iter,
     2705        .tp_compare = (cmpfunc)py_ldb_msg_compare,
    20372706};
    20382707
    2039 PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
     2708static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
    20402709{
    20412710        PyLdbTreeObject *ret;
     
    20552724{
    20562725        talloc_free(self->mem_ctx);
    2057         self->ob_type->tp_free(self);
    2058 }
    2059 
    2060 PyTypeObject PyLdbTree = {
    2061         .tp_name = "Tree",
     2726        PyObject_Del(self);
     2727}
     2728
     2729static PyTypeObject PyLdbTree = {
     2730        .tp_name = "ldb.Tree",
    20622731        .tp_basicsize = sizeof(PyLdbTreeObject),
    20632732        .tp_dealloc = (destructor)py_ldb_tree_dealloc,
     
    23673036static PyObject *py_timestring(PyObject *module, PyObject *args)
    23683037{
    2369         time_t t;
     3038        /* most times "time_t" is a signed integer type with 32 or 64 bit:
     3039         * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
     3040        long int t_val;
    23703041        char *tresult;
    23713042        PyObject *ret;
    2372         if (!PyArg_ParseTuple(args, "L", &t))
    2373                 return NULL;
    2374         tresult = ldb_timestring(NULL, t);
     3043        if (!PyArg_ParseTuple(args, "l", &t_val))
     3044                return NULL;
     3045        tresult = ldb_timestring(NULL, (time_t) t_val);
    23753046        ret = PyString_FromString(tresult);
    23763047        talloc_free(tresult);
     
    24353106                return;
    24363107
     3108        if (PyType_Ready(&PyLdbResult) < 0)
     3109                return;
     3110
     3111        if (PyType_Ready(&PyLdbControl) < 0)
     3112                return;
     3113
    24373114        m = Py_InitModule3("ldb", py_ldb_global_methods,
    24383115                "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server.");
     
    24403117                return;
    24413118
     3119        PyModule_AddObject(m, "SEQ_HIGHEST_SEQ", PyInt_FromLong(LDB_SEQ_HIGHEST_SEQ));
     3120        PyModule_AddObject(m, "SEQ_HIGHEST_TIMESTAMP", PyInt_FromLong(LDB_SEQ_HIGHEST_TIMESTAMP));
     3121        PyModule_AddObject(m, "SEQ_NEXT", PyInt_FromLong(LDB_SEQ_NEXT));
    24423122        PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT));
    24433123        PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE));
     
    24943174        PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER));
    24953175
    2496         PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY));
    2497         PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC));
    2498         PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT));
    2499         PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP));
    2500 
     3176        PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY));
     3177        PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC));
     3178        PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT));
     3179        PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP));
    25013180
    25023181        PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText"));
     
    25113190        Py_INCREF(&PyLdbMessageElement);
    25123191        Py_INCREF(&PyLdbTree);
     3192        Py_INCREF(&PyLdbResult);
     3193        Py_INCREF(&PyLdbControl);
    25133194
    25143195        PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
     
    25183199        PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
    25193200        PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
    2520 }
     3201        PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
     3202
     3203        PyModule_AddObject(m, "__version__", PyString_FromString(PACKAGE_VERSION));
     3204}
  • vendor/current/source4/lib/ldb/pyldb.h

    r414 r740  
    22   Unix SMB/CIFS implementation.
    33
    4    Swig interface to ldb.
     4   Python interface to ldb.
    55
    66   Copyright (C) 2007-2008 Jelmer Vernooij <jelmer@samba.org>
     
    2727#define _PYLDB_H_
    2828
    29 #include <Python.h>
    3029#include <talloc.h>
    3130
    3231typedef struct {
    3332        PyObject_HEAD
     33        TALLOC_CTX *mem_ctx;
    3434        struct ldb_context *ldb_ctx;
    35         TALLOC_CTX *mem_ctx;
    3635} PyLdbObject;
    3736
    38 PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx);
    3937#define PyLdb_AsLdbContext(pyobj) ((PyLdbObject *)pyobj)->ldb_ctx
    4038#define PyLdb_Check(ob) PyObject_TypeCheck(ob, &PyLdb)
     
    4240typedef struct {
    4341        PyObject_HEAD
     42        TALLOC_CTX *mem_ctx;
    4443        struct ldb_dn *dn;
    45         TALLOC_CTX *mem_ctx;
    4644} PyLdbDnObject;
    4745
     
    5351typedef struct {
    5452        PyObject_HEAD
     53        TALLOC_CTX *mem_ctx;
    5554        struct ldb_message *msg;
    56         TALLOC_CTX *mem_ctx;
    5755} PyLdbMessageObject;
    5856#define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage)
     
    6159typedef struct {
    6260        PyObject_HEAD
     61        TALLOC_CTX *mem_ctx;
    6362        struct ldb_module *mod;
    64         TALLOC_CTX *mem_ctx;
    6563} PyLdbModuleObject;
    66 PyObject *PyLdbMessage_FromMessage(struct ldb_message *message);
    67 PyObject *PyLdbModule_FromModule(struct ldb_module *mod);
    6864#define PyLdbModule_AsModule(pyobj) ((PyLdbModuleObject *)pyobj)->mod
    6965
    7066typedef struct {
    71         PyObject_HEAD   
     67        PyObject_HEAD
     68        TALLOC_CTX *mem_ctx;
    7269        struct ldb_message_element *el;
    73         TALLOC_CTX *mem_ctx;
    7470} PyLdbMessageElementObject;
    75 struct ldb_message_element *PyObject_AsMessageElement(TALLOC_CTX *mem_ctx, PyObject *obj, int flags, const char *name);
    76 PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *, TALLOC_CTX *mem_ctx);
    7771#define PyLdbMessageElement_AsMessageElement(pyobj) ((PyLdbMessageElementObject *)pyobj)->el
    7872#define PyLdbMessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement)
     
    8074typedef struct {
    8175        PyObject_HEAD
     76        TALLOC_CTX *mem_ctx;
    8277        struct ldb_parse_tree *tree;
     78} PyLdbTreeObject;
     79#define PyLdbTree_AsTree(pyobj) ((PyLdbTreeObject *)pyobj)->tree
     80
     81typedef struct {
     82        PyObject_HEAD
    8383        TALLOC_CTX *mem_ctx;
    84 } PyLdbTreeObject;
    85 PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *);
    86 #define PyLdbTree_AsTree(pyobj) ((PyLdbTreeObject *)pyobj)->tree
     84        PyObject *msgs;
     85        PyObject *referals;
     86        PyObject *controls;
     87} PyLdbResultObject;
     88
     89typedef struct {
     90        PyObject_HEAD
     91        TALLOC_CTX *mem_ctx;
     92        struct ldb_control *data;
     93} PyLdbControlObject;
    8794
    8895#define PyErr_LDB_ERROR_IS_ERR_RAISE(err,ret,ldb) \
  • vendor/current/source4/lib/ldb/tests/photo.ldif

    r414 r740  
    22changetype: modify
    33add: jpegPhoto
    4 jpegPhoto:< file://tests/tmp/samba4.png
     4jpegPhoto:< file://tests/samba4.png
    55
  • vendor/current/source4/lib/ldb/tests/python/api.py

    r414 r740  
    1 #!/usr/bin/python
     1#!/usr/bin/env python
    22# Simple tests for the ldb python bindings.
    33# Copyright (C) 2007 Jelmer Vernooij <jelmer@samba.org>
    44
    5 import os, sys
     5import os
    66import unittest
    77
    8 # Required for the standalone LDB build
    9 sys.path.append("build/lib.linux-i686-2.4")
    10 
    118import ldb
    129
     10
    1311def filename():
    14     return os.tempnam()
     12    import tempfile
     13    try:
     14        dir_prefix = os.path.join(os.environ["SELFTEST_PREFIX"], "tmp")
     15    except KeyError:
     16        dir_prefix = None
     17    return tempfile.mktemp(dir=dir_prefix)
    1518
    1619class NoContextTests(unittest.TestCase):
     
    5861
    5962    def test_modules_tdb(self):
    60         x = ldb.Ldb("bar.ldb")
     63        x = ldb.Ldb(filename())
    6164        self.assertEquals("[<ldb module 'tdb'>]", repr(x.modules()))
    6265
     
    7881
    7982    def test_search_attr_string(self):
    80         l = ldb.Ldb("foo.tdb")
     83        l = ldb.Ldb(filename())
    8184        self.assertRaises(TypeError, l.search, attrs="dc")
    8285
     
    9699        self.assertRaises(ldb.LdbError, lambda: l.delete(ldb.Dn(l, "dc=foo2")))
    97100
     101    def test_delete_w_unhandled_ctrl(self):
     102        l = ldb.Ldb(filename())
     103        m = ldb.Message()
     104        m.dn = ldb.Dn(l, "dc=foo1")
     105        m["b"] = ["a"]
     106        l.add(m)
     107        self.assertRaises(ldb.LdbError, lambda: l.delete(m.dn, ["search_options:1:2"]))
     108        l.delete(m.dn)
     109
    98110    def test_contains(self):
    99         l = ldb.Ldb(filename())
     111        name = filename()
     112        l = ldb.Ldb(name)
    100113        self.assertFalse(ldb.Dn(l, "dc=foo3") in l)
    101         l = ldb.Ldb(filename())
     114        l = ldb.Ldb(name)
    102115        m = ldb.Message()
    103116        m.dn = ldb.Dn(l, "dc=foo3")
     
    209222            rm = l.search(m.dn)[0]
    210223            self.assertEquals(1, len(rm))
    211             rm = l.search(m.dn, attrs=["bla"])[0]
     224            rm = l.search(m.dn, attrs=["bla"])
    212225            self.assertEquals(0, len(rm))
    213226        finally:
     
    267280            self.assertEquals(2, len(rm))
    268281            self.assertEquals(["1234", "456"], list(rm["bla"]))
    269            
    270             #Now create another modify, but switch the flags before we do it
     282
     283            # Now create another modify, but switch the flags before we do it
    271284            m["bla"] = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla")
    272285            m["bla"].set_flags(ldb.FLAG_MOD_DELETE)
     
    275288            self.assertEquals(1, len(rm))
    276289            self.assertEquals(["1234"], list(rm["bla"]))
    277            
    278290        finally:
    279291            l.delete(ldb.Dn(l, "dc=add"))
     
    316328        self.assertEquals("foo\0bar", res[0]["displayname"][0])
    317329
     330    def test_no_crash_broken_expr(self):
     331        l = ldb.Ldb(filename())
     332        self.assertRaises(ldb.LdbError,lambda: l.search("", ldb.SCOPE_SUBTREE, "&(dc=*)(dn=*)", ["dc"]))
     333
    318334
    319335class DnTests(unittest.TestCase):
     
    332348        y = ldb.Dn(self.ldb, "dc=foo11,bar=bloe")
    333349        self.assertEquals(x, y)
     350        y = ldb.Dn(self.ldb, "dc=foo11,bar=blie")
     351        self.assertNotEquals(x, y)
    334352
    335353    def test_str(self):
     
    356374        x = ldb.Dn(self.ldb, "@BLA")
    357375        self.assertEquals(None, x.parent())
    358 
    359     def test_compare(self):
    360         x = ldb.Dn(self.ldb, "dc=foo17,bar=bloe")
    361         y = ldb.Dn(self.ldb, "dc=foo17,bar=bloe")
    362         self.assertEquals(x, y)
    363         z = ldb.Dn(self.ldb, "dc=foo17,bar=blie")
    364         self.assertNotEquals(z, y)
    365376
    366377    def test_is_valid(self):
     
    368379        self.assertTrue(x.is_valid())
    369380        x = ldb.Dn(self.ldb, "")
    370         # is_valid()'s return values appears to be a side effect of
    371         # some other ldb functions. yuck.
    372         # self.assertFalse(x.is_valid())
     381        self.assertTrue(x.is_valid())
    373382
    374383    def test_is_special(self):
     
    413422        ldif = self.ldb.write_ldif(msg[1], ldb.CHANGETYPE_NONE)
    414423        self.assertEquals("dn: foo=bar\n\n", ldif)
    415        
     424
    416425    def test_parse_ldif_more(self):
    417426        msgs = self.ldb.parse_ldif("dn: foo=bar\n\n\ndn: bar=bar")
     
    441450    def test_iter_items(self):
    442451        self.assertEquals(0, len(self.msg.items()))
    443         self.msg.dn = ldb.Dn(ldb.Ldb("foo.tdb"), "dc=foo28")
     452        self.msg.dn = ldb.Dn(ldb.Ldb(filename()), "dc=foo28")
    444453        self.assertEquals(1, len(self.msg.items()))
    445454
    446455    def test_repr(self):
    447         self.msg.dn = ldb.Dn(ldb.Ldb("foo.tdb"), "dc=foo29")
     456        self.msg.dn = ldb.Dn(ldb.Ldb(filename()), "dc=foo29")
    448457        self.msg["dc"] = "foo"
    449458        self.assertEquals("Message({'dn': Dn('dc=foo29'), 'dc': MessageElement(['foo'])})", repr(self.msg))
     
    457466    def test_del(self):
    458467        del self.msg["foo"]
     468
     469    def test_add(self):
     470        self.msg.add(ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla"))
     471
     472    def test_elements_empty(self):
     473        self.assertEquals([], self.msg.elements())
     474
     475    def test_elements(self):
     476        el = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla")
     477        self.msg.add(el)
     478        self.assertEquals([el], self.msg.elements())
    459479
    460480    def test_add_value(self):
     
    476496
    477497    def test_keys(self):
    478         self.msg.dn = ldb.Dn(ldb.Ldb("foo.tdb"), "@BASEINFO")
     498        self.msg.dn = ldb.Dn(ldb.Ldb(filename()), "@BASEINFO")
    479499        self.msg["foo"] = ["bla"]
    480500        self.msg["bar"] = ["bla"]
     
    486506
    487507    def test_get_dn(self):
    488         self.msg.dn = ldb.Dn(ldb.Ldb("foo.tdb"), "@BASEINFO")
     508        self.msg.dn = ldb.Dn(ldb.Ldb(filename()), "@BASEINFO")
    489509        self.assertEquals("@BASEINFO", self.msg.get("dn").__str__())
    490510
    491511    def test_get_invalid(self):
    492         self.msg.dn = ldb.Dn(ldb.Ldb("foo.tdb"), "@BASEINFO")
     512        self.msg.dn = ldb.Dn(ldb.Ldb(filename()), "@BASEINFO")
    493513        self.assertRaises(TypeError, self.msg.get, 42)
    494514
     
    510530        self.assertEquals(1, len(msgdiff))
    511531
     532    def test_equal_empty(self):
     533        msg1 = ldb.Message()
     534        msg2 = ldb.Message()
     535        self.assertEquals(msg1, msg2)
     536
     537    def test_equal_simplel(self):
     538        db = ldb.Ldb(filename())
     539        msg1 = ldb.Message()
     540        msg1.dn = ldb.Dn(db, "foo=bar")
     541        msg2 = ldb.Message()
     542        msg2.dn = ldb.Dn(db, "foo=bar")
     543        self.assertEquals(msg1, msg2)
     544        msg1['foo'] = 'bar'
     545        msg2['foo'] = 'bar'
     546        self.assertEquals(msg1, msg2)
     547        msg2['foo'] = 'blie'
     548        self.assertNotEquals(msg1, msg2)
     549        msg2['foo'] = 'blie'
     550
     551    def test_from_dict(self):
     552        rec = {"dn": "dc=fromdict",
     553               "a1": ["a1-val1", "a1-val1"]}
     554        l = ldb.Ldb()
     555        # check different types of input Flags
     556        for flags in [ldb.FLAG_MOD_ADD, ldb.FLAG_MOD_REPLACE, ldb.FLAG_MOD_DELETE]:
     557            m = ldb.Message.from_dict(l, rec, flags)
     558            self.assertEquals(rec["a1"], list(m["a1"]))
     559            self.assertEquals(flags, m["a1"].flags())
     560        # check input params
     561        self.assertRaises(TypeError, ldb.Message.from_dict, dict(), rec, ldb.FLAG_MOD_REPLACE)
     562        self.assertRaises(TypeError, ldb.Message.from_dict, l, list(), ldb.FLAG_MOD_REPLACE)
     563        self.assertRaises(ValueError, ldb.Message.from_dict, l, rec, 0)
     564        # Message.from_dict expects dictionary with 'dn'
     565        err_rec = {"a1": ["a1-val1", "a1-val1"]}
     566        self.assertRaises(TypeError, ldb.Message.from_dict, l, err_rec, ldb.FLAG_MOD_REPLACE)
     567
    512568
    513569
     
    552608        self.assertEquals(y, x)
    553609
     610    def test_extended(self):
     611        el = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla")
     612        self.assertEquals("MessageElement(['456'])", repr(el))
     613
    554614
    555615class ModuleTests(unittest.TestCase):
     
    572632                return self.next.search(*args, **kwargs)
    573633
     634        def request(self, *args, **kwargs):
     635            pass
     636
     637        name = filename()
    574638        ldb.register_module(ExampleModule)
    575         if os.path.exists("usemodule.ldb"):
    576             os.unlink("usemodule.ldb")
    577         l = ldb.Ldb("usemodule.ldb")
     639        if os.path.exists(name):
     640            os.unlink(name)
     641        l = ldb.Ldb(name)
    578642        l.add({"dn": "@MODULES", "@LIST": "bla"})
    579643        self.assertEquals([], ops)
    580         l = ldb.Ldb("usemodule.ldb")
     644        l = ldb.Ldb(name)
    581645        self.assertEquals(["init"], ops)
     646
     647class LdbResultTests(unittest.TestCase):
     648
     649    def setUp(self):
     650        name = filename()
     651        self.name = name
     652        if os.path.exists(name):
     653            os.unlink(name)
     654        self.l = ldb.Ldb(name)
     655        self.l.add({"dn": "DC=SAMBA,DC=ORG", "name": "samba.org"})
     656        self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG", "name": "Admins"})
     657        self.l.add({"dn": "OU=USERS,DC=SAMBA,DC=ORG", "name": "Users"})
     658        self.l.add({"dn": "OU=OU1,DC=SAMBA,DC=ORG", "name": "OU #1"})
     659        self.l.add({"dn": "OU=OU2,DC=SAMBA,DC=ORG", "name": "OU #2"})
     660        self.l.add({"dn": "OU=OU3,DC=SAMBA,DC=ORG", "name": "OU #3"})
     661        self.l.add({"dn": "OU=OU4,DC=SAMBA,DC=ORG", "name": "OU #4"})
     662        self.l.add({"dn": "OU=OU5,DC=SAMBA,DC=ORG", "name": "OU #5"})
     663        self.l.add({"dn": "OU=OU6,DC=SAMBA,DC=ORG", "name": "OU #6"})
     664        self.l.add({"dn": "OU=OU7,DC=SAMBA,DC=ORG", "name": "OU #7"})
     665        self.l.add({"dn": "OU=OU8,DC=SAMBA,DC=ORG", "name": "OU #8"})
     666        self.l.add({"dn": "OU=OU9,DC=SAMBA,DC=ORG", "name": "OU #9"})
     667        self.l.add({"dn": "OU=OU10,DC=SAMBA,DC=ORG", "name": "OU #10"})
     668
     669    def tearDown(self):
     670        if os.path.exists(self.name):
     671            os.unlink(self.name)
     672
     673    def test_return_type(self):
     674        res = self.l.search()
     675        self.assertEquals(str(res), "<ldb result>")
     676
     677    def test_get_msgs(self):
     678        res = self.l.search()
     679        list = res.msgs
     680
     681    def test_get_controls(self):
     682        res = self.l.search()
     683        list = res.controls
     684
     685    def test_get_referals(self):
     686        res = self.l.search()
     687        list = res.referals
     688
     689    def test_iter_msgs(self):
     690        found = False
     691        for l in self.l.search().msgs:
     692            if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG":
     693                found = True
     694        self.assertTrue(found)
     695
     696    def test_iter_msgs_count(self):
     697        self.assertTrue(self.l.search().count > 0)
     698        # 13 objects has been added to the DC=SAMBA, DC=ORG
     699        self.assertEqual(self.l.search(base="DC=SAMBA,DC=ORG").count, 13)
     700
     701    def test_iter_controls(self):
     702        res = self.l.search().controls
     703        it = iter(res)
     704
     705    def test_create_control(self):
     706        self.assertRaises(ValueError, ldb.Control, self.l, "tatayoyo:0")
     707        c = ldb.Control(self.l, "relax:1")
     708        self.assertEquals(c.critical, True)
     709        self.assertEquals(c.oid, "1.3.6.1.4.1.4203.666.5.12")
     710
     711    def test_iter_refs(self):
     712        res = self.l.search().referals
     713        it = iter(res)
     714
     715    def test_iter_as_sequence_msgs(self):
     716        found = False
     717        res = self.l.search().msgs
     718
     719        for i in range(0, len(res)):
     720            l = res[i]
     721            if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG":
     722                found = True
     723        self.assertTrue(found)
     724
     725    def test_iter_as_sequence(self):
     726        found = False
     727        res = self.l.search()
     728
     729        for i in range(0, len(res)):
     730            l = res[i]
     731            if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG":
     732                found = True
     733        self.assertTrue(found)
     734
     735class VersionTests(unittest.TestCase):
     736
     737    def test_version(self):
     738        self.assertTrue(isinstance(ldb.__version__, str))
    582739
    583740
  • vendor/current/source4/lib/ldb/tests/sample_module.c

    r414 r740  
    2222*/
    2323
     24#include "replace.h"
     25#include "system/filesys.h"
     26#include "system/time.h"
    2427#include "ldb_module.h"
    2528
    26 int sample_add(struct ldb_module *mod, struct ldb_request *req)
     29static int sample_add(struct ldb_module *mod, struct ldb_request *req)
    2730{
     31        struct ldb_control *control;
     32
    2833        ldb_msg_add_fmt(req->op.add.message, "touchedBy", "sample");
    2934
    30         return ldb_next_request(mod, req);
     35        /* check if there's a relax control */
     36        control = ldb_request_get_control(req, LDB_CONTROL_RELAX_OID);
     37        if (control == NULL) {
     38                /* not found go on */
     39                return ldb_next_request(mod, req);
     40        } else {
     41                return LDB_ERR_UNWILLING_TO_PERFORM;
     42        }
    3143}
    3244
    33 const struct ldb_module_ops ldb_sample_module_ops = {
     45static int sample_modify(struct ldb_module *mod, struct ldb_request *req)
     46{
     47        struct ldb_control *control;
     48
     49        /* check if there's a relax control */
     50        control = ldb_request_get_control(req, LDB_CONTROL_RELAX_OID);
     51        if (control == NULL) {
     52                /* not found go on */
     53                return ldb_next_request(mod, req);
     54        } else {
     55                return LDB_ERR_UNWILLING_TO_PERFORM;
     56        }
     57}
     58
     59
     60static struct ldb_module_ops ldb_sample_module_ops = {
    3461        .name              = "sample",
    3562        .add               = sample_add,
     63        .del               = sample_modify,
     64        .modify            = sample_modify,
    3665};
     66
     67int ldb_sample_init(const char *version)
     68{
     69        LDB_MODULE_CHECK_VERSION(version);
     70        return ldb_register_module(&ldb_sample_module_ops);
     71}
  • vendor/current/source4/lib/ldb/tests/test-generic.sh

    r414 r740  
    4545}
    4646
    47 echo "testing indexed search"
     47echo "Testing indexed search"
    4848$VALGRIND ldbsearch$EXEEXT '(uid=uham)'  || exit 1
    4949$VALGRIND ldbsearch$EXEEXT '(&(objectclass=person)(objectclass=person)(objectclass=top))' || exit 1
     
    8282
    8383echo "Testing binary file attribute value"
    84 mkdir -p tests/tmp
    85 cp $LDBDIR/tests/samba4.png tests/tmp/samba4.png
    8684$VALGRIND ldbmodify$EXEEXT $LDBDIR/tests/photo.ldif || exit 1
    8785count=`$VALGRIND ldbsearch$EXEEXT '(cn=Hampster Ursula)' jpegPhoto | grep '^dn' | wc -l`
     
    9088    exit 1
    9189fi
    92 rm -f tests/tmp/samba4.png
    9390
    9491echo "*TODO* Testing UTF8 upper lower case searches !!"
  • vendor/current/source4/lib/ldb/tests/test-schema.sh

    r414 r740  
    2020$VALGRIND bin/ldbmodify $LDBDIR/tests/schema-tests/schema-mod-test-3.ldif || exit 1
    2121$VALGRIND bin/ldbmodify $LDBDIR/tests/schema-tests/schema-mod-test-4.ldif
    22 if [ "$?" == "0" ]; then
     22if [ "$?" = "0" ]; then
    2323        echo "test failed!"
    2424        exit 1
    2525fi
    2626$VALGRIND bin/ldbmodify $LDBDIR/tests/schema-tests/schema-mod-test-5.ldif
    27 if [ "$?" == "0" ]; then
     27if [ "$?" = "0" ]; then
    2828        echo "test failed!"
    2929        exit 1
  • vendor/current/source4/lib/ldb/tests/test-tdb.sh

    r414 r740  
    3030
    3131. $LDBDIR/tests/test-tdb-features.sh
     32
     33. $LDBDIR/tests/test-controls.sh
  • vendor/current/source4/lib/ldb/tests/test.ldif

    r414 r740  
    410410facsimiletelephonenumber: +1 313 555 9700
    411411telephonenumber: +1 313 555 5331
     412
     413dn: cn=Fred Bassett,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST
     414objectclass: OpenLDAPperson
     415cn: Fred Bassett
     416sn: Bassett
     417uid: Bassett, Fred
  • vendor/current/source4/lib/ldb/tools/cmdline.c

    r414 r740  
    2222*/
    2323
    24 #include "ldb_includes.h"
     24#include "replace.h"
     25#include "system/filesys.h"
     26#include "system/time.h"
    2527#include "ldb.h"
     28#include "ldb_module.h"
    2629#include "tools/cmdline.h"
    2730
    28 #if (_SAMBA_BUILD_ >= 4)
    29 #include "includes.h"
    30 #include "lib/cmdline/popt_common.h"
    31 #include "lib/ldb-samba/ldif_handlers.h"
    32 #include "auth/gensec/gensec.h"
    33 #include "auth/auth.h"
    34 #include "ldb_wrap.h"
    35 #include "param/param.h"
    36 #endif
    37 
    3831static struct ldb_cmdline options; /* needs to be static for older compilers */
    3932
    40 static struct poptOption popt_options[] = {
     33enum ldb_cmdline_options { CMDLINE_RELAX=1 };
     34
     35static struct poptOption builtin_popt_options[] = {
    4136        POPT_AUTOHELP
    4237        { "url",       'H', POPT_ARG_STRING, &options.url, 0, "database URL", "URL" },
     
    5449        { "nosync", 0,   POPT_ARG_NONE, &options.nosync, 0, "non-synchronous transactions", NULL },
    5550        { "sorted", 'S', POPT_ARG_NONE, &options.sorted, 0, "sort attributes", NULL },
    56         { "input", 'I', POPT_ARG_STRING, &options.input, 0, "Input File", "Input" },
    57         { "output", 'O', POPT_ARG_STRING, &options.output, 0, "Output File", "Output" },
    5851        { NULL,    'o', POPT_ARG_STRING, NULL, 'o', "ldb_connect option", "OPTION" },
    5952        { "controls", 0, POPT_ARG_STRING, NULL, 'c', "controls", NULL },
    6053        { "show-binary", 0, POPT_ARG_NONE, &options.show_binary, 0, "display binary LDIF", NULL },
    61 #if (_SAMBA_BUILD_ >= 4)
    62         POPT_COMMON_SAMBA
    63         POPT_COMMON_CREDENTIALS
    64         POPT_COMMON_CONNECTION
    65         POPT_COMMON_VERSION
    66 #endif
     54        { "paged", 0, POPT_ARG_NONE, NULL, 'P', "use a paged search", NULL },
     55        { "show-deleted", 0, POPT_ARG_NONE, NULL, 'D', "show deleted objects", NULL },
     56        { "show-recycled", 0, POPT_ARG_NONE, NULL, 'R', "show recycled objects", NULL },
     57        { "show-deactivated-link", 0, POPT_ARG_NONE, NULL, 'd', "show deactivated links", NULL },
     58        { "reveal", 0, POPT_ARG_NONE, NULL, 'r', "reveal ldb internals", NULL },
     59        { "relax", 0, POPT_ARG_NONE, NULL, CMDLINE_RELAX, "pass relax control", NULL },
     60        { "cross-ncs", 0, POPT_ARG_NONE, NULL, 'N', "search across NC boundaries", NULL },
     61        { "extended-dn", 0, POPT_ARG_NONE, NULL, 'E', "show extended DNs", NULL },
    6762        { NULL }
    6863};
    6964
    70 void ldb_cmdline_help(const char *cmdname, FILE *f)
     65void ldb_cmdline_help(struct ldb_context *ldb, const char *cmdname, FILE *f)
    7166{
    7267        poptContext pc;
    73         pc = poptGetContext(cmdname, 0, NULL, popt_options,
     68        struct poptOption **popt_options = ldb_module_popt_options(ldb);
     69        pc = poptGetContext(cmdname, 0, NULL, *popt_options,
    7470                            POPT_CONTEXT_KEEP_FIRST);
    7571        poptPrintHelp(pc, f, 0);
     72}
     73
     74/*
     75  add a control to the options structure
     76 */
     77static bool add_control(TALLOC_CTX *mem_ctx, const char *control)
     78{
     79        unsigned int i;
     80
     81        /* count how many controls we already have */
     82        for (i=0; options.controls && options.controls[i]; i++) ;
     83
     84        options.controls = talloc_realloc(mem_ctx, options.controls, const char *, i + 2);
     85        if (options.controls == NULL) {
     86                return false;
     87        }
     88        options.controls[i] = control;
     89        options.controls[i+1] = NULL;
     90        return true;
    7691}
    7792
     
    8196struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb,
    8297                                        int argc, const char **argv,
    83                                         void (*usage)(void))
     98                                        void (*usage)(struct ldb_context *))
    8499{
    85100        struct ldb_cmdline *ret=NULL;
    86101        poptContext pc;
    87 #if (_SAMBA_BUILD_ >= 4)
    88         int r;
    89 #endif
    90102        int num_options = 0;
    91103        int opt;
    92104        int flags = 0;
    93 
    94 #if (_SAMBA_BUILD_ >= 4)
    95         r = ldb_register_samba_handlers(ldb);
    96         if (r != 0) {
    97                 goto failed;
    98         }
    99 
    100 #endif
     105        int rc;
     106        struct poptOption **popt_options;
     107
     108        /* make the ldb utilities line buffered */
     109        setlinebuf(stdout);
    101110
    102111        ret = talloc_zero(ldb, struct ldb_cmdline);
     
    122131        options.scope = LDB_SCOPE_DEFAULT;
    123132
    124         pc = poptGetContext(argv[0], argc, argv, popt_options,
     133        popt_options = ldb_module_popt_options(ldb);
     134        (*popt_options) = builtin_popt_options;
     135
     136        rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_OPTIONS);
     137        if (rc != LDB_SUCCESS) {
     138                fprintf(stderr, "ldb: failed to run command line hooks : %s\n", ldb_strerror(rc));
     139                goto failed;
     140        }
     141
     142        pc = poptGetContext(argv[0], argc, argv, *popt_options,
    125143                            POPT_CONTEXT_KEEP_FIRST);
    126144
     
    160178                case 'c': {
    161179                        const char *cs = poptGetOptArg(pc);
    162                         const char *p, *q;
    163                         int cc;
    164 
    165                         for (p = cs, cc = 1; (q = strchr(p, ',')); cc++, p = q + 1) ;
    166 
    167                         options.controls = talloc_array(ret, char *, cc + 1);
    168                         if (options.controls == NULL) {
    169                                 fprintf(stderr, "Out of memory!\n");
    170                                 goto failed;
    171                         }
    172                         for (p = cs, cc = 0; p != NULL; cc++) {
    173                                 const char *t;
     180                        const char *p;
     181
     182                        for (p = cs; p != NULL; ) {
     183                                const char *t, *c;
    174184
    175185                                t = strchr(p, ',');
    176186                                if (t == NULL) {
    177                                         options.controls[cc] = talloc_strdup(options.controls, p);
     187                                        c = talloc_strdup(options.controls, p);
    178188                                        p = NULL;
    179189                                } else {
    180                                         options.controls[cc] = talloc_strndup(options.controls, p, t-p);
     190                                        c = talloc_strndup(options.controls, p, t-p);
    181191                                        p = t + 1;
    182192                                }
    183                         }
    184                         options.controls[cc] = NULL;
     193                                if (c == NULL || !add_control(ret, c)) {
     194                                        fprintf(stderr, __location__ ": out of memory\n");
     195                                        goto failed;
     196                                }
     197                        }
    185198
    186199                        break;   
    187200                }
     201                case 'P':
     202                        if (!add_control(ret, "paged_results:1:1024")) {
     203                                fprintf(stderr, __location__ ": out of memory\n");
     204                                goto failed;
     205                        }
     206                        break;
     207                case 'D':
     208                        if (!add_control(ret, "show_deleted:1")) {
     209                                fprintf(stderr, __location__ ": out of memory\n");
     210                                goto failed;
     211                        }
     212                        break;
     213                case 'R':
     214                        if (!add_control(ret, "show_recycled:0")) {
     215                                fprintf(stderr, __location__ ": out of memory\n");
     216                                goto failed;
     217                        }
     218                        break;
     219                case 'd':
     220                        if (!add_control(ret, "show_deactivated_link:0")) {
     221                                fprintf(stderr, __location__ ": out of memory\n");
     222                                goto failed;
     223                        }
     224                        break;
     225                case 'r':
     226                        if (!add_control(ret, "reveal_internals:0")) {
     227                                fprintf(stderr, __location__ ": out of memory\n");
     228                                goto failed;
     229                        }
     230                        break;
     231                case CMDLINE_RELAX:
     232                        if (!add_control(ret, "relax:0")) {
     233                                fprintf(stderr, __location__ ": out of memory\n");
     234                                goto failed;
     235                        }
     236                        break;
     237                case 'N':
     238                        if (!add_control(ret, "search_options:1:2")) {
     239                                fprintf(stderr, __location__ ": out of memory\n");
     240                                goto failed;
     241                        }
     242                        break;
     243                case 'E':
     244                        if (!add_control(ret, "extended_dn:1:1")) {
     245                                fprintf(stderr, __location__ ": out of memory\n");
     246                                goto failed;
     247                        }
     248                        break;
    188249                default:
    189250                        fprintf(stderr, "Invalid option %s: %s\n",
    190251                                poptBadOption(pc, 0), poptStrerror(opt));
    191                         if (usage) usage();
     252                        if (usage) usage(ldb);
    192253                        goto failed;
    193254                }
     
    206267        if (ret->url == NULL) {
    207268                fprintf(stderr, "You must supply a url with -H or with $LDB_URL\n");
    208                 if (usage) usage();
     269                if (usage) usage(ldb);
    209270                goto failed;
    210271        }
     
    226287        }
    227288
    228 #if (_SAMBA_BUILD_ >= 4)
    229         /* Must be after we have processed command line options */
    230         gensec_init(cmdline_lp_ctx);
    231        
    232         if (ldb_set_opaque(ldb, "sessionInfo", system_session(ldb, cmdline_lp_ctx))) {
    233                 goto failed;
    234         }
    235         if (ldb_set_opaque(ldb, "credentials", cmdline_credentials)) {
    236                 goto failed;
    237         }
    238         if (ldb_set_opaque(ldb, "loadparm", cmdline_lp_ctx)) {
    239                 goto failed;
    240         }
    241 
    242         ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
    243 #endif
    244 
    245289        if (options.modules_path != NULL) {
    246290                ldb_set_modules_dir(ldb, options.modules_path);
    247         } else if (getenv("LDB_MODULES_PATH") != NULL) {
    248                 ldb_set_modules_dir(ldb, getenv("LDB_MODULES_PATH"));
     291        }
     292
     293        rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_PRECONNECT);
     294        if (rc != LDB_SUCCESS) {
     295                fprintf(stderr, "ldb: failed to run preconnect hooks : %s\n", ldb_strerror(rc));
     296                goto failed;
    249297        }
    250298
     
    256304        }
    257305
     306        rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_POSTCONNECT);
     307        if (rc != LDB_SUCCESS) {
     308                fprintf(stderr, "ldb: failed to run post connect hooks : %s\n", ldb_strerror(rc));
     309                goto failed;
     310        }
     311
    258312        return ret;
    259313
    260314failed:
    261315        talloc_free(ret);
    262         exit(1);
     316        exit(LDB_ERR_OPERATIONS_ERROR);
    263317        return NULL;
    264318}
     
    274328int handle_controls_reply(struct ldb_control **reply, struct ldb_control **request)
    275329{
    276         int i, j;
    277         int ret = 0;
     330        unsigned int i, j;
     331        int ret = 0;
    278332
    279333        if (reply == NULL || request == NULL) return -1;
  • vendor/current/source4/lib/ldb/tools/cmdline.h

    r414 r740  
    4242        int num_searches;
    4343        const char *sasl_mechanism;
    44         const char *input;
    45         const char *output;
    46         char **controls;
     44        const char **controls;
    4745        int show_binary;
    4846        int tracing;
    4947};
    5048
    51 struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, int argc, const char **argv,
    52                                         void (*usage)(void));
     49struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, int argc,
     50                                        const char **argv,
     51                                        void (*usage)(struct ldb_context *));
    5352
    5453
    5554int handle_controls_reply(struct ldb_control **reply, struct ldb_control **request);
    56 void ldb_cmdline_help(const char *cmdname, FILE *f);
     55void ldb_cmdline_help(struct ldb_context *ldb, const char *cmdname, FILE *f);
    5756
  • vendor/current/source4/lib/ldb/tools/ldbadd.c

    r414 r740  
    1 /* 
     1/*
    22   ldb database library
    33
     
    77     ** library. This does NOT imply that all of Samba is released
    88     ** under the LGPL
    9    
     9
    1010   This library is free software; you can redistribute it and/or
    1111   modify it under the terms of the GNU Lesser General Public
     
    3434#include "ldb.h"
    3535#include "tools/cmdline.h"
     36#include "ldbutil.h"
    3637
    37 static int failures;
     38static unsigned int failures;
     39static struct ldb_cmdline *options;
    3840
    39 static void usage(void)
     41static void usage(struct ldb_context *ldb)
    4042{
    41         printf("Usage: ldbadd <options> <ldif...>\n"); 
     43        printf("Usage: ldbadd <options> <ldif...>\n");
    4244        printf("Adds records to a ldb, reading ldif the specified list of files\n\n");
    43         ldb_cmdline_help("ldbadd", stdout);
    44         exit(1);
     45        ldb_cmdline_help(ldb, "ldbadd", stdout);
     46        exit(LDB_ERR_OPERATIONS_ERROR);
    4547}
    4648
     
    4951  add records from an opened file
    5052*/
    51 static int process_file(struct ldb_context *ldb, FILE *f, int *count)
     53static int process_file(struct ldb_context *ldb, FILE *f, unsigned int *count)
    5254{
    5355        struct ldb_ldif *ldif;
    5456        int ret = LDB_SUCCESS;
     57        struct ldb_control **req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls);
     58        if (options->controls != NULL &&  req_ctrls== NULL) {
     59                printf("parsing controls failed: %s\n", ldb_errstring(ldb));
     60                return LDB_ERR_OPERATIONS_ERROR;
     61        }
     62
    5563
    5664        while ((ldif = ldb_ldif_read_file(ldb, f))) {
     
    6169                }
    6270
    63                 ldif->msg = ldb_msg_canonicalize(ldb, ldif->msg);
     71                ret = ldb_msg_normalize(ldb, ldif, ldif->msg, &ldif->msg);
     72                if (ret != LDB_SUCCESS) {
     73                        fprintf(stderr,
     74                                "ERR: Message canonicalize failed - %s\n",
     75                                ldb_strerror(ret));
     76                        failures++;
     77                        ldb_ldif_read_free(ldb, ldif);
     78                        continue;
     79                }
    6480
    65                 ret = ldb_add(ldb, ldif->msg);
     81                ret = ldb_add_ctrl(ldb, ldif->msg,req_ctrls);
    6682                if (ret != LDB_SUCCESS) {
    67                         fprintf(stderr, "ERR: \"%s\" on DN %s\n",
    68                                 ldb_errstring(ldb), ldb_dn_get_linearized(ldif->msg->dn));
     83                        fprintf(stderr, "ERR: %s : \"%s\" on DN %s\n",
     84                                ldb_strerror(ret), ldb_errstring(ldb),
     85                                ldb_dn_get_linearized(ldif->msg->dn));
    6986                        failures++;
    7087                } else {
    7188                        (*count)++;
     89                        if (options->verbose) {
     90                                printf("Added %s\n", ldb_dn_get_linearized(ldif->msg->dn));
     91                        }
    7292                }
    7393                ldb_ldif_read_free(ldb, ldif);
     
    82102{
    83103        struct ldb_context *ldb;
    84         int i, ret=0, count=0;
    85         struct ldb_cmdline *options;
     104        unsigned int i, count = 0;
     105        int ret = LDB_SUCCESS;
     106        TALLOC_CTX *mem_ctx = talloc_new(NULL);
    86107
    87         ldb = ldb_init(NULL, NULL);
     108        ldb = ldb_init(mem_ctx, NULL);
     109        if (ldb == NULL) {
     110                return LDB_ERR_OPERATIONS_ERROR;
     111        }
    88112
    89113        options = ldb_cmdline_process(ldb, argc, argv, usage);
    90114
    91         if (ldb_transaction_start(ldb) != 0) {
     115        ret = ldb_transaction_start(ldb);
     116        if (ret != LDB_SUCCESS) {
    92117                printf("Failed to start transaction: %s\n", ldb_errstring(ldb));
    93                 exit(1);
     118                return ret;
    94119        }
    95120
     
    103128                        if (!f) {
    104129                                perror(fname);
    105                                 exit(1);
     130                                return LDB_ERR_OPERATIONS_ERROR;
    106131                        }
    107132                        ret = process_file(ldb, f, &count);
     
    111136
    112137        if (count != 0) {
    113                 if (ldb_transaction_commit(ldb) != 0) {
     138                ret = ldb_transaction_commit(ldb);
     139                if (ret != LDB_SUCCESS) {
    114140                        printf("Failed to commit transaction: %s\n", ldb_errstring(ldb));
    115                         exit(1);
     141                        return ret;
    116142                }
    117143        } else {
     
    119145        }
    120146
    121         talloc_free(ldb);
     147        talloc_free(mem_ctx);
    122148
    123         printf("Added %d records with %d failures\n", count, failures);
    124        
     149        printf("Added %u records with %u failures\n", count, failures);
     150
    125151        return ret;
    126152}
  • vendor/current/source4/lib/ldb/tools/ldbdel.c

    r414 r740  
    3232 */
    3333
     34#include "replace.h"
    3435#include "ldb.h"
    3536#include "tools/cmdline.h"
     37#include "ldbutil.h"
    3638
    37 static int ldb_delete_recursive(struct ldb_context *ldb, struct ldb_dn *dn)
     39static int dn_cmp(struct ldb_message **msg1, struct ldb_message **msg2)
    3840{
    39         int ret, i, total=0;
     41        return ldb_dn_compare((*msg1)->dn, (*msg2)->dn);
     42}
     43
     44static int ldb_delete_recursive(struct ldb_context *ldb, struct ldb_dn *dn,struct ldb_control **req_ctrls)
     45{
     46        int ret;
     47        unsigned int i, total=0;
    4048        const char *attrs[] = { NULL };
    4149        struct ldb_result *res;
    4250       
    4351        ret = ldb_search(ldb, ldb, &res, dn, LDB_SCOPE_SUBTREE, attrs, "distinguishedName=*");
    44         if (ret != LDB_SUCCESS) return -1;
     52        if (ret != LDB_SUCCESS) return ret;
     53
     54        /* sort the DNs, deepest first */
     55        TYPESAFE_QSORT(res->msgs, res->count, dn_cmp);
    4556
    4657        for (i = 0; i < res->count; i++) {
    47                 if (ldb_delete(ldb, res->msgs[i]->dn) == 0) {
     58                if (ldb_delete_ctrl(ldb, res->msgs[i]->dn,req_ctrls) == LDB_SUCCESS) {
    4859                        total++;
     60                } else {
     61                        printf("Failed to delete '%s' - %s\n",
     62                               ldb_dn_get_linearized(res->msgs[i]->dn),
     63                               ldb_errstring(ldb));
    4964                }
    5065        }
     
    5368
    5469        if (total == 0) {
    55                 return -1;
     70                return LDB_ERR_OPERATIONS_ERROR;
    5671        }
    57         printf("Deleted %d records\n", total);
    58         return 0;
     72        printf("Deleted %u records\n", total);
     73        return LDB_SUCCESS;
    5974}
    6075
    61 static void usage(void)
     76static void usage(struct ldb_context *ldb)
    6277{
    6378        printf("Usage: ldbdel <options> <DN...>\n");
    6479        printf("Deletes records from a ldb\n\n");
    65         ldb_cmdline_help("ldbdel", stdout);
    66         exit(1);
     80        ldb_cmdline_help(ldb, "ldbdel", stdout);
     81        exit(LDB_ERR_OPERATIONS_ERROR);
    6782}
    6883
    6984int main(int argc, const char **argv)
    7085{
     86        struct ldb_control **req_ctrls;
     87        struct ldb_cmdline *options;
    7188        struct ldb_context *ldb;
    7289        int ret = 0, i;
    73         struct ldb_cmdline *options;
     90        TALLOC_CTX *mem_ctx = talloc_new(NULL);
    7491
    75         ldb = ldb_init(NULL, NULL);
     92        ldb = ldb_init(mem_ctx, NULL);
     93        if (ldb == NULL) {
     94                return LDB_ERR_OPERATIONS_ERROR;
     95        }
    7696
    7797        options = ldb_cmdline_process(ldb, argc, argv, usage);
    7898
    7999        if (options->argc < 1) {
    80                 usage();
    81                 exit(1);
     100                usage(ldb);
     101        }
     102
     103        req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls);
     104        if (options->controls != NULL &&  req_ctrls== NULL) {
     105                printf("parsing controls failed: %s\n", ldb_errstring(ldb));
     106                return LDB_ERR_OPERATIONS_ERROR;
    82107        }
    83108
     
    86111
    87112                dn = ldb_dn_new(ldb, ldb, options->argv[i]);
    88                 if ( ! ldb_dn_validate(dn)) {
    89                         printf("Invalid DN format\n");
    90                         exit(1);
     113                if (dn == NULL) {
     114                        return LDB_ERR_OPERATIONS_ERROR;
    91115                }
    92116                if (options->recursive) {
    93                         ret = ldb_delete_recursive(ldb, dn);
     117                        ret = ldb_delete_recursive(ldb, dn,req_ctrls);
    94118                } else {
    95                         ret = ldb_delete(ldb, dn);
    96                         if (ret == 0) {
     119                        ret = ldb_delete_ctrl(ldb, dn,req_ctrls);
     120                        if (ret == LDB_SUCCESS) {
    97121                                printf("Deleted 1 record\n");
    98122                        }
    99123                }
    100                 if (ret != 0) {
    101                         printf("delete of '%s' failed - %s\n",
    102                                 ldb_dn_get_linearized(dn),
    103                                 ldb_errstring(ldb));
     124                if (ret != LDB_SUCCESS) {
     125                        printf("delete of '%s' failed - (%s) %s\n",
     126                               ldb_dn_get_linearized(dn),
     127                               ldb_strerror(ret),
     128                               ldb_errstring(ldb));
    104129                }
    105130        }
    106131
    107         talloc_free(ldb);
     132        talloc_free(mem_ctx);
    108133
    109134        return ret;
  • vendor/current/source4/lib/ldb/tools/ldbedit.c

    r414 r740  
    1 /* 
     1/*
    22   ldb database library
    33
     
    77     ** library. This does NOT imply that all of Samba is released
    88     ** under the LGPL
    9    
     9
    1010   This library is free software; you can redistribute it and/or
    1111   modify it under the terms of the GNU Lesser General Public
     
    3131 *  Author: Andrew Tridgell
    3232 */
    33 #include "ldb_includes.h"
     33
     34#include "replace.h"
     35#include "system/filesys.h"
     36#include "system/time.h"
     37#include "system/filesys.h"
    3438#include "ldb.h"
    3539#include "tools/cmdline.h"
     40#include "tools/ldbutil.h"
    3641
    3742static struct ldb_cmdline *options;
    3843
    3944/*
    40   debug routine 
    41 */
    42 static void ldif_write_msg(struct ldb_context *ldb, 
    43                            FILE *f, 
     45  debug routine
     46*/
     47static void ldif_write_msg(struct ldb_context *ldb,
     48                           FILE *f,
    4449                           enum ldb_changetype changetype,
    4550                           struct ldb_message *msg)
     
    5560  returns the number of modified elements
    5661*/
    57 static int modify_record(struct ldb_context *ldb, 
     62static int modify_record(struct ldb_context *ldb,
    5863                         struct ldb_message *msg1,
    59                          struct ldb_message *msg2)
    60 {
     64                         struct ldb_message *msg2,
     65                         struct ldb_control **req_ctrls)
     66{
     67        int ret;
    6168        struct ldb_message *mod;
    6269
    63         mod = ldb_msg_diff(ldb, msg1, msg2);
    64         if (mod == NULL) {
     70        if (ldb_msg_difference(ldb, ldb, msg1, msg2, &mod) != LDB_SUCCESS) {
    6571                fprintf(stderr, "Failed to calculate message differences\n");
    6672                return -1;
    6773        }
    6874
    69         if (mod->num_elements == 0) {
    70                 return 0;
     75        ret = mod->num_elements;
     76        if (ret == 0) {
     77                goto done;
    7178        }
    7279
     
    7582        }
    7683
    77         if (ldb_modify(ldb, mod) != 0) {
    78                 fprintf(stderr, "failed to modify %s - %s\n", 
     84        if (ldb_modify_ctrl(ldb, mod, req_ctrls) != LDB_SUCCESS) {
     85                fprintf(stderr, "failed to modify %s - %s\n",
    7986                        ldb_dn_get_linearized(msg1->dn), ldb_errstring(ldb));
    80                 return -1;
    81         }
    82 
    83         return mod->num_elements;
     87                ret = -1;
     88                goto done;
     89        }
     90
     91done:
     92        talloc_free(mod);
     93        return ret;
    8494}
    8595
     
    8999static struct ldb_message *msg_find(struct ldb_context *ldb,
    90100                                    struct ldb_message **msgs,
    91                                     int count,
     101                                    unsigned int count,
    92102                                    struct ldb_dn *dn)
    93103{
    94         int i;
     104        unsigned int i;
    95105        for (i=0;i<count;i++) {
    96106                if (ldb_dn_compare(dn, msgs[i]->dn) == 0) {
     
    105115*/
    106116static int merge_edits(struct ldb_context *ldb,
    107                        struct ldb_message **msgs1, int count1,
    108                        struct ldb_message **msgs2, int count2)
    109 {
    110         int i;
     117                       struct ldb_message **msgs1, unsigned int count1,
     118                       struct ldb_message **msgs2, unsigned int count2)
     119{
     120        unsigned int i;
    111121        struct ldb_message *msg;
    112         int ret = 0;
    113         int adds=0, modifies=0, deletes=0;
    114 
    115         if (ldb_transaction_start(ldb) != 0) {
     122        int ret;
     123        unsigned int adds=0, modifies=0, deletes=0;
     124        struct ldb_control **req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls);
     125        if (options->controls != NULL && req_ctrls == NULL) {
     126                fprintf(stderr, "parsing controls failed: %s\n", ldb_errstring(ldb));
     127                return -1;
     128        }
     129
     130        if (ldb_transaction_start(ldb) != LDB_SUCCESS) {
    116131                fprintf(stderr, "Failed to start transaction: %s\n", ldb_errstring(ldb));
    117132                return -1;
     
    125140                                ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_ADD, msgs2[i]);
    126141                        }
    127                         if (ldb_add(ldb, msgs2[i]) != 0) {
     142                        if (ldb_add_ctrl(ldb, msgs2[i], req_ctrls) != LDB_SUCCESS) {
    128143                                fprintf(stderr, "failed to add %s - %s\n",
    129144                                        ldb_dn_get_linearized(msgs2[i]->dn),
     
    134149                        adds++;
    135150                } else {
    136                         if (modify_record(ldb, msg, msgs2[i]) > 0) {
    137                                 modifies++;
     151                        ret = modify_record(ldb, msg, msgs2[i], req_ctrls);
     152                        if (ret != -1) {
     153                                modifies += (unsigned int) ret;
     154                        } else {
     155                                return -1;
    138156                        }
    139157                }
     
    147165                                ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_DELETE, msgs1[i]);
    148166                        }
    149                         if (ldb_delete(ldb, msgs1[i]->dn) != 0) {
     167                        if (ldb_delete_ctrl(ldb, msgs1[i]->dn, req_ctrls) != LDB_SUCCESS) {
    150168                                fprintf(stderr, "failed to delete %s - %s\n",
    151169                                        ldb_dn_get_linearized(msgs1[i]->dn),
     
    158176        }
    159177
    160         if (ldb_transaction_commit(ldb) != 0) {
     178        if (ldb_transaction_commit(ldb) != LDB_SUCCESS) {
    161179                fprintf(stderr, "Failed to commit transaction: %s\n", ldb_errstring(ldb));
    162180                return -1;
    163181        }
    164182
    165         printf("# %d adds  %d modifies  %d deletes\n", adds, modifies, deletes);
    166 
    167         return ret;
     183        printf("# %u adds  %u modifies  %u deletes\n", adds, modifies, deletes);
     184
     185        return 0;
    168186}
    169187
     
    171189  save a set of messages as ldif to a file
    172190*/
    173 static int save_ldif(struct ldb_context *ldb, 
    174                      FILE *f, struct ldb_message **msgs, int count)
    175 {
    176         int i;
    177 
    178         fprintf(f, "# editing %d records\n", count);
     191static int save_ldif(struct ldb_context *ldb,
     192                     FILE *f, struct ldb_message **msgs, unsigned int count)
     193{
     194        unsigned int i;
     195
     196        fprintf(f, "# editing %u records\n", count);
    179197
    180198        for (i=0;i<count;i++) {
    181199                struct ldb_ldif ldif;
    182                 fprintf(f, "# record %d\n", i+1);
     200                fprintf(f, "# record %u\n", i+1);
    183201
    184202                ldif.changetype = LDB_CHANGETYPE_NONE;
     
    195213  edit the ldb search results in msgs using the user selected editor
    196214*/
    197 static int do_edit(struct ldb_context *ldb, struct ldb_message **msgs1, int count1,
    198                    const char *editor)
     215static int do_edit(struct ldb_context *ldb, struct ldb_message **msgs1,
     216                   unsigned int count1, const char *editor)
    199217{
    200218        int fd, ret;
     
    204222        struct ldb_ldif *ldif;
    205223        struct ldb_message **msgs2 = NULL;
    206         int count2 = 0;
     224        unsigned int count2 = 0;
    207225
    208226        /* write out the original set of messages to a temporary
     
    270288}
    271289
    272 static void usage(void)
     290static void usage(struct ldb_context *ldb)
    273291{
    274292        printf("Usage: ldbedit <options> <expression> <attributes ...>\n");
    275         ldb_cmdline_help("ldbedit", stdout);
    276         exit(1);
     293        ldb_cmdline_help(ldb, "ldbedit", stdout);
     294        exit(LDB_ERR_OPERATIONS_ERROR);
    277295}
    278296
     
    285303        const char *expression = "(|(objectClass=*)(distinguishedName=*))";
    286304        const char * const * attrs = NULL;
    287 
    288         ldb = ldb_init(NULL, NULL);
     305        TALLOC_CTX *mem_ctx = talloc_new(NULL);
     306        struct ldb_control **req_ctrls;
     307
     308        ldb = ldb_init(mem_ctx, NULL);
     309        if (ldb == NULL) {
     310                return LDB_ERR_OPERATIONS_ERROR;
     311        }
    289312
    290313        options = ldb_cmdline_process(ldb, argc, argv, usage);
    291314
    292315        /* the check for '=' is for compatibility with ldapsearch */
    293         if (options->argc > 0 && 
     316        if (options->argc > 0 &&
    294317            strchr(options->argv[0], '=')) {
    295318                expression = options->argv[0];
     
    304327        if (options->basedn != NULL) {
    305328                basedn = ldb_dn_new(ldb, ldb, options->basedn);
    306                 if ( ! ldb_dn_validate(basedn)) {
    307                         printf("Invalid Base DN format\n");
    308                         exit(1);
    309                 }
    310         }
    311 
    312         ret = ldb_search(ldb, ldb, &result, basedn, options->scope, attrs, "%s", expression);
     329                if (basedn == NULL) {
     330                        return LDB_ERR_OPERATIONS_ERROR;
     331                }
     332        }
     333
     334        req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls);
     335        if (options->controls != NULL &&  req_ctrls== NULL) {
     336                printf("parsing controls failed: %s\n", ldb_errstring(ldb));
     337                return LDB_ERR_OPERATIONS_ERROR;
     338        }
     339
     340        ret = ldb_search_ctrl(ldb, ldb, &result, basedn, options->scope, attrs, req_ctrls, "%s", expression);
    313341        if (ret != LDB_SUCCESS) {
    314342                printf("search failed - %s\n", ldb_errstring(ldb));
    315                 exit(1);
     343                return ret;
    316344        }
    317345
    318346        if (result->count == 0) {
    319347                printf("no matching records - cannot edit\n");
    320                 return 0;
    321         }
    322 
    323         do_edit(ldb, result->msgs, result->count, options->editor);
    324 
    325         if (result) {
    326                 ret = talloc_free(result);
    327                 if (ret == -1) {
    328                         fprintf(stderr, "talloc_free failed\n");
    329                         exit(1);
    330                 }
    331         }
    332 
    333         talloc_free(ldb);
    334         return 0;
    335 }
     348                talloc_free(mem_ctx);
     349                return LDB_SUCCESS;
     350        }
     351
     352        ret = do_edit(ldb, result->msgs, result->count, options->editor);
     353
     354        talloc_free(mem_ctx);
     355
     356        return ret == 0 ? LDB_SUCCESS : LDB_ERR_OPERATIONS_ERROR;
     357}
  • vendor/current/source4/lib/ldb/tools/ldbmodify.c

    r414 r740  
    3434#include "ldb.h"
    3535#include "tools/cmdline.h"
     36#include "ldbutil.h"
    3637
    37 static int failures;
     38static unsigned int failures;
     39static struct ldb_cmdline *options;
    3840
    39 static void usage(void)
     41static void usage(struct ldb_context *ldb)
    4042{
    4143        printf("Usage: ldbmodify <options> <ldif...>\n");
    4244        printf("Modifies a ldb based upon ldif change records\n\n");
    43         ldb_cmdline_help("ldbmodify", stdout);
    44         exit(1);
     45        ldb_cmdline_help(ldb, "ldbmodify", stdout);
     46        exit(LDB_ERR_OPERATIONS_ERROR);
    4547}
    4648
     
    4850  process modifies for one file
    4951*/
    50 static int process_file(struct ldb_context *ldb, FILE *f, int *count)
     52static int process_file(struct ldb_context *ldb, FILE *f, unsigned int *count)
    5153{
    5254        struct ldb_ldif *ldif;
    5355        int ret = LDB_SUCCESS;
    54        
     56        struct ldb_control **req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls);
     57
     58        if (options->controls != NULL &&  req_ctrls== NULL) {
     59                printf("parsing controls failed: %s\n", ldb_errstring(ldb));
     60                exit(LDB_ERR_OPERATIONS_ERROR);
     61        }
     62
    5563        while ((ldif = ldb_ldif_read_file(ldb, f))) {
    5664                switch (ldif->changetype) {
    5765                case LDB_CHANGETYPE_NONE:
    5866                case LDB_CHANGETYPE_ADD:
    59                         ret = ldb_add(ldb, ldif->msg);
     67                        ret = ldb_add_ctrl(ldb, ldif->msg,req_ctrls);
    6068                        break;
    6169                case LDB_CHANGETYPE_DELETE:
    62                         ret = ldb_delete(ldb, ldif->msg->dn);
     70                        ret = ldb_delete_ctrl(ldb, ldif->msg->dn,req_ctrls);
    6371                        break;
    6472                case LDB_CHANGETYPE_MODIFY:
    65                         ret = ldb_modify(ldb, ldif->msg);
     73                        ret = ldb_modify_ctrl(ldb, ldif->msg,req_ctrls);
    6674                        break;
    6775                }
    6876                if (ret != LDB_SUCCESS) {
    69                         fprintf(stderr, "ERR: \"%s\" on DN %s\n",
     77                        fprintf(stderr, "ERR: (%s) \"%s\" on DN %s\n",
     78                                ldb_strerror(ret),
    7079                                ldb_errstring(ldb), ldb_dn_get_linearized(ldif->msg->dn));
    7180                        failures++;
    7281                } else {
    7382                        (*count)++;
     83                        if (options->verbose) {
     84                                printf("Modified %s\n", ldb_dn_get_linearized(ldif->msg->dn));
     85                        }
    7486                }
    7587                ldb_ldif_read_free(ldb, ldif);
     
    8294{
    8395        struct ldb_context *ldb;
    84         int count=0;
    85         int i, ret=LDB_SUCCESS;
    86         struct ldb_cmdline *options;
     96        unsigned int i, count = 0;
     97        int ret = LDB_SUCCESS;
     98        TALLOC_CTX *mem_ctx = talloc_new(NULL);
    8799
    88         ldb = ldb_init(NULL, NULL);
     100        ldb = ldb_init(mem_ctx, NULL);
     101        if (ldb == NULL) {
     102                return LDB_ERR_OPERATIONS_ERROR;
     103        }
    89104
    90105        options = ldb_cmdline_process(ldb, argc, argv, usage);
     
    99114                        if (!f) {
    100115                                perror(fname);
    101                                 exit(1);
     116                                return LDB_ERR_OPERATIONS_ERROR;
    102117                        }
    103118                        ret = process_file(ldb, f, &count);
     
    106121        }
    107122
    108         talloc_free(ldb);
     123        talloc_free(mem_ctx);
    109124
    110         printf("Modified %d records with %d failures\n", count, failures);
     125        printf("Modified %u records with %u failures\n", count, failures);
    111126
    112127        return ret;
  • vendor/current/source4/lib/ldb/tools/ldbrename.c

    r414 r740  
    3737#include "tools/cmdline.h"
    3838
    39 static void usage(void)
     39static void usage(struct ldb_context *ldb)
    4040{
    4141        printf("Usage: ldbrename [<options>] <olddn> <newdn>\n");
    4242        printf("Renames records in a ldb\n\n");
    43         ldb_cmdline_help("ldbmodify", stdout);
    44         exit(1);
     43        ldb_cmdline_help(ldb, "ldbmodify", stdout);
     44        exit(LDB_ERR_OPERATIONS_ERROR);
    4545}
    4646
     
    5252        struct ldb_cmdline *options;
    5353        struct ldb_dn *dn1, *dn2;
     54        TALLOC_CTX *mem_ctx = talloc_new(NULL);
    5455
    55         ldb = ldb_init(NULL, NULL);
     56        ldb = ldb_init(mem_ctx, NULL);
     57        if (ldb == NULL) {
     58                return LDB_ERR_OPERATIONS_ERROR;
     59        }
    5660
    5761        options = ldb_cmdline_process(ldb, argc, argv, usage);
    5862
    5963        if (options->argc < 2) {
    60                 usage();
     64                usage(ldb);
    6165        }
    6266
    6367        dn1 = ldb_dn_new(ldb, ldb, options->argv[0]);
    6468        dn2 = ldb_dn_new(ldb, ldb, options->argv[1]);
    65 
    66         if ( ! ldb_dn_validate(dn1)) {
    67                 printf("Invalid DN1: %s\n", options->argv[0]);
    68                 return -1;
    69         }
    70         if ( ! ldb_dn_validate(dn2)) {
    71                 printf("Invalid DN2: %s\n", options->argv[1]);
    72                 return -1;
     69        if ((dn1 == NULL) || (dn2 == NULL)) {
     70                return LDB_ERR_OPERATIONS_ERROR;
    7371        }
    7472
    7573        ret = ldb_rename(ldb, dn1, dn2);
    76         if (ret == 0) {
     74        if (ret == LDB_SUCCESS) {
    7775                printf("Renamed 1 record\n");
    7876        } else  {
     
    8179        }
    8280
    83         talloc_free(ldb);
     81        talloc_free(mem_ctx);
    8482       
    8583        return ret;
  • vendor/current/source4/lib/ldb/tools/ldbsearch.c

    r414 r740  
    3232 */
    3333
    34 #include "ldb_includes.h"
     34#include "replace.h"
     35#include "system/filesys.h"
     36#include "system/time.h"
    3537#include "ldb.h"
    3638#include "tools/cmdline.h"
    3739
    38 static void usage(void)
     40static void usage(struct ldb_context *ldb)
    3941{
    4042        printf("Usage: ldbsearch <options> <expression> <attrs...>\n");
    41         ldb_cmdline_help("ldbsearch", stdout);
    42         exit(1);
     43        ldb_cmdline_help(ldb, "ldbsearch", stdout);
     44        exit(LDB_ERR_OPERATIONS_ERROR);
    4345}
    4446
     
    5557
    5658        int sort;
    57         int num_stored;
     59        unsigned int num_stored;
    5860        struct ldb_message **store;
    59         int refs_stored;
     61        unsigned int refs_stored;
    6062        char **refs_store;
    6163
    62         int entries;
    63         int refs;
    64 
    65         int pending;
     64        unsigned int entries;
     65        unsigned int refs;
     66
     67        unsigned int pending;
    6668        int status;
    6769};
     
    132134{
    133135        struct search_context *sctx;
    134         int ret;
     136        int ret = LDB_SUCCESS;
    135137
    136138        sctx = talloc_get_type(req->context, struct search_context);
     
    173175
    174176        talloc_free(ares);
    175         if (ret) {
     177        if (ret != LDB_SUCCESS) {
    176178                return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
    177179        }
     
    192194        req = NULL;
    193195       
    194         sctx = talloc(ldb, struct search_context);
    195         if (!sctx) return -1;
     196        sctx = talloc_zero(ldb, struct search_context);
     197        if (!sctx) return LDB_ERR_OPERATIONS_ERROR;
    196198
    197199        sctx->ldb = ldb;
    198200        sctx->sort = options->sorted;
    199         sctx->num_stored = 0;
    200         sctx->refs_stored = 0;
    201         sctx->store = NULL;
    202201        sctx->req_ctrls = ldb_parse_control_strings(ldb, sctx, (const char **)options->controls);
    203202        if (options->controls != NULL &&  sctx->req_ctrls== NULL) {
    204203                printf("parsing controls failed: %s\n", ldb_errstring(ldb));
    205                 return -1;
    206         }
    207         sctx->entries = 0;
    208         sctx->refs = 0;
     204                return LDB_ERR_OPERATIONS_ERROR;
     205        }
    209206
    210207        if (basedn == NULL) {
     
    225222                talloc_free(sctx);
    226223                printf("allocating request failed: %s\n", ldb_errstring(ldb));
    227                 return -1;
     224                return ret;
    228225        }
    229226
     
    233230        if (ret != LDB_SUCCESS) {
    234231                printf("search failed - %s\n", ldb_errstring(ldb));
    235                 return -1;
     232                return ret;
    236233        }
    237234
    238235        ret = ldb_wait(req->handle, LDB_WAIT_ALL);
    239         if (ret != LDB_SUCCESS) {
     236        if (ret != LDB_SUCCESS) {
    240237                printf("search error - %s\n", ldb_errstring(ldb));
    241                 return -1;
     238                return ret;
    242239        }
    243240
     
    246243
    247244        if (sctx->sort && (sctx->num_stored != 0 || sctx->refs != 0)) {
    248                 int i;
     245                unsigned int i;
    249246
    250247                if (sctx->num_stored) {
    251                         ldb_qsort(sctx->store, sctx->num_stored, sizeof(struct ldb_message *),
    252                                   ldb, (ldb_qsort_cmp_fn_t)do_compare_msg);
     248                        LDB_TYPESAFE_QSORT(sctx->store, sctx->num_stored, ldb, do_compare_msg);
    253249                }
    254250                for (i = 0; i < sctx->num_stored; i++) {
     
    261257        }
    262258
    263         printf("# returned %d records\n# %d entries\n# %d referrals\n",
     259        printf("# returned %u records\n# %u entries\n# %u referrals\n",
    264260                sctx->entries + sctx->refs, sctx->entries, sctx->refs);
    265261
     
    267263        talloc_free(req);
    268264
    269         return 0;
     265        return LDB_SUCCESS;
    270266}
    271267
     
    278274        int ret = -1;
    279275        const char *expression = "(|(objectClass=*)(distinguishedName=*))";
    280 
    281         ldb = ldb_init(NULL, NULL);
     276        TALLOC_CTX *mem_ctx = talloc_new(NULL);
     277
     278        ldb = ldb_init(mem_ctx, NULL);
    282279        if (ldb == NULL) {
    283                 return -1;
     280                return LDB_ERR_OPERATIONS_ERROR;
    284281        }
    285282
     
    301298        if (options->basedn != NULL) {
    302299                basedn = ldb_dn_new(ldb, ldb, options->basedn);
    303                 if ( ! ldb_dn_validate(basedn)) {
    304                         fprintf(stderr, "Invalid Base DN format\n");
    305                         exit(1);
     300                if (basedn == NULL) {
     301                        return LDB_ERR_OPERATIONS_ERROR;
    306302                }
    307303        }
     
    310306                char line[1024];
    311307                while (fgets(line, sizeof(line), stdin)) {
    312                         if (do_search(ldb, basedn, options, line, attrs) == -1) {
    313                                 ret = -1;
    314                         }
     308                        ret = do_search(ldb, basedn, options, line, attrs);
    315309                }
    316310        } else {
     
    318312        }
    319313
    320         talloc_free(ldb);
     314        talloc_free(mem_ctx);
     315
    321316        return ret;
    322317}
  • vendor/current/source4/lib/ldb/tools/ldbtest.c

    r414 r740  
    3232 */
    3333
    34 #include "ldb_includes.h"
     34#include "replace.h"
     35#include "system/filesys.h"
     36#include "system/time.h"
    3537#include "ldb.h"
    3638#include "tools/cmdline.h"
    3739
    38 static struct timeval tp1,tp2;
     40static struct timespec tp1,tp2;
    3941static struct ldb_cmdline *options;
    4042
    4143static void _start_timer(void)
    4244{
    43         gettimeofday(&tp1,NULL);
     45        if (clock_gettime(CUSTOM_CLOCK_MONOTONIC, &tp1) != 0) {
     46                clock_gettime(CLOCK_REALTIME, &tp1);
     47        }
    4448}
    4549
    4650static double _end_timer(void)
    4751{
    48         gettimeofday(&tp2,NULL);
     52        if (clock_gettime(CUSTOM_CLOCK_MONOTONIC, &tp2) != 0) {
     53                clock_gettime(CLOCK_REALTIME, &tp2);
     54        }
    4955        return((tp2.tv_sec - tp1.tv_sec) +
    50                (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
     56               (tp2.tv_nsec - tp1.tv_nsec)*1.0e-9);
    5157}
    5258
    5359static void add_records(struct ldb_context *ldb,
    5460                        struct ldb_dn *basedn,
    55                         int count)
     61                        unsigned int count)
    5662{
    5763        struct ldb_message msg;
    58         int i;
     64        unsigned int i;
    5965
    6066#if 0
    6167        if (ldb_lock(ldb, "transaction") != 0) {
    6268                printf("transaction lock failed\n");
    63                 exit(1);
     69                exit(LDB_ERR_OPERATIONS_ERROR);
    6470        }
    6571#endif
     
    123129                if (ldb_add(ldb, &msg) != 0) {
    124130                        printf("Add of %s failed - %s\n", name, ldb_errstring(ldb));
    125                         exit(1);
     131                        exit(LDB_ERR_OPERATIONS_ERROR);
    126132                }
    127133
     
    134140        if (ldb_unlock(ldb, "transaction") != 0) {
    135141                printf("transaction unlock failed\n");
    136                 exit(1);
     142                exit(LDB_ERR_OPERATIONS_ERROR);
    137143        }
    138144#endif
     
    142148static void modify_records(struct ldb_context *ldb,
    143149                           struct ldb_dn *basedn,
    144                            int count)
     150                           unsigned int count)
    145151{
    146152        struct ldb_message msg;
    147         int i;
     153        unsigned int i;
    148154
    149155        for (i=0;i<count;i++) {
     
    180186                if (ldb_modify(ldb, &msg) != 0) {
    181187                        printf("Modify of %s failed - %s\n", name, ldb_errstring(ldb));
    182                         exit(1);
     188                        exit(LDB_ERR_OPERATIONS_ERROR);
    183189                }
    184190
     
    195201static void delete_records(struct ldb_context *ldb,
    196202                           struct ldb_dn *basedn,
    197                            int count)
    198 {
    199         int i;
     203                           unsigned int count)
     204{
     205        unsigned int i;
    200206
    201207        for (i=0;i<count;i++) {
     
    210216                if (ldb_delete(ldb, dn) != 0) {
    211217                        printf("Delete of %s failed - %s\n", ldb_dn_get_linearized(dn), ldb_errstring(ldb));
    212                         exit(1);
     218                        exit(LDB_ERR_OPERATIONS_ERROR);
    213219                }
    214220                talloc_free(name);
     
    218224}
    219225
    220 static void search_uid(struct ldb_context *ldb, struct ldb_dn *basedn, int nrecords, int nsearches)
    221 {
    222         int i;
     226static void search_uid(struct ldb_context *ldb, struct ldb_dn *basedn,
     227                       unsigned int nrecords, unsigned int nsearches)
     228{
     229        unsigned int i;
    223230
    224231        for (i=0;i<nsearches;i++) {
     
    233240                if (ret != LDB_SUCCESS || (uid < nrecords && res->count != 1)) {
    234241                        printf("Failed to find %s - %s\n", expr, ldb_errstring(ldb));
    235                         exit(1);
     242                        exit(LDB_ERR_OPERATIONS_ERROR);
    236243                }
    237244
    238245                if (uid >= nrecords && res->count > 0) {
    239246                        printf("Found %s !? - %d\n", expr, ret);
    240                         exit(1);
     247                        exit(LDB_ERR_OPERATIONS_ERROR);
    241248                }
    242249
    243                 printf("testing uid %d/%d - %d  \r", i, uid, res->count);
     250                printf("Testing uid %d/%d - %d  \r", i, uid, res->count);
    244251                fflush(stdout);
    245252
     
    251258}
    252259
    253 static void start_test(struct ldb_context *ldb, int nrecords, int nsearches)
     260static void start_test(struct ldb_context *ldb, unsigned int nrecords,
     261                       unsigned int nsearches)
    254262{
    255263        struct ldb_dn *basedn;
     
    257265        basedn = ldb_dn_new(ldb, ldb, options->basedn);
    258266        if ( ! ldb_dn_validate(basedn)) {
    259                 printf("Invalid base DN\n");
    260                 exit(1);
     267                printf("Invalid base DN format\n");
     268                exit(LDB_ERR_INVALID_DN_SYNTAX);
    261269        }
    262270
     
    323331        if (ldb_add(*ldb, msg) != 0) {
    324332                printf("Add of %s failed - %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(*ldb));
    325                 exit(1);
     333                exit(LDB_ERR_OPERATIONS_ERROR);
    326334        }
    327335
     
    338346        if (ldb_add(*ldb, msg) != 0) {
    339347                printf("Add of %s failed - %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(*ldb));
    340                 exit(1);
     348                exit(LDB_ERR_OPERATIONS_ERROR);
    341349        }
    342350
    343351        if (talloc_free(*ldb) != 0) {
    344352                printf("failed to free/close ldb database");
    345                 exit(1);
     353                exit(LDB_ERR_OPERATIONS_ERROR);
    346354        }
    347355
     
    351359        if (ret != 0) {
    352360                printf("failed to connect to %s\n", options->url);
    353                 exit(1);
     361                exit(LDB_ERR_OPERATIONS_ERROR);
    354362        }
    355363
    356364        basedn = ldb_dn_new(*ldb, *ldb, options->basedn);
     365        msg->dn = basedn;
     366        ldb_dn_add_child_fmt(msg->dn, "cn=test");
    357367
    358368        ret = ldb_search(*ldb, *ldb, &res, basedn, LDB_SCOPE_SUBTREE, NULL, "uid=test");
    359369        if (ret != LDB_SUCCESS) {
    360370                printf("Search with (uid=test) filter failed!\n");
    361                 exit(1);
     371                exit(LDB_ERR_OPERATIONS_ERROR);
    362372        }
    363373        if(res->count != 1) {
    364374                printf("Should have found 1 record - found %d\n", res->count);
    365                 exit(1);
     375                exit(LDB_ERR_OPERATIONS_ERROR);
    366376        }
    367377
     
    371381            ldb_delete(*ldb, indexlist) != 0) {
    372382                printf("cleanup failed - %s\n", ldb_errstring(*ldb));
    373                 exit(1);
     383                exit(LDB_ERR_OPERATIONS_ERROR);
    374384        }
    375385
     
    378388
    379389
    380 static void usage(void)
     390static void usage(struct ldb_context *ldb)
    381391{
    382392        printf("Usage: ldbtest <options>\n");
     
    387397        printf("\n");
    388398        printf("tests ldb API\n\n");
    389         exit(1);
     399        exit(LDB_ERR_OPERATIONS_ERROR);
    390400}
    391401
     
    396406
    397407        ldb = ldb_init(mem_ctx, NULL);
     408        if (ldb == NULL) {
     409                return LDB_ERR_OPERATIONS_ERROR;
     410        }
    398411
    399412        options = ldb_cmdline_process(ldb, argc, argv, usage);
     
    410423               options->num_records, options->num_searches);
    411424
    412         start_test(ldb, options->num_records, options->num_searches);
     425        start_test(ldb,
     426                   (unsigned int) options->num_records,
     427                   (unsigned int) options->num_searches);
    413428
    414429        start_test_index(&ldb);
     
    416431        talloc_free(mem_ctx);
    417432
    418         return 0;
    419 }
     433        return LDB_SUCCESS;
     434}
  • vendor/current/source4/lib/ldb/web/index.html

    r414 r740  
    5151<h2>Discussion and bug reports</h2>
    5252
    53 ldb does not currently have its own mailing list or bug tracking
    54 system. For now, please use the <a
    55 href="https://lists.samba.org/mailman/listinfo/samba-technical">samba-technical</a>
    56 mailing list or the <a href="https://lists.samba.org/mailman/listinfo/ldb">ldb</a>
    57 mailing list, and the <a href="http://bugzilla.samba.org/">Samba bugzilla</a> bug tracking system.
     53ldb does not have its own mailing list or bug tracking system. Please
     54use
     55the <a href="https://lists.samba.org/mailman/listinfo/samba-technical">samba-technical</a>
     56mailing list, and the <a href="http://bugzilla.samba.org/">Samba
     57bugzilla</a> bug tracking system.
    5858
    5959<h2>Download</h2>
    6060
    61 You can download the latest release either via rsync or thtough git.<br>
    62 <br>
    63 To fetch via git see the following guide:<br>
     61You can download the latest release here:<br>
     62 <a href="http://samba.org/ftp/pub/ldb">http://samba.org/ftp/pub/ldb</a>
     63
     64Alternatively, you can fetch via git. See the following guide:<br>
    6465<a href="http://wiki.samba.org/index.php/Using_Git_for_Samba_Development">Using Git for Samba Development</a><br>
    65 Once you have cloned the tree switch to the v4-0-test branch and cd into the source/lib/ldb directory.<br>
    66 <br>
    67 To fetch via rsync use these commands:
    68 
    69 <pre>
    70   rsync -Pavz samba.org::ftp/unpacked/ldb .
    71   rsync -Pavz samba.org::ftp/unpacked/tdb .
    72   rsync -Pavz samba.org::ftp/unpacked/talloc .
    73   rsync -Pavz samba.org::ftp/unpacked/libreplace .
    74 </pre>
    75 
    76 and build in ldb. It will find the other libraries in the directory
    77 above automatically.
    7866
    7967<hr>
Note: See TracChangeset for help on using the changeset viewer.