SQL.RU
 client/server technologies
 Главная | Документация | Статьи | Книги | Форум | Блоги | Опросы | Гостевая | Рассылка | Работа | Поиск | FAQ |

Общая система безопасности приложений на предприятии

ПУБЛИКАЦИИ  

Авторы: Николай Денищенко и Сергей Гавриленко

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

Необходимость создания общей системы безопасности предприятия

Никогда не стоит полагаться на честность сотрудников и на то, что они будут добросовестно выполнять должностные предписания (если, конечно, сотрудники вашего предприятия не самураи и при первом же намёке на их нечестность докажут вам свою преданность, сделав харакири).
Предположим, что в компании, торгующей автомобилями, в разных филиалах работают два продавца Маша Ведро и Вася Пушкин. Заработная плата обоих существенно зависит от объёма продаж, так как и Маша и Вася получают процент от размера заключённых ими сделок. Продавцы, пользуясь вашей программой, каждый месяц просматривают отчёт о своих продажах, чтобы убедиться в том, что компания их не обманула и зарплата была рассчитана правильно. Всё превосходно, если вы продумали в программе разграничение прав доступа. А если нет? Тогда Маша, к примеру, может посмотреть продажи Васи и возмутиться, что процентная ставка у Васи выше. Или посмотреть отчёт по всему филиалу Васи и сделать вывод, что бизнес там идёт лучше, а затем попросить руководство перевести её на этот филиал. Можно, конечно, регулировать любопытство Маши посредством штрафных санкций. Но где гарантия, что они на неё подействуют?
Ещё один аспект, который обычно игнорируют разработчики интеллектуальные способности пользователей. Многие опрометчиво считают, что пользователь не способен установить себе инструменты вроде Query Analyzer или прилинковать табличку с SQL Server в MS Access и подправить в ней пару строчек.
Так что прежде чем приступать к разработке, давайте определим задачи, которые должна решать система безопасности.

[В начало]

Удовлетворение требованиям корпоративной безопасности: ограничение доступа к объектам приложений.

Приложения, работающие с конфиденциальными данными (денежные проводки, клиентские базы и пр.) уже сами по себе подразумевают контроль и разграничение прав доступа между сотрудниками предприятия. Для предотвращения несанкционированного доступа к базам данных приложений система безопасности должна быть тесно интегрирована с безопасностью MS SQL Server (чтобы Маша не смогла никакими инструментальными средствами получить доступ к данным, не предназначенным для её глаз).

[В начало]

Разграничение функций между системными администраторами и разработчиками

Обязанности по регистрации пользователей в приложениях, как правило, возлагаются на администратора баз данных или на системных администраторов. Во втором случае ситуация осложняется тем, что системные администраторы не должны иметь полного доступа на SQL Server'а предприятия (в силу своей квалификации).
Уменьшение трудозатрат системных администраторов при регистрации нового или изменении статуса существующего сотрудника в приложениях предприятия.
Системные администраторы не должны вникать в тонкости физической организации безопасности того или иного приложения (например, какого пользователя в какую роль добавлять или, ещё хуже, в какие таблицы прописывать информацию о нём). Принцип создания учётной записи и присвоения прав должен быть единым и не зависящим от приложения. Время, затрачиваемое администратором на создание или изменение прав учётной записи, должно измеряться секундами. Не заставляйте этих людей думать - им не всегда за это платят!

[В начало]

Существование нескольких групп разработки ПО на предприятии

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

[В начало]

Сведение повторяемости кода к минимуму

Методы защиты объектов в приложениях легко поддаются абстрагированию. Поэтому логичным было бы выделить код, предоставляющий требуемый уровень абстракции, для последующего многократного использования. Это позволит разработчикам сосредоточиться на реализации основных функций приложения и не отвлекаться на решение проблем, связанных с безопасностью.
Однако далеко не все требования к защищенным системам хорошо согласуются с абстрактной моделью. При проектировании таких систем, прежде всего, нужно руководствоваться здравым смыслом. Возможно, что существующая у вас на предприятии абстрактная модель перестанет удовлетворять внезапно возникшим новым требованиям, которые не были предусмотрены при её создании. Возникает вопрос о том, что целесообразнее дорабатывать модель под новые требования или, отказавшись полностью или частично от использования модели, решать проблему другим путём.

[В начало]

Удобство для пользователей. Необходимо помнить лишь одну учётную запись и пароль

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

[В начало]

