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

« back to all changes in this revision

Viewing changes to mapiproxy/libmapistore/database/mapistoredb_namedprops.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
 
 
4
 
   OpenChange Project
5
 
 
6
 
   Copyright (C) Julien Kerihuel 2011
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 <string.h>
23
 
 
24
 
#include "mapistore_errors.h"
25
 
#include "mapistore.h"
26
 
#include "mapistore_private.h"
27
 
#include "mapistore_common.h"
28
 
 
29
 
/**
30
 
   \file mapistoredb_namedprops.c
31
 
 
32
 
   \brief MAPIStore named properties database provisioning interface
33
 
 */
34
 
 
35
 
/**
36
 
   \details Provision the default named properties database for mapistore
37
 
 
38
 
   \param mdb_ctx pointer to the mapistore database context
39
 
 
40
 
   \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
41
 
 */
42
 
enum MAPISTORE_ERROR mapistoredb_namedprops_provision(struct mapistoredb_context *mdb_ctx)
43
 
{
44
 
        enum MAPISTORE_ERROR    retval;
45
 
        TALLOC_CTX              *mem_ctx;
46
 
        int                     ret;
47
 
        struct stat             sb;
48
 
        char                    *ldif;
49
 
 
50
 
        /* Sanity checks */
51
 
        MAPISTORE_RETVAL_IF(!mdb_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
52
 
        MAPISTORE_RETVAL_IF(!mdb_ctx->mstore_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
53
 
        MAPISTORE_RETVAL_IF(!mdb_ctx->mstore_ctx->mapistore_nprops_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
54
 
 
55
 
        ret = stat(mapistore_get_named_properties_database_path(), &sb);
56
 
        MAPISTORE_RETVAL_IF(ret == -1, MAPISTORE_ERR_DATABASE_INIT, NULL);
57
 
 
58
 
        mem_ctx = talloc_named(NULL, 0, __FUNCTION__);
59
 
        MAPISTORE_RETVAL_IF(!mem_ctx, MAPISTORE_ERR_NO_MEMORY, NULL);
60
 
 
61
 
        /* Step 1. Retrieve the path to the LDIF file */
62
 
        ldif = talloc_asprintf(mem_ctx, "%s/%s", mapistore_get_named_properties_ldif_path(), MAPISTORE_DB_NAMED_V2_LDIF);
63
 
        ret = stat(ldif, &sb);
64
 
        MAPISTORE_RETVAL_IF(ret == -1, MAPISTORE_ERR_DATABASE_INIT, mem_ctx);
65
 
 
66
 
        /* Step 2. Add database schema */
67
 
        retval = mapistore_ldb_write_ldif_string_to_store(mdb_ctx->mstore_ctx->mapistore_nprops_ctx, 
68
 
                                                          MDB_NPROPS_INIT_LDIF_TMPL);
69
 
        MAPISTORE_RETVAL_IF(retval, retval, mem_ctx);
70
 
 
71
 
        /* Step 3. Add RootDSE schema */
72
 
        retval = mapistore_ldb_write_ldif_string_to_store(mdb_ctx->mstore_ctx->mapistore_nprops_ctx,
73
 
                                                          MDB_NPROPS_ROOTDSE_LDIF_TMPL);
74
 
        MAPISTORE_RETVAL_IF(retval, retval, mem_ctx);
75
 
 
76
 
        /* Step 2. Commit the database structure and default set of named properties */
77
 
        retval = mapistore_ldb_write_ldif_file_to_store(mdb_ctx->mstore_ctx->mapistore_nprops_ctx, ldif);
78
 
        MAPISTORE_RETVAL_IF(retval, retval, mem_ctx);
79
 
 
80
 
        talloc_free(ldif);
81
 
        talloc_free(mem_ctx);
82
 
 
83
 
        return MAPISTORE_SUCCESS;
84
 
}
85
 
 
86
 
static enum MAPISTORE_ERROR mapistoredb_namedprops_provision_backend_set(TALLOC_CTX *mem_ctx,
87
 
                                                                         struct mapistore_context *mstore_ctx,
88
 
                                                                         struct ldb_ldif *ldif,
89
 
                                                                         char **ldif_record,
90
 
                                                                         uint32_t *ext_index, uint32_t *int_index)
91
 
{
92
 
        enum MAPISTORE_ERROR            retval;
93
 
        struct ldb_context              *ldb_ctx;
94
 
        struct ldb_message              *normalized_msg;
95
 
        struct ldb_message_element      *ldb_element;
96
 
        const char                      *objectClass;
97
 
        bool                            oclass_external = false;
98
 
        bool                            oclass_internal = false;
99
 
        enum MAPISTORE_NAMEDPROPS_TYPE  ntype;
100
 
        bool                            mnidstring = false;
101
 
        uint32_t                        index;
102
 
        const char                      *dn;
103
 
        int                             ret;
104
 
        int                             i;
105
 
 
106
 
        /* Sanity checks */
107
 
        MAPISTORE_RETVAL_IF(!mstore_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
108
 
        MAPISTORE_RETVAL_IF(!mstore_ctx->mapistore_nprops_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
109
 
        MAPISTORE_RETVAL_IF(!ldif, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
110
 
 
111
 
        ldb_ctx = mstore_ctx->mapistore_nprops_ctx;
112
 
 
113
 
        /* Step 1. Normalize the message */
114
 
        ret = ldb_msg_normalize(ldb_ctx, mem_ctx, ldif->msg, &normalized_msg);
115
 
        MAPISTORE_RETVAL_IF(ret != LDB_SUCCESS, MAPISTORE_ERR_DATABASE_OPS, NULL);
116
 
 
117
 
        /* Step 2. Ensure the record has a DN */
118
 
        dn = ldb_dn_get_linearized(normalized_msg->dn);
119
 
        if (!dn) {
120
 
                MSTORE_DEBUG_ERROR(MSTORE_LEVEL_CRITICAL, "Missing %s!\n", "dn");
121
 
                return MAPISTORE_ERR_DATABASE_OPS;
122
 
        }
123
 
 
124
 
        /* Step 3. Search for the objectClass attribute */
125
 
        ldb_element = ldb_msg_find_element(normalized_msg, "objectClass");
126
 
        MAPISTORE_RETVAL_IF(!ldb_element, MAPISTORE_ERR_DATABASE_OPS, NULL);
127
 
 
128
 
        oclass_external = false;
129
 
        oclass_internal = false;
130
 
        mnidstring = false;
131
 
        for (i = 0; i < ldb_element->num_values; i++) {
132
 
                if (ldb_element->values[i].length) {
133
 
                        objectClass = (const char *)ldb_element->values[i].data;
134
 
                        if (!strncmp(objectClass, "External", strlen(objectClass))) {
135
 
                                oclass_external = true;
136
 
                        } else if (!strncmp(objectClass, "Internal", strlen(objectClass))) {
137
 
                                oclass_internal = true;
138
 
                        } else if (!strncmp(objectClass, "MNID_ID", strlen(objectClass)) ||
139
 
                                   !strncmp(objectClass, "MNID_STRING", strlen(objectClass))) {
140
 
                                mnidstring = true;
141
 
                        }
142
 
                } else {
143
 
                        MSTORE_DEBUG_ERROR(MSTORE_LEVEL_CRITICAL, "Invalid objectClass for dn: %s\n", dn);
144
 
                        return MAPISTORE_ERR_DATABASE_OPS;
145
 
                }
146
 
        }
147
 
 
148
 
        /* Step 4. Perform sanity checks on objectClass */
149
 
 
150
 
        /* Step 4.1. Record can't have both External and Internal set for objectClass attribute */
151
 
        if (oclass_external == true && oclass_internal == true) {
152
 
                MSTORE_DEBUG_ERROR(MSTORE_LEVEL_CRITICAL, "External and Internal objectClass set for dn: %s\n", dn);
153
 
                return MAPISTORE_ERR_DATABASE_OPS;
154
 
        }
155
 
 
156
 
        /* Step 4.2. Neither can they be both unset */
157
 
        if (oclass_external == false && oclass_internal == false && mnidstring == true) {
158
 
                MSTORE_DEBUG_ERROR(MSTORE_LEVEL_CRITICAL, "objectClass must be set to External or Internal for dn: %s\n", dn);
159
 
                return MAPISTORE_ERR_DATABASE_OPS;
160
 
        }
161
 
 
162
 
        /* Step 5. Set index to appropriate value */
163
 
        if (oclass_external == true) {
164
 
                ntype = MAPISTORE_NAMEDPROPS_EXTERNAL;
165
 
                index = *ext_index;
166
 
        } else {
167
 
                ntype = MAPISTORE_NAMEDPROPS_INTERNAL;
168
 
                index = *int_index;
169
 
        }
170
 
 
171
 
        /* Ensure the index doesn't equal a reserved value */
172
 
        while ((retval = mapistore_namedprops_check_id(mstore_ctx, ntype, index)) != MAPISTORE_SUCCESS) {
173
 
                index++;
174
 
        }
175
 
 
176
 
        /* Step 6. Add the mapped_id attribute to the record */
177
 
        if (mnidstring == true) {
178
 
                ret = ldb_msg_add_fmt(normalized_msg, "mapped_id", "0x%.4x", index);
179
 
                if (ret != LDB_SUCCESS) {
180
 
                        MSTORE_DEBUG_ERROR(MSTORE_LEVEL_CRITICAL, "Failed to add attribute mapped_id for dn: %s\n", dn);
181
 
                        return MAPISTORE_ERR_DATABASE_OPS;
182
 
                }
183
 
 
184
 
                /* Step 7. Update the appropriate index */
185
 
                index++;
186
 
                if (oclass_external == true) {
187
 
                        *ext_index = index;
188
 
                } else {
189
 
                        *int_index = index;
190
 
                }
191
 
        }
192
 
 
193
 
        /* Step 8. Add the new msg to our LDIF buffer */
194
 
        *ldif_record = ldb_ldif_message_string(ldb_ctx, mem_ctx, LDB_CHANGETYPE_ADD, normalized_msg);
195
 
        if (!*ldif_record) {
196
 
                MSTORE_DEBUG_ERROR(MSTORE_LEVEL_CRITICAL, "Failed to save intermediary LDIF record: %s\n", dn);
197
 
                return MAPISTORE_ERR_DATABASE_OPS;
198
 
        }
199
 
        
200
 
        return MAPISTORE_SUCCESS;
201
 
}
202
 
 
203
 
 
204
 
static enum MAPISTORE_ERROR mapistoredb_namedprops_provision_backend_ldif_file(TALLOC_CTX *mem_ctx,
205
 
                                                                               struct mapistore_context *mstore_ctx,
206
 
                                                                               char *filename, char **ldif_buffer, 
207
 
                                                                               char **mod_ldif)
208
 
{
209
 
        enum MAPISTORE_ERROR            retval;
210
 
        FILE                            *f;
211
 
        struct ldb_context              *ldb_ctx;
212
 
        struct ldb_ldif                 *ldif;
213
 
        struct stat                     sb;
214
 
        char                            *ldif_record;
215
 
        uint32_t                        int_index;
216
 
        uint32_t                        ext_index;
217
 
 
218
 
        /* Sanity checks */
219
 
        MAPISTORE_RETVAL_IF(!mstore_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
220
 
        MAPISTORE_RETVAL_IF(!mstore_ctx->mapistore_nprops_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
221
 
        MAPISTORE_RETVAL_IF(!filename, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
222
 
        MAPISTORE_RETVAL_IF(!ldif_buffer, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
223
 
        MAPISTORE_RETVAL_IF(!mod_ldif, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
224
 
 
225
 
        ldb_ctx = mstore_ctx->mapistore_nprops_ctx;
226
 
 
227
 
        /* Step 1. Retrieve mapped index for CN=External and CN=Internal */
228
 
        retval = mapistore_namedprops_get_default_id(mstore_ctx, MAPISTORE_NAMEDPROPS_INTERNAL, &int_index);
229
 
        MAPISTORE_RETVAL_IF(retval, retval, NULL);
230
 
 
231
 
        retval = mapistore_namedprops_get_default_id(mstore_ctx, MAPISTORE_NAMEDPROPS_EXTERNAL, &ext_index);
232
 
        MAPISTORE_RETVAL_IF(retval, retval, NULL);
233
 
 
234
 
        /* Step 2. Ensure the file exists */
235
 
        if (stat(filename, &sb) == -1) {
236
 
                MSTORE_DEBUG_ERROR(MSTORE_LEVEL_CRITICAL, "Invalid LDIF file: %s\n", filename);
237
 
                return MAPISTORE_ERR_NOT_FOUND;
238
 
        }
239
 
 
240
 
        f = fopen(filename, "r");
241
 
        MAPISTORE_RETVAL_IF(!f, MAPISTORE_ERR_DATABASE_INIT, NULL);
242
 
 
243
 
        /* Step 3. Process the LDIF file */
244
 
        while ((ldif = ldb_ldif_read_file(ldb_ctx, f))) {
245
 
                retval = mapistoredb_namedprops_provision_backend_set(mem_ctx, mstore_ctx, ldif, &ldif_record, 
246
 
                                                                      &ext_index, &int_index);
247
 
                if (retval) {
248
 
                        if (*ldif_buffer) {
249
 
                                talloc_free(*ldif_buffer);
250
 
                                *ldif_buffer = NULL;
251
 
                        }
252
 
                        goto exit;
253
 
                }
254
 
 
255
 
                if (!*ldif_buffer) {
256
 
                        *ldif_buffer = talloc_strdup(mem_ctx, ldif_record);
257
 
                } else {
258
 
                        *ldif_buffer = talloc_asprintf_append(*ldif_buffer, "%s", ldif_record);
259
 
                }
260
 
                talloc_free(ldif_record);
261
 
                
262
 
        }
263
 
 
264
 
 
265
 
        /* Step 4. Update mapped_index attributes for CN=External and CN=Internal records */
266
 
        *mod_ldif = talloc_asprintf(mem_ctx, MDB_NPROPS_MAPPED_INDEX_CHANGE_LDIF,
267
 
                                    "External", ext_index);
268
 
        *mod_ldif = talloc_asprintf_append(*mod_ldif, MDB_NPROPS_MAPPED_INDEX_CHANGE_LDIF,
269
 
                                           "Internal", int_index);
270
 
        
271
 
exit:
272
 
        fclose(f);
273
 
 
274
 
        return retval;
275
 
}
276
 
 
277
 
 
278
 
static enum MAPISTORE_ERROR mapistoredb_namedprops_provision_backend_ldif_buffer(TALLOC_CTX *mem_ctx,
279
 
                                                                                 struct mapistore_context *mstore_ctx,
280
 
                                                                                 char *buffer, char **ldif_buffer,
281
 
                                                                                 char **mod_ldif)
282
 
{
283
 
        enum MAPISTORE_ERROR    retval;
284
 
        struct ldb_context      *ldb_ctx;
285
 
        struct ldb_ldif         *ldif;
286
 
        char                    *ldif_record;
287
 
        uint32_t                int_index;
288
 
        uint32_t                ext_index;
289
 
 
290
 
        /* Sanity checks */
291
 
        MAPISTORE_RETVAL_IF(!mstore_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
292
 
        MAPISTORE_RETVAL_IF(!mstore_ctx->mapistore_nprops_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
293
 
        MAPISTORE_RETVAL_IF(!buffer, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
294
 
        MAPISTORE_RETVAL_IF(!ldif_buffer, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
295
 
        MAPISTORE_RETVAL_IF(!mod_ldif, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
296
 
 
297
 
        ldb_ctx = mstore_ctx->mapistore_nprops_ctx;
298
 
 
299
 
        /* Step 1. Retrieved mapped index for CN=External and CN=Internal */
300
 
        retval = mapistore_namedprops_get_default_id(mstore_ctx, MAPISTORE_NAMEDPROPS_INTERNAL, &int_index);
301
 
        MAPISTORE_RETVAL_IF(retval, retval, NULL);
302
 
 
303
 
        retval = mapistore_namedprops_get_default_id(mstore_ctx, MAPISTORE_NAMEDPROPS_EXTERNAL, &ext_index);
304
 
        MAPISTORE_RETVAL_IF(retval, retval, NULL);
305
 
 
306
 
        /* Step 2. Process the LDIF buffer */
307
 
        while ((ldif = ldb_ldif_read_string(ldb_ctx, (const char **)&buffer))) {
308
 
                retval = mapistoredb_namedprops_provision_backend_set(mem_ctx, mstore_ctx, ldif, &ldif_record, 
309
 
                                                                      &ext_index, &int_index);
310
 
                if (retval) {
311
 
                        if (*ldif_buffer) {
312
 
                                talloc_free(*ldif_buffer);
313
 
                                *ldif_buffer = NULL;
314
 
                        }
315
 
                        goto exit;
316
 
                }
317
 
                
318
 
                if (!*ldif_buffer) {
319
 
                        *ldif_buffer = talloc_strdup(mem_ctx, ldif_record);
320
 
                } else {
321
 
                        *ldif_buffer = talloc_asprintf_append(*ldif_buffer, "%s", ldif_record);
322
 
                }
323
 
                talloc_free(ldif_record);
324
 
        }
325
 
 
326
 
        retval = MAPISTORE_SUCCESS;
327
 
 
328
 
        /* Step 4. Update mapped_index attributes for CN=External and CN=Internal records */
329
 
        *mod_ldif = talloc_asprintf(mem_ctx, MDB_NPROPS_MAPPED_INDEX_CHANGE_LDIF,
330
 
                                    "External", ext_index);
331
 
        *mod_ldif = talloc_asprintf_append(*mod_ldif, MDB_NPROPS_MAPPED_INDEX_CHANGE_LDIF,
332
 
                                           "Internal", int_index);
333
 
exit:
334
 
        return retval;
335
 
}
336
 
 
337
 
 
338
 
/**
339
 
   \details Provision mapistore named properties database with a LDIF
340
 
   file from a backend. This internal function also adds a mapped_id
341
 
   to Internal/External records and finally update the mapped_index
342
 
   value upon success.
343
 
 
344
 
   \param mdb_ctx pointer to the mapistore database context
345
 
   \param ldif_data pointer to the LDIF data
346
 
   \param ntype the type of ldif_data
347
 
 
348
 
   \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
349
 
 */
350
 
static enum MAPISTORE_ERROR mapistoredb_namedprops_provision_backend(struct mapistoredb_context *mdb_ctx,
351
 
                                                                     char *ldif_data,
352
 
                                                                     enum MAPISTORE_NAMEDPROPS_PROVISION_TYPE ntype)
353
 
{
354
 
        enum MAPISTORE_ERROR            retval;
355
 
        TALLOC_CTX                      *mem_ctx;
356
 
        uint32_t                        ext_index;
357
 
        uint32_t                        int_index;
358
 
        struct ldb_context              *ldb_ctx;
359
 
        struct ldb_ldif                 *ldif;
360
 
        char                            *ldif_buffer = NULL;
361
 
        char                            *ldif_mod = NULL;
362
 
        int                             trans;
363
 
 
364
 
        /* Sanity checks */
365
 
        MAPISTORE_RETVAL_IF(!mdb_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
366
 
        MAPISTORE_RETVAL_IF(!mdb_ctx->mstore_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
367
 
        MAPISTORE_RETVAL_IF(!mdb_ctx->mstore_ctx->mapistore_nprops_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
368
 
        MAPISTORE_RETVAL_IF(!ldif_data, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
369
 
        MAPISTORE_RETVAL_IF(ntype == MAPISTORE_NAMEDPROPS_PROVISION_NONE, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
370
 
 
371
 
        ldb_ctx = mdb_ctx->mstore_ctx->mapistore_nprops_ctx;
372
 
 
373
 
        /* Step 1. Retrieve mapped index for CN=External and CN=Internal */
374
 
        retval = mapistore_namedprops_get_default_id(mdb_ctx->mstore_ctx, MAPISTORE_NAMEDPROPS_INTERNAL, &int_index);
375
 
        MAPISTORE_RETVAL_IF(retval, retval, NULL);
376
 
 
377
 
        retval = mapistore_namedprops_get_default_id(mdb_ctx->mstore_ctx, MAPISTORE_NAMEDPROPS_EXTERNAL, &ext_index);
378
 
        MAPISTORE_RETVAL_IF(retval, retval, NULL);
379
 
 
380
 
        mem_ctx = talloc_named(NULL, 0, __FUNCTION__);
381
 
        MAPISTORE_RETVAL_IF(!mem_ctx, MAPISTORE_ERR_NO_MEMORY, NULL);
382
 
 
383
 
        /* Step 2. Process and retrieved updated LDIF data */
384
 
        if (ntype == MAPISTORE_NAMEDPROPS_PROVISION_FILE) {
385
 
                retval = mapistoredb_namedprops_provision_backend_ldif_file(mem_ctx, mdb_ctx->mstore_ctx, 
386
 
                                                                            ldif_data, &ldif_buffer, &ldif_mod);
387
 
        } else if (ntype == MAPISTORE_NAMEDPROPS_PROVISION_BUFFER) {
388
 
                retval = mapistoredb_namedprops_provision_backend_ldif_buffer(mem_ctx, mdb_ctx->mstore_ctx,
389
 
                                                                              ldif_data, &ldif_buffer, &ldif_mod);
390
 
        }
391
 
        MAPISTORE_RETVAL_IF(retval, retval, mem_ctx);
392
 
 
393
 
        /* Step 3. Do the LDB transaction */
394
 
        retval = MAPISTORE_SUCCESS;
395
 
        trans = ldb_transaction_start(ldb_ctx);
396
 
        if (trans != LDB_SUCCESS) {
397
 
                retval = MAPISTORE_ERR_DATABASE_OPS;
398
 
                goto failed;
399
 
        }
400
 
 
401
 
        /* Add LDIF data from backend */
402
 
        while ((ldif = ldb_ldif_read_string(ldb_ctx, (const char **)&ldif_buffer))) {
403
 
                trans = ldb_msg_normalize(ldb_ctx, ldif, ldif->msg, &ldif->msg);
404
 
                if (trans != LDB_SUCCESS) {
405
 
                        ldb_ldif_read_free(ldb_ctx, ldif);
406
 
                        MSTORE_DEBUG_ERROR(MSTORE_LEVEL_CRITICAL, "Unable to normalize %s\n", "ldif");
407
 
                        retval = MAPISTORE_ERR_DATABASE_OPS;
408
 
                        goto failed;
409
 
                }
410
 
 
411
 
                trans = ldb_add(ldb_ctx, ldif->msg);
412
 
                if (trans != LDB_SUCCESS) {
413
 
                        ldb_ldif_read_free(ldb_ctx, ldif);
414
 
                        MSTORE_DEBUG_ERROR(MSTORE_LEVEL_CRITICAL, "Unable to add ldb msg: %s\n", ldb_errstring(ldb_ctx));
415
 
                        retval = MAPISTORE_ERR_DATABASE_OPS;
416
 
                        goto failed;
417
 
                }
418
 
        }
419
 
 
420
 
        /* Update record from mapistore named properties database */
421
 
        while ((ldif = ldb_ldif_read_string(ldb_ctx, (const char **)&ldif_mod))) {
422
 
                trans = ldb_msg_normalize(ldb_ctx, ldif, ldif->msg, &ldif->msg);
423
 
                if (trans != LDB_SUCCESS) {
424
 
                        ldb_ldif_read_free(ldb_ctx, ldif);
425
 
                        MSTORE_DEBUG_ERROR(MSTORE_LEVEL_CRITICAL, "Unable to normalize %s\n", "ldif");
426
 
                        retval = MAPISTORE_ERR_DATABASE_OPS;
427
 
                        goto failed;
428
 
                }
429
 
 
430
 
                trans = ldb_modify(ldb_ctx, ldif->msg);
431
 
                if (trans != LDB_SUCCESS) {
432
 
                        ldb_ldif_read_free(ldb_ctx, ldif);
433
 
                        MSTORE_DEBUG_ERROR(MSTORE_LEVEL_CRITICAL, "Unable to modify ldb %s\n", "msg");
434
 
                        retval = MAPISTORE_ERR_DATABASE_OPS;
435
 
                        goto failed;
436
 
                }
437
 
        }       
438
 
 
439
 
        trans = ldb_transaction_commit(ldb_ctx);
440
 
        if (trans != LDB_SUCCESS) {
441
 
                MSTORE_DEBUG_ERROR(MSTORE_LEVEL_CRITICAL, "Transaction failed: %s\n", ldb_errstring(ldb_ctx));
442
 
                retval = MAPISTORE_ERR_DATABASE_OPS;
443
 
                goto failed;
444
 
        }
445
 
 
446
 
failed:
447
 
        talloc_free(mem_ctx);
448
 
 
449
 
        return retval;
450
 
}
451
 
 
452
 
/**
453
 
   \details Let registered backends provision additional Internal or
454
 
   External properties within the named properties database
455
 
 
456
 
   \param mdb_ctx pointer to the mapistore database context
457
 
 
458
 
   \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
459
 
 */
460
 
enum MAPISTORE_ERROR mapistoredb_namedprops_provision_backends(struct mapistoredb_context *mdb_ctx)
461
 
{
462
 
        enum MAPISTORE_ERROR                            retval;
463
 
        enum MAPISTORE_ERROR                            retval2;
464
 
        char                                            *ldif;
465
 
        enum MAPISTORE_NAMEDPROPS_PROVISION_TYPE        ntype;
466
 
        uint32_t                                        bindex = 0;
467
 
        const char                                      *bname = NULL;
468
 
        const char                                      *bns = NULL;
469
 
        const char                                      *bdesc = NULL;
470
 
 
471
 
        /* Sanity checks */
472
 
        MAPISTORE_RETVAL_IF(!mdb_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
473
 
        MAPISTORE_RETVAL_IF(!mdb_ctx->mstore_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
474
 
        MAPISTORE_RETVAL_IF(!mdb_ctx->mstore_ctx->mapistore_nprops_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
475
 
 
476
 
        /* Step 1. Loop over all the different registered backends */
477
 
        do {
478
 
                retval = mapistore_get_next_backend(&bname, &bns, &bdesc, &bindex);
479
 
                if (retval == MAPISTORE_SUCCESS) {
480
 
                        MSTORE_DEBUG_INFO(MSTORE_LEVEL_DEBUG, "Looking for LDIF data for backend '%s'\n", bname);
481
 
                        /* Step 2. Try to fetch LDIF information from each backend */
482
 
                        retval2 = mapistore_get_backend_ldif(mdb_ctx->mstore_ctx, bname, &ldif, &ntype);
483
 
                        if (retval2 == MAPISTORE_SUCCESS) {
484
 
                                /* Step 3. Upon success, try to register LDIF data within the database */
485
 
                                retval2 = mapistoredb_namedprops_provision_backend(mdb_ctx, ldif, ntype);
486
 
                                if (retval2) {
487
 
                                        MSTORE_DEBUG_ERROR(MSTORE_LEVEL_CRITICAL, 
488
 
                                                           "Unable to provision LDIF data for backend '%s': %s\n",
489
 
                                                           bname, mapistore_errstr(retval2));
490
 
                                }
491
 
                                talloc_free(ldif);
492
 
                                ldif = NULL;
493
 
                        }
494
 
                } 
495
 
        } while (retval != MAPISTORE_ERR_NOT_FOUND);
496
 
        
497
 
        return MAPISTORE_SUCCESS;
498
 
}
499
 
 
500
 
/**
501
 
   \details Add an entry for the user within the named properties
502
 
   database and retrieve the default mapped index that can be used for
503
 
   custom named properties
504
 
 
505
 
   \param mdb_ctx pointer to the mapistore database context
506
 
   \param username pointer to the username entry to create
507
 
 
508
 
   \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
509
 
 */
510
 
enum MAPISTORE_ERROR mapistoredb_namedprops_provision_user(struct mapistoredb_context *mdb_ctx,
511
 
                                                           const char *username)
512
 
{
513
 
        enum MAPISTORE_ERROR    retval;
514
 
        TALLOC_CTX              *mem_ctx;
515
 
        char                    *ldif;
516
 
        uint32_t                mapped_index;
517
 
 
518
 
        /* Sanity checks */
519
 
        MAPISTORE_RETVAL_IF(!mdb_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
520
 
        MAPISTORE_RETVAL_IF(!mdb_ctx->mstore_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
521
 
        MAPISTORE_RETVAL_IF(!mdb_ctx->mstore_ctx->mapistore_nprops_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
522
 
        MAPISTORE_RETVAL_IF(!username, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
523
 
 
524
 
        /* Step 1. Check if the username already exists */
525
 
        retval = mapistore_namedprops_user_exist(mdb_ctx->mstore_ctx, username);
526
 
        MAPISTORE_RETVAL_IF(retval == MAPISTORE_ERR_EXIST, retval, NULL);
527
 
 
528
 
        /* Step 2. Retrieve the first default available id */
529
 
        retval = mapistore_namedprops_get_default_id(mdb_ctx->mstore_ctx, MAPISTORE_NAMEDPROPS_EXTERNAL, &mapped_index);
530
 
        MAPISTORE_RETVAL_IF(retval, retval, NULL);
531
 
 
532
 
        /* Step 3. Create the LDIF */
533
 
        mem_ctx = talloc_named(NULL, 0, __FUNCTION__);
534
 
        MAPISTORE_RETVAL_IF(!mem_ctx, MAPISTORE_ERR_NO_MEMORY, NULL);
535
 
 
536
 
        ldif = talloc_asprintf(mem_ctx, MDB_NPROPS_USER_LDIF, username, mapped_index, username);
537
 
        MAPISTORE_RETVAL_IF(!ldif, MAPISTORE_ERR_NO_MEMORY, mem_ctx);
538
 
 
539
 
        /* Step 4. Commit the LDIF */
540
 
        retval = mapistore_ldb_write_ldif_string_to_store(mdb_ctx->mstore_ctx->mapistore_nprops_ctx, ldif);
541
 
        talloc_free(ldif);
542
 
        MAPISTORE_RETVAL_IF(retval, retval, mem_ctx);
543
 
 
544
 
        talloc_free(mem_ctx);
545
 
 
546
 
        return MAPISTORE_SUCCESS;
547
 
}
548
 
 
549
 
enum MAPISTORE_ERROR mapistoredb_namedprops_register_application(struct mapistoredb_context *mdb_ctx,
550
 
                                                                 const char *username,
551
 
                                                                 const char *app_name,
552
 
                                                                 const char *app_GUID,
553
 
                                                                 const char *ldif)
554
 
{
555
 
        return MAPISTORE_SUCCESS;
556
 
}
557
 
 
558
 
enum MAPISTORE_ERROR mapistoredb_namedprops_unregister_application(struct mapistoredb_context *mdb_ctx,
559
 
                                                                   const char *username,
560
 
                                                                   const char *app_name,
561
 
                                                                   const char *app_GUID,
562
 
                                                                   const char *ldif)
563
 
{
564
 
        return MAPISTORE_SUCCESS;
565
 
}