четверг, 23 августа 2007 г.

Прозрачная авторизация LDAP.

В продолжение поста про авторизацию LDAP, опишу своё решение этой проблемы. Если сервер крутится на Win, то существует mod_auth_sspi.so для Apache, который позволяет делать прозрачный вход для пользователя, авторизованного в домене. Но у меня сервер под Solaris 9, следовательно этот модуль мне не подошёл.

Остается 2 варианта:

  1. mod_auth_ntlm_winbind
  2. mod_ntlm

Причем mod_auth_ntlm_winbind считается намного лучше, чем mod_ntlm, который особо и не развивается и не поддерживается. А mod_auth_ntlm_winbind вышел из проекта Samba, и соответственно он жив. Т.е. по логике вещей надо ставить его. Есть только одно "НО"...зависимости. И список их впечатляет:

  • Samba 3 с Winbind
  • Kerberos
  • SSL

Вот этот список с моими неАдминскими правами и отсутствием времени мне и не захотелось поднимать. Причем это всё надо не просто установить...но и настроить. Соответственно, разбираться в этом пришлось бы. А времени не было. Поэтому было принято решение устанавливать mod_ntlm

С mod_ntlm тоже были проблемы. Он не хотел собираться и инсталлироваться. Никак не хотел. Длительный поиск по инету привел меня вот на эту страницу, где я прочёл что надо поправить в source, чтобы всё нормально собиралось. Рекомендую.

Дальше, подключаем mod_ntlm в httpd.conf, и пишем в дирректории, где у нас будет происходить авторизация в .htaccess (ну или прямо в httpd.conf прописываем):

AuthType NTLM
AuthName "NTLM authentication"
NTLMAuth On
NTLMAuthoritative Off
NTLMDomain DOMAIN_NAME
NTLMServer SERVER_ALIAS
require valid-user

Вроде работает. Если скрестить со скриптом из топика, то вытаскивается логин пользователя в домене. Если почистить его от непечатных (не ASCII) символов со помощью регулярки:

$login = preg_replace('/[\x00-\x0d]/i', '', $login);

то получим читабельный логин. И под FireFox (который правда не отсылает заголовки по умолчанию, так что с ним прозрачности нет) и под IE.

Ну а релогин пользователю выполняется просто. Если файлик, выполняющий аутентификацию у нас лежит в папочке, которая проверяется mod_ntlm, то после того, как они поговорят с браузером о логинах и хэшах автоматически, надо отправить клиенту заголовок 401, тем самым вынудив браузер выкинуть формочку для ввода логина и пароля. Т.е. мы имитируем неправильную аутентификацию.

Правда есть один неприятный момент, который я не решил. Баг. Он проявляется, если несколько раз подряд пытаться выполнить релогин. То в логах Apache появится вот такая ошибка:

[error] 11762 - SMB_Logon_Server: SMB_SessSetupAndX failed; errorclass = 1, Error Code = 5\n
2905896 12224 /login/tmp.php - PDC connection already closed
[notice] child pid 11762 exit signal Segmentation fault (11)

А вот если делать его аккуратно и не часто, то всё ок. Мне кажется это проблема самого модуля, и способа её устранить я не нашел.

вторник, 14 августа 2007 г.

Сага про Solaris 5.9, Oracle 10 и PHP 5.2.3.

Эта история является продолжением работы над славным и большим проектом. В честь которого я уже копал LDAP.

Поняв, что окончательно приложение будет крутиться на Solaris'е, я пришел к выводу, что и разработку лучще вести под этой славной операционной системой о чем смело заявил вышестоящим. С меня спросили конфигурацию сервера и количество свободного места. Долго раздумывая, я перечислил все модули для Apache и PHP, которые мне необходимы и привел примерную цифру всего этого софта в установленном виде плюс сам проект.

Решив, что скоро у меня будет свой серер под Solaris'ом, я продолжил ковырять LDAP и успел реализовать неплохую авторизацию. Правда с использованием mod_auth_sspi.so, который умеет крутиться только на виндовых серверах. А у меня будет Solaris. Но простота реализации мне очень понравилась.

Ждать пришлось не очень долго, и скоро мне прислали логин, пароль, имя сервера и имя папки. Подобное письмо вызвало у меня ряд вопросов. И меня отправили к специалисту. Специалист объяснил мне, чем коннектиться к серверу по SFTP (WinSCP) и показал как пользоваться PuTTY. Он же сказал мне, что root мне никогда не дадут, свой сервер тоже, и что он поднимал Apache с PHP под простой (не рутовой) учетной записью, и всё было номрально.

Так мне пришлось заняться чрезвычайно интересной задачей по поднятию сервера в маленькой локальной папочке на сервере под Solaris 5.9, где нет вообще ничего. Если искать в инете книги по Solaris, то вы нигде не найдете в них способ установки софта без прав админа. Я знаю про сырцы, но у меня не было binutils, g++ и кучи библиотек.

Зато мне рассказали про команду pkgtrans. После прочтения по ней manа, лично мне понятнее не стало. Рассказы о ленте и других потоковых накопитилях совершенно меня расстроили. Но команда оказалась единственной полезной, и если бы не она, мне не удалось бы осуществить задуманное.

