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

« back to all changes in this revision

Viewing changes to mapiproxy/servers/default/emsmdb/oxctabl.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
79
79
 
80
80
        handle = handles[mapi_req->handle_idx];
81
81
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
82
 
        OPENCHANGE_RETVAL_IF(retval, retval, NULL);
 
82
        if (retval) {
 
83
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
84
                DEBUG(5, ("  handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
85
                goto end;
 
86
        }
83
87
 
84
88
        retval = mapi_handles_get_private_data(parent, &data);
 
89
        if (retval) {
 
90
                mapi_repl->error_code = retval;
 
91
                DEBUG(5, ("  handle data not found, idx = %x\n", mapi_req->handle_idx));
 
92
                goto end;
 
93
        }
 
94
 
85
95
        object = (struct emsmdbp_object *) data;
86
96
 
87
97
        if (object) {
88
98
                table = object->object.table;
89
99
                OPENCHANGE_RETVAL_IF(!table, MAPI_E_INVALID_PARAMETER, NULL);
90
100
 
 
101
                if (table->ulType == MAPISTORE_RULE_TABLE) {
 
102
                        DEBUG(5, ("  query on rules table are all faked right now\n"));
 
103
                        goto end;
 
104
                }
 
105
 
91
106
                request = mapi_req->u.mapi_SetColumns;
 
107
 
92
108
                if (request.prop_count) {
93
109
                        table->prop_count = request.prop_count;
94
 
                        table->properties = (uint32_t *) talloc_memdup(table, request.properties, 
95
 
                                                                       request.prop_count * sizeof (uint32_t));
 
110
                        table->properties = talloc_memdup(table, request.properties, 
 
111
                                                          request.prop_count * sizeof (uint32_t));
 
112
                        if (emsmdbp_is_mapistore(object)) {
 
113
                                DEBUG(5, ("[%s] object: %p, backend_object: %p\n", __FUNCTION__, object, object->backend_object));
 
114
                                mapistore_table_set_columns(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(object),
 
115
                                                            object->backend_object, request.prop_count, request.properties);
 
116
                        } else {
 
117
                                /* openchangedb case */
 
118
                                DEBUG(5, ("[%s] object: Setting Columns on openchangedb table\n", __FUNCTION__));
 
119
                        }
96
120
                }
97
121
        }
 
122
end:
98
123
 
99
 
        DEBUG(0, ("RopSetColumns: returns MAPI_E_SUCCESS\n"));
100
124
        return MAPI_E_SUCCESS;
101
125
}
102
126
 
122
146
                                              struct EcDoRpc_MAPI_REPL *mapi_repl,
123
147
                                              uint32_t *handles, uint16_t *size)
