3 Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
4 2008, 2009, 2010, 2011, 2012 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_by_sid (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 print_special_by_name (PCWSTR name
, gid_t gid
)
603 DWORD size
= 256, dom_size
= 256;
604 PSID sid
= (PSID
) alloca (size
);
608 PWCHAR name_only
= wcschr (name
, L
'\\');
612 if (LookupAccountNameW (NULL
, name
, sid
, &size
, dom
, &dom_size
, &use
))
613 printf ("%ls:%s:%lu:\n",
614 name_only
?: name
, put_sid (sid
), (unsigned long) gid
);
618 usage (FILE * stream
)
621 "Usage: %s [OPTION]...\n"
623 "Print /etc/group file to stdout\n"
627 " -l,--local [machine[,offset]]\n"
628 " print local groups with gid offset offset\n"
629 " (from local machine if no machine specified)\n"
630 " -L,--Local [machine[,offset]]\n"
631 " ditto, but generate groupname with machine prefix\n"
632 " -d,--domain [domain[,offset]]\n"
633 " print domain groups with gid offset offset\n"
634 " (from current domain if no domain specified)\n"
635 " -D,--Domain [domain[,offset]]\n"
636 " ditto, but generate groupname with machine prefix\n"
637 " -c,--current print current group\n"
638 " -C,--Current ditto, but generate groupname with machine or\n"
640 " -S,--separator char for -L, -D, -C use character char as domain\\group\n"
641 " separator in groupname instead of the default '\\'\n"
642 " -o,--id-offset offset change the default offset (10000) added to gids\n"
643 " in domain or foreign server accounts.\n"
644 " -g,--group groupname only return information for the specified group\n"
645 " one of -l, -L, -d, -D must be specified, too\n"
646 " -b,--no-builtin don't print BUILTIN groups\n"
647 " -U,--unix grouplist additionally print UNIX groups when using -l or -L\n"
648 " on a UNIX Samba server\n"
649 " grouplist is a comma-separated list of groupnames\n"
650 " or gid ranges (root,-25,50-100).\n"
651 " (enumerating large ranges can take a long time!)\n"
652 " -s,--no-sids (ignored)\n"
653 " -u,--users (ignored)\n"
654 " -h,--help print this message\n"
655 " -v,--version print version information and exit\n"
657 "Default is to print local groups on stand-alone machines, plus domain\n"
658 "groups on domain controllers and domain member machines.\n"
659 "\n", program_invocation_short_name
);
663 struct option longopts
[] = {
664 {"no-builtin", no_argument
, NULL
, 'b'},
665 {"current", no_argument
, NULL
, 'c'},
666 {"Current", no_argument
, NULL
, 'C'},
667 {"domain", optional_argument
, NULL
, 'd'},
668 {"Domain", optional_argument
, NULL
, 'D'},
669 {"group", required_argument
, NULL
, 'g'},
670 {"help", no_argument
, NULL
, 'h'},
671 {"local", optional_argument
, NULL
, 'l'},
672 {"Local", optional_argument
, NULL
, 'L'},
673 {"id-offset", required_argument
, NULL
, 'o'},
674 {"no-sids", no_argument
, NULL
, 's'},
675 {"separator", required_argument
, NULL
, 'S'},
676 {"users", no_argument
, NULL
, 'u'},
677 {"unix", required_argument
, NULL
, 'U'},
678 {"version", no_argument
, NULL
, 'V'},
679 {0, no_argument
, NULL
, 0}
682 static char opts
[] = "bcCd::D::g:hl::L::o:sS:uU:V";
687 printf ("mkgroup (cygwin) %d.%d.%d\n"
688 "Group File Generator\n"
689 "Copyright (C) 1997 - %s Red Hat, Inc.\n"
690 "This is free software; see the source for copying conditions. There is NO\n"
691 "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",
692 CYGWIN_VERSION_DLL_MAJOR
/ 1000,
693 CYGWIN_VERSION_DLL_MAJOR
% 1000,
694 CYGWIN_VERSION_DLL_MINOR
,
695 strrchr (__DATE__
, ' ') + 1);
698 static PPOLICY_PRIMARY_DOMAIN_INFO p_dom
;
701 fetch_primary_domain ()
704 LSA_OBJECT_ATTRIBUTES oa
= { 0, 0, 0, 0, 0, 0 };
709 status
= LsaOpenPolicy (NULL
, &oa
, POLICY_EXECUTE
, &lsa
);
710 if (!NT_SUCCESS (status
))
712 status
= LsaQueryInformationPolicy (lsa
, PolicyPrimaryDomainInformation
,
713 (PVOID
*) ((void *) &p_dom
));
715 if (!NT_SUCCESS (status
))
722 main (int argc
, char **argv
)
724 int print_domlist
= 0;
725 domlist_t domlist
[32];
727 int print_current
= 0;
728 int print_system
= 0;
729 int print_builtin
= 1;
730 char *print_unix
= NULL
;
731 const char *sep_char
= "\\";
732 DWORD id_offset
= 10000, off
;
734 char *disp_groupname
= NULL
;
736 int optional_args
= 0;
739 setmode (1, O_BINARY
);
741 /* Use locale from environment. If not set or set to "C", use UTF-8. */
742 setlocale (LC_CTYPE
, "");
743 if (!strcmp (setlocale (LC_CTYPE
, NULL
), "C"))
744 setlocale (LC_CTYPE
, "en_US.UTF-8");
745 in_domain
= fetch_primary_domain ();
746 fetch_current_pgrp_sid ();
750 print_special_by_sid (&sid_nt_auth
, 1, SECURITY_LOCAL_SYSTEM_RID
,
751 0, 0, 0, 0, 0, 0, 0);
754 if (!enum_local_groups (TRUE
, NULL
, sep_char
, id_offset
,
755 disp_groupname
, print_builtin
, 0))
756 enum_groups (TRUE
, NULL
, sep_char
, id_offset
, disp_groupname
, 0);
758 else if (!enum_local_groups (FALSE
, NULL
, sep_char
, 0, disp_groupname
,
760 enum_groups (FALSE
, NULL
, sep_char
, 0, disp_groupname
, 0);
764 unsetenv ("POSIXLY_CORRECT"); /* To get optional arg processing right. */
765 while ((c
= getopt_long (argc
, argv
, opts
, longopts
, NULL
)) != EOF
)
772 if (print_domlist
>= 32)
774 fprintf (stderr
, "%s: Can not enumerate from more than 32 "
775 "domains and machines.\n",
776 program_invocation_short_name
);
779 domlist
[print_domlist
].domain
= (c
== 'd' || c
== 'D');
781 argv
[optind
] && argv
[optind
][0] != '-' ? argv
[optind
] : NULL
;
782 if (argv
[optind
] && opt
== argv
[optind
])
784 for (i
= 0; i
< print_domlist
; ++i
)
785 if (domlist
[i
].domain
== domlist
[print_domlist
].domain
786 && ((!domlist
[i
].str
&& !opt
)
787 || (domlist
[i
].str
&& opt
788 && (off
= strlen (domlist
[i
].str
))
789 && !strncmp (domlist
[i
].str
, opt
, off
)
790 && (!opt
[off
] || opt
[off
] == ','))))
792 fprintf (stderr
, "%s: Duplicate %s '%s'. Skipping...\n",
793 program_invocation_short_name
,
794 domlist
[i
].domain
? "domain" : "machine",
798 if (!(domlist
[print_domlist
].str
= opt
))
800 domlist
[print_domlist
].id_offset
= ULONG_MAX
;
801 if (opt
&& (p
= strchr (opt
, ',')))
804 || !isdigit ((unsigned char) p
[1])
805 || (domlist
[print_domlist
].id_offset
= strtol (p
+ 1, &ep
, 10)
808 fprintf (stderr
, "%s: Malformed machine,offset string '%s'. "
809 "Skipping...\n", program_invocation_short_name
, opt
);
814 domlist
[print_domlist
++].with_dom
= (c
== 'D' || c
== 'L');
819 if (strlen (sep_char
) > 1)
821 fprintf (stderr
, "%s: Only one character allowed as domain\\user "
822 "separator character.\n",
823 program_invocation_short_name
);
826 if (*sep_char
== ':')
828 fprintf (stderr
, "%s: Colon not allowed as domain\\user separator "
829 "character.\n", program_invocation_short_name
);
843 id_offset
= strtol (optarg
, NULL
, 10);
853 disp_groupname
= optarg
;
862 fprintf (stderr
, "Try `%s --help' for more information.\n", argv
[0]);
866 optind
+= optional_args
;
870 "mkgroup: non-option command line argument `%s' is not allowed.\n"
871 "Try `mkgroup --help' for more information.\n", argv
[optind
]);
875 /* Get 'system' group */
876 if (!disp_groupname
&& print_system
&& print_builtin
&& print_domlist
)
878 print_special_by_sid (&sid_nt_auth
, 1, SECURITY_LOCAL_SYSTEM_RID
,
879 0, 0, 0, 0, 0, 0, 0);
880 print_special_by_name (L
"NT SERVICE\\TrustedInstaller", -2);
884 for (i
= 0; i
< print_domlist
; ++i
)
886 DWORD my_off
= (domlist
[i
].domain
|| domlist
[i
].str
)
887 ? domlist
[i
].id_offset
!= ULONG_MAX
888 ? domlist
[i
].id_offset
: off
: 0;
889 if (!enum_local_groups (domlist
[i
].domain
, domlist
+ i
, sep_char
,
890 my_off
, disp_groupname
, print_builtin
, print_current
))
892 if (!domlist
[i
].domain
&& domlist
[i
].str
&& print_unix
)
893 enum_unix_groups (domlist
+ i
, sep_char
, my_off
, print_unix
);
894 enum_groups (domlist
[i
].domain
, domlist
+ i
, sep_char
, my_off
,
895 disp_groupname
, print_current
);
901 if (print_current
&& !got_curr_pgrp
)
902 current_group (sep_char
, off
);