2 Unix SMB/CIFS implementation.
4 database wrap functions
6 Copyright (C) Andrew Tridgell 2004
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 2 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, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 the stupidity of the unix fcntl locking design forces us to never
25 allow a database file to be opened twice in the same process. These
26 wrappers provide convenient access to a tdb or ldb, taking advantage
27 of talloc destructors to ensure that only a single open is done
31 #include "dlinklist.h"
32 #include "lib/events/events.h"
33 #include "lib/tdb/include/tdb.h"
34 #include "lib/ldb/include/ldb.h"
35 #include "lib/ldb/include/ldb_errors.h"
36 #include "lib/ldb/samba/ldif_handlers.h"
39 static struct tdb_wrap
*tdb_list
;
42 this is used to catch debug messages from ldb
44 static void ldb_wrap_debug(void *context
, enum ldb_debug_level level
,
45 const char *fmt
, va_list ap
) PRINTF_ATTRIBUTE(3,0);
47 static void ldb_wrap_debug(void *context
, enum ldb_debug_level level
,
48 const char *fmt
, va_list ap
)
51 if (DEBUGLEVEL
< 4 && level
> LDB_DEBUG_WARNING
) {
54 if (DEBUGLEVEL
< 2 && level
> LDB_DEBUG_ERROR
) {
57 vasprintf(&s
, fmt
, ap
);
59 DEBUG(level
, ("ldb: %s\n", s
));
63 char *wrap_casefold(void *context
, void *mem_ctx
, const char *s
)
65 return strupper_talloc(mem_ctx
, s
);
69 wrapped connection to a ldb database
70 to close just talloc_free() the returned ldb_context
72 TODO: We need an error_string parameter
74 struct ldb_context
*ldb_wrap_connect(TALLOC_CTX
*mem_ctx
,
76 struct auth_session_info
*session_info
,
77 struct cli_credentials
*credentials
,
79 const char *options
[])
81 struct ldb_context
*ldb
;
83 struct event_context
*ev
;
84 char *real_url
= NULL
;
86 ldb
= ldb_init(mem_ctx
);
91 /* we want to use the existing event context if possible. This
92 relies on the fact that in smbd, everything is a child of
93 the main event_context */
94 ev
= event_context_find(ldb
);
96 if (ldb_set_opaque(ldb
, "EventContext", ev
)) {
101 if (ldb_set_opaque(ldb
, "sessionInfo", session_info
)) {
106 if (ldb_set_opaque(ldb
, "credentials", credentials
)) {
111 ret
= ldb_register_samba_handlers(ldb
);
117 real_url
= private_path(ldb
, url
);
118 if (real_url
== NULL
) {
123 /* allow admins to force non-sync ldb for all databases */
124 if (lp_parm_bool(-1, "ldb", "nosync", False
)) {
125 flags
|= LDB_FLG_NOSYNC
;
128 ret
= ldb_connect(ldb
, real_url
, flags
, options
);
129 if (ret
!= LDB_SUCCESS
) {
134 talloc_free(real_url
);
136 ldb_set_debug(ldb
, ldb_wrap_debug
, NULL
);
138 ldb_set_utf8_fns(ldb
, NULL
, wrap_casefold
);
145 Log tdb messages via DEBUG().
147 static void tdb_wrap_log(TDB_CONTEXT
*tdb
, int level
,
148 const char *format
, ...) PRINTF_ATTRIBUTE(3,4);
150 static void tdb_wrap_log(TDB_CONTEXT
*tdb
, int level
,
151 const char *format
, ...)
156 va_start(ap
, format
);
157 vasprintf(&ptr
, format
, ap
);
161 const char *name
= tdb_name(tdb
);
162 DEBUG(level
, ("tdb(%s): %s", name
? name
: "unnamed", ptr
));
168 /* destroy the last connection to a tdb */
169 static int tdb_wrap_destructor(struct tdb_wrap
*w
)
172 DLIST_REMOVE(tdb_list
, w
);
177 wrapped connection to a tdb database
178 to close just talloc_free() the tdb_wrap pointer
180 struct tdb_wrap
*tdb_wrap_open(TALLOC_CTX
*mem_ctx
,
181 const char *name
, int hash_size
, int tdb_flags
,
182 int open_flags
, mode_t mode
)
186 for (w
=tdb_list
;w
;w
=w
->next
) {
187 if (strcmp(name
, w
->name
) == 0) {
188 return talloc_reference(mem_ctx
, w
);
192 w
= talloc(mem_ctx
, struct tdb_wrap
);
197 w
->name
= talloc_strdup(w
, name
);
199 w
->tdb
= tdb_open_ex(name
, hash_size
, tdb_flags
,
200 open_flags
, mode
, tdb_wrap_log
, NULL
);
201 if (w
->tdb
== NULL
) {
206 talloc_set_destructor(w
, tdb_wrap_destructor
);
208 DLIST_ADD(tdb_list
, w
);