3 Copyright 1997, 1998 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>
21 SID_IDENTIFIER_AUTHORITY sid_world_auth
= {SECURITY_WORLD_SID_AUTHORITY
};
22 SID_IDENTIFIER_AUTHORITY sid_nt_auth
= {SECURITY_NT_AUTHORITY
};
24 NET_API_STATUS
WINAPI (*netapibufferfree
)(PVOID
);
25 NET_API_STATUS
WINAPI (*netgroupenum
)(LPWSTR
,DWORD
,PBYTE
*,DWORD
,PDWORD
,PDWORD
,PDWORD
);
26 NET_API_STATUS
WINAPI (*netlocalgroupenum
)(LPWSTR
,DWORD
,PBYTE
*,DWORD
,PDWORD
,PDWORD
,PDWORD
);
27 NET_API_STATUS
WINAPI (*netlocalgroupgetmembers
)(LPWSTR
,LPWSTR
,DWORD
,PBYTE
*,DWORD
,PDWORD
,PDWORD
,PDWORD
);
28 NET_API_STATUS
WINAPI (*netgetdcname
)(LPWSTR
,LPWSTR
,PBYTE
*);
29 NET_API_STATUS
WINAPI (*netgroupgetusers
)(LPWSTR
,LPWSTR
,DWORD
,PBYTE
*,DWORD
,PDWORD
,PDWORD
,PDWORD
);
32 #define min(a,b) (((a)<(b))?(a):(b))
38 HANDLE h
= LoadLibrary ("netapi32.dll");
43 if (!(netapibufferfree
= (void *) GetProcAddress (h
, "NetApiBufferFree")))
45 if (!(netgroupenum
= (void *) GetProcAddress (h
, "NetGroupEnum")))
47 if (!(netgroupgetusers
= (void *) GetProcAddress (h
, "NetGroupGetUsers")))
49 if (!(netlocalgroupenum
= (void *) GetProcAddress (h
, "NetLocalGroupEnum")))
51 if (!(netlocalgroupgetmembers
= (void *) GetProcAddress (h
, "NetLocalGroupGetMembers")))
53 if (!(netgetdcname
= (void *) GetProcAddress (h
, "NetGetDCName")))
67 sprintf(t
, "%u", GetSidIdentifierAuthority (sid
)->Value
[5]);
69 for (i
= 0; i
< *GetSidSubAuthorityCount (sid
); ++i
)
71 sprintf(t
, "-%lu", *GetSidSubAuthority (sid
, i
));
78 psx_dir (char *in
, char *out
)
80 if (isalpha (in
[0]) && in
[1] == ':')
82 sprintf (out
, "/cygdrive/%c", in
[0]);
101 uni2ansi (LPWSTR wcs
, char *mbs
, int size
)
104 WideCharToMultiByte (CP_ACP
, 0, wcs
, -1, mbs
, size
, NULL
, NULL
);
110 enum_local_users (LPWSTR groupname
)
112 LOCALGROUP_MEMBERS_INFO_1
*buf1
;
117 if (!netlocalgroupgetmembers (NULL
, groupname
,
119 MAX_PREFERRED_LENGTH
,
120 &entries
, &total
, &reshdl
))
124 for (i
= 0; i
< entries
; ++i
)
125 if (buf1
[i
].lgrmi1_sidusage
== SidTypeUser
)
132 uni2ansi (buf1
[i
].lgrmi1_name
, user
, sizeof (user
));
135 netapibufferfree (buf1
);
140 enum_local_groups (int print_sids
, int print_users
)
142 LOCALGROUP_INFO_0
*buffer
;
143 DWORD entriesread
= 0;
144 DWORD totalentries
= 0;
145 DWORD resume_handle
= 0;
152 rc
= netlocalgroupenum (NULL
, 0, (LPBYTE
*) &buffer
, 1024,
153 &entriesread
, &totalentries
, &resume_handle
);
156 case ERROR_ACCESS_DENIED
:
157 fprintf (stderr
, "Access denied\n");
160 case ERROR_MORE_DATA
:
165 fprintf (stderr
, "NetLocalGroupEnum() failed with %ld\n", rc
);
169 for (i
= 0; i
< entriesread
; i
++)
171 char localgroup_name
[100];
172 char domain_name
[100];
173 DWORD domname_len
= 100;
174 char psid_buffer
[1024];
175 PSID psid
= (PSID
) psid_buffer
;
176 DWORD sid_length
= 1024;
178 SID_NAME_USE acc_type
;
179 uni2ansi (buffer
[i
].lgrpi0_name
, localgroup_name
, sizeof (localgroup_name
));
181 if (!LookupAccountName (NULL
, localgroup_name
, psid
,
182 &sid_length
, domain_name
, &domname_len
,
185 fprintf (stderr
, "LookupAccountName(%s) failed with %ld\n",
186 localgroup_name
, GetLastError ());
189 else if (acc_type
== SidTypeDomain
)
193 strcpy (domname
, domain_name
);
194 strcat (domname
, "\\");
195 strcat (domname
, localgroup_name
);
198 if (!LookupAccountName (NULL
, domname
,
200 domain_name
, &domname_len
,
204 "LookupAccountName(%s) failed with error %ld\n",
205 localgroup_name
, GetLastError ());
210 gid
= *GetSidSubAuthority (psid
, *GetSidSubAuthorityCount(psid
) - 1);
212 printf ("%s:%s:%ld:", localgroup_name
,
213 print_sids
? put_sid (psid
) : "",
216 enum_local_users (buffer
[i
].lgrpi0_name
);
220 netapibufferfree (buffer
);
223 while (rc
== ERROR_MORE_DATA
);
229 enum_users (LPWSTR servername
, LPWSTR groupname
)
231 GROUP_USERS_INFO_0
*buf1
;
236 if (!netgroupgetusers (servername
, groupname
,
238 MAX_PREFERRED_LENGTH
,
239 &entries
, &total
, &reshdl
))
243 for (i
= 0; i
< entries
; ++i
)
250 uni2ansi (buf1
[i
].grui0_name
, user
, sizeof (user
));
253 netapibufferfree (buf1
);
258 enum_groups (LPWSTR servername
, int print_sids
, int print_users
, int id_offset
)
260 GROUP_INFO_2
*buffer
;
261 DWORD entriesread
= 0;
262 DWORD totalentries
= 0;
263 DWORD resume_handle
= 0;
265 char ansi_srvname
[256];
268 uni2ansi (servername
, ansi_srvname
, sizeof (ansi_srvname
));
274 rc
= netgroupenum (servername
, 2, (LPBYTE
*) & buffer
, 1024,
275 &entriesread
, &totalentries
, &resume_handle
);
278 case ERROR_ACCESS_DENIED
:
279 fprintf (stderr
, "Access denied\n");
282 case ERROR_MORE_DATA
:
287 fprintf (stderr
, "NetGroupEnum() failed with %ld\n", rc
);
291 for (i
= 0; i
< entriesread
; i
++)
294 char domain_name
[100];
295 DWORD domname_len
= 100;
296 char psid_buffer
[1024];
297 PSID psid
= (PSID
) psid_buffer
;
298 DWORD sid_length
= 1024;
299 SID_NAME_USE acc_type
;
301 int gid
= buffer
[i
].grpi2_group_id
;
302 uni2ansi (buffer
[i
].grpi2_name
, groupname
, sizeof (groupname
));
305 if (!LookupAccountName (servername
? ansi_srvname
: NULL
,
308 domain_name
, &domname_len
,
312 "LookupAccountName (%s, %s) failed with error %ld\n",
313 servername
? ansi_srvname
: "NULL",
318 else if (acc_type
== SidTypeDomain
)
322 strcpy (domname
, domain_name
);
323 strcat (domname
, "\\");
324 strcat (domname
, groupname
);
327 if (!LookupAccountName (servername
? ansi_srvname
: NULL
,
330 domain_name
, &domname_len
,
334 "LookupAccountName(%s,%s) failed with error %ld\n",
335 servername
? ansi_srvname
: "NULL",
342 printf ("%s:%s:%d:", groupname
,
343 print_sids
? put_sid (psid
) : "",
346 enum_users (servername
, buffer
[i
].grpi2_name
);
350 netapibufferfree (buffer
);
353 while (rc
== ERROR_MORE_DATA
);
356 netapibufferfree (servername
);
360 print_special (int print_sids
,
361 PSID_IDENTIFIER_AUTHORITY auth
, BYTE cnt
,
362 DWORD sub1
, DWORD sub2
, DWORD sub3
, DWORD sub4
,
363 DWORD sub5
, DWORD sub6
, DWORD sub7
, DWORD sub8
)
365 char name
[256], dom
[256];
366 DWORD len
, len2
, rid
;
370 if (AllocateAndInitializeSid (auth
, cnt
, sub1
, sub2
, sub3
, sub4
,
371 sub5
, sub6
, sub7
, sub8
, &sid
))
373 if (LookupAccountSid (NULL
, sid
,
374 name
, (len
= 256, &len
),
375 dom
, (len2
= 256, &len
),
394 printf ("%s:%s:%lu:\n", name
,
395 print_sids
? put_sid (sid
) : "",
405 fprintf (stderr
, "Usage: mkgroup [OPTION]... [domain]\n\n");
406 fprintf (stderr
, "This program prints a /etc/group file to stdout\n\n");
407 fprintf (stderr
, "Options:\n");
408 fprintf (stderr
, " -l,--local print local group information\n");
409 fprintf (stderr
, " -d,--domain print global group information from the domain\n");
410 fprintf (stderr
, " specified (or from the current domain if there is\n");
411 fprintf (stderr
, " no domain specified)\n");
412 fprintf (stderr
, " -o,--id-offset offset change the default offset (10000) added to uids\n");
413 fprintf (stderr
, " in domain accounts.\n");
414 fprintf (stderr
, " -s,--no-sids don't print SIDs in pwd field\n");
415 fprintf (stderr
, " (this affects ntsec)\n");
416 fprintf (stderr
, " -u,--users print user list in gr_mem field\n");
417 fprintf (stderr
, " -?,--help print this message\n\n");
418 fprintf (stderr
, "One of `-l' or `-d' must be given on NT/W2K.\n");
422 struct option longopts
[] = {
423 {"local", no_argument
, NULL
, 'l'},
424 {"domain", no_argument
, NULL
, 'd'},
425 {"id-offset", required_argument
, NULL
, 'o'},
426 {"no-sids", no_argument
, NULL
, 's'},
427 {"users", no_argument
, NULL
, 'u'},
428 {"help", no_argument
, NULL
, 'h'},
429 {0, no_argument
, NULL
, 0}
432 char opts
[] = "ldo:suh";
435 main (int argc
, char **argv
)
438 DWORD rc
= ERROR_SUCCESS
;
439 WCHAR domain_name
[100];
441 int print_domain
= 0;
444 int domain_specified
= 0;
445 int id_offset
= 10000;
448 char name
[256], dom
[256];
453 if (GetVersion () < 0x80000000)
459 while ((i
= getopt_long (argc
, argv
, opts
, longopts
, NULL
)) != EOF
)
469 id_offset
= strtol (optarg
, NULL
, 10);
480 fprintf (stderr
, "Try `%s --help' for more information.\n", argv
[0]);
483 if (!print_local
&& !print_domain
)
485 fprintf (stderr
, "%s: Specify one of `-l' or `-d'\n", argv
[0]);
492 fprintf (stderr
, "%s: A domain name is only accepted "
493 "when `-d' is given.\n", argv
[0]);
496 mbstowcs (domain_name
, argv
[optind
], (strlen (argv
[optind
]) + 1));
497 domain_specified
= 1;
502 /* This takes Windows 9x/ME into account. */
503 if (GetVersion () >= 0x80000000)
505 printf ("unknown::%ld:\n", DOMAIN_ALIAS_RID_ADMINS
);
511 fprintf (stderr
, "Failed loading symbols from netapi32.dll "
512 "with error %lu\n", GetLastError ());
517 * Get `Everyone' group
519 print_special (print_sids
, &sid_world_auth
, 1, SECURITY_WORLD_RID
,
520 0, 0, 0, 0, 0, 0, 0);
524 print_special (print_sids
, &sid_nt_auth
, 1, SECURITY_LOCAL_SYSTEM_RID
,
525 0, 0, 0, 0, 0, 0, 0);
531 GetComputerName (name
, (len
= 256, &len
));
532 csid
= (PSID
) malloc (1024);
533 LookupAccountName (NULL
, name
,
534 csid
, (len
= 1024, &len
),
535 dom
, (len2
= 256, &len
),
537 print_special (print_sids
, GetSidIdentifierAuthority (csid
), 5,
538 *GetSidSubAuthority (csid
, 0),
539 *GetSidSubAuthority (csid
, 1),
540 *GetSidSubAuthority (csid
, 2),
541 *GetSidSubAuthority (csid
, 3),
551 if (domain_specified
)
552 rc
= netgetdcname (NULL
, domain_name
, (LPBYTE
*) & servername
);
555 rc
= netgetdcname (NULL
, NULL
, (LPBYTE
*) & servername
);
557 if (rc
!= ERROR_SUCCESS
)
559 fprintf (stderr
, "Cannot get PDC, code = %ld\n", rc
);
563 enum_groups (servername
, print_sids
, print_users
, id_offset
);
567 enum_local_groups (print_sids
, print_users
);