]> sourceware.org Git - newlib-cygwin.git/blob - winsup/utils/mkgroup.c
* mkgroup.c: Avoid compiler warnings.
[newlib-cygwin.git] / winsup / utils / mkgroup.c
1 /* mkgroup.c:
2
3 Copyright 1997, 1998 Cygnus Solutions.
4
5 This file is part of Cygwin.
6
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
9 details. */
10
11 #include <ctype.h>
12 #include <stdlib.h>
13 #include <wchar.h>
14 #include <stdio.h>
15 #include <windows.h>
16 #include <sys/cygwin.h>
17 #include <getopt.h>
18 #include <lmaccess.h>
19 #include <lmapibuf.h>
20
21 SID_IDENTIFIER_AUTHORITY sid_world_auth = {SECURITY_WORLD_SID_AUTHORITY};
22 SID_IDENTIFIER_AUTHORITY sid_nt_auth = {SECURITY_NT_AUTHORITY};
23
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);
30
31 #ifndef min
32 #define min(a,b) (((a)<(b))?(a):(b))
33 #endif
34
35 BOOL
36 load_netapi ()
37 {
38 HANDLE h = LoadLibrary ("netapi32.dll");
39
40 if (!h)
41 return FALSE;
42
43 if (!(netapibufferfree = (void *) GetProcAddress (h, "NetApiBufferFree")))
44 return FALSE;
45 if (!(netgroupenum = (void *) GetProcAddress (h, "NetGroupEnum")))
46 return FALSE;
47 if (!(netgroupgetusers = (void *) GetProcAddress (h, "NetGroupGetUsers")))
48 return FALSE;
49 if (!(netlocalgroupenum = (void *) GetProcAddress (h, "NetLocalGroupEnum")))
50 return FALSE;
51 if (!(netlocalgroupgetmembers = (void *) GetProcAddress (h, "NetLocalGroupGetMembers")))
52 return FALSE;
53 if (!(netgetdcname = (void *) GetProcAddress (h, "NetGetDCName")))
54 return FALSE;
55
56 return TRUE;
57 }
58
59 char *
60 put_sid (PSID sid)
61 {
62 static char s[512];
63 char t[32];
64 DWORD i;
65
66 strcpy (s, "S-1-");
67 sprintf(t, "%u", GetSidIdentifierAuthority (sid)->Value[5]);
68 strcat (s, t);
69 for (i = 0; i < *GetSidSubAuthorityCount (sid); ++i)
70 {
71 sprintf(t, "-%lu", *GetSidSubAuthority (sid, i));
72 strcat (s, t);
73 }
74 return s;
75 }
76
77 void
78 psx_dir (char *in, char *out)
79 {
80 if (isalpha (in[0]) && in[1] == ':')
81 {
82 sprintf (out, "/cygdrive/%c", in[0]);
83 in += 2;
84 out += strlen (out);
85 }
86
87 while (*in)
88 {
89 if (*in == '\\')
90 *out = '/';
91 else
92 *out = *in;
93 in++;
94 out++;
95 }
96
97 *out = '\0';
98 }
99
100 void
101 uni2ansi (LPWSTR wcs, char *mbs, int size)
102 {
103 if (wcs)
104 WideCharToMultiByte (CP_ACP, 0, wcs, -1, mbs, size, NULL, NULL);
105 else
106 *mbs = '\0';
107 }
108
109 void
110 enum_local_users (LPWSTR groupname)
111 {
112 LOCALGROUP_MEMBERS_INFO_1 *buf1;
113 DWORD entries = 0;
114 DWORD total = 0;
115 DWORD reshdl = 0;
116
117 if (!netlocalgroupgetmembers (NULL, groupname,
118 1, (LPBYTE *) &buf1,
119 MAX_PREFERRED_LENGTH,
120 &entries, &total, &reshdl))
121 {
122 int i, first = 1;
123
124 for (i = 0; i < entries; ++i)
125 if (buf1[i].lgrmi1_sidusage == SidTypeUser)
126 {
127 char user[256];
128
129 if (!first)
130 printf (",");
131 first = 0;
132 uni2ansi (buf1[i].lgrmi1_name, user, sizeof (user));
133 printf ("%s", user);
134 }
135 netapibufferfree (buf1);
136 }
137 }
138
139 int
140 enum_local_groups (int print_sids, int print_users)
141 {
142 LOCALGROUP_INFO_0 *buffer;
143 DWORD entriesread = 0;
144 DWORD totalentries = 0;
145 DWORD resume_handle = 0;
146 DWORD rc;
147
148 do
149 {
150 DWORD i;
151
152 rc = netlocalgroupenum (NULL, 0, (LPBYTE *) &buffer, 1024,
153 &entriesread, &totalentries, &resume_handle);
154 switch (rc)
155 {
156 case ERROR_ACCESS_DENIED:
157 fprintf (stderr, "Access denied\n");
158 exit (1);
159
160 case ERROR_MORE_DATA:
161 case ERROR_SUCCESS:
162 break;
163
164 default:
165 fprintf (stderr, "NetLocalGroupEnum() failed with %ld\n", rc);
166 exit (1);
167 }
168
169 for (i = 0; i < entriesread; i++)
170 {
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;
177 DWORD gid;
178 SID_NAME_USE acc_type;
179 uni2ansi (buffer[i].lgrpi0_name, localgroup_name, sizeof (localgroup_name));
180
181 if (!LookupAccountName (NULL, localgroup_name, psid,
182 &sid_length, domain_name, &domname_len,
183 &acc_type))
184 {
185 fprintf (stderr, "LookupAccountName(%s) failed with %ld\n",
186 localgroup_name, GetLastError ());
187 continue;
188 }
189 else if (acc_type == SidTypeDomain)
190 {
191 char domname[356];
192
193 strcpy (domname, domain_name);
194 strcat (domname, "\\");
195 strcat (domname, localgroup_name);
196 sid_length = 1024;
197 domname_len = 100;
198 if (!LookupAccountName (NULL, domname,
199 psid, &sid_length,
200 domain_name, &domname_len,
201 &acc_type))
202 {
203 fprintf (stderr,
204 "LookupAccountName(%s) failed with error %ld\n",
205 localgroup_name, GetLastError ());
206 continue;
207 }
208 }
209
210 gid = *GetSidSubAuthority (psid, *GetSidSubAuthorityCount(psid) - 1);
211
212 printf ("%s:%s:%ld:", localgroup_name,
213 print_sids ? put_sid (psid) : "",
214 gid);
215 if (print_users)
216 enum_local_users (buffer[i].lgrpi0_name);
217 printf ("\n");
218 }
219
220 netapibufferfree (buffer);
221
222 }
223 while (rc == ERROR_MORE_DATA);
224
225 return 0;
226 }
227
228 void
229 enum_users (LPWSTR servername, LPWSTR groupname)
230 {
231 GROUP_USERS_INFO_0 *buf1;
232 DWORD entries = 0;
233 DWORD total = 0;
234 DWORD reshdl = 0;
235
236 if (!netgroupgetusers (servername, groupname,
237 0, (LPBYTE *) &buf1,
238 MAX_PREFERRED_LENGTH,
239 &entries, &total, &reshdl))
240 {
241 int i, first = 1;
242
243 for (i = 0; i < entries; ++i)
244 {
245 char user[256];
246
247 if (!first)
248 printf (",");
249 first = 0;
250 uni2ansi (buf1[i].grui0_name, user, sizeof (user));
251 printf ("%s", user);
252 }
253 netapibufferfree (buf1);
254 }
255 }
256
257 void
258 enum_groups (LPWSTR servername, int print_sids, int print_users, int id_offset)
259 {
260 GROUP_INFO_2 *buffer;
261 DWORD entriesread = 0;
262 DWORD totalentries = 0;
263 DWORD resume_handle = 0;
264 DWORD rc;
265 char ansi_srvname[256];
266
267 if (servername)
268 uni2ansi (servername, ansi_srvname, sizeof (ansi_srvname));
269
270 do
271 {
272 DWORD i;
273
274 rc = netgroupenum (servername, 2, (LPBYTE *) & buffer, 1024,
275 &entriesread, &totalentries, &resume_handle);
276 switch (rc)
277 {
278 case ERROR_ACCESS_DENIED:
279 fprintf (stderr, "Access denied\n");
280 exit (1);
281
282 case ERROR_MORE_DATA:
283 case ERROR_SUCCESS:
284 break;
285
286 default:
287 fprintf (stderr, "NetGroupEnum() failed with %ld\n", rc);
288 exit (1);
289 }
290
291 for (i = 0; i < entriesread; i++)
292 {
293 char groupname[100];
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;
300
301 int gid = buffer[i].grpi2_group_id;
302 uni2ansi (buffer[i].grpi2_name, groupname, sizeof (groupname));
303 if (print_sids)
304 {
305 if (!LookupAccountName (servername ? ansi_srvname : NULL,
306 groupname,
307 psid, &sid_length,
308 domain_name, &domname_len,
309 &acc_type))
310 {
311 fprintf (stderr,
312 "LookupAccountName (%s, %s) failed with error %ld\n",
313 servername ? ansi_srvname : "NULL",
314 groupname,
315 GetLastError ());
316 continue;
317 }
318 else if (acc_type == SidTypeDomain)
319 {
320 char domname[356];
321
322 strcpy (domname, domain_name);
323 strcat (domname, "\\");
324 strcat (domname, groupname);
325 sid_length = 1024;
326 domname_len = 100;
327 if (!LookupAccountName (servername ? ansi_srvname : NULL,
328 domname,
329 psid, &sid_length,
330 domain_name, &domname_len,
331 &acc_type))
332 {
333 fprintf (stderr,
334 "LookupAccountName(%s,%s) failed with error %ld\n",
335 servername ? ansi_srvname : "NULL",
336 domname,
337 GetLastError ());
338 continue;
339 }
340 }
341 }
342 printf ("%s:%s:%d:", groupname,
343 print_sids ? put_sid (psid) : "",
344 gid + id_offset);
345 if (print_users)
346 enum_users (servername, buffer[i].grpi2_name);
347 printf ("\n");
348 }
349
350 netapibufferfree (buffer);
351
352 }
353 while (rc == ERROR_MORE_DATA);
354
355 if (servername)
356 netapibufferfree (servername);
357 }
358
359 void
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)
364 {
365 char name[256], dom[256];
366 DWORD len, len2, rid;
367 PSID sid;
368 SID_NAME_USE use;
369
370 if (AllocateAndInitializeSid (auth, cnt, sub1, sub2, sub3, sub4,
371 sub5, sub6, sub7, sub8, &sid))
372 {
373 if (LookupAccountSid (NULL, sid,
374 name, (len = 256, &len),
375 dom, (len2 = 256, &len),
376 &use))
377 {
378 if (sub8)
379 rid = sub8;
380 else if (sub7)
381 rid = sub7;
382 else if (sub6)
383 rid = sub6;
384 else if (sub5)
385 rid = sub5;
386 else if (sub4)
387 rid = sub4;
388 else if (sub3)
389 rid = sub3;
390 else if (sub2)
391 rid = sub2;
392 else
393 rid = sub1;
394 printf ("%s:%s:%lu:\n", name,
395 print_sids ? put_sid (sid) : "",
396 rid);
397 }
398 FreeSid (sid);
399 }
400 }
401
402 int
403 usage ()
404 {
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");
419 return 1;
420 }
421
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}
430 };
431
432 char opts[] = "ldo:suh";
433
434 int
435 main (int argc, char **argv)
436 {
437 LPWSTR servername;
438 DWORD rc = ERROR_SUCCESS;
439 WCHAR domain_name[100];
440 int print_local = 0;
441 int print_domain = 0;
442 int print_sids = 1;
443 int print_users = 0;
444 int domain_specified = 0;
445 int id_offset = 10000;
446 int i;
447
448 char name[256], dom[256];
449 DWORD len, len2;
450 PSID csid;
451 SID_NAME_USE use;
452
453 if (GetVersion () < 0x80000000)
454 {
455 if (argc == 1)
456 return usage ();
457 else
458 {
459 while ((i = getopt_long (argc, argv, opts, longopts, NULL)) != EOF)
460 switch (i)
461 {
462 case 'l':
463 print_local = 1;
464 break;
465 case 'd':
466 print_domain = 1;
467 break;
468 case 'o':
469 id_offset = strtol (optarg, NULL, 10);
470 break;
471 case 's':
472 print_sids = 0;
473 break;
474 case 'u':
475 print_users = 1;
476 break;
477 case 'h':
478 return usage ();
479 default:
480 fprintf (stderr, "Try `%s --help' for more information.\n", argv[0]);
481 return 1;
482 }
483 if (!print_local && !print_domain)
484 {
485 fprintf (stderr, "%s: Specify one of `-l' or `-d'\n", argv[0]);
486 return 1;
487 }
488 if (optind < argc)
489 {
490 if (!print_domain)
491 {
492 fprintf (stderr, "%s: A domain name is only accepted "
493 "when `-d' is given.\n", argv[0]);
494 return 1;
495 }
496 mbstowcs (domain_name, argv[optind], (strlen (argv[optind]) + 1));
497 domain_specified = 1;
498 }
499 }
500 }
501
502 /* This takes Windows 9x/ME into account. */
503 if (GetVersion () >= 0x80000000)
504 {
505 printf ("unknown::%ld:\n", DOMAIN_ALIAS_RID_ADMINS);
506 return 0;
507 }
508
509 if (!load_netapi ())
510 {
511 fprintf (stderr, "Failed loading symbols from netapi32.dll "
512 "with error %lu\n", GetLastError ());
513 return 1;
514 }
515
516 /*
517 * Get `Everyone' group
518 */
519 print_special (print_sids, &sid_world_auth, 1, SECURITY_WORLD_RID,
520 0, 0, 0, 0, 0, 0, 0);
521 /*
522 * Get `system' group
523 */
524 print_special (print_sids, &sid_nt_auth, 1, SECURITY_LOCAL_SYSTEM_RID,
525 0, 0, 0, 0, 0, 0, 0);
526 if (print_local)
527 {
528 /*
529 * Get `None' group
530 */
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),
536 &use);
537 print_special (print_sids, GetSidIdentifierAuthority (csid), 5,
538 *GetSidSubAuthority (csid, 0),
539 *GetSidSubAuthority (csid, 1),
540 *GetSidSubAuthority (csid, 2),
541 *GetSidSubAuthority (csid, 3),
542 513,
543 0,
544 0,
545 0);
546 free (csid);
547 }
548
549 if (print_domain)
550 {
551 if (domain_specified)
552 rc = netgetdcname (NULL, domain_name, (LPBYTE *) & servername);
553
554 else
555 rc = netgetdcname (NULL, NULL, (LPBYTE *) & servername);
556
557 if (rc != ERROR_SUCCESS)
558 {
559 fprintf (stderr, "Cannot get PDC, code = %ld\n", rc);
560 exit (1);
561 }
562
563 enum_groups (servername, print_sids, print_users, id_offset);
564 }
565
566 if (print_local)
567 enum_local_groups (print_sids, print_users);
568
569 return 0;
570 }
This page took 0.061919 seconds and 6 git commands to generate.