Организация централизованной обратной связи с пользователями и уменьшение трудозатрат на сопровождение

Каково бы ни было устройство защиты ваших приложений, пользователь должен знать, куда обратиться в случае утери пароля или иных проблем, так или иначе касающихся политики учётных записей. Наличие соответствующих пунктов в справочной системе приложений, где указана контактная информация и описаны процедуры разрешения проблем (получение учётной записи для нового сотрудника, восстановление пароля, смена привилегий в связи со сменой должности сотрудника и т.д.), может существенно сэкономить время пользователям и системным администраторам. Подробная документация и своевременные комментарии оставят у пользователя благоприятное впечатление о ваших разработках. Любое начинание, пусть даже такое как ограничение пользователей в правах, должно сопровождаться аргументированными доводами.

[В начало]

Устройство системы безопасности

Таким образом, мы приходим к организационной схеме, изображённой на рис.1. База общей системы безопасности содержит тот самый абстрактный уровень, который позволяет свести к минимуму повторяемость кода. Что может быть вынесено на этот уровень:

  • добавление, удаление, изменение учётных записей;

  • добавление, удаление, изменение групп;

  • присвоение прав группам и пользователям;

  • контроль над подключениями;

  • фиксирование событий в логе;

  • фиксирование ошибок клиентских частей в логе;

  • централизованное управление обновлением клиентских частей приложений;

  • контроль версий клиентских частей приложений.

Представленная функциональность должна быть доступна через Административную утилиту.
Обратите внимание, что приложения взаимодействуют с базой системы безопасности посредством своих БД, а не через клиентские части. Это избавит нас от многих проблем, если в будущем потребуется модифицировать систему безопасности.


Рис.1

Давайте теперь перейдём к непосредственному проектированию.

[В начало]

Единая политика учётных записей

В первую очередь следует выработать принцип именования учётных записей и в последствие от него не отступать. Например, вот так:

    Пользователь: Маша Ведро
    Учётная запись: vedro_m
    Пароль: не менее 7 символов.

Не связывайте пароль с личной информацией о пользователе (кличка любимого пуделя и дата рождения не подойдут). Маше также следует объяснить, что разглашать пароль можно, но излишняя болтливость будет стоить ей месячной зарплаты.

[В начало]

Создание учётной записи

Чуть выше, мы договорились, что наша система безопасности интегрирована с безопасностью MS SQL Server. Проще говоря, создание учётной записи в Административной утилите должно приводить к созданию логина на сервере. Есть два способа это сделать синхронный и асинхронный. Рассмотрим оба варианта.

[В начало]

Синхронный способ

  1. Создаём учётную запись в Административной утилите.

  2. Передаём введённые параметры (имя учётной записи и пароль) в процедуру sp_addlogin.

  3. При успешном создании логина добавляем информацию о пользователе в специальную таблицу в базе общей системы безопасности, где мы храним расширенные параметры пользователя (фамилия, филиал и пр.).

  4. Фиксируем факт создания учётной записи в логе.

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

[В начало]

Асинхронный способ

  1. Создаём учётную запись в Административной утилите.

  2. Сохраняем введённые параметры (имя учётной записи, пароль и пр.) в таблицу T и в таблицу общей системы безопасности, где мы храним информацию о пользователе.

  3. Через определённый промежуток времени на сервере срабатывает задание (job), которое берёт параметры из T и посредством процедуры sp_addlogin создаёт логин.

  4. Задание фиксирует факт создания в логе.

Асинхронный способ позволяет избежать недостатков предыдущего способа. Мы можем дать администратору права только на процедуру, добавляющую записи в T и не включать его в роль security admin. Зато задание, владелец (owner) которого обладает полномочиями security admin, на 3 шаге выполнит все необходимые действия.
Но асинхронный способ лишён интерактивности, так как невозможно сразу установить была ли добавлена учётная запись. Определённое беспокойство вызывает ещё и тот факт, что в T какое-то время должны содержаться пароли. Эта проблема решается следующим образом:

-- В таблицу T помещается не сам пароль, а хеш от него set @pwdhash = pwdencrypt(@password) -- Далее задание берёт хеш из таблицы T и передаёт его процедуре sp_addlogin EXEC sp_addlogin @login, @pwdhash, @encryptopt = 'skip_encryption'

[В начало]

