Sign in with
Sign up | Sign in
Your question

Check SID for GROUP membership

Last response: in Windows 2000/NT
Share
Anonymous
a b 8 Security
January 4, 2005 6:37:21 PM

Archived from groups: microsoft.public.win2000.security (More info?)

I'm looking for a way to compare two SIDs: the primary SID being a user
SID, and the secondary SID being either a user or group SID. So, if the
secondary SID is a group, I need to know if the primary SID is a member
of that group.

I've thought about using CheckTokenMembership(), but I don't have a
handle to an access token! Furthermore, I do not know how to get one
without creating a thread or process, because (1) I don't have the
passwords for either SID to use LogonUser(), and (2) I do not wish to
create a process/thread for the mere sake of checking SID
relationships.

If anyone could at least point in me in the right direction, this would
be appreciated. Thank you.
Anonymous
a b 8 Security
January 5, 2005 1:48:43 AM

Archived from groups: microsoft.public.win2000.security (More info?)

Hey logjam, I am a little lost in understanding just what it
is that you are trying to do.
Yes, I understand :
if PrimSID = SecondSID
return 1
elif PrimSID memberof SecondSID
return 2
else
return 0
OK. But you ask that you seek a way to compare SID,
when in fact it sounds like you seek a way to get the SIDs.

Where are these coming from? For example where you
spoke of examining the token, you would be looking at
the memberships of the SID whose token it is, so why
the need for the compare. Also, it is clear that you need
to do this for an account other than the one in use.

What is it that you are trying to do, under what circumstances,
and in what language? Comparing the SID is simple, but
how do you know what you are wanting to compare?

--
Roger Abell
Microsoft MVP (Windows Security)
MCSE (W2k3,W2k,Nt4) MCDBA
<logjam@arainia.com> wrote in message
news:1104881841.621493.302270@z14g2000cwz.googlegroups.com...
> I'm looking for a way to compare two SIDs: the primary SID being a user
> SID, and the secondary SID being either a user or group SID. So, if the
> secondary SID is a group, I need to know if the primary SID is a member
> of that group.
>
> I've thought about using CheckTokenMembership(), but I don't have a
> handle to an access token! Furthermore, I do not know how to get one
> without creating a thread or process, because (1) I don't have the
> passwords for either SID to use LogonUser(), and (2) I do not wish to
> create a process/thread for the mere sake of checking SID
> relationships.
>
> If anyone could at least point in me in the right direction, this would
> be appreciated. Thank you.
>
January 5, 2005 2:40:30 AM

Archived from groups: microsoft.public.win2000.security (More info?)

Hello Roger:

