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

« back to all changes in this revision

Viewing changes to mapiproxy/servers/default/emsmdb/oxcmsg.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:
3
3
 
4
4
   EMSMDBP: EMSMDB Provider implementation
5
5
 
6
 
   Copyright (C) Julien Kerihuel 2009-2011
 
6
   Copyright (C) Julien Kerihuel 2009
7
7
 
8
8
   This program is free software; you can redistribute it and/or modify
9
9
   it under the terms of the GNU General Public License as published by
32
32
#include "mapiproxy/libmapiserver/libmapiserver.h"
33
33
#include "dcesrv_exchange_emsmdb.h"
34
34
 
 
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 */
 
38
};
 
39
 
 
40
static inline void oxcmsg_fill_prop_index(struct oxcmsg_prop_index *prop_index, struct SPropTagArray *properties)
 
41
{
 
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;;
 
46
        }
 
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;;
 
50
        }
 
51
}
 
52
 
 
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)
 
54
{
 
55
        struct ldb_result       *res = NULL;
 
56
        const char * const      recipient_attrs[] = { "*", NULL };
 
57
        int                     ret;
 
58
        char                    *full_name, *email_address, *simple_name, *legacyExchangeDN;
 
59
 
 
60
        if (!recipient->username) {
 
61
                goto smtp_recipient;
 
62
        }
 
63
 
 
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)))",
 
68
                         recipient->username);
 
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));
 
72
                goto smtp_recipient;
 
73
        }
 
74
        full_name = (char *) ldb_msg_find_attr_as_string(res->msgs[0], "displayName", NULL);
 
75
        if (!full_name) {
 
76
                DEBUG(0, ("record found but displayName is missing for %s\n", recipient->username));
 
77
                goto smtp_recipient;
 
78
        }
 
79
        simple_name = (char *) ldb_msg_find_attr_as_string(res->msgs[0], "mailNickname", NULL);
 
80
        if (!simple_name) {
 
81
                DEBUG(0, ("record found but mailNickname is missing for %s\n", recipient->username));
 
82
                goto smtp_recipient;
 
83
        }
 
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));
 
87
                goto smtp_recipient;
 
88
        }
 
89
 
 
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);
 
96
 
 
97
        return;
 
98
 
 
99
smtp_recipient:
 
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];
 
104
                if (full_name) {
 
105
                        row->RecipientFlags |= 0x10;
 
106
                        row->DisplayName.lpszW = talloc_strdup(mem_ctx, full_name);
 
107
 
 
108
                        row->RecipientFlags |= 0x0400;
 
109
                        row->SimpleDisplayName.lpszW = row->DisplayName.lpszW;
 
110
                }
 
111
        }
 
112
        if (prop_index->email_address != (uint32_t) -1) {
 
113
                email_address = recipient->data[prop_index->email_address];
 
114
                if (email_address) {
 
115
                        row->RecipientFlags |= 0x08;
 
116
                        row->EmailAddress.lpszW = talloc_strdup(mem_ctx, email_address);
 
117
                }
 
118
        }
 
119
}
 
120
 
 
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)
 
122
{
 
123
        uint32_t        i, retval;
 
124
        void            *data;
 
125
        enum MAPITAGS   property;
 
126
 
 
127
        row->prop_count = properties->cValues;
 
128
        row->prop_values.length = 0;
 
129
        row->layout = 0;
 
130
        for (i = 0; i < properties->cValues; i++) {
 
131
                if (recipient->data[i] == NULL) {
 
132
                        row->layout = 1;
 
133
                        break;
 
134
                }
 
135
        }
 
136
 
 
137
        for (i = 0; i < properties->cValues; i++) {
 
138
                property = properties->aulPropTag[i];
 
139
                data = recipient->data[i];
 
140
                if (data == NULL) {
 
141
                        retval = MAPI_E_NOT_FOUND;
 
142
                        property = (property & 0xffff0000) + PT_ERROR;
 
143
                        data = (void *)&retval;
 
144
                }
 
145
                libmapiserver_push_property(mem_ctx,
 
146
                                            property, (const void *)data, &row->prop_values, 
 
147
                                            row->layout, 0, 0);
 
148
        }
 
149
}
 
150
 
 
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)
 
152
{
 
153
        row->CodePageId = CP_USASCII;
 
154
        row->Reserved = 0;
 
155
        row->RecipientType = recipient->type;
 
156
 
 
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);
 
159
}
35
160
 
36
161
/**
37
162
   \details EcDoRpc OpenMessage (0x03) Rop. This operation opens an
54
179
                                                struct EcDoRpc_MAPI_REPL *mapi_repl,
55
180
                                                uint32_t *handles, uint16_t *size)
56
181
{
57
 
        enum MAPISTORE_ERROR            retval;
58
 
        enum MAPISTATUS                 ret;
59
 
        struct mapi_handles             *parent = NULL;
60
 
        struct mapi_handles             *parent_handle = NULL;
61
 
        struct mapi_handles             *rec = NULL;
 
182
        struct OpenMessage_req          *request;
 
183
        struct OpenMessage_repl         *response;
 
184
        enum mapistore_error            ret;
 
185
        enum MAPISTATUS                 retval;
 
186
        uint32_t                        parent_handle_id;
 
187
        struct mapi_handles             *object_handle = NULL;
 
188
        struct mapi_handles             *context_object_handle = NULL;
62
189
        struct emsmdbp_object           *object = NULL;
63
 
        struct emsmdbp_object           *parent_object = NULL;
64
 
        struct mapistore_message        msg;
 
190
        struct emsmdbp_object           *context_object = NULL;
 
191
        struct mapistore_message        *msg;
65
192
        void                            *data;
66
193
        uint64_t                        folderID;
67
194
        uint64_t                        messageID = 0;
68
 
        uint32_t                        contextID;
69
 
        uint32_t                        handle;
70
 
        bool                            mapistore = false;
71
 
        struct indexing_folders_list    *flist;
72
 
        struct SPropTagArray            *SPropTagArray;
73
 
        char                            *subject = NULL;
74
 
        uint32_t                        i;
75
 
 
 
195
        struct oxcmsg_prop_index        prop_index;
 
196
        int                             i;
76
197
 
77
198
        DEBUG(4, ("exchange_emsmdb: [OXCMSG] OpenMessage (0x03)\n"));
78
199
 
83
204
        OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
84
205
        OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
85
206
 
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;
89
209
 
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;
 
213
 
 
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);
 
217
 
 
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;
 
225
        }
95
226
 
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;
99
 
        if (!object) {
100
 
                mapi_repl->error_code = MAPI_E_NO_SUPPORT;
101
 
                *size += libmapiserver_RopOpenMessage_size(NULL);
102
 
                return MAPI_E_SUCCESS;
103
 
        }
104
 
 
105
 
        switch (object->type) {
106
 
        case EMSMDBP_OBJECT_MAILBOX:
107
 
                retval = mapistore_indexing_get_folder_list(emsmdbp_ctx->mstore_ctx, emsmdbp_ctx->username,
108
 
                                                            messageID, &flist);
109
 
                if (retval || !flist->count) {
110
 
                        DEBUG(0, ("No parent folder found for 0x%.16"PRIx64"\n", messageID));
111
 
                }
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));
117
 
                }
118
 
 
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, 
122
 
                                                                                flist->folderID[i]);
123
 
                        if (parent_handle) {
124
 
                                break; 
125
 
                        }
126
 
                        
127
 
                }
128
 
 
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 */
132
 
                if (parent_handle) {
133
 
                recursive_open:
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,
140
 
                                                           flist->folderID[i]);
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);
144
 
                                if (object) {
145
 
                                        ret = mapi_handles_set_private_data(rec, object);
146
 
                                }
