+7 (495) 229-0436   shopadmin@itshop.ru 119334, г. Москва, ул. Бардина, д. 4, корп. 3
 
 
Вход
 
 
Каталог
 
 
Подписка на новости
Новости ITShop
Windows 7 и Office: Новости и советы
Обучение и сертификация Microsoft
Вопросы и ответы по MSSQLServer
Delphi - проблемы и решения
Adobe Photoshop: алхимия дизайна
 
Ваш отзыв
Оцените качество магазина ITShop.ru на Яндекс.Маркете. Если вам нравится наш магазин - скажите об этом Google!
 
 
Способы оплаты
 
Курс расчета
 
 1 у.е. = 92.51 руб.
 
 Цены показывать:
 
 
 
 
  
Новости, статьи, акции
 

Автоматизация миграции базы данных DocsVision

30.01.2014 14:19
Namelles_One

Преамбула

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

К сожалению, обычно все плохо: инструменты есть, но настолько неудобные, что от их наличия - никакого счастья. Приходится выкручиваться.

Итак, дано - система DocsVision (далее DV) версии 4.5 SR1. И, стоит задача переместить базу с одного сервера на другой (скажем, клиенты купили новый). Проблема, которая при этом возникает - ровно одна.

Права на объекты для локальных учетных записей при переносе базы на новое место превратятся в тыкву. А так как стандартные группы DV являются именно локальными - то проблем не избежать.

Кто заинтересован - прошу пожаловать под кат.

Стандартные инструменты

Для начала рассмотрим тот инструмент, что нам предлагает для этих целей компания DocsVision.
Он описан по ссылке dvprofessionals.blogspot.com/2010/03/blog-post_22.html

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

image

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

Поэтому и было принято решение - написать нечто свое.

Исследование структуры БД

DocsVision - платформа закрытая и документирована только в рамках предоставленных разработчикам API. Но, кое-какая информация все-таки по интернету гуляет, и ее оказалось достаточно.

Основными интересующими нас таблицами являются dvsys_instances и dvsys_security. Первая содержит информацию обо всех объектах системы (карточки, папки, справочники, файлы и т.д.), вторая же. не мудрствуя лукаво, хранит описатели безопасности. Структура таблиц приведена ниже.

image
 
image
 

Связь таблиц осуществляется по полям dvsys_instances.SDID и dvsys_security.ID. Также, необходимо отметить, что количество записей в этих таблицах различается очень сильно, спасибо наследованию прав. Например, у одного из клиентов эти значения составляют 277571 и 6639 соответственно.

Итак, задача поставлена - необходимо пройтись по всем строкам второй таблицы, раскодировать описатели безопасности, заменить старые SID для необходимых записей на новые и, предварительно закодировав, записать обратно. Что ж, приступим.

Реализация задуманного

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

Для удобства использования все настройки были вынесены в отдельный файл. К таковым можно отнести таблицу соответствия аккаунтов и настройки доступа к БД.

