# 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) \
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 \
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 \
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: \
typedef [enum8bit] enum {
ReadOnly = 0x0,
ReadWrite = 0x1,
- Create = 0x3,
+ BestAccess = 0x3,
OpenSoftDelete = 0x4
} OpenMessage_OpenModeFlags;
uint16 MessageIdSize;
uint8 MessageId[MessageIdSize];
boolean8 MarkAsRead;
- } MessageReadStates;
+ } MessageReadState;
typedef [flag(NDR_NOALIGN)] struct {
[subcontext(2),flag(NDR_REMAINING)] DATA_BLOB MessageReadStates;
} 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;
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);
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);
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
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);
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);
}
+/**
+ \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.
#include "libmapi/libmapi_private.h"
#include <util/debug.h>
+static int dispatch_nbr = 0;
+
/**
\file dcesrv_mapiproxy.c
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"));
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;
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;
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;
}
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 **);
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 *);
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 **);
*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);
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);
}
/* 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);
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.
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);
/* 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 */
\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
*/
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)
break;
default:
DEBUG(0, ("[%s:%d] Property Type 0x%.4x not supported\n", __FUNCTION__, __LINE__, (proptag & 0xFFFF)));
+ abort();
return NULL;
}
\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
*/
_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)
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" */
\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
*/
_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)
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" */
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,
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.
\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;
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);
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);
}
+/**
+ \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
\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;
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");
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;
}
/**
/* 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);
/* 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) {
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;
}
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;
_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,
/* 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;
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);
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;
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" */
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;
}
break;
default:
+ if (property != 0) {
+ DEBUG(5, ("unsupported type: %.4x\n", (property & 0xffff)));
+ abort();
+ }
break;
}
end:
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;
#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
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,
};
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 */
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;
};
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);
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) */
};
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 **);
\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;
\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;
\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;
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, ¤t_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
\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;
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;
}
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);
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;
}
/**
\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;
\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;
}
}
-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);
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;
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,
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)
{
\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;
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",
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;
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; */
+/* } */
/**
\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;
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;
\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;
\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;
\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;
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;
\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);
}
\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);
}
\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);
}
\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);
}
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) {
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)));
\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;
\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);
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;
\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;
char *namespace;
char *namespace_start;
char *backend_uri;
+ char *mapistore_dir;
struct indexing_context_list *ictx;
/* Step 1. Perform Sanity Checks on URI */
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;
\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;
/* 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;
\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;
\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;
}
/* 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));
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);
\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:
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
\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);
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);
}
/**
\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);
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);
}
\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);
/* 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;
}
/**
\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);
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);
}
\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);
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);
}
/**
\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);
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);
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);
}
\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);
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
\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);
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);
}
/**
\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);
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);
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);
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);
}
/**
\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);
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);
}
/**
\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);
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);
}
/**
\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);
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);
}
/**
\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);
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);
}
\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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
}
\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;
\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;
\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;
\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;
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;
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;
};
/* 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);
/* 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
\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;
*/
const char *mapistore_get_mapping_path(void)
{
- return (!mapping_path) ? MAPISTORE_MAPPING_PATH : (const char *)mapping_path;
+ return (const char *)mapping_path;
}
\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;
\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;
\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;
\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;
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; */
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;
\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;
\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;
\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);
\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);
\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);
\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,
\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,
\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;
\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;
\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;
\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;
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);
\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,
\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,
}
-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;
\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,
/* 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
#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;
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;
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;
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);
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;
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;
#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;
/* \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, */
/* } */
-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;
/**
\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;
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);
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) {
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;
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,
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;
TALLOC_CTX *mem_ctx,
void *r, struct mapiproxy *mapiproxy)
{
- enum MAPISTATUS retval;
const struct ndr_interface_table *table;
uint16_t opnum;
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);
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);
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;
};
struct emsmdbp_object_stream {
+ bool read_write;
bool needs_commit;
enum MAPITAGS property;
struct emsmdbp_stream stream;
#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
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 *);
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 */
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__));
\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)
{
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;
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;
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);
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__));
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);
}
(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)
\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;
&& 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)
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]);
}
}
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;
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];
}
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);
*/
_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;
/* 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;
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",
}
} 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);
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) {
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)
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:
}
}
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);
}
/* 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,
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;
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);
}
} 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 {
}
}
- talloc_free(subfolder);
talloc_free(odb_ctx);
}
_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;
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;
}
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)
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,
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;
}
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++) {
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;
}
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;
}
}
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;
}
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;
}
}
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);
}
}
* 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);
/* 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;
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
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);
--- /dev/null
+/*
+ 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, ¤t_fid);
+ if (ret != MAPI_E_SUCCESS) {
+ openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, ¤t_fid);
+ openchangedb_get_new_changeNumber(emsmdbp_ctx->oc_ctx, ¤t_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, ¤t_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, ¤t_fid);
+ if (ret == MAPI_E_SUCCESS) {
+ if (i == EMSMDBP_INBOX) {
+ inbox_fid = current_fid;
+ }
+ } else {
+ openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, ¤t_fid);
+ openchangedb_get_new_changeNumber(emsmdbp_ctx->oc_ctx, ¤t_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, ¤t_fid);
+ openchangedb_get_new_changeNumber(emsmdbp_ctx->oc_ctx, ¤t_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, ¤t_fid);
+ openchangedb_get_new_changeNumber(emsmdbp_ctx->oc_ctx, ¤t_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;
+}
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;
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);
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;
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 */
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;
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;
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;
}
}
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.
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"));
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;
}
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;
}
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);
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;
}
/**
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];
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);
}
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();
}
}
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);
{
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;
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;
}
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);
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);
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));
/* 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;
/* 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;
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;
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;
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);
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);
}
}
/* 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) {
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();
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();
}
}
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();
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;
struct mapistore_message *msg;
struct SRow aRow;
-
DEBUG(4, ("exchange_emsmdb: [OXCFXICS] RopSyncImportMessageChange (0x72)\n"));
/* Sanity checks */
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);
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 */
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"));
}
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;
}
}
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;
}
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));
+ }
}
}
}
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;
}
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++) {
}
/**
- \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;
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); */
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;
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"));
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);
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 {
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;
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:
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);
}
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);
}
{
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;
/* 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;
/* 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);
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;
struct SRow aRow;
uint32_t pt_long;
bool pt_boolean;
+ struct SBinary_short *pt_binary;
struct timeval tv;
struct FILETIME ft;
NTTIME time;
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);
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,
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"));
uint32_t contextID;
char *owner;
uint8_t flags;
+ enum mapistore_error ret;
DEBUG(4, ("exchange_emsmdb: [OXCMSG] SaveChangesMessage (0x0c)\n"));
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;
}
&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);
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;
}
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;
}
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);
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;
}
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);
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++) {
void **data_pointers;
enum MAPISTATUS *retvals;
struct emsmdbp_stream_data *stream_data;
+ enum OpenStream_OpenModeFlags mode;
DEBUG(4, ("exchange_emsmdb: [OXCPRPT] OpenStream (0x2b)\n"));
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;
}
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;
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;
}
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);
goto end;
}
+ if (!object->object.stream->read_write) {
+ mapi_repl->error_code = MAPI_E_NO_ACCESS;
+ goto end;
+ }
+
emsmdbp_object_stream_commit(object);
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;
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;
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;
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;
}
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;
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;
}
/* 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;
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) {
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;
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;
}
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;
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;
}
}
/* 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++;
}
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;
* 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;
}
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 */
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 {
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;
}
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);
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;
}
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();
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"));
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 */
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);
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,
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;
*/
#include <Python.h>
+#include <inttypes.h>
#include "pyopenchange/mapistore/pymapistore.h"
static void py_MAPIStoreContext_dealloc(PyObject *_self)
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);
}
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 }
};
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;
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;
}
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 };
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);
"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,
"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)
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
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).
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):
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():
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.
# 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."""
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 ""
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:
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"
+
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()
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)
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;
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);
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
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)