Доступ к ресурсам

66

В операционной системе ресурсы, подобные файлам и ключам системного реестра, а также дескрипторам именованных каналов, защищаются за счет применения так называемого списка контроля доступа (Access Control List — ACL). На рисунке схематично показано, как именно это делается:

Схема защиты ресурсов

С каждым ресурсом ассоциируется дескриптор безопасности (security descriptor). В этом дескрипторе содержится информация о владельце ресурса и ссылки на два списка контроля доступа: дискреционный (Discretionary Access Control List — DACL) и системный (System Access Control List — SACL). Список DACL отвечает за предоставление информации о том, кому должно быть разрешено, а кому — запрещено получать доступ к ресурсу, а список SACL — за предоставление информации о правилах аудита, которые должны применяться для регистрации связанных с безопасностью событий.

В каждом из этих списков ACL содержится свой перечень так называемых записей контроля доступа (Access-Control Entries — АСЕ). Каждая запись АСЕ включает в себя сведения о типе доступа, идентификаторе безопасности и правах. В случае DCL тип доступа в записи ACL может иметь вид либо разрешения (Allow), либо запрещения доступа (Deny). К числу некoторых прав, которые могут устанавливаться и извлекаться с файлами, относятся права на создание, чтение, запись, удаление, модификацию, изменение полномочий и передачу прав владения.

Классы для чтения и изменения списков контроля доступа находятся в пространстве имен System.Security.AccessControl. В следующем примере показано, как читать список контроля доступа из файла.

В классе FileStream определен метод GetAccessControl() , который возвращает объект FileSecurity. Класс FileSecurity в .NET представляет дескриптор безопасности для файлов. Он унаследован от таких базовых классов, как ObjectSecurity, CommonObjectSecurity, NativeObjectSecurity и FileSystemSecurity.

К числу других классов, которые могут применяться для представления дескриптора безопасности, относятся CryptoKeySecurity, EventWaitHandleSecurity, MutexSecurit, RegistrySecurity, SemaphoreSecurity, PipeSecurity и ActiveDirectorySecurity.

Все эти объекты могут защищаться с использованием списка контроля доступа. В общих чертах это сводится просто к определению в соответствующем классе .NET метода GetAccessControl, который возвращает соответствующий класс безопасности; например, метод Mutex.GetAccessControl() будет возвращать класс MutexSecurity, а метод PipeStream.GetAccessControl() — класс PipeSecurity.

Класс FileSecurity имеет методы для чтения и изменения списков DACL и SACL. Метод GetAccessRules() возвращает DACL в виде класса AuthorizationRuleCollection, а метод GetAuditRules() позволяет получать доступ к SACL.

С помощью метода GetAccessRules() можно указывать, что должны использоваться унаследованные правила доступа и касающиеся не только доступа правила, определяемые с объектом. В последнем параметре необходимо указывать тип идентификатора безопасности, который должен возвращаться. Этот тип должен быть унаследован от базового класса IdentityReference. Возможными типами являются NTAccount и SecurityIdentifier. Оба эти класса представляют либо пользователей, либо группы пользователей: класс NTAccount предусматривает поиск объекта безопасности по его имени, а класс SecurityIdentifier — по уникальному идентификатору безопасности.

Возвращаемый класс AuthorizationRuleCollection содержит объекты AuthorizationRule, которые являются в .NET представлением записей АСЕ.

В предлагаемом здесь примере получается доступ к файлу, а это значит, что AuthorizationRule может приводиться к типу FileSystemAccessRule. Для записей АСЕ остальных ресурсов в .NET предусмотрены другие представления, такие как MutexAccessRule и PipeAccessRule. В случае класса FileSystemAccessRule информацию о АСЕ возвращают свойства AccessControlType, FileSystemRights и IdentityReference.

using System;
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;

namespace SecurityCSharp
{
    class Program
    {
        static void Main(string[] args)
        {
            string filename = null;
            if (args.Length == 0)
                return;

            filename = args[0];

            FileStream stream = File.Open(filename, FileMode.Open);
            FileSecurity securityDescriptor = stream.GetAccessControl();
            AuthorizationRuleCollection rules =
                  securityDescriptor.GetAccessRules(true, true,
                        typeof(NTAccount));

            foreach (AuthorizationRule rule in rules)
            {
                var fileRule = rule as FileSystemAccessRule;
                Console.WriteLine("Access type: {0}", fileRule.AccessControlType);
                Console.WriteLine("Rights: {0}", fileRule.FileSystemRights);
                Console.WriteLine("Identity: {0}",
                      fileRule.IdentityReference.Value);
                Console.WriteLine();
            }
        }
    }
}

Запустив это приложение и передав имя файла, можно увидеть, какая информация содержится в списке контроля доступа этого файла. Согласно показанному здесь выводу, полный доступ к данному файлу имеется только у администраторов (Administrators) и системы (System), права на внесение изменений — только у аутентифицированных пользователей (Authenticated Users), а права на чтение и выполнение — у всех пользователей, которые являются членами группы Users (Пользователи):

Чтение прав на доступ к файлам

Установка прав на доступ производится во многом подобно их чтению. Для установки прав доступа многие классы ресурсов, которые могут защищаться, предлагают методы SetAccessControl() и ModifyAccessControl().

Пройди тесты
Лучший чат для C# программистов