
- •Лабораторна робота №5. Функції роботи з дескрипторами безпеки. Теоретична частина
- •1. Створення локальної групи
- •2. Отримання інформації про локальну групу
- •3. Перерахування локальних груп
- •4. Зміна інформації про локальну групу
- •1002 — Використовується структура типу localgroup_info_1002.
- •5. Додавання членів локальної групи
- •6. Видалення членів локальної групи
- •Практичне завдання:
5. Додавання членів локальної групи
Для додавання нових членів в локальну групу використовується функція NetLocalGroupAddMembers, Яка має наступний прототип:
NET_API_STATUS NetLocalGroupAddMembers(
LPCWSTR servername, // ім’я сервера
LPCWSTR groupname, // ім’я групи
DWORD level, // рівень інформації
LPBYTE buf, // буфер з інформацією
DWORD totalentries // кількість членів, що включаються
);
У разі успішного завершення функція NetLocalGroupAddMembers повертає значення NERR_success, а у разі невдачі можливі наступні коди завершення:
NERR_GroupNotFound — група не знайдена;
error_no_such_member — не існує членів, які додаються в групу;
error_member_in_alias — деякі члени вже є членами групи;
error_invalid_member — неправильний тип облікового запису члена, що додається.
Параметри функції NetLocalGroupAddMembers мають наступне призначення.
Параметр servername повинен указувати на рядок з ім’ям сервера, на якому виконуватиметься функція. Цей рядок повинен мати кодування Unicode і починатися з символів \\. Якщо функція повинна виконуватися на локальному комп’ютері, то цей параметр повинен мати значення null.
Параметр groupname повинен указувати на рядок з ім’ям групи, в яку додаються нові члени. Цей рядок повинен мати кодування Unicode.
Параметр level указує тип структури, яка містить інформацію про членів, що додаються в групу. Цей параметр може приймати одне з наступних значень:
0 — використовується структура типу localgroup_members_info_0;
3 — використовується структура типу localgroup_members_info_3.
Параметр buf повинен указувати на буфер з інформацією про членів, які додаються в локальну групу. Інформація повинна зберігатися в структурах, тип яких заданий параметром level.
Параметр totaientries повинен містити розмірність масиву структур, на який указує параметр buf.
Тепер приведемо типи структур, на які може указувати параметр level.
Структура localgroup_members_info_o має наступний тип:
typedef struct _LOCALGROUP_MEMBERS_INFO_0 {
PSID lgrmi0_sid; // покажчик на ідентифікатор безпеки
} LOCALGROUP_MEMBERS_INFO_0, * PLOCALGROUP_MEMBERS_INFO_0,
*LPLOCALGROUP_MEMBERS_INFO_0 ;
У єдиному полі igrmi0_sid цієї структури зберігається покажчик на ідентифікатор безпеки члена, який додається в локальну групу.
Структура localgroup_members_info_3 має наступне визначення:
typedef struct _LOCALGROUP_MEMBERS_INFO_3 {
LPWSTR lgrmi3_domainandname; // покажчик на ім’я облікового запису
} LOCALGROUP_MEMBERS_INFO_3 , * PLOCALGROUP_MEMBERS_INFO_3 ,
*LPLOCALGROUP_MEMBERS_INFO_3 ;
У єдиному полі igrmi3_domainandname цієї структури зберігається покажчик на рядок з ім’ям облікового запису, який стає членом групи. Цей рядок повинен мати кодування Unicode, а ім’я повинне бути задане у форматі: <ім’я_домену>\ <ім’я_облікового_запису>.
Тепер перейдемо до прикладів. Спочатку, в лістингу 5, приведемо програму, яка додає члена локальної групи по його імені, використовуючи для цього функцію NetLocalGroupSetInfо.
Лістинг 5. Додавання члена локальної групи по імені
#include <stdio.h>
#include <windows.h>
#include <lm.h>
#pragma comment( lib, "netapi32.lib" ) // підключаємо мережеву бібліотеку
int main()
{
wchar_t server_name[256] = L"\\\\"; // ім’я сервера
wchar_t group_name[GNLEN]; // ім’я локальної групи
wchar_t user_name[UNLEN]; // ім'я користувача
LOCALGROUP_MEMBERS_INFO_3 member_info; // інформація про члена групи
NET_API_STATUS ret_status; // код повернення з функції
printf("Input server name: ");
// формуємо ім’я сервера
wscanf(L"%s", server_name + wcslen(server_name));
printf("Input a local group name: ");
wscanf(L"%s", group_name); // вводимо ім’я групи
printf("Input a domain name: ");
wscanf(L"%s", user_name); // вводимо ім’я домену
wcscat(user_name, L"\\"); // приєднуємо символ '\'
printf("Input а user name: ");
// вводимо ім'я користувача
wscanf(L"%s", user_name + wcslen(user_name));
// встановлюємо інформацію про користувача
member_info.lgrmi3_domainandname = user_name;
// додаємо користувача в локальну групу
ret_status = NetLocalGroupAddMembers(
server_name, // ім’я сервера
group_name, // ім’я групи
3, // рівень інформації
(LPBYTE)&member_info, // ім'я облікового запису
1); // додаємо одного члена групи
if (ret_status != NERR_Success)
{
printf("Ret status: %d\n", ret_status);
printf("Net local group add members failed.\n");
return ret_status;
}
printf("The member is added.\n");
return 0;
}
Тепер, в лістингу 6, приведемо програму, яка додає члена локальної групи по його ідентифікатору безпеки, використовуючи для цього функцію NetLocaiGroupSetmfo. Відмітимо, що в цій програмі ідентифікатор безпеки облікового запису визначається за допомогою функції LookupAccountName.
Лістинг 6. Додавання члена локальної групи по дескриптору безпеки
#ifndef UNICODE
#define UNICODE
#endif
#include <stdio.h>
#include <windows.h>
#include <lm.h>
#pragma comment( lib, "netapi32.lib" ) // підключаємо мережеву бібліотеку
int main()
{
wchar_t server_name[256] = L"\\\\"; // ім’я сервера
wchar_t group_name[GNLEN]; // ім’я локальної групи
wchar_t user_name[UNLEN]; // ім'я користувача
LOCALGROUP_MEMBERS_INFO_0 member_info; // інформація про члена групи
NET_API_STATUS ret_status; // код повернення з функції
DWORD dwErrCode;
DWORD dwLengthOfSID = 0; // довжина SID
DWORD dwLengthOfDomainName = 0; // довжина імені домену
PSID lpSID = NULL; // вказівник на SID
LPTSTR lpDomainName = NULL; // вказівник на ім’я домену
SID_NAME_USE type_of_SID; // тип облікового запису
printf("Input server name: ");
// формируем имя сервера
wscanf(L"%s", server_name + wcslen(server_name));
printf("Input a local group name: ");
wscanf(L"%s", group_name); // вводимо ім’я групи
printf("Input a user name: ");
wscanf(L"%s", user_name); // вводимо ім'я користувача
// визначаємо довжину SID користувача
LookupAccountName(
NULL, // шукаємо ім'я на
локальному комп'ютері user_name, // ім'я
користувача
NULL, // визначуваний довжину SID
&dwLengthOfSID, // довжина SID
NULL, // визначуваний ім'я домена
&dwLengthOfDomainName, // довжина імені домена
&type_of_SID); // тип облікового запису
// перевіряємо, чи повернула функція довжину SID
if (dwLengthOfSID == 0)
{
dwErrCode = GetLastError();
printf("Lookup account name failed.\n");
printf("Error code: %d\n", dwErrCode);
return dwErrCode;
}
// розподіляємо пам'ять для SID і імені домена
lpSID = (PSID) new char[dwLengthOfSID];
lpDomainName = (LPTSTR) new char[dwLengthOfDomainName];
// визначаємо SID і ім'я домена користувача
if(!LookupAccountName(
NULL, // шукаємо ім'я на локальному комп'ютері
user_name, // ім'я користувача
lpSID, // визначуваний довжину SID
&dwLengthOfSID, // довжина SID
lpDomainName, // визначуваний ім'я домена
&dwLengthOfDomainName, // довжина імені домена
&type_of_SID)) // тип облікового запису
{
dwErrCode = GetLastError();
printf("Lookup account name failed.\n");
printf("Error code: %d\n", dwErrCode);
return dwErrCode;
}
// роздруковуємо ім'я домена
wprintf(L"%s\n", lpDomainName);
// встановлюємо SID в інформацію про члена групи
member_info.lgrmi0_sid = lpSID;
// додаємо користувача в локальну групу
ret_status = NetLocalGroupAddMembers(
server_name, // ім'я сервера
group_name, // ім'я групи
0, // рівень інформації
(LPBYTE)&member_info, // інформація про SID
1); // додаємо одного члена групи
if (ret_status != NERR_Success)
{
printf("Net local group add members failed.\n");
return ret_status;
}
printf("The member is added.\n");
return 0;
}