C#中局域网共享目录的访问
Net Use方案
public string ConnectLan()
{
Process p;
p=new Process();
p.StartInfo.FileName="cmd.exe";
// 这里是关键点,不用Shell启动/重定向输入/重定向输出/不显示窗口
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.CreateNoWindow = true;
p.Start();
p.StandardInput.WriteLine("net use """"Nt02 密码 /user:用户名");// 向cmd.exe输入command
p.StandardInput.WriteLine("exit");
p.WaitForExit();
string s = p.StandardOutput.ReadToEnd();// 得到cmd.exe的输出
p.Close();
return s;
}
WindowsImpersonationContext方案
[C#]
// 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 errorCode = 0x5; //ERROR_ACCESS_DENIED
//throw new System.ComponentModel.Win32Exception(errorCode);
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, domainName;
// Get the user token for the specified user, domain, and password using the
// unmanaged LogonUser method.
// The local machine name can be used for the domain name to impersonate a user on this machine.
Console.Write("Enter the name of the domain on which to log on: ");
domainName = Console.ReadLine();
Console.Write("Enter the login of a user on {0} that you wish to impersonate: ", domainName);
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, domainName, 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));
int errorCode = 0x5; //ERROR_ACCESS_DENIED
throw new System.ComponentModel.Win32Exception(errorCode);
}
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);
}
}
}
MSDN:
http://msdn2.microsoft.com/zh-cn/library/system.security.principal.windowsimpersonationcontext_members(VS.80).aspx
http://msdn2.microsoft.com/en-us/library/system.security.principal.windowsimpersonationcontext(vs.71).aspx
public string ConnectLan()
{
Process p;
p=new Process();
p.StartInfo.FileName="cmd.exe";
// 这里是关键点,不用Shell启动/重定向输入/重定向输出/不显示窗口
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.CreateNoWindow = true;
p.Start();
p.StandardInput.WriteLine("net use """"Nt02 密码 /user:用户名");// 向cmd.exe输入command
p.StandardInput.WriteLine("exit");
p.WaitForExit();
string s = p.StandardOutput.ReadToEnd();// 得到cmd.exe的输出
p.Close();
return s;
}
WindowsImpersonationContext方案
[C#]
// 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 errorCode = 0x5; //ERROR_ACCESS_DENIED
//throw new System.ComponentModel.Win32Exception(errorCode);
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, domainName;
// Get the user token for the specified user, domain, and password using the
// unmanaged LogonUser method.
// The local machine name can be used for the domain name to impersonate a user on this machine.
Console.Write("Enter the name of the domain on which to log on: ");
domainName = Console.ReadLine();
Console.Write("Enter the login of a user on {0} that you wish to impersonate: ", domainName);
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, domainName, 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));
int errorCode = 0x5; //ERROR_ACCESS_DENIED
throw new System.ComponentModel.Win32Exception(errorCode);
}
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);
}
}
}
MSDN:
http://msdn2.microsoft.com/zh-cn/library/system.security.principal.windowsimpersonationcontext_members(VS.80).aspx
http://msdn2.microsoft.com/en-us/library/system.security.principal.windowsimpersonationcontext(vs.71).aspx