85int _wcsicmp(
const wchar_t *,
const wchar_t *);
114 len = LsaStr.Length /
sizeof(WCHAR) + 1;
118 target = (
char *)
xmalloc(len);
123 WideCharToMultiByte(CP_ACP, 0, LsaStr.Buffer, LsaStr.Length, target, len,
nullptr,
nullptr);
126 target[len - 1] =
'\0';
133 LSA_HANDLE PolicyHandle;
134 LSA_OBJECT_ATTRIBUTES ObjectAttributes;
136 PPOLICY_PRIMARY_DOMAIN_INFO ppdiDomainInfo;
137 PWKSTA_INFO_100 pwkiWorkstationInfo;
139 char *DomainName =
nullptr;
144 memset(&ObjectAttributes,
'\0',
sizeof(ObjectAttributes));
153 netret = NetWkstaGetInfo(
nullptr, 100, (LPBYTE *) & pwkiWorkstationInfo);
154 if (netret == NERR_Success) {
162 status = LsaOpenPolicy(
165 GENERIC_READ | POLICY_VIEW_LOCAL_INFORMATION,
173 debug(
"OpenPolicy Error: %ld\n", status);
180 status = LsaQueryInformationPolicy(PolicyHandle,
181 PolicyPrimaryDomainInformation,
182 (PVOID *) & ppdiDomainInfo);
184 debug(
"LsaQueryInformationPolicy Error: %ld\n", status);
195 if (ppdiDomainInfo->Sid) {
200 debug(
"Member of Domain %s\n", DomainName);
202 DomainName =
nullptr;
211 NetApiBufferFree(pwkiWorkstationInfo);
212 LsaFreeMemory((LPVOID) ppdiDomainInfo);
214 debug(
"NetWkstaGetInfo Error: %ld\n", netret);
222 WCHAR wszGroup[GNLEN + 1];
225 MultiByteToWideChar(CP_ACP, 0, *array,
226 strlen(*array) + 1, wszGroup,
sizeof(wszGroup) /
sizeof(wszGroup[0]));
227 debug(
"Windows group: %S, Squid group: %S\n", str, wszGroup);
240 char *Domain_Separator;
241 WCHAR wszUserName[UNLEN + 1];
243 LPLOCALGROUP_USERS_INFO_0 pBuf =
nullptr;
244 LPLOCALGROUP_USERS_INFO_0 pTmpBuf;
246 DWORD dwFlags = LG_INCLUDE_INDIRECT;
247 DWORD dwPrefMaxLen = -1;
248 DWORD dwEntriesRead = 0;
249 DWORD dwTotalEntries = 0;
250 NET_API_STATUS nStatus;
252 DWORD dwTotalCount = 0;
254 if ((Domain_Separator = strchr(UserName,
'/')) !=
NULL)
255 *Domain_Separator =
'\\';
257 debug(
"Valid_Local_Groups: checking group membership of '%s'.\n", UserName);
261 MultiByteToWideChar(CP_ACP, 0, UserName,
262 strlen(UserName) + 1, wszUserName,
sizeof(wszUserName) /
sizeof(wszUserName[0]));
272 nStatus = NetUserGetLocalGroups(
284 if (nStatus == NERR_Success) {
285 if ((pTmpBuf = pBuf) !=
NULL) {
286 for (i = 0; i < dwEntriesRead; ++i) {
288 if (pTmpBuf ==
NULL) {
306 NetApiBufferFree(pBuf);
315 WCHAR wszUserName[UNLEN + 1];
317 WCHAR wszLocalDomain[DNLEN + 1];
319 WCHAR wszUserDomain[DNLEN + 1];
321 char NTDomain[DNLEN + UNLEN + 2];
322 char *domain_qualify;
323 char User[UNLEN + 1];
326 LPWSTR LclDCptr =
nullptr;
327 LPWSTR UsrDCptr =
nullptr;
328 LPGROUP_USERS_INFO_0 pUsrBuf =
nullptr;
329 LPGROUP_USERS_INFO_0 pTmpBuf;
330 LPSERVER_INFO_101 pSrvBuf =
nullptr;
332 DWORD dwPrefMaxLen = -1;
333 DWORD dwEntriesRead = 0;
334 DWORD dwTotalEntries = 0;
335 NET_API_STATUS nStatus;
337 DWORD dwTotalCount = 0;
339 xstrncpy(NTDomain, UserName,
sizeof(NTDomain));
345 if (domain_qualify ==
NULL) {
346 xstrncpy(User, NTDomain,
sizeof(User));
349 xstrncpy(User, domain_qualify + 1,
sizeof(User));
350 domain_qualify[0] =
'\0';
354 debug(
"Valid_Global_Groups: checking group membership of '%s\\%s'.\n", NTDomain, User);
358 MultiByteToWideChar(CP_ACP, 0, User,
359 strlen(User) + 1, wszUserName,
360 sizeof(wszUserName) /
sizeof(wszUserName[0]));
362 strlen(
machinedomain) + 1, wszLocalDomain,
sizeof(wszLocalDomain) /
sizeof(wszLocalDomain[0]));
366 nStatus = NetServerGetInfo(
nullptr, dwLevel, (LPBYTE *) & pSrvBuf);
368 if (nStatus == NERR_Success) {
370 if ((pSrvBuf->sv101_type & SV_TYPE_DOMAIN_CTRL) ||
371 (pSrvBuf->sv101_type & SV_TYPE_DOMAIN_BAKCTRL)) {
373 debug(
"Running on a DC.\n");
375 nStatus = (
use_PDC_only ? NetGetDCName(
nullptr, wszLocalDomain, (LPBYTE *) & LclDCptr) : NetGetAnyDCName(
nullptr, wszLocalDomain, (LPBYTE *) & LclDCptr));
377 fprintf(stderr,
"%s: ERROR: NetServerGetInfo() failed.'\n",
program_name);
379 NetApiBufferFree(pSrvBuf);
383 if (nStatus == NERR_Success) {
384 debug(
"Using '%S' as DC for '%S' local domain.\n", LclDCptr, wszLocalDomain);
387 MultiByteToWideChar(CP_ACP, 0, NTDomain,
388 strlen(NTDomain) + 1, wszUserDomain,
sizeof(wszUserDomain) /
sizeof(wszUserDomain[0]));
389 nStatus = (
use_PDC_only ? NetGetDCName(LclDCptr, wszUserDomain, (LPBYTE *) & UsrDCptr) : NetGetAnyDCName(LclDCptr, wszUserDomain, (LPBYTE *) & UsrDCptr));
390 if (nStatus != NERR_Success) {
391 fprintf(stderr,
"%s: ERROR: Can't find DC for user's domain '%s'\n",
program_name, NTDomain);
393 NetApiBufferFree(pSrvBuf);
394 if (LclDCptr !=
NULL)
395 NetApiBufferFree((LPVOID) LclDCptr);
396 if (UsrDCptr !=
NULL)
397 NetApiBufferFree((LPVOID) UsrDCptr);
403 debug(
"Using '%S' as DC for '%s' user's domain.\n", UsrDCptr, NTDomain);
409 nStatus = NetUserGetGroups(UsrDCptr,
412 (LPBYTE *) & pUsrBuf,
419 if (nStatus == NERR_Success) {
420 if ((pTmpBuf = pUsrBuf) !=
NULL) {
421 for (i = 0; i < dwEntriesRead; ++i) {
423 if (pTmpBuf ==
NULL) {
437 fprintf(stderr,
"%s: ERROR: NetUserGetGroups() failed.'\n",
program_name);
446 NetApiBufferFree(pSrvBuf);
448 NetApiBufferFree(pUsrBuf);
449 if ((UsrDCptr !=
NULL) && (UsrDCptr != LclDCptr))
450 NetApiBufferFree((LPVOID) UsrDCptr);
451 if (LclDCptr !=
NULL)
452 NetApiBufferFree((LPVOID) LclDCptr);
459 fprintf(stderr,
"Usage: %s [-D domain][-G][-P][-c][-d][-h]\n"
460 " -D default user Domain\n"
461 " -G enable Domain Global group mode\n"
462 " -P use ONLY PDCs for group validation\n"
463 " -c use case insensitive compare\n"
464 " -d enable debugging\n"
465 " -h this message\n",
475 while (-1 != (opt =
getopt(argc, argv,
"D:GPcdh"))) {
500 fprintf(stderr,
"%s: FATAL: Unknown option: -%c. Exiting\n",
program_name, opt);
516 const char *groups[512];
528 setbuf(stdout,
nullptr);
529 setbuf(stderr,
nullptr);
536 fprintf(stderr,
"%s: FATAL: Can't read machine domain\n",
program_name);
543 debug(
"%s " VERSION " " SQUID_BUILD_INFO
" starting up...\n", argv[0]);
545 debug(
"Domain Global group mode enabled using '%s' as default domain.\n",
DefaultDomain);
548 debug(
"Warning: running in case insensitive mode !!!\n");
551 debug(
"Warning: using only PDCs for group validation !!!\n");
556 if (
NULL == strchr(buf,
'\n')) {
558 debug(
"%s: ERROR: Too large: %s\n", argv[0], buf);
560 debug(
"%s: ERROR: Too large..: %s\n", argv[0], buf);
561 if (strchr(buf,
'\n') !=
NULL)
567 if ((p = strchr(buf,
'\n')) !=
NULL)
569 if ((p = strchr(buf,
'\r')) !=
NULL)
572 debug(
"Got '%s' from Squid (length: %d).\n", buf, strlen(buf));
574 if (buf[0] ==
'\0') {
578 username = strtok(buf,
" ");
579 for (n = 0; (group = strtok(
nullptr,
" ")) !=
NULL; ++n) {
585 if (
NULL == username) {
#define HELPER_INPUT_BUFFER
void debug(const char *format,...)
int main(int argc, char *argv[])
static int wcstrcmparray(const wchar_t *str, const char **array)
char * AllocStrFromLSAStr(LSA_UNICODE_STRING LsaStr)
const char NTV_VALID_DOMAIN_SEPARATOR[]
void process_options(int argc, char *argv[])
char * GetDomainName(void)
int use_case_insensitive_compare
int Valid_Global_Groups(char *UserName, const char **Groups)
int Valid_Local_Groups(char *UserName, const char **Groups)
const char * program_name
static void usage(const char *program)
int getopt(int nargc, char *const *nargv, const char *ostr)
std::vector< ServiceGroupPointer > Groups
void rfc1738_unescape(char *url)
char * xstrncpy(char *dst, const char *src, size_t n)
char * xstrndup(const char *s, size_t n)