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

« back to all changes in this revision

Viewing changes to mapiproxy/servers/default/emsmdb/oxcprpt.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
25
25
   \brief Property and Stream Object routines and Rops
26
26
 */
27
27
 
 
28
#include <stdlib.h>
 
29
#include <sys/types.h>
 
30
#include <unistd.h>
 
31
 
 
32
#include "libmapi/libmapi.h"
28
33
#include "mapiproxy/dcesrv_mapiproxy.h"
29
34
#include "mapiproxy/libmapiproxy/libmapiproxy.h"
30
35
#include "mapiproxy/libmapiserver/libmapiserver.h"
31
36
#include "dcesrv_exchange_emsmdb.h"
32
37
 
33
38
/**
34
 
   \details Retrieve properties on a mapistore object
35
 
   
36
 
   \param mem_ctx pointer to the memory context
37
 
   \param emsmdbp_ctx pointer to the emsmdb provider context
38
 
   \param request GetProps request
39
 
   \param response pointer to the GetProps reply
40
 
   \param private_data pointer tot eh private data stored for this
41
 
   object
42
 
 
43
 
   \note We do not handle anything yet. This is just a skeleton.
44
 
 
45
 
   \return MAPI_E_SUCCESS on success, otherwise MAPI error
46
 
 */
47
 
static enum MAPISTATUS RopGetPropertiesSpecific_mapistore(TALLOC_CTX *mem_ctx,
48
 
                                                          struct emsmdbp_context *emsmdbp_ctx,
49
 
                                                          struct GetProps_req request,
50
 
                                                          struct GetProps_repl *response,
51
 
                                                          void *private_data)
52
 
{
53
 
        enum MAPISTATUS         retval;
54
 
        struct emsmdbp_object   *object;
55
 
        uint32_t                contextID = -1;
56
 
        uint64_t                fmid = 0;
57
 
        void                    *data;
58
 
        struct SPropTagArray    SPropTagArray;
59
 
        struct SRow             *aRow;
60
 
        uint32_t                i;
61
 
        uint32_t                j;
62
 
        uint8_t                 type;
63
 
        bool                    found = false;
64
 
 
65
 
        object = (struct emsmdbp_object *) private_data;
66
 
        if (object) {
67
 
                switch (object->type) {
68
 
                case EMSMDBP_OBJECT_FOLDER:
69
 
                        /* contextID = object->object.folder->contextID; */
70
 
                        /* fmid = object->object.folder->folderID; */
71
 
                        /* type = MAPISTORE_FOLDER; */
72
 
                        break;
73
 
                case EMSMDBP_OBJECT_MESSAGE:
74
 
                        contextID = object->object.message->contextID;
75
 
                        fmid = object->object.message->messageID;
76
 
                        type = MAPISTORE_MESSAGE;
77
 
                        break;
78
 
                default:
79
 
                        break;
80
 
                }
81
 
        }
82
 
 
83
 
        SPropTagArray.cValues = request.prop_count;
84
 
        SPropTagArray.aulPropTag = request.properties;
85
 
 
86
 
        /* TODO: Fix contextID signed */
87
 
        if ((int)contextID != -1) {
88
 
                aRow = talloc_zero(mem_ctx, struct SRow);
89
 
                aRow->cValues = 0;
90
 
                mapistore_getprops(emsmdbp_ctx->mstore_ctx, contextID, fmid, type, &SPropTagArray, aRow);
91
 
                /* Check if we need the layout */
92
 
                for (i = 0; i < request.prop_count; i++) {
93
 
                        for (j = 0; j < aRow->cValues; j++) {
94
 
                                if (request.properties[i] == aRow->lpProps[j].ulPropTag) {
95
 
                                        found = true;
96
 
                                        response->layout = 0x0;
97
 
                                }
98
 
                        }
99
 
                        if (found == false) {
100
 
                                response->layout = 0x1;
101
 
                                break;
102
 
                        }
103
 
                }
104
 
                
105
 
                for (i = 0; i < request.prop_count; i++) {
106
 
                        response->layout = 0x1;
107
 
                        data = (void *) find_SPropValue_data(aRow, request.properties[i]);
108
 
                        if (data == NULL) {
109
 
                                request.properties[i] = (enum MAPITAGS)((int)(request.properties[i] & 0xFFFF0000) + PT_ERROR);
110
 
                                retval = MAPI_E_NOT_FOUND;
111
 
                                data = (void *)&retval;
112
 
                        } 
113
 
                        libmapiserver_push_property(mem_ctx,
114
 
                                                    request.properties[i], (const void *)data,
115
 
                                                    &response->prop_data, response->layout, 0);
116
 
                }
117
 
 
118
 
        } else {
119
 
                response->layout = 0x1;
120
 
                for (i = 0; i < request.prop_count; i++) {
121
 
                        request.properties[i] = (enum MAPITAGS)((int)(request.properties[i] & 0xFFFF0000) + PT_ERROR);
122
 
                        retval = MAPI_E_NOT_FOUND;
123
 
                        response->layout = 0x1;
124
 
                        data = (void *)&retval;
125
 
                        libmapiserver_push_property(mem_ctx,
126
 
                                                    request.properties[i], (const void *)data,
127
 
                                                    &response->prop_data, response->layout, 0);
128
 
                }
129
 
        }
130
 
 
131
 
        return MAPI_E_SUCCESS;
132
 
}
133
 
 
134
 
 
135
 
/**
136
 
   \details Retrieve properties on a mailbox object.
137
 
 
138
 
   \param mem_ctx pointer to the memory context
139
 
   \param emsmdbp_ctx pointer to the emsmdb provider context
140
 
   \param request GetProps request
141
 
   \param response pointer to the GetProps reply
142
 
   \param private_data pointer to the private data stored for this
143
 
   object
144
 
 
145
 
   \note Mailbox objects have a limited set of supported properties.
146
 
 
147
 
   \return MAPI_E_SUCCESS on success, otherwise MAPI error
148
 
 */
149
 
static enum MAPISTATUS RopGetPropertiesSpecific_Mailbox(TALLOC_CTX *mem_ctx,
150
 
                                                        struct emsmdbp_context *emsmdbp_ctx,
151
 
                                                        struct GetProps_req request,
152
 
                                                        struct GetProps_repl *response,
153
 
                                                        void *private_data)
154
 
{
155
 
        enum MAPISTATUS                 retval;
156
 
        struct emsmdbp_object           *object;
157
 
        void                            *data;
158
 
        struct SBinary_short            bin;
159
 
        uint32_t                        i;
160
 
        uint32_t                        error = 0;
161
 
 
162
 
        /* Sanity checks */
163
 
        OPENCHANGE_RETVAL_IF(!private_data, MAPI_E_INVALID_PARAMETER, NULL);
164
 
 
165
 
        object = (struct emsmdbp_object *) private_data;
166
 
 
167
 
        /* Step 1. Check if we need a layout */
168
 
        response->layout = 0;
169
 
        for (i = 0; i < request.prop_count; i++) {
170
 
                switch (request.properties[i]) {
171
 
                case PR_MAPPING_SIGNATURE:
172
 
                case PR_IPM_PUBLIC_FOLDERS_ENTRYID:
173
 
                        response->layout = 0x1;
174
 
                        break;
175
 
                case PR_USER_ENTRYID:
176
 
                        break;
177
 
                case PR_MAILBOX_OWNER_ENTRYID:
178
 
                case PR_MAILBOX_OWNER_NAME:
179
 
                case PR_MAILBOX_OWNER_NAME_UNICODE:
180
 
                        if (object->object.mailbox->mailboxstore == false) {
181
 
                                response->layout = 0x1;
182
 
                        }
183
 
                        break;
184
 
                default:
185
 
                        retval = openchangedb_get_folder_property(mem_ctx, emsmdbp_ctx->oc_ctx,
186
 
                                                                  emsmdbp_ctx->szDisplayName, 
187
 
                                                                  request.properties[i],
188
 
                                                                  object->object.mailbox->folderID, 
189
 
                                                                  (void **)&data);
190
 
                        if (retval) {
191
 
                                response->layout = 0x1;
192
 
                        }
193
 
                        break;
194
 
                }
195
 
                if (response->layout == 1) {
196
 
                        break;
197
 
                }
198
 
        }
199
 
 
200
 
        /* Step 2. Fill the GetProps blob */
201
 
        for (i = 0; i < request.prop_count; i++) {
202
 
                switch (request.properties[i]) {
203
 
                case PR_MAPPING_SIGNATURE:
204
 
                case PR_IPM_PUBLIC_FOLDERS_ENTRYID:
205
 
                        error = MAPI_E_NO_ACCESS;
206
 
                        request.properties[i] = (enum MAPITAGS)((int)(request.properties[i] & 0xFFFF0000) + PT_ERROR);
207
 
                        libmapiserver_push_property(mem_ctx,
208
 
                                                    request.properties[i], (const void *)&error, 
209
 
                                                    &response->prop_data, response->layout, 0);
210
 
                        break;
211
 
                case PR_USER_ENTRYID:
212
 
                        retval = entryid_set_AB_EntryID(mem_ctx, object->object.mailbox->szUserDN, &bin);
213
 
                        libmapiserver_push_property(mem_ctx,
214
 
                                                    request.properties[i], (const void *)&bin,
215
 
                                                    &response->prop_data, response->layout, 0);
216
 
                        talloc_free(bin.lpb);
217
 
                        break;
218
 
                case PR_MAILBOX_OWNER_ENTRYID:
219
 
                        if (object->object.mailbox->mailboxstore == false) {
220
 
                                error = MAPI_E_NO_ACCESS;
221
 
                                request.properties[i] = (enum MAPITAGS)((int)(request.properties[i] & 0xFFFF0000) + PT_ERROR);
222
 
                                libmapiserver_push_property(mem_ctx,
223
 
                                                            request.properties[i], (const void *)&error,
224
 
                                                            &response->prop_data, response->layout, 0);
225
 
                        } else {
226
 
                                retval = entryid_set_AB_EntryID(mem_ctx, object->object.mailbox->owner_EssDN,
227
 
                                                                &bin);
228
 
                                libmapiserver_push_property(mem_ctx,
229
 
                                                            request.properties[i], (const void *)&bin,
230
 
                                                            &response->prop_data, response->layout, 0);
231
 
                                talloc_free(bin.lpb);
232
 
                        }
233
 
                        break;
234
 
                case PR_MAILBOX_OWNER_NAME:
235
 
                case PR_MAILBOX_OWNER_NAME_UNICODE:
236
 
                        if (object->object.mailbox->mailboxstore == false) {
237
 
                                error = MAPI_E_NO_ACCESS;
238
 
                                request.properties[i] = (enum MAPITAGS)((int)(request.properties[i] & 0xFFFF0000) + PT_ERROR);
239
 
                                libmapiserver_push_property(mem_ctx,
240
 
                                                            request.properties[i], (const void *)&error,
241
 
                                                            &response->prop_data, response->layout, 0);
242
 
                        } else {
243
 
                                libmapiserver_push_property(mem_ctx,
244
 
                                                            request.properties[i], 
245
 
                                                            (const void *)object->object.mailbox->owner_Name,
246
 
                                                            &response->prop_data, response->layout, 0);
247
 
                        }
248
 
                        break;
249
 
                default:
250
 
                        retval = openchangedb_get_folder_property(mem_ctx, emsmdbp_ctx->oc_ctx,
251
 
                                                                  emsmdbp_ctx->szDisplayName, request.properties[i],
252
 
                                                                  object->object.mailbox->folderID, (void **)&data);
253
 
                        if (retval) {
254
 
                                request.properties[i] = (enum MAPITAGS)((int)(request.properties[i] & 0xFFFF0000) + PT_ERROR);
255
 
                                data = (void *)&retval;
256
 
                        }
257
 
                        libmapiserver_push_property(mem_ctx,
258
 
                                                    request.properties[i], (const void *)data, 
259
 
                                                    &response->prop_data, response->layout, 0);
260
 
                        break;
261
 
                }
262
 
        }
263
 
 
264
 
        return MAPI_E_SUCCESS;
265
 
}
266
 
 
267
 
 
268
 
