Всё нижеследующее вы можете использовать на свой страх и риск! Автор не несёт никакой ответственности за возможные риски: утерю информации, некорректное функционирование программного обеспечения и т.п.
Постановка задачи.
Имеется веб-портал SharePoint Services 3.0, аутентификация пользователей в котором происходит по локальным учётным записям на самом сервере. Требуется ввести сервер в домен Active Directory и использовать для аутентификации на портале учётные записи из домена.
1. Получение информации об имеющихся на портале учётных записях
Запускаем MS SQL Enterprise Manager, открываем базу данных WSS_Content. Информация о пользователях находится в таблице UserInfo. Запускаем из Enterprise Manager'а инструмент SQL Query Analyzer, в которм выполняем следующий запрос:
select tp_SystemID, tp_Login, tp_Title from UserInfo;Полученную информацию копируем в таблицу Excel. В выбранных колонках находятся: SID пользователя, логин пользователя вместе с доменом в виде "ДОМЕН\Логин", строка описания пользователя. SID пользователя в базе данных хранится в двоичном виде, а Query Analyzer выводит его в шестнадцатеричном виде.
После этого в таблице должны иметься следующие столбцы:
A - шестнадцатеричный SID локальной учётной записи,
B - логин локальной учётной записи,
C - описание локальной учётной записи.
2. Добавляем в полученный список столбец с учётными записями пользователей из домена
Каждой учётной записи, используемой для входа на портал, нужно сопоставить учётную запись из домена. Возможно, на этом этапе понадобится завести в домене учётные записи недостающих пользователей.
После этого в таблице должны иметься следующие столбцы:
A - шестнадцатеричный SID локальной учётной записи,
B - логин локальной учётной записи,
C - описание локальной учётной записи,
D - логин доменной учётной записи.
3. Получение SID пользователей из домена
Берём программу user2sid Евгения Рудного по ссылке http://evgenii.rudnyi.ru/programming.html#sid2user. Копируем столбец D в текстовый файл, а в начале каждой строки добавляем команду user2sid. Копируем получившийся bat-файл в каталог с программой. Запускаем bat-файл, перенаправив вывод из него в другой текстовый файл. В полученном текстовом файле убираем всё, кроме SID'ов, так чтобы в каждой строчке файла было по одному SID'у. Информацию из текстового файла добавляем в столбец E файла Excel.
После этого в таблице должны иметься следующие столбцы:
A - шестнадцатеричный SID локальной учётной записи,
B - логин локальной учётной записи,
C - описание локальной учётной записи,
D - логин доменной учётной записи,
E - SID доменной учётной записи.
Будьте внимательны! В списке должны присутствовать ровно столько SID'ов пользователей, сколько их имелось в первоначальном столбце. Также они должны следовать точно в таком же порядке, как в Excel-файле. Если что-то идёт не так, нужно поправить Excel-таблицу и bat-файл и повторить этот этап снова.
4. Конвертирование доменных SID в шестнадцатеричный вид
Для понимания того, каким образом SID хранится в двоичном виде в системе, можно воспользоваться следующей статьёй: Microsoft Security Descriptor(SID)Attributes.
Пишем на PHP сценарий для конвертирования SID:
<? function swap($hexdword) { $res = ""; for($i = 6; $i >= 0 ; $i -= 2) $res .= $hexdword[$i] . $hexdword[$i+1]; return $res; } function sid2hex($sid) { $sidl = explode("-", $sid); $hex_sid = "0x" . sprintf("%02X", $sidl[1]+0) . sprintf("%02X", $sidl[2]+0) . "000000000005"; for($i = 0; $i < $sidl[2]; $i++) $hex_sid .= swap(sprintf("%08X", $sidl[3+$i]+0)); return $hex_sid; } function hex2sid($hex_sid) { $hex_sid = trim($hex_sid); $sidl[0] = "S"; $sidl[1] = hexdec(substr($hex_sid, 2, 2)); $sidl[2] = hexdec(substr($hex_sid, 4, 2)); for($i = 0; $i < $sidl[2]; $i++) $sidl[3+$i] = hexdec(swap(substr($hex_sid, 18+$i*8, 8))); $sid = implode("-", $sidl); return $sid; } $sids = "S-1-5-21-583367659-4273102991-479599032-4176 S-1-5-21-583367659-4273102991-479599032-4450"; $sidsl = explode("\n", $sids); foreach ($sidsl as $sid) echo sid2hex($sid) . "<br>"; ?>Для того, чтобы быть уверенным в правильности написанных функций, я написал их пару. Проверив, что преобразование SID в шестнадцатеричный вид и обратно, не искажает его, я удостоверился, что функции написаны правильно.
В вышеприведённом сценарии я оставил только пару SID'ов. Вам следует вставить на место этих двух SID'ов содержимое столбца E. Полученный после выполнения сценария результат нужно скопировать в столбец F.
После этого в таблице должны иметься следующие столбцы:
A - шестнадцатеричный SID локальной учётной записи,
B - логин локальной учётной записи,
C - описание локальной учётной записи,
D - логин доменной учётной записи,
E - SID доменной учётной записи,
F - шестнадцатеричный SID доменной учётной записи.
5. Получение SQL-запросов для миграции портала на доменные учётные записи
Забегая вперёд, я хочу сказать, что обнаружил в базе данных ещё одну таблицу, в которой упоминаются логины пользователей. Эти логины не используются для проверки входа пользователей, они используются лишь для вывода информации о пользователе. Можно не менять их - в конце концов мы занимаемся не вполне чистым делом, а грязным хаком, а можно поменять, чтобы несоответствие реального логина и информации о логине не бросалось в глаза. итак, эта информация находилась в таблице AllUserData в поле nvarchar3.
Теперь мы можем написать в Excel'е формулы, которые сгенерируют нам SQL-запросы, необходимые для внесения необходимых изменений в БД SharePoint Services.
G ="update UserInfo set tp_Login = '" & D2 &"', tp_SystemID = " & F2 & " where tp_Login = '" & B2 &"' " H ="update AllUserData set nvarchar3 = '" & D2 &"' where nvarchar3 = '" & B2 &"' "Чтобы не бросаться голой задницей на амбразуру, подготовим SQL-запросы для отката навороченного:
I ="update UserInfo set tp_Login = '" & B2 &"', tp_SystemID = " & A2 & " where tp_Login = '" & D2 &"' " J ="update AllUserData set nvarchar3 = '" & B2 &"' where nvarchar3 = '" & D2 &"' "После этого в таблице должны иметься следующие столбцы:
A - шестнадцатеричный SID локальной учётной записи,
B - логин локальной учётной записи,
C - описание локальной учётной записи,
D - логин доменной учётной записи,
E - SID доменной учётной записи,
F - шестнадцатеричный SID доменной учётной записи,
G - SQL-запрос для обновления информации в таблице UserInfo,
H - SQL-запрос для обновления информации в таблице AllUserData,
I - SQL-запрос для отката обновления таблицы UserInfo,
J - SQL-запрос для отката обновления таблицы AllUserData.
Создаём два текстовых файла - update.txt и rollback.txt. В первый копируем столбцы G и H, а во второй - I и J.
6. Миграция
Для миграции нужно выделить перерыв обслуживания примерно в 15 минут. За это время можно будет выполнить SQL-запросы из файла update.txt и ввести компьютер в домен. На случай если что-то пойдёт не так, лучше увеличить паузу до 30 минут, чтобы вывести компьютер из домена и выполнить SQL-запросы из файла rollback.txt.
На случай же если же что-то пойдёт совсем не так, следует заготовить резервную копию базы данных. Перед снятием резервной копии нужно перевести базу данных портала в режим "Только чтение" через "Центр администрирования" SharePoint Services, вкладку "Управление приложениями", пункт "Квоты и блокировки семейства узлов", а затем снять резервную копию средствами MS SQL Enterprise Manager. После восстановления следует не забыть восстановить режим "Нет блокировки".
Я выполнял обновление из дома, глубоким вечером, разумеется проработав в рабочее время сценарий миграции и текстовые файлы с SQL-запросами.
7. Кое-что ещё
Дополнительно, я поменял учётную запись администратора SharePoint Services в "Центре администрирования" на доменную. Поменял я её в базе данных SharePoint_Admincontent_многобукв в таблицах AllUserData и UserInfo. Это уже не столь критично и не столь сложно. Администраторов мало и они, в отличие от пользователей, могут выдержать и больший перерыв в обслуживании.
9 комментариев:
А на практике, с готовым и настроенным решением, с не которым объемом данных, это получалось?
А вы думаете я чисто умозрительный эксперимент сделал?
Конечно получалось, и не раз, а два раза. Первый раз локальные учётные записи заменил на доменные. Второй раз переехал с одного домена на другой.
Ну да, я про эксперемент и спрашивал.
М.б. в стерильных условиях прокатило а в боевых условиях нет. Спасибо.
А если перед тем как вогнать в домен Shrepoint перевел все учетные записи с помощь ADMT? нужно ли всё это проделывать? Так же я этот сервер перенес бы с помощью ADMT
ADMT может не знать о том, что идентификаторы учётных записей, используемые Sharepoint хранятся в базе данных MS SQL. Поэтому, наверняка придётся это проделывать.
А если в роли сервисной учетной записи используется Local system, это никак не облегчает жизнь?)
Дело не в том, под какой учётной записью работают сервисы Sharepoint, а в том что Sharepoint проверяет права доступа к разделам портала по логинам и SID'ам пользователей.
Советую собрать стенд, на котором попробовать поставить Sharepoint, восстановить ваш портал, провести миграцию, а потом проверить, всё ли работает как должно. В случае обнаружения проблем искать метод их устранения и опробовать его на тестовом стенде. Окончательный переход делайте тогда, когда уже будет понятно, что нужно сделать, чтобы после перехода всё нормально работало.
Сделал все по инструкции, в результате выполнения запроса вылетает ошибка
Cannot insert duplicate key row in object 'dbo.UserInfo' with unique index 'UserInfo_SID'.
Как быть?
Игорь, видимо в таблице уже есть учётные записи пользователей с таким идентификатором SID.
Как быть? Можно убрать запрос update, приводящий к этой ошибке. А вообще - я писал в начале статьи уведомление. Если не понимаете, что делаете - не стоит даже начинать. Всё описанное - это очень грубый хак, я не могу дать гарантий, что всё будет работать правильно, даже если вы соблюдёте инструкцию буква в букву.
Отправить комментарий