/**
   \details Save (commit) message in openchangedb database

   \param msg the message object
   \param SaveFlags flags associated to the save operation

   \return MAPI_E_SUCCESS on success, otherwise MAPI error
 */
_PUBLIC_ enum MAPISTATUS openchangedb_message_save(void *_msg, uint8_t SaveFlags)
{
	struct openchangedb_message *msg = (struct openchangedb_message *)_msg;

	/* Sanity checks */
	OPENCHANGE_RETVAL_IF(!msg, MAPI_E_NOT_INITIALIZED, NULL);
	OPENCHANGE_RETVAL_IF(!msg->ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL);

	switch (msg->status) {
	case OPENCHANGEDB_MESSAGE_CREATE:
		OPENCHANGE_RETVAL_IF(!msg->msg, MAPI_E_NOT_INITIALIZED, NULL);
		if (ldb_add(msg->ldb_ctx, msg->msg) != LDB_SUCCESS) {
			return MAPI_E_CALL_FAILED;
		}
		break;
	case OPENCHANGEDB_MESSAGE_OPEN:
		if (ldb_modify(msg->ldb_ctx, msg->res->msgs[0]) != LDB_SUCCESS) {
			return MAPI_E_CALL_FAILED;
		}
		break;
	}

	/* FIXME: Deal with SaveFlags */

	return MAPI_E_SUCCESS;
}
Example #2
0
/**
   \details Logoff an Exchange store

   This function uninitializes the MAPI session associated to the
   object.

   \param obj_store pointer to the store object

   \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND
 */
_PUBLIC_ enum MAPISTATUS Logoff(mapi_object_t *obj_store)
{
    struct mapi_context	*mapi_ctx;
    struct mapi_session	*session;
    struct mapi_session	*el;
    bool			found = false;

    /* Sanity checks */
    session = mapi_object_get_session(obj_store);
    OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);

    mapi_ctx = session->mapi_ctx;
    OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);

    for (el = mapi_ctx->session; el; el = el->next) {
        if (session == el) {
            found = true;
            mapi_object_release(obj_store);
            DLIST_REMOVE(mapi_ctx->session, el);
            MAPIFreeBuffer(session);
            break;
        }
    }

    return (found == true) ? MAPI_E_SUCCESS : MAPI_E_NOT_FOUND;
}
Example #3
0
/**
   \details Retrieve the total number of records in the global address
   list

   The Global Address List is the full list of email addresses (and other
   account-type things, such as "rooms" and distribution lists) accessible
   on the server. A user will usually have access to both a personal
   address book, and to the Global Address List. Public Address Book is
   another name for Global Address List.

   \param session pointer to the MAPI session context
   \param totalRecs pointers to the total number of records in the
   global address list returned

   \return MAPI_E_SUCCESS on success, otherwise MAPI error.

   \note Developers may also call GetLastError() to retrieve the last
   MAPI error code. Possible MAPI error codes are:
   -# MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
   -# MAPI_E_SESSION_LIMIT: No session has been opened on the provider
   -# MAPI_E_INVALID_PARAMETER: if a function parameter is invalid
   -# MAPI_E_CALL_FAILED: A network problem was encountered during the
     transaction
 */
_PUBLIC_ enum MAPISTATUS GetGALTableCount(struct mapi_session *session,
					  uint32_t *totalRecs)
{
	TALLOC_CTX		*mem_ctx;
	struct nspi_context	*nspi;
	enum MAPISTATUS		retval;
	struct PropertyRowSet_r	*rowset;

	/* Sanity Checks */
	OPENCHANGE_RETVAL_IF(!session, MAPI_E_SESSION_LIMIT, NULL);
	OPENCHANGE_RETVAL_IF(!session->nspi, MAPI_E_SESSION_LIMIT, NULL);
	OPENCHANGE_RETVAL_IF(!session->nspi->ctx, MAPI_E_SESSION_LIMIT, NULL);

	mem_ctx = talloc_named(session, 0, "GetGALTableCount");
	nspi = (struct nspi_context *) session->nspi->ctx;

	nspi->pStat->CurrentRec = 0;
	nspi->pStat->Delta = 0;
	nspi->pStat->NumPos = 0;
	nspi->pStat->TotalRecs = 0xffffffff;

	rowset = talloc_zero(mem_ctx, struct PropertyRowSet_r);
	retval = nspi_QueryRows(nspi, mem_ctx, NULL, NULL, 0, &rowset);

	*totalRecs = nspi->pStat->TotalRecs;
	
	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
	talloc_free(mem_ctx);
	
	return MAPI_E_SUCCESS;
}
Example #4
0
/**
   \details Get the organization name (like "First Organization") as a DN.

   \param emsmdbp_ctx pointer to the EMSMDBP context
   \param basedn pointer to the returned struct ldb_dn

   \return MAPI_E_SUCCESS or an error if something happens
 */
_PUBLIC_ enum MAPISTATUS emsmdbp_get_org_dn(struct emsmdbp_context *emsmdbp_ctx, struct ldb_dn **basedn)
{
	enum MAPISTATUS		retval;
	int			ret;
	struct ldb_result	*res = NULL;
	char			*org_name;

	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx->samdb_ctx, MAPI_E_NOT_INITIALIZED, NULL);
	OPENCHANGE_RETVAL_IF(!basedn, MAPI_E_INVALID_PARAMETER, NULL);

	retval = emsmdbp_fetch_organizational_units(emsmdbp_ctx, emsmdbp_ctx, &org_name, NULL);
	OPENCHANGE_RETVAL_IF(retval != MAPI_E_SUCCESS, retval, NULL);

	ret = ldb_search(emsmdbp_ctx->samdb_ctx, emsmdbp_ctx, &res,
			 ldb_get_config_basedn(emsmdbp_ctx->samdb_ctx),
                         LDB_SCOPE_SUBTREE, NULL,
                         "(&(objectClass=msExchOrganizationContainer)(cn=%s))",
                         ldb_binary_encode_string(emsmdbp_ctx, org_name));
	talloc_free(org_name);

	/* If the search failed */
        if (ret != LDB_SUCCESS) {
	  	DEBUG(1, ("emsmdbp_get_org_dn ldb_search failure.\n"));
		return MAPI_E_NOT_FOUND;
        }

	*basedn = ldb_dn_new(emsmdbp_ctx, emsmdbp_ctx->samdb_ctx,
			     ldb_msg_find_attr_as_string(res->msgs[0], "distinguishedName", NULL));
	return MAPI_E_SUCCESS;
}
Example #5
0
/**
   \details Returns information about template objects in the address
   book.

   \param nspi_ctx pointer to the NSPI memory context
   \param mem_ctx pointer to the memory context
   \param dwFlags set of bit flags
   \param ulType specifies the display type of the template
   \param pDN the DN of the template requested
   \param ppData pointer on pointer to the data requested

   Possible values for dwFlags:
   -# TI_TEMPLATE to return the template
   -# TI_SCRIPT to return the script associated to the template
   -# TI_EMT to return the e-mail type associated to the template
   -# TI_HELPFILE_NAME to return the help file associated to the
      template
   -# TI_HELPFILE_CONTENTS to return the contents of the help file
      associated to the template
   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
 */
