Identifying if a user is in the local administrators group

穿精又带淫゛_ 提交于 2019-12-22 12:43:30

问题


My Problem

I'm using PInvoked Windows API functions to verify if a user is part of the local administrators group. I'm utilizing GetCurrentProcess, OpenProcessToken, GetTokenInformationand LookupAccountSid to verify if the user is a local admin.

GetTokenInformation returns a TOKEN_GROUPS struct with an array of SID_AND_ATTRIBUTES structs. I iterate over the collection and compare the user names returned by LookupAccountSid.

My problem is that, locally (or more generally on our in-house domain), this works as expected. The builtin\Administrators is located within the group membership of the current process token and my method returns true. On another domain of another developer the function returns false.

The LookupAccountSid functions properly for the first 2 iterations of the TOKEN_GROUPS struct, returning None and Everyone, and then craps out complaining that "A Parameter is incorrect."

What would cause only two groups to work correctly?

The TOKEN_GROUPS struct indicates that there are 14 groups. I'm assuming it's the SID that is invalid.

Everything that I have PInvoked I have taken from an example on the PInvoke website. The only difference is that with the LookupAccountSid I have changed the Sid parameter from a byte[] to a IntPtr because SID_AND_ATTRIBUTESis also defined with an IntPtr. Is this ok since LookupAccountSid is defined with a PSID?

LookupAccountSid PInvoke

    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    static extern bool LookupAccountSid(
        string lpSystemName,
        IntPtr Sid,
        StringBuilder lpName,
        ref uint cchName,
        StringBuilder ReferencedDomainName,
        ref uint cchReferencedDomainName,
        out SID_NAME_USE peUse);

Where the code falls over

                for (int i = 0; i < usize; i++)
                {
                    accountCount = 0;
                    domainCount = 0;
                    //Get Sizes
                    LookupAccountSid(null, tokenGroups.Groups[i].SID, null, ref accountCount, null,
                                     ref domainCount, out snu);

                    accountName2.EnsureCapacity((int) accountCount);
                    domainName.EnsureCapacity((int) domainCount);

                    if (!LookupAccountSid(null, tokenGroups.Groups[i].SID, accountName2, ref accountCount, domainName,
                                     ref domainCount, out snu))
                    {
                        //Finds its way here after 2 iterations
                        //But only in a different developers domain
                        var error = Marshal.GetLastWin32Error();

                        _log.InfoFormat("Failed to look up SID's account name. {0}", new Win32Exception(error).Message);
                        continue;
                    }

If more code is needed let me know. Any help would be greatly appreciated.


回答1:


It sounds like you're trying to duplicate the functionality of NetUserGetLocalGroups. You can also use NetUserGetInfo with an information level of 1, and check the value of usri1_priv in the USER_INFO_1 for USER_PRIV_ADMIN.




回答2:


I'm not sure if NetUserGetLocalGroups knows about deny SIDs (If you need to verify if the current process (not the user account!) is in the admin group, you have to handle deny SIDs)

If you only need to support 2000 and later, PInvoke CheckTokenMembership (That MSDN page has a IsUserAdmin example function)

On NT4 you need to get a TokenGroups array from GetTokenInformation, but you don't call LookupAccountSid, you just call EqualSid on every item and compare it to a admin group SID you create with AllocateAndInitializeSid(...,SECURITY_BUILTIN_DOMAIN_RID,...)



来源:https://stackoverflow.com/questions/3064217/identifying-if-a-user-is-in-the-local-administrators-group

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!