]> sourceware.org Git - newlib-cygwin.git/blob - winsup/utils/mkgroup.c
* mkgroup.c: Consolidate variable names.
[newlib-cygwin.git] / winsup / utils / mkgroup.c
1 /* mkgroup.c:
2
3 Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
4 2007, 2008 Red Hat, Inc.
5
6 This file is part of Cygwin.
7
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
10 details. */
11
12 #define _WIN32_WINNT 0x0600
13 #include <ctype.h>
14 #include <stdlib.h>
15 #include <wchar.h>
16 #include <wctype.h>
17 #include <stdio.h>
18 #include <unistd.h>
19 #include <getopt.h>
20 #include <io.h>
21 #include <sys/fcntl.h>
22 #include <sys/cygwin.h>
23 #include <windows.h>
24 #include <lm.h>
25 #include <wininet.h>
26 #include <iptypes.h>
27 #include <ntsecapi.h>
28 #include <dsgetdc.h>
29 #include <ntdef.h>
30
31 #define print_win_error(x) _print_win_error(x, __LINE__)
32
33 #define MAX_SID_LEN 40
34
35 static const char version[] = "$Revision$";
36
37 extern char *__progname;
38
39 SID_IDENTIFIER_AUTHORITY sid_world_auth = {SECURITY_WORLD_SID_AUTHORITY};
40 SID_IDENTIFIER_AUTHORITY sid_nt_auth = {SECURITY_NT_AUTHORITY};
41
42 NET_API_STATUS WINAPI (*dsgetdcname)(LPWSTR,LPWSTR,GUID*,LPWSTR,ULONG,PDOMAIN_CONTROLLER_INFOW*);
43
44 #ifndef min
45 #define min(a,b) (((a)<(b))?(a):(b))
46 #endif
47
48 typedef struct
49 {
50 char *str;
51 BOOL with_dom;
52 } domlist_t;
53
54 void
55 _print_win_error (DWORD code, int line)
56 {
57 char buf[4096];
58
59 if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
60 | FORMAT_MESSAGE_IGNORE_INSERTS,
61 NULL,
62 code,
63 MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
64 (LPTSTR) buf, sizeof (buf), NULL))
65 fprintf (stderr, "mkgroup (%d): [%lu] %s", line, code, buf);
66 else
67 fprintf (stderr, "mkgroup (%d): error %lu", line, code);
68 }
69
70 void
71 load_dsgetdcname ()
72 {
73 HANDLE h = LoadLibrary ("netapi32.dll");
74 if (h)
75 dsgetdcname = (void *) GetProcAddress (h, "DsGetDcNameW");
76 }
77
78 static PWCHAR
79 get_dcname (char *domain)
80 {
81 static WCHAR server[INTERNET_MAX_HOST_NAME_LENGTH + 1];
82 DWORD rc;
83 PWCHAR servername;
84 WCHAR domain_name[MAX_DOMAIN_NAME_LEN + 1];
85 PDOMAIN_CONTROLLER_INFOW pdci = NULL;
86
87 if (dsgetdcname)
88 {
89 if (domain)
90 {
91 mbstowcs (domain_name, domain, strlen (domain) + 1);
92 rc = dsgetdcname (NULL, domain_name, NULL, NULL, 0, &pdci);
93 }
94 else
95 rc = dsgetdcname (NULL, NULL, NULL, NULL, 0, &pdci);
96 if (rc != ERROR_SUCCESS)
97 {
98 print_win_error (rc);
99 return (PWCHAR) -1;
100 }
101 wcscpy (server, pdci->DomainControllerName);
102 NetApiBufferFree (pdci);
103 }
104 else
105 {
106 rc = NetGetDCName (NULL, NULL, (void *) &servername);
107 if (rc == ERROR_SUCCESS && domain)
108 {
109 LPWSTR server = servername;
110 mbstowcs (domain_name, domain, strlen (domain) + 1);
111 rc = NetGetDCName (server, domain_name, (void *) &servername);
112 NetApiBufferFree (server);
113 }
114 if (rc != ERROR_SUCCESS)
115 {
116 print_win_error(rc);
117 return (PWCHAR) -1;
118 }
119 wcscpy (server, servername);
120 NetApiBufferFree ((PVOID) servername);
121 }
122 return server;
123 }
124
125 char *
126 put_sid (PSID psid)
127 {
128 static char s[512];
129 char t[32];
130 DWORD i;
131
132 strcpy (s, "S-1-");
133 sprintf(t, "%u", GetSidIdentifierAuthority (psid)->Value[5]);
134 strcat (s, t);
135 for (i = 0; i < *GetSidSubAuthorityCount (psid); ++i)
136 {
137 sprintf(t, "-%lu", *GetSidSubAuthority (psid, i));
138 strcat (s, t);
139 }
140 return s;
141 }
142
143 typedef struct {
144 BYTE Revision;
145 BYTE SubAuthorityCount;
146 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
147 DWORD SubAuthority[8];
148 } DBGSID, *PDBGSID;
149
150 #define MAX_BUILTIN_SIDS 100 /* Should be enough for the forseable future. */
151 DBGSID builtin_sid_list[MAX_BUILTIN_SIDS];
152 DWORD builtin_sid_cnt;
153
154 void
155 enum_unix_groups (domlist_t *dom_or_machine, const char *sep, int id_offset,
156 char *unix_grp_list)
157 {
158 WCHAR machine[INTERNET_MAX_HOST_NAME_LENGTH + 1];
159 PWCHAR servername = NULL;
160 char *d_or_m = dom_or_machine ? dom_or_machine->str : NULL;
161 BOOL with_dom = dom_or_machine ? dom_or_machine->with_dom : FALSE;
162 SID_IDENTIFIER_AUTHORITY auth = { { 0, 0, 0, 0, 0, 22 } };
163 char *gstr, *grp_list;
164 WCHAR grp[GNLEN + sizeof ("Unix Group\\") + 1];
165 WCHAR dom[MAX_DOMAIN_NAME_LEN + 1];
166 DWORD glen, dlen, sidlen;
167 PSID psid;
168 char psid_buffer[MAX_SID_LEN];
169 SID_NAME_USE acc_type;
170
171 if (!d_or_m)
172 return;
173
174 int ret = mbstowcs (machine, d_or_m, INTERNET_MAX_HOST_NAME_LENGTH + 1);
175 if (ret < 1 || ret >= INTERNET_MAX_HOST_NAME_LENGTH + 1)
176 {
177 fprintf (stderr, "%s: Invalid machine name '%s'. Skipping...\n",
178 __progname, d_or_m);
179 return;
180 }
181 servername = machine;
182
183 if (!AllocateAndInitializeSid (&auth, 2, 2, 0, 0, 0, 0, 0, 0, 0, &psid))
184 return;
185
186 if (!(grp_list = strdup (unix_grp_list)))
187 {
188 FreeSid (psid);
189 return;
190 }
191
192 for (gstr = strtok (grp_list, ","); gstr; gstr = strtok (NULL, ","))
193 {
194 if (!isdigit (gstr[0]) && gstr[0] != '-')
195 {
196 PWCHAR p = wcpcpy (grp, L"Unix Group\\");
197 ret = mbstowcs (p, gstr, GNLEN + 1);
198 if (ret < 1 || ret >= GNLEN + 1)
199 fprintf (stderr, "%s: Invalid group name '%s'. Skipping...\n",
200 __progname, gstr);
201 else if (LookupAccountNameW (servername, grp,
202 psid = (PSID) psid_buffer,
203 (sidlen = MAX_SID_LEN, &sidlen),
204 dom,
205 (dlen = MAX_DOMAIN_NAME_LEN + 1, &dlen),
206 &acc_type))
207 printf ("%s%s%ls:%s:%lu:\n",
208 with_dom ? "Unix Group" : "",
209 with_dom ? sep : "",
210 p,
211 put_sid (psid),
212 id_offset +
213 *GetSidSubAuthority (psid,
214 *GetSidSubAuthorityCount(psid) - 1));
215 }
216 else
217 {
218 DWORD start, stop;
219 char *p = gstr;
220 if (*p == '-')
221 start = 0;
222 else
223 start = strtol (p, &p, 10);
224 if (!*p)
225 stop = start;
226 else if (*p++ != '-' || !isdigit (*p)
227 || (stop = strtol (p, &p, 10)) < start || *p)
228 {
229 fprintf (stderr, "%s: Malformed unix group list entry '%s'. "
230 "Skipping...\n", __progname, gstr);
231 continue;
232 }
233 for (; start <= stop; ++ start)
234 {
235 *GetSidSubAuthority (psid, *GetSidSubAuthorityCount(psid) - 1)
236 = start;
237 if (LookupAccountSidW (servername, psid,
238 grp, (glen = GNLEN + 1, &glen),
239 dom,
240 (dlen = MAX_DOMAIN_NAME_LEN + 1, &dlen),
241 &acc_type)
242 && !iswdigit (grp[0]))
243 printf ("%s%s%ls:%s:%lu:\n",
244 with_dom ? "Unix Group" : "",
245 with_dom ? sep : "",
246 grp,
247 put_sid (psid),
248 id_offset + start);
249 }
250 }
251 }
252
253 free (grp_list);
254 FreeSid (psid);
255 }
256
257 int
258 enum_local_groups (BOOL domain, domlist_t *dom_or_machine, const char *sep,
259 int id_offset, char *disp_groupname)
260 {
261 WCHAR machine[INTERNET_MAX_HOST_NAME_LENGTH + 1];
262 PWCHAR servername = NULL;
263 char *d_or_m = dom_or_machine ? dom_or_machine->str : NULL;
264 BOOL with_dom = dom_or_machine ? dom_or_machine->with_dom : FALSE;
265 LOCALGROUP_INFO_0 *buffer;
266 DWORD entriesread = 0;
267 DWORD totalentries = 0;
268 DWORD resume_handle = 0;
269 WCHAR gname[GNLEN + 1];
270 DWORD rc;
271
272 if (domain)
273 {
274 servername = get_dcname (d_or_m);
275 if (servername == (PWCHAR) -1)
276 return 1;
277 }
278 else if (d_or_m)
279 {
280 int ret = mbstowcs (machine, d_or_m, INTERNET_MAX_HOST_NAME_LENGTH + 1);
281 if (ret < 1 || ret >= INTERNET_MAX_HOST_NAME_LENGTH + 1)
282 {
283 fprintf (stderr, "%s: Invalid machine name '%s'. Skipping...\n",
284 __progname, d_or_m);
285 return 1;
286 }
287 servername = machine;
288 }
289
290 do
291 {
292 DWORD i;
293
294 if (disp_groupname != NULL)
295 {
296 mbstowcs (gname, disp_groupname, GNLEN + 1);
297 rc = NetApiBufferAllocate (sizeof (LOCALGROUP_INFO_0),
298 (void *) &buffer);
299 buffer[0].lgrpi0_name = gname;
300 entriesread = 1;
301 }
302 else
303 rc = NetLocalGroupEnum (servername, 0, (void *) &buffer,
304 MAX_PREFERRED_LENGTH, &entriesread,
305 &totalentries, &resume_handle);
306 switch (rc)
307 {
308 case ERROR_ACCESS_DENIED:
309 print_win_error (rc);
310 return 1;
311
312 case ERROR_MORE_DATA:
313 case ERROR_SUCCESS:
314 break;
315
316 default:
317 print_win_error (rc);
318 return 1;
319 }
320
321 for (i = 0; i < entriesread; i++)
322 {
323 WCHAR domain_name[MAX_DOMAIN_NAME_LEN + 1];
324 DWORD domname_len = MAX_DOMAIN_NAME_LEN + 1;
325 char psid_buffer[MAX_SID_LEN];
326 PSID psid = (PSID) psid_buffer;
327 DWORD sid_length = MAX_SID_LEN;
328 DWORD gid;
329 SID_NAME_USE acc_type;
330 PDBGSID pdsid;
331 BOOL is_builtin = FALSE;
332
333 if (!LookupAccountNameW (servername, buffer[i].lgrpi0_name, psid,
334 &sid_length, domain_name, &domname_len,
335 &acc_type))
336 {
337 print_win_error (rc);
338 fprintf (stderr, " (%ls)\n", buffer[i].lgrpi0_name);
339 continue;
340 }
341 else if (acc_type == SidTypeDomain)
342 {
343 WCHAR domname[MAX_DOMAIN_NAME_LEN + GNLEN + 2];
344
345 wcscpy (domname, domain_name);
346 wcscat (domname, L"\\");
347 wcscat (domname, buffer[i].lgrpi0_name);
348 sid_length = MAX_SID_LEN;
349 domname_len = MAX_DOMAIN_NAME_LEN + 1;
350 if (!LookupAccountNameW (servername, domname,
351 psid, &sid_length,
352 domain_name, &domname_len,
353 &acc_type))
354 {
355 print_win_error (rc);
356 fprintf(stderr, " (%ls)\n", domname);
357 continue;
358 }
359 }
360
361 /* Store all local SIDs with prefix "S-1-5-32-" and check if it
362 has been printed already. This allows to get all builtin
363 groups exactly once and not once per domain. */
364 pdsid = (PDBGSID) psid;
365 if (pdsid->IdentifierAuthority.Value[5] == sid_nt_auth.Value[5]
366 && pdsid->SubAuthority[0] == SECURITY_BUILTIN_DOMAIN_RID)
367 {
368 int b;
369
370 is_builtin = TRUE;
371 if (servername && builtin_sid_cnt)
372 for (b = 0; b < builtin_sid_cnt; b++)
373 if (EqualSid (&builtin_sid_list[b], psid))
374 goto skip_group;
375 if (builtin_sid_cnt < MAX_BUILTIN_SIDS)
376 CopySid (sizeof (DBGSID), &builtin_sid_list[builtin_sid_cnt++],
377 psid);
378 }
379
380 gid = *GetSidSubAuthority (psid, *GetSidSubAuthorityCount(psid) - 1);
381
382 printf ("%ls%s%ls:%s:%ld:\n",
383 with_dom ? domain_name : L"",
384 with_dom ? sep : "",
385 buffer[i].lgrpi0_name,
386 put_sid (psid),
387 gid + (is_builtin ? 0 : id_offset));
388 skip_group:
389 ;
390 }
391
392 NetApiBufferFree (buffer);
393
394 }
395 while (rc == ERROR_MORE_DATA);
396
397 return 0;
398 }
399
400 void
401 enum_groups (BOOL domain, domlist_t *dom_or_machine, const char *sep,
402 int id_offset, char *disp_groupname)
403 {
404 WCHAR machine[INTERNET_MAX_HOST_NAME_LENGTH + 1];
405 PWCHAR servername = NULL;
406 char *d_or_m = dom_or_machine ? dom_or_machine->str : NULL;
407 BOOL with_dom = dom_or_machine ? dom_or_machine->with_dom : FALSE;
408 GROUP_INFO_2 *buffer;
409 DWORD entriesread = 0;
410 DWORD totalentries = 0;
411 DWORD resume_handle = 0;
412 WCHAR gname[GNLEN + 1];
413 DWORD rc;
414
415 if (domain)
416 {
417 servername = get_dcname (d_or_m);
418 if (servername == (PWCHAR) -1)
419 return;
420 }
421 else if (d_or_m)
422 {
423 int ret = mbstowcs (machine, d_or_m, INTERNET_MAX_HOST_NAME_LENGTH + 1);
424 if (ret < 1 || ret >= INTERNET_MAX_HOST_NAME_LENGTH + 1)
425 {
426 fprintf (stderr, "%s: Invalid machine name '%s'. Skipping...\n",
427 __progname, d_or_m);
428 return;
429 }
430 servername = machine;
431 }
432
433 do
434 {
435 DWORD i;
436
437 if (disp_groupname != NULL)
438 {
439 mbstowcs (gname, disp_groupname, GNLEN + 1);
440 rc = NetGroupGetInfo (servername, (LPWSTR) & gname, 2,
441 (void *) &buffer);
442 entriesread=1;
443 }
444 else
445 rc = NetGroupEnum (servername, 2, (void *) & buffer,
446 MAX_PREFERRED_LENGTH, &entriesread, &totalentries,
447 &resume_handle);
448 switch (rc)
449 {
450 case ERROR_ACCESS_DENIED:
451 print_win_error (rc);
452 return;
453
454 case ERROR_MORE_DATA:
455 case ERROR_SUCCESS:
456 break;
457
458 default:
459 print_win_error (rc);
460 return;
461 }
462
463 for (i = 0; i < entriesread; i++)
464 {
465 WCHAR domain_name[MAX_DOMAIN_NAME_LEN + 1];
466 DWORD domname_len = MAX_DOMAIN_NAME_LEN + 1;
467 char psid_buffer[MAX_SID_LEN];
468 PSID psid = (PSID) psid_buffer;
469 DWORD sid_length = MAX_SID_LEN;
470 SID_NAME_USE acc_type;
471
472 int gid = buffer[i].grpi2_group_id;
473 if (!LookupAccountNameW (servername, buffer[i].grpi2_name,
474 psid, &sid_length,
475 domain_name, &domname_len,
476 &acc_type))
477 {
478 print_win_error (rc);
479 fprintf(stderr, " (%ls)\n", buffer[i].grpi2_name);
480 continue;
481 }
482 else if (acc_type == SidTypeDomain)
483 {
484 WCHAR domname[MAX_DOMAIN_NAME_LEN + GNLEN + 2];
485
486 wcscpy (domname, domain || !servername
487 ? domain_name : servername);
488 wcscat (domname, L"\\");
489 wcscat (domname, buffer[i].grpi2_name);
490 sid_length = MAX_SID_LEN;
491 domname_len = MAX_DOMAIN_NAME_LEN + 1;
492 if (!LookupAccountNameW (servername, domname,
493 psid, &sid_length,
494 domain_name, &domname_len,
495 &acc_type))
496 {
497 print_win_error (rc);
498 fprintf(stderr, " (%ls)\n", domname);
499 continue;
500 }
501 }
502 printf ("%ls%s%ls:%s:%u:\n",
503 with_dom ? domain_name : L"",
504 with_dom ? sep : "",
505 buffer[i].grpi2_name,
506 put_sid (psid),
507 gid + id_offset);
508 }
509
510 NetApiBufferFree (buffer);
511
512 }
513 while (rc == ERROR_MORE_DATA);
514 }
515
516 void
517 print_special (PSID_IDENTIFIER_AUTHORITY auth, BYTE cnt,
518 DWORD sub1, DWORD sub2, DWORD sub3, DWORD sub4,
519 DWORD sub5, DWORD sub6, DWORD sub7, DWORD sub8)
520 {
521 WCHAR grp[GNLEN + 1], dom[MAX_DOMAIN_NAME_LEN + 1];
522 DWORD glen, dlen, rid;
523 PSID psid;
524 SID_NAME_USE acc_type;
525
526 if (AllocateAndInitializeSid (auth, cnt, sub1, sub2, sub3, sub4,
527 sub5, sub6, sub7, sub8, &psid))
528 {
529 if (LookupAccountSidW (NULL, psid,
530 grp, (glen = GNLEN + 1, &glen),
531 dom, (dlen = MAX_DOMAIN_NAME_LEN + 1, &dlen),
532 &acc_type))
533 {
534 if (sub8)
535 rid = sub8;
536 else if (sub7)
537 rid = sub7;
538 else if (sub6)
539 rid = sub6;
540 else if (sub5)
541 rid = sub5;
542 else if (sub4)
543 rid = sub4;
544 else if (sub3)
545 rid = sub3;
546 else if (sub2)
547 rid = sub2;
548 else
549 rid = sub1;
550 printf ("%ls:%s:%lu:\n", grp, put_sid (psid), rid);
551 }
552 FreeSid (psid);
553 }
554 }
555
556 void
557 current_group (const char *sep, int id_offset)
558 {
559 DWORD len;
560 HANDLE ptok;
561 struct {
562 PSID psid;
563 char buffer[MAX_SID_LEN];
564 } tg;
565 WCHAR grp[GNLEN + 1];
566 WCHAR dom[MAX_DOMAIN_NAME_LEN + 1];
567 DWORD glen = GNLEN + 1;
568 DWORD dlen = MAX_DOMAIN_NAME_LEN + 1;
569 int gid;
570 SID_NAME_USE acc_type;
571
572 if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &ptok)
573 || !GetTokenInformation (ptok, TokenPrimaryGroup, &tg, sizeof tg, &len)
574 || !CloseHandle (ptok)
575 || !LookupAccountSidW (NULL, tg.psid, grp, &glen, dom, &dlen, &acc_type))
576 {
577 print_win_error (GetLastError ());
578 return;
579 }
580 gid = *GetSidSubAuthority (tg.psid, *GetSidSubAuthorityCount(tg.psid) - 1);
581 printf ("%ls%s%ls:%s:%u:\n",
582 sep ? dom : L"",
583 sep ?: "",
584 grp,
585 put_sid (tg.psid),
586 gid + id_offset);
587 }
588
589 int
590 usage (FILE * stream)
591 {
592 fprintf (stream,
593 "Usage: mkgroup [OPTION]...\n"
594 "Print /etc/group file to stdout\n"
595 "\n"
596 "Options:\n"
597 " -l,--local [machine] print local groups (from local machine if no\n"
598 " machine specified)\n"
599 " -L,--Local [machine] ditto, but generate groupname with machine prefix\n"
600 " -d,--domain [domain] print domain groups (from current domain if no\n"
601 " domain specified)\n"
602 " -D,--Domain [domain] ditto, but generate groupname with machine prefix\n"
603 " -c,--current print current group\n"
604 " -C,--Current ditto, but generate groupname with machine or\n"
605 " domain prefix\n"
606 " -S,--separator char for -L, -D, -C use character char as domain\\group\n"
607 " separator in groupname instead of the default '\\'\n"
608 " -o,--id-offset offset change the default offset (10000) added to gids\n"
609 " in domain or foreign server accounts.\n"
610 " -g,--group groupname only return information for the specified group\n"
611 " one of -l, -L, -d, -D must be specified, too\n"
612 " -U,--unix grouplist additionally print UNIX groups when using -l or -L\n"
613 " on a UNIX Samba server\n"
614 " grouplist is a comma-separated list of groupnames\n"
615 " or gid ranges (root,-25,50-100).\n"
616 " (enumerating large ranges can take a long time!)\n"
617 " -s,--no-sids (ignored)\n"
618 " -u,--users (ignored)\n"
619 " -h,--help print this message\n"
620 " -v,--version print version information and exit\n"
621 "\n"
622 "Default is to print local groups on stand-alone machines, plus domain\n"
623 "groups on domain controllers and domain member machines.\n");
624 return 1;
625 }
626
627 struct option longopts[] = {
628 {"current", no_argument, NULL, 'c'},
629 {"Current", no_argument, NULL, 'C'},
630 {"domain", optional_argument, NULL, 'd'},
631 {"Domain", optional_argument, NULL, 'D'},
632 {"group", required_argument, NULL, 'g'},
633 {"help", no_argument, NULL, 'h'},
634 {"local", optional_argument, NULL, 'l'},
635 {"Local", optional_argument, NULL, 'L'},
636 {"id-offset", required_argument, NULL, 'o'},
637 {"no-sids", no_argument, NULL, 's'},
638 {"separator", required_argument, NULL, 'S'},
639 {"users", no_argument, NULL, 'u'},
640 {"unix", required_argument, NULL, 'U'},
641 {"version", no_argument, NULL, 'v'},
642 {0, no_argument, NULL, 0}
643 };
644
645 char opts[] = "cCd::D::g:hl::L::o:sS:uU:v";
646
647 void
648 print_version ()
649 {
650 const char *v = strchr (version, ':');
651 int len;
652 if (!v)
653 {
654 v = "?";
655 len = 1;
656 }
657 else
658 {
659 v += 2;
660 len = strchr (v, ' ') - v;
661 }
662 printf ("\
663 mkgroup (cygwin) %.*s\n\
664 group File Generator\n\
665 Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Red Hat, Inc.\n\
666 Compiled on %s\n\
667 ", len, v, __DATE__);
668 }
669
670 static PPOLICY_PRIMARY_DOMAIN_INFO p_dom;
671
672 static BOOL
673 fetch_primary_domain ()
674 {
675 NTSTATUS status;
676 LSA_OBJECT_ATTRIBUTES oa = { 0, 0, 0, 0, 0, 0 };
677 LSA_HANDLE lsa;
678
679 if (!p_dom)
680 {
681 status = LsaOpenPolicy (NULL, &oa, POLICY_EXECUTE, &lsa);
682 if (!NT_SUCCESS (status))
683 return FALSE;
684 status = LsaQueryInformationPolicy (lsa, PolicyPrimaryDomainInformation,
685 (PVOID *) &p_dom);
686 LsaClose (lsa);
687 if (!NT_SUCCESS (status))
688 return FALSE;
689 }
690 return !!p_dom->Sid;
691 }
692
693 int
694 main (int argc, char **argv)
695 {
696 int print_local = 0;
697 domlist_t locals[16];
698 int print_domain = 0;
699 domlist_t domains[16];
700 char *opt;
701 int print_current = 0;
702 int print_system = 0;
703 char *print_unix = NULL;
704 const char *sep_char = "\\";
705 int id_offset = 10000;
706 int c, i, off;
707 char *disp_groupname = NULL;
708 BOOL in_domain;
709
710 if (!isatty (1))
711 setmode (1, O_BINARY);
712
713 load_dsgetdcname ();
714 in_domain = fetch_primary_domain ();
715 if (argc == 1)
716 {
717 print_special (&sid_nt_auth, 1, SECURITY_LOCAL_SYSTEM_RID,
718 0, 0, 0, 0, 0, 0, 0);
719 if (in_domain)
720 {
721 if (!enum_local_groups (TRUE, NULL, sep_char, id_offset,
722 disp_groupname))
723 enum_groups (TRUE, NULL, sep_char, id_offset, disp_groupname);
724 }
725 else if (!enum_local_groups (FALSE, NULL, sep_char, 0, disp_groupname))
726 enum_groups (FALSE, NULL, sep_char, 0, disp_groupname);
727 return 0;
728 }
729
730 while ((c = getopt_long (argc, argv, opts, longopts, NULL)) != EOF)
731 switch (c)
732 {
733 case 'l':
734 case 'L':
735 if (print_local >= 16)
736 {
737 fprintf (stderr, "%s: Can not enumerate from more than 16 "
738 "servers.\n", __progname);
739 return 1;
740 }
741 opt = optarg ?:
742 argv[optind] && argv[optind][0] != '-' ? argv[optind] : NULL;
743 for (i = 0; i < print_local; ++i)
744 if ((!locals[i].str && !opt)
745 || (locals[i].str && opt && !strcmp (locals[i].str, opt)))
746 goto skip_local;
747 if (!(locals[print_local].str = opt))
748 print_system = 1;
749 locals[print_local++].with_dom = c == 'L';
750 skip_local:
751 break;
752 case 'd':
753 case 'D':
754 if (print_domain >= 16)
755 {
756 fprintf (stderr, "%s: Can not enumerate from more than 16 "
757 "domains.\n", __progname);
758 return 1;
759 }
760 opt = optarg ?:
761 argv[optind] && argv[optind][0] != '-' ? argv[optind] : NULL;
762 for (i = 0; i < print_domain; ++i)
763 if ((!domains[i].str && !opt)
764 || (domains[i].str && opt && !strcmp (domains[i].str, opt)))
765 goto skip_domain;
766 if (!(domains[print_domain].str = opt))
767 print_system = 1;
768 domains[print_domain++].with_dom = c == 'D';
769 skip_domain:
770 break;
771 case 'S':
772 sep_char = optarg;
773 if (strlen (sep_char) > 1)
774 {
775 fprintf (stderr, "%s: Only one character allowed as domain\\user "
776 "separator character.\n", __progname);
777 return 1;
778 }
779 if (*sep_char == ':')
780 {
781 fprintf (stderr, "%s: Colon not allowed as domain\\user separator "
782 "character.\n", __progname);
783 return 1;
784 }
785 break;
786 case 'U':
787 print_unix = optarg;
788 break;
789 case 'c':
790 sep_char = NULL;
791 /*FALLTHRU*/
792 case 'C':
793 print_current = 1;
794 break;
795 case 'o':
796 id_offset = strtol (optarg, NULL, 10);
797 break;
798 case 's':
799 break;
800 case 'u':
801 break;
802 case 'g':
803 disp_groupname = optarg;
804 break;
805 case 'h':
806 usage (stdout);
807 return 0;
808 case 'v':
809 print_version ();
810 return 0;
811 default:
812 fprintf (stderr, "Try '%s --help' for more information.\n", argv[0]);
813 return 1;
814 }
815
816 if (optind < argc - 1)
817 usage (stdout);
818
819 /* Get 'system' group */
820 if (!disp_groupname && print_system)
821 print_special (&sid_nt_auth, 1, SECURITY_LOCAL_SYSTEM_RID,
822 0, 0, 0, 0, 0, 0, 0);
823
824 off = 1;
825 for (i = 0; i < print_local; ++i)
826 {
827 if (locals[i].str)
828 {
829 if (!enum_local_groups (FALSE, locals + i, sep_char,
830 id_offset * off, disp_groupname))
831 {
832 if (print_unix)
833 enum_unix_groups (locals + i, sep_char, id_offset * off,
834 print_unix);
835 enum_groups (FALSE, locals + i, sep_char, id_offset * off++,
836 disp_groupname);
837 }
838 }
839 else if (!enum_local_groups (FALSE, locals + i, sep_char, 0,
840 disp_groupname))
841 enum_groups (FALSE, locals + i, sep_char, 0, disp_groupname);
842 }
843
844 for (i = 0; i < print_domain; ++i)
845 {
846 if (!enum_local_groups (TRUE, domains + i, sep_char, id_offset * off,
847 disp_groupname))
848 enum_groups (TRUE, domains + i, sep_char, id_offset * off++,
849 disp_groupname);
850 }
851
852 if (print_current)
853 current_group (sep_char, id_offset);
854
855 return 0;
856 }
This page took 0.076012 seconds and 6 git commands to generate.