Установка софта без прав root

Идем на www.sunfreeware.com (пакеты вообще без расширений) или на www.blastwave.org (пакеты с расширением pkg). Там лежат большие архивы собранного софта. Для кучи версий Solaris'а. Качаем то, что нам нужно, копируем себе в дирректорию (обозначим её для краткости $HOME), распаковываем командой gunzip pack_name распаковываем его. А дальше вступает pkgtrans. В той же дирректории пишем pkgtrans pack_name pack/ Эта комманда распакует наш пакет в поддиректорию $HOME/pack/SMCpack_name или pack/CSWpack_name, в зависимости от того, откуда качали файл. Теперь у нас есть автомат. Т.е. скомпилированный софт. Т.е. хотя бы gcc =).

Сборка софта для сборки сервера.

Я собирал сервер неделю. Возможно, столь большой срок связан с тем, что мне пришлось решать кучу проблем впервые. Обладая теперешними знаниями, я бы собрал его чуть быстрее.

Я не буду подробно описывать сборку всех пакетов, я просто приведу конфиги и то, что мне пришлось поставить для того, чтобы все заработало. Ну и расскажу о нескольких подводных камнях, которые я обходил порой пару дней.

Итак, у меня есть работающий GCC, т.е. оба компилятора и для C и для C++. Это уже хорошо. Теперь можно собрать binutils, в которых присутствуют необходимые для сборки инструменты. Единственный параметр, с которым я собирал был --prefix=/u01/users/php/tools. Т.е. я просил установить всё в папку tools, где у меня со временем образовалось почти полное дерево системы. Таким образом, собирая все инструменты в эту папку, я избавил себя от необходимости прописывать десятки путей в свой .profile. Важно прописать пути к этой папке до основных путей системы. Т.е. при задании переменных окружения надо писать export PATH=/u01/users/php/tools:$PATH.

После binutils, установим пакеты bison, flex, gawk, m4, make (все есть на gnu.org, кроме flex, он живет на flex.sourceforge.net). Эти пакеты необходимо собирать с тем же префиксом, что и binutils. Они собираются без проблем, насколько я помню. Чтобы понять что использует ваша система, когды вы говорите ей, допустим make, стоит набрать which make, и получите путь, откуда этот make запускается. Так стоит проверять, чтобы использовались нужные инструменты.

Сборка Apache 2.0.59

Собрать, как я уже говорил, мне необходимо работающий сервер Apache+PHP и связать его с Oracle. Я начал с Apache. Как с наиболее простого. По каким-то причинам Apache ветки 2.2 у меня собираться отказался. Поэтому я собирал проверенный Apache 2.0.59. Создаем простой файлик, куда пишем полный конфиг, делаем файлику chmod +x, или каждый раз пишем sh apache2_config. Вот содержимое файлика:

cd /u01/users/php/src/httpd-2.0.59
./configure \
--prefix=/u01/users/php/apache2 \
--enable-so \
--enable-mods-shared='rewrite mime-magic ssl vhost-alias' \
--disable-cgi \
--disable-autoindex \
--with-mpm=prefork \
--with-ssl=/u01/users/php/openssl \

Модулей не очень много. Для сборки Apache мне пришлось установить только собранный из сырцов OpenSSL. Хотя для сборки PHP, мне пришлось использовать скомпилированный openssl 0.9.7, потому что при сборке с текущим 0.9.8 выпадал ld, который под Solaris не очень стабилен. А заставить ПСС использовать GNU ld мне не удалось. Для этого пришлось бы пересобирать компилятор. Это мне не удалось. Вообщем, с Apache проблем особо не возникло.

Сборка PHP 5.2.3

Вот здесь начались танцы с бубном. Для начала приведу конфиг:

cd /u01/users/php/src/php-5.2.3/
./configure \
--prefix=/u01/users/php/php5 \
--with-apxs2=/u01/users/php/apache2/bin/apxs \
--enable-bcmath \
--enable-calendar \
--enable-exif \
--enable-mbstring \
--enable-soap \
--enable-sockets \
--with-gd=/u01/users/php/tools \
--with-jpeg-dir=/u01/users/php/tools \
--with-png-dir=/u01/users/php/libpng \
--with-iconv \
--with-libxml-dir=/u01/users/php/tools \
--with-xsl=/u01/users/php/tools \
--enable-zip \
--with-zlib \
--with-ldap=/u01/users/php/tools \
--with-openssl=/u01/users/php/pack/SMCosslg/reloc \
--enable-soap \
--with-mcrypt=/u01/users/php/libmcrypt \
--disable-ipv6 \
--with-oci8=instantclient,/u01/users/php/instantclient_10_2 \
--enable-pdo \
--with-pdo-oci=instantclient,/u01/users/php/instantclient_10_2,10.2.0.3 \
--without-pdo-sqlite \
--without-sqlite

В принципе из конфига видно, где я использовал собранные руками библиотеки, а где пакеты. Пробегусь быстро по интересным пунктам конфигурации.

