Good day, it is necessary for a group of users, for example: administrators to prohibit the right to execute a file ... The GetLastError () function returns error 1337 - The data protection code has an invalid structure. The code is operational, but only for users ... It is for groups that the program does not work. Please help!
#include "stdafx.h" #ifndef UNICODE #define UNICODE #endif #include <windows.h> #include <iostream> #include <lm.h> #include <stdio.h> #include <string.h> #include <sddl.h> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { setlocale(LC_ALL, "RUSSIAN"); PACL pACL = NULL; ACL *lpNewDacl; DWORD dwRetCode; DWORD dwSidLength = 0; DWORD dwDaclLength = 0;//Длина в байтах буфера, на который указывает параметр pAcl DWORD dwLengthOfDomainName = 0;//размер буфера ReferencedDomainName SID_NAME_USE typeOfSid;//Указатель на SID_NAME_USE перечисляемого типа, который указывает тип учетной записи, который функция возвращает PSID lpSid = NULL;//Указатель на структуру SID, представляющий учетную запись пользователя или группы LPTSTR sid; LPTSTR lpDomainName = NULL;//Указатель на буфер, который получает имя домена, где находится имя учетной записи wchar_t wchUserName[UNLEN];//имя компа SECURITY_DESCRIPTOR sdAbsoluteSd;// Указатель на структуру SECURITY_DESCRIPTOR, которая инициализирует функцию PSID AdministratorsGroup;//указатель на SID структуру BOOL b;//получает результаты проверки CheckTokenMembership SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;//указатель на SID_IDENTIFIER_AUTHORITY структуру TCHAR filename[] = TEXT("d:\lol.dat"); PSID Sid; BOOL bRes = ConvertStringSidToSid(TEXT("S-1-5-32-544"), &Sid); Sid = (SID*) new char[12]; // ======= извлекаем идентификатор безопасности (SID) для учетной записи и имя домена, на котором была найдена учетная запись.============= /* printf("Введите пользователя: "); _getws_s(wchUserName); if (LookupAccountName(//Функция LookupAccountName принимает название системы и учетную запись в качестве входных данных. Он извлекает идентификатор безопасности (SID) для учетной записи и имя домена, на котором была найдена учетная запись. NULL,// lpSystemName указывают на системное имя. Для параметра lpSystemName часто используется значение NULL, обозначающее локальную систему. wchUserName,// lpAccountName учетное имя NULL,// Sid возвращаемая информация, хранящаяся в структуре размером *cbSid. Если размер буфера недостаточно велик, функция выполняется с ошибкой, возвращая размер, который требуется. &dwSidLength,// cbSid Указатель на переменную. На входе, это значение определяет размер в байтах буфера Sid. Если функция терпит неудачу, потому что буфер слишком мал или если CBSID равен нулю, эта переменная принимает требуемый размер буфера. NULL,// ReferencedDomainName строка, состоящая из *cbReferencedDomainName символов. Параметр длины строки должен инициализироваться размером буфера (для обработки ошибок используются обычные методы). Возвращаемое значение указывает домен, в котором обнаружено данное имя. В случае учетного имени Administrators возвращается значение BUILTIN, тогда как в случае пользовательского учетного имени возвращается имя этого пользователя. &dwLengthOfDomainName,// cchReferencedDomainName Указатель на переменную. На входе, это значение указывает размер, в TCHARs, буфера ReferencedDomainName. Если функция терпит неудачу, потому что буфер слишком мал, эта переменная получает необходимый размер буфера, включая завершающий нулевой символ. Если параметр ReferencedDomainName является NULL, то этот параметр должен быть равен нулю. &typeOfSid)==0)// peUse указывает на переменную SID_NAME_USE (перечислительный тип данных), проверяемыми значениями которой могут быть SidTypeWellKnownGroup, SidTypeUser, SidTypeGroup и так далее. { dwRetCode = GetLastError();//Получает значение кода последней ошибки вызывающего потока. Код последней ошибки поддерживается на основе каждого потока. Несколько потоков не перекрывают друг друга код последней ошибки. if (dwRetCode == ERROR_INSUFFICIENT_BUFFER)//Если буфер вывода данных является слишком маленьким, чтобы получить какие-либо данные, вызов завершается ошибкой, GetLastError возвращает значение ERROR_INSUFFICIENT_BUFFER { lpSid = (SID*) new char[dwSidLength]; lpDomainName = (LPTSTR) new wchar_t[dwLengthOfDomainName]; } } if (LookupAccountName( NULL, wchUserName, lpSid, &dwSidLength, lpDomainName, &dwLengthOfDomainName, &typeOfSid)==0) { dwRetCode = GetLastError(); printf("Посмотреть учетную запись не удалось.\n"); if(dwRetCode==1332) { printf("Код ошибки 1332, скорее всего имя компьютера задано неверно.\n", dwRetCode); system ("pause"); return 0; } else { printf("Error code: %d\n", dwRetCode);//выводим код ошибки system ("pause"); return 0; } }*/ //==========================================инициализируем новый дескриптор безопасности=========================== if (!InitializeSecurityDescriptor( &sdAbsoluteSd,//pSecurityDescriptor Указатель на структуру SECURITY_DESCRIPTOR, которая инициализирует функцию. SECURITY_DESCRIPTOR_REVISION))//dwRevision Уровень ревизии, чтобы присвоить дескриптор безопасности. Этот параметр должен быть SECURITY_DESCRIPTOR_REVISION. { dwRetCode = GetLastError(); printf("Инициализировать дескриптор безопасности не удалось.\n"); printf("The last error code: %u\n", dwRetCode); } //====================инициализируем новую структуру ACL========================================= dwDaclLength = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD)+dwSidLength;// Размер буфера в бфйтах. Это значение должно быть достаточно большим, чтобы содержать заголовок ACL и все элементы управления доступом (ACE), которые будут сохранены в ACL. lpNewDacl = (ACL*)new char[dwDaclLength];//адрес буфера if (!InitializeAcl(//Функция InitializeAcl инициализирует новую структуру ACL. lpNewDacl,//pAcl адрес предоставляемого программистом буфера размером cbAcl байт dwDaclLength,//nAclLength Длина в байтах буфера, на который указывает параметр PACL. Это значение должно быть достаточно большим, чтобы содержать заголовок ACL и все элементы управления доступом (ACE), которые будут сохранены в ACL. Кроме того, это значение должно быть типа DWORD выровнены. ACL_REVISION))//dwAclRevision Уровень ревизии структуры ACL создается. Это значение может быть ACL_REVISION или ACL_REVISION_DS. { dwRetCode = GetLastError(); printf("Получить дескриптор безопасности DACL не удалось.\n"); printf("Error code: %d\n", dwRetCode); } //===========================добовляем элементы управления доступом============================ //AddAccessAllowedAce добавляет разрешающий ACE в ACL. if (!AddAccessDeniedAce(//Функция AddAccessDeniedAce добавляет запрещающий ACE в ACL. lpNewDacl,//pAcl указывает на ту же структуру ACL, которая была инициализирована функцией InitializeACL ACL_REVISION,//dwAceRevision Определяет уровень пересмотра ACL модифицируется. Это значение может быть ACL_REVISION или ACL_REVISION_DS. GENERIC_EXECUTE ,//AccessMask Задает маску прав доступа отказано в указанный SID. (обобщенное исполнение) Sid))//pSid указывает на SID, который был получен с помощью функции LookupAccountName { dwRetCode = GetLastError(); printf("Добавить доступ ACE не удалось.\n"); printf("The last error code: %u\n", dwRetCode); } //==========================================связываем дескриптор с нашим списком======================================== if (!SetSecurityDescriptorDacl(//Функция SetSecurityDescriptorDacl устанавливает информацию в список управления доступом (DACL). Если DACL уже присутствует в дескрипторе безопасности, DACL заменяется. &sdAbsoluteSd,//pSecurityDescriptor указатель на дескриптор который нужно связать с ACL-списком TRUE,//bDaclPresent Флаг, указывающий на наличие ACL-списка в дескрипторе безопасности. Если этот параметр равен TRUE, функция устанавливает флаг SE_DACL_PRESENT в структуре SECURITY_DESCRIPTOR_CONTROL и использует значения в параметрах pDacl и bDaclDefaulted. lpNewDacl,//pDacl Указатель на структуру ACL, которая определяет DACL для дескриптора безопасности. Если этот параметр равен NULL, то пустое значение DACL присваивается дескриптор безопасности, что позволяет весь доступ к объекту. DACL ссылается, не копируются в дескриптор безопасности. FALSE))//bDaclDefaulted Флаг, указывающий на источник DACL. Если этот флаг имеет значение ИСТИНА, то DACL был получен по какой-то механизм по умолчанию. Если FALSE, то DACL было явно указано пользователем. Функция сохраняет это значение в флаг SE_DACL_DEFAULTED структуры SECURITY_DESCRIPTOR_CONTROL. Если этот параметр не указан, то SE_DACL_DEFAULTED флаг сброшен. { dwRetCode = GetLastError(); printf("Установить дескрипторов безопасности DACL не удалось\n"); printf("The last error code: %u\n", dwRetCode); } if(SetFileSecurity( filename, DACL_SECURITY_INFORMATION, &sdAbsoluteSd )!=0) // установить новый SD для файла с именем в filename printf("Исполнение файла запрещено\n"); system("pause"); return 0; }