root/source4/lib/ldb_wrap.c

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

DEFINITIONS

This source file includes following definitions.
  1. ldb_wrap_debug
  2. ldb_wrap_destructor
  3. ldb_wrap_connect

   1 /* 
   2    Unix SMB/CIFS implementation.
   3 
   4    LDB wrap functions
   5 
   6    Copyright (C) Andrew Tridgell 2004
   7    
   8    This program is free software; you can redistribute it and/or modify
   9    it under the terms of the GNU General Public License as published by
  10    the Free Software Foundation; either version 3 of the License, or
  11    (at your option) any later version.
  12    
  13    This program is distributed in the hope that it will be useful,
  14    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16    GNU General Public License for more details.
  17    
  18    You should have received a copy of the GNU General Public License
  19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20 */
  21 
  22 /*
  23   the stupidity of the unix fcntl locking design forces us to never
  24   allow a database file to be opened twice in the same process. These
  25   wrappers provide convenient access to a tdb or ldb, taking advantage
  26   of talloc destructors to ensure that only a single open is done
  27 */
  28 
  29 #include "includes.h"
  30 #include "lib/events/events.h"
  31 #include "lib/ldb/include/ldb.h"
  32 #include "lib/ldb/include/ldb_errors.h"
  33 #include "lib/ldb-samba/ldif_handlers.h"
  34 #include "ldb_wrap.h"
  35 #include "dsdb/samdb/samdb.h"
  36 #include "param/param.h"
  37 
  38 /*
  39   this is used to catch debug messages from ldb
  40 */
  41 static void ldb_wrap_debug(void *context, enum ldb_debug_level level, 
     /* [<][>][^][v][top][bottom][index][help] */
  42                            const char *fmt, va_list ap)  PRINTF_ATTRIBUTE(3,0);
  43 
  44 static void ldb_wrap_debug(void *context, enum ldb_debug_level level, 
  45                            const char *fmt, va_list ap)
  46 {
  47         int samba_level = -1;
  48         char *s = NULL;
  49         switch (level) {
  50         case LDB_DEBUG_FATAL:
  51                 samba_level = 0;
  52                 break;
  53         case LDB_DEBUG_ERROR:
  54                 samba_level = 1;
  55                 break;
  56         case LDB_DEBUG_WARNING:
  57                 samba_level = 2;
  58                 break;
  59         case LDB_DEBUG_TRACE:
  60                 samba_level = 5;
  61                 break;
  62                 
  63         };
  64         vasprintf(&s, fmt, ap);
  65         if (!s) return;
  66         DEBUG(samba_level, ("ldb: %s\n", s));
  67         free(s);
  68 }
  69 
  70 /* check for memory leaks on the ldb context */
  71 static int ldb_wrap_destructor(struct ldb_context *ldb)
     /* [<][>][^][v][top][bottom][index][help] */
  72 {
  73         size_t *startup_blocks = (size_t *)ldb_get_opaque(ldb, "startup_blocks");
  74 
  75         if (startup_blocks &&
  76             talloc_total_blocks(ldb) > *startup_blocks + 400) {
  77                 DEBUG(0,("WARNING: probable memory leak in ldb %s - %lu blocks (startup %lu) %lu bytes\n",
  78                          (char *)ldb_get_opaque(ldb, "wrap_url"), 
  79                          (unsigned long)talloc_total_blocks(ldb), 
  80                          (unsigned long)*startup_blocks,
  81                          (unsigned long)talloc_total_size(ldb)));
  82 #if 0
  83                 talloc_report_full(ldb, stdout);
  84                 call_backtrace();
  85                 smb_panic("probable memory leak in ldb");
  86 #endif
  87         }
  88         return 0;
  89 }                                
  90 
  91 /*
  92   wrapped connection to a ldb database
  93   to close just talloc_free() the returned ldb_context
  94 
  95   TODO:  We need an error_string parameter
  96  */
  97 struct ldb_context *ldb_wrap_connect(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
  98                                      struct tevent_context *ev,
  99                                      struct loadparm_context *lp_ctx,
 100                                      const char *url,
 101                                      struct auth_session_info *session_info,
 102                                      struct cli_credentials *credentials,
 103                                      unsigned int flags,
 104                                      const char *options[])
 105 {
 106         struct ldb_context *ldb;
 107         int ret;
 108         char *real_url = NULL;
 109         size_t *startup_blocks;
 110 
 111         /* we want to use the existing event context if possible. This
 112            relies on the fact that in smbd, everything is a child of
 113            the main event_context */
 114         if (ev == NULL) {
 115                 return NULL;
 116         }
 117 
 118         ldb = ldb_init(mem_ctx, ev);
 119         if (ldb == NULL) {
 120                 return NULL;
 121         }
 122 
 123         ldb_set_modules_dir(ldb,
 124                             talloc_asprintf(ldb,
 125                                             "%s/ldb",
 126                                             lp_modulesdir(lp_ctx)));
 127 
 128         if (ldb_set_opaque(ldb, "sessionInfo", session_info)) {
 129                 talloc_free(ldb);
 130                 return NULL;
 131         }
 132 
 133         if (ldb_set_opaque(ldb, "credentials", credentials)) {
 134                 talloc_free(ldb);
 135                 return NULL;
 136         }
 137 
 138         if (ldb_set_opaque(ldb, "loadparm", lp_ctx)) {
 139                 talloc_free(ldb);
 140                 return NULL;
 141         }
 142 
 143         /* This must be done before we load the schema, as these
 144          * handlers for objectSid and objectGUID etc must take
 145          * precedence over the 'binary attribute' declaration in the
 146          * schema */
 147         ret = ldb_register_samba_handlers(ldb);
 148         if (ret == -1) {
 149                 talloc_free(ldb);
 150                 return NULL;
 151         }
 152 
 153         if (lp_ctx != NULL && strcmp(lp_sam_url(lp_ctx), url) == 0) {
 154                 dsdb_set_global_schema(ldb);
 155         }
 156 
 157         ldb_set_debug(ldb, ldb_wrap_debug, NULL);
 158 
 159         ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
 160 
 161         real_url = private_path(ldb, lp_ctx, url);
 162         if (real_url == NULL) {
 163                 talloc_free(ldb);
 164                 return NULL;
 165         }
 166 
 167         /* allow admins to force non-sync ldb for all databases */
 168         if (lp_parm_bool(lp_ctx, NULL, "ldb", "nosync", false)) {
 169                 flags |= LDB_FLG_NOSYNC;
 170         }
 171 
 172         /* we usually want Samba databases to be private. If we later
 173            find we need one public, we will need to add a parameter to
 174            ldb_wrap_connect() */
 175         ldb_set_create_perms(ldb, 0600);
 176         
 177         ret = ldb_connect(ldb, real_url, flags, options);
 178         if (ret != LDB_SUCCESS) {
 179                 talloc_free(ldb);
 180                 return NULL;
 181         }
 182 
 183         /* setup for leak detection */
 184         ldb_set_opaque(ldb, "wrap_url", real_url);
 185         startup_blocks = talloc(ldb, size_t);
 186         *startup_blocks = talloc_total_blocks(ldb);
 187         ldb_set_opaque(ldb, "startup_blocks", startup_blocks);
 188         
 189         talloc_set_destructor(ldb, ldb_wrap_destructor);
 190 
 191         return ldb;
 192 }

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