Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / external / bsd / bind / dist / lib / isc / win32 / ntgroups.c
blob390504a5272066138278ae8a1bce9e64f6f2a8b9
1 /* $NetBSD$ */
3 /*
4 * Copyright (C) 2004, 2006, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 2001 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 /* Id: ntgroups.c,v 1.12 2009/09/29 23:48:04 tbox Exp */
23 * The NT Groups have two groups that are not well documented and are
24 * not normally seen: None and Everyone. A user account belongs to
25 * any number of groups, but if it is not a member of any group then
26 * it is a member of the None Group. The None group is not listed
27 * anywhere. You cannot remove an account from the none group except
28 * by making it a member of some other group, The second group is the
29 * Everyone group. All accounts, no matter how many groups that they
30 * belong to, also belong to the Everyone group. You cannot remove an
31 * account from the Everyone group.
34 #ifndef UNICODE
35 #define UNICODE
36 #endif /* UNICODE */
39 * Silence warnings.
41 #define _CRT_SECURE_NO_DEPRECATE 1
43 #include <windows.h>
44 #include <assert.h>
45 #include <lm.h>
47 #include <isc/ntgroups.h>
48 #include <isc/result.h>
50 #define MAX_NAME_LENGTH 256
52 isc_result_t
53 isc_ntsecurity_getaccountgroups(char *username, char **GroupList,
54 unsigned int maxgroups,
55 unsigned int *totalGroups) {
56 LPGROUP_USERS_INFO_0 pTmpBuf;
57 LPLOCALGROUP_USERS_INFO_0 pTmpLBuf;
58 DWORD i;
59 LPLOCALGROUP_USERS_INFO_0 pBuf = NULL;
60 LPGROUP_USERS_INFO_0 pgrpBuf = NULL;
61 DWORD dwLevel = 0;
62 DWORD dwFlags = LG_INCLUDE_INDIRECT;
63 DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH;
64 DWORD dwEntriesRead = 0;
65 DWORD dwTotalEntries = 0;
66 NET_API_STATUS nStatus;
67 DWORD dwTotalCount = 0;
68 size_t retlen;
69 wchar_t user[MAX_NAME_LENGTH];
71 retlen = mbstowcs(user, username, MAX_NAME_LENGTH);
73 *totalGroups = 0;
75 * Call the NetUserGetLocalGroups function
76 * specifying information level 0.
78 * The LG_INCLUDE_INDIRECT flag specifies that the
79 * function should also return the names of the local
80 * groups in which the user is indirectly a member.
82 nStatus = NetUserGetLocalGroups(NULL,
83 user,
84 dwLevel,
85 dwFlags,
86 (LPBYTE *) &pBuf,
87 dwPrefMaxLen,
88 &dwEntriesRead,
89 &dwTotalEntries);
91 * See if the call succeeds,
93 if (nStatus != NERR_Success) {
94 if (nStatus == ERROR_ACCESS_DENIED)
95 return (ISC_R_NOPERM);
96 if (nStatus == ERROR_MORE_DATA)
97 return (ISC_R_NOSPACE);
98 if (nStatus == NERR_UserNotFound)
99 dwEntriesRead = 0;
102 dwTotalCount = 0;
103 if (pBuf != NULL) {
104 pTmpLBuf = pBuf;
106 * Loop through the entries
108 for (i = 0;
109 (i < dwEntriesRead && *totalGroups < maxgroups); i++) {
110 assert(pTmpLBuf != NULL);
111 if (pTmpLBuf == NULL)
112 break;
113 retlen = wcslen(pTmpLBuf->lgrui0_name);
114 GroupList[*totalGroups] = (char *) malloc(retlen +1);
115 if (GroupList[*totalGroups] == NULL)
116 return (ISC_R_NOMEMORY);
118 retlen = wcstombs(GroupList[*totalGroups],
119 pTmpLBuf->lgrui0_name, retlen);
120 GroupList[*totalGroups][retlen] = '\0';
121 if (strcmp(GroupList[*totalGroups], "None") == 0)
122 free(GroupList[*totalGroups]);
123 else
124 (*totalGroups)++;
125 pTmpLBuf++;
128 /* Free the allocated memory. */
129 if (pBuf != NULL)
130 NetApiBufferFree(pBuf);
134 * Call the NetUserGetGroups function, specifying level 0.
136 nStatus = NetUserGetGroups(NULL,
137 user,
138 dwLevel,
139 (LPBYTE*)&pgrpBuf,
140 dwPrefMaxLen,
141 &dwEntriesRead,
142 &dwTotalEntries);
144 * See if the call succeeds,
146 if (nStatus != NERR_Success) {
147 if (nStatus == ERROR_ACCESS_DENIED)
148 return (ISC_R_NOPERM);
149 if (nStatus == ERROR_MORE_DATA)
150 return (ISC_R_NOSPACE);
151 if (nStatus == NERR_UserNotFound)
152 dwEntriesRead = 0;
155 if (pgrpBuf != NULL) {
156 pTmpBuf = pgrpBuf;
158 * Loop through the entries
160 for (i = 0;
161 (i < dwEntriesRead && *totalGroups < maxgroups); i++) {
162 assert(pTmpBuf != NULL);
164 if (pTmpBuf == NULL)
165 break;
166 retlen = wcslen(pTmpBuf->grui0_name);
167 GroupList[*totalGroups] = (char *) malloc(retlen +1);
168 if (GroupList[*totalGroups] == NULL)
169 return (ISC_R_NOMEMORY);
171 retlen = wcstombs(GroupList[*totalGroups],
172 pTmpBuf->grui0_name, retlen);
173 GroupList[*totalGroups][retlen] = '\0';
174 if (strcmp(GroupList[*totalGroups], "None") == 0)
175 free(GroupList[*totalGroups]);
176 else
177 (*totalGroups)++;
178 pTmpBuf++;
182 * Free the allocated memory.
184 if (pgrpBuf != NULL)
185 NetApiBufferFree(pgrpBuf);
187 return (ISC_R_SUCCESS);