quinta-feira, 13 de novembro de 2008

Gmail - Caixa de entrada - ginochen@gmail.com

http://alt.pluralsight.com/wiki/default.aspx/Keith.GuideBook/HowToRunAProgramAsAnotherUser.html

How To Run A Program As Another User
.

There are three ways of doing this: via Explorer, via a command-line tool, and programmatically. Using Explorer, right-click the program you want to run and choose the "Run As" option. You'll see the dialog shown in Figure 30.1. If the "Run As" menu option doesn't show up in the context menu when you right-click, try holding down the Shift key on your keyboard while right clicking. That should do the trick.

Figure 30.1 The Run As dialog

In case you've ever wondered what the other option in this dialog is for, the one that says, "Protect my computer and data from unauthorized program activity," it's designed specifically for people who normally run as administrators but want to run an application without administrative privileges. What this does is duplicate the caller's token into a restricted token that sets a special flag on the BUILTIN\Administrators group so that it becomes a "deny only" group. This means that, even though this SID will be in your token, it will never be used to grant access, but can only be used for permission denials (such as someone explicitly denying access to Administrators1). In other words, it allows you to continue running with the same user profile (WhatIsAUserProfile) but demotes you to a normal user. If you find yourself doing this a lot, maybe you should consider running as a non-admin (WhatIsANonPrivilegedUser) on a regular basis!

To use the command-line option, there's the runas utility (you'll be prompted to type in a password, of course):

runas /u:xyzzy\alice "cmd /K title ALICE"

This command establishes a fresh interactive logon for Alice and executes cmd.exe with a command line of /K title ALICE, which sets the command prompt's window title to "ALICE." By default, her user profile will be loaded (WhatIsAUserProfile), but if you’re running a program that doesn't make use of the user profile, you can speed up the launch significantly by using the /noprofile switch.

Here's another rather trippy thing you can do with this command:

runas /u:SalesDomain\Bob /netonly "cmd /K title NetBob"

This runs the command prompt as you but with the network credentials of SalesDomain\Bob, which is really convenient if you are running on a computer that's not part of a domain but you need to use your domain credentials to access network resources. I used these tricks in HowToDevelopCodeAsANonAdmin to set up a privileged command prompt for use when developing code as a normal user.

Finally, you can invoke this feature programmatically via a Win32 API called CreateProcessWithLogonW. Be careful about using this function, though, because it requires a password, and where are you going to get that? Don't be hardcoding passwords into your code, now! If you need to do this sort of thing, prompt the user for a password (HowToPromptForAPassword) or, if you must store the password on the machine, do it as carefully as possible (HowToStoreSecretsOnAMachine). I show an example of calling this function in Figure 30.2 and use helper code developed in HowToPromptForAPassword to prompt the user for a password.

 using System;
using System.Runtime.InteropServices;
using System.IO;
using KBC.WindowsSecurityUtilities;


class RunCommandShellAsAlice {
static void Main() {
StartupInfo si = new StartupInfo();
si.cb = Marshal.SizeOf(typeof(StartupInfo));
si.title = "Alice's command prompt";


ProcessInfo pi = new ProcessInfo();
string app = Path.Combine(Environment.SystemDirectory,
"cmd.exe");


Console.WriteLine("Please enter Alice's password:");


if (CreateProcessWithLogonW(
"alice", // user name
".", // domain name, or "." for a local account
PasswordPrompt.GetPasswordFromCmdLine(),
LogonFlags.LOGON_WITH_PROFILE,
app, null,
0, IntPtr.Zero, null,
ref si, out pi)) {
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
else Console.WriteLine("CPWL failed with error code: {0}",
Marshal.GetLastWin32Error());
}
[Flags]
enum LogonFlags {
LOGON_WITH_PROFILE = 0x00000001,
LOGON_NETCREDENTIALS_ONLY = 0x00000002
}


[Flags]
enum CreationFlags {
CREATE_SUSPENDED = 0x00000004,
CREATE_NEW_CONSOLE = 0x00000010,
CREATE_NEW_PROCESS_GROUP = 0x00000200,
CREATE_UNICODE_ENVIRONMENT = 0x00000400,
CREATE_SEPARATE_WOW_VDM = 0x00000800,
CREATE_DEFAULT_ERROR_MODE = 0x04000000,
}


[StructLayout(LayoutKind.Sequential)]
struct ProcessInfo {
public IntPtr hProcess;
public IntPtr hThread;
public uint dwProcessId;
public uint dwThreadId;
}


[StructLayout(LayoutKind.Sequential,
CharSet=CharSet.Unicode)]
struct StartupInfo {
public int cb;
public string reserved1;
public string desktop;
public string title;
public uint dwX;
public uint dwY;
public uint dwXSize;
public uint dwYSize;
public uint dwXCountChars;
public uint dwYCountChars;
public uint dwFillAttribute;
public uint dwFlags;
public ushort wShowWindow;
public short reserved2;
public int reserved3;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}


[DllImport("advapi32.dll", CharSet=CharSet.Unicode,
ExactSpelling=true, SetLastError=true)]
static extern bool CreateProcessWithLogonW(
string principal,
string authority,
string password,
LogonFlags logonFlags,
string appName,
string cmdLine,
CreationFlags creationFlags,
IntPtr environmentBlock,
string currentDirectory,
ref StartupInfo startupInfo,
out ProcessInfo processInfo);


[DllImport("kernel32.dll")]
static extern bool CloseHandle(IntPtr h);
}

Figure 30.2 Programmatically starting a program as another user

1 If you think about it, this is a pointless thing to do because an administrator can change any DACL in the system by taking ownership of the object if necessary (WhatIsOwnership).

PortedBy RjaeEaston

Nenhum comentário: