Merge in r3480 from sogo branch: Fix const * warning
[jelmer/openchange.git] / mapiproxy / libmapistore / mapistore_ldb_wrap.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    LDB wrap functions
5
6    Copyright (C) Andrew Tridgell 2004-2009
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 #include "config.h"
23 #include <stdio.h>
24 #include <string.h>
25
26 #include "mapistore.h"
27 #include "mapistore_private.h"
28 #include <dlinklist.h>
29 #include <ldb.h>
30
31 static struct ldb_wrap *ldb_wrap_list;
32
33 /*
34   see if two database opens are equivalent
35  */
36 static bool mapistore_ldb_wrap_same_context(const struct ldb_wrap_context *c1,
37                                             const struct ldb_wrap_context *c2)
38 {
39         return (c1->ev == c2->ev &&
40                 c1->flags == c2->flags &&
41                 (c1->url == c2->url || strcmp(c1->url, c2->url) == 0));
42 }
43
44 /* 
45    free a ldb_wrap structure
46  */
47 static int mapistore_ldb_wrap_destructor(struct ldb_wrap *w)
48 {
49         DLIST_REMOVE(ldb_wrap_list, w);
50         return 0;
51 }
52
53 /*
54   wrapped connection to a ldb database
55   to close just talloc_free() the returned ldb_context
56
57   TODO:  We need an error_string parameter
58  */
59 struct ldb_context *mapistore_ldb_wrap_connect(TALLOC_CTX *mem_ctx,
60                                                struct tevent_context *ev,
61                                                const char *url,
62                                                unsigned int flags)
63 {
64         struct ldb_context      *ldb;
65         int                     ret;
66         struct ldb_wrap         *w;
67         struct ldb_wrap_context c;
68
69         c.url          = url;
70         c.ev           = ev;
71         c.flags        = flags;
72
73         /* see if we can re-use an existing ldb */
74         for (w = ldb_wrap_list; w; w = w->next) {
75                 if (mapistore_ldb_wrap_same_context(&c, &w->context)) {
76                         return talloc_reference(mem_ctx, w->ldb);
77                 }
78         }
79
80         /* we want to use the existing event context if possible. This
81            relies on the fact that in smbd, everything is a child of
82            the main event_context */
83         if (ev == NULL) {
84                 return NULL;
85         }
86
87         ldb = ldb_init(mem_ctx, ev);
88         if (ldb == NULL) {
89                 return NULL;
90         }
91
92         ldb_set_create_perms(ldb, 0600);
93         
94         ret = ldb_connect(ldb, url, flags, NULL);
95         if (ret != LDB_SUCCESS) {
96                 talloc_free(ldb);
97                 return NULL;
98         }
99
100         /* add to the list of open ldb contexts */
101         w = talloc(ldb, struct ldb_wrap);
102         if (w == NULL) {
103                 talloc_free(ldb);
104                 return NULL;
105         }
106
107         w->context = c;
108         w->context.url = talloc_strdup(w, url);
109         if (w->context.url == NULL) {
110                 talloc_free(ldb);
111                 return NULL;
112         }
113
114         w->ldb = ldb;
115
116         DLIST_ADD(ldb_wrap_list, w);
117
118         DEBUG(3,("ldb_wrap open of %s\n", url));
119
120         talloc_set_destructor(w, mapistore_ldb_wrap_destructor);
121
122         return ldb;
123 }