root/source4/lib/ldb/common/ldb.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ldb_context_destructor
  2. ldb_tevent_debug
  3. ldb_init
  4. ldb_set_default_dns
  5. ldb_get_root_basedn
  6. ldb_get_config_basedn
  7. ldb_get_schema_basedn
  8. ldb_get_default_basedn
  9. ldb_connect
  10. ldb_set_errstring
  11. ldb_asprintf_errstring
  12. ldb_reset_err_string
  13. ldb_transaction_start
  14. ldb_transaction_commit
  15. ldb_transaction_cancel
  16. ldb_autotransaction_request
  17. ldb_wait
  18. ldb_set_timeout
  19. ldb_set_timeout_from_prev_req
  20. ldb_set_create_perms
  21. ldb_get_create_perms
  22. ldb_set_event_context
  23. ldb_get_event_context
  24. ldb_request_set_state
  25. ldb_request_get_status
  26. ldb_request
  27. ldb_request_done
  28. ldb_search_default_callback
  29. ldb_op_default_callback
  30. ldb_build_search_req_ex
  31. ldb_build_search_req
  32. ldb_build_add_req
  33. ldb_build_mod_req
  34. ldb_build_del_req
  35. ldb_build_rename_req
  36. ldb_extended_default_callback
  37. ldb_build_extended_req
  38. ldb_extended
  39. ldb_search
  40. ldb_add
  41. ldb_modify
  42. ldb_delete
  43. ldb_rename
  44. ldb_sequence_number
  45. ldb_errstring
  46. ldb_strerror
  47. ldb_set_opaque
  48. ldb_get_opaque

   1 /*
   2    ldb database library
   3 
   4    Copyright (C) Andrew Tridgell  2004
   5    Copyright (C) Simo Sorce  2005-2008
   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
  10 
  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,
  17    but WITHOUT ANY WARRANTY; without even the implied warranty of
  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/>.
  23 */
  24 
  25 /*
  26  *  Name: ldb
  27  *
  28  *  Component: ldb core API
  29  *
  30  *  Description: core API routines interfacing to ldb backends
  31  *
  32  *  Author: Andrew Tridgell
  33  */
  34 
  35 #define TEVENT_DEPRECATED 1
  36 #include "ldb_private.h"
  37 
  38 static int ldb_context_destructor(void *ptr)
     /* [<][>][^][v][top][bottom][index][help] */
  39 {
  40         struct ldb_context *ldb = talloc_get_type(ptr, struct ldb_context);
  41 
  42         if (ldb->transaction_active) {
  43                 ldb_debug(ldb, LDB_DEBUG_FATAL,
  44                           "A transaction is still active in ldb context [%p]",
  45                           ldb);
  46         }
  47 
  48         return 0;
  49 }
  50 
  51 /*
  52   this is used to catch debug messages from events
  53 */
  54 static void ldb_tevent_debug(void *context, enum tevent_debug_level level,
     /* [<][>][^][v][top][bottom][index][help] */
  55                              const char *fmt, va_list ap)  PRINTF_ATTRIBUTE(3,0);
  56 
  57 static void ldb_tevent_debug(void *context, enum tevent_debug_level level,
  58                              const char *fmt, va_list ap)
  59 {
  60         struct ldb_context *ldb = talloc_get_type(context, struct ldb_context);
  61         enum ldb_debug_level ldb_level = LDB_DEBUG_FATAL;
  62         char *s = NULL;
  63 
  64         switch (level) {
  65         case TEVENT_DEBUG_FATAL:
  66                 ldb_level = LDB_DEBUG_FATAL;
  67                 break;
  68         case TEVENT_DEBUG_ERROR:
  69                 ldb_level = LDB_DEBUG_ERROR;
  70                 break;
  71         case TEVENT_DEBUG_WARNING:
  72                 ldb_level = LDB_DEBUG_WARNING;
  73                 break;
  74         case TEVENT_DEBUG_TRACE:
  75                 ldb_level = LDB_DEBUG_TRACE;
  76                 break;
  77         };
  78 
  79         vasprintf(&s, fmt, ap);
  80         if (!s) return;
  81         ldb_debug(ldb, ldb_level, "tevent: %s", s);
  82         free(s);
  83 }
  84 
  85 /*
  86    initialise a ldb context
  87    The mem_ctx is required
  88    The event_ctx is required
  89 */
  90 struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx)
     /* [<][>][^][v][top][bottom][index][help] */
  91 {
  92         struct ldb_context *ldb;
  93         int ret;
  94 
  95         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 */
  98         if (ev_ctx == NULL) {
  99                 ev_ctx = tevent_context_init(talloc_autofree_context());
 100                 tevent_set_debug(ev_ctx, ldb_tevent_debug, ldb);
 101                 tevent_loop_allow_nesting(ev_ctx);
 102         }
 103 
 104         ret = ldb_setup_wellknown_attributes(ldb);
 105         if (ret != 0) {
 106                 talloc_free(ldb);
 107                 return NULL;
 108         }
 109 
 110         ldb_set_utf8_default(ldb);
 111         ldb_set_create_perms(ldb, 0666);
 112         ldb_set_modules_dir(ldb, LDB_MODULESDIR);
 113         ldb_set_event_context(ldb, ev_ctx);
 114 
 115         /* TODO: get timeout from options if available there */
 116         ldb->default_timeout = 300; /* set default to 5 minutes */
 117 
 118         talloc_set_destructor((TALLOC_CTX *)ldb, ldb_context_destructor);
 119 
 120         return ldb;
 121 }
 122 
 123 /*
 124   try to autodetect a basedn if none specified. This fixes one of my
 125   pet hates about ldapsearch, which is that you have to get a long,
 126   complex basedn right to make any use of it.
 127 */
 128 void ldb_set_default_dns(struct ldb_context *ldb)
     /* [<][>][^][v][top][bottom][index][help] */
 129 {
 130         TALLOC_CTX *tmp_ctx;
 131         int ret;
 132         struct ldb_result *res;
 133         struct ldb_dn *tmp_dn=NULL;
 134         static const char *attrs[] = {
 135                 "rootDomainNamingContext",
 136                 "configurationNamingContext",
 137                 "schemaNamingContext",
 138                 "defaultNamingContext",
 139                 NULL
 140         };
 141 
 142         tmp_ctx = talloc_new(ldb);
 143         ret = ldb_search(ldb, tmp_ctx, &res, ldb_dn_new(tmp_ctx, ldb, NULL),
 144                          LDB_SCOPE_BASE, attrs, "(objectClass=*)");
 145         if (ret != LDB_SUCCESS) {
 146                 talloc_free(tmp_ctx);
 147                 return;
 148         }
 149 
 150         if (res->count != 1) {
 151                 talloc_free(tmp_ctx);
 152                 return;
 153         }
 154 
 155         if (!ldb_get_opaque(ldb, "rootDomainNamingContext")) {
 156                 tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0],
 157                                                  "rootDomainNamingContext");
 158                 ldb_set_opaque(ldb, "rootDomainNamingContext", tmp_dn);
 159         }
 160 
 161         if (!ldb_get_opaque(ldb, "configurationNamingContext")) {
 162                 tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0],
 163                                                  "configurationNamingContext");
 164                 ldb_set_opaque(ldb, "configurationNamingContext", tmp_dn);
 165         }
 166 
 167         if (!ldb_get_opaque(ldb, "schemaNamingContext")) {
 168                 tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0],
 169                                                  "schemaNamingContext");
 170                 ldb_set_opaque(ldb, "schemaNamingContext", tmp_dn);
 171         }
 172 
 173         if (!ldb_get_opaque(ldb, "defaultNamingContext")) {
 174                 tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0],
 175                                                  "defaultNamingContext");
 176                 ldb_set_opaque(ldb, "defaultNamingContext", tmp_dn);
 177         }
 178 
 179         talloc_free(tmp_ctx);
 180 }
 181 
 182 struct ldb_dn *ldb_get_root_basedn(struct ldb_context *ldb)
     /* [<][>][^][v][top][bottom][index][help] */
 183 {
 184         void *opaque = ldb_get_opaque(ldb, "rootDomainNamingContext");
 185         return talloc_get_type(opaque, struct ldb_dn);
 186 }
 187 
 188 struct ldb_dn *ldb_get_config_basedn(struct ldb_context *ldb)
     /* [<][>][^][v][top][bottom][index][help] */
 189 {
 190         void *opaque = ldb_get_opaque(ldb, "configurationNamingContext");
 191         return talloc_get_type(opaque, struct ldb_dn);
 192 }
 193 
 194 struct ldb_dn *ldb_get_schema_basedn(struct ldb_context *ldb)
     /* [<][>][^][v][top][bottom][index][help] */
 195 {
 196         void *opaque = ldb_get_opaque(ldb, "schemaNamingContext");
 197         return talloc_get_type(opaque, struct ldb_dn);
 198 }
 199 
 200 struct ldb_dn *ldb_get_default_basedn(struct ldb_context *ldb)
     /* [<][>][^][v][top][bottom][index][help] */
 201 {
 202         void *opaque = ldb_get_opaque(ldb, "defaultNamingContext");
 203         return talloc_get_type(opaque, struct ldb_dn);
 204 }
 205 
 206 /*
 207    connect to a database. The URL can either be one of the following forms
 208    ldb://path
 209    ldapi://path
 210 
 211    flags is made up of LDB_FLG_*
 212 
 213    the options are passed uninterpreted to the backend, and are
 214    backend specific
 215 */
 216 int ldb_connect(struct ldb_context *ldb, const char *url,
     /* [<][>][^][v][top][bottom][index][help] */
 217                 unsigned int flags, const char *options[])
 218 {
 219         int ret;
 220         const char *url2;
 221         /* We seem to need to do this here, or else some utilities don't
 222          * get ldb backends */
 223 
 224         ldb->flags = flags;
 225 
 226         url2 = talloc_strdup(ldb, url);
 227         if (!url2) {
 228                 ldb_oom(ldb);
 229                 return LDB_ERR_OPERATIONS_ERROR;
 230         }
 231         ret = ldb_set_opaque(ldb, "ldb_url", talloc_strdup(ldb, url2));
 232         if (ret != LDB_SUCCESS) {
 233                 return ret;
 234         }
 235 
 236         ret = ldb_connect_backend(ldb, url, options, &ldb->modules);
 237         if (ret != LDB_SUCCESS) {
 238                 return ret;
 239         }
 240 
 241         if (ldb_load_modules(ldb, options) != LDB_SUCCESS) {
 242                 ldb_debug(ldb, LDB_DEBUG_FATAL,
 243                           "Unable to load modules for %s: %s\n",
 244                           url, ldb_errstring(ldb));
 245                 return LDB_ERR_OTHER;
 246         }
 247 
 248         /* set the default base dn */
 249         ldb_set_default_dns(ldb);
 250 
 251         return LDB_SUCCESS;
 252 }
 253 
 254 void ldb_set_errstring(struct ldb_context *ldb, const char *err_string)
     /* [<][>][^][v][top][bottom][index][help] */
 255 {
 256         if (ldb->err_string) {
 257                 talloc_free(ldb->err_string);
 258         }
 259         ldb->err_string = talloc_strdup(ldb, err_string);
 260 }
 261 
 262 void ldb_asprintf_errstring(struct ldb_context *ldb, const char *format, ...)
     /* [<][>][^][v][top][bottom][index][help] */
 263 {
 264         va_list ap;
 265         char *old_string = NULL;
 266 
 267         if (ldb->err_string) {
 268                 old_string = ldb->err_string;
 269         }
 270 
 271         va_start(ap, format);
 272         ldb->err_string = talloc_vasprintf(ldb, format, ap);
 273         va_end(ap);
 274         talloc_free(old_string);
 275 }
 276 
 277 void ldb_reset_err_string(struct ldb_context *ldb)
     /* [<][>][^][v][top][bottom][index][help] */
 278 {
 279         if (ldb->err_string) {
 280                 talloc_free(ldb->err_string);
 281                 ldb->err_string = NULL;
 282         }
 283 }
 284 
 285 #define FIRST_OP(ldb, op) do { \
 286         module = ldb->modules;                                  \
 287         while (module && module->ops->op == NULL) module = module->next; \
 288         if (module == NULL) {                                           \
 289                 ldb_asprintf_errstring(ldb, "unable to find module or backend to handle operation: " #op); \
 290                 return LDB_ERR_OPERATIONS_ERROR;                        \
 291         } \
 292 } while (0)
 293 
 294 /*
 295   start a transaction
 296 */
 297 int ldb_transaction_start(struct ldb_context *ldb)
     /* [<][>][^][v][top][bottom][index][help] */
 298 {
 299         struct ldb_module *module;
 300         int status;
 301 
 302         ldb_debug(ldb, LDB_DEBUG_TRACE,
 303                   "start ldb transaction (nesting: %d)",
 304                   ldb->transaction_active);
 305 
 306         /* explicit transaction active, count nested requests */
 307         if (ldb->transaction_active) {
 308                 ldb->transaction_active++;
 309                 return LDB_SUCCESS;
 310         }
 311 
 312         /* start a new transaction */
 313         ldb->transaction_active++;
 314 
 315         FIRST_OP(ldb, start_transaction);
 316 
 317         ldb_reset_err_string(ldb);
 318 
 319         status = module->ops->start_transaction(module);
 320         if (status != LDB_SUCCESS) {
 321                 if (ldb->err_string == NULL) {
 322                         /* no error string was setup by the backend */
 323                         ldb_asprintf_errstring(ldb,
 324                                 "ldb transaction start: %s (%d)",
 325                                 ldb_strerror(status),
 326                                 status);
 327                 }
 328         }
 329         return status;
 330 }
 331 
 332 /*
 333   commit a transaction
 334 */
 335 int ldb_transaction_commit(struct ldb_context *ldb)
     /* [<][>][^][v][top][bottom][index][help] */
 336 {
 337         struct ldb_module *module;
 338         int status;
 339 
 340         ldb->transaction_active--;
 341 
 342         ldb_debug(ldb, LDB_DEBUG_TRACE,
 343                   "commit ldb transaction (nesting: %d)",
 344                   ldb->transaction_active);
 345 
 346         /* commit only when all nested transactions are complete */
 347         if (ldb->transaction_active > 0) {
 348                 return LDB_SUCCESS;
 349         }
 350 
 351         if (ldb->transaction_active < 0) {
 352                 ldb_debug(ldb, LDB_DEBUG_FATAL,
 353                           "commit called but no ldb transactions are active!");
 354                 ldb->transaction_active = 0;
 355                 return LDB_ERR_OPERATIONS_ERROR;
 356         }
 357 
 358         FIRST_OP(ldb, end_transaction);
 359 
 360         ldb_reset_err_string(ldb);
 361 
 362         status = module->ops->end_transaction(module);
 363         if (status != LDB_SUCCESS) {
 364                 if (ldb->err_string == NULL) {
 365                         /* no error string was setup by the backend */
 366                         ldb_asprintf_errstring(ldb,
 367                                 "ldb transaction commit: %s (%d)",
 368                                 ldb_strerror(status),
 369                                 status);
 370                 }
 371         }
 372         return status;
 373 }
 374 
 375 /*
 376   cancel a transaction
 377 */
 378 int ldb_transaction_cancel(struct ldb_context *ldb)
     /* [<][>][^][v][top][bottom][index][help] */
 379 {
 380         struct ldb_module *module;
 381         int status;
 382 
 383         ldb->transaction_active--;
 384 
 385         ldb_debug(ldb, LDB_DEBUG_TRACE,
 386                   "cancel ldb transaction (nesting: %d)",
 387                   ldb->transaction_active);
 388 
 389         /* really cancel only if all nested transactions are complete */
 390         if (ldb->transaction_active > 0) {
 391                 return LDB_SUCCESS;
 392         }
 393 
 394         if (ldb->transaction_active < 0) {
 395                 ldb_debug(ldb, LDB_DEBUG_FATAL,
 396                           "commit called but no ldb transactions are active!");
 397                 ldb->transaction_active = 0;
 398                 return LDB_ERR_OPERATIONS_ERROR;
 399         }
 400 
 401         FIRST_OP(ldb, del_transaction);
 402 
 403         status = module->ops->del_transaction(module);
 404         if (status != LDB_SUCCESS) {
 405                 if (ldb->err_string == NULL) {
 406                         /* no error string was setup by the backend */
 407                         ldb_asprintf_errstring(ldb,
 408                                 "ldb transaction cancel: %s (%d)",
 409                                 ldb_strerror(status),
 410                                 status);
 411                 }
 412         }
 413         return status;
 414 }
 415 
 416 /* autostarts a transacion if none active */
 417 static int ldb_autotransaction_request(struct ldb_context *ldb,
     /* [<][>][^][v][top][bottom][index][help] */
 418                                        struct ldb_request *req)
 419 {
 420         int ret;
 421 
 422         ret = ldb_transaction_start(ldb);
 423         if (ret != LDB_SUCCESS) {
 424                 return ret;
 425         }
 426 
 427         ret = ldb_request(ldb, req);
 428         if (ret == LDB_SUCCESS) {
 429                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
 430         }
 431 
 432         if (ret == LDB_SUCCESS) {
 433                 return ldb_transaction_commit(ldb);
 434         }
 435         ldb_transaction_cancel(ldb);
 436 
 437         if (ldb->err_string == NULL) {
 438                 /* no error string was setup by the backend */
 439                 ldb_asprintf_errstring(ldb, "%s (%d)", ldb_strerror(ret), ret);
 440         }
 441 
 442         return ret;
 443 }
 444 
 445 int ldb_wait(struct ldb_handle *handle, enum ldb_wait_type type)
     /* [<][>][^][v][top][bottom][index][help] */
 446 {
 447         struct tevent_context *ev;
 448         int ret;
 449 
 450         if (!handle) {
 451                 return LDB_ERR_UNAVAILABLE;
 452         }
 453 
 454         if (handle->state == LDB_ASYNC_DONE) {
 455                 return handle->status;
 456         }
 457 
 458         ev = ldb_get_event_context(handle->ldb);
 459         if (NULL == ev) {
 460                 return LDB_ERR_OPERATIONS_ERROR;
 461         }
 462 
 463         switch (type) {
 464         case LDB_WAIT_NONE:
 465                 ret = tevent_loop_once(ev);
 466                 if (ret != 0) {
 467                         return LDB_ERR_OPERATIONS_ERROR;
 468                 }
 469                 if (handle->state == LDB_ASYNC_DONE ||
 470                     handle->status != LDB_SUCCESS) {
 471                         return handle->status;
 472                 }
 473                 break;
 474 
 475         case LDB_WAIT_ALL:
 476                 while (handle->state != LDB_ASYNC_DONE) {
 477                         ret = tevent_loop_once(ev);
 478                         if (ret != 0) {
 479                                 return LDB_ERR_OPERATIONS_ERROR;
 480                         }
 481                         if (handle->status != LDB_SUCCESS) {
 482                                 return handle->status;
 483                         }
 484                 }
 485                 return handle->status;
 486         }
 487 
 488         return LDB_SUCCESS;
 489 }
 490 
 491 /* set the specified timeout or, if timeout is 0 set the default timeout */
 492 int ldb_set_timeout(struct ldb_context *ldb,
     /* [<][>][^][v][top][bottom][index][help] */
 493                     struct ldb_request *req,
 494                     int timeout)
 495 {
 496         if (req == NULL) return LDB_ERR_OPERATIONS_ERROR;
 497 
 498         if (timeout != 0) {
 499                 req->timeout = timeout;
 500         } else {
 501                 req->timeout = ldb->default_timeout;
 502         }
 503         req->starttime = time(NULL);
 504 
 505         return LDB_SUCCESS;
 506 }
 507 
 508 /* calculates the new timeout based on the previous starttime and timeout */
 509 int ldb_set_timeout_from_prev_req(struct ldb_context *ldb,
     /* [<][>][^][v][top][bottom][index][help] */
 510                                   struct ldb_request *oldreq,
 511                                   struct ldb_request *newreq)
 512 {
 513         if (newreq == NULL) return LDB_ERR_OPERATIONS_ERROR;
 514 
 515         if (oldreq == NULL) {
 516                 return ldb_set_timeout(ldb, newreq, 0);
 517         }
 518 
 519         newreq->starttime = oldreq->starttime;
 520         newreq->timeout = oldreq->timeout;
 521 
 522         return LDB_SUCCESS;
 523 }
 524 
 525 
 526 /*
 527    set the permissions for new files to be passed to open() in
 528    backends that use local files
 529  */
 530 void ldb_set_create_perms(struct ldb_context *ldb, unsigned int perms)
     /* [<][>][^][v][top][bottom][index][help] */
 531 {
 532         ldb->create_perms = perms;
 533 }
 534 
 535 unsigned int ldb_get_create_perms(struct ldb_context *ldb)
     /* [<][>][^][v][top][bottom][index][help] */
 536 {
 537         return ldb->create_perms;
 538 }
 539 
 540 void ldb_set_event_context(struct ldb_context *ldb, struct tevent_context *ev)
     /* [<][>][^][v][top][bottom][index][help] */
 541 {
 542         ldb->ev_ctx = ev;
 543 }
 544 
 545 struct tevent_context * ldb_get_event_context(struct ldb_context *ldb)
     /* [<][>][^][v][top][bottom][index][help] */
 546 {
 547         return ldb->ev_ctx;
 548 }
 549 
 550 void ldb_request_set_state(struct ldb_request *req, int state)
     /* [<][>][^][v][top][bottom][index][help] */
 551 {
 552         req->handle->state = state;
 553 }
 554 
 555 int ldb_request_get_status(struct ldb_request *req)
     /* [<][>][^][v][top][bottom][index][help] */
 556 {
 557         return req->handle->status;
 558 }
 559 
 560 /*
 561   start an ldb request
 562   NOTE: the request must be a talloc context.
 563   returns LDB_ERR_* on errors.
 564 */
 565 int ldb_request(struct ldb_context *ldb, struct ldb_request *req)
     /* [<][>][^][v][top][bottom][index][help] */
 566 {
 567         struct ldb_module *module;
 568         int ret;
 569 
 570         if (req->callback == NULL) {
 571                 ldb_set_errstring(ldb, "Requests MUST define callbacks");
 572                 return LDB_ERR_UNWILLING_TO_PERFORM;
 573         }
 574 
 575         ldb_reset_err_string(ldb);
 576 
 577         /* call the first module in the chain */
 578         switch (req->operation) {
 579         case LDB_SEARCH:
 580                 FIRST_OP(ldb, search);
 581                 ret = module->ops->search(module, req);
 582                 break;
 583         case LDB_ADD:
 584                 FIRST_OP(ldb, add);
 585                 ret = module->ops->add(module, req);
 586                 break;
 587         case LDB_MODIFY:
 588                 FIRST_OP(ldb, modify);
 589                 ret = module->ops->modify(module, req);
 590                 break;
 591         case LDB_DELETE:
 592                 FIRST_OP(ldb, del);
 593                 ret = module->ops->del(module, req);
 594                 break;
 595         case LDB_RENAME:
 596                 FIRST_OP(ldb, rename);
 597                 ret = module->ops->rename(module, req);
 598                 break;
 599         case LDB_EXTENDED:
 600                 FIRST_OP(ldb, extended);
 601                 ret = module->ops->extended(module, req);
 602                 break;
 603         default:
 604                 FIRST_OP(ldb, request);
 605                 ret = module->ops->request(module, req);
 606                 break;
 607         }
 608 
 609         return ret;
 610 }
 611 
 612 int ldb_request_done(struct ldb_request *req, int status)
     /* [<][>][^][v][top][bottom][index][help] */
 613 {
 614         req->handle->state = LDB_ASYNC_DONE;
 615         req->handle->status = status;
 616         return status;
 617 }
 618 
 619 /*
 620   search the database given a LDAP-like search expression
 621 
 622   returns an LDB error code
 623 
 624   Use talloc_free to free the ldb_message returned in 'res', if successful
 625 
 626 */
 627 int ldb_search_default_callback(struct ldb_request *req,
     /* [<][>][^][v][top][bottom][index][help] */
 628                                 struct ldb_reply *ares)
 629 {
 630         struct ldb_result *res;
 631         int n;
 632 
 633         res = talloc_get_type(req->context, struct ldb_result);
 634 
 635         if (!ares) {
 636                 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
 637         }
 638         if (ares->error != LDB_SUCCESS) {
 639                 return ldb_request_done(req, ares->error);
 640         }
 641 
 642         switch (ares->type) {
 643         case LDB_REPLY_ENTRY:
 644                 res->msgs = talloc_realloc(res, res->msgs,
 645                                         struct ldb_message *, res->count + 2);
 646                 if (! res->msgs) {
 647                         return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
 648                 }
 649 
 650                 res->msgs[res->count + 1] = NULL;
 651 
 652                 res->msgs[res->count] = talloc_move(res->msgs, &ares->message);
 653                 res->count++;
 654                 break;
 655 
 656         case LDB_REPLY_REFERRAL:
 657                 if (res->refs) {
 658                         for (n = 0; res->refs[n]; n++) /*noop*/ ;
 659                 } else {
 660                         n = 0;
 661                 }
 662 
 663                 res->refs = talloc_realloc(res, res->refs, char *, n + 2);
 664                 if (! res->refs) {
 665                         return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
 666                 }
 667 
 668                 res->refs[n] = talloc_move(res->refs, &ares->referral);
 669                 res->refs[n + 1] = NULL;
 670                 break;
 671 
 672         case LDB_REPLY_DONE:
 673                 /* TODO: we should really support controls on entries
 674                  * and referrals too! */
 675                 res->controls = talloc_move(res, &ares->controls);
 676 
 677                 /* this is the last message, and means the request is done */
 678                 /* we have to signal and eventual ldb_wait() waiting that the
 679                  * async request operation was completed */
 680                 return ldb_request_done(req, LDB_SUCCESS);
 681         }
 682 
 683         talloc_free(ares);
 684         return LDB_SUCCESS;
 685 }
 686 
 687 int ldb_op_default_callback(struct ldb_request *req, struct ldb_reply *ares)
     /* [<][>][^][v][top][bottom][index][help] */
 688 {
 689         int ret;
 690 
 691         if (!ares) {
 692                 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
 693         }
 694 
 695         if (ares->error != LDB_SUCCESS) {
 696                 ret = ares->error;
 697                 talloc_free(ares);
 698                 return ldb_request_done(req, ret);
 699         }
 700 
 701         if (ares->type != LDB_REPLY_DONE) {
 702                 talloc_free(ares);
 703                 ldb_set_errstring(req->handle->ldb, "Invalid reply type!");
 704                 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
 705         }
 706 
 707         talloc_free(ares);
 708         return ldb_request_done(req, LDB_SUCCESS);
 709 }
 710 
 711 int ldb_build_search_req_ex(struct ldb_request **ret_req,
     /* [<][>][^][v][top][bottom][index][help] */
 712                         struct ldb_context *ldb,
 713                         void *mem_ctx,
 714                         struct ldb_dn *base,
 715                         enum ldb_scope scope,
 716                         struct ldb_parse_tree *tree,
 717                         const char * const *attrs,
 718                         struct ldb_control **controls,
 719                         void *context,
 720                         ldb_request_callback_t callback,
 721                         struct ldb_request *parent)
 722 {
 723         struct ldb_request *req;
 724 
 725         *ret_req = NULL;
 726 
 727         req = talloc(mem_ctx, struct ldb_request);
 728         if (req == NULL) {
 729                 ldb_oom(ldb);
 730                 return LDB_ERR_OPERATIONS_ERROR;
 731         }
 732 
 733         req->operation = LDB_SEARCH;
 734         if (base == NULL) {
 735                 req->op.search.base = ldb_dn_new(req, ldb, NULL);
 736         } else {
 737                 req->op.search.base = base;
 738         }
 739         req->op.search.scope = scope;
 740 
 741         req->op.search.tree = tree;
 742         if (req->op.search.tree == NULL) {
 743                 ldb_set_errstring(ldb, "'tree' can't be NULL");
 744                 talloc_free(req);
 745                 return LDB_ERR_OPERATIONS_ERROR;
 746         }
 747 
 748         req->op.search.attrs = attrs;
 749         req->controls = controls;
 750         req->context = context;
 751         req->callback = callback;
 752 
 753         ldb_set_timeout_from_prev_req(ldb, parent, req);
 754 
 755         req->handle = ldb_handle_new(req, ldb);
 756         if (req->handle == NULL) {
 757                 ldb_oom(ldb);
 758                 return LDB_ERR_OPERATIONS_ERROR;
 759         }
 760 
 761         *ret_req = req;
 762         return LDB_SUCCESS;
 763 }
 764 
 765 int ldb_build_search_req(struct ldb_request **ret_req,
     /* [<][>][^][v][top][bottom][index][help] */
 766                         struct ldb_context *ldb,
 767                         void *mem_ctx,
 768                         struct ldb_dn *base,
 769                         enum ldb_scope scope,
 770                         const char *expression,
 771                         const char * const *attrs,
 772                         struct ldb_control **controls,
 773                         void *context,
 774                         ldb_request_callback_t callback,
 775                         struct ldb_request *parent)
 776 {
 777         struct ldb_parse_tree *tree;
 778         int ret;
 779 
 780         tree = ldb_parse_tree(mem_ctx, expression);
 781         if (tree == NULL) {
 782                 ldb_set_errstring(ldb, "Unable to parse search expression");
 783                 return LDB_ERR_OPERATIONS_ERROR;
 784         }
 785 
 786         ret = ldb_build_search_req_ex(ret_req, ldb, mem_ctx, base,
 787                                       scope, tree, attrs, controls,
 788                                       context, callback, parent);
 789         if (ret == LDB_SUCCESS) {
 790                 talloc_steal(*ret_req, tree);
 791         }
 792         return ret;
 793 }
 794 
 795 int ldb_build_add_req(struct ldb_request **ret_req,
     /* [<][>][^][v][top][bottom][index][help] */
 796                         struct ldb_context *ldb,
 797                         void *mem_ctx,
 798                         const struct ldb_message *message,
 799                         struct ldb_control **controls,
 800                         void *context,
 801                         ldb_request_callback_t callback,
 802                         struct ldb_request *parent)
 803 {
 804         struct ldb_request *req;
 805 
 806         *ret_req = NULL;
 807 
 808         req = talloc(mem_ctx, struct ldb_request);
 809         if (req == NULL) {
 810                 ldb_set_errstring(ldb, "Out of Memory");
 811                 return LDB_ERR_OPERATIONS_ERROR;
 812         }
 813 
 814         req->operation = LDB_ADD;
 815         req->op.add.message = message;
 816         req->controls = controls;
 817         req->context = context;
 818         req->callback = callback;
 819 
 820         ldb_set_timeout_from_prev_req(ldb, parent, req);
 821 
 822         req->handle = ldb_handle_new(req, ldb);
 823         if (req->handle == NULL) {
 824                 ldb_oom(ldb);
 825                 return LDB_ERR_OPERATIONS_ERROR;
 826         }
 827 
 828         *ret_req = req;
 829 
 830         return LDB_SUCCESS;
 831 }
 832 
 833 int ldb_build_mod_req(struct ldb_request **ret_req,
     /* [<][>][^][v][top][bottom][index][help] */
 834                         struct ldb_context *ldb,
 835                         void *mem_ctx,
 836                         const struct ldb_message *message,
 837                         struct ldb_control **controls,
 838                         void *context,
 839                         ldb_request_callback_t callback,
 840                         struct ldb_request *parent)
 841 {
 842         struct ldb_request *req;
 843 
 844         *ret_req = NULL;
 845 
 846         req = talloc(mem_ctx, struct ldb_request);
 847         if (req == NULL) {
 848                 ldb_set_errstring(ldb, "Out of Memory");
 849                 return LDB_ERR_OPERATIONS_ERROR;
 850         }
 851 
 852         req->operation = LDB_MODIFY;
 853         req->op.mod.message = message;
 854         req->controls = controls;
 855         req->context = context;
 856         req->callback = callback;
 857 
 858         ldb_set_timeout_from_prev_req(ldb, parent, req);
 859 
 860         req->handle = ldb_handle_new(req, ldb);
 861         if (req->handle == NULL) {
 862                 ldb_oom(ldb);
 863                 return LDB_ERR_OPERATIONS_ERROR;
 864         }
 865 
 866         *ret_req = req;
 867 
 868         return LDB_SUCCESS;
 869 }
 870 
 871 int ldb_build_del_req(struct ldb_request **ret_req,
     /* [<][>][^][v][top][bottom][index][help] */
 872                         struct ldb_context *ldb,
 873                         void *mem_ctx,
 874                         struct ldb_dn *dn,
 875                         struct ldb_control **controls,
 876                         void *context,
 877                         ldb_request_callback_t callback,
 878                         struct ldb_request *parent)
 879 {
 880         struct ldb_request *req;
 881 
 882         *ret_req = NULL;
 883 
 884         req = talloc(mem_ctx, struct ldb_request);
 885         if (req == NULL) {
 886                 ldb_set_errstring(ldb, "Out of Memory");
 887                 return LDB_ERR_OPERATIONS_ERROR;
 888         }
 889 
 890         req->operation = LDB_DELETE;
 891         req->op.del.dn = dn;
 892         req->controls = controls;
 893         req->context = context;
 894         req->callback = callback;
 895 
 896         ldb_set_timeout_from_prev_req(ldb, parent, req);
 897 
 898         req->handle = ldb_handle_new(req, ldb);
 899         if (req->handle == NULL) {
 900                 ldb_oom(ldb);
 901                 return LDB_ERR_OPERATIONS_ERROR;
 902         }
 903 
 904         *ret_req = req;
 905 
 906         return LDB_SUCCESS;
 907 }
 908 
 909 int ldb_build_rename_req(struct ldb_request **ret_req,
     /* [<][>][^][v][top][bottom][index][help] */
 910                         struct ldb_context *ldb,
 911                         void *mem_ctx,
 912                         struct ldb_dn *olddn,
 913                         struct ldb_dn *newdn,
 914                         struct ldb_control **controls,
 915                         void *context,
 916                         ldb_request_callback_t callback,
 917                         struct ldb_request *parent)
 918 {
 919         struct ldb_request *req;
 920 
 921         *ret_req = NULL;
 922 
 923         req = talloc(mem_ctx, struct ldb_request);
 924         if (req == NULL) {
 925                 ldb_set_errstring(ldb, "Out of Memory");
 926                 return LDB_ERR_OPERATIONS_ERROR;
 927         }
 928 
 929         req->operation = LDB_RENAME;
 930         req->op.rename.olddn = olddn;
 931         req->op.rename.newdn = newdn;
 932         req->controls = controls;
 933         req->context = context;
 934         req->callback = callback;
 935 
 936         ldb_set_timeout_from_prev_req(ldb, parent, req);
 937 
 938         req->handle = ldb_handle_new(req, ldb);
 939         if (req->handle == NULL) {
 940                 ldb_oom(ldb);
 941                 return LDB_ERR_OPERATIONS_ERROR;
 942         }
 943 
 944         *ret_req = req;
 945 
 946         return LDB_SUCCESS;
 947 }
 948 
 949 int ldb_extended_default_callback(struct ldb_request *req,
     /* [<][>][^][v][top][bottom][index][help] */
 950                                   struct ldb_reply *ares)
 951 {
 952         struct ldb_result *res;
 953 
 954         res = talloc_get_type(req->context, struct ldb_result);
 955 
 956         if (!ares) {
 957                 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
 958         }
 959         if (ares->error != LDB_SUCCESS) {
 960                 return ldb_request_done(req, ares->error);
 961         }
 962 
 963         if (ares->type == LDB_REPLY_DONE) {
 964 
 965                 /* TODO: we should really support controls on entries and referrals too! */
 966                 res->extended = talloc_move(res, &ares->response);
 967                 res->controls = talloc_move(res, &ares->controls);
 968 
 969                 talloc_free(ares);
 970                 return ldb_request_done(req, LDB_SUCCESS);
 971         }
 972 
 973         talloc_free(ares);
 974         ldb_set_errstring(req->handle->ldb, "Invalid reply type!");
 975         return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
 976 }
 977 
 978 int ldb_build_extended_req(struct ldb_request **ret_req,
     /* [<][>][^][v][top][bottom][index][help] */
 979                            struct ldb_context *ldb,
 980                            void *mem_ctx,
 981                            const char *oid,
 982                            void *data,
 983                            struct ldb_control **controls,
 984                            void *context,
 985                            ldb_request_callback_t callback,
 986                            struct ldb_request *parent)
 987 {
 988         struct ldb_request *req;
 989 
 990         *ret_req = NULL;
 991 
 992         req = talloc(mem_ctx, struct ldb_request);
 993         if (req == NULL) {
 994                 ldb_set_errstring(ldb, "Out of Memory");
 995                 return LDB_ERR_OPERATIONS_ERROR;
 996         }
 997 
 998         req->operation = LDB_EXTENDED;
 999         req->op.extended.oid = oid;
1000         req->op.extended.data = data;
1001         req->controls = controls;
1002         req->context = context;
1003         req->callback = callback;
1004 
1005         ldb_set_timeout_from_prev_req(ldb, parent, req);
1006 
1007         req->handle = ldb_handle_new(req, ldb);
1008         if (req->handle == NULL) {
1009                 ldb_oom(ldb);
1010                 return LDB_ERR_OPERATIONS_ERROR;
1011         }
1012 
1013         *ret_req = req;
1014 
1015         return LDB_SUCCESS;
1016 }
1017 
1018 int ldb_extended(struct ldb_context *ldb,
     /* [<][>][^][v][top][bottom][index][help] */
1019                  const char *oid,
1020                  void *data,
1021                  struct ldb_result **_res)
1022 {
1023         struct ldb_request *req;
1024         int ret;
1025         struct ldb_result *res;
1026 
1027         *_res = NULL;
1028 
1029         res = talloc_zero(ldb, struct ldb_result);
1030         if (!res) {
1031                 return LDB_ERR_OPERATIONS_ERROR;
1032         }
1033 
1034         ret = ldb_build_extended_req(&req, ldb, ldb,
1035                                      oid, data, NULL,
1036                                      res, ldb_extended_default_callback,
1037                                      NULL);
1038         if (ret != LDB_SUCCESS) goto done;
1039 
1040         ldb_set_timeout(ldb, req, 0); /* use default timeout */
1041 
1042         ret = ldb_request(ldb, req);
1043 
1044         if (ret == LDB_SUCCESS) {
1045                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1046         }
1047 
1048         talloc_free(req);
1049 
1050 done:
1051         if (ret != LDB_SUCCESS) {
1052                 talloc_free(res);
1053         }
1054 
1055         *_res = res;
1056         return ret;
1057 }
1058 
1059 /*
1060   note that ldb_search() will automatically replace a NULL 'base' value
1061   with the defaultNamingContext from the rootDSE if available.
1062 */
1063 int ldb_search(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
1064                 struct ldb_result **result, struct ldb_dn *base,
1065                 enum ldb_scope scope, const char * const *attrs,
1066                 const char *exp_fmt, ...)
1067 {
1068         struct ldb_request *req;
1069         struct ldb_result *res;
1070         char *expression;
1071         va_list ap;
1072         int ret;
1073 
1074         expression = NULL;
1075         *result = NULL;
1076         req = NULL;
1077 
1078         res = talloc_zero(mem_ctx, struct ldb_result);
1079         if (!res) {
1080                 return LDB_ERR_OPERATIONS_ERROR;
1081         }
1082 
1083         if (exp_fmt) {
1084                 va_start(ap, exp_fmt);
1085                 expression = talloc_vasprintf(mem_ctx, exp_fmt, ap);
1086                 va_end(ap);
1087 
1088                 if (!expression) {
1089                         talloc_free(res);
1090                         return LDB_ERR_OPERATIONS_ERROR;
1091                 }
1092         }
1093 
1094         ret = ldb_build_search_req(&req, ldb, mem_ctx,
1095                                         base?base:ldb_get_default_basedn(ldb),
1096                                         scope,
1097                                         expression,
1098                                         attrs,
1099                                         NULL,
1100                                         res,
1101                                         ldb_search_default_callback,
1102                                         NULL);
1103 
1104         if (ret != LDB_SUCCESS) goto done;
1105 
1106         ret = ldb_request(ldb, req);
1107 
1108         if (ret == LDB_SUCCESS) {
1109                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1110         }
1111 
1112 done:
1113         if (ret != LDB_SUCCESS) {
1114                 talloc_free(res);
1115                 res = NULL;
1116         }
1117 
1118         talloc_free(expression);
1119         talloc_free(req);
1120 
1121         *result = res;
1122         return ret;
1123 }
1124 
1125 /*
1126   add a record to the database. Will fail if a record with the given class
1127   and key already exists
1128 */
1129 int ldb_add(struct ldb_context *ldb,
     /* [<][>][^][v][top][bottom][index][help] */
1130             const struct ldb_message *message)
1131 {
1132         struct ldb_request *req;
1133         int ret;
1134 
1135         ret = ldb_msg_sanity_check(ldb, message);
1136         if (ret != LDB_SUCCESS) {
1137                 return ret;
1138         }
1139 
1140         ret = ldb_build_add_req(&req, ldb, ldb,
1141                                         message,
1142                                         NULL,
1143                                         NULL,
1144                                         ldb_op_default_callback,
1145                                         NULL);
1146 
1147         if (ret != LDB_SUCCESS) return ret;
1148 
1149         /* do request and autostart a transaction */
1150         ret = ldb_autotransaction_request(ldb, req);
1151 
1152         talloc_free(req);
1153         return ret;
1154 }
1155 
1156 /*
1157   modify the specified attributes of a record
1158 */
1159 int ldb_modify(struct ldb_context *ldb,
     /* [<][>][^][v][top][bottom][index][help] */
1160                const struct ldb_message *message)
1161 {
1162         struct ldb_request *req;
1163         int ret;
1164 
1165         ret = ldb_msg_sanity_check(ldb, message);
1166         if (ret != LDB_SUCCESS) {
1167                 return ret;
1168         }
1169 
1170         ret = ldb_build_mod_req(&req, ldb, ldb,
1171                                         message,
1172                                         NULL,
1173                                         NULL,
1174                                         ldb_op_default_callback,
1175                                         NULL);
1176 
1177         if (ret != LDB_SUCCESS) return ret;
1178 
1179         /* do request and autostart a transaction */
1180         ret = ldb_autotransaction_request(ldb, req);
1181 
1182         talloc_free(req);
1183         return ret;
1184 }
1185 
1186 
1187 /*
1188   delete a record from the database
1189 */
1190 int ldb_delete(struct ldb_context *ldb, struct ldb_dn *dn)
     /* [<][>][^][v][top][bottom][index][help] */
