diff --git a/lib/isc/win32/include/isc/ntgroups.h b/lib/isc/win32/include/isc/ntgroups.h new file mode 100644 index 0000000000..55824061ec --- /dev/null +++ b/lib/isc/win32/include/isc/ntgroups.h @@ -0,0 +1,34 @@ +/* + * 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.h,v 1.1 2001/09/25 01:37:02 mayer Exp $ */ + +#ifndef ISC_NTGROUPS_H +#define ISC_NTGROUPS_H 1 + +#include + +ISC_LANG_BEGINDECLS + + +int +isc_ntsecurity_getaccountgroups(char *name, char **Groups, unsigned int maxgroups, + unsigned int *total); + +ISC_LANG_ENDDECLS + +#endif /* ISC_NTGROUPS_H */ diff --git a/lib/isc/win32/ntgroups.c b/lib/isc/win32/ntgroups.c new file mode 100644 index 0000000000..c03192aabb --- /dev/null +++ b/lib/isc/win32/ntgroups.c @@ -0,0 +1,175 @@ +/* + * 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 +#include +#include + +#include + +#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); +}