窗口模拟的古怪行为 [英] Odd behavior of windows Impersonation

查看:188
本文介绍了窗口模拟的古怪行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的Windows应用程序可能需要对一些人来说的部分管理权限。
对于这些情况,我想询问用户的管理员凭据,并使用以下code冒充管理员:

My windows application may require administrative privileges for some of it's sections. For those cases, I'd like to ask the user for an administrator credentials, and use the following code to impersonate the administrator:

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:结果
从运行一个管理员帐户的申请。

Scenario 1:
Running the application from an administrator account.


  1. 调用IsUserAdmin()=>收益 TRUE (好)

调用模仿(非管理员用户,域名,密码)=>收益 FALSE (好!)

calling impersonate ("non-admin-user" , "domain", "password" ) => returns FALSE (good!)

情景2:结果
从非管理员帐户运行应用程序,使用 runas.exe 从管理员帐户。

Scenario 2:
Running the application from a non-administrator account, using runas.exe from an administrator account.


  1. 调用IsUserAdmin()=>收益 FALSE (好)

调用模拟(管理员,域名,密码)=>收益 FALSE (不太好!)

calling impersonate ("administrator" , "domain", "password" ) => returns FALSE (not good!)

场景3:结果
运行应用程序的直接从非管理员帐户


  1. 调用IsUserAdmin()=>收益 FALSE (好)

调用模拟(管理员,域名,密码)=>收益 FALSE (不太好!)

calling impersonate ("administrator" , "domain", "password" ) => returns FALSE (not good!)

所有场景同时打印第1步第2步

All scenarios print both step 1 and step 2.

据我所知,上面应该有保证模拟,给出一个合法的凭据。什么我在这里丢失?

As far as I can tell, the above should have assure impersonation, given the a legitimate credentials. what am I missing here?

推荐答案

您真的不应该成为管理权限可编程做检查,需要管理员权限执行任务之前。只是无条件地尝试任务,让API告诉你,如果任务由于权限不足失败,如果是这样,那么你可以决定是否只能是失败的任务,并显示错误或提示用户输入凭据,然后重试任务。

You really should not be programmably checking for admin rights before doing a task that requires admin rights. Just attempt the task unconditionally and let the API tell you if the task failed due to insufficient rights, and if so then you can decide whether to just fail the task with an error or prompt the user for credentials and try the task again.

如果你正在尝试播放与UAC,你应该做的是实现你ADMIN code作为一个单独的进程或COM对象有什么好的,那么你就可以在需要时没有运行在提升的状态,这一过程/ COM有提升你的主要过程。让OS提示输入管理员凭据用户(并决定迅速应该如何看),当操作系统需要它,不要做手工你自己。

If you are trying to play nice with UAC, what you are supposed to do is implement your admin code as a separate process or COM object, then you can run that process/COM in an elevated state when needed without having to elevate your main process. Let the OS prompt the user for admin credentials (and decide how that prompt should look) when the OS needs it, don't do it manually yourself.

这篇关于窗口模拟的古怪行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