~ubuntu-branches/debian/sid/openchange/sid

« back to all changes in this revision

Viewing changes to mapiproxy/libmapistore/backends/mapistore_mstoredb.c

  • Committer: Package Import Robot
  • Author(s): Jelmer Vernooij
  • Date: 2012-04-12 20:07:57 UTC
  • mfrom: (11 sid)
  • mto: This revision was merged to the branch mainline in revision 12.
  • Revision ID: package-import@ubuntu.com-20120412200757-k933d9trljmxj1l4
Tags: 1:1.0-4
* openchangeserver: Add dependency on openchangeproxy.
* Rebuild against newer version of Samba 4.
* Use dpkg-buildflags.
* Migrate to Git, update Vcs-Git header.
* Switch to debhelper 9.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
   OpenChange Storage Abstraction Layer library
3
 
   MAPIStore database backend
4
 
 
5
 
   OpenChange Project
6
 
 
7
 
   Copyright (C) Julien Kerihuel 2010-2011
8
 
   Copyright (C) Brad Hards 2010-2011
9
 
 
10
 
   This program is free software; you can redistribute it and/or modify
11
 
   it under the terms of the GNU General Public License as published by
12
 
   the Free Software Foundation; either version 3 of the License, or
13
 
   (at your option) any later version.
14
 
   
15
 
   This program is distributed in the hope that it will be useful,
16
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 
   GNU General Public License for more details.
19
 
   
20
 
   You should have received a copy of the GNU General Public License
21
 
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
 
 */
23
 
 
24
 
#include "mapistore_mstoredb.h"
25
 
#include "mapiproxy/libmapiproxy/libmapiproxy.h"
26
 
 
27
 
/**
28
 
   \details Initialize mstoredb mapistore backend
29
 
 
30
 
   \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
31
 
 */
32
 
static enum MAPISTORE_ERROR mstoredb_init(void)
33
 
{
34
 
        MSTORE_DEBUG_INFO(MSTORE_LEVEL_INFO, MSTORE_SINGLE_MSG, "mstoredb backend initialized\n");
35
 
        return MAPISTORE_SUCCESS;
36
 
}
37
 
 
38
 
/**
39
 
   \details Generate a mapistore URI for root (system/special) folders
40
 
 
41
 
   \param mem_ctx pointer to the memory context
42
 
   \param index the folder index for which to create the mapistore URI
43
 
   \param username the username for which to create the mapistore URI
44
 
   \param mapistore_uri pointer on pointer to the string to return
45
 
 
46
 
   \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
47
 
 */
48
 
static enum MAPISTORE_ERROR mstoredb_create_mapistore_uri(TALLOC_CTX *mem_ctx,
49
 
                                                          enum MAPISTORE_DFLT_FOLDERS index,
50
 
                                                          const char *username,
51
 
                                                          char **mapistore_uri)
52
 
{
53
 
        const char      *firstorgdn;
54
 
        int             i;
55
 
 
56
 
        /* Sanity checks */
57
 
        if (!username || !mapistore_uri) {
58
 
                MSTORE_DEBUG_ERROR(MSTORE_LEVEL_PEDANTIC, MSTORE_SINGLE_MSG, "Invalid parameter\n");
59
 
                return MAPISTORE_ERR_INVALID_PARAMETER;
60
 
        }
61
 
 
62
 
        firstorgdn = mapistore_get_firstorgdn();
63
 
        if (!firstorgdn) {
64
 
                MSTORE_DEBUG_ERROR(MSTORE_LEVEL_PEDANTIC, MSTORE_SINGLE_MSG, "Invalid firstorgdn\n");
65
 
                return MAPISTORE_ERR_INVALID_PARAMETER;
66
 
        }
67
 
 
68
 
        for (i = 0; dflt_folders[i].name; i++) {
69
 
                if (dflt_folders[i].index == index) {
70
 
                        *mapistore_uri = talloc_asprintf(mem_ctx, "mstoredb://%s,CN=%s,%s", dflt_folders[i].name, username, firstorgdn);
71
 
                        MSTORE_DEBUG_SUCCESS(MSTORE_LEVEL_DEBUG, "URI = %s\n", *mapistore_uri);
72
 
                        return MAPISTORE_SUCCESS;
73
 
                }
74
 
        }
75
 
 
76
 
        return MAPISTORE_ERR_NOT_FOUND;
77
 
}
78
 
 
79
 
