
- •Лабораторна робота №4. Функції роботи з ідентифікаторами безпеки. Теоретична частина
- •1. Основні поняття
- •2. Структура ідентифікатора безпеки
- •3. Створення ідентифікатора безпеки
- •4. Визначення облікового запису по ідентифікатору безпеки
- •5. Визначення ідентифікатора безпеки по імені облікового запису
- •6. Отримання характеристик ідентифікатора безпеки
- •Практичне завдання:
4. Визначення облікового запису по ідентифікатору безпеки
Для визначення імені облікового запису по її ідентифікатору безпеки використовується функція LookupAccountsid, яка має наступний прототип, :
BOOL LookupAccountsid(
LPCSTR IpSystemName, // ім'я комп'ютера
PSID pSid, // покажчик на SID
LPSTR lpName, // ім'я облікового запису
LPDWORD cbName, // довжина імені облікового запису
LPSTR ReferencedDomainName, // ім'я домена
LPDWORD cbReferencedDomainName, // довжина імені домена
PSID_NAME_USE peUse // тип ідентифікатора безпеки
);
Функція LookupAccountsid окрім імені облікового запису повертає також і ім'я домена, в якому знайдений обліковий запис. Пошук облікового запису виконується в наступному порядку. Спочатку перевіряються зумовлені загальновідомі облікові записи. Потім перевіряються облікові записи, зареєстровані на локальному комп'ютері. Після цього перевіряються облікові записи, зареєстровані в первинному домені. І, в останню чергу, перевіряються облікові записи з довірчих доменів.
Параметри функції LookupAccountsid мають наступне призначення.
Параметр lpSystemName повинен вказувати на рядок з ім'ям комп'ютера, на якому шукається ім'я облікового запису. Якщо цей параметр має значення null, то обліковий запис шукається на локальному комп'ютері.
Параметр psid повинен вказувати на структуру типу sid, яка містить ідентифікатор безпеки облікового запису, ім'я якого треба визначити.
Параметр lpName повинен вказувати на буфер, в який функція LookupAccountsid запише ім'я облікового запису, відповідного ідентифікатору безпеки, заданому параметром psid.
Параметр cbName повинен вказувати на змінну типу dword, яка містить довжину буфера для імені облікового запису, на який вказує параметр lpName. Якщо довжина буфера недостатня, то виконання функції закінчиться невдачею, а в подвійне слово, на яке вказує параметр cbName, функція запише необхідну довжину буфера.
Параметр ReferencedDomainName повинен містити адресу буфера, в який функція запише ім'я домена, в якому знайдений обліковий запис. Якщо встановити значення цього параметра в null, to функція запише в подвійне слово, на яке вказує Параметр cbReferencedDomainName, необхідну довжину буфера для імені домена. Відмітимо, що рядок з ім'ям домена має кодування Unicode.
Параметр peUse повинен вказувати на змінну типу перерахування sid_name_use, в яку функція запише тип облікового запису. Типи облікових записів визначаються як значення цього перерахування, яке визначене таким чином, :
typedef enum _SID_NAME_USE {
SidTypeUser = 1, // SID користувача
SidTypeGroup, // SID групи
SidTypeDomain, // SID домена
SidTypeAlias, // SID синоніма
SidTypeWellKnownGroup, // SID зумовленої групи
SidTypeDeletedAccount, // SID видаленого облікового запису
SidTypelnvalid, // недійсний SID
SidTypeUnknown, // невідомий SID
SidTypeComputer // SID комп'ютера
} SID_NAME_USE, *PSID_NAME_USE;
У лістингу 2 приведена програма, яка визначає ім'я облікового запису і ім'я домена по ідентифікатору безпеки облікового запису, використовуючи Для цього фунКЦИЮ LookupAccountSid.
Лістинг 2. Визначення імені облікового запису по ідентифікатору безпеки
##ifndef UNICODE
##define UNICODE
##endif
##include <stdio.h>
##include <windows.h>
##include <lm.h>
int main()
{
wchar_t user_name[UNLEN]; // ім'я користувача
HANDLE hProcess; // дескриптор процесу
HANDLE hTokenHandle; // дескриптор маркера доступу
DWORD dwErrCode; // код повернення
TOKEN_OWNER *lpTokenOwner = NULL; // буфер для інформації
DWORD dwLength= 0; // довжина буфера
DWORD dwLengthOfUserName = UNLEN; // довжина імені облікового запису
DWORD dwLengthOfDomainName = 0; // довжина імені домена
LPTSTR lpDomainName = NULL; // покажчик на ім'я домена
SID_NAME_USE type_of_SID; // тип облікового запису
// // отримуємо маркер доступу процесу
hProcess = GetCurrentProcess();
// // отримати маркер доступу процесу
if (!OpenProcessToken(
hProcess, // дескриптор процесу
TOKEN_QUERY, // запит інформації з маркера
& &hTokenHandle)) // дескриптор маркера
{
dwErrCode = GetLastError();
printf( "Open process token failed: %u\n", dwErrCode);
return dwErrCode;
}
// // визначаємо довжину SID
if (!GetTokenInformation(
hTokenHandle, // дескриптор маркера доступу
TokenOwner, // отримуємо SID власника
NULL, // потрібна довжина буфера
0, // 0, // поки довжина дорівнює 0
& &dwLength)) // для довжини буфера
{
dwErrCode = GetLastError();
if (dwErrCode == ERROR_INSUFFICIENT_BUFFER)
// // захоплюємо пам'ять під SID
lpTokenOwner = (TOKEN_OWNER*) new char[dwLength];
else
{
// // виходимо з програми
printf( "Get token information for length failed: %u\n",
dwErrCode);
return dwErrCode;
}
}
// // визначаємо ім'я власника
if (!GetTokenInformation(
hTokenHandle, // дескриптор маркера доступу
TokenOwner, // потрібний SID маркера доступу
lpTokenOwner, // адреса буфера для SID
dwLength, // довжина буфера
& &dwLength)) // довжина буфера
{
dwErrCode = GetLastError();
printf( "Get token information failed: %u\n", dwErrCode);
return dwErrCode;
}
// // визначаємо довжину імені домена
if(!LookupAccountSid(
NULL, // шукаємо на локальному комп'ютері
lpTokenOwner ->Owner, // покажчик на SID
user_name, // ім'я користувача
& &dwLengthOfUserName, // довжина імені користувача
lpDomainName, // визначаємо ім'я домена
& &dwLengthOfDomainName, // довжина імені домена
& &type_of_SID)) // тип облікового запису
{
dwErrCode = GetLastError();
if (dwErrCode == ERROR_INSUFFICIENT_BUFFER)
// // розподіляємо пам'ять під ім'я домена
lpDomainName = (LPTSTR) new wchar_t[dwLengthOfDomainName];
else
{
printf("Lookup account SID for length failed.\n");
printf("Error code: %d\n", dwErrCode);
return dwErrCode;
}
}
// // визначаємо ім'я облікового запису по SID
if(!LookupAccountSid(
NULL, // шукаємо на локальному комп'ютері
lpTokenOwner ->Owner, // покажчик на SID
user_name, // ім'я користувача
& &dwLengthOfUserName, // довжина імені користувача
lpDomainName, // визначаємо ім'я домена
& &dwLengthOfDomainName, // довжина імені домена
& &type_of_SID)) // тип облікового запису
{
dwErrCode = GetLastError();
printf("Lookup account SID failed.\n");
printf("Error code: %d\n", dwErrCode);
return dwErrCode;
}
wprintf(L" User name: %s\n", user_name);
wprintf(L" Domain name: %s\n", lpDomainName);
// // звільняємо пам'ять
delete[] lpDomainName;
delete[] lpTokenOwner;
return 0;
}