Вот как-то так. Если где есть косяки, прошу сильно не пинать.
Код | #include <windows.h> #include <ntsecapi.h> #include <Sddl.h>
#ifndef STATUS_SUCCESS #define STATUS_SUCCESS 0 #endif
void FreeTokenUser(TOKEN_USER* token_ptr) { if(token_ptr) { operator delete(token_ptr); } }
//------------------------------------------------------------------------ // Получает пользователя определённого токена безопасности // // IN: // hToken - токен безопасности // // RETURNS: // Указатель на токен или NULL в случае ошибки. // За удаление отвечает вызывающая функция. // используйте free_token_user //------------------------------------------------------------------------ TOKEN_USER* GetTokenUser(HANDLE hToken) { TOKEN_USER* pTokUser = NULL; DWORD dwLength;
// Узнаём размер, необходимый для получения SID. if(!GetTokenInformation( hToken, TokenUser, NULL, 0, &dwLength ) && GetLastError()==ERROR_INSUFFICIENT_BUFFER ) { // выделяем память для SID pTokUser = (TOKEN_USER*) operator new (dwLength);
// Получаем SID. if(!GetTokenInformation( hToken, TokenUser, pTokUser, dwLength, &dwLength ) ) { FreeTokenUser(pTokUser); pTokUser = NULL; } }
return pTokUser; }
void FreeSidInformation(PSID psid) { if(psid) { operator delete (psid); } }
PSID GetSIDInformation (const wchar_t* server, const wchar_t* AccountName) { PSID psid = NULL; DWORD dwSize = 0;
TCHAR *buf = NULL; DWORD dwBuf = 0;
SID_NAME_USE siu;
// Узнаем необходимые размеры буферов LookupAccountName( server, AccountName, NULL, &dwSize, NULL, &dwBuf, &siu );
// Выделим память под буферы psid = operator new ( dwSize );// За освобождение этого указателя отвечает вызывающая функция buf = (TCHAR*)operator new ( dwBuf*sizeof( TCHAR ) );
// Получим описатель безопасности if(!LookupAccountName( server, AccountName, psid, &dwSize, buf, &dwBuf, &siu )) { FreeSidInformation(psid); psid = NULL; }
// нам не нужны имена доменов, в которых происходил поиск if( buf ) operator delete ( buf );
return psid; }
LSA_HANDLE GetPolicyHandle(const wchar_t *SystemName) { LSA_OBJECT_ATTRIBUTES ObjectAttributes; USHORT SystemNameLength; LSA_UNICODE_STRING lusSystemName; NTSTATUS ntsResult; LSA_HANDLE lsahPolicyHandle;
// Инициализация ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
// Инициализация wchar_t buffer[1024]; if(SystemName != NULL) { wcscpy_s(buffer, sizeof(buffer)/sizeof(buffer[0]), SystemName); }
SystemNameLength = (SystemName!=NULL)?static_cast<USHORT>(wcslen(SystemName)) : 0; lusSystemName.Buffer = (SystemName==NULL) ? NULL : buffer; lusSystemName.Length = SystemNameLength * sizeof(WCHAR); lusSystemName.MaximumLength = (SystemNameLength+1) * sizeof(WCHAR);
// Get a handle to the Policy object. ntsResult = LsaOpenPolicy( &lusSystemName, //Name of the target system. &ObjectAttributes, //Object attributes. POLICY_ALL_ACCESS, //Desired access permissions. &lsahPolicyHandle //Receives the policy handle. );
if (ntsResult != STATUS_SUCCESS) { // An error occurred. Display it as a win32 error code. return NULL; } return lsahPolicyHandle; }
bool InitLsaString( PLSA_UNICODE_STRING pLsaString, LPCWSTR pwszString ) { DWORD dwLen = 0;
if (NULL == pLsaString) return FALSE;
// Длина строки if (NULL != pwszString) { dwLen = static_cast<int>(wcslen(pwszString)); if (dwLen > 0x7ffe) // Слишком большая строка return FALSE; }
// Сохраняем строку pLsaString->Buffer = (WCHAR *)pwszString; pLsaString->Length = (USHORT)dwLen * sizeof(WCHAR); pLsaString->MaximumLength= (USHORT)(dwLen+1) * sizeof(WCHAR);
return TRUE; }
/* * server - сервер, для которого устанавливается политика (NULL для локального) * wacct - учётная запись для которой устанавливается политика. * NULL - для текущего пользователя. * policy - имя политики * add - добавить или удалить политику */ BOOL SetPolicy(const wchar_t* server, const wchar_t *wacct, const wchar_t *policy, bool add) { NTSTATUS ntsResult = 0; PSID user_sid = NULL; TOKEN_USER* token_user = NULL;
// Получаем описатель безопасности для учётной записи if(wacct == NULL) { // Учётная запись не указана. Получаем текущую HANDLE process_token = NULL; if(OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &process_token)) { token_user = GetTokenUser(process_token); if(token_user) { // Описатель безопасности текущего пользователя user_sid = token_user->User.Sid; } CloseHandle(process_token); } } else { // Получаем описатель безопасности для текущей учётной записи user_sid = GetSIDInformation(NULL, wacct); }
// Не нашли описатель пользвоателя if(user_sid == NULL) { return FALSE; }
// Создаём LSA-строку LSA_UNICODE_STRING lucPrivilege; if (!InitLsaString(&lucPrivilege, policy)) { return FALSE; }
// Получаем дескриптор политик для компьютера LSA_HANDLE ph = GetPolicyHandle( server );
// Добавляем политику if( add ) { ntsResult = LsaAddAccountRights(ph, user_sid, &lucPrivilege, 1 ); } else { ntsResult = LsaRemoveAccountRights( ph, user_sid, FALSE, &lucPrivilege, 1 ); }
// закрываем описатель политики LsaClose( ph );
// удаляем память, выделенную под описатель безопасности УЗ if(wacct == NULL) { FreeTokenUser(token_user); } else { FreeSidInformation(user_sid); }
return (ntsResult == STATUS_SUCCESS) ? TRUE : FALSE; }
int _tmain(int argc, _TCHAR* argv[]) { SetPolicy(NULL, NULL, L"SeLockMemoryPrivilege", true); return 0; }
|
|