_PUBLIC_ enum MAPISTATUS nspi_GetTemplateInfo(struct nspi_context *nspi_ctx,
					      TALLOC_CTX *mem_ctx,
					      uint32_t dwFlags,
					      uint32_t ulType,
					      char *pDN,
					      struct PropertyRow_r **ppData)
{
	struct NspiGetTemplateInfo	r;
	NTSTATUS			status;
	enum MAPISTATUS			retval;

	/* Sanity checks */
	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
	OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL);
	OPENCHANGE_RETVAL_IF(!ppData, MAPI_E_INVALID_PARAMETER, NULL);

	r.in.handle = &nspi_ctx->handle;
	r.in.dwFlags = dwFlags;
	r.in.ulType = ulType;
	r.in.pDN = pDN;
	r.in.dwCodePage = nspi_ctx->pStat->CodePage;
	r.in.dwLocaleID = nspi_ctx->pStat->TemplateLocale;
	
	r.out.ppData = ppData;

	status = dcerpc_NspiGetTemplateInfo_r(nspi_ctx->rpc_connection->binding_handle, mem_ctx, &r);
	retval = r.out.result;
	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
	

	return MAPI_E_SUCCESS;
}
Example #6
0
/**
   \details Updates the STAT block representing position in a table to
   reflect positioning changes requested by the client.

   \param nspi_ctx pointer to the NSPI connection context
   \param mem_ctx pointer to the memory context
   \param plDelta pointer to an unsigned long indicating movement
   within the address book container specified by the input parameter
   pStat.

   \return MAPI_E_SUCCESS on success, otherwise MAPI error
 */
_PUBLIC_ enum MAPISTATUS nspi_UpdateStat(struct nspi_context *nspi_ctx, 
					 TALLOC_CTX *mem_ctx,
					 uint32_t *plDelta)
{
	struct NspiUpdateStat		r;
	NTSTATUS			status;
	enum MAPISTATUS			retval;

	/* Sanity checks */
	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
	OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL);
	OPENCHANGE_RETVAL_IF(!plDelta, MAPI_E_INVALID_PARAMETER, NULL);

	r.in.handle = &nspi_ctx->handle;
	r.in.Reserved = 0x0;

	r.in.pStat = nspi_ctx->pStat;
	r.in.plDelta = plDelta;

	r.out.pStat = nspi_ctx->pStat;
	r.out.plDelta = r.in.plDelta;

	status = dcerpc_NspiUpdateStat_r(nspi_ctx->rpc_connection->binding_handle, mem_ctx, &r);
	retval = r.out.result;
	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
	OPENCHANGE_RETVAL_IF(retval, retval, NULL);

	return MAPI_E_SUCCESS;
}
Example #7
0
/**
   \details EcDoRpc SetSearchCriteria (0x30) Rop. This operation sets
   the search criteria for a search folder.

   \param mem_ctx pointer to the memory context
   \param emsmdbp_ctx pointer to the emsmdb provider context
   \param mapi_req pointer to the SetSearchCriteria EcDoRpc_MAPI_REQ
   structure
   \param mapi_repl pointer to the SetSearchCriteria EcDoRpc_MAPI_REPL
   structure
   \param handles pointer to the MAPI handles array
   \param size pointer to the mapi_response size to update

   \return MAPI_E_SUCCESS on success, otherwise MAPI error  
 */
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetSearchCriteria(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)
{
	OC_DEBUG(4, "exchange_emsmdb: [OXCFOLD] SetSearchCriteria (0x30)\n");

	/* Sanity checks */
	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
	OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
	OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
	OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
	OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);

	mapi_repl->opnum = mapi_req->opnum;
	mapi_repl->handle_idx = mapi_req->handle_idx;
	mapi_repl->error_code = MAPI_E_SUCCESS;

	/* TODO: actually implement this */

	*size += libmapiserver_RopSetSearchCriteria_size(mapi_repl);

	return MAPI_E_SUCCESS;
}
Example #8
0
/**
   \details Map an EphemeralEntryID structure into a Binary_r structure

   \param mem_ctx pointer to the memory context
   \param ephEntryID pointer to the Ephemeral EntryID structure
   \param bin pointer to the Binary_r structure the server will return

   \return MAPI_E_SUCCESS on success, otherwise MAPI_E_INVALID_PARAMETER
 */
_PUBLIC_ enum MAPISTATUS emsabp_EphemeralEntryID_to_Binary_r(TALLOC_CTX *mem_ctx,
							     struct EphemeralEntryID *ephEntryID,
							     struct Binary_r *bin)
{
	/* Sanity checks */
	OPENCHANGE_RETVAL_IF(!ephEntryID, MAPI_E_INVALID_PARAMETER, NULL);
	OPENCHANGE_RETVAL_IF(!bin, MAPI_E_INVALID_PARAMETER, NULL);

	bin->cb = sizeof (*ephEntryID);
	bin->lpb = talloc_array(mem_ctx, uint8_t, bin->cb);

