Моему приложению Windows могут потребоваться права администратора для некоторых его разделов. В таких случаях я хотел бы запросить у пользователя учетные данные администратора и использовать следующий код для выдачи себя за администратора:
BOOL impersonate(LPTSTR lpszUsername, LPTSTR lpszDomain, LPTSTR lpszPassword) {
BOOL ret = LogonUser(lpszUsername,
lpszDomain,
lpszPassword,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
&hToken);
if (ret != TRUE) return FALSE;
OutputDebugString (L"step 1");
ret = ImpersonateLoggedOnUser(hToken);
if (ret != TRUE) return FALSE;
OutputDebugString(L"step 2");
return IsUserAdmin()
}
где была взята функция IsUserAdmin()
из MSDN и выглядит следующим образом:
BOOL IsUserAdmin(VOID) {
BOOL b;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
PSID AdministratorsGroup;
b = AllocateAndInitializeSid( &NtAuthority,
2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&AdministratorsGroup);
if (b) {
if (!CheckTokenMembership(NULL, AdministratorsGroup, &b)) {
b = FALSE;
}
FreeSid(AdministratorsGroup);
}
return(b);
}
Сценарий 1.
Запуск приложения из учетной записи администратора.
вызов IsUserAdmin () => возвращает
TRUE
(хорошо)вызов impersonate ("пользователь без прав администратора", "домен", "пароль") => возвращает
FALSE
(хорошо!)
Сценарий 2:
Запуск приложения из учетной записи без прав администратора с использованием runas.exe
из учетной записи администратора.
вызов IsUserAdmin () => возвращает
FALSE
(хорошо)вызов impersonate ("администратор", "домен", "пароль") => возвращает
FALSE
(не очень хорошо!)
Сценарий 3:
Запуск приложения напрямую из учетной записи без прав администратора.
вызов IsUserAdmin () => возвращает
FALSE
(хорошо)вызов impersonate ("администратор", "домен", "пароль") => возвращает
FALSE
(не очень хорошо!)
Все сценарии печатают как step 1
, так и step 2
.
Насколько я могу судить, приведенное выше должно гарантировать выдачу себя за другое лицо при наличии законных учетных данных. что мне здесь не хватает?
impersonate()
возвращает ЛОЖЬ, но вы не указали, где именно происходит сбой.impersonate()
имеет 4 точки отказа, которые могут привести к возврату FALSE - еслиLogonUser()
не удается, еслиImpersonateLoggedOnUser()
не удается, еслиAllocateAndInitializeSid()
не удается илиCheckTokenMembership()
. Вам нужно отладить свой код и точно выяснить, что на самом деле дает сбой. - person Remy Lebeau   schedule 10.12.2013