125
71
OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
126
72
OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
128
mapi_repl->u.mapi_OpenFolder.HasRules = 0;
129
mapi_repl->u.mapi_OpenFolder.IsGhosted = 0;
74
request = &mapi_req->u.mapi_OpenFolder;
75
response = &mapi_repl->u.mapi_OpenFolder;
77
mapi_repl->opnum = mapi_req->opnum;
78
mapi_repl->error_code = MAPI_E_SUCCESS;
79
mapi_repl->handle_idx = request->handle_idx;
131
81
/* Step 1. Retrieve parent handle in the hierarchy */
132
82
handle = handles[mapi_req->handle_idx];
133
83
retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
134
OPENCHANGE_RETVAL_IF(retval, retval, NULL);
136
mapistore = emsmdbp_is_mapistore(parent);
139
/* system/special folder */
140
DEBUG(0, ("Opening system/special folder\n"));
141
retval = RopOpenFolder_SystemSpecialFolder(mem_ctx, emsmdbp_ctx,
142
mapi_req->u.mapi_OpenFolder,
143
&mapi_repl->u.mapi_OpenFolder);
144
mapi_repl->error_code = retval;
147
/* handled by mapistore */
148
DEBUG(0, ("Opening Generic folder\n"));
149
retval = RopOpenFolder_GenericFolder(mem_ctx, emsmdbp_ctx,
150
mapi_req->u.mapi_OpenFolder,
151
&mapi_repl->u.mapi_OpenFolder, parent);
152
mapi_repl->error_code = retval;
85
DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
86
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
90
/* With OpenFolder, the parent object may NOT BE the direct parent folder of the folder */
91
mapi_handles_get_private_data(parent, &private_data);
92
parent_object = private_data;
93
if (!parent_object || (parent_object->type != EMSMDBP_OBJECT_FOLDER && parent_object->type != EMSMDBP_OBJECT_MAILBOX)) {
94
DEBUG(5, (" invalid handle (%x): %x\n", handle, mapi_req->handle_idx));
95
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
99
/* Fill EcDoRpc_MAPI_REPL reply */
100
response->HasRules = 0;
101
response->IsGhosted = 0;
103
mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
104
ret = emsmdbp_object_open_folder_by_fid(rec, emsmdbp_ctx, parent_object, request->folder_id, &object);
105
if (ret != MAPISTORE_SUCCESS) {
106
if (ret == MAPISTORE_ERR_DENIED) {
107
mapi_repl->error_code = MAPI_E_NO_ACCESS;
110
mapi_repl->error_code = MAPI_E_NOT_FOUND;
114
retval = mapi_handles_set_private_data(rec, object);
115
handles[mapi_repl->handle_idx] = rec->handle;
156
118
*size += libmapiserver_RopOpenFolder_size(mapi_repl);
158
/* Fill EcDoRpc_MAPI_REPL reply */
159
if (!mapi_repl->error_code) {
160
retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
162
object = emsmdbp_object_folder_init((TALLOC_CTX *)emsmdbp_ctx, emsmdbp_ctx,
163
mapi_req->u.mapi_OpenFolder.folder_id, parent);
165
retval = mapi_handles_set_private_data(rec, object);
167
mapi_repl->opnum = mapi_req->opnum;
168
mapi_repl->handle_idx = mapi_req->u.mapi_OpenFolder.handle_idx;
170
handles[mapi_repl->handle_idx] = rec->handle;
173
120
return MAPI_E_SUCCESS;
215
162
OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
216
163
OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
218
handle = handles[mapi_req->handle_idx];
219
ret = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
220
OPENCHANGE_RETVAL_IF(ret, ret, NULL);
222
165
/* Initialize default empty GetHierarchyTable reply */
223
166
mapi_repl->opnum = mapi_req->opnum;
167
mapi_repl->error_code = MAPI_E_SUCCESS;
224
168
mapi_repl->handle_idx = mapi_req->u.mapi_GetHierarchyTable.handle_idx;
225
mapi_repl->error_code = MAPI_E_SUCCESS;
227
170
/* GetHierarchyTable can only be called for mailbox/folder objects */
171
handle = handles[mapi_req->handle_idx];
172
retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
174
DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
175
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
228
179
mapi_handles_get_private_data(parent, &data);
229
object = (struct emsmdbp_object *)data;
180
parent_object = (struct emsmdbp_object *)data;
181
if (!parent_object) {
182
DEBUG(5, (" no object found\n"));
231
183
mapi_repl->error_code = MAPI_E_NO_SUPPORT;
232
*size += libmapiserver_RopGetHierarchyTable_size(NULL);
233
return MAPI_E_SUCCESS;
236
switch (object->type) {
187
switch (parent_object->type) {
237
188
case EMSMDBP_OBJECT_MAILBOX:
238
folderID = object->object.mailbox->folderID;
239
contextID = object->object.folder->contextID;
189
folderID = parent_object->object.mailbox->folderID;
241
191
case EMSMDBP_OBJECT_FOLDER:
242
folderID = object->object.folder->folderID;
243
contextID = object->object.folder->contextID;
192
folderID = parent_object->object.folder->folderID;
195
DEBUG(5, (" unsupported object type\n"));
246
196
mapi_repl->error_code = MAPI_E_NO_SUPPORT;
247
*size += libmapiserver_RopGetHierarchyTable_size(NULL);
248
return MAPI_E_SUCCESS;
251
mapistore = emsmdbp_is_mapistore(parent);
254
/* system/special folder */
255
ret = openchangedb_get_folder_count(emsmdbp_ctx->oc_ctx, folderID,
256
&mapi_repl->u.mapi_GetHierarchyTable.RowCount);
259
/* handled by mapistore */
260
retval = mapistore_get_folder_count(emsmdbp_ctx->mstore_ctx, contextID, folderID,
261
&mapi_repl->u.mapi_GetHierarchyTable.RowCount);
265
200
/* Initialize Table object */
266
handle = handles[mapi_req->handle_idx];
267
ret = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
201
retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
268
202
handles[mapi_repl->handle_idx] = rec->handle;
270
object = emsmdbp_object_table_init((TALLOC_CTX *)rec, emsmdbp_ctx, parent);
272
ret = mapi_handles_set_private_data(rec, object);
273
object->object.table->denominator = mapi_repl->u.mapi_GetHierarchyTable.RowCount;
274
object->object.table->ulType = EMSMDBP_TABLE_FOLDER_TYPE;
204
object = emsmdbp_folder_open_table(rec, parent_object, MAPISTORE_FOLDER_TABLE, rec->handle);
206
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
209
mapi_handles_set_private_data(rec, object);
210
mapi_repl->u.mapi_GetHierarchyTable.RowCount = object->object.table->denominator;
213
if ((mapi_req->u.mapi_GetHierarchyTable.TableFlags & TableFlags_NoNotifications)) {
214
DEBUG(5, (" notifications skipped\n"));
217
/* we attach the subscription to the session object */
218
subscription_list = talloc_zero(emsmdbp_ctx->mstore_ctx, struct mapistore_subscription_list);
219
DLIST_ADD(emsmdbp_ctx->mstore_ctx->subscriptions, subscription_list);
221
subscription_parameters.table_type = MAPISTORE_FOLDER_TABLE;
222
subscription_parameters.folder_id = folderID;
224
/* note that a mapistore_subscription can exist without a corresponding emsmdbp_object (tables) */
225
subscription = mapistore_new_subscription(subscription_list, emsmdbp_ctx->mstore_ctx,
226
emsmdbp_ctx->username,
227
rec->handle, fnevTableModified, &subscription_parameters);
228
subscription_list->subscription = subscription;
229
object->object.table->subscription_list = subscription_list;
277
233
*size += libmapiserver_RopGetHierarchyTable_size(mapi_repl);
279
235
return MAPI_E_SUCCESS;
328
285
mapi_repl->u.mapi_GetContentsTable.RowCount = 0;
330
287
handle = handles[mapi_req->handle_idx];
331
ret = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
288
retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
290
DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
333
291
mapi_repl->error_code = MAPI_E_NO_SUPPORT;
334
*size += libmapiserver_RopGetContentsTable_size(NULL);
335
return MAPI_E_SUCCESS;
338
295
/* GetContentsTable can only be called for folder objects */
339
mapi_handles_get_private_data(parent, &data);
340
object = (struct emsmdbp_object *)data;
296
retval = mapi_handles_get_private_data(parent, &data);
298
mapi_repl->error_code = retval;
299
DEBUG(5, (" handle data not found, idx = %x\n", mapi_req->handle_idx));
303
parent_object = (struct emsmdbp_object *)data;
304
if (!parent_object) {
342
305
mapi_repl->error_code = MAPI_E_NO_SUPPORT;
343
*size += libmapiserver_RopGetContentsTable_size(NULL);
344
return MAPI_E_SUCCESS;
347
switch (object->type) {
348
case EMSMDBP_OBJECT_FOLDER:
349
folderID = object->object.folder->folderID;
350
contextID = object->object.folder->contextID;
353
mapi_repl->u.mapi_GetContentsTable.RowCount = 0;
354
*size += libmapiserver_RopGetContentsTable_size(NULL);
355
return MAPI_E_SUCCESS;
358
mapistore = emsmdbp_is_mapistore(parent);
361
/* system/special folder */
362
mapi_repl->u.mapi_GetContentsTable.RowCount = 0;
365
/* handled by mapistore */
366
retval = mapistore_get_message_count(emsmdbp_ctx->mstore_ctx, contextID, folderID,
367
&mapi_repl->u.mapi_GetContentsTable.RowCount);
306
DEBUG(5, (" handle data not found, idx = %x\n", mapi_req->handle_idx));
310
if (parent_object->type != EMSMDBP_OBJECT_FOLDER) {
311
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
315
folderID = parent_object->object.folder->folderID;
316
if ((mapi_req->u.mapi_GetContentsTable.TableFlags & TableFlags_Associated)) {
317
DEBUG(5, (" table is FAI table\n"));
318
table_type = MAPISTORE_FAI_TABLE;
321
DEBUG(5, (" table is contents table\n"));
322
table_type = MAPISTORE_MESSAGE_TABLE;
371
325
/* Initialize Table object */
372
handle = handles[mapi_req->handle_idx];
373
ret = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
326
retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
374
327
handles[mapi_repl->handle_idx] = rec->handle;
376
object = emsmdbp_object_table_init((TALLOC_CTX *)rec, emsmdbp_ctx, parent);
378
ret = mapi_handles_set_private_data(rec, object);
379
object->object.table->denominator = mapi_repl->u.mapi_GetHierarchyTable.RowCount;
380
object->object.table->ulType = EMSMDBP_TABLE_MESSAGE_TYPE;
329
object = emsmdbp_folder_open_table(rec, parent_object, table_type, rec->handle);
331
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
334
mapi_handles_set_private_data(rec, object);
335
mapi_repl->u.mapi_GetContentsTable.RowCount = object->object.table->denominator;
338
if ((mapi_req->u.mapi_GetContentsTable.TableFlags & TableFlags_NoNotifications)) {
339
DEBUG(5, (" notifications skipped\n"));
342
/* we attach the subscription to the session object */
343
subscription_list = talloc_zero(emsmdbp_ctx->mstore_ctx, struct mapistore_subscription_list);
344
DLIST_ADD(emsmdbp_ctx->mstore_ctx->subscriptions, subscription_list);
346
if ((mapi_req->u.mapi_GetContentsTable.TableFlags & TableFlags_Associated)) {
347
subscription_parameters.table_type = MAPISTORE_FAI_TABLE;
350
subscription_parameters.table_type = MAPISTORE_MESSAGE_TABLE;
352
subscription_parameters.folder_id = folderID;
354
/* note that a mapistore_subscription can exist without a corresponding emsmdbp_object (tables) */
355
subscription = mapistore_new_subscription(subscription_list, emsmdbp_ctx->mstore_ctx,
356
emsmdbp_ctx->username,
357
rec->handle, fnevTableModified, &subscription_parameters);
358
subscription_list->subscription = subscription;
359
object->object.table->subscription_list = subscription_list;
383
364
*size += libmapiserver_RopGetContentsTable_size(mapi_repl);
385
366
return MAPI_E_SUCCESS;
389
static enum MAPISTATUS EcDoRpc_RopCreateSystemSpecialFolder(struct emsmdbp_context *emsmdbp_ctx,
391
enum FOLDER_FLAGS folderFlags,
392
uint64_t parentFolder,
393
struct CreateFolder_repl *response)
396
enum MAPISTATUS retval;
397
struct ldb_message *msg;
398
struct ldb_dn *basedn;
404
uint32_t *folderType;
406
DEBUG(4, ("exchange_emsmdb: [OXCFOLD] CreateSystemSpecialFolder\n"));
408
displayName = (char *) find_SPropValue_data(aRow, PR_DISPLAY_NAME);
410
displayName = (char *) find_SPropValue_data(aRow, PR_DISPLAY_NAME_UNICODE);
413
/* Step 0. Determine if the folder already exists */
414
if (openchangedb_get_fid_by_name(emsmdbp_ctx->oc_ctx, parentFolder,
415
displayName, &response->folder_id) == MAPI_E_SUCCESS) {
416
/* this folder already exists */
417
if ( folderFlags & OPEN_IF_EXISTS ) {
418
DEBUG(4, ("exchange_emsmdb: [OXCFOLD] CreateFolder Duplicate Folder\n"));
419
response->IsExistingFolder = true;
420
return MAPI_E_SUCCESS;
422
DEBUG(4, ("exchange_emsmdb: [OXCFOLD] CreateFolder Duplicate Folder error\n"));
423
return MAPI_E_COLLISION;
427
mem_ctx = talloc_named(NULL, 0, "RopCreateSystemSpecialFolder");
429
/* Step 1. Retrieve the next available folderID */
430
retval = openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, &response->folder_id);
431
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
433
/* Retrieve dn of parentfolder */
434
retval = openchangedb_get_distinguishedName(mem_ctx, emsmdbp_ctx->oc_ctx, parentFolder, &parentfid);
435
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
437
/* Step 2. Create the folder LDB record for openchange.ldb */
438
dn = talloc_asprintf(mem_ctx, "CN=0x%016"PRIx64",%s", response->folder_id, parentfid);
440
/* Ensure dn is within user mailbox / prevent from creating
441
* folders in other mailboxes: check dn vs emsmdbp_ctx->username */
443
basedn = ldb_dn_new(mem_ctx, (struct ldb_context *)emsmdbp_ctx->oc_ctx, dn);
445
OPENCHANGE_RETVAL_IF(!ldb_dn_validate(basedn), MAPI_E_BAD_VALUE, mem_ctx);
447
msg = ldb_msg_new(mem_ctx);
448
msg->dn = ldb_dn_copy(mem_ctx, basedn);
449
ldb_msg_add_string(msg, "objectClass", "systemfolder");
450
ldb_msg_add_fmt(msg, "cn", "0x%.16"PRIx64, response->folder_id);
451
ldb_msg_add_string(msg, "PidTagContentUnreadCount", "0");
452
ldb_msg_add_string(msg, "PidTagContentCount", "0");
453
ldb_msg_add_string(msg, "PidTagContainerClass", "IPF.Note");
454
ldb_msg_add_string(msg, "PidTagAttrHidden", "0");
455
ldb_msg_add_string(msg, "PidTagAccess", "63");
456
ldb_msg_add_string(msg, "PidTagRights", "2043");
457
ldb_msg_add_string(msg, "PidTagDisplayName", displayName);
459
folderType = (uint32_t *) find_SPropValue_data(aRow, PR_FOLDER_TYPE);
460
ldb_msg_add_fmt(msg, "PidTagFolderType", "%d", *folderType);
462
comment = (char *) find_SPropValue_data(aRow, PR_COMMENT);
464
comment = (char *) find_SPropValue_data(aRow, PR_COMMENT_UNICODE);
466
ldb_msg_add_string(msg, "PidTagComment", comment);
468
ldb_msg_add_fmt(msg, "PidTagParentFolderId", "0x%.16"PRIx64, parentFolder);
469
ldb_msg_add_fmt(msg, "PidTagFolderId", "0x%.16"PRIx64, response->folder_id);
470
ldb_msg_add_fmt(msg, "mapistore_uri", "fsocpf:///usr/local/samba/private/mapistore/%s/0x%.16"PRIx64,
471
emsmdbp_ctx->username, response->folder_id);
472
ldb_msg_add_string(msg, "PidTagSubFolders", "0");
473
ldb_msg_add_string(msg, "FolderType", "1");
474
ldb_msg_add_fmt(msg, "distinguishedName", "%s", ldb_dn_get_linearized(msg->dn));
476
msg->elements[0].flags = LDB_FLAG_MOD_ADD;
478
ret = ldb_add((struct ldb_context *)emsmdbp_ctx->oc_ctx, msg);
479
OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NO_SUPPORT, mem_ctx);
481
talloc_free(parentfid);
482
talloc_free(mem_ctx);
484
return MAPI_E_SUCCESS;
488
static enum MAPISTATUS EcDoRpc_RopCreateGenericFolder(struct emsmdbp_context *emsmdbp_ctx,
489
struct mapi_handles *parent,
491
enum FOLDER_FLAGS folderFlags,
492
struct CreateFolder_repl *response)
495
enum MAPISTORE_ERROR retval;
496
enum MAPISTATUS retmapi;
498
struct ldb_result *res = NULL;
499
struct ldb_message *msg;
500
const char *new_folder_name = NULL;
501
struct ldb_dn *ldb_dn;
502
struct emsmdbp_object *parent_object = NULL;
503
const char * const attrs[] = { "*", NULL };
512
DEBUG(4, ("exchange_emsmdb: [OXCFOLD] CreateGenericFolder\n"));
514
/* Step 1. Retrieve the parent fid given the handle */
515
mapi_handles_get_private_data(parent, &data);
516
parent_object = (struct emsmdbp_object *) data;
517
/* checks are already done in upper function / code factorization required */
519
parent_fid = parent_object->object.folder->folderID;
520
context_id = parent_object->object.folder->contextID;
522
/* Step 2. Get the name of the folder we have to create */
523
for (i = 0; i < aRow->cValues; ++i) {
524
if (aRow->lpProps[i].ulPropTag == PR_DISPLAY_NAME) {
525
new_folder_name = aRow->lpProps[i].value.lpszA;
528
DEBUG(4, ("target folder name: %s\n", new_folder_name));
529
if (folderFlags & OPEN_IF_EXISTS) {
530
/* Determine if the folder already exists */
531
retval = mapistore_get_fid_by_name(emsmdbp_ctx->mstore_ctx, context_id, parent_fid,
532
new_folder_name, &folder_fid);
533
if (retval == MAPISTORE_SUCCESS) {
534
DEBUG(4, ("exchange_emsmdb: [OXCFOLD] CreateFolder Duplicate Folder at 0x%.16"PRIx64"\n", folder_fid));
535
/* Open the folder using folder_fid */
536
retval = mapistore_opendir(emsmdbp_ctx->mstore_ctx, context_id, parent_fid, folder_fid);
537
if (retval != MAPISTORE_SUCCESS) {
538
return MAPI_E_NOT_FOUND; /* shouldn't happen */
540
response->IsExistingFolder = true;
541
return MAPI_E_SUCCESS;
544
/* Step 3. Retrieve the next available folderID */
545
retmapi = openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, &response->folder_id);
546
OPENCHANGE_RETVAL_IF(retmapi, retmapi, NULL);
548
/* Step 4. Create folder in mapistore */
549
/* FIXME: THIS IS MAPISTORE V1 CODE TO BE CHANGED */
550
/* retval = mapistore_mkdir(emsmdbp_ctx->mstore_ctx, context_id, parent_fid, response->folder_id, */
552
if (retval == MAPISTORE_ERR_EXIST) {
553
/* folder with this name already exists */
554
DEBUG(4, ("exchange_emsmdb: [OXCFOLD] CreateFolder Duplicate Folder error\n"));
555
return MAPI_E_COLLISION;
557
OPENCHANGE_RETVAL_IF(retval, MAPI_E_CALL_FAILED, NULL);
559
/* Step 5. Update openchangedb record if needed */
560
if (parent_object->type == EMSMDBP_OBJECT_FOLDER && parent_object->object.folder->mapistore_root == true) {
561
mem_ctx = talloc_named(NULL, 0, "RopCreateGenericFolder");
563
/* Retrieve previous value */
564
ret = ldb_search((struct ldb_context *)emsmdbp_ctx->oc_ctx, mem_ctx, &res,
565
ldb_get_default_basedn((struct ldb_context *)emsmdbp_ctx->oc_ctx),
566
LDB_SCOPE_SUBTREE, attrs, "PidTagFolderId=0x%.16"PRIx64, parent_fid);
567
OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx);
569
count = ldb_msg_find_attr_as_int(res->msgs[0], "PidTagFolderChildCount", 0);
572
retmapi = openchangedb_get_distinguishedName(mem_ctx, emsmdbp_ctx->oc_ctx, parent_fid, &parentfid);
573
OPENCHANGE_RETVAL_IF(retmapi, retmapi, mem_ctx);
575
ldb_dn = ldb_dn_new(mem_ctx, (struct ldb_context *)emsmdbp_ctx->oc_ctx, parentfid);
576
OPENCHANGE_RETVAL_IF(!ldb_dn_validate(ldb_dn), MAPI_E_BAD_VALUE, mem_ctx);
578
msg = ldb_msg_new(mem_ctx);
579
msg->dn = ldb_dn_copy(mem_ctx, ldb_dn);
580
ldb_msg_add_fmt(msg, "PidTagFolderChildCount", "%d", count + 1);
581
ldb_msg_add_fmt(msg, "PidTagSubFolders", "TRUE");
582
msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
583
msg->elements[1].flags = LDB_FLAG_MOD_REPLACE;
585
ret = ldb_modify((struct ldb_context *)emsmdbp_ctx->oc_ctx, msg);
586
OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NO_SUPPORT, mem_ctx);
588
talloc_free(mem_ctx);
591
return MAPI_E_SUCCESS;
596
370
\details EcDoRpc CreateFolder (0x1c) Rop. This operation creates a
597
371
folder on the remote server.
638
415
/* Set up sensible values for the reply */
639
416
mapi_repl->opnum = mapi_req->opnum;
417
mapi_repl->error_code = MAPI_E_SUCCESS;
640
418
mapi_repl->handle_idx = mapi_req->u.mapi_CreateFolder.handle_idx;
641
mapi_repl->u.mapi_CreateFolder.IsExistingFolder = false;
643
420
/* Step 1. Retrieve parent handle in the hierarchy */
644
421
handle = handles[mapi_req->handle_idx];
645
422
retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
646
423
OPENCHANGE_RETVAL_IF(retval, retval, NULL);
425
/* With CreateFolder, the parent object really IS the parent object */
648
426
mapi_handles_get_private_data(parent, &data);
649
427
parent_object = (struct emsmdbp_object *)data;
650
428
if (!parent_object) {
651
429
DEBUG(4, ("exchange_emsmdb: [OXCFOLD] CreateFolder null object\n"));
652
430
mapi_repl->error_code = MAPI_E_NO_SUPPORT;
653
return MAPI_E_SUCCESS;
656
if (parent_object->type != EMSMDBP_OBJECT_FOLDER) {
434
if (parent_object->type != EMSMDBP_OBJECT_FOLDER && parent_object->type != EMSMDBP_OBJECT_MAILBOX) {
657
435
DEBUG(4, ("exchange_emsmdb: [OXCFOLD] CreateFolder wrong object type: 0x%x\n", parent_object->type));
658
436
mapi_repl->error_code = MAPI_E_NO_SUPPORT;
659
return MAPI_E_SUCCESS;
661
parent_fid = parent_object->object.folder->folderID;
662
DEBUG(4, ("exchange_emsmdb: [OXCFOLD] CreateFolder parent: 0x%"PRIx64"\n", parent_fid));
663
DEBUG(4, ("exchange_emsmdb: [OXCFOLD] Creating %s\n", mapi_req->u.mapi_CreateFolder.FolderName.lpszA));
665
/* Step 3. Turn CreateFolder parameters into MAPI property array */
666
aRow = libmapiserver_ROP_request_to_properties(mem_ctx, (void *)&mapi_req->u.mapi_CreateFolder, op_MAPI_CreateFolder);
667
aRow->lpProps = add_SPropValue(mem_ctx, aRow->lpProps, &(aRow->cValues), PR_PARENT_FID, (void *)(&parent_fid));
669
/* Step 4. Do effective work here */
670
mapistore = emsmdbp_is_mapistore(parent);
673
switch (mapi_req->u.mapi_CreateFolder.ulFolderType) {
675
mapi_repl->error_code = EcDoRpc_RopCreateSystemSpecialFolder(emsmdbp_ctx, aRow,
676
mapi_req->u.mapi_CreateFolder.ulFlags,
677
parent_fid, &mapi_repl->u.mapi_CreateFolder);
680
DEBUG(4, ("exchange_emsmdb: [OXCFOLD] FOLDER_SEARCH not implemented\n"));
681
mapi_repl->error_code = MAPI_E_NO_SUPPORT;
684
DEBUG(4, ("exchange_emsmdb: [OXCFOLD] Unexpected folder type 0x%x\n", mapi_req->u.mapi_CreateFolder.ulType));
685
mapi_repl->error_code = MAPI_E_NO_SUPPORT;
689
mapi_repl->error_code = EcDoRpc_RopCreateGenericFolder(emsmdbp_ctx, parent, aRow,
690
mapi_req->u.mapi_CreateFolder.ulFlags,
691
&mapi_repl->u.mapi_CreateFolder);
695
mapi_repl->handle_idx = mapi_req->u.mapi_CreateFolder.handle_idx;
697
if (mapi_repl->u.mapi_CreateFolder.IsExistingFolder == true) {
698
mapi_repl->u.mapi_CreateFolder.GhostUnion.GhostInfo.HasRules = false;
699
mapi_repl->u.mapi_CreateFolder.GhostUnion.GhostInfo.IsGhosted = false;
702
if (!mapi_repl->error_code) {
703
retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
704
object = emsmdbp_object_folder_init((TALLOC_CTX *)rec, emsmdbp_ctx,
705
mapi_repl->u.mapi_CreateFolder.folder_id, parent);
707
retval = mapi_handles_set_private_data(rec, object);
710
handles[mapi_repl->handle_idx] = rec->handle;
440
request = &mapi_req->u.mapi_CreateFolder;
441
response = &mapi_repl->u.mapi_CreateFolder;
443
/* DEBUG(4, ("exchange_emsmdb: [OXCFOLD] CreateFolder parent: 0x%.16"PRIx64"\n", parent_fid)); */
444
/* DEBUG(4, ("exchange_emsmdb: [OXCFOLD] Creating %s\n", request->FolderName.lpszW)); */
446
/* if (request->ulFolderType != FOLDER_GENERIC) { */
447
/* DEBUG(4, ("exchange_emsmdb: [OXCFOLD] Unexpected folder type 0x%x\n", request->ulType)); */
448
/* mapi_repl->error_code = MAPI_E_NO_SUPPORT; */
452
response->IsExistingFolder = false;
454
ret = emsmdbp_object_get_fid_by_name(emsmdbp_ctx, parent_object, request->FolderName.lpszW, &fid);
455
if (ret == MAPISTORE_SUCCESS) {
456
if (request->ulFlags != OPEN_IF_EXISTS) {
457
mapi_repl->error_code = MAPI_E_COLLISION;
460
response->IsExistingFolder = true;
463
mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
464
if (response->IsExistingFolder) {
465
ret = emsmdbp_object_open_folder_by_fid(rec, emsmdbp_ctx, parent_object, fid, &object);
466
if (ret != MAPISTORE_SUCCESS) {
467
DEBUG(5, (__location__": failure opening existing folder\n"));
468
mapi_handles_delete(emsmdbp_ctx->handles_ctx, rec->handle);
469
mapi_repl->error_code = retval;
470
if (ret == MAPISTORE_ERR_DENIED) {
471
mapi_repl->error_code = MAPI_E_NO_ACCESS;
474
mapi_repl->error_code = MAPI_E_CALL_FAILED;
480
/* Step 3. Turn CreateFolder parameters into MAPI property array */
481
retval = openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, &fid);
482
if (retval != MAPI_E_SUCCESS) {
483
DEBUG(4, ("exchange_emsmdb: [OXCFOLD] Could not obtain a new folder id\n"));
484
mapi_repl->error_code = MAPI_E_NO_SUPPORT;
488
retval = openchangedb_get_new_changeNumber(emsmdbp_ctx->oc_ctx, &cn);
489
if (retval != MAPI_E_SUCCESS) {
490
DEBUG(4, ("exchange_emsmdb: [OXCFOLD] Could not obtain a new folder cn\n"));
491
mapi_repl->error_code = MAPI_E_NO_SUPPORT;
495
parent_fid = parent_object->object.folder->folderID;
497
aRow = libmapiserver_ROP_request_to_properties(mem_ctx, (void *)&mapi_req->u.mapi_CreateFolder, op_MAPI_CreateFolder);
498
aRow->lpProps = add_SPropValue(mem_ctx, aRow->lpProps, &(aRow->cValues), PR_PARENT_FID, (void *)(&parent_fid));
499
cnValue.ulPropTag = PidTagChangeNumber;
500
cnValue.value.d = cn;
501
SRow_addprop(aRow, cnValue);
503
retval = emsmdbp_object_create_folder(emsmdbp_ctx, parent_object, rec, fid, aRow, &object);
504
if (retval != MAPI_E_SUCCESS) {
505
DEBUG(5, (__location__": folder creation failed\n"));
506
mapi_handles_delete(emsmdbp_ctx->handles_ctx, rec->handle);
507
mapi_repl->error_code = retval;
512
handles[mapi_repl->handle_idx] = rec->handle;
513
mapi_handles_set_private_data(rec, object);
515
response->folder_id = fid;
517
if (response->IsExistingFolder == true) {
518
response->GhostUnion.GhostInfo.HasRules = false;
519
response->GhostUnion.GhostInfo.IsGhosted = false;
713
523
*size += libmapiserver_RopCreateFolder_size(mapi_repl);
1165
934
return MAPI_E_SUCCESS;
940
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopMoveCopyMessages(TALLOC_CTX *mem_ctx,
941
struct emsmdbp_context *emsmdbp_ctx,
942
struct EcDoRpc_MAPI_REQ *mapi_req,
943
struct EcDoRpc_MAPI_REPL *mapi_repl,
944
uint32_t *handles, uint16_t *size)
946
enum MAPISTATUS retval;
949
struct mapi_handles *rec = NULL;
950
void *private_data = NULL;
951
struct emsmdbp_object *destination_object;
952
struct emsmdbp_object *source_object;
953
uint64_t *targetMIDs;
955
bool mapistore = false;
957
DEBUG(4, ("exchange_emsmdb: [OXCFOLD] RopMoveCopyMessages (0x33)\n"));
960
OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
961
OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
962
OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
963
OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
964
OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
966
mapi_repl->opnum = mapi_req->opnum;
967
mapi_repl->error_code = MAPI_E_SUCCESS;
968
mapi_repl->handle_idx = mapi_req->handle_idx;
970
mapi_repl->u.mapi_MoveCopyMessages.PartialCompletion = 0;
972
/* Get the destionation information */
973
handle = handles[mapi_req->u.mapi_MoveCopyMessages.handle_idx];
974
retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
976
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
977
DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
981
retval = mapi_handles_get_private_data(rec, &private_data);
983
/* object is our destination folder */
984
destination_object = private_data;
985
if (!destination_object) {
986
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
987
DEBUG(5, (" object (%x) not found: %x\n", handle, mapi_req->handle_idx));
991
/* Get the source folder information */
992
handle = handles[mapi_req->handle_idx];
993
retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
995
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
996
DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
1000
retval = mapi_handles_get_private_data(rec, &private_data);
1001
source_object = private_data;
1002
if (!source_object) {
1003
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
1004
DEBUG(5, (" object (%x) not found: %x\n", handle, mapi_req->u.mapi_MoveCopyMessages.handle_idx));
1008
contextID = emsmdbp_get_contextID(destination_object);
1009
mapistore = emsmdbp_is_mapistore(source_object);
1011
/* We prepare a set of new MIDs for the backend */
1012
targetMIDs = talloc_array(NULL, uint64_t, mapi_req->u.mapi_MoveCopyMessages.count);
1013
for (i = 0; i < mapi_req->u.mapi_MoveCopyMessages.count; i++) {
1014
openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, &targetMIDs[i]);
1017
/* We invoke the backend method */
1018
mapistore_folder_move_copy_messages(emsmdbp_ctx->mstore_ctx, contextID, destination_object->backend_object, source_object->backend_object, mapi_req->u.mapi_MoveCopyMessages.count, mapi_req->u.mapi_MoveCopyMessages.message_id, targetMIDs, NULL, mapi_req->u.mapi_MoveCopyMessages.WantCopy);
1019
talloc_free(targetMIDs);
1021
/* /\* The backend might do this for us. In any case, we try to add it ourselves *\/ */
1022
/* mapistore_indexing_record_add_mid(emsmdbp_ctx->mstore_ctx, contextID, targetMID); */
1025
DEBUG(0, ("["__location__"] - mapistore support not implemented yet - shouldn't occur\n"));
1026
mapi_repl->error_code = MAPI_E_NO_SUPPORT;
1030
*size += libmapiserver_RopMoveCopyMessages_size(mapi_repl);
1032
return MAPI_E_SUCCESS;