3 Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
4 2007, 2008, 2009 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
22 #include <sys/fcntl.h>
23 #include <sys/cygwin.h>
32 #define print_win_error(x) _print_win_error(x, __LINE__)
34 #define MAX_SID_LEN 40
36 static const char version
[] = "$Revision$";
38 extern char *__progname
;
40 SID_IDENTIFIER_AUTHORITY sid_world_auth
= {SECURITY_WORLD_SID_AUTHORITY
};
41 SID_IDENTIFIER_AUTHORITY sid_nt_auth
= {SECURITY_NT_AUTHORITY
};
43 NET_API_STATUS
WINAPI (*dsgetdcname
)(LPWSTR
,LPWSTR
,GUID
*,LPWSTR
,ULONG
,PDOMAIN_CONTROLLER_INFOW
*);
46 #define min(a,b) (((a)<(b))?(a):(b))
58 _print_win_error (DWORD code
, int line
)
62 if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
63 | FORMAT_MESSAGE_IGNORE_INSERTS
,
66 MAKELANGID (LANG_NEUTRAL
, SUBLANG_DEFAULT
),
67 (LPTSTR
) buf
, sizeof (buf
), NULL
))
68 fprintf (stderr
, "mkgroup (%d): [%lu] %s", line
, code
, buf
);
70 fprintf (stderr
, "mkgroup (%d): error %lu", line
, code
);
76 HANDLE h
= LoadLibrary ("netapi32.dll");
78 dsgetdcname
= (void *) GetProcAddress (h
, "DsGetDcNameW");
82 get_dcname (char *domain
)
84 static WCHAR server
[INTERNET_MAX_HOST_NAME_LENGTH
+ 1];
87 WCHAR domain_name
[MAX_DOMAIN_NAME_LEN
+ 1];
88 PDOMAIN_CONTROLLER_INFOW pdci
= NULL
;
94 mbstowcs (domain_name
, domain
, strlen (domain
) + 1);
95 rc
= dsgetdcname (NULL
, domain_name
, NULL
, NULL
, 0, &pdci
);
98 rc
= dsgetdcname (NULL
, NULL
, NULL
, NULL
, 0, &pdci
);
99 if (rc
!= ERROR_SUCCESS
)
101 print_win_error (rc
);
104 wcscpy (server
, pdci
->DomainControllerName
);
105 NetApiBufferFree (pdci
);
109 rc
= NetGetDCName (NULL
, NULL
, (void *) &servername
);
110 if (rc
== ERROR_SUCCESS
&& domain
)
112 LPWSTR server
= servername
;
113 mbstowcs (domain_name
, domain
, strlen (domain
) + 1);
114 rc
= NetGetDCName (server
, domain_name
, (void *) &servername
);
115 NetApiBufferFree (server
);
117 if (rc
!= ERROR_SUCCESS
)
122 wcscpy (server
, servername
);
123 NetApiBufferFree ((PVOID
) servername
);
136 sprintf(t
, "%u", GetSidIdentifierAuthority (psid
)->Value
[5]);
138 for (i
= 0; i
< *GetSidSubAuthorityCount (psid
); ++i
)
140 sprintf(t
, "-%lu", *GetSidSubAuthority (psid
, i
));
148 BYTE SubAuthorityCount
;
149 SID_IDENTIFIER_AUTHORITY IdentifierAuthority
;
150 DWORD SubAuthority
[8];
153 #define MAX_BUILTIN_SIDS 100 /* Should be enough for the forseable future. */
154 DBGSID builtin_sid_list
[MAX_BUILTIN_SIDS
];
155 DWORD builtin_sid_cnt
;
162 static sidbuf curr_pgrp
;
163 static BOOL got_curr_pgrp
= FALSE
;
166 fetch_current_pgrp_sid ()
171 if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY
, &ptok
)
172 || !GetTokenInformation (ptok
, TokenPrimaryGroup
, &curr_pgrp
,
173 sizeof curr_pgrp
, &len
)
174 || !CloseHandle (ptok
))
176 print_win_error (GetLastError ());
182 current_group (const char *sep
, DWORD id_offset
)
184 WCHAR grp
[GNLEN
+ 1];
185 WCHAR dom
[MAX_DOMAIN_NAME_LEN
+ 1];
186 DWORD glen
= GNLEN
+ 1;
187 DWORD dlen
= MAX_DOMAIN_NAME_LEN
+ 1;
189 SID_NAME_USE acc_type
;
192 || !LookupAccountSidW (NULL
, curr_pgrp
.psid
, grp
, &glen
, dom
, &dlen
,
195 print_win_error (GetLastError ());
198 gid
= *GetSidSubAuthority (curr_pgrp
.psid
,
199 *GetSidSubAuthorityCount(curr_pgrp
.psid
) - 1);
200 printf ("%ls%s%ls:%s:%lu:\n",
204 put_sid (curr_pgrp
.psid
),
209 enum_unix_groups (domlist_t
*dom_or_machine
, const char *sep
, DWORD id_offset
,
212 WCHAR machine
[INTERNET_MAX_HOST_NAME_LENGTH
+ 1];
213 PWCHAR servername
= NULL
;
214 char *d_or_m
= dom_or_machine
? dom_or_machine
->str
: NULL
;
215 BOOL with_dom
= dom_or_machine
? dom_or_machine
->with_dom
: FALSE
;
216 SID_IDENTIFIER_AUTHORITY auth
= { { 0, 0, 0, 0, 0, 22 } };
217 char *gstr
, *grp_list
;
218 WCHAR grp
[GNLEN
+ sizeof ("Unix Group\\") + 1];
219 WCHAR dom
[MAX_DOMAIN_NAME_LEN
+ 1];
220 DWORD glen
, dlen
, sidlen
;
222 char psid_buffer
[MAX_SID_LEN
];
223 SID_NAME_USE acc_type
;
228 int ret
= mbstowcs (machine
, d_or_m
, INTERNET_MAX_HOST_NAME_LENGTH
+ 1);
229 if (ret
< 1 || ret
>= INTERNET_MAX_HOST_NAME_LENGTH
+ 1)
231 fprintf (stderr
, "%s: Invalid machine name '%s'. Skipping...\n",
235 servername
= machine
;
237 if (!AllocateAndInitializeSid (&auth
, 2, 2, 0, 0, 0, 0, 0, 0, 0, &psid
))
240 if (!(grp_list
= strdup (unix_grp_list
)))
246 for (gstr
= strtok (grp_list
, ","); gstr
; gstr
= strtok (NULL
, ","))
248 if (!isdigit ((unsigned char) gstr
[0]) && gstr
[0] != '-')
250 PWCHAR p
= wcpcpy (grp
, L
"Unix Group\\");
251 ret
= mbstowcs (p
, gstr
, GNLEN
+ 1);
252 if (ret
< 1 || ret
>= GNLEN
+ 1)
253 fprintf (stderr
, "%s: Invalid group name '%s'. Skipping...\n",
255 else if (LookupAccountNameW (servername
, grp
,
256 psid
= (PSID
) psid_buffer
,
257 (sidlen
= MAX_SID_LEN
, &sidlen
),
259 (dlen
= MAX_DOMAIN_NAME_LEN
+ 1, &dlen
),
261 printf ("%s%s%ls:%s:%lu:\n",
262 with_dom
? "Unix Group" : "",
267 *GetSidSubAuthority (psid
,
268 *GetSidSubAuthorityCount(psid
) - 1));
277 start
= strtol (p
, &p
, 10);
280 else if (*p
++ != '-' || !isdigit ((unsigned char) *p
)
281 || (stop
= strtol (p
, &p
, 10)) < start
|| *p
)
283 fprintf (stderr
, "%s: Malformed unix group list entry '%s'. "
284 "Skipping...\n", __progname
, gstr
);
287 for (; start
<= stop
; ++ start
)
289 *GetSidSubAuthority (psid
, *GetSidSubAuthorityCount(psid
) - 1)
291 if (LookupAccountSidW (servername
, psid
,
292 grp
, (glen
= GNLEN
+ 1, &glen
),
294 (dlen
= MAX_DOMAIN_NAME_LEN
+ 1, &dlen
),
296 && !iswdigit (grp
[0]))
297 printf ("%s%s%ls:%s:%lu:\n",
298 with_dom
? "Unix Group" : "",
312 enum_local_groups (BOOL domain
, domlist_t
*dom_or_machine
, const char *sep
,
313 DWORD id_offset
, char *disp_groupname
, int print_builtin
,
316 WCHAR machine
[INTERNET_MAX_HOST_NAME_LENGTH
+ 1];
317 PWCHAR servername
= NULL
;
318 char *d_or_m
= dom_or_machine
? dom_or_machine
->str
: NULL
;
319 BOOL with_dom
= dom_or_machine
? dom_or_machine
->with_dom
: FALSE
;
320 LOCALGROUP_INFO_0
*buffer
;
321 DWORD entriesread
= 0;
322 DWORD totalentries
= 0;
323 DWORD resume_handle
= 0;
324 WCHAR gname
[GNLEN
+ 1];
329 servername
= get_dcname (d_or_m
);
330 if (servername
== (PWCHAR
) -1)
335 int ret
= mbstowcs (machine
, d_or_m
, INTERNET_MAX_HOST_NAME_LENGTH
+ 1);
336 if (ret
< 1 || ret
>= INTERNET_MAX_HOST_NAME_LENGTH
+ 1)
338 fprintf (stderr
, "%s: Invalid machine name '%s'. Skipping...\n",
342 servername
= machine
;
351 mbstowcs (gname
, disp_groupname
, GNLEN
+ 1);
352 rc
= NetLocalGroupGetInfo (servername
, gname
, 0, (void *) &buffer
);
353 if (rc
== ERROR_SUCCESS
)
355 /* Allow further searching for the group and avoid annoying
356 error messages just because the group is not a local group or
357 the group hasn't been found. */
358 else if (rc
== ERROR_NO_SUCH_ALIAS
|| rc
== NERR_GroupNotFound
)
362 rc
= NetLocalGroupEnum (servername
, 0, (void *) &buffer
,
363 MAX_PREFERRED_LENGTH
, &entriesread
,
364 &totalentries
, &resume_handle
);
367 case ERROR_ACCESS_DENIED
:
368 print_win_error (rc
);
371 case ERROR_MORE_DATA
:
376 print_win_error (rc
);
380 for (i
= 0; i
< entriesread
; i
++)
382 WCHAR domain_name
[MAX_DOMAIN_NAME_LEN
+ 1];
383 DWORD domname_len
= MAX_DOMAIN_NAME_LEN
+ 1;
384 char psid_buffer
[MAX_SID_LEN
];
385 PSID psid
= (PSID
) psid_buffer
;
386 DWORD sid_length
= MAX_SID_LEN
;
388 SID_NAME_USE acc_type
;
390 BOOL is_builtin
= FALSE
;
392 if (!LookupAccountNameW (servername
, buffer
[i
].lgrpi0_name
, psid
,
393 &sid_length
, domain_name
, &domname_len
,
396 print_win_error (GetLastError ());
397 fprintf (stderr
, " (%ls)\n", buffer
[i
].lgrpi0_name
);
400 else if (acc_type
== SidTypeDomain
)
402 WCHAR domname
[MAX_DOMAIN_NAME_LEN
+ GNLEN
+ 2];
404 wcscpy (domname
, domain_name
);
405 wcscat (domname
, L
"\\");
406 wcscat (domname
, buffer
[i
].lgrpi0_name
);
407 sid_length
= MAX_SID_LEN
;
408 domname_len
= MAX_DOMAIN_NAME_LEN
+ 1;
409 if (!LookupAccountNameW (servername
, domname
,
411 domain_name
, &domname_len
,
414 print_win_error (GetLastError ());
415 fprintf(stderr
, " (%ls)\n", domname
);
420 /* Store all local SIDs with prefix "S-1-5-32-" and check if it
421 has been printed already. This allows to get all builtin
422 groups exactly once and not once per domain. */
423 pdsid
= (PDBGSID
) psid
;
424 if (pdsid
->IdentifierAuthority
.Value
[5] == sid_nt_auth
.Value
[5]
425 && pdsid
->SubAuthority
[0] == SECURITY_BUILTIN_DOMAIN_RID
)
433 for (b
= 0; b
< builtin_sid_cnt
; b
++)
434 if (EqualSid (&builtin_sid_list
[b
], psid
))
436 if (builtin_sid_cnt
< MAX_BUILTIN_SIDS
)
437 CopySid (sizeof (DBGSID
), &builtin_sid_list
[builtin_sid_cnt
++],
442 else if (EqualSid (curr_pgrp
.psid
, psid
))
443 got_curr_pgrp
= TRUE
;
445 gid
= *GetSidSubAuthority (psid
, *GetSidSubAuthorityCount(psid
) - 1);
446 printf ("%ls%s%ls:%s:%ld:\n",
447 with_dom
&& !is_builtin
? domain_name
: L
"",
448 with_dom
&& !is_builtin
? sep
: "",
449 buffer
[i
].lgrpi0_name
,
451 gid
+ (is_builtin
? 0 : id_offset
));
456 NetApiBufferFree (buffer
);
459 while (rc
== ERROR_MORE_DATA
);
461 /* Return 1 if the single group we're looking for has been found here to
462 avoid calling enum_groups for the same group, thus avoiding a spurious
463 error message "group name could not be found" in enum_groups. */
464 return disp_groupname
&& entriesread
? 1 : 0;
468 enum_groups (BOOL domain
, domlist_t
*dom_or_machine
, const char *sep
,
469 DWORD id_offset
, char *disp_groupname
, int print_current
)
471 WCHAR machine
[INTERNET_MAX_HOST_NAME_LENGTH
+ 1];
472 PWCHAR servername
= NULL
;
473 char *d_or_m
= dom_or_machine
? dom_or_machine
->str
: NULL
;
474 BOOL with_dom
= dom_or_machine
? dom_or_machine
->with_dom
: FALSE
;
475 GROUP_INFO_2
*buffer
;
476 DWORD entriesread
= 0;
477 DWORD totalentries
= 0;
478 DWORD resume_handle
= 0;
479 WCHAR gname
[GNLEN
+ 1];
484 servername
= get_dcname (d_or_m
);
485 if (servername
== (PWCHAR
) -1)
490 int ret
= mbstowcs (machine
, d_or_m
, INTERNET_MAX_HOST_NAME_LENGTH
+ 1);
491 if (ret
< 1 || ret
>= INTERNET_MAX_HOST_NAME_LENGTH
+ 1)
493 fprintf (stderr
, "%s: Invalid machine name '%s'. Skipping...\n",
497 servername
= machine
;
504 if (disp_groupname
!= NULL
)
506 mbstowcs (gname
, disp_groupname
, GNLEN
+ 1);
507 rc
= NetGroupGetInfo (servername
, (LPWSTR
) & gname
, 2,
510 /* Avoid annoying error messages just because the group hasn't been
512 if (rc
== NERR_GroupNotFound
)
516 rc
= NetGroupEnum (servername
, 2, (void *) & buffer
,
517 MAX_PREFERRED_LENGTH
, &entriesread
, &totalentries
,
521 case ERROR_ACCESS_DENIED
:
522 print_win_error (rc
);
525 case ERROR_MORE_DATA
:
530 print_win_error (rc
);
534 for (i
= 0; i
< entriesread
; i
++)
536 WCHAR domain_name
[MAX_DOMAIN_NAME_LEN
+ 1];
537 DWORD domname_len
= MAX_DOMAIN_NAME_LEN
+ 1;
538 char psid_buffer
[MAX_SID_LEN
];
539 PSID psid
= (PSID
) psid_buffer
;
540 DWORD sid_length
= MAX_SID_LEN
;
541 SID_NAME_USE acc_type
;
543 int gid
= buffer
[i
].grpi2_group_id
;
544 if (!LookupAccountNameW (servername
, buffer
[i
].grpi2_name
,
546 domain_name
, &domname_len
,
549 print_win_error (GetLastError ());
550 fprintf(stderr
, " (%ls)\n", buffer
[i
].grpi2_name
);
553 else if (acc_type
== SidTypeDomain
)
555 WCHAR domname
[MAX_DOMAIN_NAME_LEN
+ GNLEN
+ 2];
557 wcscpy (domname
, domain
|| !servername
558 ? domain_name
: servername
);
559 wcscat (domname
, L
"\\");
560 wcscat (domname
, buffer
[i
].grpi2_name
);
561 sid_length
= MAX_SID_LEN
;
562 domname_len
= MAX_DOMAIN_NAME_LEN
+ 1;
563 if (!LookupAccountNameW (servername
, domname
,
565 domain_name
, &domname_len
,
568 print_win_error (GetLastError ());
569 fprintf(stderr
, " (%ls)\n", domname
);
575 else if (EqualSid (curr_pgrp
.psid
, psid
))
576 got_curr_pgrp
= TRUE
;
578 printf ("%ls%s%ls:%s:%lu:\n",
579 with_dom
? domain_name
: L
"",
581 buffer
[i
].grpi2_name
,
586 NetApiBufferFree (buffer
);
589 while (rc
== ERROR_MORE_DATA
);
593 print_special (PSID_IDENTIFIER_AUTHORITY auth
, BYTE cnt
,
594 DWORD sub1
, DWORD sub2
, DWORD sub3
, DWORD sub4
,
595 DWORD sub5
, DWORD sub6
, DWORD sub7
, DWORD sub8
)
597 WCHAR grp
[GNLEN
+ 1], dom
[MAX_DOMAIN_NAME_LEN
+ 1];
598 DWORD glen
, dlen
, rid
;
600 SID_NAME_USE acc_type
;
602 if (AllocateAndInitializeSid (auth
, cnt
, sub1
, sub2
, sub3
, sub4
,
603 sub5
, sub6
, sub7
, sub8
, &psid
))
605 if (LookupAccountSidW (NULL
, psid
,
606 grp
, (glen
= GNLEN
+ 1, &glen
),
607 dom
, (dlen
= MAX_DOMAIN_NAME_LEN
+ 1, &dlen
),
626 printf ("%ls:%s:%lu:\n", grp
, put_sid (psid
), rid
);
633 usage (FILE * stream
)
636 "Usage: mkgroup [OPTION]...\n"
637 "Print /etc/group file to stdout\n"
640 " -l,--local [machine[,offset]]\n"
641 " print local groups with gid offset offset\n"
642 " (from local machine if no machine specified)\n"
643 " -L,--Local [machine[,offset]]\n"
644 " ditto, but generate groupname with machine prefix\n"
645 " -d,--domain [domain[,offset]]\n"
646 " print domain groups with gid offset offset\n"
647 " (from current domain if no domain specified)\n"
648 " -D,--Domain [domain[,offset]]\n"
649 " ditto, but generate groupname with machine prefix\n"
650 " -c,--current print current group\n"
651 " -C,--Current ditto, but generate groupname with machine or\n"
653 " -S,--separator char for -L, -D, -C use character char as domain\\group\n"
654 " separator in groupname instead of the default '\\'\n"
655 " -o,--id-offset offset change the default offset (10000) added to gids\n"
656 " in domain or foreign server accounts.\n"
657 " -g,--group groupname only return information for the specified group\n"
658 " one of -l, -L, -d, -D must be specified, too\n"
659 " -b,--no-builtin don't print BUILTIN groups\n"
660 " -U,--unix grouplist additionally print UNIX groups when using -l or -L\n"
661 " on a UNIX Samba server\n"
662 " grouplist is a comma-separated list of groupnames\n"
663 " or gid ranges (root,-25,50-100).\n"
664 " (enumerating large ranges can take a long time!)\n"
665 " -s,--no-sids (ignored)\n"
666 " -u,--users (ignored)\n"
667 " -h,--help print this message\n"
668 " -v,--version print version information and exit\n"
670 "Default is to print local groups on stand-alone machines, plus domain\n"
671 "groups on domain controllers and domain member machines.\n");
675 struct option longopts
[] = {
676 {"no-builtin", no_argument
, NULL
, 'b'},
677 {"current", no_argument
, NULL
, 'c'},
678 {"Current", no_argument
, NULL
, 'C'},
679 {"domain", optional_argument
, NULL
, 'd'},
680 {"Domain", optional_argument
, NULL
, 'D'},
681 {"group", required_argument
, NULL
, 'g'},
682 {"help", no_argument
, NULL
, 'h'},
683 {"local", optional_argument
, NULL
, 'l'},
684 {"Local", optional_argument
, NULL
, 'L'},
685 {"id-offset", required_argument
, NULL
, 'o'},
686 {"no-sids", no_argument
, NULL
, 's'},
687 {"separator", required_argument
, NULL
, 'S'},
688 {"users", no_argument
, NULL
, 'u'},
689 {"unix", required_argument
, NULL
, 'U'},
690 {"version", no_argument
, NULL
, 'v'},
691 {0, no_argument
, NULL
, 0}
694 static char opts
[] = "bcCd::D::g:hl::L::o:sS:uU:v";
699 const char *v
= strchr (version
, ':');
709 len
= strchr (v
, ' ') - v
;
712 mkgroup (cygwin) %.*s\n\
713 group File Generator\n\
714 Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Red Hat, Inc.\n\
716 ", len
, v
, __DATE__
);
719 static PPOLICY_PRIMARY_DOMAIN_INFO p_dom
;
722 fetch_primary_domain ()
725 LSA_OBJECT_ATTRIBUTES oa
= { 0, 0, 0, 0, 0, 0 };
730 status
= LsaOpenPolicy (NULL
, &oa
, POLICY_EXECUTE
, &lsa
);
731 if (!NT_SUCCESS (status
))
733 status
= LsaQueryInformationPolicy (lsa
, PolicyPrimaryDomainInformation
,
734 (PVOID
*) ((void *) &p_dom
));
736 if (!NT_SUCCESS (status
))
743 main (int argc
, char **argv
)
745 int print_domlist
= 0;
746 domlist_t domlist
[32];
748 int print_current
= 0;
749 int print_system
= 0;
750 int print_builtin
= 1;
751 char *print_unix
= NULL
;
752 const char *sep_char
= "\\";
753 DWORD id_offset
= 10000, off
;
755 char *disp_groupname
= NULL
;
757 int optional_args
= 0;
760 setmode (1, O_BINARY
);
762 /* Use locale from environment. If not set or set to "C", use UTF-8. */
763 setlocale (LC_CTYPE
, "");
764 if (!strcmp (setlocale (LC_CTYPE
, NULL
), "C"))
765 setlocale (LC_CTYPE
, "en_US.UTF-8");
767 in_domain
= fetch_primary_domain ();
768 fetch_current_pgrp_sid ();
772 print_special (&sid_nt_auth
, 1, SECURITY_LOCAL_SYSTEM_RID
,
773 0, 0, 0, 0, 0, 0, 0);
776 if (!enum_local_groups (TRUE
, NULL
, sep_char
, id_offset
,
777 disp_groupname
, print_builtin
, 0))
778 enum_groups (TRUE
, NULL
, sep_char
, id_offset
, disp_groupname
, 0);
780 else if (!enum_local_groups (FALSE
, NULL
, sep_char
, 0, disp_groupname
,
782 enum_groups (FALSE
, NULL
, sep_char
, 0, disp_groupname
, 0);
786 unsetenv ("POSIXLY_CORRECT"); /* To get optional arg processing right. */
787 while ((c
= getopt_long (argc
, argv
, opts
, longopts
, NULL
)) != EOF
)
794 if (print_domlist
>= 32)
796 fprintf (stderr
, "%s: Can not enumerate from more than 32 "
797 "domains and machines.\n", __progname
);
800 domlist
[print_domlist
].domain
= (c
== 'd' || c
== 'D');
802 argv
[optind
] && argv
[optind
][0] != '-' ? argv
[optind
] : NULL
;
803 if (argv
[optind
] && opt
== argv
[optind
])
805 for (i
= 0; i
< print_domlist
; ++i
)
806 if (domlist
[i
].domain
== domlist
[print_domlist
].domain
807 && ((!domlist
[i
].str
&& !opt
)
808 || (domlist
[i
].str
&& opt
809 && (off
= strlen (domlist
[i
].str
))
810 && !strncmp (domlist
[i
].str
, opt
, off
)
811 && (!opt
[off
] || opt
[off
] == ','))))
813 fprintf (stderr
, "%s: Duplicate %s '%s'. Skipping...\n",
814 __progname
, domlist
[i
].domain
? "domain" : "machine",
818 if (!(domlist
[print_domlist
].str
= opt
))
820 domlist
[print_domlist
].id_offset
= ULONG_MAX
;
821 if (opt
&& (p
= strchr (opt
, ',')))
824 || !isdigit ((unsigned char) p
[1])
825 || (domlist
[print_domlist
].id_offset
= strtol (p
+ 1, &ep
, 10)
828 fprintf (stderr
, "%s: Malformed machine,offset string '%s'. "
829 "Skipping...\n", __progname
, opt
);
834 domlist
[print_domlist
++].with_dom
= (c
== 'D' || c
== 'L');
839 if (strlen (sep_char
) > 1)
841 fprintf (stderr
, "%s: Only one character allowed as domain\\user "
842 "separator character.\n", __progname
);
845 if (*sep_char
== ':')
847 fprintf (stderr
, "%s: Colon not allowed as domain\\user separator "
848 "character.\n", __progname
);
862 id_offset
= strtol (optarg
, NULL
, 10);
872 disp_groupname
= optarg
;
881 fprintf (stderr
, "Try '%s --help' for more information.\n", argv
[0]);
885 optind
+= optional_args
;
889 "mkgroup: non-option command line argument `%s' is not allowed.\n"
890 "Try `mkgroup --help' for more information.\n", argv
[optind
]);
894 /* Get 'system' group */
895 if (!disp_groupname
&& print_system
&& print_builtin
&& print_domlist
)
896 print_special (&sid_nt_auth
, 1, SECURITY_LOCAL_SYSTEM_RID
,
897 0, 0, 0, 0, 0, 0, 0);
900 for (i
= 0; i
< print_domlist
; ++i
)
902 DWORD my_off
= (domlist
[i
].domain
|| domlist
[i
].str
)
903 ? domlist
[i
].id_offset
!= ULONG_MAX
904 ? domlist
[i
].id_offset
: off
: 0;
905 if (!enum_local_groups (domlist
[i
].domain
, domlist
+ i
, sep_char
,
906 my_off
, disp_groupname
, print_builtin
, print_current
))
908 if (!domlist
[i
].domain
&& domlist
[i
].str
&& print_unix
)
909 enum_unix_groups (domlist
+ i
, sep_char
, my_off
, print_unix
);
910 enum_groups (domlist
[i
].domain
, domlist
+ i
, sep_char
, my_off
,
911 disp_groupname
, print_current
);
917 if (print_current
&& !got_curr_pgrp
)
918 current_group (sep_char
, off
);