/**
269
 
   \details Retrieve properties on a systemfolder object.
270
 
 
271
 
   \param mem_ctx pointer to the memory context
272
 
   \param emsmdbp_ctx pointer to the emsmdb provider context
273
 
   \param request GetProps request
274
 
   \param response pointer to the GetProps reply
275
 
   \param private_data pointer to the private data stored for this
276
 
   object
277
 
   \param private_data pointer to the private data stored for this
278
 
   object
279
 
 
280
 
   \return MAPI_E_SUCCESS on success, otherwise MAPI error
281
 
 */
282
 
static enum MAPISTATUS RopGetPropertiesSpecific_SystemSpecialFolder(TALLOC_CTX *mem_ctx,
283
 
                                                                    struct emsmdbp_context *emsmdbp_ctx,
284
 
                                                                    struct GetProps_req request,
285
 
                                                                    struct GetProps_repl *response,
286
 
                                                                    void *private_data)
287
 
{
288
 
        enum MAPISTATUS                 retval;
289
 
        struct emsmdbp_object           *object;
290
 
        struct emsmdbp_object_folder    *folder;
291
 
        void                            *data;
292
 
        int                             i;
293
 
 
294
 
        /* Sanity checks */
295
 
        OPENCHANGE_RETVAL_IF(!private_data, MAPI_E_INVALID_PARAMETER, NULL);
296
 
 
297
 
        object = (struct emsmdbp_object *) private_data;
298
 
        folder = (struct emsmdbp_object_folder *) object->object.folder;
299
 
 
300
 
        /* Step 1. Lookup properties and set layout */
301
 
        response->layout = 0x0;
302
 
        for (i = 0; i < request.prop_count; i++) {
303
 
                if (openchangedb_lookup_folder_property(emsmdbp_ctx->oc_ctx, request.properties[i], 
304
 
                                                        folder->folderID)) {
305
 
                        response->layout = 0x1;
306
 
                        break;
307
 
                }
308
 
        }
309
 
 
310
 
        /* Step 2. Fetch properties values */
311
 
        for (i = 0; i < request.prop_count; i++) {
312
 
                retval = openchangedb_get_folder_property(mem_ctx, emsmdbp_ctx->oc_ctx, 
313
 
                                                          emsmdbp_ctx->szDisplayName, request.properties[i],
314
 
                                                          folder->folderID, (void **)&data);
315
 
                if (retval) {
316
 
                        request.properties[i] = (enum MAPITAGS)((int)(request.properties[i] & 0xFFFF0000) + PT_ERROR);
317
 
                        data = (void *)&retval;
318
 
                }
319
 
                libmapiserver_push_property(mem_ctx,
320
 
                                            request.properties[i], (const void *)data,
321
 
                                            &response->prop_data, response->layout, 0);
322
 
        }
323
 
 
324
 
        return MAPI_E_SUCCESS;
325
 
}
326
 
 
327
 
 
328
 
/**
329
39
   \details EcDoRpc GetPropertiesSpecific (0x07) Rop. This operation
330
40
   retrieves from properties data from specified object.
331
41
 
347
57
                                                          uint32_t *handles, uint16_t *size)
348
58
{
349
59
        enum MAPISTATUS         retval;
350
 
        struct GetProps_req     request;
351
 
        struct GetProps_repl    response;
 
60
        struct GetProps_req     *request;
 
61
        struct GetProps_repl    *response;
352
62
        uint32_t                handle;
353
63
        struct mapi_handles     *rec = NULL;
354
64
        void                    *private_data = NULL;
355
 
        bool                    mapistore = false;
356
65
        struct emsmdbp_object   *object;
 
66
        struct SPropTagArray    *properties;
 
67
        void                    **data_pointers;
 
68
        enum MAPISTATUS         *retvals = NULL;
 
69
        bool                    *untyped_status;
 
70
        uint16_t                i, propType;
 
71
        uint32_t                stream_size;
 
72
        struct emsmdbp_stream_data *stream_data;
357
73
 
358
74
        DEBUG(4, ("exchange_emsmdb: [OXCPRPT] GetPropertiesSpecific (0x07)\n"));
359
75
 
364
80
        OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
365
81
        OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
366
82
 
367
 
        request = mapi_req->u.mapi_GetProps;
368
 
        response = mapi_repl->u.mapi_GetProps;
 
83
        request = &mapi_req->u.mapi_GetProps;
 
84
        response = &mapi_repl->u.mapi_GetProps;
369
85
 
370
86
        /* Initialize GetProps response blob */
371
 
        response.prop_data.length = 0;
372
 
        response.prop_data.data = NULL;
 
87
        response->prop_data.length = 0;
 
88
        response->prop_data.data = NULL;
373
89
 
374
90
        /* Fill EcDoRpc_MAPI_REPL reply */
375
91
        mapi_repl->opnum = mapi_req->opnum;
378
94
 
379
95
        handle = handles[mapi_req->handle_idx];
380
96
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
381
 
        if (retval) goto end;
 
