Пишу, по большей части, про историю, свою жизнь и немного про программирование.

Эпопея с MAPI

Все эти пляски с ctypes — следствие одной большой задачи, с которой мы столкнулись в группе внутренних сервисов. Интеграция нашего интранета с Microsoft Exchange Server — это сервер для обмена сообщениями и совместной работы. Основной протокол, по которому этот сервер работает — MAPI.

После небольшого исследования выяснилось, что направлений для дальнейшего исследования три: можно попытаться работать с MAPI через RPC, можно использовать библиотеки, которые только-только начали бурно расти (т. к. Microsoft открыла протокол) или использовать Windows-машину, на которой сделать RPC-обёртку для готового клиента Exchange, COM-объекта.

Последний вариант, с COM-объектом, нравится нам всем меньше всего и является запасным, в случае, если ничего больше не заработает.

Я долго не мог выяснить что за RPC применяет Microsoft, пока не начал перебирать всё, что приходит на ум. Оказалось, что Microsoft, в основном, использует диалект DCE-RPC, который называется MSRPC. C DCE-RPC, да и вообще с технологиями Microsoft (NMB, SMB) из Python можно работать модулем impacket. Библиотека не обновлялась два года, но работает.

Документации на него — кот наплакал, чуть примеров и в Сети есть несколько эксплоитов, написанных при помощи этого модуля. Этого хватило, чтобы понять как примерно им пользоваться и несколько дней и я пытался сделать прототип для общения с Exchange на нём.

Довольно быстро оказалось, что задача очень трудоёмкая. Даже для того, чтоб описать только вызовы верхнего уровня, ушёл бы не один день, а описывать MAPI-вызовы внутри DoRCP… В общем, от этой идеи пришлось отказаться.

Готовых библиотек для работы с MAPI немного. Бесплатная, кажется, так и вовсе одна — libmapi. Сейчас стабильной версией считается 0.7, поскольку библиотека требует присутствия Samba4, то решено было ставить её из исходников. Оказалось, дело это очень непростое, так как база пакетов на машине, куда пришлось её ставить была разрушена, «Пайтонов» было два, от чего у исталлятора уносило крышу и имелась собственная Samba3, которая используется в работе.

Наши админы попробовали её поставить, но после нескольких проблем, сказали, что это очень сыро и ставить не получается. Я их понимаю — работы у них масса, слишком много времени на исталляцию недописанного софта они выделять не в состоянии. Поэтому библиотеку я ставил сам. В рунете я не смог найти никаких описаний того, что это кто-то делал, поэтому несколько советов.

Для начала, лучше всего ставить версию из транка. Встаёт она значительно проще, чем стабильная. Далее. Сначала надо поставить Samba4, для этого в каталоге «script» есть специальный скрипт, который выкачивает её и ставит. Посколько API Samba меняется очень часто (это «альфа»), выкачивать нужно определённую ревизию, скрипт это умеет, но ему нужен git. Git — это распределённая система контроля версий, это пакет в Debian называется git-core, а не git. Git нужен последней версии (sic!), иначе скрипт скачать ревизию не сможет.

Как оказалось, Samba4 в памяти не нужна. Всё что он неё надо, чтобы она была скомпилена со всеми библиотеками и небольшой конфиг, образец которого есть в дебрях libmapi. Не забудьте правильно выставить язык в конфиге, в небольшой инструкции по установке есть описание того, как это делается. В установочных файлах конфига проследите, чтобы все пути были указаны правильно. Например, мне пришлось поправить пути до исходников Samba с «samba4» на «samba4/source4», а так же руками добавлять PKG_CONFIG_DIR в файлы configure.

Дайте libmapi и Samba4 весь софт, который она попросит. Даже опциональный. И самый свежий (к Python это не относится, у меня взлетело с 2.4). Это важно. Некоторые файлы нужно будет перенести вручную, например, библиотеки для Python. После компиляции создайте профиль (в wiki libmapi есть инструкция) и запустите openchangeclient, чтобы проверить соединение. Если у вас домен, то не забудьте про утилиту provision (описание можно найти в инете, важно пускать её именно так как в примерах — чтобы текущей была указанная в примерах папка).

Если openchangeclient выдаёт какую-то ерунду, воспользуйтесь strace, libmapi укладывает не все файлы как надо, посмотрите что openchangeclient пытается открыть и не находит. Некоторые файлы я перекладывал руками, в дистрибутиве всё есть, просто не всё попадает в свои папки.

Кажется, это всё. Да, если у вас несколько «Пайтонов» на машине, удалите все, кроме одного, или перепишите место, где в конфигах определяется версия «Пайтона» руками (я так и сделал), иначе часть модулей, возможно, встанет не туда, куда ожидается. Python нужен для работы provision (кстати, некоторые утилиты написаны на Perl, но с ним проблем у меня не было).

После всех боданий, из Си удалось подключиться к Exchange и получить данные. Из Python пока удаётся только залогиниться, но это дело времени — нужно описать нужные структуры и понять что куда передавать. В документации, кстати, есть неточности, лучше читать исходники.

Ctrl →Captain Lenin
6 комментариев
Азат Разетдинов (razetdinov.ya.ru) 2008

http://exler.ru/blog/item/4093/
Полагаю, рекорд побит ;-)

Евгений Степанищев (bolknote.ru) 2008

Комментарий для razetdinov.ya.ru:

Тут плотность ниже :)

ninjacolumbo.ya.ru 2008

Это кросспост из корп. вики?

Евгений Степанищев (bolknote.ru) 2008

Комментарий для ninjacolumbo.ya.ru:

Нет :)

barushev.livejournal.com 2008

это пакет в Debian называется git-svn, а не git.

Этот пакет в Debian называется git-core ( http://packages.debian.org/etch/git-core )
Это git-svn его по зависимости установил.

Евгений Степанищев (bolknote.ru) 2008

Комментарий для barushev.livejournal.com:

Ага, ну сейчас поправлю.