	/* Copy EphemeralEntryID into bin->lpb */
	memset(bin->lpb, 0, bin->cb);
	bin->lpb[0] = ephEntryID->ID_type;
	bin->lpb[1] = ephEntryID->R1;
	bin->lpb[2] = ephEntryID->R2;
	bin->lpb[3] = ephEntryID->R3;
	memcpy(bin->lpb + 4, ephEntryID->ProviderUID.ab, 16);
	bin->lpb[20] = (ephEntryID->R4 & 0xFF);
	bin->lpb[21] = ((ephEntryID->R4 >> 8)  & 0xFF);
	bin->lpb[22] = ((ephEntryID->R4 >> 16) & 0xFF);
	bin->lpb[23] = ((ephEntryID->R4 >> 24) & 0xFF);
	bin->lpb[24] = (ephEntryID->DisplayType & 0xFF);
	bin->lpb[25] = ((ephEntryID->DisplayType >> 8)  & 0xFF);
	bin->lpb[26] = ((ephEntryID->DisplayType >> 16) & 0xFF);
	bin->lpb[27] = ((ephEntryID->DisplayType >> 24) & 0xFF);
	bin->lpb[28] = (ephEntryID->MId & 0xFF);
	bin->lpb[29] = ((ephEntryID->MId >> 8)  & 0xFF);
	bin->lpb[30] = ((ephEntryID->MId >> 16) & 0xFF);
	bin->lpb[31] = ((ephEntryID->MId >> 24) & 0xFF);

	return MAPI_E_SUCCESS;
}
Example #9
0
/**
   \details Compares the position in an address book container of two
   objects identified by MId and returns the value of the comparison

   \param nspi_ctx pointer to the NSPI connection context
   \param mem_ctx pointer to the memory context
   \param MId1 the first MId to compare
   \param MId2 the second MId to compare
   \param plResult pointer to the value of the comparison

   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
 */
_PUBLIC_ enum MAPISTATUS nspi_CompareMIds(struct nspi_context *nspi_ctx,
					  TALLOC_CTX *mem_ctx,
					  uint32_t MId1, uint32_t MId2,
					  uint32_t *plResult)
{
	struct NspiCompareMIds	r;
	NTSTATUS		status;
	enum MAPISTATUS		retval;

	/* Sanity Checks */
	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
	OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL);
	OPENCHANGE_RETVAL_IF(!plResult, MAPI_E_INVALID_PARAMETER, NULL);

	r.in.handle = &nspi_ctx->handle;
	r.in.Reserved = 0x0;
	r.in.pStat = nspi_ctx->pStat;
	r.in.MId1 = MId1;
	r.in.MId2 = MId2;

	r.out.plResult = plResult;

	status = dcerpc_NspiCompareMIds_r(nspi_ctx->rpc_connection->binding_handle, mem_ctx, &r);
	retval = r.out.result;
	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
	OPENCHANGE_RETVAL_IF(retval, retval, NULL);

	return MAPI_E_SUCCESS;
}
Example #10
0
/**
   \details Returns a list of all the properties the NSPI server is
   aware off.

   \param nspi_ctx pointer to the NSPI connection context
   \param mem_ctx pointer to the memory context
   \param WantUnicode whether we want UNICODE properties or not
   \param ppColumns pointer on pointer to a property tag array

   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
 */
_PUBLIC_ enum MAPISTATUS nspi_QueryColumns(struct nspi_context *nspi_ctx,
					   TALLOC_CTX *mem_ctx,
					   bool WantUnicode,
					   struct SPropTagArray **ppColumns)
{
	struct NspiQueryColumns	r;
	NTSTATUS		status;
	enum MAPISTATUS		retval;

	/* Sanity checks */
	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
	OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL);
	OPENCHANGE_RETVAL_IF(!ppColumns, MAPI_E_INVALID_PARAMETER, NULL);

	r.in.handle = &nspi_ctx->handle;
	r.in.Reserved = 0x0;
	r.in.dwFlags = (WantUnicode != false) ? NspiUnicodeProptypes : 0x0;
	
	r.out.ppColumns = ppColumns;

	status = dcerpc_NspiQueryColumns_r(nspi_ctx->rpc_connection->binding_handle, mem_ctx, &r);
	retval = r.out.result;
	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, NULL);
	OPENCHANGE_RETVAL_IF(retval, retval, NULL);

	return MAPI_E_SUCCESS;
}
Example #11
0
/**
   \details Build an EphemeralEntryID structure

   \param emsabp_ctx pointer to the EMSABP context
   \param DisplayType the AB object display type
   \param MId the MId value
   \param ephEntryID pointer to the EphemeralEntryID returned by the
   function

   \return MAPI_E_SUCCESS on success, otherwise
   MAPI_E_NOT_ENOUGH_RESOURCES or MAPI_E_CORRUPT_STORE
 */
_PUBLIC_ enum MAPISTATUS emsabp_set_EphemeralEntryID(struct emsabp_context *emsabp_ctx,
						     uint32_t DisplayType, uint32_t MId,
						     struct EphemeralEntryID *ephEntryID)
{
	struct GUID	*guid = (struct GUID *) NULL;

	/* Sanity checks */
	OPENCHANGE_RETVAL_IF(!ephEntryID, MAPI_E_NOT_ENOUGH_RESOURCES, NULL);

	guid = (struct GUID *) samdb_ntds_objectGUID(emsabp_ctx->samdb_ctx);
	OPENCHANGE_RETVAL_IF(!guid, MAPI_E_CORRUPT_STORE, NULL);

