I am trying to get both the username and the group(s) of the user currently
logged on a Win NT system. In MSDN I found GetUserName which returns the
user name (as a char *). How can I get the group or groups of which the user
is a member ?
Thanks,
Christian
Here's a sketch to get you started...
SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;
BOOL fAdmin;
HANDLE hThread;
TOKEN_GROUPS *ptg = NULL;
DWORD cbTokenGroups;
DWORD dwGroup;
// Get a handle to either the current thread.
//
if (OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hThread))
// Then we must query the size of the group information associated with
// the token. Note that we expect a FALSE result from GetTokenInformation
// because we've given it a NULL buffer. On exit cbTokenGroups will tell
// the size of the group information.
//
if (GetTokenInformation(hThread, TokenGroups, NULL, 0, &cbTokenGroups))
// Now we allocate a buffer for the group information.
//
ptg = (TOKEN_GROUPS *)malloc(cbTokenGroups);
// Now we ask for the group information again. This may fail if an
administrator
// has added this account to an additional group between our first call to
// GetTokenInformation() and this one...
//
if (GetTokenInformation(hThread, TokenGroups, ptg, cbTokenGroups,
&cbTokenGroups))
{
// Fetch the account names for all the SIDs.
for (dwGroup = 0;dwGroup < ptg->GroupCount;dwGroup++)
{
SID_NAME_USE snu;
TCHAR szName[ACCOUNT_NAME_STRING],
szDomainName[ACCOUNT_NAME_STRING];
DWORD dwSizeofName = sizeof(szName);
DWORD dwSizeofDomainName = sizeof(szDomainName);
if (LookupAccountSid(NULL, ptg->Groups[dwGroup].Sid, szName,
&dwSizeofName, szDomainName, &dwSizeofDomainName, &snu))
{
printf("szName=%s\n", szName);
}
}
}
I see you've already gotten one followup telling about a method that
involves inspecting the DACL and such in the current process token.
I'd _strongly_ advise ignoring it. It's MUCH better to simply call
NetUserGetLocalGroups and/or NetUserGetGroups. The former tells you
about groups on the local machine while the latter tells you about
groups on the domain controller, if you're using one.
--
Later,
Jerry.
The universe is a figment of its own imagination.
"Jerry Coffin" <jco...@taeus.com> wrote in message
news:MPG.13e6216b5...@news.mindspring.com...
Unconviced. Results in my current session (including LG_INCLUDE_INDIRECT
passed to NetUserGetLocalGroups()) are:
Working from process token:
Domain Users
Everyone
Users
Administrators
Domain Admins
LOCAL
INTERACTIVE
Authenticated Users
Working from NetUserGetGroups():
Working from NetUserGetLocalGroups():
Users
Administrators
T
[ ... ]
> Unconviced. Results in my current session (including LG_INCLUDE_INDIRECT
> passed to NetUserGetLocalGroups()) are:
>
> Working from process token:
[ ... a bunch of things, most of them not even real groups at all. ]
> Working from NetUserGetGroups():
>
> Working from NetUserGetLocalGroups():
> Users
> Administrators
This, of course, is precisely why you should NOT work from the
process token: doing so says you're a member of a LOT of groups of
which you're really NOT a member at all. In fact, quite a few of
those (e.g. "Everyone" aren't really groups at all). You've
demonstrated that your program gives incorrect and misleading
information; how is it that you remain unconvinced that it's the
wrong way to do things?
Granted, if you don't think 'Domain Admins', 'Domain Users' are useful
to know about. According to User Manager on the PDC they're groups and
I am definately a member of each.
Clearly LOCAL, INTERACTIVE and 'Authenticated Users' are artifical
additions, but then again if I were writing a program which needed
to know about them...
>
> demonstrated that your program gives incorrect and misleading
> information; how is it that you remain unconvinced that it's the
> wrong way to do things?
>
I doubt the information provided by either method is incorrect or
misleading, we just need to be clear what it means.
The approach you outline basically assumes you use the accounting
information available via the Net* functions to _duplicate_the_work_
the O/S does in building the token assigned to your shell on login.
Richard Ward wrote:
>
> Actually, NetUserGetLocalGroups / NetUserGetGroups
> do *not* handle nested or universal groups in windows 2000
> native domains. Enumerating the SIDs from the token is
> the only reliable way.
>
As Richard points out, there are significant things not covered
by the Net* APIs, i.e. MS are free to change the way the token
is built.
In addition, the system may include a non default GINA which is
also free to modify the token during session creation.
Sorry <G>, the more I think about it the more drawbacks there are
to using the Net functions for this. Use the token, Luke.
T
The original question was about what groups the user was a member of.
Yes, if you want to know something else entirely, then you probably
want to use a different sort of program to find it.
> > demonstrated that your program gives incorrect and misleading
> > information; how is it that you remain unconvinced that it's the
> > wrong way to do things?
> >
>
> I doubt the information provided by either method is incorrect or
> misleading, we just need to be clear what it means.
As an answer to the question that was originally asked, the results
are clearly incorect and misleading. Your results might be a useful
answer to some othe question, but if so, it seems to be a question
nobody's asked, or is interested in asking.
[ ... ]
> > Actually, NetUserGetLocalGroups / NetUserGetGroups
> > do *not* handle nested or universal groups in windows 2000
> > native domains. Enumerating the SIDs from the token is
> > the only reliable way.
> >
> As Richard points out, there are significant things not covered
> by the Net* APIs, i.e. MS are free to change the way the token
> is built.
Again, this is basically about a different question than the OP
asked. He asked what groups the user is a member of. He did NOT
asked about what groups THOSE groups are members of. It's barely
possible that what he really wanted was to know about the effective
rights granted to the user, which is basically what you reccommended
finding. If so, there's little question that doing so via the
process token is the way to do the job. OTOH, if he wants an answer
to the question he asked, the process token is NOT the way to do the
job: it gives information that's basically inaccurate and misleading.
> In addition, the system may include a non default GINA which is
> also free to modify the token during session creation.
Quite true. This does NOT, however, mean the user is a member of any
other groups. IOW, you've cited yet another reason that the method
you're advocating is a BAD answer to the question.
> Sorry <G>, the more I think about it the more drawbacks there are
> to using the Net functions for this. Use the token, Luke.
Funny, but looking back at the question that was asked, and looking
at exactly what you presented, I draw precisely the opposite
conclusion. If you want to know about group membership, do the job
right and use the Net* functions that give you _exactl_ that.
If you want to know something else entirely, such as rights available
to the user as currently logged in, then yes, the process token will
tell you that.
Your answer is a bit like somebody asking how much you weigh, and
your replying by telling them how much weight you can lift. Your
size is probably a factor in determining how much you can lift, but
telling them how much you can lift really isn't answering their
question. You might consider how much you can lift a more important
question, but it's not the one they asked.