3 Copyright 1997, 1998, 2002 Cygnus Solutions.
5 This file is part of Cygwin.
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
16 #include <sys/cygwin.h>
23 static const char version
[] = "$Revision$";
25 SID_IDENTIFIER_AUTHORITY sid_world_auth
= {SECURITY_WORLD_SID_AUTHORITY
};
26 SID_IDENTIFIER_AUTHORITY sid_nt_auth
= {SECURITY_NT_AUTHORITY
};
28 NET_API_STATUS
WINAPI (*netapibufferfree
)(PVOID
);
29 NET_API_STATUS
WINAPI (*netgroupenum
)(LPWSTR
,DWORD
,PBYTE
*,DWORD
,PDWORD
,PDWORD
,PDWORD
);
30 NET_API_STATUS
WINAPI (*netlocalgroupenum
)(LPWSTR
,DWORD
,PBYTE
*,DWORD
,PDWORD
,PDWORD
,PDWORD
);
31 NET_API_STATUS
WINAPI (*netlocalgroupgetmembers
)(LPWSTR
,LPWSTR
,DWORD
,PBYTE
*,DWORD
,PDWORD
,PDWORD
,PDWORD
);
32 NET_API_STATUS
WINAPI (*netgetdcname
)(LPWSTR
,LPWSTR
,PBYTE
*);
33 NET_API_STATUS
WINAPI (*netgroupgetusers
)(LPWSTR
,LPWSTR
,DWORD
,PBYTE
*,DWORD
,PDWORD
,PDWORD
,PDWORD
);
36 #define min(a,b) (((a)<(b))?(a):(b))
42 HANDLE h
= LoadLibrary ("netapi32.dll");
47 if (!(netapibufferfree
= (void *) GetProcAddress (h
, "NetApiBufferFree")))
49 if (!(netgroupenum
= (void *) GetProcAddress (h
, "NetGroupEnum")))
51 if (!(netgroupgetusers
= (void *) GetProcAddress (h
, "NetGroupGetUsers")))
53 if (!(netlocalgroupenum
= (void *) GetProcAddress (h
, "NetLocalGroupEnum")))
55 if (!(netlocalgroupgetmembers
= (void *) GetProcAddress (h
, "NetLocalGroupGetMembers")))
57 if (!(netgetdcname
= (void *) GetProcAddress (h
, "NetGetDCName")))
71 sprintf(t
, "%u", GetSidIdentifierAuthority (sid
)->Value
[5]);
73 for (i
= 0; i
< *GetSidSubAuthorityCount (sid
); ++i
)
75 sprintf(t
, "-%lu", *GetSidSubAuthority (sid
, i
));
82 psx_dir (char *in
, char *out
)
84 if (isalpha (in
[0]) && in
[1] == ':')
86 sprintf (out
, "/cygdrive/%c", in
[0]);
105 uni2ansi (LPWSTR wcs
, char *mbs
, int size
)
108 WideCharToMultiByte (CP_ACP
, 0, wcs
, -1, mbs
, size
, NULL
, NULL
);
114 enum_local_users (LPWSTR groupname
)
116 LOCALGROUP_MEMBERS_INFO_1
*buf1
;
121 if (!netlocalgroupgetmembers (NULL
, groupname
,
123 MAX_PREFERRED_LENGTH
,
124 &entries
, &total
, &reshdl
))
128 for (i
= 0; i
< entries
; ++i
)
129 if (buf1
[i
].lgrmi1_sidusage
== SidTypeUser
)
136 uni2ansi (buf1
[i
].lgrmi1_name
, user
, sizeof (user
));
139 netapibufferfree (buf1
);
144 enum_local_groups (int print_sids
, int print_users
)
146 LOCALGROUP_INFO_0
*buffer
;
147 DWORD entriesread
= 0;
148 DWORD totalentries
= 0;
149 DWORD resume_handle
= 0;
156 rc
= netlocalgroupenum (NULL
, 0, (LPBYTE
*) &buffer
, 1024,
157 &entriesread
, &totalentries
, &resume_handle
);
160 case ERROR_ACCESS_DENIED
:
161 fprintf (stderr
, "Access denied\n");
164 case ERROR_MORE_DATA
:
169 fprintf (stderr
, "NetLocalGroupEnum() failed with %ld\n", rc
);
173 for (i
= 0; i
< entriesread
; i
++)
175 char localgroup_name
[100];
176 char domain_name
[100];
177 DWORD domname_len
= 100;
178 char psid_buffer
[1024];
179 PSID psid
= (PSID
) psid_buffer
;
180 DWORD sid_length
= 1024;
182 SID_NAME_USE acc_type
;
183 uni2ansi (buffer
[i
].lgrpi0_name
, localgroup_name
, sizeof (localgroup_name
));
185 if (!LookupAccountName (NULL
, localgroup_name
, psid
,
186 &sid_length
, domain_name
, &domname_len
,
189 fprintf (stderr
, "LookupAccountName(%s) failed with %ld\n",
190 localgroup_name
, GetLastError ());
193 else if (acc_type
== SidTypeDomain
)
197 strcpy (domname
, domain_name
);
198 strcat (domname
, "\\");
199 strcat (domname
, localgroup_name
);
202 if (!LookupAccountName (NULL
, domname
,
204 domain_name
, &domname_len
,
208 "LookupAccountName(%s) failed with error %ld\n",
209 localgroup_name
, GetLastError ());
214 gid
= *GetSidSubAuthority (psid
, *GetSidSubAuthorityCount(psid
) - 1);
216 printf ("%s:%s:%ld:", localgroup_name
,
217 print_sids
? put_sid (psid
) : "",
220 enum_local_users (buffer
[i
].lgrpi0_name
);
224 netapibufferfree (buffer
);
227 while (rc
== ERROR_MORE_DATA
);
233 enum_users (LPWSTR servername
, LPWSTR groupname
)
235 GROUP_USERS_INFO_0
*buf1
;
240 if (!netgroupgetusers (servername
, groupname
,
242 MAX_PREFERRED_LENGTH
,
243 &entries
, &total
, &reshdl
))
247 for (i
= 0; i
< entries
; ++i
)
254 uni2ansi (buf1
[i
].grui0_name
, user
, sizeof (user
));
257 netapibufferfree (buf1
);
262 enum_groups (LPWSTR servername
, int print_sids
, int print_users
, int id_offset
)
264 GROUP_INFO_2
*buffer
;
265 DWORD entriesread
= 0;
266 DWORD totalentries
= 0;
267 DWORD resume_handle
= 0;
269 char ansi_srvname
[256];
272 uni2ansi (servername
, ansi_srvname
, sizeof (ansi_srvname
));
278 rc
= netgroupenum (servername
, 2, (LPBYTE
*) & buffer
, 1024,
279 &entriesread
, &totalentries
, &resume_handle
);
282 case ERROR_ACCESS_DENIED
:
283 fprintf (stderr
, "Access denied\n");
286 case ERROR_MORE_DATA
:
291 fprintf (stderr
, "NetGroupEnum() failed with %ld\n", rc
);
295 for (i
= 0; i
< entriesread
; i
++)
298 char domain_name
[100];
299 DWORD domname_len
= 100;
300 char psid_buffer
[1024];
301 PSID psid
= (PSID
) psid_buffer
;
302 DWORD sid_length
= 1024;
303 SID_NAME_USE acc_type
;
305 int gid
= buffer
[i
].grpi2_group_id
;
306 uni2ansi (buffer
[i
].grpi2_name
, groupname
, sizeof (groupname
));
309 if (!LookupAccountName (servername
? ansi_srvname
: NULL
,
312 domain_name
, &domname_len
,
316 "LookupAccountName (%s, %s) failed with error %ld\n",
317 servername
? ansi_srvname
: "NULL",
322 else if (acc_type
== SidTypeDomain
)
326 strcpy (domname
, domain_name
);
327 strcat (domname
, "\\");
328 strcat (domname
, groupname
);
331 if (!LookupAccountName (servername
? ansi_srvname
: NULL
,
334 domain_name
, &domname_len
,
338 "LookupAccountName(%s,%s) failed with error %ld\n",
339 servername
? ansi_srvname
: "NULL",
346 printf ("%s:%s:%d:", groupname
,
347 print_sids
? put_sid (psid
) : "",
350 enum_users (servername
, buffer
[i
].grpi2_name
);
354 netapibufferfree (buffer
);
357 while (rc
== ERROR_MORE_DATA
);
360 netapibufferfree (servername
);
364 print_special (int print_sids
,
365 PSID_IDENTIFIER_AUTHORITY auth
, BYTE cnt
,
366 DWORD sub1
, DWORD sub2
, DWORD sub3
, DWORD sub4
,
367 DWORD sub5
, DWORD sub6
, DWORD sub7
, DWORD sub8
)
369 char name
[256], dom
[256];
370 DWORD len
, len2
, rid
;
374 if (AllocateAndInitializeSid (auth
, cnt
, sub1
, sub2
, sub3
, sub4
,
375 sub5
, sub6
, sub7
, sub8
, &sid
))
377 if (LookupAccountSid (NULL
, sid
,
378 name
, (len
= 256, &len
),
379 dom
, (len2
= 256, &len
),
398 printf ("%s:%s:%lu:\n", name
,
399 print_sids
? put_sid (sid
) : "",
407 usage (FILE * stream
, int status
)
409 fprintf (stream
, "Usage: mkgroup [OPTION]... [domain]\n\n");
410 fprintf (stream
, "This program prints a /etc/group file to stdout\n\n");
411 fprintf (stream
, "Options:\n");
412 fprintf (stream
, " -l,--local print local group information\n");
413 fprintf (stream
, " -d,--domain print global group information from the domain\n");
414 fprintf (stream
, " specified (or from the current domain if there is\n");
415 fprintf (stream
, " no domain specified)\n");
416 fprintf (stream
, " -o,--id-offset offset change the default offset (10000) added to uids\n");
417 fprintf (stream
, " in domain accounts.\n");
418 fprintf (stream
, " -s,--no-sids don't print SIDs in pwd field\n");
419 fprintf (stream
, " (this affects ntsec)\n");
420 fprintf (stream
, " -u,--users print user list in gr_mem field\n");
421 fprintf (stream
, " -h,--help print this message\n\n");
422 fprintf (stream
, " -v,--version print version information and exit\n\n");
423 fprintf (stream
, "One of `-l' or `-d' must be given on NT/W2K.\n");
427 struct option longopts
[] = {
428 {"local", no_argument
, NULL
, 'l'},
429 {"domain", no_argument
, NULL
, 'd'},
430 {"id-offset", required_argument
, NULL
, 'o'},
431 {"no-sids", no_argument
, NULL
, 's'},
432 {"users", no_argument
, NULL
, 'u'},
433 {"help", no_argument
, NULL
, 'h'},
434 {"version", no_argument
, NULL
, 'v'},
435 {0, no_argument
, NULL
, 0}
438 char opts
[] = "ldo:suhv";
442 const char *v
= strchr (version
, ':');
452 len
= strchr (v
, ' ') - v
;
455 mkgroup (cygwin) %.*s\n\
456 group File Generator\n\
457 Copyright 1997, 1998, 2002 Red Hat, Inc.\n\
458 Compiled on %s", len
, v
, __DATE__
);
462 main (int argc
, char **argv
)
465 DWORD rc
= ERROR_SUCCESS
;
466 WCHAR domain_name
[100];
468 int print_domain
= 0;
471 int domain_specified
= 0;
472 int id_offset
= 10000;
475 char name
[256], dom
[256];
481 LSA_OBJECT_ATTRIBUTES oa
= { 0, 0, 0, 0, 0, 0 };
482 LSA_HANDLE lsa
= INVALID_HANDLE_VALUE
;
484 PPOLICY_PRIMARY_DOMAIN_INFO pdi
;
486 if (GetVersion () < 0x80000000)
489 return usage(stderr
, 1);
492 while ((i
= getopt_long (argc
, argv
, opts
, longopts
, NULL
)) != EOF
)
502 id_offset
= strtol (optarg
, NULL
, 10);
511 return usage (stdout
, 0);
516 fprintf (stderr
, "Try `%s --help' for more information.\n", argv
[0]);
519 if (!print_local
&& !print_domain
)
521 fprintf (stderr
, "%s: Specify one of `-l' or `-d'\n", argv
[0]);
528 fprintf (stderr
, "%s: A domain name is only accepted "
529 "when `-d' is given.\n", argv
[0]);
532 mbstowcs (domain_name
, argv
[optind
], (strlen (argv
[optind
]) + 1));
533 domain_specified
= 1;
538 /* This takes Windows 9x/ME into account. */
539 if (GetVersion () >= 0x80000000)
541 printf ("unknown::%ld:\n", DOMAIN_ALIAS_RID_ADMINS
);
547 fprintf (stderr
, "Failed loading symbols from netapi32.dll "
548 "with error %lu\n", GetLastError ());
553 * Get `Everyone' group
555 print_special (print_sids
, &sid_world_auth
, 1, SECURITY_WORLD_RID
,
556 0, 0, 0, 0, 0, 0, 0);
560 print_special (print_sids
, &sid_nt_auth
, 1, SECURITY_LOCAL_SYSTEM_RID
,
561 0, 0, 0, 0, 0, 0, 0);
568 GetComputerName (name
, &len
);
571 if (LookupAccountName (NULL
, name
, (PSID
) buf
, &len
, dom
, &len
, &use
))
575 ret
= LsaOpenPolicy(NULL
, &oa
, POLICY_VIEW_LOCAL_INFORMATION
, &lsa
);
576 if (ret
== STATUS_SUCCESS
&& lsa
!= INVALID_HANDLE_VALUE
)
578 ret
= LsaQueryInformationPolicy (lsa
,
579 PolicyPrimaryDomainInformation
,
581 if (ret
== STATUS_SUCCESS
)
585 CopySid (1024, (PSID
) buf
, pdi
->Sid
);
595 "WARNING: Group 513 couldn't get retrieved. Try mkgroup -d\n");
597 print_special (print_sids
, GetSidIdentifierAuthority (psid
), 5,
598 *GetSidSubAuthority (psid
, 0),
599 *GetSidSubAuthority (psid
, 1),
600 *GetSidSubAuthority (psid
, 2),
601 *GetSidSubAuthority (psid
, 3),
610 if (domain_specified
)
611 rc
= netgetdcname (NULL
, domain_name
, (LPBYTE
*) & servername
);
614 rc
= netgetdcname (NULL
, NULL
, (LPBYTE
*) & servername
);
616 if (rc
!= ERROR_SUCCESS
)
618 fprintf (stderr
, "Cannot get PDC, code = %ld\n", rc
);
622 enum_groups (servername
, print_sids
, print_users
, id_offset
);
626 enum_local_groups (print_sids
, print_users
);