	ephEntryID->ID_type = 0x87;
	ephEntryID->R1 = 0x0;
	ephEntryID->R2 = 0x0;
	ephEntryID->R3 = 0x0;
	ephEntryID->ProviderUID.ab[0] = (guid->time_low & 0xFF);
	ephEntryID->ProviderUID.ab[1] = ((guid->time_low >> 8)  & 0xFF);
	ephEntryID->ProviderUID.ab[2] = ((guid->time_low >> 16) & 0xFF);
	ephEntryID->ProviderUID.ab[3] = ((guid->time_low >> 24) & 0xFF);
	ephEntryID->ProviderUID.ab[4] = (guid->time_mid & 0xFF);
	ephEntryID->ProviderUID.ab[5] = ((guid->time_mid >> 8)  & 0xFF);
	ephEntryID->ProviderUID.ab[6] = (guid->time_hi_and_version & 0xFF);
	ephEntryID->ProviderUID.ab[7] = ((guid->time_hi_and_version >> 8) & 0xFF);
	memcpy(ephEntryID->ProviderUID.ab + 8,  guid->clock_seq, sizeof (uint8_t) * 2);
	memcpy(ephEntryID->ProviderUID.ab + 10, guid->node, sizeof (uint8_t) * 6);
	ephEntryID->R4 = 0x1;
	ephEntryID->DisplayType = DisplayType;
	ephEntryID->MId = MId;

	return MAPI_E_SUCCESS;
}
Example #12
0
/**
   \details Returns a list of all the properties that have values on
   the specified object

   \param nspi_ctx pointer to the NSPI connection context
   \param mem_ctx pointer to the memory context
   \param WantObject boolean value defining whether we want the server
   to include properties with the type set to PT_OBJECT
   \param dwMId the MId of the specified object
   \param ppPropTags pointer on pointer to the list of property tags
   associated to the object.

   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
 */
_PUBLIC_ enum MAPISTATUS nspi_GetPropList(struct nspi_context *nspi_ctx,
					  TALLOC_CTX *mem_ctx,
					  bool WantObject,
					  uint32_t dwMId,
					  struct SPropTagArray **ppPropTags)
{
	struct NspiGetPropList	r;
	NTSTATUS		status;
	enum MAPISTATUS		retval;

	/* Sanity checks */
	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
	OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL);
	OPENCHANGE_RETVAL_IF(!ppPropTags, MAPI_E_INVALID_PARAMETER, NULL);
	
	r.in.handle = &nspi_ctx->handle;
	r.in.dwFlags = (WantObject == true) ? 0x0 : fSkipObjects;
	r.in.dwMId = dwMId;
	r.in.CodePage = nspi_ctx->pStat->CodePage;
	
	r.out.ppPropTags = ppPropTags;

	status = dcerpc_NspiGetPropList_r(nspi_ctx->rpc_connection->binding_handle, mem_ctx, &r);
	retval = r.out.result;
	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
	OPENCHANGE_RETVAL_IF(retval, retval, NULL);

	return MAPI_E_SUCCESS;
}
Example #13
0
/**
   \details Create a FID from an EntryID

   \param cb count of lpb bytes
   \param lpb pointer on an array of bytes
   \param parent_fid the parent folder identifier
   \param fid pointer to the returned fid

   \return MAPI_E_SUCCESS on success, otherwise
   MAPI_E_INVALID_PARAMETER
 */
_PUBLIC_ enum MAPISTATUS GetFIDFromEntryID(uint16_t cb, 
					   uint8_t *lpb, 
					   uint64_t parent_fid, 
					   uint64_t *fid)
{
	/* Sanity checks */
	OPENCHANGE_RETVAL_IF(!lpb, MAPI_E_INVALID_PARAMETER, NULL);
	OPENCHANGE_RETVAL_IF(!fid, MAPI_E_INVALID_PARAMETER, NULL);
	OPENCHANGE_RETVAL_IF(cb < 8, MAPI_E_INVALID_PARAMETER, NULL);

	*fid = 0;
	*fid += ((uint64_t)lpb[cb - 3] << 56);
	*fid += ((uint64_t)lpb[cb - 4] << 48);
	*fid += ((uint64_t)lpb[cb - 5] << 40);
	*fid += ((uint64_t)lpb[cb - 6] << 32);
	*fid += ((uint64_t)lpb[cb - 7] << 24);
	*fid += ((uint64_t)lpb[cb - 8] << 16);
	/* WARNING: for some unknown reason the latest byte of folder
	   ID may change (0x1 or 0x4 values identified so far).
	   However this byte sounds the same than the parent folder
	   one */
	*fid += (parent_fid & 0xFFFF);

	return MAPI_E_SUCCESS;
}
Example #14
0
/**
   \details EcDoRpc GetSearchCriteria (0x31) Rop. This operation gets
   the search criteria for a search folder.

   \param mem_ctx pointer to the memory context
   \param emsmdbp_ctx pointer to the emsmdb provider context
   \param mapi_req pointer to the GetSearchCriteria EcDoRpc_MAPI_REQ
   structure
   \param mapi_repl pointer to the GetSearchCriteria EcDoRpc_MAPI_REPL
   structure
   \param handles pointer to the MAPI handles array
   \param size pointer to the mapi_response size to update

   \return MAPI_E_SUCCESS on success, otherwise MAPI error
 */
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetSearchCriteria(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 mapi_SRestriction *res; */

	OC_DEBUG(4, "exchange_emsmdb: [OXCFOLD] GetSearchCriteria (0x31)\n");

	/* Sanity checks */
	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
	OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
	OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
	OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
	OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);

	mapi_repl->opnum = mapi_req->opnum;
	mapi_repl->handle_idx = mapi_req->handle_idx;
	mapi_repl->error_code = MAPI_E_SUCCESS;

	/* res = NULL; */
	mapi_repl->u.mapi_GetSearchCriteria.RestrictionDataSize = 0;
	mapi_repl->u.mapi_GetSearchCriteria.LogonId = mapi_req->logon_id;
	mapi_repl->u.mapi_GetSearchCriteria.FolderIdCount = 0;
	mapi_repl->u.mapi_GetSearchCriteria.FolderIds = NULL;
	mapi_repl->u.mapi_GetSearchCriteria.SearchFlags = 0;

	/* TODO: actually implement this */

	*size += libmapiserver_RopGetSearchCriteria_size(mapi_repl);

	return MAPI_E_SUCCESS;
}
/**
   \details Save (commit) message in openchangedb database

   \param msg the message object
   \param SaveFlags flags associated to the save operation

   \return MAPI_E_SUCCESS on success, otherwise MAPI error
 */
