3 Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
4 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
6 This file is part of Cygwin.
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
12 #define _WIN32_WINNT 0x0600
23 #include <sys/fcntl.h>
24 #include <sys/cygwin.h>
25 #include <cygwin/version.h>
35 #define print_win_error(x) _print_win_error(x, __LINE__)
37 #define MAX_SID_LEN 40
39 SID_IDENTIFIER_AUTHORITY sid_world_auth
= {SECURITY_WORLD_SID_AUTHORITY
};
40 SID_IDENTIFIER_AUTHORITY sid_nt_auth
= {SECURITY_NT_AUTHORITY
};
43 #define min(a,b) (((a)<(b))?(a):(b))
55 _print_win_error (DWORD code
, int line
)
59 if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
60 | FORMAT_MESSAGE_IGNORE_INSERTS
,
63 MAKELANGID (LANG_NEUTRAL
, SUBLANG_DEFAULT
),
64 (LPTSTR
) buf
, sizeof (buf
), NULL
))
65 fprintf (stderr
, "mkgroup (%d): [%lu] %s", line
, code
, buf
);
67 fprintf (stderr
, "mkgroup (%d): error %lu", line
, code
);
71 get_dcname (char *domain
)
73 static WCHAR server
[INTERNET_MAX_HOST_NAME_LENGTH
+ 1];
75 WCHAR domain_name
[MAX_DOMAIN_NAME_LEN
+ 1];
76 PDOMAIN_CONTROLLER_INFOW pdci
= NULL
;
80 mbstowcs (domain_name
, domain
, strlen (domain
) + 1);
81 rc
= DsGetDcNameW (NULL
, domain_name
, NULL
, NULL
, 0, &pdci
);
84 rc
= DsGetDcNameW (NULL
, NULL
, NULL
, NULL
, 0, &pdci
);
85 if (rc
!= ERROR_SUCCESS
)
90 wcscpy (server
, pdci
->DomainControllerName
);
91 NetApiBufferFree (pdci
);
103 sprintf(t
, "%u", GetSidIdentifierAuthority (psid
)->Value
[5]);
105 for (i
= 0; i
< *GetSidSubAuthorityCount (psid
); ++i
)
107 sprintf(t
, "-%lu", *GetSidSubAuthority (psid
, i
));
115 BYTE SubAuthorityCount
;
116 SID_IDENTIFIER_AUTHORITY IdentifierAuthority
;
117 DWORD SubAuthority
[8];
120 #define MAX_BUILTIN_SIDS 100 /* Should be enough for the forseable future. */
121 DBGSID builtin_sid_list
[MAX_BUILTIN_SIDS
];
122 DWORD builtin_sid_cnt
;
129 static sidbuf curr_pgrp
;
130 static BOOL got_curr_pgrp
= FALSE
;
133 fetch_current_pgrp_sid ()
138 if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY
, &ptok
)
139 || !GetTokenInformation (ptok
, TokenPrimaryGroup
, &curr_pgrp
,
140 sizeof curr_pgrp
, &len
)
141 || !CloseHandle (ptok
))
143 print_win_error (GetLastError ());
149 current_group (const char *sep
, DWORD id_offset
)
151 WCHAR grp
[GNLEN
+ 1];
152 WCHAR dom
[MAX_DOMAIN_NAME_LEN
+ 1];
153 DWORD glen
= GNLEN
+ 1;
154 DWORD dlen
= MAX_DOMAIN_NAME_LEN
+ 1;
156 SID_NAME_USE acc_type
;
159 || !LookupAccountSidW (NULL
, curr_pgrp
.psid
, grp
, &glen
, dom
, &dlen
,
162 print_win_error (GetLastError ());
165 gid
= *GetSidSubAuthority (curr_pgrp
.psid
,
166 *GetSidSubAuthorityCount(curr_pgrp
.psid
) - 1);
167 printf ("%ls%s%ls:%s:%lu:\n",
171 put_sid (curr_pgrp
.psid
),
176 enum_unix_groups (domlist_t
*dom_or_machine
, const char *sep
, DWORD id_offset
,
179 WCHAR machine
[INTERNET_MAX_HOST_NAME_LENGTH
+ 1];
180 PWCHAR servername
= NULL
;
181 char *d_or_m
= dom_or_machine
? dom_or_machine
->str
: NULL
;
182 BOOL with_dom
= dom_or_machine
? dom_or_machine
->with_dom
: FALSE
;
183 SID_IDENTIFIER_AUTHORITY auth
= { { 0, 0, 0, 0, 0, 22 } };
184 char *gstr
, *grp_list
;
185 WCHAR grp
[GNLEN
+ sizeof ("Unix Group\\") + 1];
186 WCHAR dom
[MAX_DOMAIN_NAME_LEN
+ 1];
187 DWORD glen
, dlen
, sidlen
;
189 char psid_buffer
[MAX_SID_LEN
];
190 SID_NAME_USE acc_type
;
195 int ret
= mbstowcs (machine
, d_or_m
, INTERNET_MAX_HOST_NAME_LENGTH
+ 1);
196 if (ret
< 1 || ret
>= INTERNET_MAX_HOST_NAME_LENGTH
+ 1)
198 fprintf (stderr
, "%s: Invalid machine name '%s'. Skipping...\n",
199 program_invocation_short_name
, d_or_m
);
202 servername
= machine
;
204 if (!AllocateAndInitializeSid (&auth
, 2, 2, 0, 0, 0, 0, 0, 0, 0, &psid
))
207 if (!(grp_list
= strdup (unix_grp_list
)))
213 for (gstr
= strtok (grp_list
, ","); gstr
; gstr
= strtok (NULL
, ","))
215 if (!isdigit ((unsigned char) gstr
[0]) && gstr
[0] != '-')
217 PWCHAR p
= wcpcpy (grp
, L
"Unix Group\\");
218 ret
= mbstowcs (p
, gstr
, GNLEN
+ 1);
219 if (ret
< 1 || ret
>= GNLEN
+ 1)
220 fprintf (stderr
, "%s: Invalid group name '%s'. Skipping...\n",
221 program_invocation_short_name
, gstr
);
222 else if (LookupAccountNameW (servername
, grp
,
223 psid
= (PSID
) psid_buffer
,
224 (sidlen
= MAX_SID_LEN
, &sidlen
),
226 (dlen
= MAX_DOMAIN_NAME_LEN
+ 1, &dlen
),
228 printf ("%s%s%ls:%s:%lu:\n",
229 with_dom
? "Unix Group" : "",
234 *GetSidSubAuthority (psid
,
235 *GetSidSubAuthorityCount(psid
) - 1));
244 start
= strtol (p
, &p
, 10);
247 else if (*p
++ != '-' || !isdigit ((unsigned char) *p
)
248 || (stop
= strtol (p
, &p
, 10)) < start
|| *p
)
250 fprintf (stderr
, "%s: Malformed unix group list entry '%s'. "
252 program_invocation_short_name
, gstr
);
255 for (; start
<= stop
; ++ start
)
257 *GetSidSubAuthority (psid
, *GetSidSubAuthorityCount(psid
) - 1)
259 if (LookupAccountSidW (servername
, psid
,
260 grp
, (glen
= GNLEN
+ 1, &glen
),
262 (dlen
= MAX_DOMAIN_NAME_LEN
+ 1, &dlen
),
264 && !iswdigit (grp
[0]))
265 printf ("%s%s%ls:%s:%lu:\n",
266 with_dom
? "Unix Group" : "",
280 enum_local_groups (BOOL domain
, domlist_t
*dom_or_machine
, const char *sep
,
281 DWORD id_offset
, char *disp_groupname
, int print_builtin
,
284 WCHAR machine
[INTERNET_MAX_HOST_NAME_LENGTH
+ 1];
285 PWCHAR servername
= NULL
;
286 char *d_or_m
= dom_or_machine
? dom_or_machine
->str
: NULL
;
287 BOOL with_dom
= dom_or_machine
? dom_or_machine
->with_dom
: FALSE
;
288 LOCALGROUP_INFO_0
*buffer
;
289 DWORD entriesread
= 0;
290 DWORD totalentries
= 0;
291 DWORD resume_handle
= 0;
292 WCHAR gname
[GNLEN
+ 1];
297 servername
= get_dcname (d_or_m
);
298 if (servername
== (PWCHAR
) -1)
303 int ret
= mbstowcs (machine
, d_or_m
, INTERNET_MAX_HOST_NAME_LENGTH
+ 1);
304 if (ret
< 1 || ret
>= INTERNET_MAX_HOST_NAME_LENGTH
+ 1)
306 fprintf (stderr
, "%s: Invalid machine name '%s'. Skipping...\n",
307 program_invocation_short_name
, d_or_m
);
310 servername
= machine
;
319 mbstowcs (gname
, disp_groupname
, GNLEN
+ 1);
320 rc
= NetLocalGroupGetInfo (servername
, gname
, 0, (void *) &buffer
);
321 if (rc
== ERROR_SUCCESS
)
323 /* Allow further searching for the group and avoid annoying
324 error messages just because the group is not a local group or
325 the group hasn't been found. */
326 else if (rc
== ERROR_NO_SUCH_ALIAS
|| rc
== NERR_GroupNotFound
)
330 rc
= NetLocalGroupEnum (servername
, 0, (void *) &buffer
,
331 MAX_PREFERRED_LENGTH
, &entriesread
,
332 &totalentries
, &resume_handle
);
335 case ERROR_ACCESS_DENIED
:
336 print_win_error (rc
);
339 case ERROR_MORE_DATA
:
344 print_win_error (rc
);
348 for (i
= 0; i
< entriesread
; i
++)
350 WCHAR domain_name
[MAX_DOMAIN_NAME_LEN
+ 1];
351 DWORD domname_len
= MAX_DOMAIN_NAME_LEN
+ 1;
352 char psid_buffer
[MAX_SID_LEN
];
353 PSID psid
= (PSID
) psid_buffer
;
354 DWORD sid_length
= MAX_SID_LEN
;
356 SID_NAME_USE acc_type
;
358 BOOL is_builtin
= FALSE
;
360 if (!LookupAccountNameW (servername
, buffer
[i
].lgrpi0_name
, psid
,
361 &sid_length
, domain_name
, &domname_len
,
364 print_win_error (GetLastError ());
365 fprintf (stderr
, " (%ls)\n", buffer
[i
].lgrpi0_name
);
368 else if (acc_type
== SidTypeDomain
)
370 WCHAR domname
[MAX_DOMAIN_NAME_LEN
+ GNLEN
+ 2];
372 wcscpy (domname
, domain_name
);
373 wcscat (domname
, L
"\\");
374 wcscat (domname
, buffer
[i
].lgrpi0_name
);
375 sid_length
= MAX_SID_LEN
;
376 domname_len
= MAX_DOMAIN_NAME_LEN
+ 1;
377 if (!LookupAccountNameW (servername
, domname
,
379 domain_name
, &domname_len
,
382 print_win_error (GetLastError ());
383 fprintf(stderr
, " (%ls)\n", domname
);
388 /* Store all local SIDs with prefix "S-1-5-32-" and check if it
389 has been printed already. This allows to get all builtin
390 groups exactly once and not once per domain. */
391 pdsid
= (PDBGSID
) psid
;
392 if (pdsid
->IdentifierAuthority
.Value
[5] == sid_nt_auth
.Value
[5]
393 && pdsid
->SubAuthority
[0] == SECURITY_BUILTIN_DOMAIN_RID
)
401 for (b
= 0; b
< builtin_sid_cnt
; b
++)
402 if (EqualSid (&builtin_sid_list
[b
], psid
))
404 if (builtin_sid_cnt
< MAX_BUILTIN_SIDS
)
405 CopySid (sizeof (DBGSID
), &builtin_sid_list
[builtin_sid_cnt
++],
410 else if (EqualSid (curr_pgrp
.psid
, psid
))
411 got_curr_pgrp
= TRUE
;
413 gid
= *GetSidSubAuthority (psid
, *GetSidSubAuthorityCount(psid
) - 1);
414 printf ("%ls%s%ls:%s:%ld:\n",
415 with_dom
&& !is_builtin
? domain_name
: L
"",
416 with_dom
&& !is_builtin
? sep
: "",
417 buffer
[i
].lgrpi0_name
,
419 gid
+ (is_builtin
? 0 : id_offset
));
424 NetApiBufferFree (buffer
);
427 while (rc
== ERROR_MORE_DATA
);
429 /* Return 1 if the single group we're looking for has been found here to
430 avoid calling enum_groups for the same group, thus avoiding a spurious
431 error message "group name could not be found" in enum_groups. */
432 return disp_groupname
&& entriesread
? 1 : 0;
436 enum_groups (BOOL domain
, domlist_t
*dom_or_machine
, const char *sep
,
437 DWORD id_offset
, char *disp_groupname
, int print_current
)
439 WCHAR machine
[INTERNET_MAX_HOST_NAME_LENGTH
+ 1];
440 PWCHAR servername
= NULL
;
441 char *d_or_m
= dom_or_machine
? dom_or_machine
->str
: NULL
;
442 BOOL with_dom
= dom_or_machine
? dom_or_machine
->with_dom
: FALSE
;
443 GROUP_INFO_2
*buffer
;
444 DWORD entriesread
= 0;
445 DWORD totalentries
= 0;
446 DWORD resume_handle
= 0;
447 WCHAR gname
[GNLEN
+ 1];
452 servername
= get_dcname (d_or_m
);
453 if (servername
== (PWCHAR
) -1)
458 int ret
= mbstowcs (machine
, d_or_m
, INTERNET_MAX_HOST_NAME_LENGTH
+ 1);
459 if (ret
< 1 || ret
>= INTERNET_MAX_HOST_NAME_LENGTH
+ 1)
461 fprintf (stderr
, "%s: Invalid machine name '%s'. Skipping...\n",
462 program_invocation_short_name
, d_or_m
);
465 servername
= machine
;
472 if (disp_groupname
!= NULL
)
474 mbstowcs (gname
, disp_groupname
, GNLEN
+ 1);
475 rc
= NetGroupGetInfo (servername
, (LPWSTR
) & gname
, 2,
478 /* Avoid annoying error messages just because the group hasn't been
480 if (rc
== NERR_GroupNotFound
)
484 rc
= NetGroupEnum (servername
, 2, (void *) & buffer
,
485 MAX_PREFERRED_LENGTH
, &entriesread
, &totalentries
,
489 case ERROR_ACCESS_DENIED
:
490 print_win_error (rc
);
493 case ERROR_MORE_DATA
:
498 print_win_error (rc
);
502 for (i
= 0; i
< entriesread
; i
++)
504 WCHAR domain_name
[MAX_DOMAIN_NAME_LEN
+ 1];
505 DWORD domname_len
= MAX_DOMAIN_NAME_LEN
+ 1;
506 char psid_buffer
[MAX_SID_LEN
];
507 PSID psid
= (PSID
) psid_buffer
;
508 DWORD sid_length
= MAX_SID_LEN
;
509 SID_NAME_USE acc_type
;
511 int gid
= buffer
[i
].grpi2_group_id
;
512 if (!LookupAccountNameW (servername
, buffer
[i
].grpi2_name
,
514 domain_name
, &domname_len
,
517 print_win_error (GetLastError ());
518 fprintf(stderr
, " (%ls)\n", buffer
[i
].grpi2_name
);
521 else if (acc_type
== SidTypeDomain
)
523 WCHAR domname
[MAX_DOMAIN_NAME_LEN
+ GNLEN
+ 2];
525 wcscpy (domname
, domain
|| !servername
526 ? domain_name
: servername
);
527 wcscat (domname
, L
"\\");
528 wcscat (domname
, buffer
[i
].grpi2_name
);
529 sid_length
= MAX_SID_LEN
;
530 domname_len
= MAX_DOMAIN_NAME_LEN
+ 1;
531 if (!LookupAccountNameW (servername
, domname
,
533 domain_name
, &domname_len
,
536 print_win_error (GetLastError ());
537 fprintf(stderr
, " (%ls)\n", domname
);
543 else if (EqualSid (curr_pgrp
.psid
, psid
))
544 got_curr_pgrp
= TRUE
;
546 printf ("%ls%s%ls:%s:%lu:\n",
547 with_dom
? domain_name
: L
"",
549 buffer
[i
].grpi2_name
,
554 NetApiBufferFree (buffer
);
557 while (rc
== ERROR_MORE_DATA
);
561 print_special (PSID_IDENTIFIER_AUTHORITY auth
, BYTE cnt
,
562 DWORD sub1
, DWORD sub2
, DWORD sub3
, DWORD sub4
,
563 DWORD sub5
, DWORD sub6
, DWORD sub7
, DWORD sub8
)
565 WCHAR grp
[GNLEN
+ 1], dom
[MAX_DOMAIN_NAME_LEN
+ 1];
566 DWORD glen
, dlen
, rid
;
568 SID_NAME_USE acc_type
;
570 if (AllocateAndInitializeSid (auth
, cnt
, sub1
, sub2
, sub3
, sub4
,
571 sub5
, sub6
, sub7
, sub8
, &psid
))
573 if (LookupAccountSidW (NULL
, psid
,
574 grp
, (glen
= GNLEN
+ 1, &glen
),
575 dom
, (dlen
= MAX_DOMAIN_NAME_LEN
+ 1, &dlen
),
594 printf ("%ls:%s:%lu:\n", grp
, put_sid (psid
), rid
);
601 usage (FILE * stream
)
604 "Usage: %s [OPTION]...\n"
606 "Print /etc/group file to stdout\n"
610 " -l,--local [machine[,offset]]\n"
611 " print local groups with gid offset offset\n"
612 " (from local machine if no machine specified)\n"
613 " -L,--Local [machine[,offset]]\n"
614 " ditto, but generate groupname with machine prefix\n"
615 " -d,--domain [domain[,offset]]\n"
616 " print domain groups with gid offset offset\n"
617 " (from current domain if no domain specified)\n"
618 " -D,--Domain [domain[,offset]]\n"
619 " ditto, but generate groupname with machine prefix\n"
620 " -c,--current print current group\n"
621 " -C,--Current ditto, but generate groupname with machine or\n"
623 " -S,--separator char for -L, -D, -C use character char as domain\\group\n"
624 " separator in groupname instead of the default '\\'\n"
625 " -o,--id-offset offset change the default offset (10000) added to gids\n"
626 " in domain or foreign server accounts.\n"
627 " -g,--group groupname only return information for the specified group\n"
628 " one of -l, -L, -d, -D must be specified, too\n"
629 " -b,--no-builtin don't print BUILTIN groups\n"
630 " -U,--unix grouplist additionally print UNIX groups when using -l or -L\n"
631 " on a UNIX Samba server\n"
632 " grouplist is a comma-separated list of groupnames\n"
633 " or gid ranges (root,-25,50-100).\n"
634 " (enumerating large ranges can take a long time!)\n"
635 " -s,--no-sids (ignored)\n"
636 " -u,--users (ignored)\n"
637 " -h,--help print this message\n"
638 " -v,--version print version information and exit\n"
640 "Default is to print local groups on stand-alone machines, plus domain\n"
641 "groups on domain controllers and domain member machines.\n"
642 "\n", program_invocation_short_name
);
646 struct option longopts
[] = {
647 {"no-builtin", no_argument
, NULL
, 'b'},
648 {"current", no_argument
, NULL
, 'c'},
649 {"Current", no_argument
, NULL
, 'C'},
650 {"domain", optional_argument
, NULL
, 'd'},
651 {"Domain", optional_argument
, NULL
, 'D'},
652 {"group", required_argument
, NULL
, 'g'},
653 {"help", no_argument
, NULL
, 'h'},
654 {"local", optional_argument
, NULL
, 'l'},
655 {"Local", optional_argument
, NULL
, 'L'},
656 {"id-offset", required_argument
, NULL
, 'o'},
657 {"no-sids", no_argument
, NULL
, 's'},
658 {"separator", required_argument
, NULL
, 'S'},
659 {"users", no_argument
, NULL
, 'u'},
660 {"unix", required_argument
, NULL
, 'U'},
661 {"version", no_argument
, NULL
, 'V'},
662 {0, no_argument
, NULL
, 0}
665 static char opts
[] = "bcCd::D::g:hl::L::o:sS:uU:V";
670 printf ("mkgroup (cygwin) %d.%d.%d\n"
671 "Group File Generator\n"
672 "Copyright (C) 1997 - %s Red Hat, Inc.\n"
673 "This is free software; see the source for copying conditions. There is NO\n"
674 "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",
675 CYGWIN_VERSION_DLL_MAJOR
/ 1000,
676 CYGWIN_VERSION_DLL_MAJOR
% 1000,
677 CYGWIN_VERSION_DLL_MINOR
,
678 strrchr (__DATE__
, ' ') + 1);
681 static PPOLICY_PRIMARY_DOMAIN_INFO p_dom
;
684 fetch_primary_domain ()
687 LSA_OBJECT_ATTRIBUTES oa
= { 0, 0, 0, 0, 0, 0 };
692 status
= LsaOpenPolicy (NULL
, &oa
, POLICY_EXECUTE
, &lsa
);
693 if (!NT_SUCCESS (status
))
695 status
= LsaQueryInformationPolicy (lsa
, PolicyPrimaryDomainInformation
,
696 (PVOID
*) ((void *) &p_dom
));
698 if (!NT_SUCCESS (status
))
705 main (int argc
, char **argv
)
707 int print_domlist
= 0;
708 domlist_t domlist
[32];
710 int print_current
= 0;
711 int print_system
= 0;
712 int print_builtin
= 1;
713 char *print_unix
= NULL
;
714 const char *sep_char
= "\\";
715 DWORD id_offset
= 10000, off
;
717 char *disp_groupname
= NULL
;
719 int optional_args
= 0;
722 setmode (1, O_BINARY
);
724 /* Use locale from environment. If not set or set to "C", use UTF-8. */
725 setlocale (LC_CTYPE
, "");
726 if (!strcmp (setlocale (LC_CTYPE
, NULL
), "C"))
727 setlocale (LC_CTYPE
, "en_US.UTF-8");
728 in_domain
= fetch_primary_domain ();
729 fetch_current_pgrp_sid ();
733 print_special (&sid_nt_auth
, 1, SECURITY_LOCAL_SYSTEM_RID
,
734 0, 0, 0, 0, 0, 0, 0);
737 if (!enum_local_groups (TRUE
, NULL
, sep_char
, id_offset
,
738 disp_groupname
, print_builtin
, 0))
739 enum_groups (TRUE
, NULL
, sep_char
, id_offset
, disp_groupname
, 0);
741 else if (!enum_local_groups (FALSE
, NULL
, sep_char
, 0, disp_groupname
,
743 enum_groups (FALSE
, NULL
, sep_char
, 0, disp_groupname
, 0);
747 unsetenv ("POSIXLY_CORRECT"); /* To get optional arg processing right. */
748 while ((c
= getopt_long (argc
, argv
, opts
, longopts
, NULL
)) != EOF
)
755 if (print_domlist
>= 32)
757 fprintf (stderr
, "%s: Can not enumerate from more than 32 "
758 "domains and machines.\n",
759 program_invocation_short_name
);
762 domlist
[print_domlist
].domain
= (c
== 'd' || c
== 'D');
764 argv
[optind
] && argv
[optind
][0] != '-' ? argv
[optind
] : NULL
;
765 if (argv
[optind
] && opt
== argv
[optind
])
767 for (i
= 0; i
< print_domlist
; ++i
)
768 if (domlist
[i
].domain
== domlist
[print_domlist
].domain
769 && ((!domlist
[i
].str
&& !opt
)
770 || (domlist
[i
].str
&& opt
771 && (off
= strlen (domlist
[i
].str
))
772 && !strncmp (domlist
[i
].str
, opt
, off
)
773 && (!opt
[off
] || opt
[off
] == ','))))
775 fprintf (stderr
, "%s: Duplicate %s '%s'. Skipping...\n",
776 program_invocation_short_name
,
777 domlist
[i
].domain
? "domain" : "machine",
781 if (!(domlist
[print_domlist
].str
= opt
))
783 domlist
[print_domlist
].id_offset
= ULONG_MAX
;
784 if (opt
&& (p
= strchr (opt
, ',')))
787 || !isdigit ((unsigned char) p
[1])
788 || (domlist
[print_domlist
].id_offset
= strtol (p
+ 1, &ep
, 10)
791 fprintf (stderr
, "%s: Malformed machine,offset string '%s'. "
792 "Skipping...\n", program_invocation_short_name
, opt
);
797 domlist
[print_domlist
++].with_dom
= (c
== 'D' || c
== 'L');
802 if (strlen (sep_char
) > 1)
804 fprintf (stderr
, "%s: Only one character allowed as domain\\user "
805 "separator character.\n",
806 program_invocation_short_name
);
809 if (*sep_char
== ':')
811 fprintf (stderr
, "%s: Colon not allowed as domain\\user separator "
812 "character.\n", program_invocation_short_name
);
826 id_offset
= strtol (optarg
, NULL
, 10);
836 disp_groupname
= optarg
;
845 fprintf (stderr
, "Try `%s --help' for more information.\n", argv
[0]);
849 optind
+= optional_args
;
853 "mkgroup: non-option command line argument `%s' is not allowed.\n"
854 "Try `mkgroup --help' for more information.\n", argv
[optind
]);
858 /* Get 'system' group */
859 if (!disp_groupname
&& print_system
&& print_builtin
&& print_domlist
)
860 print_special (&sid_nt_auth
, 1, SECURITY_LOCAL_SYSTEM_RID
,
861 0, 0, 0, 0, 0, 0, 0);
864 for (i
= 0; i
< print_domlist
; ++i
)
866 DWORD my_off
= (domlist
[i
].domain
|| domlist
[i
].str
)
867 ? domlist
[i
].id_offset
!= ULONG_MAX
868 ? domlist
[i
].id_offset
: off
: 0;
869 if (!enum_local_groups (domlist
[i
].domain
, domlist
+ i
, sep_char
,
870 my_off
, disp_groupname
, print_builtin
, print_current
))
872 if (!domlist
[i
].domain
&& domlist
[i
].str
&& print_unix
)
873 enum_unix_groups (domlist
+ i
, sep_char
, my_off
, print_unix
);
874 enum_groups (domlist
[i
].domain
, domlist
+ i
, sep_char
, my_off
,
875 disp_groupname
, print_current
);
881 if (print_current
&& !got_curr_pgrp
)
882 current_group (sep_char
, off
);