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 "lib/util/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 /* we usually want Samba databases to be private. If we later
129 find we need one public, we will need to add a parameter to
130 ldb_wrap_connect() */
131 ldb_set_create_perms(ldb
, 0600);
133 ret
= ldb_connect(ldb
, real_url
, flags
, options
);
134 if (ret
!= LDB_SUCCESS
) {
139 talloc_free(real_url
);
141 ldb_set_debug(ldb
, ldb_wrap_debug
, NULL
);
143 ldb_set_utf8_fns(ldb
, NULL
, wrap_casefold
);
150 Log tdb messages via DEBUG().
152 static void tdb_wrap_log(TDB_CONTEXT
*tdb
, enum tdb_debug_level level
,
153 const char *format
, ...) PRINTF_ATTRIBUTE(3,4);
155 static void tdb_wrap_log(TDB_CONTEXT
*tdb
, enum tdb_debug_level level
,
156 const char *format
, ...)
162 va_start(ap
, format
);
163 vasprintf(&ptr
, format
, ap
);
167 case TDB_DEBUG_FATAL
:
170 case TDB_DEBUG_ERROR
:
173 case TDB_DEBUG_WARNING
:
176 case TDB_DEBUG_TRACE
:
184 const char *name
= tdb_name(tdb
);
185 DEBUG(debug_level
, ("tdb(%s): %s", name
? name
: "unnamed", ptr
));
191 /* destroy the last connection to a tdb */
192 static int tdb_wrap_destructor(struct tdb_wrap
*w
)
195 DLIST_REMOVE(tdb_list
, w
);
200 wrapped connection to a tdb database
201 to close just talloc_free() the tdb_wrap pointer
203 struct tdb_wrap
*tdb_wrap_open(TALLOC_CTX
*mem_ctx
,
204 const char *name
, int hash_size
, int tdb_flags
,
205 int open_flags
, mode_t mode
)
208 struct tdb_logging_context log_ctx
;
209 log_ctx
.log_fn
= tdb_wrap_log
;
211 for (w
=tdb_list
;w
;w
=w
->next
) {
212 if (strcmp(name
, w
->name
) == 0) {
213 return talloc_reference(mem_ctx
, w
);
217 w
= talloc(mem_ctx
, struct tdb_wrap
);
222 w
->name
= talloc_strdup(w
, name
);
224 w
->tdb
= tdb_open_ex(name
, hash_size
, tdb_flags
,
225 open_flags
, mode
, &log_ctx
, NULL
);
226 if (w
->tdb
== NULL
) {
231 talloc_set_destructor(w
, tdb_wrap_destructor
);
233 DLIST_ADD(tdb_list
, w
);