Exemple #1
0
/**
   \details EcDoRpc GetPermissionsTable (0x3e) Rop. This operation get
   the permissions table of a folder.

   \param mem_ctx pointer to the memory context
   \param emsmdbp_ctx pointer to the emsmdb provider context
   \param mapi_req pointer to the GetPermissionsTable EcDoRpc_MAPI_REQ
   structure
   \param mapi_repl pointer to the GetPermissionsTable
   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_RopGetPermissionsTable(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)
{
	enum MAPISTATUS		retval;
	struct mapi_handles	*parent;
	struct mapi_handles	*rec;
	struct emsmdbp_object	*parent_object, *object;
	void			*data = NULL;
	uint32_t		handle;

	OC_DEBUG(4, "exchange_emsmdb: [OXCPERM] GetPermissionsTable (0x3e)\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->u.mapi_GetPermissionsTable.handle_idx;
	mapi_repl->error_code = MAPI_E_SUCCESS;

	/* Ensure parent handle references a folder object */
	handle = handles[mapi_req->handle_idx];
	retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
	if (retval) {
		mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
		OC_DEBUG(5, "  handle (%x) not found: %x\n", handle, mapi_req->handle_idx);
		goto end;
	}

	retval = mapi_handles_get_private_data(parent, &data);
	if (retval || !data) {
		mapi_repl->error_code = MAPI_E_NOT_FOUND;
		OC_DEBUG(5, "  handle data not found, idx = %x\n", mapi_req->handle_idx);
		goto end;
	}

	parent_object = (struct emsmdbp_object *) data;
	if (parent_object->type != EMSMDBP_OBJECT_FOLDER) {
		mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
		OC_DEBUG(5, "  unhandled object type: %d\n", parent_object->type);
		goto end;
	}

	/* Initialize Table object */
	retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
	handles[mapi_repl->handle_idx] = rec->handle;
	
	if (emsmdbp_is_mapistore(parent_object)) {
		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);
	}
	if (object) {
		retval = mapi_handles_set_private_data(rec, object);
	}
	else {
		mapi_handles_delete(emsmdbp_ctx->handles_ctx, rec->handle);
		mapi_repl->error_code = MAPI_E_NOT_FOUND;
		goto end;
	}

end:
	*size += libmapiserver_RopGetPermissionsTable_size(mapi_repl);

	return MAPI_E_SUCCESS;
}
Exemple #2
0
/**
   \details EcDoRpc GetContentsTable (0x05) Rop. This operation get
   the content table of a container.

   \param mem_ctx pointer to the memory context
   \param emsmdbp_ctx pointer to the emsmdb provider context
   \param mapi_req pointer to the GetContentsTable EcDoRpc_MAPI_REQ
   structure
   \param mapi_repl pointer to the GetContentsTable 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_RopGetContentsTable(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)
{
	enum MAPISTATUS		retval;
	struct mapi_handles	*parent;
	struct mapi_handles	*rec = NULL;
	struct emsmdbp_object	*object = NULL, *parent_object;
	void			*data;
	uint32_t		handle;
	uint8_t			table_type;

	OC_DEBUG(4, "exchange_emsmdb: [OXCFOLD] GetContentsTable (0x05)\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);

	/* Initialize default empty GetContentsTable reply */
	mapi_repl->opnum = mapi_req->opnum;
	mapi_repl->handle_idx = mapi_req->u.mapi_GetContentsTable.handle_idx;
	mapi_repl->error_code = MAPI_E_SUCCESS;
	mapi_repl->u.mapi_GetContentsTable.RowCount = 0;

	handle = handles[mapi_req->handle_idx];
	retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
	if (retval != MAPI_E_SUCCESS) {
		OC_DEBUG(5, "  handle (%x) not found: %x\n", handle, mapi_req->handle_idx);
		mapi_repl->error_code = MAPI_E_NO_SUPPORT;
		goto end;
	}

	/* GetContentsTable can only be called for folder objects */
	retval = mapi_handles_get_private_data(parent, &data);
	if (retval != MAPI_E_SUCCESS) {
		mapi_repl->error_code = retval;
		OC_DEBUG(5, "  handle data not found, idx = %x\n", mapi_req->handle_idx);
		goto end;
	}

	parent_object = (struct emsmdbp_object *)data;
	if (!parent_object) {
		mapi_repl->error_code = MAPI_E_NO_SUPPORT;
		OC_DEBUG(5, "  handle data not found, idx = %x\n", mapi_req->handle_idx);
		goto end;
	}

	if (parent_object->type != EMSMDBP_OBJECT_FOLDER) {
		mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
		goto end;
	}

	if ((mapi_req->u.mapi_GetContentsTable.TableFlags & TableFlags_Associated)) {
		OC_DEBUG(5, "  table is FAI table\n");
		table_type = MAPISTORE_FAI_TABLE;
	}
	else {
		OC_DEBUG(5, "  table is contents table\n");
		table_type = MAPISTORE_MESSAGE_TABLE;
	}

	/* Initialize Table object */
	retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
	if (retval != MAPI_E_SUCCESS) {
		mapi_repl->error_code = retval;
		goto end;
	}
	handles[mapi_repl->handle_idx] = rec->handle;

	object = emsmdbp_folder_open_table(rec, parent_object, table_type, rec->handle);
	if (!object) {
		mapi_handles_delete(emsmdbp_ctx->handles_ctx, rec->handle);
		mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
		goto end;
	}
	mapi_handles_set_private_data(rec, object);
	mapi_repl->u.mapi_GetContentsTable.RowCount = object->object.table->denominator;

	/* notifications */
	if ((mapi_req->u.mapi_GetContentsTable.TableFlags & TableFlags_NoNotifications)) {
		OC_DEBUG(5, "  notifications skipped\n");
	}

