root/source3/lib/ldb/common/ldb_modules.c

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

DEFINITIONS

This source file includes following definitions.
  1. ldb_modules_strdup_no_spaces
  2. ldb_modules_list_from_string
  3. ldb_find_module_ops
  4. ldb_global_init
  5. ldb_register_module
  6. ldb_try_load_dso
  7. ldb_load_modules_list
  8. ldb_init_module_chain
  9. ldb_load_modules
  10. ldb_next_request
  11. ldb_next_init
  12. ldb_next_start_trans
  13. ldb_next_end_trans
  14. ldb_next_del_trans

   1 
   2 /* 
   3    ldb database library
   4 
   5    Copyright (C) Simo Sorce  2004
   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 modules core
  29  *
  30  *  Description: core modules routines
  31  *
  32  *  Author: Simo Sorce
  33  */
  34 
  35 #include "includes.h"
  36 #include "ldb/include/includes.h"
  37 
  38 #if (_SAMBA_BUILD_ >= 4)
  39 #include "build.h"
  40 #include "dynconfig.h"
  41 #endif
  42 
  43 #define LDB_MODULE_PREFIX       "modules:"
  44 #define LDB_MODULE_PREFIX_LEN   8
  45 
  46 static char *ldb_modules_strdup_no_spaces(TALLOC_CTX *mem_ctx, const char *string)
     /* [<][>][^][v][top][bottom][index][help] */
  47 {
  48         int i, len;
  49         char *trimmed;
  50 
  51         trimmed = talloc_strdup(mem_ctx, string);
  52         if (!trimmed) {
  53                 return NULL;
  54         }
  55 
  56         len = strlen(trimmed);
  57         for (i = 0; trimmed[i] != '\0'; i++) {
  58                 switch (trimmed[i]) {
  59                 case ' ':
  60                 case '\t':
  61                 case '\n':
  62                         memmove(&trimmed[i], &trimmed[i + 1], len -i -1);
  63                         break;
  64                 }
  65         }
  66 
  67         return trimmed;
  68 }
  69 
  70 
  71 /* modules are called in inverse order on the stack.
  72    Lets place them as an admin would think the right order is.
  73    Modules order is important */
  74 const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *string)
     /* [<][>][^][v][top][bottom][index][help] */
  75 {
  76         char **modules = NULL;
  77         const char **m;
  78         char *modstr, *p;
  79         int i;
  80 
  81         /* spaces not admitted */
  82         modstr = ldb_modules_strdup_no_spaces(mem_ctx, string);
  83         if ( ! modstr) {
  84                 ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_strdup_no_spaces()\n");
  85                 return NULL;
  86         }
  87 
  88         modules = talloc_realloc(mem_ctx, modules, char *, 2);
  89         if ( ! modules ) {
  90                 ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()\n");
  91                 talloc_free(modstr);
  92                 return NULL;
  93         }
  94         talloc_steal(modules, modstr);
  95 
  96         i = 0;
  97         /* The str*r*chr walks backwards:  This is how we get the inverse order mentioned above */
  98         while ((p = strrchr(modstr, ',')) != NULL) {
  99                 *p = '\0';
 100                 p++;
 101                 modules[i] = p;
 102 
 103                 i++;
 104                 modules = talloc_realloc(mem_ctx, modules, char *, i + 2);
 105                 if ( ! modules ) {
 106                         ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()\n");
 107                         return NULL;
 108                 }
 109 
 110         }
 111         modules[i] = modstr;
 112 
 113         modules[i + 1] = NULL;
 114 
 115         m = (const char **)modules;
 116 
 117         return m;
 118 }
 119 
 120 static struct ops_list_entry {
 121         const struct ldb_module_ops *ops;
 122         struct ops_list_entry *next;    
 123 } *registered_modules = NULL;
 124 
 125 static const struct ldb_module_ops *ldb_find_module_ops(const char *name)
     /* [<][>][^][v][top][bottom][index][help] */
 126 {
 127         struct ops_list_entry *e;
 128  
 129         for (e = registered_modules; e; e = e->next) {
 130                 if (strcmp(e->ops->name, name) == 0) 
 131                         return e->ops;
 132         }
 133 
 134         return NULL;
 135 }
 136 
 137 #ifndef STATIC_ldb_MODULES
 138 
 139 #ifdef HAVE_LDB_LDAP
 140 #define LDAP_INIT ldb_ldap_init,
 141 #else
 142 #define LDAP_INIT
 143 #endif
 144 
 145 #ifdef HAVE_LDB_SQLITE3
 146 #define SQLITE3_INIT ldb_sqlite3_init,
 147 #else
 148 #define SQLITE3_INIT
 149 #endif
 150 
 151 #define STATIC_ldb_MODULES \
 152         {       \
 153                 LDAP_INIT \
 154                 SQLITE3_INIT \
 155                 ldb_tdb_init,   \
 156                 ldb_operational_init,   \
 157                 ldb_rdn_name_init,      \
 158                 ldb_objectclass_init,   \
 159                 ldb_paged_results_init, \
 160                 ldb_sort_init,          \
 161                 ldb_asq_init,           \
 162                 NULL                    \
 163         }
 164 #endif
 165 
 166 int ldb_global_init(void)
     /* [<][>][^][v][top][bottom][index][help] */
 167 {
 168         static int (*static_init_fns[])(void) = STATIC_ldb_MODULES;
 169 
 170         static int initialized = 0;
 171         int ret = 0, i;
 172 
 173         if (initialized) 
 174                 return 0;
 175 
 176         initialized = 1;
 177         
 178         for (i = 0; static_init_fns[i]; i++) {
 179                 if (static_init_fns[i]() == -1)
 180                         ret = -1;
 181         }
 182 
 183         return ret;
 184 }
 185 
 186 int ldb_register_module(const struct ldb_module_ops *ops)
     /* [<][>][^][v][top][bottom][index][help] */
 187 {
 188         struct ops_list_entry *entry = talloc(talloc_autofree_context(), struct ops_list_entry);
 189 
 190         if (ldb_find_module_ops(ops->name) != NULL)
 191                 return -1;
 192 
 193         if (entry == NULL)
 194                 return -1;
 195 
 196         entry->ops = ops;
 197         entry->next = registered_modules;
 198         registered_modules = entry;
 199 
 200         return 0;
 201 }
 202 
 203 int ldb_try_load_dso(struct ldb_context *ldb, const char *name)
     /* [<][>][^][v][top][bottom][index][help] */
 204 {
 205         char *path;
 206         void *handle;
 207         int (*init_fn) (void);
 208         char *modulesdir;
 209         int ret;
 210 
 211 #ifdef HAVE_DLOPEN
 212         if (getenv("LD_LDB_MODULE_PATH") != NULL) {
 213                 modulesdir = talloc_strdup(ldb, getenv("LD_LDB_MODULE_PATH"));
 214         } else {
 215 #ifdef _SAMBA_BUILD_
 216                 modulesdir = talloc_asprintf(ldb, "%s/ldb", get_dyn_LIBDIR());
 217 #else
 218                 modulesdir = talloc_strdup(ldb, MODULESDIR);
 219 #endif
 220         }
 221 
 222         path = talloc_asprintf(ldb, "%s/%s.%s", modulesdir, name, SHLIBEXT);
 223 
 224         talloc_free(modulesdir);
 225 
 226         ldb_debug(ldb, LDB_DEBUG_TRACE, "trying to load %s from %s\n", name, path);
 227 
 228         handle = dlopen(path, RTLD_NOW);
 229         if (handle == NULL) {
 230                 ldb_debug(ldb, LDB_DEBUG_WARNING, "unable to load %s from %s: %s\n", name, path, dlerror());
 231                 return -1;
 232         }
 233 
 234         init_fn = (int (*)(void))dlsym(handle, "init_samba_module");
 235 
 236         if (init_fn == NULL) {
 237                 ldb_debug(ldb, LDB_DEBUG_ERROR, "no symbol "
 238                           "`init_samba_module' found in %s: %s\n", path,
 239                           dlerror());
 240                 dlclose(handle);
 241                 return -1;
 242         }
 243 
 244         talloc_free(path);
 245 
 246         ret = init_fn();
 247         if (ret == -1) {
 248                 dlclose(handle);
 249         }
 250         return ret;
 251 #else
 252         ldb_debug(ldb, LDB_DEBUG_TRACE, "no dlopen() - not trying to load %s module\n", name);
 253         return -1;
 254 #endif
 255 }
 256 
 257 int ldb_load_modules_list(struct ldb_context *ldb, const char **module_list, struct ldb_module *backend, struct ldb_module **out)
     /* [<][>][^][v][top][bottom][index][help] */
 258 {
 259         struct ldb_module *module;
 260         int i;
 261         
 262         module = backend;
 263 
 264         for (i = 0; module_list[i] != NULL; i++) {
 265                 struct ldb_module *current;
 266                 const struct ldb_module_ops *ops;
 267                 
 268                 ops = ldb_find_module_ops(module_list[i]);
 269                 if (ops == NULL) {
 270                         if (ldb_try_load_dso(ldb, module_list[i]) == 0) {
 271                                 ops = ldb_find_module_ops(module_list[i]);
 272                         }
 273                 }
 274                 
 275                 if (ops == NULL) {
 276                         ldb_debug(ldb, LDB_DEBUG_WARNING, "WARNING: Module [%s] not found\n", 
 277                                   module_list[i]);
 278                         continue;
 279                 }
 280                 
 281                 current = talloc_zero(ldb, struct ldb_module);
 282                 if (current == NULL) {
 283                         return LDB_ERR_OPERATIONS_ERROR;
 284                 }
 285                 talloc_set_name(current, "ldb_module: %s", module_list[i]);
 286                 
 287                 current->ldb = ldb;
 288                 current->ops = ops;
 289                 
 290                 DLIST_ADD(module, current);
 291         }
 292         *out = module;
 293         return LDB_SUCCESS;
 294 }
 295 
 296 int ldb_init_module_chain(struct ldb_context *ldb, struct ldb_module *module) 
     /* [<][>][^][v][top][bottom][index][help] */
 297 {
 298         while (module && module->ops->init_context == NULL) 
 299                 module = module->next;
 300 
 301         if (module && module->ops->init_context &&
 302                 module->ops->init_context(module) != LDB_SUCCESS) {
 303                 ldb_debug(ldb, LDB_DEBUG_FATAL, "module initialization failed\n");
 304                 return LDB_ERR_OPERATIONS_ERROR;
 305         }
 306 
 307         return LDB_SUCCESS;
 308 }
 309 
 310 int ldb_load_modules(struct ldb_context *ldb, const char *options[])
     /* [<][>][^][v][top][bottom][index][help] */
 311 {
 312         const char **modules = NULL;
 313         int i;
 314         int ret;
 315         TALLOC_CTX *mem_ctx = talloc_new(ldb);
 316         if (!mem_ctx) {
 317                 return LDB_ERR_OPERATIONS_ERROR;
 318         }
 319 
 320         /* find out which modules we are requested to activate */
 321 
 322         /* check if we have a custom module list passd as ldb option */
 323         if (options) {
 324                 for (i = 0; options[i] != NULL; i++) {
 325                         if (strncmp(options[i], LDB_MODULE_PREFIX, LDB_MODULE_PREFIX_LEN) == 0) {
 326                                 modules = ldb_modules_list_from_string(ldb, mem_ctx, &options[i][LDB_MODULE_PREFIX_LEN]);
 327                         }
 328                 }
 329         }
 330 
 331         /* if not overloaded by options and the backend is not ldap try to load the modules list from ldb */
 332         if ((modules == NULL) && (strcmp("ldap", ldb->modules->ops->name) != 0)) { 
 333                 const char * const attrs[] = { "@LIST" , NULL};
 334                 struct ldb_result *res = NULL;
 335                 struct ldb_dn *mods_dn;
 336 
 337                 mods_dn = ldb_dn_explode(mem_ctx, "@MODULES");
 338                 if (mods_dn == NULL) {
 339                         talloc_free(mem_ctx);
 340                         return -1;
 341                 }
 342 
 343                 ret = ldb_search(ldb, ldb, &res, mods_dn, LDB_SCOPE_BASE, attrs, "");
 344                 talloc_steal(mods_dn, res);
 345                 if (ret == LDB_SUCCESS && (res->count == 0 || res->msgs[0]->num_elements == 0)) {
 346                         ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db\n");
 347                 } else {
 348                         if (ret != LDB_SUCCESS) {
 349                                 ldb_debug(ldb, LDB_DEBUG_FATAL, "ldb error (%s) occurred searching for modules, bailing out\n", ldb_errstring(ldb));
 350                                 talloc_free(mem_ctx);
 351                                 return -1;
 352                         }
 353                         if (res->count > 1) {
 354                                 ldb_debug(ldb, LDB_DEBUG_FATAL, "Too many records found (%d), bailing out\n", res->count);
 355                                 talloc_free(mem_ctx);
 356                                 return -1;
 357                         }
 358 
 359                         modules = ldb_modules_list_from_string(ldb, mem_ctx,
 360                                                                (const char *)res->msgs[0]->elements[0].values[0].data);
 361 
 362                 }
 363 
 364                 talloc_free(mods_dn);
 365         }
 366 
 367         if (modules != NULL) {
 368                 ret = ldb_load_modules_list(ldb, modules, ldb->modules, &ldb->modules);
 369                 talloc_free(modules);
 370                 if (ret != LDB_SUCCESS) {
 371                         return ret;
 372                 }
 373         } else {
 374                 ldb_debug(ldb, LDB_DEBUG_TRACE, "No modules specified for this database\n");
 375         }
 376 
 377         return ldb_init_module_chain(ldb, ldb->modules);
 378 }
 379 
 380 /*
 381   by using this we allow ldb modules to only implement the functions they care about,
 382   which makes writing a module simpler, and makes it more likely to keep working
 383   when ldb is extended
 384 */
 385 #define FIND_OP(module, op) do { \
 386         struct ldb_context *ldb = module->ldb; \
 387         module = module->next; \
 388         while (module && module->ops->op == NULL) module = module->next; \
 389         if (module == NULL) { \
 390                 ldb_asprintf_errstring(ldb, "Unable to find backend operation for " #op ); \
 391                 return LDB_ERR_OPERATIONS_ERROR;        \
 392         }                                               \
 393 } while (0)
 394 
 395 
 396 /*
 397    helper functions to call the next module in chain
 398 */
 399 
 400 int ldb_next_request(struct ldb_module *module, struct ldb_request *request)
     /* [<][>][^][v][top][bottom][index][help] */
 401 {
 402         switch (request->operation) {
 403         case LDB_SEARCH:
 404                 FIND_OP(module, search);
 405                 return module->ops->search(module, request);
 406         case LDB_ADD:
 407                 FIND_OP(module, add);
 408                 return module->ops->add(module, request);
 409         case LDB_MODIFY:
 410                 FIND_OP(module, modify);
 411                 return module->ops->modify(module, request);
 412         case LDB_DELETE:
 413                 FIND_OP(module, del);
 414                 return module->ops->del(module, request);
 415         case LDB_RENAME:
 416                 FIND_OP(module, rename);
 417                 return module->ops->rename(module, request);
 418         case LDB_SEQUENCE_NUMBER:
 419                 FIND_OP(module, sequence_number);
 420                 return module->ops->sequence_number(module, request);
 421         default:
 422                 FIND_OP(module, request);
 423                 return module->ops->request(module, request);
 424         }
 425 }
 426 
 427 int ldb_next_init(struct ldb_module *module)
     /* [<][>][^][v][top][bottom][index][help] */
 428 {
 429         /* init is different in that it is not an error if modules
 430          * do not require initialization */
 431 
 432         module = module->next;
 433 
 434         while (module && module->ops->init_context == NULL) 
 435                 module = module->next;
 436 
 437         if (module == NULL) 
 438                 return LDB_SUCCESS;
 439 
 440         return module->ops->init_context(module);
 441 }
 442 
 443 int ldb_next_start_trans(struct ldb_module *module)
     /* [<][>][^][v][top][bottom][index][help] */
 444 {
 445         FIND_OP(module, start_transaction);
 446         return module->ops->start_transaction(module);
 447 }
 448 
 449 int ldb_next_end_trans(struct ldb_module *module)
     /* [<][>][^][v][top][bottom][index][help] */
 450 {
 451         FIND_OP(module, end_transaction);
 452         return module->ops->end_transaction(module);
 453 }
 454 
 455 int ldb_next_del_trans(struct ldb_module *module)
     /* [<][>][^][v][top][bottom][index][help] */
 456 {
 457         FIND_OP(module, del_transaction);
 458         return module->ops->del_transaction(module);
 459 }

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