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