2 OpenChange Storage Abstraction Layer library
6 Copyright (C) Julien Kerihuel 2010-2011
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/>.
22 #include "mapiproxy/libmapistore/mapistore_errors.h"
23 #include "mapiproxy/libmapistore/mapistore.h"
24 #include "mapiproxy/libmapistore/mapistore_private.h"
29 \brief MAPIStore database provisioning interface
32 int lpcfg_server_role(struct loadparm_context *lp_ctx);
35 \details Initialize the mapistore database context
37 \param mem_ctx pointer to the memory context
38 \param path string pointer to the mapistore database location
40 If path if NULL use the default mapistore database path instead.
42 \return Allocated mapistore database context on success, otherwise NULL
44 struct mapistoredb_context *mapistoredb_init(TALLOC_CTX *mem_ctx,
47 struct mapistoredb_context *mdb_ctx;
56 path = MAPISTORE_DBPATH;
59 /* Ensure the path is valid */
60 if (stat(path, &sb) == -1) {
65 /* Step 1. Initialize mapistoredb context */
66 mdb_ctx = talloc_zero(mem_ctx, struct mapistoredb_context);
67 mdb_ctx->param = talloc_zero(mem_ctx, struct mapistoredb_conf);
68 if (!mdb_ctx->param) {
69 DEBUG(5, ("! [%s:%d][%s]: Failed to allocate memory for mdb_ctx->param", __FILE__, __LINE__, __FUNCTION__));
74 /* Step 2. Initialize Samba loadparm context and load default values */
75 mdb_ctx->lp_ctx = loadparm_init(mdb_ctx);
76 lpcfg_load_default(mdb_ctx->lp_ctx);
78 /* Step 3. Initialize tevent structure */
79 mdb_ctx->ev = tevent_context_init(mdb_ctx);
81 /* Step 4. Open a wrapped connection on the mapistore database */
82 full_path = talloc_asprintf(mem_ctx, "%s/mapistore.ldb", path);
83 mdb_ctx->ldb_ctx = mapistore_ldb_wrap_connect(mdb_ctx, mdb_ctx->ev, full_path, 0);
84 talloc_free(full_path);
85 if (!mdb_ctx->ldb_ctx) {
86 DEBUG(5, ("! [%s:%d][%s]: Failed to open wrapped connection over mapistore.ldb\n", __FILE__, __LINE__, __FUNCTION__));
91 /* Step 5. Retrieve default values from smb.conf */
92 mdb_ctx->param->netbiosname = strlower_talloc(mdb_ctx->param, lpcfg_netbios_name(mdb_ctx->lp_ctx));
93 mdb_ctx->param->dnsdomain = strlower_talloc(mdb_ctx->param, lpcfg_realm(mdb_ctx->lp_ctx));
94 mdb_ctx->param->domain = strlower_talloc(mdb_ctx->param, lpcfg_sam_name(mdb_ctx->lp_ctx));
96 switch (lpcfg_server_role(mdb_ctx->lp_ctx)) {
97 case ROLE_DOMAIN_CONTROLLER:
98 domaindn = str_list_make(mdb_ctx->param, mdb_ctx->param->dnsdomain, ".");
99 strlower_m(domaindn[0]);
100 mdb_ctx->param->domaindn = talloc_asprintf(mdb_ctx->param, "DC_%s", domaindn[0]);
101 for (i = 1; domaindn[i]; i++) {
102 strlower_m(domaindn[i]);
103 mdb_ctx->param->domaindn = talloc_asprintf_append_buffer(mdb_ctx->param->domaindn, ",DC=%s", domaindn[i]);
105 talloc_free(domaindn);
108 mdb_ctx->param->domaindn = talloc_asprintf(mdb_ctx->param, "CN=%s", mdb_ctx->param->domain);
112 mdb_ctx->param->serverdn = talloc_asprintf(mdb_ctx->param, TMPL_MDB_SERVERDN,
113 mdb_ctx->param->netbiosname,
114 mdb_ctx->param->domaindn);
115 mdb_ctx->param->firstorg = talloc_strdup(mdb_ctx->param, DFLT_MDB_FIRSTORG);
116 mdb_ctx->param->firstou = talloc_strdup(mdb_ctx->param, DFLT_MDB_FIRSTOU);
117 mdb_ctx->param->firstorgdn = talloc_asprintf(mdb_ctx->param, TMPL_MDB_FIRSTORGDN,
118 mdb_ctx->param->firstou,
119 mdb_ctx->param->firstorg,
120 mdb_ctx->param->serverdn);
121 mdb_ctx->param->db_path = talloc_asprintf(mdb_ctx->param, "%s/mapistore.ldb", path);
122 mdb_ctx->param->mstore_path = talloc_asprintf(mdb_ctx->param, "%s/mapistore", path);
124 /* Step 6. Initialize mapistore */
125 if (stat(mdb_ctx->param->mstore_path, &sb) == -1) {
126 ret = mkdir(mdb_ctx->param->mstore_path, 0700);
128 perror(mdb_ctx->param->mstore_path);
129 talloc_free(mdb_ctx);
134 mapistore_set_database_path(mdb_ctx->param->db_path);
135 mapistore_set_mapping_path(mdb_ctx->param->mstore_path);
136 mdb_ctx->mstore_ctx = mapistore_init(mdb_ctx, NULL);
137 if (!mdb_ctx->mstore_ctx) {
138 DEBUG(5, ("! [%s:%d][%s]: Failed to initialize mapistore context\n", __FILE__, __LINE__, __FUNCTION__));
139 talloc_free(mdb_ctx);
148 \details Free a mapistore database context
150 \param mdb_ctx the context to free (from mapistoredb_init())
152 void mapistoredb_release(struct mapistoredb_context *mdb_ctx)
155 DEBUG(5, ("! [%s:%d][%s]: Invalid mapistore database context\n", __FILE__, __LINE__, __FUNCTION__));
159 talloc_free(mdb_ctx->lp_ctx);
160 talloc_free(mdb_ctx->param);
161 talloc_free(mdb_ctx);
166 \details Get a mapistore URI for a system/special folder from
169 \param mdb_ctx pointer to the mapistore database context
170 \param username the username for which we want to retrieve the uri
171 \param uri the uri namespace to query
172 \param namespace_uri the namespace uri to return
174 \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR
176 enum MAPISTORE_ERROR mapistoredb_get_mapistore_uri(struct mapistoredb_context *mdb_ctx,
177 enum MAPISTORE_DFLT_FOLDERS index,
178 const char *namespace_uri,
179 const char *username,
182 enum MAPISTORE_ERROR retval;
186 if (!mdb_ctx || !mdb_ctx->mstore_ctx) {
187 DEBUG(5, ("! [%s:%d][%s]: Invalid mapistore database context\n", __FILE__, __LINE__, __FUNCTION__));
188 return MAPISTORE_ERR_INVALID_CONTEXT;
190 if (!namespace_uri || !username) {
191 DEBUG(5, ("! [%s:%d][%s]: Invalid parameter\n", __FILE__, __LINE__, __FUNCTION__));
192 return MAPISTORE_ERR_INVALID_PARAMETER;
195 retval = mapistore_create_uri(mdb_ctx->mstore_ctx, index, namespace_uri, username, &_uri);
196 if (retval == MAPISTORE_SUCCESS) {
204 /** TODO: this is a copy of code in mapistore_mstoredb.c */
205 static bool write_ldif_string_to_store(struct ldb_context *ldb_ctx, const char *ldif_string)
207 struct ldb_ldif *ldif;
210 while ((ldif = ldb_ldif_read_string(ldb_ctx, (const char **)&ldif_string))) {
211 ret = ldb_msg_normalize(ldb_ctx, ldif, ldif->msg, &ldif->msg);
212 if (ret != LDB_SUCCESS) {
213 ldb_ldif_read_free(ldb_ctx, ldif);
216 ret = ldb_add(ldb_ctx, ldif->msg);
217 if (ret != LDB_SUCCESS) {
218 ldb_ldif_read_free(ldb_ctx, ldif);
221 ldb_ldif_read_free(ldb_ctx, ldif);
229 \details Default provisioning for mapistore.ldb database
231 \param mdb_ctx pointer to the mapistore database context
233 \return MAPISTORE_SUCCESS on success, otherwise a non-zero MAPISTORE_ERROR
235 enum MAPISTORE_ERROR mapistoredb_provision(struct mapistoredb_context *mdb_ctx)
240 if (!mdb_ctx || !mdb_ctx->ldb_ctx) return MAPISTORE_ERR_NOT_INITIALIZED;
242 /* Step 1. Add database schema */
243 if (write_ldif_string_to_store(mdb_ctx->ldb_ctx, MDB_INIT_LDIF_TMPL) == false) {
244 DEBUG(5, ("! [%s:%d][%s]: Failed to add database schema\n", __FILE__, __LINE__, __FUNCTION__));
245 return MAPISTORE_ERR_DATABASE_OPS;
248 /* Step 2. Add RootDSE schema */
249 ldif_str = talloc_asprintf(mdb_ctx, MDB_ROOTDSE_LDIF_TMPL,
250 mdb_ctx->param->firstou,
251 mdb_ctx->param->firstorg,
252 mdb_ctx->param->serverdn,
253 mdb_ctx->param->serverdn);
254 if (write_ldif_string_to_store(mdb_ctx->ldb_ctx, ldif_str) == false) {
255 DEBUG(5, ("! [%s:%d][%s]: Failed to add RootDSE schema\n", __FILE__, __LINE__, __FUNCTION__));
256 talloc_free(ldif_str);
257 return MAPISTORE_ERR_DATABASE_OPS;
259 talloc_free(ldif_str);
261 /* Step 3. Provision Server object responsible for maintaining
262 * the Replica identifier */
263 ldif_str = talloc_asprintf(mdb_ctx, MDB_SERVER_LDIF_TMPL,
264 mdb_ctx->param->serverdn,
265 mdb_ctx->param->netbiosname,
266 mdb_ctx->param->firstorg,
267 mdb_ctx->param->serverdn,
268 mdb_ctx->param->firstorg,
269 mdb_ctx->param->firstou,
270 mdb_ctx->param->firstorg,
271 mdb_ctx->param->serverdn,
272 mdb_ctx->param->firstou);
273 if (write_ldif_string_to_store(mdb_ctx->ldb_ctx, ldif_str) == false) {
274 DEBUG(5, ("! [%s:%d][%s]: Failed to provision server object\n", __FILE__, __LINE__, __FUNCTION__));
275 talloc_free(ldif_str);
276 return MAPISTORE_ERR_DATABASE_OPS;
278 talloc_free(ldif_str);
280 return MAPISTORE_SUCCESS;