quasoft / websspi

HTTP auth middleware for Go that uses Kerberos/NTLM SPNEGO with SSPI for single sign-on authentication of HTTP requests in Windows environments
MIT License
33 stars 7 forks source link

Get all groups for a user #1

Closed TheJayMann closed 3 years ago

TheJayMann commented 4 years ago

While looking at the code, I noticed that groups for a user are retrieved using the NetUserGetGroups function. From testing I've done, I've noticed that this only retrieves groups the user is directly assigned, and it will not retrieve groups the user is indirectly assigned, such as groups containing groups containing the user. Also, NetUserGetGroups requires providing the server name of a DC in order to get the groups of a domain user.

With some experimenting, I found that the groups can be obtained from the CtxtHandle. By using QueryContextAttributes passing the SECPKG_ATTR_ACCESS_TOKEN attribute (value 18), an SecPkgContext_AccessToken value is returned, which contains an access token, which can be passed to GetTokenInformation using the TokenGroups class, which results in TOKEN_GROUPS value.

The TOKEN_GROUPS value will contain an array of group SIDs and attributes assigned, and, by filtering the groups to only include those containing an attribute bit flag SE_GROUP_ENABLED, and using LookupAccountSid, a list of group names can be achieved.

Given this amount of work, I would have wanted to instead include a pull request. However, this is the first time I'm writing any Go code, I wasn't really able to make any progress except by using the helper functions defined in golang.org/x/sys/windows, and I was only able to make it work by removing tests (rather than augmenting and modifying the tests to work with the updated code). If you would still like to see the changes I made to help clarify the above description of work, I can make that available.

sorokinmax commented 3 years ago

@TheJayMann Hello, if it isn't difficult for you, publish your results, I will try to refine them.

TheJayMann commented 3 years ago

The difficulty at this point would be finding my code from about a year ago and getting it pushed out. If I can find it before the end of the week, I'll get it pushed.