流程开始从用户的域管理员启动过程中的UAC域网络启动 [英] Process Start as domain administrator from user started process with UAC activated in domain network

查看:209
本文介绍了流程开始从用户的域管理员启动过程中的UAC域网络启动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图做一些事情,现在经过多次敲我的头靠在屏幕,我不知道这是可以做到。

的情况如下:

  • 在Windows网络与域控制器其中PC的正常用户没有管理权限。
  • ,当它发现在网络(UNC路径)的比例更新(MSI)的程序,将运行更新。
  • 因为用户不能做安装。更新必须以管理员权限其他用户运行。

的理论是合理的,但是:

  • 在它只有在管理员用户是在特定计算机的本地管理员的工作。我不能使它与域管理员没有在PC本地帐户的工作。

我曾尝试与

  • 用户模拟与ADVAPI32.DLL LogonUser的令牌。
  • 流程 - >开始()安装提供域管理员的用户凭据。
  • 流程 - >开始()广告的域管理员,然后流程 - >启动()上安装的普通用户。

如上所述,如果管理员用户在PC上的本地帐户,它将工作。不过,如果我使用域管理员,电脑会提示UAC的屏幕要求有效的管理员凭据。

如果我请与任务管理器,开始处理与给定的凭据。它只是没有安装权利。

是否有可能做什么,我想在这里?如果没有,身边什么办法?

的问题是,所述网络是从一个域施用和PC的不必具有本地创建admin用户帐户。

解决方案
  

如上所述,如果管理员用户在PC上的本地帐户,它将工作。不过,如果我使用域管理员,电脑会提示UAC的屏幕要求有效的管理员凭据。

你有什么事要发生?为了模拟用户,你必须知道他们的密码。

用户需要了解域管理员无论哪种方式的密码,所以他们键入入同意对话框,并安装可以继续。

您设想一个系统,一个应用程序可以在没有任何人不必输入域管理员凭据以管理员身份运行?这是完全不允许的。


  

是否有可能做什么,我想在这里?

我不知道它是什么,你想有发生在这里。这就是为什么我在问究竟你想有发生。

我得到你想要启动一个过程,具有管理权限的帐户的感觉;所以这个独立的过程中可以进行更新。这个问题,我推测,是登录的用户不是管理员。

  

我不能使它与域管理员没有在PC本地帐户的工作。

什么,特别是你想使工作中使用域管理员的时候?什么, precisely 的你希望看到的情况呢?你是否认为,通过code,就可以启动一个提升的过程作为域用户没有UAC提示出现?这是不会发生的。

但是,有可能

所有这一切是说,你的描述是可能的。作为<一个href="http://blogs.msdn.com/b/cjacks/archive/2010/02/01/why-can-t-i-elevate-my-application-to-run-as-administrator-while-using-createprocesswithlogonw.aspx?Redirected=true"相对=nofollow>克里斯·杰克逊在博客中诀窍特别指出的是:

  1. 在启动程序为使用域管理员 CreateProcessWithLogonW
  2. 从该应用程序中,使用的ShellExecute 运行方式动词提升到管理员
  3. 执行您的更新

我模拟它与一个快速的Delphi应用程序。

最初的测试程序运行为的标准的用户(名为阿甘正传)。我发现他是不是管理员,并显示在更新软件按钮一个UAC盾:

单击该按钮会导致软件,推出自己的副本,但使用域管理员帐户的凭据(我的伊恩)。使用这是通过 CreateProcessWithLogonW

 如果IsUserAdmin然后
开始
    //无需篮球,我们已经管理员。做了更新。
    PerformUpdate();
    出口;
结束;

//重新启动自己作为一个特定的域管理员用户。
用户名:='ian@redacted.com';
密码:='正确的电池马主食;
的applicationName:= ParamStr这(0);
命令行:=的applicationName +'/ performUpdates;

ZeroMemory(@si,一下SizeOf(SI));
si.cb:=一下SizeOf(SI);

CreateProcessWithLogonW(PWideChar(用户名),无,PWideChar(密码),0,PWideChar(的applicationName),PWideChar(命令行),0,零,零,SI,{VAR} PI)
 

诀窍是,我们通过 / performUpdates 选项。当我们的应用程序启动时,它检测到,如果它被指示来执行更新。如果是这样,我们使用的ShellExecute 运行方式动词发动升高的自我复制

 程序TForm1.FormActivate(发件人:TObject的);