147
 
 
148
 
                                parent_handle = rec;
149
 
                                
150
 
                        }
151
 
                } else {
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);
155
 
                        if (object) {
156
 
                                ret = mapi_handles_set_private_data(rec, object);
157
 
                        }
158
 
                        parent_handle = rec;
159
 
                        i = 0;
160
 
                        /* now we have a context_id, we can use code above to open subfolders subsequently */
161
 
                        goto recursive_open;
162
 
                }
163
 
 
164
 
                /* Add this stage our new parent_handle should point to the message */
165
 
 
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;
171
 
                break;
172
 
        case EMSMDBP_OBJECT_FOLDER:
173
 
                folderID = object->object.folder->folderID;
174
 
                contextID = object->object.folder->contextID;
175
 
                break;
176
 
        default:
177
 
                mapi_repl->error_code = MAPI_E_NO_SUPPORT;
178
 
                *size += libmapiserver_RopGetHierarchyTable_size(NULL);
179
 
                return MAPI_E_SUCCESS;
180
 
        }
181
 
 
182
 
        mapistore = emsmdbp_is_mapistore(parent);
183
 
        switch (mapistore) {
184
 
        case false:
185
 
                /* system/special folder */
186
 
                DEBUG(0, ("Not implemented yet - shouldn't occur\n"));
187
 
                break;
188
 
        case true:
189
 
                /* mapistore implementation goes here */
190
 
                mapistore_openmessage(emsmdbp_ctx->mstore_ctx, contextID, folderID, messageID, &msg);
191
 
 
192
 
                /* Build the OpenMessage reply */
193
 
                subject = (char *) find_SPropValue_data(msg.properties, PR_SUBJECT);
194
 
 
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;
200
 
 
201
 
                SPropTagArray = set_SPropTagArray(mem_ctx, 0x4,
202
 
                                                  PR_DISPLAY_TYPE,
203
 
                                                  PR_OBJECT_TYPE,
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));
220
 
                }
221
 
 
222
 
                break;
223
 
        }
 
228
        if (!(context_object->type == EMSMDBP_OBJECT_MAILBOX || context_object->type == EMSMDBP_OBJECT_FOLDER)) {
 
229
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
230
                goto end;
 
231
        }
 
232
 
 
233
        messageID = request->MessageId;
 
234
        folderID = request->FolderId;
224
235
 
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;
229
 
 
230
 
        if (messageID) {
231
 
                object = emsmdbp_object_message_init((TALLOC_CTX *)rec, emsmdbp_ctx, messageID, parent_handle);
232
 
                if (object) {
233
 
                        ret = mapi_handles_set_private_data(rec, object);
234
 
                }
235
 
        }
236
 
 
 
237
        retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, 0, &object_handle);
 
238
 
 
239
        if (request->OpenModeFlags == ReadOnly) {
 
240
                ret = emsmdbp_object_message_open(object_handle, emsmdbp_ctx, context_object, folderID, messageID, false, &object, &msg);
 
241
        }
 
242
        else if (request->OpenModeFlags == OpenSoftDelete) {
 
243
                ret = MAPISTORE_ERROR;
 
244
        }
 
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);
 
249
                }
 
250
        }
 
251
 
 
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;
 
256
                }
 
257
                else if (ret == MAPISTORE_ERR_NOT_FOUND) {
 
258
                        mapi_repl->error_code = MAPI_E_NOT_FOUND;
 
259
                }
 
260
                else {
 
261
                        mapi_repl->error_code = MAPI_E_CALL_FAILED;
 
262
                }
 
263
                goto end;
 
264
        }
 
265
 
 
266
        handles[mapi_repl->handle_idx] = object_handle->handle;
 
267
        retval = mapi_handles_set_private_data(object_handle, object);
 
268
 
 
269
        /* Build the OpenMessage reply */
 
270
        response->HasNamedProperties = true;
 
271
 
 
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);
 
275
        }
 
276
        else {
 
277
                response->SubjectPrefix.StringType = StringType_EMPTY;
 
278
        }
 
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);
 
282
        }
 
283
        else {
 
284
                response->NormalizedSubject.StringType = StringType_EMPTY;
 
285
        }
 
286
        if (msg->columns) {
 
287
                response->RecipientColumns.cValues = msg->columns->cValues;
 
288
                response->RecipientColumns.aulPropTag = msg->columns->aulPropTag;
 
289
        }
 
290
        else {
 
291
                response->RecipientColumns.cValues = 0;
 
292
        }
 
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);
 
302
                }
 
303
        }
 
304
        else {
 
305
                response->RecipientCount = 0;
 
306
        }
 
307
        response->RowCount = response->RecipientCount;
 
308
 
 
309
end:
237
310
        *size += libmapiserver_RopOpenMessage_size(mapi_repl);
238
311
 
239
312
        return MAPI_E_SUCCESS;
262
335
                                                  uint32_t *handles, uint16_t *size)
263
336
{
264
337
        enum MAPISTATUS                 retval;
265
 
        struct mapi_handles             *rec = NULL;
266
 
        struct mapi_handles             *parent = NULL;
267
 
        struct mapi_handles             *parent_handle = NULL;
268
 
        struct emsmdbp_object           *object = NULL;
 
338
        enum mapistore_error            ret;
 
339
        struct mapi_handles             *context_handle = NULL;
 
340
        struct mapi_handles             *message_handle = NULL;
 
341
        struct emsmdbp_object           *context_object = NULL;
 
342
        struct emsmdbp_object           *folder_object = NULL;
 
343
        struct emsmdbp_object           *message_object = NULL;
269
344
        uint32_t                        handle;
270
 
        uint64_t                        folderID;
271
 
        uint64_t                        messageID;
 
345
        uint64_t                        folderID, messageID;
272
346
        uint32_t                        contextID;
273
347
        bool                            mapistore = false;
274
348
        void                            *data;
275
349
        struct SRow                     aRow;
276
350
        uint32_t                        pt_long;
277
351
        bool                            pt_boolean;
 
352
        struct SBinary_short            *pt_binary;
278
353
        struct timeval                  tv;
279
354
        struct FILETIME                 ft;
280
355
        NTTIME                          time;
288
363
        OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
289
364
        OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
290
365
 
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);
294
 
 
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;
299
370
 
 
371
        handle = handles[mapi_req->handle_idx];
 