1191 {
1192         struct ldb_request *req;
1193         int ret;
1194 
1195         ret = ldb_build_del_req(&req, ldb, ldb,
1196                                         dn,
1197                                         NULL,
1198                                         NULL,
1199                                         ldb_op_default_callback,
1200                                         NULL);
1201 
1202         if (ret != LDB_SUCCESS) return ret;
1203 
1204         /* do request and autostart a transaction */
1205         ret = ldb_autotransaction_request(ldb, req);
1206 
1207         talloc_free(req);
1208         return ret;
1209 }
1210 
1211 /*
1212   rename a record in the database
1213 */
1214 int ldb_rename(struct ldb_context *ldb,
     /* [<][>][^][v][top][bottom][index][help] */
1215                 struct ldb_dn *olddn, struct ldb_dn *newdn)
1216 {
1217         struct ldb_request *req;
1218         int ret;
1219 
1220         ret = ldb_build_rename_req(&req, ldb, ldb,
1221                                         olddn,
1222                                         newdn,
1223                                         NULL,
1224                                         NULL,
1225                                         ldb_op_default_callback,
1226                                         NULL);
1227 
1228         if (ret != LDB_SUCCESS) return ret;
1229 
1230         /* do request and autostart a transaction */
1231         ret = ldb_autotransaction_request(ldb, req);
1232 
1233         talloc_free(req);
1234         return ret;
1235 }
1236 
1237 
1238 /*
1239   return the global sequence number
1240 */
1241 int ldb_sequence_number(struct ldb_context *ldb,
     /* [<][>][^][v][top][bottom][index][help] */
1242                         enum ldb_sequence_type type, uint64_t *seq_num)
1243 {
1244         struct ldb_seqnum_request *seq;
1245         struct ldb_seqnum_result *seqr;
1246         struct ldb_result *res;
1247         TALLOC_CTX *tmp_ctx;
1248         int ret;
1249 
1250         *seq_num = 0;
1251 
1252         tmp_ctx = talloc_zero(ldb, struct ldb_request);
1253         if (tmp_ctx == NULL) {
1254                 ldb_set_errstring(ldb, "Out of Memory");
1255                 return LDB_ERR_OPERATIONS_ERROR;
1256         }
1257         seq = talloc_zero(tmp_ctx, struct ldb_seqnum_request);
1258         if (seq == NULL) {
1259                 ldb_set_errstring(ldb, "Out of Memory");
1260                 ret = LDB_ERR_OPERATIONS_ERROR;
1261                 goto done;
1262         }
1263         seq->type = type;
1264 
1265         ret = ldb_extended(ldb, LDB_EXTENDED_SEQUENCE_NUMBER, seq, &res);
1266         if (ret != LDB_SUCCESS) {
1267                 goto done;
1268         }
1269         talloc_steal(tmp_ctx, res);
1270 
1271         if (strcmp(LDB_EXTENDED_SEQUENCE_NUMBER, res->extended->oid) != 0) {
1272                 ldb_set_errstring(ldb, "Invalid OID in reply");
1273                 ret = LDB_ERR_OPERATIONS_ERROR;
1274                 goto done;
1275         }
1276         seqr = talloc_get_type(res->extended->data,
1277                                 struct ldb_seqnum_result);
1278         *seq_num = seqr->seq_num;
1279 
1280 done:
1281         talloc_free(tmp_ctx);
1282         return ret;
1283 }
1284 
1285 /*
1286   return extended error information
1287 */
1288 const char *ldb_errstring(struct ldb_context *ldb)
     /* [<][>][^][v][top][bottom][index][help] */
