启动下其他用户的凭据的过程 [英] Launch a process under another user's credentials

查看:214
本文介绍了启动下其他用户的凭据的过程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想以另一个用户名的凭据启动一个进程。
这就是我现在:

I want to launch a process under another username's credentials. This is what I have now:

        /// <summary>
        /// Do actions under another username's credentials
        /// </summary>
        /// <param name="username">Username to inpersonate</param>
        /// <param name="domain">Domain/Machine</param>
        /// <param name="password">Password </param>
        public static void Action(string username,string domain, string password )
        {
            try
            {
                if (LogonUser(username, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref hToken))
                {
                    if (DuplicateToken(hToken, 2, ref hTokenDuplicate))
                    {

                        WindowsIdentity windowsIdentity = new WindowsIdentity(hTokenDuplicate);

                        WindowsImpersonationContext impersonationContext = windowsIdentity.Impersonate();

                        // Check the identity but it could do any other action under given username credentials
                      try
                        {
                            ProcessStartInfo info = new ProcessStartInfo("cmd.exe");
                            info.UseShellExecute = false;
                            info.RedirectStandardInput = true;
                            info.RedirectStandardError = true;
                            info.RedirectStandardOutput = true;
                            info.UserName = "dummy"; // see the link mentioned at the top
                            // Define the string value to assign to a new secure string.
                            char[] chars = { 'p', 'a', 's', 's','1','2','3','4','/' };
                            // Instantiate the secure string.
                            SecureString testString = new SecureString();
                            // Assign the character array to the secure string.
                            foreach (char ch in chars)
                                testString.AppendChar(ch);

                            info.Password = testString;

                            Process.Start(info);

                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine("Exception Occurred :{0},{1}",ex.Message, ex.StackTrace.ToString());
                        }

                        // Stop impersonating the user
                        impersonationContext.Undo();
                    }
                }
                // Free the tokens
                if (hToken != IntPtr.Zero) 
                    CloseHandle(hToken);
                if (hTokenDuplicate != IntPtr.Zero)
                    CloseHandle(hTokenDuplicate);

        }catch(Exception ex)
         {
             Console.WriteLine("Exception occurred. " + ex);
          }

这似乎并没有工作,我得到一个拒绝访问。如何做到这一点任何想法?
如果我们要求的凭据,我们得到了正确的,所以应该根据凭据执行任何程序。即:

It does not seem to work and I get an "Access denied". Any ideas of how to do it? If we ask for the credentials, we get the right ones, so it should execute any program under that credentials. i.e:

               if (DuplicateToken(hToken, 2, ref hTokenDuplicate))
                    {

                        WindowsIdentity windowsIdentity = new WindowsIdentity(hTokenDuplicate);                      
                        WindowsImpersonationContext impersonationContext = windowsIdentity.Impersonate();

                        // Check the identity but it could do any other action under given username credentials
                        Console.WriteLine("After impersonation: {0}", WindowsIdentity.GetCurrent().Name);

                        // Stop impersonating the user
                        impersonationContext.Undo();
                    }

和答案是正确的,我们得到的虚拟。

And the answer is right, we get "dummy".

我们可以使它更简单:

 public static void Run()
        {
            try
            {
                const string file = "cmd.exe";

                var sspw = new SecureString();

                foreach (var c in "pass1234/")
                    sspw.AppendChar(c);

                var proc = new Process();

                proc.StartInfo.UseShellExecute = false;

                proc.StartInfo.WorkingDirectory = Path.GetDirectoryName(file);

                proc.StartInfo.FileName = Path.GetFileName(file);

                proc.StartInfo.Domain = "WIN08";
                proc.StartInfo.Arguments = "";
                proc.StartInfo.UserName = "dummy";
                proc.StartInfo.Password = sspw;
                proc.StartInfo.LoadUserProfile = false;
                proc.Start();
            }catch(Exception e)
            {
                Console.WriteLine(e);
             }

不过,我仍然得到例外...

However, I still get exceptions...

推荐答案

我不认为你需要登录用户和重复句柄。所有你需要做的是设置在ProcessStartInfo对象的用户名,域和密码。如果我没有记错这一直可用,因为.NET 3.0。

I don't think you need to login the user and duplicate the handle. All you need to do is set the username, domain, and password in the ProcessStartInfo object. That's been available since .NET 3.0 if I recall correctly.

编辑:

也为更多的信息,这是当你给的用户名/域/密码的ProcessStartInfo到底发生了什么:的http://支持。 microsoft.com/kb/165194 。之所以拒绝访问很可能是你不能够访问用户的桌面或windowstation。只是主叫LoginUser是不充分的。

Also for more information, this is what really happens when you give username/domain/password to ProcessStartInfo: http://support.microsoft.com/kb/165194. The reason for access denied is probably that you don't have access to the user's desktop or windowstation. Just calling LoginUser is not sufficient.

这篇关于启动下其他用户的凭据的过程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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