102
89
const char *mapistore_get_mapping_path(void)
104
return (!mapping_path) ? MAPISTORE_MAPPING_PATH : (const char *)mapping_path;
109
\details Set the mapistore.ldb mapping path
111
\param dbname string pointer to the mapistore database path
113
\return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
115
enum MAPISTORE_ERROR mapistore_set_database_path(const char *dbname)
120
if (mapistore_dbpath) {
121
talloc_free(mapistore_dbpath);
123
mapistore_dbpath = NULL;
124
return MAPISTORE_SUCCESS;
127
if (mapistore_dbpath) {
128
talloc_free(mapistore_dbpath);
129
mapistore_dbpath = NULL;
132
mem_ctx = talloc_autofree_context();
133
mapistore_dbpath = talloc_strdup(mem_ctx, dbname);
135
return MAPISTORE_SUCCESS;
140
\details Return the current path to mapistore.ldb database
142
\return pointer to the mapistore database path
144
const char *mapistore_get_database_path(void)
146
return (!mapistore_dbpath) ? MAPISTORE_DBPATH : (const char *) mapistore_dbpath;
150
\details Return the current path to mapistore named properties LDIF
153
\return pointer to the mapistore named properties LDIF path
155
const char *mapistore_get_named_properties_ldif_path(void)
157
return MAPISTORE_LDIF;
161
\details Set the mapistore_named_properties.ldb mapping path
163
\param dbname string pointer to the mapistore named properties database path
165
\return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
167
enum MAPISTORE_ERROR mapistore_set_named_properties_database_path(const char *dbname)
172
if (mapistore_nprops_dbpath) {
173
talloc_free(mapistore_nprops_dbpath);
175
mapistore_nprops_dbpath = NULL;
176
return MAPISTORE_SUCCESS;
179
if (mapistore_nprops_dbpath) {
180
talloc_free(mapistore_nprops_dbpath);
181
mapistore_nprops_dbpath = NULL;
184
mem_ctx = talloc_autofree_context();
185
mapistore_nprops_dbpath = talloc_strdup(mem_ctx, dbname);
187
return MAPISTORE_SUCCESS;
191
\details Return the current path to mapistore_named_properties.ldb
194
\return pointer to the mapistore named properties database path on
195
success, otherwise NULL
197
const char *mapistore_get_named_properties_database_path(void)
199
return (!mapistore_nprops_dbpath) ? MAPISTORE_DB_NAMEDPROPS_PATH : mapistore_nprops_dbpath;
203
enum MAPISTORE_ERROR mapistore_set_firstorgdn(const char *firstou, const char *firstorg, const char *serverdn)
207
if (mapistore_firstorgdn) {
208
talloc_free(mapistore_firstorgdn);
211
mem_ctx = talloc_autofree_context();
212
mapistore_firstorgdn = talloc_asprintf(mem_ctx, TMPL_MDB_FIRSTORGDN, firstou, firstorg, serverdn);
213
if (!mapistore_firstorgdn) {
214
MSTORE_DEBUG_ERROR(MSTORE_LEVEL_CRITICAL, "Unable to allocate memory to set %s\n", "firstorgdn");
215
return MAPISTORE_ERR_NO_MEMORY;
218
return MAPISTORE_SUCCESS;
221
const char *mapistore_get_firstorgdn(void)
223
return mapistore_firstorgdn;
91
return (const char *)mapping_path;
249
114
MAPISTORE_RETVAL_IF(!pctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
250
115
MAPISTORE_RETVAL_IF(pctx->mapping_ctx, MAPISTORE_ERR_ALREADY_INITIALIZED, NULL);
252
117
pctx->mapping_ctx = talloc_zero(pctx, struct id_mapping_context);
253
118
MAPISTORE_RETVAL_IF(!pctx->mapping_ctx, MAPISTORE_ERR_NO_MEMORY, NULL);
255
mem_ctx = talloc_named(NULL, 0, __FUNCTION__);
257
/* Step 1. Retrieve the mapistore database path */
258
db_path = mapistore_get_database_path();
260
MSTORE_DEBUG_ERROR(MSTORE_LEVEL_CRITICAL, "Unable to retrieve the mapistore database %s\n", "path");
261
talloc_free(mem_ctx);
262
talloc_free(pctx->mapping_ctx);
263
return MAPISTORE_ERR_DATABASE_INIT;
266
/* Step 2. Initialize tevent structure */
267
pctx->mapping_ctx->ev = tevent_context_init(pctx);
269
/* Step 3. Open a wrapped connection to mapistore.ldb */
270
pctx->mapping_ctx->ldb_ctx = mapistore_ldb_wrap_connect(pctx, pctx->mapping_ctx->ev, db_path, 0);
271
if (!pctx->mapping_ctx->ldb_ctx) {
272
MSTORE_DEBUG_ERROR(MSTORE_LEVEL_CRITICAL, "Failed to open wrapped connection over %s\n", "mapistore.ldb");
273
talloc_free(pctx->mapping_ctx);
274
return MAPISTORE_ERR_DATABASE_INIT;
120
mem_ctx = talloc_named(NULL, 0, "mapistore_init_mapping_context");
277
122
/* Open/Create the used ID database */
278
123
if (!pctx->mapping_ctx->used_ctx) {
279
124
dbpath = talloc_asprintf(mem_ctx, "%s/%s", mapistore_get_mapping_path(), MAPISTORE_DB_NAME_USED_ID);
280
pctx->mapping_ctx->used_ctx = tdb_wrap_open(pctx, dbpath, 0, 0, O_RDWR|O_CREAT, 0600);
125
pctx->mapping_ctx->used_ctx = mapistore_tdb_wrap_open(pctx, dbpath, 0, 0, O_RDWR|O_CREAT, 0600);
281
126
talloc_free(dbpath);
282
127
if (!pctx->mapping_ctx->used_ctx) {
283
MSTORE_DEBUG_ERROR(MSTORE_LEVEL_CRITICAL, "Unable to create/open used ID database: %s\n", strerror(errno));
128
DEBUG(3, ("[%s:%d]: %s\n", __FUNCTION__, __LINE__, strerror(errno)));
284
129
talloc_free(mem_ctx);
285
130
talloc_free(pctx->mapping_ctx);
286
131
return MAPISTORE_ERR_DATABASE_INIT;
324
169
return MAPISTORE_SUCCESS;
327
enum MAPISTORE_ERROR mapistore_ldb_write_ldif_string_to_store(struct ldb_context *ldb_ctx, const char *ldif_string)
330
struct ldb_ldif *ldif;
333
MAPISTORE_RETVAL_IF(!ldb_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
334
MAPISTORE_RETVAL_IF(!ldif_string, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
336
while ((ldif = ldb_ldif_read_string(ldb_ctx, (const char **)&ldif_string))) {
337
ret = ldb_msg_normalize(ldb_ctx, ldif, ldif->msg, &ldif->msg);
338
if (ret != LDB_SUCCESS) {
339
ldb_ldif_read_free(ldb_ctx, ldif);
340
MSTORE_DEBUG_ERROR(MSTORE_LEVEL_INFO, "Unable to normalize %s\n", "ldif");
341
return MAPISTORE_ERROR;
343
ret = ldb_add(ldb_ctx, ldif->msg);
344
if (ret != LDB_SUCCESS) {
345
ldb_ldif_read_free(ldb_ctx, ldif);
346
MSTORE_DEBUG_ERROR(MSTORE_LEVEL_INFO, "Unable to add ldb %s\n", "msg");
347
return MAPISTORE_ERROR;
349
ldb_ldif_read_free(ldb_ctx, ldif);
352
return MAPISTORE_SUCCESS;
356
enum MAPISTORE_ERROR mapistore_write_ldif_string_to_store(struct processing_context *pctx, const char *ldif_string)
358
struct ldb_context *ldb_ctx;
361
MAPISTORE_RETVAL_IF(!pctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
362
MAPISTORE_RETVAL_IF(!pctx->mapping_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
363
MAPISTORE_RETVAL_IF(!pctx->mapping_ctx->ldb_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
364
MAPISTORE_RETVAL_IF(!ldif_string, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
366
ldb_ctx = pctx->mapping_ctx->ldb_ctx;
368
return mapistore_ldb_write_ldif_string_to_store(ldb_ctx, ldif_string);
372
enum MAPISTORE_ERROR mapistore_ldb_write_ldif_file_to_store(struct ldb_context *ldb_ctx, const char *ldif_path)
376
struct ldb_ldif *ldif;
380
MAPISTORE_RETVAL_IF(!ldb_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
381
MAPISTORE_RETVAL_IF(!ldif_path, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
383
f = fopen(ldif_path, "r");
384
MAPISTORE_RETVAL_IF(!f, MAPISTORE_ERR_DATABASE_INIT, NULL);
386
mem_ctx = talloc_named(NULL, 0, __FUNCTION__);
388
while ((ldif = ldb_ldif_read_file(ldb_ctx, f))) {
389
struct ldb_message *normalized_msg;
391
ret = ldb_msg_normalize(ldb_ctx, mem_ctx, ldif->msg, &normalized_msg);
392
MAPISTORE_RETVAL_IF(ret != LDB_SUCCESS, MAPISTORE_ERR_DATABASE_OPS, mem_ctx);
393
ret = ldb_add(ldb_ctx, normalized_msg);
394
if (ret != LDB_SUCCESS) {
396
MAPISTORE_RETVAL_IF(ret != LDB_SUCCESS, MAPISTORE_ERR_DATABASE_OPS, mem_ctx);
398
ldb_ldif_read_free(ldb_ctx, ldif);
399
talloc_free(normalized_msg);
403
talloc_free(mem_ctx);
405
return MAPISTORE_SUCCESS;
410
\details Retrieve the next available folder or message identifier
412
\param pctx pointer to the mapistore processing context
413
\param username the username's mailbox to retrieve GlobalCount from
414
\param fmid pointer to the first available fmid within the range
416
\return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
418
enum MAPISTORE_ERROR mapistore_get_new_fmid(struct processing_context *pctx,
419
const char *username,
424
struct ldb_context *ldb_ctx;
425
struct ldb_result *res = NULL;
426
struct ldb_message *msg;
427
const char * const attrs[] = { "*", NULL };
429
uint64_t GlobalCount;
430
uint64_t new_GlobalCount;
433
MAPISTORE_RETVAL_IF(!pctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
434
MAPISTORE_RETVAL_IF(!pctx->mapping_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
435
MAPISTORE_RETVAL_IF(!pctx->mapping_ctx->ldb_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
436
MAPISTORE_RETVAL_IF(!username, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
437
MAPISTORE_RETVAL_IF(!fmid, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
439
mem_ctx = talloc_named(NULL, 0, __FUNCTION__);
441
/* Step 1. Retrieve the server object */
442
ldb_ctx = pctx->mapping_ctx->ldb_ctx;
444
/* TODO: In the future, we may want to deal with different servers */
445
/* TODO: Use ldb_transaction to lock between get/set operations */
446
ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_root_basedn(ldb_ctx),
447
LDB_SCOPE_SUBTREE, attrs, "(&(cn=%s)(objectClass=store))", username);
448
if (ret != LDB_SUCCESS || res->count != 1) {
449
talloc_free(mem_ctx);
450
MSTORE_DEBUG_ERROR(MSTORE_LEVEL_INFO, "Unable to find the user store %s\n", "object");
451
return MAPISTORE_ERR_NOT_FOUND;
454
/* Step 2. Get the [48 GlobalCount][16 ReplicaID] */
455
GlobalCount = ldb_msg_find_attr_as_uint64(res->msgs[0], "GlobalCount", 0);
456
new_GlobalCount = GlobalCount + 1;
458
ReplicaID = ldb_msg_find_attr_as_uint64(res->msgs[0], "ReplicaID", 0);
460
/* Step 3. Update the GlobalCount */
461
msg = ldb_msg_new(mem_ctx);
462
msg->dn = ldb_dn_copy(msg, ldb_msg_find_attr_as_dn(ldb_ctx, mem_ctx, res->msgs[0], "distinguishedName"));
463
ldb_msg_add_fmt(msg, "GlobalCount", "0x%"PRIx64, new_GlobalCount);
464
msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
465
ret = ldb_modify(ldb_ctx, msg);
466
if (ret != LDB_SUCCESS) {
467
talloc_free(mem_ctx);
468
MSTORE_DEBUG_ERROR(MSTORE_LEVEL_INFO, "Unable to update GlobalCount for server %s\n", "object");
469
return MAPISTORE_ERROR;
472
/* Step 4. Set the fmid value */
474
talloc_free(mem_ctx);
475
*fmid = (GlobalCount << 16) + ReplicaID;
477
return MAPISTORE_SUCCESS;
482
\details Retrieve an allocation range
484
\param pctx pointer to the mapistore processing context
485
\param username the user store from which to retrieve the new allocation range
486
\param range the range to allocate
487
\param range_start pointer to the first allocation range fmid to return
488
\param range_end pointer to the last allocation range fmid to return
490
\return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
492
enum MAPISTORE_ERROR mapistore_get_new_allocation_range(struct processing_context *pctx,
493
const char *username,
495
uint64_t *range_start,
500
struct ldb_context *ldb_ctx;
501
struct ldb_result *res = NULL;
502
struct ldb_message *msg;
503
const char * const attrs[] = { "*", NULL };
505
uint64_t GlobalCount;
506
uint64_t new_GlobalCount;
509
MAPISTORE_RETVAL_IF(!pctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
510
MAPISTORE_RETVAL_IF(!pctx->mapping_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
511
MAPISTORE_RETVAL_IF(!pctx->mapping_ctx->ldb_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
512
MAPISTORE_RETVAL_IF(!range_start || !range_end, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
514
mem_ctx = talloc_named(NULL, 0, __FUNCTION__);
516
/* Step 1. Retrieve the user store object */
517
ldb_ctx = pctx->mapping_ctx->ldb_ctx;
518
ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_root_basedn(ldb_ctx),
519
LDB_SCOPE_SUBTREE, attrs, "(&(objectClass=store)(cn=%s))", username);
520
if (ret != LDB_SUCCESS || res->count != 1) {
521
talloc_free(mem_ctx);
522
MSTORE_DEBUG_ERROR(MSTORE_LEVEL_INFO, "Unable to find the user store %s\n", "object");
523
return MAPISTORE_ERR_NOT_FOUND;
526
/* Step 2. Get the current GlobalCount and set the new one */
527
GlobalCount = ldb_msg_find_attr_as_uint64(res->msgs[0], "GlobalCount", 0);
528
ReplicaID = ldb_msg_find_attr_as_uint64(res->msgs[0], "ReplicaID", 0);
530
*range_start = GlobalCount;
532
new_GlobalCount = GlobalCount + range -1;
533
*range_end = new_GlobalCount;
535
new_GlobalCount += 1;
537
/* Step 3. Update the GlobalCount */
538
msg = ldb_msg_new(mem_ctx);
539
msg->dn = ldb_dn_copy(msg, ldb_msg_find_attr_as_dn(ldb_ctx, mem_ctx, res->msgs[0], "distinguishedName"));
540
ldb_msg_add_fmt(msg, "GlobalCount", "0x%"PRIx64, new_GlobalCount);
541
msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
542
ret = ldb_modify(ldb_ctx, msg);
543
if (ret != LDB_SUCCESS) {
544
talloc_free(mem_ctx);
545
MSTORE_DEBUG_ERROR(MSTORE_LEVEL_INFO, "Unable to update GlobalCount for server %s\n", "object");
546
return MAPISTORE_ERROR;
549
/* Step 4. Set the fmid value ranges */
550
talloc_free(mem_ctx);
551
*range_start = (*range_start << 16) + ReplicaID;
552
*range_end = (*range_end << 16) + ReplicaID;
554
return MAPISTORE_SUCCESS;
559
\details Retrieve the mapistore URI for a given user mailbox
561
\param pctx pointer to the processing context
562
\param username pointer to the username to lookup
563
\param mapistore_uri pointer on pointer to the mapistore URI
565
\return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
567
enum MAPISTORE_ERROR mapistore_get_mailbox_uri(struct processing_context *pctx,
568
const char *username,
569
char **mapistore_uri)
574
const char * const attrs[] = { "*", NULL };
575
struct ldb_context *ldb_ctx;
576
struct ldb_result *res;
580
MAPISTORE_RETVAL_IF(!pctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
581
MAPISTORE_RETVAL_IF(!username, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
582
MAPISTORE_RETVAL_IF(!mapistore_uri, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
584
mem_ctx = talloc_new(pctx);
585
ldb_ctx = pctx->mapping_ctx->ldb_ctx;
587
dn = ldb_dn_new_fmt(mem_ctx, ldb_ctx, TMPL_MDB_USERSTORE, username, mapistore_get_firstorgdn());
588
ret = ldb_search(ldb_ctx, mem_ctx, &res, dn, LDB_SCOPE_SUBTREE, attrs, "(&(objectClass=mailbox)(objectClass=container))");
589
if (ret != LDB_SUCCESS || res->count != 1) {
590
talloc_free(mem_ctx);
591
MSTORE_DEBUG_ERROR(MSTORE_LEVEL_INFO, "Unable to find the user mailbox root %s\n", "container");
592
return MAPISTORE_ERR_NOT_FOUND;
595
uri = ldb_msg_find_attr_as_string(res->msgs[0], "mapistore_uri", NULL);
596
MAPISTORE_RETVAL_IF(!uri, MAPISTORE_ERR_NOT_FOUND, mem_ctx);
598
*mapistore_uri = talloc_strdup(pctx, (char *)uri);
600
talloc_free(mem_ctx);
601
return MAPISTORE_SUCCESS;
606
174
\details Return an unused or new context identifier