$SIDReplacement = @{ "S-1-5-21-2179127525-659978549-3108502893-1019" = "a31003\akushsky"; #akushsky "S-1-5-21-2179127525-659978549-3108502893-1016" = "a31003\ASPNET"; #ASPNET "S-1-5-21-2179127525-659978549-3108502893-1008" = "a31003\DocsVision Administrators"; #DV Administrators "S-1-5-21-2179127525-659978549-3108502893-1010" = "a31003\DocsVision Power Users"; #DV Power Users "S-1-5-21-2179127525-659978549-3108502893-1012" = "a31003\DocsVision Users"; #DV Users "S-1-5-21-2179127525-659978549-3108502893-1026" = "a31003\dobriy"; #DV Editors } $SQLServerName = "a31003" $SQLDatabaseName = "DV-BASE"

Мне показалось логичнее запускать скрипт на целевом сервере, поэтому старые учетные записи присутствуют в виде SID-ов (для их получение также можно использовать PowerShell, об этом знает Гугл). А новые - укажем в виде учеток и их SID-ы получим в процессе работы скрипта.

Также, как выяснилось в процессе разработки, PowerShell не умеет создавать экземпляры объектов generic-ков, поэтому из недр Гугла для этого пришлось достать функцию New-GenericObject. Ее код приводить не буду, в конце статьи будет ссылка на репозитарий - все там.

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

# Struct for log add-type @" public struct DVObject { public string ID; public string Description; public string Accounts; } "@

Для наиболее полного логирования запрос, конечно же, возвращает гораздо больше информации, чем мог бы, но - красота требует жертв.

SELECT I.InstanceID, I.Description, S.ID, S.SecurityDesc FROM [DV-BASE].[dbo].[dvsys_security] S LEFT JOIN [DV-BASE].[dbo].[dvsys_instances] I ON I.SDID = S.ID

Поэтому, чтобы не обрабатывать один и тот же описатель много раз - идентификаторы записываются.

# Replace SDDL in each row only once $IDList = New-Object System.Collections.Generic.HashSet[Guid] ... # We need only one SQL-request for each ID if ($IDList.Contains($row["ID"])) {continue} else {$isOk = $IDList.Add($row["ID"])}

А далее начинается самое интересное:

  1. Полученный SecurityDesc представляет собой бинарную последовательность символов, закодированную Base64. А, для подмены SID-ов нам необходимо получить SDDL-строку. Описание формата есть на MSDN. А теперь то же самое, только кодом:

    # Convert SDDL from Base64 to binary form $ObjectWithSDDL = ([wmiclass]"Win32_SecurityDescriptorHelper") .BinarySDToSDDL([System.Convert]::FromBase64String($row["SecurityDesc"])) $sddl = $ObjectWithSDDL.SDDL

  2. Далее, вычленяя при помощи регулярки SID-ы из SDDL-строки, проверяем их по таблице соответствия и, в случае совпадения, подменяем.

    # Match all SIDs and replace [regex]::Matches($sddl,"(S(-\d+){2,8})") / sort index -desc / % { if ($SIDReplacement.ContainsKey($_.ToString())) { # Translate NT account name to SID $objUser = New-Object System.Security.Principal.NTAccount($SIDReplacement[$_.ToString()]) $strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier]) # Replace it in SDDL $sddl = $sddl.Remove($_.index,$_.length) $sddl = $sddl.Insert($_.index,$strSID.Value) # Add to list of current object accounts $dvobject.Accounts += $SIDReplacement[$_.ToString()] $dvobject.Accounts += "`n" # Set replace completed $replaceComplete = $true } }

  3. Если замена была произведена, то тогда необходимо произвести обратные действия и записать данное изменение в БД:
    if ($replaceComplete) { # Add current info object to list $DVObjectList.Add($dvobject) $binarySDDL = ([wmiclass]"Win32_SecurityDescriptorHelper").SDDLToBinarySD($sddl).BinarySD $ret = [System.Convert]::ToBase64String($binarySDDL) ##### Update database ##### # Update query for currently replaced SDDL $SqlQuery = "UPDATE [dbo].[dvsys_security] SET Hash = '" + $binarySDDL.GetHashCode() + "', SecurityDesc = '" + $ret + "' WHERE ID = CONVERT(uniqueidentifier, '" + $row["ID"] + "')" # Attach query to command $UpdateSqlCmd.CommandText = $SqlQuery # Execute update query if ($UpdateSqlCmd.ExecuteNonQuery()) { Write-host "Update true for ID: " $row["ID"] } else { Write-host "Update false for ID: " $row["ID"] } }

Таким образом, получен универсальный механизм для любой миграции - между серверами заказчика, между сервером разработки и заказчиком, да мало ли еще как.

В конце, как и было обещано: ссылка на репозитарий с описанным кодом.

Ссылки по теме

  
Помощь
Задать вопрос
 программы
 обучение
 экзамены
 компьютеры
Бесплатный звонок
ICQ-консультанты
Skype-консультанты

Общая справка
Как оформить заказ
Тарифы доставки
Способы оплаты
Прайс-лист
Карта сайта
 
Бестселлеры
Курсы обучения "Atlassian JIRA - система управления проектами и задачами на предприятии"
Microsoft Windows 10 Профессиональная 32-bit/64-bit. Все языки. Электронный ключ
Microsoft Office для Дома и Учебы 2019. Все языки. Электронный ключ
Курс "Oracle. Программирование на SQL и PL/SQL"
Курс "Основы TOGAF® 9"
Microsoft Office 365 Персональный 32-bit/x64. 1 ПК/MAC + 1 Планшет + 1 Телефон. Все языки. Подписка на 1 год. Электронный ключ
Курс "Нотация BPMN 2.0. Ее использование для моделирования бизнес-процессов и их регламентации"
 

О нас
Интернет-магазин ITShop.ru предлагает широкий спектр услуг информационных технологий и ПО.

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

Хорошие отзывы постоянных клиентов и высокий уровень специалистов позволяет получить наивысший результат при совместной работе.

В нашем магазине вы можете приобрести лицензионное ПО выбрав необходимое из широкого спектра и ассортимента по самым доступным ценам. Наши менеджеры любезно помогут определиться с выбором ПО, которое необходимо именно вам. Также мы проводим учебные курсы. Мы приглашаем к сотрудничеству учебные центры, организаторов семинаров и бизнес-тренингов, преподавателей. Сфера сотрудничества - продвижение бизнес-тренингов и курсов обучения по информационным технологиям.



 

О нас

 
Главная
Каталог
Новинки
Акции
Вакансии
 

Помощь

 
Общая справка
Как оформить заказ
Тарифы доставки
Способы оплаты
Прайс-лист
Карта сайта
 

Способы оплаты

 

Проекты Interface Ltd.

 
Interface.ru   ITShop.ru   Interface.ru/training   Olap.ru   ITnews.ru  
 

119334, г. Москва, ул. Бардина, д. 4, корп. 3
+7 (495) 229-0436   shopadmin@itshop.ru
Проверить аттестат
© ООО "Interface Ltd."
Продаем программное обеспечение с 1990 года