1289 {
1290         if (ldb->err_string) {
1291                 return ldb->err_string;
1292         }
1293 
1294         return NULL;
1295 }
1296 
1297 /*
1298   return a string explaining what a ldb error constant meancs
1299 */
1300 const char *ldb_strerror(int ldb_err)
     /* [<][>][^][v][top][bottom][index][help] */
1301 {
1302         switch (ldb_err) {
1303         case LDB_SUCCESS:
1304                 return "Success";
1305         case LDB_ERR_OPERATIONS_ERROR:
1306                 return "Operations error";
1307         case LDB_ERR_PROTOCOL_ERROR:
1308                 return "Protocol error";
1309         case LDB_ERR_TIME_LIMIT_EXCEEDED:
1310                 return "Time limit exceeded";
1311         case LDB_ERR_SIZE_LIMIT_EXCEEDED:
1312                 return "Size limit exceeded";
1313         case LDB_ERR_COMPARE_FALSE:
1314                 return "Compare false";
1315         case LDB_ERR_COMPARE_TRUE:
1316                 return "Compare true";
1317         case LDB_ERR_AUTH_METHOD_NOT_SUPPORTED:
1318                 return "Auth method not supported";
1319         case LDB_ERR_STRONG_AUTH_REQUIRED:
1320                 return "Strong auth required";
1321 /* 9 RESERVED */
1322         case LDB_ERR_REFERRAL:
1323                 return "Referral error";
1324         case LDB_ERR_ADMIN_LIMIT_EXCEEDED:
1325                 return "Admin limit exceeded";
1326         case LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION:
1327                 return "Unsupported critical extension";
1328         case LDB_ERR_CONFIDENTIALITY_REQUIRED:
1329                 return "Confidentiality required";
1330         case LDB_ERR_SASL_BIND_IN_PROGRESS:
1331                 return "SASL bind in progress";
1332         case LDB_ERR_NO_SUCH_ATTRIBUTE:
1333                 return "No such attribute";
1334         case LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE:
1335                 return "Undefined attribute type";
1336         case LDB_ERR_INAPPROPRIATE_MATCHING:
1337                 return "Inappropriate matching";
1338         case LDB_ERR_CONSTRAINT_VIOLATION:
1339                 return "Constraint violation";
1340         case LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS:
1341                 return "Attribute or value exists";
1342         case LDB_ERR_INVALID_ATTRIBUTE_SYNTAX:
1343                 return "Invalid attribute syntax";
1344 /* 22-31 unused */
1345         case LDB_ERR_NO_SUCH_OBJECT:
1346                 return "No such object";
1347         case LDB_ERR_ALIAS_PROBLEM:
1348                 return "Alias problem";
1349         case LDB_ERR_INVALID_DN_SYNTAX:
1350                 return "Invalid DN syntax";
1351 /* 35 RESERVED */
1352         case LDB_ERR_ALIAS_DEREFERENCING_PROBLEM:
1353                 return "Alias dereferencing problem";
1354 /* 37-47 unused */
1355         case LDB_ERR_INAPPROPRIATE_AUTHENTICATION:
1356                 return "Inappropriate authentication";
1357         case LDB_ERR_INVALID_CREDENTIALS:
1358                 return "Invalid credentials";
1359         case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1360                 return "insufficient access rights";
1361         case LDB_ERR_BUSY:
1362                 return "Busy";
1363         case LDB_ERR_UNAVAILABLE:
1364                 return "Unavailable";
1365         case LDB_ERR_UNWILLING_TO_PERFORM:
1366                 return "Unwilling to perform";
1367         case LDB_ERR_LOOP_DETECT:
1368                 return "Loop detect";
1369 /* 55-63 unused */
1370         case LDB_ERR_NAMING_VIOLATION:
1371                 return "Naming violation";
1372         case LDB_ERR_OBJECT_CLASS_VIOLATION:
1373                 return "Object class violation";
1374         case LDB_ERR_NOT_ALLOWED_ON_NON_LEAF:
1375                 return "Not allowed on non-leaf";
1376         case LDB_ERR_NOT_ALLOWED_ON_RDN:
1377                 return "Not allowed on RDN";
1378         case LDB_ERR_ENTRY_ALREADY_EXISTS:
1379                 return "Entry already exists";
1380         case LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED:
1381                 return "Object class mods prohibited";
1382 /* 70 RESERVED FOR CLDAP */
1383         case LDB_ERR_AFFECTS_MULTIPLE_DSAS:
1384                 return "Affects multiple DSAs";
1385 /* 72-79 unused */
1386         case LDB_ERR_OTHER:
1387                 return "Other";
1388         }
1389 
1390         return "Unknown error";
1391 }
1392 
1393 /*
1394   set backend specific opaque parameters
1395 */
1396 int ldb_set_opaque(struct ldb_context *ldb, const char *name, void *value)
     /* [<][>][^][v][top][bottom][index][help] */
1397 {
1398         struct ldb_opaque *o;
1399 
1400         /* allow updating an existing value */
1401         for (o=ldb->opaque;o;o=o->next) {
1402                 if (strcmp(o->name, name) == 0) {
1403                         o->value = value;
1404                         return LDB_SUCCESS;
1405                 }
1406         }
1407 
1408         o = talloc(ldb, struct ldb_opaque);
1409         if (o == NULL) {
1410                 ldb_oom(ldb);
1411                 return LDB_ERR_OTHER;
1412         }
1413         o->next = ldb->opaque;
1414         o->name = name;
1415         o->value = value;
1416         ldb->opaque = o;
1417         return LDB_SUCCESS;
1418 }
1419 
1420 /*
1421   get a previously set opaque value
1422 */
1423 void *ldb_get_opaque(struct ldb_context *ldb, const char *name)
     /* [<][>][^][v][top][bottom][index][help] */
1424 {
1425         struct ldb_opaque *o;
1426         for (o=ldb->opaque;o;o=o->next) {
1427                 if (strcmp(o->name, name) == 0) {
1428                         return o->value;
1429                 }
1430         }
1431         return NULL;
1432 }

/* [<][>][^][v][top][bottom][index][help] */