talloc: Do an early return
[Samba.git] / lib / ldb-samba / ldb_wrap.c
blob65956efffbf0f6cab574250b10805b06713989a4
1 /*
2 Unix SMB/CIFS implementation.
4 LDB wrap functions
6 Copyright (C) Andrew Tridgell 2004-2009
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.
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.
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/>.
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
29 #include "includes.h"
30 #include "lib/events/events.h"
31 #include <ldb.h>
32 #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 #include "../lib/util/dlinklist.h"
38 #include <tdb.h>
40 #define DBGC_CLASS DBGC_LDB
43 this is used to catch debug messages from ldb
45 static void ldb_wrap_debug(void *context, enum ldb_debug_level level,
46 const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
48 static void ldb_wrap_debug(void *context, enum ldb_debug_level level,
49 const char *fmt, va_list ap)
51 int samba_level = -1;
52 switch (level) {
53 case LDB_DEBUG_FATAL:
54 samba_level = 0;
55 break;
56 case LDB_DEBUG_ERROR:
57 samba_level = 1;
58 break;
59 case LDB_DEBUG_WARNING:
60 samba_level = 2;
61 break;
62 case LDB_DEBUG_TRACE:
63 samba_level = 10;
64 break;
67 if (CHECK_DEBUGLVL(samba_level)) {
68 char *s = NULL;
69 vasprintf(&s, fmt, ap);
70 if (!s) return;
71 DEBUG(samba_level, ("ldb: %s\n", s));
72 free(s);
78 connecting to a ldb can be a relatively expensive operation because
79 of the schema and partition loads. We keep a list of open ldb
80 contexts here, and try to re-use when possible.
82 This means callers of ldb_wrap_connect() must use talloc_unlink() or
83 the free of a parent to destroy the context
85 static struct ldb_wrap {
86 struct ldb_wrap *next, *prev;
87 struct ldb_wrap_context {
88 /* the context is what we use to tell if two ldb
89 * connections are exactly equivalent
91 const char *url;
92 struct tevent_context *ev;
93 struct loadparm_context *lp_ctx;
94 struct auth_session_info *session_info;
95 struct cli_credentials *credentials;
96 unsigned int flags;
97 } context;
98 struct ldb_context *ldb;
99 } *ldb_wrap_list;
102 free a ldb_wrap structure
104 static int ldb_wrap_destructor(struct ldb_wrap *w)
106 DLIST_REMOVE(ldb_wrap_list, w);
107 return 0;
111 * The casefolder for s4's LDB databases - Unicode-safe
113 char *wrap_casefold(void *context, void *mem_ctx, const char *s, size_t n)
115 return strupper_talloc_n(mem_ctx, s, n);
119 struct ldb_context *samba_ldb_init(TALLOC_CTX *mem_ctx,
120 struct tevent_context *ev,
121 struct loadparm_context *lp_ctx,
122 struct auth_session_info *session_info,
123 struct cli_credentials *credentials)
125 struct ldb_context *ldb;
126 int ret;
128 ldb = ldb_init(mem_ctx, ev);
129 if (ldb == NULL) {
130 return NULL;
133 ldb_set_modules_dir(ldb, modules_path(ldb, "ldb"));
135 ldb_set_debug(ldb, ldb_wrap_debug, NULL);
137 ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
139 if (session_info) {
140 if (ldb_set_opaque(ldb, "sessionInfo", session_info)) {
141 talloc_free(ldb);
142 return NULL;
146 if (credentials) {
147 if (ldb_set_opaque(ldb, "credentials", credentials)) {
148 talloc_free(ldb);
149 return NULL;
153 if (ldb_set_opaque(ldb, "loadparm", lp_ctx)) {
154 talloc_free(ldb);
155 return NULL;
158 /* This must be done before we load the schema, as these
159 * handlers for objectSid and objectGUID etc must take
160 * precedence over the 'binary attribute' declaration in the
161 * schema */
162 ret = ldb_register_samba_handlers(ldb);
163 if (ret != LDB_SUCCESS) {
164 talloc_free(ldb);
165 return NULL;
168 /* we usually want Samba databases to be private. If we later
169 find we need one public, we will need to add a parameter to
170 ldb_wrap_connect() */
171 ldb_set_create_perms(ldb, 0600);
173 return ldb;
176 struct ldb_context *ldb_wrap_find(const char *url,
177 struct tevent_context *ev,
178 struct loadparm_context *lp_ctx,
179 struct auth_session_info *session_info,
180 struct cli_credentials *credentials,
181 unsigned int flags)
183 struct ldb_wrap *w;
184 /* see if we can re-use an existing ldb */
185 for (w=ldb_wrap_list; w; w=w->next) {
186 if (w->context.ev == ev &&
187 w->context.lp_ctx == lp_ctx &&
188 w->context.session_info == session_info &&
189 w->context.credentials == credentials &&
190 w->context.flags == flags &&
191 (w->context.url == url || strcmp(w->context.url, url) == 0))
192 return w->ldb;
195 return NULL;
198 int samba_ldb_connect(struct ldb_context *ldb, struct loadparm_context *lp_ctx,
199 const char *url, unsigned int flags)
201 int ret;
202 char *real_url = NULL;
204 /* allow admins to force non-sync ldb for all databases */
205 if (lpcfg_parm_bool(lp_ctx, NULL, "ldb", "nosync", false)) {
206 flags |= LDB_FLG_NOSYNC;
209 if (DEBUGLVL(10)) {
210 flags |= LDB_FLG_ENABLE_TRACING;
213 real_url = lpcfg_private_path(ldb, lp_ctx, url);
214 if (real_url == NULL) {
215 return LDB_ERR_OPERATIONS_ERROR;
218 ret = ldb_connect(ldb, real_url, flags, NULL);
220 if (ret != LDB_SUCCESS) {
221 return ret;
224 /* setup for leak detection */
225 ldb_set_opaque(ldb, "wrap_url", real_url);
227 return LDB_SUCCESS;
230 bool ldb_wrap_add(const char *url, struct tevent_context *ev,
231 struct loadparm_context *lp_ctx,
232 struct auth_session_info *session_info,
233 struct cli_credentials *credentials,
234 unsigned int flags,
235 struct ldb_context *ldb)
237 struct ldb_wrap *w;
238 struct ldb_wrap_context c;
240 /* add to the list of open ldb contexts */
241 w = talloc(ldb, struct ldb_wrap);
242 if (w == NULL) {
243 return false;
246 c.url = url;
247 c.ev = ev;
248 c.lp_ctx = lp_ctx;
249 c.session_info = session_info;
250 c.credentials = credentials;
251 c.flags = flags;
253 w->context = c;
254 w->context.url = talloc_strdup(w, url);
255 if (w->context.url == NULL) {
256 return false;
259 if (session_info) {
260 /* take a reference to the session_info, as it is
261 * possible for the ldb to live longer than the
262 * session_info. This happens when a DRS DsBind call
263 * reuses a handle, but the original connection is
264 * shutdown. The token for the new connection is still
265 * valid, so we need the session_info to remain valid for
266 * ldb modules to use
268 if (talloc_reference(w, session_info) == NULL) {
269 return false;
273 w->ldb = ldb;
275 DLIST_ADD(ldb_wrap_list, w);
277 talloc_set_destructor(w, ldb_wrap_destructor);
279 return true;
284 wrapped connection to a ldb database
285 to close just talloc_free() the returned ldb_context
287 TODO: We need an error_string parameter
289 struct ldb_context *ldb_wrap_connect(TALLOC_CTX *mem_ctx,
290 struct tevent_context *ev,
291 struct loadparm_context *lp_ctx,
292 const char *url,
293 struct auth_session_info *session_info,
294 struct cli_credentials *credentials,
295 unsigned int flags)
297 struct ldb_context *ldb;
298 int ret;
300 ldb = ldb_wrap_find(url, ev, lp_ctx, session_info, credentials, flags);
301 if (ldb != NULL)
302 return talloc_reference(mem_ctx, ldb);
304 ldb = samba_ldb_init(mem_ctx, ev, lp_ctx, session_info, credentials);
306 if (ldb == NULL)
307 return NULL;
309 ret = samba_ldb_connect(ldb, lp_ctx, url, flags);
310 if (ret != LDB_SUCCESS) {
311 talloc_free(ldb);
312 return NULL;
315 if (!ldb_wrap_add(url, ev, lp_ctx, session_info, credentials, flags, ldb)) {
316 talloc_free(ldb);
317 return NULL;
320 DEBUG(3,("ldb_wrap open of %s\n", url));
322 return ldb;
326 when we fork() we need to make sure that any open ldb contexts have
327 any open transactions cancelled (ntdb databases doesn't need reopening,
328 as we don't use clear_if_first).
330 void ldb_wrap_fork_hook(void)
332 struct ldb_wrap *w;
334 for (w=ldb_wrap_list; w; w=w->next) {
335 if (ldb_transaction_cancel_noerr(w->ldb) != LDB_SUCCESS) {
336 smb_panic("Failed to cancel child transactions\n");
340 if (tdb_reopen_all(1) != 0) {
341 smb_panic("tdb_reopen_all failed\n");
345 char *ldb_relative_path(struct ldb_context *ldb,
346 TALLOC_CTX *mem_ctx,
347 const char *name)
349 const char *base_url =
350 (const char *)ldb_get_opaque(ldb, "ldb_url");
351 char *path, *p, *full_name;
352 if (name == NULL) {
353 return NULL;
355 if (strncmp("tdb://", base_url, 6) == 0) {
356 base_url = base_url+6;
358 path = talloc_strdup(mem_ctx, base_url);
359 if (path == NULL) {
360 return NULL;
362 if ( (p = strrchr(path, '/')) != NULL) {
363 p[0] = '\0';
364 full_name = talloc_asprintf(mem_ctx, "%s/%s", path, name);
365 } else {
366 full_name = talloc_asprintf(mem_ctx, "./%s", name);
368 talloc_free(path);
369 return full_name;