Thank you for the response. To elaborate on the scenario: I basically
have a client/server app which shares (shall we say) "objects", very
similar to sharing a file via SMB. So in a way, I am trying to mimic a
watered-down version of file sharing. (But instead of files, I am
securing "objects") The administrator defines the users that can access
the objects shared from this server. (This is where that "secondary
SID" comes from) Either being a user SID, or for the sake of
convenience, a group SID. From what I've learned reading MSDN, a SID
can represent a user or a group. Right? (i.e. Administrators, Everyone,
etc.)

The primary SID that I was referring to comes from the client side.
This would always be a user SID. (Since the client was written to
extract the SID of the currently logged in user) But to avoid redundant
password checking or Kerberos authentication, I was hoping I could do a
simple SID comparison to keep things simple. But the problem is that
the comparison is done on the server end, so I cannot evaulate the
client's "access token" without doing some kind of RPC, I imagine.
(Which I'm trying to avoid)

Language used: good 'ol C++

So far, I've conjured this up::

1. Check if secondary SID is user, if so then do a simple SID
comparison; problem solved
2. But if secondary SID is group SID, then somehow enumerate the groups
of the primary user SID to see if the secondary group SID mathces up
anywhere

But what is the best way to enumerate the groups of a user without an
access token? (and using a SID)

I've seen NetUserGetGroups() mentioned a couple of times. I guess I
could convert my SIDs to account names and call this function to
enumerate/compare each group name. But this seems inefficient, or is
this the only way?
Thanks for any information or input.
Kind regards,
Logan
Related resources
Anonymous
a b 8 Security
January 5, 2005 4:41:51 AM

Archived from groups: microsoft.public.win2000.security (More info?)

OK, I think I am sync'd with you now.

Case one, client SID is direct match - no problem.

Next, when not, is client SID member of an allowed
(per admin of your app) group or admin stated allowed
account.

It has been some time since I was doing in C++, but in
langs used of late I would either use client SID to get
the _direct_ group memberships of that account, or
I would iterate through admin defined allowed groups
testing for client. Now, which would depend on which
is shorter - i.e. do you expect only a couple admin def'd
allowed groups ?

See, the issue really is that groups can be nested, so using
the client SID to get its _direct_ group memberships only
gives you the inital list on which you must recurse for each
group its memberships in other groups, appending those to
the list to recurse provided not already on list, in order to
form the closure. Then you could compare to the admin def'd
groups. Note that if you are writing this for the general case,
a multi-domain, and potentially trusting multi-forest, environ
then this is non-trivial.

After considering that, it seems likely that it may be more
efficient to work from the other end. At startup is it feasible
for your app to compile the admin def'd groups into a hash
table of account (no groups) SIDs. Would that be a reasonably
small struct? Then the response would be near immediate on
client request - is client SID in hash? y/n
However, if one went this route then one would want to be
able the signal the app to recompile so admin defs of groups
allowed and/or memberships in those could be changed.

Now, what I believe would be the best way to do this is to
leverage the security system of the OS - in other words to
use what you said you wanted to avoid in hopes of overhead
conservation (but notice, no new authentication is needed).
If you could ACL your service, or componentize it so COM+
security could be applied to it, or include your unmanaged code
in .Net wrappering so .Net security could be applied to the
assembly, then you only need to train the admins on how to
allow groups and the system would handle making sure that
the client token allows the access. Now, if the clients are not
in the same security realm (domain, forest, . . .) then you have
issues that may prevent you from going this route.

? Have you looked at what can be done in .Net for remote
instancing of objects and marshalling back/forth with client?

--
Roger Abell
Microsoft MVP (Windows Security)
MCSE (W2k3,W2k,Nt4) MCDBA
"Logan" <logjam@arainia.com> wrote in message
news:1104910830.760416.323160@c13g2000cwb.googlegroups.com...
> Hello Roger:
>
> Thank you for the response. To elaborate on the scenario: I basically
> have a client/server app which shares (shall we say) "objects", very
> similar to sharing a file via SMB. So in a way, I am trying to mimic a
> watered-down version of file sharing. (But instead of files, I am
> securing "objects") The administrator defines the users that can access
> the objects shared from this server. (This is where that "secondary
> SID" comes from) Either being a user SID, or for the sake of
> convenience, a group SID. From what I've learned reading MSDN, a SID
> can represent a user or a group. Right? (i.e. Administrators, Everyone,
> etc.)
>
> The primary SID that I was referring to comes from the client side.
> This would always be a user SID. (Since the client was written to
> extract the SID of the currently logged in user) But to avoid redundant
> password checking or Kerberos authentication, I was hoping I could do a
> simple SID comparison to keep things simple. But the problem is that
> the comparison is done on the server end, so I cannot evaulate the
> client's "access token" without doing some kind of RPC, I imagine.
> (Which I'm trying to avoid)
>
> Language used: good 'ol C++
>
> So far, I've conjured this up::
>
> 1. Check if secondary SID is user, if so then do a simple SID
> comparison; problem solved
> 2. But if secondary SID is group SID, then somehow enumerate the groups
> of the primary user SID to see if the secondary group SID mathces up
> anywhere
>
> But what is the best way to enumerate the groups of a user without an
> access token? (and using a SID)
>
> I've seen NetUserGetGroups() mentioned a couple of times. I guess I
> could convert my SIDs to account names and call this function to
> enumerate/compare each group name. But this seems inefficient, or is
> this the only way?
> Thanks for any information or input.
> Kind regards,
> Logan
>
January 5, 2005 8:09:48 PM

Archived from groups: microsoft.public.win2000.security (More info?)

I sincerely appreciate your time, information, and suggestions.

Pertaining to .NET, I would love to take advantage of its high-level
conveniences, but unfortunately our target environments are not
guaranteed to have the framework installed! Nor have we decided to
include its dependency with the installation......

I would like to avoid RPCs (i.e. via COM+) or remote services, if
possible.

I agree with you, the evaluation should probably be done on the client
end. At least at this point I could use the "access token" of the user
logged in, then CheckTokenInformation() on each SID? From what I
understand, CheckTokenInformation() will automatically evaluate
sub-groups, if I'm not mistaken.
!