2009-10-16 44 views
3

我打电话给Advapi32.dll LsaEnumerateAccountRights函数,它有一个来自LsaOpenPolicy的策略句柄和一个来自LookupAccountName的账号SID。LsaEnumerateAccountRights总是返回“找不到文件”

但是,尽我所能,我总是回来0xC0000034,这是由LsaNtStatusToWinError翻译后给我“无法找到引用的文件。”

这不是一大堆好东西。我的代码处理这个并继续使用LsaAddAccountRights为SeServiceLogonRight授予帐户SID,所以我知道策略句柄和帐户SID都很好,因为如果其中一个出现问题,它就会被炸掉。

最终的结果是,该帐户确实有它需要的权利,因此整体代码的工作原理。

但是,我在MSI自定义操作中使用此操作,安装检查以查看帐户是否有权利,如果它没有(或如上述那样失败)它授予权利并记住它已完成它处于安装状态。如果发生回滚,并且它添加了正确的值,则会将其删除。我们绝不会在卸载时将其删除,因为其他应用程序可能使用与我们运行的服务相同的域帐户进行安装。

所以问题是当一个MSI执行回滚 - 它总是会删除它一直认为它已经添加它的权利。因此,使用LsaEnumerateAccountRights检查权限是用于此 - 但我不能让它工作。

任何想法 - 请注意,我使用C#与DllImport属性来公开Win32函数,并且我不是世界上最好的Win32程序员,在C#之前一直是Unix!

回答

1

我最近遇到了这个问题。在我对此问题的测试中,LookupAccountName调用看起来会返回一个安全主体而不是完整的SID。实际的失败似乎是用户权限所在的SID中的部分要么不在那里,要么缩短到仅登录权限。

对当前登录用户执行LookupAccountName调用,然后尝试针对该SID尝试LsaEnumerateAccountRights将导致仅用户登录权限。虽然很清楚,但还有许多其他权利。尝试检索除登录用户以外的任何其他用户,都成功返回SID。但是,该SID将不具有任何用户权限。

我已经在作为管理员和普通用户的域名工作组系统和域成员系统上测试了这一点。成功时LookupAccountName调用总是会生成一个不包含完整用户权限集的SID。

我只能假设,如果可以从安全数据库中获得完整的SID,那么LookupAccountName将正确地迭代权限。

0

我也有完全相同的问题。有人建议我通过WMI获得SID与此查询:

SELECT * FROM Win32_Account WHERE domain = 'ntdomain' AND name = 'username' 

我试了一下,用ConvertStringSidToSid()拿到魔法BLOB LsaEnumerateAccountRights()希望和......同样的错误。 “该系统找不到指定的文件。”

7

我一直在为此苦苦挣扎,但刚刚破解了它......

回想起来,我现在看到msdn文档中有一条线索: “此函数返回的帐户直接通过用户帐户拥有指定的权限,而不是作为群组成员的一部分。”

参见:link text

获得来自LsaOpenPolicy()政策手柄和LookupAccountName(帐户SID)完全一样,你说。

如果您输入的用户名是组的名称(“用户”,“管理员”等),那么LsaEnumerateAccountRights()工作正常,并枚举组的所有权利。

如果你在一个用户名上调用它,这个用户名的权限只从它所属的组中获得,那么它返回0xc0000034(= Windows错误2 - 系统找不到指定的“文件”),意思是(我们现在意识到)“找不到任何单独分配的附加权利”。看起来,Windows Error 2翻译对于“你正在寻找的东西还没有找到”是一个全面的解决方案。现在

... 如果你有Ntrights.exe的,运行它...例如:

ntrights + R SeNetworkLogonRight -u MyUserName输入

然后,LsaEnumerateAccountRights()工作正常,返回没有错误并列举一个单一的权利,“SeNetworkLogonRight”。

+0

超级惊人!感谢那! – Ajay 2011-07-10 17:44:05

0

我遇到了同样的问题,这是因为你没有为用户指定spefic privledge,所以用户priveldge是空的,如果你添加一个到它,它不会失败。

与一个组调用相同的功能,你可以看到一切正常工作。