LsaEnumerateAccountRights始终返回“找不到文件”

时间:2009-10-16 15:43:52

标签: security winapi

我正在调用Advapi32.dll LsaEnumerateAccountRights函数,该函数具有来自LsaOpenPolicy的策略句柄和来自LookupAccountName的帐户SID。

然而,尽量尝试,我总是回到0xC0000034,经过LsaNtStatusToWinError的翻译后,我发现“找不到引用的文件。”

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

最终结果是该帐户确实具有所需的权限,因此整个代码可以正常工作。

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

所以问题是当MSI执行回滚时 - 它总是会删除权限,因为它总是认为已经添加了它。因此,使用LsaEnumerateAccountRights检查权限是为了这个 - 但我无法让它工作。

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

4 个答案:

答案 0 :(得分:8)

我也一直在努力解决这个问题,但刚刚破解了它......

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

请参阅:link text

从LsaOpenPolicy()获取策略句柄,并从LookupAccountName()获取完全如您所述的帐户SID。

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

如果你用权限来源于其所属组的用户名,那么它会返回0xc0000034(= Windows错误2 - 系统找不到指定的“文件”),这意味着(我们现在意识到) )“找不到任何单独指定的附加权利”。似乎Windows Error 2翻译对于“找不到的内容”来说是一个全能的翻译。

现在... 如果您有ntrights.exe,请运行它...例如:

ntrights + r SeNetworkLogonRight -u MyUserName

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

答案 1 :(得分:1)

我最近遇到了同样的问题。在我对此问题的测试中,似乎LookupAccountName调用返回安全主体而不是完整的SID。实际的失败似乎是SID中用户权利所在的部分要么不存在,要么缩短为只有登录权。

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

我在没有域工作组系统和域成员系统上测试了这个,无论是管理员还是普通用户。成功时调用LookupAccountName,始终会生成不包含完整用户权限集的SID。

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

答案 2 :(得分:0)

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

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

我尝试了,使用ConvertStringSidToSid()来获得魔法blob LsaEnumerateAccountRights()期望和...同样的错误。 “系统无法找到指定的文件。”

答案 3 :(得分:0)

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

使用组调用相同的功能,您可以看到一切正常。