124
148
{
 
149
        enum MAPISTATUS                 retval;
 
150
        struct mapi_handles             *parent;
 
151
        struct emsmdbp_object           *object;
 
152
        struct emsmdbp_object_table     *table;
 
153
        struct SortTable_req            *request;
 
154
        uint32_t                        handle;
 
155
        void                            *data = NULL;
 
156
        uint8_t                         status;
 
157
 
125
158
        DEBUG(4, ("exchange_emsmdb: [OXCTABL] SortTable (0x13)\n"));
126
159
 
127
160
        /* Sanity checks */
136
169
        mapi_repl->error_code = MAPI_E_SUCCESS;
137
170
        mapi_repl->u.mapi_SortTable.TableStatus = TBLSTAT_COMPLETE;
138
171
 
 
172
        if ((mapi_req->u.mapi_SortTable.SortTableFlags & TBL_ASYNC)) {
 
173
                DEBUG(5, ("  requested async operation -> failure\n"));
 
174
                mapi_repl->error_code = MAPI_E_UNKNOWN_FLAGS;
 
175
                goto end;
 
176
        }
 
177
 
 
178
        handle = handles[mapi_req->handle_idx];
 
179
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
 
180
        if (retval) {
 
181
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
182
                DEBUG(5, ("  handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
183
                goto end;
 
184
        }
 
185
 
 
186
        retval = mapi_handles_get_private_data(parent, &data);
 
187
        if (retval) {
 
188
                mapi_repl->error_code = retval;
 
189
                DEBUG(5, ("  handle data not found, idx = %x\n", mapi_req->handle_idx));
 
190
                goto end;
 
191
        }
 
192
        object = (struct emsmdbp_object *) data;
 
193
 
 
194
        /* Ensure referring object exists and is a table */
 
195
        if (!object || (object->type != EMSMDBP_OBJECT_TABLE)) {
 
196
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
197
                DEBUG(5, ("  missing object or not table\n"));
 
198
                goto end;
 
199
        }
 
200
 
 
201
        table = object->object.table;
 
202
        OPENCHANGE_RETVAL_IF(!table, MAPI_E_INVALID_PARAMETER, NULL);
 
203
 
 
204
        if (table->ulType != MAPISTORE_MESSAGE_TABLE
 
205
            && table->ulType != MAPISTORE_FAI_TABLE) {
 
206
                mapi_repl->error_code = MAPI_E_NO_SUPPORT;
 
207
                DEBUG(5, ("  query performed on non contents table\n"));
 
208
                goto end;
 
209
        }
 
210
 
 
211
        OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
 
212
 
 
213
        /* we reset the cursor to the beginning of the table */
 
214
        table->numerator = 0;
 
215
 
 
216
        /* TODO: we should invalidate current bookmarks on the table */
 
217
 
 
218
        /* If parent folder has a mapistore context */
 
219
        request = &mapi_req->u.mapi_SortTable;
 
220
        if (emsmdbp_is_mapistore(object)) {
 
221
                status = TBLSTAT_COMPLETE;
 
222
                retval = mapistore_table_set_sort_order(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(object), object->backend_object, &request->lpSortCriteria, &status);
 
223
                if (retval) {
 
224
                        mapi_repl->error_code = retval;
 
225
                        goto end;
 
226
                }
 
227
                mapi_repl->u.mapi_SortTable.TableStatus = status;
 
228
        } else {
 
229
                /* Parent folder doesn't have any mapistore context associated */
 
230
                status = TBLSTAT_COMPLETE;
 
231
                mapi_repl->u.mapi_SortTable.TableStatus = status;
 
232
                retval = openchangedb_table_set_sort_order(object->backend_object, &request->lpSortCriteria);
 
233
                if (retval) {
 
234
                        mapi_repl->error_code = retval;
 
235
                        goto end;
 
236
                }
 
237
        }
 
238
        
 
239
end:
139
240
        *size += libmapiserver_RopSortTable_size(mapi_repl);
140
241
 
141
242
        return MAPI_E_SUCCESS;
162
263
                                             struct EcDoRpc_MAPI_REPL *mapi_repl,
163
264
                                             uint32_t *handles, uint16_t *size)
164
265
{
 
266
        enum MAPISTATUS                 retval;
 
267
        struct mapi_handles             *parent;
 
268
        struct emsmdbp_object           *object;
 
269
        struct emsmdbp_object_table     *table;
 
270
        struct Restrict_req             request;
 
271
        uint32_t                        handle, contextID;
 
272
        void                            *data = NULL;
 
273
        uint8_t                         status;
 
274
 
165
275
        DEBUG(4, ("exchange_emsmdb: [OXCTABL] Restrict (0x14)\n"));
166
276
 
167
277
        /* Sanity checks */
171
281
        OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
172
282
        OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
173
283
        
 
284
        request = mapi_req->u.mapi_Restrict;
 
285
 
174
286
        mapi_repl->opnum = mapi_req->opnum;
175
287
        mapi_repl->handle_idx = mapi_req->handle_idx;
176
288
        mapi_repl->error_code = MAPI_E_SUCCESS;
177
289
        mapi_repl->u.mapi_Restrict.TableStatus = TBLSTAT_COMPLETE;
178
290
 
 
291
        handle = handles[mapi_req->handle_idx];
 
292
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
 
293
        if (retval) {
 
294
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
295
                DEBUG(5, ("  handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
296
                goto end;
 
297
        }
 
298
 
 
299
        retval = mapi_handles_get_private_data(parent, &data);
 
300
        if (retval) {
 
301
                mapi_repl->error_code = retval;
 
302
                DEBUG(5, ("  handle data not found, idx = %x\n", mapi_req->handle_idx));
 
303
                goto end;
 
304
        }
 
305
        object = (struct emsmdbp_object *) data;
 
306
 
 
307
        /* Ensure referring object exists and is a table */
 
308
        if (!object || (object->type != EMSMDBP_OBJECT_TABLE)) {
 
309
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
310
                DEBUG(5, ("  missing object or not table\n"));
 
311
                goto end;
 
312
        }
 
313
 
 
314
        table = object->object.table;
 
315
        OPENCHANGE_RETVAL_IF(!table, MAPI_E_INVALID_PARAMETER, NULL);
 
316
 
 
317
        table->restricted = true;
 
318
        if (table->ulType == MAPISTORE_RULE_TABLE) {
 
319
                DEBUG(5, ("  query on rules table are all faked right now\n"));
 
320
                goto end;
 
321
        }
 
322
 
 
323
        /* If parent folder has a mapistore context */
 
324
        if (emsmdbp_is_mapistore(object)) {
 
325
                status = TBLSTAT_COMPLETE;
 
326
                contextID = emsmdbp_get_contextID(object);
 
327
                retval = mapistore_table_set_restrictions(emsmdbp_ctx->mstore_ctx, contextID, object->backend_object, &request.restrictions, &status);
 
328
                if (retval) {
 
329
                        mapi_repl->error_code = retval;
 
330
                        goto end;
 
331
                }
 
332
 
 
333
                mapistore_table_get_row_count(emsmdbp_ctx->mstore_ctx, contextID, object->backend_object, MAPISTORE_PREFILTERED_QUERY, &object->object.table->denominator);
 
334
                
 
335
                mapi_repl->u.mapi_Restrict.TableStatus = status;
 
336
 
 
337
                /* Parent folder doesn't have any mapistore context associated */
 
338
        } else {
 
339
                DEBUG(0, ("not mapistore Restrict: Not implemented yet\n"));
 
340
                goto end;
 
341
        }
 
342
 
 
343
end:
179
344
        *size += libmapiserver_RopRestrict_size(mapi_repl);
180
345
 
181
346
        return MAPI_E_SUCCESS;  
200
365
                                              struct EcDoRpc_MAPI_REPL *mapi_repl,
201
366
                                              uint32_t *handles, uint16_t *size)
202
367
{
203
 
        enum MAPISTORE_ERROR            retval;
204
 
        enum MAPISTATUS                 ret;
205
368
        struct mapi_handles             *parent;
206
369
        struct emsmdbp_object           *object;
207
370
        struct emsmdbp_object_table     *table;
208
 
        struct QueryRows_req            request;
209
 
        struct QueryRows_repl           response;
 
371
        struct QueryRows_req            *request;
 
372
        struct QueryRows_repl           *response;
 
373
        enum MAPISTATUS                 retval;
210
374
        void                            *data;
211
 
        char                            *table_filter = NULL;
 
375
        enum MAPISTATUS                 *retvals;
 
376
        void                            **data_pointers;
 
377
        uint32_t                        count, max;
212
378
        uint32_t                        handle;
213
 
        uint32_t                        count;
214
 
        uint32_t                        property;
215
 
        uint8_t                         flagged;
216
 
        uint32_t                        i, j;
 
379
        uint32_t                        i;
217
380
 
218
381
        DEBUG(4, ("exchange_emsmdb: [OXCTABL] QueryRows (0x15)\n"));
219
382
 
224
387
        OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
225
388
        OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
226
389
 
227
 
        request = mapi_req->u.mapi_QueryRows;
228
 
        response = mapi_repl->u.mapi_QueryRows;
 
390
        request = &mapi_req->u.mapi_QueryRows;
 
391
        response = &mapi_repl->u.mapi_QueryRows;
229
392
 
230
393
        mapi_repl->opnum = mapi_req->opnum;
231
394
        mapi_repl->handle_idx = mapi_req->handle_idx;
232
395
        mapi_repl->error_code = MAPI_E_NOT_FOUND;
233
396
        
234
 
        response.RowData.length = 0;
 
397
        response->RowData.length = 0;
235
398
 
236
399
        handle = handles[mapi_req->handle_idx];
237
 
        ret = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
238
 
        if (ret) goto end;
239
 
 
240
 
        ret = mapi_handles_get_private_data(parent, &data);
 
400
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
 
401
        if (retval) {
 
402
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
403
                DEBUG(5, ("  handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
404
                goto end;
 
405
        }
 
406
 
 
407
        retval = mapi_handles_get_private_data(parent, &data);
 
408
        if (retval) {
 
409
                DEBUG(5, ("  handle data not found, idx = %x\n", mapi_req->handle_idx));
 
410
                goto end;
 
411
        }
 
412
 
241
413
        object = (struct emsmdbp_object *) data;
242
414
 
243
415
        /* Ensure referring object exists and is a table */
244
 
        if (!object || (object->type != EMSMDBP_OBJECT_TABLE)) {
 
416
        if (!object) {
 
417
                DEBUG(5, ("  missing object\n"));
 
418
                goto end;
 
419
        }
 
420
        if (object->type != EMSMDBP_OBJECT_TABLE) {
 
421
                DEBUG(5, ("  unhandled object type: %d\n", object->type));
245
422
                goto end;
246
423
        }
247
424
 
248
425
        table = object->object.table;
249
 
        if (!table->folderID) {
250
 
                goto end;
251
 
        }
252
 
 
253
 
        if ((request.RowCount + table->numerator) > table->denominator) {
254
 
                request.RowCount = table->denominator - table->numerator;
255
 
        }
256
 
 
257
 
        /* If parent folder has a mapistore context */
258
 
        if (table->mapistore == true) {
259
 
                /* Lookup the properties and check if we need to flag the PropertyRow blob */
260
 
                for (i = 0, count = 0; i < request.RowCount; i++, count++) {
261
 
                        flagged = 0;
262
 
 
263
 
                        /* Lookup for flagged property row */
264
 
                        for (j = 0; j < table->prop_count; j++) {
265
 
                                retval = mapistore_get_table_property(emsmdbp_ctx->mstore_ctx, table->contextID,
266
 
                                                                      table->ulType, table->folderID, 
267
 
                                                                      (enum MAPITAGS) table->properties[j],
268
 
                                                                      table->numerator, &data);
269
 
                                if (retval == MAPISTORE_ERR_INVALID_OBJECT || retval == MAPISTORE_ERROR) {
270
 
                                        goto finish;
271
 
                                }
272
 
 
273
 
                                if (retval == MAPISTORE_ERR_NOT_FOUND) {
274
 
                                        flagged = 1;
275
 
                                        libmapiserver_push_property(mem_ctx, 
276
 
                                                                    0x0000000b, (const void *)&flagged,
277
 
                                                                    &response.RowData, 0, 0);
278
 
                                        break;
279
 
                                }
280
 
                        }
281
 
 
282
 
                        /* StandardPropertyRow hack */
283
 
                        if (!flagged) {
284
 
                                libmapiserver_push_property(mem_ctx, 
285
 
                                                            0x00000000, (const void *)&flagged,
286
 
                                                            &response.RowData, 0, 1);
287
 
                        }
288
 
 
289
 
                        /* Push the properties */
290
 
                        for (j = 0; j < table->prop_count; j++) {
291
 
                                property = table->properties[j];
292
 
                                retval = mapistore_get_table_property(emsmdbp_ctx->mstore_ctx, table->contextID,
293
 
                                                                      table->ulType, table->folderID,
294
 
                                                                      (enum MAPITAGS) table->properties[j],
295
 
                                                                      table->numerator, &data);
296
 
                                if (retval == MAPISTORE_ERR_INVALID_OBJECT || retval == MAPISTORE_ERROR) {
297
 
                                        goto finish;
298
 
                                }
299
 
                                if (retval == MAPISTORE_ERR_NOT_FOUND) {
300
 
                                        property = (property & 0xFFFF0000) + PT_ERROR;
301
 
                                        data = (void *)&retval;
302
 
                                }
303
 
 
304
 
                                libmapiserver_push_property(mem_ctx,
305
 
                                                            property, (const void *)data, &response.RowData,
306
 
                                                            flagged?PT_ERROR:0, flagged);
307
 
                        }
308
 
 
309
 
                        table->numerator++;
 
426
 
 
427
        count = 0;
 
428
        if (table->ulType == MAPISTORE_RULE_TABLE) {
 
429
                DEBUG(5, ("  query on rules table are all faked right now\n"));
 
430
                goto finish;
 
431
        }
 
432
 
 
433
        /* Ensure we are in a case which we can handle, until the featureset is complete. */
 
434
        if (!request->ForwardRead) {
 
435
                DEBUG(0, ("  !ForwardRead is not supported yet\n"));
 
436
                abort();
 
437
        }
 
438
 
 
439
        /* Lookup the properties */
 
440
        max = table->numerator + request->RowCount;
 
441
        if (max > table->denominator) {
 
442
                max = table->denominator;
 
443
        }
 
444
        for (i = table->numerator; i < max; i++) {
 
445
                data_pointers = emsmdbp_object_table_get_row_props(mem_ctx, emsmdbp_ctx, object, i, MAPISTORE_PREFILTERED_QUERY, &retvals);
 
446
                if (data_pointers) {
 
447
                        emsmdbp_fill_table_row_blob(mem_ctx, emsmdbp_ctx,
 
448
                                                    &response->RowData, table->prop_count,
 
449
                                                    table->properties, data_pointers, retvals);
 
450
                        talloc_free(retvals);
 
451
                        talloc_free(data_pointers);
 
452
                        count++;
310
453
                }
311
 
 
312
 
        /* parent folder doesn't have any mapistore context associated */
313
 
        } else {
314
 
                table_filter = talloc_asprintf(mem_ctx, "(&(PidTagParentFolderId=0x%.16"PRIx64")(PidTagFolderId=*))", table->folderID);
315
 
                /* Lookup the properties and check if we need to flag the PropertyRow blob */
316
 
                for (i = 0, count = 0; i < request.RowCount; i++, count++) {
317
 
                        flagged = 0;
318
 
 
319
 
                        /* Lookup for flagged property row */
320
 
                        for (j = 0; j < table->prop_count; j++) {
321
 
                                ret = openchangedb_get_table_property(mem_ctx, emsmdbp_ctx->oc_ctx, 
322
 
                                                                      emsmdbp_ctx->szDisplayName,
323
 
                                                                      table_filter, table->properties[j], 
324
 
                                                                      table->numerator, &data);
325
 
                                if (ret == MAPI_E_INVALID_OBJECT) {
326
 
                                        goto finish;
327
 
                                }
328
 
                                if (ret == MAPI_E_NOT_FOUND) {
329
 
                                        flagged = 1;
330
 
                                        libmapiserver_push_property(mem_ctx, 
331
 
                                                                    0x0000000b, (const void *)&flagged, 
332
 
                                                                    &response.RowData, 0, 0);
333
 
                                        break;
334
 
                                }                       
335
 
                        }
336
 
 
337
 
                        /* SandardPropertyRow hack */
338
 
                        if (!flagged) {
339
 
                                libmapiserver_push_property(mem_ctx, 
340
 
                                                            0x00000000, (const void *)&flagged,
341
 
                                                            &response.RowData, 0, 1);
342
 
                        }
343
 
 
344
 
                        /* Push the property */
345
 
                        for (j = 0; j < table->prop_count; j++) {
346
 
                                property = table->properties[j];
347
 
                                ret = openchangedb_get_table_property(mem_ctx, emsmdbp_ctx->oc_ctx, 
348
 
                                                                      emsmdbp_ctx->szDisplayName,
349
 
                                                                      table_filter, table->properties[j], 
350
 
                                                                      table->numerator, &data);
351
 
                                if (ret == MAPI_E_INVALID_OBJECT) {
352
 
                                        count = 0;
353
 
                                        goto finish;
354
 
                                }
355
 
                                if (ret == MAPI_E_NOT_FOUND) {
356
 
                                        property = (property & 0xFFFF0000) + PT_ERROR;
357
 
                                        data = (void *)&retval;
358
 
                                }
359
 
                                
360
 
                                libmapiserver_push_property(mem_ctx,
361
 
                                                            property, (const void *)data,
362
 
                                                            &response.RowData, flagged?PT_ERROR:0, flagged);
363
 
                                
364
 
                        }
365
 
                        
366
 
                        table->numerator++;
 
454
                else {
 
455
                        count = 0;
 
456
                        goto finish;
367
457
                }
368
458
        }
369
459
 
370
460
finish:
371
 
        talloc_free(table_filter);
 
461
        if ((request->QueryRowsFlags & TBL_NOADVANCE) != TBL_NOADVANCE) {
 
462
                table->numerator = i;
 
463
        }
372
464
 
373
465
        /* QueryRows reply parameters */
 
466
        mapi_repl->error_code = MAPI_E_SUCCESS;
 
467
        response->RowCount = count;
374
468
        if (count) {
375
 
                if (count < request.RowCount) {
376
 
                        mapi_repl->u.mapi_QueryRows.Origin = 0;
 
469
                if ((count < request->RowCount) || (table->numerator > (table->denominator - 2))) {
 
470
                        response->Origin = BOOKMARK_END;
377
471
                } else {
378
 
                        mapi_repl->u.mapi_QueryRows.Origin = 2;
 
472
                        response->Origin = BOOKMARK_CURRENT;
379
473
                }
380
 
                mapi_repl->error_code = MAPI_E_SUCCESS;
381
 
                mapi_repl->u.mapi_QueryRows.RowCount = count;
382
 
                mapi_repl->u.mapi_QueryRows.RowData.length = response.RowData.length;
383
 
                mapi_repl->u.mapi_QueryRows.RowData.data = response.RowData.data;
384
 
                dump_data(0, response.RowData.data, response.RowData.length);
 
474
                /* dump_data(0, response.RowData.data, response.RowData.length); */
385
475
        } else {
386
476
                /* useless code for the moment */
387
 
                mapi_repl->error_code = MAPI_E_SUCCESS;
388
 
                mapi_repl->u.mapi_QueryRows.Origin = 2;
389
 
                mapi_repl->u.mapi_QueryRows.RowCount = 0;
390
 
                mapi_repl->u.mapi_QueryRows.RowData.length = 0;
391
 
                mapi_repl->u.mapi_QueryRows.RowData.data = NULL;
 
477
                if (table->restricted) {
 
478
                        response->Origin = BOOKMARK_BEGINNING;  
 
479
                }
 
480
                else {
 
481
                        response->Origin = BOOKMARK_END;
 
482
                }
 
483
                response->RowData.length = 0;
 
484
                response->RowData.data = NULL;
 
485
                DEBUG(5, ("%s: returning empty data set\n", __location__));
392
486
        }
393
487
 
394
488
end:
439
533
        
440
534
        handle = handles[mapi_req->handle_idx];
441
535
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
442
 
        if (retval) goto end;
 
536
        if (retval) {
 
537
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
538
                DEBUG(5, ("  handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
539
                goto end;
 
540
        }
443
541
 
444
542
        retval = mapi_handles_get_private_data(parent, &data);
445
 
        if (retval) goto end;
 
543
        if (retval) {
 
544
                DEBUG(5, ("  no private data or object is not a table"));
 
545
                goto end;
 
546
        }
446
547
        object = (struct emsmdbp_object *) data;
447
548
 
448
549
        /* Ensure object exists and is table type */
449
 
        if (!object || (object->type != EMSMDBP_OBJECT_TABLE)) goto end;
 
550
        if (!object || (object->type != EMSMDBP_OBJECT_TABLE)) {
 
551
                DEBUG(5, ("  no object or object is not a table\n"));
 
552
                goto end;
 
553
        }
450
554
 
451
555
        table = object->object.table;
452
 
        if (!table->folderID) goto end;
453
556
 
454
 
        mapi_repl->u.mapi_QueryPosition.Numerator = table->numerator;
 
557
        mapi_repl->u.mapi_QueryPosition.Numerator = table->numerator;
455
558
        mapi_repl->u.mapi_QueryPosition.Denominator = table->denominator;
456
559
        mapi_repl->error_code = MAPI_E_SUCCESS;
457
560
 
481
584
                                            struct EcDoRpc_MAPI_REPL *mapi_repl,
482
585
                                            uint32_t *handles, uint16_t *size)
483
586
{
 
587
        uint32_t                        handle;
 
588
        enum MAPISTATUS                 retval;
 
589
        struct mapi_handles             *parent;
 
590
        struct emsmdbp_object           *object;
 
591
        struct emsmdbp_object_table     *table;
 
592
        void                            *data;
 
593
        int32_t                         next_position;
 
594
 
484
595
        DEBUG(4, ("exchange_emsmdb: [OXCTABL] SeekRow (0x18)\n"));
485
596
 
486
597
        /* Sanity checks */
496
607
        mapi_repl->u.mapi_SeekRow.HasSoughtLess = 0;
497
608
        mapi_repl->u.mapi_SeekRow.RowsSought = 0;
498
609
 
 
610
        handle = handles[mapi_req->handle_idx];
 
611
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
 
612
        if (retval) {
 
613
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
614
                DEBUG(5, ("  handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
615
                goto end;
 
616
        }
 
617
 
 
618
        retval = mapi_handles_get_private_data(parent, &data);
 
619
        if (retval) {
 
620
                mapi_repl->error_code = retval;
 
621
                DEBUG(5, ("  handle data not found, idx = %x\n", mapi_req->handle_idx));
 
622
                goto end;
 
623
        }
 
624
        object = (struct emsmdbp_object *) data;
 
625
 
 
626
        /* Ensure object exists and is table type */
 
627
        if (!object || (object->type != EMSMDBP_OBJECT_TABLE)) {
 
628
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
629
                DEBUG(5, ("  no object or object is not a table\n"));
 
630
                goto end;
 
631
        }
 
632
 
 
633
        /* We don't handle backward/forward yet , just go through the
 
634
         * entire table, nor do we handle bookmarks */
 
635
 
 
636
        table = object->object.table;
 
637
        if (mapi_req->u.mapi_SeekRow.origin == BOOKMARK_BEGINNING) {
 
638
                next_position = mapi_req->u.mapi_SeekRow.offset;
 
639
        }
 
640
        else if (mapi_req->u.mapi_SeekRow.origin == BOOKMARK_CURRENT) {
 
641
                next_position = table->numerator + mapi_req->u.mapi_SeekRow.offset;
 
642
        }
 
643
        else if (mapi_req->u.mapi_SeekRow.origin == BOOKMARK_END) {
 
644
                next_position = table->denominator - 1 + mapi_req->u.mapi_SeekRow.offset;
 
645
        }
 
646
        else {
 
647
                next_position = 0;
 
648
                mapi_repl->error_code = MAPI_E_NOT_FOUND;
 
649
                DEBUG(5, ("  unhandled 'origin' type: %d\n", mapi_req->u.mapi_SeekRow.origin));
 
650
        }
 
651
 
 
652
        if (mapi_repl->error_code == MAPI_E_SUCCESS) {
 
653
                if (next_position < 0) {
 
654
                        next_position = 0;
 
655
                        mapi_repl->u.mapi_SeekRow.HasSoughtLess = 1;
 
656
                }
 
657
                else if (next_position >= table->denominator) {
 
658
                        next_position = table->denominator - 1;
 
659
                        mapi_repl->u.mapi_SeekRow.HasSoughtLess = 1;
 
660
                }
 
661
                if (mapi_req->u.mapi_SeekRow.WantRowMovedCount) {
 
662
                        mapi_repl->u.mapi_SeekRow.RowsSought = (next_position - table->numerator);
 
663
                }
 
664
                else {
 
665
                        mapi_repl->u.mapi_SeekRow.RowsSought = 0;
 
666
                }
 
667
                table->numerator = next_position;
 
668
        }
 
669
 
 
670
end:
499
671
        *size += libmapiserver_RopSeekRow_size(mapi_repl);
500
672
 
501
673
        return MAPI_E_SUCCESS;
521
693
                                            struct EcDoRpc_MAPI_REPL *mapi_repl,
522
694
                                            uint32_t *handles, uint16_t *size)
523
695
{
524
 
        enum MAPISTATUS                 retval;
525
696
        struct mapi_handles             *parent;
526
697
        struct emsmdbp_object           *object;
527
698
        struct emsmdbp_object_table     *table;
528
 
        void                            *data;
 
699
        struct FindRow_req              request;
 
700
        enum MAPISTATUS                 retval;
 
701
        void                            *data = NULL;
 
702
        enum MAPISTATUS                 *retvals;
 
703
        void                            **data_pointers;
529
704
        uint32_t                        handle;
 
705
        DATA_BLOB                       row;
 
706
        uint32_t                        property;
 
707
        uint8_t                         flagged;
 
708
        uint8_t                         status = 0;
 
709
        uint32_t                        i;
 
710
        bool                            found = false;
530
711
 
531
712
        DEBUG(4, ("exchange_emsmdb: [OXCTABL] FindRow (0x4f)\n"));
532
713
 
536
717
        OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
537
718
        OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
538
719
        OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
 
720
 
 
721
        request = mapi_req->u.mapi_FindRow;
539
722
        
540
723
        mapi_repl->opnum = mapi_req->opnum;
541
724
        mapi_repl->handle_idx = mapi_req->handle_idx;
543
726
        mapi_repl->u.mapi_FindRow.RowNoLongerVisible = 0;
544
727
        mapi_repl->u.mapi_FindRow.HasRowData = 0;
545
728
        mapi_repl->u.mapi_FindRow.row.length = 0;
546
 
        mapi_repl->u.mapi_FindRow.row.data = 0;
 
729
        mapi_repl->u.mapi_FindRow.row.data = NULL;
547
730
 
548
731
        handle = handles[mapi_req->handle_idx];
549
732
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
550
 
        if (retval) goto end;
 
733
        if (retval) {
 
734
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
735
                DEBUG(5, ("  handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
736
                goto end;
 
737
        }
551
738
 
552
739
        retval = mapi_handles_get_private_data(parent, &data);
553
 
        if (retval) goto end;
 
740
        if (retval) {
 
741
                mapi_repl->error_code = retval;
 
742
                DEBUG(5, ("  handle data not found, idx = %x\n", mapi_req->handle_idx));
 
743
                goto end;
 
744
        }
554
745
        object = (struct emsmdbp_object *) data;
555
746
 
556
747
        /* Ensure object exists and is table type */
557
 
        if (!object || (object->type != EMSMDBP_OBJECT_TABLE)) goto end;
 
748
        if (!object || (object->type != EMSMDBP_OBJECT_TABLE)) {
 
749
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
750
                DEBUG(5, ("  no object or object is not a table\n"));
 
751
                goto end;
 
752
        }
558
753
 
559
754
        /* We don't handle backward/forward yet , just go through the
560
755
         * entire table, nor do we handle bookmarks */
561
756
 
562
 
        /* Handle PropertyRestriction */
563
 
        if (mapi_req->u.mapi_FindRow.res.rt != 0x4) goto end;   
564
 
        /* Ensure the property we search exists in the array */
565
 
 
566
757
        table = object->object.table;
567
 
        if (!table->folderID) goto end;
568
 
 
569
 
        switch (table->mapistore) {
 
758
        if (table->ulType == MAPISTORE_RULE_TABLE) {
 
759
                DEBUG(5, ("  query on rules table are all faked right now\n"));
 
760
                goto end;
 
761
        }
 
762
 
 
763
        if (mapi_req->u.mapi_FindRow.origin == BOOKMARK_BEGINNING) {
 
764
                table->numerator = 0;
 
765
        }
 
766
        if (mapi_req->u.mapi_FindRow.ulFlags == DIR_BACKWARD) {
 
767
                DEBUG(5, ("  only DIR_FORWARD is supported right now, using work-around\n"));
 
768
                table->numerator = 0;
 
769
        }
 
770
 
 
771
        memset (&row, 0, sizeof(DATA_BLOB));
 
772
 
 
773
        switch (emsmdbp_is_mapistore(object)) {
570
774
        case true:
 
775
                /* Restrict rows to be fetched */
 
776
                retval = mapistore_table_set_restrictions(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(object), object->backend_object, &request.res, &status);
 
777
                /* Then fetch rows */
 
778
                /* Lookup the properties and check if we need to flag the PropertyRow blob */
 
779
 
 
780
                while (!found && table->numerator < table->denominator) {
 
781
                        flagged = 0;
 
782
 
 
783
                        data_pointers = emsmdbp_object_table_get_row_props(NULL, emsmdbp_ctx, object, table->numerator, MAPISTORE_LIVEFILTERED_QUERY, &retvals);
 
784
                        if (data_pointers) {
 
785
                                found = true;
 
786
                                for (i = 0; i < table->prop_count; i++) {
 
787
                                        if (retvals[i] != MAPI_E_SUCCESS) {
 
788
                                                flagged = 1;
 
789
                                        }
 
790
                                }
 
791
 
 
792
                                if (flagged) {
 
793
                                        libmapiserver_push_property(mem_ctx, 
 
794
                                                                    0x0000000b, (const void *)&flagged,
 
795
                                                                    &row, 0, 0, 0);
 
796
                                }
 
797
                                else {
 
798
                                        libmapiserver_push_property(mem_ctx, 
 
799
                                                                    0x00000000, (const void *)&flagged,
 
800
                                                                    &row, 0, 1, 0);
 
801
                                }
 
802
                                
 
803
                                /* Push the properties */
 
804
                                for (i = 0; i < table->prop_count; i++) {
 
805
                                        property = table->properties[i];
 
806
                                        retval = retvals[i];
 
807
                                        if (retval == MAPI_E_NOT_FOUND) {
 
808
                                                property = (property & 0xFFFF0000) + PT_ERROR;
 
809
                                                data = &retval;
 
810
                                        }
 
811
                                        else {
 
812
                                                data = data_pointers[i];
 
813
                                        }
 
814
                                
 
815
                                        libmapiserver_push_property(mem_ctx,
 
816
                                                                    property, data, &row,
 
817
                                                                    flagged?PT_ERROR:0, flagged, 0);
 
818
                                }
 
819
                                talloc_free(retvals);
 
820
                                talloc_free(data_pointers);
 
821
                        }
 
822
                        else {
 
823
                                table->numerator++;
 
824
                        }
 
825
                }
 
826
 
 
827
                retval = mapistore_table_set_restrictions(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(object), object->backend_object, NULL, &status);
 
828
 
 
829
                /* Adjust parameters */
 
830
                if (found) {
 
831
                        mapi_repl->u.mapi_FindRow.HasRowData = 1;
 
832
                }
 
833
                else {
 
834
                        mapi_repl->error_code = MAPI_E_NOT_FOUND;
 
835
                }
 
836
 
 
837
                mapi_repl->u.mapi_FindRow.row.length = row.length;
 
838
                mapi_repl->u.mapi_FindRow.row.data = row.data;
 
839
 
571
840
                break;
572
841
        case false:
 
842
                memset (&row, 0, sizeof(DATA_BLOB));
 
843
                DEBUG(0, ("FindRow for openchangedb\n"));
 
844
                /* Restrict rows to be fetched */
 
845
                retval = openchangedb_table_set_restrictions(object->backend_object, &request.res);
 
846
                /* Then fetch rows */
 
847
                /* Lookup the properties and check if we need to flag the PropertyRow blob */
 
848
                while (!found && table->numerator < table->denominator) {
 
849
                        flagged = 0;
 
850
 
 
851
                        data_pointers = emsmdbp_object_table_get_row_props(NULL, emsmdbp_ctx, object, table->numerator, MAPISTORE_LIVEFILTERED_QUERY, &retvals);
 
852
                        if (data_pointers) {
 
853
                                found = true;
 
854
                                for (i = 0; i < table->prop_count; i++) {
 
855
                                        if (retvals[i] != MAPI_E_SUCCESS) {
 
856
                                                flagged = 1;
 
857
                                        }
 
858
                                }
 
859
 
 
860
                                if (flagged) {
 
861
                                        libmapiserver_push_property(mem_ctx, 
 
862
                                                                    0x0000000b, (const void *)&flagged,
 
863
                                                                    &row, 0, 0, 0);
 
864
                                }
 
865
                                else {
 
866
                                        libmapiserver_push_property(mem_ctx, 
 
867
                                                                    0x00000000, (const void *)&flagged,
 
868
                                                                    &row, 0, 1, 0);
 
869
                                }
 
870
                                
 
871
                                /* Push the properties */
 
872
                                for (i = 0; i < table->prop_count; i++) {
 
873
                                        property = table->properties[i];
 
874
                                        retval = retvals[i];
 
875
                                        if (retval == MAPI_E_NOT_FOUND) {
 
876
                                                property = (property & 0xFFFF0000) + PT_ERROR;
 
877
                                                data = &retval;
 
878
                                        }
 
879
                                        else {
 
880
                                                data = data_pointers[i];
 
881
                                        }
 
882
                                
 
883
                                        libmapiserver_push_property(mem_ctx,
 
884
                                                                    property, data, &row,
 
885
                                                                    flagged?PT_ERROR:0, flagged, 0);
 
886
                                }
 
887
                                talloc_free(retvals);
 
888
                                talloc_free(data_pointers);
 
889
                        } else {
 
890
                                table->numerator++;
 
891
                        }
 
892
                }
 
893
                /* Reset restrictions */
 
894
                openchangedb_table_set_restrictions(object->backend_object, NULL);
 
895
 
 
896
                /* Adjust parameters */
 
897
                if (found) {
 
898
                        mapi_repl->u.mapi_FindRow.HasRowData = 1;
 
899
                }
 
900
                else {
 
901
                        mapi_repl->error_code = MAPI_E_NOT_FOUND;
 
902
                }
 
903
 
 
904
                mapi_repl->u.mapi_FindRow.row.length = row.length;
 
905
                mapi_repl->u.mapi_FindRow.row.data = row.data;
573
906
                break;
574
907
        }
575
908
 
578
911
 
579
912
        return MAPI_E_SUCCESS;
580
913
}
 
914
 
 
915
/**
 
916
   \details EcDoRpc ResetTable (0x81) Rop. This operation resets the
 
917
   table as follows:
 
918
     - Removes the existing column set, restriction, and sort order (ignored) from the table.
 
919
     - Invalidates bookmarks. (ignored)
 
920
     - Resets the cursor to the beginning of the table.
 
921
 
 
922
   \param mem_ctx pointer to the memory context
 
923
   \param emsmdbp_ctx pointer to the emsmdb provider context
 
924
   \param mapi_req pointer to the SetColumns EcDoRpc_MAPI_REQ
 
925
   structure
 
926
   \param mapi_repl pointer to the SetColumns EcDoRpc_MAPI_REPL
 
927
   structure
 
928
   \param handles pointer to the MAPI handles array
 
929
   \param size pointer to the mapi_response size to update
 
930
 
 
931
   \return MAPI_E_SUCCESS on success, otherwise MAPI error
 
932
 */
 
933
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopResetTable(TALLOC_CTX *mem_ctx,
 
934
                                               struct emsmdbp_context *emsmdbp_ctx,
 
935
                                               struct EcDoRpc_MAPI_REQ *mapi_req,
 
936
                                               struct EcDoRpc_MAPI_REPL *mapi_repl,
 
937
                                               uint32_t *handles, uint16_t *size)
 
938
{
 
939
        enum MAPISTATUS                 retval;
 
940
        struct mapi_handles             *parent;
 
941
        struct emsmdbp_object           *object;
 
942
        struct emsmdbp_object_table     *table;
 
943
        void                            *data;
 
944
        uint32_t                        handle, contextID;
 
945
        uint8_t                         status; /* ignored */
 
946
 
 
947
        DEBUG(4, ("exchange_emsmdb: [OXCTABL] ResetTable (0x81)\n"));
 
948
 
 
949
        /* Sanity checks */
 
950
        OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
 
951
        OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
 
952
        OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
 
953
        OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
 
954
        OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
 
955
        
 
956
        /* Initialize default empty ResetTable reply */
 
957
        mapi_repl->opnum = mapi_req->opnum;
 
958
        mapi_repl->handle_idx = mapi_req->handle_idx;
 
959
        *size += libmapiserver_RopResetTable_size(mapi_repl);
 
960
 
 
961
        handle = handles[mapi_req->handle_idx];
 
962
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
 
963
        if (retval) {
 
964
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
965
                DEBUG(5, ("  handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
 
966
                goto end;
 
967
        }
 
968
 
 
969
        retval = mapi_handles_get_private_data(parent, &data);
 
970
        if (retval) {
 
971
                mapi_repl->error_code = retval;
 
972
                DEBUG(5, ("  handle data not found, idx = %x\n", mapi_req->handle_idx));
 
973
                goto end;
 
974
        }
 
975
 
 
976
        object = (struct emsmdbp_object *) data;
 
977
        /* Ensure referring object exists and is a table */
 
978
        if (!object || (object->type != EMSMDBP_OBJECT_TABLE)) {
 
979
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
 
980
                DEBUG(5, ("  missing object or not table\n"));
 
981
                goto end;
 
982
        }
 
983
 
 
984
        mapi_repl->error_code = MAPI_E_SUCCESS;
 
985
 
 
986
        table = object->object.table;
 
987
        if (table->ulType == MAPISTORE_RULE_TABLE) {
 
988
                DEBUG(5, ("  query on rules table are all faked right now\n"));
 
989
        }
 
990
        else {
 
991
                /* 1.1. removes the existing column set */
 
992
                if (table->properties) {
 
993
                        talloc_free(table->properties);
 
994
                        table->properties = NULL;
 
995
                        table->prop_count = 0;
 
996
                }
 
997
 
 
998
                /* 1.2. empty restrictions */
 
999
                if (emsmdbp_is_mapistore(object)) {
 
1000
                        contextID = emsmdbp_get_contextID(object);
 
1001
                        retval = mapistore_table_set_restrictions(emsmdbp_ctx->mstore_ctx, contextID, object->backend_object, NULL, &status);
 
1002
                        mapistore_table_get_row_count(emsmdbp_ctx->mstore_ctx, contextID, object->backend_object, MAPISTORE_PREFILTERED_QUERY, &object->object.table->denominator);
 
1003
                } else {
 
1004
                        DEBUG(0, ("  mapistore Restrict: Not implemented yet\n"));
 
1005
                        goto end;
 
1006
                }
 
1007
 
 
1008
                /* 3. reset the cursor to the beginning of the table. */
 
1009
                table->numerator = 0;
 
1010
        }
 
1011
 
 
1012
end:
 
1013
 
 
1014
        return MAPI_E_SUCCESS;
 
1015
}