97
        if (retval) {
 
98
                mapi_repl->error_code = MAPI_E_NOT_FOUND;
 
99
                DEBUG(5, ("  handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
100
                goto end;
 
101
        }
382
102
 
383
103
        retval = mapi_handles_get_private_data(rec, &private_data);
384
 
 
385
 
        mapistore = emsmdbp_is_mapistore(rec);
386
 
        /* Nasty hack */
387
 
        if (!private_data) {
388
 
                mapistore = true;
389
 
        }
390
 
 
391
 
        /* Temporary hack: If this is a mapistore root container
392
 
         * (e.g. Inbox, Calendar etc.), directly stored under
393
 
         * IPM.Subtree, then fetch properties from openchange
394
 
         * dispatcher db, not mapistore */
395
 
        object = (struct emsmdbp_object *) private_data;
396
 
        if (object && object->type == EMSMDBP_OBJECT_FOLDER &&
397
 
            object->object.folder->mapistore_root == true) {
398
 
                retval = RopGetPropertiesSpecific_SystemSpecialFolder(mem_ctx, emsmdbp_ctx, 
399
 
                                                                      request, &response, private_data);
400
 
        } else {
401
 
                switch (mapistore) {
402
 
                case false:
403
 
                        switch (object->type) {
404
 
                        case EMSMDBP_OBJECT_MAILBOX:
405
 
                                retval = RopGetPropertiesSpecific_Mailbox(mem_ctx, emsmdbp_ctx, request, &response, private_data);
406
 
                                break;
407
 
                        case EMSMDBP_OBJECT_FOLDER:
408
 
                                retval = RopGetPropertiesSpecific_SystemSpecialFolder(mem_ctx, emsmdbp_ctx, request, &response, private_data);
409
 
                                break;
410
 
                        default:
411
 
                                break;
 
104
        object = private_data;
 
105
        if (!object) {
 
106
                mapi_repl->error_code = MAPI_E_NOT_FOUND;
 
107
                DEBUG(5, ("  object (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
108
                goto end;
 
109
        }
 
110
 
 
111
        if (!(object->type == EMSMDBP_OBJECT_MAILBOX
 
112
              || object->type == EMSMDBP_OBJECT_FOLDER
 
113
              || object->type == EMSMDBP_OBJECT_MESSAGE
 
114
              || object->type == EMSMDBP_OBJECT_ATTACHMENT)) {
 
115
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
116
                DEBUG(5, ("  GetProperties cannot occur on an object of type '%s' (%d)\n", emsmdbp_getstr_type(object), object->type));
 
117
                goto end;
 
118
        }
 
119
 
 
120
        properties = talloc_zero(NULL, struct SPropTagArray);
 
121
        properties->cValues = request->prop_count;
 
122
        properties->aulPropTag = talloc_array(properties, enum MAPITAGS, request->prop_count);
 
123
        untyped_status = talloc_array(NULL, bool, request->prop_count);
 
124
 
 
125
        for (i = 0; i < request->prop_count; i++) {
 
126
                properties->aulPropTag[i] = request->properties[i];
 
127
                if ((request->properties[i] & 0xffff) == 0) {
 
128
                        properties->aulPropTag[i] |= get_property_type(request->properties[i] >> 16);
 
129
                        untyped_status[i] = true;
 
130
                }
 
131
                else {
 
132
                        untyped_status[i] = false;
 
133
                }
 
134
        }
 
135
 
 
136
        data_pointers = emsmdbp_object_get_properties(mem_ctx, emsmdbp_ctx, object, properties, &retvals);
 
137
        if (data_pointers) {
 
138
                for (i = 0; i < request->prop_count; i++) {
 
139
                        if (retvals[i] == MAPI_E_SUCCESS) {
 
140
                                propType = properties->aulPropTag[i] & 0xffff;
 
141
                                if (propType == PT_STRING8) {
 
142
                                        stream_size = strlen((const char *) data_pointers[i]) + 1;
 
143
                                }
 
144
                                else if (propType == PT_UNICODE) {
 
145
                                        stream_size = strlen_m_ext((char *) data_pointers[i], CH_UTF8, CH_UTF16LE) * 2 + 2;
 
146
                                }
 
147
                                else if (propType == PT_BINARY) {
 
148
                                        stream_size = ((struct Binary_r *) data_pointers[i])->cb;
 
149
                                }
 
150
                                else {
 
151
                                        stream_size = 0;
 
152
                                }
 
153
                                if (stream_size > 8192) {
 
154
                                        DEBUG(5, ("%s: attaching stream data for property %.8x\n", __FUNCTION__, properties->aulPropTag[i]));
 
155
                                        stream_data = emsmdbp_stream_data_from_value(object, properties->aulPropTag[i], data_pointers[i]);
 
156
                                        if (stream_data) {
 
157
                                                DLIST_ADD(object->stream_data, stream_data);
 
158
                                        }
 
159
                                        /* This will trigger the opening of a property stream from the client. */
 
160
                                        retvals[i] = MAPI_E_NOT_ENOUGH_MEMORY;
 
161
                                }
412
162
                        }
413
 
                        break;
414
 
                case true:
415
 
                        /* folder or messages handled by mapistore */
416
 
                        retval = RopGetPropertiesSpecific_mapistore(mem_ctx, emsmdbp_ctx, request, &response, private_data);
417
 
                        break;
418
163
                }
419
 
        }
420
 
 
421
 
        mapi_repl->error_code = MAPI_E_SUCCESS;
422
 
        mapi_repl->u.mapi_GetProps = response;
 
164
                mapi_repl->error_code = MAPI_E_SUCCESS;
 
165
                emsmdbp_fill_row_blob(mem_ctx,
 
166
                                      emsmdbp_ctx,
 
167
                                      &response->layout,
 
168
                                      &response->prop_data,
 
169
                                      properties,
 
170
                                      data_pointers,
 
171
                                      retvals,
 
172
                                      untyped_status);
 
173
                talloc_free(data_pointers);
 
174
        }
 
175
        talloc_free(properties);
 
176
        talloc_free(retvals);
423
177
 
424
178
 end:
425
179
        *size += libmapiserver_RopGetPropertiesSpecific_size(mapi_req, mapi_repl);
427
181
        return MAPI_E_SUCCESS;
428
182
}
429
183
 
 
184
/**
 
185
   \details EcDoRpc GetPropertiesAll (0x08) Rop. This operation gets
 
186
   all the property values for an object.
 
187
 
 
188
   \param mem_ctx pointer to the memory context
 
189
   \param emsmdbp_ctx pointer to the emsmdb provider context
 
190
   \param mapi_req pointer to the GetPropertiesAll EcDoRpc_MAPI_REQ
 
191
   structure
 
192
   \param mapi_repl pointer to the GetPropertiesAll EcDoRpc_MAPI_REPL
 
193
   structure
 
194
   \param handles pointer to the MAPI handles array
 
195
   \param size pointer to the mapi_response size to update
 
196
 
 
197
   \return MAPI_E_SUCCESS on success, otherwise MAPI error
 
198
 */
 
199
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPropertiesAll(TALLOC_CTX *mem_ctx,
 
200
                                                     struct emsmdbp_context *emsmdbp_ctx,
 
201
                                                     struct EcDoRpc_MAPI_REQ *mapi_req,
 
202
                                                     struct EcDoRpc_MAPI_REPL *mapi_repl,
 
203
                                                     uint32_t *handles, uint16_t *size)
 
204
{
 
205
        enum MAPISTATUS                 retval;
 
206
        enum MAPISTATUS                 *retvals = NULL;
 
207
        struct GetPropsAll_repl         *response;
 
208
        uint32_t                        handle;
 
209
        struct mapi_handles             *rec = NULL;
 
210
        void                            *private_data = NULL;
 
211
        struct emsmdbp_object           *object;
 
212
        struct SPropTagArray            *SPropTagArray;
 
213
        void                            **data_pointers;
 
214
        int                             i;
 
215
 
 
216
        DEBUG(4, ("exchange_emsmdb: [OXCPRPT] GetPropertiesAll (0x08)\n"));
 
217
 
 
218
        /* Sanity checks */
 
219
        OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
 
220
        OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
 
221
        OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
 
222
        OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
 
223
        OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
 
224
 
 
225
        response = &mapi_repl->u.mapi_GetPropsAll;
 
226
 
 
227
        /* Initialize GetPropsAll response */
 
228
        response->properties.cValues = 0;
 
229
        response->properties.lpProps = NULL;
 
230
 
 
231
        /* Fill EcDoRpc_MAPI_REPL reply */
 
232
        mapi_repl->opnum = mapi_req->opnum;
 
233
        mapi_repl->handle_idx = mapi_req->handle_idx;
 
234
        /* mapi_repl->error_code = MAPI_E_NOT_FOUND; */
 
235
        mapi_repl->error_code = MAPI_E_SUCCESS;
 
236
 
 
237
        handle = handles[mapi_req->handle_idx];
 
238
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
 
239
        if (retval) {
 
240
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
241
                DEBUG(5, ("  handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
242
                goto end;
 
243
        }
 
244
 
 
245
        retval = mapi_handles_get_private_data(rec, &private_data);
 
246
        object = private_data;
 
247
        if (!object) {
 
248
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
249
                DEBUG(5, ("  object (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
250
                goto end;
 
251
        }
 
252
 
 
253
        retval = emsmdbp_object_get_available_properties(mem_ctx, emsmdbp_ctx, object, &SPropTagArray);
 
254
        if (retval) {
 
255
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
256
                DEBUG(5, ("  object (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
257
                goto end;
 
258
        }
 
259
 
 
260
        data_pointers = emsmdbp_object_get_properties(mem_ctx, emsmdbp_ctx, object, SPropTagArray, &retvals);
 
261
        if (data_pointers) {            
 
262
                response->properties.lpProps = talloc_array(mem_ctx, struct mapi_SPropValue, 2);
 
263
                response->properties.cValues = 0;
 
264
                for (i = 0; i < SPropTagArray->cValues; i++) {
 
265
                        if (retvals[i] == MAPI_E_SUCCESS) {
 
266
                                response->properties.lpProps = add_mapi_SPropValue(mem_ctx, 
 
267
                                                                                   response->properties.lpProps,
 
268
                                                                                   &response->properties.cValues,
 
269
                                                                                   SPropTagArray->aulPropTag[i], 
 
270
                                                                                   (void *)data_pointers[i]);
 
271
                                
 
272
                        }
 
273
                }
 
274
        }
 
275
 
 
276
end:
 
277
        *size += libmapiserver_RopGetPropertiesAll_size(mapi_repl);
 
278
        return MAPI_E_SUCCESS;
 
279
}
 
280
 
 
281
 
 
282
/**
 
283
   \details EcDoRpc GetPropertiesList (0x9) Rop. This operation
 
284
   retrieves the list of MAPI tags for an object.
 
285
 
 
286
   \param mem_ctx pointer to the memory context
 
287
   \param emsmdbp_ctx pointer to the emsmdb provider context
 
288
   \param mapi_req pointer to the SetProperties EcDoRpc_MAPI_REQ
 
289
   structure
 
290
   \param mapi_repl pointer to the SetProperties EcDoRpc_MAPI_REPL
 
291
   structure
 
292
   \param handles pointer to the MAPI handles array
 
293
   \param size pointer to the mapi_response size to update
 
294
 
 
295
   \return MAPI_E_SUCCESS on success, otherwise MAPI error
 
296
 */
 
297
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPropertiesList(TALLOC_CTX *mem_ctx,
 
298
                                                      struct emsmdbp_context *emsmdbp_ctx,
 
299
                                                      struct EcDoRpc_MAPI_REQ *mapi_req,
 
300
                                                      struct EcDoRpc_MAPI_REPL *mapi_repl,
 
301
                                                      uint32_t *handles, uint16_t *size)
 
302
{
 
303
        enum MAPISTATUS         retval;
 
304
        struct GetPropList_repl *response;
 
305
        uint32_t                handle;
 
306
        struct mapi_handles     *rec = NULL;
 
307
        void                    *private_data = NULL;
 
308
        struct emsmdbp_object   *object;
 
309
        struct SPropTagArray    *SPropTagArray;
 
310
        
 
311
        DEBUG(4, ("exchange_emsmdb: [OXCPRPT] GetPropertiesList (0x9)\n"));
 
312
 
 
313
        /* Sanity checks */
 
314
        OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
 
315
        OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
 
316
        OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
 
317
        OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
 
318
        OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
 
319
 
 
320
        response = &mapi_repl->u.mapi_GetPropList;
 
321
 
 
322
        /* Initialize GetPropList response */
 
323
        response->count = 0;
 
324
        response->tags = NULL;
 
325
 
 
326
        /* Fill EcDoRpc_MAPI_REPL reply */
 
327
        mapi_repl->opnum = mapi_req->opnum;
 
328
        mapi_repl->handle_idx = mapi_req->handle_idx;
 
329
        mapi_repl->error_code = MAPI_E_SUCCESS;
 
330
 
 
331
        handle = handles[mapi_req->handle_idx];
 
332
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
 
333
        if (retval) {
 
334
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
335
                DEBUG(5, ("  handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
336
                goto end;
 
337
        }
 
338
 
 
339
        retval = mapi_handles_get_private_data(rec, &private_data);
 
340
        object = private_data;
 
341
        if (!object) {
 
342
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
343
                DEBUG(5, ("  object (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
344
                goto end;
 
345
        }
 
346
 
 
347
        retval = emsmdbp_object_get_available_properties(mem_ctx, emsmdbp_ctx, object, &SPropTagArray);
 
348
        if (retval) {
 
349
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
350
                DEBUG(5, ("  object (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
351
                goto end;
 
352
        }
 
353
 
 
354
        response->count = SPropTagArray->cValues;
 
355
        response->tags = SPropTagArray->aulPropTag;
 
356
 
 
357
end:
 
358
        *size += libmapiserver_RopGetPropertiesList_size(mapi_repl);
 
359
        return MAPI_E_SUCCESS;
 
360
}
430
361
 
431
362
/**
432
363
   \details EcDoRpc SetProperties (0x0a) Rop. This operation sets
453
384
        uint32_t                handle;
454
385
        struct mapi_handles     *rec = NULL;
455
386
        void                    *private_data = NULL;
456
 
        bool                    mapistore = false;
457
387
        struct emsmdbp_object   *object;
458
 
        uint64_t                messageID;
459
 
        uint32_t                contextID;
460
388
        uint16_t                i;
461
389
        struct SRow             aRow;
462
390
 
479
407
        handle = handles[mapi_req->handle_idx];
480
408
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
481
409
        if (retval) {
482
 
                mapi_repl->error_code = MAPI_E_NOT_FOUND;
 
410
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
411
                DEBUG(5, ("  handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
483
412
                goto end;
484
413
        }
485
414
 
490
419
                goto end;
491
420
        }
492
421
 
493
 
        mapistore = emsmdbp_is_mapistore(rec);
494
 
        switch (mapistore) {
495
 
        case false:
496
 
                DEBUG(0, ("SetProps on openchangedb not implemented yet\n"));
497
 
                break;
498
 
        case true:
499
 
                if (object->type == EMSMDBP_OBJECT_MESSAGE) {
500
 
                        messageID = object->object.message->messageID;
501
 
                        contextID = object->object.message->contextID;
502
 
 
503
 
                        aRow.cValues = mapi_req->u.mapi_SetProps.values.cValues;
504
 
                        aRow.lpProps = talloc_array(mem_ctx, struct SPropValue, aRow.cValues + 2);
505
 
                        for (i = 0; i < mapi_req->u.mapi_SetProps.values.cValues; i++) {
506
 
                          cast_SPropValue(aRow.lpProps, &(mapi_req->u.mapi_SetProps.values.lpProps[i]),
507
 
                                          &(aRow.lpProps[i]));
508
 
                        }
509
 
 
510
 
                        mapistore_setprops(emsmdbp_ctx->mstore_ctx, contextID, messageID, 
511
 
                                           MAPISTORE_MESSAGE, &aRow);
512
 
                } 
513
 
                break;
514
 
        }
515
 
        
 
422
        if (object->type == EMSMDBP_OBJECT_MESSAGE && !object->object.message->read_write) {
 
423
                mapi_repl->error_code = MAPI_E_NO_ACCESS;
 
424
                goto end;
 
425
        }
 
426
 
 
427
        aRow.cValues = mapi_req->u.mapi_SetProps.values.cValues;
 
428
        aRow.lpProps = talloc_array(mem_ctx, struct SPropValue, aRow.cValues + 2);
 
429
        for (i = 0; i < mapi_req->u.mapi_SetProps.values.cValues; i++) {
 
430
                cast_SPropValue(aRow.lpProps, &(mapi_req->u.mapi_SetProps.values.lpProps[i]),
 
431
                                &(aRow.lpProps[i]));
 
432
        }
 
433
 
 
434
        retval = emsmdbp_object_set_properties(emsmdbp_ctx, object, &aRow);
 
435
        if (retval) {
 
436
                mapi_repl->error_code = MAPI_E_NO_SUPPORT;
 
437
                goto end;
 
438
        }
516
439
 
517
440
end:
518
441
        *size += libmapiserver_RopSetProperties_size(mapi_repl);
542
465
                                                     struct EcDoRpc_MAPI_REPL *mapi_repl,
543
466
                                                     uint32_t *handles, uint16_t *size)
544
467
{
545
 
        DEBUG(4, ("exchange_emsmdb: [OXCPRPT] DeleteProperties (0x0b)\n"));
 
468
        DEBUG(4, ("exchange_emsmdb: [OXCPRPT] DeleteProperties (0x0b) -- stub\n"));
546
469
 
547
470
        /* Sanity checks */
548
471
        OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
589
512
        struct mapi_handles             *parent = NULL;
590
513
        struct mapi_handles             *rec = NULL;
591
514
        struct emsmdbp_object           *object = NULL;
 
515
        struct emsmdbp_object           *parent_object = NULL;
 
516
        struct OpenStream_req           *request;
592
517
        uint32_t                        handle;
 
518
        void                            *data;
 
519
        struct SPropTagArray            properties;
 
520
        void                            **data_pointers;
 
521
        enum MAPISTATUS                 *retvals;
 
522
        struct emsmdbp_stream_data      *stream_data;
 
523
        enum OpenStream_OpenModeFlags   mode;
593
524
 
594
525
        DEBUG(4, ("exchange_emsmdb: [OXCPRPT] OpenStream (0x2b)\n"));
595
526
 
602
533
 
603
534
        mapi_repl->opnum = mapi_req->opnum;
604
535
        mapi_repl->error_code = MAPI_E_SUCCESS;
605
 
        mapi_repl->handle_idx = mapi_req->handle_idx;
 
536
        mapi_repl->handle_idx = mapi_req->u.mapi_OpenStream.handle_idx;
606
537
        mapi_repl->u.mapi_OpenStream.StreamSize = 0;
607
538
 
608
539
        /* Step 1. Retrieve parent handle in the hierarchy */
609
540
        handle = handles[mapi_req->handle_idx];
610
541
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
611
 
        OPENCHANGE_RETVAL_IF(retval, retval, NULL);
612
 
 
613
 
        if (!mapi_repl->error_code) {
614
 
                retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
615
 
                object = emsmdbp_object_stream_init((TALLOC_CTX *)rec, emsmdbp_ctx,
616
 
                                                    mapi_req->u.mapi_OpenStream.PropertyTag, parent);
617
 
                
618
 
                if (object) {
619
 
                        retval = mapi_handles_set_private_data(rec, object);
620
 
                }
621
 
 
622
 
                mapi_repl->handle_idx = mapi_req->u.mapi_OpenStream.handle_idx;
623
 
                handles[mapi_repl->handle_idx] = rec->handle;
624
 
        }
625
 
 
 
542
        if (retval) {
 
543
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
544
                DEBUG(5, ("  handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
545
                goto end;
 
546
        }
 
547
 
 
548
        mapi_handles_get_private_data(parent, &data);
 
549
        parent_object = (struct emsmdbp_object *) data;
 
550
        if (!(parent_object->type == EMSMDBP_OBJECT_FOLDER
 
551
              || parent_object->type == EMSMDBP_OBJECT_MESSAGE
 
552
              || parent_object->type == EMSMDBP_OBJECT_ATTACHMENT)) {
 
553
                mapi_repl->error_code = MAPI_E_NO_SUPPORT;
 
554
                goto end;
 
555
        }
 
556
 
 
557
        request = &mapi_req->u.mapi_OpenStream;
 
558
 
 
559
        mode = request->OpenModeFlags;
 
560
        if (mode == OpenStream_BestAccess) {
 
561
                if (parent_object->type == EMSMDBP_OBJECT_MESSAGE) {
 
562
                        if (parent_object->object.message->read_write) {
 
563
                                mode = OpenStream_ReadWrite;
 
564
                        }
 
565
                        else {
 
566
                                mode = OpenStream_ReadOnly;
 
567
                        }
 
568
                }
 
569
                else {
 
570
                        mode = OpenStream_ReadOnly;
 
571
                }
 
572
        }
 
573
 
 
574
        if (parent_object->type == EMSMDBP_OBJECT_MESSAGE && !parent_object->object.message->read_write && (mode == OpenStream_ReadWrite || mode == OpenStream_Create)) {
 
575
                mapi_repl->error_code = MAPI_E_NO_ACCESS;
 
576
                goto end;
 
577
        }
 
578
 
 
579
        if (request->PropertyTag == PidTagSecurityDescriptorAsXml) {
 
580
                /* exception; see oxcperm - 3.1.4.1 Retrieving Folder Permissions */
 
581
                mapi_repl->error_code = MAPI_E_NOT_IMPLEMENTED;
 
582
                goto end;
 
583
        }
 
584
 
 
585
        /* TODO: implementation status:
 
586
           - OpenStream_ReadOnly (supported)
 
587
           - OpenStream_ReadWrite (supported)
 
588
           - OpenStream_Create (supported)
 
589
           - OpenStream_BestAccess
 
590
        */
 
591
 
 
592
        object = emsmdbp_object_stream_init(NULL, emsmdbp_ctx, parent_object);
 
593
        object->object.stream->property = request->PropertyTag;
 
594
        object->object.stream->stream.position = 0;
 
595
        object->object.stream->stream.buffer.length = 0;
 
596
 
 
597
        if (mode == OpenStream_ReadOnly || mode == OpenStream_ReadWrite) {
 
598
                object->object.stream->read_write = (mode == OpenStream_ReadWrite);
 
599
                stream_data = emsmdbp_object_get_stream_data(parent_object, object->object.stream->property);
 
600
                if (stream_data) {
 
601
                        object->object.stream->stream.buffer = stream_data->data;
 
602
                        (void) talloc_reference(object->object.stream, object->object.stream->stream.buffer.data);
 
603
                        DLIST_REMOVE(parent_object->stream_data, stream_data);
 
604
                        talloc_free(stream_data);
 
605
                }
 
606
                else {
 
607
                        properties.cValues = 1;
 
608
                        properties.aulPropTag = &request->PropertyTag;
 
609
 
 
610
                        data_pointers = emsmdbp_object_get_properties(mem_ctx, emsmdbp_ctx, parent_object, &properties, &retvals);
 
611
                        if (data_pointers == NULL) {
 
612
                                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
613
                                talloc_free(object);
 
614
                                goto end;
 
615
                        }
 
616
                        if (retvals[0] == MAPI_E_SUCCESS) {
 
617
                                stream_data = emsmdbp_stream_data_from_value(data_pointers, request->PropertyTag, data_pointers[0]);
 
618
                                object->object.stream->stream.buffer = stream_data->data;
 
619
                                (void) talloc_reference(object->object.stream, object->object.stream->stream.buffer.data);
 
620
                                talloc_free(data_pointers);
 
621
                                talloc_free(retvals);
 
622
                        }
 
623
                        else {
 
624
                                mapi_repl->error_code = retvals[0];
 
625
                                talloc_free(data_pointers);
 
626
                                talloc_free(retvals);
 
627
                                talloc_free(object);
 
628
                                goto end;
 
629
                        }
 
630
                }
 
631
        }
 
632
        else { /* OpenStream_Create */
 
633
                object->object.stream->read_write = true;
 
634
                object->object.stream->stream.buffer.data = talloc_zero(object->object.stream, uint8_t);
 
635
                object->object.stream->stream.buffer.length = 0;
 
636
        }
 
637
 
 
638
        mapi_repl->u.mapi_OpenStream.StreamSize = object->object.stream->stream.buffer.length;
 
639
 
 
640
        retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
 
641
        (void) talloc_reference(rec, object);
 
642
        handles[mapi_repl->handle_idx] = rec->handle;
 
643
        mapi_handles_set_private_data(rec, object);
 
644
        talloc_free(object);
 
645
 
 
646
end:
626
647
        *size += libmapiserver_RopOpenStream_size(mapi_repl);
627
648
 
628
649
        return MAPI_E_SUCCESS;
651
672
                                               uint32_t *handles, uint16_t *size)
652
673
{
653
674
        enum MAPISTATUS                 retval;
654
 
        struct mapi_handles             *parent = NULL;
655
675
        struct mapi_handles             *rec = NULL;
656
676
        void                            *private_data;
657
 
        struct emsmdbp_object           *object = NULL;
658
 
        uint32_t                        handle;
 
677
        struct emsmdbp_object           *object;
 
678
        uint32_t                        handle, buffer_size;
659
679
 
660
680
        DEBUG(4, ("exchange_emsmdb: [OXCPRPT] ReadStream (0x2c)\n"));
661
681
 
674
694
 
675
695
        /* Step 1. Retrieve parent handle in the hierarchy */
676
696
        handle = handles[mapi_req->handle_idx];
677
 
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
678
 
        if (retval) goto end;
 
697
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
 
698
        if (retval) {
 
699
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
700
                DEBUG(5, ("  handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
701
                goto end;
 
702
        }
679
703
 
 
704
        /* Step 2. Retrieve the stream object */
680
705
        retval = mapi_handles_get_private_data(rec, &private_data);
681
706
        object = (struct emsmdbp_object *) private_data;
682
 
        if (!object || object->type != EMSMDBP_OBJECT_STREAM) goto end;
683
 
 
684
 
        /* TODO effective work goes here */
 
707
        if (!object || object->type != EMSMDBP_OBJECT_STREAM) {
 
708
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
709
                DEBUG(5, ("  invalid object\n"));
 
710
                goto end;
 
711
        }
 
712
 
 
713
        /* Step 3. Return the data and update the position in the stream */
 
714
        buffer_size = mapi_req->u.mapi_ReadStream.ByteCount;
 
715
        /* careful here, let's switch to idiot mode */
 
716
        if (buffer_size == 0xBABE) {
 
717
                buffer_size = mapi_req->u.mapi_ReadStream.MaximumByteCount.value;
 
718
        }
 
719
 
 
720
        mapi_repl->u.mapi_ReadStream.data = emsmdbp_stream_read_buffer(&object->object.stream->stream, buffer_size);
 
721
 
685
722
end:
686
723
        *size += libmapiserver_RopReadStream_size(mapi_repl);
687
724
 
712
749
{
713
750
        enum MAPISTATUS                 retval;
714
751
        struct mapi_handles             *parent = NULL;
715
 
        struct mapi_handles             *rec = NULL;
716
752
        void                            *private_data;
717
 
        struct emsmdbp_object           *object = NULL;
 
753
        struct emsmdbp_object           *object;
718
754
        uint32_t                        handle;
 
755
        struct WriteStream_req          *request;
719
756
 
720
757
        DEBUG(4, ("exchange_emsmdb: [OXCPRPT] WriteStream (0x2d)\n"));
721
758
 
729
766
        mapi_repl->opnum = mapi_req->opnum;
730
767
        mapi_repl->error_code = MAPI_E_SUCCESS;
731
768
        mapi_repl->handle_idx = mapi_req->handle_idx;
732
 
        mapi_repl->u.mapi_WriteStream.WrittenSize = mapi_req->u.mapi_WriteStream.data.length;
 
769
        mapi_repl->u.mapi_WriteStream.WrittenSize = 0;
733
770
 
734
771
        /* Step 1. Retrieve parent handle in the hierarchy */
735
772
        handle = handles[mapi_req->handle_idx];
736
773
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
737
 
        if (retval) goto end;
 
774
        if (retval) {
 
775
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
776
                DEBUG(5, ("  handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
777
                goto end;
 
778
        }
738
779
 
739
 
        retval = mapi_handles_get_private_data(rec, &private_data);
 
780
        retval = mapi_handles_get_private_data(parent, &private_data);
740
781
        object = (struct emsmdbp_object *) private_data;
741
 
        if (!object || object->type != EMSMDBP_OBJECT_STREAM) goto end;
742
 
 
743
 
        /* TODO effective work goes here */
 
782
        if (!object || object->type != EMSMDBP_OBJECT_STREAM) {
 
783
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
784
                DEBUG(5, ("  invalid object\n"));
 
785
                goto end;
 
786
        }
 
787
 
 
788
        if (!object->object.stream->read_write) {
 
789
                mapi_repl->error_code = MAPI_E_NO_ACCESS;
 
790
                goto end;
 
791
        }
 
792
 
 
793
        request = &mapi_req->u.mapi_WriteStream;
 
794
        if (request->data.length > 0) {
 
795
                emsmdbp_stream_write_buffer(object->object.stream, &object->object.stream->stream, request->data);
 
796
                mapi_repl->u.mapi_WriteStream.WrittenSize = request->data.length;
 
797
        }
 
798
 
 
799
        object->object.stream->needs_commit = true;
744
800
end:
745
801
        *size += libmapiserver_RopWriteStream_size(mapi_repl);
746
802
 
747
803
        return MAPI_E_SUCCESS;
748
804
}
749
805
 
 
806
/**
 
807
   \details EcDoRpc CommitStream (0x5d) Rop.
 
808
 
 
809
   \param mem_ctx pointer to the memory context
 
810
   \param emsmdbp_ctx pointer to the emsmdb provider context
 
811
   \param mapi_req pointer to the DeleteProperties EcDoRpc_MAPI_REQ
 
812
   structure
 
813
   \param mapi_repl pointer to the DeleteProperties EcDoRpc_MAPI_REPL
 
814
   structure
 
815
   \param handles pointer to the MAPI handles array
 
816
   \param size pointer to the mapi_response size to update
 
817
 
 
818
   \return MAPI_E_SUCCESS on success, otherwise MAPI error
 
819
 */
 
820
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopCommitStream(TALLOC_CTX *mem_ctx,
 
821
                                                 struct emsmdbp_context *emsmdbp_ctx,
 
822
                                                 struct EcDoRpc_MAPI_REQ *mapi_req,
 
823
                                                 struct EcDoRpc_MAPI_REPL *mapi_repl,
 
824
                                                 uint32_t *handles, uint16_t *size)
 
825
{
 
826
        enum MAPISTATUS                 retval;
 
827
        struct mapi_handles             *rec = NULL;
 
828
        struct emsmdbp_object           *object = NULL;
 
829
        uint32_t                        handle;
 
830
        void                            *private_data;
 
831
 
 
832
        DEBUG(4, ("exchange_emsmdb: [OXCPRPT] CommitStream (0x5d)\n"));
 
833
 
 
834
        /* Sanity checks */
 
835
        OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
 
836
        OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
 
837
        OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
 
838
        OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
 
839
        OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
 
840
 
 
841
        mapi_repl->opnum = mapi_req->opnum;
 
842
        mapi_repl->error_code = MAPI_E_SUCCESS;
 
843
        mapi_repl->handle_idx = mapi_req->handle_idx;
 
844
 
 
845
 
 
846
        /* Step 1. Retrieve parent handle in the hierarchy */
 
847
        handle = handles[mapi_req->handle_idx];
 
848
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
 
849
        if (retval) {
 
850
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
851
                DEBUG(5, ("  handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
852
                goto end;
 
853
        }
 
854
 
 
855
        retval = mapi_handles_get_private_data(rec, &private_data);
 
856
        object = (struct emsmdbp_object *) private_data;
 
857
        if (!object || object->type != EMSMDBP_OBJECT_STREAM) {
 
858
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
859
                DEBUG(5, ("  invalid object\n"));
 
860
                goto end;
 
861
        }
 
862
 
 
863
        if (!object->object.stream->read_write) {
 
864
                mapi_repl->error_code = MAPI_E_NO_ACCESS;
 
865
                goto end;
 
866
        }
 
867
 
 
868
        emsmdbp_object_stream_commit(object);
 
869
 
 
870
end:
 
871
        *size += libmapiserver_RopCommitStream_size(mapi_repl);
 
872
 
 
873
        return MAPI_E_SUCCESS;
 
874
}
 
875
 
 
876
/**
 
877
   \details EcDoRpc GetStreamSize (0x5e) Rop. This operation returns the
 
878
   number of bytes in a stream.
 
879
 
 
880
   \param mem_ctx pointer to the memory context
 
881
   \param emsmdbp_ctx pointer to the emsmdb provider context
 
882
   \param mapi_req pointer to the WriteStream EcDoRpc_MAPI_REQ
 
883
   structure
 
884
   \param mapi_repl pointer to the WriteStream EcDoRpc_MAPI_REPL
 
885
   structure
 
886
   \param handles pointer to the MAPI handles array
 
887
   \param size pointer to the mapi response size to update
 
888
 
 
889
   \return MAPI_E_SUCCESS on success, otherwise MAPI error
 
890
 */
 
891
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetStreamSize(TALLOC_CTX *mem_ctx,
 
892
                                                  struct emsmdbp_context *emsmdbp_ctx,
 
893
                                                  struct EcDoRpc_MAPI_REQ *mapi_req,
 
894
                                                  struct EcDoRpc_MAPI_REPL *mapi_repl,
 
895
                                                  uint32_t *handles, uint16_t *size)
 
896
{
 
897
        enum MAPISTATUS                 retval;
 
898
        struct mapi_handles             *parent = NULL;
 
899
        void                            *private_data;
 
900
        struct emsmdbp_object           *object = NULL;
 
901
        uint32_t                        handle;
 
902
 
 
903
        DEBUG(4, ("exchange_emsmdb: [OXCPRPT] GetStreamSize (0x5e)\n"));
 
904
 
 
905
        /* Sanity checks */
 
906
        OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
 
907
        OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
 
908
        OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
 
909
        OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
 
910
        OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
 
911
 
 
912
        mapi_repl->opnum = mapi_req->opnum;
 
913
        mapi_repl->error_code = MAPI_E_SUCCESS;
 
914
        mapi_repl->handle_idx = mapi_req->handle_idx;
 
915
 
 
916
        /* Step 1. Retrieve parent handle in the hierarchy */
 
917
        handle = handles[mapi_req->handle_idx];
 
918
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
 
919
        if (retval) {
 
920
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
921
                DEBUG(5, ("  handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
922
                goto end;
 
923
        }
 
924
 
 
925
        retval = mapi_handles_get_private_data(parent, &private_data);
 
926
        object = (struct emsmdbp_object *) private_data;
 
927
        if (!object || object->type != EMSMDBP_OBJECT_STREAM) {
 
928
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
929
                DEBUG(5, ("  invalid object\n"));
 
930
                goto end;
 
931
        }
 
932
 
 
933
        mapi_repl->u.mapi_GetStreamSize.StreamSize = object->object.stream->stream.buffer.length;
 
934
 
 
935
end:
 
936
        *size += libmapiserver_RopGetStreamSize_size(mapi_repl);
 
937
 
 
938
        return MAPI_E_SUCCESS;
 
939
}
 
940
 
 
941
/**
 
942
   \details EcDoRpc SeekStream (0x2e) Rop. This operation positions the cursor
 
943
   in the stream.
 
944
 
 
945
   \param mem_ctx pointer to the memory context
 
946
   \param emsmdbp_ctx pointer to the emsmdb provider context
 
947
   \param mapi_req pointer to the WriteStream EcDoRpc_MAPI_REQ
 
948
   structure
 
949
   \param mapi_repl pointer to the WriteStream EcDoRpc_MAPI_REPL
 
950
   structure
 
951
   \param handles pointer to the MAPI handles array
 
952
   \param size pointer to the mapi response size to update
 
953
 
 
954
   \return MAPI_E_SUCCESS on success, otherwise MAPI error
 
955
 */
 
956
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSeekStream(TALLOC_CTX *mem_ctx,
 
957
                                               struct emsmdbp_context *emsmdbp_ctx,
 
958
                                               struct EcDoRpc_MAPI_REQ *mapi_req,
 
959
                                               struct EcDoRpc_MAPI_REPL *mapi_repl,
 
960
                                               uint32_t *handles, uint16_t *size)
 
961
{
 
962
        enum MAPISTATUS                 retval;
 
963
        struct mapi_handles             *parent = NULL;
 
964
        void                            *private_data;
 
965
        struct emsmdbp_object           *object = NULL;
 
966
        uint32_t                        handle, new_position;
 
967
 
 
968
        DEBUG(4, ("exchange_emsmdb: [OXCPRPT] SeekStream (0x2e)\n"));
 
969
 
 
970
        /* Sanity checks */
 
971
        OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
 
972
        OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
 
973
        OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
 
974
        OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
 
975
        OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
 
976
 
 
977
        mapi_repl->opnum = mapi_req->opnum;
 
978
        mapi_repl->error_code = MAPI_E_SUCCESS;
 
979
        mapi_repl->handle_idx = mapi_req->handle_idx;
 
980
 
 
981
        /* Step 1. Retrieve parent handle in the hierarchy */
 
982
        handle = handles[mapi_req->handle_idx];
 
983
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
 
984
        if (retval) {
 
985
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
986
                DEBUG(5, ("  handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
987
                goto end;
 
988
        }
 
989
 
 
990
        retval = mapi_handles_get_private_data(parent, &private_data);
 
991
        object = (struct emsmdbp_object *) private_data;
 
992
        if (!object || object->type != EMSMDBP_OBJECT_STREAM) {
 
993
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
994
                DEBUG(5, ("  invalid object\n"));
 
995
                goto end;
 
996
        }
 
997
 
 
998
        switch (mapi_req->u.mapi_SeekStream.Origin) {
 
999
        case 0: /* beginning */
 
1000
                new_position = 0;
 
1001
                break;
 
1002
        case 1: /* current */
 
1003
                new_position = object->object.stream->stream.position;
 
1004
                break;
 
1005
        case 2: /* end */
 
1006
                new_position = object->object.stream->stream.buffer.length;
 
1007
                break;
 
1008
        default:
 
1009
                mapi_repl->error_code = MAPI_E_INVALID_PARAMETER;
 
1010
                goto end;
 
1011
        }
 
1012
 
 
1013
        new_position += mapi_req->u.mapi_SeekStream.Offset;
 
1014
        if (new_position < object->object.stream->stream.buffer.length + 1) {
 
1015
                object->object.stream->stream.position = new_position;
 
1016
                mapi_repl->u.mapi_SeekStream.NewPosition = new_position;
 
1017
        }
 
1018
        else {
 
1019
                mapi_repl->error_code = MAPI_E_DISK_ERROR;
 
1020
        }
 
1021
 
 
1022
end:
 
1023
        *size += libmapiserver_RopSeekStream_size(mapi_repl);
 
1024
 
 
1025
        return MAPI_E_SUCCESS;
 
1026
}
 
1027
 
 
1028
 
 
1029
/**
 
1030
   \details EcDoRpc SetStreamSize (0x2f) Rop. This operation
 
1031
   copy messages from one folder to another.
 
1032
 
 
1033
   \param mem_ctx pointer to the memory context
 
1034
   \param emsmdbp_ctx pointer to the emsmdb provider context
 
1035
   \param mapi_req pointer to the DeleteProperties EcDoRpc_MAPI_REQ
 
1036
   structure
 
1037
   \param mapi_repl pointer to the DeleteProperties EcDoRpc_MAPI_REPL
 
1038
   structure
 
1039
   \param handles pointer to the MAPI handles array
 
1040
   \param size pointer to the mapi_response size to update
 
1041
 
 
1042
   \return MAPI_E_SUCCESS on success, otherwise MAPI error
 
1043
 */
 
1044
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetStreamSize(TALLOC_CTX *mem_ctx,
 
1045
                                                  struct emsmdbp_context *emsmdbp_ctx,
 
1046
                                                  struct EcDoRpc_MAPI_REQ *mapi_req,
 
1047
                                                  struct EcDoRpc_MAPI_REPL *mapi_repl,
 
1048
                                                  uint32_t *handles, uint16_t *size)
 
1049
{
 
1050
        enum MAPISTATUS                 retval;
 
1051
        struct mapi_handles             *parent = NULL;
 
1052
        void                            *private_data;
 
1053
        struct emsmdbp_object           *object;
 
1054
        uint32_t                        handle;
 
1055
        struct SetStreamSize_req        *request;
 
1056
 
 
1057
        DEBUG(4, ("exchange_emsmdb: [OXCPRPT] SetStreamSize (0x2f)\n"));
 
1058
 
 
1059
        /* Sanity checks */
 
1060
        OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
 
1061
        OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
 
1062
        OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
 
1063
        OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
 
1064
        OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
 
1065
 
 
1066
        mapi_repl->opnum = mapi_req->opnum;
 
1067
        mapi_repl->error_code = MAPI_E_SUCCESS;
 
1068
        mapi_repl->handle_idx = mapi_req->handle_idx;
 
1069
        mapi_repl->u.mapi_WriteStream.WrittenSize = 0;
 
1070
 
 
1071
        /* Step 1. Retrieve parent handle in the hierarchy */
 
1072
        handle = handles[mapi_req->handle_idx];
 
1073
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
 
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(parent, &private_data);
 
1081
        object = (struct emsmdbp_object *) private_data;
 
1082
        if (!object || object->type != EMSMDBP_OBJECT_STREAM) {
 
1083
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
1084
                DEBUG(5, ("  invalid object\n"));
 
1085
                goto end;
 
1086
        }
 
1087
 
 
1088
        request = &mapi_req->u.mapi_SetStreamSize;
 
1089
        object->object.stream->stream.buffer.length = request->SizeStream;
 
1090
 
 
1091
end:
 
1092
        *size += libmapiserver_RopSetStreamSize_size(mapi_repl);
 
1093
 
 
1094
        return MAPI_E_SUCCESS;
 
1095
}
750
1096
 
751
1097
/**
752
1098
   \details EcDoRpc GetPropertyIdsFromNames (0x56) Rop. This operation
769
1115
                                                            struct EcDoRpc_MAPI_REPL *mapi_repl,
770
1116
                                                            uint32_t *handles, uint16_t *size)
771
1117
{
772
 
        int             i;
 
1118
        int             i, ret;
 
1119
        struct GUID     *lpguid;
 
1120
        bool            has_transaction = false;
 
1121
        uint16_t        mapped_id;
773
1122
 
774
1123
        DEBUG(4, ("exchange_emsmdb: [OXCPRPT] GetPropertyIdsFromNames (0x56)\n"));
775
1124
 
788
1137
                                                                mapi_req->u.mapi_GetIDsFromNames.count);
789
1138
 
790
1139
        for (i = 0; i < mapi_req->u.mapi_GetIDsFromNames.count; i++) {
791
 
                mapistore_namedprops_get_mapped_id(emsmdbp_ctx->mstore_ctx->mapistore_nprops_ctx, 
792
 
                                                   mapi_req->u.mapi_GetIDsFromNames.nameid[i],
793
 
                                                   &mapi_repl->u.mapi_GetIDsFromNames.propID[i]);
 
1140
                ret = mapistore_namedprops_get_mapped_id(emsmdbp_ctx->mstore_ctx->nprops_ctx, 
 
1141
                                                         mapi_req->u.mapi_GetIDsFromNames.nameid[i],
 
1142
                                                         &mapi_repl->u.mapi_GetIDsFromNames.propID[i]);
 
1143
                if (ret != MAPISTORE_SUCCESS) {
 
1144
                        if (mapi_req->u.mapi_GetIDsFromNames.ulFlags == GetIDsFromNames_GetOrCreate) {
 
1145
                                if (!has_transaction) {
 
1146
                                        has_transaction = true;
 
1147
                                        ldb_transaction_start(emsmdbp_ctx->mstore_ctx->nprops_ctx);
 
1148
                                        mapped_id = mapistore_namedprops_next_unused_id(emsmdbp_ctx->mstore_ctx->nprops_ctx);
 
1149
                                        if (mapped_id == 0) {
 
1150
                                                abort();
 
1151
                                        }
 
1152
                                }
 
1153
                                else {
 
1154
                                        mapped_id++;
 
1155
                                }
 
1156
                                mapistore_namedprops_create_id(emsmdbp_ctx->mstore_ctx->nprops_ctx,
 
1157
                                                               mapi_req->u.mapi_GetIDsFromNames.nameid[i],
 
1158
                                                               mapped_id);
 
1159
                                mapi_repl->u.mapi_GetIDsFromNames.propID[i] = mapped_id;
 
1160
                        }
 
1161
                        else {
 
1162
                                mapi_repl->u.mapi_GetIDsFromNames.propID[i] = 0x0000;
 
1163
                                lpguid = &mapi_req->u.mapi_GetIDsFromNames.nameid[i].lpguid;
 
1164
                                DEBUG(5, ("  no mapping for property %.8x-%.4x-%.4x-%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x:",
 
1165
                                          lpguid->time_low, lpguid->time_mid, lpguid->time_hi_and_version,
 
1166
                                          lpguid->clock_seq[0], lpguid->clock_seq[1],
 
1167
                                          lpguid->node[0], lpguid->node[1],
 
1168
                                          lpguid->node[2], lpguid->node[3],
 
1169
                                          lpguid->node[4], lpguid->node[5]));
 
1170
                                
 
1171
                                if (mapi_req->u.mapi_GetIDsFromNames.nameid[i].ulKind == MNID_ID)
 
1172
                                        DEBUG(5, ("%.4x\n", mapi_req->u.mapi_GetIDsFromNames.nameid[i].kind.lid));
 
1173
                                else if (mapi_req->u.mapi_GetIDsFromNames.nameid[i].ulKind == MNID_STRING)
 
1174
                                        DEBUG(5, ("%s\n", mapi_req->u.mapi_GetIDsFromNames.nameid[i].kind.lpwstr.Name));
 
1175
                                else
 
1176
                                        DEBUG(5, ("[invalid ulKind]"));
 
1177
 
 
1178
                                mapi_repl->error_code = MAPI_W_ERRORS_RETURNED;
 
1179
                        }
 
1180
                }
 
1181
        }
 
1182
 
 
1183
        if (has_transaction) {
 
1184
                ldb_transaction_commit(emsmdbp_ctx->mstore_ctx->nprops_ctx);
794
1185
        }
795
1186
 
796
1187
        *size += libmapiserver_RopGetPropertyIdsFromNames_size(mapi_repl);
797
1188
 
798
1189
        return MAPI_E_SUCCESS;
799
1190
}
 
1191
 
 
1192
/**
 
1193
   \details EcDoRpc GetNamesFromIDs (0x56) Rop. This operation
 
1194
   gets property IDs for specified property names.
 
1195
 
 
1196
   \param mem_ctx pointer to the memory context
 
1197
   \param emsmdbp_ctx pointer to the emsmdb provider context
 
1198
   \param mapi_req pointer to the GetNamesFromIDs
 
1199
   EcDoRpc_MAPI_REQ structure
 
1200
   \param mapi_repl pointer to the GetNamesFromIDs
 
1201
   EcDoRpc_MAPI_REPL structure
 
1202
   \param handles pointer to the MAPI handles array
 
1203
   \param size pointer to the mapi_response size to update
 
1204
 
 
1205
   \return MAPI_E_SUCCESS on success, otherwise MAPI error
 
1206
*/
 
1207
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetNamesFromIDs(TALLOC_CTX *mem_ctx,
 
1208
                                                    struct emsmdbp_context *emsmdbp_ctx,
 
1209
                                                    struct EcDoRpc_MAPI_REQ *mapi_req,
 
1210
                                                    struct EcDoRpc_MAPI_REPL *mapi_repl,
 
1211
                                                    uint32_t *handles, uint16_t *size)
 
1212
{
 
1213
        uint16_t                        i;
 
1214
        struct GetNamesFromIDs_req      *request;
 
1215
        struct GetNamesFromIDs_repl     *response;
 
1216
        struct MAPINAMEID               *nameid;
 
1217
 
 
1218
        DEBUG(4, ("exchange_emsmdb: [OXCPRPT] GetNamesFromIDs (0x55)\n"));
 
1219
 
 
1220
        /* Sanity checks */
 
1221
        OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
 
1222
        OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
 
1223
        OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
 
1224
        OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
 
1225
        OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
 
1226
 
 
1227
        mapi_repl->opnum = mapi_req->opnum;
 
1228
        mapi_repl->error_code = MAPI_E_SUCCESS;
 
1229
        mapi_repl->handle_idx = mapi_req->handle_idx;
 
1230
 
 
1231
        request = &mapi_req->u.mapi_GetNamesFromIDs;
 
1232
        response = &mapi_repl->u.mapi_GetNamesFromIDs;
 
1233
 
 
1234
        response->nameid = talloc_array(mem_ctx, struct MAPINAMEID, request->PropertyIdCount);
 
1235
        response->count = request->PropertyIdCount;
 
1236
        for (i = 0; i < request->PropertyIdCount; i++) {
 
1237
                if (request->PropertyIds[i] < 0x8000) {
 
1238
                        response->nameid[i].ulKind = MNID_ID;
 
1239
                        GUID_from_string(PS_MAPI, &response->nameid[i].lpguid);
 
1240
                        response->nameid[i].kind.lid = (uint32_t) request->PropertyIds[i] << 16 | get_property_type(request->PropertyIds[i]);
 
1241
                }
 
1242
                else if (mapistore_namedprops_get_nameid(emsmdbp_ctx->mstore_ctx->nprops_ctx, request->PropertyIds[i], &nameid) == MAPISTORE_SUCCESS) {
 
1243
                        response->nameid[i] = *nameid;
 
1244
                }
 
1245
                else {
 
1246
                        response->nameid[i].ulKind = 0xff;
 
1247
                }
 
1248
        }
 
1249
 
 
1250
        *size += libmapiserver_RopGetNamesFromIDs_size(mapi_repl);
 
1251
 
 
1252
        return MAPI_E_SUCCESS;
 
1253
}
 
1254
 
 
1255
/**
 
1256
   \details EcDoRpc DeletePropertiesNoReplicate (0x7a) Rop. deletes property
 
1257
   values from an object without invoking replication.
 
1258
 
 
1259
   \param mem_ctx pointer to the memory context
 
1260
   \param emsmdbp_ctx pointer to the emsmdb provider context
 
1261
   \param mapi_req pointer to the DeletePropertiesNoReplicate
 
1262
   EcDoRpc_MAPI_REQ structure
 
1263
   \param mapi_repl pointer to the DeletePropertiesNoReplicate
 
1264
   EcDoRpc_MAPI_REPL structure
 
1265
   \param handles pointer to the MAPI handles array
 
1266
   \param size pointer to the mapi_response size to update
 
1267
 
 
1268
   \return MAPI_E_SUCCESS on success, otherwise MAPI error
 
1269
*/
 
1270
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopDeletePropertiesNoReplicate(TALLOC_CTX *mem_ctx,
 
1271
                                                                struct emsmdbp_context *emsmdbp_ctx,
 
1272
                                                                struct EcDoRpc_MAPI_REQ *mapi_req,
 
1273
                                                                struct EcDoRpc_MAPI_REPL *mapi_repl,
 
1274
                                                                uint32_t *handles, uint16_t *size)
 
1275
{
 
1276
        DEBUG(4, ("exchange_emsmdb: [OXCPRPT] DeletePropertiesNoReplicate (0x7a) -- stub\n"));
 
1277
 
 
1278
        /* Sanity checks */
 
1279
        OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
 
1280
        OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
 
1281
        OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
 
1282
        OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
 
1283
        OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
 
1284
 
 
1285
        mapi_repl->opnum = mapi_req->opnum;
 
1286
        mapi_repl->error_code = MAPI_E_SUCCESS;
 
1287
        mapi_repl->handle_idx = mapi_req->handle_idx;
 
1288
 
 
1289
        mapi_repl->u.mapi_DeletePropertiesNoReplicate.PropertyProblemCount = 0;
 
1290
        mapi_repl->u.mapi_DeletePropertiesNoReplicate.PropertyProblem = NULL;
 
1291
 
 
1292
        *size += libmapiserver_RopDeletePropertiesNoReplicate_size(mapi_repl);
 
1293
 
 
1294
        return MAPI_E_SUCCESS;
 
1295
}
 
1296
 
 
1297
/**
 
1298
   \details EcDoRpc CopyTo (0x39) Rop. This operation
 
1299
   copy messages from one folder to another.
 
1300
 
 
1301
   \param mem_ctx pointer to the memory context
 
1302
   \param emsmdbp_ctx pointer to the emsmdb provider context
 
1303
   \param mapi_req pointer to the DeleteProperties EcDoRpc_MAPI_REQ
 
1304
   structure
 
1305
   \param mapi_repl pointer to the DeleteProperties EcDoRpc_MAPI_REPL
 
1306
   structure
 
1307
   \param handles pointer to the MAPI handles array
 
1308
   \param size pointer to the mapi_response size to update
 
1309
 
 
1310
   \return MAPI_E_SUCCESS on success, otherwise MAPI error
 
1311
 */
 
1312
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopCopyTo(TALLOC_CTX *mem_ctx,
 
1313
                                           struct emsmdbp_context *emsmdbp_ctx,
 
1314
                                           struct EcDoRpc_MAPI_REQ *mapi_req,
 
1315
                                           struct EcDoRpc_MAPI_REPL *mapi_repl,
 
1316
                                           uint32_t *handles, uint16_t *size)
 
1317
{
 
1318
        struct CopyTo_req       *request;
 
1319
        struct CopyTo_repl      *response;
 
1320
        enum MAPISTATUS         retval;
 
1321
        uint32_t                handle;
 
1322
        struct mapi_handles     *rec = NULL;
 
1323
        void                    *private_data = NULL;
 
1324
        struct emsmdbp_object   *source_object;
 
1325
        struct emsmdbp_object   *dest_object;
 
1326
        struct SPropTagArray    excluded_tags;
 
1327
 
 
1328
        DEBUG(4, ("exchange_emsmdb: [OXCPRPT] CopyTo (0x39)\n"));
 
1329
 
 
1330
        /* Sanity checks */
 
1331
        OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
 
1332
        OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
 
1333
        OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
 
1334
        OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
 
1335
        OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
 
1336
 
 
1337
        request = &mapi_req->u.mapi_CopyTo;
 
1338
        response = &mapi_repl->u.mapi_CopyTo;
 
1339
 
 
1340
        mapi_repl->opnum = mapi_req->opnum;
 
1341
        mapi_repl->error_code = MAPI_E_SUCCESS;
 
1342
        mapi_repl->handle_idx = mapi_req->handle_idx;
 
1343
        
 
1344
        response->PropertyProblemCount = 0;
 
1345
        response->PropertyProblem = NULL;
 
1346
 
 
1347
        if (request->WantAsynchronous) {
 
1348
                DEBUG(0, ("  warning: asynchronous operations are not supported\n"));
 
1349
        }
 
1350
        if ((request->CopyFlags & CopyFlagsMove)) {
 
1351
                DEBUG(0, ("  moving properties is not supported\n"));
 
1352
        }
 
1353
        if ((request->CopyFlags & CopyFlagsNoOverwrite)) {
 
1354
                DEBUG(0, ("  properties WILL BE overwriten despite the operation flags\n"));
 
1355
        }
 
1356
 
 
1357
        /* Get the source object */
 
1358
        handle = handles[mapi_req->handle_idx];
 
1359
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
 
1360
        if (retval) {
 
1361
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
1362
                DEBUG(0, ("  handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
1363
                goto end;
 
1364
        }
 
1365
 
 
1366
        retval = mapi_handles_get_private_data(rec, &private_data);
 
1367
        source_object = private_data;
 
1368
        if (!source_object) {
 
1369
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
1370
                DEBUG(0, ("  object (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
1371
                goto end;
 
1372
        }
 
1373
 
 
1374
        /* Get the destination object */
 
1375
        handle = handles[request->handle_idx];
 
1376
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
 
1377
        if (retval) {
 
1378
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
1379
                DEBUG(0, ("  handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
1380
                goto end;
 
1381
        }
 
1382
 
 
1383
        retval = mapi_handles_get_private_data(rec, &private_data);
 
1384
        dest_object = private_data;
 
1385
        if (!dest_object) {
 
1386
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
1387
                DEBUG(0, ("  object (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
1388
                goto end;
 
1389
        }
 
1390
 
 
1391
        excluded_tags.cValues = request->ExcludedTags.cValues;
 
1392
        excluded_tags.aulPropTag = request->ExcludedTags.aulPropTag;
 
1393
 
 
1394
        mapi_repl->error_code = emsmdbp_object_copy_properties(emsmdbp_ctx, source_object, dest_object, &excluded_tags, request->WantSubObjects);
 
1395
 
 
1396
end:
 
1397
        *size += libmapiserver_RopCopyTo_size(mapi_repl);
 
1398
 
 
1399
        return MAPI_E_SUCCESS;
 
1400
}