mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-10-21 14:39:03 +00:00
176 lines
4.9 KiB
C
176 lines
4.9 KiB
C
![]() |
/*
|
||
|
* Copyright (C) 2001 Internet Software Consortium.
|
||
|
*
|
||
|
* Permission to use, copy, modify, and distribute this software for any
|
||
|
* purpose with or without fee is hereby granted, provided that the above
|
||
|
* copyright notice and this permission notice appear in all copies.
|
||
|
*
|
||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
|
||
|
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||
|
* INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||
|
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
|
||
|
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||
|
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
||
|
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||
|
*/
|
||
|
|
||
|
/* $Id: ntgroups.c,v 1.1 2001/09/25 01:37:02 mayer Exp $ */
|
||
|
|
||
|
/*
|
||
|
* The NT Groups have two groups that are not well documented and are not
|
||
|
* normally seen: None and Everyone.
|
||
|
* A user account belongs to any number of groups, but if it is not a
|
||
|
* member of any group then it is a member of the None Group. The None
|
||
|
* group is not listed anywhere. You cannot remove an account from the
|
||
|
* none group except by making it a member of some other group,
|
||
|
* The second group is the Everyone group. All accounts, no matter how many
|
||
|
* groups that they belong to, also belong to the Everyone group. You
|
||
|
* cannot remove an account from the Everyone group.
|
||
|
*/
|
||
|
|
||
|
#ifndef UNICODE
|
||
|
#define UNICODE
|
||
|
#endif // UNICODE
|
||
|
|
||
|
#include <windows.h>
|
||
|
#include <assert.h>
|
||
|
#include <lm.h>
|
||
|
|
||
|
#include <isc/ntgroups.h>
|
||
|
|
||
|
#define MAX_NAME_LENGTH 25
|
||
|
|
||
|
#ifndef STATUS_SUCCESS
|
||
|
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
|
||
|
#endif
|
||
|
|
||
|
int
|
||
|
isc_ntsecurity_getaccountgroups(char *username, char **GroupList,
|
||
|
unsigned int maxgroups,
|
||
|
unsigned int *totalGroups) {
|
||
|
LPGROUP_USERS_INFO_0 pTmpBuf;
|
||
|
LPLOCALGROUP_USERS_INFO_0 pTmpLBuf;
|
||
|
DWORD i;
|
||
|
LPLOCALGROUP_USERS_INFO_0 pBuf = NULL;
|
||
|
LPGROUP_USERS_INFO_0 pgrpBuf = NULL;
|
||
|
DWORD dwLevel = 0;
|
||
|
DWORD dwFlags = LG_INCLUDE_INDIRECT;
|
||
|
DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH;
|
||
|
DWORD dwEntriesRead = 0;
|
||
|
DWORD dwTotalEntries = 0;
|
||
|
NET_API_STATUS nStatus;
|
||
|
DWORD dwTotalCount = 0;
|
||
|
int retlen;
|
||
|
wchar_t *user = (wchar_t *)malloc(MAX_NAME_LENGTH*sizeof(wchar_t) + 1);
|
||
|
|
||
|
retlen = mbstowcs(user, username, MAX_NAME_LENGTH);
|
||
|
|
||
|
*totalGroups = 0;
|
||
|
/*
|
||
|
* Call the NetUserGetLocalGroups function
|
||
|
* specifying information level 0.
|
||
|
*
|
||
|
* The LG_INCLUDE_INDIRECT flag specifies that the
|
||
|
* function should also return the names of the local
|
||
|
* groups in which the user is indirectly a member.
|
||
|
*/
|
||
|
nStatus = NetUserGetLocalGroups(NULL,
|
||
|
user,
|
||
|
dwLevel,
|
||
|
dwFlags,
|
||
|
(LPBYTE *) &pBuf,
|
||
|
dwPrefMaxLen,
|
||
|
&dwEntriesRead,
|
||
|
&dwTotalEntries);
|
||
|
/*
|
||
|
* If the call succeeds,
|
||
|
*/
|
||
|
if (nStatus != NERR_Success) {
|
||
|
return (nStatus);
|
||
|
}
|
||
|
dwTotalCount = 0;
|
||
|
if ((pTmpLBuf = pBuf) != NULL) {
|
||
|
/*
|
||
|
* Loop through the entries
|
||
|
*/
|
||
|
for (i = 0;
|
||
|
(i < dwEntriesRead && *totalGroups < maxgroups); i++) {
|
||
|
assert(pTmpLBuf != NULL);
|
||
|
if (pTmpLBuf == NULL) {
|
||
|
break;
|
||
|
}
|
||
|
retlen = wcslen(pTmpLBuf->lgrui0_name);
|
||
|
GroupList[*totalGroups] = (char *) malloc(retlen +1);
|
||
|
retlen = wcstombs(GroupList[*totalGroups],
|
||
|
pTmpLBuf->lgrui0_name, retlen);
|
||
|
GroupList[*totalGroups][retlen] = '\0';
|
||
|
if(strcmp(GroupList[*totalGroups], "None") == 0) {
|
||
|
free(GroupList[*totalGroups]);
|
||
|
}
|
||
|
else {
|
||
|
(*totalGroups)++;
|
||
|
}
|
||
|
pTmpLBuf++;
|
||
|
}
|
||
|
}
|
||
|
/* Free the allocated memory. */
|
||
|
if (pBuf != NULL)
|
||
|
NetApiBufferFree(pBuf);
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Call the NetUserGetGroups function, specifying level 0.
|
||
|
*/
|
||
|
nStatus = NetUserGetGroups(NULL,
|
||
|
user,
|
||
|
dwLevel,
|
||
|
(LPBYTE*)&pgrpBuf,
|
||
|
dwPrefMaxLen,
|
||
|
&dwEntriesRead,
|
||
|
&dwTotalEntries);
|
||
|
/*
|
||
|
* If the call succeeds,
|
||
|
*/
|
||
|
if (nStatus != NERR_Success) {
|
||
|
return (nStatus);
|
||
|
}
|
||
|
|
||
|
if ((pTmpBuf = pgrpBuf) != NULL) {
|
||
|
/*
|
||
|
* Loop through the entries
|
||
|
*/
|
||
|
for (i = 0;
|
||
|
(i < dwEntriesRead && *totalGroups < maxgroups); i++) {
|
||
|
assert(pTmpBuf != NULL);
|
||
|
|
||
|
if (pTmpBuf == NULL) {
|
||
|
break;
|
||
|
}
|
||
|
retlen = wcslen(pTmpBuf->grui0_name);
|
||
|
GroupList[*totalGroups] = (char *) malloc(retlen +1);
|
||
|
retlen = wcstombs(GroupList[*totalGroups],
|
||
|
pTmpBuf->grui0_name, retlen);
|
||
|
GroupList[*totalGroups][retlen] = '\0';
|
||
|
|
||
|
if(strcmp(GroupList[*totalGroups], "None") == 0) {
|
||
|
free(GroupList[*totalGroups]);
|
||
|
}
|
||
|
else {
|
||
|
(*totalGroups)++;
|
||
|
}
|
||
|
pTmpBuf++;
|
||
|
}
|
||
|
}
|
||
|
/*
|
||
|
* Free the allocated memory.
|
||
|
*/
|
||
|
if (pgrpBuf != NULL)
|
||
|
NetApiBufferFree(pgrpBuf);
|
||
|
|
||
|
if(user != NULL)
|
||
|
free(user);
|
||
|
|
||
|
return (0);
|
||
|
}
|