2009-10-16 68 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是空的,如果你添加一個到它,它不會失敗。

與一個組調用相同的功能,你可以看到一切正常工作。