372
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &context_handle);
 
373
        if (retval) {
 
374
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
375
                DEBUG(5, ("  handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
376
                goto end;
 
377
        }
 
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);
 
380
        if (retval) {
 
381
                mapi_repl->error_code = retval;
 
382
                DEBUG(5, ("  handle data not found, idx = %x\n", mapi_req->handle_idx));
 
383
                goto end;
 
384
        }
 
385
        context_object = data;
 
386
 
300
387
        folderID = mapi_req->u.mapi_CreateMessage.FolderId;
301
388
 
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;
305
 
        if (!object) {
306
 
                mapi_repl->error_code = MAPI_E_NO_SUPPORT;
307
 
                goto end;
308
 
        }
309
 
 
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;
314
 
                goto end;
315
 
        }
316
 
        contextID = emsmdbp_get_contextID(parent_handle);
317
 
        mapistore = emsmdbp_is_mapistore(parent_handle);
318
 
 
319
 
        switch (mapistore) {
320
 
        case false:
321
 
                /* system/special folder */
322
 
                DEBUG(0, ("Not implemented yet - shouldn't occur\n"));
323
 
                break;
324
 
        case true:
325
 
                /* This should be handled differently here: temporary hack */
326
 
                retval = openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, &messageID);
327
 
                if (retval) {
 
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;
 
394
                }
 
395
                else {
328
396
                        mapi_repl->error_code = MAPI_E_NO_SUPPORT;
329
 
                        goto end;
330
397
                }
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); */
334
 
 
335
 
                /* Set default properties for message: MS-OXCMSG 3.2.5.2 */
336
 
                aRow.lpProps = talloc_array(mem_ctx, struct SPropValue, 2);
337
 
                aRow.cValues = 0;
338
 
 
339
 
                pt_long = 0x1;
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");
342
 
                pt_long = 0x0;
343
 
                aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_SENSITIVITY, (const void *)&pt_long);
344
 
                pt_long = 0x9;
345
 
                aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_MESSAGE_FLAGS, (const void *)&pt_long);
346
 
                pt_boolean = false;
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);
349
 
                pt_long = 0x1;
350
 
                aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_TRUST_SENDER, (const void *)&pt_long);
351
 
                pt_long = 0x3;
352
 
                aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_ACCESS, (const void *)&pt_long);
353
 
                pt_long = 0x1;
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");
356
 
 
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);
366
 
 
367
 
                mapistore_setprops(emsmdbp_ctx->mstore_ctx, contextID, messageID, MAPISTORE_MESSAGE, &aRow);
368
 
                break;
369
 
        }
370
 
 
371
 
        DEBUG(0, ("CreateMessage: 0x%.16"PRIx64": mapistore = %s\n", folderID, 
372
 
                  emsmdbp_is_mapistore(parent_handle) == true ? "true" : "false"));
 
398
                goto end;
 
399
        }
 
400
 
 
401
        /* This should be handled differently here: temporary hack */
 
402
        retval = openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, &messageID);
 
403
        if (retval) {
 
404
                mapi_repl->error_code = MAPI_E_NO_SUPPORT;
 
405
                goto end;
 
406
        }
 
407
        mapi_repl->u.mapi_CreateMessage.HasMessageId = 1;
 
408
        mapi_repl->u.mapi_CreateMessage.MessageId.MessageId = messageID;
373
409
 
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;
378
 
 
379
 
        if (messageID) {
380
 
                object = emsmdbp_object_message_init((TALLOC_CTX *)rec, emsmdbp_ctx, messageID, parent_handle);
381
 
                if (object) {
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);
 
413
 
 
414
        message_object = emsmdbp_object_message_init((TALLOC_CTX *)message_handle, emsmdbp_ctx, messageID, folder_object);
 
415
        message_object->object.message->read_write = true;
 
416
 
 
417
        contextID = emsmdbp_get_contextID(folder_object);
 
418
        mapistore = emsmdbp_is_mapistore(folder_object);
 
419
        switch (mapistore) {
 
420
        case true:
 
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;
 
428
                        }
 
429
                        else if (ret == MAPISTORE_ERR_NOT_FOUND) {
 
430
                                mapi_repl->error_code = MAPI_E_NOT_FOUND;
 
431
                        }
 
432
                        else {
 
433
                                mapi_repl->error_code = MAPI_E_CALL_FAILED;
 
434
                        }
 
435
                        goto end;
384
436
                }
 
437
                break;
 
438
        case false:
 
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));
 
443
                break;
385
444
        }
386
445
 
 
446
        handles[mapi_repl->handle_idx] = message_handle->handle;
 
447
 
 
448
        /* Add default properties to message MS-OXCMSG 3.2.5.2 */
 
449
        retval = mapi_handles_set_private_data(message_handle, message_object);
 
450
 
 
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);
 
454
        aRow.cValues = 0;
 
455
 
 
456
        pt_long = 0x1;
 
457
        set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_IMPORTANCE, (const void *)&pt_long);
 
458
        aRow.cValues++;
 
459
        set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_MESSAGE_CLASS_UNICODE, (const void *)"IPM.Note");
 
460
        aRow.cValues++;
 
461
        pt_long = 0x0;
 
462
        set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_SENSITIVITY, (const void *)&pt_long);
 
463
        aRow.cValues++;
 
464
        set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_DISPLAY_TO_UNICODE, (const void *)"");
 
465
        aRow.cValues++;
 
466
        set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_DISPLAY_CC_UNICODE, (const void *)"");
 
467
        aRow.cValues++;
 
468
        set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_DISPLAY_BCC_UNICODE, (const void *)"");
 
469
        aRow.cValues++;
 
470
        pt_long = 0x9;
 
471
        set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_MESSAGE_FLAGS, (const void *)&pt_long);
 
472
        aRow.cValues++;
 
473
 
 
474
        pt_boolean = false;
 
475
        set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_HASATTACH, (const void *)&pt_boolean);
 
476
        aRow.cValues++;
 
