[prev in list] [next in list] [prev in thread] [next in thread]
List: apr-dev
Subject: Re: Getting the groups a user belongs to
From: William R Speirs <bill.speirs () gmail ! com>
Date: 2010-12-23 21:08:38
Message-ID: 4D13BA56.4030603 () gmail ! com
[Download RAW message or body]
I took a first stab at the Windows code for this... it's ugly. There is a lot of
apr_wchar_t* <-> char* conversion code. Is there an easier way to do this?
If not, then maybe it would be helpful to create two functions with the
following signatures that do all of the string length and allocation work for you:
apr_wchar_t* apr_conv_utf8_to_ucs2(char *str, apr_pool_t *p);
char* apr_conv_ucs2_to_utf8(apr_wchar_t *str, apr_pool_t *p);
Here is my code, not sure if this name is 100% consistent with the rest of the
codebase:
APR_DECLARE(apr_status_t) apr_uid_groups_get(apr_gid_t **groups, int *ngroup,
const char *username, apr_pool_t *p)
{
#ifdef _WIN32_WCE
return APR_ENOTIMPL;
#else
GROUP_USERS_INFO_0 *pGroups = NULL;
DWORD entriesRead = 0;
DWORD totalEntries = 0;
NET_API_STATUS status;
FIXED_INFO *pFixedInfo = NULL;
ULONG infoSize = 0;
DWORD i;
apr_wchar_t *wUsername;
apr_size_t wUsernameLen;
apr_wchar_t *fullDomain;
apr_size_t fullDomainLen;
apr_size_t domainLen;
char *groupName;
// first call is to get the size
status = GetNetworkParams(pFixedInfo, &infoSize);
pFixedInfo = (FIXED_INFO*)apr_palloc(p, infoSize);
// now make the actual call
status = GetNetworkParams(pFixedInfo, &infoSize);
// printf("DOMAIN: %s\n", pFixedInfo->DomainName);
if(NERR_Success != status)
return APR_EINVAL;
// convert the username to an apr_wchar_t
domainLen = lstrlen(username); // re-use of var here
wUsernameLen = lstrlen(username) * sizeof(apr_wchar_t);
wUsername = (apr_wchar_t*)apr_palloc(p, wUsernameLen);
apr_conv_utf8_to_ucs2(username, &domainLen, wUsername, &wUsernameLen);
// get the length of the domain string
domainLen = lstrlenA(pFixedInfo->DomainName);
// if there is no domain name, then get local groups
if(0 == domainLen) {
// printf("NO DOMAIN\n");
status = NetUserGetLocalGroups(NULL, wUsername, 0,
LG_INCLUDE_INDIRECT,
(LPBYTE*) &pGroups,
MAX_PREFERRED_LENGTH,
&entriesRead, &totalEntries);
if(NERR_Success != status) {
NetApiBufferFree(pGroups);
return APR_EINVAL;
}
} else { // we have a domain, get those groups
domainLen = lstrlen(pFixedInfo->DomainName);
fullDomainLen = (2 + domainLen) * sizeof(apr_wchar_t);
fullDomain = (apr_wchar_t*)apr_palloc(p, fullDomainLen);
// add the \\ to the start of the domain
fullDomain[0] = '\\';
fullDomain[1] = '\\';
fullDomainLen -= 2;
// convert over to an apr_wchar_t
apr_conv_utf8_to_ucs2(pFixedInfo->DomainName, &domainLen,
fullDomain+2, &fullDomainLen);
status = NetUserGetGroups(fullDomain, wUsername, 0,
(LPBYTE*) &pGroups,
MAX_PREFERRED_LENGTH,
&entriesRead, &totalEntries);
if(NERR_Success != status) {
NetApiBufferFree(pGroups);
return APR_EINVAL;
}
}
// allocate space for all of the apr_gid_t
*groups = (apr_gid_t*)apr_palloc(p, entriesRead);
*ngroup = entriesRead;
// we have all of the groups, but as strings
for(i=0; i < entriesRead; ++i) {
printf("GROUP: %S\n", pGroups[i].grui0_name);
// convert the wchar_t group name to a char* group name
domainLen = lstrlenW(pGroups[i].grui0_name);
wUsernameLen = domainLen * sizeof(char);
groupName = (char*)apr_palloc(p, wUsernameLen);
apr_conv_ucs2_to_utf8(pGroups[i].grui0_name, &domainLen,
groupName, &wUsernameLen);
apr_gid_get(*groups[i], groupName, p);
}
// free the memory associated with the groups
NetApiBufferFree(pGroups);
return APR_SUCCESS;
#endif
}
Thoughts?
Bill-
On 12/13/2010 09:33 AM, Bill Speirs wrote:
>>> The other issue is that on Windows I get back a char* for the groups; whereas, on
>>> Unix/Linux I get back a gid list. Is there a preference? Would people rather a function
>>> that returns a gid list or a char* list?
>>
>> Well, we should treat them as apr_gid_t, which on win32 would devolve to a pointer
>> to a full UUID of the appropriate group (and we then unwind the identifier into a
>> human-readable string with the appropriate apr_group_name_get function).
>
> In Linux this is a non-issue as the function naturally returns
> apr_gid_t; whereas, with Windows I only get back a char* for the
> group. I can call LookupAccountName on each name to get the
> SID/apr_gid_t. If there is a function to get apr_gid_ts for the groups
> a user is a member of, I am unaware of such a function.
>
> Bill-
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic