环境:Windows XP SP3,C#,. Net 4.0
问题:
我正在尝试在模拟类中添加对模拟用户注册表配置单元的访问权限,并且我根据被模拟的用户类型遇到问题(或者更准确地说,模拟用户的限制似乎更多).
我最初是在跟踪CodeProject中的模拟示例,该示例显示LoadUserProfile()在模拟开始后使用DuplcateToken()通过从原始令牌调用生成的重复令牌发生的调用LogonUser().我无法让这个示例在我的环境中使用管理员帐户冒充有限的用户(从示例中包含的屏幕截图看来,它似乎是在Windows Vista\7系统上完成的,并且没有提供有关涉及的帐户类型).
该调用LoadUserProfile()抛出了"拒绝访问"的错误.查看userenv.log显示"LoadUserProfile:无法启用还原权限.错误c0000022"行.MSDN上的LoadUserProfile文档显示调用进程必须拥有SE_RESTORE_NAME和SE_BACKUP_NAME权限,默认情况下只有Administrators和Backup Operators组的成员具有这些权限.(作为附注,当我试图稍后将这两个权限添加到Users组时,我仍然收到拒绝访问但是userenv.log显示"DropClientContext:Client [number]没有足够的权限.错误5"我无法'找到任何信息)
鉴于我模仿的用户没有这些权限,我LoadUserProfile()在开始模拟之前将调用移至最后,这次加载没有问题,我能够在此测试中读取和写入.考虑到我发现了我的答案,我创建了帐户类型的条件检查,以便LoadUserProfile()在模拟之前调用,如果当前用户是管理员的成员,或者等到模仿之后如果该成员不是管理员的成员(在以后的实例我将依赖具有这些特权的模拟用户).不幸的是我错了; 我没有发现我的答案.当我用角色反转测试呼叫时(用户>管理员)调用LoadUserProfile()仍然失败的Access Denied错误和userenv.log显示相同的"LoadUserProfile:无法启用还原权限.错误c0000061 "但这次使用不同的错误号.
认为默认情况下可能没有在从LogonUser()和/或DuplicateToken()我返回的令牌上启用权限,而是我从AdjustTokenPrivilege()当前用户令牌(在模拟后发生)中添加了两个调用WindowsIdentity.GetCurrent(TokenAccessLevels.AdjustPrivileges | TokenAccessLevels.Query).Token.
TokenAccessLevels.AdjustPrivileges并且TokenAccessLevels.Query被指定是因为MSDN上的AdjustTokenPrivilege文档指定在正在调整的令牌上需要它们(我还尝试通过调用OpenProcessToken()使用从中检索到的句柄来获取令牌System.Diagnostics.Process.GetCurrentProcess().Handle但在模拟内部和外部从用户调用时失败与GetCurrentProcess()被抛出接入功能拒绝)
AdjustTokenPrivilege()与之一起使用时返回成功WindowsIdentity...Token但LoadUserProfile()仍导致拒绝访问(还原权限).在这一点上,我不相信这AdjustTokenPrivilege()是在做它的工作,所以我开始确定可用的特权和他们所处的特定令牌的状态,GetTokenInformation()这导致了它自己的一小部分乐趣.在学习了一些新东西后,我能够调用GetTokenInformation()并打印出一系列权限及其当前状态,但结果有些不确定,因为恢复和备份在调用AdjustTokenPrivilege()管理员和模拟管理员之前和之后都显示了0的属性(奇怪的是,三个其他权限在调用时在令牌上从2变为1AdjustTokenPrivilege() 但不是那些实际被调整的值保持在0的值)
我删除了调用DuplicateToken()并替换了它所使用的所有地方和返回的令牌LogonUser(),看看这是否有助于测试令牌上的权限LogonUser() …
我正在尝试检索与 C# 中的令牌关联的权限及其当前状态,但我不知道如何调整LUID_AND_ATTRIBUTES返回的数组的大小以适应实际的元素数量。
来自MSDN
当 MarshalAsAttribute.Value 设置为 ByValArray 时,必须设置 SizeConst 以指示数组中的元素数量。
TOKEN_PRIVILEGES.PrivilegeCount在调用后,我能够观察该属性GetTokenInformation,并发现我正在使用的令牌具有特权常量参考页上列出的 35 项特权中的 24 项。更改SizeConst = 24将使我能够看到所有这些,而不仅仅是第一个(我最初是按照PInvokeSizeConst = 1的使用示例进行设置的)
有没有办法在创建传入数组时指定其深度,或者在编写代码之前我需要知道有多少特权?
[DllImport("advapi32.dll", SetLastError = true)]
protected static extern bool GetTokenInformation(IntPtr TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, IntPtr TokenInformation, int TokenInformationLength, ref int ReturnLength);
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)][return: MarshalAs(UnmanagedType.Bool)]
protected static extern bool LookupPrivilegeName(string lpSystemName, IntPtr lpLuid,System.Text.StringBuilder lpName, ref int cchName);
protected struct TOKEN_PRIVILEGES {
public UInt32 …Run Code Online (Sandbox Code Playgroud)