477
        set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_HAS_NAMED_PROPERTIES, (const void *)&pt_boolean);
 
478
        aRow.cValues++;
 
479
        set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_URL_COMP_NAME_SET, (const void *)&pt_boolean);
 
480
        aRow.cValues++;
 
481
 
 
482
        pt_long = 0x1;
 
483
        set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_TRUST_SENDER, (const void *)&pt_long);
 
484
        aRow.cValues++;
 
485
        pt_long = 0x3;
 
486
        set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_ACCESS, (const void *)&pt_long);
 
487
        aRow.cValues++;
 
488
        pt_long = 0x1;
 
489
        set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_ACCESS_LEVEL, (const void *)&pt_long);
 
490
        aRow.cValues++;
 
491
        set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_URL_COMP_NAME_UNICODE, (const void *)"No Subject.EML");
 
492
        aRow.cValues++;
 
493
 
 
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);
 
499
        aRow.cValues++;
 
500
        set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_LAST_MODIFICATION_TIME, (const void *)&ft);
 
501
        aRow.cValues++;
 
502
        set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_LOCAL_COMMIT_TIME, (const void *)&ft);
 
503
        aRow.cValues++;
 
504
 
 
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);
 
508
        aRow.cValues++;
 
509
        set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_LOCALE_ID, (const void *)&pt_long);
 
510
        aRow.cValues++;
 
511
 
 
512
        set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_CREATOR_NAME_UNICODE, (const void *)emsmdbp_ctx->szDisplayName);
 
513
        aRow.cValues++;
 
514
        set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_LAST_MODIFIER_NAME_UNICODE, (const void *)emsmdbp_ctx->szDisplayName);
 
515
        aRow.cValues++;
 
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);
 
519
        aRow.cValues++;
 
520
        set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_LAST_MODIFIER_ENTRYID, (const void *)pt_binary);
 
521
        aRow.cValues++;
 
522
 
 
523
        /* TODO: some required properties are not set: PidTagSearchKey, PidTagMessageSize, PidTagSecurityDescriptor */
 
524
        emsmdbp_object_set_properties(emsmdbp_ctx, message_object, &aRow);
 
525
 
 
526
        DEBUG(0, ("CreateMessage: 0x%.16"PRIx64": mapistore = %s\n", folderID, mapistore ? "true" : "false"));
 
527
 
387
528
end:
 
529
 
388
530
        *size += libmapiserver_RopCreateMessage_size(mapi_repl);
389
531
 
390
532
        return MAPI_E_SUCCESS;
421
563
        struct emsmdbp_object   *object;
422
564
        uint64_t                messageID;
423
565
        uint32_t                contextID;
 
566
        char                    *owner;
424
567
        uint8_t                 flags;
 
568
        enum mapistore_error    ret;
425
569
 
426
570
        DEBUG(4, ("exchange_emsmdb: [OXCMSG] SaveChangesMessage (0x0c)\n"));
427
571
 
450
594
                goto end;
451
595
        }
452
596
 
453
 
        mapistore = emsmdbp_is_mapistore(rec);
 
597
        flags = mapi_req->u.mapi_SaveChangesMessage.SaveFlags;
 
598
 
 
599
        mapistore = emsmdbp_is_mapistore(object);
454
600
        switch (mapistore) {
455
601
        case false:
456
 
                DEBUG(0, ("Not implement yet - shouldn't occur\n"));
 
602
                retval = openchangedb_message_save(object->backend_object, flags);
 
603
                DEBUG(0, ("[%s:%d]: openchangedb_save_message: retval = 0x%x\n", __FUNCTION__, __LINE__, retval));
457
604
                break;
458
605
        case true:
 
606
                contextID = emsmdbp_get_contextID(object);
459
607
                messageID = object->object.message->messageID;
460
 
                contextID = object->object.message->contextID;
461
 
                flags = mapi_req->u.mapi_SaveChangesMessage.SaveFlags;
462
 
                /* mapistore_savechangesmessage(emsmdbp_ctx->mstore_ctx, contextID, messageID, flags); */
463
 
                mapistore_indexing_record_add_mid(emsmdbp_ctx->mstore_ctx, contextID, messageID);
 
608
                ret = mapistore_message_save(emsmdbp_ctx->mstore_ctx, contextID, object->backend_object);
 
609
                if (ret == MAPISTORE_ERR_DENIED) {
 
610
                        mapi_repl->error_code = MAPI_E_NO_ACCESS;
 
611
                        goto end;
 
612
                }
 
613
                owner = emsmdbp_get_owner(object);
 
614
                mapistore_indexing_record_add_mid(emsmdbp_ctx->mstore_ctx, contextID, owner, messageID);
464
615
                break;
465
616
        }
466
617
 
474
625
}
475
626
 
476
627
/**
 
628
   \details EcDoRpc RemoveAllRecipients (0x0d) Rop. This operation removes all
 
629
   recipients from a message.
 
630
 
 
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
 
634
   structure
 
635
   \param mapi_repl pointer to the RemoveAllRecipients EcDoRpc_MAPI_REPL
 
636
   structure
 
637
   \param handles pointer to the MAPI handles array
 
638
   \param size pointer to the mapi_response size to update
 
639
 
 
640
   \return MAPI_E_SUCCESS on success, otherwise MAPI error
 
641
 */
 
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)
 
647
{
 
648
        struct mapi_handles     *rec = NULL;
 
649
        struct emsmdbp_object   *object;
 
650
        enum MAPISTATUS         retval;
 
651
        uint32_t                handle;
 
652
        void                    *private_data;
 
653
        bool                    mapistore = false;
 
654
        uint32_t                contextID;
 
655
        struct SPropTagArray    columns;
 
656
 
 
657
        DEBUG(4, ("exchange_emsmdb: [OXCMSG] RemoveAllRecipients (0x0d)\n"));
 
658
 
 
659
        /* Sanity checks */
 
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);
 
665
 
 
666
        mapi_repl->opnum = mapi_req->opnum;
 
667
        mapi_repl->error_code = MAPI_E_SUCCESS;
 
668
 
 
669
        handle = handles[mapi_req->handle_idx];
 
670
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
 
671
        if (retval) {
 
672
                mapi_repl->error_code = MAPI_E_NOT_FOUND;
 
673
                goto end;
 
674
        }
 
675
 
 
676
        mapi_repl->handle_idx = mapi_req->handle_idx;
 
677
 
 
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;
 
682
                goto end;
 
683
        }
 
684
 
 
685
        mapistore = emsmdbp_is_mapistore(object);
 
686
        if (mapistore) {
 
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);
 
690
        }
 
691
        else {
 
692
                DEBUG(0, ("Not implement yet - shouldn't occur\n"));
 
693
        }
 
