|
|
|
date: Thu, 1 May 2008 19:18:00 -0700,
group: microsoft.public.platformsdk.security
back
Getting all security groups without a token?
Please excuse the long post. I hope I have provided enough background.
I have an application that applies security-group based authorization rules.
It uses CheckTokenMembership for groups that it cares about, using a token
obtained through LogonUser or via SSPI.
I now have a case where I need to apply these rules in the absence of a
token. It seems like the most optimal way to do this is to mimic Windows'
own behavior when creating the list of group SIDs in a login token, and then
use that list for these checks in lieu of CheckTokenMembership.
So, my question is, how is Windows doing this at login time, and/or what is
the most optimal way of computing a user's expanded / transitive security
group memberships, including local groups?
I'm working in native C++ on Server 2003, supporting both 2003 and 2000
domains.
There are examples in "The .NET Developer's Guide to Directory Services
Programming" which illustrate how to compute this (specifically example 11.6)
but it appears as though this results in multiple round-trips to the domain
controller. That seems inefficient, is it really the best way?
I also noticed the "calculated" tokenGroups attribute, but when I do an LDAP
search for that attribute I get a ERROR_DS_OPERATIONS_ERROR. I'm not sure
what the non-.NET equivalent is to RefreshCache() that is supposed to
populate this.
Hope someone has been through this before and can point me in the right
direction. This is code that may execute frequently so I'm looking for the
solution that involves the least number of network round-trips.
Thanks in advance!
Doug
date: Thu, 1 May 2008 19:18:00 -0700
author: clarkd4
Re: Getting all security groups without a token?
Hi Doug,
If you were already using the NT token-based APIs for doing this type of
thing you might be interested in the Authz APIs that provide some functional
equivalents without the requirement of getting a kernel mode login token for
the user.
You might start with the various AuthZInitializeContextxxxx functions to see
if they get you going in the direction you want.
Under the hood, the code will still end up querying the directory to get the
user's group membership (it uses tokenGroupsGlobalAndUniversal instead of
tokenGroups, so you won't get any DLGs this way). Authz uses RPC APIs
instead of LDAP to do the query, but the overall results are similar, just
the wire traffic is different.
If you can avoid doing the LDAP query, that is probably easiest.
I'm sure we can fix the operations error if you need to as that is usually
just the result of binding to the directory as the anonymous user instead of
a valid one which typically results from something that went wrong with the
passing of credentials in the bind operation. However, there is no point in
dealing with that unless we have to.
Joe K.
--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
--
"clarkd4" wrote in message
news:A4554819-3951-4FDC-94B6-1FD36A4D5568@microsoft.com...
> Please excuse the long post. I hope I have provided enough background.
>
> I have an application that applies security-group based authorization
> rules.
> It uses CheckTokenMembership for groups that it cares about, using a token
> obtained through LogonUser or via SSPI.
>
> I now have a case where I need to apply these rules in the absence of a
> token. It seems like the most optimal way to do this is to mimic Windows'
> own behavior when creating the list of group SIDs in a login token, and
> then
> use that list for these checks in lieu of CheckTokenMembership.
>
> So, my question is, how is Windows doing this at login time, and/or what
> is
> the most optimal way of computing a user's expanded / transitive security
> group memberships, including local groups?
>
> I'm working in native C++ on Server 2003, supporting both 2003 and 2000
> domains.
>
> There are examples in "The .NET Developer's Guide to Directory Services
> Programming" which illustrate how to compute this (specifically example
> 11.6)
> but it appears as though this results in multiple round-trips to the
> domain
> controller. That seems inefficient, is it really the best way?
>
> I also noticed the "calculated" tokenGroups attribute, but when I do an
> LDAP
> search for that attribute I get a ERROR_DS_OPERATIONS_ERROR. I'm not sure
> what the non-.NET equivalent is to RefreshCache() that is supposed to
> populate this.
>
> Hope someone has been through this before and can point me in the right
> direction. This is code that may execute frequently so I'm looking for
> the
> solution that involves the least number of network round-trips.
>
> Thanks in advance!
>
> Doug
date: Fri, 2 May 2008 10:15:08 -0500
author: Joe Kaplan
Re: Getting all security groups without a token?
Hi Joe,
Awesome. That appears to do exactly what I need. I can use
AuthzInitializeContextFromSid to construct a pseudo-token structure, and then
use AuthzGetInformationFromContext(AuthzContextInfoGroupsSids) in combination
with EqualSid to check group memberships.
Will this work for Windows 2000 domains as well?
I noticed a caution in the notes for AuthzInitializeContextFromSid about
access to the tokenGroupsGlobalAndUniversal attribute. The function is
working fine in my test environment, but what can I tell users to fix when it
returns ACCESS_DENIED? Is that likely to happen if the service is running as
LocalSystem on a domain member?
Thanks so much for your help!
Doug
"Joe Kaplan" wrote:
> Hi Doug,
>
> If you were already using the NT token-based APIs for doing this type of
> thing you might be interested in the Authz APIs that provide some functional
> equivalents without the requirement of getting a kernel mode login token for
> the user.
>
> You might start with the various AuthZInitializeContextxxxx functions to see
> if they get you going in the direction you want.
>
> Under the hood, the code will still end up querying the directory to get the
> user's group membership (it uses tokenGroupsGlobalAndUniversal instead of
> tokenGroups, so you won't get any DLGs this way). Authz uses RPC APIs
> instead of LDAP to do the query, but the overall results are similar, just
> the wire traffic is different.
>
> If you can avoid doing the LDAP query, that is probably easiest.
>
> I'm sure we can fix the operations error if you need to as that is usually
> just the result of binding to the directory as the anonymous user instead of
> a valid one which typically results from something that went wrong with the
> passing of credentials in the bind operation. However, there is no point in
> dealing with that unless we have to.
>
> Joe K.
> --
> Joe Kaplan-MS MVP Directory Services Programming
> Co-author of "The .NET Developer's Guide to Directory Services Programming"
> http://www.directoryprogramming.net
date: Fri, 2 May 2008 10:09:01 -0700
author: clarkd4
Re: Getting all security groups without a token?
I think this will work on a Win2K domain although I don't know if these APIs
are backported to Win2K, so you might want to check that. Hopefully your
code won't be running on Win2K.
Regarding access to this attribute, it is normal to have read access to it
for authenticated users (which should apply to local system on a domain
member machine as it will auth to AD as the computer account for the member
server). From what I've seen, you only tend to have access issues if the
domain was set up to not have "authenticated users" in the "pre-win2K
access" group. However, since AD ACLs are so flexible, there are any number
of ways that this access could have been removed. To a certain extent, it
will be on the AD admins of the environment to understand why they have
things a specific way.
Glad that approach looks promising...
Joe K.
--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
--
"clarkd4" wrote in message
news:E64B668B-FF6F-4479-9B7F-857B64B5BEC0@microsoft.com...
> Hi Joe,
>
> Awesome. That appears to do exactly what I need. I can use
> AuthzInitializeContextFromSid to construct a pseudo-token structure, and
> then
> use AuthzGetInformationFromContext(AuthzContextInfoGroupsSids) in
> combination
> with EqualSid to check group memberships.
>
> Will this work for Windows 2000 domains as well?
>
> I noticed a caution in the notes for AuthzInitializeContextFromSid about
> access to the tokenGroupsGlobalAndUniversal attribute. The function is
> working fine in my test environment, but what can I tell users to fix when
> it
> returns ACCESS_DENIED? Is that likely to happen if the service is running
> as
> LocalSystem on a domain member?
>
> Thanks so much for your help!
>
> Doug
>
> "Joe Kaplan" wrote:
>
>> Hi Doug,
>>
>> If you were already using the NT token-based APIs for doing this type of
>> thing you might be interested in the Authz APIs that provide some
>> functional
>> equivalents without the requirement of getting a kernel mode login token
>> for
>> the user.
>>
>> You might start with the various AuthZInitializeContextxxxx functions to
>> see
>> if they get you going in the direction you want.
>>
>> Under the hood, the code will still end up querying the directory to get
>> the
>> user's group membership (it uses tokenGroupsGlobalAndUniversal instead of
>> tokenGroups, so you won't get any DLGs this way). Authz uses RPC APIs
>> instead of LDAP to do the query, but the overall results are similar,
>> just
>> the wire traffic is different.
>>
>> If you can avoid doing the LDAP query, that is probably easiest.
>>
>> I'm sure we can fix the operations error if you need to as that is
>> usually
>> just the result of binding to the directory as the anonymous user instead
>> of
>> a valid one which typically results from something that went wrong with
>> the
>> passing of credentials in the bind operation. However, there is no point
>> in
>> dealing with that unless we have to.
>>
>> Joe K.
>> --
>> Joe Kaplan-MS MVP Directory Services Programming
>> Co-author of "The .NET Developer's Guide to Directory Services
>> Programming"
>> http://www.directoryprogramming.net
>
date: Fri, 2 May 2008 13:39:47 -0500
author: Joe Kaplan
Re: Getting all security groups without a token?
On May 2, 11:39 am, "Joe Kaplan"
wrote:
> I think this will work on a Win2K domain although I don't know if these APIs
> are backported to Win2K, so you might want to check that. Hopefully your
> code won't be running on Win2K.
>
> Regarding access to this attribute, it is normal to have read access to it> for authenticated users (which should apply to local system on a domain
> member machine as it will auth to AD as the computer account for the member
> server). From what I've seen, you only tend to have access issues if the
> domain was set up to not have "authenticated users" in the "pre-win2K
> access" group. However, since AD ACLs are so flexible, there are any number
> of ways that this access could have been removed. To a certain extent, it
> will be on the AD admins of the environment to understand why they have
> things a specific way.
>
> Glad that approach looks promising...
>
> Joe K.
> --
> Joe Kaplan-MS MVP Directory Services Programming
> Co-author of "The .NET Developer's Guide to Directory Services Programming"http://www.directoryprogramming.net
> --"clarkd4" wrote in message
>
> news:E64B668B-FF6F-4479-9B7F-857B64B5BEC0@microsoft.com...
>
>
>
> > Hi Joe,
>
> > Awesome. That appears to do exactly what I need. I can use
> > AuthzInitializeContextFromSid to construct a pseudo-token structure, and> > then
> > use AuthzGetInformationFromContext(AuthzContextInfoGroupsSids) in
> > combination
> > with EqualSid to check group memberships.
>
> > Will this work for Windows 2000 domains as well?
>
> > I noticed a caution in the notes for AuthzInitializeContextFromSid about> > access to the tokenGroupsGlobalAndUniversal attribute. The function is
> > working fine in my test environment, but what can I tell users to fix when
> > it
> > returns ACCESS_DENIED? Is that likely to happen if the service is running
> > as
> > LocalSystem on a domain member?
>
> > Thanks so much for your help!
>
> > Doug
>
> > "Joe Kaplan" wrote:
>
> >> Hi Doug,
>
> >> If you were already using the NT token-based APIs for doing this type of
> >> thing you might be interested in the Authz APIs that provide some
> >> functional
> >> equivalents without the requirement of getting a kernel mode login token
> >> for
> >> the user.
>
> >> You might start with the various AuthZInitializeContextxxxx functions to
> >> see
> >> if they get you going in the direction you want.
>
> >> Under the hood, the code will still end up querying the directory to get
> >> the
> >> user's group membership (it uses tokenGroupsGlobalAndUniversal instead of
> >> tokenGroups, so you won't get any DLGs this way). Authz uses RPC APIs
> >> instead of LDAP to do the query, but the overall results are similar,
> >> just
> >> the wire traffic is different.
>
> >> If you can avoid doing the LDAP query, that is probably easiest.
>
> >> I'm sure we can fix the operations error if you need to as that is
> >> usually
> >> just the result of binding to the directory as the anonymous user instead
> >> of
> >> a valid one which typically results from something that went wrong with> >> the
> >> passing of credentials in the bind operation. However, there is no point
> >> in
> >> dealing with that unless we have to.
>
> >> Joe K.
> >> --
> >> Joe Kaplan-MS MVP Directory Services Programming
> >> Co-author of "The .NET Developer's Guide to Directory Services
> >> Programming"
> >>http://www.directoryprogramming.net- Hide quoted text -
>
> - Show quoted text -
The AuthZ API will work on Windows 2000 domains, but it might behave a
bit differently so pay close attention. On Win2k3 the underlying
mechanism is Kerberos S4U to do the group expansion while on Win2k
domains it uses a legacy mechanism. There are subtle differences
between the two, mostly having to do with which domain the operation
is performed relative to in multi-domain environments where the server
that you will be calling the API and the user who is the subject of
the API are in different domains. In this scenario the domain local
groups are expanded relative to the server's domain in the S4U case
and to the user's domain in the Win2k mechanism case.
Dave
date: Mon, 12 May 2008 11:50:52 -0700 (PDT)
author: DaveMo
|
|