end:
	
	*size += libmapiserver_RopGetContentsTable_size(mapi_repl);

	return MAPI_E_SUCCESS;
}
Exemple #3
0
/**
   \details EcDoRpc CreateFolder (0x1c) Rop. This operation creates a
   folder on the remote server.

   \param mem_ctx pointer to the memory context
   \param emsmdbp_ctx pointer to the emsmdb provider context
   \param mapi_req pointer to the CreateFolder EcDoRpc_MAPI_REQ
   structure
   \param mapi_repl pointer to the CreateFolder 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

   \note We do not provide support for GhostInfo
 */
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopCreateFolder(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)
{
	enum MAPISTATUS			retval;
	enum mapistore_error		ret;
	struct mapi_handles		*parent = NULL;
	uint32_t			handle;
	uint64_t			parent_fid, fid, cn;
	struct SPropValue		cnValue;
	struct emsmdbp_object		*parent_object = NULL;
	struct emsmdbp_object		*object = NULL;
	struct CreateFolder_req		*request;
	struct CreateFolder_repl	*response;
	struct SRow			*aRow = NULL;
	void				*data;
	struct mapi_handles		*rec = NULL;

	OC_DEBUG(4, "exchange_emsmdb: [OXCFOLD] CreateFolder (0x1c)\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);

	/* Set up sensible values for the reply */
	mapi_repl->opnum = mapi_req->opnum;
	mapi_repl->error_code = MAPI_E_SUCCESS;
	mapi_repl->handle_idx = mapi_req->u.mapi_CreateFolder.handle_idx;

	if (!mapi_req->u.mapi_CreateFolder.ulFolderType ||
	    mapi_req->u.mapi_CreateFolder.ulFolderType > 0x2) {
		mapi_repl->error_code = MAPI_E_INVALID_PARAMETER;
		goto end;
	}

	/* Step 1. Retrieve parent handle in the hierarchy */
	handle = handles[mapi_req->handle_idx];
	retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
	OPENCHANGE_RETVAL_IF(retval, retval, NULL);

	/* With CreateFolder, the parent object really IS the parent object */
	mapi_handles_get_private_data(parent, &data);
	parent_object = (struct emsmdbp_object *)data;
	if (!parent_object) {
		OC_DEBUG(4, "exchange_emsmdb: [OXCFOLD] CreateFolder null object\n");
		mapi_repl->error_code = MAPI_E_NO_SUPPORT;
		goto end;
	}

	if (parent_object->type == EMSMDBP_OBJECT_MAILBOX) {
		mapi_repl->error_code = MAPI_E_NO_SUPPORT;
		goto end;
	}

	if (parent_object->type != EMSMDBP_OBJECT_FOLDER && parent_object->type != EMSMDBP_OBJECT_MAILBOX) {
		OC_DEBUG(4, "exchange_emsmdb: [OXCFOLD] CreateFolder wrong object type: 0x%x\n", parent_object->type);
		mapi_repl->error_code = MAPI_E_NO_SUPPORT;
		goto end;
	}

	request = &mapi_req->u.mapi_CreateFolder;
	response = &mapi_repl->u.mapi_CreateFolder;

	/* OC_DEBUG(4, ("exchange_emsmdb: [OXCFOLD] CreateFolder parent: 0x%.16"PRIx64"\n", parent_fid)); */
	/* OC_DEBUG(4, ("exchange_emsmdb: [OXCFOLD] Creating %s\n", request->FolderName.lpszW)); */

	/* if (request->ulFolderType != FOLDER_GENERIC) { */
	/* 	OC_DEBUG(4, ("exchange_emsmdb: [OXCFOLD] Unexpected folder type 0x%x\n", request->ulType)); */
	/* 	mapi_repl->error_code = MAPI_E_NO_SUPPORT; */
	/* 	goto end; */
	/* } */

	response->IsExistingFolder = false;

	ret = emsmdbp_object_get_fid_by_name(emsmdbp_ctx, parent_object, request->FolderName.lpszW, &fid);
	if (ret == MAPISTORE_SUCCESS) {
		if (oxosfld_is_special_folder(emsmdbp_ctx, fid) || request->ulFlags == OPEN_IF_EXISTS) {
			response->IsExistingFolder = true;
		} else {
			if (emsmdbp_is_mapistore(parent_object)) {
				OC_DEBUG(5, "Folder %s exists in MAPIStore", request->FolderName.lpszW);
			} else {
				OC_DEBUG(5, "Folder %s exists in OpenChangeDB", request->FolderName.lpszW);
			}
			mapi_repl->error_code = MAPI_E_COLLISION;
			goto end;
		}
	}

	mapi_handles_add(emsmdbp_ctx->handles_ctx, 0, &rec);
	if (response->IsExistingFolder) {
		retval = emsmdbp_object_open_folder_by_fid(rec, emsmdbp_ctx, parent_object, fid, &object);
		if (retval != MAPI_E_SUCCESS) {
			OC_DEBUG(4, "exchange_emsmdb: [OXCFOLD] Failure opening existing folder: %s\n", mapi_get_errstr(retval));
			mapi_handles_delete(emsmdbp_ctx->handles_ctx, rec->handle);
			mapi_repl->error_code = retval;
			goto end;
		}
	} else {
		/* Step 3. Turn CreateFolder parameters into MAPI property array */
		parent_fid = parent_object->object.folder->folderID;
		if (openchangedb_is_public_folder_id(emsmdbp_ctx->oc_ctx, parent_fid)) {
			retval = openchangedb_get_new_public_folderID(emsmdbp_ctx->oc_ctx, emsmdbp_ctx->username, &fid);
		} else {
			retval = mapistore_error_to_mapi(mapistore_indexing_get_new_folderID(emsmdbp_ctx->mstore_ctx, &fid));
		}
		if (retval != MAPI_E_SUCCESS) {
			OC_DEBUG(4, "exchange_emsmdb: [OXCFOLD] Could not obtain a new folder id\n");
			mapi_repl->error_code = MAPI_E_NO_SUPPORT;
			goto end;
		}

		retval = openchangedb_get_new_changeNumber(emsmdbp_ctx->oc_ctx, emsmdbp_ctx->username, &cn);
		if (retval != MAPI_E_SUCCESS) {
			OC_DEBUG(4, "exchange_emsmdb: [OXCFOLD] Could not obtain a new folder cn\n");
			mapi_repl->error_code = MAPI_E_NO_SUPPORT;
			goto end;
		}

		aRow = libmapiserver_ROP_request_to_properties(mem_ctx, (void *)&mapi_req->u.mapi_CreateFolder, op_MAPI_CreateFolder);
		aRow->lpProps = add_SPropValue(mem_ctx, aRow->lpProps, &(aRow->cValues), PR_PARENT_FID, (void *)(&parent_fid));
		cnValue.ulPropTag = PidTagChangeNumber;
		cnValue.value.d = cn;
		SRow_addprop(aRow, cnValue);

		retval = emsmdbp_object_create_folder(emsmdbp_ctx, parent_object, rec, fid,
						      aRow, true, &object);
		if (retval != MAPI_E_SUCCESS) {
			OC_DEBUG(5, "folder creation failed\n");
			mapi_handles_delete(emsmdbp_ctx->handles_ctx, rec->handle);
			mapi_repl->error_code = retval;
			goto end;
		}
	}

	handles[mapi_repl->handle_idx] = rec->handle;
	mapi_handles_set_private_data(rec, object);

	response->folder_id = fid;

	if (response->IsExistingFolder == true) {
		response->GhostUnion.GhostInfo.HasRules = false;
		response->GhostUnion.GhostInfo.IsGhosted = false;
	}

end:
	*size += libmapiserver_RopCreateFolder_size(mapi_repl);

	if (aRow) {
		talloc_free(aRow);
	}

	return MAPI_E_SUCCESS;
}
Exemple #4
0
/**
   \details EcDoRpc GetContentsTable (0x05) Rop. This operation get
   the content table of a container.

   \param mem_ctx pointer to the memory context
   \param emsmdbp_ctx pointer to the emsmdb provider context
   \param mapi_req pointer to the GetContentsTable EcDoRpc_MAPI_REQ
   structure
   \param mapi_repl pointer to the GetContentsTable 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_RopGetContentsTable(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)
{
	enum MAPISTATUS		retval;
	struct mapi_handles	*parent;
	struct mapi_handles	*rec = NULL;
	struct emsmdbp_object	*object = NULL, *parent_object;
        struct mapistore_subscription_list *subscription_list;
        struct mapistore_subscription *subscription;
        struct mapistore_table_subscription_parameters subscription_parameters;
	void			*data;
	uint64_t		folderID;
	uint32_t		handle;
	uint8_t			table_type;

	DEBUG(4, ("exchange_emsmdb: [OXCFOLD] GetContentsTable (0x05)\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);

	/* Initialize default empty GetContentsTable reply */
	mapi_repl->opnum = mapi_req->opnum;
	mapi_repl->handle_idx = mapi_req->u.mapi_GetContentsTable.handle_idx;
	mapi_repl->error_code = MAPI_E_SUCCESS;
	mapi_repl->u.mapi_GetContentsTable.RowCount = 0;

	handle = handles[mapi_req->handle_idx];
	retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
	if (MAPI_STATUS_IS_ERR(retval)) {
		DEBUG(5, ("  handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
		mapi_repl->error_code = MAPI_E_NO_SUPPORT;
		goto end;
	}

	/* GetContentsTable can only be called for folder objects */
	retval = mapi_handles_get_private_data(parent, &data);
	if (MAPI_STATUS_IS_ERR(retval)) {
		mapi_repl->error_code = retval;
		DEBUG(5, ("  handle data not found, idx = %x\n", mapi_req->handle_idx));
		goto end;
	}

	parent_object = (struct emsmdbp_object *)data;
	if (!parent_object) {
		mapi_repl->error_code = MAPI_E_NO_SUPPORT;
		DEBUG(5, ("  handle data not found, idx = %x\n", mapi_req->handle_idx));
		goto end;
	}

	if (parent_object->type != EMSMDBP_OBJECT_FOLDER) {
		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 = MAPISTORE_FAI_TABLE;
	}
	else {
		DEBUG(5, ("  table is contents table\n"));
		table_type = MAPISTORE_MESSAGE_TABLE;
	}

	/* Initialize Table object */
	retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
	if (MAPI_STATUS_IS_ERR(retval)) {
		mapi_repl->error_code = retval;
		goto end;
	}
	handles[mapi_repl->handle_idx] = rec->handle;

	object = emsmdbp_folder_open_table(rec, parent_object, table_type, rec->handle);
	if (!object) {
		mapi_handles_delete(emsmdbp_ctx->handles_ctx, rec->handle);
		mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
		goto end;
	}
	mapi_handles_set_private_data(rec, object);
	mapi_repl->u.mapi_GetContentsTable.RowCount = object->object.table->denominator;

	/* notifications */
	if ((mapi_req->u.mapi_GetContentsTable.TableFlags & TableFlags_NoNotifications)) {
		DEBUG(5, ("  notifications skipped\n"));
	}
	else {
		/* we attach the subscription to the session object */
		subscription_list = talloc_zero(emsmdbp_ctx->mstore_ctx, struct mapistore_subscription_list);
		DLIST_ADD(emsmdbp_ctx->mstore_ctx->subscriptions, subscription_list);
		
		if ((mapi_req->u.mapi_GetContentsTable.TableFlags & TableFlags_Associated)) {
			subscription_parameters.table_type = MAPISTORE_FAI_TABLE;
		}
		else {
			subscription_parameters.table_type = MAPISTORE_MESSAGE_TABLE;
		}
		subscription_parameters.folder_id = folderID; 
                
		/* note that a mapistore_subscription can exist without a corresponding emsmdbp_object (tables) */
		subscription = mapistore_new_subscription(subscription_list, emsmdbp_ctx->mstore_ctx,
							  emsmdbp_ctx->username,
							  rec->handle, fnevTableModified, &subscription_parameters);
		subscription_list->subscription = subscription;
		object->object.table->subscription_list = subscription_list;
        }

end:
	
	*size += libmapiserver_RopGetContentsTable_size(mapi_repl);

	return MAPI_E_SUCCESS;
}