694
 
 
695
end:
 
696
        *size += libmapiserver_RopRemoveAllRecipients_size(mapi_repl);
 
697
 
 
698
        return MAPI_E_SUCCESS;
 
699
}
 
700
 
 
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)
 
702
{
 
703
        int                     i, data_pos;
 
704
        uint8_t                 *src_value;
 
705
        void                    *dest_value;
 
706
        char                    *uni_value;
 
707
        struct Binary_r         *bin_value;
 
708
        struct FILETIME         *ft_value;
 
709
        size_t                  value_size;
 
710
        const uint16_t          *unicode_char;
 
711
        size_t                  dest_size, dest_len;
 
712
 
 
713
        recipient->type = recipient_row->RecipClass;
 
714
 
 
715
        if ((recipient_row->RecipientRow.RecipientFlags & 0x07) == 1) {
 
716
                recipient->username = (char *) recipient_row->RecipientRow.X500DN.recipient_x500name;
 
717
        }
 
718
        else {
 
719
                recipient->username = NULL;
 
720
        }
 
721
 
 
722
        recipient->data = talloc_array(mem_ctx, void *, prop_count + 2);
 
723
 
 
724
        /* PR_DISPLAY_NAME_UNICODE */
 
725
        switch ((recipient_row->RecipientRow.RecipientFlags & 0x210)) {
 
726
        case 0x10:
 
727
                recipient->data[0] = (void *) recipient_row->RecipientRow.DisplayName.lpszA;
 
728
                break;
 
729
        case 0x210:
 
730
                recipient->data[0] = (void *) recipient_row->RecipientRow.DisplayName.lpszW;
 
731
                break;
 
732
        default:
 
733
                recipient->data[0] = NULL;
 
734
        }
 
735
 
 
736
        /* PR_EMAIL_ADDRESS_UNICODE */
 
737
        switch ((recipient_row->RecipientRow.RecipientFlags & 0x208)) {
 
738
        case 0x08:
 
739
                recipient->data[1] = (void *) recipient_row->RecipientRow.EmailAddress.lpszA;
 
740
                break;
 
741
        case 0x208:
 
742
                recipient->data[1] = (void *) recipient_row->RecipientRow.EmailAddress.lpszW;
 
743
                break;
 
744
        default:
 
745
                recipient->data[1] = NULL;
 
746
        }
 
747
      
 
748
        data_pos = 0;
 
749
        for (i = 0; i < prop_count; i++) {
 
750
                if (properties[i] & MV_FLAG) {
 
751
                        DEBUG(0, ("multivalue not supported yet\n"));
 
752
                        abort();
 
753
                }
 
754
 
 
755
                if (recipient_row->RecipientRow.layout) {
 
756
                        data_pos++;
 
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) {
 
760
                                        data_pos += 4;
 
761
                                }
 
762
                                continue;
 
763
                        }
 
764
                }
 
765
 
 
766
                dest_value = src_value = recipient_row->RecipientRow.prop_values.data + data_pos;
 
767
                switch (properties[i] & 0xffff) {
 
768
                case PT_BOOLEAN:
 
769
                        value_size = sizeof(uint8_t);
 
770
                        break;
 
771
                case PT_I2:
 
772
                        value_size = sizeof(uint16_t);
 
773
                        break;
 
774
                case PT_LONG:
 
775
                case PT_ERROR:
 
776
                        value_size = sizeof(uint32_t);
 
777
                        break;
 
778
                case PT_DOUBLE:
 
779
                        value_size = sizeof(double);
 
780
                        break;
 
781
                case PT_I8:
 
782
                        value_size = sizeof(uint64_t);
 
783
                        break;
 
784
                case PT_STRING8:
 
785
                        value_size = strlen(dest_value) + 1;
 
786
                        break;
 
787
                case PT_SYSTIME:
 
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;
 
793
                        break;
 
794
                case PT_UNICODE:
 
795
                        unicode_char = (const uint16_t *) src_value;
 
796
                        value_size = 0;
 
797
                        while (*unicode_char++)
 
798
                                value_size += 2;
 
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,
 
804
                                       &dest_len);
 
805
                        uni_value[dest_len] = 0;
 
806
                        dest_value = uni_value;
 
807
                        value_size += 2;
 
808
                        break;
 
809
                case PT_BINARY:
 
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;
 
815
                        break;
 
816
                }
 
817
                recipient->data[i+2] = dest_value;
 
818
                data_pos += value_size;
 
819
        }
 
820
}
 
821
 
 
822
/**
477
823
   \details EcDoRpc ModifyRecipients (0x0e) Rop. This operation modifies an
478
824
   existing message to add recipients (TO, CC, BCC).
479
825
 
494
840
                                                     struct EcDoRpc_MAPI_REPL *mapi_repl,
495
841
                                                     uint32_t *handles, uint16_t *size)
496
842
{
 
843
        struct mapi_handles                     *rec = NULL;
 
844
        struct emsmdbp_object                   *object;
 
845
        enum MAPISTATUS                         retval;
 
846
        uint32_t                                handle;
 
847
        void                                    *private_data;
 
848
        bool                                    mapistore = false;
 
849
        uint32_t                                contextID;
 
850
        struct mapistore_message_recipient      *recipients;
 
851
        struct SPropTagArray                    *columns;
 
852
        int                                     i;
 
853
 
497
854
        DEBUG(4, ("exchange_emsmdb: [OXCMSG] ModifyRecipients (0x0e)\n"));
498
855
 
499
856
        /* Sanity checks */
506
863
        mapi_repl->opnum = mapi_req->opnum;
507
864
        mapi_repl->error_code = MAPI_E_SUCCESS;
508
865
 
509
 
        /* TODO: actually implement this */
510
 
 
 
866
        handle = handles[mapi_req->handle_idx];
 
867
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
 
868
        if (retval) {
 
869
                mapi_repl->error_code = MAPI_E_NOT_FOUND;
 
870
                goto end;
 
871
        }
 
872
 
 
873
        mapi_repl->handle_idx = mapi_req->handle_idx;
 
874
 
 
875
        retval = mapi_handles_get_private_data(rec, &private_data);
 
876
        object = (struct emsmdbp_object *)private_data;
 
877
        if (!object || object->type != EMSMDBP_OBJECT_MESSAGE) {
 
878
                mapi_repl->error_code = MAPI_E_NO_SUPPORT;
 
879
                goto end;
 
880
        }
 
881
 
 
882
        mapistore = emsmdbp_is_mapistore(object);
 