_PUBLIC_
enum MAPISTATUS openchangedb_message_save(struct openchangedb_context *oc_ctx,
					  void *msg, uint8_t SaveFlags)
{
	OPENCHANGE_RETVAL_IF(!oc_ctx, MAPI_E_NOT_INITIALIZED, NULL);
	OPENCHANGE_RETVAL_IF(!msg, MAPI_E_NOT_INITIALIZED, NULL);

	return oc_ctx->message_save(oc_ctx, msg, SaveFlags);
}
Example #16
0
/**
   \details Free allocated memory

   This function frees memory previously allocated with
   MAPIAllocateBuffer.

   \param ptr memory region to free
       
   \return MAPI_E_SUCCESS on success, otherwise MAPI error.

   \note Developers may also call GetLastError() to retrieve the last
   MAPI error code. Possible MAPI error codes are:
   - MAPI_E_INVALID_PARAMER: ptr is not set properly.

   \sa MAPIAllocateBuffer, GetLastError
*/
_PUBLIC_ enum MAPISTATUS MAPIFreeBuffer(void *ptr)
{
	int		ret;

	OPENCHANGE_RETVAL_IF(!ptr, MAPI_E_INVALID_PARAMETER, NULL);

	ret = talloc_free(ptr);
	OPENCHANGE_RETVAL_IF(ret == -1, MAPI_E_INVALID_PARAMETER, NULL);

	return MAPI_E_SUCCESS;
}
/**
   \details Initialize and open a message object

   \param mem_ctx pointer to the memory context to use for allocation
   \param oc_ctx pointer to the openchangedb context
   \param username the name of the mailbox where the parent folder of the
   message is.
   \param messageID the identifier of the message to open
   \param folderID the identifier of the folder where the message is stored
   \param message_object pointer on pointer to the message object to return
   \param msgp pointer on pointer to the mapistore message to return

   \return MAPI_E_SUCCESS on success, otherwise MAPISTORE error
 */
_PUBLIC_
enum MAPISTATUS openchangedb_message_open(TALLOC_CTX *mem_ctx,
					  struct openchangedb_context *oc_ctx,
					  const char *username,
					  uint64_t messageID, uint64_t folderID,
					  void **message_object, void **msgp)
{
	OPENCHANGE_RETVAL_IF(!oc_ctx, MAPI_E_NOT_INITIALIZED, NULL);
	OPENCHANGE_RETVAL_IF(!message_object, MAPI_E_NOT_INITIALIZED, NULL);

	return oc_ctx->message_open(mem_ctx, oc_ctx, username, messageID,
				    folderID, message_object, msgp);
}
/**
   \details Set a list of properties on a message

   \param mem_ctx pointer to the memory context
   \param message_object pointer to the openchangedb message object
   \param row pointer to the SRow structure holding the array of
   properties to set on the message

   \return MAPI_E_SUCCESS on success, otherwise MAPI errors.
 */
_PUBLIC_
enum MAPISTATUS openchangedb_message_set_properties(TALLOC_CTX *mem_ctx,
						    struct openchangedb_context *oc_ctx,
						    void *message_object,
						    struct SRow *row)
{
	OPENCHANGE_RETVAL_IF(!oc_ctx, MAPI_E_NOT_INITIALIZED, NULL);
	OPENCHANGE_RETVAL_IF(!message_object, MAPI_E_NOT_INITIALIZED, NULL);
	OPENCHANGE_RETVAL_IF(!row, MAPI_E_NOT_INITIALIZED, NULL);

	return oc_ctx->message_set_properties(mem_ctx, oc_ctx, message_object,
					      row);
}
/**
   \details Retrieve a property on a LDB message

   \param mem_ctx pointer to the memory context
   \param message_object the openchangedb message to retrieve data from
   \param proptag the MAPI property tag to lookup
   \param data pointer on pointer to the data to return

   \return MAPI_E_SUCCESS on success, otherwise MAPI error
 */
_PUBLIC_
enum MAPISTATUS openchangedb_message_get_property(TALLOC_CTX *mem_ctx,
						  struct openchangedb_context *oc_ctx,
						  void *message_object,
						  uint32_t proptag, void **data)
{
	OPENCHANGE_RETVAL_IF(!oc_ctx, MAPI_E_NOT_INITIALIZED, NULL);
	OPENCHANGE_RETVAL_IF(!message_object, MAPI_E_NOT_INITIALIZED, NULL);
	OPENCHANGE_RETVAL_IF(!data, MAPI_E_NOT_INITIALIZED, NULL);

	return oc_ctx->message_get_property(mem_ctx, oc_ctx, message_object,
					    proptag, data);
}
Example #20
0
/**
   \details Release an object on the server

   The function releases the object \a obj on the server.

   \param obj the object to release

   \return MAPI_E_SUCCESS on success, otherwise MAPI error.

   \note Developers may also call GetLastError() to retrieve the last
   MAPI error code. Possible MAPI error codes are:
   - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
   - MAPI_E_CALL_FAILED: A network problem was encountered during the
     transaction

   \sa GetLastError
*/
_PUBLIC_ enum MAPISTATUS Release(mapi_object_t *obj)
{
	struct mapi_request	*mapi_request;
	struct mapi_response	*mapi_response;
	struct EcDoRpc_MAPI_REQ *mapi_req;
	struct mapi_session	*session;
	NTSTATUS		status;
	TALLOC_CTX		*mem_ctx;
	uint32_t		size = 0;
	enum MAPISTATUS		retval;
	uint8_t 		logon_id = 0;

	mapi_response = 0;

	/* Sanity checks */
	session = mapi_object_get_session(obj);
	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);

	if ((retval = mapi_object_get_logon_id(obj, &logon_id)) != MAPI_E_SUCCESS)
		return retval;

	mem_ctx = talloc_named(session, 0, "Release");

	/* Fill the MAPI_REQ request */
	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
	mapi_req->opnum = op_MAPI_Release;
	mapi_req->logon_id = logon_id;
	mapi_req->handle_idx = 0;
	size += 5;

	/* Fill the mapi_request structure */
	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
	mapi_request->mapi_len = size + sizeof (uint32_t);
	mapi_request->length = (uint16_t)size;
	mapi_request->mapi_req = mapi_req;
	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
	mapi_request->handles[0] = mapi_object_get_handle(obj);

	status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response);
	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);

	if (mapi_response->mapi_repl) {
		OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
	}

	talloc_free(mapi_response);
	talloc_free(mem_ctx);

	errno = 0;
	return MAPI_E_SUCCESS;
}
Example #21
0
/**
   \details Returns a number of Rows from a specified table.

   \param nspi_ctx pointer to the NSPI connection context
   \param mem_ctx pointer to the memory context
   \param pPropTags pointer to the list of proptags that the client
   requires to be returned for each row.
   \param MIds pointer to a list of values representing an Explicit
   table
   \param count the number of rows requested
   \param ppRows pointer on pointer to the the rows returned by the
   server

   \return MAPI_E_SUCCESS on success, otherwise MAPI error
 */
