Выбрать главу

  if (hNp == INVALID_HANDLE_VALUE) ReportError(_T("Невозможно открыть именованный канал."), 1, TRUE);

 }

 …

Защита объектов ядра и приватных объектов

Многие объекты, такие как процессы, потоки или мьютексы, являются объектами ядра (kernel objects). Для получения и установки дескрипторов безопасности ядра используются функции GetKernelObjectsSecurity и SetKernelObjectsSecurity, аналогичные функциям защиты файлов, описанным в настоящей главе. Однако при этом вы должны знать, какие права доступа соответствуют данному объекту; в следующем разделе показано, как определить эти права. 

Существует также возможность связывания дескрипторов безопасности с приватными, сгенерированными программой объектами, такими как объекты Windows Sockets или патентованные базы данных. Соответствующими функциями являются GetPrivateObjectSecurity и SetPrivateObjectSecurity. Ответственность за принудительное введение определенных прав доступа к таким объектам несет программист, который для изменения дескрипторов безопасности должен использовать функции CreatePrivateObjectSecurity и DestroyPrivateObjectSecurity.

Значения маски АСЕ

Модели "пользователь, группа, прочие", которую реализует функция InitUnixSA в большинстве случаев будет вполне достаточно, хотя с использованием тех же базовых методов могут реализовываться и другие модели.

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

• Прочитайте документацию с описанием функции открытия интересующего вас объекта. Флаги доступа имеют те же значения, что и флаги, используемые в маске АСЕ. Так, функция OpenMutex использует флаги MUTEX_ALL_ACCESS и SYNCHRONIZE (второй из указанных флагов требуется для любого объекта, который может использоваться с функциями WaitForSingleObject или WaitForMultipleObjects). Другие объекты, например процессы, имеют множество других дополнительных флагов доступа.

• Полезная в этом отношении информация может содержаться также в документации по функциям "создания" объектов.

• Проверьте, не содержатся ли флаги, применимые к интересующему вас объекту, в заголовочных файлах WINNT.H и WINBASE.Н.

Пример: защита процесса и его потоков

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

Так, значение PROCESS_TERMINATE параметра доступа разрешает процессу (а фактически — потока внутри процесса) использовать дескриптор процесса в функции TerminateProcess для завершения процесса.

Доступ на уровне PROCESS_QUERY_INFORMATION разрешает использование дескриптора процесса при вызове функций GetExitCodeProcess или GetPriorityClass, тогда как уровень доступа PROCESS_ALL_ACCESS разрешает любой доступ, а доступ SYNCHRONIZE требуется для выполнения функций ожидания завершения процесса. 

Чтобы проиллюстрировать эти идеи, на основе программы JobShell, рассмотренной в главе 6, была разработана программа JobShellSecure.c, которая разрешает доступ к управляемому процессу только его владельцу (или администратору). Эта программа находится на Web-сайте книги.

Обзор дополнительных возможностей защиты объектов

О средствах безопасности Windows можно было сказать намного больше, но настоящая глава является лишь введением в эту тему, показывая, как организовать защиту объектов Windows, используя API системы безопасности. В последующих разделах кратко рассмотрены дополнительные вопросы, относящиеся к этой тематике.

Удаление элементов АСЕ

Функция DeleteAce удаляет АСЕ, определяемый с помощью индекса аналогично тому, как это делается в случае функции GetAce.

Абсолютные и самоопределяющиеся относительные дескрипторы безопасности

Программа 15.5, позволяющая изменять ACL, удобна тем, что просто заменяет один дескриптор безопасности (SD) другим. В то же время, при замене существующих SD следует проявлять осторожность, поскольку они бывают двух типов: абсолютные (absolute) и самоопределяющиеся относительные (self-relative). Внутреннее устройство этих структур данных для наших целей не имеет значения, однако вы должны понимать, в чем состоит различие между ними, и как переходить от одного из них к другому.

• В процессе создания SD они являются абсолютными, и входящие в них указатели указывают на различные структуры, находящиеся в памяти. По сути, функция InitializeSecurityDescriptor создает абсолютный SD.