883
        if (mapistore) {
 
884
                /* Convention: we somewhat flatten the row and provide PR_DISPLAY_NAME_UNICODE and PR_EMAIL_ADDRESS_UNICODE to the backend */
 
885
                contextID = emsmdbp_get_contextID(object);
 
886
                columns = talloc_zero(mem_ctx, struct SPropTagArray);
 
887
                columns->cValues = mapi_req->u.mapi_ModifyRecipients.prop_count + 2;
 
888
                columns->aulPropTag = talloc_array(columns, enum MAPITAGS, columns->cValues);
 
889
                columns->aulPropTag[0] = PR_DISPLAY_NAME_UNICODE;
 
890
                columns->aulPropTag[1] = PR_EMAIL_ADDRESS_UNICODE;
 
891
                memcpy(columns->aulPropTag + 2, mapi_req->u.mapi_ModifyRecipients.properties, mapi_req->u.mapi_ModifyRecipients.prop_count * sizeof(enum MAPITAGS));
 
892
 
 
893
                recipients = talloc_array(mem_ctx, struct mapistore_message_recipient, mapi_req->u.mapi_ModifyRecipients.cValues);
 
894
                for (i = 0; i < mapi_req->u.mapi_ModifyRecipients.cValues; i++) {
 
895
                        oxcmsg_parse_ModifyRecipientRow(recipients, mapi_req->u.mapi_ModifyRecipients.RecipientRow + i, mapi_req->u.mapi_ModifyRecipients.prop_count, mapi_req->u.mapi_ModifyRecipients.properties, recipients + i);
 
896
                }
 
897
                mapistore_message_modify_recipients(emsmdbp_ctx->mstore_ctx, contextID, object->backend_object, columns, mapi_req->u.mapi_ModifyRecipients.cValues, recipients);
 
898
        }
 
899
        else {
 
900
                DEBUG(0, ("Not implement yet - shouldn't occur\n"));
 
901
        }
 
902
 
 
903
end:
511
904
        *size += libmapiserver_RopModifyRecipients_size(mapi_repl);
512
905
 
513
906
        return MAPI_E_SUCCESS;
540
933
        struct mapi_handles             *rec = NULL;
541
934
        void                            *private_data;
542
935
        bool                            mapistore = false;
543
 
        struct mapistore_message        msg;
 
936
        struct mapistore_message        *msg;
544
937
        struct emsmdbp_object           *object;
545
 
        uint64_t                        folderID;
546
 
        uint64_t                        messageID;
547
938
        uint32_t                        contextID;
548
 
        struct SPropTagArray            *SPropTagArray;
549
 
        char                            *subject = NULL;
550
 
        uint32_t                        i;
 
939
        struct oxcmsg_prop_index        prop_index;
 
940
        int                             i;
551
941
 
552
942
        DEBUG(4, ("exchange_emsmdb: [OXCMSG] ReloadCachedInformation (0x10)\n"));
553
943
 
576
966
                goto end;
577
967
        }
578
968
 
579
 
        mapistore = emsmdbp_is_mapistore(rec);
 
969
        mapistore = emsmdbp_is_mapistore(object);
580
970
        switch (mapistore) {
581
971
        case false:
582
972
                DEBUG(0, ("Not implemented yet - shouldn't occur\n"));
583
973
                break;
584
974
        case true:
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);
 
976
 
 
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;
 
979
                        goto end;
 
980
                }
589
981
 
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;
594
 
                if (subject) {
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);
597
 
                } else {
 
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);
 
986
                }
 
987
                else {
 
988
                        mapi_repl->u.mapi_ReloadCachedInformation.SubjectPrefix.StringType = StringType_EMPTY;
 
989
                }
 
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);
 
993
                }
 
994
                else {
598
995
                        mapi_repl->u.mapi_ReloadCachedInformation.NormalizedSubject.StringType = StringType_EMPTY;
599
996
                }
600
 
                mapi_repl->u.mapi_ReloadCachedInformation.RecipientCount = msg.recipients->cRows;
601
 
 
602
 
                SPropTagArray = set_SPropTagArray(mem_ctx, 0x4,
603
 
                                                  PR_DISPLAY_TYPE,
604
 
                                                  PR_OBJECT_TYPE,
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));
 
997
                if (msg->columns) {
 
998
                        mapi_repl->u.mapi_ReloadCachedInformation.RecipientColumns.cValues = msg->columns->cValues;
 
999
                        mapi_repl->u.mapi_ReloadCachedInformation.RecipientColumns.aulPropTag = msg->columns->aulPropTag;
 
1000
                }
 
1001
                else {
 
1002
                        mapi_repl->u.mapi_ReloadCachedInformation.RecipientColumns.cValues = 0;
 
1003
                }
 
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);
 
1013
                        }
621
1014
                }
622
1015
                break;
623
1016
        }
651
1044
                                                       struct EcDoRpc_MAPI_REPL *mapi_repl,
652
1045
                                                       uint32_t *handles, uint16_t *size)