_PUBLIC_ enum MAPISTATUS nspi_QueryRows(struct nspi_context *nspi_ctx, 
					TALLOC_CTX *mem_ctx,
					struct SPropTagArray *pPropTags,
					struct PropertyTagArray_r *MIds, 
					uint32_t count,
					struct PropertyRowSet_r **ppRows)
{
	struct NspiQueryRows		r;
	NTSTATUS			status;
	enum MAPISTATUS			retval;
	struct STAT			*pStat;

	/* Sanity Checks */
	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
	OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL);

	r.in.handle = &nspi_ctx->handle;
	r.in.dwFlags = 0x0;
	r.in.pStat = nspi_ctx->pStat;

	if (MIds && MIds->cValues) {
		r.in.dwETableCount = MIds->cValues;
		r.in.lpETable = (uint32_t *) MIds->aulPropTag;
		/* We set CurrentRec to the first entry */
		r.in.pStat->CurrentRec = MIds->aulPropTag[0];
	} else {
		r.in.dwETableCount = 0;
		r.in.lpETable = NULL;
	}

	r.in.Count = count;	
 	r.in.pPropTags = pPropTags;

	pStat = talloc(mem_ctx, struct STAT);
	r.out.pStat = pStat;

	r.out.ppRows = ppRows;

	status = dcerpc_NspiQueryRows_r(nspi_ctx->rpc_connection->binding_handle, mem_ctx, &r);
	retval = r.out.result;
	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
	OPENCHANGE_RETVAL_IF(retval, retval, NULL);

	nspi_ctx->pStat->CurrentRec = r.out.pStat->CurrentRec;
	nspi_ctx->pStat->Delta = r.out.pStat->Delta;
	nspi_ctx->pStat->NumPos = r.out.pStat->NumPos;
	nspi_ctx->pStat->TotalRecs = r.out.pStat->TotalRecs;

	return MAPI_E_SUCCESS;

}
Example #22
0
/**
   \details Initialize the notification subsystem

   This function initializes the notification subsystem, binds a local
   UDP port to receive Exchange (server side) notifications and
   configures the server to send notifications on this port.

   \param session the session context to register for notifications on.

   \return MAPI_E_SUCCESS on success, otherwise MAPI error.

   \note Developers may also call GetLastError() to retrieve the last
   MAPI error code. Possible MAPI error codes are:
   - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
   - MAPI_E_CALL_FAILED: A network problem was encountered during the
     transaction

   \sa RegisterAsyncNotification, Subscribe, Unsubscribe, MonitorNotification, GetLastError
*/
_PUBLIC_ enum MAPISTATUS RegisterNotification(struct mapi_session *session)
{
    NTSTATUS		status;
    struct mapi_context	*mapi_ctx;
    struct emsmdb_context	*emsmdb;
    TALLOC_CTX		*mem_ctx;
    struct NOTIFKEY		*lpKey;
    static uint8_t		rand = 0;
    static uint8_t		attempt = 0;

    /* Sanity checks */
    OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
    OPENCHANGE_RETVAL_IF(!session->emsmdb, MAPI_E_SESSION_LIMIT, NULL);

    emsmdb = (struct emsmdb_context *)session->emsmdb->ctx;
    OPENCHANGE_RETVAL_IF(!emsmdb, MAPI_E_SESSION_LIMIT, NULL);

    mapi_ctx = session->mapi_ctx;
    OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);

    mem_ctx = emsmdb->mem_ctx;

    /* bind local udp port */
    session->notify_ctx = emsmdb_bind_notification(mapi_ctx, mem_ctx);
    if (!session->notify_ctx) return MAPI_E_CANCEL;

    /* tell exchange where to send notifications */
    lpKey = talloc_zero(mem_ctx, struct NOTIFKEY);
    lpKey->cb = 8;
    lpKey->ab = talloc_array((TALLOC_CTX *)lpKey, uint8_t, lpKey->cb);
    memcpy(lpKey->ab, "libmapi", 7);
retry:
    lpKey->ab[7] = rand;

    status = emsmdb_register_notification(session, lpKey);
    if (!NT_STATUS_IS_OK(status)) {
        if (attempt < 5) {
            rand++;
            attempt++;
            errno = 0;
            goto retry;
        } else {
            talloc_free(lpKey);
            return MAPI_E_CALL_FAILED;
        }
    }

    attempt = 0;
    talloc_free(lpKey);
    return MAPI_E_SUCCESS;
}
Example #23
0
/**
   \details Extract organization name and group name from the legacy exchange
   dn of the current logged user.

   \param mem_ctx memory context used for returned values
   \param emsmdbp_ctx pointer to the EMSMDBP context
   \param organization_name pointer to the returned organization name
   \param group_name pointer to the returned group name

   \note You can set organization_name or group_name to NULL if you don't want
   this values

   \return MAPI_E_SUCCESS or an error if something happens
 */
