11.09.2013

Отправляем почту из php

Вот тоже сюда положу, чтоб не искать потом. 

Будет использоваться библиотека Pear, у кого не установлена, тому сюда:

Цель:

Отправить письмо пользователю с русским заголовком и русским html текстом.
Сообщение должно проходить от авторизованного пользователя.

Реализация:

// Подключаем библиотеку
include('Mail.php'); 
include('Mail/mime.php'); 

// Задаем начальные значения
$html = '<html><body>Пишем по-русски!</body></html>'; 
$crlf = "\r\n"; 
// Отправитель и заголовок письма
$hdrs = array( 
              'From' => 'ivanov.i@domain.ru', 
              'Subject' => 'Автоматическое сообщение' 
              ); 
// Правильные параметры, что бы писать по-русски
$params = array( 
             'text_encoding' => '8bit', 
             "head_charset" => "windows-1251", 
             "text_charset" => "windows-1251", 
             "html_charset" => "windows-1251", 
              ); 
// Проводим инициализацию
$mime = new Mail_mime($crlf); 
$mime->setHTMLBody($html); 
$body = $mime->get($params); 
$hdrs = $mime->headers($hdrs); 
$mail =& Mail::factory('mail'); 

// А теперь хитрость
// Сообщение будем отправлять по smtp с авторизацией
// Иначе получатель в отправителях увидит не "Иванов И.И.", а ivanov.i.domain.ru
// Да что там получатель, анти-спам фильтр может обидится
$host = "mail.domain.ru"; 
$port = 25; 
$username = "domain\ivanov"; 
$password = "password"; 
$smtp = Mail::factory("smtp",
        array(
              "host" => $host, 
              "port" => $port, 
              "auth" => true, 
              "username" => $username, 
              "password" => $password)); 

// Адрес получателя
$to_email = "petrov.p@domain.ru"; 

// Отправляем письмо
$mail = $smtp->send($to_email, $hdrs, $body);

Ищем пользователя в AD из MS SQL

Пока не забыл, запишу здесь. Каждый раз с этим вопросом какая-то непонятная возня происходит.

Задача

Есть корпоративное программное обеспечение (далее - ПО), в котором необходимо сделать аутентификацию пользователей по их логину (Windows Authentication).
Пользователям необходимо назначать персонализированные права.
Пользователям необходимо рассылать e-mail в процессе эксплуатации ПО.

Идея

В базе данных MS SQL создать таблицу со списком пользователей.
Данные о пользователях (account, e-mail, должность, подразделение) подтянуть из корпоративной Active Directory.

Реализация

Запускаем консоль MS SQL (на примере MS SQL 2000)

Подключение ADSI

EXEC master.dbo.sp_addlinkedserver @server = N'ADSI' , @srvproduct=N'Active Directory Service Interfaces' , @provider=N'ADSDSOObject' , @datasrc=N'adsdatasource'

Настройка аутентификации для ADSI

EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'ADSI' ,@useself=N'False' ,@locallogin=NULL ,@rmtuser=N'username' ,@rmtpassword='password'

В качестве username/password используется учетная запись корпоративного пользователя, имеющего право работать с доменом.
Прилинкованный ADSI выглядит следующим образом:
Кстати, прежде чем экспериментировать в консоли, можно запустить замечательную бесплатную программу LDAP Admin
В программе все те же настройки, что и на

Тестовое подключение

Возвращаемся в консоль:

SELECT * FROM OPENQUERY(ADSI,'SELECT cn,sAMAccountName FROM ''LDAP://domainname:port/DC=dc''')

Вот тут все должно заработать
Порт обычно 386 или 3268
DC можно узнать, выбрав в программе LDAP Admin "Fetch DNs" при подключении.
Если не заработало, дальше двигаться смысла нет. Нужно добиваться, что бы заработало.

Настройка запроса

Вытащим список пользователей, совпадающих по началу имени

SELECT * FROM OPENQUERY(ADSI,'SELECT userPrincipalName, cn,title,name,mail,company,department,displayName FROM ''LDAP://domainname:port/DC=dc'' WHERE cn =''Иванов И*'' AND objectClass=''person'' AND objectClass<>''computer''')

Если получилось, совсем замечательно. К сожалению, MS SQL не даст выполнить запрос просто так, если имя пользователя передавать параметрически, так что через exec и добавить немного кавычек:

declare @name nvarchar(150)
set @name='Иванов И*'
exec ('SELECT * FROM OPENQUERY(ADSI,''SELECT userPrincipalName, cn,title,name,mail,company,department,displayName FROM ''''LDAP://domainname:port/DC=dc'''' WHERE cn ='''''+@name+''''' AND objectClass=''''person'''' AND objectClass<>''''computer'''' '')')

Ну и маленькая хитрость.
Если  результат exec вытащить не удается, то можно вернуть результат запроса во временную таблицу внутри exec:

exec ('insert into temp_table (userPrincipalName, cn,title,name,mail,company,department,displayName) SELECT userPrincipalName, cn,title,name,mail,company,department,displayName FROM OPENQUERY(ADSI,...

Теперь Иванова можно найти в AD, если он есть и сразу вытащить его account и e-mail, ну и еще чего записано, что бы жить легче стало.

Всё, вроде ничего не забыл?...