Поделиться через


Идентификатор безопасности

Windows использует идентификатор безопасности (SID) в качестве окончательного значения для различения сущностей безопасности друг от друга. Например, уникальный идентификатор безопасности назначается каждой новой учетной записи, созданной для отдельных пользователей в системе. Для файловой системы используется только этот идентификатор безопасности.

На следующем рисунке показана структура идентификатора безопасности.

схема, иллюстрирующая структуру идентификатора безопасности.

Помимо уникальных идентификаторов SID система Windows определяет набор известных идентификаторов. Например, локальный администратор — это известный идентификатор безопасности.

Windows предоставляет механизм в ядре для преобразования между идентификаторами SID и именами пользователей в среде ядра. Эти вызовы функций доступны из драйвера ksecd , который реализует эти функции с помощью вспомогательных служб пользовательского режима. Соответственно, их использование в файловых системах должно соответствовать обычным правилам обмена данными со службами пользовательского режима. Эти вызовы нельзя использовать во время разбиения на страницах ввода-вывода файла.

Некоторые из этих функций:

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

  • SecMakeSPNEx — это дополненная версия SecMakeSPN , представленная в Windows XP.

  • SecMakeSPNEx2 — это дополненная версия SecMakeSPNEx , которая доступна начиная с Windows Vista и Windows Server 2008.

  • SecLookupAccountSid возвращает имя учетной записи для указанного идентификатора безопасности.

  • SecLookupAccountName извлекает идентификатор безопасности для указанного имени учетной записи.

  • SecLookupWellKnownSid возвращает правильный идентификатор безопасности для указанного известного типа SID. Эта функция доступна в Windows Server 2003 и более поздних версиях.

Кроме того, любой драйвер ядра может создать идентификатор безопасности с помощью следующих стандартных подпрограмм библиотеки среды выполнения:

  • RtlInitializeSid инициализирует буфер для нового идентификатора безопасности.

  • RtlLengthSid определяет размер идентификатора безопасности, хранящегося в заданном буфере.

  • RtlValidSid определяет, является ли заданный буфер SID допустимым форматированным буфером.

RtlLengthSid и RtlValidSid предполагают, что 8-байтовый фиксированный заголовок для sid присутствует. Поэтому драйвер должен проверить эту минимальную длину заголовка SID перед вызовом этих функций.

Хотя существует несколько других функций RTL, этот список предоставляет основные функции, необходимые при создании идентификатора безопасности.

В следующем примере кода показано, как создать идентификатор безопасности для сущности "локальная система". Более простая функция SecLookupWellKnownSid , представленная в Windows Server 2003, также может использоваться.

{
    //
    // temporary stack-based storage for an SID
    //
    UCHAR sidBuffer[128];
    PISID localSid = (PISID) sidBuffer;
    SID_IDENTIFIER_AUTHORITY localSidAuthority = 
        SECURITY_NT_AUTHORITY;

    //
    // build the local system SID
    //
    RtlZeroMemory(sidBuffer, sizeof(sidBuffer));
 
    localSid->Revision = SID_REVISION;
    localSid->SubAuthorityCount = 1;
    localSid->IdentifierAuthority = localSidAuthority;
    localSid->SubAuthority[0] = SECURITY_LOCAL_SYSTEM_RID;
 
    //
    // make sure it is valid
    //
    if (!RtlValidSid(localSid)) {
        DbgPrint("no dice - SID is invalid\n");
        return(1);
    }
}

В следующем примере кода показано, как создать идентификатор безопасности с помощью функции SecLookupWellKnownSid для сущности локальной системы:

{
    UCHAR sidBuffer[128];
    PISID localSid = (PISID) sidBuffer;
    SIZE_T sidSize;
    status = SecLookupWellKnownSid(WinLocalSid,
                                   &localSid,
                                   sizeof(sidBuffer),
                                   &sidSize);

    if (!NT_SUCCESS(status)) {
      //
      // error handling
      //
    }
  }

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