Как запустить процесс с правами определенного пользователя.
От: Айкон Россия  
Дата: 13.05.03 07:52
Оценка:
Например, есть у меня какой-то exe файл, который запускается в виде процесса из моей программы, но так как в этом файле я не очень уверен, то хочу, запускать его с правами Guest в Windows NT. Как бы это сделать?
Re: Как запустить процесс с правами определенного пользовате
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 13.05.03 09:16
Оценка: 10 (2)
Здравствуйте, Айкон, Вы писали:

А>Например, есть у меня какой-то exe файл, который запускается в виде процесса из моей программы, но так как в этом файле я не очень уверен, то хочу, запускать его с правами Guest в Windows NT. Как бы это сделать?


Если просто запустить ехе то есть утилитка runas.exe. Если же из программы то вот пример из SDK:
// This sample demonstrates the use of the WindowsIdentity class to impersonate a user.
// IMPORTANT NOTES: 
// This sample can be run only on Windows XP.  The default Windows 2000 security policy 
// prevents this sample from executing properly, and changing the policy to allow
// proper execution presents a security risk. 
// This sample requests the user to enter a password on the console screen.
// Because the console window does not support methods allowing the password to be masked, 
// it will be visible to anyone viewing the screen.

using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.Permissions;

[assembly:SecurityPermissionAttribute(SecurityAction.RequestMinimum, UnmanagedCode=true)]
[assembly:PermissionSetAttribute(SecurityAction.RequestMinimum, Name = "FullTrust")]
public class ImpersonationDemo
{
    [DllImport("advapi32.dll", SetLastError=true)]
    public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, 
        int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

    [DllImport("kernel32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto)]
    private unsafe static extern int FormatMessage(int dwFlags, ref IntPtr lpSource, 
        int dwMessageId, int dwLanguageId, ref String lpBuffer, int nSize, IntPtr *Arguments);

    [DllImport("kernel32.dll", CharSet=CharSet.Auto)]
    public extern static bool CloseHandle(IntPtr handle);

    [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
    public extern static bool DuplicateToken(IntPtr ExistingTokenHandle, 
        int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);


    // GetErrorMessage formats and returns an error message
    // corresponding to the input errorCode.
    public unsafe static string GetErrorMessage(int errorCode)
    {
        int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
        int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
        int FORMAT_MESSAGE_FROM_SYSTEM  = 0x00001000;

        int messageSize = 255;
        String lpMsgBuf = "";
        int dwFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;

        IntPtr ptrlpSource = IntPtr.Zero;
        IntPtr prtArguments = IntPtr.Zero;
        
        int retVal = FormatMessage(dwFlags, ref ptrlpSource, errorCode, 0, ref lpMsgBuf, messageSize, &prtArguments);
        if (0 == retVal)
        {
            throw new Exception("Failed to format message for error code " + errorCode + ". ");
        }

        return lpMsgBuf;
    }

    // Test harness.
    // If you incorporate this code into a DLL, be sure to demand FullTrust.
    [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
    public static void Main(string[] args)
    {    
        IntPtr tokenHandle = new IntPtr(0);
        IntPtr dupeTokenHandle = new IntPtr(0);
        try
        {
            string UserName, MachineName;

            // Get the user token for the specified user, machine, and password using the 
            // unmanaged LogonUser method.

            Console.Write("Enter the name of a machine on which to log on: ");
            MachineName = Console.ReadLine();

            Console.Write("Enter the login of a user on {0} that you wish to impersonate: ", MachineName);
            UserName = Console.ReadLine();

            Console.Write("Enter the password for {0}: ", UserName);
            
            const int LOGON32_PROVIDER_DEFAULT = 0;
            //This parameter causes LogonUser to create a primary token.
            const int LOGON32_LOGON_INTERACTIVE = 2;
            const int SecurityImpersonation = 2;

            tokenHandle = IntPtr.Zero;
            dupeTokenHandle = IntPtr.Zero;

            // Call LogonUser to obtain a handle to an access token.
            bool returnValue = LogonUser(UserName, MachineName, Console.ReadLine(), 
                LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
                ref tokenHandle);
                    
            Console.WriteLine("LogonUser called.");
                
            if (false == returnValue)
            {
                int ret = Marshal.GetLastWin32Error();
                Console.WriteLine("LogonUser failed with error code : {0}", ret);
                Console.WriteLine("\nError: [{0}] {1}\n", ret, GetErrorMessage(ret));

                return;
            }

            Console.WriteLine("Did LogonUser Succeed? " + (returnValue? "Yes" : "No"));
                Console.WriteLine("Value of Windows NT token: " + tokenHandle);

            // Check the identity.
            Console.WriteLine("Before impersonation: "
                + WindowsIdentity.GetCurrent().Name);

            bool retVal = DuplicateToken(tokenHandle, SecurityImpersonation, ref dupeTokenHandle);
            if (false == retVal)
            {
                CloseHandle(tokenHandle);
                Console.WriteLine("Exception thrown in trying to duplicate token.");        
                return;
            }
            
            // The token that is passed to the following constructor must 
            // be a primary token in order to use it for impersonation.
            WindowsIdentity newId = new WindowsIdentity(dupeTokenHandle);
            WindowsImpersonationContext impersonatedUser = newId.Impersonate();

            // Check the identity.
            Console.WriteLine("After impersonation: "
                + WindowsIdentity.GetCurrent().Name);
        
            // Stop impersonating the user.
            impersonatedUser.Undo();

            // Check the identity.
            Console.WriteLine("After Undo: " + WindowsIdentity.GetCurrent().Name);
            
            // Free the tokens.
            if (tokenHandle != IntPtr.Zero)
                CloseHandle(tokenHandle);
            if (dupeTokenHandle != IntPtr.Zero) 
                CloseHandle(dupeTokenHandle);
        }
        catch(Exception ex)
        {
            Console.WriteLine("Exception occurred. " + ex.Message);
        }

    }
}
... << RSDN@Home 1.0 beta 7a >>
AVK Blog
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.