开始
    如果FindCmdLineSwitch('pe​​rformUpdates,真)则
    开始
        //如果不是管理员,然后使用的ShellExecute推出自己为一体
        如果没有IsUserAdmin话
        开始
            //重新启动自己作为一个管理员
            Toolkit.RunAsAdmin(0,ParamStr这(0),'/ performUpdates'); //不要忘了通过命令选项
            Application.Terminate;
            出口;
        结束;

        //我们是一个管理;做了更新。
        PerformUpdates;
        的MessageDlg(更新完成。,mtINformation,[MBOK],0);

        Application.Terminate;
        出口;
    结束;
结束;
 

的ShellExecute 运行方式动词触发UAC提升提示,然后提升应用程序运行的我( 伊恩),具有管理员权限不同的管理员用户出现:

RunAsAdmin 函数是的ShellExecute 一个简单的包装:

 函数RunAsAdmin(HWND:HWND;文件名:字符串;参数:字符串):布尔;
{
    见第3步:重新设计的UAC兼容(UAC)
    http://msdn.microsoft.com/en-us/library/bb756922.aspx
}
变种
    SEI:TShellExecuteInfo;
开始
    ZeroMemory(@sei,一下SizeOf(SEI));
    sei.cbSize:=一下SizeOf(TShellExecuteInfo);
    sei.Wnd:= HWND;
    sei.fMask:= SEE_MASK_FLAG_DDEWAIT或SEE_MASK_FLAG_NO_UI;
    sei.lpVerb:= PChar类型(运行方式);
    sei.lpFile:= PChar类型(文件名); // PAnsiChar;
    如果参数&LT;&GT; '' 然后
        sei.lpParameters:= PChar类型(参数); // PAnsiChar;
    sei.nShow:= SW_SHOWNORMAL; //整数;

    结果:=的ShellExecuteEx(@sei);
结束;
 

在语法稍微容易些,但 UseShellExecute 动词=运行方式是临界点。

函数的 IsUserAdmin 是很容易里面的.NET:

  //辅助函数,它告诉我们,如果我们已经使用管理权限运行
私人布尔IsUserAnAdmin()
{
    //用户可以是管理员组的成员,但不是管理员。
    //相反,用户可以是管理员,而不是管理员组的成员。

    //检查当前用户具​​有管理privelages
    变种同一性= WindowsIdentity.GetCurrent();
    返回(空=身份和放大器;!&安培;新的WindowsPrincipal(身份).IsInRole(WindowsBuiltInRole.Administrator));
}
 

绝对比原生code:

 功能IsUserAdmin:布尔;
变种
    B:BOOL;
    AdministratorsGroup:PSID;
开始
    {
        如果你正在使用管理privelages运行该函数返回true。
        在Vista和更高版本,如果你是不高的,这个函数将返回false(你是不是用行政privelages运行)。
        如果你*的*运行高架,然后IsUserAdmin将返回true,因为你是用管理员privelages运行。

        Windows提供的Shell32.IsUserAnAdmin此类似的功能。但功能depricated,这code被提起
        从文档的CheckTokenMembership:http://msdn.microsoft.com/en-us/library/aa376389.aspx
    }

    {
        常规说明:此例程返回TRUE,如果来电者
        过程是本地管理员组的成员。调用方不在
        预计将冒充任何人,预计能够
        打开自己的进程和进程令牌。
        参数:无。
        返回值:
            TRUE  - 来电拥有Administrators本地组。
            FALSE  - 来电显示没有管理员本地组。
    }
    B:= AllocateAndInitializeSid(
            SECURITY_NT_AUTHORITY,
            2,// 2分部门
            SECURITY_BUILTIN_DOMAIN_RID,//子权威0
            DOMAIN_ALIAS_RID_ADMINS,//子机构1
            0,0,0,0,0,0,//子当局2-7未通过
            AdministratorsGroup);
    如果(b)其次
    开始
        如果不是CheckTokenMembership(0,AdministratorsGroup,二)然后
            B:= FALSE;
        FreeSid(AdministratorsGroup);
    结束;

    结果:= B;
结束;
 

因此​​,所有的作品,并做了你所需要的。但是,用户仍然会presented一个UAC 同意对话框;虽然它们只需要继续。我推测,这不是理想的你。而且即使是:

不要去做

在上面的code中的关键问题,和克里斯同时杰克逊提到在他的博客:

  

最普遍的要求是一个人写的本土软件部署的软件,他们希望EN code凭据对进入应用程序,并提升自己的过程。这里真正的问题并不在于缺少的API,那就是 你有管理员凭据连接codeD在你的应用程序,为世界阅读。如果你有,你想要的是一种方式来获得的地方你没有说尽快,而不是更容易建立上设计的地方。

可怕的,可怕的,得罪code是:

  //重新推出自己作为一个特定的域管理员用户。
用户名:='ian@redacted.com';
密码:='正确的电池马主食;
 

您已经硬codeD的用户的密码。这是没有好。你不希望出现这种情况。

您的需要以实际需要管理员步行到机器并输入了他的证件。

很多简单的选择

你是在一个世界里的所有用户是允许更新的应用程序。如果这是真的,如果所有的用户允许修改的文件和注册表项,然后的让他们的!

在应用程序安装,更改你的应用程序文件夹的NTFS权限,使所有的用户有无完全控制

这是正确的解决您的问题。

尽管没有上述回答你的问题。

你要什么看的?

现在,我们又回到了原地。你想看看吗?

I am trying to do something that, now after much banging my head against the screen, am not sure it can be done.

The scenario is as follows:

  • a windows network with a domain controller where the normal users of the PC's don't have administrative privileges.
  • A program that, when it finds an update (MSI) in a share of the network (UNC path), will run the update.
  • Because the user cannot do installations. The update must be run with some other user with admin rights.

The theory is sound but:

  • it only works if the admin user is a local administrator in the given PC. I cannot make it work with a domain administrator that does not have a local account in the PC.

I have tried with:

  • User impersonation with a token from advapi32.dll LogonUser.
  • Process->Start() install providing the Domain administrator user credentials.
  • Process->Start() Advertise with the Domain administrator and then Process->start() install with the normal user.

As mentioned above, if the admin user has a Local account in the PC, it will work. However, if I use a Domain administrator, the PC will prompt a UAC screen asking for valid administrator credentials.

If I check with task manager, the process is started with the given credentials. It just doesn't have the rights to install.

Is it possible to do what I am trying here? If not, any way around?

The problem is that the network is administered from a domain and the PC's do not necessarily have the admin user account locally created.

解决方案

As mentioned above, if the admin user has a Local account in the PC, it will work. However, if I use a Domain administrator, the PC will prompt a UAC screen asking for valid administrator credentials.

What is it you want to happen? In order to impersonate a user, you have to know their password.

The user needs to know the password of the domain administrator either way, so they type it into the Consent dialog, and the install can proceed.

Are you envisioning a system where an application can be run as an administrator without anyone having to enter the domain admin credentials? That is simply not allowed.


Is it possible to do what I am trying here?

i'm not sure what it is you want to have happen here. Which is why i was asking what exactly you want to have happen.

I get the sense that you want to launch a process as an account with Administrative privileges; so this separate process can perform an update. The issue, i gather, is that the logged in user is not an administrator.

I cannot make it work with a domain administrator that does not have a local account in the PC.

What, in particular, are you trying to make work when using a domain administrator? What, precisely do you want to see happen? Are you thinking that that, through code, you can launch an elevated process as a domain user without a UAC prompt appearing? That's not going to happen.

But it is possible

All that being said, what you describe is possible. As Chris Jackson noted in a blog entry the trick is:

  1. Launch a program as the domain administrator using CreateProcessWithLogonW
  2. From that application, use ShellExecute with the runas verb to elevate to an administrator
  3. Perform your updates

I simulated it with a quick Delphi app.

Initially the test app is running as a standard user (named Forest Gump). I detect that he is not an administrator, and show a UAC shield on the Update Software button:

Clicking the button causes the software to launch a copy of itself, but using the credentials of a domain administrator account (me, Ian). This is done using CreateProcessWithLogonW:

if IsUserAdmin then
begin
    //No need for hoops, we're already an admin. Do the update.
    PerformUpdate();
    Exit;
end;

//Relaunch ourselves as a particular domain admin user.
username := 'ian@redacted.com';
password := 'correct battery horse staple';
applicationName := ParamStr(0);
commandLine := applicationName+' /performUpdates';

ZeroMemory(@si, SizeOf(si));
si.cb := SizeOf(si);

CreateProcessWithLogonW(PWideChar(username), nil, PWideChar(password), 0, PWideChar(applicationName), PWideChar(commandLine), 0, nil, nil, si, {var} pi)

The trick is that we pass the /performUpdates option. When our app starts up, it detects if it's being instructed to perform updates. If so, we use ShellExecute with the runas verb to launch an elevated copy of ourselves:

procedure TForm1.FormActivate(Sender: TObject);
begin
    if FindCmdLineSwitch('performUpdates', True) then
    begin
        //If we're not an admin, then use ShellExecute to launch ourselves as one
        if not IsUserAdmin then
        begin
            //Relaunch ourselves as an admin
            Toolkit.RunAsAdmin(0, ParamStr(0), '/performUpdates'); //don't forget to pass the command option
            Application.Terminate;
            Exit;
        end;

        //We are an admin; do the updates.
        PerformUpdates;
        MessageDlg('Update complete.', mtINformation, [mbOk], 0);

        Application.Terminate;
        Exit;
    end;
end;

The ShellExecute with the runas verb triggers the UAC elevation prompt, and then the elevated app running as me (Ian), a different admin user with admin privileges appears:

The RunAsAdmin function is a simple wrapper around ShellExecute:

function RunAsAdmin(hWnd: HWND; filename: string; Parameters: string): Boolean;
{
    See Step 3: Redesign for UAC Compatibility (UAC)
    http://msdn.microsoft.com/en-us/library/bb756922.aspx
}
var
    sei: TShellExecuteInfo;
begin
    ZeroMemory(@sei, SizeOf(sei));
    sei.cbSize := SizeOf(TShellExecuteInfo);
    sei.Wnd := hwnd;
    sei.fMask := SEE_MASK_FLAG_DDEWAIT or SEE_MASK_FLAG_NO_UI;
    sei.lpVerb := PChar('runas');
    sei.lpFile := PChar(Filename); // PAnsiChar;
    if parameters <> '' then
        sei.lpParameters := PChar(parameters); // PAnsiChar;
    sei.nShow := SW_SHOWNORMAL; //Integer;

    Result := ShellExecuteEx(@sei);
end;

In syntax is slightly easier, but UseShellExecute and Verb = "runas" are the critical points.

The function IsUserAdmin is much easier inside .NET:

//helper function that tells us if we're already running with administrative rights
private Boolean IsUserAnAdmin()
{
    //A user can be a member of the Administrator group, but not an administrator.
    //Conversely, the user can be an administrator and not a member of the administrators group.

    //Check if the current user has administrative privelages
    var identity = WindowsIdentity.GetCurrent();
    return (null != identity && new WindowsPrincipal(identity).IsInRole(WindowsBuiltInRole.Administrator));
}

than it is for native code:

function IsUserAdmin: Boolean;
var
    b: BOOL;
    AdministratorsGroup: PSID;
begin
    {
        This function returns true if you are currently running with admin privelages.
        In Vista and later, if you are non-elevated, this function will return false (you are not running with administrative privelages).
        If you *are* running elevated, then IsUserAdmin will return true, as you are running with admin privelages.

        Windows provides this similar function in Shell32.IsUserAnAdmin. But the function is depricated, and this code is lifted
        from the docs for CheckTokenMembership: http://msdn.microsoft.com/en-us/library/aa376389.aspx
    }

    {
        Routine Description: This routine returns TRUE if the callers
        process is a member of the Administrators local group. Caller is NOT
        expected to be impersonating anyone and is expected to be able to
        open its own process and process token.
        Arguments: None.
        Return Value:
            TRUE - Caller has Administrators local group.
            FALSE - Caller does not have Administrators local group.
    }
    b := AllocateAndInitializeSid(
            SECURITY_NT_AUTHORITY,
            2, //2 sub-authorities
            SECURITY_BUILTIN_DOMAIN_RID,    //sub-authority 0
            DOMAIN_ALIAS_RID_ADMINS,        //sub-authority 1
            0, 0, 0, 0, 0, 0,               //sub-authorities 2-7 not passed
            AdministratorsGroup);
    if (b) then
    begin
        if not CheckTokenMembership(0, AdministratorsGroup, b) then
            b := False;
        FreeSid(AdministratorsGroup);
    end;

    Result := b;
end;

So, all that works, and does what you need. But the user will still be presented a UAC Consent dialog; although they will only have to continue. i gather that's not desirable to you. And even if it is:

Don't do it

The critical problem in the above code, and Chris Jackon mentions it in his blog:

The most common request is for people writing home-grown software deployment software, where they’d like to encode credentials right into the app and elevate their own process. The real problem here is not the lack of the API, it’s that you have admin credentials encoded in your app for the world to read. If you have that, what you want is a way to get to a place where you do not have that as quickly as possible, not make it easier to build on that design.

The horrible, horrible, offending code is:

//Relaunch ourselves as a particular domain admin user.
username := 'ian@redacted.com';
password := 'correct battery horse staple';

You've hard-coded the password of a user. That's no good. You don't want that.

You want an administrator to actually be required to walk to the machine and enter his credentials.

Much simpler option

You're in a world where any user is allowed to update the application. If that is true, if all users are allowed to modify the files and registry keys, then let them!

During application install, change the NTFS permissions on your application's folder so that all Users have Full Control:

This is the correct solution to your problem.

Even though none of the above answers your question.

What do you want to see?

And now we come full circle. What do you want to see?

这篇关于流程开始从用户的域管理员启动过程中的UAC域网络启动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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