653
1046
{
 
1047
        struct SetMessageReadFlag_req   *request;
 
1048
        /* struct SetMessageReadFlag_repl       *response; */
 
1049
        enum MAPISTATUS                 retval;
 
1050
        uint32_t                        handle;
 
1051
        struct mapi_handles             *rec = NULL;
 
1052
        struct emsmdbp_object           *message_object = NULL;
 
1053
        uint32_t                        contextID;
 
1054
        void                            *data;
 
1055
 
654
1056
        DEBUG(4, ("exchange_emsmdb: [OXCMSG] SetMessageReadFlag (0x11)\n"));
655
1057
 
656
1058
        /* Sanity checks */
660
1062
        OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
661
1063
        OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
662
1064
 
 
1065
        request = &mapi_req->u.mapi_SetMessageReadFlag;
 
1066
        /* response = &mapi_repl->u.mapi_SetMessageReadFlag; */
 
1067
 
663
1068
        mapi_repl->opnum = mapi_req->opnum;
664
1069
        mapi_repl->error_code = MAPI_E_SUCCESS;
665
1070
        mapi_repl->handle_idx = mapi_req->handle_idx;
666
1071
 
667
 
        /* TODO: actually implement this */
 
1072
        handle = handles[request->handle_idx];
 
1073
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
 
1074
        if (retval) {
 
1075
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
1076
                DEBUG(5, ("  handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
1077
                goto end;
 
1078
        }
 
1079
 
 
1080
        retval = mapi_handles_get_private_data(rec, &data);
 
1081
        if (retval) {
 
1082
                mapi_repl->error_code = retval;
 
1083
                DEBUG(5, ("  handle data not found, idx = %x\n", mapi_req->handle_idx));
 
1084
                goto end;
 
1085
        }
 
1086
 
 
1087
        message_object = (struct emsmdbp_object *) data;
 
1088
        if (!message_object || message_object->type != EMSMDBP_OBJECT_MESSAGE) {
 
1089
                DEBUG(5, ("  no object or object is not a message\n"));
 
1090
                mapi_repl->error_code = MAPI_E_NO_SUPPORT;
 
1091
                goto end;
 
1092
        }
 
1093
 
 
1094
        switch (emsmdbp_is_mapistore(message_object)) {
 
1095
        case false:
 
1096
                DEBUG(0, ("Not implemented yet\n"));
 
1097
                break;
 
1098
        case true:
 
1099
                contextID = emsmdbp_get_contextID(message_object);
 
1100
                mapistore_message_set_read_flag(emsmdbp_ctx->mstore_ctx, contextID, message_object->backend_object, request->flags);
 
1101
                break;
 
1102
        }
 
1103
 
 
1104
        /* TODO: public folders */
668
1105
        mapi_repl->u.mapi_SetMessageReadFlag.ReadStatusChanged = false;
669
1106
 
 
1107
end:
670
1108
        *size += libmapiserver_RopSetMessageReadFlag_size(mapi_repl);
671
1109
 
672
1110
        return MAPI_E_SUCCESS;
695
1133
                                                       uint32_t *handles, uint16_t *size)
696
1134
{
697
1135
        enum MAPISTATUS         retval;
698
 
        struct mapi_handles     *rec = NULL;
699
1136
        uint32_t                handle;
 
1137
        struct mapi_handles             *rec = NULL;
 
1138
        struct mapi_handles             *table_rec = NULL;
 
1139
        struct emsmdbp_object           *message_object = NULL;
 
1140
        struct emsmdbp_object           *table_object = NULL;
 
1141
        void                            *data;
700
1142
 
701
1143
        DEBUG(4, ("exchange_emsmdb: [OXCMSG] GetAttachmentTable (0x21)\n"));
702
1144
 
709
1151
 
710
1152
        mapi_repl->opnum = mapi_req->opnum;
711
1153
        mapi_repl->error_code = MAPI_E_SUCCESS;
712
 
 
713
 
        /* TODO: actually implement this */
714
 
 
 
1154
        mapi_repl->handle_idx = mapi_req->u.mapi_GetAttachmentTable.handle_idx;
 
1155
 
 
1156
        handle = handles[mapi_req->handle_idx];
 
1157
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
 
1158
        if (retval) {
 
1159
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
1160
                DEBUG(5, ("  handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
1161
                goto end;
 
1162
        }
 
1163
 
 
1164
        retval = mapi_handles_get_private_data(rec, &data);
 
1165
        if (retval) {
 
1166
                mapi_repl->error_code = retval;
 
1167
                DEBUG(5, ("  handle data not found, idx = %x\n", mapi_req->handle_idx));
 
1168
                goto end;
 
1169
        }
 
1170
 
 
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;
 
1175
                goto end;
 
1176
        }
 
1177
 
 
1178
        retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &table_rec);
 
1179
        handles[mapi_repl->handle_idx] = table_rec->handle;
 
1180
 
 
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;
 
1185
                goto end;
 
1186
        }
 
1187
        mapi_handles_set_private_data(table_rec, table_object);
 
1188
        
 
1189
 end:
715
1190
        *size += libmapiserver_RopGetAttachmentTable_size(mapi_repl);
716
1191
 
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;  
 
1193
}
 
1194
 
 
1195
/**
 
1196
   \details EcDoRpc OpenAttach (0x22) Rop. This operation open an attachment
 
1197
   from the message handle.
 
1198
 
 
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
 
1202
   structure
 
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
 
1207
 
 
1208
   \return MAPI_E_SUCCESS on success, otherwise MAPI error
 
1209
 */
 
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)
 
1215
{
 
1216
        enum MAPISTATUS         retval;
 
1217
        uint32_t                handle;
 
1218
        uint32_t                attachmentID;
 
1219
        uint32_t                contextID;
 
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;
 
1224
        void                            *data;
 
1225
 
 
1226
        DEBUG(4, ("exchange_emsmdb: [OXCMSG] OpenAttach (0x22)\n"));
 
1227
 
 
1228
        /* Sanity checks */
 
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);
 
1234
 
 
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;
 
1238
 
 
1239
        handle = handles[mapi_req->handle_idx];
 
1240
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
 
1241
        if (retval) {
 
1242
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
1243
                DEBUG(5, ("  handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
1244
                goto end;
 
1245
        }
 
1246
 
 
1247
        retval = mapi_handles_get_private_data(rec, &data);
 
1248
        if (retval) {
 
1249
                mapi_repl->error_code = retval;
 
1250
                DEBUG(5, ("  handle data not found, idx = %x\n", mapi_req->handle_idx));
 
1251
                goto end;
 
1252
        }
 
1253
 
 
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;
 
1258
                goto end;
 
1259
        }
 
1260
 
 
1261
        switch (emsmdbp_is_mapistore(message_object)) {
 
1262
        case false:
 
1263
                /* system/special folder */
 
1264
                DEBUG(0, ("Not implemented yet - shouldn't occur\n"));
 
1265
                break;
 
1266
        case true:
 
1267
                contextID = emsmdbp_get_contextID(message_object);
 
1268
                attachmentID = mapi_req->u.mapi_OpenAttach.AttachmentID;
 
1269
 
 
1270
                retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &attachment_rec);
 
1271
                handles[mapi_repl->handle_idx] = attachment_rec->handle;
 
1272
 
 
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);
 
1278
                        if (retval) {
 
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;
 
1282
                        }
 
1283
                        retval = mapi_handles_set_private_data(attachment_rec, attachment_object);
 
1284
                }
 
1285
        }
 
1286
 
 
1287
 end:
 
1288
        *size += libmapiserver_RopOpenAttach_size(mapi_repl);
 
1289
 
 
1290
        return MAPI_E_SUCCESS;  
 
1291
}
 
1292
 
 
1293
/**
 
1294
   \details EcDoRpc CreateAttach (0x23) Rop. This operation open an attachment
 
1295
   from the message handle.
 
1296
 
 
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
 
1300
   structure
 
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
 
1305
 
 
1306
   \return MAPI_E_SUCCESS on success, otherwise MAPI error
 
1307
 */
 
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)
 
1313
{
 
1314
        enum MAPISTATUS         retval;
 
1315
        uint32_t                handle;
 
1316
        uint32_t                contextID;
 
1317
        uint64_t                messageID;
 
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;
 
1322
        void                            *data;
 
1323
 
 
1324
        DEBUG(4, ("exchange_emsmdb: [OXCMSG] CreateAttach (0x23)\n"));
 
1325
 
 
1326
        /* Sanity checks */
 
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);
 
1332
 
 
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;
 
