当计算机未连接到网络时,是否有一系列标志允许LogonUser
返回可用于冒充本地用户的令牌(但所有帐户已在本地存在)。
我有域帐户执行应用
MYDOMAIN \ FooUser
我试图获取
的模拟令牌MYLAPTOP \ TestUser用户
然后我读了一个文件夹中的一系列文本文件,所有这些文件都可以被FooUser
读取,但是有些文件被TestUser
拒绝了读取权限。
如果我登录Windows并从TestUser
运行应用程序,则权限映射正确,并且文件上的权限被拒绝。如果我已连接到我的域并从FooUser
运行应用程序,我还可以模拟TestUser
和文件权限再次正确拒绝访问(使用LOGON32_LOGON_INTERACTIVE
)。
当拔掉我的以太网电缆时出现问题,我尝试拨打LogonUser
TestUser
,我希望我能以某种方式验证本地凭据......本地?< / p>
使用LOGON32_LOGON_INTERACTIVE
:
TestUser
的凭据会返回错误,指示&#34;错误的用户名或密码&#34; FooUser
的凭据会返回错误,指示&#34;没有可用的登录服务器&#34; (有道理,我没有抱怨......除了我没有连接到我的域时,我是如何首先登录Windows的?)使用LOGON32_LOGON_NEW_CREDENTIALS
:
FooUser
具有相同访问权限的令牌using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Principal;
using Common.NativeMethods.Enumerations;
namespace Common.NativeMethods
{
public static class AdvApi32
{
// http://www.pinvoke.net/default.aspx/advapi32.logonuser
// http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.securestringtoglobalallocunicode(v=vs.100).aspx
// PInvoke into the Win32 API to provide access to the
// LogonUser and CloseHandle functions.
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern bool LogonUser(
IntPtr username,
IntPtr domain,
IntPtr password,
LogonType logonType,
LogonProvider logonProvider,
ref IntPtr token
);
public static WindowsIdentity LogonUser(SecureString p_userName, SecureString p_password, SecureString p_domainName)
{
IntPtr UserAccountToken = IntPtr.Zero;
IntPtr UserNamePointer = IntPtr.Zero;
IntPtr PasswordPointer = IntPtr.Zero;
IntPtr DomainNamePointer = IntPtr.Zero;
try
{
// Marshal the SecureString to unmanaged memory.
UserNamePointer = Marshal.SecureStringToGlobalAllocUnicode(p_password);
PasswordPointer = Marshal.SecureStringToGlobalAllocUnicode(p_userName);
DomainNamePointer = Marshal.SecureStringToGlobalAllocUnicode(p_domainName);
// Call LogonUser, passing the unmanaged (and decrypted) copy of the SecureString password.
bool ReturnValue =
AdvApi32
.LogonUser(
UserNamePointer,
DomainNamePointer,
PasswordPointer,
LogonType.LOGON32_LOGON_INTERACTIVE, //.LOGON32_LOGON_NEW_CREDENTIALS,
LogonProvider.LOGON32_PROVIDER_DEFAULT, //.LOGON32_PROVIDER_WINNT50,
ref UserAccountToken);
// Get the Last win32 Error and throw an exception.
if (!ReturnValue && UserAccountToken == IntPtr.Zero)
{
int error = Marshal.GetLastWin32Error();
throw
new Win32Exception(error);
}
// The token that is passed to the following constructor must
// be a primary token in order to use it for impersonation.
return
new WindowsIdentity(UserAccountToken);
}
finally
{
// Zero-out and free the unmanaged string reference.
Marshal.ZeroFreeGlobalAllocUnicode(UserNamePointer);
Marshal.ZeroFreeGlobalAllocUnicode(PasswordPointer);
Marshal.ZeroFreeGlobalAllocUnicode(DomainNamePointer);
// Close the token handle.
Kernel32.CloseHandle(UserAccountToken);
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Runtime.ConstrainedExecution;
using System.Security;
namespace Common.NativeMethods
{
// http://msdn.microsoft.com/en-us/library/system.security.principal.windowsimpersonationcontext%28v=vs.100%29.aspx
public static class Kernel32
{
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
internal extern static bool CloseHandle(IntPtr handle);
}
}
答案 0 :(得分:0)
LogonUser
在未连接到域时工作正常;如果你至少指向正确的参数。
UserNamePointer = Marshal.SecureStringToGlobalAllocUnicode(p_password);
PasswordPointer = Marshal.SecureStringToGlobalAllocUnicode(p_userName);
固定
UserNamePointer = Marshal.SecureStringToGlobalAllocUnicode(p_userName);
PasswordPointer = Marshal.SecureStringToGlobalAllocUnicode(p_password);