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.
41 #define _CRT_SECURE_NO_DEPRECATE 1
47 #include <isc/ntgroups.h>
48 #include <isc/result.h>
50 #define MAX_NAME_LENGTH 256
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
;
59 LPLOCALGROUP_USERS_INFO_0 pBuf
= NULL
;
60 LPGROUP_USERS_INFO_0 pgrpBuf
= NULL
;
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;
69 wchar_t user
[MAX_NAME_LENGTH
];
71 retlen
= mbstowcs(user
, username
, MAX_NAME_LENGTH
);
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
,
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
)
106 * Loop through the entries
109 (i
< dwEntriesRead
&& *totalGroups
< maxgroups
); i
++) {
110 assert(pTmpLBuf
!= NULL
);
111 if (pTmpLBuf
== NULL
)
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
]);
128 /* Free the allocated memory. */
130 NetApiBufferFree(pBuf
);
134 * Call the NetUserGetGroups function, specifying level 0.
136 nStatus
= NetUserGetGroups(NULL
,
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
)
155 if (pgrpBuf
!= NULL
) {
158 * Loop through the entries
161 (i
< dwEntriesRead
&& *totalGroups
< maxgroups
); i
++) {
162 assert(pTmpBuf
!= NULL
);
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
]);
182 * Free the allocated memory.
185 NetApiBufferFree(pgrpBuf
);
187 return (ISC_R_SUCCESS
);