1336
 
 
1337
        handle = handles[mapi_req->handle_idx];
 
1338
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
 
1339
        if (retval) {
 
1340
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
1341
                DEBUG(5, ("  handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
1342
                goto end;
 
1343
        }
 
1344
 
 
1345
        retval = mapi_handles_get_private_data(rec, &data);
 
1346
        if (retval) {
 
1347
                mapi_repl->error_code = retval;
 
1348
                DEBUG(5, ("  handle data not found, idx = %x\n", mapi_req->handle_idx));
 
1349
                goto end;
 
1350
        }
 
1351
 
 
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;
 
1356
                goto end;
 
1357
        }
 
1358
 
 
1359
        switch (emsmdbp_is_mapistore(message_object)) {
 
1360
        case false:
 
1361
                /* system/special folder */
 
1362
                DEBUG(0, ("Not implemented yet - shouldn't occur\n"));
 
1363
                break;
 
1364
        case true:
 
1365
                messageID = message_object->object.message->messageID;
 
1366
                contextID = emsmdbp_get_contextID(message_object);
 
1367
 
 
1368
                retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &attachment_rec);
 
1369
                handles[mapi_repl->handle_idx] = attachment_rec->handle;
 
1370
                
 
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);
 
1376
                        if (retval) {
 
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;
 
1380
                        }
 
1381
                        retval = mapi_handles_set_private_data(attachment_rec, attachment_object);
 
1382
                }
 
1383
        }
 
1384
 
 
1385
 end:
 
1386
        *size += libmapiserver_RopCreateAttach_size(mapi_repl);
 
1387
 
 
1388
        return MAPI_E_SUCCESS;  
 
1389
}
 
1390
 
 
1391
/**
 
1392
   \details EcDoRpc SaveChangesAttachment (0x25) Rop. This operation open an attachment
 
1393
   from the message handle.
 
1394
 
 
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
 
1398
   structure
 
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
 
1403
 
 
1404
   \return MAPI_E_SUCCESS on success, otherwise MAPI error
 
1405
 */
 
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)
 
1411
{
 
1412
        DEBUG(4, ("exchange_emsmdb: [OXCMSG] SaveChangesAttachment (0x25) -- valid stub\n"));
 
1413
 
 
1414
        /* Sanity checks */
 
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);
 
1420
 
 
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;
 
1424
 
 
1425
        *size += libmapiserver_RopSaveChangesAttachment_size(mapi_repl);
 
1426
 
 
1427
        return MAPI_E_SUCCESS;  
 
1428
}
 
1429
 
 
1430
/**
 
1431
   \details EcDoRpc OpenEmbeddedMessage (0x46) Rop. This operation open an attachment
 
1432
   from the message handle.
 
1433
 
 
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
 
1437
   structure
 
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
 
1442
 
 
1443
   \return MAPI_E_SUCCESS on success, otherwise MAPI error
 
1444
 */
 
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)
 
1450
{
 
1451
        enum mapistore_error            ret;
 
1452
        enum MAPISTATUS                 retval;
 
1453
        uint32_t                        handle;
 
1454
        uint32_t                        contextID;
 
1455
        uint64_t                        messageID;
 
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;
 
1462
        bool                            mapistore;
 
1463
        struct oxcmsg_prop_index        prop_index;
 
1464
        int                             i;
 
1465
 
 
1466
        DEBUG(4, ("exchange_emsmdb: [OXCMSG] OpenEmbeddedMessage (0x46)\n"));
 
1467
 
 
1468
        /* Sanity checks */
 
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);
 
1474
 
 
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;
 
1478
 
 
1479
        handle = handles[mapi_req->handle_idx];
 
1480
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &attachment_rec);
 
1481
        if (retval) {
 
1482
                DEBUG(5, ("  handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
1483
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
1484
                goto end;
 
1485
        }
 
1486
 
 
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;
 
1491
                goto end;
 
1492
        }
 
1493
 
 
1494
        memset(&mapi_repl->u.mapi_OpenEmbeddedMessage, 0, sizeof(struct OpenEmbeddedMessage_repl));
 
1495
 
 
1496
        mapistore = emsmdbp_is_mapistore(attachment_object);
 
1497
        switch (mapistore) {
 
1498
        case false:
 
1499
                DEBUG(0, ("Not implemented - shouldn't occur\n"));
 
1500
                break;
 
1501
        case true:
 
1502
                if (mapi_req->u.mapi_OpenEmbeddedMessage.OpenModeFlags == MAPI_CREATE) {
 
1503
                        retval = openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, &messageID);
 
1504
                        if (retval) {
 
1505
                                mapi_repl->error_code = MAPI_E_NO_SUPPORT;
 
1506
                                goto end;
 
1507
                        }
 
1508
                }
 
1509
 
 
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,
 
1513
                                                                            &messageID,
 
1514
                                                                            &msg);
 
1515
                if (ret != MAPISTORE_SUCCESS) {
 
1516
                        mapi_repl->error_code = MAPI_E_NOT_FOUND;
 
1517
                        goto end;
 
1518
                }
 
1519
 
 
1520
                mapi_repl->u.mapi_OpenEmbeddedMessage.MessageId = messageID;
 
1521
 
 
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);
 
1525
                }
 
1526
                else {
 
1527
                        mapi_repl->u.mapi_OpenEmbeddedMessage.SubjectPrefix.StringType = StringType_EMPTY;
 
1528
                }
 
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);
 
1532
                }
 
1533
                else {
 
1534
                        mapi_repl->u.mapi_OpenEmbeddedMessage.NormalizedSubject.StringType = StringType_EMPTY;
 
1535
                }
 
1536
                if (msg->columns) {
 
1537
                        mapi_repl->u.mapi_OpenEmbeddedMessage.RecipientColumns.cValues = msg->columns->cValues;
 
1538
                        mapi_repl->u.mapi_OpenEmbeddedMessage.RecipientColumns.aulPropTag = msg->columns->aulPropTag;
 
1539
                }
 
1540
                else {
 
1541
                        mapi_repl->u.mapi_OpenEmbeddedMessage.RecipientColumns.cValues = 0;
 
1542
                }
 
1543
 
 
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);
 
1553
                        }
 
1554
                }
 
1555
 
 
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;
 
1560
 
 
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);
 
1565
                talloc_free(msg);
 
1566
                retval = mapi_handles_set_private_data(message_rec, message_object);
 
1567
 
 
1568
                break;
 
1569
        }
 
1570
 
 
1571
 end:
 
1572
        *size += libmapiserver_RopOpenEmbeddedMessage_size(mapi_repl);
720
1573
 
721
1574
        return MAPI_E_SUCCESS;  
722
1575
}