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