_PUBLIC_ enum MAPISTATUS emsmdbp_fetch_organizational_units(TALLOC_CTX *mem_ctx,
							    struct emsmdbp_context *emsmdbp_ctx,
							    char **organization_name,
							    char **group_name)
{
	char 		*exdn0, *exdn1;
	const char 	*EssDN;

	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx->szUserDN, MAPI_E_NOT_INITIALIZED, NULL);

	EssDN = emsmdbp_ctx->szUserDN;
	// EssDN has format: /o=organizacion name/ou=group name/cn=Recipients/cn=username

	if (organization_name) {
		exdn0 = strstr(EssDN, "/o=");
		OPENCHANGE_RETVAL_IF(!exdn0, MAPI_E_BAD_VALUE, NULL);
		exdn1 = strstr(EssDN, "/ou=");
		OPENCHANGE_RETVAL_IF(!exdn1, MAPI_E_BAD_VALUE, NULL);
		*organization_name = talloc_strndup(mem_ctx, exdn0 + 3, exdn1 - exdn0 - 3);
		OPENCHANGE_RETVAL_IF(!*organization_name, MAPI_E_NOT_ENOUGH_MEMORY, NULL);
	}

	if (group_name) {
		exdn0 = strstr(EssDN, "/ou=");
		OPENCHANGE_RETVAL_IF(!exdn0, MAPI_E_BAD_VALUE, NULL);
		exdn1 = strstr(EssDN, "/cn=");
		OPENCHANGE_RETVAL_IF(!exdn1, MAPI_E_BAD_VALUE, NULL);
		*group_name = talloc_strndup(mem_ctx, exdn0 + 4, exdn1 - exdn0 - 4);
		OPENCHANGE_RETVAL_IF(!*group_name, MAPI_E_NOT_ENOUGH_MEMORY, NULL);
	}

	return MAPI_E_SUCCESS;
}
Example #24
0
/**
   \details Returns values of one or more properties for an object
 
   The function takes a pointer on the object obj, a MAPITAGS array
   specified in mapitags, and the count of properties.  The function
   returns associated values within the SPropValue values pointer.

   The array of MAPI property tags can be filled with both known and
   named properties.

   \param obj the object to get properties on
   \param flags Flags for behaviour; can be bit-OR of MAPI_UNICODE and
      MAPI_PROPS_SKIP_NAMEDID_CHECK constants
   \param SPropTagArray an array of MAPI property tags
   \param lpProps the result of the query
   \param PropCount the count of property tags

   \return MAPI_E_SUCCESS on success, otherwise MAPI error.

   \note Developers may also call GetLastError() to retrieve the last
   MAPI error code. Possible MAPI error codes are:
   - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
   - MAPI_E_INVALID_PARAMETER: obj or SPropTagArray are null, or the
   session context could not be obtained
   - MAPI_E_CALL_FAILED: A network problem was encountered during the
     transaction

   \sa SetProps, GetPropList, GetPropsAll, DeleteProps, GetLastError
*/
_PUBLIC_ enum MAPISTATUS GetProps(mapi_object_t *obj,
				  uint32_t flags,
				  struct SPropTagArray *SPropTagArray,
				  struct SPropValue **lpProps, 
				  uint32_t *PropCount)
{
	struct mapi_context	*mapi_ctx;
	struct mapi_request	*mapi_request;
	struct mapi_response	*mapi_response;
	struct EcDoRpc_MAPI_REQ	*mapi_req;
	struct GetProps_req	request;
	struct mapi_session	*session;
	struct mapi_nameid	*nameid;
	struct SPropTagArray	properties;
	struct SPropTagArray	*SPropTagArray2 = NULL;
	NTSTATUS		status;
	enum MAPISTATUS		retval;
	enum MAPISTATUS		mapistatus;
	uint32_t		size;
	TALLOC_CTX		*mem_ctx;
	bool			named = false;
	uint8_t			logon_id;

	/* Sanity checks */
	OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL);
	OPENCHANGE_RETVAL_IF(!SPropTagArray, MAPI_E_INVALID_PARAMETER, NULL);

	session = mapi_object_get_session(obj);
	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);

	mapi_ctx = session->mapi_ctx;
	OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);

	if ((retval = mapi_object_get_logon_id(obj, &logon_id)) != MAPI_E_SUCCESS)
		return retval;

	mem_ctx = talloc_named(session, 0, "GetProps");

	/* Named property mapping */
	nameid = mapi_nameid_new(mem_ctx);
	if (!(flags & MAPI_PROPS_SKIP_NAMEDID_CHECK)) {
		retval = mapi_nameid_lookup_SPropTagArray(nameid, SPropTagArray);
		if (retval == MAPI_E_SUCCESS) {
			named = true;
			SPropTagArray2 = talloc_zero(mem_ctx, struct SPropTagArray);
			retval = GetIDsFromNames(obj, nameid->count, nameid->nameid, 0, &SPropTagArray2);
			OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);		
			mapi_nameid_map_SPropTagArray(nameid, SPropTagArray, SPropTagArray2);
			MAPIFreeBuffer(SPropTagArray2);
		}
Example #25
0
/**
   \details Allocate memory using the MAPI memory context
   
   \param mapi_ctx pointer to the MAPI context
   \param size the number of bytes to allocate
   \param ptr pointer to the allocated byte region

   \return MAPI_E_SUCCESS on success, otherwise MAPI error.

   \note Developers may also call GetLastError() to retrieve the last
   MAPI error code. Possible MAPI error codes are:
   - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
   - MAPI_E_SESSION_LIMIT: No session has been opened on the provider
   - MAPI_E_NOT_ENOUGH_RESOURCES: MAPI subsystem failed to allocate
     the necessary resources to operate properly
   - MAPI_E_INVALID_PARAMER: size is not set properly.

   \sa MAPIFreeBuffer, GetLastError
*/
_PUBLIC_ enum MAPISTATUS MAPIAllocateBuffer(struct mapi_context *mapi_ctx, uint32_t size, void **ptr)
{
	TALLOC_CTX	*mem_ctx;

	/* Sanity checks */
	OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
	OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);

	mem_ctx = (TALLOC_CTX *) mapi_ctx->mem_ctx;

	*ptr = talloc_size(mem_ctx, size);
	OPENCHANGE_RETVAL_IF(!ptr, MAPI_E_NOT_ENOUGH_RESOURCES, NULL);

	return MAPI_E_SUCCESS;
}
/**
   \details Initialize and open a message object

   \param mem_ctx pointer to the memory context to use for allocation
   \param ldb_ctx pointer to the ldb context
   \param messageID the identifier of the message to open
   \param folderID the identifier of the folder where the message is stored
   \param message_object pointer on pointer to the message object to return
   \param msgp pointer on pointer to the mapistore message to return

   \return MAPI_E_SUCCESS on success, otherwise MAPISTORE error
 */