Удаление учётной записи

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

  1. Удаляем учётную запись из Административной утилиты.

  2. Удалённая учётная запись помещается в таблицу Q.

  3. Через некоторый промежуток времени запускается задание (job).

  4. Задание выбирает все учётные записи, подлежащие удалению, и меняет им пароли на случайные.

  5. Для каждого логина выполняется следующее: задание вызывает команду kill для первого найденного процесса удаляемого логина и делает это до тех пор, пока ни одного процесса, запущенного под этим логином, не останется.

  6. Факт удаления фиксируется в логе.

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

[В начало]

Сессии

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

  1. Пользователь запускает приложение и вводит имя своей учётной записи и пароль.

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

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

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

Если ваши приложения рассчитаны на работу через службу терминалов или Citrix Metaframe, то для получения реального IP-адреса и хоста можно воспользоваться соответствующими API. Например, Citrix предоставляет Server SDK, куда входит документация и готовые примеры.
Даже когда Маша Ведро откроет терминальную сессию, а в ней ещё одну терминальную сессию, а уже затем вашу программу, то клиентская часть всё равно определит IP-адрес компьютера Маши, а не IP сервера терминалов.
Во избежание неоднозначности при идентификации пользователя следует запрещать разным сотрудникам входить в приложение под одной и той же учётной записью. При этом отдельно взятый сотрудник должен без проблем открывать и работать с другой программой под тем же самым логином.
Делается это примерно так:

  1. Пользователь авторизуется в приложении.

  2. Если для этой учётной записи уже существует сессия, то она принудительно закрывается (только для данного приложения!).

  3. Механизм регистрации создаёт новую сессию для пользователя, который авторизовался на шаге 1.

Описанный алгоритм быстро отучает весь отдел продаж работать под учётной записью Маши Ведро.
Мы обсудили только случай, когда пользователь корректно завершил работу с программой. Давайте теперь рассмотрим ситуацию, когда приложение, к примеру, "повисло" или пользователь закрыл терминальную сессию, не завершая сеанс работы с программой. Как сервер узнает, что сессия больше не нужна? Существует два способа с таймером и без.

Способ с таймером

  1. Пользователь авторизуется и получает код сессии.

  2. В приложении запускается сессионный таймер, который через определённые промежутки времени подтверждает, что клиентская часть работает.

  3. На сервере запущено задание (job), которое следит за тем, чтобы в таблице текущих сессий не оставалось неподтверждённых подключений. Если таковые обнаруживаются, задание их уничтожает.

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

Способ без таймера

  1. Пользователь авторизуется и подключается к серверу.

  2. Запускается процедура регистрации сессии, которая устанавливает для текущего процесса context _info равным уникальному коду сессии. Вместе с кодом сессии в таблицу сессий помещается spid и context_info.

  3. Пользователь работает и получает удовольствие от своей работы.

  4. На сервере запущено задание, которое с заданной периодичностью проверяет для каждой активной сессии наличие соответствующих процессов в sysprocesses. Если обнаруживается, что у незавершённой сессии нет процесса с таким spid и таким context_info, сессия уничтожается.

Теперь, вооружившись бесценной теорией, мы уже можем реализовать небольшую часть схемы данных. На рис.2 изображён вариант, который получился у нас.
Таблица Applications содержит параметры приложений, которые используют общую систему безопасности. Назначение полей этой таблицы будет дано ниже.
Таблица Users хранит служебную информацию о пользователе (ФИО, флаг "заблокирован", дату последнего подключения и количество подключений). Вы можете расширить эту таблицу любыми полями (например, филиал, телефон и пр.) Обратите внимание, что идентификатор пользователя object_id фактически содержится в таблице Objects. Objects объединяет в себе две сущности - пользователей и группы. Это сделано для того, чтобы членом группы можно было сделать не только пользователя, но и группу. Ведь с точки зрения наследования прав эти две сущности эквивалентны. О правах и группах мы поговорим чуть ниже.
Таблица Sessions предназначена для контроля пользовательских сессий. Здесь есть всё, о чём мы уже упоминали: дата и время начала сеанса работы, дата и время завершения сеанса, имя хоста, IP-адрес, а также ссылка на пользователя. CurrentSessions содержит только текущие подключения. Поле notify_date используется для уведомления сервера о том, что сессия всё ещё активна (Способ с таймером шаг 2), а status для принудительного завершения сеанса работы.
EventLog и Events нужны для фиксации событий. Позже мы обсудим их более подробно.


Рис.2

[В начало]

Группы пользователей

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

[В начало]

Права пользователей