/**
80
 
   \details Provides a LDIF file or buffer to upper mapistore layers
81
 
   to provision mstoredb:// Internal namespace
82
 
 
83
 
   \param mem_ctx pointer to the memory context
84
 
   \param ldif pointer on pointer to the LDIF filename or buffer to return
85
 
   \param type pointer to the type of LDIF content to return
86
 
 
87
 
   \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
88
 
 */
89
 
static enum MAPISTORE_ERROR mstoredb_provision_namedprops(TALLOC_CTX *mem_ctx,
90
 
                                                          char **ldif,
91
 
                                                          enum MAPISTORE_NAMEDPROPS_PROVISION_TYPE *ntype)
92
 
{
93
 
        /* Sanity checks */
94
 
        MAPISTORE_RETVAL_IF(!ldif, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
95
 
 
96
 
        return MAPISTORE_ERR_NOT_IMPLEMENTED;
97
 
}
98
 
 
99
 
/**
100
 
   \details Create a connection context to the mstoredb backend 
101
 
 
102
 
   \param ctx pointer to the opaque mapistore backend context
103
 
   \param login_user the username used to authenticate
104
 
   \param username the username we want to impersonate
105
 
   \param uri pointer to the mstoredb DN to open
106
 
   \param private_data pointer to the private backend context to return
107
 
 */
108
 
static enum MAPISTORE_ERROR mstoredb_create_context(struct mapistore_backend_context *ctx,
109
 
                                                    const char *login_user,
110
 
                                                    const char *username,
111
 
                                                    const char *uri,
112
 
                                                    void **private_data)
113
 
{
114
 
        enum MAPISTORE_ERROR    retval;
115
 
        TALLOC_CTX              *mem_ctx;
116
 
        struct mstoredb_context *mstoredb_ctx;
117
 
        char                    *new_uri;
118
 
 
119
 
        /* Sanity checks */
120
 
        MAPISTORE_RETVAL_IF(!ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
121
 
        MAPISTORE_RETVAL_IF(!uri, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
122
 
        MAPISTORE_RETVAL_IF(!private_data, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
123
 
 
124
 
        MSTORE_DEBUG_SUCCESS(MSTORE_LEVEL_PEDANTIC, "uri = %s\n", uri);
125
 
 
126
 
        mem_ctx = (TALLOC_CTX *) ctx;
127
 
        
128
 
        /* Step 1. Initialize mstoredb context */
129
 
        mstoredb_ctx = talloc_zero(mem_ctx, struct mstoredb_context);
130
 
        mstoredb_ctx->context_dn = talloc_strdup(mstoredb_ctx, uri);
131
 
        mstoredb_ctx->login_user = talloc_strdup(mstoredb_ctx, username);
132
 
        mstoredb_ctx->username = talloc_strdup(mstoredb_ctx, username);
133
 
        mstoredb_ctx->mdb_ctx = ctx;
134
 
 
135
 
        /* Step 2. Retrieve path to the mapistore database */
136
 
        mstoredb_ctx->dbpath = mapistore_get_database_path();
137
 
        MSTORE_DEBUG_SUCCESS(MSTORE_LEVEL_PEDANTIC, "database path = %s\n", mstoredb_ctx->dbpath);
138
 
 
139
 
        /* Step 3. Open a wrapped connection to mapistore.ldb */
140
 
        mstoredb_ctx->ldb_ctx = mapistore_public_ldb_connect(mstoredb_ctx->mdb_ctx, mstoredb_ctx->dbpath);
141
 
        if (!mstoredb_ctx->ldb_ctx) {
142
 
                MSTORE_DEBUG_ERROR(MSTORE_LEVEL_CRITICAL, "Unable to open mapistore.ldb at %s\n", mstoredb_ctx->dbpath);
143
 
                talloc_free(mstoredb_ctx);
144
 
                return MAPISTORE_ERR_DATABASE_INIT;
145
 
        }
146
 
 
147
 
        /* Step 4. Retrieve the FID associated to this URI */
148
 
        new_uri = talloc_asprintf(mem_ctx, "mstoredb://%s", uri);
149
 
        retval = mapistore_exist(mstoredb_ctx->mdb_ctx, username, new_uri);
150
 
        if (retval != MAPISTORE_ERR_EXIST) {
151
 
                MSTORE_DEBUG_ERROR(MSTORE_LEVEL_DEBUG, "Indexing database failed to find a record for URI: %s\n", uri);
152
 
                talloc_free(new_uri);
153
 
                talloc_free(mstoredb_ctx);
154
 
                
155
 
                return retval;
156
 
        }
157
 
        talloc_free(new_uri);
158
 
 
159
 
        mstoredb_ctx->basedn = ldb_dn_new(mstoredb_ctx, mstoredb_ctx->ldb_ctx, uri);
160
 
        if (!mstoredb_ctx->basedn) {
161
 
                MSTORE_DEBUG_ERROR(MSTORE_LEVEL_DEBUG, MSTORE_SINGLE_MSG, "Unable to create DN from URI");
162
 
                talloc_free(mstoredb_ctx);
163
 
                return MAPISTORE_ERROR;         
164
 
        }
165
 
 
166
 
        *private_data = (void *)mstoredb_ctx;
167
 
 
168
 
        return MAPISTORE_SUCCESS;
169
 
}
170
 
 
171
 
/**
172
 
   \details Delete a connection context from the mstoredb backend
173
 
 
174
 
   \param private_data pointer to the current mstoredb context
175
 
 
176
 
   \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
177
 
 */
178
 
static enum MAPISTORE_ERROR mstoredb_delete_context(void *private_data)
179
 
{
180
 
        MSTORE_DEBUG_INFO(MSTORE_LEVEL_DEBUG, MSTORE_SINGLE_MSG, "");
181
 
 
182
 
        return MAPISTORE_SUCCESS;
183
 
}
184
 
 
185
 
/**
186
 
   \details Create a root default/system mailbox folder in the
187
 
   mstoredb backend and store store common attributes for caching
188
 
   purposes.
189
 
 
190
 
   \param private_data pointer to the current mstoredb context
191
 
   \param mapistore_uri pointer to the mapistore URI for the folder
192
 
   \param folder_name the name of the folder to create
193
 
   \param folder_desc the description for the folder
194
 
 
195
 
   \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
196
 
 */
197
 
static enum MAPISTORE_ERROR mstoredb_op_db_mkdir(void *private_data,
198
 
                                                 enum MAPISTORE_DFLT_FOLDERS system_idx,
199
 
                                                 const char *mapistore_uri,
200
 
                                                 const char *folder_name)
201
 
{
202
 
        TALLOC_CTX                      *mem_ctx;
203
 
        struct mstoredb_context         *mstoredb_ctx = (struct mstoredb_context *) private_data;
204
 
        enum MAPISTORE_ERROR            retval;
205
 
        char                            *mapistore_root_folder = NULL;
206
 
        int                             i;
207
 
        const char                      *cn = NULL;
208
 
        const char                      *container_class = "IPF.Note";
209
 
        const char                      *uri;
210
 
 
211
 
        MSTORE_DEBUG_INFO(MSTORE_LEVEL_DEBUG, MSTORE_SINGLE_MSG, "");
212
 
 
213
 
        /* Sanity checks */
214
 
        MAPISTORE_RETVAL_IF(!mstoredb_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
215
 
        MAPISTORE_RETVAL_IF(!mapistore_uri, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
216
 
 
217
 
        /* Step 1. Ensure the mapistore URI doesn't already exist in the indexing database */
218
 
        retval = mapistore_exist(mstoredb_ctx->mdb_ctx, mstoredb_ctx->username, mapistore_uri);
219
 
        if (retval == MAPISTORE_ERR_EXIST) {
220
 
                MSTORE_DEBUG_ERROR(MSTORE_LEVEL_HIGH, "URI for %s already registered (%s)\n", mstoredb_ctx->username, mapistore_uri);
221
 
                return retval;
222
 
        }
223
 
 
224
 
        /* Step 2. Retrieve the cn attribute's value from our dflt folder array */
225
 
        for (i = 0; dflt_folders[i].name; i++) {
226
 
                if (dflt_folders[i].index == system_idx) {
227
 
                        if (!folder_name) {
228
 
                                folder_name = dflt_folders[i].cn;
229
 
                        }
230
 
                        cn = dflt_folders[i].cn;
231
 
                        container_class = dflt_folders[i].container_class;
232
 
                        break;
233
 
                }
234
 
        }
235
 
        MAPISTORE_RETVAL_IF(!cn, MAPISTORE_ERR_INVALID_URI, NULL);
236
 
 
237
 
        /* Step 3. Strip out the namespace from URI if required */
238
 
        if (!strncmp("mstoredb://", mapistore_uri, strlen("mstoredb://"))) {
239
 
                uri = &mapistore_uri[strlen("mstoredb://")];
240
 
        } else {
241
 
                uri = mapistore_uri;
242
 
        }
243
 
 
244
 
        /* Step 3. Create the LDIF formated entry for the folder */
245
 
        mem_ctx = talloc_new(NULL);
246
 
        mapistore_root_folder = talloc_asprintf(mem_ctx, MDB_ROOTFOLDER_LDIF_TMPL,
247
 
                                                uri, cn, folder_name, container_class,
248
 
                                                system_idx);
249
 
 
250
 
        /* Step 3. Create folder entry within mapistore.ldb */
251
 
        retval = mapistore_ldb_write_ldif_string_to_store(mstoredb_ctx->ldb_ctx, mapistore_root_folder);
252
 
        talloc_free(mapistore_root_folder);
253
 
        talloc_free(mem_ctx);
254
 
 
255
 
        return retval;
256
 
}
257
 
 
258
 
/**
259
 
   \details Create a folder in the mstoredb backend
260
 
 
261
 
   \param private_data pointer to the current mstoredb backend
262
 
   \param parent_uri the parent folder mapistore URI
263
 
   \param folder_name the folder name to be created
264
 
   \param folder_desc the folder description for the folder 
265
 
   \param folder_type the type of folder
266
 
   \param folder_uri the folder URI to return
267
 
 
268
 
   \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
269
 
 */
270
 
static enum MAPISTORE_ERROR mstoredb_op_mkdir(void *private_data,
271
 
                                              const char *parent_uri,
272
 
                                              const char *folder_name,
273
 
                                              const char *folder_desc,
274
 
                                              enum FOLDER_TYPE folder_type,
275
 
                                              char **folder_uri)
276
 
{
277
 
        TALLOC_CTX                      *mem_ctx;
278
 
        enum MAPISTORE_ERROR            retval = MAPISTORE_SUCCESS;
279
 
        const char                      *stripped_uri;
280
 
        struct mstoredb_context         *mstoredb_ctx = (struct mstoredb_context *) private_data;
281
 
        char                            *ldif;
282
 
        const char                      *folder_dn;
283
 
 
284
 
        MSTORE_DEBUG_INFO(MSTORE_LEVEL_DEBUG, MSTORE_SINGLE_MSG, "");
285
 
 
286
 
        /* Sanity checks */
287
 
        MAPISTORE_RETVAL_IF(!mstoredb_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
288
 
        MAPISTORE_RETVAL_IF(!parent_uri, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
289
 
        MAPISTORE_RETVAL_IF(!folder_name, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
290
 
        MAPISTORE_RETVAL_IF(!folder_uri, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
291
 
 
292
 
        *folder_uri = NULL;
293
 
 
294
 
        /* Step 1. Ensure the parent uri exists */
295
 
        retval = mapistore_exist(mstoredb_ctx->mdb_ctx, mstoredb_ctx->username, parent_uri);
296
 
        if (retval != MAPISTORE_ERR_EXIST) {
297
 
                MSTORE_DEBUG_ERROR(MSTORE_LEVEL_HIGH, "Failed to find parent folder: %s\n", parent_uri);
298
 
                return retval;
299
 
        }
300
 
 
301
 
        mem_ctx = talloc_named(NULL, 0, __FUNCTION__);
302
 
 
303
 
        /* Step 2. Generate the URI for the folder */
304
 
        retval = mapistore_strip_ns_from_uri(parent_uri, &stripped_uri);
305
 
 
306
 
        *folder_uri = talloc_asprintf((TALLOC_CTX *)mstoredb_ctx, "mstoredb://CN=%s,%s", folder_name, stripped_uri);
307
 
        MAPISTORE_RETVAL_IF(!*folder_uri, MAPISTORE_ERR_NO_MEMORY, mem_ctx);
308
 
        MSTORE_DEBUG_INFO(MSTORE_LEVEL_DEBUG, "Generated URI: '%s'\n", *folder_uri);
309
 
 
310
 
        retval = mapistore_strip_ns_from_uri(*folder_uri, &folder_dn);
311
 
        if (retval) {
312
 
                talloc_free(*folder_uri);
313
 
                *folder_uri = NULL;
314
 
                goto error;
315
 
        }
316
 
 
317
 
        /* Ensure the folder doesn't exist */
318
 
        retval = mapistore_exist(mstoredb_ctx->mdb_ctx, mstoredb_ctx->username, (const char *)*folder_uri);
319
 
        if (retval == MAPISTORE_ERR_EXIST) {
320
 
                MSTORE_DEBUG_ERROR(MSTORE_LEVEL_INFO, "URI already exists!: %s\n", *folder_uri);
321
 
                talloc_free(*folder_uri);
322
 
                *folder_uri = NULL;
323
 
                goto error;
324
 
        }
325
 
 
326
 
        /* Do ACLs check on parent URI */
327
 
        
328
 
        /* Do folder creation */
329
 
        if (folder_desc) {
330
 
                ldif = talloc_asprintf(mem_ctx, MDB_FOLDER_WITH_COMMENT_LDIF_TMPL,
331
 
                                       folder_dn, folder_name, (uint32_t)folder_type,
332
 
                                       folder_name, folder_desc);
333
 
                if (!ldif) {
334
 
                        retval = MAPISTORE_ERR_NO_MEMORY;
335
 
                        goto error;
336
 
                }
337
 
        } else {
338
 
                ldif = talloc_asprintf(mem_ctx, MDB_FOLDER_WITH_NAME_LDIF_TMPL,
339
 
                                       folder_dn, folder_name, (uint32_t)folder_type,
340
 
                                       folder_name);
341
 
        }
342
 
 
343
 
        retval = mapistore_ldb_write_ldif_string_to_store(mstoredb_ctx->ldb_ctx, ldif);
344
 
        talloc_free(ldif);
345
 
 
346
 
error:
347
 
        talloc_free(mem_ctx);
348
 
        return retval;
349
 
}
350
 
 
351
 
 
352
 
static enum MAPISTORE_ERROR mstoredb_op_opendir(void *private_data,
353
 
                                                const char *parent_uri,
354
 
                                                const char *folder_uri)
355
 
{
356
 
        struct mstoredb_context *mstoredb_ctx = (struct mstoredb_context *) private_data;
357
 
 
358
 
        /* Sanity checks */
359
 
        MAPISTORE_RETVAL_IF(!mstoredb_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
360
 
        MAPISTORE_RETVAL_IF(!parent_uri, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
361
 
        MAPISTORE_RETVAL_IF(!folder_uri, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
362
 
 
363
 
        /* TODO: This is just a stub implementation */
364
 
        MSTORE_DEBUG_INFO(MSTORE_LEVEL_DEBUG, "Opening: %s\n", folder_uri);
365
 
 
366
 
        return MAPISTORE_SUCCESS;
367
 
}
368
 
 
369
 
static enum MAPISTORE_ERROR mstoredb_op_setprops(void *private_data,
370
 
                                                 const char *uri,
371
 
                                                 uint8_t type,
372
 
                                                 struct SRow *aRow)
373
 
{
374
 
        struct mstoredb_context         *mstoredb_ctx = (struct mstoredb_context *) private_data;
375
 
        const char                      *dn = NULL;
376
 
        enum MAPISTORE_ERROR            retval;
377
 
        struct ldb_message              *msg = NULL;
378
 
        TALLOC_CTX                      *mem_ctx = NULL;
379
 
        int                             i = 0;
380
 
        int                             ret;
381
 
 
382
 
        MSTORE_DEBUG_INFO(MSTORE_LEVEL_DEBUG, "Setting properties on %s\n", uri);
383
 
 
384
 
        /* Sanity checks */
385
 
        MAPISTORE_RETVAL_IF(!mstoredb_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
386
 
        MAPISTORE_RETVAL_IF(!uri, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
387
 
        MAPISTORE_RETVAL_IF(!aRow, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
388
 
 
389
 
        retval = mapistore_strip_ns_from_uri(uri, &dn);
390
 
        MAPISTORE_RETVAL_IF(retval, retval, NULL);
391
 
 
392
 
        MSTORE_DEBUG_INFO(MSTORE_LEVEL_DEBUG, "Setting props on dn: '%s'\n", dn);
393
 
 
394
 
        /* TODO: ensure the uri exists */
395
 
 
396
 
        /* TODO: check ACLs on folder */
397
 
 
398
 
        /* build the ldb_msg */
399
 
        mem_ctx = talloc_named(NULL, 0, __FUNCTION__);
400
 
        msg = ldb_msg_new(mem_ctx);
401
 
        msg->dn = ldb_dn_new(msg, mstoredb_ctx->ldb_ctx, dn);
402
 
        for (i = 0; i < aRow->cValues; ++i) {
403
 
                char *property_tag = talloc_strdup(mem_ctx, get_proptag_name(aRow->lpProps[i].ulPropTag));
404
 
                if (!property_tag) {
405
 
                        property_tag = talloc_asprintf(mem_ctx, "0x%"PRIx32, aRow->lpProps[i].ulPropTag);
406
 
                }
407
 
                switch (aRow->lpProps[i].ulPropTag & 0xFFFF) {
408
 
                case PT_I2:
409
 
                        ldb_msg_add_fmt(msg, property_tag , "%"PRIi16, aRow->lpProps[i].value.i);
410
 
                        break;
411
 
                case PT_LONG:
412
 
                        ldb_msg_add_fmt(msg, property_tag, "%"PRIi32, aRow->lpProps[i].value.l);
413
 
                        break;
414
 
                case PT_BOOLEAN:
415
 
                        ldb_msg_add_fmt(msg, property_tag, aRow->lpProps[i].value.b?"True":"False");
416
 
                        break;
417
 
                case PT_DOUBLE:
418
 
                        ldb_msg_add_fmt(msg, property_tag, "%g", aRow->lpProps[i].value.dbl);
419
 
                        break;
420
 
                case PT_I8:
421
 
                        ldb_msg_add_fmt(msg, property_tag, "0x%"PRIx64, aRow->lpProps[i].value.d);
422
 
                        break;
423
 
                case PT_STRING8:
424
 
                        ldb_msg_add_fmt(msg, property_tag, "%s", aRow->lpProps[i].value.lpszA);
425
 
                        break;
426
 
                case PT_UNICODE:
427
 
                        ldb_msg_add_fmt(msg, property_tag, "%s", aRow->lpProps[i].value.lpszW);
428
 
                        break;
429
 
                default:
430
 
                        MSTORE_DEBUG_INFO(MSTORE_LEVEL_CRITICAL, "Unsupported property type: 0x%x\n", aRow->lpProps[i].ulPropTag & 0xFFFF);
431
 
                }
432
 
                msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
433
 
        }
434
 
      
435
 
        /* Write properties to store */
436
 
        ret = ldb_modify(mstoredb_ctx->ldb_ctx, msg);
437
 
        if (ret != LDB_SUCCESS) {
438
 
                MSTORE_DEBUG_INFO(MSTORE_LEVEL_CRITICAL, "Failed to set properties on %s: %s\n", uri, ldb_strerror(ret));;
439
 
                talloc_free(mem_ctx);
440
 
                return MAPISTORE_ERR_DATABASE_OPS;
441
 
        }
442
 
        talloc_free(mem_ctx);
443
 
 
444
 
        return MAPISTORE_SUCCESS;
445
 
}
446
 
 
447
 
/**
448
 
   \details Entry point for mapistore MSTOREDB backend
449
 
 
450
 
   \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
451
 
 */
452
 
enum MAPISTORE_ERROR mapistore_init_backend(void)
453
 
{
454
 
        struct mapistore_backend        backend;
455
 
        enum MAPISTORE_ERROR            retval;
456
 
 
457
 
        /* Initialize backend with defaults */
458
 
        retval = mapistore_backend_init_defaults(&backend);
459
 
        MAPISTORE_RETVAL_IF(retval, retval, NULL);
460
 
 
461
 
        /* Fill in our name */
462
 
        backend.name = "mstoredb";
463
 
        backend.description = "mapistore database backend";
464
 
        backend.uri_namespace = "mstoredb://";
465
 
        
466
 
        /* Fill in backend operations */
467
 
        backend.init = mstoredb_init;
468
 
        backend.create_context = mstoredb_create_context;
469
 
        backend.delete_context = mstoredb_delete_context;
470
 
 
471
 
        /* Fill in folder operations */
472
 
        backend.op_mkdir = mstoredb_op_mkdir;
473
 
        backend.op_opendir = mstoredb_op_opendir;
474
 
        backend.op_setprops = mstoredb_op_setprops;
475
 
 
476
 
        /* Fill in MAPIStoreDB/store operations */
477
 
        backend.op_db_create_uri = mstoredb_create_mapistore_uri;
478
 
        backend.op_db_provision_namedprops = mstoredb_provision_namedprops;
479
 
        backend.op_db_mkdir = mstoredb_op_db_mkdir;
480
 
 
481
 
        /* Register ourselves with the MAPISTORE subsystem */
482
 
        retval = mapistore_backend_register(&backend);
483
 
        if (retval != MAPISTORE_SUCCESS) {
484
 
                MSTORE_DEBUG_ERROR(MSTORE_LEVEL_CRITICAL, "Failed to register the '%s' mapistore backend!\n", backend.name);
485
 
        }
486
 
 
487
 
        return retval;
488
 
}