3 Copyright 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
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 "This program prints a /etc/group file to stdout\n\n"
412 " -l,--local print local group information\n"
413 " -d,--domain print global group information from the domain\n"
414 " specified (or from the current domain if there is\n"
415 " no domain specified)\n"
416 " -o,--id-offset offset change the default offset (10000) added to uids\n"
417 " in domain accounts.\n"
418 " -s,--no-sids don't print SIDs in pwd field\n"
419 " (this affects ntsec)\n"
420 " -u,--users print user list in gr_mem field\n"
421 " -h,--help print this message\n\n"
422 " -v,--version print version information and exit\n\n"
423 "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";
443 const char *v
= strchr (version
, ':');
453 len
= strchr (v
, ' ') - v
;
456 mkgroup (cygwin) %.*s\n\
457 group File Generator\n\
458 Copyright 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.\n\
459 Compiled on %s", len
, v
, __DATE__
);
463 main (int argc
, char **argv
)
466 DWORD rc
= ERROR_SUCCESS
;
467 WCHAR domain_name
[100];
469 int print_domain
= 0;
472 int domain_specified
= 0;
473 int id_offset
= 10000;
476 char name
[256], dom
[256];
482 LSA_OBJECT_ATTRIBUTES oa
= { 0, 0, 0, 0, 0, 0 };
483 LSA_HANDLE lsa
= INVALID_HANDLE_VALUE
;
485 PPOLICY_PRIMARY_DOMAIN_INFO pdi
;
487 if (GetVersion () < 0x80000000)
490 return usage(stderr
, 1);
493 while ((i
= getopt_long (argc
, argv
, opts
, longopts
, NULL
)) != EOF
)
503 id_offset
= strtol (optarg
, NULL
, 10);
512 return usage (stdout
, 0);
517 fprintf (stderr
, "Try `%s --help' for more information.\n", argv
[0]);
520 if (!print_local
&& !print_domain
)
522 fprintf (stderr
, "%s: Specify one of `-l' or `-d'\n", argv
[0]);
529 fprintf (stderr
, "%s: A domain name is only accepted "
530 "when `-d' is given.\n", argv
[0]);
533 mbstowcs (domain_name
, argv
[optind
], (strlen (argv
[optind
]) + 1));
534 domain_specified
= 1;
539 /* This takes Windows 9x/ME into account. */
540 if (GetVersion () >= 0x80000000)
542 printf ("unknown::%ld:\n", DOMAIN_ALIAS_RID_ADMINS
);
548 fprintf (stderr
, "Failed loading symbols from netapi32.dll "
549 "with error %lu\n", GetLastError ());
554 * Get `Everyone' group
556 print_special (print_sids
, &sid_world_auth
, 1, SECURITY_WORLD_RID
,
557 0, 0, 0, 0, 0, 0, 0);
561 print_special (print_sids
, &sid_nt_auth
, 1, SECURITY_LOCAL_SYSTEM_RID
,
562 0, 0, 0, 0, 0, 0, 0);
569 GetComputerName (name
, &len
);
572 if (LookupAccountName (NULL
, name
, (PSID
) buf
, &len
, dom
, &len
, &use
))
576 ret
= LsaOpenPolicy(NULL
, &oa
, POLICY_VIEW_LOCAL_INFORMATION
, &lsa
);
577 if (ret
== STATUS_SUCCESS
&& lsa
!= INVALID_HANDLE_VALUE
)
579 ret
= LsaQueryInformationPolicy (lsa
,
580 PolicyPrimaryDomainInformation
,
582 if (ret
== STATUS_SUCCESS
)
586 CopySid (1024, (PSID
) buf
, pdi
->Sid
);
596 "WARNING: Group 513 couldn't get retrieved. Try mkgroup -d\n");
598 print_special (print_sids
, GetSidIdentifierAuthority (psid
), 5,
599 *GetSidSubAuthority (psid
, 0),
600 *GetSidSubAuthority (psid
, 1),
601 *GetSidSubAuthority (psid
, 2),
602 *GetSidSubAuthority (psid
, 3),
611 if (domain_specified
)
612 rc
= netgetdcname (NULL
, domain_name
, (LPBYTE
*) & servername
);
615 rc
= netgetdcname (NULL
, NULL
, (LPBYTE
*) & servername
);
617 if (rc
!= ERROR_SUCCESS
)
619 fprintf (stderr
, "Cannot get PDC, code = %ld\n", rc
);
623 enum_groups (servername
, print_sids
, print_users
, id_offset
);
627 enum_local_groups (print_sids
, print_users
);