_PUBLIC_ enum MAPISTATUS openchangedb_message_open(TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx,
						   uint64_t messageID, uint64_t folderID, 
						   void **message_object, void **msgp)
{
	struct mapistore_message	*mmsg;
	struct openchangedb_message	*msg;
	const char * const		attrs[] = { "*", NULL };
	int				ret;
	char				*ldb_filter;

	/* Sanity checks */
	OPENCHANGE_RETVAL_IF(!ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL);
	OPENCHANGE_RETVAL_IF(!message_object, MAPI_E_NOT_INITIALIZED, NULL);

	msg = talloc_zero(mem_ctx, struct openchangedb_message);
	if (!msg) {
		return MAPI_E_NOT_ENOUGH_MEMORY;
	}
	printf("openchangedb_message_open: folderID=%"PRIu64" messageID=%"PRIu64"\n", folderID, messageID);

	msg->status = OPENCHANGEDB_MESSAGE_OPEN;
	msg->folderID = folderID;
	msg->messageID = messageID;
	msg->ldb_ctx = ldb_ctx;
	msg->msg = NULL;
	msg->res = NULL;

	/* Open the message and load results */
	ldb_filter = talloc_asprintf(mem_ctx, "(&(PidTagParentFolderId=%"PRIu64")(PidTagMessageId=%"PRIu64"))", folderID, messageID);
	ret = ldb_search(ldb_ctx, (TALLOC_CTX *)msg, &msg->res, ldb_get_default_basedn(ldb_ctx),
			 LDB_SCOPE_SUBTREE, attrs, ldb_filter, NULL);
	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);
	*message_object = (void *)msg;

	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;
}
Example #27
0
/**
   \details Create an asynchronous notification

   This function initializes the notification subsystem and configures the
   server to send notifications. Note that this call will block.

   \param session the session context to register for notifications on.
   \param resultFlag the result of the operation (true if there was anything returned)

   \return MAPI_E_SUCCESS on success, otherwise MAPI error.

   \note Developers may also call GetLastError() to retrieve the last
   MAPI error code. Possible MAPI error codes are:
   - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
   - MAPI_E_CALL_FAILED: A network problem was encountered during the
     transaction

   \sa RegisterNotification
*/
_PUBLIC_ enum MAPISTATUS RegisterAsyncNotification(struct mapi_session *session, uint32_t *resultFlag)
{
    enum MAPISTATUS		mapistatus;
    struct emsmdb_context	*emsmdb;

    /* Sanity checks */
    OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
    OPENCHANGE_RETVAL_IF(!session->emsmdb, MAPI_E_SESSION_LIMIT, NULL);

    emsmdb = (struct emsmdb_context *)session->emsmdb->ctx;

    mapistatus = emsmdb_async_waitex(emsmdb, 0, resultFlag);
    OPENCHANGE_RETVAL_IF(mapistatus, mapistatus, NULL);

    return MAPI_E_SUCCESS;
}
Example #28
0
/**
   \details Destroy the EMSMDB context handle

   \param emsmdb_ctx pointer to the EMSMDB context

   \return MAPI_E_SUCCESS on success, otherwise MAPI error
 */
enum MAPISTATUS emsmdb_disconnect(struct emsmdb_context *emsmdb_ctx)
{
	NTSTATUS		status;
	enum MAPISTATUS		retval;
	struct EcDoDisconnect	r;

	/* Sanity Checks */
	OPENCHANGE_RETVAL_IF(!emsmdb_ctx, MAPI_E_NOT_INITIALIZED, NULL);

	r.in.handle = r.out.handle = &emsmdb_ctx->handle;

	status = dcerpc_EcDoDisconnect_r(emsmdb_ctx->rpc_connection->binding_handle, emsmdb_ctx, &r);
	retval = r.out.result;
	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
	OPENCHANGE_RETVAL_IF(retval, retval, NULL);

	return MAPI_E_SUCCESS;
}
Example #29
0
/**
   \details Retrieve a free logon identifier within the session

   \param session pointer to the MAPI session context
   \param logon_id pointer to the logon identifier the function
   returns

   \return MAPI_E_SUCCESS on success, otherwise MAPI eorr
 */
enum MAPISTATUS GetNewLogonId(struct mapi_session *session, uint8_t *logon_id)
{
    int	i = 0;

    /* Sanity checks */
    OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
    OPENCHANGE_RETVAL_IF(!logon_id, MAPI_E_INVALID_PARAMETER, NULL);

    for (i = 0; i < 255; i++) {
        if (!session->logon_ids[i]) {
            session->logon_ids[i] = 1;
            *logon_id = i;
            return MAPI_E_SUCCESS;
        }
    }

    return MAPI_E_NOT_FOUND;
}
Example #30
0
/**
   \details Destroys the context handle

   \param nspi_ctx pointer to the NSPI connection context

   \return return 1 on success or 2 if the input context is NULL
 */
_PUBLIC_ enum MAPISTATUS nspi_unbind(struct nspi_context *nspi_ctx)
{
	struct NspiUnbind	r;
	NTSTATUS		status;
	enum MAPISTATUS		retval;

	/* Sanity checks */
	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);

	r.in.handle = r.out.handle = &nspi_ctx->handle;
	r.in.Reserved = 0;

	status = dcerpc_NspiUnbind_r(nspi_ctx->rpc_connection->binding_handle, nspi_ctx->mem_ctx, &r);
	retval = r.out.result;
	OPENCHANGE_RETVAL_IF((retval != 1) && !MAPI_STATUS_IS_OK(NT_STATUS_V(status)), retval, NULL);

	return MAPI_E_SUCCESS;
}