Первые две строчки говорят куда собирать (предпочитаю отдельную папку и для Apache и для PHP, т.к их приходится пересобирать по много раз, и вычищать каждый раз папку tools было бы маразмом), и где лежит прежде собранный Apache. Всё просто. Дальнейшие несколько строк ничего интересного не представляют, эти модули включены в поставку PHP и собираются без проблем

Дальше начинается GD. Для сборки GD, надо сначала собрать libpng (без проблем) и libjpeg. Собрав libjpeg командой ./configure --prefix=/u01/users/php/tools, самое главное на забыть после команды make install, скомандовать make install-lib. Без этого, GD будет конфигурироваться, но не будет собираться (отняло примерно день, решение нашлось на каком-то форуме).Если нужна поддержка ttf или xpm, их тоже надо собирать. Мне они нужны не были. После этого сборка GD проходит гладко, и в конфиге мы указываем его, и пути к библиотекам jpeg и png.

Дальше идет iconv, xml и xslt, для них необходимо собрать библиотеки, соответственно iconv, libxml2 и libxslt. Здесь проблем нет. Не забываем про prefix, иначе make install не пройдет.

Теперь ldap, openssl и mcrypt. LDAP собирается (правда, он у меня попросил Berkeley DB, но это проблемой не считается =)), а вот openssl, как я уже говорил, мне пришлось использовать готовый. Т.к. PHP отказывался делать make, вызывая панику у ld. Это проблема новой версии 0.9.8 и архитектуры SPARC. С mcrypt проблем не было.

И вот начинается самое интересное. Oracle. Достаем мануал The Underground PHP and Oracle® Manual с оракловского сайта. Читаем. Идем на тот же оракловский сайт и качаем instant client под Solaris Sparc. Почему он в zip, я не знаю. Разкатываем архив в нашу папочку. Теперь у нас есть оракловый клиент. С ним-то мы и будем собирать PHP. Это стоило мне где-то трех дней. PHP спокойно конфигурировался с OCI8, но отказывлся конфигурировать PDO_OCI. А он мне был очень нужен. Проблема скрывалась в Sun'овском SH (шелле), который немного отлично ведет себя от обычных. Я решил проблему, прописав в конфигурационном файле #!bin/bash вместо #!bin/sh. У меня всё собралось. Эту проблему обещали исправить в PHP 5.2.4 (Тред по этой проблеме на phpClub).

Соединяемся с Oracle

В принципе на этом проблемы со сборкой закончились. Всё собралось, запустилось и заработало. Не хватало только соединиться с Oracle. Здесь меня тоже ожидали сюрпризы (дня два). Не смотря на всё, что написано в Подземелье ПХП и Оракла, они никак не соединялись. У меня в наличие было два файлика sqlnet.ora и ldap.ora, которые объясняли Ораклу где искать сервер, но не смотря на всякие TNS_ADMIN, Oracke Instant Client не видел сервер. И файлики, видимо тоже. Всё решилось довольно хитро. Обычно, если устанавливать на компьютер обычный оракловый клиент, эти файлики лежат в папочке $ORACLE_HOME/network/admin/. Это и есть ключ. Пришлось в папке instantclietn_10_2, которая жила у меня, сделать эту структуру подпапок. И уже в подпапку admin положить два файлика. И он их нашёл. Я не знаю, зачем так всё сложно. Но мне кажется, что без программерской лени тут не обошлось.

Первый этап саги окончен. Сервер работает. Связь с БД есть. Но что-то мне подсказывает, что пересобирать я буду и Apache и PHP. Тогда, если будет о чем написать - буду дописывать сюда.

пятница, 3 августа 2007 г.

Zend Framework 1.0 и Oracle.

На работе надо было связаться с оракловым сервером. Так как я решил поплотнее пообщаться с Zend Framework, было решено соединяться им. К тому же он предоставляет достаточно хороший каркас для создания приложений. И со временем, я думаю, я буду использовать его всё больше.

Ну так вот. Соединился я с базой. И всё, вроде, нормально, если писать запросы руками. Т.е. "SELECT * FROM USER". Но это не очень интересно. Так как ZF предоставляет достаточно классов для работы с базой в более прозрачном режиме. НО! При попытке создать запрос его средствами, я получал ошибку. 942 ORA-00942: table or view does not exist. И дальше шёл странный такой SQL-запрос. Слабо похожий на то, что любит Oracle.

Мне сразу не очень понравились все эти кавычки вокруг имени таблицы и полей. И Ораклу они тоже не нравятся.

В документации я решения проблемы не нашёл. Долго бродил по исходному коду. Безысходно. Спросил у умных. Те объяснили мне, что эти кавычки появляются автоматически и отвечает за это переменная $_autoQuoteIdentifiers в классе Zend_Db_Adapter_Abstract.

Поначалу я на радостях просто выставил ей false, но потом понял, что модификация фреймворка не есть гуд. Потому что проблемы с обновлениями не заставят себя ждать. И тогда мне очередные умные люди объяснили, что надо просто при инициализации подключения надо указать в параметрах опцию 'options' => array(Zend_Db::AUTO_QUOTE_IDENTIFIERS => false). И всё будет ок.