Для того чтобы изменение прав в Административной утилите (например, путём включения пользователя в группу) как-то отражалось на полномочиях учётных записей в SQL Server'е, мы должны предусмотреть возможность сопоставления серверных ролей и ролей баз данных нашим объектам безопасности. Один из вариантов организации такой связи представлен на рис.3.
Каждое приложение имеет одну или несколько баз данных, что отражено на схеме в виде связей таблиц Applications, ApplicationDatabases и ServerDatabases. Таблица ServerDatabases содержит список баз данных сервера. В ApplicationsDatabases происходит сопоставление конкретных баз с приложениями.
Если в одном из приложений необходимо поддерживать свою таблицу пользователей, то для этих целей предусмотрены поля enable_synchronization, table_name, key_field_name и undelete_view_name. Зачем это может понадобиться? Например, в приложении есть документы, при создании которых помечается, кем они были сделаны. Таким образом, возникает необходимость в синхронизации таблицы пользователей, чтобы приложение могло оперировать только своей таблицей. Делается это асинхронным способом. Задание на сервере обрабатывает флаг enable_synchronization и, если он включён, синхронизирует данные между таблицей Users общей системы безопасности и таблицей table_name. Изменения вычисляются по полю, имя которого указано в key_field_name. В поле undelete_view_name прописывается имя представления (view), которое показывает можно ли удалять ту или иную учётную запись.
В таблице PermissObjects содержатся абстрактные объекты, доступ к которым должен быть разграничен. К таким объектам можно отнести, например, кнопку в приложении, отчёт "Продажи" или какое-нибудь действие вроде "подписать документ". Вы можете выстраивать объекты безопасности в иерархии, для этих целей используется поле parent_id. Иерархия даёт большую гибкость, так как на практике все объекты приложений имеют похожую структуру (например, "Главная форма" имеет подчинённые объекты "Пипка 1" и "Пипка 2").
Таблица Databases сопоставляет объекты безопасности и базы данных, а таблицы DbRoles и ServerRoles описывают соответственно роли БД и серверные роли, в которые будет включён логин, когда он получит права на эти абстрактные объекты.


Рис.3

На рис.4 приведены уже ставшие родными таблицы Users и Objects. Как несложно догадаться Groups содержит список групп общей системы безопасности. Флаг is_built_in говорит о том, что данная группа является встроенной (такую группу нельзя удалить), а at_least_one_member, что в данной группе должна оставаться хотя бы одна учётная запись.
Таблица Membership определяет иерархические связи между группами и учётными записями. В группы могут быть включены не только учётные записи, но и другие группы. Число вложений не ограничено, но, по понятным причинам, циклические вложения запрещены.
При изменении членства в группах возможны две ситуации:

  1. В Административной утилите в группу включается учётная запись.

  2. Object_id, соответствующий этой учётной записи, помещается в таблицу ObjectChanges.

  3. Задание (job) берёт из ObjectChanges все учётные записи, которые накопились там со времени последнего запуска и запоминает последний id (max_id).

  4. Задание исключает полученные учётные записи из всех ролей.

  5. Задание собирает явные и неявные права на каждую учётную запись и включает их в соответствующие роли.

  6. В случае успешного применения прав из ObjectChanges удаляются строки, id которых меньше или равен max_id.

Второй случай.

  1. В Административной утилите в группу включается другая группа.

  2. В ObjectChanges помещаются значения object_id всех учётных записей, явно или неявно входящих во включаемую группу.

  3. Задание (job) берёт из ObjectChanges все учётные записи, которые накопились там со времени последнего запуска и запоминает последний id (max_id).

  4. Задание исключает полученные учётные записи из всех ролей.

  5. Задание собирает явные и неявные права на каждую учётную запись и включает их в соответствующие роли (рекурсивно разворачивает всю иерархию групп).

  6. В случае успешного применения прав из ObjectChanges удаляются строки, id которых меньше или равен max_id.

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


Рис.4

[В начало]

Лог событий в приложениях

