Merge sogo branch into sogo-good for further "back to trunk" merge
authorJulien Kerihuel <j.kerihuel@openchange.org>
Fri, 17 Feb 2012 14:11:47 +0000 (14:11 +0000)
committerJulien Kerihuel <j.kerihuel@openchange.org>
Fri, 17 Feb 2012 14:11:47 +0000 (14:11 +0000)
57 files changed:
Makefile
exchange.idl
libmapi/IMAPISession.c
libmapi/conf/mapi-properties
libmapi/idset.c
libmapi/libmapi.h
libmapi/property.c
mapiproxy/dcesrv_mapiproxy.c
mapiproxy/libmapiproxy/libmapiproxy.h
mapiproxy/libmapiproxy/mapi_handles.c
mapiproxy/libmapiproxy/openchangedb.c
mapiproxy/libmapiproxy/openchangedb_message.c
mapiproxy/libmapiproxy/openchangedb_table.c
mapiproxy/libmapiserver/libmapiserver_oxcprpt.c
mapiproxy/libmapiserver/libmapiserver_oxcstor.c
mapiproxy/libmapistore/mapistore.h
mapiproxy/libmapistore/mapistore_backend.c
mapiproxy/libmapistore/mapistore_indexing.c
mapiproxy/libmapistore/mapistore_interface.c
mapiproxy/libmapistore/mapistore_namedprops.c
mapiproxy/libmapistore/mapistore_notification.c
mapiproxy/libmapistore/mapistore_private.h
mapiproxy/libmapistore/mapistore_processing.c
mapiproxy/libmapistore/mapistore_replica_mapping.c
mapiproxy/libmapistore/mgmt/mapistore_mgmt.c
mapiproxy/libmapistore/mgmt/mapistore_mgmt.h
mapiproxy/libmapistore/mgmt/mapistore_mgmt_messages.c
mapiproxy/libmapistore/mgmt/mapistore_mgmt_send.c
mapiproxy/libmapistore/tests/mapistore_test.c
mapiproxy/modules/mpm_cache.c
mapiproxy/servers/default/emsmdb/dcesrv_exchange_emsmdb.c
mapiproxy/servers/default/emsmdb/dcesrv_exchange_emsmdb.h
mapiproxy/servers/default/emsmdb/emsmdbp.c
mapiproxy/servers/default/emsmdb/emsmdbp_object.c
mapiproxy/servers/default/emsmdb/emsmdbp_provisioning.c [new file with mode: 0644]
mapiproxy/servers/default/emsmdb/oxcfold.c
mapiproxy/servers/default/emsmdb/oxcfxics.c
mapiproxy/servers/default/emsmdb/oxcmsg.c
mapiproxy/servers/default/emsmdb/oxcperm.c
mapiproxy/servers/default/emsmdb/oxcprpt.c
mapiproxy/servers/default/emsmdb/oxcstor.c
mapiproxy/servers/default/emsmdb/oxctabl.c
mapiproxy/servers/default/emsmdb/oxomsg.c
mapiproxy/servers/default/emsmdb/oxorule.c
mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.c
mapiproxy/servers/default/nspi/emsabp.c
property.idl
pyopenchange/mapistore/context.c
pyopenchange/mapistore/folder.c
pyopenchange/mapistore/pymapistore.c
python/openchange/mailbox.py
python/openchange/provision.py
python/openchange/urlutils.py
setup/openchange_newuser
setup/openchange_provision
testprogs/check_fasttransfer.c
testprogs/parse-getprops.py

index 60115d07e3c896c9db814fefe668e45e5aceafc3..ed6994f148292c949799a16158353fdecc34ba0d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -41,6 +41,17 @@ samba-git-update:
 # top level compilation rules
 #################################################################
 
+ifeq ($(PYTHON_CONFIG),)
+PYTHON_CFLAGS=$(shell $(PYTHON_CONFIG) --cflags)
+PYTHON_LIBS=$(shell $(PYTHON_CONFIG) --libs)
+else
+PYTHON_VERSION=$(shell $(PYTHON) -V 2>& 1 | awk '{ print $$2 }')
+PYTHON_MAJOR_VERSION=$(shell echo $(PYTHON_VERSION) | cut -d . -f 1)
+PYTHON_MINOR_VERSION=$(shell echo $(PYTHON_VERSION) | cut -d . -f 2)
+PYTHON_CFLAGS=-I/usr/include/python$(PYTHON_MAJOR_VERSION).$(PYTHON_MINOR_VERSION) -I/usr/include/python
+PYTHON_LIBS=-lpython$(PYTHON_MAJOR_VERSION).$(PYTHON_MINOR_VERSION)
+endif
+
 all:           $(OC_IDL)               \
                $(OC_LIBS)              \
                $(OC_TOOLS)             \
@@ -1065,6 +1076,7 @@ mapiproxy/servers/exchange_nsp.$(SHLIBEXT):       mapiproxy/servers/default/nspi/dcesr
 mapiproxy/servers/exchange_emsmdb.$(SHLIBEXT): mapiproxy/servers/default/emsmdb/dcesrv_exchange_emsmdb.po      \
                                                mapiproxy/servers/default/emsmdb/emsmdbp.po                     \
                                                mapiproxy/servers/default/emsmdb/emsmdbp_object.po              \
+                                               mapiproxy/servers/default/emsmdb/emsmdbp_provisioning.po        \
                                                mapiproxy/servers/default/emsmdb/oxcstor.po                     \
                                                mapiproxy/servers/default/emsmdb/oxcprpt.po                     \
                                                mapiproxy/servers/default/emsmdb/oxcfold.po                     \
@@ -1521,20 +1533,20 @@ clean-python:
 clean:: clean-python
 
 pyopenchange:  $(pythonscriptdir)/openchange/mapi.$(SHLIBEXT)                  \
-               $(pythonscriptdir)/openchange/ocpf.$(SHLIBEXT)                  \
                $(pythonscriptdir)/openchange/mapistore.$(SHLIBEXT)             
+#              $(pythonscriptdir)/openchange/ocpf.$(SHLIBEXT)                  \
 
 $(pythonscriptdir)/openchange/mapi.$(SHLIBEXT):        pyopenchange/pymapi.c                           \
                                                pyopenchange/pymapi_properties.c                \
                                                libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
        @echo "Linking $@"
-       @$(CC) $(CFLAGS) $(DSOOPT) $(LDFLAGS) -o $@ $^ `$(PYTHON_CONFIG) --cflags --libs` $(LIBS) 
+       @$(CC) $(CFLAGS) $(DSOOPT) $(LDFLAGS) -o $@ $^ $(PYTHON_CFLAGS) $(PYTHON_LIBS) $(LIBS) 
 
-$(pythonscriptdir)/openchange/ocpf.$(SHLIBEXT):        pyopenchange/pyocpf.c                           \
-                                               libocpf.$(SHLIBEXT).$(PACKAGE_VERSION)          \
-                                               libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
-       @echo "Linking $@"
-       @$(CC) $(CFLAGS) $(DSOOPT) $(LDFLAGS) -o $@ $^ `$(PYTHON_CONFIG) --cflags --libs` $(LIBS) 
+# $(pythonscriptdir)/openchange/ocpf.$(SHLIBEXT):      pyopenchange/pyocpf.c                           \
+#                                              libocpf.$(SHLIBEXT).$(PACKAGE_VERSION)          \
+#                                              libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
+#      @echo "Linking $@"
+#      @$(CC) $(CFLAGS) $(DSOOPT) $(LDFLAGS) -o $@ $^ $(PYTHON_CFLAGS) $(PYTHON_LIBS) $(LIBS) 
 
  $(pythonscriptdir)/openchange/mapistore.$(SHLIBEXT):  pyopenchange/mapistore/pymapistore.c                    \
                                                        pyopenchange/mapistore/mgmt.c                           \
@@ -1544,7 +1556,7 @@ $(pythonscriptdir)/openchange/ocpf.$(SHLIBEXT):   pyopenchange/pyocpf.c                           \
                                                        mapiproxy/libmapistore.$(SHLIBEXT).$(PACKAGE_VERSION)   \
                                                        mapiproxy/libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION)
        @echo "Linking $@"
-       @$(CC) $(CFLAGS) $(DSOOPT) $(LDFLAGS) -o $@ $^ `$(PYTHON_CONFIG) --cflags --libs` $(LIBS)
+       @$(CC) $(CFLAGS) $(DSOOPT) $(LDFLAGS) -o $@ $^ $(PYTHON_CFLAGS) $(PYTHON_LIBS) $(LIBS)
 
 
 pyopenchange/pymapi_properties.c:              \
index e83fbd0bf57995951a9412184ae566b734bf326b..4d8a9bb910fb2843553d7ca32ae73eb07aa3d46e 100644 (file)
@@ -1167,7 +1167,7 @@ System Attendant Private Interface
        typedef [enum8bit] enum {
                ReadOnly        = 0x0,
                ReadWrite       = 0x1,
-               Create          = 0x3,
+               BestAccess      = 0x3,
                OpenSoftDelete  = 0x4
        } OpenMessage_OpenModeFlags;
 
@@ -3533,7 +3533,7 @@ System Attendant Private Interface
                uint16          MessageIdSize;
                uint8           MessageId[MessageIdSize];
                boolean8        MarkAsRead;
-       } MessageReadStates;
+       } MessageReadState;
 
        typedef [flag(NDR_NOALIGN)] struct {
                [subcontext(2),flag(NDR_REMAINING)] DATA_BLOB MessageReadStates;
@@ -3714,14 +3714,40 @@ System Attendant Private Interface
        } ResponseFlags;
 
        typedef [flag(NDR_NOALIGN)] struct {
-               hyper                   FolderIds[13];
+               /* folders */
+               hyper                   Root;
+               hyper                   IPMSubTree;
+               hyper                   NonIPMSubTree;
+               hyper                   EFormsRegistry;
+               hyper                   FreeBusy;
+               hyper                   OAB;
+               hyper                   LocalizedEFormsRegistry;
+               hyper                   LocalFreeBusy;
+               hyper                   LocalOAB;
+               hyper                   NNTPIndex;
+               hyper                   _empty[3];
+
                uint16                  ReplId;
                GUID                    Guid;
                GUID                    PerUserGuid;
        } store_pf;
 
        typedef [flag(NDR_NOALIGN)] struct {
-               hyper                   FolderIds[13];
+               /* folders */
+               hyper                   Root;
+               hyper                   DeferredAction;
+               hyper                   SpoolerQueue;
+               hyper                   IPMSubTree;
+               hyper                   Inbox;
+               hyper                   Outbox;
+               hyper                   SentItems;
+               hyper                   DeletedItems;
+               hyper                   CommonViews;
+               hyper                   Schedule;
+               hyper                   Search;
+               hyper                   Views;
+               hyper                   Shortcuts;
+
                ResponseFlags           ResponseFlags;
                GUID                    MailboxGuid;
                uint16                  ReplId;
index 4b7a5be8120282380df0df1c02274de78a0e3c9f..137ae8f4ff866c0c4d8a2b563191f000533ff9f2 100644 (file)
@@ -223,16 +223,16 @@ retry:
        store = (mapi_object_store_t*)obj_store->private_data;
        OPENCHANGE_RETVAL_IF(!obj_store->private_data, MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
 
-       store->fid_pf_public_root = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.FolderIds[0];
-       store->fid_pf_ipm_subtree = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.FolderIds[1];
-       store->fid_pf_non_ipm_subtree = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.FolderIds[2];
-       store->fid_pf_EFormsRegistryRoot = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.FolderIds[3];
-       store->fid_pf_FreeBusyRoot = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.FolderIds[4];
-       store->fid_pf_OfflineAB = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.FolderIds[5];
-       store->fid_pf_EFormsRegistry = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.FolderIds[6];
-       store->fid_pf_LocalSiteFreeBusy = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.FolderIds[7];
-       store->fid_pf_LocalSiteOfflineAB = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.FolderIds[8];
-       store->fid_pf_NNTPArticle = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.FolderIds[9];
+       store->fid_pf_public_root = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.Root;
+       store->fid_pf_ipm_subtree = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.IPMSubTree;
+       store->fid_pf_non_ipm_subtree = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.NonIPMSubTree;
+       store->fid_pf_EFormsRegistryRoot = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.EFormsRegistry;
+       store->fid_pf_FreeBusyRoot = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.FreeBusy;
+       store->fid_pf_OfflineAB = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.OAB;
+       store->fid_pf_EFormsRegistry = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.LocalizedEFormsRegistry;
+       store->fid_pf_LocalSiteFreeBusy = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.LocalFreeBusy;
+       store->fid_pf_LocalSiteOfflineAB = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.LocalOAB;
+       store->fid_pf_NNTPArticle = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.NNTPIndex;
        store->store_type = PublicFolder;
 
        talloc_free(mapi_response);
@@ -395,19 +395,19 @@ retry:
        store = (mapi_object_store_t *)obj_store->private_data;
        OPENCHANGE_RETVAL_IF(!obj_store->private_data, MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
 
-       store->fid_mailbox_root = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.FolderIds[0];
-       store->fid_deferred_actions = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.FolderIds[1];
-       store->fid_spooler_queue = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.FolderIds[2];
-       store->fid_top_information_store = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.FolderIds[3];
-       store->fid_inbox = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.FolderIds[4]; 
-       store->fid_outbox = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.FolderIds[5];
-       store->fid_sent_items = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.FolderIds[6];
-       store->fid_deleted_items = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.FolderIds[7];
-       store->fid_common_views = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.FolderIds[8];
-       store->fid_schedule = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.FolderIds[9];
-       store->fid_search = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.FolderIds[10];
-       store->fid_views = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.FolderIds[11];
-       store->fid_shortcuts = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.FolderIds[12];
+       store->fid_mailbox_root = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.Root;
+       store->fid_deferred_actions = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.DeferredAction;
+       store->fid_spooler_queue = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.SpoolerQueue;
+       store->fid_top_information_store = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.IPMSubTree;
+       store->fid_inbox = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.Inbox;
+       store->fid_outbox = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.Outbox;
+       store->fid_sent_items = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.SentItems;
+       store->fid_deleted_items = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.DeletedItems;
+       store->fid_common_views = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.CommonViews;
+       store->fid_schedule = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.Schedule;
+       store->fid_search = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.Search;
+       store->fid_views = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.Views;
+       store->fid_shortcuts = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.Shortcuts;
        store->store_type = PrivateFolderWithoutCachedFids;
 
        talloc_free(mapi_response);
index c19266b47c65705fe4c6477da32f3420653b2292..3f3108bdcaf879d71ccbf33a6aafe2c2ee37eef5 100644 (file)
 0x36e00102  PR_FOLDER_XVIEWINFO_E                      PidTagXViewInfoE
 0x36e10003  PR_FOLDER_VIEWS_ONLY
 0x36e41102  PR_FREEBUSY_ENTRYIDS                       PidTagFreeBusyEntryIds
-0x36e5001e  PR_DEF_MSG_CLASS
+0x36e5001e  PR_DEF_POST_MSGCLASS                        PidTagDefaultPostMessageClass
 0x36e6001e  PR_DEF_FORM_NAME
 0x36e9000b  PR_GENERATE_EXCHANGE_VIEWS
 0x36eb0102  PR_FOLDER_VIEWLIST
index 042fb7bb99481d8c2d18871ca416deaeb9193ede..b6a77782b2cfac3a77bee85544f4327aa2b67333 100644 (file)
@@ -772,8 +772,8 @@ _PUBLIC_ struct idset *IDSET_merge_idsets(TALLOC_CTX *mem_ctx, const struct idse
        bool added_ranges = false, same_id, idbased;
        struct globset_range *range;
 
-       if (!left) return IDSET_clone(mem_ctx, right);
-       if (!right) return IDSET_clone(mem_ctx, left);
+       if (!left || left->range_count == 0) return IDSET_clone(mem_ctx, right);
+       if (!right || right->range_count == 0) return IDSET_clone(mem_ctx, left);
 
        merged_idset = IDSET_clone(mem_ctx, left);
        clone_right = IDSET_clone(mem_ctx, right);
index f37dc6e69041dd76e8ef5dfb52675c850471f64d..1c5c31f8b26a3c091b84e95fa7474723c2c372ca 100644 (file)
@@ -259,6 +259,7 @@ struct SPropValue   *add_SPropValue(TALLOC_CTX *, struct SPropValue *, uint32_t *,
 struct mapi_SPropValue *add_mapi_SPropValue(TALLOC_CTX *, struct mapi_SPropValue *, uint16_t *, uint32_t, const void *);
 bool                   set_SPropValue(struct SPropValue *, const void *);
 uint32_t               get_mapi_property_size(struct mapi_SPropValue *);
+void                   mapi_copy_spropvalues(TALLOC_CTX *, struct SPropValue *, struct SPropValue *, uint32_t);
 uint32_t               cast_mapi_SPropValue(TALLOC_CTX *, struct mapi_SPropValue *, struct SPropValue *);
 uint32_t               cast_SPropValue(TALLOC_CTX *, struct mapi_SPropValue *, struct SPropValue *);
 enum MAPISTATUS                SRow_addprop(struct SRow *, struct SPropValue);
index 9b761df1a1af0fa3be01793fe79a43d4af938080..358089914ac9a7ac793ae6712a5b2802242b5d2a 100644 (file)
@@ -646,6 +646,46 @@ _PUBLIC_ uint32_t get_mapi_property_size(struct mapi_SPropValue *lpProp)
 }
 
 
+/**
+   \details Convenience function to copy an array of struct SPropValue or a
+   part thereof into another array, by duplicating and properly parenting
+   pointer data. The destination array is considered to be preallocated.
+*/
+_PUBLIC_ void mapi_copy_spropvalues(TALLOC_CTX *mem_ctx, struct SPropValue *source_values, struct SPropValue *dest_values, uint32_t count)
+{
+       uint32_t                i;
+       struct SPropValue       *source_value, *dest_value;
+       uint16_t                prop_type;
+
+       for (i = 0; i < count; i++) {
+               source_value = source_values + i;
+               dest_value = dest_values + i;
+               *dest_value = *source_value;
+
+               prop_type = (source_value->ulPropTag & 0xFFFF);
+               if ((prop_type & MV_FLAG)) {
+                       DEBUG(5, ("multivalues not handled\n"));
+                       abort();
+               }
+               else {
+                       switch(prop_type) {
+                       case PT_STRING8:
+                               dest_value->value.lpszA = talloc_strdup(mem_ctx, source_value->value.lpszA);
+                               break;
+                       case PT_UNICODE:
+                               dest_value->value.lpszW = talloc_strdup(mem_ctx, source_value->value.lpszW);
+                               break;
+                       case PT_BINARY:
+                               dest_value->value.bin.cb = source_value->value.bin.cb;
+                               dest_value->value.bin.lpb = talloc_memdup(mem_ctx, source_value->value.bin.lpb, sizeof(uint8_t) * source_value->value.bin.cb);
+                               break;
+                       default:
+                               *dest_value = *source_value;
+                       }
+               }
+       }
+}
+
 /**
    \details Convenience function to convert a SPropValue structure
    into a mapi_SPropValue structure and return the associated size.
index 3b44c478409947c2f06d32e7b3a5baa481c57241..916b014a393b511382cab6d16a16fb0dfc7ecfd8 100644 (file)
@@ -28,6 +28,8 @@
 #include "libmapi/libmapi_private.h"
 #include <util/debug.h>
 
+static int dispatch_nbr = 0;
+
 /**
    \file dcesrv_mapiproxy.c
 
@@ -368,9 +370,9 @@ static NTSTATUS mapiproxy_op_ndr_push(struct dcesrv_call_state *dce_call, TALLOC
        struct dcesrv_mapiproxy_private         *private;
        enum ndr_err_code                       ndr_err;
        const struct ndr_interface_table        *table;
-       const struct ndr_interface_call         *call;
+       /* const struct ndr_interface_call              *call; */
        uint16_t                                opnum;
-       const char                              *name;
+       /* const char                           *name; */
 
        DEBUG(5, ("mapiproxy::mapiproxy_op_ndr_push\n"));
 
@@ -378,8 +380,8 @@ static NTSTATUS mapiproxy_op_ndr_push(struct dcesrv_call_state *dce_call, TALLOC
        table = (const struct ndr_interface_table *)dce_call->context->iface->private_data;
        opnum = dce_call->pkt.u.request.opnum;
 
-       name = table->calls[opnum].name;
-       call = &table->calls[opnum];
+       /* name = table->calls[opnum].name; */
+       /* call = &table->calls[opnum]; */
 
        dce_call->fault_code = 0;
 
@@ -449,6 +451,14 @@ static NTSTATUS mapiproxy_op_dispatch(struct dcesrv_call_state *dce_call, TALLOC
        uint16_t                                opnum;
        const char                              *name;
        NTSTATUS                                status;
+       int                                     this_dispatch;
+       struct timeval                          tv;
+
+       this_dispatch = dispatch_nbr;
+       dispatch_nbr++;
+
+       gettimeofday(&tv, NULL);
+       DEBUG(5, ("mapiproxy::mapiproxy_op_dispatch: [tv=%lu.%.6lu] [#%d start]\n", tv.tv_sec, tv.tv_usec, this_dispatch));
 
        private = dce_call->context->private_data;
        table = dce_call->context->iface->private_data;
@@ -529,6 +539,9 @@ static NTSTATUS mapiproxy_op_dispatch(struct dcesrv_call_state *dce_call, TALLOC
                
                if (mapiproxy.ahead == true) goto ahead;
        }
+
+       gettimeofday(&tv, NULL);
+       DEBUG(5, ("mapiproxy::mapiproxy_op_dispatch: [tv=%lu.%.6lu] [#%d end]\n", tv.tv_sec, tv.tv_usec, this_dispatch));
        
        return NT_STATUS_OK;
 }
index fbb576f0b00d3e82aefd4c697eb7bbde0cbd301a..ba6cfaae2bacf40e2b04f0c5f14f95b80853725e 100644 (file)
@@ -230,6 +230,7 @@ enum MAPISTATUS     openchangedb_get_MailboxGuid(struct ldb_context *, const char *,
 enum MAPISTATUS        openchangedb_get_MailboxReplica(struct ldb_context *, const char *, uint16_t *, struct GUID *);
 enum MAPISTATUS openchangedb_get_PublicFolderReplica(struct ldb_context *, uint16_t *, struct GUID *);
 enum MAPISTATUS openchangedb_get_parent_fid(struct ldb_context *, uint64_t, uint64_t *, bool);
+enum MAPISTATUS openchangedb_get_MAPIStoreURIs(struct ldb_context *, const char *, TALLOC_CTX *, struct WStringArray_r **);
 enum MAPISTATUS openchangedb_get_mapistoreURI(TALLOC_CTX *, struct ldb_context *, uint64_t, char **, bool);
 enum MAPISTATUS openchangedb_get_fid(struct ldb_context *, const char *, uint64_t *);
 enum MAPISTATUS openchangedb_get_ReceiveFolder(TALLOC_CTX *, struct ldb_context *, const char *, const char *, uint64_t *, const char **);
@@ -237,16 +238,19 @@ enum MAPISTATUS openchangedb_get_TransportFolder(struct ldb_context *, const cha
 enum MAPISTATUS openchangedb_lookup_folder_property(struct ldb_context *, uint32_t, uint64_t);
 enum MAPISTATUS openchangedb_set_folder_properties(struct ldb_context *, uint64_t, struct SRow *);
 char *openchangedb_set_folder_property_data(TALLOC_CTX *, struct SPropValue *);
-enum MAPISTATUS openchangedb_get_folder_property(TALLOC_CTX *, struct ldb_context *, const char *, uint32_t, uint64_t, void **);
+enum MAPISTATUS openchangedb_get_folder_property(TALLOC_CTX *, struct ldb_context *, uint32_t, uint64_t, void **);
 enum MAPISTATUS openchangedb_get_folder_count(struct ldb_context *, uint64_t, uint32_t *);
 enum MAPISTATUS openchangedb_get_message_count(struct ldb_context *, uint64_t, uint32_t *, bool);
-enum MAPISTATUS openchangedb_get_table_property(TALLOC_CTX *, struct ldb_context *, const char *, char *, uint32_t, uint32_t, void **);
+enum MAPISTATUS openchangedb_get_table_property(TALLOC_CTX *, struct ldb_context *, const char *, uint32_t, uint32_t, void **);
 enum MAPISTATUS openchangedb_get_fid_by_name(struct ldb_context *, uint64_t, const char*, uint64_t *);
-enum MAPISTATUS openchangedb_set_ReceiveFolder(TALLOC_CTX *, struct ldb_context *, const char *, const char *, uint64_t);
+enum MAPISTATUS openchangedb_get_mid_by_subject(struct ldb_context *, uint64_t, const char *, bool, uint64_t *);
+enum MAPISTATUS openchangedb_set_ReceiveFolder(struct ldb_context *, const char *, const char *, uint64_t);
+enum MAPISTATUS openchangedb_create_mailbox(struct ldb_context *, const char *, int, uint64_t *);
+enum MAPISTATUS openchangedb_create_folder(struct ldb_context *, uint64_t, uint64_t, uint64_t, const char *, int);
+enum MAPISTATUS openchangedb_delete_folder(struct ldb_context *, uint64_t);
 enum MAPISTATUS openchangedb_get_fid_from_partial_uri(struct ldb_context *, const char *, uint64_t *);
-enum MAPISTATUS        openchangedb_get_users_from_partial_uri(TALLOC_CTX *, struct ldb_context *, const char *, uint32_t *, char ***, char ***);
-enum MAPISTATUS openchangedb_create_folder(struct ldb_context *, uint64_t, uint64_t, const char *, NTTIME, int64_t);
-void *openchangedb_get_special_property(TALLOC_CTX *, struct ldb_context *, const char *, struct ldb_result *, uint32_t, const char *);
+enum MAPISTATUS openchangedb_get_users_from_partial_uri(TALLOC_CTX *, struct ldb_context *, const char *, uint32_t *, char ***, char ***);
+void *openchangedb_get_special_property(TALLOC_CTX *, struct ldb_context *, struct ldb_result *, uint32_t, const char *);
 void *openchangedb_get_property_data(TALLOC_CTX *, struct ldb_result *, uint32_t, uint32_t, const char *);
 void *openchangedb_get_property_data_message(TALLOC_CTX *, struct ldb_message *, uint32_t, const char *);
 
@@ -254,7 +258,7 @@ void *openchangedb_get_property_data_message(TALLOC_CTX *, struct ldb_message *,
 enum MAPISTATUS openchangedb_table_init(TALLOC_CTX *, uint8_t, uint64_t, void **);
 enum MAPISTATUS openchangedb_table_set_sort_order(void *, struct SSortOrderSet *);
 enum MAPISTATUS openchangedb_table_set_restrictions(void *, struct mapi_SRestriction *);
-enum MAPISTATUS openchangedb_table_get_property(TALLOC_CTX *, void *, struct ldb_context *, const char *, enum MAPITAGS, uint32_t, bool live_filtered, void **);
+enum MAPISTATUS openchangedb_table_get_property(TALLOC_CTX *, void *, struct ldb_context *, enum MAPITAGS, uint32_t, bool live_filtered, void **);
 
 /* definitions from openchangedb_message.c */
 enum MAPISTATUS openchangedb_message_open(TALLOC_CTX *, struct ldb_context *, uint64_t, uint64_t, void **, void **);
index a715e6818a47bd272577dc280b3b20b2571f4e5e..0cc227ccd015abea6a675dcbed4e3880c43a8117 100644 (file)
@@ -343,6 +343,7 @@ _PUBLIC_ enum MAPISTATUS mapi_handles_add(struct mapi_handles_context *handles_c
        *rec = el;
        DLIST_ADD_END(handles_ctx->handles, el, struct mapi_handles *);
 
+       DEBUG(5, ("handle 0x%.2x is a father of 0x%.2x\n", container_handle, el->handle));
        handles_ctx->last_handle += 1;
        talloc_free(mem_ctx);
 
@@ -425,6 +426,7 @@ static int mapi_handles_traverse_delete(TDB_CONTEXT *tdb_ctx,
        if (dbuf.dptr && strlen(container_handle_str) == dbuf.dsize && !strncmp((const char *)dbuf.dptr, container_handle_str, dbuf.dsize)) {
                handle_str = talloc_strndup(mem_ctx, (char *)key.dptr, key.dsize);
                handle = strtol((const char *) handle_str, NULL, 16);
+               DEBUG(5, ("deleting child handle: %d, %s\n", handle, handle_str));
                mapi_handles_delete(handles_private->handles_ctx, handle);
        }
 
index 2beabe1adff385f805703a25708d0e3f53df5c9c..53f9c4a19546552b03261a841f53030e5ff4cb91 100644 (file)
@@ -84,7 +84,6 @@ _PUBLIC_ enum MAPISTATUS openchangedb_get_SystemFolderID(struct ldb_context *ldb
        /* Step 3. Search FolderID */
        ldb_dn = ldb_dn_new(mem_ctx, ldb_ctx, dn);
        OPENCHANGE_RETVAL_IF(!ldb_dn, MAPI_E_CORRUPT_STORE, mem_ctx);
-       talloc_free(res);
 
        ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_dn, LDB_SCOPE_SUBTREE, attrs, 
                         "(&(objectClass=systemfolder)(SystemIdx=%d))", SystemIdx);
@@ -480,6 +479,63 @@ _PUBLIC_ enum MAPISTATUS openchangedb_get_fid(struct ldb_context *ldb_ctx, const
        return MAPI_E_SUCCESS;
 }
 
+/**
+   \details Retrieve a list of mapistore URI in use for a certain user
+
+   \param ldb_ctx pointer to the openchange LDB context
+   \param fid the Folder identifier to search for
+   \param mapistoreURL pointer on pointer to the mapistore URI the
+   function returns
+   \param mailboxstore boolean value which defines whether the record
+   has to be searched within Public folders hierarchy or not
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND
+ */
+_PUBLIC_ enum MAPISTATUS openchangedb_get_MAPIStoreURIs(struct ldb_context *ldb_ctx, const char *username, TALLOC_CTX *mem_ctx, struct WStringArray_r **urisP)
+{
+       TALLOC_CTX              *local_mem_ctx;
+       struct ldb_result       *res = NULL;
+       struct ldb_dn           *dn;
+       const char * const      attrs[] = { "*", NULL };
+       char                    *dnstr;
+       int                     i, elements, ret;
+       struct WStringArray_r   *uris;
+
+       local_mem_ctx = talloc_named(NULL, 0, "openchangedb_get_fid");
+
+       /* fetch mailbox DN */
+       ret = ldb_search(ldb_ctx, local_mem_ctx, &res, ldb_get_default_basedn(ldb_ctx),
+                        LDB_SCOPE_SUBTREE, attrs, "(&(cn=%s)(MailboxGUID=*))", username);
+       OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, local_mem_ctx);
+
+       dnstr = talloc_strdup(local_mem_ctx, ldb_msg_find_attr_as_string(res->msgs[0], "distinguishedName", NULL));
+       OPENCHANGE_RETVAL_IF(!dnstr, MAPI_E_NOT_FOUND, local_mem_ctx);
+       dn = ldb_dn_new(local_mem_ctx, ldb_ctx, dnstr);
+
+       uris = talloc_zero(mem_ctx, struct WStringArray_r);
+       uris->lppszW = talloc_zero(uris, const char *);
+       *urisP = uris;
+
+       elements = 0;
+
+       /* search subfolders which have a non-null mapistore uri */
+       ret = ldb_search(ldb_ctx, local_mem_ctx, &res, dn, LDB_SCOPE_SUBTREE, attrs, "(MAPIStoreURI=*)");
+       if (ret == LDB_SUCCESS) {
+               for (i = 0; i < res->count; i++) {
+                       if ((uris->cValues + 1) > elements) {
+                               elements = uris->cValues + 16;
+                               uris->lppszW = talloc_realloc(uris, uris->lppszW, const char *, elements);
+                       }
+                       uris->lppszW[uris->cValues] = talloc_strdup(uris, ldb_msg_find_attr_as_string(res->msgs[i], "MAPIStoreURI", NULL));
+                       uris->cValues++;
+               }
+       }
+
+       talloc_free(local_mem_ctx);
+
+       return MAPI_E_SUCCESS;
+}
+
 /**
    \details Retrieve the Explicit message class and Folder identifier
    associated to the MessageClass search pattern.
@@ -522,8 +578,6 @@ _PUBLIC_ enum MAPISTATUS openchangedb_get_ReceiveFolder(TALLOC_CTX *parent_ctx,
        OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx);
 
        dnstr = talloc_strdup(mem_ctx, ldb_msg_find_attr_as_string(res->msgs[0], "distinguishedName", NULL));
-       DEBUG(5, ("openchangedb_get_ReceiveFolder, dnstr: %s\n", dnstr));
-
        OPENCHANGE_RETVAL_IF(!dnstr, MAPI_E_NOT_FOUND, mem_ctx);
 
        talloc_free(res);
@@ -548,8 +602,6 @@ _PUBLIC_ enum MAPISTATUS openchangedb_get_ReceiveFolder(TALLOC_CTX *parent_ctx,
        /* Step 2B. Search for all MessageClasses within user's mailbox */
        ret = ldb_search(ldb_ctx, mem_ctx, &res, dn, LDB_SCOPE_SUBTREE, attrs, 
                         "(PidTagMessageClass=*)");
-       DEBUG(5, ("openchangedb_get_ReceiveFolder, res->count: %i\n", res->count));
-
        OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx);
 
        /* Step 3. Find the message class that has the longest matching string entry */
@@ -718,7 +770,6 @@ _PUBLIC_ enum MAPISTATUS openchangedb_lookup_folder_property(struct ldb_context
 
    \param mem_ctx pointer to the memory context
    \param ldb_ctx pointer to the OpenChange LDB context
-   \param recipient the mailbox username
    \param res pointer to the LDB result
    \param proptag the MAPI property tag to lookup
    \param PidTagAttr the mapped MAPI property name
@@ -727,7 +778,6 @@ _PUBLIC_ enum MAPISTATUS openchangedb_lookup_folder_property(struct ldb_context
  */
 void *openchangedb_get_special_property(TALLOC_CTX *mem_ctx,
                                        struct ldb_context *ldb_ctx,
-                                       const char *recipient,
                                        struct ldb_result *res,
                                        uint32_t proptag,
                                        const char *PidTagAttr)
@@ -933,6 +983,7 @@ void *openchangedb_get_property_data_message(TALLOC_CTX *mem_ctx,
                break;
        default:
                DEBUG(0, ("[%s:%d] Property Type 0x%.4x not supported\n", __FUNCTION__, __LINE__, (proptag & 0xFFFF)));
+               abort();
                return NULL;
        }
 
@@ -1133,7 +1184,6 @@ _PUBLIC_ enum MAPISTATUS openchangedb_reserve_fmid_range(struct ldb_context *ldb
 
    \param parent_ctx pointer to the memory context
    \param ldb_ctx pointer to the openchange LDB context
-   \param recipient the mailbox username
    \param proptag the MAPI property tag to retrieve value for
    \param fid the record folder identifier
    \param data pointer on pointer to the data the function returns
@@ -1142,7 +1192,6 @@ _PUBLIC_ enum MAPISTATUS openchangedb_reserve_fmid_range(struct ldb_context *ldb
  */
 _PUBLIC_ enum MAPISTATUS openchangedb_get_folder_property(TALLOC_CTX *parent_ctx, 
                                                          struct ldb_context *ldb_ctx,
-                                                         const char *recipient,
                                                          uint32_t proptag,
                                                          uint64_t fid,
                                                          void **data)
@@ -1168,7 +1217,7 @@ _PUBLIC_ enum MAPISTATUS openchangedb_get_folder_property(TALLOC_CTX *parent_ctx
        OPENCHANGE_RETVAL_IF(!ldb_msg_find_element(res->msgs[0], PidTagAttr), MAPI_E_NOT_FOUND, mem_ctx);
 
        /* Step 4. Check if this is a "special property" */
-       *data = openchangedb_get_special_property(parent_ctx, ldb_ctx, recipient, res, proptag, PidTagAttr);
+       *data = openchangedb_get_special_property(parent_ctx, ldb_ctx, res, proptag, PidTagAttr);
        OPENCHANGE_RETVAL_IF(*data != NULL, MAPI_E_SUCCESS, mem_ctx);
 
        /* Step 5. If this is not a "special property" */
@@ -1270,7 +1319,6 @@ _PUBLIC_ enum MAPISTATUS openchangedb_set_folder_properties(struct ldb_context *
 
    \param parent_ctx pointer to the memory context
    \param ldb_ctx pointer to the openchange LDB context
-   \param recipient the mailbox username
    \param ldb_filter the ldb search string
    \param proptag the MAPI property tag to retrieve value for
    \param pos the record position in search results
@@ -1280,8 +1328,7 @@ _PUBLIC_ enum MAPISTATUS openchangedb_set_folder_properties(struct ldb_context *
  */
 _PUBLIC_ enum MAPISTATUS openchangedb_get_table_property(TALLOC_CTX *parent_ctx,
                                                         struct ldb_context *ldb_ctx,
-                                                        const char *recipient,
-                                                        char *ldb_filter,
+                                                        const char *ldb_filter,
                                                         uint32_t proptag,
                                                         uint32_t pos,
                                                         void **data)
@@ -1310,7 +1357,7 @@ _PUBLIC_ enum MAPISTATUS openchangedb_get_table_property(TALLOC_CTX *parent_ctx,
        OPENCHANGE_RETVAL_IF(!ldb_msg_find_element(res->msgs[0], PidTagAttr), MAPI_E_NOT_FOUND, mem_ctx);
 
        /* Step 5. Check if this is a "special property" */
-       *data = openchangedb_get_special_property(parent_ctx, ldb_ctx, recipient, res, proptag, PidTagAttr);
+       *data = openchangedb_get_special_property(parent_ctx, ldb_ctx, res, proptag, PidTagAttr);
        OPENCHANGE_RETVAL_IF(*data != NULL, MAPI_E_SUCCESS, mem_ctx);
 
        /* Step 6. Check if this is not a "special property" */
@@ -1348,7 +1395,6 @@ _PUBLIC_ enum MAPISTATUS openchangedb_get_fid_by_name(struct ldb_context *ldb_ct
        int                     ret;
 
        mem_ctx = talloc_named(NULL, 0, "get_fid_by_name");
-       *fid = 0;
 
        ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx),
                         LDB_SCOPE_SUBTREE, attrs,
@@ -1368,6 +1414,80 @@ _PUBLIC_ enum MAPISTATUS openchangedb_get_fid_by_name(struct ldb_context *ldb_ct
        return MAPI_E_SUCCESS;
 }
 
+/**
+   \details Retrieve the message ID associated with a given subject (normalized)
+
+   \param ldb_ctx pointer to the openchange LDB context
+   \param parent_fid the folder ID of the parent folder 
+   \param subject the normalized subject to look up
+   \param mid the message ID for the message (0 if not found)
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND
+ */
+_PUBLIC_ enum MAPISTATUS openchangedb_get_mid_by_subject(struct ldb_context *ldb_ctx, uint64_t parent_fid, const char *subject, bool mailboxstore, uint64_t *mid)
+{
+       TALLOC_CTX              *mem_ctx;
+       struct ldb_result       *res;
+       struct ldb_dn           *base_dn;
+       const char * const      attrs[] = { "*", NULL };
+       int                     ret;
+
+       mem_ctx = talloc_named(NULL, 0, "get_mid_by_subject");
+
+       if (mailboxstore) {
+               base_dn = ldb_get_default_basedn(ldb_ctx);
+       } else {
+               base_dn = ldb_get_root_basedn(ldb_ctx);
+       }
+
+       ret = ldb_search(ldb_ctx, mem_ctx, &res, base_dn,
+                        LDB_SCOPE_SUBTREE, attrs,
+                        "(&(PidTagParentFolderId=%"PRIu64")(PidTagNormalizedSubject=%s))",
+                        parent_fid, subject);
+
+       OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NOT_FOUND, mem_ctx);
+
+       /* We should only ever get 0 records or 1 record, but there is always a chance
+          that things got confused at some point, so just return one of the records */
+       OPENCHANGE_RETVAL_IF(res->count < 1, MAPI_E_NOT_FOUND, mem_ctx);
+       
+       *mid = ldb_msg_find_attr_as_uint64(res->msgs[0], "PidTagMessageId", 0);
+
+       talloc_free(mem_ctx);
+
+       return MAPI_E_SUCCESS;
+}
+
+_PUBLIC_ enum MAPISTATUS openchangedb_delete_folder(struct ldb_context *ldb_ctx, uint64_t fid)
+{
+       TALLOC_CTX      *mem_ctx;
+       char            *dnstr;
+       struct ldb_dn   *dn;
+       int             retval;
+       enum MAPISTATUS ret;
+
+       mem_ctx = talloc_zero(NULL, TALLOC_CTX);
+
+       ret = openchangedb_get_distinguishedName(mem_ctx, ldb_ctx, fid, &dnstr);
+       if (ret != MAPI_E_SUCCESS) {
+               goto end;
+       }
+
+       dn = ldb_dn_new(mem_ctx, ldb_ctx, dnstr);
+       retval = ldb_delete(ldb_ctx, dn);
+       if (retval == LDB_SUCCESS) {
+               ret = MAPI_E_SUCCESS;
+       }
+       else {
+               ret = MAPI_E_CORRUPT_STORE;
+       }
+
+end:
+       talloc_free(mem_ctx);
+       
+       return ret;
+}
+
 /**
    \details Set the receive folder for a specific message class.
 
@@ -1379,11 +1499,7 @@ _PUBLIC_ enum MAPISTATUS openchangedb_get_fid_by_name(struct ldb_context *ldb_ct
 
    \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND
  */
-_PUBLIC_ enum MAPISTATUS openchangedb_set_ReceiveFolder(TALLOC_CTX *parent_ctx,
-                                                       struct ldb_context *ldb_ctx,
-                                                       const char *recipient,
-                                                       const char *MessageClass,
-                                                       uint64_t fid)
+_PUBLIC_ enum MAPISTATUS openchangedb_set_ReceiveFolder(struct ldb_context *ldb_ctx, const char *recipient, const char *MessageClass, uint64_t fid)
 {
        TALLOC_CTX                      *mem_ctx;
        struct ldb_result               *res = NULL;
@@ -1431,7 +1547,7 @@ _PUBLIC_ enum MAPISTATUS openchangedb_set_ReceiveFolder(TALLOC_CTX *parent_ctx,
                uint64_t folderid = ldb_msg_find_attr_as_uint64(res->msgs[0], "PidTagFolderId", 0x0);
                DEBUG(6, ("openchangedb_set_ReceiveFolder, fid to delete from: 0x%.16"PRIx64"\n", folderid));
 
-               openchangedb_get_distinguishedName(parent_ctx, ldb_ctx, folderid, &distinguishedName);
+               openchangedb_get_distinguishedName(mem_ctx, ldb_ctx, folderid, &distinguishedName);
                DEBUG(6, ("openchangedb_set_ReceiveFolder, dn to delete from: %s\n", distinguishedName));
                dn = ldb_dn_new(mem_ctx, ldb_ctx, distinguishedName);
                talloc_free(distinguishedName);
@@ -1454,7 +1570,7 @@ _PUBLIC_ enum MAPISTATUS openchangedb_set_ReceiveFolder(TALLOC_CTX *parent_ctx,
                char                    *distinguishedName;
                struct ldb_message      *msg;
 
-               openchangedb_get_distinguishedName(parent_ctx, ldb_ctx, fid, &distinguishedName);
+               openchangedb_get_distinguishedName(mem_ctx, ldb_ctx, fid, &distinguishedName);
                DEBUG(6, ("openchangedb_set_ReceiveFolder, dn to create in: %s\n", distinguishedName));
 
                dn = ldb_dn_new(mem_ctx, ldb_ctx, distinguishedName);
@@ -1560,6 +1676,89 @@ _PUBLIC_ enum MAPISTATUS openchangedb_get_users_from_partial_uri(TALLOC_CTX *par
 }
 
 
+/**
+   \details Create a folder in openchangedb
+
+   \param ldb_ctx pointer to the openchangedb LDB context
+   \param username the owner of the mailbox
+   \param systemIdx the id of the mailbox
+   \param fidp a pointer to the fid of the mailbox
+
+   \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
+ */
+_PUBLIC_ enum MAPISTATUS openchangedb_create_mailbox(struct ldb_context *ldb_ctx, const char *username, int systemIdx, uint64_t *fidp)
+{
+       enum MAPISTATUS         retval;
+       TALLOC_CTX              *mem_ctx;
+       struct ldb_dn           *mailboxdn;
+       struct ldb_message      *msg;
+       NTTIME                  now;
+       uint64_t                fid, changeNum;
+       struct GUID             guid;
+
+       /* Sanity Checks */
+       MAPI_RETVAL_IF(!ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+       MAPI_RETVAL_IF(!username, MAPI_E_NOT_INITIALIZED, NULL);
+
+       unix_to_nt_time(&now, time(NULL));
+
+       mem_ctx = talloc_named(NULL, 0, "openchangedb_create_mailbox");
+
+       openchangedb_get_new_folderID(ldb_ctx, &fid);
+       openchangedb_get_new_changeNumber(ldb_ctx, &changeNum);
+
+       /* Retrieve distinguesName for parent folder */
+
+       mailboxdn = ldb_dn_copy(mem_ctx, ldb_get_default_basedn(ldb_ctx));
+       MAPI_RETVAL_IF(!mailboxdn, MAPI_E_NOT_ENOUGH_MEMORY, mem_ctx);
+
+       ldb_dn_add_child_fmt(mailboxdn, "CN=%s", username);
+       MAPI_RETVAL_IF(!ldb_dn_validate(mailboxdn), MAPI_E_BAD_VALUE, mem_ctx);
+       
+       msg = ldb_msg_new(mem_ctx);
+       MAPI_RETVAL_IF(!msg, MAPI_E_NOT_ENOUGH_MEMORY, mem_ctx);
+
+       msg->dn = mailboxdn;
+       ldb_msg_add_string(msg, "objectClass", "systemfolder");
+       ldb_msg_add_string(msg, "objectClass", "container");
+       ldb_msg_add_string(msg, "ReplicaID", "1");
+       guid = GUID_random();
+       ldb_msg_add_fmt(msg, "ReplicaGUID", "%s", GUID_string(mem_ctx, &guid));
+       guid = GUID_random();
+       ldb_msg_add_fmt(msg, "MailboxGUID", "%s", GUID_string(mem_ctx, &guid));
+       ldb_msg_add_string(msg, "cn", username);
+       ldb_msg_add_string(msg, "PidTagAccess", "63");
+       ldb_msg_add_string(msg, "PidTagRights", "2043");
+       ldb_msg_add_fmt(msg, "PidTagDisplayName", "OpenChange Mailbox: %s", username);
+       ldb_msg_add_fmt(msg, "PidTagCreationTime", "%"PRId64, now);
+       ldb_msg_add_fmt(msg, "PidTagLastModificationTime", "%"PRId64, now);
+       ldb_msg_add_string(msg, "PidTagSubFolders", "TRUE");
+       ldb_msg_add_fmt(msg, "PidTagFolderId", "%"PRIu64, fid);
+       ldb_msg_add_fmt(msg, "PidTagChangeNumber", "%"PRIu64, changeNum);
+       ldb_msg_add_fmt(msg, "PidTagFolderType", "1");
+       if (systemIdx > -1) {
+               ldb_msg_add_fmt(msg, "SystemIdx", "%d", systemIdx);
+       }
+       ldb_msg_add_fmt(msg, "distinguishedName", "%s", ldb_dn_get_linearized(msg->dn));
+
+       msg->elements[0].flags = LDB_FLAG_MOD_ADD;
+
+       if (ldb_add(ldb_ctx, msg) != LDB_SUCCESS) {
+               retval = MAPI_E_CALL_FAILED;
+       }
+       else {
+               if (fidp) {
+                       *fidp = fid;
+               }
+
+               retval = MAPI_E_SUCCESS;
+       }
+
+       talloc_free(mem_ctx);
+
+       return retval;
+}
+
 /**
    \details Create a folder in openchangedb
 
@@ -1572,12 +1771,7 @@ _PUBLIC_ enum MAPISTATUS openchangedb_get_users_from_partial_uri(TALLOC_CTX *par
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-_PUBLIC_ enum MAPISTATUS openchangedb_create_folder(struct ldb_context *ldb_ctx,
-                                                   uint64_t parentFolderID,
-                                                   uint64_t fid,
-                                                   const char *MAPIStoreURI,
-                                                   NTTIME nt_time,
-                                                   int64_t changeNumber)
+_PUBLIC_ enum MAPISTATUS openchangedb_create_folder(struct ldb_context *ldb_ctx, uint64_t parentFolderID, uint64_t fid, uint64_t changeNumber, const char *MAPIStoreURI, int systemIdx)
 {
        enum MAPISTATUS         retval;
        TALLOC_CTX              *mem_ctx;
@@ -1586,11 +1780,15 @@ _PUBLIC_ enum MAPISTATUS openchangedb_create_folder(struct ldb_context *ldb_ctx,
        char                    *parentDN;
        struct ldb_dn           *basedn;
        struct ldb_message      *msg;
+       NTTIME                  now;
 
        /* Sanity Checks */
        MAPI_RETVAL_IF(!ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL);
-       MAPI_RETVAL_IF(!MAPIStoreURI, MAPI_E_NOT_INITIALIZED, NULL);
+       MAPI_RETVAL_IF(!parentFolderID, MAPI_E_NOT_INITIALIZED, NULL);
        MAPI_RETVAL_IF(!fid, MAPI_E_NOT_INITIALIZED, NULL);
+       MAPI_RETVAL_IF(!changeNumber, MAPI_E_NOT_INITIALIZED, NULL);
+
+       unix_to_nt_time(&now, time(NULL));
 
        mem_ctx = talloc_named(NULL, 0, "openchangedb_create_folder");
 
@@ -1614,37 +1812,45 @@ _PUBLIC_ enum MAPISTATUS openchangedb_create_folder(struct ldb_context *ldb_ctx,
        msg->dn = ldb_dn_copy(mem_ctx, basedn);
        ldb_msg_add_string(msg, "objectClass", "systemfolder");
        ldb_msg_add_fmt(msg, "cn", "%"PRIu64, fid);
+       ldb_msg_add_string(msg, "FolderType", "1");
        ldb_msg_add_string(msg, "PidTagContentUnreadCount", "0");
        ldb_msg_add_string(msg, "PidTagContentCount", "0");
-       ldb_msg_add_string(msg, "PidTagContainerClass", "IPF.Note");
        ldb_msg_add_string(msg, "PidTagAttributeHidden", "0");
        ldb_msg_add_string(msg, "PidTagAttributeSystem", "0");
        ldb_msg_add_string(msg, "PidTagAttributeReadOnly", "0");
        ldb_msg_add_string(msg, "PidTagAccess", "63");
        ldb_msg_add_string(msg, "PidTagRights", "2043");
-       ldb_msg_add_string(msg, "MAPIStoreURI", MAPIStoreURI);
-       ldb_msg_add_string(msg, "PidTagSubFolders", "FALSE");
        ldb_msg_add_fmt(msg, "PidTagFolderType", "1");
-       ldb_msg_add_fmt(msg, "PidTagParentFolderId", "%"PRIu64, parentFolderID);
-       ldb_msg_add_fmt(msg, "PidTagFolderId", "%"PRIu64, fid);
+       ldb_msg_add_fmt(msg, "PidTagCreationTime", "%"PRIu64, now);
+       ldb_msg_add_fmt(msg, "PidTagNTSDModificationTime", "%"PRIu64, now);
        if (mailboxDN) {
                ldb_msg_add_string(msg, "mailboxDN", mailboxDN);
        }
+       if (parentFolderID) {
+               ldb_msg_add_fmt(msg, "PidTagParentFolderId", "%"PRIu64, parentFolderID);
+       }
+       ldb_msg_add_fmt(msg, "PidTagFolderId", "%"PRIu64, fid);
        ldb_msg_add_fmt(msg, "PidTagChangeNumber", "%"PRIu64, changeNumber);
-       ldb_msg_add_fmt(msg, "PidTagCreationTime", "%"PRIu64, nt_time);
-       ldb_msg_add_fmt(msg, "PidTagNTSDModificationTime", "%"PRIu64, nt_time);
-       ldb_msg_add_string(msg, "FolderType", "1");
+       if (MAPIStoreURI) {
+               ldb_msg_add_string(msg, "MAPIStoreURI", MAPIStoreURI);
+       }
+       if (systemIdx > -1) {
+               ldb_msg_add_fmt(msg, "SystemIdx", "%d", systemIdx);
+       }
        ldb_msg_add_fmt(msg, "distinguishedName", "%s", ldb_dn_get_linearized(msg->dn));
 
        msg->elements[0].flags = LDB_FLAG_MOD_ADD;
 
        if (ldb_add(ldb_ctx, msg) != LDB_SUCCESS) {
-               talloc_free(mem_ctx);
-               return MAPI_E_CALL_FAILED;
+               retval = MAPI_E_CALL_FAILED;
+       }
+       else {
+               retval = MAPI_E_SUCCESS;
        }
 
        talloc_free(mem_ctx);
-       return MAPI_E_SUCCESS;
+
+       return retval;
 }
 
 /**
index 45c2aa99c372682a7d8ae2baefd77425dedf1ba1..a1a003b115fa40b79a535e93f54a97b6e676e983 100644 (file)
@@ -66,7 +66,9 @@ _PUBLIC_ enum MAPISTATUS openchangedb_message_create(TALLOC_CTX *mem_ctx, struct
 
        /* Retrieve mailboxDN of parent folder */
        retval = openchangedb_get_mailboxDN(mem_ctx, ldb_ctx, folderID, &mailboxDN);
-       OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+       if (retval) {
+               mailboxDN = NULL;
+       }
        
        dn = talloc_asprintf(mem_ctx, "CN=%"PRIu64",%s", messageID, parentDN);
        OPENCHANGE_RETVAL_IF(!dn, MAPI_E_NOT_ENOUGH_MEMORY, NULL);
@@ -186,7 +188,6 @@ _PUBLIC_ enum MAPISTATUS openchangedb_message_open(TALLOC_CTX *mem_ctx, struct l
        /* Sanity checks */
        OPENCHANGE_RETVAL_IF(!ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL);
        OPENCHANGE_RETVAL_IF(!message_object, MAPI_E_NOT_INITIALIZED, NULL);
-       OPENCHANGE_RETVAL_IF(!msgp, MAPI_E_NOT_INITIALIZED, NULL);
 
        msg = talloc_zero(mem_ctx, struct openchangedb_message);
        if (!msg) {
@@ -208,16 +209,17 @@ _PUBLIC_ enum MAPISTATUS openchangedb_message_open(TALLOC_CTX *mem_ctx, struct l
        printf("We have found: %d messages for ldb_filter = %s\n", msg->res->count, ldb_filter);
        talloc_free(ldb_filter);
        OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !msg->res->count, MAPI_E_NOT_FOUND, msg);
-
-       mmsg = talloc_zero(mem_ctx, struct mapistore_message);
-       mmsg->subject_prefix = NULL;
-       mmsg->normalized_subject = (char *)ldb_msg_find_attr_as_string(msg->res->msgs[0], "PidTagNormalizedSubject", NULL);
-       mmsg->columns = NULL;
-       mmsg->recipients_count = 0;
-       mmsg->recipients = NULL;
-
        *message_object = (void *)msg;
-       *msgp = (void *)mmsg;
+
+       if (msgp) {
+               mmsg = talloc_zero(mem_ctx, struct mapistore_message);
+               mmsg->subject_prefix = NULL;
+               mmsg->normalized_subject = (char *)ldb_msg_find_attr_as_string(msg->res->msgs[0], "PidTagNormalizedSubject", NULL);
+               mmsg->columns = NULL;
+               mmsg->recipients_count = 0;
+               mmsg->recipients = NULL;
+               *msgp = (void *)mmsg;
+       }
 
        return MAPI_E_SUCCESS;
 }
index 9b2ef8a969a756d2bde02e6c317269679d6b7d83..1887f2bc219dd83b68439b633a1f66905287cfe4 100644 (file)
@@ -54,7 +54,7 @@ _PUBLIC_ enum MAPISTATUS openchangedb_table_init(TALLOC_CTX *mem_ctx, uint8_t ta
        if (!table) {
                return MAPI_E_NOT_ENOUGH_MEMORY;
        }
-       printf("openchangedb_table_init: folderID=%"PRIu64"\n", folderID);
+       /* printf("openchangedb_table_init: folderID=%"PRIu64"\n", folderID); */
        table->folderID = folderID;
        table->table_type = table_type;
        table->lpSortCriteria = NULL;
@@ -220,7 +220,6 @@ static char *openchangedb_table_build_filter(TALLOC_CTX *mem_ctx, struct opencha
 _PUBLIC_ enum MAPISTATUS openchangedb_table_get_property(TALLOC_CTX *mem_ctx,
                                                         void *table_object,
                                                         struct ldb_context *ldb_ctx,
-                                                        const char *recipient,
                                                         enum MAPITAGS proptag,
                                                         uint32_t pos,
                                                         bool live_filtered,
@@ -237,7 +236,6 @@ _PUBLIC_ enum MAPISTATUS openchangedb_table_get_property(TALLOC_CTX *mem_ctx,
        /* Sanity checks */
        OPENCHANGE_RETVAL_IF(!table_object, MAPI_E_NOT_INITIALIZED, NULL);
        OPENCHANGE_RETVAL_IF(!ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL);
-       OPENCHANGE_RETVAL_IF(!recipient, MAPI_E_NOT_INITIALIZED, NULL);
        OPENCHANGE_RETVAL_IF(!data, MAPI_E_NOT_INITIALIZED, NULL);
 
        table = (struct openchangedb_table *)table_object;
@@ -259,7 +257,6 @@ _PUBLIC_ enum MAPISTATUS openchangedb_table_get_property(TALLOC_CTX *mem_ctx,
                OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_INVALID_OBJECT, NULL);
        }
        res = table->res;
-       printf("res->count = %d\n", res->count);
 
        /* Ensure position is within search results range */
        OPENCHANGE_RETVAL_IF(pos >= res->count, MAPI_E_INVALID_OBJECT, NULL);
@@ -296,6 +293,20 @@ _PUBLIC_ enum MAPISTATUS openchangedb_table_get_property(TALLOC_CTX *mem_ctx,
                talloc_free(live_res);
        }
 
+       /* hacks for some attributes specific to tables */
+       if (proptag == PR_INST_ID) {
+               if (table->table_type == 1) {
+                       proptag = PR_FID;
+               }
+               else {
+                       proptag = PR_MID;
+               }
+       }
+       else if (proptag == PR_INSTANCE_NUM) {
+               *data = talloc_zero(mem_ctx, uint32_t);
+               return MAPI_E_SUCCESS;
+       }
+
        /* Convert proptag into PidTag attribute */
        if ((table->table_type != 0x1) && proptag == PR_FID) {
                proptag = PR_PARENT_FID;
@@ -307,7 +318,7 @@ _PUBLIC_ enum MAPISTATUS openchangedb_table_get_property(TALLOC_CTX *mem_ctx,
        OPENCHANGE_RETVAL_IF(!ldb_msg_find_element(res->msgs[pos], PidTagAttr), MAPI_E_NOT_FOUND, NULL);
 
        /* Check if this is a "special property" */
-       *data = openchangedb_get_special_property(mem_ctx, ldb_ctx, recipient, res, proptag, PidTagAttr);
+       *data = openchangedb_get_special_property(mem_ctx, ldb_ctx, res, proptag, PidTagAttr);
        OPENCHANGE_RETVAL_IF(*data != NULL, MAPI_E_SUCCESS, NULL);
 
        /* Check if this is NOT a "special property" */
index 6c773b8bfcf2090a4e55874e365c4909f289615d..b5fa0fc48938342776a751b1a5297eb0794b1f99 100644 (file)
@@ -505,6 +505,10 @@ _PUBLIC_ int libmapiserver_push_property(TALLOC_CTX *mem_ctx,
                ndr_push_FILETIME(ndr, NDR_SCALARS, (struct FILETIME *) value);
                break;
 
+       case PT_MV_LONG:
+               ndr_push_mapi_MV_LONG_STRUCT(ndr, NDR_SCALARS, (struct mapi_MV_LONG_STRUCT *) value);
+               break;
+
        case PT_MV_UNICODE:
                 ndr_push_mapi_SPLSTRArrayW(ndr, NDR_SCALARS, (struct mapi_SPLSTRArrayW *) value);
                break;
@@ -519,6 +523,10 @@ _PUBLIC_ int libmapiserver_push_property(TALLOC_CTX *mem_ctx,
                }
                break;
        default:
+               if (property != 0) {
+                       DEBUG(5, ("unsupported type: %.4x\n", (property & 0xffff)));
+                       abort();
+               }
                break;
        }
 end:
index e895cb90a6fb3d0dfd08c3540fc31f500811d0f5..629b6b209fc4328a08624949540931fdf358bc30 100644 (file)
@@ -48,10 +48,7 @@ _PUBLIC_ uint16_t libmapiserver_RopLogon_size(struct EcDoRpc_MAPI_REQ *request,
        if (response->error_code == ecWrongServer) {
                size += SIZE_DFLT_ROPLOGON_REDIRECT;
                size += strlen (response->us.mapi_Logon.ServerName) + 1;
-               return size;
-       }
-
-       if (request->u.mapi_Logon.LogonFlags & LogonPrivate) {
+       } else if (request->u.mapi_Logon.LogonFlags & LogonPrivate) {
                size += SIZE_DFLT_ROPLOGON_MAILBOX;
        } else {
                size += SIZE_DFLT_ROPLOGON_PUBLICFOLDER;
index 736db4bf97e495ef31d2e4876c480a40554dac79..2639de062b89a77718ae187cb479ed5f08ffbdcb 100644 (file)
@@ -53,13 +53,6 @@ typedef      int (*init_backend_fn) (void);
 
 #define        MAPISTORE_INIT_MODULE   "mapistore_init_backend"
 
-#define        MAPISTORE_FOLDER_TABLE          1
-#define        MAPISTORE_MESSAGE_TABLE         2
-#define        MAPISTORE_FAI_TABLE             3
-#define        MAPISTORE_RULE_TABLE            4
-#define        MAPISTORE_ATTACHMENT_TABLE      5
-#define        MAPISTORE_PERMISSIONS_TABLE     6
-
 #define MAPISTORE_FOLDER        1
 #define        MAPISTORE_MESSAGE       2
 #define        MAPISTORE_ATTACHMENT    3
@@ -90,7 +83,16 @@ struct indexing_folders_list {
        uint32_t                        count;
 };
 
-enum table_query_type {
+enum mapistore_table_type {
+       MAPISTORE_FOLDER_TABLE = 1,
+       MAPISTORE_MESSAGE_TABLE = 2,
+       MAPISTORE_FAI_TABLE = 3,
+       MAPISTORE_RULE_TABLE = 4,
+       MAPISTORE_ATTACHMENT_TABLE = 5,
+       MAPISTORE_PERMISSIONS_TABLE = 6
+};
+
+enum mapistore_query_type {
        MAPISTORE_PREFILTERED_QUERY,
        MAPISTORE_LIVEFILTERED_QUERY,
 };
@@ -110,11 +112,32 @@ struct mapistore_connection_info {
        struct ldb_context              *oc_ctx; /* openchangedb */
 };
 
-struct tdb_wrap;
+enum mapistore_context_role {
+       MAPISTORE_MAIL_ROLE,
+       MAPISTORE_DRAFTS_ROLE,
+       MAPISTORE_SENTITEMS_ROLE,
+       MAPISTORE_OUTBOX_ROLE,
+       MAPISTORE_DELETEDITEMS_ROLE,
+       MAPISTORE_CALENDAR_ROLE,
+       MAPISTORE_CONTACTS_ROLE,
+       MAPISTORE_TASKS_ROLE,
+       MAPISTORE_NOTES_ROLE,
+       MAPISTORE_JOURNAL_ROLE,
+       MAPISTORE_FALLBACK_ROLE,
+       MAPISTORE_MAX_ROLES
+};
+
+struct mapistore_contexts_list {
+       char                            *url;
+       char                            *name;
+       bool                            main_folder;
+       enum mapistore_context_role     role;
+       char                            *tag;
+       struct mapistore_contexts_list  *prev;
+       struct mapistore_contexts_list  *next;
+};
 
-/* notes:
-   openfolder takes the folderid alone as argument
-   openmessage takes the message id and its parent folderid as arguments  */
+struct tdb_wrap;
 
 struct mapistore_backend {
        /** backend operations */
@@ -123,67 +146,69 @@ struct mapistore_backend {
                const char      *description;
                const char      *namespace;
 
-               int             (*init)(void);
-               int             (*create_context)(TALLOC_CTX *, struct mapistore_connection_info *, struct tdb_wrap *, const char *, void **);
+               enum mapistore_error    (*init)(void);
+               enum mapistore_error    (*list_contexts)(const char *, struct tdb_wrap *, TALLOC_CTX *, struct mapistore_contexts_list **);
+               enum mapistore_error    (*create_context)(TALLOC_CTX *, struct mapistore_connection_info *, struct tdb_wrap *, const char *, void **);
+               enum mapistore_error    (*create_root_folder)(const char *, enum mapistore_context_role, uint64_t, const char *, TALLOC_CTX *, char **);
        } backend;
 
        /** context operations */
        struct {
-               int             (*get_path)(void *, TALLOC_CTX *, uint64_t, char **);
-               int             (*get_root_folder)(void *, TALLOC_CTX *, uint64_t, void **);
+               enum mapistore_error    (*get_path)(void *, TALLOC_CTX *, uint64_t, char **);
+               enum mapistore_error    (*get_root_folder)(void *, TALLOC_CTX *, uint64_t, void **);
        } context;
 
         /** oxcfold operations */
         struct {
-               int             (*open_folder)(void *, TALLOC_CTX *, uint64_t, void **);
-               int             (*create_folder)(void *, TALLOC_CTX *, uint64_t, struct SRow *, void **);
-               int             (*delete_folder)(void *, uint64_t);
-               int             (*open_message)(void *, TALLOC_CTX *, uint64_t, void **);
-               int             (*create_message)(void *, TALLOC_CTX *, uint64_t, uint8_t, void **);
-               int             (*delete_message)(void *, uint64_t, uint8_t flags);
-               int             (*move_copy_messages)(void *, void *, uint32_t, uint64_t *, uint64_t *, struct Binary_r **, uint8_t);
-               int             (*get_deleted_fmids)(void *, TALLOC_CTX *, uint8_t, uint64_t, struct I8Array_r **, uint64_t *);
-               int             (*get_child_count)(void *, uint8_t, uint32_t *);
-                int            (*open_table)(void *, TALLOC_CTX *, uint8_t, uint32_t, void **, uint32_t *);
-               int             (*modify_permissions)(void *, uint8_t, uint16_t, struct PermissionData *);
+               enum mapistore_error    (*open_folder)(void *, TALLOC_CTX *, uint64_t, void **);
+               enum mapistore_error    (*create_folder)(void *, TALLOC_CTX *, uint64_t, struct SRow *, void **);
+               enum mapistore_error    (*delete)(void *);
+               enum mapistore_error    (*open_message)(void *, TALLOC_CTX *, uint64_t, bool, void **);
+               enum mapistore_error    (*create_message)(void *, TALLOC_CTX *, uint64_t, uint8_t, void **);
+               enum mapistore_error    (*delete_message)(void *, uint64_t, uint8_t);
+               enum mapistore_error    (*move_copy_messages)(void *, void *, uint32_t, uint64_t *, uint64_t *, struct Binary_r **, uint8_t);
+               enum mapistore_error    (*get_deleted_fmids)(void *, TALLOC_CTX *, enum mapistore_table_type, uint64_t, struct I8Array_r **, uint64_t *);
+               enum mapistore_error    (*get_child_count)(void *, enum mapistore_table_type, uint32_t *);
+                enum mapistore_error   (*open_table)(void *, TALLOC_CTX *, enum mapistore_table_type, uint32_t, void **, uint32_t *);
+               enum mapistore_error    (*modify_permissions)(void *, uint8_t, uint16_t, struct PermissionData *);
         } folder;
 
         /** oxcmsg operations */
         struct {
-               int             (*get_message_data)(void *, TALLOC_CTX *, struct mapistore_message **);
-               int             (*modify_recipients)(void *, struct SPropTagArray *, uint16_t, struct mapistore_message_recipient *);
-                int            (*set_read_flag)(void *, uint8_t);
-               int             (*save)(void *);
-               int             (*submit)(void *, enum SubmitFlags);
-                int            (*open_attachment)(void *, TALLOC_CTX *, uint32_t, void **);
-                int            (*create_attachment)(void *, TALLOC_CTX *, void **, uint32_t *);
-                int            (*get_attachment_table)(void *, TALLOC_CTX *, void **, uint32_t *);
+               enum mapistore_error    (*get_message_data)(void *, TALLOC_CTX *, struct mapistore_message **);
+               enum mapistore_error    (*modify_recipients)(void *, struct SPropTagArray *, uint16_t, struct mapistore_message_recipient *);
+                enum mapistore_error   (*set_read_flag)(void *, uint8_t);
+               enum mapistore_error    (*save)(void *);
+               enum mapistore_error    (*submit)(void *, enum SubmitFlags);
+                enum mapistore_error   (*open_attachment)(void *, TALLOC_CTX *, uint32_t, void **);
+                enum mapistore_error   (*create_attachment)(void *, TALLOC_CTX *, void **, uint32_t *);
+                enum mapistore_error   (*get_attachment_table)(void *, TALLOC_CTX *, void **, uint32_t *);
 
                /* attachments */
-                int            (*open_embedded_message)(void *, TALLOC_CTX *, void **, uint64_t *, struct mapistore_message **);
+                enum mapistore_error   (*open_embedded_message)(void *, TALLOC_CTX *, void **, uint64_t *, struct mapistore_message **);
         } message;
 
         /** oxctabl operations */
         struct {
-                int            (*get_available_properties)(void *, TALLOC_CTX *, struct SPropTagArray **);
-                int            (*set_columns)(void *, uint16_t, enum MAPITAGS *);
-                int            (*set_restrictions)(void *, struct mapi_SRestriction *, uint8_t *);
-                int            (*set_sort_order)(void *, struct SSortOrderSet *, uint8_t *);
-                int            (*get_row)(void *, TALLOC_CTX *, enum table_query_type, uint32_t, struct mapistore_property_data **);
-                int            (*get_row_count)(void *, enum table_query_type, uint32_t *);
-               int             (*handle_destructor)(void *, uint32_t);
+                enum mapistore_error   (*get_available_properties)(void *, TALLOC_CTX *, struct SPropTagArray **);
+                enum mapistore_error   (*set_columns)(void *, uint16_t, enum MAPITAGS *);
+                enum mapistore_error   (*set_restrictions)(void *, struct mapi_SRestriction *, uint8_t *);
+                enum mapistore_error   (*set_sort_order)(void *, struct SSortOrderSet *, uint8_t *);
+                enum mapistore_error   (*get_row)(void *, TALLOC_CTX *, enum mapistore_query_type, uint32_t, struct mapistore_property_data **);
+                enum mapistore_error   (*get_row_count)(void *, enum mapistore_query_type, uint32_t *);
+               enum mapistore_error    (*handle_destructor)(void *, uint32_t);
         } table;
 
         /** oxcprpt operations */
         struct {
-                int            (*get_available_properties)(void *, TALLOC_CTX *, struct SPropTagArray **);
-                int            (*get_properties)(void *, TALLOC_CTX *, uint16_t, enum MAPITAGS *, struct mapistore_property_data *);
-                int            (*set_properties)(void *, struct SRow *);
+                enum mapistore_error   (*get_available_properties)(void *, TALLOC_CTX *, struct SPropTagArray **);
+                enum mapistore_error   (*get_properties)(void *, TALLOC_CTX *, uint16_t, enum MAPITAGS *, struct mapistore_property_data *);
+                enum mapistore_error   (*set_properties)(void *, struct SRow *);
         } properties;
 
        /** manager operations */
        struct {
-               int             (*generate_uri)(TALLOC_CTX *, const char *, const char *, const char *, const char *, char **);
+               enum mapistore_error    (*generate_uri)(TALLOC_CTX *, const char *, const char *, const char *, const char *, char **);
        } manager;
 };
 
@@ -237,57 +262,59 @@ __BEGIN_DECLS
 int mapistore_getprops(struct mapistore_context *, uint32_t, TALLOC_CTX *, uint64_t, uint8_t, struct SPropTagArray *, struct SRow *);
 int mapistore_setprops(struct mapistore_context *, uint32_t, uint64_t, uint8_t, struct SRow *);
 
-struct mapistore_context *mapistore_init(TALLOC_CTX *, const char *);
-int mapistore_release(struct mapistore_context *);
-int mapistore_set_connection_info(struct mapistore_context *, struct ldb_context *, struct ldb_context *, const char *);
-int mapistore_add_context(struct mapistore_context *, const char *, const char *, uint64_t, uint32_t *, void **);
-int mapistore_add_context_ref_count(struct mapistore_context *, uint32_t);
-int mapistore_del_context(struct mapistore_context *, uint32_t);
-int mapistore_search_context_by_uri(struct mapistore_context *, const char *, uint32_t *, void **);
-const char *mapistore_errstr(int);
-
-int mapistore_folder_open_folder(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint64_t, void **);
-int mapistore_folder_create_folder(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint64_t, struct SRow *, void **);
-int mapistore_folder_delete_folder(struct mapistore_context *, uint32_t, void *, uint64_t, uint8_t);
-int mapistore_folder_open_message(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint64_t, void **);
-int mapistore_folder_create_message(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint64_t, uint8_t, void **);
-int mapistore_folder_delete_message(struct mapistore_context *, uint32_t, void *, uint64_t, uint8_t);
-int mapistore_folder_move_copy_messages(struct mapistore_context *, uint32_t, void *, void *, uint32_t, uint64_t *, uint64_t *, struct Binary_r **, uint8_t);
-int mapistore_folder_get_deleted_fmids(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint8_t, uint64_t, struct I8Array_r **, uint64_t *);
-int mapistore_folder_get_folder_count(struct mapistore_context *, uint32_t, void *, uint32_t *);
-int mapistore_folder_get_message_count(struct mapistore_context *, uint32_t, void *, uint8_t, uint32_t *);
-int mapistore_folder_get_child_fids(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint64_t **, uint32_t *);
-int mapistore_folder_get_child_fid_by_name(struct mapistore_context *, uint32_t, void *, const char *, uint64_t *);
-int mapistore_folder_open_table(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint8_t, uint32_t, void **, uint32_t *);
-int mapistore_folder_modify_permissions(struct mapistore_context *, uint32_t, void *, uint8_t, uint16_t, struct PermissionData *);
-
-int mapistore_message_get_message_data(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, struct mapistore_message **);
-int mapistore_message_modify_recipients(struct mapistore_context *, uint32_t, void *, struct SPropTagArray *, uint16_t, struct mapistore_message_recipient *);
-int mapistore_message_set_read_flag(struct mapistore_context *, uint32_t, void *, uint8_t);
-int mapistore_message_save(struct mapistore_context *, uint32_t, void *);
-int mapistore_message_submit(struct mapistore_context *, uint32_t, void *, enum SubmitFlags);
-int mapistore_message_open_attachment(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint32_t, void **);
-int mapistore_message_create_attachment(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, void **, uint32_t *);
-int mapistore_message_get_attachment_table(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, void **, uint32_t *);
-int mapistore_message_attachment_open_embedded_message(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, void **, uint64_t *, struct mapistore_message **msg);
-
-int mapistore_table_get_available_properties(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, struct SPropTagArray **);
-int mapistore_table_set_columns(struct mapistore_context *, uint32_t, void *, uint16_t, enum MAPITAGS *);
-int mapistore_table_set_restrictions(struct mapistore_context *, uint32_t, void *, struct mapi_SRestriction *, uint8_t *);
-int mapistore_table_set_sort_order(struct mapistore_context *, uint32_t, void *, struct SSortOrderSet *, uint8_t *);
-int mapistore_table_get_row(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, enum table_query_type, uint32_t, struct mapistore_property_data **);
-int mapistore_table_get_row_count(struct mapistore_context *, uint32_t, void *, enum table_query_type, uint32_t *);
-int mapistore_table_handle_destructor(struct mapistore_context *, uint32_t, void *, uint32_t);
-
-int mapistore_properties_get_available_properties(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, struct SPropTagArray **);
-int mapistore_properties_get_properties(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint16_t, enum MAPITAGS *, struct mapistore_property_data *);
-int mapistore_properties_set_properties(struct mapistore_context *, uint32_t, void *, struct SRow *);
+struct mapistore_context *mapistore_init(TALLOC_CTX *, struct loadparm_context *, const char *);
+enum mapistore_error mapistore_release(struct mapistore_context *);
+enum mapistore_error mapistore_set_connection_info(struct mapistore_context *, struct ldb_context *, struct ldb_context *, const char *);
+enum mapistore_error mapistore_add_context(struct mapistore_context *, const char *, const char *, uint64_t, uint32_t *, void **);
+enum mapistore_error mapistore_add_context_ref_count(struct mapistore_context *, uint32_t);
+enum mapistore_error mapistore_del_context(struct mapistore_context *, uint32_t);
+enum mapistore_error mapistore_search_context_by_uri(struct mapistore_context *, const char *, uint32_t *, void **);
+const char *mapistore_errstr(enum mapistore_error);
+
+enum mapistore_error mapistore_list_contexts_for_user(struct mapistore_context *, const char *, TALLOC_CTX *, struct mapistore_contexts_list **);
+enum mapistore_error mapistore_create_root_folder(const char *, enum mapistore_context_role, uint64_t, const char *, TALLOC_CTX *, char **);
+
+enum mapistore_error mapistore_folder_open_folder(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint64_t, void **);
+enum mapistore_error mapistore_folder_create_folder(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint64_t, struct SRow *, void **);
+enum mapistore_error mapistore_folder_delete(struct mapistore_context *, uint32_t, void *, uint8_t);
+enum mapistore_error mapistore_folder_open_message(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint64_t, bool, void **);
+enum mapistore_error mapistore_folder_create_message(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint64_t, uint8_t, void **);
+enum mapistore_error mapistore_folder_delete_message(struct mapistore_context *, uint32_t, void *, uint64_t, uint8_t);
+enum mapistore_error mapistore_folder_move_copy_messages(struct mapistore_context *, uint32_t, void *, void *, uint32_t, uint64_t *, uint64_t *, struct Binary_r **, uint8_t);
+enum mapistore_error mapistore_folder_get_deleted_fmids(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, enum mapistore_table_type, uint64_t, struct I8Array_r **, uint64_t *);
+enum mapistore_error mapistore_folder_get_child_count(struct mapistore_context *, uint32_t, void *, enum mapistore_table_type, uint32_t *);
+enum mapistore_error mapistore_folder_get_child_fmids(struct mapistore_context *, uint32_t, void *, enum mapistore_table_type, TALLOC_CTX *, uint64_t **, uint32_t *);
+enum mapistore_error mapistore_folder_get_child_fid_by_name(struct mapistore_context *, uint32_t, void *, const char *, uint64_t *);
+enum mapistore_error mapistore_folder_open_table(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, enum mapistore_table_type, uint32_t, void **, uint32_t *);
+enum mapistore_error mapistore_folder_modify_permissions(struct mapistore_context *, uint32_t, void *, uint8_t, uint16_t, struct PermissionData *);
+
+enum mapistore_error mapistore_message_get_message_data(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, struct mapistore_message **);
+enum mapistore_error mapistore_message_modify_recipients(struct mapistore_context *, uint32_t, void *, struct SPropTagArray *, uint16_t, struct mapistore_message_recipient *);
+enum mapistore_error mapistore_message_set_read_flag(struct mapistore_context *, uint32_t, void *, uint8_t);
+enum mapistore_error mapistore_message_save(struct mapistore_context *, uint32_t, void *);
+enum mapistore_error mapistore_message_submit(struct mapistore_context *, uint32_t, void *, enum SubmitFlags);
+enum mapistore_error mapistore_message_open_attachment(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint32_t, void **);
+enum mapistore_error mapistore_message_create_attachment(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, void **, uint32_t *);
+enum mapistore_error mapistore_message_get_attachment_table(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, void **, uint32_t *);
+enum mapistore_error mapistore_message_attachment_open_embedded_message(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, void **, uint64_t *, struct mapistore_message **msg);
+
+enum mapistore_error mapistore_table_get_available_properties(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, struct SPropTagArray **);
+enum mapistore_error mapistore_table_set_columns(struct mapistore_context *, uint32_t, void *, uint16_t, enum MAPITAGS *);
+enum mapistore_error mapistore_table_set_restrictions(struct mapistore_context *, uint32_t, void *, struct mapi_SRestriction *, uint8_t *);
+enum mapistore_error mapistore_table_set_sort_order(struct mapistore_context *, uint32_t, void *, struct SSortOrderSet *, uint8_t *);
+enum mapistore_error mapistore_table_get_row(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, enum mapistore_query_type, uint32_t, struct mapistore_property_data **);
+enum mapistore_error mapistore_table_get_row_count(struct mapistore_context *, uint32_t, void *, enum mapistore_query_type, uint32_t *);
+enum mapistore_error mapistore_table_handle_destructor(struct mapistore_context *, uint32_t, void *, uint32_t);
+
+enum mapistore_error mapistore_properties_get_available_properties(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, struct SPropTagArray **);
+enum mapistore_error mapistore_properties_get_properties(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint16_t, enum MAPITAGS *, struct mapistore_property_data *);
+enum mapistore_error mapistore_properties_set_properties(struct mapistore_context *, uint32_t, void *, struct SRow *);
 
 /* definitions from mapistore_processing.c */
-int mapistore_set_mapping_path(const char *);
+enum mapistore_error mapistore_set_mapping_path(const char *);
 
 /* definitions from mapistore_backend.c */
-extern int     mapistore_backend_register(const void *);
+enum mapistore_error mapistore_backend_register(const void *);
 const char     *mapistore_backend_get_installdir(void);
 init_backend_fn        *mapistore_backend_load(TALLOC_CTX *, const char *);
 struct backend_context *mapistore_backend_lookup(struct backend_context_list *, uint32_t);
@@ -296,30 +323,30 @@ struct backend_context *mapistore_backend_lookup_by_name(TALLOC_CTX *, const cha
 bool           mapistore_backend_run_init(init_backend_fn *);
 
 /* definitions from mapistore_indexing.c */
-int mapistore_indexing_record_add_fid(struct mapistore_context *, uint32_t, const char *, uint64_t);
-int mapistore_indexing_record_del_fid(struct mapistore_context *, uint32_t, const char *, uint64_t, uint8_t);
-int mapistore_indexing_record_add_mid(struct mapistore_context *, uint32_t, const char *, uint64_t);
-int mapistore_indexing_record_del_mid(struct mapistore_context *, uint32_t, const char *, uint64_t, uint8_t);
-int mapistore_indexing_record_get_uri(struct mapistore_context *, const char *, TALLOC_CTX *, uint64_t, char **, bool *);
-int mapistore_indexing_record_get_fmid(struct mapistore_context *, const char *, const char *, bool, uint64_t *, bool *);
+enum mapistore_error mapistore_indexing_record_add_fid(struct mapistore_context *, uint32_t, const char *, uint64_t);
+enum mapistore_error mapistore_indexing_record_del_fid(struct mapistore_context *, uint32_t, const char *, uint64_t, uint8_t);
+enum mapistore_error mapistore_indexing_record_add_mid(struct mapistore_context *, uint32_t, const char *, uint64_t);
+enum mapistore_error mapistore_indexing_record_del_mid(struct mapistore_context *, uint32_t, const char *, uint64_t, uint8_t);
+enum mapistore_error mapistore_indexing_record_get_uri(struct mapistore_context *, const char *, TALLOC_CTX *, uint64_t, char **, bool *);
+enum mapistore_error mapistore_indexing_record_get_fmid(struct mapistore_context *, const char *, const char *, bool, uint64_t *, bool *);
 
 /* definitions from mapistore_replica_mapping.c */
-_PUBLIC_ int mapistore_replica_mapping_add(struct mapistore_context *, const char *, struct replica_mapping_context_list **);
-_PUBLIC_ int mapistore_replica_mapping_guid_to_replid(struct mapistore_context *, const char *username, const struct GUID *, uint16_t *);
-_PUBLIC_ int mapistore_replica_mapping_replid_to_guid(struct mapistore_context *, const char *username, uint16_t, struct GUID *);
+enum mapistore_error mapistore_replica_mapping_add(struct mapistore_context *, const char *, struct replica_mapping_context_list **);
+enum mapistore_error mapistore_replica_mapping_guid_to_replid(struct mapistore_context *, const char *username, const struct GUID *, uint16_t *);
+enum mapistore_error mapistore_replica_mapping_replid_to_guid(struct mapistore_context *, const char *username, uint16_t, struct GUID *);
 
 /* definitions from mapistore_namedprops.c */
-int mapistore_namedprops_get_mapped_id(struct ldb_context *ldb_ctx, struct MAPINAMEID, uint16_t *);
+enum mapistore_error mapistore_namedprops_get_mapped_id(struct ldb_context *ldb_ctx, struct MAPINAMEID, uint16_t *);
 uint16_t mapistore_namedprops_next_unused_id(struct ldb_context *);
-int mapistore_namedprops_create_id(struct ldb_context *, struct MAPINAMEID, uint16_t);
-int mapistore_namedprops_get_nameid(struct ldb_context *, uint16_t, struct MAPINAMEID **);
+enum mapistore_error mapistore_namedprops_create_id(struct ldb_context *, struct MAPINAMEID, uint16_t);
+enum mapistore_error mapistore_namedprops_get_nameid(struct ldb_context *, uint16_t, struct MAPINAMEID **);
 
 /* definitions from mapistore_mgmt.c */
-int mapistore_mgmt_backend_register_user(struct mapistore_connection_info *, const char *, const char *);
-int mapistore_mgmt_backend_unregister_user(struct mapistore_connection_info *, const char *, const char *);
-int mapistore_mgmt_interface_register_subscription(struct mapistore_connection_info *, struct mapistore_mgmt_notif *);
-int mapistore_mgmt_interface_unregister_subscription(struct mapistore_connection_info *, struct mapistore_mgmt_notif *);
-int mapistore_mgmt_interface_register_bind(struct mapistore_connection_info *, uint16_t, uint8_t *, uint16_t, uint8_t *);
+enum mapistore_error mapistore_mgmt_backend_register_user(struct mapistore_connection_info *, const char *, const char *);
+enum mapistore_error mapistore_mgmt_backend_unregister_user(struct mapistore_connection_info *, const char *, const char *);
+enum mapistore_error mapistore_mgmt_interface_register_subscription(struct mapistore_connection_info *, struct mapistore_mgmt_notif *);
+enum mapistore_error mapistore_mgmt_interface_unregister_subscription(struct mapistore_connection_info *, struct mapistore_mgmt_notif *);
+enum mapistore_error mapistore_mgmt_interface_register_bind(struct mapistore_connection_info *, uint16_t, uint8_t *, uint16_t, uint8_t *);
 
 /* definitions from mapistore_notifications.c (proof-of-concept) */
 
@@ -402,7 +429,7 @@ struct mapistore_notification {
 };
 
 struct mapistore_subscription_list *mapistore_find_matching_subscriptions(struct mapistore_context *, struct mapistore_notification *);
-_PUBLIC_ int mapistore_delete_subscription(struct mapistore_context *, uint32_t, uint16_t);
+enum mapistore_error mapistore_delete_subscription(struct mapistore_context *, uint32_t, uint16_t);
 void mapistore_push_notification(struct mapistore_context *, uint8_t, enum mapistore_notification_type, void *);
 enum MAPISTATUS mapistore_get_queued_notifications(struct mapistore_context *, struct mapistore_subscription *, struct mapistore_notification_list **);
 enum MAPISTATUS mapistore_get_queued_notifications_named(struct mapistore_context *, const char *, struct mapistore_notification_list **);
index b9cf945cf76925136c943a88f59cd70775abda5d..ca2a1173013ee0fbb3fde860e7e6bb5a2de5caaa 100644 (file)
@@ -57,7 +57,7 @@ int                                   num_backends;
 
    \return MAPISTORE_SUCCESS on success
  */
-_PUBLIC_ extern int mapistore_backend_register(const void *_backend)
+_PUBLIC_ enum mapistore_error mapistore_backend_register(const void *_backend)
 {
        const struct mapistore_backend  *backend = _backend;
        uint32_t                        i;
@@ -99,7 +99,7 @@ _PUBLIC_ extern int mapistore_backend_register(const void *_backend)
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-_PUBLIC_ int mapistore_backend_registered(const char *name)
+_PUBLIC_ enum mapistore_error mapistore_backend_registered(const char *name)
 {
        int     i;
 
@@ -265,7 +265,7 @@ _PUBLIC_ bool mapistore_backend_run_init(init_backend_fn *fns)
    \return MAPISTORE_SUCCESS on success, otherwise
    MAPISTORE_ERR_BACKEND_INIT
  */
-int mapistore_backend_init(TALLOC_CTX *mem_ctx, const char *path)
+enum mapistore_error mapistore_backend_init(TALLOC_CTX *mem_ctx, const char *path)
 {
        init_backend_fn                 *ret;
        bool                            status;
@@ -290,6 +290,38 @@ int mapistore_backend_init(TALLOC_CTX *mem_ctx, const char *path)
        return (status != true) ? MAPISTORE_SUCCESS : MAPISTORE_ERR_BACKEND_INIT;
 }
 
+/**
+   \details List backend contexts for given user
+
+   \param mem_ctx pointer to the memory context
+   \param namespace the backend namespace
+   \param uri the backend parameters which can be passes inline
+
+   \return a valid backend_context pointer on success, otherwise NULL
+ */
+enum mapistore_error mapistore_backend_list_contexts(const char *username, struct tdb_wrap *tdbwrap, TALLOC_CTX *mem_ctx, struct mapistore_contexts_list **contexts_listP)
+{
+       enum mapistore_error            retval;
+       int                             i;
+       struct mapistore_contexts_list  *contexts_list = NULL, *current_contexts_list;
+
+       MAPISTORE_RETVAL_IF(!username, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
+       MAPISTORE_RETVAL_IF(!contexts_listP, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
+
+       for (i = 0; i < num_backends; i++) {
+               retval = backends[i].backend->backend.list_contexts(username, tdbwrap, mem_ctx, &current_contexts_list);
+               if (retval != MAPISTORE_SUCCESS) {
+                       return retval;
+               }
+               DLIST_CONCATENATE(contexts_list, current_contexts_list, void);
+       }
+
+       *contexts_listP = contexts_list;
+       (void) talloc_reference(mem_ctx, contexts_list);
+
+       return MAPISTORE_SUCCESS;
+}
+
 /**
    \details Create backend context
 
@@ -299,11 +331,11 @@ int mapistore_backend_init(TALLOC_CTX *mem_ctx, const char *path)
 
    \return a valid backend_context pointer on success, otherwise NULL
  */
-struct backend_context *mapistore_backend_create_context(TALLOC_CTX *mem_ctx, struct mapistore_connection_info *conn_info, struct tdb_wrap *tdbwrap,
-                                                        const char *namespace, const char *uri, uint64_t fid)
+enum mapistore_error mapistore_backend_create_context(TALLOC_CTX *mem_ctx, struct mapistore_connection_info *conn_info, struct tdb_wrap *tdbwrap,
+                                                     const char *namespace, const char *uri, uint64_t fid, struct backend_context **context_p)
 {
        struct backend_context          *context;
-       int                             retval;
+       enum mapistore_error            retval;
        bool                            found = false;
        void                            *backend_object = NULL;
        int                             i;
@@ -315,7 +347,7 @@ struct backend_context *mapistore_backend_create_context(TALLOC_CTX *mem_ctx, st
                        found = true;
                        retval = backends[i].backend->backend.create_context(NULL, conn_info, tdbwrap, uri, &backend_object);
                        if (retval != MAPISTORE_SUCCESS) {
-                               return NULL;
+                               return retval;
                        }
 
                        break;
@@ -323,7 +355,7 @@ struct backend_context *mapistore_backend_create_context(TALLOC_CTX *mem_ctx, st
        }
        if (found == false) {
                DEBUG(0, ("MAPISTORE: no backend with namespace '%s' is available\n", namespace));
-               return NULL;
+               return MAPISTORE_ERR_NOT_FOUND;
        }
 
        context = talloc_zero(mem_ctx, struct backend_context);
@@ -334,8 +366,22 @@ struct backend_context *mapistore_backend_create_context(TALLOC_CTX *mem_ctx, st
        talloc_unlink(NULL, backend_object);
        context->ref_count = 1;
        context->uri = talloc_asprintf(context, "%s%s", namespace, uri);
+       *context_p = context;
 
-       return context;
+       return MAPISTORE_SUCCESS;
+}
+
+
+enum mapistore_error mapistore_backend_create_root_folder(const char *username, enum mapistore_context_role ctx_role, uint64_t fid, const char *name, TALLOC_CTX *mem_ctx, char **mapistore_urip)
+{
+       enum mapistore_error            retval = MAPISTORE_ERR_NOT_FOUND;
+       int                             i;
+
+       for (i = 0; retval == MAPISTORE_ERR_NOT_FOUND && i < num_backends; i++) {
+               retval = backends[i].backend->backend.create_root_folder(username, ctx_role, fid, name, mem_ctx, mapistore_urip);
+       }
+
+       return retval;
 }
 
 /**
@@ -345,7 +391,7 @@ struct backend_context *mapistore_backend_create_context(TALLOC_CTX *mem_ctx, st
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR
  */
-_PUBLIC_ int mapistore_backend_add_ref_count(struct backend_context *bctx)
+_PUBLIC_ enum mapistore_error mapistore_backend_add_ref_count(struct backend_context *bctx)
 {
        if (!bctx) {
                return MAPISTORE_ERROR;
@@ -364,9 +410,9 @@ _PUBLIC_ int mapistore_backend_add_ref_count(struct backend_context *bctx)
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-_PUBLIC_ int mapistore_backend_delete_context(struct backend_context *bctx)
+_PUBLIC_ enum mapistore_error mapistore_backend_delete_context(struct backend_context *bctx)
 {
-       if (bctx->ref_count > 1) {
+       if (bctx->ref_count) {
                bctx->ref_count -= 1;
                return MAPISTORE_ERR_REF_COUNT;
        }
@@ -461,10 +507,10 @@ _PUBLIC_ struct backend_context *mapistore_backend_lookup_by_name(TALLOC_CTX *me
 }
 
 
-int mapistore_backend_get_path(struct backend_context *bctx, TALLOC_CTX *mem_ctx, uint64_t fmid, char **path)
+enum mapistore_error mapistore_backend_get_path(struct backend_context *bctx, TALLOC_CTX *mem_ctx, uint64_t fmid, char **path)
 {
-       int     ret;
-       char    *bpath = NULL;
+       enum mapistore_error    ret;
+       char                    *bpath = NULL;
 
        ret = bctx->backend->context.get_path(bctx->backend_object, mem_ctx, fmid, &bpath);
 
@@ -477,60 +523,56 @@ int mapistore_backend_get_path(struct backend_context *bctx, TALLOC_CTX *mem_ctx
        return ret;
 }
 
-int mapistore_backend_folder_open_folder(struct backend_context *bctx, void *folder, TALLOC_CTX *mem_ctx, uint64_t fid, void **child_folder)
+enum mapistore_error mapistore_backend_folder_open_folder(struct backend_context *bctx, void *folder, TALLOC_CTX *mem_ctx, uint64_t fid, void **child_folder)
 {
        return bctx->backend->folder.open_folder(folder, mem_ctx, fid, child_folder);
 }
 
-int mapistore_backend_folder_create_folder(struct backend_context *bctx, void *folder,
+enum mapistore_error mapistore_backend_folder_create_folder(struct backend_context *bctx, void *folder,
                                           TALLOC_CTX *mem_ctx, uint64_t fid, struct SRow *aRow, void **child_folder)
 {
        return bctx->backend->folder.create_folder(folder, mem_ctx, fid, aRow, child_folder);
 }
 
-int mapistore_backend_folder_delete_folder(struct backend_context *bctx, void *folder, uint64_t fid)
+enum mapistore_error mapistore_backend_folder_delete(struct backend_context *bctx, void *folder)
 {
-       return bctx->backend->folder.delete_folder(folder, fid);
+       return bctx->backend->folder.delete(folder);
 }
 
-int mapistore_backend_folder_open_message(struct backend_context *bctx, void *folder,
-                                         TALLOC_CTX *mem_ctx, uint64_t mid, void **messagep)
+enum mapistore_error mapistore_backend_folder_open_message(struct backend_context *bctx, void *folder,
+                                         TALLOC_CTX *mem_ctx, uint64_t mid, bool read_write, void **messagep)
 {
-       return bctx->backend->folder.open_message(folder, mem_ctx, mid, messagep);
+       return bctx->backend->folder.open_message(folder, mem_ctx, mid, read_write, messagep);
 }
 
-int mapistore_backend_folder_create_message(struct backend_context *bctx, void *folder, TALLOC_CTX *mem_ctx, uint64_t mid, uint8_t associated, void **messagep)
+enum mapistore_error mapistore_backend_folder_create_message(struct backend_context *bctx, void *folder, TALLOC_CTX *mem_ctx, uint64_t mid, uint8_t associated, void **messagep)
 {
        return bctx->backend->folder.create_message(folder, mem_ctx, mid, associated, messagep);
 }
 
-int mapistore_backend_folder_delete_message(struct backend_context *bctx, void *folder, uint64_t mid, uint8_t flags)
+enum mapistore_error mapistore_backend_folder_delete_message(struct backend_context *bctx, void *folder, uint64_t mid, uint8_t flags)
 {
         return bctx->backend->folder.delete_message(folder, mid, flags);
 }
 
-int mapistore_backend_folder_move_copy_messages(struct backend_context *bctx, void *target_folder, void *source_folder, uint32_t mid_count, uint64_t *source_mids, uint64_t *target_mids, struct Binary_r **target_change_keys, uint8_t want_copy)
+enum mapistore_error mapistore_backend_folder_move_copy_messages(struct backend_context *bctx, void *target_folder, void *source_folder, uint32_t mid_count, uint64_t *source_mids, uint64_t *target_mids, struct Binary_r **target_change_keys, uint8_t want_copy)
 {
         return bctx->backend->folder.move_copy_messages(target_folder, source_folder, mid_count, source_mids, target_mids, target_change_keys, want_copy);
 }
 
-int mapistore_backend_folder_get_deleted_fmids(struct backend_context *bctx, void *folder, TALLOC_CTX *mem_ctx, uint8_t table_type, uint64_t change_num, struct I8Array_r **fmidsp, uint64_t *cnp)
+enum mapistore_error mapistore_backend_folder_get_deleted_fmids(struct backend_context *bctx, void *folder, TALLOC_CTX *mem_ctx, enum mapistore_table_type table_type, uint64_t change_num, struct I8Array_r **fmidsp, uint64_t *cnp)
 {
         return bctx->backend->folder.get_deleted_fmids(folder, mem_ctx, table_type, change_num, fmidsp, cnp);
 }
 
-int mapistore_backend_folder_get_child_count(struct backend_context *bctx, void *folder, uint8_t table_type, uint32_t *RowCount)
+enum mapistore_error mapistore_backend_folder_get_child_count(struct backend_context *bctx, void *folder, enum mapistore_table_type table_type, uint32_t *RowCount)
 {
-       int             ret;
-
-       ret = bctx->backend->folder.get_child_count(folder, table_type, RowCount);
-
-       return ret;
+       return bctx->backend->folder.get_child_count(folder, table_type, RowCount);
 }
 
-int mapistore_backend_folder_get_child_fid_by_name(struct backend_context *bctx, void *folder, const char *name, uint64_t *fidp)
+enum mapistore_error mapistore_backend_folder_get_child_fid_by_name(struct backend_context *bctx, void *folder, const char *name, uint64_t *fidp)
 {
-       int                             ret = MAPISTORE_SUCCESS;
+       enum mapistore_error            ret = MAPISTORE_SUCCESS;
        struct mapi_SRestriction        name_restriction;
        void                            *table;
        uint8_t                         status;
@@ -570,106 +612,106 @@ int mapistore_backend_folder_get_child_fid_by_name(struct backend_context *bctx,
        return ret;
 }
 
-int mapistore_backend_folder_open_table(struct backend_context *bctx, void *folder,
-                                       TALLOC_CTX *mem_ctx, uint8_t table_type, uint32_t handle_id, void **table, uint32_t *row_count)
+enum mapistore_error mapistore_backend_folder_open_table(struct backend_context *bctx, void *folder,
+                                                        TALLOC_CTX *mem_ctx, enum mapistore_table_type table_type, uint32_t handle_id, void **table, uint32_t *row_count)
 {
         return bctx->backend->folder.open_table(folder, mem_ctx, table_type, handle_id, table, row_count);
 }
 
-int mapistore_backend_folder_modify_permissions(struct backend_context *bctx, void *folder,
+enum mapistore_error mapistore_backend_folder_modify_permissions(struct backend_context *bctx, void *folder,
                                                uint8_t flags, uint16_t pcount, struct PermissionData *permissions)
 {
         return bctx->backend->folder.modify_permissions(folder, flags, pcount, permissions);
 }
 
-int mapistore_backend_message_get_message_data(struct backend_context *bctx, void *message, TALLOC_CTX *mem_ctx, struct mapistore_message **msg)
+enum mapistore_error mapistore_backend_message_get_message_data(struct backend_context *bctx, void *message, TALLOC_CTX *mem_ctx, struct mapistore_message **msg)
 {
        return bctx->backend->message.get_message_data(message, mem_ctx, msg);
 }
 
-int mapistore_backend_message_modify_recipients(struct backend_context *bctx, void *message, struct SPropTagArray *columns, uint16_t count, struct mapistore_message_recipient *recipients)
+enum mapistore_error mapistore_backend_message_modify_recipients(struct backend_context *bctx, void *message, struct SPropTagArray *columns, uint16_t count, struct mapistore_message_recipient *recipients)
 {
        return bctx->backend->message.modify_recipients(message, columns, count, recipients);
 }
 
-int mapistore_backend_message_set_read_flag(struct backend_context *bctx, void *message, uint8_t flag)
+enum mapistore_error mapistore_backend_message_set_read_flag(struct backend_context *bctx, void *message, uint8_t flag)
 {
        return bctx->backend->message.set_read_flag(message, flag);
 }
 
-int mapistore_backend_message_save(struct backend_context *bctx, void *message)
+enum mapistore_error mapistore_backend_message_save(struct backend_context *bctx, void *message)
 {
        return bctx->backend->message.save(message);
 }
 
-int mapistore_backend_message_submit(struct backend_context *bctx, void *message, enum SubmitFlags flags)
+enum mapistore_error mapistore_backend_message_submit(struct backend_context *bctx, void *message, enum SubmitFlags flags)
 {
        return bctx->backend->message.submit(message, flags);
 }
 
-int mapistore_backend_message_open_attachment(struct backend_context *bctx, void *message, TALLOC_CTX *mem_ctx, uint32_t aid, void **attachment)
+enum mapistore_error mapistore_backend_message_open_attachment(struct backend_context *bctx, void *message, TALLOC_CTX *mem_ctx, uint32_t aid, void **attachment)
 {
         return bctx->backend->message.open_attachment(message, mem_ctx, aid, attachment);
 }
 
-int mapistore_backend_message_create_attachment(struct backend_context *bctx, void *message, TALLOC_CTX *mem_ctx, void **attachment, uint32_t *aid)
+enum mapistore_error mapistore_backend_message_create_attachment(struct backend_context *bctx, void *message, TALLOC_CTX *mem_ctx, void **attachment, uint32_t *aid)
 {
         return bctx->backend->message.create_attachment(message, mem_ctx, attachment, aid);
 }
 
-int mapistore_backend_message_get_attachment_table(struct backend_context *bctx, void *message, TALLOC_CTX *mem_ctx, void **table, uint32_t *row_count)
+enum mapistore_error mapistore_backend_message_get_attachment_table(struct backend_context *bctx, void *message, TALLOC_CTX *mem_ctx, void **table, uint32_t *row_count)
 {
         return bctx->backend->message.get_attachment_table(message, mem_ctx, table, row_count);
 }
 
-int mapistore_backend_message_attachment_open_embedded_message(struct backend_context *bctx, void *message, TALLOC_CTX *mem_ctx, void **embedded_message, uint64_t *mid, struct mapistore_message **msg)
+enum mapistore_error mapistore_backend_message_attachment_open_embedded_message(struct backend_context *bctx, void *message, TALLOC_CTX *mem_ctx, void **embedded_message, uint64_t *mid, struct mapistore_message **msg)
 {
         return bctx->backend->message.open_embedded_message(message, mem_ctx, embedded_message, mid, msg);
 }
 
-int mapistore_backend_table_get_available_properties(struct backend_context *bctx, void *table, TALLOC_CTX *mem_ctx, struct SPropTagArray **propertiesp)
+enum mapistore_error mapistore_backend_table_get_available_properties(struct backend_context *bctx, void *table, TALLOC_CTX *mem_ctx, struct SPropTagArray **propertiesp)
 {
         return bctx->backend->table.get_available_properties(table, mem_ctx, propertiesp);
 }
 
-int mapistore_backend_table_set_columns(struct backend_context *bctx, void *table, uint16_t count, enum MAPITAGS *properties)
+enum mapistore_error mapistore_backend_table_set_columns(struct backend_context *bctx, void *table, uint16_t count, enum MAPITAGS *properties)
 {
         return bctx->backend->table.set_columns(table, count, properties);
 }
 
-int mapistore_backend_table_set_restrictions(struct backend_context *bctx, void *table, struct mapi_SRestriction *restrictions, uint8_t *table_status)
+enum mapistore_error mapistore_backend_table_set_restrictions(struct backend_context *bctx, void *table, struct mapi_SRestriction *restrictions, uint8_t *table_status)
 {
         return bctx->backend->table.set_restrictions(table, restrictions, table_status);
 }
 
-int mapistore_backend_table_set_sort_order(struct backend_context *bctx, void *table, struct SSortOrderSet *sort_order, uint8_t *table_status)
+enum mapistore_error mapistore_backend_table_set_sort_order(struct backend_context *bctx, void *table, struct SSortOrderSet *sort_order, uint8_t *table_status)
 {
         return bctx->backend->table.set_sort_order(table, sort_order, table_status);
 }
 
-int mapistore_backend_table_get_row(struct backend_context *bctx, void *table, TALLOC_CTX *mem_ctx,
-                                   enum table_query_type query_type, uint32_t rowid,
-                                   struct mapistore_property_data **data)
+enum mapistore_error mapistore_backend_table_get_row(struct backend_context *bctx, void *table, TALLOC_CTX *mem_ctx,
+                                                    enum mapistore_query_type query_type, uint32_t rowid,
+                                                    struct mapistore_property_data **data)
 {
         return bctx->backend->table.get_row(table, mem_ctx, query_type, rowid, data);
 }
 
-int mapistore_backend_table_get_row_count(struct backend_context *bctx, void *table, enum table_query_type query_type, uint32_t *row_countp)
+enum mapistore_error mapistore_backend_table_get_row_count(struct backend_context *bctx, void *table, enum mapistore_query_type query_type, uint32_t *row_countp)
 {
         return bctx->backend->table.get_row_count(table, query_type, row_countp);
 }
 
-int mapistore_backend_table_handle_destructor(struct backend_context *bctx, void *table, uint32_t handle_id)
+enum mapistore_error mapistore_backend_table_handle_destructor(struct backend_context *bctx, void *table, uint32_t handle_id)
 {
         return bctx->backend->table.handle_destructor(table, handle_id);
 }
 
-int mapistore_backend_properties_get_available_properties(struct backend_context *bctx, void *object, TALLOC_CTX *mem_ctx, struct SPropTagArray **propertiesp)
+enum mapistore_error mapistore_backend_properties_get_available_properties(struct backend_context *bctx, void *object, TALLOC_CTX *mem_ctx, struct SPropTagArray **propertiesp)
 {
         return bctx->backend->properties.get_available_properties(object, mem_ctx, propertiesp);
 }
 
-int mapistore_backend_properties_get_properties(struct backend_context *bctx,
+enum mapistore_error mapistore_backend_properties_get_properties(struct backend_context *bctx,
                                                void *object, TALLOC_CTX *mem_ctx,
                                                uint16_t count, enum MAPITAGS
                                                *properties,
@@ -678,12 +720,12 @@ int mapistore_backend_properties_get_properties(struct backend_context *bctx,
         return bctx->backend->properties.get_properties(object, mem_ctx, count, properties, data);
 }
 
-int mapistore_backend_properties_set_properties(struct backend_context *bctx, void *object, struct SRow *aRow)
+enum mapistore_error mapistore_backend_properties_set_properties(struct backend_context *bctx, void *object, struct SRow *aRow)
 {
         return bctx->backend->properties.set_properties(object, aRow);
 }
 
-int mapistore_backend_manager_generate_uri(struct backend_context *bctx, TALLOC_CTX *mem_ctx, 
+enum mapistore_error mapistore_backend_manager_generate_uri(struct backend_context *bctx, TALLOC_CTX *mem_ctx, 
                                           const char *username, const char *folder, 
                                           const char *message, const char *root_uri, char **uri)
 {
index 3dee11133196e788d6b2f970d00aedf3d528035e..ff0be0761ee065026dfac1e30c520e2d5908d3ad 100644 (file)
@@ -65,8 +65,8 @@ struct indexing_context_list *mapistore_indexing_search(struct mapistore_context
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-_PUBLIC_ int mapistore_indexing_add(struct mapistore_context *mstore_ctx, 
-                                   const char *username, struct indexing_context_list **ictxp)
+_PUBLIC_ enum mapistore_error mapistore_indexing_add(struct mapistore_context *mstore_ctx, 
+                                                    const char *username, struct indexing_context_list **ictxp)
 {
        TALLOC_CTX                      *mem_ctx;
        struct indexing_context_list    *ictx;
@@ -82,7 +82,7 @@ _PUBLIC_ int mapistore_indexing_add(struct mapistore_context *mstore_ctx,
        MAPISTORE_RETVAL_IF(ictx, MAPISTORE_SUCCESS, NULL);
 
        mem_ctx = talloc_named(NULL, 0, "mapistore_indexing_init");
-       ictx = talloc_zero(mstore_ctx->indexing_list, struct indexing_context_list);
+       ictx = talloc_zero(mstore_ctx, struct indexing_context_list);
 
        /* Step 1. Open/Create the indexing database */
        dbpath = talloc_asprintf(mem_ctx, "%s/%s/indexing.tdb", 
@@ -96,7 +96,7 @@ _PUBLIC_ int mapistore_indexing_add(struct mapistore_context *mstore_ctx,
                return MAPISTORE_ERR_DATABASE_INIT;
        }
        ictx->username = talloc_strdup(ictx, username);
-       ictx->ref_count = 0;
+       /* ictx->ref_count = 0; */
        DLIST_ADD_END(mstore_ctx->indexing_list, ictx, struct indexing_context_list *);
 
        *ictxp = ictx;
@@ -106,39 +106,39 @@ _PUBLIC_ int mapistore_indexing_add(struct mapistore_context *mstore_ctx,
        return MAPISTORE_SUCCESS;
 }
 
-/**
-   \details Increase the ref count associated to a given indexing context
+/* /\** */
+/*    \details Increase the ref count associated to a given indexing context */
 
-   \param ictx pointer to the indexing context
+/*    \param ictx pointer to the indexing context */
 
-   \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR
- */
-int mapistore_indexing_add_ref_count(struct indexing_context_list *ictx)
-{
-       MAPISTORE_RETVAL_IF(!ictx, MAPISTORE_ERROR, NULL);
+/*    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR */
+/*  *\/ */
+/* enum mapistore_error mapistore_indexing_add_ref_count(struct indexing_context_list *ictx) */
+/* { */
+/*     MAPISTORE_RETVAL_IF(!ictx, MAPISTORE_ERROR, NULL); */
 
-       ictx->ref_count += 1;
+/*     ictx->ref_count += 1; */
 
-       return MAPISTORE_SUCCESS;
-}
+/*     return MAPISTORE_SUCCESS; */
+/* } */
 
 
-/**
-   \details Decrease the ref count associated to a given indexing context
+/* /\** */
+/*    \details Decrease the ref count associated to a given indexing context */
 
-   \param ictx pointer to the indexing context
+/*    \param ictx pointer to the indexing context */
 
-   \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR
- */
-int mapistore_indexing_del_ref_count(struct indexing_context_list *ictx)
-{
-       MAPISTORE_RETVAL_IF(!ictx, MAPISTORE_ERROR, NULL);
-       MAPISTORE_RETVAL_IF(!ictx->ref_count, MAPISTORE_SUCCESS, NULL);
+/*    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR */
+/*  *\/ */
+/* enum mapistore_error mapistore_indexing_del_ref_count(struct indexing_context_list *ictx) */
+/* { */
+/*     MAPISTORE_RETVAL_IF(!ictx, MAPISTORE_ERROR, NULL); */
+/*     MAPISTORE_RETVAL_IF(!ictx->ref_count, MAPISTORE_SUCCESS, NULL); */
 
-       ictx->ref_count -= 1;
+/*     ictx->ref_count -= 1; */
 
-       return MAPISTORE_SUCCESS;
-}
+/*     return MAPISTORE_SUCCESS; */
+/* } */
 
 
 /**
@@ -154,8 +154,8 @@ int mapistore_indexing_del_ref_count(struct indexing_context_list *ictx)
    \return MAPISTORE_SUCCESS if the folder/message ID doesn't exist,
    otherwise MAPISTORE_ERR_EXIST.
  */
-int mapistore_indexing_search_existing_fmid(struct indexing_context_list *ictx, 
-                                           uint64_t fmid, bool *IsSoftDeleted)
+enum mapistore_error mapistore_indexing_search_existing_fmid(struct indexing_context_list *ictx, 
+                                                            uint64_t fmid, bool *IsSoftDeleted)
 {
        int             ret;
        TDB_DATA        key;
@@ -188,10 +188,10 @@ int mapistore_indexing_search_existing_fmid(struct indexing_context_list *ictx,
        return MAPISTORE_SUCCESS;
 }
 
-int mapistore_indexing_record_add(TALLOC_CTX *mem_ctx,
-                                 struct indexing_context_list *ictx,
-                                 uint64_t fmid,
-                                 const char *mapistore_URI)
+enum mapistore_error mapistore_indexing_record_add(TALLOC_CTX *mem_ctx,
+                                                  struct indexing_context_list *ictx,
+                                                  uint64_t fmid,
+                                                  const char *mapistore_URI)
 {
        int             ret;
        TDB_DATA        key;
@@ -228,8 +228,8 @@ int mapistore_indexing_record_add(TALLOC_CTX *mem_ctx,
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-int mapistore_indexing_record_add_fmid(struct mapistore_context *mstore_ctx,
-                                      uint32_t context_id, const char *username, uint64_t fmid)
+enum mapistore_error mapistore_indexing_record_add_fmid(struct mapistore_context *mstore_ctx,
+                                                       uint32_t context_id, const char *username, uint64_t fmid)
 {
        int                             ret;
        struct backend_context          *backend_ctx;
@@ -278,9 +278,9 @@ int mapistore_indexing_record_add_fmid(struct mapistore_context *mstore_ctx,
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-int mapistore_indexing_record_del_fmid(struct mapistore_context *mstore_ctx,
-                                      uint32_t context_id, const char *username, uint64_t fmid,
-                                      uint8_t flags)
+enum mapistore_error mapistore_indexing_record_del_fmid(struct mapistore_context *mstore_ctx,
+                                                       uint32_t context_id, const char *username, uint64_t fmid,
+                                                       uint8_t flags)
 {
        int                             ret;
        struct backend_context          *backend_ctx;
@@ -354,7 +354,7 @@ int mapistore_indexing_record_del_fmid(struct mapistore_context *mstore_ctx,
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-_PUBLIC_ int mapistore_indexing_record_get_uri(struct mapistore_context *mstore_ctx, const char *username, TALLOC_CTX *mem_ctx, uint64_t fmid, char **urip, bool *soft_deletedp)
+_PUBLIC_ enum mapistore_error mapistore_indexing_record_get_uri(struct mapistore_context *mstore_ctx, const char *username, TALLOC_CTX *mem_ctx, uint64_t fmid, char **urip, bool *soft_deletedp)
 {
        struct indexing_context_list    *ictx;
        TDB_DATA                        key, dbuf;
@@ -482,7 +482,7 @@ static int tdb_get_fid_traverse_partial(struct tdb_context *tdb_ctx, TDB_DATA ke
        return ret;
 }
 
-_PUBLIC_ int mapistore_indexing_record_get_fmid(struct mapistore_context *mstore_ctx, const char *username, const char *uri, bool partial, uint64_t *fmidp, bool *soft_deletedp)
+_PUBLIC_ enum mapistore_error mapistore_indexing_record_get_fmid(struct mapistore_context *mstore_ctx, const char *username, const char *uri, bool partial, uint64_t *fmidp, bool *soft_deletedp)
 {
        struct indexing_context_list    *ictx;
        int                             ret;
@@ -569,8 +569,8 @@ _PUBLIC_ int mapistore_indexing_record_get_fmid(struct mapistore_context *mstore
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-_PUBLIC_ int mapistore_indexing_record_add_fid(struct mapistore_context *mstore_ctx,
-                                              uint32_t context_id, const char *username, uint64_t fid)
+_PUBLIC_ enum mapistore_error mapistore_indexing_record_add_fid(struct mapistore_context *mstore_ctx,
+                                                               uint32_t context_id, const char *username, uint64_t fid)
 {
        return mapistore_indexing_record_add_fmid(mstore_ctx, context_id, username, fid);
 }
@@ -588,9 +588,9 @@ _PUBLIC_ int mapistore_indexing_record_add_fid(struct mapistore_context *mstore_
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-_PUBLIC_ int mapistore_indexing_record_del_fid(struct mapistore_context *mstore_ctx,
-                                              uint32_t context_id, const char *username, uint64_t fid, 
-                                              uint8_t flags)
+_PUBLIC_ enum mapistore_error mapistore_indexing_record_del_fid(struct mapistore_context *mstore_ctx,
+                                                               uint32_t context_id, const char *username, uint64_t fid, 
+                                                               uint8_t flags)
 {
        return mapistore_indexing_record_del_fmid(mstore_ctx, context_id, username, fid, flags);
 }
@@ -609,8 +609,8 @@ _PUBLIC_ int mapistore_indexing_record_del_fid(struct mapistore_context *mstore_
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-_PUBLIC_ int mapistore_indexing_record_add_mid(struct mapistore_context *mstore_ctx,
-                                              uint32_t context_id, const char *username, uint64_t mid)
+_PUBLIC_ enum mapistore_error mapistore_indexing_record_add_mid(struct mapistore_context *mstore_ctx,
+                                                               uint32_t context_id, const char *username, uint64_t mid)
 {
        return mapistore_indexing_record_add_fmid(mstore_ctx, context_id, username, mid);
 }
@@ -628,9 +628,9 @@ _PUBLIC_ int mapistore_indexing_record_add_mid(struct mapistore_context *mstore_
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-_PUBLIC_ int mapistore_indexing_record_del_mid(struct mapistore_context *mstore_ctx,
-                                              uint32_t context_id, const char *username, uint64_t mid,
-                                              uint8_t flags)
+_PUBLIC_ enum mapistore_error mapistore_indexing_record_del_mid(struct mapistore_context *mstore_ctx,
+                                                               uint32_t context_id, const char *username, uint64_t mid,
+                                                               uint8_t flags)
 {
        return mapistore_indexing_record_del_fmid(mstore_ctx, context_id, username, mid, flags);
 }
index b390da39f5fcf2134f75d41062c6d0d003a5c4af..a132d31130a68762568657801478a3b17a641cac 100644 (file)
@@ -19,6 +19,9 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <sys/stat.h>
+#include <sys/types.h>
+
 #include "mapistore.h"
 #include "mapistore_errors.h"
 #include "mapistore_private.h"
 
    \return allocate mapistore context on success, otherwise NULL
  */
-_PUBLIC_ struct mapistore_context *mapistore_init(TALLOC_CTX *mem_ctx, const char *path)
+_PUBLIC_ struct mapistore_context *mapistore_init(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, const char *path)
 {
        int                             retval;
        struct mapistore_context        *mstore_ctx;
+       const char                      *private_dir;
+       char                            *mapping_path;
+
+       if (!lp_ctx) {
+               return NULL;
+       }
 
        mstore_ctx = talloc_zero(mem_ctx, struct mapistore_context);
        if (!mstore_ctx) {
@@ -46,6 +55,18 @@ _PUBLIC_ struct mapistore_context *mapistore_init(TALLOC_CTX *mem_ctx, const cha
 
        mstore_ctx->processing_ctx = talloc_zero(mstore_ctx, struct processing_context);
 
+       private_dir = lpcfg_private_dir(lp_ctx);
+       if (!private_dir) {
+               DEBUG(5, ("private directory was not returned from configuration\n"));
+               return NULL;
+       }
+
+       mapping_path = talloc_asprintf(NULL, "%s/mapistore", private_dir);
+       mkdir(mapping_path, 0700);
+
+       mapistore_set_mapping_path(mapping_path);
+       talloc_free(mapping_path);
+
        retval = mapistore_init_mapping_context(mstore_ctx->processing_ctx);
        if (retval != MAPISTORE_SUCCESS) {
                DEBUG(0, ("[%s:%d]: %s\n", __FUNCTION__, __LINE__, mapistore_errstr(retval)));
@@ -92,7 +113,7 @@ _PUBLIC_ struct mapistore_context *mapistore_init(TALLOC_CTX *mem_ctx, const cha
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-_PUBLIC_ int mapistore_release(struct mapistore_context *mstore_ctx)
+_PUBLIC_ enum mapistore_error mapistore_release(struct mapistore_context *mstore_ctx)
 {
        if (!mstore_ctx) return MAPISTORE_ERR_NOT_INITIALIZED;
 
@@ -114,11 +135,9 @@ _PUBLIC_ int mapistore_release(struct mapistore_context *mstore_ctx)
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-_PUBLIC_ int mapistore_set_connection_info(struct mapistore_context *mstore_ctx, 
-                                          struct ldb_context *sam_ctx, struct ldb_context *oc_ctx, const char *username)
+_PUBLIC_ enum mapistore_error mapistore_set_connection_info(struct mapistore_context *mstore_ctx, 
+                                                           struct ldb_context *sam_ctx, struct ldb_context *oc_ctx, const char *username)
 {
-       int     ret;
-
        /* Sanity checks */
        MAPISTORE_RETVAL_IF(!mstore_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
        MAPISTORE_RETVAL_IF(!sam_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
@@ -129,7 +148,7 @@ _PUBLIC_ int mapistore_set_connection_info(struct mapistore_context *mstore_ctx,
        mstore_ctx->conn_info->mstore_ctx = mstore_ctx;
        mstore_ctx->conn_info->sam_ctx = sam_ctx;
        mstore_ctx->conn_info->oc_ctx = oc_ctx;
-       talloc_reference(mstore_ctx->conn_info, mstore_ctx->conn_info->oc_ctx);
+       (void) talloc_reference(mstore_ctx->conn_info, mstore_ctx->conn_info->oc_ctx);
        mstore_ctx->conn_info->username = talloc_strdup(mstore_ctx->conn_info, username);
 
        return MAPISTORE_SUCCESS;
@@ -145,8 +164,8 @@ _PUBLIC_ int mapistore_set_connection_info(struct mapistore_context *mstore_ctx,
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
 #warning the "owner" parameter should be deduced from the uri
-_PUBLIC_ int mapistore_add_context(struct mapistore_context *mstore_ctx, const char *owner,
-                                  const char *uri, uint64_t fid, uint32_t *context_id, void **backend_object)
+_PUBLIC_ enum mapistore_error mapistore_add_context(struct mapistore_context *mstore_ctx, const char *owner,
+                                                   const char *uri, uint64_t fid, uint32_t *context_id, void **backend_object)
 {
        TALLOC_CTX                              *mem_ctx;
        int                                     retval;
@@ -155,6 +174,7 @@ _PUBLIC_ int mapistore_add_context(struct mapistore_context *mstore_ctx, const c
        char                                    *namespace;
        char                                    *namespace_start;
        char                                    *backend_uri;
+       char                                    *mapistore_dir;
        struct indexing_context_list            *ictx;
 
        /* Step 1. Perform Sanity Checks on URI */
@@ -175,14 +195,18 @@ _PUBLIC_ int mapistore_add_context(struct mapistore_context *mstore_ctx, const c
        if (namespace[1] && namespace[1] == '/' &&
            namespace[2] && namespace[2] == '/' &&
            namespace[3]) {
+               /* ensure the user mapistore directory exists before any mapistore operation occurs */
+               mapistore_dir = talloc_asprintf(mem_ctx, "%s/%s", mapistore_get_mapping_path(), owner);
+               mkdir(mapistore_dir, 0700);
+
                mapistore_indexing_add(mstore_ctx, owner, &ictx);
-               mapistore_indexing_add_ref_count(ictx);
+               /* mapistore_indexing_add_ref_count(ictx); */
 
                backend_uri = talloc_strdup(mem_ctx, &namespace[3]);
                namespace[3] = '\0';
-               backend_ctx = mapistore_backend_create_context(mstore_ctx, mstore_ctx->conn_info, ictx->index_ctx, namespace_start, backend_uri, fid);
-               if (!backend_ctx) {
-                       return MAPISTORE_ERR_CONTEXT_FAILED;
+               retval = mapistore_backend_create_context(mstore_ctx, mstore_ctx->conn_info, ictx->index_ctx, namespace_start, backend_uri, fid, &backend_ctx);
+               if (retval != MAPISTORE_SUCCESS) {
+                       return retval;
                }
 
                backend_ctx->indexing = ictx;
@@ -217,8 +241,8 @@ _PUBLIC_ int mapistore_add_context(struct mapistore_context *mstore_ctx, const c
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-_PUBLIC_ int mapistore_add_context_ref_count(struct mapistore_context *mstore_ctx,
-                                            uint32_t context_id)
+_PUBLIC_ enum mapistore_error mapistore_add_context_ref_count(struct mapistore_context *mstore_ctx,
+                                                             uint32_t context_id)
 {
        struct backend_context          *backend_ctx;
        int                             retval;
@@ -238,9 +262,10 @@ _PUBLIC_ int mapistore_add_context_ref_count(struct mapistore_context *mstore_ct
 
        /* Step 2. Increment backend indexing ref count */
        if (backend_ctx->indexing) {
-               mapistore_indexing_add_ref_count(backend_ctx->indexing);
+               /* mapistore_indexing_add_ref_count(backend_ctx->indexing); */
        } else {
                DEBUG(0, ("[%s:%d]: This should never occur\n", __FUNCTION__, __LINE__));
+               abort();
        }
 
        return retval;
@@ -256,8 +281,8 @@ _PUBLIC_ int mapistore_add_context_ref_count(struct mapistore_context *mstore_ct
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-_PUBLIC_ int mapistore_search_context_by_uri(struct mapistore_context *mstore_ctx,
-                                            const char *uri, uint32_t *context_id, void **backend_object)
+_PUBLIC_ enum mapistore_error mapistore_search_context_by_uri(struct mapistore_context *mstore_ctx,
+                                                             const char *uri, uint32_t *context_id, void **backend_object)
 {
        struct backend_context          *backend_ctx;
 
@@ -285,8 +310,8 @@ _PUBLIC_ int mapistore_search_context_by_uri(struct mapistore_context *mstore_ct
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-_PUBLIC_ int mapistore_del_context(struct mapistore_context *mstore_ctx, 
-                                  uint32_t context_id)
+_PUBLIC_ enum mapistore_error mapistore_del_context(struct mapistore_context *mstore_ctx, 
+                                                   uint32_t context_id)
 {
        struct backend_context_list     *backend_list;
        struct backend_context          *backend_ctx;
@@ -315,7 +340,7 @@ _PUBLIC_ int mapistore_del_context(struct mapistore_context *mstore_ctx,
        }
 
        /* Step 1. Release the indexing context within backend */
-       if (backend_ctx->indexing) {
+       /* if (backend_ctx->indexing) {
                mapistore_indexing_del_ref_count(backend_ctx->indexing);
                if (backend_ctx->indexing->ref_count == 0) {
                        DEBUG(5, ("freeing up mapistore_indexing ctx: %p\n", backend_ctx->indexing));
@@ -323,7 +348,7 @@ _PUBLIC_ int mapistore_del_context(struct mapistore_context *mstore_ctx,
                        talloc_unlink(mstore_ctx->indexing_list, backend_ctx->indexing);
                        backend_ctx->indexing = NULL;
                }
-       }
+       } */
 
        /* Step 2. Delete the context within backend */
        retval = mapistore_backend_delete_context(backend_ctx);
@@ -358,7 +383,7 @@ void mapistore_set_errno(int status)
 
    \return constant string
  */
-_PUBLIC_ const char *mapistore_errstr(int mapistore_err)
+_PUBLIC_ const char *mapistore_errstr(enum mapistore_error mapistore_err)
 {
        switch (mapistore_err) {
        case MAPISTORE_SUCCESS:
@@ -401,11 +426,37 @@ _PUBLIC_ const char *mapistore_errstr(int mapistore_err)
                return "Error while sending message";
        case MAPISTORE_ERR_MSG_RCV:
                return "Error receiving message";
+       case MAPISTORE_ERR_DENIED:
+               return "Insufficient rights to perform the operation";
        }
 
        return "Unknown error";
 }
 
+_PUBLIC_ enum mapistore_error mapistore_list_contexts_for_user(struct mapistore_context *mstore_ctx, const char *owner, TALLOC_CTX *mem_ctx, struct mapistore_contexts_list **contexts_listp)
+{
+       char                                    *mapistore_dir;
+       struct indexing_context_list            *ictx;
+
+       /* ensure the user mapistore directory exists before any mapistore operation occurs */
+       mapistore_dir = talloc_asprintf(mem_ctx, "%s/%s", mapistore_get_mapping_path(), owner);
+       mkdir(mapistore_dir, 0700);
+
+       mapistore_indexing_add(mstore_ctx, owner, &ictx);
+       /* mapistore_indexing_add_ref_count(ictx); */
+       return mapistore_backend_list_contexts(owner, ictx->index_ctx, mem_ctx, contexts_listp);
+}
+
+_PUBLIC_ enum mapistore_error mapistore_create_root_folder(const char *username, enum mapistore_context_role ctx_role, uint64_t fid, const char *name, TALLOC_CTX *mem_ctx, char **mapistore_urip)
+{
+       /* Sanity checks */
+       MAPISTORE_RETVAL_IF(!username, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
+       MAPISTORE_RETVAL_IF(!mapistore_urip, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
+
+       return mapistore_backend_create_root_folder(username, ctx_role, fid, name, mem_ctx, mapistore_urip);
+}
+
 /**
    \details Open a directory in mapistore
 
@@ -417,11 +468,10 @@ _PUBLIC_ const char *mapistore_errstr(int mapistore_err)
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors
  */
-_PUBLIC_ int mapistore_folder_open_folder(struct mapistore_context *mstore_ctx, uint32_t context_id,
-                                         void *folder, TALLOC_CTX *mem_ctx, uint64_t fid, void **child_folder)
+_PUBLIC_ enum mapistore_error mapistore_folder_open_folder(struct mapistore_context *mstore_ctx, uint32_t context_id,
+                                                          void *folder, TALLOC_CTX *mem_ctx, uint64_t fid, void **child_folder)
 {
        struct backend_context          *backend_ctx;
-       int                             ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -431,9 +481,7 @@ _PUBLIC_ int mapistore_folder_open_folder(struct mapistore_context *mstore_ctx,
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
        /* Step 2. Call backend open_folder */
-       ret = mapistore_backend_folder_open_folder(backend_ctx, folder, mem_ctx, fid, child_folder);
-
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return mapistore_backend_folder_open_folder(backend_ctx, folder, mem_ctx, fid, child_folder);
 }
 
 /**
@@ -449,11 +497,10 @@ _PUBLIC_ int mapistore_folder_open_folder(struct mapistore_context *mstore_ctx,
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors
  */
-_PUBLIC_ int mapistore_folder_create_folder(struct mapistore_context *mstore_ctx, uint32_t context_id,
-                                           void *folder, TALLOC_CTX *mem_ctx, uint64_t fid, struct SRow *aRow, void **child_folder)
+_PUBLIC_ enum mapistore_error mapistore_folder_create_folder(struct mapistore_context *mstore_ctx, uint32_t context_id,
+                                                            void *folder, TALLOC_CTX *mem_ctx, uint64_t fid, struct SRow *aRow, void **child_folder)
 {
        struct backend_context          *backend_ctx;
-       int                             ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -463,9 +510,7 @@ _PUBLIC_ int mapistore_folder_create_folder(struct mapistore_context *mstore_ctx
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);       
        
        /* Step 2. Call backend create_folder */
-       ret = mapistore_backend_folder_create_folder(backend_ctx, folder, mem_ctx, fid, aRow, child_folder);
-
-       return ret;
+       return mapistore_backend_folder_create_folder(backend_ctx, folder, mem_ctx, fid, aRow, child_folder);
 }
 
 
@@ -480,13 +525,16 @@ _PUBLIC_ int mapistore_folder_create_folder(struct mapistore_context *mstore_ctx
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors
  */
-_PUBLIC_ int mapistore_folder_delete_folder(struct mapistore_context *mstore_ctx, uint32_t context_id,
-                                           void *folder, uint64_t fid, uint8_t flags)
+_PUBLIC_ enum mapistore_error mapistore_folder_delete(struct mapistore_context *mstore_ctx, uint32_t context_id, void *folder, uint8_t flags)
 {
-       struct backend_context          *backend_ctx;
-       int                             ret;
-       TALLOC_CTX                      *mem_ctx, *sub_mem_ctx;
-       void                            *subfolder;
+       struct backend_context  *backend_ctx;
+       enum mapistore_error    ret;
+       TALLOC_CTX              *mem_ctx;
+       void                    *subfolder;
+       uint64_t                *child_fmids;
+       uint32_t                i, child_count;
+
+       /* TODO : handle the removal of entries in indexing.tdb */
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -495,44 +543,83 @@ _PUBLIC_ int mapistore_folder_delete_folder(struct mapistore_context *mstore_ctx
 
        /* Step 1. Find the backend context */
        backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id);
-       MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, mem_ctx);
-
-       sub_mem_ctx = talloc_zero(mem_ctx, TALLOC_CTX);
-       ret = mapistore_folder_open_folder(mstore_ctx, context_id, folder, sub_mem_ctx, fid, &subfolder);
-       MAPISTORE_RETVAL_IF(ret != MAPISTORE_SUCCESS, ret, mem_ctx);
-
-       /* Step 2. Handle deletion of child folders / messages */
-       if ((flags & DEL_FOLDERS)) {
-               uint64_t        *childFolders;
-               uint32_t        childFolderCount;
-               int             retval;
-               uint32_t        i;
-
-               /* Get subfolders list */
-               retval = mapistore_folder_get_child_fids(mstore_ctx, context_id, subfolder, mem_ctx, &childFolders, &childFolderCount);
-               if (retval) {
-                       DEBUG(4, ("mapistore_delete_folder bad retval: 0x%x", retval));
-                       return MAPI_E_NOT_FOUND;
+       if (!backend_ctx) {
+               ret = MAPISTORE_ERR_INVALID_PARAMETER;
+               goto end;
+       }
+
+       /* Step 2a. Handle deletion of normal messages */
+       ret = mapistore_folder_get_child_fmids(mstore_ctx, context_id, folder, MAPISTORE_MESSAGE_TABLE, mem_ctx, &child_fmids, &child_count);
+       if (ret != MAPISTORE_SUCCESS) {
+               goto end;
+       }
+       if (child_count > 0) {
+               if ((flags & DEL_MESSAGES)) {
+                       for (i = 0; i < child_count; i++) {
+                               ret = mapistore_backend_folder_delete_message(backend_ctx, folder, child_fmids[i], 0);
+                               if (ret != MAPISTORE_SUCCESS) {
+                                       goto end;
+                               }
+                       }
+               }
+               else {
+                       ret = MAPISTORE_ERR_EXIST;
+                       goto end;
                }
+       }
 
-               /* Delete each subfolder in mapistore */
-               for (i = 0; i < childFolderCount; ++i) {
-                       retval = mapistore_folder_delete_folder(mstore_ctx, context_id, subfolder, childFolders[i], flags);
-                       if (retval) {
-                                 DEBUG(4, ("mapistore_delete_folder failed to delete fid 0x%"PRIx64" (0x%x)", childFolders[i], retval));
-                                 talloc_free(mem_ctx);
-                                 return MAPI_E_NOT_FOUND;
+       /* Step 2b. Handle deletion of FAI messages */
+       ret = mapistore_folder_get_child_fmids(mstore_ctx, context_id, folder, MAPISTORE_FAI_TABLE, mem_ctx, &child_fmids, &child_count);
+       if (ret != MAPISTORE_SUCCESS) {
+               goto end;
+       }
+       if (child_count > 0) {
+               if ((flags & DEL_MESSAGES)) {
+                       for (i = 0; i < child_count; i++) {
+                               ret = mapistore_backend_folder_delete_message(backend_ctx, folder, child_fmids[i], 0);
+                               if (ret != MAPISTORE_SUCCESS) {
+                                       goto end;
+                               }
                        }
                }
+               else {
+                       ret = MAPISTORE_ERR_EXIST;
+                       goto end;
+               }
        }
-       talloc_free(sub_mem_ctx);
-       
+
+       /* Step 3. Handle deletion of child folders */
+       ret = mapistore_folder_get_child_fmids(mstore_ctx, context_id, folder, MAPISTORE_FOLDER_TABLE, mem_ctx, &child_fmids, &child_count);
+       if (ret != MAPISTORE_SUCCESS) {
+               goto end;
+       }
+       if (child_count > 0) {
+               if ((flags & DEL_FOLDERS)) {
+                       for (i = 0; i < child_count; i++) {
+                               ret = mapistore_backend_folder_open_folder(backend_ctx, folder, mem_ctx, child_fmids[i], &subfolder);
+                               if (ret != MAPISTORE_SUCCESS) {
+                                       goto end;
+                               }
+
+                               ret = mapistore_backend_folder_delete(backend_ctx, subfolder);
+                               if (ret != MAPISTORE_SUCCESS) {
+                                       goto end;
+                               }
+                       }
+               }
+               else {
+                       ret = MAPISTORE_ERR_EXIST;
+                       goto end;
+               }
+       }
+
        /* Step 3. Call backend delete_folder */
-       ret = mapistore_backend_folder_delete_folder(backend_ctx, folder, fid);
+       ret = mapistore_backend_folder_delete(backend_ctx, folder);
 
+end:
        talloc_free(mem_ctx);
 
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return ret;
 }
 
 /**
@@ -547,11 +634,10 @@ _PUBLIC_ int mapistore_folder_delete_folder(struct mapistore_context *mstore_ctx
 
    \return MAPISTORE SUCCESS on success, otherwise MAPISTORE errors
  */
-_PUBLIC_ int mapistore_folder_open_message(struct mapistore_context *mstore_ctx, uint32_t context_id,
-                                          void *folder, TALLOC_CTX *mem_ctx, uint64_t mid, void **messagep)
+_PUBLIC_ enum mapistore_error mapistore_folder_open_message(struct mapistore_context *mstore_ctx, uint32_t context_id,
+                                                           void *folder, TALLOC_CTX *mem_ctx, uint64_t mid, bool read_write, void **messagep)
 {
        struct backend_context          *backend_ctx;
-       int                             ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -561,9 +647,7 @@ _PUBLIC_ int mapistore_folder_open_message(struct mapistore_context *mstore_ctx,
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
        /* Step 2. Call backend open_message */
-       ret = mapistore_backend_folder_open_message(backend_ctx, folder, mem_ctx, mid, messagep);
-
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return mapistore_backend_folder_open_message(backend_ctx, folder, mem_ctx, mid, read_write, messagep);
 }
 
 
@@ -579,11 +663,10 @@ _PUBLIC_ int mapistore_folder_open_message(struct mapistore_context *mstore_ctx,
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors
  */
-_PUBLIC_ int mapistore_folder_create_message(struct mapistore_context *mstore_ctx, uint32_t context_id,
-                                            void *folder, TALLOC_CTX *mem_ctx, uint64_t mid, uint8_t associated, void **messagep)
+_PUBLIC_ enum mapistore_error mapistore_folder_create_message(struct mapistore_context *mstore_ctx, uint32_t context_id,
+                                                             void *folder, TALLOC_CTX *mem_ctx, uint64_t mid, uint8_t associated, void **messagep)
 {
        struct backend_context          *backend_ctx;
-       int                             ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -593,9 +676,7 @@ _PUBLIC_ int mapistore_folder_create_message(struct mapistore_context *mstore_ct
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
        
        /* Step 2. Call backend create_message */
-       ret = mapistore_backend_folder_create_message(backend_ctx, folder, mem_ctx, mid, associated, messagep);
-
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return mapistore_backend_folder_create_message(backend_ctx, folder, mem_ctx, mid, associated, messagep);
 }
 
 /**
@@ -610,11 +691,10 @@ _PUBLIC_ int mapistore_folder_create_message(struct mapistore_context *mstore_ct
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors
  */
-_PUBLIC_ int mapistore_folder_delete_message(struct mapistore_context *mstore_ctx, uint32_t context_id,
-                                            void *folder, uint64_t mid, uint8_t flags)
+_PUBLIC_ enum mapistore_error mapistore_folder_delete_message(struct mapistore_context *mstore_ctx, uint32_t context_id,
+                                                             void *folder, uint64_t mid, uint8_t flags)
 {
        struct backend_context  *backend_ctx;
-       int                     ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -624,19 +704,16 @@ _PUBLIC_ int mapistore_folder_delete_message(struct mapistore_context *mstore_ct
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
        /* Step 2. Call backend operation */
-       ret = mapistore_backend_folder_delete_message(backend_ctx, folder, mid, flags);
-
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return mapistore_backend_folder_delete_message(backend_ctx, folder, mid, flags);
 }
 
 /**
 
  */
-_PUBLIC_ int mapistore_folder_move_copy_messages(struct mapistore_context *mstore_ctx, uint32_t context_id,
-                                                void *target_folder, void *source_folder, uint32_t mid_count, uint64_t *source_mids, uint64_t *target_mids, struct Binary_r **target_change_keys, uint8_t want_copy)
+_PUBLIC_ enum mapistore_error mapistore_folder_move_copy_messages(struct mapistore_context *mstore_ctx, uint32_t context_id,
+                                                                 void *target_folder, void *source_folder, uint32_t mid_count, uint64_t *source_mids, uint64_t *target_mids, struct Binary_r **target_change_keys, uint8_t want_copy)
 {
        struct backend_context  *backend_ctx;
-       int                     ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -646,9 +723,7 @@ _PUBLIC_ int mapistore_folder_move_copy_messages(struct mapistore_context *mstor
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
        /* Step 2. Call backend operation */
-       ret = mapistore_backend_folder_move_copy_messages(backend_ctx, target_folder, source_folder, mid_count, source_mids, target_mids, target_change_keys, want_copy);
-
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return mapistore_backend_folder_move_copy_messages(backend_ctx, target_folder, source_folder, mid_count, source_mids, target_mids, target_change_keys, want_copy);
 }
 
 
@@ -666,10 +741,9 @@ _PUBLIC_ int mapistore_folder_move_copy_messages(struct mapistore_context *mstor
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors
  */
-_PUBLIC_ int mapistore_folder_get_deleted_fmids(struct mapistore_context *mstore_ctx, uint32_t context_id, void *folder, TALLOC_CTX *mem_ctx, uint8_t table_type, uint64_t change_num, struct I8Array_r **fmidsp, uint64_t *cnp)
+_PUBLIC_ enum mapistore_error mapistore_folder_get_deleted_fmids(struct mapistore_context *mstore_ctx, uint32_t context_id, void *folder, TALLOC_CTX *mem_ctx, enum mapistore_table_type table_type, uint64_t change_num, struct I8Array_r **fmidsp, uint64_t *cnp)
 {
        struct backend_context  *backend_ctx;
-       int                     ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -679,42 +753,9 @@ _PUBLIC_ int mapistore_folder_get_deleted_fmids(struct mapistore_context *mstore
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
        /* Step 2. Call backend operation */
-       ret = mapistore_backend_folder_get_deleted_fmids(backend_ctx, folder, mem_ctx, table_type, change_num, fmidsp, cnp);
-
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return mapistore_backend_folder_get_deleted_fmids(backend_ctx, folder, mem_ctx, table_type, change_num, fmidsp, cnp);
 }
 
-/**
-   \details Retrieve the number of child folders within a mapistore
-   folder
-
-   \param mstore_ctx pointer to the mapistore context
-   \param context_id the context identifier referencing the backend
-   \param fid the folder identifier
-   \param RowCount pointer to the count result to return
-
-   \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors
- */
-_PUBLIC_ int mapistore_folder_get_folder_count(struct mapistore_context *mstore_ctx, uint32_t context_id,
-                                              void *folder, uint32_t *RowCount)
-{
-       struct backend_context          *backend_ctx;
-       int                             ret;
-
-       /* Sanity checks */
-       MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
-
-       /* Step 0. Ensure the context exists */
-       backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id);
-       MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
-
-       /* Step 1. Call backend readdir */
-       ret = mapistore_backend_folder_get_child_count(backend_ctx, folder, MAPISTORE_FOLDER_TABLE, RowCount);
-
-       return ret;
-}
-
-
 /**
    \details Retrieve the number of child messages within a mapistore folder
 
@@ -725,11 +766,9 @@ _PUBLIC_ int mapistore_folder_get_folder_count(struct mapistore_context *mstore_
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors
  */
-_PUBLIC_ int mapistore_folder_get_message_count(struct mapistore_context *mstore_ctx, uint32_t context_id,
-                                               void *folder, uint8_t table_type, uint32_t *RowCount)
+_PUBLIC_ enum mapistore_error mapistore_folder_get_child_count(struct mapistore_context *mstore_ctx, uint32_t context_id, void *folder, enum mapistore_table_type table_type, uint32_t *RowCount)
 {
        struct backend_context          *backend_ctx;
-       int                             ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -739,9 +778,7 @@ _PUBLIC_ int mapistore_folder_get_message_count(struct mapistore_context *mstore
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
        /* Step 2. Call backend get_child_count */
-       ret = mapistore_backend_folder_get_child_count(backend_ctx, folder, table_type, RowCount);
-
-       return ret;
+       return mapistore_backend_folder_get_child_count(backend_ctx, folder, table_type, RowCount);
 }
 
 /**
@@ -759,45 +796,66 @@ _PUBLIC_ int mapistore_folder_get_message_count(struct mapistore_context *mstore
    
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors
  */
-_PUBLIC_ int mapistore_folder_get_child_fids(struct mapistore_context *mstore_ctx, uint32_t context_id,
-                                            void *folder, TALLOC_CTX *mem_ctx, uint64_t *child_fids[], uint32_t *child_fid_count)
+_PUBLIC_ enum mapistore_error mapistore_folder_get_child_fmids(struct mapistore_context *mstore_ctx, uint32_t context_id, void *folder, enum mapistore_table_type table_type, TALLOC_CTX *mem_ctx, uint64_t *child_fmids[], uint32_t *child_fmid_count)
 {
-       TALLOC_CTX      *local_mem_ctx;
-       int             ret;
-       void            *backend_table;
-       uint32_t        i, row_count;
-       uint64_t        *fids, *current_fid;
-       enum MAPITAGS   fid_column;
-       struct mapistore_property_data *row_data;
+       TALLOC_CTX                      *local_mem_ctx;
+       enum mapistore_error            ret;
+       void                            *backend_table;
+       uint32_t                        i, row_count;
+       uint64_t                        *fmids, *current_fmid;
+       enum MAPITAGS                   fmid_column;
+       struct mapistore_property_data  *row_data;
+
+       switch (table_type) {
+       case MAPISTORE_FOLDER_TABLE:
+               fmid_column = PR_FID;
+               break;
+       case MAPISTORE_MESSAGE_TABLE:
+       case MAPISTORE_FAI_TABLE:
+               fmid_column = PR_MID;
+               break;
+       case MAPISTORE_RULE_TABLE:
+               fmid_column = PR_RULE_ID;
+               break;
+       case MAPISTORE_ATTACHMENT_TABLE:
+               fmid_column = PR_ATTACH_ID;
+               break;
+       case MAPISTORE_PERMISSIONS_TABLE:
+               fmid_column = PR_MEMBER_ID;
+               break;
+       }
 
        local_mem_ctx = talloc_zero(NULL, TALLOC_CTX);
-       ret = mapistore_folder_open_table(mstore_ctx, context_id,
-                                         folder, local_mem_ctx, MAPISTORE_FOLDER_TABLE, -1, &backend_table, &row_count);
-       MAPISTORE_RETVAL_IF(ret != MAPISTORE_SUCCESS, ret, local_mem_ctx);
-
-       fid_column = PR_FID;
-       ret = mapistore_table_set_columns(mstore_ctx, context_id, backend_table, 1, &fid_column);
-       MAPISTORE_RETVAL_IF(ret != MAPISTORE_SUCCESS, ret, local_mem_ctx);
-
-       *child_fid_count = row_count;
-       fids = talloc_array(mem_ctx, uint64_t, row_count);
-       *child_fids = fids;
-       current_fid = fids;
+       ret = mapistore_folder_open_table(mstore_ctx, context_id, folder, local_mem_ctx, table_type, 0, &backend_table, &row_count);
+       if (ret != MAPISTORE_SUCCESS) {
+               goto end;
+       }
+
+       ret = mapistore_table_set_columns(mstore_ctx, context_id, backend_table, 1, &fmid_column);
+       if (ret != MAPISTORE_SUCCESS) {
+               goto end;
+       }
+
+       *child_fmid_count = row_count;
+       fmids = talloc_array(mem_ctx, uint64_t, row_count);
+       *child_fmids = fmids;
+       current_fmid = fmids;
        for (i = 0; i < row_count; i++) {
                mapistore_table_get_row(mstore_ctx, context_id, backend_table, local_mem_ctx,
                                        MAPISTORE_PREFILTERED_QUERY, i, &row_data);
-               *current_fid = *(uint64_t *) row_data->data;
-               current_fid++;
+               *current_fmid = *(uint64_t *) row_data->data;
+               current_fmid++;
        }
+
+end:
        talloc_free(local_mem_ctx);
 
        return ret;
 }
 
-_PUBLIC_ int mapistore_folder_get_child_fid_by_name(struct mapistore_context *mstore_ctx, uint32_t context_id, void *folder, const char *name, uint64_t *fidp)
+_PUBLIC_ enum mapistore_error mapistore_folder_get_child_fid_by_name(struct mapistore_context *mstore_ctx, uint32_t context_id, void *folder, const char *name, uint64_t *fidp)
 {
        struct backend_context  *backend_ctx;
-       int                     ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -807,16 +865,13 @@ _PUBLIC_ int mapistore_folder_get_child_fid_by_name(struct mapistore_context *ms
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
        /* Step 2. Call backend operation */
-       ret = mapistore_backend_folder_get_child_fid_by_name(backend_ctx, folder, name, fidp);
-
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return mapistore_backend_folder_get_child_fid_by_name(backend_ctx, folder, name, fidp);
 }
 
-_PUBLIC_ int mapistore_folder_open_table(struct mapistore_context *mstore_ctx, uint32_t context_id,
-                                        void *folder, TALLOC_CTX *mem_ctx, uint8_t table_type, uint32_t handle_id, void **table, uint32_t *row_count)
+_PUBLIC_ enum mapistore_error mapistore_folder_open_table(struct mapistore_context *mstore_ctx, uint32_t context_id,
+                                                         void *folder, TALLOC_CTX *mem_ctx, enum mapistore_table_type table_type, uint32_t handle_id, void **table, uint32_t *row_count)
 {
        struct backend_context  *backend_ctx;
-       int                     ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -826,15 +881,12 @@ _PUBLIC_ int mapistore_folder_open_table(struct mapistore_context *mstore_ctx, u
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
        /* Step 2. Call backend operation */
-       ret = mapistore_backend_folder_open_table(backend_ctx, folder, mem_ctx, table_type, handle_id, table, row_count);
-
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return mapistore_backend_folder_open_table(backend_ctx, folder, mem_ctx, table_type, handle_id, table, row_count);
 }
 
-_PUBLIC_ int mapistore_folder_modify_permissions(struct mapistore_context *mstore_ctx, uint32_t context_id, void *folder, uint8_t flags, uint16_t pcount, struct PermissionData *permissions)
+_PUBLIC_ enum mapistore_error mapistore_folder_modify_permissions(struct mapistore_context *mstore_ctx, uint32_t context_id, void *folder, uint8_t flags, uint16_t pcount, struct PermissionData *permissions)
 {
        struct backend_context  *backend_ctx;
-       int                     ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -844,9 +896,7 @@ _PUBLIC_ int mapistore_folder_modify_permissions(struct mapistore_context *mstor
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
        /* Step 2. Call backend operation */
-       ret = mapistore_backend_folder_modify_permissions(backend_ctx, folder, flags, pcount, permissions);
-
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return mapistore_backend_folder_modify_permissions(backend_ctx, folder, flags, pcount, permissions);
 }
 
 /**
@@ -861,10 +911,9 @@ _PUBLIC_ int mapistore_folder_modify_permissions(struct mapistore_context *mstor
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors
  */
-int mapistore_message_get_message_data(struct mapistore_context *mstore_ctx, uint32_t context_id, void *message, TALLOC_CTX *mem_ctx, struct mapistore_message **msg)
+enum mapistore_error mapistore_message_get_message_data(struct mapistore_context *mstore_ctx, uint32_t context_id, void *message, TALLOC_CTX *mem_ctx, struct mapistore_message **msg)
 {
        struct backend_context  *backend_ctx;
-       int                     ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -874,9 +923,7 @@ int mapistore_message_get_message_data(struct mapistore_context *mstore_ctx, uin
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
        /* Step 2. Call backend modifyrecipients */
-       ret = mapistore_backend_message_get_message_data(backend_ctx, message, mem_ctx, msg);
-
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return mapistore_backend_message_get_message_data(backend_ctx, message, mem_ctx, msg);
 }
 
 /**
@@ -891,10 +938,9 @@ int mapistore_message_get_message_data(struct mapistore_context *mstore_ctx, uin
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors
  */
-int mapistore_message_modify_recipients(struct mapistore_context *mstore_ctx, uint32_t context_id, void *message, struct SPropTagArray *columns, uint16_t count, struct mapistore_message_recipient *recipients)
+enum mapistore_error mapistore_message_modify_recipients(struct mapistore_context *mstore_ctx, uint32_t context_id, void *message, struct SPropTagArray *columns, uint16_t count, struct mapistore_message_recipient *recipients)
 {
        struct backend_context  *backend_ctx;
-       int                     ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -904,9 +950,7 @@ int mapistore_message_modify_recipients(struct mapistore_context *mstore_ctx, ui
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
        /* Step 2. Call backend modifyrecipients */
-       ret = mapistore_backend_message_modify_recipients(backend_ctx, message, columns, count, recipients);
-
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return mapistore_backend_message_modify_recipients(backend_ctx, message, columns, count, recipients);
 }
 
 /**
@@ -920,10 +964,9 @@ int mapistore_message_modify_recipients(struct mapistore_context *mstore_ctx, ui
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors
  */
-_PUBLIC_ int mapistore_message_set_read_flag(struct mapistore_context *mstore_ctx, uint32_t context_id, void *message, uint8_t flag)
+_PUBLIC_ enum mapistore_error mapistore_message_set_read_flag(struct mapistore_context *mstore_ctx, uint32_t context_id, void *message, uint8_t flag)
 {
        struct backend_context  *backend_ctx;
-       int                     ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -933,9 +976,7 @@ _PUBLIC_ int mapistore_message_set_read_flag(struct mapistore_context *mstore_ct
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
        /* Step 2. Call backend savechangesmessage */
-       ret = mapistore_backend_message_set_read_flag(backend_ctx, message, flag);
-
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return mapistore_backend_message_set_read_flag(backend_ctx, message, flag);
 }
 
 /**
@@ -949,11 +990,9 @@ _PUBLIC_ int mapistore_message_set_read_flag(struct mapistore_context *mstore_ct
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors
  */
-_PUBLIC_ int mapistore_message_save(struct mapistore_context *mstore_ctx, uint32_t context_id,
-                                   void *message)
+_PUBLIC_ enum mapistore_error mapistore_message_save(struct mapistore_context *mstore_ctx, uint32_t context_id, void *message)
 {
        struct backend_context  *backend_ctx;
-       int                     ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -963,9 +1002,7 @@ _PUBLIC_ int mapistore_message_save(struct mapistore_context *mstore_ctx, uint32
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
        /* Step 2. Call backend savechangesmessage */
-       ret = mapistore_backend_message_save(backend_ctx, message);
-
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return mapistore_backend_message_save(backend_ctx, message);
 }
 
 
@@ -980,11 +1017,10 @@ _PUBLIC_ int mapistore_message_save(struct mapistore_context *mstore_ctx, uint32
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors
  */
-_PUBLIC_ int mapistore_message_submit(struct mapistore_context *mstore_ctx, uint32_t context_id,
-                                     void *message, enum SubmitFlags flags)
+_PUBLIC_ enum mapistore_error mapistore_message_submit(struct mapistore_context *mstore_ctx, uint32_t context_id,
+                                                      void *message, enum SubmitFlags flags)
 {
        struct backend_context  *backend_ctx;
-       int                     ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -994,16 +1030,13 @@ _PUBLIC_ int mapistore_message_submit(struct mapistore_context *mstore_ctx, uint
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
        /* Step 2. Call backend submitmessage */
-       ret = mapistore_backend_message_submit(backend_ctx, message, flags);
-
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return mapistore_backend_message_submit(backend_ctx, message, flags);
 }
 
-_PUBLIC_ int mapistore_message_get_attachment_table(struct mapistore_context *mstore_ctx, uint32_t context_id,
-                                                   void *message, TALLOC_CTX *mem_ctx, void **table, uint32_t *row_count)
+_PUBLIC_ enum mapistore_error mapistore_message_get_attachment_table(struct mapistore_context *mstore_ctx, uint32_t context_id,
+                                                                    void *message, TALLOC_CTX *mem_ctx, void **table, uint32_t *row_count)
 {
        struct backend_context  *backend_ctx;
-       int                     ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -1013,16 +1046,13 @@ _PUBLIC_ int mapistore_message_get_attachment_table(struct mapistore_context *ms
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
        /* Step 2. Call backend operation */
-       ret = mapistore_backend_message_get_attachment_table(backend_ctx, message, mem_ctx, table, row_count);
-
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return mapistore_backend_message_get_attachment_table(backend_ctx, message, mem_ctx, table, row_count);
 }
 
-_PUBLIC_ int mapistore_message_open_attachment(struct mapistore_context *mstore_ctx, uint32_t context_id,
-                                              void *message, TALLOC_CTX *mem_ctx, uint32_t aid, void **attachment)
+_PUBLIC_ enum mapistore_error mapistore_message_open_attachment(struct mapistore_context *mstore_ctx, uint32_t context_id,
+                                                               void *message, TALLOC_CTX *mem_ctx, uint32_t aid, void **attachment)
 {
        struct backend_context  *backend_ctx;
-       int                     ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -1032,16 +1062,13 @@ _PUBLIC_ int mapistore_message_open_attachment(struct mapistore_context *mstore_
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
        /* Step 2. Call backend operation */
-       ret = mapistore_backend_message_open_attachment(backend_ctx, message, mem_ctx, aid, attachment);
-
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return mapistore_backend_message_open_attachment(backend_ctx, message, mem_ctx, aid, attachment);
 }
 
-_PUBLIC_ int mapistore_message_create_attachment(struct mapistore_context *mstore_ctx, uint32_t context_id,
-                                                void *message, TALLOC_CTX *mem_ctx, void **attachment, uint32_t *aid)
+_PUBLIC_ enum mapistore_error mapistore_message_create_attachment(struct mapistore_context *mstore_ctx, uint32_t context_id,
+                                                                 void *message, TALLOC_CTX *mem_ctx, void **attachment, uint32_t *aid)
 {
        struct backend_context  *backend_ctx;
-       int                     ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -1051,15 +1078,12 @@ _PUBLIC_ int mapistore_message_create_attachment(struct mapistore_context *mstor
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
        /* Step 2. Call backend operation */
-       ret = mapistore_backend_message_create_attachment(backend_ctx, message, mem_ctx, attachment, aid);
-
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return mapistore_backend_message_create_attachment(backend_ctx, message, mem_ctx, attachment, aid);
 }
 
-_PUBLIC_ int mapistore_message_attachment_open_embedded_message(struct mapistore_context *mstore_ctx, uint32_t context_id, void *message, TALLOC_CTX *mem_ctx, void **embedded_message, uint64_t *mid, struct mapistore_message **msg)
+_PUBLIC_ enum mapistore_error mapistore_message_attachment_open_embedded_message(struct mapistore_context *mstore_ctx, uint32_t context_id, void *message, TALLOC_CTX *mem_ctx, void **embedded_message, uint64_t *mid, struct mapistore_message **msg)
 {
        struct backend_context  *backend_ctx;
-       int                     ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -1069,15 +1093,12 @@ _PUBLIC_ int mapistore_message_attachment_open_embedded_message(struct mapistore
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
        /* Step 2. Call backend operation */
-       ret = mapistore_backend_message_attachment_open_embedded_message(backend_ctx, message, mem_ctx, embedded_message, mid, msg);
-
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return mapistore_backend_message_attachment_open_embedded_message(backend_ctx, message, mem_ctx, embedded_message, mid, msg);
 }
 
-_PUBLIC_ int mapistore_table_get_available_properties(struct mapistore_context *mstore_ctx, uint32_t context_id, void *table, TALLOC_CTX *mem_ctx, struct SPropTagArray **propertiesp)
+_PUBLIC_ enum mapistore_error mapistore_table_get_available_properties(struct mapistore_context *mstore_ctx, uint32_t context_id, void *table, TALLOC_CTX *mem_ctx, struct SPropTagArray **propertiesp)
 {
        struct backend_context  *backend_ctx;
-       int                     ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -1087,15 +1108,12 @@ _PUBLIC_ int mapistore_table_get_available_properties(struct mapistore_context *
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
        /* Step 2. Call backend operation */
-       ret = mapistore_backend_table_get_available_properties(backend_ctx, table, mem_ctx, propertiesp);
-
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return mapistore_backend_table_get_available_properties(backend_ctx, table, mem_ctx, propertiesp);
 }
 
-_PUBLIC_ int mapistore_table_set_columns(struct mapistore_context *mstore_ctx, uint32_t context_id, void *table, uint16_t count, enum MAPITAGS *properties)
+_PUBLIC_ enum mapistore_error mapistore_table_set_columns(struct mapistore_context *mstore_ctx, uint32_t context_id, void *table, uint16_t count, enum MAPITAGS *properties)
 {
        struct backend_context  *backend_ctx;
-       int                     ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -1105,15 +1123,12 @@ _PUBLIC_ int mapistore_table_set_columns(struct mapistore_context *mstore_ctx, u
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
        /* Step 2. Call backend operation */
-       ret = mapistore_backend_table_set_columns(backend_ctx, table, count, properties);
-
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return mapistore_backend_table_set_columns(backend_ctx, table, count, properties);
 }
 
-_PUBLIC_ int mapistore_table_set_restrictions(struct mapistore_context *mstore_ctx, uint32_t context_id, void *table, struct mapi_SRestriction *restrictions, uint8_t *table_status)
+_PUBLIC_ enum mapistore_error mapistore_table_set_restrictions(struct mapistore_context *mstore_ctx, uint32_t context_id, void *table, struct mapi_SRestriction *restrictions, uint8_t *table_status)
 {
        struct backend_context  *backend_ctx;
-       int                     ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -1123,15 +1138,12 @@ _PUBLIC_ int mapistore_table_set_restrictions(struct mapistore_context *mstore_c
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
        /* Step 2. Call backend operation */
-       ret = mapistore_backend_table_set_restrictions(backend_ctx, table, restrictions, table_status);
-
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return mapistore_backend_table_set_restrictions(backend_ctx, table, restrictions, table_status);
 }
 
-_PUBLIC_ int mapistore_table_set_sort_order(struct mapistore_context *mstore_ctx, uint32_t context_id, void *table, struct SSortOrderSet *sort_order, uint8_t *table_status)
+_PUBLIC_ enum mapistore_error mapistore_table_set_sort_order(struct mapistore_context *mstore_ctx, uint32_t context_id, void *table, struct SSortOrderSet *sort_order, uint8_t *table_status)
 {
        struct backend_context  *backend_ctx;
-       int                     ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -1141,16 +1153,13 @@ _PUBLIC_ int mapistore_table_set_sort_order(struct mapistore_context *mstore_ctx
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
        /* Step 2. Call backend operation */
-       ret = mapistore_backend_table_set_sort_order(backend_ctx, table, sort_order, table_status);
-
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return mapistore_backend_table_set_sort_order(backend_ctx, table, sort_order, table_status);
 }
 
-_PUBLIC_ int mapistore_table_get_row(struct mapistore_context *mstore_ctx, uint32_t context_id, void *table, TALLOC_CTX *mem_ctx,
-                                    enum table_query_type query_type, uint32_t rowid, struct mapistore_property_data **data)
+_PUBLIC_ enum mapistore_error mapistore_table_get_row(struct mapistore_context *mstore_ctx, uint32_t context_id, void *table, TALLOC_CTX *mem_ctx,
+                                                     enum mapistore_query_type query_type, uint32_t rowid, struct mapistore_property_data **data)
 {
        struct backend_context  *backend_ctx;
-       int                     ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -1160,15 +1169,12 @@ _PUBLIC_ int mapistore_table_get_row(struct mapistore_context *mstore_ctx, uint3
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
        /* Step 2. Call backend operation */
-       ret = mapistore_backend_table_get_row(backend_ctx, table, mem_ctx, query_type, rowid, data);
-
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return mapistore_backend_table_get_row(backend_ctx, table, mem_ctx, query_type, rowid, data);
 }
 
-_PUBLIC_ int mapistore_table_get_row_count(struct mapistore_context *mstore_ctx, uint32_t context_id, void *table, enum table_query_type query_type, uint32_t *row_countp)
+_PUBLIC_ enum mapistore_error mapistore_table_get_row_count(struct mapistore_context *mstore_ctx, uint32_t context_id, void *table, enum mapistore_query_type query_type, uint32_t *row_countp)
 {
        struct backend_context  *backend_ctx;
-       int                     ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -1178,15 +1184,12 @@ _PUBLIC_ int mapistore_table_get_row_count(struct mapistore_context *mstore_ctx,
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
        /* Step 2. Call backend operation */
-       ret = mapistore_backend_table_get_row_count(backend_ctx, table, query_type, row_countp);
-
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return mapistore_backend_table_get_row_count(backend_ctx, table, query_type, row_countp);
 }
 
-_PUBLIC_ int mapistore_table_handle_destructor(struct mapistore_context *mstore_ctx, uint32_t context_id, void *table, uint32_t handle_id)
+_PUBLIC_ enum mapistore_error mapistore_table_handle_destructor(struct mapistore_context *mstore_ctx, uint32_t context_id, void *table, uint32_t handle_id)
 {
-       struct backend_context          *backend_ctx;
-       int                             ret;
+       struct backend_context  *backend_ctx;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -1196,15 +1199,12 @@ _PUBLIC_ int mapistore_table_handle_destructor(struct mapistore_context *mstore_
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
        /* Step 2. Call backend operation */
-       ret = mapistore_backend_table_handle_destructor(backend_ctx, table, handle_id);
-
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return mapistore_backend_table_handle_destructor(backend_ctx, table, handle_id);
 }
 
-_PUBLIC_ int mapistore_properties_get_available_properties(struct mapistore_context *mstore_ctx, uint32_t context_id, void *object, TALLOC_CTX *mem_ctx, struct SPropTagArray **propertiesp)
+_PUBLIC_ enum mapistore_error mapistore_properties_get_available_properties(struct mapistore_context *mstore_ctx, uint32_t context_id, void *object, TALLOC_CTX *mem_ctx, struct SPropTagArray **propertiesp)
 {
        struct backend_context  *backend_ctx;
-       int                     ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -1214,19 +1214,16 @@ _PUBLIC_ int mapistore_properties_get_available_properties(struct mapistore_cont
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
        /* Step 2. Call backend operation */
-       ret = mapistore_backend_properties_get_available_properties(backend_ctx, object, mem_ctx, propertiesp);
-
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return mapistore_backend_properties_get_available_properties(backend_ctx, object, mem_ctx, propertiesp);
 }
 
 
-_PUBLIC_ int mapistore_properties_get_properties(struct mapistore_context *mstore_ctx, uint32_t context_id,
-                                                void *object, TALLOC_CTX *mem_ctx,
-                                                uint16_t count, enum MAPITAGS *properties,
-                                                struct mapistore_property_data *data)
+_PUBLIC_ enum mapistore_error mapistore_properties_get_properties(struct mapistore_context *mstore_ctx, uint32_t context_id,
+                                                                 void *object, TALLOC_CTX *mem_ctx,
+                                                                 uint16_t count, enum MAPITAGS *properties,
+                                                                 struct mapistore_property_data *data)
 {
        struct backend_context  *backend_ctx;
-       int                     ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -1236,18 +1233,15 @@ _PUBLIC_ int mapistore_properties_get_properties(struct mapistore_context *mstor
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
        /* Step 2. Call backend operation */
-       ret = mapistore_backend_properties_get_properties(backend_ctx, object, mem_ctx, count, properties, data);
-
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return mapistore_backend_properties_get_properties(backend_ctx, object, mem_ctx, count, properties, data);
 }
 
-_PUBLIC_ int mapistore_properties_set_properties(struct mapistore_context
-                                                *mstore_ctx, uint32_t context_id,
-                                                void *object,
-                                                struct SRow *aRow)
+_PUBLIC_ enum mapistore_error mapistore_properties_set_properties(struct mapistore_context
+                                                                 *mstore_ctx, uint32_t context_id,
+                                                                 void *object,
+                                                                 struct SRow *aRow)
 {
        struct backend_context  *backend_ctx;
-       int                     ret;
 
        /* Sanity checks */
        MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL);
@@ -1257,7 +1251,5 @@ _PUBLIC_ int mapistore_properties_set_properties(struct mapistore_context
        MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
        /* Step 2. Call backend operation */
-       ret = mapistore_backend_properties_set_properties(backend_ctx, object, aRow);
-
-       return !ret ? MAPISTORE_SUCCESS : MAPISTORE_ERROR;
+       return mapistore_backend_properties_set_properties(backend_ctx, object, aRow);
 }
index 93174edba7cd6cebfe1054d97620bcd5ac4f1c6a..e676a88750f916462e8c9f12733902fe47815075 100644 (file)
@@ -44,7 +44,7 @@ static const char *mapistore_namedprops_get_ldif_path(void)
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-int mapistore_namedprops_init(TALLOC_CTX *mem_ctx, struct ldb_context **_ldb_ctx)
+enum mapistore_error mapistore_namedprops_init(TALLOC_CTX *mem_ctx, struct ldb_context **_ldb_ctx)
 {
        int                     ret;
        struct stat             sb;
@@ -153,7 +153,7 @@ _PUBLIC_ uint16_t mapistore_namedprops_next_unused_id(struct ldb_context *ldb_ct
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR
  */
-_PUBLIC_ int mapistore_namedprops_create_id(struct ldb_context *ldb_ctx, struct MAPINAMEID nameid, uint16_t mapped_id)
+_PUBLIC_ enum mapistore_error mapistore_namedprops_create_id(struct ldb_context *ldb_ctx, struct MAPINAMEID nameid, uint16_t mapped_id)
 {
        int ret;
        TALLOC_CTX *mem_ctx;
@@ -212,7 +212,7 @@ _PUBLIC_ int mapistore_namedprops_create_id(struct ldb_context *ldb_ctx, struct
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR
  */
-_PUBLIC_ int mapistore_namedprops_get_mapped_id(struct ldb_context *ldb_ctx, struct MAPINAMEID nameid, uint16_t *propID)
+_PUBLIC_ enum mapistore_error mapistore_namedprops_get_mapped_id(struct ldb_context *ldb_ctx, struct MAPINAMEID nameid, uint16_t *propID)
 {
        TALLOC_CTX              *mem_ctx;
        struct ldb_result       *res = NULL;
@@ -263,9 +263,9 @@ _PUBLIC_ int mapistore_namedprops_get_mapped_id(struct ldb_context *ldb_ctx, str
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR
  */
-_PUBLIC_ int mapistore_namedprops_get_nameid(struct ldb_context *ldb_ctx, 
-                                            uint16_t propID,
-                                            struct MAPINAMEID **nameidp)
+_PUBLIC_ enum mapistore_error mapistore_namedprops_get_nameid(struct ldb_context *ldb_ctx, 
+                                                             uint16_t propID,
+                                                             struct MAPINAMEID **nameidp)
 {
        TALLOC_CTX                      *mem_ctx;
        struct ldb_result               *res = NULL;
index f84d6ba7585bac029222c1c273620f679587d9a2..703eae9c46d541a0a4b2c83ad7ef6ad9edf481c7 100644 (file)
@@ -461,8 +461,8 @@ static bool notification_matches_subscription(struct mapistore_notification *not
         return result;
 }
 
-_PUBLIC_ int mapistore_delete_subscription(struct mapistore_context *mstore_ctx, uint32_t identifier, 
-                                          uint16_t NotificationFlags)
+_PUBLIC_ enum mapistore_error mapistore_delete_subscription(struct mapistore_context *mstore_ctx, uint32_t identifier, 
+                                                           uint16_t NotificationFlags)
 {
        struct mapistore_subscription_list *el;
 
index 8732a8715b0fa22c566332ae35f2255c79062ced..720a33ce93936163baef1bf057ce788144aba9f2 100644 (file)
@@ -123,7 +123,7 @@ struct processing_context {
 struct indexing_context_list {
        struct tdb_wrap                 *index_ctx;
        char                            *username;
-       uint32_t                        ref_count;
+       // uint32_t                     ref_count;
        struct indexing_context_list    *prev;
        struct indexing_context_list    *next;
 };
@@ -160,55 +160,57 @@ __BEGIN_DECLS
 
 /* definitions from mapistore_processing.c */
 const char *mapistore_get_mapping_path(void);
-int mapistore_init_mapping_context(struct processing_context *);
-int mapistore_get_context_id(struct processing_context *, uint32_t *);
-int mapistore_free_context_id(struct processing_context *, uint32_t);
+enum mapistore_error mapistore_init_mapping_context(struct processing_context *);
+enum mapistore_error mapistore_get_context_id(struct processing_context *, uint32_t *);
+enum mapistore_error mapistore_free_context_id(struct processing_context *, uint32_t);
 
 
 /* definitions from mapistore_backend.c */
-int mapistore_backend_init(TALLOC_CTX *, const char *);
-int mapistore_backend_registered(const char *);
-struct backend_context *mapistore_backend_create_context(TALLOC_CTX *, struct mapistore_connection_info *, struct tdb_wrap *, const char *, const char *, uint64_t);
-int mapistore_backend_add_ref_count(struct backend_context *);
-int mapistore_backend_delete_context(struct backend_context *);
-int mapistore_backend_get_path(struct backend_context *, TALLOC_CTX *, uint64_t, char **);
-
-int mapistore_backend_folder_open_folder(struct backend_context *, void *, TALLOC_CTX *, uint64_t, void **);
-int mapistore_backend_folder_create_folder(struct backend_context *, void *, TALLOC_CTX *, uint64_t, struct SRow *, void **);
-int mapistore_backend_folder_delete_folder(struct backend_context *, void *, uint64_t);
-int mapistore_backend_folder_open_message(struct backend_context *, void *, TALLOC_CTX *, uint64_t, void **);
-int mapistore_backend_folder_create_message(struct backend_context *, void *, TALLOC_CTX *, uint64_t, uint8_t, void **);
-int mapistore_backend_folder_delete_message(struct backend_context *, void *, uint64_t, uint8_t);
-int mapistore_backend_folder_move_copy_messages(struct backend_context *, void *, void *, uint32_t, uint64_t *, uint64_t *, struct Binary_r **, uint8_t);
-int mapistore_backend_folder_get_deleted_fmids(struct backend_context *, void *, TALLOC_CTX *, uint8_t, uint64_t, struct I8Array_r **, uint64_t *);
-int mapistore_backend_folder_get_child_count(struct backend_context *, void *, uint8_t, uint32_t *);
-int mapistore_backend_folder_get_child_fid_by_name(struct backend_context *, void *, const char *, uint64_t *);
-int mapistore_backend_folder_open_table(struct backend_context *, void *, TALLOC_CTX *, uint8_t, uint32_t, void **, uint32_t *);
-int mapistore_backend_folder_modify_permissions(struct backend_context *, void *, uint8_t, uint16_t, struct PermissionData *);
-
-int mapistore_backend_message_get_message_data(struct backend_context *, void *, TALLOC_CTX *, struct mapistore_message **);
-int mapistore_backend_message_modify_recipients(struct backend_context *, void *, struct SPropTagArray *, uint16_t, struct mapistore_message_recipient *);
-int mapistore_backend_message_set_read_flag(struct backend_context *, void *, uint8_t);
-int mapistore_backend_message_save(struct backend_context *, void *);
-int mapistore_backend_message_submit(struct backend_context *, void *, enum SubmitFlags);
-int mapistore_backend_message_get_attachment_table(struct backend_context *, void *, TALLOC_CTX *, void **, uint32_t *);
-int mapistore_backend_message_open_attachment(struct backend_context *, void *, TALLOC_CTX *, uint32_t, void **);
-int mapistore_backend_message_create_attachment(struct backend_context *, void *, TALLOC_CTX *, void **, uint32_t *);
-int mapistore_backend_message_attachment_open_embedded_message(struct backend_context *, void *, TALLOC_CTX *, void **, uint64_t *, struct mapistore_message **msg);
-
-int mapistore_backend_table_get_available_properties(struct backend_context *, void *, TALLOC_CTX *, struct SPropTagArray **);
-int mapistore_backend_table_set_columns(struct backend_context *, void *, uint16_t, enum MAPITAGS *);
-int mapistore_backend_table_set_restrictions(struct backend_context *, void *, struct mapi_SRestriction *, uint8_t *);
-int mapistore_backend_table_set_sort_order(struct backend_context *, void *, struct SSortOrderSet *, uint8_t *);
-int mapistore_backend_table_get_row(struct backend_context *, void *, TALLOC_CTX *, enum table_query_type, uint32_t, struct mapistore_property_data **);
-int mapistore_backend_table_get_row_count(struct backend_context *, void *, enum table_query_type, uint32_t *);
-int mapistore_backend_table_handle_destructor(struct backend_context *, void *, uint32_t);
-
-int mapistore_backend_properties_get_available_properties(struct backend_context *, void *, TALLOC_CTX *, struct SPropTagArray **);
-int mapistore_backend_properties_get_properties(struct backend_context *, void *, TALLOC_CTX *, uint16_t, enum MAPITAGS *, struct mapistore_property_data *);
-int mapistore_backend_properties_set_properties(struct backend_context *, void *, struct SRow *);
-
-int mapistore_backend_manager_generate_uri(struct backend_context *, TALLOC_CTX *, const char *, const char *, const char *, const char *, char **);
+enum mapistore_error mapistore_backend_init(TALLOC_CTX *, const char *);
+enum mapistore_error mapistore_backend_registered(const char *);
+enum mapistore_error mapistore_backend_list_contexts(const char *, struct tdb_wrap *, TALLOC_CTX *, struct mapistore_contexts_list **);
+enum mapistore_error mapistore_backend_create_context(TALLOC_CTX *, struct mapistore_connection_info *, struct tdb_wrap *, const char *, const char *, uint64_t, struct backend_context **);
+enum mapistore_error mapistore_backend_create_root_folder(const char *, enum mapistore_context_role, uint64_t, const char *, TALLOC_CTX *, char **);
+enum mapistore_error mapistore_backend_add_ref_count(struct backend_context *);
+enum mapistore_error mapistore_backend_delete_context(struct backend_context *);
+enum mapistore_error mapistore_backend_get_path(struct backend_context *, TALLOC_CTX *, uint64_t, char **);
+
+enum mapistore_error mapistore_backend_folder_open_folder(struct backend_context *, void *, TALLOC_CTX *, uint64_t, void **);
+enum mapistore_error mapistore_backend_folder_create_folder(struct backend_context *, void *, TALLOC_CTX *, uint64_t, struct SRow *, void **);
+enum mapistore_error mapistore_backend_folder_delete(struct backend_context *, void *);
+enum mapistore_error mapistore_backend_folder_open_message(struct backend_context *, void *, TALLOC_CTX *, uint64_t, bool, void **);
+enum mapistore_error mapistore_backend_folder_create_message(struct backend_context *, void *, TALLOC_CTX *, uint64_t, uint8_t, void **);
+enum mapistore_error mapistore_backend_folder_delete_message(struct backend_context *, void *, uint64_t, uint8_t);
+enum mapistore_error mapistore_backend_folder_move_copy_messages(struct backend_context *, void *, void *, uint32_t, uint64_t *, uint64_t *, struct Binary_r **, uint8_t);
+enum mapistore_error mapistore_backend_folder_get_deleted_fmids(struct backend_context *, void *, TALLOC_CTX *, enum mapistore_table_type, uint64_t, struct I8Array_r **, uint64_t *);
+enum mapistore_error mapistore_backend_folder_get_child_count(struct backend_context *, void *, enum mapistore_table_type, uint32_t *);
+enum mapistore_error mapistore_backend_folder_get_child_fid_by_name(struct backend_context *, void *, const char *, uint64_t *);
+enum mapistore_error mapistore_backend_folder_open_table(struct backend_context *, void *, TALLOC_CTX *, enum mapistore_table_type, uint32_t, void **, uint32_t *);
+enum mapistore_error mapistore_backend_folder_modify_permissions(struct backend_context *, void *, uint8_t, uint16_t, struct PermissionData *);
+
+enum mapistore_error mapistore_backend_message_get_message_data(struct backend_context *, void *, TALLOC_CTX *, struct mapistore_message **);
+enum mapistore_error mapistore_backend_message_modify_recipients(struct backend_context *, void *, struct SPropTagArray *, uint16_t, struct mapistore_message_recipient *);
+enum mapistore_error mapistore_backend_message_set_read_flag(struct backend_context *, void *, uint8_t);
+enum mapistore_error mapistore_backend_message_save(struct backend_context *, void *);
+enum mapistore_error mapistore_backend_message_submit(struct backend_context *, void *, enum SubmitFlags);
+enum mapistore_error mapistore_backend_message_get_attachment_table(struct backend_context *, void *, TALLOC_CTX *, void **, uint32_t *);
+enum mapistore_error mapistore_backend_message_open_attachment(struct backend_context *, void *, TALLOC_CTX *, uint32_t, void **);
+enum mapistore_error mapistore_backend_message_create_attachment(struct backend_context *, void *, TALLOC_CTX *, void **, uint32_t *);
+enum mapistore_error mapistore_backend_message_attachment_open_embedded_message(struct backend_context *, void *, TALLOC_CTX *, void **, uint64_t *, struct mapistore_message **msg);
+
+enum mapistore_error mapistore_backend_table_get_available_properties(struct backend_context *, void *, TALLOC_CTX *, struct SPropTagArray **);
+enum mapistore_error mapistore_backend_table_set_columns(struct backend_context *, void *, uint16_t, enum MAPITAGS *);
+enum mapistore_error mapistore_backend_table_set_restrictions(struct backend_context *, void *, struct mapi_SRestriction *, uint8_t *);
+enum mapistore_error mapistore_backend_table_set_sort_order(struct backend_context *, void *, struct SSortOrderSet *, uint8_t *);
+enum mapistore_error mapistore_backend_table_get_row(struct backend_context *, void *, TALLOC_CTX *, enum mapistore_query_type, uint32_t, struct mapistore_property_data **);
+enum mapistore_error mapistore_backend_table_get_row_count(struct backend_context *, void *, enum mapistore_query_type, uint32_t *);
+enum mapistore_error mapistore_backend_table_handle_destructor(struct backend_context *, void *, uint32_t);
+
+enum mapistore_error mapistore_backend_properties_get_available_properties(struct backend_context *, void *, TALLOC_CTX *, struct SPropTagArray **);
+enum mapistore_error mapistore_backend_properties_get_properties(struct backend_context *, void *, TALLOC_CTX *, uint16_t, enum MAPITAGS *, struct mapistore_property_data *);
+enum mapistore_error mapistore_backend_properties_set_properties(struct backend_context *, void *, struct SRow *);
+
+enum mapistore_error mapistore_backend_manager_generate_uri(struct backend_context *, TALLOC_CTX *, const char *, const char *, const char *, const char *, char **);
 
 /* definitions from mapistore_tdb_wrap.c */
 struct tdb_wrap *tdb_wrap_open(TALLOC_CTX *, const char *, int, int, int, mode_t);
@@ -218,16 +220,16 @@ struct ldb_context *mapistore_ldb_wrap_connect(TALLOC_CTX *, struct tevent_conte
 
 /* definitions from mapistore_indexing.c */
 struct indexing_context_list *mapistore_indexing_search(struct mapistore_context *, const char *);
-int mapistore_indexing_add(struct mapistore_context *, const char *, struct indexing_context_list **);
-int mapistore_indexing_search_existing_fmid(struct indexing_context_list *, uint64_t, bool *);
-int mapistore_indexing_record_add(TALLOC_CTX *, struct indexing_context_list *, uint64_t, const char *);
-int mapistore_indexing_record_add_fmid(struct mapistore_context *, uint32_t, const char *, uint64_t);
-int mapistore_indexing_record_del_fmid(struct mapistore_context *, uint32_t, const char *, uint64_t, uint8_t);
-int mapistore_indexing_add_ref_count(struct indexing_context_list *);
-int mapistore_indexing_del_ref_count(struct indexing_context_list *);
+enum mapistore_error mapistore_indexing_add(struct mapistore_context *, const char *, struct indexing_context_list **);
+enum mapistore_error mapistore_indexing_search_existing_fmid(struct indexing_context_list *, uint64_t, bool *);
+enum mapistore_error mapistore_indexing_record_add(TALLOC_CTX *, struct indexing_context_list *, uint64_t, const char *);
+enum mapistore_error mapistore_indexing_record_add_fmid(struct mapistore_context *, uint32_t, const char *, uint64_t);
+enum mapistore_error mapistore_indexing_record_del_fmid(struct mapistore_context *, uint32_t, const char *, uint64_t, uint8_t);
+// enum mapistore_error mapistore_indexing_add_ref_count(struct indexing_context_list *);
+// enum mapistore_error mapistore_indexing_del_ref_count(struct indexing_context_list *);
 
 /* definitions from mapistore_namedprops.c */
-int mapistore_namedprops_init(TALLOC_CTX *, struct ldb_context **);
+enum mapistore_error mapistore_namedprops_init(TALLOC_CTX *, struct ldb_context **);
 
 __END_DECLS
 
index 2b634b9de750c1521b0341c60932f9bb95c7f50b..6242379df8fc365f836f6a5c87bbf3129d6c2eef 100644 (file)
@@ -47,7 +47,7 @@ char *mapping_path = NULL;
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-_PUBLIC_ int mapistore_set_mapping_path(const char *path)
+_PUBLIC_ enum mapistore_error mapistore_set_mapping_path(const char *path)
 {
        TALLOC_CTX      *mem_ctx;
        DIR             *dir;
@@ -93,7 +93,7 @@ _PUBLIC_ int mapistore_set_mapping_path(const char *path)
  */
 const char *mapistore_get_mapping_path(void)
 {
-       return (!mapping_path) ? MAPISTORE_MAPPING_PATH : (const char *)mapping_path;
+       return (const char *)mapping_path;
 }
 
 
@@ -105,7 +105,7 @@ const char *mapistore_get_mapping_path(void)
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-int mapistore_init_mapping_context(struct processing_context *pctx)
+enum mapistore_error mapistore_init_mapping_context(struct processing_context *pctx)
 {
        TDB_DATA        key;
        TDB_DATA        dbuf;
@@ -196,7 +196,7 @@ int mapistore_init_mapping_context(struct processing_context *pctx)
 
    \return a non zero context identifier on success, otherwise 0.
  */
-int mapistore_get_context_id(struct processing_context *pctx, uint32_t *context_id)
+enum mapistore_error mapistore_get_context_id(struct processing_context *pctx, uint32_t *context_id)
 {
        struct context_id_list  *el;
 
@@ -230,7 +230,7 @@ int mapistore_get_context_id(struct processing_context *pctx, uint32_t *context_
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-int mapistore_free_context_id(struct processing_context *pctx, uint32_t context_id)
+enum mapistore_error mapistore_free_context_id(struct processing_context *pctx, uint32_t context_id)
 {
        struct context_id_list  *el;
 
index 4a6a61d6ed3a9777a188b3f0b5be149a07ff9cdf..6a07d69a2dd8177af3a556380b3f60afb544d912 100644 (file)
@@ -72,16 +72,14 @@ static struct replica_mapping_context_list *mapistore_replica_mapping_search(str
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
 
-static int context_list_destructor(void *object)
+static int context_list_destructor(struct replica_mapping_context_list *rmctx)
 {
-       struct replica_mapping_context_list     *rmctx = object;
-
        tdb_close(rmctx->tdb);
 
        return 1;
 }
 
-_PUBLIC_ int mapistore_replica_mapping_add(struct mapistore_context *mstore_ctx, const char *username, struct replica_mapping_context_list **rmctxp)
+_PUBLIC_ enum mapistore_error mapistore_replica_mapping_add(struct mapistore_context *mstore_ctx, const char *username, struct replica_mapping_context_list **rmctxp)
 {
        TALLOC_CTX                              *mem_ctx;
        struct replica_mapping_context_list     *rmctx;
@@ -122,7 +120,7 @@ _PUBLIC_ int mapistore_replica_mapping_add(struct mapistore_context *mstore_ctx,
        return MAPISTORE_SUCCESS;
 }
 
-/* _PUBLIC_ int mapistore_replica_mapping_add(struct mapistore_context *mstore_ctx, const char *username) */
+/* _PUBLIC_ enum mapistore_error mapistore_replica_mapping_add(struct mapistore_context *mstore_ctx, const char *username) */
 /* { */
 /*     TALLOC_CTX                      *mem_ctx; */
 /*     char                            *dbpath = NULL; */
@@ -220,7 +218,7 @@ static void mapistore_replica_mapping_add_pair(struct tdb_context *tdb, const st
        talloc_free(mem_ctx);
 }
 
-static int mapistore_replica_mapping_search_guid(struct tdb_context *tdb, const struct GUID *guidP, uint16_t *replidP)
+static enum mapistore_error mapistore_replica_mapping_search_guid(struct tdb_context *tdb, const struct GUID *guidP, uint16_t *replidP)
 {
        TDB_DATA        guid_key;
        TDB_DATA        replid_key;
@@ -255,7 +253,7 @@ static int mapistore_replica_mapping_search_guid(struct tdb_context *tdb, const
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-_PUBLIC_ int mapistore_replica_mapping_guid_to_replid(struct mapistore_context *mstore_ctx, const char *username, const struct GUID *guidP, uint16_t *replidP)
+_PUBLIC_ enum mapistore_error mapistore_replica_mapping_guid_to_replid(struct mapistore_context *mstore_ctx, const char *username, const struct GUID *guidP, uint16_t *replidP)
 {
        int             ret;
        uint16_t        new_replid;
@@ -293,7 +291,7 @@ _PUBLIC_ int mapistore_replica_mapping_guid_to_replid(struct mapistore_context *
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-_PUBLIC_ int mapistore_replica_mapping_replid_to_guid(struct mapistore_context *mstore_ctx, const char *username, uint16_t replid, struct GUID *guidP)
+_PUBLIC_ enum mapistore_error mapistore_replica_mapping_replid_to_guid(struct mapistore_context *mstore_ctx, const char *username, uint16_t replid, struct GUID *guidP)
 {
        void                                    *mem_ctx;
        TDB_DATA                                guid_key, replid_key;
index c33115fc60a1df347140fe1e1e2574727675e0e4..d07742742200d8ec838a3ed64699a41d9dc58cbb 100644 (file)
@@ -201,7 +201,7 @@ _PUBLIC_ struct mapistore_mgmt_context *mapistore_mgmt_init(struct mapistore_con
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-_PUBLIC_ int mapistore_mgmt_release(struct mapistore_mgmt_context *mgmt_ctx)
+_PUBLIC_ enum mapistore_error mapistore_mgmt_release(struct mapistore_mgmt_context *mgmt_ctx)
 {
        /* Sanity checks */
        MAPISTORE_RETVAL_IF(!mgmt_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
@@ -230,7 +230,7 @@ _PUBLIC_ int mapistore_mgmt_release(struct mapistore_mgmt_context *mgmt_ctx)
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-_PUBLIC_ int mapistore_mgmt_set_verbosity(struct mapistore_mgmt_context *mgmt_ctx, bool verbose)
+_PUBLIC_ enum mapistore_error mapistore_mgmt_set_verbosity(struct mapistore_mgmt_context *mgmt_ctx, bool verbose)
 {
        /* Sanity checks */
        MAPISTORE_RETVAL_IF(!mgmt_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
@@ -247,7 +247,7 @@ _PUBLIC_ int mapistore_mgmt_set_verbosity(struct mapistore_mgmt_context *mgmt_ct
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-_PUBLIC_ int mapistore_mgmt_registered_backend(struct mapistore_mgmt_context *mgmt_ctx, const char *backend)
+_PUBLIC_ enum mapistore_error mapistore_mgmt_registered_backend(struct mapistore_mgmt_context *mgmt_ctx, const char *backend)
 {
        /* Sanity checks */
        MAPISTORE_RETVAL_IF(backend == NULL, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
@@ -361,9 +361,9 @@ _PUBLIC_ struct mapistore_mgmt_users_list *mapistore_mgmt_registered_users(struc
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-_PUBLIC_ int mapistore_mgmt_backend_register_user(struct mapistore_connection_info *conn_info,
-                                                 const char *backend,
-                                                 const char *vuser)
+_PUBLIC_ enum mapistore_error mapistore_mgmt_backend_register_user(struct mapistore_connection_info *conn_info,
+                                                                  const char *backend,
+                                                                  const char *vuser)
 {
        return mgmt_user_registration_cmd(MAPISTORE_MGMT_REGISTER, 
                                          MAPISTORE_COMMAND_USER_REGISTER_PRIO, 
@@ -381,9 +381,9 @@ _PUBLIC_ int mapistore_mgmt_backend_register_user(struct mapistore_connection_in
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-_PUBLIC_ int mapistore_mgmt_backend_unregister_user(struct mapistore_connection_info *conn_info,
-                                                   const char *backend,
-                                                   const char *vuser)
+_PUBLIC_ enum mapistore_error mapistore_mgmt_backend_unregister_user(struct mapistore_connection_info *conn_info,
+                                                                    const char *backend,
+                                                                    const char *vuser)
 {
        return mgmt_user_registration_cmd(MAPISTORE_MGMT_UNREGISTER,
                                          MAPISTORE_COMMAND_USER_UNREGISTER_PRIO, 
@@ -410,10 +410,10 @@ _PUBLIC_ int mapistore_mgmt_backend_unregister_user(struct mapistore_connection_
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-_PUBLIC_ int mapistore_mgmt_generate_uri(struct mapistore_mgmt_context *mgmt_ctx,
-                                        const char *backend, const char *username,
-                                        const char *folder, const char *message,
-                                        const char *rootURI, char **uri)
+_PUBLIC_ enum mapistore_error mapistore_mgmt_generate_uri(struct mapistore_mgmt_context *mgmt_ctx,
+                                                         const char *backend, const char *username,
+                                                         const char *folder, const char *message,
+                                                         const char *rootURI, char **uri)
 {
        struct backend_context *backend_ctx;
 
@@ -452,10 +452,10 @@ _PUBLIC_ int mapistore_mgmt_generate_uri(struct mapistore_mgmt_context *mgmt_ctx
 
    \return true if the message is registered, otherwise false
  */
-_PUBLIC_ int mapistore_mgmt_registered_message(struct mapistore_mgmt_context *mgmt_ctx,
-                                              const char *backend, const char *sysuser,
-                                              const char *username, const char *folder, 
-                                              const char *rootURI, const char *message)
+_PUBLIC_ enum mapistore_error mapistore_mgmt_registered_message(struct mapistore_mgmt_context *mgmt_ctx,
+                                                               const char *backend, const char *sysuser,
+                                                               const char *username, const char *folder, 
+                                                               const char *rootURI, const char *message)
 {
        struct indexing_context_list    *ictxp;
        char                            *uri;
@@ -504,13 +504,13 @@ _PUBLIC_ int mapistore_mgmt_registered_message(struct mapistore_mgmt_context *mg
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-_PUBLIC_ int mapistore_mgmt_register_message(struct mapistore_mgmt_context *mgmt_ctx,
-                                            const char *backend,
-                                            const char *sysuser,
-                                            uint64_t mid,
-                                            const char *rootURI,
-                                            const char *messageID,
-                                            char **registered_uri)
+_PUBLIC_ enum mapistore_error mapistore_mgmt_register_message(struct mapistore_mgmt_context *mgmt_ctx,
+                                                             const char *backend,
+                                                             const char *sysuser,
+                                                             uint64_t mid,
+                                                             const char *rootURI,
+                                                             const char *messageID,
+                                                             char **registered_uri)
 {
        struct indexing_context_list    *ictxp;
        int                             ret;
@@ -542,9 +542,9 @@ _PUBLIC_ int mapistore_mgmt_register_message(struct mapistore_mgmt_context *mgmt
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-_PUBLIC_ int mapistore_mgmt_registered_folder_subscription(struct mapistore_mgmt_context *mgmt_ctx,
-                                                          const char *username, const char *folderURI,
-                                                          uint16_t NotificationFlags)
+_PUBLIC_ enum mapistore_error mapistore_mgmt_registered_folder_subscription(struct mapistore_mgmt_context *mgmt_ctx,
+                                                                           const char *username, const char *folderURI,
+                                                                           uint16_t NotificationFlags)
 {
        struct mapistore_mgmt_users     *uel;
        struct mapistore_mgmt_notif     *el;
@@ -617,6 +617,8 @@ static int mgmt_notification_registration_cmd(enum mapistore_mgmt_status status,
        MAPISTORE_RETVAL_IF(notification->WholeStore == false && !notification->MAPIStoreURI,
                            MAPISTORE_ERR_INVALID_PARAMETER, NULL);
 
+       /* TotalNumberOfMessages and UnreadNumberOfMessages are not initialized here, triggering a warning in valgrind */
+       memset(&cmd, 0, sizeof(struct mapistore_mgmt_command));
        cmd.type = MAPISTORE_MGMT_NOTIF;
        cmd.command.notification.status = status;
        printf("NotificationFlags = 0x%x\n", notification->NotificationFlags);
@@ -660,8 +662,8 @@ static int mgmt_notification_registration_cmd(enum mapistore_mgmt_status status,
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-_PUBLIC_ int mapistore_mgmt_interface_register_subscription(struct mapistore_connection_info *conn_info,
-                                                           struct mapistore_mgmt_notif *notification)
+_PUBLIC_ enum mapistore_error mapistore_mgmt_interface_register_subscription(struct mapistore_connection_info *conn_info,
+                                                                            struct mapistore_mgmt_notif *notification)
 {
        return mgmt_notification_registration_cmd(MAPISTORE_MGMT_REGISTER,
                                                  MAPISTORE_COMMAND_NOTIF_REGISTER_PRIO,
@@ -676,8 +678,8 @@ _PUBLIC_ int mapistore_mgmt_interface_register_subscription(struct mapistore_con
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-_PUBLIC_ int mapistore_mgmt_interface_unregister_subscription(struct mapistore_connection_info *conn_info,
-                                                             struct mapistore_mgmt_notif *notification)
+_PUBLIC_ enum mapistore_error mapistore_mgmt_interface_unregister_subscription(struct mapistore_connection_info *conn_info,
+                                                                              struct mapistore_mgmt_notif *notification)
 {
        return mgmt_notification_registration_cmd(MAPISTORE_MGMT_UNREGISTER,
                                                  MAPISTORE_COMMAND_NOTIF_UNREGISTER_PRIO,
@@ -685,11 +687,11 @@ _PUBLIC_ int mapistore_mgmt_interface_unregister_subscription(struct mapistore_c
 }
 
 
-static int mgmt_bind_registration_command(enum mapistore_mgmt_status status,
-                                         unsigned msg_prio,
-                                         struct mapistore_connection_info *conn_info,
-                                         uint16_t cbContext, uint8_t *rgbContext,
-                                         uint16_t cbCallbackAddress, uint8_t *rgbCallbackAddress)
+static enum mapistore_error mgmt_bind_registration_command(enum mapistore_mgmt_status status,
+                                                          unsigned msg_prio,
+                                                          struct mapistore_connection_info *conn_info,
+                                                          uint16_t cbContext, uint8_t *rgbContext,
+                                                          uint16_t cbCallbackAddress, uint8_t *rgbCallbackAddress)
 {
        int                             ret;
        TALLOC_CTX                      *mem_ctx;
@@ -744,9 +746,9 @@ static int mgmt_bind_registration_command(enum mapistore_mgmt_status status,
 
    \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
  */
-_PUBLIC_ int mapistore_mgmt_interface_register_bind(struct mapistore_connection_info *conn_info,
-                                                   uint16_t cbContext, uint8_t *rgbContext,
-                                                   uint16_t cbCallbackAddress, uint8_t *rgbCallbackAddress)
+_PUBLIC_ enum mapistore_error mapistore_mgmt_interface_register_bind(struct mapistore_connection_info *conn_info,
+                                                                    uint16_t cbContext, uint8_t *rgbContext,
+                                                                    uint16_t cbCallbackAddress, uint8_t *rgbCallbackAddress)
 {
        return mgmt_bind_registration_command(MAPISTORE_MGMT_REGISTER,
                                              MAPISTORE_COMMAND_NOTIF_SOCKET_REGISTER_PRIO, 
index 39c1372c822a3a5886965a7a0635615de815b5c4..fd458ab23be6c77bff9d1d8d792065417191ffd2 100644 (file)
@@ -90,25 +90,25 @@ __BEGIN_DECLS
 
 /* definitions from mapistore_mgmt.c */
 struct mapistore_mgmt_context *mapistore_mgmt_init(struct mapistore_context *);
-int mapistore_mgmt_release(struct mapistore_mgmt_context *);
-int mapistore_mgmt_registered_backend(struct mapistore_mgmt_context *, const char *);
+enum mapistore_error mapistore_mgmt_release(struct mapistore_mgmt_context *);
+enum mapistore_error mapistore_mgmt_registered_backend(struct mapistore_mgmt_context *, const char *);
 struct mapistore_mgmt_users_list *mapistore_mgmt_existing_users(struct mapistore_mgmt_context *, void *, const char *, const char *, const char *);
 struct mapistore_mgmt_users_list *mapistore_mgmt_registered_users(struct mapistore_mgmt_context *, const char *, const char *);
-int mapistore_mgmt_set_verbosity(struct mapistore_mgmt_context *, bool);
+enum mapistore_error mapistore_mgmt_set_verbosity(struct mapistore_mgmt_context *, bool);
 
-int mapistore_mgmt_generate_uri(struct mapistore_mgmt_context *, const char *, const char *, const char *, const char *, const char *, char **);
-int mapistore_mgmt_registered_message(struct mapistore_mgmt_context *, const char *, const char *, const char *,const char *, const char *, const char *);
-int mapistore_mgmt_register_message(struct mapistore_mgmt_context *, const char *, const char *, uint64_t, const char *, const char *, char **);
-int mapistore_mgmt_registered_folder_subscription(struct mapistore_mgmt_context *, const char *, const char *, uint16_t);
+enum mapistore_error mapistore_mgmt_generate_uri(struct mapistore_mgmt_context *, const char *, const char *, const char *, const char *, const char *, char **);
+enum mapistore_error mapistore_mgmt_registered_message(struct mapistore_mgmt_context *, const char *, const char *, const char *,const char *, const char *, const char *);
+enum mapistore_error mapistore_mgmt_register_message(struct mapistore_mgmt_context *, const char *, const char *, uint64_t, const char *, const char *, char **);
+enum mapistore_error mapistore_mgmt_registered_folder_subscription(struct mapistore_mgmt_context *, const char *, const char *, uint16_t);
 
 /* definitions from mapistore_mgmt_messages.c */
-int mapistore_mgmt_message_user_command(struct mapistore_mgmt_context *, struct mapistore_mgmt_user_cmd);
-int mapistore_mgmt_message_notification_command(struct mapistore_mgmt_context *, struct mapistore_mgmt_notification_cmd);
-int mapistore_mgmt_message_bind_command(struct mapistore_mgmt_context *, struct mapistore_mgmt_bind_cmd);
+enum mapistore_error mapistore_mgmt_message_user_command(struct mapistore_mgmt_context *, struct mapistore_mgmt_user_cmd);
+enum mapistore_error mapistore_mgmt_message_notification_command(struct mapistore_mgmt_context *, struct mapistore_mgmt_notification_cmd);
+enum mapistore_error mapistore_mgmt_message_bind_command(struct mapistore_mgmt_context *, struct mapistore_mgmt_bind_cmd);
 
 /* definitions from mapistore_mgmt_send.c */
-int mapistore_mgmt_send_newmail_notification(struct mapistore_mgmt_context *, const char *, uint64_t, uint64_t, const char *);
-int mapistore_mgmt_send_udp_notification(struct mapistore_mgmt_context *, const char *);
+enum mapistore_error mapistore_mgmt_send_newmail_notification(struct mapistore_mgmt_context *, const char *, uint64_t, uint64_t, const char *);
+enum mapistore_error mapistore_mgmt_send_udp_notification(struct mapistore_mgmt_context *, const char *);
 
 __END_DECLS
 
index 9fc276a10dc83db07e1e3e0c159354b9bb196cc3..f09df8b5d80b3a9a2521a85ea7a72a9c892005a0 100644 (file)
@@ -31,9 +31,9 @@
 #include "mapiproxy/libmapistore/mgmt/mapistore_mgmt.h"
 #include "mapiproxy/libmapistore/mgmt/gen_ndr/ndr_mapistore_mgmt.h"
 
-static int mapistore_mgmt_message_user_command_add(struct mapistore_mgmt_context *mgmt_ctx,
-                                                  struct mapistore_mgmt_user_cmd user_cmd,
-                                                  bool populated)
+static enum mapistore_error mapistore_mgmt_message_user_command_add(struct mapistore_mgmt_context *mgmt_ctx,
+                                                                   struct mapistore_mgmt_user_cmd user_cmd,
+                                                                   bool populated)
 {
        struct mapistore_mgmt_users     *el;
 
@@ -64,8 +64,8 @@ static int mapistore_mgmt_message_user_command_add(struct mapistore_mgmt_context
        return MAPISTORE_SUCCESS;
 }
 
-int mapistore_mgmt_message_user_command(struct mapistore_mgmt_context *mgmt_ctx,
-                                       struct mapistore_mgmt_user_cmd user_cmd)
+enum mapistore_error mapistore_mgmt_message_user_command(struct mapistore_mgmt_context *mgmt_ctx,
+                                                        struct mapistore_mgmt_user_cmd user_cmd)
 {
        struct mapistore_mgmt_users     *el;
        bool                            found = false;
@@ -152,8 +152,8 @@ int mapistore_mgmt_message_user_command(struct mapistore_mgmt_context *mgmt_ctx,
        return MAPISTORE_SUCCESS;
 }
 
-int mapistore_mgmt_message_bind_command(struct mapistore_mgmt_context *mgmt_ctx,
-                                       struct mapistore_mgmt_bind_cmd bind)
+enum mapistore_error mapistore_mgmt_message_bind_command(struct mapistore_mgmt_context *mgmt_ctx,
+                                                        struct mapistore_mgmt_bind_cmd bind)
 {
        struct mapistore_mgmt_users     *el;
        bool                            found = false;
@@ -186,7 +186,17 @@ int mapistore_mgmt_message_bind_command(struct mapistore_mgmt_context *mgmt_ctx,
                                                             bind.cbCallbackAddress);
                        
                        /* socket / connect calls */
+#ifdef SOCK_NONBLOCK
                        el->notify_ctx->fd = socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_UDP);
+#else /* SOCK_NONBLOCK */
+                       {
+                               int flags;
+                               el->notify_ctx->fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+                               flags = fcntl(el->notify_ctx->fd, F_GETFL, 0);
+                               fcntl(el->notify_ctx->fd, F_SETFL, flags | O_NONBLOCK);
+                       }
+#endif /* SOCK_NONBLOCK */
+
                        if (el->notify_ctx->fd == -1) {
                                perror("socket");
                                talloc_free(el->notify_ctx);
@@ -204,8 +214,8 @@ int mapistore_mgmt_message_bind_command(struct mapistore_mgmt_context *mgmt_ctx,
        return (found == true) ? MAPISTORE_SUCCESS : MAPISTORE_ERR_NOT_FOUND;
 }
 
-static int mapistore_mgmt_message_notification_command_add(struct mapistore_mgmt_users *user_cmd,
-                                                          struct mapistore_mgmt_notification_cmd notif)
+static enum mapistore_error mapistore_mgmt_message_notification_command_add(struct mapistore_mgmt_users *user_cmd,
+                                                                           struct mapistore_mgmt_notification_cmd notif)
 {
        struct mapistore_mgmt_notif     *el;
 
@@ -357,8 +367,8 @@ static bool mapistore_mgmt_message_notification_folder(struct mapistore_mgmt_use
        return true;
 }
 
-int mapistore_mgmt_message_notification_command(struct mapistore_mgmt_context *mgmt_ctx,
-                                               struct mapistore_mgmt_notification_cmd notif)
+enum mapistore_error mapistore_mgmt_message_notification_command(struct mapistore_mgmt_context *mgmt_ctx,
+                                                                struct mapistore_mgmt_notification_cmd notif)
 {
        struct mapistore_mgmt_users     *el;
        bool                            ret;
index f9eed5b8140a92d68e734426a1fa8e8ca3a7c10b..34837f6b4d0129b7f728d0f7fa159ba461196ee2 100644 (file)
@@ -35,7 +35,7 @@
 #include "mapiproxy/libmapistore/mgmt/mapistore_mgmt.h"
 #include "mapiproxy/libmapistore/mgmt/gen_ndr/ndr_mapistore_mgmt.h"
 
-int mapistore_mgmt_send_udp_notification(struct mapistore_mgmt_context *mgmt_ctx,
+enum mapistore_error mapistore_mgmt_send_udp_notification(struct mapistore_mgmt_context *mgmt_ctx,
                                         const char *username)
 {
        struct mapistore_mgmt_users     *el;
@@ -77,7 +77,7 @@ int mapistore_mgmt_send_udp_notification(struct mapistore_mgmt_context *mgmt_ctx
 
 /*     \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error. */
 /*  *\/ */
-/* int mapistore_mgmt_send_newmail_notification(struct mapistore_mgmt_context *mgmt_ctx, */
+/* enum mapistore_error mapistore_mgmt_send_newmail_notification(struct mapistore_mgmt_context *mgmt_ctx, */
 /*                                          const char *username, */
 /*                                          uint64_t FolderID, */
 /*                                          uint64_t MessageID, */
@@ -150,7 +150,7 @@ int mapistore_mgmt_send_udp_notification(struct mapistore_mgmt_context *mgmt_ctx
 /* } */
 
 
-static int mapistore_mgmt_push_send(TALLOC_CTX *mem_ctx, mqd_t mqfd, struct mapistore_mgmt_command cmd)
+static enum mapistore_error mapistore_mgmt_push_send(TALLOC_CTX *mem_ctx, mqd_t mqfd, struct mapistore_mgmt_command cmd)
 {
        DATA_BLOB               data;
        enum ndr_err_code       ndr_err;
@@ -185,11 +185,11 @@ static int mapistore_mgmt_push_send(TALLOC_CTX *mem_ctx, mqd_t mqfd, struct mapi
 /**
    \details Send notifications 
  */
-int mapistore_mgmt_send_newmail_notification(struct mapistore_mgmt_context *mgmt_ctx,
-                                            const char *username,
-                                            uint64_t FolderID,
-                                            uint64_t MessageID,
-                                            const char *MAPIStoreURI)
+enum mapistore_error mapistore_mgmt_send_newmail_notification(struct mapistore_mgmt_context *mgmt_ctx,
+                                                             const char *username,
+                                                             uint64_t FolderID,
+                                                             uint64_t MessageID,
+                                                             const char *MAPIStoreURI)
 {
        mqd_t                                   mqfd;
        int                                     ret;
index 383a5a218e9672068613c4fc17eff3789b1acb2b..23394dcd545e0f839ba943bf2d8af2ae6a57c15e 100644 (file)
@@ -82,7 +82,7 @@ int main(int argc, const char *argv[])
                exit (1);
        }
 
-       mstore_ctx = mapistore_init(mem_ctx, NULL);
+       mstore_ctx = mapistore_init(mem_ctx, lp_ctx, NULL);
        if (!mstore_ctx) {
                DEBUG(0, ("%s\n", mapistore_errstr(retval)));
                exit (1);
index fc304b2641310e3c2b717a5eb2ff5d8b2b4fad4a..b32572d351269a901499589437356091c96ac502 100644 (file)
@@ -744,11 +744,11 @@ static NTSTATUS cache_push_ReadStream(struct dcesrv_call_state *dce_call,
        struct mpm_stream       *stream;
        struct mapi_response    *mapi_response;
        struct ReadStream_repl  response;
-       struct ReadStream_req   request;
+       /* struct ReadStream_req        request; */
 
        mapi_response = EcDoRpc->out.mapi_response;
        response = mapi_repl.u.mapi_ReadStream;
-       request = mapi_req.u.mapi_ReadStream;
+       /* request = mapi_req.u.mapi_ReadStream; */
 
        /* Check if the handle is registered */
        for (stream = mpm->streams; stream; stream = stream->next) {
index 5342ddf376edeb746158c2ab052806faab4174cd..43215591a21bd0d5cae0e4d87d1ef387fc8a2337 100644 (file)
@@ -300,7 +300,7 @@ static bool emsmdbp_fill_notification(TALLOC_CTX *mem_ctx,
        enum MAPISTATUS         retval;
         void                    **data_pointers;
         DATA_BLOB               *table_row;
-        uint32_t                *retvals;
+        enum MAPISTATUS                *retvals;
         uint32_t                contextID, saved_prop_count, prev_instance;
         enum MAPITAGS           *saved_properties, *previous_row_properties;
         uint64_t                prev_fid, prev_mid;
@@ -1251,7 +1251,7 @@ notif:
                        DEBUG(0, ("subscription: mqueue name = %s\n", sel->subscription->mqueue_name));
                }
                retval = mapistore_get_queued_notifications(emsmdbp_ctx->mstore_ctx, sel->subscription, &nlist);
-               if (retval == MAPISTORE_SUCCESS) {
+               if (retval == MAPI_E_SUCCESS) {
                        for (el = nlist; el->notification; el = el->next) {
                                if (needs_realloc) {
                                        mapi_response->mapi_repl = talloc_realloc(mem_ctx, mapi_response->mapi_repl, 
@@ -1819,6 +1819,7 @@ static enum MAPISTATUS dcesrv_EcDoAsyncConnectEx(struct dcesrv_call_state *dce_c
                                                 struct EcDoAsyncConnectEx *r)
 {
        DEBUG(3, ("exchange_emsmdb: EcDoAsyncConnectEx (0xe) not implemented\n"));
+       r->out.result = ecRejected;
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
 
        return MAPI_E_SUCCESS;
@@ -1841,7 +1842,6 @@ static NTSTATUS dcesrv_exchange_emsmdb_dispatch(struct dcesrv_call_state *dce_ca
                                                TALLOC_CTX *mem_ctx,
                                                void *r, struct mapiproxy *mapiproxy)
 {
-       enum MAPISTATUS                         retval;
        const struct ndr_interface_table        *table;
        uint16_t                                opnum;
 
@@ -1854,22 +1854,22 @@ static NTSTATUS dcesrv_exchange_emsmdb_dispatch(struct dcesrv_call_state *dce_ca
 
        switch (opnum) {
        case NDR_ECDOCONNECT:
-               retval = dcesrv_EcDoConnect(dce_call, mem_ctx, (struct EcDoConnect *)r);
+               dcesrv_EcDoConnect(dce_call, mem_ctx, (struct EcDoConnect *)r);
                break;
        case NDR_ECDODISCONNECT:
-               retval = dcesrv_EcDoDisconnect(dce_call, mem_ctx, (struct EcDoDisconnect *)r);
+               dcesrv_EcDoDisconnect(dce_call, mem_ctx, (struct EcDoDisconnect *)r);
                break;
        case NDR_ECDORPC:
-               retval = dcesrv_EcDoRpc(dce_call, mem_ctx, (struct EcDoRpc *)r);
+               dcesrv_EcDoRpc(dce_call, mem_ctx, (struct EcDoRpc *)r);
                break;
        case NDR_ECGETMORERPC:
                dcesrv_EcGetMoreRpc(dce_call, mem_ctx, (struct EcGetMoreRpc *)r);
                break;
        case NDR_ECRREGISTERPUSHNOTIFICATION:
-               retval = dcesrv_EcRRegisterPushNotification(dce_call, mem_ctx, (struct EcRRegisterPushNotification *)r);
+               dcesrv_EcRRegisterPushNotification(dce_call, mem_ctx, (struct EcRRegisterPushNotification *)r);
                break;
        case NDR_ECRUNREGISTERPUSHNOTIFICATION:
-               retval = dcesrv_EcRUnregisterPushNotification(dce_call, mem_ctx, (struct EcRUnregisterPushNotification *)r);
+               dcesrv_EcRUnregisterPushNotification(dce_call, mem_ctx, (struct EcRUnregisterPushNotification *)r);
                break;
        case NDR_ECDUMMYRPC:
                dcesrv_EcDummyRpc(dce_call, mem_ctx, (struct EcDummyRpc *)r);
@@ -1884,10 +1884,10 @@ static NTSTATUS dcesrv_exchange_emsmdb_dispatch(struct dcesrv_call_state *dce_ca
                dcesrv_EcDoRpcExt(dce_call, mem_ctx, (struct EcDoRpcExt *)r);
                break;
        case NDR_ECDOCONNECTEX:
-               retval = dcesrv_EcDoConnectEx(dce_call, mem_ctx, (struct EcDoConnectEx *)r);
+               dcesrv_EcDoConnectEx(dce_call, mem_ctx, (struct EcDoConnectEx *)r);
                break;
        case NDR_ECDORPCEXT2:
-               retval = dcesrv_EcDoRpcExt2(dce_call, mem_ctx, (struct EcDoRpcExt2 *)r);
+               dcesrv_EcDoRpcExt2(dce_call, mem_ctx, (struct EcDoRpcExt2 *)r);
                break;
        case NDR_ECUNKNOWN0XC:
                dcesrv_EcUnknown0xC(dce_call, mem_ctx, (struct EcUnknown0xC *)r);
index c06fafe56dcf84efd7a8985e3a08918ff7172e8b..e0c05209fd9f1eae63039df6f3b41f413a63f6a5 100644 (file)
@@ -127,16 +127,31 @@ struct emsmdbp_object_folder {
        uint64_t                        folderID;
        uint32_t                        contextID; /* requires mapistore_root == true, undefined otherwise */
        bool                            mapistore_root; /* root mapistore container or not */
+       struct SRow                     *postponed_props; /* storage for properties set until PR_CONTAINER_CLASS_UNICODE is set */
 };
 
 struct emsmdbp_object_message {
-       uint64_t                        folderID;
-       uint64_t                        messageID;
-       struct ldb_message              *msg;
+       uint64_t                                                folderID;
+       uint64_t                                                messageID;
+       bool                                                    read_write;
+       struct emsmdbp_object_message_freebusy_properties       *fb_properties;
+};
+
+struct emsmdbp_object_message_freebusy_properties {
+       uint16_t        nbr_months;
+       uint32_t        *months_ranges;
+       struct Binary_r *freebusy_tentative;
+       struct Binary_r *freebusy_busy;
+       struct Binary_r *freebusy_away;
+       struct Binary_r *freebusy_merged;
+       uint32_t        publish_start;
+       uint32_t        publish_end;
+       char            *email_address;
+       struct FILETIME timestamp;
 };
 
 struct emsmdbp_object_table {
-       uint8_t                                 ulType;
+       enum mapistore_table_type               ulType;
        uint32_t                                handle;
        bool                                    restricted;
        uint16_t                                prop_count;
@@ -147,6 +162,7 @@ struct emsmdbp_object_table {
 };
 
 struct emsmdbp_object_stream {
+       bool                            read_write;
        bool                            needs_commit;
        enum MAPITAGS                   property;
        struct emsmdbp_stream           stream;
@@ -223,39 +239,43 @@ struct emsmdbp_object {
 #define        EMSMDB_PCRETRY                  6
 #define        EMSMDB_PCRETRYDELAY             10000
 
-#define        EMSMDBP_MAILBOX_ROOT            0x1
-#define        EMSMDBP_DEFERRED_ACTIONS        0x2
-#define        EMSMDBP_SPOOLER_QUEUE           0x3
-#define        EMSMDBP_TODO_SEARCH             0x4
-#define        EMSMDBP_TOP_INFORMATION_STORE   0x5
-#define        EMSMDBP_INBOX                   0x6
-#define        EMSMDBP_OUTBOX                  0x7
-#define        EMSMDBP_SENT_ITEMS              0x8
-#define        EMSMDBP_DELETED_ITEMS           0x9
-#define        EMSMDBP_COMMON_VIEWS            0xA
-#define        EMSMDBP_SCHEDULE                0xB
-#define        EMSMDBP_SEARCH                  0xC
-#define        EMSMDBP_VIEWS                   0xD
-#define        EMSMDBP_SHORTCUTS               0xE
-
-#define EMSMDBP_PF_ROOT                        0x0
-#define EMSMDBP_PF_IPMSUBTREE          0x1
-#define EMSMDBP_PF_NONIPMSUBTREE       0x2
-#define EMSMDBP_PF_EFORMSREGISTRY      0x3
-#define EMSMDBP_PF_FREEBUSY            0x4
-#define EMSMDBP_PF_OAB                 0x5
-#define EMSMDBP_PF_LOCALEFORMS         0x6
-#define EMSMDBP_PF_LOCALFREEBUSY       0x7
-#define EMSMDBP_PF_LOCALOAB            0x8
-
-
-/* Note: would be nice to keep this compatible with the equivalent list in mapistore.h, maybe remove one of them... */
-#define        EMSMDBP_TABLE_FOLDER_TYPE       0x1
-#define        EMSMDBP_TABLE_MESSAGE_TYPE      0x2
-#define        EMSMDBP_TABLE_FAI_TYPE          0x3
-#define        EMSMDBP_TABLE_RULE_TYPE         0x4
-#define        EMSMDBP_TABLE_ATTACHMENT_TYPE   0x5
-#define        EMSMDBP_TABLE_PERMISSIONS_TYPE  0x6
+enum emsmdbp_mailbox_systemidx {
+       EMSMDBP_MAILBOX_ROOT = 1,
+       EMSMDBP_DEFERRED_ACTION,
+       EMSMDBP_SPOOLER_QUEUE,
+       EMSMDBP_COMMON_VIEWS,
+       EMSMDBP_SCHEDULE,
+       EMSMDBP_SEARCH,
+       EMSMDBP_VIEWS,
+       EMSMDBP_SHORTCUTS,
+       EMSMDBP_TOP_INFORMATION_STORE,
+       EMSMDBP_INBOX,
+       EMSMDBP_OUTBOX,
+       EMSMDBP_SENT_ITEMS,
+       EMSMDBP_DELETED_ITEMS,
+
+       EMSMDBP_MAX_MAILBOX_SYSTEMIDX
+};
+
+enum emsmdbp_pf_systemidx {
+       EMSMDBP_PF_ROOT = 1,
+       EMSMDBP_PF_IPMSUBTREE,
+       EMSMDBP_PF_NONIPMSUBTREE,
+       EMSMDBP_PF_EFORMSREGISTRY,
+       EMSMDBP_PF_FREEBUSY,
+       EMSMDBP_PF_OAB,
+       EMSMDBP_PF_LOCALEFORMS,
+       EMSMDBP_PF_LOCALFREEBUSY,
+       EMSMDBP_PF_LOCALOAB,
+
+       EMSMDBP_MAX_PF_SYSTEMIDX
+};
+
+struct emsmdbp_special_folder {
+       enum mapistore_context_role     role;
+       enum MAPITAGS                   entryid_property;
+       const char                      *name;
+};
 
 __BEGIN_DECLS
 
@@ -284,23 +304,29 @@ char                  *emsmdbp_get_owner(struct emsmdbp_object *object);
 int                  emsmdbp_get_uri_from_fid(TALLOC_CTX *, struct emsmdbp_context *, uint64_t, char **);
 int                  emsmdbp_get_fid_from_uri(struct emsmdbp_context *, const char *, uint64_t *);
 uint32_t             emsmdbp_get_contextID(struct emsmdbp_object *);
+
+/* definitions from emsmdbp_privisioning.c */
+enum MAPISTATUS       emsmdbp_mailbox_provision(struct emsmdbp_context *, const char *);
+enum MAPISTATUS       emsmdbp_mailbox_provision_public_freebusy(struct emsmdbp_context *, const char *);
+
 /* With emsmdbp_object_create_folder and emsmdbp_object_open_folder, the parent object IS the direct parent */
-enum MAPISTATUS       emsmdbp_object_get_fid_by_name(struct emsmdbp_context *, struct emsmdbp_object *, const char *, uint64_t *);
+enum mapistore_error  emsmdbp_object_get_fid_by_name(struct emsmdbp_context *, struct emsmdbp_object *, const char *, uint64_t *);
 enum MAPISTATUS       emsmdbp_object_create_folder(struct emsmdbp_context *, struct emsmdbp_object *, TALLOC_CTX *, uint64_t, struct SRow *, struct emsmdbp_object **);
-struct emsmdbp_object *emsmdbp_object_open_folder(TALLOC_CTX *, struct emsmdbp_context *, struct emsmdbp_object *, uint64_t);
-struct emsmdbp_object *emsmdbp_object_open_folder_by_fid(TALLOC_CTX *, struct emsmdbp_context *, struct emsmdbp_object *, uint64_t);
+enum mapistore_error  emsmdbp_object_open_folder(TALLOC_CTX *, struct emsmdbp_context *, struct emsmdbp_object *, uint64_t, struct emsmdbp_object **);
+enum mapistore_error  emsmdbp_object_open_folder_by_fid(TALLOC_CTX *, struct emsmdbp_context *, struct emsmdbp_object *, uint64_t, struct emsmdbp_object **);
 
 struct emsmdbp_object *emsmdbp_object_init(TALLOC_CTX *, struct emsmdbp_context *, struct emsmdbp_object *parent_object);
 int emsmdbp_object_copy_properties(struct emsmdbp_context *, struct emsmdbp_object *, struct emsmdbp_object *, struct SPropTagArray *, bool);
-struct emsmdbp_object *emsmdbp_object_mailbox_init(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, bool);
+struct emsmdbp_object *emsmdbp_object_mailbox_init(TALLOC_CTX *, struct emsmdbp_context *, const char *, bool);
 struct emsmdbp_object *emsmdbp_object_folder_init(TALLOC_CTX *, struct emsmdbp_context *, uint64_t, struct emsmdbp_object *);
 int emsmdbp_folder_get_folder_count(struct emsmdbp_context *, struct emsmdbp_object *, uint32_t *);
+enum mapistore_error emsmdbp_folder_delete(struct emsmdbp_context *, struct emsmdbp_object *, uint64_t, uint8_t);
 struct emsmdbp_object *emsmdbp_folder_open_table(TALLOC_CTX *, struct emsmdbp_object *, uint32_t, uint32_t);
 struct emsmdbp_object *emsmdbp_object_table_init(TALLOC_CTX *, struct emsmdbp_context *, struct emsmdbp_object *);
 int emsmdbp_object_table_get_available_properties(TALLOC_CTX *, struct emsmdbp_context *, struct emsmdbp_object *, struct SPropTagArray **);
-void **emsmdbp_object_table_get_row_props(TALLOC_CTX *, struct emsmdbp_context *, struct emsmdbp_object *, uint32_t, enum table_query_type, uint32_t **);
+void **emsmdbp_object_table_get_row_props(TALLOC_CTX *, struct emsmdbp_context *, struct emsmdbp_object *, uint32_t, enum mapistore_query_type, enum MAPISTATUS **);
 struct emsmdbp_object *emsmdbp_object_message_init(TALLOC_CTX *, struct emsmdbp_context *, uint64_t, struct emsmdbp_object *);
-struct emsmdbp_object *emsmdbp_object_message_open(TALLOC_CTX *, struct emsmdbp_context *, struct emsmdbp_object *, uint64_t, uint64_t, struct mapistore_message **);
+enum mapistore_error emsmdbp_object_message_open(TALLOC_CTX *, struct emsmdbp_context *, struct emsmdbp_object *, uint64_t, uint64_t, bool, struct emsmdbp_object **, struct mapistore_message **);
 struct emsmdbp_object *emsmdbp_object_message_open_attachment_table(TALLOC_CTX *, struct emsmdbp_context *, struct emsmdbp_object *);
 struct emsmdbp_object *emsmdbp_object_stream_init(TALLOC_CTX *, struct emsmdbp_context *, struct emsmdbp_object *);
 int emsmdbp_object_stream_commit(struct emsmdbp_object *);
@@ -315,7 +341,7 @@ struct emsmdbp_stream_data *emsmdbp_stream_data_from_value(TALLOC_CTX *, enum MA
 struct emsmdbp_stream_data *emsmdbp_object_get_stream_data(struct emsmdbp_object *, enum MAPITAGS);
 DATA_BLOB emsmdbp_stream_read_buffer(struct emsmdbp_stream *, uint32_t);
 void emsmdbp_stream_write_buffer(TALLOC_CTX *, struct emsmdbp_stream *, DATA_BLOB);
-void emsmdbp_fill_table_row_blob(TALLOC_CTX *, struct emsmdbp_context *, DATA_BLOB *, uint16_t, enum MAPITAGS *, void **, uint32_t *);
+void emsmdbp_fill_table_row_blob(TALLOC_CTX *, struct emsmdbp_context *, DATA_BLOB *, uint16_t, enum MAPITAGS *, void **, enum MAPISTATUS *);
 void emsmdbp_fill_row_blob(TALLOC_CTX *, struct emsmdbp_context *, uint8_t *, DATA_BLOB *,struct SPropTagArray *, void **, enum MAPISTATUS *, bool *);
 
 /* definitions from oxcfold.c */
index 964f9a9d2a199c6856cd3d42b323695d317b4f85..09ff8cdceea9b67467b8b3f8bbe4b37ccac2cb06 100644 (file)
@@ -132,7 +132,7 @@ _PUBLIC_ struct emsmdbp_context *emsmdbp_init(struct loadparm_context *lp_ctx,
        emsmdbp_ctx->oc_ctx = ldb_ctx;
 
        /* Initialize the mapistore context */          
-       emsmdbp_ctx->mstore_ctx = mapistore_init(mem_ctx, NULL);
+       emsmdbp_ctx->mstore_ctx = mapistore_init(mem_ctx, lp_ctx, NULL);
        if (!emsmdbp_ctx->mstore_ctx) {
                DEBUG(0, ("[%s:%d]: MAPISTORE initialization failed\n", __FUNCTION__, __LINE__));
 
index 15a0845530b28dfc9c70c83bb73572e4aef4b6c9..abb5cbad237669014759a1a059ec3ba12d62e242 100644 (file)
    \brief Server-side specific objects init/release routines
  */
 
+#include <ctype.h>
+#include <time.h>
+
+#include "mapiproxy/libmapistore/mapistore_nameid.h"
 #include "mapiproxy/dcesrv_mapiproxy.h"
 #include "mapiproxy/libmapiproxy/libmapiproxy.h"
 #include "mapiproxy/libmapiserver/libmapiserver.h"
 
 #include "dcesrv_exchange_emsmdb.h"
 
-/* a private struct used to map array for properties with MV_FLAG set in a type-agnostic way */
-struct DataArray_r {
-       uint32_t cValues;
-       const void *values;
-};
+static const int       max_mins_per_month = 31 * 24 * 60;
 
 const char *emsmdbp_getstr_type(struct emsmdbp_object *object)
 {
@@ -163,14 +163,14 @@ _PUBLIC_ uint32_t emsmdbp_get_contextID(struct emsmdbp_object *object)
        return -1;
 }
 
-_PUBLIC_ enum MAPISTATUS emsmdbp_object_get_fid_by_name(struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *parent_folder, const char *name, uint64_t *fidp)
+_PUBLIC_ enum mapistore_error emsmdbp_object_get_fid_by_name(struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *parent_folder, const char *name, uint64_t *fidp)
 {
        uint64_t        folderID;
 
-       if (!emsmdbp_ctx) return MAPI_E_CALL_FAILED;
-       if (!parent_folder) return MAPI_E_CALL_FAILED;
-       if (!name) return MAPI_E_CALL_FAILED;
-       if (!fidp) return MAPI_E_CALL_FAILED;
+       if (!emsmdbp_ctx) return MAPISTORE_ERROR;
+       if (!parent_folder) return MAPISTORE_ERROR;
+       if (!name) return MAPISTORE_ERROR;
+       if (!fidp) return MAPISTORE_ERROR;
 
        if (parent_folder->type == EMSMDBP_OBJECT_FOLDER) {
                folderID = parent_folder->object.folder->folderID;
@@ -179,49 +179,170 @@ _PUBLIC_ enum MAPISTATUS emsmdbp_object_get_fid_by_name(struct emsmdbp_context *
                folderID = parent_folder->object.mailbox->folderID;
        }
        else {
-               return MAPI_E_CALL_FAILED;
+               return MAPISTORE_ERROR;
        }
 
        if (emsmdbp_is_mapistore(parent_folder)) {
                if (mapistore_folder_get_child_fid_by_name(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(parent_folder), parent_folder->backend_object, name, fidp)) {
-                       return MAPI_E_NOT_FOUND;
+                       return MAPISTORE_ERR_NOT_FOUND;
                }
 
-               return MAPI_E_SUCCESS;
+               return MAPISTORE_SUCCESS;
        }
        else {
                return openchangedb_get_fid_by_name(emsmdbp_ctx->oc_ctx, folderID, name, fidp);
        }
 }
 
+static enum mapistore_context_role emsmdbp_container_class_to_role(const char *container_class)
+{
+       enum mapistore_context_role     i, role = MAPISTORE_FALLBACK_ROLE;
+       static const char               **container_classes = NULL;
+       bool                            found = false;
+
+       if (!container_classes) {
+               container_classes = talloc_array(NULL, const char *, MAPISTORE_MAX_ROLES);
+               for (i = MAPISTORE_MAIL_ROLE; i < MAPISTORE_MAX_ROLES; i++) {
+                       container_classes[i] = "IPF.Note";
+               }
+               container_classes[MAPISTORE_CALENDAR_ROLE] = "IPF.Appointment";
+               container_classes[MAPISTORE_CONTACTS_ROLE] = "IPF.Contact";
+               container_classes[MAPISTORE_TASKS_ROLE] = "IPF.Task";
+               container_classes[MAPISTORE_NOTES_ROLE] = "IPF.StickyNote";
+               container_classes[MAPISTORE_JOURNAL_ROLE] = "IPF.Journal";
+               container_classes[MAPISTORE_FALLBACK_ROLE] = "";
+       }
+
+       if (container_class) {
+               for (i = 0; !found && i < MAPISTORE_MAX_ROLES; i++) {
+                       if (strcmp(container_class, container_classes[i]) == 0) {
+                               role = i;
+                               found = true;
+                       }
+               }
+       }
+
+       return role;
+}
+
+static enum mapistore_error emsmdbp_object_folder_commit_creation(struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *new_folder, bool force_container_class)
+{
+       enum mapistore_error            ret = MAPISTORE_SUCCESS;
+       enum MAPISTATUS                 retval;
+       struct SPropValue               *value;
+       char                            *mapistore_uri, *owner;
+       enum mapistore_context_role     role;
+       TALLOC_CTX                      *mem_ctx;
+       uint64_t                        parent_fid, fid;
+       uint32_t                        context_id;
+
+       if (!new_folder->object.folder->postponed_props) {
+               return ret;
+       }
+
+       mem_ctx = talloc_zero(NULL, TALLOC_CTX);
+
+       value = get_SPropValue_SRow(new_folder->object.folder->postponed_props, PR_CONTAINER_CLASS_UNICODE);
+       if (!value) {
+               /* Sometimes Outlook does pass non-unicode values. */
+               value = get_SPropValue_SRow(new_folder->object.folder->postponed_props, PR_CONTAINER_CLASS);
+       }
+       if (value) {
+               role = emsmdbp_container_class_to_role(value->value.lpszW);
+       }
+       else if (force_container_class) {
+               DEBUG(5, (__location__": forcing folder backend role to 'fallback'\n"));
+               role = MAPISTORE_FALLBACK_ROLE;
+       }
+       else {
+               DEBUG(5, (__location__": container class not set yet\n"));
+               goto end;
+       }
+
+       value = get_SPropValue_SRow(new_folder->object.folder->postponed_props, PR_DISPLAY_NAME_UNICODE);
+       if (!value) {
+               DEBUG(5, (__location__": display name not set yet\n"));
+               goto end;
+       }
+
+       fid = new_folder->object.folder->folderID;
+       owner = emsmdbp_get_owner(new_folder);
+
+       ret = mapistore_create_root_folder(owner, role, fid, value->value.lpszW, mem_ctx, &mapistore_uri);
+       if (ret != MAPISTORE_SUCCESS) {
+               goto end;
+       }
+
+       ret = mapistore_add_context(emsmdbp_ctx->mstore_ctx, owner, mapistore_uri, fid, &context_id, &new_folder->backend_object);
+       if (ret != MAPISTORE_SUCCESS) {
+               abort();
+       }
+
+       new_folder->object.folder->contextID = context_id;
+
+       if (new_folder->parent_object->type == EMSMDBP_OBJECT_MAILBOX) {
+               parent_fid = new_folder->parent_object->object.mailbox->folderID;
+       }
+       else { /* EMSMDBP_OBJECT_FOLDER */
+               parent_fid = new_folder->parent_object->object.folder->folderID;
+       }
+
+       value = get_SPropValue_SRow(new_folder->object.folder->postponed_props, PR_CHANGE_NUM);
+       retval = openchangedb_create_folder(emsmdbp_ctx->oc_ctx, parent_fid, fid, value->value.d, mapistore_uri, -1);
+       if (retval != MAPI_E_SUCCESS) {
+               ret = MAPISTORE_ERR_NOT_FOUND;
+               DEBUG(0, (__location__": openchangedb folder creation failed: 0x%.8x\n", retval));
+               abort();
+       }
+
+       mapistore_indexing_record_add_fid(emsmdbp_ctx->mstore_ctx, context_id, owner, fid);
+       new_folder->object.folder->contextID = context_id;
+
+       openchangedb_set_folder_properties(emsmdbp_ctx->oc_ctx, fid, new_folder->object.folder->postponed_props);
+       mapistore_properties_set_properties(emsmdbp_ctx->mstore_ctx, context_id, new_folder->backend_object, new_folder->object.folder->postponed_props);
+
+       talloc_unlink(new_folder, new_folder->object.folder->postponed_props);
+       new_folder->object.folder->postponed_props = NULL;
+
+       DEBUG(5, ("new mapistore context created at uri: %s\n", mapistore_uri));
+
+end:
+       talloc_free(mem_ctx);
+
+       return ret;
+}
+
 _PUBLIC_ enum MAPISTATUS emsmdbp_object_create_folder(struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *parent_folder, TALLOC_CTX *mem_ctx, uint64_t fid, struct SRow *rowp, struct emsmdbp_object **new_folderp)
 {
-       uint64_t                        parentFolderID;
-       uint64_t                        testFolderID;
-       char                            *MAPIStoreURI;
-       char                            *owner;
+       uint64_t                        parentFolderID, testFolderID;
        struct SPropValue               *value;
-       NTTIME                          nt_time;
        int                             retval;
-       TALLOC_CTX                      *local_mem_ctx;
        struct emsmdbp_object           *new_folder;
-       uint32_t                        contextID;
+       struct SRow                     *postponed_props;
 
        /* Sanity checks */
-       if (!emsmdbp_ctx) return MAPI_E_CALL_FAILED;
-       if (!parent_folder) return MAPI_E_CALL_FAILED;
-       if (!rowp) return MAPI_E_CALL_FAILED;
+       if (!emsmdbp_ctx) return MAPISTORE_ERROR;
+       if (!parent_folder) return MAPISTORE_ERROR;
+       if (!rowp) return MAPISTORE_ERROR;
 
        new_folder = emsmdbp_object_folder_init(mem_ctx, emsmdbp_ctx, fid, parent_folder);
        if (emsmdbp_is_mapistore(parent_folder)) {
                retval = mapistore_folder_create_folder(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(parent_folder), parent_folder->backend_object, new_folder, fid, rowp, &new_folder->backend_object);
-               if (retval == MAPISTORE_ERR_EXIST) {
-                       /* folder with this name already exists */
-                       DEBUG(4, ("emsmdbp_object: CreateFolder Duplicate Folder error\n"));
+               if (retval != MAPISTORE_SUCCESS) {
                        talloc_free(new_folder);
-                       return MAPI_E_COLLISION;
+                       if (retval == MAPISTORE_ERR_EXIST) {
+                               /* folder with this name already exists */
+                               DEBUG(5, (__location__": folder already exists\n"));
+                               return MAPI_E_COLLISION;
+                       }
+                       else if (retval == MAPISTORE_ERR_DENIED) {
+                               DEBUG(5, (__location__": folder creation denied\n"));
+                               return MAPI_E_NO_ACCESS;
+                       }
+                       else {
+                               return MAPI_E_NOT_FOUND;
+                       }
                }
-               OPENCHANGE_RETVAL_IF(retval, MAPI_E_CALL_FAILED, new_folder);
        }
        else {
                parentFolderID = parent_folder->object.folder->folderID;
@@ -241,59 +362,36 @@ _PUBLIC_ enum MAPISTATUS emsmdbp_object_create_folder(struct emsmdbp_context *em
                        return MAPI_E_COLLISION;
                }
 
-               local_mem_ctx = talloc_zero(NULL, void);
-               owner = emsmdbp_get_owner(parent_folder);
-               value = get_SPropValue_SRow(rowp, PR_LAST_MODIFICATION_TIME);
-               if (value) {
-                       nt_time = ((NTTIME) value->value.ft.dwHighDateTime << 32
-                                  | value->value.ft.dwLowDateTime);
-               }
-               else {
-                       unix_to_nt_time(&nt_time, time(NULL));
-               }
                value = get_SPropValue_SRow(rowp, PR_CHANGE_NUM);
                if (value) {
-                       MAPIStoreURI = talloc_asprintf(local_mem_ctx, "sogo://%s:%s@fallback/0x%.16"PRIx64,
-                                                      owner, owner, fid);
-                       retval = openchangedb_create_folder(emsmdbp_ctx->oc_ctx, parentFolderID, fid, 
-                                                           MAPIStoreURI, nt_time, value->value.d);
-                       if (retval != MAPI_E_SUCCESS) {
-                               DEBUG(0, (__location__": openchangedb folder creation failed: 0x%.8x\n", retval));
-                               abort();
-                       }
+                       postponed_props = talloc_zero(new_folder, struct SRow);
+                       postponed_props->cValues = rowp->cValues;
+                       postponed_props->lpProps = talloc_array(postponed_props, struct SPropValue, rowp->cValues);
+                       mapi_copy_spropvalues(postponed_props->lpProps, rowp->lpProps, postponed_props->lpProps, rowp->cValues);
+                       new_folder->object.folder->postponed_props = postponed_props;
+                       new_folder->object.folder->mapistore_root = true;
+
+                       emsmdbp_object_folder_commit_creation(emsmdbp_ctx, new_folder, false);
                }
                else {
                        DEBUG(0, (__location__": PR_CHANGE_NUM *must* be present\n"));
                        abort();
                }
-
-               openchangedb_set_folder_properties(emsmdbp_ctx->oc_ctx, fid, rowp);
-
-               /* Created top folders are always using a mapistore backend */
-               retval = mapistore_add_context(emsmdbp_ctx->mstore_ctx, owner, MAPIStoreURI, 
-                                              new_folder->object.folder->folderID,
-                                              &contextID, &new_folder->backend_object);
-               if (retval != MAPISTORE_SUCCESS) {
-                       abort();
-               }
-               mapistore_indexing_record_add_fid(emsmdbp_ctx->mstore_ctx, contextID, owner, fid);
-               new_folder->object.folder->mapistore_root = true;
-               new_folder->object.folder->contextID = contextID;
-
-               talloc_free(local_mem_ctx);
        }
        *new_folderp = new_folder;
 
        return MAPI_E_SUCCESS;
 }
 
-_PUBLIC_ struct emsmdbp_object *emsmdbp_object_open_folder(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *parent, uint64_t fid)
+_PUBLIC_ enum mapistore_error emsmdbp_object_open_folder(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *parent, uint64_t fid, struct emsmdbp_object **folder_object_p)
 {
-       struct emsmdbp_object                   *folder_object;
-       int                                     retval;
+       struct emsmdbp_object                   *folder_object, *mailbox_object;
+       enum mapistore_error                    retval;
+       enum MAPISTATUS                         ret;
        char                                    *path;
        char                                    *owner;
        uint32_t                                contextID;
+       uint64_t                                parent_fid, oc_parent_fid;
        void                                    *local_ctx;
 
        folder_object = emsmdbp_object_folder_init(mem_ctx, emsmdbp_ctx, fid, parent);
@@ -302,14 +400,14 @@ _PUBLIC_ struct emsmdbp_object *emsmdbp_object_open_folder(TALLOC_CTX *mem_ctx,
                retval = mapistore_folder_open_folder(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(parent), parent->backend_object, folder_object, fid, &folder_object->backend_object);
                if (retval != MAPISTORE_SUCCESS) {
                        talloc_free(folder_object);
-                       folder_object = NULL;
+                       return retval;
                }
        }
        else {
                local_ctx = talloc_zero(NULL, void);
        
                retval = openchangedb_get_mapistoreURI(local_ctx, emsmdbp_ctx->oc_ctx, fid, &path, true);
-               if (retval == MAPI_E_SUCCESS && path) {
+               if (retval == MAPISTORE_SUCCESS && path) {
                        folder_object->object.folder->mapistore_root = true;
                        /* system/special folder */
                        DEBUG(0, ("%s: opening base mapistore folder\n", __FUNCTION__));
@@ -321,7 +419,9 @@ _PUBLIC_ struct emsmdbp_object *emsmdbp_object_open_folder(TALLOC_CTX *mem_ctx,
                                owner = emsmdbp_get_owner(folder_object);
                                retval = mapistore_add_context(emsmdbp_ctx->mstore_ctx, owner, path, folder_object->object.folder->folderID, &contextID, &folder_object->backend_object);
                                if (retval != MAPISTORE_SUCCESS) {
-                                       abort();
+                                       talloc_free(local_ctx);
+                                       talloc_free(folder_object);
+                                       return retval;
                                }
                                mapistore_indexing_record_add_fid(emsmdbp_ctx->mstore_ctx, contextID, owner, fid);
                        }
@@ -329,12 +429,39 @@ _PUBLIC_ struct emsmdbp_object *emsmdbp_object_open_folder(TALLOC_CTX *mem_ctx,
                        (void) talloc_reference(folder_object, folder_object->backend_object);
                }
                else {
+                       switch (parent->type) {
+                       case EMSMDBP_OBJECT_MAILBOX:
+                               parent_fid = parent->object.mailbox->folderID;
+                               break;
+                       case EMSMDBP_OBJECT_FOLDER:
+                               parent_fid = parent->object.folder->folderID;
+                               break;
+                       default:
+                               DEBUG(5, ("you should never get here\n"));
+                               abort();
+                       }
+                       mailbox_object = emsmdbp_get_mailbox(parent);
+                       ret = openchangedb_get_parent_fid(emsmdbp_ctx->oc_ctx, fid, &oc_parent_fid, mailbox_object->object.mailbox->mailboxstore);
+                       if (ret != MAPI_E_SUCCESS) {
+                               DEBUG(0, ("folder %.16"PRIx64" or %.16"PRIx64" does not exist\n", parent_fid, fid));
+                               talloc_free(local_ctx);
+                               talloc_free(folder_object);
+                               return MAPISTORE_ERR_NOT_FOUND;
+                       }
+                       if (oc_parent_fid != parent_fid) {
+                               DEBUG(0, ("parent folder mismatch: expected %.16"PRIx64" but got %.16"PRIx64"\n", parent_fid, oc_parent_fid));
+                               talloc_free(local_ctx);
+                               talloc_free(folder_object);
+                               return MAPISTORE_ERR_NOT_FOUND;
+                       }
                        DEBUG(0, ("%s: opening openchangedb folder\n", __FUNCTION__));
                }
                talloc_free(local_ctx);
        }
 
-       return folder_object;
+       *folder_object_p = folder_object;
+
+       return MAPISTORE_SUCCESS;
 }
 
 _PUBLIC_ int emsmdbp_get_uri_from_fid(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, uint64_t fid, char **urip)
@@ -431,10 +558,7 @@ end:
 
    \return Valid emsmdbp object structure on success, otherwise NULL
  */
-_PUBLIC_ struct emsmdbp_object *emsmdbp_object_open_folder_by_fid(TALLOC_CTX *mem_ctx, 
-                                                                 struct emsmdbp_context *emsmdbp_ctx, 
-                                                                 struct emsmdbp_object *context_object, 
-                                                                 uint64_t fid)
+_PUBLIC_ enum mapistore_error emsmdbp_object_open_folder_by_fid(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *context_object, uint64_t fid, struct emsmdbp_object **folder_object_p)
 {
        uint64_t                parent_fid;
        int                     retval;
@@ -444,23 +568,33 @@ _PUBLIC_ struct emsmdbp_object *emsmdbp_object_open_folder_by_fid(TALLOC_CTX *me
             && fid == context_object->object.mailbox->folderID)
            || (context_object->type == EMSMDBP_OBJECT_FOLDER
                && fid == context_object->object.folder->folderID)) {
-               return context_object;
+               *folder_object_p = context_object;
+               return MAPISTORE_SUCCESS;
+       }
+       else {
+               parent_object = emsmdbp_get_mailbox(context_object);
+               if (fid == parent_object->object.mailbox->folderID) {
+                       *folder_object_p = parent_object;
+                       return MAPISTORE_SUCCESS;
+               }
        }
 
        retval = emsmdbp_get_parent_fid(emsmdbp_ctx, fid, &parent_fid);
        if (retval == MAPISTORE_SUCCESS) {
                if (parent_fid) {
-                       parent_object = emsmdbp_object_open_folder_by_fid(mem_ctx, emsmdbp_ctx, context_object, parent_fid);
-                       if (parent_object) {
-                               return emsmdbp_object_open_folder(mem_ctx, emsmdbp_ctx, parent_object, fid);
+                       retval = emsmdbp_object_open_folder_by_fid(mem_ctx, emsmdbp_ctx, context_object, parent_fid, &parent_object);
+                       if (retval != MAPISTORE_SUCCESS) {
+                               return retval;
                        }
+                       return emsmdbp_object_open_folder(mem_ctx, emsmdbp_ctx, parent_object, fid, folder_object_p);
                }
                else {
-                       return emsmdbp_object_folder_init(mem_ctx, emsmdbp_ctx, fid, NULL);
+                       *folder_object_p = emsmdbp_object_folder_init(mem_ctx, emsmdbp_ctx, fid, NULL);
+                       return MAPISTORE_SUCCESS;
                }
        }
 
-       return NULL;
+       return MAPISTORE_ERROR;
 }
 
 _PUBLIC_ int emsmdbp_object_stream_commit(struct emsmdbp_object *stream_object)
@@ -621,27 +755,27 @@ static int emsmdbp_copy_properties(struct emsmdbp_context *emsmdbp_ctx, struct e
        memset(properties_exclusion, 0, 65536 * sizeof(bool));
 
        /* 1a. Explicit exclusions */
-       properties_exclusion[PR_ROW_TYPE >> 16] = true;
-       properties_exclusion[PR_INSTANCE_KEY >> 16] = true;
-       properties_exclusion[PR_INSTANCE_NUM >> 16] = true;
-       properties_exclusion[PR_INST_ID >> 16] = true;
-       properties_exclusion[PR_FID >> 16] = true;
-       properties_exclusion[PR_MID >> 16] = true;
-       properties_exclusion[PR_SOURCE_KEY >> 16] = true;
-       properties_exclusion[PR_PARENT_SOURCE_KEY >> 16] = true;
-       properties_exclusion[PR_PARENT_FID >> 16] = true;
+       properties_exclusion[(uint16_t) (PR_ROW_TYPE >> 16)] = true;
+       properties_exclusion[(uint16_t) (PR_INSTANCE_KEY >> 16)] = true;
+       properties_exclusion[(uint16_t) (PR_INSTANCE_NUM >> 16)] = true;
+       properties_exclusion[(uint16_t) (PR_INST_ID >> 16)] = true;
+       properties_exclusion[(uint16_t) (PR_FID >> 16)] = true;
+       properties_exclusion[(uint16_t) (PR_MID >> 16)] = true;
+       properties_exclusion[(uint16_t) (PR_SOURCE_KEY >> 16)] = true;
+       properties_exclusion[(uint16_t) (PR_PARENT_SOURCE_KEY >> 16)] = true;
+       properties_exclusion[(uint16_t) (PR_PARENT_FID >> 16)] = true;
 
        /* 1b. Request exclusions */
        if (excluded_tags != NULL) {
                for (i = 0; i < excluded_tags->cValues; i++) {
-                       properties_exclusion[excluded_tags->aulPropTag[i] >> 16] = true;
+                       properties_exclusion[(uint16_t) (excluded_tags->aulPropTag[i] >> 16)] = true;
                }
        }
 
        needed_properties = talloc_zero(mem_ctx, struct SPropTagArray);
        needed_properties->aulPropTag = talloc_zero(needed_properties, void);
        for (i = 0; i < properties->cValues; i++) {
-               if (!properties_exclusion[properties->aulPropTag[i] >> 16]) {
+               if (!properties_exclusion[(uint16_t) (properties->aulPropTag[i] >> 16)]) {
                        SPropTagArray_add(mem_ctx, needed_properties, properties->aulPropTag[i]);
                }
        }
@@ -754,7 +888,8 @@ static inline int emsmdbp_copy_message_attachments_mapistore(struct emsmdbp_cont
        TALLOC_CTX              *mem_ctx;
        uint32_t                i, count, contextID, dest_num;
        void                    **data_pointers;
-       uint32_t                *retvals, *attach_nums;
+       enum MAPISTATUS         *retvals;
+       uint32_t                *attach_nums;
        struct emsmdbp_object   *table_object, *source_attach, *dest_attach;
        enum MAPITAGS           column;
        int                     ret;
@@ -786,12 +921,12 @@ static inline int emsmdbp_copy_message_attachments_mapistore(struct emsmdbp_cont
                data_pointers = emsmdbp_object_table_get_row_props(mem_ctx, emsmdbp_ctx, table_object, i, MAPISTORE_PREFILTERED_QUERY, &retvals);
                if (!data_pointers) {
                        talloc_free(mem_ctx);
-                       return MAPI_E_CALL_FAILED;
+                       return MAPISTORE_ERROR;
                }
-               if (retvals[0] != MAPISTORE_SUCCESS) {
+               if (retvals[0] != MAPI_E_SUCCESS) {
                        talloc_free(mem_ctx);
                        DEBUG(5, ("cannot copy attachments without PR_ATTACH_NUM\n"));
-                       return MAPI_E_CALL_FAILED;
+                       return MAPISTORE_ERROR;
                }
                attach_nums[i] = *(uint32_t *) data_pointers[0];
        }
@@ -802,14 +937,14 @@ static inline int emsmdbp_copy_message_attachments_mapistore(struct emsmdbp_cont
                if (!source_attach
                    || mapistore_message_open_attachment(emsmdbp_ctx->mstore_ctx, contextID, source_object->backend_object, source_attach, attach_nums[i], &source_attach->backend_object)) {
                        talloc_free(mem_ctx);
-                       return MAPI_E_CALL_FAILED;
+                       return MAPISTORE_ERROR;
                }
 
                dest_attach = emsmdbp_object_attachment_init(mem_ctx, emsmdbp_ctx, dest_object->object.message->messageID, dest_object);
                if (!dest_attach
                    || mapistore_message_create_attachment(emsmdbp_ctx->mstore_ctx, contextID, dest_object->backend_object, dest_attach, &dest_attach->backend_object, &dest_num)) {
                        talloc_free(mem_ctx);
-                       return MAPI_E_CALL_FAILED;
+                       return MAPISTORE_ERROR;
                }
 
                ret = emsmdbp_copy_properties(emsmdbp_ctx, source_attach, dest_attach, NULL);
@@ -902,7 +1037,7 @@ end:
  */
 _PUBLIC_ struct emsmdbp_object *emsmdbp_object_mailbox_init(TALLOC_CTX *mem_ctx,
                                                            struct emsmdbp_context *emsmdbp_ctx,
-                                                           struct EcDoRpc_MAPI_REQ *request,
+                                                           const char *essDN,
                                                            bool mailboxstore)
 {
        struct emsmdbp_object           *object;
@@ -913,7 +1048,7 @@ _PUBLIC_ struct emsmdbp_object *emsmdbp_object_mailbox_init(TALLOC_CTX *mem_ctx,
 
        /* Sanity checks */
        if (!emsmdbp_ctx) return NULL;
-       if (!request) return NULL;
+       if (!essDN) return NULL;
 
        object = emsmdbp_object_init(mem_ctx, emsmdbp_ctx, NULL);
        if (!object) return NULL;
@@ -933,8 +1068,7 @@ _PUBLIC_ struct emsmdbp_object *emsmdbp_object_mailbox_init(TALLOC_CTX *mem_ctx,
        object->object.mailbox->mailboxstore = mailboxstore;
 
        if (mailboxstore == true) {
-               object->object.mailbox->owner_EssDN = talloc_strdup(object->object.mailbox, 
-                                                                   request->u.mapi_Logon.EssDN);
+               object->object.mailbox->owner_EssDN = talloc_strdup(object->object.mailbox, essDN);
                ret = ldb_search(emsmdbp_ctx->samdb_ctx, mem_ctx, &res,
                                 ldb_get_default_basedn(emsmdbp_ctx->samdb_ctx),
                                 LDB_SCOPE_SUBTREE, recipient_attrs, "legacyExchangeDN=%s", 
@@ -956,7 +1090,7 @@ _PUBLIC_ struct emsmdbp_object *emsmdbp_object_mailbox_init(TALLOC_CTX *mem_ctx,
                }
        } else {
                /* Retrieve Public folder identifier */
-               openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, 0x1, &object->object.mailbox->folderID);
+               openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, EMSMDBP_PF_ROOT, &object->object.mailbox->folderID);
        }
 
        object->object.mailbox->szUserDN = talloc_strdup(object->object.mailbox, emsmdbp_ctx->szUserDN);
@@ -1010,8 +1144,8 @@ int emsmdbp_folder_get_folder_count(struct emsmdbp_context *emsmdbp_ctx, struct
        uint64_t        folderID;
 
        if (emsmdbp_is_mapistore(folder)) {
-               retval = mapistore_folder_get_folder_count(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(folder),
-                                                          folder->backend_object, row_countp);
+               retval = mapistore_folder_get_child_count(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(folder),
+                                                         folder->backend_object, MAPISTORE_FOLDER_TABLE, row_countp);
        }
        else {
                if (folder->type == EMSMDBP_OBJECT_FOLDER) {
@@ -1031,6 +1165,75 @@ int emsmdbp_folder_get_folder_count(struct emsmdbp_context *emsmdbp_ctx, struct
        return retval;
 }
 
+_PUBLIC_ enum mapistore_error emsmdbp_folder_delete(struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *parent_folder, uint64_t fid, uint8_t flags)
+{
+       enum mapistore_error    ret;
+       enum MAPISTATUS         mapiret;
+       TALLOC_CTX              *mem_ctx;
+       bool                    mailboxstore;
+       uint32_t                context_id;
+       void                    *subfolder;
+       char                    *mapistoreURL;
+
+       mem_ctx = talloc_zero(NULL, TALLOC_CTX);
+
+       mailboxstore = emsmdbp_is_mailboxstore(parent_folder);
+       if (emsmdbp_is_mapistore(parent_folder)) {      /* fid is not a mapistore root */
+               DEBUG(0, ("Deleting mapistore folder\n"));
+               /* handled by mapistore */
+               context_id = emsmdbp_get_contextID(parent_folder);
+
+               ret = mapistore_folder_open_folder(emsmdbp_ctx->mstore_ctx, context_id, parent_folder->backend_object, mem_ctx, fid, &subfolder);
+               if (ret != MAPISTORE_SUCCESS) {
+                       goto end;
+               }
+
+               ret = mapistore_folder_delete(emsmdbp_ctx->mstore_ctx, context_id, subfolder, flags);
+               if (ret != MAPISTORE_SUCCESS) {
+                       goto end;
+               }
+       }
+       else {
+               mapiret = openchangedb_get_mapistoreURI(mem_ctx, emsmdbp_ctx->oc_ctx, fid, &mapistoreURL, mailboxstore);
+               if (mapiret != MAPI_E_SUCCESS) {
+                       ret = MAPISTORE_ERR_NOT_FOUND;
+                       goto end;
+               }
+
+               mapiret = openchangedb_delete_folder(emsmdbp_ctx->oc_ctx, fid);
+               if (mapiret != MAPI_E_SUCCESS) {
+                       ret = MAPISTORE_ERR_NOT_FOUND;
+                       goto end;
+               }
+
+               if (mapistoreURL) {     /* fid is mapistore root */
+                       ret = mapistore_search_context_by_uri(emsmdbp_ctx->mstore_ctx, mapistoreURL, &context_id, &subfolder);
+                       if (ret == MAPISTORE_SUCCESS) {
+                               mapistore_add_context_ref_count(emsmdbp_ctx->mstore_ctx, context_id);
+                       } else {
+                               ret = mapistore_add_context(emsmdbp_ctx->mstore_ctx, emsmdbp_ctx->username, mapistoreURL, fid, &context_id, &subfolder);
+                               if (ret != MAPISTORE_SUCCESS) {
+                                       goto end;
+                               }
+                       }
+
+                       ret = mapistore_folder_delete(emsmdbp_ctx->mstore_ctx, context_id, subfolder, flags);
+                       if (ret != MAPISTORE_SUCCESS) {
+                               goto end;
+                       }
+
+                        mapistore_del_context(emsmdbp_ctx->mstore_ctx, context_id);
+               }
+       }
+
+       ret = MAPISTORE_SUCCESS;
+
+end:
+       talloc_free(mem_ctx);
+
+       return ret;
+}
 _PUBLIC_ struct emsmdbp_object *emsmdbp_folder_open_table(TALLOC_CTX *mem_ctx, 
                                                          struct emsmdbp_object *parent_object, 
                                                          uint32_t table_type, uint32_t handle_id)
@@ -1045,22 +1248,26 @@ _PUBLIC_ struct emsmdbp_object *emsmdbp_folder_open_table(TALLOC_CTX *mem_ctx,
                return NULL;
        }
 
+       if (parent_object->type == EMSMDBP_OBJECT_FOLDER && parent_object->object.folder->postponed_props) {
+               emsmdbp_object_folder_commit_creation(parent_object->emsmdbp_ctx, parent_object, true);
+       }
+
        table_object = emsmdbp_object_table_init(mem_ctx, parent_object->emsmdbp_ctx, parent_object);
        if (table_object) {
                table_object->object.table->handle = handle_id;
                table_object->object.table->ulType = table_type;
                if (emsmdbp_is_mapistore(parent_object)) {
                        switch (table_type) {
-                       case EMSMDBP_TABLE_MESSAGE_TYPE:
+                       case MAPISTORE_MESSAGE_TABLE:
                                mstore_type = MAPISTORE_MESSAGE_TABLE;
                                break;
-                       case EMSMDBP_TABLE_FAI_TYPE:
+                       case MAPISTORE_FAI_TABLE:
                                mstore_type = MAPISTORE_FAI_TABLE;
                                break;
-                       case EMSMDBP_TABLE_FOLDER_TYPE:
+                       case MAPISTORE_FOLDER_TABLE:
                                mstore_type = MAPISTORE_FOLDER_TABLE;
                                break;
-                       case EMSMDBP_TABLE_PERMISSIONS_TYPE:
+                       case MAPISTORE_PERMISSIONS_TABLE:
                                mstore_type = MAPISTORE_PERMISSIONS_TABLE;
                                break;
                        default:
@@ -1075,7 +1282,7 @@ _PUBLIC_ struct emsmdbp_object *emsmdbp_folder_open_table(TALLOC_CTX *mem_ctx,
                        }
                }
                else {
-                       if (table_type == EMSMDBP_TABLE_FOLDER_TYPE) {
+                       if (table_type == MAPISTORE_FOLDER_TABLE) {
                                /* this gets data both for openchangedb and mapistore: needs improvement */
                                emsmdbp_folder_get_folder_count(parent_object->emsmdbp_ctx, parent_object, &table_object->object.table->denominator);
                        }
@@ -1096,13 +1303,13 @@ _PUBLIC_ struct emsmdbp_object *emsmdbp_folder_open_table(TALLOC_CTX *mem_ctx,
 
                                /* Non-mapistore message tables */
                                switch (table_type) {
-                               case EMSMDBP_TABLE_MESSAGE_TYPE:
+                               case MAPISTORE_MESSAGE_TABLE:
                                        openchangedb_get_message_count(parent_object->emsmdbp_ctx->oc_ctx, 
                                                                       folderID, 
                                                                       &table_object->object.table->denominator,
                                                                       false);
                                        break;
-                               case EMSMDBP_TABLE_FAI_TYPE:
+                               case MAPISTORE_FAI_TABLE:
                                        openchangedb_get_message_count(parent_object->emsmdbp_ctx->oc_ctx, 
                                                                       folderID, 
                                                                       &table_object->object.table->denominator,
@@ -1242,16 +1449,19 @@ _PUBLIC_ int emsmdbp_object_table_get_available_properties(TALLOC_CTX *mem_ctx,
        return retval;
 }
 
-_PUBLIC_ void **emsmdbp_object_table_get_row_props(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *table_object, uint32_t row_id, enum table_query_type query_type, uint32_t **retvalsp)
+_PUBLIC_ void **emsmdbp_object_table_get_row_props(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *table_object, uint32_t row_id, enum mapistore_query_type query_type, enum MAPISTATUS **retvalsp)
 {
         void                           **data_pointers;
         enum MAPISTATUS                        retval;
-        uint32_t                       *retvals;
-       struct emsmdbp_object           *subfolder;
+       enum mapistore_error            ret;
+        enum MAPISTATUS                        *retvals;
         struct emsmdbp_object_table    *table;
         struct mapistore_property_data *properties;
         uint32_t                       contextID, i, num_props, *obj_count;
-       uint64_t                        *rowFolderID;
+       struct emsmdbp_object           *rowobject;
+       uint64_t                        *rowFMId;
+       uint64_t                        parentFolderId;
+       bool                            mapistore_folder;
        uint8_t                         *has_subobj;
        void                            *odb_ctx;
        char                            *owner;
@@ -1262,7 +1472,7 @@ _PUBLIC_ void **emsmdbp_object_table_get_row_props(TALLOC_CTX *mem_ctx, struct e
 
         data_pointers = talloc_array(mem_ctx, void *, num_props);
         memset(data_pointers, 0, sizeof(void *) * num_props);
-        retvals = talloc_array(mem_ctx, uint32_t, num_props);
+        retvals = talloc_array(mem_ctx, enum MAPISTATUS, num_props);
         memset(retvals, 0, sizeof(uint32_t) * num_props);
 
        contextID = emsmdbp_get_contextID(table_object);
@@ -1299,83 +1509,152 @@ _PUBLIC_ void **emsmdbp_object_table_get_row_props(TALLOC_CTX *mem_ctx, struct e
                }
        } else {
                if (table_object->parent_object->type == EMSMDBP_OBJECT_FOLDER) {
-                       /* folderID = table_object->parent_object->object.folder->folderID; */
+                       parentFolderId = table_object->parent_object->object.folder->folderID;
                }
                else if (table_object->parent_object->type == EMSMDBP_OBJECT_MAILBOX) {
-                       /* folderID = table_object->parent_object->object.mailbox->folderID; */
+                       parentFolderId = table_object->parent_object->object.mailbox->folderID;
                }
                else {
-                       DEBUG(5, ("%s: non-poc tables can only be client of folder objects\n", __location__));
+                       DEBUG(5, ("%s: non-mapistore tables can only be client of folder objects\n", __location__));
                        talloc_free(retvals);
                        talloc_free(data_pointers);
                        return NULL;
                }
 
                odb_ctx = talloc_zero(NULL, void);
-               retval = openchangedb_table_get_property(odb_ctx, table_object->backend_object, emsmdbp_ctx->oc_ctx, emsmdbp_ctx->username,
-                                                        PR_FID, row_id, (query_type == MAPISTORE_LIVEFILTERED_QUERY), (void **) &rowFolderID);
-               printf("openchangedb_table_get_property retval = 0x%.8x\n", retval);
+
+               /* Setup table_filter for openchangedb */
+               /* switch (table_object->object.table->ulType) { */
+               /* case MAPISTORE_MESSAGE_TABLE: */
+               /*      table_filter = talloc_asprintf(odb_ctx, "(&(PidTagParentFolderId=%"PRIu64")(PidTagMessageId=*))", folderID); */
+               /*      break; */
+               /* case MAPISTORE_FOLDER_TABLE: */
+               /*      table_filter = talloc_asprintf(odb_ctx, "(&(PidTagParentFolderId=%"PRIu64")(PidTagFolderId=*))", folderID); */
+               /*      break; */
+               /* default: */
+               /*      DEBUG(5, ("[%s:%d]: Unsupported table type for openchangedb: %d\n", __FUNCTION__, __LINE__,  */
+               /*                    table_object->object.table->ulType)); */
+               /*      talloc_free(retvals); */
+               /*      talloc_free(data_pointers); */
+               /*      return NULL; */
+               /* } */
+
+               /* 1. retrieve the object id from odb */
+               switch (table_object->object.table->ulType) {
+               case MAPISTORE_FOLDER_TABLE:
+                       retval = openchangedb_table_get_property(odb_ctx, table_object->backend_object, emsmdbp_ctx->oc_ctx, PR_FID, row_id, (query_type == MAPISTORE_LIVEFILTERED_QUERY), (void **) &rowFMId);
+                       break;
+               case MAPISTORE_MESSAGE_TABLE:
+                       retval = openchangedb_table_get_property(odb_ctx, table_object->backend_object, emsmdbp_ctx->oc_ctx, PR_MID, row_id, (query_type == MAPISTORE_LIVEFILTERED_QUERY), (void **) &rowFMId);
+                       break;
+                       /* case MAPISTORE_FAI_TABLE: 
+                          retval = openchangedb_table_get_property(odb_ctx, table_object->backend_object, emsmdbp_ctx->oc_ctx,
+                          PR_MID, row_id, (query_type == MAPISTORE_LIVEFILTERED_QUERY), (void **) &rowFMId);
+                          break; */
+               default:
+                       DEBUG(5, ("table type %d not supported for non-mapistore table\n", table_object->object.table->ulType));
+                       retval = MAPI_E_INVALID_OBJECT;
+               }
+               /* printf("openchangedb_table_get_property retval = 0x%.8x\n", retval); */
                if (retval != MAPI_E_SUCCESS) {
                        talloc_free(retvals);
                        talloc_free(data_pointers);
+                       talloc_free(odb_ctx);
                        return NULL;
                }
 
-               subfolder = emsmdbp_object_open_folder(NULL, table_object->parent_object->emsmdbp_ctx, table_object->parent_object, *(uint64_t *)rowFolderID);
+               /* 2. open the corresponding object */
+               switch (table_object->object.table->ulType) {
+               case MAPISTORE_FOLDER_TABLE:
+                       ret = emsmdbp_object_open_folder(odb_ctx, table_object->parent_object->emsmdbp_ctx, table_object->parent_object, *(uint64_t *)rowFMId, &rowobject);
+                       mapistore_folder = emsmdbp_is_mapistore(rowobject);
+                       break;
+               case MAPISTORE_MESSAGE_TABLE:
+                       ret = emsmdbp_object_message_open(odb_ctx, table_object->parent_object->emsmdbp_ctx, table_object->parent_object, parentFolderId, *(uint64_t *)rowFMId, false, &rowobject, NULL);
+                       mapistore_folder = false;
+                       break;
+               default:
+                       DEBUG(5, ("you should never get here\n"));
+                       abort();
+               }
+               if (ret != MAPISTORE_SUCCESS) {
+                       talloc_free(retvals);
+                       talloc_free(data_pointers);
+                       talloc_free(odb_ctx);
+                       return NULL;
+               }
 
-               /* Lookup for flagged property row */
+               /* read the row properties */
                 retval = MAPI_E_SUCCESS;
                for (i = 0; retval != MAPI_E_INVALID_OBJECT && i < num_props; i++) {
-                       if (table->properties[i] == PR_CONTENT_COUNT) {
+                       if (mapistore_folder) {
                                /* a hack to avoid fetching dynamic fields from openchange.ldb */
-                               obj_count = talloc_zero(data_pointers, uint32_t);
-                               retval = mapistore_folder_get_message_count(emsmdbp_ctx->mstore_ctx, contextID, subfolder,
-                                                                           MAPISTORE_MESSAGE_TABLE, obj_count);
-                               data_pointers[i] = obj_count;
-                       }
-                       else if (table->properties[i] == PR_ASSOC_CONTENT_COUNT) {
-                               obj_count = talloc_zero(data_pointers, uint32_t);
-                               retval = mapistore_folder_get_message_count(emsmdbp_ctx->mstore_ctx, contextID, subfolder,
-                                                                           MAPISTORE_FAI_TABLE, obj_count);
-                               data_pointers[i] = obj_count;
-                       }
-                       else if (table->properties[i] == PR_FOLDER_CHILD_COUNT) {
-                               obj_count = talloc_zero(data_pointers, uint32_t);
-                               retval = emsmdbp_folder_get_folder_count(emsmdbp_ctx, subfolder, obj_count);
-                               data_pointers[i] = obj_count;
-                       }
-                       else if (table->properties[i] == PR_SOURCE_KEY) {
-                               owner = emsmdbp_get_owner(table_object);
-                               emsmdbp_source_key_from_fmid(data_pointers, emsmdbp_ctx, owner, subfolder->object.folder->folderID, &binr);
-                               data_pointers[i] = binr;
-                       }
-                       else if (table->properties[i] == PR_SUBFOLDERS) {
-                               obj_count = talloc_zero(NULL, uint32_t);
-                               retval = emsmdbp_folder_get_folder_count(emsmdbp_ctx, subfolder, obj_count);
-                               has_subobj = talloc_zero(data_pointers, uint8_t);
-                               *has_subobj = (*obj_count > 0) ? 1 : 0;
-                               data_pointers[i] = has_subobj;
-                               talloc_free(obj_count);
-                       }
-                       else if (table->properties[i] == PR_CONTENT_UNREAD || table->properties[i] == PR_DELETED_COUNT_TOTAL) {
-                               /* TODO: temporary */
-                               obj_count = talloc_zero(data_pointers, uint32_t);
-                               data_pointers[i] = obj_count;
-                               retval = MAPI_E_SUCCESS;
+                               switch (table->properties[i]) {
+                               case PR_CONTENT_COUNT:
+                                       obj_count = talloc_zero(data_pointers, uint32_t);
+                                       retval = mapistore_folder_get_child_count(emsmdbp_ctx->mstore_ctx, contextID, rowobject,
+                                                                                 MAPISTORE_MESSAGE_TABLE, obj_count);
+                                       data_pointers[i] = obj_count;
+                                       break;
+                               case PR_ASSOC_CONTENT_COUNT:
+                                       obj_count = talloc_zero(data_pointers, uint32_t);
+                                       retval = mapistore_folder_get_child_count(emsmdbp_ctx->mstore_ctx, contextID, rowobject,
+                                                                                 MAPISTORE_FAI_TABLE, obj_count);
+                                       data_pointers[i] = obj_count;
+                                       break;
+                               case PR_FOLDER_CHILD_COUNT:
+                                       obj_count = talloc_zero(data_pointers, uint32_t);
+                                       retval = emsmdbp_folder_get_folder_count(emsmdbp_ctx, rowobject, obj_count);
+                                       data_pointers[i] = obj_count;
+                                       break;
+                               case PR_SOURCE_KEY:
+                                       owner = emsmdbp_get_owner(table_object);
+                                       emsmdbp_source_key_from_fmid(data_pointers, emsmdbp_ctx, owner, rowobject->object.folder->folderID, &binr);
+                                       data_pointers[i] = binr;
+                                       break;
+                               case PR_SUBFOLDERS:
+                                       obj_count = talloc_zero(NULL, uint32_t);
+                                       retval = emsmdbp_folder_get_folder_count(emsmdbp_ctx, rowobject, obj_count);
+                                       has_subobj = talloc_zero(data_pointers, uint8_t);
+                                       *has_subobj = (*obj_count > 0) ? 1 : 0;
+                                       data_pointers[i] = has_subobj;
+                                       talloc_free(obj_count);
+                                       break;
+                               case PR_CONTENT_UNREAD:
+                               case PR_DELETED_COUNT_TOTAL:
+                                       /* TODO: temporary */
+                                       obj_count = talloc_zero(data_pointers, uint32_t);
+                                       data_pointers[i] = obj_count;
+                                       retval = MAPI_E_SUCCESS;
+                                       break;
+                               default:
+                                       retval = openchangedb_table_get_property(data_pointers, table_object->backend_object, 
+                                                                                emsmdbp_ctx->oc_ctx,
+                                                                                table->properties[i], 
+                                                                                row_id,
+                                                                                (query_type == MAPISTORE_LIVEFILTERED_QUERY),
+                                                                                data_pointers + i);
+                                       /* retval = openchangedb_get_table_property(data_pointers, emsmdbp_ctx->oc_ctx,  */
+                                       /*                                       emsmdbp_ctx->username, */
+                                       /*                                       table_filter, table->properties[i],  */
+                                       /*                                       row_id, data_pointers + i); */
+                               }
                        }
                        else {
                                retval = openchangedb_table_get_property(data_pointers, table_object->backend_object, 
-                                                                        emsmdbp_ctx->oc_ctx, emsmdbp_ctx->username,
+                                                                        emsmdbp_ctx->oc_ctx,
                                                                         table->properties[i], 
                                                                         row_id,
                                                                         (query_type == MAPISTORE_LIVEFILTERED_QUERY),
                                                                         data_pointers + i);
                        }
+
+                       /* DEBUG(5, ("  %.8x: %d", table->properties[j], retval)); */
                        if (retval == MAPI_E_INVALID_OBJECT) {
                                DEBUG(5, ("%s: invalid object in non-mapistore folder, count set to 0\n", __location__));
                                talloc_free(retvals);
                                talloc_free(data_pointers);
-                               talloc_free(subfolder);
+                               talloc_free(odb_ctx);
                                return NULL;
                        }
                        else {
@@ -1383,7 +1662,6 @@ _PUBLIC_ void **emsmdbp_object_table_get_row_props(TALLOC_CTX *mem_ctx, struct e
                        }
                }
 
-               talloc_free(subfolder);
                talloc_free(odb_ctx);
        }
 
@@ -1397,7 +1675,7 @@ _PUBLIC_ void **emsmdbp_object_table_get_row_props(TALLOC_CTX *mem_ctx, struct e
 _PUBLIC_ void emsmdbp_fill_table_row_blob(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx,
                                          DATA_BLOB *table_row, uint16_t num_props,
                                          enum MAPITAGS *properties,
-                                         void **data_pointers, uint32_t *retvals)
+                                         void **data_pointers, enum MAPISTATUS *retvals)
 {
         uint16_t i;
         uint8_t flagged;
@@ -1478,22 +1756,491 @@ _PUBLIC_ struct emsmdbp_object *emsmdbp_object_message_init(TALLOC_CTX *mem_ctx,
 
        object->type = EMSMDBP_OBJECT_MESSAGE;
        object->object.message->messageID = messageID;
+       object->object.message->read_write = false;
 
        return object;
 }
 
-_PUBLIC_ struct emsmdbp_object *emsmdbp_object_message_open(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *parent_object, uint64_t folderID, uint64_t messageID, struct mapistore_message **msgp)
+static int emsmdbp_days_in_month(int month, int year)
+{
+       static int      max_mdays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+       int             dec_year, days;
+
+       if (month == 1) {
+               dec_year = year % 100;
+               if ((dec_year == 0
+                    && ((((year + 1900) / 100) % 4) == 0))
+                   || (dec_year % 4) == 0) {
+                       days = 29;
+               }
+               else {
+                       days = max_mdays[month];
+               }
+       }
+       else {
+               days = max_mdays[month];
+       }
+
+       return days;
+}
+
+static int emsmdbp_mins_in_ymon(uint32_t ymon)
+{
+       return emsmdbp_days_in_month((ymon & 0xf) - 1, ymon >> 4) * 24 * 60;
+}
+
+static inline void emsmdbp_freebusy_make_range(struct tm *start_time, struct tm *end_time)
+{
+       time_t                                                  now;
+       struct tm                                               time_data;
+       int                                                     mw_delta, month;
+
+       /* (from OXOPFFB - 3.1.4.1.1)
+          Start of range is 12:00 A.M. UTC on the first day of the month or the first day of the week, whichever occurs earlier at the time of publishing.
+          End of range is calculated by adding the value of the PidTagFreeBusyCountMonths property ([MS-OXOCAL] section 2.2.12.1) to start of range.
+
+          Since PidTagFreeBusyCountMonths is not supported yet, we use a count of 3 months
+       */
+
+       now = time(NULL);
+       time_data = *gmtime(&now);
+       time_data.tm_hour = 0;
+       time_data.tm_min = 0;
+       time_data.tm_sec = 0;
+
+       /* take the first day of the week OR the first day of the month */
+       month = time_data.tm_mon;
+       if (time_data.tm_mday < 7) {
+               mw_delta = (time_data.tm_wday + 1 - time_data.tm_mday);
+               if (mw_delta > 0) {
+                       if (time_data.tm_mon > 0) {
+                               time_data.tm_mon--;
+                       }
+                       else {
+                               time_data.tm_mon = 11;
+                               time_data.tm_year--;
+                       }
+                       time_data.tm_mday = emsmdbp_days_in_month(time_data.tm_mon, time_data.tm_year) + 1 - mw_delta;
+               }
+               else {
+                       time_data.tm_mday = 1;
+               }
+       }
+       else {
+               mw_delta = 0;
+               time_data.tm_mday = 1;
+       }
+
+       *start_time = time_data;
+
+       time_data.tm_mon = month + 2;
+       if (time_data.tm_mon > 11) {
+               time_data.tm_year++;
+               time_data.tm_mon -= 12;
+       }
+       time_data.tm_mday = emsmdbp_days_in_month(time_data.tm_mon, time_data.tm_year) + 1 - mw_delta;
+       time_data.tm_hour = 23;
+       time_data.tm_min = 59;
+       time_data.tm_sec = 59;
+
+       *end_time = time_data;
+}
+
+static void emsmdbp_freebusy_convert_filetime(struct FILETIME *ft_value, uint32_t *ymon, uint32_t *mins)
+{
+       NTTIME          nt_time;
+       time_t          u_time;
+       struct tm       *gm_time;
+
+       nt_time = ((NTTIME) ft_value->dwHighDateTime << 32) | ft_value->dwLowDateTime;
+       u_time = nt_time_to_unix(nt_time);
+       gm_time = gmtime(&u_time);
+
+       *ymon = ((gm_time->tm_year + 1900) << 4) | (gm_time->tm_mon + 1);
+       *mins = gm_time->tm_min + (gm_time->tm_hour + ((gm_time->tm_mday - 1) * 24)) * 60;
+}
+
+static uint16_t emsmdbp_freebusy_find_month_range(uint32_t ymon, uint32_t *months_ranges, uint16_t nbr_months, bool *overflow)
+{
+       uint16_t        range;
+
+       if (nbr_months > 0) {
+               if (months_ranges[0] > ymon) {
+                       *overflow = true;
+                       return 0;
+               }
+               else {
+                       if (months_ranges[nbr_months - 1] < ymon) {
+                               *overflow = true;
+                               return (nbr_months - 1);
+                       }
+                       else {
+                               *overflow = false;
+                               for (range = 0; range < nbr_months; range++) {
+                                       if (months_ranges[range] == ymon) {
+                                               return range;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       return (uint16_t) -1;
+}
+
+/* TODO: both following methods could be merged. This would certainly enhance performance by avoiding to wander through long arrays multiple times */
+static void emsmdbp_freebusy_fill_fbarray(uint8_t **minutes_array, uint32_t *months_ranges, uint16_t nbr_months, struct FILETIME *start, struct FILETIME *end)
+{
+       uint32_t        i, max, start_ymon, start_mins, end_ymon, end_mins;
+       uint16_t        start_mr_idx, end_mr_idx;
+       bool            start_range_overflow, end_range_overflow;
+
+       emsmdbp_freebusy_convert_filetime(start, &start_ymon, &start_mins);
+       emsmdbp_freebusy_convert_filetime(end, &end_ymon, &end_mins);
+
+       start_mr_idx = emsmdbp_freebusy_find_month_range(start_ymon, months_ranges, nbr_months, &start_range_overflow);
+       if (start_range_overflow) {
+               start_mins = 0;
+       }
+       end_mr_idx = emsmdbp_freebusy_find_month_range(end_ymon, months_ranges, nbr_months, &end_range_overflow);
+       if (end_range_overflow) {
+               end_mins = emsmdbp_mins_in_ymon(end_ymon);
+       }
+
+       /* head */
+       if (end_mr_idx > start_mr_idx) {
+               /* end occurs after start range */
+
+               /* middle */
+               for (i = start_mr_idx + 1; i < end_mr_idx; i++) {
+                       memset(minutes_array[i], 1, emsmdbp_mins_in_ymon(months_ranges[i]));
+               }
+
+               /* tail */
+               memset(minutes_array[end_mr_idx], 1, end_mins);
+
+               max = emsmdbp_mins_in_ymon(start_ymon); /* = max chunk for first range */
+       }
+       else {
+               /* end occurs on same range as start */
+
+               max = end_mins;
+       }
+       memset(minutes_array[start_mr_idx] + start_mins, 1, (max - start_mins));
+}
+
+static void emsmdbp_freebusy_compile_fbarray(TALLOC_CTX *mem_ctx, uint8_t *minutes_array, struct Binary_r *fb_bin)
+{
+       int                     i;
+       bool                    filled;
+       struct ndr_push         *ndr;
+       TALLOC_CTX              *local_mem_ctx;
+
+       local_mem_ctx = talloc_zero(NULL, TALLOC_CTX);
+
+       ndr = ndr_push_init_ctx(local_mem_ctx);
+
+       filled = (minutes_array[0] != 0);
+       if (filled) {
+               ndr_push_uint16(ndr, NDR_SCALARS, 0);
+       }
+
+       for (i = 1; i < max_mins_per_month; i++) {
+               if (filled && !minutes_array[i]) {
+                       ndr_push_uint16(ndr, NDR_SCALARS, (i - 1));
+                       filled = false;
+               }
+               else if (!filled && minutes_array[i]) {
+                       ndr_push_uint16(ndr, NDR_SCALARS, i);
+                       filled = true;
+               }
+       }
+       if (filled) {
+               ndr_push_uint16(ndr, NDR_SCALARS, (max_mins_per_month - 1));
+       }
+
+       fb_bin->cb = ndr->offset;
+       fb_bin->lpb = ndr->data;
+       (void) talloc_reference(mem_ctx, fb_bin->lpb);
+
+       talloc_free(local_mem_ctx);
+}
+
+static void emsmdbp_freebusy_merge_subarray(uint8_t *minutes_array, uint8_t *included_array)
+{
+       int i;
+
+       for (i = 0; i < max_mins_per_month; i++) {
+               if (included_array[i]) {
+                       minutes_array[i] = 1;
+               }
+       }
+}
+
+static void emsmdbp_object_message_fill_freebusy_properties(struct emsmdbp_object *message_object)
+{
+       /* freebusy mechanism:
+          - lookup events in range now + 3 months, requesting end date, start date and PidLidBusyStatus
+          - fill (olTentative) PidTagScheduleInfoMonthsTentative,
+          PidTagScheduleInfoFreeBusyTentative
+          - fill (olBusy) PidTagScheduleInfoMonthsBusy,
+          PidTagScheduleInfoFreeBusyBusy
+          - fill (olOutOfOffice) PidTagScheduleInfoMonthsAway,
+          PidTagScheduleInfoFreeBusyAway
+          - fill (olBusy + olOutOfOffice) PidTagScheduleInfoMonthsMerged,
+          PidTagScheduleInfoFreeBusyMerged
+          - fill PidTagFreeBusyPublishStart, PidTagFreeBusyPublishEnd and
+          PidTagFreeBusyRangeTimestamp.
+          - fill PidTagFreeBusyMessageEmailAddress */
+
+       TALLOC_CTX                                              *mem_ctx;
+       struct emsmdbp_object_message_freebusy_properties       *fb_props;
+       char                                                    *subject, *email, *username, *tmp;
+       struct SPropTagArray                                    *props;
+        void                                                   **data_pointers;
+        enum MAPISTATUS                                                *retvals = NULL;
+       struct emsmdbp_object                                   *mailbox, *inbox, *calendar, *table;
+       uint64_t                                                inboxFID, calendarFID;
+       uint32_t                                                contextID;
+       struct mapi_SRestriction                                and_res;
+       uint8_t                                                 state;
+       struct tm                                               start_tm, end_tm;
+       time_t                                                  start_time, end_time;
+       NTTIME                                                  nt_time;
+       struct mapi_SRestriction_and                            time_restrictions[2];
+       int                                                     i, month, nbr_months;
+       uint8_t                                                 **minutes_array, **tentative_array, **busy_array, **oof_array;
+       char                                                    *tz;
+
+       mem_ctx = talloc_zero(NULL, TALLOC_CTX);
+
+       /* 1. retrieve subject and deduce username */
+       props = talloc_zero(mem_ctx, struct SPropTagArray);
+       props->cValues = 1;
+       props->aulPropTag = talloc_zero(props, enum MAPITAGS);
+       props->aulPropTag[0] = PR_NORMALIZED_SUBJECT_UNICODE;
+       data_pointers = emsmdbp_object_get_properties(mem_ctx, message_object->emsmdbp_ctx, message_object, props, &retvals);
+       if (!data_pointers || retvals[0] != MAPI_E_SUCCESS) {
+               goto end;
+       }
+       subject = data_pointers[0];
+       // format is "..../CN="
+       username = strrchr(subject, '/');
+       if (!username) {
+               goto end;
+       }
+       username += 4;
+       username = talloc_strdup(mem_ctx, username);
+
+       fb_props = talloc_zero(message_object, struct emsmdbp_object_message_freebusy_properties);
+       message_object->object.message->fb_properties = fb_props;
+
+       // WARNING: the mechanism here will fail if username is not all lower-case, as LDB does not support case-insensitive queries
+       tmp = username;
+       while (*tmp) {
+               *tmp = tolower(*tmp);
+               tmp++;
+       }
+       email = talloc_asprintf(mem_ctx, "/o=First Organization/ou=First Administrative Group/cn=Recipients/cn=%s", username);
+       fb_props->email_address = email;
+
+       /* open user mailbox */
+       mailbox = emsmdbp_object_mailbox_init(mem_ctx, message_object->emsmdbp_ctx, email, true);
+       if (!mailbox) {
+               goto end;
+       }
+
+       /* open Inbox */
+       openchangedb_get_SystemFolderID(message_object->emsmdbp_ctx->oc_ctx, username, EMSMDBP_INBOX, &inboxFID);
+       if (emsmdbp_object_open_folder_by_fid(mem_ctx, message_object->emsmdbp_ctx, mailbox, inboxFID, &inbox) != MAPISTORE_SUCCESS) {
+               goto end;
+       }
+
+       /* retrieve Calendar entry id */
+       props->aulPropTag[0] = PR_IPM_APPOINTMENT_ENTRYID;
+       data_pointers = emsmdbp_object_get_properties(mem_ctx, message_object->emsmdbp_ctx, inbox, props, &retvals);
+       if (!data_pointers || retvals[0] != MAPI_E_SUCCESS) {
+               goto end;
+       }
+       calendarFID = 0;
+       for (i = 0; i < 6; i++) {
+               calendarFID <<= 8;
+               calendarFID |= *(((struct Binary_r *) data_pointers[0])->lpb + (43 - i));
+       }
+       calendarFID <<= 16;
+       calendarFID |= 1;
+
+       /* open user calendar */
+       if (emsmdbp_object_open_folder_by_fid(mem_ctx, message_object->emsmdbp_ctx, mailbox, calendarFID, &calendar) != MAPISTORE_SUCCESS) {
+               goto end;
+       }
+       if (!emsmdbp_is_mapistore(calendar)) {
+               DEBUG(5, ("non-mapistore calendars are not supported for freebusy\n"));
+               goto end;
+       }
+
+       /* fetch events from this month for 3 months: start + enddate + fbstatus */
+       table = emsmdbp_folder_open_table(mem_ctx, calendar, MAPISTORE_MESSAGE_TABLE, 0);
+       if (!table) {
+               goto end;
+       }
+       contextID = emsmdbp_get_contextID(calendar);
+
+       /* fetch freebusy range */
+       emsmdbp_freebusy_make_range(&start_tm, &end_tm);
+
+       unix_to_nt_time(&nt_time, time(NULL));
+       fb_props->timestamp.dwLowDateTime = (nt_time & 0xffffffff);
+       fb_props->timestamp.dwHighDateTime = nt_time >> 32;
+
+       tz = getenv("TZ");
+       setenv("TZ", "", 1);
+       tzset();
+       start_time = mktime(&start_tm);
+       end_time = mktime(&end_tm);
+       if (tz) {
+               setenv("TZ", tz, 1);
+       }
+       else {
+               unsetenv("TZ");
+       }
+       tzset();
+
+       /* setup restriction */
+       and_res.rt = RES_AND;
+       and_res.res.resAnd.cRes = 2;
+       and_res.res.resAnd.res = time_restrictions;
+
+       time_restrictions[0].rt = RES_PROPERTY;
+       time_restrictions[0].res.resProperty.relop = RELOP_GE;
+       time_restrictions[0].res.resProperty.ulPropTag = PidLidAppointmentEndWhole; 
+       time_restrictions[0].res.resProperty.lpProp.ulPropTag = PidLidAppointmentEndWhole;
+       unix_to_nt_time(&nt_time, start_time);
+       time_restrictions[0].res.resProperty.lpProp.value.ft.dwLowDateTime = (nt_time & 0xffffffff);
+       time_restrictions[0].res.resProperty.lpProp.value.ft.dwHighDateTime = nt_time >> 32;
+       fb_props->publish_start = (uint32_t) (nt_time / (60 * 10000000));
+
+       time_restrictions[1].rt = RES_PROPERTY;
+       time_restrictions[1].res.resProperty.relop = RELOP_LE;
+       time_restrictions[1].res.resProperty.ulPropTag = PidLidAppointmentStartWhole; 
+       time_restrictions[1].res.resProperty.lpProp.ulPropTag = PidLidAppointmentStartWhole;
+       unix_to_nt_time(&nt_time, end_time);
+       time_restrictions[1].res.resProperty.lpProp.value.ft.dwLowDateTime = (nt_time & 0xffffffff);
+       time_restrictions[1].res.resProperty.lpProp.value.ft.dwHighDateTime = nt_time >> 32;
+       fb_props->publish_end = (uint32_t) (nt_time / (60 * 10000000));
+
+       mapistore_table_set_restrictions(message_object->emsmdbp_ctx->mstore_ctx, contextID, table->backend_object, &and_res, &state);
+
+       /* setup table columns */
+       props->cValues = 3;
+       props->aulPropTag = talloc_array(props, enum MAPITAGS, props->cValues);
+       props->aulPropTag[0] = PidLidAppointmentStartWhole;
+       props->aulPropTag[1] = PidLidAppointmentEndWhole;
+       props->aulPropTag[2] = PidLidBusyStatus;
+       mapistore_table_set_columns(message_object->emsmdbp_ctx->mstore_ctx, contextID, table->backend_object, props->cValues, props->aulPropTag);
+       table->object.table->prop_count = props->cValues;
+       table->object.table->properties = props->aulPropTag;
+
+       /* setup months arrays */
+       if (start_tm.tm_year == end_tm.tm_year) {
+               nbr_months = (end_tm.tm_mon - start_tm.tm_mon + 1);
+       }
+       else {
+               nbr_months = (12 - start_tm.tm_mon) + end_tm.tm_mon + 1;
+       }
+       fb_props->months_ranges = talloc_array(fb_props, uint32_t, nbr_months);
+       if (start_tm.tm_year == end_tm.tm_year) {
+               for (i = 0; i < nbr_months; i++) {
+                       fb_props->months_ranges[i] = ((start_tm.tm_year + 1900) << 4) + (start_tm.tm_mon + 1 + i);
+               }
+       }
+       else {
+               month = start_tm.tm_mon;
+               i = 0;
+               while (month < 12) {
+                       fb_props->months_ranges[i] = ((start_tm.tm_year + 1900) << 4) + month + 1;
+                       i++;
+                       month++;
+               }
+               month = 0;
+               while (month < end_tm.tm_mon) {
+                       fb_props->months_ranges[i] = ((end_tm.tm_year + 1900) << 4) + month + 1;
+                       i++;
+                       month++;
+               }
+               fb_props->months_ranges[i] = ((end_tm.tm_year + 1900) << 4) + month + 1;
+       }
+
+       /* fetch events and fill freebusy arrays */
+       tentative_array = talloc_array(mem_ctx, uint8_t *, nbr_months);
+       busy_array = talloc_array(mem_ctx, uint8_t *, nbr_months);
+       oof_array = talloc_array(mem_ctx, uint8_t *, nbr_months);
+       for (i = 0; i < nbr_months; i++) {
+               tentative_array[i] = talloc_array(tentative_array, uint8_t, max_mins_per_month);
+               memset(tentative_array[i], 0, max_mins_per_month);
+               busy_array[i] = talloc_array(tentative_array, uint8_t, max_mins_per_month);
+               memset(busy_array[i], 0, max_mins_per_month);
+               oof_array[i] = talloc_array(tentative_array, uint8_t, max_mins_per_month);
+               memset(oof_array[i], 0, max_mins_per_month);
+       }
+
+       i = 0;
+       while ((data_pointers = emsmdbp_object_table_get_row_props(mem_ctx, message_object->emsmdbp_ctx, table, i, MAPISTORE_PREFILTERED_QUERY, &retvals))) {
+               if (retvals[0] == MAPI_E_SUCCESS && retvals[1] == MAPI_E_SUCCESS && retvals[2] == MAPI_E_SUCCESS) {
+                       switch (*((uint32_t *) data_pointers[2])) {
+                       case olTentative:
+                               minutes_array = tentative_array;
+                               break;
+                       case olBusy:
+                               minutes_array = busy_array;
+                               break;
+                       case olOutOfOffice:
+                               minutes_array = oof_array;
+                               break;
+                       default:
+                               minutes_array = NULL;
+                       }
+                       if (minutes_array) {
+                               emsmdbp_freebusy_fill_fbarray(minutes_array, fb_props->months_ranges, nbr_months, data_pointers[0], data_pointers[1]);
+                       }
+               }
+               i++;
+       }
+
+        /* compile minutes array into arrays of ranges */
+       fb_props->nbr_months = nbr_months;
+       fb_props->freebusy_tentative = talloc_array(fb_props, struct Binary_r, nbr_months);
+       fb_props->freebusy_busy = talloc_array(fb_props, struct Binary_r, nbr_months);
+       fb_props->freebusy_away = talloc_array(fb_props, struct Binary_r, nbr_months);
+       fb_props->freebusy_merged = talloc_array(fb_props, struct Binary_r, nbr_months);
+       for (i = 0; i < nbr_months; i++) {
+               emsmdbp_freebusy_compile_fbarray(fb_props, tentative_array[i], fb_props->freebusy_tentative + i);
+               emsmdbp_freebusy_compile_fbarray(fb_props, busy_array[i], fb_props->freebusy_busy + i);
+               emsmdbp_freebusy_compile_fbarray(fb_props, oof_array[i], fb_props->freebusy_away + i);
+               emsmdbp_freebusy_merge_subarray(busy_array[i], oof_array[i]);
+               emsmdbp_freebusy_compile_fbarray(fb_props, busy_array[i], fb_props->freebusy_merged + i);
+       }
+
+end:
+       talloc_free(mem_ctx);
+
+       return;
+}
+
+_PUBLIC_ enum mapistore_error emsmdbp_object_message_open(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *parent_object, uint64_t folderID, uint64_t messageID, bool read_write, struct emsmdbp_object **messageP, struct mapistore_message **msgp)
 {
        struct emsmdbp_object *folder_object, *message_object = NULL;
        uint32_t contextID;
        bool mapistore;
        TALLOC_CTX *local_mem_ctx;
+       enum mapistore_error ret = MAPISTORE_SUCCESS;
 
-       if (!parent_object) return NULL;
+       if (!messageP) return MAPISTORE_ERROR;
+       if (!parent_object) return MAPISTORE_ERROR;
 
        local_mem_ctx = talloc_zero(NULL, TALLOC_CTX);
-       folder_object = emsmdbp_object_open_folder_by_fid(local_mem_ctx, emsmdbp_ctx, parent_object, folderID);
-       if (!folder_object)  {
+       ret = emsmdbp_object_open_folder_by_fid(local_mem_ctx, emsmdbp_ctx, parent_object, folderID, &folder_object);
+       if (ret != MAPISTORE_SUCCESS)  {
                goto end;
        }
 
@@ -1502,27 +2249,39 @@ _PUBLIC_ struct emsmdbp_object *emsmdbp_object_message_open(TALLOC_CTX *mem_ctx,
        case false:
                /* system/special folder */
                message_object = emsmdbp_object_message_init(mem_ctx, emsmdbp_ctx, messageID, folder_object);
-               if (openchangedb_message_open(mem_ctx, emsmdbp_ctx->oc_ctx, messageID, folderID, &message_object->backend_object, (void **)msgp) != MAPI_E_SUCCESS) {
+               ret = openchangedb_message_open(mem_ctx, emsmdbp_ctx->oc_ctx, messageID, folderID, &message_object->backend_object, (void **)msgp);
+               if (ret != MAPISTORE_SUCCESS) {
                        printf("Invalid openchangedb message\n");
                        talloc_free(message_object);
-                       message_object = NULL;
+                       goto end;
                }
+
+               emsmdbp_object_message_fill_freebusy_properties(message_object);
                break;
        case true:
                /* mapistore implementation goes here */
                message_object = emsmdbp_object_message_init(mem_ctx, emsmdbp_ctx, messageID, folder_object);
                contextID = emsmdbp_get_contextID(folder_object);
-               if (mapistore_folder_open_message(emsmdbp_ctx->mstore_ctx, contextID, folder_object->backend_object, message_object, messageID, &message_object->backend_object) != MAPISTORE_SUCCESS
-                   || mapistore_message_get_message_data(emsmdbp_ctx->mstore_ctx, contextID, message_object->backend_object, mem_ctx, msgp) != MAPISTORE_SUCCESS) {
+               ret = mapistore_folder_open_message(emsmdbp_ctx->mstore_ctx, contextID, folder_object->backend_object, message_object, messageID, read_write, &message_object->backend_object);
+               if (ret == MAPISTORE_SUCCESS && msgp) {
+                       if (mapistore_message_get_message_data(emsmdbp_ctx->mstore_ctx, contextID, message_object->backend_object, mem_ctx, msgp) != MAPISTORE_SUCCESS) {
+                               ret = MAPISTORE_ERROR;
+                       }
+               }
+               if (ret != MAPISTORE_SUCCESS) {
                        talloc_free(message_object);
-                       message_object = NULL;
                }
        }
 
 end:
        talloc_free(local_mem_ctx);
 
-       return message_object;
+       if (ret == MAPISTORE_SUCCESS) {
+               message_object->object.message->read_write = read_write;
+               *messageP = message_object;
+       }
+
+       return ret;
 }
 
 _PUBLIC_ struct emsmdbp_object *emsmdbp_object_message_open_attachment_table(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *message_object)
@@ -1545,7 +2304,7 @@ _PUBLIC_ struct emsmdbp_object *emsmdbp_object_message_open_attachment_table(TAL
 
                table_object = emsmdbp_object_table_init(mem_ctx, emsmdbp_ctx, message_object);
                if (table_object) {
-                       table_object->object.table->ulType = EMSMDBP_TABLE_ATTACHMENT_TYPE;
+                       table_object->object.table->ulType = MAPISTORE_ATTACHMENT_TABLE;
                        mapistore_message_get_attachment_table(emsmdbp_ctx->mstore_ctx, contextID,
                                                               message_object->backend_object,
                                                               table_object, &table_object->backend_object,
@@ -1740,9 +2499,7 @@ static int emsmdbp_object_get_properties_systemspecialfolder(TALLOC_CTX *mem_ctx
                        retval = MAPI_E_SUCCESS;
                }
                 else {
-                       retval = openchangedb_get_folder_property(data_pointers, emsmdbp_ctx->oc_ctx, 
-                                                                 emsmdbp_ctx->username, properties->aulPropTag[i],
-                                                                 folder->folderID, data_pointers + i);
+                       retval = openchangedb_get_folder_property(data_pointers, emsmdbp_ctx->oc_ctx, properties->aulPropTag[i], folder->folderID, data_pointers + i);
                 }
                retvals[i] = retval;
         }
@@ -1754,10 +2511,15 @@ static int emsmdbp_object_get_properties_message(TALLOC_CTX *mem_ctx, struct ems
                                                 struct emsmdbp_object *object, struct SPropTagArray *properties,
                                                 void **data_pointers, enum MAPISTATUS *retvals)
 {
-       enum MAPISTATUS         retval;
-       int                     i;
-       char                    *owner;
-       struct Binary_r         *binr;
+       enum MAPISTATUS                                         retval;
+       int                                                     i;
+       char                                                    *owner;
+       struct Binary_r                                         *binr;
+       struct emsmdbp_object_message_freebusy_properties       *fb_props;
+       struct LongArray_r                                      *long_array;
+       struct BinaryArray_r                                    *bin_array;
+
+       fb_props = object->object.message->fb_properties;
 
        /* Look over properties */
        for (i = 0; i < properties->cValues; i++) {
@@ -1768,7 +2530,69 @@ static int emsmdbp_object_get_properties_message(TALLOC_CTX *mem_ctx, struct ems
                        data_pointers[i] = binr;
                        retval = MAPI_E_SUCCESS;
                } else {
-                       retval = openchangedb_message_get_property(data_pointers, object->backend_object, properties->aulPropTag[i], data_pointers + i);
+                       if (fb_props) {
+                               switch (properties->aulPropTag[i]) {
+                               case PR_SCHDINFO_MONTHS_TENTATIVE:
+                               case PR_SCHDINFO_MONTHS_BUSY:
+                               case PR_SCHDINFO_MONTHS_OOF:
+                               case PR_SCHDINFO_MONTHS_MERGED:
+                                       long_array = talloc_zero(data_pointers, struct LongArray_r);
+                                       long_array->cValues = fb_props->nbr_months;
+                                       long_array->lpl = fb_props->months_ranges;
+                                       data_pointers[i] = long_array;
+                                       retval = MAPI_E_SUCCESS;
+                                       break;
+                               case PR_SCHDINFO_FREEBUSY_TENTATIVE:
+                                       bin_array = talloc_zero(data_pointers, struct BinaryArray_r);
+                                       bin_array->cValues = fb_props->nbr_months;
+                                       bin_array->lpbin = fb_props->freebusy_tentative;
+                                       data_pointers[i] = bin_array;
+                                       retval = MAPI_E_SUCCESS;
+                                       break;
+                               case PR_SCHDINFO_FREEBUSY_BUSY:
+                                       bin_array = talloc_zero(data_pointers, struct BinaryArray_r);
+                                       bin_array->cValues = fb_props->nbr_months;
+                                       bin_array->lpbin = fb_props->freebusy_busy;
+                                       data_pointers[i] = bin_array;
+                                       retval = MAPI_E_SUCCESS;
+                                       break;
+                               case PR_SCHDINFO_FREEBUSY_OOF:
+                                       bin_array = talloc_zero(data_pointers, struct BinaryArray_r);
+                                       bin_array->cValues = fb_props->nbr_months;
+                                       bin_array->lpbin = fb_props->freebusy_away;
+                                       data_pointers[i] = bin_array;
+                                       retval = MAPI_E_SUCCESS;
+                                       break;
+                               case PR_SCHDINFO_FREEBUSY_MERGED:
+                                       bin_array = talloc_zero(data_pointers, struct BinaryArray_r);
+                                       bin_array->cValues = fb_props->nbr_months;
+                                       bin_array->lpbin = fb_props->freebusy_merged;
+                                       data_pointers[i] = bin_array;
+                                       retval = MAPI_E_SUCCESS;
+                                       break;
+                               case PR_FREEBUSY_PUBLISH_START:
+                                       data_pointers[i] = &fb_props->publish_start;
+                                       retval = MAPI_E_SUCCESS;
+                                       break;
+                               case PR_FREEBUSY_PUBLISH_END:
+                                       data_pointers[i] = &fb_props->publish_end;
+                                       retval = MAPI_E_SUCCESS;
+                                       break;
+                               case PR_FREEBUSY_EMA:
+                                       data_pointers[i] = fb_props->email_address;
+                                       retval = MAPI_E_SUCCESS;
+                                       break;
+                               case PR_FREEBUSY_RANGE_TIMESTAMP:
+                                       data_pointers[i] = &fb_props->timestamp;
+                                       retval = MAPI_E_SUCCESS;
+                                       break;
+                               default:
+                                       retval = openchangedb_message_get_property(data_pointers, object->backend_object, properties->aulPropTag[i], data_pointers + i);
+                               }
+                       }
+                       else {
+                               retval = openchangedb_message_get_property(data_pointers, object->backend_object, properties->aulPropTag[i], data_pointers + i);
+                       }
                }
                retvals[i] = retval;
        }
@@ -1783,19 +2607,21 @@ static int emsmdbp_object_get_properties_mapistore_root(TALLOC_CTX *mem_ctx, str
        char                            *owner;
        struct Binary_r                 *binr;
        int                             i;
+       uint32_t                        contextID;
         uint32_t                        *obj_count;
        uint8_t                         *has_subobj;
        time_t                          unix_time;
        NTTIME                          nt_time;
        struct FILETIME                 *ft;
 
+       contextID = emsmdbp_get_contextID(object);
+
        folder = (struct emsmdbp_object_folder *) object->object.folder;
         for (i = 0; i < properties->cValues; i++) {
                 if (properties->aulPropTag[i] == PR_CONTENT_COUNT) {
                         /* a hack to avoid fetching dynamic fields from openchange.ldb */
                         obj_count = talloc_zero(data_pointers, uint32_t);
-                        retval = mapistore_folder_get_message_count(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(object), object->backend_object,
-                                                                   MAPISTORE_MESSAGE_TABLE, obj_count);
+                        retval = mapistore_folder_get_child_count(emsmdbp_ctx->mstore_ctx, contextID, object->backend_object, MAPISTORE_MESSAGE_TABLE, obj_count);
                        if (!retval) {
                                data_pointers[i] = obj_count;
                        }
@@ -1814,8 +2640,8 @@ static int emsmdbp_object_get_properties_mapistore_root(TALLOC_CTX *mem_ctx, str
                }
                 else if (properties->aulPropTag[i] == PR_ASSOC_CONTENT_COUNT) {
                         obj_count = talloc_zero(data_pointers, uint32_t);
-                        retval = mapistore_folder_get_message_count(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(object), object->backend_object,
-                                                                   MAPISTORE_FAI_TABLE, obj_count);
+                        retval = mapistore_folder_get_child_count(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(object), object->backend_object,
+                                                                 MAPISTORE_FAI_TABLE, obj_count);
                        if (!retval) {
                                data_pointers[i] = obj_count;
                        }
@@ -1854,10 +2680,20 @@ static int emsmdbp_object_get_properties_mapistore_root(TALLOC_CTX *mem_ctx, str
                        data_pointers[i] = ft;
                        retval = MAPI_E_SUCCESS;
                }
+               else if (properties->aulPropTag[i] == PR_ACCESS || properties->aulPropTag[i] == PR_ACCESS_LEVEL) {
+                       struct mapistore_property_data prop_data;
+
+                       mapistore_properties_get_properties(emsmdbp_ctx->mstore_ctx, contextID,
+                                                           object->backend_object,
+                                                           data_pointers,
+                                                           1,
+                                                           properties->aulPropTag + i,
+                                                           &prop_data);
+                       data_pointers[i] = prop_data.data;
+                       retval = prop_data.error;
+               }
                 else {
-                       retval = openchangedb_get_folder_property(data_pointers, emsmdbp_ctx->oc_ctx, 
-                                                                 emsmdbp_ctx->username, properties->aulPropTag[i],
-                                                                 folder->folderID, data_pointers + i);
+                       retval = openchangedb_get_folder_property(data_pointers, emsmdbp_ctx->oc_ctx, properties->aulPropTag[i], folder->folderID, data_pointers + i);
                 }
                retvals[i] = retval;
         }
@@ -1901,9 +2737,7 @@ static int emsmdbp_object_get_properties_mailbox(TALLOC_CTX *mem_ctx, struct ems
                        }
                        break;
                default:
-                       retvals[i] = openchangedb_get_folder_property(data_pointers, emsmdbp_ctx->oc_ctx,
-                                                                     emsmdbp_ctx->username, properties->aulPropTag[i],
-                                                                     object->object.mailbox->folderID, data_pointers + i);
+                       retvals[i] = openchangedb_get_folder_property(data_pointers, emsmdbp_ctx->oc_ctx, properties->aulPropTag[i], object->object.mailbox->folderID, data_pointers + i);
                }
        }
 
@@ -1972,6 +2806,10 @@ _PUBLIC_ void **emsmdbp_object_get_properties(TALLOC_CTX *mem_ctx, struct emsmdb
         * dispatcher db, not mapistore */
        if (object && object->type == EMSMDBP_OBJECT_FOLDER &&
            object->object.folder->mapistore_root == true) {
+               if (object->object.folder->postponed_props) {
+                       emsmdbp_object_folder_commit_creation(emsmdbp_ctx, object, true);
+               }
+
                retval = emsmdbp_object_get_properties_mapistore_root(mem_ctx, emsmdbp_ctx, object, properties, data_pointers, retvals);
        } else {
                mapistore = emsmdbp_is_mapistore(object);
@@ -2020,8 +2858,10 @@ _PUBLIC_ void **emsmdbp_object_get_properties(TALLOC_CTX *mem_ctx, struct emsmdb
 /* TODO: handling of "property problems" */
 _PUBLIC_ int emsmdbp_object_set_properties(struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *object, struct SRow *rowp)
 {
-       uint32_t contextID;
-       bool mapistore;
+       uint32_t                contextID, new_cvalues;
+       bool                    mapistore;
+       enum mapistore_error    ret;
+       struct SRow             *postponed_props;
 
        /* Sanity checks */
        if (!emsmdbp_ctx) return MAPI_E_CALL_FAILED;
@@ -2035,6 +2875,24 @@ _PUBLIC_ int emsmdbp_object_set_properties(struct emsmdbp_context *emsmdbp_ctx,
                return MAPI_E_NO_SUPPORT;
        }
 
+       if (object->type == EMSMDBP_OBJECT_FOLDER) {
+               postponed_props = object->object.folder->postponed_props;
+               if (postponed_props) {
+                       new_cvalues = postponed_props->cValues + rowp->cValues;
+                       postponed_props->lpProps = talloc_realloc(postponed_props, postponed_props->lpProps, struct SPropValue, new_cvalues);
+                       mapi_copy_spropvalues(postponed_props, rowp->lpProps, postponed_props->lpProps + postponed_props->cValues, rowp->cValues);
+                       postponed_props->cValues = new_cvalues;
+
+                       ret = emsmdbp_object_folder_commit_creation(emsmdbp_ctx, object, false);
+                       if (ret == MAPISTORE_SUCCESS) {
+                               return MAPI_E_SUCCESS;
+                       }
+                       else {
+                               return MAPI_E_NOT_FOUND;
+                       }
+               }
+       }
+
        /* Temporary hack: If this is a mapistore root container
         * (e.g. Inbox, Calendar etc.), directly stored under
         * IPM.Subtree, then set properties from openchange
@@ -2042,6 +2900,8 @@ _PUBLIC_ int emsmdbp_object_set_properties(struct emsmdbp_context *emsmdbp_ctx,
        if (object->type == EMSMDBP_OBJECT_FOLDER
            && object->object.folder->mapistore_root == true) {
                openchangedb_set_folder_properties(emsmdbp_ctx->oc_ctx, object->object.folder->folderID, rowp);
+               contextID = emsmdbp_get_contextID(object);
+               mapistore_properties_set_properties(emsmdbp_ctx->mstore_ctx, contextID, object->backend_object, rowp);
        }
        else {
                contextID = emsmdbp_get_contextID(object);
diff --git a/mapiproxy/servers/default/emsmdb/emsmdbp_provisioning.c b/mapiproxy/servers/default/emsmdb/emsmdbp_provisioning.c
new file mode 100644 (file)
index 0000000..a78ed3c
--- /dev/null
@@ -0,0 +1,536 @@
+/*
+   OpenChange Server implementation
+
+   EMSMDBP: EMSMDB Provider implementation
+
+   Copyright (C) Wolfgang Sourdeau 2012
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+   \file emsmdbp_provisioning.c
+
+   \brief Account provisioning
+ */
+
+#include <ctype.h>
+#include <string.h>
+#include <sys/mman.h>
+
+
+#include "dcesrv_exchange_emsmdb.h"
+
+#include <gen_ndr/ndr_property.h>
+
+_PUBLIC_ enum MAPISTATUS emsmdbp_mailbox_provision_public_freebusy(struct emsmdbp_context *emsmdbp_ctx, const char *EssDN)
+{
+       enum MAPISTATUS         ret;
+       char                    *dn_root, *dn_user, *cn_ptr;
+       uint64_t                public_fb_fid, group_fid, fb_mid, change_num;
+       size_t                  i, max;
+       void                    *message_object;
+       struct SRow             property_row;
+       TALLOC_CTX              *mem_ctx;
+
+       mem_ctx = talloc_zero(NULL, TALLOC_CTX);
+
+       dn_root = talloc_asprintf(mem_ctx, "EX:%s", EssDN);
+       cn_ptr = strstr(dn_root, "/cn");
+       if (!cn_ptr) {
+               ret = MAPI_E_INVALID_PARAMETER;
+               goto end;
+       }
+
+       dn_user = talloc_asprintf(mem_ctx, "USER-%s", cn_ptr);
+       *cn_ptr = 0;
+
+       /* convert dn_root to lowercase */
+       max = cn_ptr - dn_root;
+       for (i = 3; i < max; i++) {
+               dn_root[i] = tolower(dn_root[i]);
+       }
+
+       /* convert dn_user to uppercase. Yes, it's stupid like that. */
+       max = strlen(dn_user);
+       for (i = 5; i < max; i++) {
+               dn_user[i] = toupper(dn_user[i]);
+       }
+
+       ret = openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, EMSMDBP_PF_FREEBUSY, &public_fb_fid);
+       if (ret != MAPI_E_SUCCESS) {
+               DEBUG(5, ("provisioning: freebusy root folder not found in openchange.ldb\n"));
+               goto end;
+       }
+
+       ret = openchangedb_get_fid_by_name(emsmdbp_ctx->oc_ctx, public_fb_fid, dn_root, &group_fid);
+       if (ret != MAPI_E_SUCCESS) {
+               openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, &group_fid);
+               openchangedb_get_new_changeNumber(emsmdbp_ctx->oc_ctx, &change_num);
+               openchangedb_create_folder(emsmdbp_ctx->oc_ctx, public_fb_fid, group_fid, change_num, NULL, -1);
+       }
+
+       ret = openchangedb_get_mid_by_subject(emsmdbp_ctx->oc_ctx, group_fid, dn_user, false, &fb_mid);
+       if (ret != MAPI_E_SUCCESS) {
+               openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, &fb_mid);
+               openchangedb_get_new_changeNumber(emsmdbp_ctx->oc_ctx, &change_num);
+               openchangedb_message_create(mem_ctx, emsmdbp_ctx->oc_ctx, fb_mid, group_fid, false, &message_object);
+               property_row.cValues = 1;
+               property_row.lpProps = talloc_zero(mem_ctx, struct SPropValue);
+               property_row.lpProps[0].ulPropTag = PR_NORMALIZED_SUBJECT_UNICODE;
+               property_row.lpProps[0].value.lpszW = dn_user;
+               openchangedb_message_set_properties(mem_ctx, message_object, &property_row);
+               openchangedb_message_save(message_object, 0);
+       }
+
+       ret = MAPI_E_SUCCESS;
+
+end:
+       talloc_free(mem_ctx);
+
+       return ret;
+}
+
+_PUBLIC_ enum MAPISTATUS emsmdbp_mailbox_provision(struct emsmdbp_context *emsmdbp_ctx, const char *username)
+{
+/* auto-provisioning:
+
+  During private logon:
+   - fetch list of available folders from all backends + list of capabilities (handled folder types) + fallback entry
+   - if fallback is not available: FAIL
+   - fetch list of existing folders from openchangedb
+   - if mailbox does not exist:
+    - create basic structure
+    - if certain folders are not available (Inbox, Deleted Items, Spooler Queue, Outbox), use fallback
+   - synchronize list of non-mandatory and secondary folders
+    - update relevant entry ids in relevant objects
+   - ability to leave creation of fallback and other url to the relevant backend
+   - freebusy entry
+
+  folder creation = createfolder + setprops (class) + release
+
+
+* RopLogon entries (mandatory) (autoprovisioning)
+
+mailbox (Root): (None)
+
+"Common Views": (None) (sogo://wsourdeau:wsourdeau@common-views/)          -> fallback
+"Deferred Action": (None) (sogo://wsourdeau:wsourdeau@deferred-actions/)   -> fallback
+"Search" (Finder): None (sogo://wsourdeau:wsourdeau@search/)               -> fallback
+"Schedule": (None) (sogo://wsourdeau:wsourdeau@schedule/)                  -> fallback
+"Shortcuts": (None) (sogo://wsourdeau:wsourdeau@shortcuts/)                -> fallback
+"Spooler Queue": (None) (sogo://wsourdeau:wsourdeau@spooler-queue/)        -> fallback
+"Views": (sogo://wsourdeau:wsourdeau@views/)                               -> fallback
+
+"IPM Subtree" (Top of Personal Folders): (None)
+
+* autoprovisioning backend based
+
+"Inbox": IPF.Note (sogo://wsourdeau:wsourdeau@inbox/)
+"Outbox": IPF.Note (sogo://wsourdeau:wsourdeau@outbox/)
+"Sent Items": IPF.Note (sogo://wsourdeau:wsourdeau@sent-items/)
+"Deleted Items": IPF.Note (sogo://wsourdeau:wsourdeau@deleted-items/)
+
+* additional special folders
+"Calendar": IPF.Appointment (PidTagIpmAppointmentEntryId)
+"Contacts": IPF.Contact (PidTagIpmContactEntryId)
+"Notes": IPF.StickyNote (PidTagIpmNoteEntryId)
+"Tasks": IPF.Task (PidTagIpmTaskEntryId)
+"Journal": IPF.Journal (PidTagIpmJournalEntryId)
+"Drafts": IPF.Note (PidTagIpmDraftsEntryId)
+
+* client-created:
+
+"Freebusy Data": 
+"Reminders": Outlook.Reminder (sogo://wsourdeau:wsourdeau@reminders/)  (PidTagRemindersOnlineEntryId)    -> fallback
+"To-Do blabnla"
+"Sync Issues": IPF.Note (PidTagAdditionalRenEntryIds)
+"Junk E-mail": IPF.Note (PidTagAdditionalRenEntryIds)
+...
+
+
+
+Exchange hierarchy for virgin account:
+
+FolderId: 0x67ca828f02000001      Display Name: "                        ";  Container Class: MAPI_E_NOT_FOUND;        Message Class: MAPI_E_NOT_FOUND; Has Subfolders: TRUE; 
+
+  FolderId: 0x71ca828f02000001    Display Name: "            Common Views";  Container Class: MAPI_E_NOT_FOUND;        Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; 
+  FolderId: 0x69ca828f02000001    Display Name: "         Deferred Action";  Container Class: MAPI_E_NOT_FOUND;        Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; 
+  FolderId: 0x6fca828f02000001    Display Name: "                  Finder";  Container Class: MAPI_E_NOT_FOUND;        Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; 
+  FolderId: 0x72ca828f02000001    Display Name: "                Schedule";  Container Class: MAPI_E_NOT_FOUND;        Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; 
+  FolderId: 0x73ca828f02000001    Display Name: "               Shortcuts";  Container Class: MAPI_E_NOT_FOUND;        Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; 
+  FolderId: 0x6aca828f02000001    Display Name: "           Spooler Queue";  Container Class: MAPI_E_NOT_FOUND;        Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; 
+  FolderId: 0x70ca828f02000001    Display Name: "                   Views";  Container Class: MAPI_E_NOT_FOUND;        Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; 
+
+  FolderId: 0x68ca828f02000001    Display Name: "Top of Information Store";  Container Class: MAPI_E_NOT_FOUND;        Message Class: MAPI_E_NOT_FOUND; Has Subfolders: TRUE; 
+
+    FolderId: 0x6bca828f02000001  Display Name: "      Boîte de réception";  Container Class: "            IPF.Note";  Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; 
+    FolderId: 0x6cca828f02000001  Display Name: "           Boîte d'envoi";  Container Class: "            IPF.Note";  Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; 
+    FolderId: 0x67c3828f02000001  Display Name: "              Brouillons";  Container Class: "            IPF.Note";  Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; 
+    FolderId: 0x65c3828f02000001  Display Name: "              Calendrier";  Container Class: "     IPF.Appointment";  Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; 
+    FolderId: 0x66c3828f02000001  Display Name: "                Contacts";  Container Class: "         IPF.Contact";  Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; 
+    FolderId: 0x6dca828f02000001  Display Name: "        Ã‰léments envoyés";  Container Class: "            IPF.Note";  Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; 
+    FolderId: 0x6eca828f02000001  Display Name: "      Ã‰léments supprimés";  Container Class: "            IPF.Note";  Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; 
+    FolderId: 0x68c3828f02000001  Display Name: "                 Journal";  Container Class: "         IPF.Journal";  Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; 
+    FolderId: 0x69c3828f02000001  Display Name: "                   Notes";  Container Class: "      IPF.StickyNote";  Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; 
+    FolderId: 0x6ac3828f02000001  Display Name: "                  Tâches";  Container Class: "            IPF.Task";  Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; 
+
+
+
+ */
+       TALLOC_CTX                              *mem_ctx;
+       enum MAPISTATUS                         ret;
+       enum mapistore_error                    retval;
+       struct mapistore_contexts_list          *contexts_list;
+       struct WStringArray_r                   *existing_uris;
+       struct mapistore_contexts_list          *main_entries[MAPISTORE_MAX_ROLES], *secondary_entries[MAPISTORE_MAX_ROLES], *next_entry, *current_entry;
+       static const char                       *folder_names[] = {NULL, "Root", "Deferred Action", "Spooler Queue", "Common Views", "Schedule", "Finder", "Views", "Shortcuts", "Top of Information Store", "Inbox", "Outbox", "Sent Items", "Deleted Items"};
+       static struct emsmdbp_special_folder    special_folders[] = {{MAPISTORE_DRAFTS_ROLE, PR_IPM_DRAFTS_ENTRYID, "Drafts"},
+                                                                    {MAPISTORE_CALENDAR_ROLE, PR_IPM_APPOINTMENT_ENTRYID, "Calendar"},
+                                                                    {MAPISTORE_CONTACTS_ROLE, PR_IPM_CONTACT_ENTRYID, "Contacts"},
+                                                                    {MAPISTORE_TASKS_ROLE, PR_IPM_TASK_ENTRYID, "Tasks"},
+                                                                    {MAPISTORE_NOTES_ROLE, PR_IPM_NOTE_ENTRYID, "Notes"},
+                                                                    {MAPISTORE_JOURNAL_ROLE, PR_IPM_JOURNAL_ENTRYID, "Journal"}};
+       const char                              **container_classes;
+       uint32_t                                context_id;
+       uint64_t                                mailbox_fid = 0, ipm_fid, inbox_fid = 0, current_fid, found_fid, current_cn;
+       char                                    *fallback_url, *entryid_dump;
+       const char                              *mapistore_url, *current_name, *base_name;
+       struct emsmdbp_special_folder           *current_folder;
+       struct SRow                             property_row;
+       int                                     i, j, nbr_special_folders = sizeof(special_folders) / sizeof(struct emsmdbp_special_folder);
+       DATA_BLOB                               entryid_data;
+       struct FolderEntryId                    folder_entryid;
+       struct Binary_r                         *entryId;
+       bool                                    exists;
+       void                                    *backend_object;
+
+       mem_ctx = talloc_zero(NULL, TALLOC_CTX);
+
+       ldb_transaction_start(emsmdbp_ctx->oc_ctx);
+
+       /* Retrieve list of folders from backends */
+       retval = mapistore_list_contexts_for_user(emsmdbp_ctx->mstore_ctx, username, mem_ctx, &contexts_list);
+       if (retval != MAPISTORE_SUCCESS) {
+               talloc_free(mem_ctx);
+               return MAPI_E_DISK_ERROR;
+       }
+
+       /* Fix mapistore uris in returned entries */
+       current_entry = contexts_list;
+       while (current_entry) {
+               mapistore_url = current_entry->url;
+               if (mapistore_url) {
+                       if (mapistore_url[strlen(mapistore_url)-1] != '/') {
+                               current_entry->url = talloc_asprintf(mem_ctx, "%s/", mapistore_url);
+                       }
+                       /* DEBUG(5, ("received entry: '%s' (%p)\n", current_entry->url, current_entry)); */
+               }
+               else {
+                       DEBUG(5, ("received entry without uri\n"));
+                       abort();
+               }
+               current_entry = current_entry->next;
+       }
+
+       /* Retrieve list of existing entries */
+       ret = openchangedb_get_MAPIStoreURIs(emsmdbp_ctx->oc_ctx, username, mem_ctx, &existing_uris);
+       if (ret == MAPI_E_SUCCESS) {
+               for (i = 0; i < existing_uris->cValues; i++) {
+                       /* DEBUG(5, ("checking entry '%s'\n", existing_uris->lppszW[i])); */
+                       exists = false;
+                       mapistore_url = existing_uris->lppszW[i];
+                       if (mapistore_url[strlen(mapistore_url)-1] != '/') {
+                               abort();
+                       }
+                       current_entry = contexts_list;
+                       while (!exists && current_entry) {
+                               /* DEBUG(5, ("  compare with '%s'\n", current_entry->url)); */
+                               if (strcmp(mapistore_url, current_entry->url) == 0) {
+                                       /* DEBUG(5, ("  entry found\n")); */
+                                       exists = true;
+                               }
+                               current_entry = current_entry->next;
+                       }
+                       if (!exists) {
+                               DEBUG(5, ("  removing entry '%s'\n", mapistore_url));
+                               openchangedb_get_fid(emsmdbp_ctx->oc_ctx, mapistore_url, &found_fid);
+                               openchangedb_delete_folder(emsmdbp_ctx->oc_ctx, found_fid);
+                       }
+               }
+       }
+
+       container_classes = talloc_array(mem_ctx, const char *, MAPISTORE_MAX_ROLES);
+       for (i = MAPISTORE_MAIL_ROLE; i < MAPISTORE_MAX_ROLES; i++) {
+               container_classes[i] = "IPF.Note";
+       }
+       container_classes[MAPISTORE_CALENDAR_ROLE] = "IPF.Appointment";
+       container_classes[MAPISTORE_CONTACTS_ROLE] = "IPF.Contact";
+       container_classes[MAPISTORE_TASKS_ROLE] = "IPF.Task";
+       container_classes[MAPISTORE_NOTES_ROLE] = "IPF.StickyNote";
+       container_classes[MAPISTORE_JOURNAL_ROLE] = "IPF.Journal";
+
+       memset(&property_row, 0, sizeof(struct SRow));
+       memset(main_entries, 0, sizeof(struct mapistore_contexts_list *) * MAPISTORE_MAX_ROLES);
+       memset(secondary_entries, 0, sizeof(struct mapistore_contexts_list *) * MAPISTORE_MAX_ROLES);
+
+       /* Sort them between our main_entries and secondary_entries */
+       current_entry = contexts_list;
+       while (current_entry) {
+               next_entry = current_entry->next;
+               current_entry->next = NULL;
+               current_entry->prev = NULL;
+               if (current_entry->main_folder) {
+                       if (main_entries[current_entry->role]) {
+                               DEBUG(5, ("duplicate entry for role %d ignored\n  existing entry: %s\n  current entry: %s\n",
+                                         current_entry->role, main_entries[current_entry->role]->url, current_entry->url));
+                       }
+                       else {
+                               main_entries[current_entry->role] = current_entry;
+                       }
+               }
+               else {
+                       DLIST_ADD_END(secondary_entries[current_entry->role], current_entry, void);
+               }
+               current_entry = next_entry;
+       }
+
+       /* Fallback role MUST exist */
+       if (!main_entries[MAPISTORE_FALLBACK_ROLE]) {
+               DEBUG(5, ("No fallback provisioning role was found while such role is mandatory. Provisiong must be done manually.\n"));
+               talloc_free(mem_ctx);
+               return MAPI_E_DISK_ERROR;
+       }
+       fallback_url = main_entries[MAPISTORE_FALLBACK_ROLE]->url;
+       if (fallback_url[strlen(fallback_url)-1] != '/') {
+               fallback_url = talloc_asprintf(mem_ctx, "%s/", fallback_url);
+       }
+
+       /* Mailbox and subfolders */
+       ret = openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_MAILBOX_ROOT, &mailbox_fid);
+       if (ret != MAPI_E_SUCCESS) {
+               openchangedb_create_mailbox(emsmdbp_ctx->oc_ctx, username, EMSMDBP_MAILBOX_ROOT, &mailbox_fid);
+       }
+       property_row.lpProps = talloc_array(mem_ctx, struct SPropValue, 2); /* allocate max needed until the end of the function */
+       property_row.cValues = 1;
+       property_row.lpProps[0].ulPropTag = PR_DISPLAY_NAME_UNICODE;
+       for (i = EMSMDBP_DEFERRED_ACTION; i < EMSMDBP_TOP_INFORMATION_STORE; i++) {
+               /* TODO: mapistore_tag change */
+               ret = openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, i, &current_fid);
+               if (ret != MAPI_E_SUCCESS) {
+                       openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, &current_fid);
+                       openchangedb_get_new_changeNumber(emsmdbp_ctx->oc_ctx, &current_cn);
+                       mapistore_url = talloc_asprintf(mem_ctx, "%s0x%"PRIx64"/", fallback_url, current_fid);
+                       openchangedb_create_folder(emsmdbp_ctx->oc_ctx, mailbox_fid, current_fid, current_cn, mapistore_url, i);
+                       property_row.lpProps->value.lpszW = folder_names[i];
+                       openchangedb_set_folder_properties(emsmdbp_ctx->oc_ctx, current_fid, &property_row);
+
+                       /* instantiate the new folder in the backend to make sure it is initialized properly */
+                       retval = mapistore_add_context(emsmdbp_ctx->mstore_ctx, username, mapistore_url, current_fid, &context_id, &backend_object);
+                       mapistore_indexing_record_add_fid(emsmdbp_ctx->mstore_ctx, context_id, username, current_fid);
+               }
+       }
+
+       /* IPM and subfolders */
+       ret = openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_TOP_INFORMATION_STORE, &ipm_fid);
+       if (ret != MAPI_E_SUCCESS) {
+               openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, &ipm_fid);
+               openchangedb_get_new_changeNumber(emsmdbp_ctx->oc_ctx, &current_cn);
+               property_row.cValues = 2;
+               property_row.lpProps[1].ulPropTag = PR_SUBFOLDERS;
+               property_row.lpProps[0].value.lpszW = folder_names[EMSMDBP_TOP_INFORMATION_STORE];
+               property_row.lpProps[1].value.b = true;
+               openchangedb_create_folder(emsmdbp_ctx->oc_ctx, mailbox_fid, ipm_fid, current_cn, NULL, EMSMDBP_TOP_INFORMATION_STORE);
+               openchangedb_set_folder_properties(emsmdbp_ctx->oc_ctx, ipm_fid, &property_row);
+               openchangedb_set_ReceiveFolder(emsmdbp_ctx->oc_ctx, username, "IPC", mailbox_fid);
+       }
+       property_row.cValues = 2;
+       property_row.lpProps[1].ulPropTag = PR_CONTAINER_CLASS_UNICODE;
+       property_row.lpProps[1].value.lpszW = "IPF.Note";
+       /* TODO: mapistore_url/mapistore_tag change */
+       for (i = EMSMDBP_INBOX; i < EMSMDBP_MAX_MAILBOX_SYSTEMIDX; i++) {
+               ret = openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, i, &current_fid);
+               if (ret == MAPI_E_SUCCESS) {
+                       if (i == EMSMDBP_INBOX) {
+                               inbox_fid = current_fid;
+                       }
+               } else {
+                       openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, &current_fid);
+                       openchangedb_get_new_changeNumber(emsmdbp_ctx->oc_ctx, &current_cn);
+                       current_name = folder_names[i];
+
+                       switch (i) {
+                       case EMSMDBP_INBOX:
+                               current_entry = main_entries[MAPISTORE_MAIL_ROLE];
+                               inbox_fid = current_fid;
+                               break;
+                       case EMSMDBP_OUTBOX:
+                               current_entry = main_entries[MAPISTORE_OUTBOX_ROLE];
+                               break;
+                       case EMSMDBP_SENT_ITEMS:
+                               current_entry = main_entries[MAPISTORE_SENTITEMS_ROLE];
+                               break;
+                       case EMSMDBP_DELETED_ITEMS:
+                               current_entry = main_entries[MAPISTORE_DELETEDITEMS_ROLE];
+                               break;
+                       default:
+                               current_entry = NULL;
+                       }
+
+                       if (current_entry) {
+                               if (current_entry->name) {
+                                       current_name = current_entry->name;
+                               }
+                               mapistore_url = current_entry->url;
+                       }
+                       else {
+                               mapistore_url = talloc_asprintf(mem_ctx, "%s0x%"PRIx64"/", fallback_url, current_fid);
+                       }
+
+                       /* Ensure the name is unique */
+                       base_name = current_name;
+                       j = 1;
+                       while (openchangedb_get_fid_by_name(emsmdbp_ctx->oc_ctx, ipm_fid, current_name, &found_fid) == MAPI_E_SUCCESS) {
+                               current_name = talloc_asprintf(mem_ctx, "%s (%d)", base_name, j);
+                               j++;
+                       }
+
+                       openchangedb_create_folder(emsmdbp_ctx->oc_ctx, ipm_fid, current_fid, current_cn, mapistore_url, i);
+                       property_row.lpProps[0].value.lpszW = current_name;
+                       openchangedb_set_folder_properties(emsmdbp_ctx->oc_ctx, current_fid, &property_row);
+
+                       /* instantiate the new folder in the backend to make sure it is initialized properly */
+                       retval = mapistore_add_context(emsmdbp_ctx->mstore_ctx, username, mapistore_url, current_fid, &context_id, &backend_object);
+                       mapistore_indexing_record_add_fid(emsmdbp_ctx->mstore_ctx, context_id, username, current_fid);
+
+                       if (i == EMSMDBP_INBOX) {
+                               /* set INBOX as receive folder for "All", "IPM", "Report.IPM" */
+                               openchangedb_set_ReceiveFolder(emsmdbp_ctx->oc_ctx, username, "All", inbox_fid);
+                               openchangedb_set_ReceiveFolder(emsmdbp_ctx->oc_ctx, username, "IPM", inbox_fid);
+                               openchangedb_set_ReceiveFolder(emsmdbp_ctx->oc_ctx, username, "Report.IPM", inbox_fid);
+                       }
+               }
+       }
+
+       /* Main special folders */
+       /* TODO: handle entryId change + mapistore_url/mapistore_tag change */
+
+       memset(&folder_entryid, 0, sizeof(struct FolderEntryId));
+       openchangedb_get_MailboxGuid(emsmdbp_ctx->oc_ctx, username, &folder_entryid.ProviderUID);
+       folder_entryid.FolderType = eitLTPrivateFolder;
+       openchangedb_get_MailboxReplica(emsmdbp_ctx->oc_ctx, username, NULL, &folder_entryid.FolderDatabaseGuid);
+
+       for (i = 0; i < nbr_special_folders; i++) {
+               current_folder = special_folders + i;
+               ret = openchangedb_get_folder_property(mem_ctx, emsmdbp_ctx->oc_ctx, current_folder->entryid_property, mailbox_fid, (void **) &entryId);
+               if (ret != MAPI_E_SUCCESS) {
+                       property_row.cValues = 2;
+                       property_row.lpProps[0].ulPropTag = PR_DISPLAY_NAME_UNICODE;
+
+                       openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, &current_fid);
+                       openchangedb_get_new_changeNumber(emsmdbp_ctx->oc_ctx, &current_cn);
+
+                       current_name = current_folder->name;
+                       current_entry = main_entries[current_folder->role];
+                       if (current_entry) {
+                               if (current_entry->name) {
+                                       current_name = current_entry->name;
+                               }
+                               mapistore_url = current_entry->url;
+                       }
+                       else {
+                               mapistore_url = talloc_asprintf(mem_ctx, "%s0x%"PRIx64"/", fallback_url, current_fid);
+                       }
+
+                       /* Ensure the name is unique */
+                       base_name = current_name;
+                       j = 1;
+                       while (openchangedb_get_fid_by_name(emsmdbp_ctx->oc_ctx, ipm_fid, current_name, &found_fid) == MAPI_E_SUCCESS) {
+                               current_name = talloc_asprintf(mem_ctx, "%s (%d)", base_name, j);
+                               j++;
+                       }
+
+                       property_row.lpProps[0].value.lpszW = current_name;
+                       property_row.lpProps[1].value.lpszW = container_classes[current_folder->role];
+                       openchangedb_create_folder(emsmdbp_ctx->oc_ctx, ipm_fid, current_fid, current_cn, mapistore_url, i);
+                       openchangedb_set_folder_properties(emsmdbp_ctx->oc_ctx, current_fid, &property_row);
+
+                       /* instantiate the new folder in the backend to make sure it is initialized properly */
+                       retval = mapistore_add_context(emsmdbp_ctx->mstore_ctx, username, mapistore_url, current_fid, &context_id, &backend_object);
+                       mapistore_indexing_record_add_fid(emsmdbp_ctx->mstore_ctx, context_id, username, current_fid);
+
+                       /* set entryid on mailbox and inbox */
+                       folder_entryid.FolderGlobalCounter.value = (current_fid >> 16);
+                       ndr_push_struct_blob(&entryid_data, mem_ctx, &folder_entryid, (ndr_push_flags_fn_t)ndr_push_FolderEntryId);
+                       property_row.cValues = 1;
+                       property_row.lpProps[0].ulPropTag = current_folder->entryid_property;
+                       property_row.lpProps[0].value.bin.cb = entryid_data.length;
+                       property_row.lpProps[0].value.bin.lpb = entryid_data.data;
+
+                       entryid_dump = ndr_print_struct_string(mem_ctx, (ndr_print_fn_t) ndr_print_FolderEntryId, current_name, &folder_entryid);
+                       DEBUG(5, ("%s\n", entryid_dump));
+
+                       openchangedb_set_folder_properties(emsmdbp_ctx->oc_ctx, mailbox_fid, &property_row);
+                       openchangedb_set_folder_properties(emsmdbp_ctx->oc_ctx, inbox_fid, &property_row);
+               }
+       }
+       /* DEBUG(5, ("size of operation: %ld\n", talloc_total_size(mem_ctx))); */
+
+       /* secondary folders */
+       property_row.cValues = 2;
+       property_row.lpProps[0].ulPropTag = PR_DISPLAY_NAME_UNICODE;
+
+       for (i = MAPISTORE_MAIL_ROLE; i < MAPISTORE_MAX_ROLES; i++) {
+               /* secondary fallback roles are only used for synchronization */
+               if (i == MAPISTORE_FALLBACK_ROLE) {
+                       continue;
+               }
+
+               property_row.lpProps[1].value.lpszW = container_classes[i];
+               current_entry = secondary_entries[i];
+               while (current_entry) {
+                       mapistore_url = current_entry->url;
+                       if (openchangedb_get_fid(emsmdbp_ctx->oc_ctx, mapistore_url, &found_fid) != MAPI_E_SUCCESS) {
+                               /* DEBUG(5, ("creating secondary entry '%s'\n", current_entry->url)); */
+                               openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, &current_fid);
+                               openchangedb_get_new_changeNumber(emsmdbp_ctx->oc_ctx, &current_cn);
+
+                               current_name = current_entry->name;
+                               /* Ensure the name is unique */
+                               base_name = current_name;
+                               j = 1;
+                               while (openchangedb_get_fid_by_name(emsmdbp_ctx->oc_ctx, ipm_fid, current_name, &found_fid) == MAPI_E_SUCCESS) {
+                                       current_name = talloc_asprintf(mem_ctx, "%s (%d)", base_name, j);
+                                       j++;
+                               }
+                               property_row.lpProps[0].value.lpszW = current_name;
+
+                               openchangedb_create_folder(emsmdbp_ctx->oc_ctx, ipm_fid, current_fid, current_cn, mapistore_url, -1);
+                               openchangedb_set_folder_properties(emsmdbp_ctx->oc_ctx, current_fid, &property_row);
+                       }
+                       else {
+                               /* DEBUG(5, ("secondary entry '%s' already exists\n", current_entry->url)); */
+                       }
+                       current_entry = current_entry->next;
+               }
+       }
+
+       ldb_transaction_commit(emsmdbp_ctx->oc_ctx);
+
+       /* TODO: rename/create/delete folders at IPM level */
+
+       talloc_free(mem_ctx);
+
+       return MAPI_E_SUCCESS;
+}
index 6597d05b480824816bdbdfed26ad2ddbf371c623..10bf55e400557eb7c4452ae5cd7c5753fb944083 100644 (file)
@@ -53,6 +53,7 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenFolder(TALLOC_CTX *mem_ctx,
                                               uint32_t *handles, uint16_t *size)
 {
        enum MAPISTATUS                 retval;
+       enum mapistore_error            ret;
        struct mapi_handles             *parent = NULL;
        struct mapi_handles             *rec = NULL;
         void                            *private_data;
@@ -100,9 +101,14 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenFolder(TALLOC_CTX *mem_ctx,
        response->IsGhosted = 0;
 
        mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
-       object = emsmdbp_object_open_folder_by_fid(rec, emsmdbp_ctx, parent_object, request->folder_id);
-       if (!object) {
-               mapi_repl->error_code = MAPI_E_NOT_FOUND;
+       ret = emsmdbp_object_open_folder_by_fid(rec, emsmdbp_ctx, parent_object, request->folder_id, &object);
+       if (ret != MAPISTORE_SUCCESS) {
+               if (ret == MAPISTORE_ERR_DENIED) {
+                       mapi_repl->error_code = MAPI_E_NO_ACCESS;
+               }
+               else {
+                       mapi_repl->error_code = MAPI_E_NOT_FOUND;
+               }
                goto end;
        }
        retval = mapi_handles_set_private_data(rec, object);
@@ -195,7 +201,7 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetHierarchyTable(TALLOC_CTX *mem_ctx,
        retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
        handles[mapi_repl->handle_idx] = rec->handle;
 
-       object = emsmdbp_folder_open_table(rec, parent_object, EMSMDBP_TABLE_FOLDER_TYPE, rec->handle);
+       object = emsmdbp_folder_open_table(rec, parent_object, MAPISTORE_FOLDER_TABLE, rec->handle);
        if (!object) {
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
                goto end;
@@ -309,11 +315,11 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetContentsTable(TALLOC_CTX *mem_ctx,
        folderID = parent_object->object.folder->folderID;
        if ((mapi_req->u.mapi_GetContentsTable.TableFlags & TableFlags_Associated)) {
                DEBUG(5, ("  table is FAI table\n"));
-               table_type = EMSMDBP_TABLE_FAI_TYPE;
+               table_type = MAPISTORE_FAI_TABLE;
        }
        else {
                DEBUG(5, ("  table is contents table\n"));
-               table_type = EMSMDBP_TABLE_MESSAGE_TYPE;
+               table_type = MAPISTORE_MESSAGE_TABLE;
        }
 
        /* Initialize Table object */
@@ -384,6 +390,7 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopCreateFolder(TALLOC_CTX *mem_ctx,
                                                 uint32_t *handles, uint16_t *size)
 {
        enum MAPISTATUS                 retval;
+       enum mapistore_error            ret;
        struct mapi_handles             *parent = NULL;
        uint32_t                        handle;
        uint64_t                        parent_fid, fid, cn;
@@ -444,8 +451,8 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopCreateFolder(TALLOC_CTX *mem_ctx,
 
        response->IsExistingFolder = false;
 
-       retval = emsmdbp_object_get_fid_by_name(emsmdbp_ctx, parent_object, request->FolderName.lpszW, &fid);
-       if (!retval) {
+       ret = emsmdbp_object_get_fid_by_name(emsmdbp_ctx, parent_object, request->FolderName.lpszW, &fid);
+       if (ret == MAPISTORE_SUCCESS) {
                if (request->ulFlags != OPEN_IF_EXISTS) {
                        mapi_repl->error_code = MAPI_E_COLLISION;
                        goto end;
@@ -453,14 +460,19 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopCreateFolder(TALLOC_CTX *mem_ctx,
                response->IsExistingFolder = true;
        }
 
-       /* Step 4. Do effective work here */
        mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
        if (response->IsExistingFolder) {
-               object = emsmdbp_object_open_folder_by_fid(rec, emsmdbp_ctx, parent_object, fid);
-               if (!object) {
+               ret = emsmdbp_object_open_folder_by_fid(rec, emsmdbp_ctx, parent_object, fid, &object);
+               if (ret != MAPISTORE_SUCCESS) {
                        DEBUG(5, (__location__": failure opening existing folder\n"));
                        mapi_handles_delete(emsmdbp_ctx->handles_ctx, rec->handle);
                        mapi_repl->error_code = retval;
+                       if (ret == MAPISTORE_ERR_DENIED) {
+                               mapi_repl->error_code = MAPI_E_NO_ACCESS;
+                       }
+                       else {
+                               mapi_repl->error_code = MAPI_E_CALL_FAILED;
+                       }
                        goto end;
                }
        }
@@ -517,49 +529,6 @@ end:
        return MAPI_E_SUCCESS;
 }
 
-static enum MAPISTATUS DoDeleteSystemFolder(struct emsmdbp_context *emsmdbp_ctx,
-                                           uint64_t parent_fid, uint64_t fid,
-                                           uint8_t flags)
-{
-       TALLOC_CTX                      *mem_ctx;
-       char                            *parentdn;
-       enum MAPISTATUS                 retval;
-       struct ldb_dn                   *dn;
-       char                            *dn_str;
-       int                             ret = 0;
-
-       DEBUG(4, ("exchange_emsmdb: [OXCFOLD] DeleteFolder parent FID: 0x%"PRIx64"\n", parent_fid));
-       DEBUG(4, ("exchange_emsmdb: [OXCFOLD] DeleteFolder target FID: 0x%"PRIx64"\n", fid));
-
-       mem_ctx = talloc_named(NULL, 0, "DoDeleteFolder");
-
-       /* TODO:
-               1. We should be careful not to delete special folders
-               2. We need to handle deleting associated folders and messages (based on the flags)
-       */
-       /* Retrieve dn of parentfolder */
-       retval = openchangedb_get_distinguishedName(mem_ctx, emsmdbp_ctx->oc_ctx, parent_fid, &parentdn);
-       OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
-
-       /* Create the folder dn record for openchange.ldb */
-       dn_str = talloc_asprintf(mem_ctx, "CN=%"PRIu64",%s", fid, parentdn);
-       DEBUG(4, ("exchange_emsmdb: [OXCFOLD] DeleteFolder target DN: %s\n", dn_str));
-       dn = ldb_dn_new(mem_ctx, emsmdbp_ctx->oc_ctx, dn_str);
-       talloc_free(dn_str);
-       OPENCHANGE_RETVAL_IF(!ldb_dn_validate(dn), MAPI_E_BAD_VALUE, mem_ctx);
-
-       ret = ldb_delete(emsmdbp_ctx->oc_ctx, dn);
-       if (ret != LDB_SUCCESS) {
-               DEBUG(4, ("exchange_emsmdb: [OXCFOLD] DeleteFolder failed ldb_delete, ret: 0x%x\n", ret));
-               talloc_free(mem_ctx);
-               return MAPI_E_NO_SUPPORT;
-       }
-
-       talloc_free(mem_ctx);
-       return MAPI_E_SUCCESS;
-}
-
-
 /**
    \details EcDoRpc DeleteFolder (0x1d) Rop. This operation deletes a
    folder on the remote server.
@@ -581,13 +550,11 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopDeleteFolder(TALLOC_CTX *mem_ctx,
                                                 uint32_t *handles, uint16_t *size)
 {
        enum MAPISTATUS         retval;
+       enum mapistore_error    ret;
        struct mapi_handles     *rec = NULL;
        uint32_t                handle;
        void                    *handle_priv_data;
        struct emsmdbp_object   *handle_object = NULL;
-       uint64_t                parent_fid = 0;
-       bool                    mapistore = false;
-       uint32_t                context_id;
 
        DEBUG(4, ("exchange_emsmdb: [OXCFOLD] DeleteFolder (0x1d)\n"));
 
@@ -623,37 +590,21 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopDeleteFolder(TALLOC_CTX *mem_ctx,
                return MAPI_E_SUCCESS;
        }
 
-       mapistore = emsmdbp_is_mapistore(handle_object);
-       switch (mapistore) {
-       case false:
-               /* system/special folder */
-               DEBUG(0, ("Deleting system/special folder\n"));
-               parent_fid = handle_object->object.folder->folderID;
-               mapi_repl->error_code = DoDeleteSystemFolder(emsmdbp_ctx, parent_fid,
-                                                            mapi_req->u.mapi_DeleteFolder.FolderId,
-                                                            mapi_req->u.mapi_DeleteFolder.DeleteFolderFlags);
-
-               break;
-       case true:
-               DEBUG(0, ("Deleting mapistore folder\n"));
-               /* handled by mapistore */
-               context_id = emsmdbp_get_contextID(handle_object);
-               retval = mapistore_folder_delete_folder(emsmdbp_ctx->mstore_ctx, context_id, handle_object->backend_object,
-                                                       mapi_req->u.mapi_DeleteFolder.FolderId,
-                                                       mapi_req->u.mapi_DeleteFolder.DeleteFolderFlags);
-               if (retval) {
-                         DEBUG(4, ("exchange_emsmdb: [OXCFOLD] DeleteFolder failed to delete fid 0x%.16"PRIx64" (0x%x)",
-                                   mapi_req->u.mapi_DeleteFolder.FolderId, retval));
-                         mapi_repl->error_code = MAPI_E_NOT_FOUND;
-               } else {
-                       mapi_repl->error_code = MAPI_E_SUCCESS;
-               }
-               break;
+       retval = MAPI_E_SUCCESS;
+       ret = emsmdbp_folder_delete(emsmdbp_ctx, handle_object, mapi_req->u.mapi_DeleteFolder.FolderId, mapi_req->u.mapi_DeleteFolder.DeleteFolderFlags);
+       if (ret == MAPISTORE_ERR_EXIST) {
+               mapi_repl->u.mapi_DeleteFolder.PartialCompletion = true;
        }
+       else if (ret != MAPISTORE_SUCCESS) {
+               DEBUG(4, ("exchange_emsmdb: [OXCFOLD] DeleteFolder failed to delete fid 0x%.16"PRIx64" (0x%x)",
+                         mapi_req->u.mapi_DeleteFolder.FolderId, retval));
+               retval = MAPI_E_NOT_FOUND;
+       }
+       mapi_repl->error_code = retval;
 
        *size += libmapiserver_RopDeleteFolder_size(mapi_repl);
 
-       return retval;
+       return MAPI_E_SUCCESS;
 }
 
 
@@ -727,8 +678,13 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopDeleteMessages(TALLOC_CTX *mem_ctx,
                uint64_t mid = mapi_req->u.mapi_DeleteMessages.message_ids[i];
                DEBUG(0, ("MID %i to delete: 0x%.16"PRIx64"\n", i, mid));
                ret = mapistore_folder_delete_message(emsmdbp_ctx->mstore_ctx, contextID, parent_object->backend_object, mid, MAPISTORE_SOFT_DELETE);
-               if (ret != MAPISTORE_SUCCESS) {
-                       mapi_repl->error_code = MAPI_E_CALL_FAILED;
+               if (ret != MAPISTORE_SUCCESS && ret != MAPISTORE_ERR_NOT_FOUND) {
+                       if (ret == MAPISTORE_ERR_DENIED) {
+                               mapi_repl->error_code = MAPI_E_NO_ACCESS;
+                       }
+                       else {
+                               mapi_repl->error_code = MAPI_E_CALL_FAILED;
+                       }
                        goto delete_message_response;
                }
 
@@ -844,15 +800,17 @@ static enum MAPISTATUS RopEmptyFolder_GenericFolder(TALLOC_CTX *mem_ctx,
                                                     struct EmptyFolder_repl *response,
                                                     struct mapi_handles *folder)
 {
+       enum MAPISTATUS         ret = MAPI_E_SUCCESS;
        void                    *folder_priv;
        struct emsmdbp_object   *folder_object = NULL;
        uint32_t                context_id;
-       int                     retval;
+       enum mapistore_error    retval;
        uint64_t                *childFolders;
        uint32_t                childFolderCount;
        uint32_t                i;
        uint8_t                 flags = DELETE_HARD_DELETE| DEL_MESSAGES | DEL_FOLDERS;
        TALLOC_CTX              *local_mem_ctx;
+       void                    *subfolder;
 
        /* Step 1. Retrieve the fid for the folder, given the handle */
        mapi_handles_get_private_data(folder, &folder_priv);
@@ -870,26 +828,34 @@ static enum MAPISTATUS RopEmptyFolder_GenericFolder(TALLOC_CTX *mem_ctx,
 
        local_mem_ctx = talloc_zero(NULL, TALLOC_CTX);
 
-       retval = mapistore_folder_get_child_fids(emsmdbp_ctx->mstore_ctx, context_id, folder_object->backend_object, local_mem_ctx,
-                                                &childFolders, &childFolderCount);
+       retval = mapistore_folder_get_child_fmids(emsmdbp_ctx->mstore_ctx, context_id, folder_object->backend_object, MAPISTORE_FOLDER_TABLE, local_mem_ctx,
+                                                 &childFolders, &childFolderCount);
        if (retval) {
                DEBUG(4, ("exchange_emsmdb: [OXCFOLD] EmptyFolder bad retval: 0x%x", retval));
-               return MAPI_E_NOT_FOUND;
+               ret = MAPI_E_NOT_FOUND;
+               goto end;
        }
 
        /* Step 3. Delete contents of the folder in mapistore */
        for (i = 0; i < childFolderCount; ++i) {
-               retval = mapistore_folder_delete_folder(emsmdbp_ctx->mstore_ctx, context_id, folder_object->backend_object, childFolders[i],
-                                                       flags);
+               retval = mapistore_folder_open_folder(emsmdbp_ctx->mstore_ctx, context_id, folder, local_mem_ctx, childFolders[i], &subfolder);
+               if (retval != MAPISTORE_SUCCESS) {
+                       ret = MAPI_E_NOT_FOUND;
+                       goto end;
+               }
+
+               retval = mapistore_folder_delete(emsmdbp_ctx->mstore_ctx, context_id, subfolder, flags);
                if (retval) {
                          DEBUG(4, ("exchange_emsmdb: [OXCFOLD] EmptyFolder failed to delete fid 0x%.16"PRIx64" (0x%x)", childFolders[i], retval));
-                         talloc_free(local_mem_ctx);
-                         return MAPI_E_NOT_FOUND;
+                         ret = MAPI_E_NOT_FOUND;
+                         goto end;
                }
        }
+
+end:
        talloc_free(local_mem_ctx);
 
-       return MAPI_E_SUCCESS;
+       return ret;
 }
 
 /**
index 2799ca71246d5efff6081f2d2dc2ffdf5bea9540..dc692d4e5ba0a19b55ab2bfd68dbfa7089686689 100644 (file)
@@ -162,10 +162,12 @@ static void oxcfxics_ndr_push_properties(struct ndr_push *ndr, struct ndr_push *
         struct MAPINAMEID       *nameid;
        struct BinaryArray_r    *bin_array;
        struct WStringArray_r   *unicode_array;
+       struct ShortArray_r     *short_array;
+       struct LongArray_r      *long_array;
+       struct I8Array_r        *i8_array;
        uint16_t                prop_type, propID;
         int                     retval;
 
-
         for (i = 0; i < properties->cValues; i++) {
                 if (retvals[i] == MAPI_E_SUCCESS) {
                         property = properties->aulPropTag[i];
@@ -198,6 +200,27 @@ static void oxcfxics_ndr_push_properties(struct ndr_push *ndr, struct ndr_push *
                                prop_type &= 0x0fff;
 
                                switch (prop_type) {
+                               case PT_SHORT:
+                                       short_array = data_pointers[i];
+                                       ndr_push_uint32(ndr, NDR_SCALARS, short_array->cValues);
+                                       for (j = 0; j < short_array->cValues; j++) {
+                                               oxcfxics_ndr_push_simple_data(ndr, prop_type, short_array->lpi + j);
+                                       }
+                                       break;
+                               case PT_LONG:
+                                       long_array = data_pointers[i];
+                                       ndr_push_uint32(ndr, NDR_SCALARS, long_array->cValues);
+                                       for (j = 0; j < long_array->cValues; j++) {
+                                               oxcfxics_ndr_push_simple_data(ndr, prop_type, long_array->lpl + j);
+                                       }
+                                       break;
+                               case PT_I8:
+                                       i8_array = data_pointers[i];
+                                       ndr_push_uint32(ndr, NDR_SCALARS, i8_array->cValues);
+                                       for (j = 0; j < i8_array->cValues; j++) {
+                                               oxcfxics_ndr_push_simple_data(ndr, prop_type, i8_array->lpi8 + j);
+                                       }
+                                       break;
                                case PT_BINARY:
                                        bin_array = data_pointers[i];
                                        ndr_push_uint32(ndr, NDR_SCALARS, bin_array->cValues);
@@ -213,7 +236,7 @@ static void oxcfxics_ndr_push_properties(struct ndr_push *ndr, struct ndr_push *
                                        }
                                        break;
                                default:
-                                       DEBUG(5, ("No handling for multi values of type %.4x\n", prop_type));
+                                       DEBUG(5, (__location__": no handling for multi values of type %.4x\n", prop_type));
                                        abort();
                                }
                        }
@@ -488,7 +511,7 @@ static void oxcfxics_push_messageChange_attachments(TALLOC_CTX *mem_ctx, struct
        static const int        prop_count = sizeof(prop_tags) / sizeof (enum MAPITAGS);
        struct SPropTagArray    query_props;
        uint32_t                i;
-       uint32_t                *retvals;
+       enum MAPISTATUS         *retvals;
        void                    **data_pointers;
 
        ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PR_FX_DEL_PROP);
@@ -566,7 +589,7 @@ static void oxcfxics_push_messageChange(TALLOC_CTX *mem_ctx, struct emsmdbp_cont
 {
        struct emsmdbp_object           *table_object, *message_object;
        uint32_t                        i, j;
-       uint32_t                        *retvals, *header_retvals;
+       enum MAPISTATUS                 *retvals, *header_retvals;
        void                            **data_pointers, **header_data_pointers;
        struct FILETIME                 *lm_time;
        NTTIME                          nt_time;
@@ -593,7 +616,7 @@ static void oxcfxics_push_messageChange(TALLOC_CTX *mem_ctx, struct emsmdbp_cont
                abort();
        }
 
-       if (sync_data->table_type == EMSMDBP_TABLE_FAI_TYPE) {
+       if (sync_data->table_type == MAPISTORE_FAI_TABLE) {
                original_cnset_seen = synccontext->cnset_seen_fai;
                properties = &synccontext->fai_properties;
        }
@@ -622,8 +645,8 @@ static void oxcfxics_push_messageChange(TALLOC_CTX *mem_ctx, struct emsmdbp_cont
                        oxcfxics_ndr_check(sync_data->cutmarks_ndr, "sync_data->cutmarks_ndr");
 
                        /** fixed header props */
-                       header_data_pointers = talloc_array(NULL, void *, 9);
-                       header_retvals = talloc_array(header_data_pointers, uint32_t, 9);
+                       header_data_pointers = talloc_array(data_pointers, void *, 9);
+                       header_retvals = talloc_array(header_data_pointers, enum MAPISTATUS, 9);
                        memset(header_retvals, 0, 9 * sizeof(uint32_t));
                        query_props.aulPropTag = talloc_array(header_data_pointers, enum MAPITAGS, 9);
 
@@ -634,9 +657,14 @@ static void oxcfxics_push_messageChange(TALLOC_CTX *mem_ctx, struct emsmdbp_cont
 
                        if (eid == 0x7fffffffffffffffLL) {
                                DEBUG(0, ("message without a valid eid\n"));
-                               talloc_free(header_data_pointers);
-                               continue;
+                               goto end_row;
                        }
+
+                       if (emsmdbp_object_message_open(data_pointers, emsmdbp_ctx, folder_object, folder_object->object.folder->folderID, eid, false, &message_object, &msg) != MAPISTORE_SUCCESS) {
+                               DEBUG(5, ("message '%.16"PRIx64"' could not be open, skipped\n", eid));
+                               goto end_row;
+                       }
+
                        emsmdbp_replid_to_guid(emsmdbp_ctx, owner, eid & 0xffff, &replica_guid);
                        RAWIDSET_push_guid_glob(sync_data->eid_set, &replica_guid, eid >> 16);
 
@@ -763,15 +791,11 @@ static void oxcfxics_push_messageChange(TALLOC_CTX *mem_ctx, struct emsmdbp_cont
                           embeddedMessage:
                           StartEmbed messageContent EndEmbed */
 
-                       message_object = emsmdbp_object_message_open(NULL, emsmdbp_ctx, folder_object, folder_object->object.folder->folderID, eid, &msg);
                        oxcfxics_push_messageChange_recipients(mem_ctx, emsmdbp_ctx, sync_data, message_object, msg);
                        oxcfxics_push_messageChange_attachments(mem_ctx, emsmdbp_ctx, sync_data, message_object);
-                       talloc_free(message_object);
 
                end_row:
-                       talloc_free(header_data_pointers);
                        talloc_free(data_pointers);
-                       talloc_free(retvals);
                }
                else {
                        DEBUG(5, ("no data returned for message row %d\n", i));
@@ -833,7 +857,7 @@ static void oxcfxics_prepare_synccontext_with_messageChange(TALLOC_CTX *mem_ctx,
        /* 2a. we build the message stream (normal messages) */
        if (synccontext->request.normal) {
                sync_data->cnset_seen = RAWIDSET_make(NULL, false, true);
-               sync_data->table_type = EMSMDBP_TABLE_MESSAGE_TYPE;
+               sync_data->table_type = MAPISTORE_MESSAGE_TABLE;
                oxcfxics_push_messageChange(mem_ctx, emsmdbp_ctx, synccontext, owner, sync_data, synccontext_object->parent_object);
                new_idset = RAWIDSET_convert_to_idset(NULL, sync_data->cnset_seen);
                old_idset = synccontext->cnset_seen;
@@ -848,7 +872,7 @@ static void oxcfxics_prepare_synccontext_with_messageChange(TALLOC_CTX *mem_ctx,
        /* 2b. we build the message stream (FAI messages) */
        if (synccontext->request.fai) {
                sync_data->cnset_seen = RAWIDSET_make(NULL, false, true);
-               sync_data->table_type = EMSMDBP_TABLE_FAI_TYPE;
+               sync_data->table_type = MAPISTORE_FAI_TABLE;
                oxcfxics_push_messageChange(mem_ctx, emsmdbp_ctx, synccontext, owner, sync_data, synccontext_object->parent_object);
                new_idset = RAWIDSET_convert_to_idset(NULL, sync_data->cnset_seen);
                old_idset = synccontext->cnset_seen_fai;
@@ -937,7 +961,7 @@ static void oxcfxics_push_folderChange(TALLOC_CTX *mem_ctx, struct emsmdbp_conte
        NTTIME                  nt_time;
        int32_t                 unix_time;
        uint32_t                i, j;
-       uint32_t                *retvals, *header_retvals;
+       enum MAPISTATUS         *retvals, *header_retvals;
        void                    **data_pointers, **header_data_pointers;
        struct SPropTagArray    query_props;
        TALLOC_CTX              *local_mem_ctx;
@@ -946,7 +970,7 @@ static void oxcfxics_push_folderChange(TALLOC_CTX *mem_ctx, struct emsmdbp_conte
        local_mem_ctx = talloc_zero(NULL, void);
 
        /* 2b. we build the stream */
-       table_object = emsmdbp_folder_open_table(local_mem_ctx, folder_object, EMSMDBP_TABLE_FOLDER_TYPE, 0); 
+       table_object = emsmdbp_folder_open_table(local_mem_ctx, folder_object, MAPISTORE_FOLDER_TABLE, 0); 
        if (!table_object) {
                DEBUG(5, ("folder does not handle hierarchy tables\n"));
                return;
@@ -966,7 +990,7 @@ static void oxcfxics_push_folderChange(TALLOC_CTX *mem_ctx, struct emsmdbp_conte
                if (data_pointers) {
                        /** fixed header props */
                        header_data_pointers = talloc_array(NULL, void *, 8);
-                       header_retvals = talloc_array(header_data_pointers, uint32_t, 8);
+                       header_retvals = talloc_array(header_data_pointers, enum MAPISTATUS, 8);
                        memset(header_retvals, 0, 8 * sizeof(uint32_t));
                        query_props.aulPropTag = talloc_array(header_data_pointers, enum MAPITAGS, 8);
 
@@ -1093,8 +1117,9 @@ static void oxcfxics_push_folderChange(TALLOC_CTX *mem_ctx, struct emsmdbp_conte
                        talloc_free(header_data_pointers);
                        talloc_free(data_pointers);
                        talloc_free(retvals);
-
-                       subfolder_object = emsmdbp_object_open_folder(NULL, emsmdbp_ctx, folder_object, eid);
+                       
+                       /* TODO: check return code */
+                       emsmdbp_object_open_folder(NULL, emsmdbp_ctx, folder_object, eid, &subfolder_object);
                        oxcfxics_push_folderChange(mem_ctx, emsmdbp_ctx, synccontext, owner, topmost_folder_object, sync_data, subfolder_object);
                        talloc_free(subfolder_object);
                }
@@ -1474,20 +1499,20 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncConfigure(TALLOC_CTX *mem_ctx,
        }
 
        /* Explicit exclusions */
-       properties_exclusion[PR_ROW_TYPE >> 16] = true;
-       properties_exclusion[PR_INSTANCE_KEY >> 16] = true;
-       properties_exclusion[PR_INSTANCE_NUM >> 16] = true;
-       properties_exclusion[PR_INST_ID >> 16] = true;
-       properties_exclusion[PR_FID >> 16] = true;
-       properties_exclusion[PR_MID >> 16] = true;
-       properties_exclusion[PR_SOURCE_KEY >> 16] = true;
-       properties_exclusion[PR_PARENT_SOURCE_KEY >> 16] = true;
-       properties_exclusion[PR_PARENT_FID >> 16] = true;
+       properties_exclusion[(uint16_t) (PR_ROW_TYPE >> 16)] = true;
+       properties_exclusion[(uint16_t) (PR_INSTANCE_KEY >> 16)] = true;
+       properties_exclusion[(uint16_t) (PR_INSTANCE_NUM >> 16)] = true;
+       properties_exclusion[(uint16_t) (PR_INST_ID >> 16)] = true;
+       properties_exclusion[(uint16_t) (PR_FID >> 16)] = true;
+       properties_exclusion[(uint16_t) (PR_MID >> 16)] = true;
+       properties_exclusion[(uint16_t) (PR_SOURCE_KEY >> 16)] = true;
+       properties_exclusion[(uint16_t) (PR_PARENT_SOURCE_KEY >> 16)] = true;
+       properties_exclusion[(uint16_t) (PR_PARENT_FID >> 16)] = true;
 
        /* Include or exclude specified properties passed in array */
        include_props = ((request->SynchronizationFlag & SynchronizationFlag_OnlySpecifiedProperties));
        for (j = 0; j < request->PropertyTags.cValues; j++) {
-               i = (request->PropertyTags.aulPropTag[j] & 0xffff0000) >> 16;
+               i = (uint16_t) (request->PropertyTags.aulPropTag[j] >> 16);
                if (!properties_exclusion[i]) {
                        properties_exclusion[i] = true; /* avoid including the same prop twice */
                        if (include_props) {
@@ -1506,7 +1531,7 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncConfigure(TALLOC_CTX *mem_ctx,
        if (!include_props) {
                if (synccontext->request.contents_mode) {
                        if (synccontext->request.normal) {
-                               table_object = emsmdbp_folder_open_table(NULL, folder_object, EMSMDBP_TABLE_MESSAGE_TYPE, 0);
+                               table_object = emsmdbp_folder_open_table(NULL, folder_object, MAPISTORE_MESSAGE_TABLE, 0);
                                if (!table_object) {
                                        DEBUG(5, ("could not open message table\n"));
                                        abort();
@@ -1529,7 +1554,7 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncConfigure(TALLOC_CTX *mem_ctx,
                                synccontext->fai_properties.cValues = synccontext->properties.cValues;
                                synccontext->fai_properties.aulPropTag = talloc_memdup(synccontext, synccontext->properties.aulPropTag, synccontext->properties.cValues * sizeof (enum MAPITAGS));
 
-                               table_object = emsmdbp_folder_open_table(NULL, folder_object, EMSMDBP_TABLE_FAI_TYPE, 0);
+                               table_object = emsmdbp_folder_open_table(NULL, folder_object, MAPISTORE_FAI_TABLE, 0);
                                if (!table_object) {
                                        DEBUG(5, ("could not open FAI table\n"));
                                        abort();
@@ -1549,7 +1574,7 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncConfigure(TALLOC_CTX *mem_ctx,
                        }
                }
                else {
-                       table_object = emsmdbp_folder_open_table(NULL, folder_object, EMSMDBP_TABLE_FOLDER_TYPE, 0);
+                       table_object = emsmdbp_folder_open_table(NULL, folder_object, MAPISTORE_FOLDER_TABLE, 0);
                        if (!table_object) {
                                DEBUG(5, ("could not open folder table\n"));
                                abort();
@@ -1604,6 +1629,7 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncImportMessageChange(TALLOC_CTX *mem_ctx,
                                                            uint32_t *handles, uint16_t *size)
 {
        enum MAPISTATUS                         retval;
+       enum mapistore_error                    ret;
        struct mapi_handles                     *synccontext_object_handle = NULL, *message_object_handle;
        struct emsmdbp_object                   *synccontext_object = NULL, *message_object;
        uint32_t                                synccontext_handle_id, message_handle_id;
@@ -1617,7 +1643,6 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncImportMessageChange(TALLOC_CTX *mem_ctx,
        struct mapistore_message                *msg;
        struct SRow                             aRow;
 
-
        DEBUG(4, ("exchange_emsmdb: [OXCFXICS] RopSyncImportMessageChange (0x72)\n"));
 
        /* Sanity checks */
@@ -1670,8 +1695,8 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncImportMessageChange(TALLOC_CTX *mem_ctx,
        retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, message_handle_id, &message_object_handle);
        handles[mapi_repl->handle_idx] = message_object_handle->handle;
 
-       message_object = emsmdbp_object_message_open(message_object_handle, emsmdbp_ctx, synccontext_object->parent_object, folderID, messageID, &msg);
-       if (!message_object) {
+       ret = emsmdbp_object_message_open(message_object_handle, emsmdbp_ctx, synccontext_object->parent_object, folderID, messageID, true, &message_object, &msg);
+       if (ret == MAPISTORE_ERR_NOT_FOUND) {
                message_object = emsmdbp_object_message_init(message_object_handle, emsmdbp_ctx, messageID, synccontext_object->parent_object);
                if (mapistore_folder_create_message(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(synccontext_object->parent_object), synccontext_object->parent_object->backend_object, message_object, messageID, (request->ImportFlag & ImportFlag_Associated), &message_object->backend_object)) {
                        mapi_handles_delete(emsmdbp_ctx->handles_ctx, message_object_handle->handle);
@@ -1679,7 +1704,19 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncImportMessageChange(TALLOC_CTX *mem_ctx,
                        mapi_repl->error_code = MAPI_E_NOT_FOUND;
                        goto end;
                }
+               message_object->object.message->read_write = true;
        }
+       else if (ret != MAPISTORE_SUCCESS) {
+               mapi_handles_delete(emsmdbp_ctx->handles_ctx, message_object_handle->handle);
+               if (ret == MAPISTORE_ERR_DENIED) {
+                       mapi_repl->error_code = MAPI_E_NO_ACCESS;
+               }
+               else {
+                       mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
+               }
+               goto end;
+       }
+
        mapi_handles_set_private_data(message_object_handle, message_object);
 
        response->MessageId = 0; /* Must be set to 0 */
@@ -1795,12 +1832,12 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncImportHierarchyChange(TALLOC_CTX *mem_ct
                folder_was_open = true;
        }
        else {
-               parent_folder = emsmdbp_object_open_folder_by_fid(NULL, emsmdbp_ctx, synccontext_object->parent_object, parentFolderID);
+               /* TODO: check return code */
+               emsmdbp_object_open_folder_by_fid(NULL, emsmdbp_ctx, synccontext_object->parent_object, parentFolderID, &parent_folder);
                folder_was_open = false;
        }
 
-       folder_object = emsmdbp_object_open_folder(NULL, emsmdbp_ctx, parent_folder, folderID);
-       if (!folder_object) {
+       if (emsmdbp_object_open_folder(NULL, emsmdbp_ctx, parent_folder, folderID, &folder_object) != MAPISTORE_SUCCESS) {
                retval = openchangedb_get_new_changeNumber(emsmdbp_ctx->oc_ctx, &cn);
                if (retval) {
                        DEBUG(5, (__location__": unable to obtain a change number\n"));
@@ -1810,11 +1847,12 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncImportHierarchyChange(TALLOC_CTX *mem_ct
                }
                aRow.lpProps[aRow.cValues].ulPropTag = PR_CHANGE_NUM;
                aRow.lpProps[aRow.cValues].value.d = cn;
+               aRow.cValues++;
                retval = emsmdbp_object_create_folder(emsmdbp_ctx, parent_folder, NULL, folderID, &aRow, &folder_object);
                if (retval) {
+                       mapi_repl->error_code = retval;
                        DEBUG(5, (__location__": folder creation failed\n"));
                        folder_object = NULL;
-                       mapi_repl->error_code = MAPI_E_NO_SUPPORT;
                        goto end;
                }
        }
@@ -1906,12 +1944,6 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncImportDeletes(TALLOC_CTX *mem_ctx,
 
        request = &mapi_req->u.mapi_SyncImportDeletes;
 
-       if (request->Flags & SyncImportDeletes_Hierarchy) {
-               DEBUG(5, ("  hierarchy deletes not supported yet\n"));
-               mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
-               goto end;
-       }
-
        if (request->Flags & SyncImportDeletes_HardDelete) {
                delete_type = MAPISTORE_PERMANENT_DELETE;
        }
@@ -1919,27 +1951,39 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncImportDeletes(TALLOC_CTX *mem_ctx,
                delete_type = MAPISTORE_SOFT_DELETE;
        }
 
-       if (!emsmdbp_is_mapistore(synccontext_object)) {
-               DEBUG(5, ("  no message deletes on non-mapistore store\n"));
-               mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
-               goto end;
-       }
-
-       contextID = emsmdbp_get_contextID(synccontext_object);
        owner = emsmdbp_get_owner(synccontext_object);
        openchangedb_get_MailboxReplica(emsmdbp_ctx->oc_ctx, owner, &repl_id, &replica_guid);
 
-       object_array = &request->PropertyValues.lpProps[0].value.MVbin;
-       for (i = 0; i < object_array->cValues; i++) {
-               ret = oxcfxics_fmid_from_source_key(emsmdbp_ctx, owner, object_array->bin + i, &objectID);
-               if (ret == MAPISTORE_SUCCESS) {
-                       ret = mapistore_folder_delete_message(emsmdbp_ctx->mstore_ctx, contextID, synccontext_object->parent_object->backend_object, objectID, delete_type);
-                       if (ret != MAPISTORE_SUCCESS) {
-                               DEBUG(5, ("message deletion failed for fmid: 0x%.16"PRIx64"\n", objectID));
+       if (request->Flags & SyncImportDeletes_Hierarchy) {
+               object_array = &request->PropertyValues.lpProps[0].value.MVbin;
+               for (i = 0; i < object_array->cValues; i++) {
+                       ret = oxcfxics_fmid_from_source_key(emsmdbp_ctx, owner, object_array->bin + i, &objectID);
+                       if (ret == MAPISTORE_SUCCESS) {
+                               emsmdbp_folder_delete(emsmdbp_ctx, synccontext_object->parent_object, objectID, 0xff);
                        }
-                       ret = mapistore_indexing_record_del_mid(emsmdbp_ctx->mstore_ctx, contextID, owner, objectID, delete_type);
-                       if (ret != MAPISTORE_SUCCESS) {
-                               DEBUG(5, ("message deletion of index record failed for fmid: 0x%.16"PRIx64"\n", objectID));
+               }
+       }
+       else {
+               if (!emsmdbp_is_mapistore(synccontext_object)) {
+                       DEBUG(5, ("  no message deletes on non-mapistore store\n"));
+                       mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
+                       goto end;
+               }
+
+               contextID = emsmdbp_get_contextID(synccontext_object);
+
+               object_array = &request->PropertyValues.lpProps[0].value.MVbin;
+               for (i = 0; i < object_array->cValues; i++) {
+                       ret = oxcfxics_fmid_from_source_key(emsmdbp_ctx, owner, object_array->bin + i, &objectID);
+                       if (ret == MAPISTORE_SUCCESS) {
+                               ret = mapistore_folder_delete_message(emsmdbp_ctx->mstore_ctx, contextID, synccontext_object->parent_object->backend_object, objectID, delete_type);
+                               if (ret != MAPISTORE_SUCCESS) {
+                                       DEBUG(5, ("message deletion failed for fmid: 0x%.16"PRIx64"\n", objectID));
+                               }
+                               ret = mapistore_indexing_record_del_mid(emsmdbp_ctx->mstore_ctx, contextID, owner, objectID, delete_type);
+                               if (ret != MAPISTORE_SUCCESS) {
+                                       DEBUG(5, ("message deletion of index record failed for fmid: 0x%.16"PRIx64"\n", objectID));
+                               }
                        }
                }
        }
@@ -2329,8 +2373,7 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncImportMessageMove(TALLOC_CTX *mem_ctx,
                goto end;
        }
 
-       source_folder_object = emsmdbp_object_open_folder_by_fid(NULL, emsmdbp_ctx, synccontext_object, sourceFID);
-       if (!source_folder_object) {
+       if (emsmdbp_object_open_folder_by_fid(NULL, emsmdbp_ctx, synccontext_object, sourceFID, &source_folder_object) != MAPISTORE_SUCCESS) {
                mapi_repl->error_code = MAPI_E_NOT_FOUND;
                goto end;
        }
@@ -2492,7 +2535,7 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetLocalReplicaIds(TALLOC_CTX *mem_ctx,
 
        request = &mapi_req->u.mapi_GetLocalReplicaIds;
 
-       emsmdbp_replid_to_guid(emsmdbp_ctx, mailbox_object->object.mailbox->owner_Name, 0x0001, &mapi_repl->u.mapi_GetLocalReplicaIds.ReplGuid);
+       emsmdbp_replid_to_guid(emsmdbp_ctx, mailbox_object->object.mailbox->owner_username, 0x0001, &mapi_repl->u.mapi_GetLocalReplicaIds.ReplGuid);
        openchangedb_reserve_fmid_range(emsmdbp_ctx->oc_ctx, request->IdCount, &new_id);
        new_id >>= 16;
        for (i = 0; i < 6 ; i++) {
@@ -2507,18 +2550,18 @@ end:
 }
 
 /**
-   \details Retrieve a MessageReadStates structure from a binary blob
+   \details Retrieve a MessageReadState structure from a binary blob
 
    \param mem_ctx pointer to the memory context
-   \param bin pointer to the Binary_r structure with raw MessageReadStates data
+   \param bin pointer to the Binary_r structure with raw MessageReadState data
 
-   \return Allocated MessageReadStates structure on success, otherwise NULL
+   \return Allocated MessageReadState structure on success, otherwise NULL
 
-   \note Developers must free the allocated MessageReadStates when finished.
+   \note Developers must free the allocated MessageReadState when finished.
  */
-static struct MessageReadStates *get_MessageReadStates(TALLOC_CTX *mem_ctx, struct Binary_r *bin)
+static struct MessageReadState *get_MessageReadState(TALLOC_CTX *mem_ctx, struct Binary_r *bin)
 {
-       struct MessageReadStates        *message_read_states = NULL;
+       struct MessageReadState *message_read_states = NULL;
        struct ndr_pull                 *ndr;
        enum ndr_err_code               ndr_err_code;
 
@@ -2533,8 +2576,8 @@ static struct MessageReadStates *get_MessageReadStates(TALLOC_CTX *mem_ctx, stru
        ndr->data_size = bin->cb;
 
        ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
-       message_read_states = talloc_zero(mem_ctx, struct MessageReadStates);
-       ndr_err_code = ndr_pull_MessageReadStates(ndr, NDR_SCALARS, message_read_states);
+       message_read_states = talloc_zero(mem_ctx, struct MessageReadState);
+       ndr_err_code = ndr_pull_MessageReadState(ndr, NDR_SCALARS, message_read_states);
 
        /* talloc_free(ndr); */
 
@@ -2570,7 +2613,8 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncImportReadStateChanges(TALLOC_CTX *mem_c
        struct mapi_handles                     *synccontext_rec;
        struct emsmdbp_object                   *synccontext_object, *folder_object, *message_object;
        enum MAPISTATUS                         retval;
-       struct MessageReadStates                *read_states;
+       enum mapistore_error                    ret;
+       struct MessageReadState                 *read_states;
        uint32_t                                read_states_size;
        struct Binary_r                         *bin_data;
        char                                    *owner;
@@ -2579,6 +2623,7 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncImportReadStateChanges(TALLOC_CTX *mem_c
        int                                     i;
        struct mapistore_message                *msg;
        struct GUID                             guid;
+       DATA_BLOB                               guid_blob = { .length = 16, .data = NULL };
        uint8_t                                 flag;
 
        DEBUG(4, ("exchange_emsmdb: [OXCSTOR] SyncImportReadStateChanges (0x80)\n"));
@@ -2620,9 +2665,14 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncImportReadStateChanges(TALLOC_CTX *mem_c
                bin_data->cb = request->MessageReadStates.length;
                bin_data->lpb = request->MessageReadStates.data;
                while (bin_data->cb) {
-                       read_states = get_MessageReadStates(mem_ctx, bin_data);
+                       read_states = get_MessageReadState(mem_ctx, bin_data);
                        read_states_size = read_states->MessageIdSize + 3;
-                       if (GUID_from_string((char *) read_states->MessageId, &guid).v != 0) {
+
+                       bin_data->cb -= read_states_size;
+                       bin_data->lpb += read_states_size;
+
+                       guid_blob.data = read_states->MessageId;
+                       if (GUID_from_data_blob(&guid_blob, &guid).v != 0) {
                                continue;
                        }
                        owner = emsmdbp_get_owner(synccontext_object);
@@ -2646,14 +2696,11 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncImportReadStateChanges(TALLOC_CTX *mem_c
                                flag = CLEAR_READ_FLAG | CLEAR_NRN_PENDING;
                        }
 
-                       message_object = emsmdbp_object_message_open(NULL, emsmdbp_ctx, folder_object, folder_object->object.folder->folderID, mid, &msg);
-                       if (message_object) {
+                       ret = emsmdbp_object_message_open(NULL, emsmdbp_ctx, folder_object, folder_object->object.folder->folderID, mid, true, &message_object, &msg);
+                       if (ret == MAPISTORE_SUCCESS) {
                                mapistore_message_set_read_flag(emsmdbp_ctx->mstore_ctx, contextID, message_object->backend_object, flag);
                                talloc_free(message_object);
                        }
-
-                       bin_data->cb -= read_states_size;
-                       bin_data->lpb += read_states_size;
                }
        }
        else {
@@ -2674,7 +2721,7 @@ static void oxcfxics_fill_transfer_state_arrays(TALLOC_CTX *mem_ctx, struct emsm
        uint64_t                        eid, cn;
        uint32_t                        i, nr_eid;
        void                            **data_pointers;
-       uint32_t                        *retvals;
+       enum MAPISTATUS                 *retvals;
        struct emsmdbp_object           *table_object, *subfolder_object;
        struct emsmdbp_object_table     *table;
        uint32_t                        unix_time;
@@ -2690,13 +2737,13 @@ static void oxcfxics_fill_transfer_state_arrays(TALLOC_CTX *mem_ctx, struct emsm
        count_query_props->cValues = 1;
        count_query_props->aulPropTag = talloc_zero(count_query_props, enum MAPITAGS);
        switch (sync_data->table_type) {
-       case EMSMDBP_TABLE_FOLDER_TYPE:
+       case MAPISTORE_FOLDER_TABLE:
                count_query_props->aulPropTag[0] = PR_FOLDER_CHILD_COUNT;
                break;
-       case EMSMDBP_TABLE_MESSAGE_TYPE:
+       case MAPISTORE_MESSAGE_TABLE:
                count_query_props->aulPropTag[0] = PR_CONTENT_COUNT;
                break;
-       case EMSMDBP_TABLE_FAI_TYPE:
+       case MAPISTORE_FAI_TABLE:
                count_query_props->aulPropTag[0] = PR_ASSOC_CONTENT_COUNT;
                break;
        default:
@@ -2759,8 +2806,9 @@ static void oxcfxics_fill_transfer_state_arrays(TALLOC_CTX *mem_ctx, struct emsm
                        talloc_free(retvals);
                        talloc_free(data_pointers);
 
-                       if (sync_data->table_type == EMSMDBP_TABLE_FOLDER_TYPE) {
-                               subfolder_object = emsmdbp_object_open_folder(local_mem_ctx, emsmdbp_ctx, folder_object, eid);
+                       if (sync_data->table_type == MAPISTORE_FOLDER_TABLE) {
+                               /* TODO: check return code */
+                               emsmdbp_object_open_folder(local_mem_ctx, emsmdbp_ctx, folder_object, eid, &subfolder_object);
                                oxcfxics_fill_transfer_state_arrays(mem_ctx, emsmdbp_ctx, synccontext, owner, sync_data, subfolder_object);
                                talloc_free(subfolder_object);
                        }
@@ -2802,18 +2850,18 @@ static void oxcfxics_ndr_push_transfer_state(struct ndr_push *ndr, const char *o
                synccontext->properties.aulPropTag[0] = PR_MID;
 
                if (synccontext->request.normal) {
-                       sync_data->table_type = EMSMDBP_TABLE_MESSAGE_TYPE;
+                       sync_data->table_type = MAPISTORE_MESSAGE_TABLE;
                        oxcfxics_fill_transfer_state_arrays(mem_ctx, emsmdbp_ctx, synccontext, owner, sync_data, synccontext_object->parent_object);
                }
 
                if (synccontext->request.fai) {
-                       sync_data->table_type = EMSMDBP_TABLE_FAI_TYPE;
+                       sync_data->table_type = MAPISTORE_FAI_TABLE;
                        oxcfxics_fill_transfer_state_arrays(mem_ctx, emsmdbp_ctx, synccontext, owner, sync_data, synccontext_object->parent_object);
                }
        }
        else {
                synccontext->properties.aulPropTag[0] = PR_FID;
-               sync_data->table_type = EMSMDBP_TABLE_FOLDER_TYPE;
+               sync_data->table_type = MAPISTORE_FOLDER_TABLE;
 
                oxcfxics_fill_transfer_state_arrays(mem_ctx, emsmdbp_ctx, synccontext, owner, sync_data, synccontext_object->parent_object);
        }
index 7650ef7a436f14604b7b71cf938ebcc95a30e842..9a13cd2f17f44f7ecda1ad24945798986425764c 100644 (file)
@@ -181,7 +181,7 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenMessage(TALLOC_CTX *mem_ctx,
 {
        struct OpenMessage_req          *request;
        struct OpenMessage_repl         *response;
-       /* int                          ret; */
+       enum mapistore_error            ret;
        enum MAPISTATUS                 retval;
        uint32_t                        parent_handle_id;
        struct mapi_handles             *object_handle = NULL;
@@ -231,8 +231,7 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenMessage(TALLOC_CTX *mem_ctx,
        /* OpenMessage can only be called for mailbox/folder objects */
        if (!(context_object->type == EMSMDBP_OBJECT_MAILBOX || context_object->type == EMSMDBP_OBJECT_FOLDER)) {
                mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
-               *size += libmapiserver_RopOpenMessage_size(NULL);
-               return MAPI_E_SUCCESS;
+               goto end;
        }
 
        messageID = request->MessageId;
@@ -241,17 +240,34 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenMessage(TALLOC_CTX *mem_ctx,
        /* Initialize Message object */
        handle = handles[mapi_req->handle_idx];
        retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &object_handle);
-       object = emsmdbp_object_message_open(object_handle, emsmdbp_ctx, context_object, folderID, messageID, &msg);
-       if (!object) {
+
+       if (request->OpenModeFlags == ReadOnly) {
+               ret = emsmdbp_object_message_open(object_handle, emsmdbp_ctx, context_object, folderID, messageID, false, &object, &msg);
+       }
+       else if (request->OpenModeFlags == OpenSoftDelete) {
+               ret = MAPISTORE_ERROR;
+       }
+       else { /* ReadWrite/BestAccess */
+               ret = emsmdbp_object_message_open(object_handle, emsmdbp_ctx, context_object, folderID, messageID, true, &object, &msg);
+               if (ret == MAPISTORE_ERR_DENIED && request->OpenModeFlags == BestAccess) {
+                       ret = emsmdbp_object_message_open(object_handle, emsmdbp_ctx, context_object, folderID, messageID, false, &object, &msg);
+               }
+       }
+
+       if (ret != MAPISTORE_SUCCESS) {
                mapi_handles_delete(emsmdbp_ctx->handles_ctx, object_handle->handle);
-               if ((request->OpenModeFlags & Create)) {
-                       mapi_repl->error_code = MAPI_E_NO_SUPPORT;
+               if (ret == MAPISTORE_ERR_DENIED) {
+                       mapi_repl->error_code = MAPI_E_NO_ACCESS;
                }
-               else {
+               else if (ret == MAPISTORE_ERR_NOT_FOUND) {
                        mapi_repl->error_code = MAPI_E_NOT_FOUND;
                }
+               else {
+                       mapi_repl->error_code = MAPI_E_CALL_FAILED;
+               }
                goto end;
        }
+
        handles[mapi_repl->handle_idx] = object_handle->handle;
        retval = mapi_handles_set_private_data(object_handle, object);
 
@@ -324,6 +340,7 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopCreateMessage(TALLOC_CTX *mem_ctx,
                                                  uint32_t *handles, uint16_t *size)
 {
        enum MAPISTATUS                 retval;
+       enum mapistore_error            ret;
        struct mapi_handles             *context_handle = NULL;
        struct mapi_handles             *message_handle = NULL;
        struct emsmdbp_object           *context_object = NULL;
@@ -337,6 +354,7 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopCreateMessage(TALLOC_CTX *mem_ctx,
        struct SRow                     aRow;
        uint32_t                        pt_long;
        bool                            pt_boolean;
+       struct SBinary_short            *pt_binary;
        struct timeval                  tv;
        struct FILETIME                 ft;
        NTTIME                          time;
@@ -374,7 +392,16 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopCreateMessage(TALLOC_CTX *mem_ctx,
        folderID = mapi_req->u.mapi_CreateMessage.FolderId;
 
        /* Step 1. Retrieve parent handle in the hierarchy */
-       folder_object = emsmdbp_object_open_folder_by_fid(mem_ctx, emsmdbp_ctx, context_object, folderID);
+       ret = emsmdbp_object_open_folder_by_fid(mem_ctx, emsmdbp_ctx, context_object, folderID, &folder_object);
+       if (ret != MAPISTORE_SUCCESS) {
+               if (ret == MAPISTORE_ERR_DENIED) {
+                       mapi_repl->error_code = MAPI_E_NO_ACCESS;
+               }
+               else {
+                       mapi_repl->error_code = MAPI_E_NO_SUPPORT;
+               }
+               goto end;
+       }
 
        /* This should be handled differently here: temporary hack */
        retval = openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, &messageID);
@@ -391,15 +418,28 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopCreateMessage(TALLOC_CTX *mem_ctx,
        handles[mapi_repl->handle_idx] = message_handle->handle;
 
        message_object = emsmdbp_object_message_init((TALLOC_CTX *)message_handle, emsmdbp_ctx, messageID, folder_object);
+       message_object->object.message->read_write = true;
+
        contextID = emsmdbp_get_contextID(folder_object);
        mapistore = emsmdbp_is_mapistore(folder_object);
        switch (mapistore) {
        case true:
-               retval = mapistore_folder_create_message(emsmdbp_ctx->mstore_ctx, contextID, 
-                                                        folder_object->backend_object, message_object, 
-                                                        messageID, mapi_req->u.mapi_CreateMessage.AssociatedFlag, 
-                                                        &message_object->backend_object);
-               DEBUG(5, ("mapistore_folder_create_message returned 0x%.8x\n", retval));
+               ret = mapistore_folder_create_message(emsmdbp_ctx->mstore_ctx, contextID, 
+                                                     folder_object->backend_object, message_object, 
+                                                     messageID, mapi_req->u.mapi_CreateMessage.AssociatedFlag, 
+                                                     &message_object->backend_object);
+               if (ret != MAPISTORE_SUCCESS) {
+                       if (ret == MAPISTORE_ERR_DENIED) {
+                               mapi_repl->error_code = MAPI_E_NO_ACCESS;
+                       }
+                       else if (ret == MAPISTORE_ERR_NOT_FOUND) {
+                               mapi_repl->error_code = MAPI_E_NOT_FOUND;
+                       }
+                       else {
+                               mapi_repl->error_code = MAPI_E_CALL_FAILED;
+                       }
+                       goto end;
+               }
                break;
        case false:
                retval = openchangedb_message_create(emsmdbp_ctx->mstore_ctx, 
@@ -413,38 +453,78 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopCreateMessage(TALLOC_CTX *mem_ctx,
        retval = mapi_handles_set_private_data(message_handle, message_object);
 
        /* Set default properties for message: MS-OXCMSG 3.2.5.2 */
-       aRow.lpProps = talloc_array(mem_ctx, struct SPropValue, 2);
+       aRow.ulAdrEntryPad = 0;
+       aRow.lpProps = talloc_array(mem_ctx, struct SPropValue, 23);
        aRow.cValues = 0;
 
        pt_long = 0x1;
-       aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_IMPORTANCE, (const void *)&pt_long);
-       aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_MESSAGE_CLASS, (const void *)"IPM.Note");
+       set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_IMPORTANCE, (const void *)&pt_long);
+       aRow.cValues++;
+       set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_MESSAGE_CLASS_UNICODE, (const void *)"IPM.Note");
+       aRow.cValues++;
        pt_long = 0x0;
-       aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_SENSITIVITY, (const void *)&pt_long);
+       set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_SENSITIVITY, (const void *)&pt_long);
+       aRow.cValues++;
+       set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_DISPLAY_TO_UNICODE, (const void *)"");
+       aRow.cValues++;
+       set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_DISPLAY_CC_UNICODE, (const void *)"");
+       aRow.cValues++;
+       set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_DISPLAY_BCC_UNICODE, (const void *)"");
+       aRow.cValues++;
        pt_long = 0x9;
-       aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_MESSAGE_FLAGS, (const void *)&pt_long);
+       set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_MESSAGE_FLAGS, (const void *)&pt_long);
+       aRow.cValues++;
+
        pt_boolean = false;
-       aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_HASATTACH, (const void *)&pt_boolean);
-       aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_URL_COMP_NAME_SET, (const void *)&pt_boolean);
+       set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_HASATTACH, (const void *)&pt_boolean);
+       aRow.cValues++;
+       set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_HAS_NAMED_PROPERTIES, (const void *)&pt_boolean);
+       aRow.cValues++;
+       set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_URL_COMP_NAME_SET, (const void *)&pt_boolean);
+       aRow.cValues++;
+
        pt_long = 0x1;
-       aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_TRUST_SENDER, (const void *)&pt_long);
+       set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_TRUST_SENDER, (const void *)&pt_long);
+       aRow.cValues++;
        pt_long = 0x3;
-       aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_ACCESS, (const void *)&pt_long);
+       set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_ACCESS, (const void *)&pt_long);
+       aRow.cValues++;
        pt_long = 0x1;
-       aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_ACCESS_LEVEL, (const void *)&pt_long);
-       aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_URL_COMP_NAME, (const void *)"No Subject.EML");
+       set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_ACCESS_LEVEL, (const void *)&pt_long);
+       aRow.cValues++;
+       set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_URL_COMP_NAME_UNICODE, (const void *)"No Subject.EML");
+       aRow.cValues++;
 
        gettimeofday(&tv, NULL);
        time = timeval_to_nttime(&tv);
        ft.dwLowDateTime = (time << 32) >> 32;
        ft.dwHighDateTime = time >> 32;         
-       aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_CREATION_TIME, (const void *)&ft);
-       aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_LAST_MODIFICATION_TIME, (const void *)&ft);
-       aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_LOCAL_COMMIT_TIME, (const void *)&ft);
-       aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_MESSAGE_LOCALE_ID, (const void *)&mapi_req->u.mapi_CreateMessage.CodePageId);
-       aRow.lpProps = add_SPropValue(mem_ctx, aRow.lpProps, &aRow.cValues, PR_LOCALE_ID, (const void *)&mapi_req->u.mapi_CreateMessage.CodePageId);
-
-       /* TODO: some required properties are not set: PidTagSearchKey, PidTagCreatorName, ... */
+       set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_CREATION_TIME, (const void *)&ft);
+       aRow.cValues++;
+       set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_LAST_MODIFICATION_TIME, (const void *)&ft);
+       aRow.cValues++;
+       set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_LOCAL_COMMIT_TIME, (const void *)&ft);
+       aRow.cValues++;
+
+       /* we copy CodePageId (uint16_t) into an uint32_t to avoid a buffer error */
+       pt_long = mapi_req->u.mapi_CreateMessage.CodePageId;
+       set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_MESSAGE_LOCALE_ID, (const void *)&pt_long);
+       aRow.cValues++;
+       set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_LOCALE_ID, (const void *)&pt_long);
+       aRow.cValues++;
+
+       set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_CREATOR_NAME_UNICODE, (const void *)emsmdbp_ctx->szDisplayName);
+       aRow.cValues++;
+       set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_LAST_MODIFIER_NAME_UNICODE, (const void *)emsmdbp_ctx->szDisplayName);
+       aRow.cValues++;
+       pt_binary = talloc_zero(mem_ctx, struct SBinary_short);
+       entryid_set_AB_EntryID(pt_binary, emsmdbp_ctx->szUserDN, pt_binary);
+       set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_CREATOR_ENTRYID, (const void *)pt_binary);
+       aRow.cValues++;
+       set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_LAST_MODIFIER_ENTRYID, (const void *)pt_binary);
+       aRow.cValues++;
+
+       /* TODO: some required properties are not set: PidTagSearchKey, PidTagMessageSize, PidTagSecurityDescriptor */
        emsmdbp_object_set_properties(emsmdbp_ctx, message_object, &aRow);
 
        DEBUG(0, ("CreateMessage: 0x%.16"PRIx64": mapistore = %s\n", folderID, mapistore ? "true" : "false"));
@@ -489,6 +569,7 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSaveChangesMessage(TALLOC_CTX *mem_ctx,
        uint32_t                contextID;
        char                    *owner;
        uint8_t                 flags;
+       enum mapistore_error    ret;
 
        DEBUG(4, ("exchange_emsmdb: [OXCMSG] SaveChangesMessage (0x0c)\n"));
 
@@ -528,9 +609,13 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSaveChangesMessage(TALLOC_CTX *mem_ctx,
        case true:
                 contextID = emsmdbp_get_contextID(object);
                messageID = object->object.message->messageID;
-               mapistore_message_save(emsmdbp_ctx->mstore_ctx, contextID, object->backend_object);
+               ret = mapistore_message_save(emsmdbp_ctx->mstore_ctx, contextID, object->backend_object);
+               if (ret == MAPISTORE_ERR_DENIED) {
+                       mapi_repl->error_code = MAPI_E_NO_ACCESS;
+                       goto end;
+               }
                owner = emsmdbp_get_owner(object);
-                mapistore_indexing_record_add_mid(emsmdbp_ctx->mstore_ctx, contextID, owner, messageID);
+               mapistore_indexing_record_add_mid(emsmdbp_ctx->mstore_ctx, contextID, owner, messageID);
                break;
        }
 
@@ -723,6 +808,7 @@ static void oxcmsg_parse_ModifyRecipientRow(TALLOC_CTX *mem_ctx, struct ModifyRe
                                       &dest_len);
                        uni_value[dest_len] = 0;
                        dest_value = uni_value;
+                       value_size += 2;
                        break;
                case PT_BINARY:
                        bin_value = talloc_zero(recipient->data, struct Binary_r);
@@ -1369,6 +1455,7 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenEmbeddedMessage(TALLOC_CTX *mem_ctx,
                                                         struct EcDoRpc_MAPI_REPL *mapi_repl,
                                                         uint32_t *handles, uint16_t *size)
 {
+       enum mapistore_error            ret;
        enum MAPISTATUS                 retval;
         uint32_t                        handle;
         uint32_t                        contextID;
@@ -1428,11 +1515,11 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenEmbeddedMessage(TALLOC_CTX *mem_ctx,
                 }
 
                contextID = emsmdbp_get_contextID(attachment_object);
-               retval = mapistore_message_attachment_open_embedded_message(emsmdbp_ctx->mstore_ctx, contextID, attachment_object->backend_object,
+               ret = mapistore_message_attachment_open_embedded_message(emsmdbp_ctx->mstore_ctx, contextID, attachment_object->backend_object,
                                                                            NULL, &backend_attachment_message,
                                                                            &messageID,
                                                                            &msg);
-                if (retval != MAPISTORE_SUCCESS) {
+                if (ret != MAPISTORE_SUCCESS) {
                        mapi_repl->error_code = MAPI_E_NOT_FOUND;
                        goto end;
                 }
index 8c4360b036093ea0c1d4745a09f245b6fd2f8964..ded2b50bafe26980b4eb6d1b3ca1ea7133fdbd6d 100644 (file)
@@ -100,7 +100,7 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPermissionsTable(TALLOC_CTX *mem_ctx,
        handles[mapi_repl->handle_idx] = rec->handle;
        
        if (emsmdbp_is_mapistore(parent_object)) {
-               object = emsmdbp_folder_open_table(rec, parent_object, EMSMDBP_TABLE_PERMISSIONS_TYPE, mapi_repl->handle_idx);
+               object = emsmdbp_folder_open_table(rec, parent_object, MAPISTORE_PERMISSIONS_TABLE, mapi_repl->handle_idx);
        }
        else {
                object = emsmdbp_object_table_init((TALLOC_CTX *)rec, emsmdbp_ctx, parent_object);
index e2a5df4c00d93d77edc8574b0a0466aa100bfa97..92accaa1aad770bd51dbe5600af728d71f726bfb 100644 (file)
@@ -95,7 +95,7 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPropertiesSpecific(TALLOC_CTX *mem_ctx,
        handle = handles[mapi_req->handle_idx];
        retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
        if (retval) {
-               mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
+               mapi_repl->error_code = MAPI_E_NOT_FOUND;
                DEBUG(5, ("  handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
                goto end;
        }
@@ -103,11 +103,20 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPropertiesSpecific(TALLOC_CTX *mem_ctx,
        retval = mapi_handles_get_private_data(rec, &private_data);
         object = private_data;
        if (!object) {
-               mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
+               mapi_repl->error_code = MAPI_E_NOT_FOUND;
                DEBUG(5, ("  object (%x) not found: %x\n", handle, mapi_req->handle_idx));
                goto end;
        }
 
+       if (!(object->type == EMSMDBP_OBJECT_MAILBOX
+             || object->type == EMSMDBP_OBJECT_FOLDER
+             || object->type == EMSMDBP_OBJECT_MESSAGE
+             || object->type == EMSMDBP_OBJECT_ATTACHMENT)) {
+               mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
+               DEBUG(5, ("  GetProperties cannot occur on an object of type '%s' (%d)\n", emsmdbp_getstr_type(object), object->type));
+               goto end;
+       }
+
         properties = talloc_zero(NULL, struct SPropTagArray);
         properties->cValues = request->prop_count;
         properties->aulPropTag = talloc_array(properties, enum MAPITAGS, request->prop_count);
@@ -410,6 +419,11 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetProperties(TALLOC_CTX *mem_ctx,
                goto end;
        }
 
+       if (object->type == EMSMDBP_OBJECT_MESSAGE && !object->object.message->read_write) {
+               mapi_repl->error_code = MAPI_E_NO_ACCESS;
+               goto end;
+       }
+
        aRow.cValues = mapi_req->u.mapi_SetProps.values.cValues;
        aRow.lpProps = talloc_array(mem_ctx, struct SPropValue, aRow.cValues + 2);
        for (i = 0; i < mapi_req->u.mapi_SetProps.values.cValues; i++) {
@@ -506,6 +520,7 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenStream(TALLOC_CTX *mem_ctx,
        void                            **data_pointers;
        enum MAPISTATUS                 *retvals;
        struct emsmdbp_stream_data      *stream_data;
+       enum OpenStream_OpenModeFlags   mode;
 
        DEBUG(4, ("exchange_emsmdb: [OXCPRPT] OpenStream (0x2b)\n"));
 
@@ -541,8 +556,23 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenStream(TALLOC_CTX *mem_ctx,
 
        request = &mapi_req->u.mapi_OpenStream;
 
-       if (request->PropertyTag == PR_NT_SECURITY_DESCRIPTOR_AS_XML) {
-               mapi_repl->error_code = MAPI_E_NO_SUPPORT;
+       mode = request->OpenModeFlags;
+       if (mode == OpenStream_BestAccess) {
+               if (parent_object->type == EMSMDBP_OBJECT_MESSAGE) {
+                       if (parent_object->object.message->read_write) {
+                               mode = OpenStream_ReadWrite;
+                       }
+                       else {
+                               mode = OpenStream_ReadOnly;
+                       }
+               }
+               else {
+                       mode = OpenStream_ReadOnly;
+               }
+       }
+
+       if (parent_object->type == EMSMDBP_OBJECT_MESSAGE && !parent_object->object.message->read_write && (mode == OpenStream_ReadWrite || mode == OpenStream_Create)) {
+               mapi_repl->error_code = MAPI_E_NO_ACCESS;
                 goto end;
        }
 
@@ -558,7 +588,8 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenStream(TALLOC_CTX *mem_ctx,
        object->object.stream->stream.position = 0;
        object->object.stream->stream.buffer.length = 0;
 
-       if (request->OpenModeFlags == OpenStream_ReadOnly || request->OpenModeFlags == OpenStream_ReadWrite) {
+       if (mode == OpenStream_ReadOnly || mode == OpenStream_ReadWrite) {
+               object->object.stream->read_write = (mode == OpenStream_ReadWrite);
                stream_data = emsmdbp_object_get_stream_data(parent_object, object->object.stream->property);
                if (stream_data) {
                        object->object.stream->stream.buffer = stream_data->data;
@@ -584,15 +615,16 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenStream(TALLOC_CTX *mem_ctx,
                                talloc_free(retvals);
                        }
                        else {
+                               mapi_repl->error_code = retvals[0];
                                talloc_free(data_pointers);
                                talloc_free(retvals);
-                               mapi_repl->error_code = retvals[0];
                                talloc_free(object);
                                goto end;
                        }
                }
        }
        else { /* OpenStream_Create */
+               object->object.stream->read_write = true;
                object->object.stream->stream.buffer.data = talloc_zero(object->object.stream, uint8_t);
                object->object.stream->stream.buffer.length = 0;
        }
@@ -747,6 +779,11 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopWriteStream(TALLOC_CTX *mem_ctx,
                goto end;
        }
 
+       if (!object->object.stream->read_write) {
+               mapi_repl->error_code = MAPI_E_NO_ACCESS;
+               goto end;
+       }
+
        request = &mapi_req->u.mapi_WriteStream;
        if (request->data.length > 0) {
                 emsmdbp_stream_write_buffer(object->object.stream, &object->object.stream->stream, request->data);
@@ -817,6 +854,11 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopCommitStream(TALLOC_CTX *mem_ctx,
                goto end;
        }
 
+       if (!object->object.stream->read_write) {
+               mapi_repl->error_code = MAPI_E_NO_ACCESS;
+               goto end;
+       }
+
        emsmdbp_object_stream_commit(object);
 
 end:
@@ -994,10 +1036,10 @@ end:
    \return MAPI_E_SUCCESS on success, otherwise MAPI error
  */
 _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetStreamSize(TALLOC_CTX *mem_ctx,
-                                           struct emsmdbp_context *emsmdbp_ctx,
-                                           struct EcDoRpc_MAPI_REQ *mapi_req,
-                                           struct EcDoRpc_MAPI_REPL *mapi_repl,
-                                           uint32_t *handles, uint16_t *size)
+                                                 struct emsmdbp_context *emsmdbp_ctx,
+                                                 struct EcDoRpc_MAPI_REQ *mapi_req,
+                                                 struct EcDoRpc_MAPI_REPL *mapi_repl,
+                                                 uint32_t *handles, uint16_t *size)
 {
        enum MAPISTATUS                 retval;
        struct mapi_handles             *parent = NULL;
index 46a5b3696725d8e208db0b5d70ea12e8cc1a1138..d97f54689631be6f0230c5bf97d9cce44366cd40 100644 (file)
@@ -51,7 +51,7 @@ static enum MAPISTATUS RopLogon_Mailbox(TALLOC_CTX *mem_ctx,
        struct Logon_req        *request;
        struct Logon_repl       *response;
        const char * const      attrs[] = { "*", NULL };
-       int                     ret;
+       enum MAPISTATUS         ret;
        struct ldb_result       *res = NULL;
        const char              *username;
        struct tm               *LogonTime;
@@ -72,26 +72,30 @@ static enum MAPISTATUS RopLogon_Mailbox(TALLOC_CTX *mem_ctx,
        username = ldb_msg_find_attr_as_string(res->msgs[0], "sAMAccountName", NULL);
        OPENCHANGE_RETVAL_IF(!username, ecUnknownUser, NULL);
 
-       /* Step 2. Check if mailbox corresponding to the specified username does exist */
-       ret = openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_MAILBOX_ROOT, &response->LogonType.store_mailbox.FolderIds[0]);
-       OPENCHANGE_RETVAL_IF(ret, ecUnknownUser, NULL);
+       /* Step 2. Init and or update the user mailbox (auto-provisioning) */
+       ret = emsmdbp_mailbox_provision(emsmdbp_ctx, username);
+       OPENCHANGE_RETVAL_IF(ret, MAPI_E_DISK_ERROR, NULL);
+       /* TODO: freebusy entry should be created only during freebusy lookups */
+       ret = emsmdbp_mailbox_provision_public_freebusy(emsmdbp_ctx, request->EssDN);
+       OPENCHANGE_RETVAL_IF(ret, MAPI_E_DISK_ERROR, NULL);
 
        /* Step 3. Set LogonFlags */
        response->LogonFlags = request->LogonFlags;
 
        /* Step 4. Build FolderIds list */
-       openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_DEFERRED_ACTIONS, &response->LogonType.store_mailbox.FolderIds[1]);
-       openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_SPOOLER_QUEUE, &response->LogonType.store_mailbox.FolderIds[2]);
-       openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_TOP_INFORMATION_STORE, &response->LogonType.store_mailbox.FolderIds[3]);
-       openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_INBOX, &response->LogonType.store_mailbox.FolderIds[4]);
-       openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_OUTBOX, &response->LogonType.store_mailbox.FolderIds[5]);
-       openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_SENT_ITEMS, &response->LogonType.store_mailbox.FolderIds[6]);
-       openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_DELETED_ITEMS, &response->LogonType.store_mailbox.FolderIds[7]);
-       openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_COMMON_VIEWS, &response->LogonType.store_mailbox.FolderIds[8]);
-       openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_SCHEDULE, &response->LogonType.store_mailbox.FolderIds[9]);
-       openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_SEARCH, &response->LogonType.store_mailbox.FolderIds[10]);
-       openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_VIEWS, &response->LogonType.store_mailbox.FolderIds[11]);
-       openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_SHORTCUTS, &response->LogonType.store_mailbox.FolderIds[12]);
+       openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_MAILBOX_ROOT, &response->LogonType.store_mailbox.Root);
+       openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_DEFERRED_ACTION, &response->LogonType.store_mailbox.DeferredAction);
+       openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_SPOOLER_QUEUE, &response->LogonType.store_mailbox.SpoolerQueue);
+       openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_TOP_INFORMATION_STORE, &response->LogonType.store_mailbox.IPMSubTree);
+       openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_INBOX, &response->LogonType.store_mailbox.Inbox);
+       openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_OUTBOX, &response->LogonType.store_mailbox.Outbox);
+       openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_SENT_ITEMS, &response->LogonType.store_mailbox.SentItems);
+       openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_DELETED_ITEMS, &response->LogonType.store_mailbox.DeletedItems);
+       openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_COMMON_VIEWS, &response->LogonType.store_mailbox.CommonViews);
+       openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_SCHEDULE, &response->LogonType.store_mailbox.Schedule);
+       openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_SEARCH, &response->LogonType.store_mailbox.Search);
+       openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_VIEWS, &response->LogonType.store_mailbox.Views);
+       openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_SHORTCUTS, &response->LogonType.store_mailbox.Shortcuts);
 
        /* Step 5. Set ResponseFlags */
        response->LogonType.store_mailbox.ResponseFlags = ResponseFlags_Reserved | ResponseFlags_OwnerRight | ResponseFlags_SendAsRight;
@@ -141,34 +145,30 @@ static enum MAPISTATUS RopLogon_PublicFolder(TALLOC_CTX *mem_ctx,
                                             struct EcDoRpc_MAPI_REQ *mapi_req,
                                             struct EcDoRpc_MAPI_REPL *mapi_repl)
 {
-       struct Logon_req        request;
-       struct Logon_repl       response;
-
-       request = mapi_req->u.mapi_Logon;
-       response = mapi_repl->u.mapi_Logon;
-
-       response.LogonFlags = request.LogonFlags;
-
-       openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, EMSMDBP_PF_ROOT, &(response.LogonType.store_pf.FolderIds[0]));
-       openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, EMSMDBP_PF_IPMSUBTREE, &(response.LogonType.store_pf.FolderIds[1]));
-       openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, EMSMDBP_PF_NONIPMSUBTREE, &(response.LogonType.store_pf.FolderIds[2]));
-       openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, EMSMDBP_PF_EFORMSREGISTRY, &(response.LogonType.store_pf.FolderIds[3]));
-       openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, EMSMDBP_PF_FREEBUSY, &(response.LogonType.store_pf.FolderIds[4]));
-       openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, EMSMDBP_PF_OAB, &(response.LogonType.store_pf.FolderIds[5]));
-       response.LogonType.store_pf.FolderIds[6] = 0x00000000000000000000; /* Eforms Registry */
-       openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, EMSMDBP_PF_LOCALFREEBUSY, &(response.LogonType.store_pf.FolderIds[7]));
-       openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, EMSMDBP_PF_LOCALOAB, &(response.LogonType.store_pf.FolderIds[8]));
-       response.LogonType.store_pf.FolderIds[9] = 0x00000000000000000000; /* NNTP Article Index */
-       response.LogonType.store_pf.FolderIds[10] = 0x00000000000000000000; /* Empty */
-       response.LogonType.store_pf.FolderIds[11] = 0x00000000000000000000; /* Empty */
-       response.LogonType.store_pf.FolderIds[12] = 0x00000000000000000000; /* Empty */
+       struct Logon_req        *request;
+       struct Logon_repl       *response;
 
-       openchangedb_get_PublicFolderReplica(emsmdbp_ctx->oc_ctx,
-                                            &(response.LogonType.store_pf.ReplId),
-                                            &(response.LogonType.store_pf.Guid));
-       memset(&(response.LogonType.store_pf.PerUserGuid), 0, sizeof(struct GUID));
+       request = &mapi_req->u.mapi_Logon;
+       response = &mapi_repl->u.mapi_Logon;
 
-       mapi_repl->u.mapi_Logon = response;
+       response->LogonFlags = request->LogonFlags;
+
+       openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, EMSMDBP_PF_ROOT, &response->LogonType.store_pf.Root);
+       openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, EMSMDBP_PF_IPMSUBTREE, &response->LogonType.store_pf.IPMSubTree);
+       openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, EMSMDBP_PF_NONIPMSUBTREE, &response->LogonType.store_pf.NonIPMSubTree);
+       openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, EMSMDBP_PF_EFORMSREGISTRY, &response->LogonType.store_pf.EFormsRegistry);
+       openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, EMSMDBP_PF_FREEBUSY, &response->LogonType.store_pf.FreeBusy);
+       openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, EMSMDBP_PF_OAB, &response->LogonType.store_pf.OAB);
+       response->LogonType.store_pf.LocalizedEFormsRegistry = 0;
+       openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, EMSMDBP_PF_LOCALFREEBUSY, &response->LogonType.store_pf.LocalFreeBusy);
+       openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, EMSMDBP_PF_LOCALOAB, &response->LogonType.store_pf.LocalOAB);
+       response->LogonType.store_pf.NNTPIndex = 0;
+       memset(response->LogonType.store_pf._empty, 0, sizeof(uint64_t) * 3);
+
+       openchangedb_get_PublicFolderReplica(emsmdbp_ctx->oc_ctx,
+                                            &response->LogonType.store_pf.ReplId,
+                                            &response->LogonType.store_pf.Guid);
+       memset(&response->LogonType.store_pf.PerUserGuid, 0, sizeof(struct GUID));
 
        return MAPI_E_SUCCESS;
 }
@@ -198,7 +198,7 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopLogon(TALLOC_CTX *mem_ctx,
                                          uint32_t *handles, uint16_t *size)
 {
        enum MAPISTATUS                 retval;
-       struct Logon_req                request;
+       struct Logon_req                *request;
        struct mapi_handles             *rec = NULL;
        struct emsmdbp_object           *object;
        bool                            mailboxstore = true;
@@ -212,26 +212,27 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopLogon(TALLOC_CTX *mem_ctx,
        OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
        OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
 
-       request = mapi_req->u.mapi_Logon;
+       request = &mapi_req->u.mapi_Logon;
 
        /* Fill EcDoRpc_MAPI_REPL reply */
        mapi_repl->opnum = mapi_req->opnum;
        mapi_repl->handle_idx = mapi_req->handle_idx;
 
-       if (request.LogonFlags & LogonPrivate) {
+       if (request->LogonFlags & LogonPrivate) {
                retval = RopLogon_Mailbox(mem_ctx, emsmdbp_ctx, mapi_req, mapi_repl);
                mapi_repl->error_code = retval;
                *size += libmapiserver_RopLogon_size(mapi_req, mapi_repl);
        } else {
                retval = RopLogon_PublicFolder(mem_ctx, emsmdbp_ctx, mapi_req, mapi_repl);
                /* mapi_repl->error_code = MAPI_E_LOGON_FAILED; */
+               mapi_repl->error_code = retval;
                mailboxstore = false;
                *size += libmapiserver_RopLogon_size(mapi_req, mapi_repl);
        }
 
        if (!mapi_repl->error_code) {
                retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, 0, &rec);
-               object = emsmdbp_object_mailbox_init((TALLOC_CTX *)rec, emsmdbp_ctx, mapi_req, mailboxstore);
+               object = emsmdbp_object_mailbox_init((TALLOC_CTX *)rec, emsmdbp_ctx, request->EssDN, mailboxstore);
                retval = mapi_handles_set_private_data(rec, object);
 
                handles[mapi_repl->handle_idx] = rec->handle;
@@ -394,8 +395,7 @@ static enum MAPISTATUS RopSetReceiveFolder(TALLOC_CTX *mem_ctx,
        }
 
        /* Step 3.Set the receive folder for this message class within user mailbox */
-       retval = openchangedb_set_ReceiveFolder(mem_ctx, emsmdbp_ctx->oc_ctx, object->object.mailbox->owner_username,
-                                               MessageClass, fid);
+       retval = openchangedb_set_ReceiveFolder(emsmdbp_ctx->oc_ctx, object->object.mailbox->owner_username, MessageClass, fid);
        OPENCHANGE_RETVAL_IF(retval, ecNoReceiveFolder, NULL);
 
        return MAPI_E_SUCCESS;
index 7a5a3b2c103b5388ea3d1da5d11c1099583c0f7e..047119f72444e963ab96243d3b58bb7955c125c5 100644 (file)
@@ -98,6 +98,11 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetColumns(TALLOC_CTX *mem_ctx,
                table = object->object.table;
                OPENCHANGE_RETVAL_IF(!table, MAPI_E_INVALID_PARAMETER, NULL);
 
+               if (table->ulType == MAPISTORE_RULE_TABLE) {
+                       DEBUG(5, ("  query on rules table are all faked right now\n"));
+                       goto end;
+               }
+
                request = mapi_req->u.mapi_SetColumns;
 
                if (request.prop_count) {
@@ -196,8 +201,8 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSortTable(TALLOC_CTX *mem_ctx,
        table = object->object.table;
        OPENCHANGE_RETVAL_IF(!table, MAPI_E_INVALID_PARAMETER, NULL);
 
-       if (table->ulType != EMSMDBP_TABLE_MESSAGE_TYPE
-            && table->ulType != EMSMDBP_TABLE_FAI_TYPE) {
+       if (table->ulType != MAPISTORE_MESSAGE_TABLE
+            && table->ulType != MAPISTORE_FAI_TABLE) {
                mapi_repl->error_code = MAPI_E_NO_SUPPORT;
                DEBUG(5, ("  query performed on non contents table\n"));
                goto end;
@@ -310,7 +315,7 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopRestrict(TALLOC_CTX *mem_ctx,
        OPENCHANGE_RETVAL_IF(!table, MAPI_E_INVALID_PARAMETER, NULL);
 
        table->restricted = true;
-       if (table->ulType == EMSMDBP_TABLE_RULE_TYPE) {
+       if (table->ulType == MAPISTORE_RULE_TABLE) {
                DEBUG(5, ("  query on rules table are all faked right now\n"));
                goto end;
        }
@@ -367,7 +372,7 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopQueryRows(TALLOC_CTX *mem_ctx,
        struct QueryRows_repl           response;
        enum MAPISTATUS                 retval;
        void                            *data;
-       uint32_t                        *mapistore_retvals;
+       enum MAPISTATUS                 *retvals;
        void                            **data_pointers;
        uint32_t                        count, max;
        uint32_t                        handle;
@@ -419,7 +424,8 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopQueryRows(TALLOC_CTX *mem_ctx,
 
        table = object->object.table;
 
-       if (table->ulType == EMSMDBP_TABLE_RULE_TYPE) {
+       count = 0;
+       if (table->ulType == MAPISTORE_RULE_TABLE) {
                DEBUG(5, ("  query on rules table are all faked right now\n"));
                goto finish;
        }
@@ -431,18 +437,17 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopQueryRows(TALLOC_CTX *mem_ctx,
        }
 
         /* Lookup the properties */
-       count = 0;
        max = table->numerator + request->RowCount;
        if (max > table->denominator) {
                max = table->denominator;
        }
         for (i = table->numerator; i < max; i++) {
-               data_pointers = emsmdbp_object_table_get_row_props(mem_ctx, emsmdbp_ctx, object, i, MAPISTORE_PREFILTERED_QUERY, &mapistore_retvals);
+               data_pointers = emsmdbp_object_table_get_row_props(mem_ctx, emsmdbp_ctx, object, i, MAPISTORE_PREFILTERED_QUERY, &retvals);
                if (data_pointers) {
                        emsmdbp_fill_table_row_blob(mem_ctx, emsmdbp_ctx,
                                                    &response.RowData, table->prop_count,
-                                                   table->properties, data_pointers, mapistore_retvals);
-                       talloc_free(mapistore_retvals);
+                                                   table->properties, data_pointers, retvals);
+                       talloc_free(retvals);
                        talloc_free(data_pointers);
                        count++;
                }
@@ -695,7 +700,7 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopFindRow(TALLOC_CTX *mem_ctx,
        struct FindRow_req              request;
        enum MAPISTATUS                 retval;
        void                            *data = NULL;
-       uint32_t                        *retvals;
+       enum MAPISTATUS                 *retvals;
        void                            **data_pointers;
        uint32_t                        handle;
        DATA_BLOB                       row;
@@ -751,7 +756,7 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopFindRow(TALLOC_CTX *mem_ctx,
         * entire table, nor do we handle bookmarks */
 
        table = object->object.table;
-       if (table->ulType == EMSMDBP_TABLE_RULE_TYPE) {
+       if (table->ulType == MAPISTORE_RULE_TABLE) {
                DEBUG(5, ("  query on rules table are all faked right now\n"));
                goto end;
        }
@@ -764,10 +769,10 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopFindRow(TALLOC_CTX *mem_ctx,
                table->numerator = 0;
        }
 
+       memset (&row, 0, sizeof(DATA_BLOB));
+
        switch (emsmdbp_is_mapistore(object)) {
        case true:
-               memset (&row, 0, sizeof(DATA_BLOB));
-
                /* Restrict rows to be fetched */
                retval = mapistore_table_set_restrictions(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(object), object->backend_object, &request.res, &status);
                /* Then fetch rows */
@@ -980,7 +985,7 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopResetTable(TALLOC_CTX *mem_ctx,
        mapi_repl->error_code = MAPI_E_SUCCESS;
 
        table = object->object.table;
-       if (table->ulType == EMSMDBP_TABLE_RULE_TYPE) {
+       if (table->ulType == MAPISTORE_RULE_TABLE) {
                DEBUG(5, ("  query on rules table are all faked right now\n"));
        }
        else {
index 282256bd396294b4617aa2794d7255e4003bd566..ef4eaa74916672520a07f1066d81de6fa604e9ae 100644 (file)
@@ -81,8 +81,7 @@ static void oxomsg_mapistore_handle_target_entryid(struct emsmdbp_context *emsmd
        messageID = (entryID->MessageGlobalCounter.value << 16) | replID;
        /* DEBUG(5, (__location__": dest message id: %.16"PRIx64"\n", messageID)); */
 
-       folder_object = emsmdbp_object_open_folder_by_fid(mem_ctx, emsmdbp_ctx, old_message_object, folderID);
-       if (!folder_object) {
+       if (emsmdbp_object_open_folder_by_fid(mem_ctx, emsmdbp_ctx, old_message_object, folderID, &folder_object) != MAPISTORE_SUCCESS) {
                DEBUG(5, (__location__": unable to open folder\n"));
                return;
        }
@@ -93,7 +92,7 @@ static void oxomsg_mapistore_handle_target_entryid(struct emsmdbp_context *emsmd
                return;
        }
 
-       /* FIXME: (from oxomsg 3.2.5.1.2.8) PidTagMessageFlags: mfUnsent and mfRead must be cleared */
+       /* FIXME: (from oxomsg 3.2.5.1) PidTagMessageFlags: mfUnsent and mfRead must be cleared */
        emsmdbp_object_copy_properties(emsmdbp_ctx, old_message_object, message_object, &excluded_tags, true);
 
        mapistore_message_save(emsmdbp_ctx->mstore_ctx, contextID, message_object->backend_object);
@@ -195,6 +194,7 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSubmitMessage(TALLOC_CTX *mem_ctx,
                flags = mapi_req->u.mapi_SubmitMessage.SubmitFlags;
                owner = emsmdbp_get_owner(object);
                mapistore_message_submit(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(object), object->backend_object, flags);
+               oxomsg_mapistore_handle_target_entryid(emsmdbp_ctx, object);
                mapistore_indexing_record_add_mid(emsmdbp_ctx->mstore_ctx, contextID, owner, messageID);
                break;
        }
index 54379e0ea40546f4edcf6f0e2b7131c949077841..e62676ad3ea88640784a45e000e90ac1a566208b 100644 (file)
@@ -106,7 +106,7 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetRulesTable(TALLOC_CTX *mem_ctx,
                retval = mapi_handles_set_private_data(rec, object);
                /* rules tables are stub objects for now */
                object->object.table->denominator = 0;
-               object->object.table->ulType = EMSMDBP_TABLE_RULE_TYPE;
+               object->object.table->ulType = MAPISTORE_RULE_TABLE;
        }
 end:
        *size += libmapiserver_RopGetRulesTable_size();
index 2d05af33e1314fe701d1cf22be738e8376d1483e..21abaa2b7dd79067e1cd048bf5ad37783ddfb62c 100644 (file)
@@ -345,7 +345,7 @@ static void dcesrv_NspiQueryRows(struct dcesrv_call_state *dce_call,
        struct emsabp_context           *emsabp_ctx = NULL;
        struct SPropTagArray            *pPropTags;
        struct SRowSet                  *pRows;
-       uint32_t                        i;
+       uint32_t                        i, j;
 
        DEBUG(3, ("exchange_nsp: NspiQueryRows (0x3)\n"));
 
@@ -413,17 +413,21 @@ static void dcesrv_NspiQueryRows(struct dcesrv_call_state *dce_call,
                r->in.pStat->Delta = 0;
        } else {
                /* Step 2.2 Fill ppRows for supplied table of MIds */
-               pRows->cRows = r->in.dwETableCount;
-               pRows->aRow = talloc_array(mem_ctx, struct SRow, r->in.dwETableCount);
-               if (pRows->cRows) {
-                       r->in.pStat->CurrentRec = r->in.lpETable[0];
+               j = 0;
+               if (r->in.pStat->NumPos < r->in.dwETableCount) {
+                       pRows->cRows = r->in.dwETableCount - r->in.pStat->NumPos;
+                       pRows->aRow = talloc_array(mem_ctx, struct SRow, pRows->cRows);
                        for (i = r->in.pStat->NumPos; i < r->in.dwETableCount; i++) {
-                               retval = emsabp_fetch_attrs(mem_ctx, emsabp_ctx, &(pRows->aRow[i]), r->in.lpETable[i], r->in.dwFlags, pPropTags);
+                               retval = emsabp_fetch_attrs(mem_ctx, emsabp_ctx, &(pRows->aRow[j]), r->in.lpETable[i], r->in.dwFlags, pPropTags);
                                if (retval != MAPI_E_SUCCESS) {
                                        goto failure;
                                }
+                               j++;
                        }
                }
+               r->in.pStat->CurrentRec = MID_END_OF_TABLE;
+               r->in.pStat->TotalRecs = j;
+               r->in.pStat->Delta = 0;
        }
 
        /* Step 3. Fill output params */
index 23c2dd90f7d86f1999a3cbb1ffff3c02646585c3..4d07c323936fb850bc067049d466f0fd0d75224a 100644 (file)
@@ -480,6 +480,7 @@ _PUBLIC_ void *emsabp_query(TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_c
        case PR_SEND_INTERNET_ENCODING:
                data = talloc_zero(mem_ctx, uint32_t);
                *((uint32_t *)data) = 0x00160000;
+               return data;
        case PR_ENTRYID:
        case PR_ORIGINAL_ENTRYID:
                bin = talloc(mem_ctx, struct Binary_r);
index 43762e834600d6880b900b2efea337a23f89fc3e..91a5e5617130b8cb523f5b7557b0bf2b9abac1ca 100644 (file)
@@ -57,6 +57,13 @@ interface property
                Sa              = 0x00000040
        } WeekRecurrencePattern;
 
+       typedef [v1_enum] enum {
+               olFree          = 0x00000000,
+               olTentative     = 0x00000001,
+               olBusy          = 0x00000002,
+               olOutOfOffice   = 0x00000003
+       } FreeBusyStatus; /* oxocal - 2.2.1.2 */
+
        typedef [v1_enum] enum {
                RecurrenceN_First       =       0x1,
                RecurrenceN_Second      =       0x2,
@@ -261,11 +268,31 @@ interface property
                uint8                   Data[Size];
        } GlobalObjectId;
 
+       typedef [enum16bit] enum {
+               eitLTPrivateFolder              = 0x01,
+               eitLTPPublicFolder              = 0x03,
+               eitLTPMappedPublicFolder        = 0x05,
+               eitLTPPrivateMessage            = 0x07,
+               eitLTPPublicMessage             = 0x09,
+               eitLTPMappedPublicMessage       = 0x0b,
+               eitLTPPublicNewsgroupFolder     = 0x0c
+       } EntryIdFolderType;
+
+       /* FolderEntryId */
+       typedef [public,flag(NDR_NOALIGN)] struct {
+               uint32                  Flags;
+               GUID                    ProviderUID;
+               EntryIdFolderType       FolderType;
+               GUID                    FolderDatabaseGuid;
+               [switch_is(1)] GLOBCNT  FolderGlobalCounter;
+               uint16                  Pad;
+       } FolderEntryId;
+
        /* PR_ENTRYID/PR_TARGET_ENTRYID (messages) */
        typedef [public,flag(NDR_NOALIGN)] struct {
                uint32                  Flags;
                GUID                    ProviderUID;
-               uint16                  MessageType;
+               EntryIdFolderType       MessageType;
                GUID                    FolderDatabaseGuid;
                [switch_is(1)] GLOBCNT  FolderGlobalCounter;
                uint16                  Pad1;
index ea59e29c11d476dd719b25d9a695a3aac3bfa317..b70c4ffc22f2f4cb26967f5a97e27e749983566f 100644 (file)
@@ -20,6 +20,7 @@
 */
 
 #include <Python.h>
+#include <inttypes.h>
 #include "pyopenchange/mapistore/pymapistore.h"
 
 static void py_MAPIStoreContext_dealloc(PyObject *_self)
index dadf6932d24ae97a3fb6a3f62fbced1815cada86..600f6043d44b7d94e9ae95728637af23c1425da1 100644 (file)
@@ -68,48 +68,20 @@ static PyObject *py_MAPIStoreFolder_get_fid(PyMAPIStoreFolderObject *self, void
        return PyLong_FromLongLong(self->fid);
 }
 
-static PyObject *py_MAPIStoreFolder_get_folder_count(PyMAPIStoreFolderObject *self, void *closure)
+static PyObject *py_MAPIStoreFolder_get_child_count(PyMAPIStoreFolderObject *self, PyObject *args, PyObject *kwargs)
 {
-       uint32_t        RowCount;
-       int             retval;
+       uint32_t                        RowCount;
+       enum mapistore_table_type       table_type;
+       char                            *kwnames[] = { "table_type" };
+       int                             retval;
 
-       retval = mapistore_folder_get_folder_count(self->context->mstore_ctx, self->context->context_id,
-                                                  (self->folder_object ? self->folder_object : 
-                                                   self->context->folder_object), &RowCount);
-       if (retval != MAPISTORE_SUCCESS) {
-               return PyInt_FromLong(-1);
-       }
-
-       return PyInt_FromLong(RowCount);
-}
-
-
-static PyObject *py_MAPIStoreFolder_get_message_count(PyMAPIStoreFolderObject *self, void *closure)
-{
-       uint32_t        RowCount;
-       int             retval;
-
-       retval = mapistore_folder_get_message_count(self->context->mstore_ctx, self->context->context_id,
-                                                  (self->folder_object ? self->folder_object : 
-                                                   self->context->folder_object), 
-                                                   MAPISTORE_MESSAGE_TABLE, &RowCount);
-       if (retval != MAPISTORE_SUCCESS) {
-               return PyInt_FromLong(-1);
+       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwnames, &table_type)) {
+               return NULL;
        }
 
-       return PyInt_FromLong(RowCount);
-}
-
-
-static PyObject *py_MAPIStoreFolder_get_fai_message_count(PyMAPIStoreFolderObject *self, void *closure)
-{
-       uint32_t        RowCount;
-       int             retval;
-
-       retval = mapistore_folder_get_message_count(self->context->mstore_ctx, self->context->context_id,
-                                                  (self->folder_object ? self->folder_object : 
-                                                   self->context->folder_object), 
-                                                   MAPISTORE_FAI_TABLE, &RowCount);
+       retval = mapistore_folder_get_child_count(self->context->mstore_ctx, self->context->context_id,
+                                                 (self->folder_object ? self->folder_object : 
+                                                  self->context->folder_object), table_type, &RowCount);
        if (retval != MAPISTORE_SUCCESS) {
                return PyInt_FromLong(-1);
        }
@@ -119,14 +91,12 @@ static PyObject *py_MAPIStoreFolder_get_fai_message_count(PyMAPIStoreFolderObjec
 
 static PyMethodDef mapistore_folder_methods[] = {
        { "create_folder", (PyCFunction)py_MAPIStoreFolder_create_folder, METH_VARARGS|METH_KEYWORDS },
+       { "get_child_count", (PyCFunction)py_MAPIStoreFolder_get_child_count, METH_VARARGS|METH_KEYWORDS },
        { NULL },
 };
 
 static PyGetSetDef mapistore_folder_getsetters[] = {
        { (char *)"fid", (getter)py_MAPIStoreFolder_get_fid, NULL, NULL },
-       { (char *)"folder_count", (getter)py_MAPIStoreFolder_get_folder_count, NULL, NULL },
-       { (char *)"message_count", (getter)py_MAPIStoreFolder_get_message_count, NULL, NULL },
-       { (char *)"fai_message_count", (getter)py_MAPIStoreFolder_get_fai_message_count, NULL, NULL },
        { NULL }
 };
 
index 9cac6e60a0474bead281ce64e11dde016bfa3e94..53bf4c7b49db123e0873d280011ef3230704d47a 100644 (file)
@@ -41,6 +41,13 @@ static void *sam_ldb_init(TALLOC_CTX *mem_ctx, const char *syspath)
        char                    *ldb_path;
        struct tevent_context   *ev;
        int                     ret;
+       /* struct ldb_result    *res; */
+       /* struct ldb_dn                *tmp_dn = NULL; */
+       /* static const char    *attrs[] = { */
+       /*      "rootDomainNamingContext", */
+       /*      "defaultNamingContext", */
+       /*      NULL */
+       /* }; */
 
        /* Sanity checks */
        if (sam_ldb_ctx) return sam_ldb_ctx;
@@ -58,6 +65,21 @@ static void *sam_ldb_init(TALLOC_CTX *mem_ctx, const char *syspath)
        talloc_free(ldb_path);
        if (ret != LDB_SUCCESS) return NULL;
 
+       /* /\* Step 3. Search for rootDSE record *\/ */
+       /* ret = ldb_search(sam_ldb_ctx, mem_ctx, &res, ldb_dn_new(mem_ctx, sam_ldb_ctx, "@ROOTDSE"), */
+       /*               LDB_SCOPE_BASE, attrs, NULL); */
+       /* if (ret != LDB_SUCCESS) return NULL; */
+       /* if (res->count != 1) return NULL; */
+
+       /* /\* Step 4. Set opaque naming *\/ */
+       /* tmp_dn = ldb_msg_find_attr_as_dn(sam_ldb_ctx, sam_ldb_ctx,  */
+       /*                               res->msgs[0], "rootDomainNamingContext"); */
+       /* ldb_set_opaque(sam_ldb_ctx, "rootDomainNamingContext", tmp_dn); */
+       
+       /* tmp_dn = ldb_msg_find_attr_as_dn(sam_ldb_ctx, sam_ldb_ctx, */
+       /*                               res->msgs[0], "defaultNamingContext"); */
+       /* ldb_set_opaque(sam_ldb_ctx, "defaultNamingContext", tmp_dn); */
+
        return sam_ldb_ctx;
 
 }
@@ -113,6 +135,7 @@ static void *openchange_ldb_init(TALLOC_CTX *mem_ctx, const char *syspath)
 static PyObject *py_MAPIStore_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
 {
        TALLOC_CTX                      *mem_ctx;
+       struct loadparm_context         *lp_ctx;
        struct mapistore_context        *mstore_ctx;
        PyMAPIStoreObject               *msobj;
        char                            *kwnames[] = { "syspath", "path", NULL };
@@ -147,8 +170,12 @@ static PyObject *py_MAPIStore_new(PyTypeObject *type, PyObject *args, PyObject *
                return NULL;
        }
 
+       /* Initialize configuration */
+       lp_ctx = loadparm_init(mem_ctx);
+       lpcfg_load_default(lp_ctx);
+
        /* Initialize mapistore */
-       mstore_ctx = mapistore_init(mem_ctx, path);
+       mstore_ctx = mapistore_init(mem_ctx, lp_ctx, path);
        if (mstore_ctx == NULL) {
                printf("Error in mapistore_init\n");
                talloc_free(mem_ctx);
index c8a4730211e043480d3bc25a27e14292b51d5704..7705e2cea579c0148e9655fe7190ac798776ad9e 100644 (file)
@@ -79,27 +79,26 @@ dn: CASE_INSENSITIVE
                       "objectClass": ["top", "ou"],
                       "cn": firstou})
 
-    def add_root_public_folder(self, pfdn, fid, cn, SystemIdx, childcount, mapistoreURL):
-        self.ldb.add({"dn": "CN=%s,%s" % (fid, pfdn),
+    def add_root_public_folder(self, dn, fid, change_num, SystemIdx, childcount):
+        self.ldb.add({"dn": dn,
                       "objectClass": ["publicfolder"],
                       "cn": fid,
                       "PidTagFolderId": fid,
-                      "PidTagChangeNumber": cn,
+                      "PidTagChangeNumber": change_num,
                       "PidTagDisplayName": "Public Folder Root",
                       "PidTagCreationTime": "%d" % self.nttime,
                       "PidTagLastModificationTime": "%d" % self.nttime,
                       "PidTagSubFolders": "TRUE" if (childcount != 0) else "FALSE",
                       "PidTagFolderChildCount": str(childcount),
                       "SystemIdx": str(SystemIdx)})
-        return mapistoreURL + "/" + fid
 
-    def add_sub_public_folder(self, pfdn, parentfid, fid, cn, name, SystemIndex, childcount, mapistoreURL):
-        self.ldb.add({"dn": "CN=%s,%s" % (fid, pfdn),
+    def add_sub_public_folder(self, dn, parentfid, fid, change_num, name, SystemIndex, childcount):
+        self.ldb.add({"dn": dn,
                       "objectClass": ["publicfolder"],
                       "cn": fid,
-                      "PidTagParentFolderId": parentfid,
                       "PidTagFolderId": fid,
-                      "PidTagChangeNumber": cn,
+                      "PidTagParentFolderId": parentfid,
+                      "PidTagChangeNumber": change_num,
                       "PidTagDisplayName": name,
                       "PidTagCreationTime": "%d" % self.nttime,
                       "PidTagLastModificationTime": "%d" % self.nttime,
@@ -110,24 +109,25 @@ dn: CASE_INSENSITIVE
                       "PidTagSubFolders": "TRUE" if (childcount != 0) else "FALSE",
                       "PidTagFolderChildCount": str(childcount),
                       "FolderType": str(1),
-                      "FolderType": str(1),
                       "SystemIdx": str(SystemIndex)})
-        return mapistoreURL + "/" + fid
 
-    def add_one_public_folder(self, parent_fid, path, children, SystemIndex, names, mapistoreURL):
+    def add_one_public_folder(self, parent_fid, path, children, SystemIndex, names, dn_prefix = None):
+
         name = path[-1]
         GlobalCount = self.get_message_GlobalCount(names.netbiosname)
         ChangeNumber = self.get_message_ChangeNumber(names.netbiosname)
         ReplicaID = self.get_message_ReplicaID(names.netbiosname)
-        pfdn = "CN=publicfolders,CN=%s,CN=%s,%s" % (names.firstou, names.firstorg, names.ocserverdn)
+        if dn_prefix is None:
+            dn_prefix = "CN=publicfolders,CN=%s,CN=%s,%s" % (names.firstou, names.firstorg, names.ocserverdn)
         fid = gen_mailbox_folder_fid(GlobalCount, ReplicaID)
-        cn = gen_mailbox_folder_fid(ChangeNumber, ReplicaID)
+        dn = "CN=%s,%s" % (fid, dn_prefix)
+        change_num = gen_mailbox_folder_fid(ChangeNumber, ReplicaID)
         childcount = len(children)
         print "\t* %-40s: 0x%.16x (%s)" % (name, int(fid, 10), fid)
         if parent_fid == 0:
-            mapistoreURL = self.add_root_public_folder(pfdn, fid, cn, SystemIndex, childcount, mapistoreURL)
+            self.add_root_public_folder(dn, fid, change_num, SystemIndex, childcount)
         else:
-            mapistoreURL = self.add_sub_public_folder(pfdn, parent_fid, fid, cn, name, SystemIndex, childcount, mapistoreURL);
+            self.add_sub_public_folder(dn, parent_fid, fid, change_num, name, SystemIndex, childcount);
 
         GlobalCount += 1
         self.set_message_GlobalCount(names.netbiosname, GlobalCount=GlobalCount)
@@ -135,37 +135,30 @@ dn: CASE_INSENSITIVE
         self.set_message_ChangeNumber(names.netbiosname, ChangeNumber=ChangeNumber)
 
         for name, grandchildren in children.iteritems():
-            self.add_one_public_folder(fid, path + (name,), grandchildren[0], grandchildren[1], names, mapistoreURL)
-        return mapistoreURL
+            self.add_one_public_folder(fid, path + (name,), grandchildren[0], grandchildren[1], names, dn)
 
-    def add_mapistore_pf_dir(self, mapistoreURL):
-        mapistorepath = openchangedb_mapistore_url_split(mapistoreURL)[1]
-        if not os.path.isdir(mapistorepath):
-            os.makedirs(mapistorepath, mode=0700)
-
-    def add_public_folders(self, names, mapistoreURL):
-        self.add_mapistore_pf_dir(mapistoreURL)
+    def add_public_folders(self, names):
         pfstoreGUID = str(uuid.uuid4())
         self.ldb.add({"dn": "CN=publicfolders,CN=%s,CN=%s,%s" % (names.firstou, names.firstorg, names.ocserverdn),
-                "objectClass": ["container"],
-                "cn": "publicfolders",
-                "StoreGUID": pfstoreGUID,
-                "ReplicaID": str(1)})
+                      "objectClass": ["container"],
+                      "cn": "publicfolders",
+                      "StoreGUID": pfstoreGUID,
+                      "ReplicaID": str(1)})
         public_folders = ({
-            "IPM_SUBTREE": ({}, 1),
-            "NON_IPM_SUBTREE": ({
-                "EFORMS REGISTRY": ({}, 3),
-                "Events Root": ({}, -1),
-                "OFFLINE ADDRESS BOOK": ({
-                        "/o=%s/cn=addrlists/cn=oabs/cn=Default Offline Address Book" % (names.firstorg): ({}, 8),
-                }, 5),
-                "SCHEDULE+ FREE BUSY": ({
-                        "EX:/o=%s/ou=Exchange Administrative Group (%s)" % (names.firstorg, names.netbiosname): ({}, 7),
-                }, 4),
-            }, 2),
-        }, 0)
-
-        self.add_one_public_folder(0, ("Public Folder Root",), public_folders[0], public_folders[1], names, mapistoreURL)
+                "IPM_SUBTREE": ({}, 2),
+                "NON_IPM_SUBTREE": ({
+                        "EFORMS REGISTRY": ({}, 4),
+                        "Events Root": ({}, -1),
+                        "OFFLINE ADDRESS BOOK": ({
+                                "/o=%s/cn=addrlists/cn=oabs/cn=Default Offline Address Book" % (names.firstorg): ({}, 9),
+                                }, 6),
+                        "SCHEDULE+ FREE BUSY": ({
+                                "EX:/o=%s/ou=%s" % (names.firstorg.lower(), names.firstou.lower()): ({}, 8),
+                                }, 5),
+                        }, 3),
+                }, 1)
+
+        self.add_one_public_folder(0, ("Public Folder Root",), public_folders[0], public_folders[1], names)
         
     def lookup_server(self, cn, attributes=[]):
         # Step 1. Search Server object
@@ -190,13 +183,19 @@ dn: CASE_INSENSITIVE
         return self.ldb.search(server_dn, scope=ldb.SCOPE_SUBTREE,
                            expression=filter, attrs=attributes)
 
-    def user_exists(self, server, username):
-        """Check whether a user exists.
+    def lookup_public_folder(self, server, displayname, attributes=[]):
+        """Retrieve the record for a public folder matching a specific display name
 
-        :param username: Username of the user
-        :param server: Server object name
+        :param server: Server Object Name
+        :param displayname: Display Name of the Folder
+        :param attributes: Requested Attributes
+        :return: LDB Object of the Folder
         """
-        return len(self.lookup_mailbox_user(server, username)) == 1
+        server_dn = self.lookup_server(server, []).dn
+
+        filter = "(&(objectClass=publicfolder)(PidTagDisplayName=%s))" % (displayname)
+        return self.ldb.search(server_dn, scope=ldb.SCOPE_SUBTREE,
+                               expression=filter, attrs=attributes)
 
     def get_message_attribute(self, server, attribute):
         """Retrieve attribute value from given message database (server).
@@ -270,246 +269,6 @@ ChangeNumber: %d
         finally:
             self.ldb.transaction_commit()
 
-    def get_user_attribute(self, server, username, attribute):
-        """Retrieve attribute value from given mailbox (server, username).
-
-        :param server: Server object name
-        :param username: User name
-        """
-        return self.lookup_mailbox_user(server, username, [attribute])[0][attribute]
-
-    def get_user_MailboxGUID(self, server, username):
-        return self.get_user_attribute(server, username, "MailboxGUID")
-
-    def get_user_ReplicaGUID(self, server, username):
-        return self.get_user_attribute(server, username, "ReplicaGUID")
-
-    def add_mailbox_user(self, basedn, username):
-        """Add a user record in openchange database.
-
-        :param username: Username
-        :return: DN of the created object
-        """
-        
-        mailboxGUID = str(uuid.uuid4())
-        replicaID = str(1)
-        replicaGUID = str(uuid.uuid4())
-        
-        retdn = "CN=%s,%s" % (username, basedn)
-        self.ldb.add({"dn": retdn,
-                  "objectClass": ["mailbox", "container"],
-                  "PidTagDisplayName": "OpenChange Mailbox: %s" % (username),
-                  "PidTagCreationTime": "%d" % self.nttime,
-                  "PidTagLastModificationTime": "%d" % self.nttime,
-                  "PidTagParentFolderId": "0",
-                  "PidTagSubFolders": "TRUE",
-                  "cn": username,
-                  "MailboxGUID": mailboxGUID,
-                  "PidTagAccess": str(63),
-                  "ReplicaID": replicaID,
-                  "ReplicaGUID": replicaGUID})
-        return retdn
-
-    def add_storage_dir(self, mapistoreURL, username):
-        """Add mapistore storage space for the user
-
-        :param username: Username object
-        :param mapistore: mapistore object
-        """
-
-        mapistore_dir = os.path.join(mapistoreURL, username)
-        if not os.path.isdir(mapistore_dir):
-            os.makedirs(mapistore_dir, mode=0700)
-    
-    def add_folder_property(self, folderID, attribute, value):
-        """Add a attribute/value to the record folderID refers to
-
-        :param folderID: the folder identifier where to add attribute/value
-        :param attribute: the ldb attribute
-        :param value: the attribute value
-        """
-
-        # Step 1. Find the folder record
-        res = self.ldb.search("", ldb.SCOPE_SUBTREE, "(PidTagFolderId=%s)" % folderID, ["*"])
-        if len(res) != 1:
-            raise Exception("Invalid search (PidTagFolderId=%s)" % folderID)
-
-        # Step 2. Add attribute/value pair
-        m = ldb.Message()
-        m.dn = ldb.Dn(self.ldb, "%s" % res[0].dn)
-        m[attribute] = ldb.MessageElement([value], ldb.CHANGETYPE_ADD, attribute);
-        self.ldb.modify(m)
-
-    def add_mailbox_root_folder(self, ocfirstorgdn, username, 
-                                foldername, parentfolder, 
-                                GlobalCount, ChangeNumber,
-                                ReplicaID,
-                                SystemIdx, mapistoreURL,
-                                mapistoreSuffix):
-        """Add a root folder to the user mailbox
-
-        :param username: Username object
-        :param foldername: Folder name
-        :param GlobalCount: current global counter for message database
-        :param ReplicaID: replica identifier for message database
-        :param SystemIdx: System Index for root folders
-        :param mapistoreURL: storage URL prefix (including type)
-        :param mapistoreSuffix: file type suffix to use with mapistore
-        """
-
-        ocuserdn = "CN=%s,%s" % (username, ocfirstorgdn)
-        FID = gen_mailbox_folder_fid(GlobalCount, ReplicaID)
-        CN = gen_mailbox_folder_fid(ChangeNumber, ReplicaID)
-
-        # Step 1. If we are handling Mailbox Root
-        if parentfolder == 0:
-            m = ldb.Message()
-            m.dn = ldb.Dn(self.ldb, ocuserdn)
-            m["PidTagFolderId"] = ldb.MessageElement([FID], ldb.CHANGETYPE_ADD, "PidTagFolderId")
-            m["PidTagChangeNumber"] = ldb.MessageElement([CN], ldb.CHANGETYPE_ADD, "PidTagChangeNumber")
-            m["SystemIdx"] = ldb.MessageElement([str(SystemIdx)], ldb.CHANGETYPE_ADD, "SystemIdx")
-            self.ldb.modify(m)
-            return FID
-
-        # Step 2. Lookup parent DN
-        res = self.ldb.search("", ldb.SCOPE_SUBTREE, "(PidTagFolderId=%s)" % parentfolder, ["*"])
-        if len(res) != 1:
-            raise Exception("Invalid search (PidTagFolderId=%s)" % parentfolder)
-
-        # Step 3. Add root folder to correct container
-        if (foldername == "IPM Subtree"):
-             self.ldb.add({"dn": "CN=%s,%s" % (FID, res[0].dn),
-                          "objectClass": ["systemfolder", "container"],
-                          "cn": FID,
-                          "PidTagParentFolderId": parentfolder,
-                          "PidTagFolderId": FID,
-                          "PidTagChangeNumber": CN,
-                          "PidTagDisplayName": foldername,
-                          "PidTagCreationTime": "%d" % self.nttime,
-                          "PidTagLastModificationTime": "%d" % self.nttime,
-                          "PidTagAttributeHidden": str(0),
-                          "PidTagAttributeReadOnly": str(0),
-                          "PidTagAttributeSystem": str(0),
-                          "PidTagContainerClass": "IPF.Note",
-                          "PidTagSubFolders": "TRUE",
-                          "FolderType": str(1),
-                          "PidTagAccess": str(63),
-                          "SystemIdx": str(SystemIdx),
-                          "mailboxDN": str(ocuserdn)})           
-        elif (foldername == "To-Do Search"):
-            self.ldb.add({"dn": "CN=%s,%s" % (FID, res[0].dn),
-                          "objectClass": ["systemfolder", "container"],
-                          "cn": FID,
-                          "PidTagParentFolderId": parentfolder,
-                          "PidTagFolderId": FID,
-                          "PidTagChangeNumber": CN,
-                          "PidTagDisplayName": foldername,
-                          "PidTagCreationTime": "%d" % self.nttime,
-                          "PidTagLastModificationTime": "%d" % self.nttime,
-                          "PidTagAttributeHidden": str(0),
-                          "PidTagAttributeReadOnly": str(0),
-                          "PidTagAttributeSystem": str(0),
-                          "PidTagContainerClass": "IPF.Note",
-                          "PidTagSubFolders": "FALSE",
-                          "FolderType": str(1),
-                          "PidTagAccess": str(63),
-                          "SystemIdx": str(SystemIdx),
-                          "mailboxDN": str(ocuserdn)})           
-        else:
-            self.ldb.add({"dn": "CN=%s,%s" % (FID, res[0].dn),
-                          "objectClass": ["systemfolder"],
-                          "cn": FID,
-                          "PidTagParentFolderId": parentfolder,
-                          "PidTagFolderId": FID,
-                          "PidTagChangeNumber": CN,
-                          "PidTagDisplayName": foldername,
-                          "PidTagCreationTime": "%d" % self.nttime,
-                          "PidTagLastModificationTime": "%d" % self.nttime,
-                          "PidTagAttributeHidden": str(0),
-                          "PidTagAttributeReadOnly": str(0),
-                          "PidTagAttributeSystem": str(0),
-                          "PidTagContainerClass": "IPF.Note",
-                          "PidTagSubFolders": "TRUE",
-                          "PidTagFolderChildCount": str(0),
-                          "FolderType": str(1),
-                          "MAPIStoreURI": "sogo://%s:%s@%s/" % (username, username, foldername.replace(" ", "-").lower()),
-                          "FolderType": str(1),
-                          "PidTagAccess": str(63),
-                          "PidTagRights":str(2043),
-                          "SystemIdx": str(SystemIdx),
-                          "mailboxDN": str(ocuserdn)})           
-
-        return FID
-
-    def add_mailbox_special_folder(self, username, parentfolder, 
-                                   foldername, containerclass, GlobalCount, ChangeNumber, ReplicaID, 
-                                   mapistoreURL, mapistoreSuffix, mailboxDN):
-        """Add a special folder to the user mailbox
-
-        :param username: Username object
-        :param parent_folder: Folder identifier where record should be added
-        :param foldername: Folder name
-        :param containerclass: Folder container class
-        :param GlobalCount: current global counter for message database
-        :param ChangeNumber: current change number for message database
-        :param ReplicaID: replica identifier for message database
-        :param mapistoreURL: mapistore default content repository URI
-        :param mapistoreSuffix: file type suffix to use with mapistore
-        :param mailboxDN: the DN of the user's mailbox
-        """
-
-        FID = gen_mailbox_folder_fid(GlobalCount, ReplicaID)
-        CN = gen_mailbox_folder_fid(ChangeNumber, ReplicaID)
-
-        # Step 1. Lookup parent DN
-        res = self.ldb.search("", ldb.SCOPE_SUBTREE, "(PidTagFolderId=%s)" % parentfolder, ["*"])
-        if len(res) != 1:
-            raise Exception("Invalid search (PidTagFolderId=%s)" % parentfolder)
-
-        # Step 2. Add special folder to user subtree
-        self.ldb.add({"dn": "CN=%s,%s" % (FID, res[0].dn),
-                      "objectClass": ["specialfolder"],
-                      "cn": FID,
-                      "PidTagParentFolderId": parentfolder,
-                      "PidTagFolderId": FID,
-                      "PidTagChangeNumber": CN,
-                      "PidTagDisplayName": foldername,
-                      "PidTagCreationTime": "%d" % self.nttime,
-                      "PidTagLastModificationTime": "%d" % self.nttime,
-                      "PidTagContainerClass": containerclass,
-                      "MAPIStoreURI": "sogo://%s:%s@%s/" % (username, username, foldername.replace(" ", "-").lower()),
-                      "PidTagContentCount": str(0),
-                      "PidTagAttributeHidden": str(0),
-                      "PidTagAttributeReadOnly": str(0),
-                      "PidTagAttributeSystem": str(0),
-                      "PidTagAccess": str(63),
-                      "PidTagRights": str(2043),
-                      "PidTagContentUnreadCount": str(0),
-                      "PidTagSubFolders": str(0),
-                      "FolderType": str(1),
-                      "mailboxDN": str(mailboxDN)})
-
-        return FID
-
-    def set_receive_folder(self, username, ocfirstorgdn, fid, messageclass):
-        """Set MessageClass for given folder
-
-        :param username: Username object
-        :param ocfirstorgdn: Base DN
-        :param fid: Folder identifier
-        :param messageclass: Explicit Message Class
-        """
-        
-        # Step 1. Search fid DN
-        res = self.ldb.search("", ldb.SCOPE_SUBTREE, "(PidTagFolderId=%s)" % fid, ["*"])
-        if len(res) != 1:
-            raise Exception("Invalid search (PidTagFolderId=%s)" % fid)
-
-        m = ldb.Message()
-        m.dn = res[0].dn
-        m["PidTagMessageClass"] = ldb.MessageElement([messageclass], ldb.CHANGETYPE_ADD, "PidTagMessageClass")
-        self.ldb.modify(m)
-
 def reverse_int64counter(GlobalCount):
     rev_counter = 0
     for x in xrange(6):
index 65d7569954cd60affc3588c6bfbb2e48646c69bd..d3fa5d7eefb1ff43279ff03d3b834b070847d7b5 100644 (file)
@@ -27,13 +27,13 @@ from samba import Ldb
 from samba.samdb import SamDB
 from samba.auth import system_session
 from samba.provision import setup_add_ldif, setup_modify_ldif
-from openchange.urlutils import openchangedb_url, openchangedb_mapistore_url, openchangedb_mapistore_dir, openchangedb_suffix_for_mapistore_url
+from openchange.urlutils import openchangedb_url
 
 __docformat__ = 'restructuredText'
 
 DEFAULTSITE = "Default-First-Site-Name"
 FIRST_ORGANIZATION = "First Organization"
-FIRST_ORGANIZATION_UNIT = "First Organization Unit"
+FIRST_ORGANIZATION_UNIT = "First Administrative Group"
 
 # This is a hack. Kind-of cute, but still a hack
 def abstract():
@@ -252,178 +252,6 @@ def install_schemas(setup_path, names, lp, creds, reporter):
     provision_schema(setup_path, names, lp, creds, reporter, "AD/oc_provision_configuration.ldif", "Exchange Samba with Exchange configuration objects")
     print "[SUCCESS] Done!"
 
-def newmailbox(lp, username, firstorg, firstou, backend):
-    def guid_to_binary(guid):
-        # "31c32976-efda-4d3c-81fb-63dd2ab9f780"
-       time_low = int(guid[0:8], 16)
-        time_mid = int(guid[9:13], 16)
-        time_hi_and_version = int(guid[14:18], 16)
-        clock_seq = ""
-        for x in xrange(2):
-            idx = 19 + x * 2
-            clock_seq = clock_seq + chr(int(guid[idx:idx+2], 16))
-        node = ""
-        for x in xrange(6):
-            idx = 24 + x * 2
-            node = node + chr(int(guid[idx:idx+2], 16))
-
-        binguid = struct.pack("<LHH", time_low, time_mid, time_hi_and_version) + clock_seq + node
-
-        return binguid
-
-    def make_folder_entryid(provider_uid, folder_type, database_guid, counter):
-        entryid = (4 * chr(0)  #flags
-                   + provider_uid
-                   + struct.pack("<H", folder_type)
-                   + database_guid
-                   + struct.pack(">LH", (counter >> 16) & 0xffffffff, (counter & 0xffff))
-                   + 2 * chr(0)) # padding
-
-        return entryid
-
-    names = guess_names_from_smbconf(lp, firstorg, firstou)
-
-    db = mailbox.OpenChangeDB(openchangedb_url(lp))
-
-    # Step 1. Retrieve current FID index
-    GlobalCount = db.get_message_GlobalCount(names.netbiosname)
-    ChangeNumber = db.get_message_ChangeNumber(names.netbiosname)
-    ReplicaID = db.get_message_ReplicaID(names.netbiosname)
-
-    print "[+] Mailbox for '%s'" % (username)
-    print "==================" + "=" * len(username)
-    print "* GlobalCount (0x%x), ChangeNumber (0x%x) and ReplicaID (0x%x)" % (GlobalCount, ChangeNumber, ReplicaID)
-
-    # Step 2. Check if the user already exists
-    assert not db.user_exists(names.netbiosname, username)
-
-    # Step 3. Create a default mapistore content repository for this user
-    db.add_storage_dir(mapistoreURL=openchangedb_mapistore_dir(lp), username=username)
-    print "* Mapistore content repository created: %s" % os.path.join(openchangedb_mapistore_dir(lp), username)
-
-    # Step 4. Create the user object
-    retdn = db.add_mailbox_user(names.ocfirstorgdn, username=username)
-    print "* User object created: %s" % (retdn)
-
-    # Step 5. Create system mailbox folders for this user
-    print "* Adding System Folders"
-
-    system_folders = ({
-        "Deferred Actions": ({}, 2),
-        "Spooler Queue": ({}, 3),
-        "To-Do Search": ({}, 4),
-        "IPM Subtree": ({
-            "Inbox": ({}, 6),
-            "Outbox": ({}, 7),
-            "Sent Items": ({}, 8),
-            "Deleted Items": ({}, 9),
-        }, 5),
-        "Common Views": ({}, 10),
-        "Schedule": ({}, 11),
-        "Search": ({}, 12),
-        "Views": ({}, 13),
-        "Shortcuts": ({}, 14),
-        "Reminders": ({}, 15),
-    }, 1)
-
-    fids = {}
-    def add_folder(parent_fid, path, children, SystemIdx):
-        name = path[-1]
-
-        GlobalCount = db.get_message_GlobalCount(names.netbiosname)
-        ChangeNumber = db.get_message_ChangeNumber(names.netbiosname)
-        ReplicaID = db.get_message_ReplicaID(names.netbiosname)
-        url = openchangedb_mapistore_url(lp, backend)
-
-        fid = db.add_mailbox_root_folder(names.ocfirstorgdn, 
-                                         username=username, foldername=name,
-                                         parentfolder=parent_fid,
-                                         GlobalCount=GlobalCount, ChangeNumber=ChangeNumber,
-                                         ReplicaID=ReplicaID, SystemIdx=SystemIdx, 
-                                         mapistoreURL=url,
-                                         mapistoreSuffix=openchangedb_suffix_for_mapistore_url(url))
-
-        GlobalCount += 1
-        db.set_message_GlobalCount(names.netbiosname, GlobalCount=GlobalCount)
-        ChangeNumber += 1
-        db.set_message_ChangeNumber(names.netbiosname, ChangeNumber=ChangeNumber)
-
-        fids[path] = fid
-
-        print "\t* %-40s: 0x%.16x (%s)" % (name, int(fid, 10), fid)
-        for name, grandchildren in children.iteritems():
-            add_folder(fid, path + (name,), grandchildren[0], grandchildren[1])
-
-    add_folder(0, ("Mailbox Root",), system_folders[0], system_folders[1])
-
-    # Step 6. Add special folders
-    print "* Adding Special Folders:"
-    special_folders = [
-        (("Mailbox Root", "IPM Subtree"), "Calendar",   "IPF.Appointment",  "PidTagIpmAppointmentEntryId"),
-        (("Mailbox Root", "IPM Subtree"), "Contacts",   "IPF.Contact",      "PidTagIpmContactEntryId"),
-        (("Mailbox Root", "IPM Subtree"), "Journal",    "IPF.Journal",      "PidTagIpmJournalEntryId"),
-        (("Mailbox Root", "IPM Subtree"), "Notes",      "IPF.StickyNote",   "PidTagIpmNoteEntryId"),
-        (("Mailbox Root", "IPM Subtree"), "Tasks",      "IPF.Task",         "PidTagIpmTaskEntryId"),
-        (("Mailbox Root", "IPM Subtree"), "Drafts",     "IPF.Note",         "PidTagIpmDraftsEntryId")
-        ]
-
-    fid_inbox = fids[("Mailbox Root", "IPM Subtree", "Inbox")]
-    fid_reminders = fids[("Mailbox Root", "Reminders")]
-    fid_mailbox = fids[("Mailbox Root",)]
-
-    mailbox_guid = guid_to_binary(db.get_user_MailboxGUID(names.netbiosname, username)[0])
-    replica_guid = guid_to_binary(db.get_user_ReplicaGUID(names.netbiosname, username)[0])
-
-    for path, foldername, containerclass, pidtag in special_folders:
-        GlobalCount = db.get_message_GlobalCount(names.netbiosname)
-        ChangeNumber = db.get_message_ChangeNumber(names.netbiosname)
-        ReplicaID = db.get_message_ReplicaID(names.netbiosname)
-        url = openchangedb_mapistore_url(lp, backend)
-        fid = db.add_mailbox_special_folder(username, fids[path], foldername, 
-                                            containerclass, GlobalCount, ChangeNumber, ReplicaID, 
-                                            url, openchangedb_suffix_for_mapistore_url(url), retdn)
-        entryid = make_folder_entryid(mailbox_guid, 1, replica_guid, GlobalCount)
-        db.add_folder_property(fid_inbox, pidtag, entryid.encode("base64").strip())
-        db.add_folder_property(fid_mailbox, pidtag, entryid.encode("base64").strip())
-        GlobalCount += 1
-        db.set_message_GlobalCount(names.netbiosname, GlobalCount=GlobalCount)
-        ChangeNumber += 1
-        db.set_message_ChangeNumber(names.netbiosname, ChangeNumber=ChangeNumber)
-        print "\t* %-40s: 0x%.16x (%s)" % ("%s (%s)" % (foldername, containerclass), int(fid, 10), fid)
-
-    # Step 7. Set default receive folders
-    print "* Adding default Receive Folders:"
-    receive_folders = [
-        (("Mailbox Root", "IPM Subtree", "Inbox"), "All"),
-        (("Mailbox Root", "IPM Subtree", "Inbox"), "IPM"),
-        (("Mailbox Root", "IPM Subtree", "Inbox"), "Report.IPM"),
-        (("Mailbox Root", "IPM Subtree", "Inbox"), "IPM.Note"),
-        (("Mailbox Root", "IPM Subtree",), "IPC")
-        ]
-    
-    for path, messageclass in receive_folders:
-        print "\t* Message Class '%s' added to 0x%.16x (%s)" % (messageclass, int(fids[path], 10), fids[path])
-        db.set_receive_folder(username, names.ocfirstorgdn, fids[path], messageclass)
-
-    # Step 8. Set additional properties on Inbox
-    print "* Adding additional default properties to Inbox"
-    db.add_folder_property(fid_inbox, "PidTagContentCount", "0")
-    db.add_folder_property(fid_inbox, "PidTagContentUnreadCount", "0")
-    db.add_folder_property(fid_inbox, "PidTagSubFolders", "FALSE")
-
-    print "* Adding additional default properties to Reminders"
-    db.add_folder_property(fid_reminders, "PidTagContainerClass", "Outlook.Reminder");
-
-    rev_fid_reminders = mailbox.reverse_int64counter(int(fid_reminders, 10) >> 16) >> 16
-    entryid = make_folder_entryid(mailbox_guid, 1, replica_guid, rev_fid_reminders)
-    db.add_folder_property(fid_inbox, "PidTagRemindersOnlineEntryId", entryid.encode("base64").strip())
-    db.add_folder_property(fid_mailbox, "PidTagRemindersOnlineEntryId", entryid.encode("base64").strip())
-    GlobalCount = db.get_message_GlobalCount(names.netbiosname)
-    print "* GlobalCount (0x%.12x)" % GlobalCount
-    ChangeNumber = db.get_message_ChangeNumber(names.netbiosname)
-    print "* ChangeNumber (0x%.12x)" % ChangeNumber
-
-
 def newuser(lp, creds, username=None):
     """extend user record with OpenChange settings.
     
@@ -540,10 +368,9 @@ def openchangedb_provision(lp, firstorg=None, firstou=None, mapistore=None):
     # and the Replica identifier
     openchange_ldb.add_server(names.ocserverdn, names.netbiosname, names.firstorg, names.firstou)
 
-    mapistoreURL = os.path.join( openchangedb_mapistore_url(lp, mapistore), "publicfolders")
     print "[+] Public Folders"
     print "==================="
-    openchange_ldb.add_public_folders(names, mapistoreURL)
+    openchange_ldb.add_public_folders(names)
 
 def find_setup_dir():
     """Find the setup directory used by provision."""
index 95e9f798948fdd92b9b9a15691af2de5d6f6a4fb..6a92490b52bc122513b3875b164e5f3987fe01c3 100644 (file)
 
 import os
 
-
-class UnsupportedMapistoreBackend(Exception):
-    
-    def __init__(self, backend):
-        super(UnsupportedMapistoreBackend, self).__init__("unsupported mapistore backend type: %s" % backend)
-
-
 def openchangedb_url(lp):
     return os.path.join(lp.get("private dir"), "openchange.ldb")
-
-
-def openchangedb_mapistore_dir(lp):
-    return os.path.join(lp.get("private dir"), "mapistore")
-
-
-def openchangedb_mapistore_url(lp, backend):
-    if backend in ("fsocpf", None):
-        return "fsocpf://%s" % openchangedb_mapistore_dir(lp)
-    elif backend == "sqlite":
-        return "sqlite://%s" % openchangedb_mapistore_dir(lp)
-    elif backend == "sogo":
-        return "sogo://%s" % openchangedb_mapistore_dir(lp)
-    raise UnsupportedMapistoreBackend(backend)
-
-
-def openchangedb_mapistore_url_split(url):
-    if url.startswith("fsocpf://"):
-        return url.partition("fsocpf://")[1:]
-    if url.startswith("sqlite://"):
-        return url.partition("sqlite://")[1:]
-    if url.startswith("sogo://"):
-        return url.partition("sogo://")[1:]
-
-
-def openchangedb_suffix_for_mapistore_url(url):
-    if (url.startswith("fsocpf://")):
-        return ""
-    if (url.startswith("sqlite://")):
-        return ".db"
-    if (url.startswith("sogo://")):
-        return ""
-    return ""
index d78a08e532bf2d9feb9bc911d4d4a9ee0e060d77..e2fcc998190a2f75757784c82c3bde69fd526633 100755 (executable)
@@ -44,8 +44,6 @@ parser.add_option("--create", action="store_true", metavar="CREATE",
                  help="Create the OpenChange user account")
 parser.add_option("--mailbox", action="store_true", metavar="MAILBOX",
                  help="Create the OpenChange user mailbox")
-parser.add_option("--mapistore", type="string", metavar="STORE",
-                 help="The backend storage type to use (only for --mailbox)")
 opts, args = parser.parse_args()
 
 if len(args) == 0:
@@ -67,9 +65,6 @@ if opts.disable == True:
 if opts.create == True:
        openchange.newuser(lp, creds, username=args[0])
 
-backend = "fsocpf" #default
-if opts.mapistore is not None:
-       backend = opts.mapistore
-
 if opts.mailbox == True:
-       openchange.newmailbox(lp, username=args[0], firstorg=None, firstou=None, backend=backend)
+        print "Mailbox provisioning is now performed automatically at user logon"
+
index e827de17752d3c16a6e535e3bc623b9e330e95b0..869c3bb32b90c95a5d98ecc4e3a8df5479bf1f02 100755 (executable)
@@ -41,8 +41,6 @@ parser.add_option("--firstorg", type="string", metavar="FIRSTORG",
 parser.add_option("--firstou", type="string", metavar="FIRSTOU", 
                   help="set OpenChange First Organization Unit (otherwise First Organization Unit)")
 parser.add_option("--openchangedb", action="store_true", help="Initialize OpenChange dispatcher database")
-parser.add_option("--mapistore", type="string", metavar="STORE",
-                 help="The backend storage type to use (only for --openchangedb)")
 opts,args = parser.parse_args()
 if len(args) != 0:
     parser.print_usage()
@@ -54,11 +52,7 @@ creds = credopts.get_credentials(lp)
 def setup_path(*args):
     return os.path.join(os.path.dirname(__file__), *args)
 
-backend = "fsocpf" #default
-if opts.mapistore is not None:
-       backend = opts.mapistore
-
 if not opts.openchangedb:
        openchange.provision(setup_path, lp, creds, firstorg=opts.firstorg, firstou=opts.firstou)
 else:
-       openchange.openchangedb_provision(lp, firstorg=opts.firstorg, firstou=opts.firstou, mapistore=backend)
+       openchange.openchangedb_provision(lp, firstorg=opts.firstorg, firstou=opts.firstou)
index b0d3052125bb4c2fa93f946f1f07bf93691473b5..1282f98613ea8485e54b062747913d1a7ef1d6e8 100644 (file)
@@ -242,6 +242,7 @@ int main(int argc, const char *argv[])
        enum TransferStatus             fxTransferStatus;
        DATA_BLOB                       transferdata;
        struct fx_parser_context        *parser;
+       struct loadparm_context         *lp_ctx;
        struct mapistore_output_ctx     output_ctx;
        poptContext                     pc;
        int                             opt;
@@ -390,7 +391,11 @@ int main(int argc, const char *argv[])
                        exit (1);
                }
 
-               output_ctx.mstore_ctx = mapistore_init(mem_ctx, NULL);
+               /* Initialize configuration */
+               lp_ctx = loadparm_init(mem_ctx);
+               lpcfg_load_default(lp_ctx);
+
+               output_ctx.mstore_ctx = mapistore_init(mem_ctx, lp_ctx, NULL);
                if (!(output_ctx.mstore_ctx)) {
                        mapi_errstr("mapistore_init", retval);
                        exit (1);
index 5efa599c8ebcef7034dc1c99dd9ac7ef8af417e3..7fe8772b6f666d2b3a5c39b5eeb03994601a7fbd 100755 (executable)
@@ -220,7 +220,10 @@ class GetPropsParser:
     def _printSysTime(self, pos):
         nano100Seconds = struct.unpack_from("<Q", self.response, pos)[0]
         seconds = (nano100Seconds / 10000000) - 11644473600
-        print "(PT_SYSTIME) %s" % time.strftime("%a, %d %b %Y %T %z", time.localtime(seconds))
+        try:
+            print "(PT_SYSTIME) %s" % time.strftime("%a, %d %b %Y %T %z", time.localtime(seconds))
+        except:
+            print "(PT_SYSTIME) %d (seconds)" % seconds
 
         return 8
 
@@ -253,7 +256,7 @@ class GetPropsParser:
     def _printMultiValue(self, pos, colType):
         length = struct.unpack_from("<L", self.response, pos)[0]
         subtype = colType & 0x0fff
-        print "multivalue (%d, 0x%.4x)" % (length, subtype)
+        print "multivalue (%d, 0xX%.3x)" % (length, subtype)
         consumed = 4
         for x in xrange(length):
             consumed = consumed + self._printValue(pos + consumed, subtype)