32
32
#include "mapiproxy/libmapiserver/libmapiserver.h"
33
33
#include "dcesrv_exchange_emsmdb.h"
35
struct oxcmsg_prop_index {
36
uint32_t display_name; /* PR_DISPLAY_NAME_UNICODE or PR_7BIT_DISPLAY_NAME_UNICODE or PR_RECIPIENT_DISPLAY_NAME_UNICODE */
37
uint32_t email_address; /* PR_EMAIL_ADDRESS_UNICODE or PR_SMTP_ADDRESS_UNICODE */
40
static inline void oxcmsg_fill_prop_index(struct oxcmsg_prop_index *prop_index, struct SPropTagArray *properties)
42
if (SPropTagArray_find(*properties, PR_DISPLAY_NAME_UNICODE, &prop_index->display_name) == MAPI_E_NOT_FOUND
43
&& SPropTagArray_find(*properties, PR_7BIT_DISPLAY_NAME_UNICODE, &prop_index->display_name) == MAPI_E_NOT_FOUND
44
&& SPropTagArray_find(*properties, PR_RECIPIENT_DISPLAY_NAME_UNICODE, &prop_index->display_name) == MAPI_E_NOT_FOUND) {
45
prop_index->display_name = (uint32_t) -1;;
47
if (SPropTagArray_find(*properties, PR_EMAIL_ADDRESS_UNICODE, &prop_index->email_address) == MAPI_E_NOT_FOUND
48
&& SPropTagArray_find(*properties, PR_SMTP_ADDRESS_UNICODE, &prop_index->email_address) == MAPI_E_NOT_FOUND) {
49
prop_index->email_address = (uint32_t) -1;;
53
static void oxcmsg_fill_RecipientRow(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct RecipientRow *row, struct mapistore_message_recipient *recipient, struct oxcmsg_prop_index *prop_index)
55
struct ldb_result *res = NULL;
56
const char * const recipient_attrs[] = { "*", NULL };
58
char *full_name, *email_address, *simple_name, *legacyExchangeDN;
60
if (!recipient->username) {
64
ret = ldb_search(emsmdbp_ctx->samdb_ctx, emsmdbp_ctx, &res,
65
ldb_get_default_basedn(emsmdbp_ctx->samdb_ctx),
66
LDB_SCOPE_SUBTREE, recipient_attrs,
67
"(&(objectClass=user)(sAMAccountName=*%s*)(!(objectClass=computer)))",
69
/* If the search failed, build an external recipient: very basic for the moment */
70
if (ret != LDB_SUCCESS || !res->count) {
71
DEBUG(0, ("record not found for %s\n", recipient->username));
74
full_name = (char *) ldb_msg_find_attr_as_string(res->msgs[0], "displayName", NULL);
76
DEBUG(0, ("record found but displayName is missing for %s\n", recipient->username));
79
simple_name = (char *) ldb_msg_find_attr_as_string(res->msgs[0], "mailNickname", NULL);
81
DEBUG(0, ("record found but mailNickname is missing for %s\n", recipient->username));
84
legacyExchangeDN = (char *) ldb_msg_find_attr_as_string(res->msgs[0], "legacyExchangeDN", NULL);
85
if (!legacyExchangeDN) {
86
DEBUG(0, ("record found but legacyExchangeDN is missing for %s\n", recipient->username));
90
row->RecipientFlags = 0x06d1;
91
row->AddressPrefixUsed.prefix_size = strlen(legacyExchangeDN) - strlen(recipient->username);
92
row->DisplayType.display_type = SINGLE_RECIPIENT;
93
row->X500DN.recipient_x500name = talloc_strdup(mem_ctx, recipient->username);
94
row->DisplayName.lpszW = talloc_strdup(mem_ctx, full_name);
95
row->SimpleDisplayName.lpszW = talloc_strdup(mem_ctx, simple_name);
100
row->RecipientFlags = 0x303; /* type = SMTP, no rich text, unicode */
101
row->RecipientFlags |= 0x80; /* from doc: a different transport is responsible for delivery to this recipient. */
102
if (prop_index->display_name != (uint32_t) -1) {
103
full_name = recipient->data[prop_index->display_name];
105
row->RecipientFlags |= 0x10;
106
row->DisplayName.lpszW = talloc_strdup(mem_ctx, full_name);
108
row->RecipientFlags |= 0x0400;
109
row->SimpleDisplayName.lpszW = row->DisplayName.lpszW;
112
if (prop_index->email_address != (uint32_t) -1) {
113
email_address = recipient->data[prop_index->email_address];
115
row->RecipientFlags |= 0x08;
116
row->EmailAddress.lpszW = talloc_strdup(mem_ctx, email_address);
121
static void oxcmsg_fill_RecipientRow_data(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct RecipientRow *row, struct SPropTagArray *properties, struct mapistore_message_recipient *recipient)
125
enum MAPITAGS property;
127
row->prop_count = properties->cValues;
128
row->prop_values.length = 0;
130
for (i = 0; i < properties->cValues; i++) {
131
if (recipient->data[i] == NULL) {
137
for (i = 0; i < properties->cValues; i++) {
138
property = properties->aulPropTag[i];
139
data = recipient->data[i];
141
retval = MAPI_E_NOT_FOUND;
142
property = (property & 0xffff0000) + PT_ERROR;
143
data = (void *)&retval;
145
libmapiserver_push_property(mem_ctx,
146
property, (const void *)data, &row->prop_values,
151
static void oxcmsg_fill_OpenRecipientRow(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct OpenRecipientRow *row, struct SPropTagArray *properties, struct mapistore_message_recipient *recipient, struct oxcmsg_prop_index *prop_index)
153
row->CodePageId = CP_USASCII;
155
row->RecipientType = recipient->type;
157
oxcmsg_fill_RecipientRow(mem_ctx, emsmdbp_ctx, &row->RecipientRow, recipient, prop_index);
158
oxcmsg_fill_RecipientRow_data(mem_ctx, emsmdbp_ctx, &row->RecipientRow, properties, recipient);
37
162
\details EcDoRpc OpenMessage (0x03) Rop. This operation opens an
83
204
OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
84
205
OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
86
handle = handles[mapi_req->handle_idx];
87
ret = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
88
OPENCHANGE_RETVAL_IF(ret, ret, NULL);
207
request = &mapi_req->u.mapi_OpenMessage;
208
response = &mapi_repl->u.mapi_OpenMessage;
90
210
mapi_repl->opnum = mapi_req->opnum;
91
211
mapi_repl->error_code = MAPI_E_SUCCESS;
92
mapi_repl->handle_idx = mapi_req->u.mapi_OpenMessage.handle_idx;
93
messageID = mapi_req->u.mapi_OpenMessage.MessageId;
94
folderID = mapi_req->u.mapi_OpenMessage.FolderId;
212
mapi_repl->handle_idx = request->handle_idx;
214
parent_handle_id = handles[mapi_req->handle_idx];
215
retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, parent_handle_id, &context_object_handle);
216
OPENCHANGE_RETVAL_IF(retval, retval, NULL);
218
/* With OpenMessage, the parent object may NOT BE the direct parent folder of the message */
219
mapi_handles_get_private_data(context_object_handle, &data);
220
context_object = (struct emsmdbp_object *)data;
221
if (!context_object) {
222
mapi_repl->error_code = MAPI_E_NOT_FOUND;
223
*size += libmapiserver_RopOpenMessage_size(NULL);
224
return MAPI_E_SUCCESS;
96
227
/* OpenMessage can only be called for mailbox/folder objects */
97
mapi_handles_get_private_data(parent, &data);
98
object = (struct emsmdbp_object *)data;
100
mapi_repl->error_code = MAPI_E_NO_SUPPORT;
101
*size += libmapiserver_RopOpenMessage_size(NULL);
102
return MAPI_E_SUCCESS;
105
switch (object->type) {
106
case EMSMDBP_OBJECT_MAILBOX:
107
retval = mapistore_indexing_get_folder_list(emsmdbp_ctx->mstore_ctx, emsmdbp_ctx->username,
109
if (retval || !flist->count) {
110
DEBUG(0, ("No parent folder found for 0x%.16"PRIx64"\n", messageID));
112
/* If last element in the list doesn't match folderID, that's incorrect */
113
if (folderID != flist->folderID[flist->count - 1]) {
114
DEBUG(0, ("Last parent folder 0x%.16"PRIx64" doesn't match " \
115
"with expected 0x%.16"PRIx64"\n",
116
flist->folderID[flist->count - 1], folderID));
119
/* Look if we have a parent folder already opened */
120
for (i = flist->count - 1 ; i >= 0; i--) {
121
parent_handle = emsmdbp_object_get_folder_handle_by_fid(emsmdbp_ctx->handles_ctx,
129
/* If we have a parent handle, we have a context_id
130
* and we can call subsequent OpenFolder - this will
131
* increment ref_count whereas needed */
134
for (i = i + 1; i < flist->count; i++) {
135
mapi_handles_get_private_data(parent_handle, &data);
136
parent_object = (struct emsmdbp_object *) data;
137
folderID = parent_object->object.folder->folderID;
138
contextID = parent_object->object.folder->contextID;
139
retval = mapistore_opendir(emsmdbp_ctx->mstore_ctx, contextID, folderID,
141
mapi_handles_add(emsmdbp_ctx->handles_ctx, parent_handle->handle, &rec);
142
object = emsmdbp_object_folder_init((TALLOC_CTX *)emsmdbp_ctx, emsmdbp_ctx,
143
flist->folderID[i], parent_handle);
145
ret = mapi_handles_set_private_data(rec, object);
152
ret = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
153
object = emsmdbp_object_folder_init((TALLOC_CTX *)emsmdbp_ctx, emsmdbp_ctx,
154
flist->folderID[0], parent);
156
ret = mapi_handles_set_private_data(rec, object);
160
/* now we have a context_id, we can use code above to open subfolders subsequently */
164
/* Add this stage our new parent_handle should point to the message */
166
mapi_handles_get_private_data(parent_handle, &data);
167
parent_object = (struct emsmdbp_object *) data;
168
folderID = parent_object->object.folder->folderID;
169
contextID = parent_object->object.folder->contextID;
170
parent = parent_handle;
172
case EMSMDBP_OBJECT_FOLDER:
173
folderID = object->object.folder->folderID;
174
contextID = object->object.folder->contextID;
177
mapi_repl->error_code = MAPI_E_NO_SUPPORT;
178
*size += libmapiserver_RopGetHierarchyTable_size(NULL);
179
return MAPI_E_SUCCESS;
182
mapistore = emsmdbp_is_mapistore(parent);
185
/* system/special folder */
186
DEBUG(0, ("Not implemented yet - shouldn't occur\n"));
189
/* mapistore implementation goes here */
190
mapistore_openmessage(emsmdbp_ctx->mstore_ctx, contextID, folderID, messageID, &msg);
192
/* Build the OpenMessage reply */
193
subject = (char *) find_SPropValue_data(msg.properties, PR_SUBJECT);
195
mapi_repl->u.mapi_OpenMessage.HasNamedProperties = false;
196
mapi_repl->u.mapi_OpenMessage.SubjectPrefix.StringType = StringType_EMPTY;
197
mapi_repl->u.mapi_OpenMessage.NormalizedSubject.StringType = StringType_UNICODE_REDUCED;
198
mapi_repl->u.mapi_OpenMessage.NormalizedSubject.String.lpszW_reduced = talloc_strdup(mem_ctx, subject);
199
mapi_repl->u.mapi_OpenMessage.RecipientCount = msg.recipients->cRows;
201
SPropTagArray = set_SPropTagArray(mem_ctx, 0x4,
204
PR_7BIT_DISPLAY_NAME_UNICODE,
205
PR_SMTP_ADDRESS_UNICODE);
206
mapi_repl->u.mapi_OpenMessage.RecipientColumns.cValues = SPropTagArray->cValues;
207
mapi_repl->u.mapi_OpenMessage.RecipientColumns.aulPropTag = SPropTagArray->aulPropTag;
208
mapi_repl->u.mapi_OpenMessage.RowCount = msg.recipients->cRows;
209
mapi_repl->u.mapi_OpenMessage.recipients = talloc_array(mem_ctx,
210
struct OpenMessage_recipients,
211
msg.recipients->cRows + 1);
212
for (i = 0; i < msg.recipients->cRows; i++) {
213
mapi_repl->u.mapi_OpenMessage.recipients[i].RecipClass = (enum ulRecipClass) msg.recipients->aRow[i].lpProps[0].value.l;
214
mapi_repl->u.mapi_OpenMessage.recipients[i].codepage = CP_USASCII;
215
mapi_repl->u.mapi_OpenMessage.recipients[i].Reserved = 0;
216
emsmdbp_resolve_recipient(mem_ctx, emsmdbp_ctx,
217
(char *)msg.recipients->aRow[i].lpProps[1].value.lpszA,
218
&(mapi_repl->u.mapi_OpenMessage.RecipientColumns),
219
&(mapi_repl->u.mapi_OpenMessage.recipients[i].RecipientRow));
228
if (!(context_object->type == EMSMDBP_OBJECT_MAILBOX || context_object->type == EMSMDBP_OBJECT_FOLDER)) {
229
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
233
messageID = request->MessageId;
234
folderID = request->FolderId;
225
236
/* Initialize Message object */
226
handle = handles[mapi_req->handle_idx];
227
ret = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
228
handles[mapi_repl->handle_idx] = rec->handle;
231
object = emsmdbp_object_message_init((TALLOC_CTX *)rec, emsmdbp_ctx, messageID, parent_handle);
233
ret = mapi_handles_set_private_data(rec, object);
237
retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, 0, &object_handle);
239
if (request->OpenModeFlags == ReadOnly) {
240
ret = emsmdbp_object_message_open(object_handle, emsmdbp_ctx, context_object, folderID, messageID, false, &object, &msg);
242
else if (request->OpenModeFlags == OpenSoftDelete) {
243
ret = MAPISTORE_ERROR;
245
else { /* ReadWrite/BestAccess */
246
ret = emsmdbp_object_message_open(object_handle, emsmdbp_ctx, context_object, folderID, messageID, true, &object, &msg);
247
if (ret == MAPISTORE_ERR_DENIED && request->OpenModeFlags == BestAccess) {
248
ret = emsmdbp_object_message_open(object_handle, emsmdbp_ctx, context_object, folderID, messageID, false, &object, &msg);
252
if (ret != MAPISTORE_SUCCESS) {
253
mapi_handles_delete(emsmdbp_ctx->handles_ctx, object_handle->handle);
254
if (ret == MAPISTORE_ERR_DENIED) {
255
mapi_repl->error_code = MAPI_E_NO_ACCESS;
257
else if (ret == MAPISTORE_ERR_NOT_FOUND) {
258
mapi_repl->error_code = MAPI_E_NOT_FOUND;
261
mapi_repl->error_code = MAPI_E_CALL_FAILED;
266
handles[mapi_repl->handle_idx] = object_handle->handle;
267
retval = mapi_handles_set_private_data(object_handle, object);
269
/* Build the OpenMessage reply */
270
response->HasNamedProperties = true;
272
if (msg->subject_prefix && strlen(msg->subject_prefix) > 0) {
273
response->SubjectPrefix.StringType = StringType_UNICODE;
274
response->SubjectPrefix.String.lpszW = talloc_strdup(mem_ctx, msg->subject_prefix);
277
response->SubjectPrefix.StringType = StringType_EMPTY;
279
if (msg->normalized_subject && strlen(msg->normalized_subject) > 0) {
280
response->NormalizedSubject.StringType = StringType_UNICODE;
281
response->NormalizedSubject.String.lpszW = talloc_strdup(mem_ctx, msg->normalized_subject);
284
response->NormalizedSubject.StringType = StringType_EMPTY;
287
response->RecipientColumns.cValues = msg->columns->cValues;
288
response->RecipientColumns.aulPropTag = msg->columns->aulPropTag;
291
response->RecipientColumns.cValues = 0;
293
response->RecipientCount = msg->recipients_count;
294
response->RowCount = msg->recipients_count;
295
if (msg->recipients_count > 0) {
296
response->RecipientRows = talloc_array(mem_ctx,
297
struct OpenRecipientRow,
298
msg->recipients_count + 1);
299
oxcmsg_fill_prop_index(&prop_index, msg->columns);
300
for (i = 0; i < msg->recipients_count; i++) {
301
oxcmsg_fill_OpenRecipientRow(mem_ctx, emsmdbp_ctx, &(response->RecipientRows[i]), msg->columns, msg->recipients + i, &prop_index);
305
response->RecipientCount = 0;
307
response->RowCount = response->RecipientCount;
237
310
*size += libmapiserver_RopOpenMessage_size(mapi_repl);
239
312
return MAPI_E_SUCCESS;
288
363
OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
289
364
OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
291
handle = handles[mapi_req->handle_idx];
292
retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
293
OPENCHANGE_RETVAL_IF(retval, retval, NULL);
295
366
mapi_repl->opnum = mapi_req->opnum;
296
367
mapi_repl->error_code = MAPI_E_SUCCESS;
297
368
mapi_repl->handle_idx = mapi_req->u.mapi_CreateMessage.handle_idx;
298
369
mapi_repl->u.mapi_CreateMessage.HasMessageId = 0;
371
handle = handles[mapi_req->handle_idx];
372
retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &context_handle);
374
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
375
DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
378
/* With CreateMessage, the parent object may NOT BE the direct parent folder of the message */
379
retval = mapi_handles_get_private_data(context_handle, &data);
381
mapi_repl->error_code = retval;
382
DEBUG(5, (" handle data not found, idx = %x\n", mapi_req->handle_idx));
385
context_object = data;
300
387
folderID = mapi_req->u.mapi_CreateMessage.FolderId;
302
/* CreateMessage can only be called for a mailbox/folder object */
303
mapi_handles_get_private_data(parent, &data);
304
object = (struct emsmdbp_object *)data;
306
mapi_repl->error_code = MAPI_E_NO_SUPPORT;
310
/* FIXME: we can't assume the folder is already opened */
311
parent_handle = emsmdbp_object_get_folder_handle_by_fid(emsmdbp_ctx->handles_ctx, folderID);
312
if (!parent_handle) {
313
mapi_repl->error_code = MAPI_E_NOT_FOUND;
316
contextID = emsmdbp_get_contextID(parent_handle);
317
mapistore = emsmdbp_is_mapistore(parent_handle);
321
/* system/special folder */
322
DEBUG(0, ("Not implemented yet - shouldn't occur\n"));
325
/* This should be handled differently here: temporary hack */
326
retval = openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, &messageID);
389
/* Step 1. Retrieve parent handle in the hierarchy */
390
ret = emsmdbp_object_open_folder_by_fid(mem_ctx, emsmdbp_ctx, context_object, folderID, &folder_object);
391
if (ret != MAPISTORE_SUCCESS) {
392
if (ret == MAPISTORE_ERR_DENIED) {
393
mapi_repl->error_code = MAPI_E_NO_ACCESS;
328
396
mapi_repl->error_code = MAPI_E_NO_SUPPORT;
331
mapi_repl->u.mapi_CreateMessage.HasMessageId = 1;
332
mapi_repl->u.mapi_CreateMessage.MessageId.MessageId = messageID;
333
/* mapistore_createmessage(emsmdbp_ctx->mstore_ctx, contextID, folderID, &messageID); */
335
/* Set default properties for message: MS-OXCMSG 3.2.5.2 */
336
aRow.lpProps = talloc_array(mem_ctx, struct SPropValue, 2);
340
aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_IMPORTANCE, (const void *)&pt_long);
341
aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_MESSAGE_CLASS, (const void *)"IPM.Note");
343
aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_SENSITIVITY, (const void *)&pt_long);
345
aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_MESSAGE_FLAGS, (const void *)&pt_long);
347
aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_HASATTACH, (const void *)&pt_boolean);
348
aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_URL_COMP_NAME_SET, (const void *)&pt_boolean);
350
aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_TRUST_SENDER, (const void *)&pt_long);
352
aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_ACCESS, (const void *)&pt_long);
354
aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_ACCESS_LEVEL, (const void *)&pt_long);
355
aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_URL_COMP_NAME, (const void *)"No Subject.EML");
357
gettimeofday(&tv, NULL);
358
time = timeval_to_nttime(&tv);
359
ft.dwLowDateTime = (time << 32) >> 32;
360
ft.dwHighDateTime = time >> 32;
361
aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_CREATION_TIME, (const void *)&ft);
362
aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_LAST_MODIFICATION_TIME, (const void *)&ft);
363
aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_LOCAL_COMMIT_TIME, (const void *)&ft);
364
aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_MESSAGE_LOCALE_ID, (const void *)&mapi_req->u.mapi_CreateMessage.CodePageId);
365
aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_LOCALE_ID, (const void *)&mapi_req->u.mapi_CreateMessage.CodePageId);
367
mapistore_setprops(emsmdbp_ctx->mstore_ctx, contextID, messageID, MAPISTORE_MESSAGE, &aRow);
371
DEBUG(0, ("CreateMessage: 0x%.16"PRIx64": mapistore = %s\n", folderID,
372
emsmdbp_is_mapistore(parent_handle) == true ? "true" : "false"));
401
/* This should be handled differently here: temporary hack */
402
retval = openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, &messageID);
404
mapi_repl->error_code = MAPI_E_NO_SUPPORT;
407
mapi_repl->u.mapi_CreateMessage.HasMessageId = 1;
408
mapi_repl->u.mapi_CreateMessage.MessageId.MessageId = messageID;
374
410
/* Initialize Message object */
375
411
handle = handles[mapi_req->handle_idx];
376
retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
377
handles[mapi_repl->handle_idx] = rec->handle;
380
object = emsmdbp_object_message_init((TALLOC_CTX *)rec, emsmdbp_ctx, messageID, parent_handle);
382
/* Add default properties to message MS-OXCMSG 3.2.5.2 */
383
retval = mapi_handles_set_private_data(rec, object);
412
retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &message_handle);
414
message_object = emsmdbp_object_message_init((TALLOC_CTX *)message_handle, emsmdbp_ctx, messageID, folder_object);
415
message_object->object.message->read_write = true;
417
contextID = emsmdbp_get_contextID(folder_object);
418
mapistore = emsmdbp_is_mapistore(folder_object);
421
ret = mapistore_folder_create_message(emsmdbp_ctx->mstore_ctx, contextID,
422
folder_object->backend_object, message_object,
423
messageID, mapi_req->u.mapi_CreateMessage.AssociatedFlag,
424
&message_object->backend_object);
425
if (ret != MAPISTORE_SUCCESS) {
426
if (ret == MAPISTORE_ERR_DENIED) {
427
mapi_repl->error_code = MAPI_E_NO_ACCESS;
429
else if (ret == MAPISTORE_ERR_NOT_FOUND) {
430
mapi_repl->error_code = MAPI_E_NOT_FOUND;
433
mapi_repl->error_code = MAPI_E_CALL_FAILED;
439
retval = openchangedb_message_create(emsmdbp_ctx->mstore_ctx,
440
emsmdbp_ctx->oc_ctx, messageID, folderID, mapi_req->u.mapi_CreateMessage.AssociatedFlag,
441
&message_object->backend_object);
442
DEBUG(5, ("openchangedb_create_message returned 0x%.8x\n", retval));
446
handles[mapi_repl->handle_idx] = message_handle->handle;
448
/* Add default properties to message MS-OXCMSG 3.2.5.2 */
449
retval = mapi_handles_set_private_data(message_handle, message_object);
451
/* Set default properties for message: MS-OXCMSG 3.2.5.2 */
452
aRow.ulAdrEntryPad = 0;
453
aRow.lpProps = talloc_array(mem_ctx, struct SPropValue, 23);
457
set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_IMPORTANCE, (const void *)&pt_long);
459
set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_MESSAGE_CLASS_UNICODE, (const void *)"IPM.Note");
462
set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_SENSITIVITY, (const void *)&pt_long);
464
set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_DISPLAY_TO_UNICODE, (const void *)"");
466
set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_DISPLAY_CC_UNICODE, (const void *)"");
468
set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_DISPLAY_BCC_UNICODE, (const void *)"");
471
set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_MESSAGE_FLAGS, (const void *)&pt_long);
475
set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_HASATTACH, (const void *)&pt_boolean);
477
set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_HAS_NAMED_PROPERTIES, (const void *)&pt_boolean);
479
set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_URL_COMP_NAME_SET, (const void *)&pt_boolean);
483
set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_TRUST_SENDER, (const void *)&pt_long);
486
set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_ACCESS, (const void *)&pt_long);
489
set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_ACCESS_LEVEL, (const void *)&pt_long);
491
set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_URL_COMP_NAME_UNICODE, (const void *)"No Subject.EML");
494
gettimeofday(&tv, NULL);
495
time = timeval_to_nttime(&tv);
496
ft.dwLowDateTime = (time << 32) >> 32;
497
ft.dwHighDateTime = time >> 32;
498
set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_CREATION_TIME, (const void *)&ft);
500
set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_LAST_MODIFICATION_TIME, (const void *)&ft);
502
set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_LOCAL_COMMIT_TIME, (const void *)&ft);
505
/* we copy CodePageId (uint16_t) into an uint32_t to avoid a buffer error */
506
pt_long = mapi_req->u.mapi_CreateMessage.CodePageId;
507
set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_MESSAGE_LOCALE_ID, (const void *)&pt_long);
509
set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_LOCALE_ID, (const void *)&pt_long);
512
set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_CREATOR_NAME_UNICODE, (const void *)emsmdbp_ctx->szDisplayName);
514
set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_LAST_MODIFIER_NAME_UNICODE, (const void *)emsmdbp_ctx->szDisplayName);
516
pt_binary = talloc_zero(mem_ctx, struct SBinary_short);
517
entryid_set_AB_EntryID(pt_binary, emsmdbp_ctx->szUserDN, pt_binary);
518
set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_CREATOR_ENTRYID, (const void *)pt_binary);
520
set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_LAST_MODIFIER_ENTRYID, (const void *)pt_binary);
523
/* TODO: some required properties are not set: PidTagSearchKey, PidTagMessageSize, PidTagSecurityDescriptor */
524
emsmdbp_object_set_properties(emsmdbp_ctx, message_object, &aRow);
526
DEBUG(0, ("CreateMessage: 0x%.16"PRIx64": mapistore = %s\n", folderID, mapistore ? "true" : "false"));
388
530
*size += libmapiserver_RopCreateMessage_size(mapi_repl);
390
532
return MAPI_E_SUCCESS;
628
\details EcDoRpc RemoveAllRecipients (0x0d) Rop. This operation removes all
629
recipients from a message.
631
\param mem_ctx pointer to the memory context
632
\param emsmdbp_ctx pointer to the emsmdb provider context
633
\param mapi_req pointer to the RemoveAllRecipients EcDoRpc_MAPI_REQ
635
\param mapi_repl pointer to the RemoveAllRecipients EcDoRpc_MAPI_REPL
637
\param handles pointer to the MAPI handles array
638
\param size pointer to the mapi_response size to update
640
\return MAPI_E_SUCCESS on success, otherwise MAPI error
642
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopRemoveAllRecipients(TALLOC_CTX *mem_ctx,
643
struct emsmdbp_context *emsmdbp_ctx,
644
struct EcDoRpc_MAPI_REQ *mapi_req,
645
struct EcDoRpc_MAPI_REPL *mapi_repl,
646
uint32_t *handles, uint16_t *size)
648
struct mapi_handles *rec = NULL;
649
struct emsmdbp_object *object;
650
enum MAPISTATUS retval;
653
bool mapistore = false;
655
struct SPropTagArray columns;
657
DEBUG(4, ("exchange_emsmdb: [OXCMSG] RemoveAllRecipients (0x0d)\n"));
660
OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
661
OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
662
OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
663
OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
664
OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
666
mapi_repl->opnum = mapi_req->opnum;
667
mapi_repl->error_code = MAPI_E_SUCCESS;
669
handle = handles[mapi_req->handle_idx];
670
retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
672
mapi_repl->error_code = MAPI_E_NOT_FOUND;
676
mapi_repl->handle_idx = mapi_req->handle_idx;
678
retval = mapi_handles_get_private_data(rec, &private_data);
679
object = (struct emsmdbp_object *)private_data;
680
if (!object || object->type != EMSMDBP_OBJECT_MESSAGE) {
681
mapi_repl->error_code = MAPI_E_NO_SUPPORT;
685
mapistore = emsmdbp_is_mapistore(object);
687
contextID = emsmdbp_get_contextID(object);
688
memset(&columns, 0, sizeof(struct SPropTagArray));
689
mapistore_message_modify_recipients(emsmdbp_ctx->mstore_ctx, contextID, &columns, object->backend_object, 0, NULL);
692
DEBUG(0, ("Not implement yet - shouldn't occur\n"));
696
*size += libmapiserver_RopRemoveAllRecipients_size(mapi_repl);
698
return MAPI_E_SUCCESS;
701
static void oxcmsg_parse_ModifyRecipientRow(TALLOC_CTX *mem_ctx, struct ModifyRecipientRow *recipient_row, uint16_t prop_count, enum MAPITAGS *properties, struct mapistore_message_recipient *recipient)
707
struct Binary_r *bin_value;
708
struct FILETIME *ft_value;
710
const uint16_t *unicode_char;
711
size_t dest_size, dest_len;
713
recipient->type = recipient_row->RecipClass;
715
if ((recipient_row->RecipientRow.RecipientFlags & 0x07) == 1) {
716
recipient->username = (char *) recipient_row->RecipientRow.X500DN.recipient_x500name;
719
recipient->username = NULL;
722
recipient->data = talloc_array(mem_ctx, void *, prop_count + 2);
724
/* PR_DISPLAY_NAME_UNICODE */
725
switch ((recipient_row->RecipientRow.RecipientFlags & 0x210)) {
727
recipient->data[0] = (void *) recipient_row->RecipientRow.DisplayName.lpszA;
730
recipient->data[0] = (void *) recipient_row->RecipientRow.DisplayName.lpszW;
733
recipient->data[0] = NULL;
736
/* PR_EMAIL_ADDRESS_UNICODE */
737
switch ((recipient_row->RecipientRow.RecipientFlags & 0x208)) {
739
recipient->data[1] = (void *) recipient_row->RecipientRow.EmailAddress.lpszA;
742
recipient->data[1] = (void *) recipient_row->RecipientRow.EmailAddress.lpszW;
745
recipient->data[1] = NULL;
749
for (i = 0; i < prop_count; i++) {
750
if (properties[i] & MV_FLAG) {
751
DEBUG(0, ("multivalue not supported yet\n"));
755
if (recipient_row->RecipientRow.layout) {
757
if (recipient_row->RecipientRow.prop_values.data[data_pos] != 0) {
758
recipient->data[i+2] = NULL;
759
if (recipient_row->RecipientRow.prop_values.data[data_pos] == 0xa) {
766
dest_value = src_value = recipient_row->RecipientRow.prop_values.data + data_pos;
767
switch (properties[i] & 0xffff) {
769
value_size = sizeof(uint8_t);
772
value_size = sizeof(uint16_t);
776
value_size = sizeof(uint32_t);
779
value_size = sizeof(double);
782
value_size = sizeof(uint64_t);
785
value_size = strlen(dest_value) + 1;
788
ft_value = talloc_zero(recipient->data, struct FILETIME);
789
ft_value->dwLowDateTime = *(uint32_t *) src_value;
790
ft_value->dwHighDateTime = *(uint32_t *) (src_value + 4);
791
value_size = sizeof(uint64_t);
792
dest_value = ft_value;
795
unicode_char = (const uint16_t *) src_value;
797
while (*unicode_char++)
799
dest_size = value_size * 3 + 3;
800
uni_value = talloc_array(recipient->data, char, dest_size);
801
convert_string(CH_UTF16LE, CH_UTF8,
802
src_value, value_size,
803
uni_value, dest_size,
805
uni_value[dest_len] = 0;
806
dest_value = uni_value;
810
bin_value = talloc_zero(recipient->data, struct Binary_r);
811
bin_value->cb = *(uint16_t *) src_value;
812
bin_value->lpb = src_value + 2;
813
value_size = (bin_value->cb + sizeof(uint16_t));
814
dest_value = bin_value;
817
recipient->data[i+2] = dest_value;
818
data_pos += value_size;
477
823
\details EcDoRpc ModifyRecipients (0x0e) Rop. This operation modifies an
478
824
existing message to add recipients (TO, CC, BCC).
579
mapistore = emsmdbp_is_mapistore(rec);
969
mapistore = emsmdbp_is_mapistore(object);
580
970
switch (mapistore) {
582
972
DEBUG(0, ("Not implemented yet - shouldn't occur\n"));
585
folderID = object->object.message->folderID;
586
messageID = object->object.message->messageID;
587
contextID = object->object.message->contextID;
588
mapistore_openmessage(emsmdbp_ctx->mstore_ctx, contextID, folderID, messageID, &msg);
975
contextID = emsmdbp_get_contextID(object);
977
if (mapistore_message_get_message_data(emsmdbp_ctx->mstore_ctx, contextID, object->backend_object, mem_ctx, &msg) != MAPISTORE_SUCCESS) {
978
mapi_repl->error_code = MAPI_E_NOT_FOUND;
590
982
/* Build the ReloadCachedInformation reply */
591
subject = (char *) find_SPropValue_data(msg.properties, PR_SUBJECT);
592
mapi_repl->u.mapi_ReloadCachedInformation.HasNamedProperties = false;
593
mapi_repl->u.mapi_ReloadCachedInformation.SubjectPrefix.StringType = StringType_EMPTY;
595
mapi_repl->u.mapi_ReloadCachedInformation.NormalizedSubject.StringType = StringType_UNICODE_REDUCED;
596
mapi_repl->u.mapi_ReloadCachedInformation.NormalizedSubject.String.lpszW_reduced = talloc_strdup(mem_ctx, subject);
983
if (msg->subject_prefix && strlen(msg->subject_prefix) > 0) {
984
mapi_repl->u.mapi_ReloadCachedInformation.SubjectPrefix.StringType = StringType_UNICODE;
985
mapi_repl->u.mapi_ReloadCachedInformation.SubjectPrefix.String.lpszW = talloc_strdup(mem_ctx, msg->subject_prefix);
988
mapi_repl->u.mapi_ReloadCachedInformation.SubjectPrefix.StringType = StringType_EMPTY;
990
if (msg->normalized_subject && strlen(msg->normalized_subject) > 0) {
991
mapi_repl->u.mapi_ReloadCachedInformation.NormalizedSubject.StringType = StringType_UNICODE;
992
mapi_repl->u.mapi_ReloadCachedInformation.NormalizedSubject.String.lpszW = talloc_strdup(mem_ctx, msg->normalized_subject);
598
995
mapi_repl->u.mapi_ReloadCachedInformation.NormalizedSubject.StringType = StringType_EMPTY;
600
mapi_repl->u.mapi_ReloadCachedInformation.RecipientCount = msg.recipients->cRows;
602
SPropTagArray = set_SPropTagArray(mem_ctx, 0x4,
605
PR_7BIT_DISPLAY_NAME_UNICODE,
606
PR_SMTP_ADDRESS_UNICODE);
607
mapi_repl->u.mapi_ReloadCachedInformation.RecipientColumns.cValues = SPropTagArray->cValues;
608
mapi_repl->u.mapi_ReloadCachedInformation.RecipientColumns.aulPropTag = SPropTagArray->aulPropTag;
609
mapi_repl->u.mapi_ReloadCachedInformation.RowCount = msg.recipients->cRows;
610
mapi_repl->u.mapi_ReloadCachedInformation.RecipientRows = talloc_array(mem_ctx,
611
struct OpenRecipientRow,
612
msg.recipients->cRows + 1);
613
for (i = 0; i < msg.recipients->cRows; i++) {
614
mapi_repl->u.mapi_ReloadCachedInformation.RecipientRows[i].RecipientType = (enum ulRecipClass) msg.recipients->aRow[i].lpProps[0].value.l;
615
mapi_repl->u.mapi_ReloadCachedInformation.RecipientRows[i].CodePageId = CP_USASCII;
616
mapi_repl->u.mapi_ReloadCachedInformation.RecipientRows[i].Reserved = 0;
617
emsmdbp_resolve_recipient(mem_ctx, emsmdbp_ctx,
618
(char *)msg.recipients->aRow[i].lpProps[1].value.lpszA,
619
&(mapi_repl->u.mapi_ReloadCachedInformation.RecipientColumns),
620
&(mapi_repl->u.mapi_ReloadCachedInformation.RecipientRows[i].RecipientRow));
998
mapi_repl->u.mapi_ReloadCachedInformation.RecipientColumns.cValues = msg->columns->cValues;
999
mapi_repl->u.mapi_ReloadCachedInformation.RecipientColumns.aulPropTag = msg->columns->aulPropTag;
1002
mapi_repl->u.mapi_ReloadCachedInformation.RecipientColumns.cValues = 0;
1004
mapi_repl->u.mapi_ReloadCachedInformation.RecipientCount = msg->recipients_count;
1005
mapi_repl->u.mapi_ReloadCachedInformation.RowCount = msg->recipients_count;
1006
if (msg->recipients_count > 0) {
1007
mapi_repl->u.mapi_ReloadCachedInformation.RecipientRows = talloc_array(mem_ctx,
1008
struct OpenRecipientRow,
1009
msg->recipients_count + 1);
1010
oxcmsg_fill_prop_index(&prop_index, msg->columns);
1011
for (i = 0; i < msg->recipients_count; i++) {
1012
oxcmsg_fill_OpenRecipientRow(mem_ctx, emsmdbp_ctx, &(mapi_repl->u.mapi_ReloadCachedInformation.RecipientRows[i]), msg->columns, msg->recipients + i, &prop_index);
710
1152
mapi_repl->opnum = mapi_req->opnum;
711
1153
mapi_repl->error_code = MAPI_E_SUCCESS;
713
/* TODO: actually implement this */
1154
mapi_repl->handle_idx = mapi_req->u.mapi_GetAttachmentTable.handle_idx;
1156
handle = handles[mapi_req->handle_idx];
1157
retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
1159
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
1160
DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
1164
retval = mapi_handles_get_private_data(rec, &data);
1166
mapi_repl->error_code = retval;
1167
DEBUG(5, (" handle data not found, idx = %x\n", mapi_req->handle_idx));
1171
message_object = (struct emsmdbp_object *) data;
1172
if (!message_object || message_object->type != EMSMDBP_OBJECT_MESSAGE) {
1173
DEBUG(5, (" no object or object is not a message\n"));
1174
mapi_repl->error_code = MAPI_E_NO_SUPPORT;
1178
retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &table_rec);
1179
handles[mapi_repl->handle_idx] = table_rec->handle;
1181
table_object = emsmdbp_object_message_open_attachment_table(table_rec, emsmdbp_ctx, message_object);
1182
if (!table_object) {
1183
mapi_handles_delete(emsmdbp_ctx->handles_ctx, table_rec->handle);
1184
mapi_repl->error_code = MAPI_E_NOT_FOUND;
1187
mapi_handles_set_private_data(table_rec, table_object);
715
1190
*size += libmapiserver_RopGetAttachmentTable_size(mapi_repl);
717
handle = handles[mapi_req->handle_idx];
718
retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
719
handles[mapi_repl->handle_idx] = rec->handle;
1192
return MAPI_E_SUCCESS;
1196
\details EcDoRpc OpenAttach (0x22) Rop. This operation open an attachment
1197
from the message handle.
1199
\param mem_ctx pointer to the memory context
1200
\param emsmdbp_ctx pointer to the emsmdb provider context
1201
\param mapi_req pointer to the OpenAttach EcDoRpc_MAPI_REQ
1203
\param mapi_repl pointer to the OpenAttach
1204
EcDoRpc_MAPI_REPL structure
1205
\param handles pointer to the MAPI handles array
1206
\param size pointer to the mapi_response size to update
1208
\return MAPI_E_SUCCESS on success, otherwise MAPI error
1210
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenAttach(TALLOC_CTX *mem_ctx,
1211
struct emsmdbp_context *emsmdbp_ctx,
1212
struct EcDoRpc_MAPI_REQ *mapi_req,
1213
struct EcDoRpc_MAPI_REPL *mapi_repl,
1214
uint32_t *handles, uint16_t *size)
1216
enum MAPISTATUS retval;
1218
uint32_t attachmentID;
1220
struct mapi_handles *rec = NULL;
1221
struct mapi_handles *attachment_rec = NULL;
1222
struct emsmdbp_object *message_object = NULL;
1223
struct emsmdbp_object *attachment_object = NULL;
1226
DEBUG(4, ("exchange_emsmdb: [OXCMSG] OpenAttach (0x22)\n"));
1229
OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
1230
OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
1231
OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
1232
OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
1233
OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
1235
mapi_repl->opnum = mapi_req->opnum;
1236
mapi_repl->error_code = MAPI_E_SUCCESS;
1237
mapi_repl->handle_idx = mapi_req->u.mapi_OpenAttach.handle_idx;
1239
handle = handles[mapi_req->handle_idx];
1240
retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
1242
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
1243
DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
1247
retval = mapi_handles_get_private_data(rec, &data);
1249
mapi_repl->error_code = retval;
1250
DEBUG(5, (" handle data not found, idx = %x\n", mapi_req->handle_idx));
1254
message_object = (struct emsmdbp_object *) data;
1255
if (!message_object || message_object->type != EMSMDBP_OBJECT_MESSAGE) {
1256
DEBUG(5, (" no object or object is not a message\n"));
1257
mapi_repl->error_code = MAPI_E_NO_SUPPORT;
1261
switch (emsmdbp_is_mapistore(message_object)) {
1263
/* system/special folder */
1264
DEBUG(0, ("Not implemented yet - shouldn't occur\n"));
1267
contextID = emsmdbp_get_contextID(message_object);
1268
attachmentID = mapi_req->u.mapi_OpenAttach.AttachmentID;
1270
retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &attachment_rec);
1271
handles[mapi_repl->handle_idx] = attachment_rec->handle;
1273
attachment_object = emsmdbp_object_attachment_init((TALLOC_CTX *)attachment_rec, emsmdbp_ctx,
1274
message_object->object.message->messageID, message_object);
1275
if (attachment_object) {
1276
retval = mapistore_message_open_attachment(emsmdbp_ctx->mstore_ctx, contextID, message_object->backend_object,
1277
attachment_object, attachmentID, &attachment_object->backend_object);
1279
mapi_handles_delete(emsmdbp_ctx->handles_ctx, attachment_rec->handle);
1280
DEBUG(5, ("could not open nor create mapistore message\n"));
1281
mapi_repl->error_code = MAPI_E_NOT_FOUND;
1283
retval = mapi_handles_set_private_data(attachment_rec, attachment_object);
1288
*size += libmapiserver_RopOpenAttach_size(mapi_repl);
1290
return MAPI_E_SUCCESS;
1294
\details EcDoRpc CreateAttach (0x23) Rop. This operation open an attachment
1295
from the message handle.
1297
\param mem_ctx pointer to the memory context
1298
\param emsmdbp_ctx pointer to the emsmdb provider context
1299
\param mapi_req pointer to the CreateAttach EcDoRpc_MAPI_REQ
1301
\param mapi_repl pointer to the CreateAttach
1302
EcDoRpc_MAPI_REPL structure
1303
\param handles pointer to the MAPI handles array
1304
\param size pointer to the mapi_response size to update
1306
\return MAPI_E_SUCCESS on success, otherwise MAPI error
1308
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopCreateAttach(TALLOC_CTX *mem_ctx,
1309
struct emsmdbp_context *emsmdbp_ctx,
1310
struct EcDoRpc_MAPI_REQ *mapi_req,
1311
struct EcDoRpc_MAPI_REPL *mapi_repl,
1312
uint32_t *handles, uint16_t *size)
1314
enum MAPISTATUS retval;
1318
struct mapi_handles *rec = NULL;
1319
struct mapi_handles *attachment_rec = NULL;
1320
struct emsmdbp_object *message_object = NULL;
1321
struct emsmdbp_object *attachment_object = NULL;
1324
DEBUG(4, ("exchange_emsmdb: [OXCMSG] CreateAttach (0x23)\n"));
1327
OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
1328
OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
1329
OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
1330
OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
1331
OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
1333
mapi_repl->opnum = mapi_req->opnum;
1334
mapi_repl->error_code = MAPI_E_SUCCESS;
1335
mapi_repl->handle_idx = mapi_req->u.mapi_CreateAttach.handle_idx;
1337
handle = handles[mapi_req->handle_idx];
1338
retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
1340
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
1341
DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
1345
retval = mapi_handles_get_private_data(rec, &data);
1347
mapi_repl->error_code = retval;
1348
DEBUG(5, (" handle data not found, idx = %x\n", mapi_req->handle_idx));
1352
message_object = (struct emsmdbp_object *) data;
1353
if (!message_object || message_object->type != EMSMDBP_OBJECT_MESSAGE) {
1354
DEBUG(5, (" no object or object is not a message\n"));
1355
mapi_repl->error_code = MAPI_E_NO_SUPPORT;
1359
switch (emsmdbp_is_mapistore(message_object)) {
1361
/* system/special folder */
1362
DEBUG(0, ("Not implemented yet - shouldn't occur\n"));
1365
messageID = message_object->object.message->messageID;
1366
contextID = emsmdbp_get_contextID(message_object);
1368
retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &attachment_rec);
1369
handles[mapi_repl->handle_idx] = attachment_rec->handle;
1371
attachment_object = emsmdbp_object_attachment_init((TALLOC_CTX *)attachment_rec, emsmdbp_ctx,
1372
messageID, message_object);
1373
if (attachment_object) {
1374
retval = mapistore_message_create_attachment(emsmdbp_ctx->mstore_ctx, contextID, message_object->backend_object,
1375
attachment_object, &attachment_object->backend_object, &mapi_repl->u.mapi_CreateAttach.AttachmentID);
1377
mapi_handles_delete(emsmdbp_ctx->handles_ctx, attachment_rec->handle);
1378
DEBUG(5, ("could not open nor create mapistore message\n"));
1379
mapi_repl->error_code = MAPI_E_NOT_FOUND;
1381
retval = mapi_handles_set_private_data(attachment_rec, attachment_object);
1386
*size += libmapiserver_RopCreateAttach_size(mapi_repl);
1388
return MAPI_E_SUCCESS;
1392
\details EcDoRpc SaveChangesAttachment (0x25) Rop. This operation open an attachment
1393
from the message handle.
1395
\param mem_ctx pointer to the memory context
1396
\param emsmdbp_ctx pointer to the emsmdb provider context
1397
\param mapi_req pointer to the SaveChangesAttachment EcDoRpc_MAPI_REQ
1399
\param mapi_repl pointer to the SaveChangesAttachment
1400
EcDoRpc_MAPI_REPL structure
1401
\param handles pointer to the MAPI handles array
1402
\param size pointer to the mapi_response size to update
1404
\return MAPI_E_SUCCESS on success, otherwise MAPI error
1406
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSaveChangesAttachment(TALLOC_CTX *mem_ctx,
1407
struct emsmdbp_context *emsmdbp_ctx,
1408
struct EcDoRpc_MAPI_REQ *mapi_req,
1409
struct EcDoRpc_MAPI_REPL *mapi_repl,
1410
uint32_t *handles, uint16_t *size)
1412
DEBUG(4, ("exchange_emsmdb: [OXCMSG] SaveChangesAttachment (0x25) -- valid stub\n"));
1415
OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
1416
OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
1417
OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
1418
OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
1419
OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
1421
mapi_repl->opnum = mapi_req->opnum;
1422
mapi_repl->error_code = MAPI_E_SUCCESS;
1423
mapi_repl->handle_idx = mapi_req->u.mapi_SaveChangesAttachment.handle_idx;
1425
*size += libmapiserver_RopSaveChangesAttachment_size(mapi_repl);
1427
return MAPI_E_SUCCESS;
1431
\details EcDoRpc OpenEmbeddedMessage (0x46) Rop. This operation open an attachment
1432
from the message handle.
1434
\param mem_ctx pointer to the memory context
1435
\param emsmdbp_ctx pointer to the emsmdb provider context
1436
\param mapi_req pointer to the OpenEmbeddedMessage EcDoRpc_MAPI_REQ
1438
\param mapi_repl pointer to the OpenEmbeddedMessage
1439
EcDoRpc_MAPI_REPL structure
1440
\param handles pointer to the MAPI handles array
1441
\param size pointer to the mapi_response size to update
1443
\return MAPI_E_SUCCESS on success, otherwise MAPI error
1445
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenEmbeddedMessage(TALLOC_CTX *mem_ctx,
1446
struct emsmdbp_context *emsmdbp_ctx,
1447
struct EcDoRpc_MAPI_REQ *mapi_req,
1448
struct EcDoRpc_MAPI_REPL *mapi_repl,
1449
uint32_t *handles, uint16_t *size)
1451
enum mapistore_error ret;
1452
enum MAPISTATUS retval;
1456
struct mapi_handles *attachment_rec = NULL;
1457
struct mapi_handles *message_rec = NULL;
1458
struct mapistore_message *msg;
1459
void *backend_attachment_message;
1460
struct emsmdbp_object *attachment_object = NULL;
1461
struct emsmdbp_object *message_object = NULL;
1463
struct oxcmsg_prop_index prop_index;
1466
DEBUG(4, ("exchange_emsmdb: [OXCMSG] OpenEmbeddedMessage (0x46)\n"));
1469
OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
1470
OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
1471
OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
1472
OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
1473
OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
1475
mapi_repl->opnum = mapi_req->opnum;
1476
mapi_repl->error_code = MAPI_E_SUCCESS;
1477
mapi_repl->handle_idx = mapi_req->u.mapi_OpenEmbeddedMessage.handle_idx;
1479
handle = handles[mapi_req->handle_idx];
1480
retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &attachment_rec);
1482
DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
1483
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
1487
retval = mapi_handles_get_private_data(attachment_rec, (void *) &attachment_object);
1488
if (!attachment_object || attachment_object->type != EMSMDBP_OBJECT_ATTACHMENT) {
1489
DEBUG(5, (" no object or object is not an attachment\n"));
1490
mapi_repl->error_code = MAPI_E_NO_SUPPORT;
1494
memset(&mapi_repl->u.mapi_OpenEmbeddedMessage, 0, sizeof(struct OpenEmbeddedMessage_repl));
1496
mapistore = emsmdbp_is_mapistore(attachment_object);
1497
switch (mapistore) {
1499
DEBUG(0, ("Not implemented - shouldn't occur\n"));
1502
if (mapi_req->u.mapi_OpenEmbeddedMessage.OpenModeFlags == MAPI_CREATE) {
1503
retval = openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, &messageID);
1505
mapi_repl->error_code = MAPI_E_NO_SUPPORT;
1510
contextID = emsmdbp_get_contextID(attachment_object);
1511
ret = mapistore_message_attachment_open_embedded_message(emsmdbp_ctx->mstore_ctx, contextID, attachment_object->backend_object,
1512
NULL, &backend_attachment_message,
1515
if (ret != MAPISTORE_SUCCESS) {
1516
mapi_repl->error_code = MAPI_E_NOT_FOUND;
1520
mapi_repl->u.mapi_OpenEmbeddedMessage.MessageId = messageID;
1522
if (msg->subject_prefix && strlen(msg->subject_prefix) > 0) {
1523
mapi_repl->u.mapi_OpenEmbeddedMessage.SubjectPrefix.StringType = StringType_UNICODE;
1524
mapi_repl->u.mapi_OpenEmbeddedMessage.SubjectPrefix.String.lpszW = talloc_strdup(mem_ctx, msg->subject_prefix);
1527
mapi_repl->u.mapi_OpenEmbeddedMessage.SubjectPrefix.StringType = StringType_EMPTY;
1529
if (msg->normalized_subject && strlen(msg->normalized_subject) > 0) {
1530
mapi_repl->u.mapi_OpenEmbeddedMessage.NormalizedSubject.StringType = StringType_UNICODE;
1531
mapi_repl->u.mapi_OpenEmbeddedMessage.NormalizedSubject.String.lpszW = talloc_strdup(mem_ctx, msg->normalized_subject);
1534
mapi_repl->u.mapi_OpenEmbeddedMessage.NormalizedSubject.StringType = StringType_EMPTY;
1537
mapi_repl->u.mapi_OpenEmbeddedMessage.RecipientColumns.cValues = msg->columns->cValues;
1538
mapi_repl->u.mapi_OpenEmbeddedMessage.RecipientColumns.aulPropTag = msg->columns->aulPropTag;
1541
mapi_repl->u.mapi_OpenEmbeddedMessage.RecipientColumns.cValues = 0;
1544
mapi_repl->u.mapi_OpenEmbeddedMessage.RecipientCount = msg->recipients_count;
1545
mapi_repl->u.mapi_OpenEmbeddedMessage.RowCount = msg->recipients_count;
1546
if (msg->recipients_count > 0) {
1547
mapi_repl->u.mapi_OpenEmbeddedMessage.RecipientRows = talloc_array(mem_ctx,
1548
struct OpenRecipientRow,
1549
msg->recipients_count + 1);
1550
oxcmsg_fill_prop_index(&prop_index, msg->columns);
1551
for (i = 0; i < msg->recipients_count; i++) {
1552
oxcmsg_fill_OpenRecipientRow(mem_ctx, emsmdbp_ctx, &(mapi_repl->u.mapi_OpenEmbeddedMessage.RecipientRows[i]), msg->columns, msg->recipients + i, &prop_index);
1556
/* Initialize Message object */
1557
handle = handles[mapi_req->handle_idx];
1558
retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &message_rec);
1559
handles[mapi_repl->handle_idx] = message_rec->handle;
1561
message_object = emsmdbp_object_message_init((TALLOC_CTX *)message_rec, emsmdbp_ctx, messageID, attachment_object);
1562
message_object->backend_object = backend_attachment_message;
1563
talloc_reference(message_object, backend_attachment_message);
1564
talloc_free(backend_attachment_message);
1566
retval = mapi_handles_set_private_data(message_rec, message_object);
1572
*size += libmapiserver_RopOpenEmbeddedMessage_size(mapi_repl);
721
1574
return MAPI_E_SUCCESS;