В логах удобно использовать категории событий, особенно когда число событий довольно большое. Чтобы обеспечить приемлемую гибкость, каждое приложение должно иметь собственный набор категорий. На рис.5 таблица EventCategories как раз выполняет эту функцию.
Полезно также вводить расширения для определённого типа события. Объясним сказанное на примере. Допустим, у вас есть событие "Открыт отчёт продажи". Это событие не требует никаких дополнений и вполне можно обойтись текстовым комментарием. Дальше вы определили ещё одно событие "Открыт документ Расходная накладная". Если вы в будущем предполагаете вести какую-нибудь аналитику, то текстового комментария вам будет недостаточно. Как минимум, вам потребуется код и номер открытого документа.
Мы предлагаем выходить из ситуации так, как изображено на схеме. То есть каждому типу событий (EventObjectTypesList) сопоставляются в отношении один-ко-многим аналитические признаки (EventObjectTypes). Все возможные события содержатся в таблице Events. Когда событие возникает, оно помещается в EventLog, а значения аналитических признаков в EventLogExt. Таким образом, "Открыт документ Расходная накладная" сохраняется в EventLog, а код документа и его номер в EventLogExt.
Инициатора события можно определить по session_id в таблице EventLog.


Рис.5

[В начало]

Лог ошибок клиентских частей

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


Рис.6

Учтите, что ошибки иногда возникают даже до того, как клиентская часть подключится к серверу. Следовательно, приложение не всегда может отправить эту информацию в систему безопасности.
Мы в своих программах используем следующий метод:

  1. При возникновении исключения (exception) информация о нём помещается в массив.

  2. В приложении запущен поток (ERROR_SPOOL), который проверяет состояние подключения к серверу и, если проблем с соединением нет, отправляет накопившиеся сообщения об ошибках в систему безопасности. Вне зависимости от состояния подключения, информация дублируется в локальном файле на компьютере пользователя.

  3. Принятые системой безопасности исключения сохраняются в логе.

[В начало]

Автоматическое обновление клиентских частей и контроль версий

Самый простой и, как нам кажется, самый надёжный способ обновления приложений может выглядеть следующим образом.

  1. Вместе с клиентской частью приложения поставляется исполняемый файл. Назовём его downloader.exe

  2. При запуске приложение проверяет в общей системе безопасности наличие нового релиза клиентской части. Если таковой имеется, программа запрашивает систему безопасности на предмет того, не требуется ли заодно обновить и файл downloader.exe. Если это необходимо, приложение выкачивает downloader.exe

  3. Далее управление передаётся downloader.exe, который корректно закрывает приложение, выкачивает релиз и снова запускает клиентскую часть.

Представим теперь, что на предприятии имеется несколько филиалов, 2000 одарённых сотрудников и на рабочих местах установлены ваши приложения. Нетрудно вообразить, что произойдёт, если вечером вы выложили новый релиз, а на следующее утро все 2000 одарённых начнут выкачивать с центрального сервера актуальную версию. Ситуация, конечно, неприятная, но разрешимая. На рис.7 изображён один из возможных вариантов.


Рис.7

После выхода релиза разработчики выкладывают его на свой сервер. На шаге 1 любыми доступными средствами обновление тиражируется на файловые сервера каждого из филиалов. Пользователи, пришедшие с утра на работу, запускают приложение и успешно обновляются на шаге 2. Каким же образом программа узнает, с какого файлового сервера выкачивать релиз? Подсказкой может служить IP-адрес компьютера пользователя. Как правило, на филиале имеется несколько подсетей, а все IP-адреса одной подсети обычно имеют три одинаковые байта. Таким образом, в системе безопасности мы можем сопоставить эти три байта файловому серверу филиала.
Описанный метод может найти отражение, например, в схеме данных на рис. 8.
В таблице ApplicationVersions содержатся параметры всех релизов приложения. Флаг allowed позволяет, при необходимости, заблокировать релиз (это иногда требуется в случае, если релиз перестал быть совместимым с БД приложения или в нём была найдена ошибка, которая приводит к сокрушительным последствиям).
В ApplicationUpdateContainer хранятся пути к хранилищам обновлений, расположенных на файловых серверах филиалов, а в ApplicationContainers происходит сопоставление трёх байт IP-адреса c этими путями. Таблица Applications имеет также поле container_folder - это наименование корневой папки хранилища.


Рис.8

[В начало]

Заключение

Совсем не обязательно слепо следовать нашим рекомендациям. Мы продемонстрировали только общие принципы. То, как эти принципы могут быть воплощены в жизнь, зависит от требований, которые предъявляются системе безопасности на вашем предприятии.

[В начало]

Авторы: Николай Денищенко и Сергей Гавриленко  2005г.

Rambler's Top100 Рейтинг@Mail.ru  Administrator: Обратная связь 
Copyright: SQL.Ru 2000-2013