]> sourceware.org Git - newlib-cygwin.git/blob - winsup/utils/mkpasswd.c
* Makefile.in (cygcheck.exe): Link against ntdll.
[newlib-cygwin.git] / winsup / utils / mkpasswd.c
1 /* mkpasswd.c:
2
3 Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
4 2008 Red Hat, Inc.
5
6 This file is part of Cygwin.
7
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
10 details. */
11
12 #define _WIN32_WINNT 0x0600
13 #include <ctype.h>
14 #include <stdlib.h>
15 #include <wchar.h>
16 #include <stdio.h>
17 #include <unistd.h>
18 #include <getopt.h>
19 #include <io.h>
20 #include <sys/fcntl.h>
21 #include <sys/cygwin.h>
22 #include <windows.h>
23 #include <lm.h>
24 #include <iptypes.h>
25 #include <wininet.h>
26 #include <ntsecapi.h>
27 #include <dsgetdc.h>
28 #include <ntdef.h>
29
30 #define print_win_error(x) _print_win_error(x, __LINE__)
31
32 #define MAX_SID_LEN 40
33
34 static const char version[] = "$Revision$";
35
36 extern char *__progname;
37
38 SID_IDENTIFIER_AUTHORITY sid_world_auth = {SECURITY_WORLD_SID_AUTHORITY};
39 SID_IDENTIFIER_AUTHORITY sid_nt_auth = {SECURITY_NT_AUTHORITY};
40
41 NET_API_STATUS WINAPI (*dsgetdcname)(LPWSTR,LPWSTR,GUID*,LPWSTR,ULONG,PDOMAIN_CONTROLLER_INFOW*);
42
43 #ifndef min
44 #define min(a,b) (((a)<(b))?(a):(b))
45 #endif
46
47 typedef struct
48 {
49 char *str;
50 BOOL with_dom;
51 } domlist_t;
52
53 void
54 _print_win_error(DWORD code, int line)
55 {
56 char buf[4096];
57
58 if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
59 | FORMAT_MESSAGE_IGNORE_INSERTS,
60 NULL,
61 code,
62 MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
63 (LPTSTR) buf, sizeof (buf), NULL))
64 fprintf (stderr, "mkpasswd (%d): [%lu] %s", line, code, buf);
65 else
66 fprintf (stderr, "mkpasswd (%d): error %lu", line, code);
67 }
68
69 void
70 load_dsgetdcname ()
71 {
72 HANDLE h = LoadLibrary ("netapi32.dll");
73
74 if (h)
75 dsgetdcname = (void *) GetProcAddress (h, "DsGetDcNameW");
76 }
77
78 static PWCHAR
79 get_dcname (char *domain)
80 {
81 static WCHAR server[INTERNET_MAX_HOST_NAME_LENGTH + 1];
82 DWORD rc;
83 PWCHAR servername;
84 WCHAR domain_name[MAX_DOMAIN_NAME_LEN + 1];
85 PDOMAIN_CONTROLLER_INFOW pdci = NULL;
86
87 if (dsgetdcname)
88 {
89 if (domain)
90 {
91 mbstowcs (domain_name, domain, strlen (domain) + 1);
92 rc = dsgetdcname (NULL, domain_name, NULL, NULL, 0, &pdci);
93 }
94 else
95 rc = dsgetdcname (NULL, NULL, NULL, NULL, 0, &pdci);
96 if (rc != ERROR_SUCCESS)
97 {
98 print_win_error(rc);
99 return (PWCHAR) -1;
100 }
101 wcscpy (server, pdci->DomainControllerName);
102 NetApiBufferFree (pdci);
103 }
104 else
105 {
106 rc = NetGetDCName (NULL, NULL, (void *) &servername);
107 if (rc == ERROR_SUCCESS && domain)
108 {
109 LPWSTR server = servername;
110 mbstowcs (domain_name, domain, strlen (domain) + 1);
111 rc = NetGetDCName (server, domain_name, (void *) &servername);
112 NetApiBufferFree (server);
113 }
114 if (rc != ERROR_SUCCESS)
115 {
116 print_win_error(rc);
117 return (PWCHAR) -1;
118 }
119 wcscpy (server, servername);
120 NetApiBufferFree ((PVOID) servername);
121 }
122 return server;
123 }
124
125 char *
126 put_sid (PSID sid)
127 {
128 static char s[512];
129 char t[32];
130 DWORD i;
131
132 strcpy (s, "S-1-");
133 sprintf(t, "%u", GetSidIdentifierAuthority (sid)->Value[5]);
134 strcat (s, t);
135 for (i = 0; i < *GetSidSubAuthorityCount (sid); ++i)
136 {
137 sprintf(t, "-%lu", *GetSidSubAuthority (sid, i));
138 strcat (s, t);
139 }
140 return s;
141 }
142
143 void
144 psx_dir (char *in, char *out)
145 {
146 if (isalpha (in[0]) && in[1] == ':')
147 {
148 sprintf (out, "/cygdrive/%c", in[0]);
149 in += 2;
150 out += strlen (out);
151 }
152
153 while (*in)
154 {
155 if (*in == '\\')
156 *out = '/';
157 else
158 *out = *in;
159 in++;
160 out++;
161 }
162
163 *out = '\0';
164 }
165
166 void
167 uni2ansi (LPWSTR wcs, char *mbs, int size)
168 {
169 if (wcs)
170 wcstombs (mbs, wcs, size);
171 else
172 *mbs = '\0';
173 }
174
175 void
176 current_user (int print_cygpath, const char *sep, const char *passed_home_path,
177 int id_offset, const char *disp_username)
178 {
179 DWORD len;
180 HANDLE ptok;
181 struct {
182 PSID psid;
183 int buffer[10];
184 } tu, tg;
185 char user[UNLEN + 1];
186 char dom[MAX_DOMAIN_NAME_LEN + 1];
187 DWORD ulen = UNLEN + 1;
188 DWORD dlen = MAX_DOMAIN_NAME_LEN + 1;
189 SID_NAME_USE acc_type;
190 int uid, gid;
191 char homedir_psx[PATH_MAX] = {0}, homedir_w32[MAX_PATH] = {0};
192
193 if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &ptok)
194 || !GetTokenInformation (ptok, TokenUser, &tu, sizeof tu, &len)
195 || !GetTokenInformation (ptok, TokenPrimaryGroup, &tg, sizeof tg, &len)
196 || !CloseHandle (ptok)
197 || !LookupAccountSidA (NULL, tu.psid, user, &ulen, dom, &dlen, &acc_type))
198 {
199 print_win_error (GetLastError ());
200 return;
201 }
202
203 uid = *GetSidSubAuthority (tu.psid, *GetSidSubAuthorityCount(tu.psid) - 1);
204 gid = *GetSidSubAuthority (tg.psid, *GetSidSubAuthorityCount(tg.psid) - 1);
205 if (passed_home_path[0] == '\0')
206 {
207 char *envhome = getenv ("HOME");
208 char *envhomedrive = getenv ("HOMEDRIVE");
209 char *envhomepath = getenv ("HOMEPATH");
210
211 if (envhome && envhome[0])
212 {
213 if (print_cygpath)
214 cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_ABSOLUTE, envhome,
215 homedir_psx, PATH_MAX);
216 else
217 psx_dir (envhome, homedir_psx);
218 }
219 else if (envhomepath && envhomepath[0])
220 {
221 if (envhomedrive)
222 strlcpy (homedir_w32, envhomedrive, sizeof (homedir_w32));
223 if (envhomepath[0] != '\\')
224 strlcat (homedir_w32, "\\", sizeof (homedir_w32));
225 strlcat (homedir_w32, envhomepath, sizeof (homedir_w32));
226 if (print_cygpath)
227 cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_ABSOLUTE, homedir_w32,
228 homedir_psx, PATH_MAX);
229 else
230 psx_dir (homedir_w32, homedir_psx);
231 }
232 else
233 {
234 strlcpy (homedir_psx, "/home/", sizeof (homedir_psx));
235 strlcat (homedir_psx, user, sizeof (homedir_psx));
236 }
237 }
238 else
239 {
240 strlcpy (homedir_psx, passed_home_path, sizeof (homedir_psx));
241 strlcat (homedir_psx, user, sizeof (homedir_psx));
242 }
243
244 printf ("%s%s%s:unused:%u:%u:U-%s\\%s,%s:%s:/bin/bash\n",
245 sep ? dom : "",
246 sep ?: "",
247 user,
248 uid + id_offset,
249 gid + id_offset,
250 dom,
251 user,
252 put_sid (tu.psid),
253 homedir_psx);
254 }
255
256 int
257 enum_users (BOOL domain, domlist_t *dom_or_machine, const char *sep,
258 int print_cygpath, const char *passed_home_path, int id_offset,
259 char *disp_username)
260 {
261 WCHAR machine[INTERNET_MAX_HOST_NAME_LENGTH + 1];
262 PWCHAR servername = NULL;
263 char *d_or_m = dom_or_machine ? dom_or_machine->str : NULL;
264 BOOL with_dom = dom_or_machine ? dom_or_machine->with_dom : FALSE;
265 USER_INFO_3 *buffer;
266 DWORD entriesread = 0;
267 DWORD totalentries = 0;
268 DWORD resume_handle = 0;
269 DWORD rc;
270 WCHAR uni_name[UNLEN + 1];
271
272 if (domain)
273 {
274 servername = get_dcname (d_or_m);
275 if (servername == (PWCHAR) -1)
276 return 1;
277 }
278 else if (d_or_m)
279 {
280 int ret = mbstowcs (machine, d_or_m, INTERNET_MAX_HOST_NAME_LENGTH + 1);
281 if (ret < 1 || ret >= INTERNET_MAX_HOST_NAME_LENGTH + 1)
282 {
283 fprintf (stderr, "%s: Invalid machine name '%s'. Skipping...\n",
284 __progname, d_or_m);
285 return 1;
286 }
287 servername = machine;
288 }
289
290 do
291 {
292 DWORD i;
293
294 if (disp_username != NULL)
295 {
296 mbstowcs (uni_name, disp_username, UNLEN + 1);
297 rc = NetUserGetInfo (servername, (LPWSTR) &uni_name, 3,
298 (void *) &buffer);
299 entriesread = 1;
300 }
301 else
302 rc = NetUserEnum (servername, 3, FILTER_NORMAL_ACCOUNT,
303 (void *) &buffer, MAX_PREFERRED_LENGTH,
304 &entriesread, &totalentries, &resume_handle);
305 switch (rc)
306 {
307 case ERROR_ACCESS_DENIED:
308 print_win_error(rc);
309 return 1;
310
311 case ERROR_MORE_DATA:
312 case ERROR_SUCCESS:
313 break;
314
315 default:
316 print_win_error(rc);
317 return 1;
318 }
319
320 for (i = 0; i < entriesread; i++)
321 {
322 char homedir_psx[PATH_MAX];
323 char homedir_w32[MAX_PATH];
324 WCHAR domain_name[MAX_DOMAIN_NAME_LEN + 1];
325 DWORD domname_len = MAX_DOMAIN_NAME_LEN + 1;
326 char psid_buffer[MAX_SID_LEN];
327 PSID psid = (PSID) psid_buffer;
328 DWORD sid_length = MAX_SID_LEN;
329 SID_NAME_USE acc_type;
330
331 int uid = buffer[i].usri3_user_id;
332 int gid = buffer[i].usri3_primary_group_id;
333 homedir_w32[0] = homedir_psx[0] = '\0';
334 if (passed_home_path[0] == '\0')
335 {
336 uni2ansi (buffer[i].usri3_home_dir, homedir_w32,
337 sizeof (homedir_w32));
338 if (homedir_w32[0] != '\0')
339 {
340 if (print_cygpath)
341 cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_ABSOLUTE,
342 homedir_w32, homedir_psx, PATH_MAX);
343 else
344 psx_dir (homedir_w32, homedir_psx);
345 }
346 else
347 uni2ansi (buffer[i].usri3_name,
348 stpcpy (homedir_psx, "/home/"), PATH_MAX - 6);
349 }
350 else
351 uni2ansi (buffer[i].usri3_name,
352 stpcpy (homedir_psx, passed_home_path),
353 PATH_MAX - strlen (passed_home_path));
354
355 if (!LookupAccountNameW (servername, buffer[i].usri3_name,
356 psid, &sid_length, domain_name,
357 &domname_len, &acc_type))
358 {
359 print_win_error(GetLastError ());
360 fprintf(stderr, " (%ls)\n", buffer[i].usri3_name);
361 continue;
362 }
363 else if (acc_type == SidTypeDomain)
364 {
365 WCHAR domname[MAX_DOMAIN_NAME_LEN + UNLEN + 2];
366
367 wcscpy (domname, domain_name);
368 wcscat (domname, L"\\");
369 wcscat (domname, buffer[i].usri3_name);
370 sid_length = MAX_SID_LEN;
371 domname_len = sizeof (domname);
372 if (!LookupAccountNameW (servername, domname, psid,
373 &sid_length, domain_name,
374 &domname_len, &acc_type))
375 {
376 print_win_error(GetLastError ());
377 fprintf(stderr, " (%ls)\n", domname);
378 continue;
379 }
380 }
381
382 printf ("%ls%s%ls:unused:%u:%u:%ls%sU-%ls\\%ls,%s:%s:/bin/bash\n",
383 with_dom ? domain_name : L"",
384 with_dom ? sep : "",
385 buffer[i].usri3_name,
386 uid + id_offset,
387 gid + id_offset,
388 buffer[i].usri3_full_name ?: L"",
389 buffer[i].usri3_full_name
390 && buffer[i].usri3_full_name[0] ? "," : "",
391 domain_name,
392 buffer[i].usri3_name,
393 put_sid (psid),
394 homedir_psx);
395 }
396
397 NetApiBufferFree (buffer);
398
399 }
400 while (rc == ERROR_MORE_DATA);
401
402 return 0;
403 }
404
405 void
406 print_special (PSID_IDENTIFIER_AUTHORITY auth, BYTE cnt,
407 DWORD sub1, DWORD sub2, DWORD sub3, DWORD sub4,
408 DWORD sub5, DWORD sub6, DWORD sub7, DWORD sub8)
409 {
410 char name[UNLEN + 1], dom[MAX_DOMAIN_NAME_LEN + 1];
411 DWORD len, len2, rid;
412 PSID sid;
413 SID_NAME_USE use;
414
415 if (AllocateAndInitializeSid (auth, cnt, sub1, sub2, sub3, sub4,
416 sub5, sub6, sub7, sub8, &sid))
417 {
418 if (LookupAccountSid (NULL, sid,
419 name, (len = UNLEN + 1, &len),
420 dom, (len2 = MAX_DOMAIN_NAME_LEN + 1, &len),
421 &use))
422 {
423 if (sub8)
424 rid = sub8;
425 else if (sub7)
426 rid = sub7;
427 else if (sub6)
428 rid = sub6;
429 else if (sub5)
430 rid = sub5;
431 else if (sub4)
432 rid = sub4;
433 else if (sub3)
434 rid = sub3;
435 else if (sub2)
436 rid = sub2;
437 else
438 rid = sub1;
439 printf ("%s:*:%lu:%lu:,%s::\n",
440 name, rid, rid == 18 ? 544 : rid, /* SYSTEM hack */
441 put_sid (sid));
442 }
443 FreeSid (sid);
444 }
445 }
446
447 int
448 usage (FILE * stream)
449 {
450 fprintf (stream,
451 "Usage: mkpasswd [OPTIONS]...\n"
452 "Print /etc/passwd file to stdout\n"
453 "\n"
454 "Options:\n"
455 " -l,--local [machine] print local user accounts (from local machine\n"
456 " if no machine specified)\n"
457 " -L,--Local [machine] ditto, but generate username with machine prefix\n"
458 " -d,--domain [domain] print domain accounts (from current domain\n"
459 " if no domain specified)\n"
460 " -D,--Domain [domain] ditto, but generate username with domain prefix\n"
461 " -c,--current print current user\n"
462 " -C,--Current ditto, but generate username with machine or\n"
463 " domain prefix\n"
464 " -S,--separator char for -L, -D, -C use character char as domain\\user\n"
465 " separator in username instead of the default '\\'\n"
466 " -o,--id-offset offset change the default offset (10000) added to uids\n"
467 " in domain or foreign server accounts.\n"
468 " -u,--username username only return information for the specified user\n"
469 " one of -l, -L, -d, -D must be specified, too\n"
470 " -p,--path-to-home path use specified path instead of user account home dir\n"
471 " or /home prefix\n"
472 " -m,--no-mount don't use mount points for home dir\n"
473 " -s,--no-sids (ignored)\n"
474 " -g,--local-groups (ignored)\n"
475 " -h,--help displays this message\n"
476 " -v,--version version information and exit\n"
477 "\n"
478 "Default is to print local accounts on stand-alone machines, domain accounts\n"
479 "on domain controllers and domain member machines.\n");
480 return 1;
481 }
482
483 struct option longopts[] = {
484 {"current", no_argument, NULL, 'c'},
485 {"Current", no_argument, NULL, 'C'},
486 {"domain", optional_argument, NULL, 'd'},
487 {"Domain", optional_argument, NULL, 'D'},
488 {"local-groups", no_argument, NULL, 'g'},
489 {"help", no_argument, NULL, 'h'},
490 {"local", optional_argument, NULL, 'l'},
491 {"Local", optional_argument, NULL, 'L'},
492 {"no-mount", no_argument, NULL, 'm'},
493 {"id-offset", required_argument, NULL, 'o'},
494 {"path-to-home", required_argument, NULL, 'p'},
495 {"no-sids", no_argument, NULL, 's'},
496 {"separator", required_argument, NULL, 'S'},
497 {"username", required_argument, NULL, 'u'},
498 {"version", no_argument, NULL, 'v'},
499 {0, no_argument, NULL, 0}
500 };
501
502 char opts[] = "cCd::D::ghl::L::mo:sS:p:u:v";
503
504 static void
505 print_version ()
506 {
507 const char *v = strchr (version, ':');
508 int len;
509 if (!v)
510 {
511 v = "?";
512 len = 1;
513 }
514 else
515 {
516 v += 2;
517 len = strchr (v, ' ') - v;
518 }
519 printf ("\
520 mkpasswd (cygwin) %.*s\n\
521 passwd File Generator\n\
522 Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2008 Red Hat, Inc.\n\
523 Compiled on %s\n\
524 ", len, v, __DATE__);
525 }
526
527 static void
528 enum_std_accounts ()
529 {
530 /* Generate service starter account entries. */
531 printf ("SYSTEM:*:18:544:,S-1-5-18::\n");
532 printf ("LocalService:*:19:544:U-NT AUTHORITY\\LocalService,S-1-5-19::\n");
533 printf ("NetworkService:*:20:544:U-NT AUTHORITY\\NetworkService,S-1-5-20::\n");
534 /* Get 'administrators' group (has localized name). */
535 print_special (&sid_nt_auth, 2, SECURITY_BUILTIN_DOMAIN_RID,
536 DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0);
537 }
538
539 static PPOLICY_PRIMARY_DOMAIN_INFO p_dom;
540
541 static BOOL
542 fetch_primary_domain ()
543 {
544 NTSTATUS status;
545 LSA_OBJECT_ATTRIBUTES oa = { 0, 0, 0, 0, 0, 0 };
546 LSA_HANDLE lsa;
547
548 if (!p_dom)
549 {
550 status = LsaOpenPolicy (NULL, &oa, POLICY_VIEW_LOCAL_INFORMATION, &lsa);
551 if (!NT_SUCCESS (status))
552 return FALSE;
553 status = LsaQueryInformationPolicy (lsa, PolicyPrimaryDomainInformation,
554 (PVOID *) &p_dom);
555 LsaClose (lsa);
556 if (!NT_SUCCESS (status))
557 return FALSE;
558 }
559 return !!p_dom->Sid;
560 }
561
562 int
563 main (int argc, char **argv)
564 {
565 int print_local = 0;
566 domlist_t locals[16];
567 int print_domain = 0;
568 domlist_t domains[16];
569 char *opt;
570 int print_cygpath = 1;
571 int print_current = 0;
572 const char *sep_char = "\\";
573 int id_offset = 10000;
574 int c, i, off;
575 char *disp_username = NULL;
576 char passed_home_path[PATH_MAX];
577 BOOL in_domain;
578
579 passed_home_path[0] = '\0';
580 if (!isatty (1))
581 setmode (1, O_BINARY);
582
583 load_dsgetdcname ();
584 in_domain = fetch_primary_domain ();
585 if (argc == 1)
586 {
587 enum_std_accounts ();
588 if (in_domain)
589 enum_users (TRUE, NULL, sep_char, print_cygpath, passed_home_path,
590 10000, disp_username);
591 else
592 enum_users (FALSE, NULL, sep_char, print_cygpath, passed_home_path, 0,
593 disp_username);
594 return 0;
595 }
596
597 while ((c = getopt_long (argc, argv, opts, longopts, NULL)) != EOF)
598 switch (c)
599 {
600 case 'l':
601 case 'L':
602 if (print_local >= 16)
603 {
604 fprintf (stderr, "%s: Can not enumerate from more than 16 "
605 "servers.\n", __progname);
606 return 1;
607 }
608 opt = optarg ?:
609 argv[optind] && argv[optind][0] != '-' ? argv[optind] : NULL;
610 for (i = 0; i < print_local; ++i)
611 if ((!locals[i].str && !opt)
612 || (locals[i].str && opt && !strcmp (locals[i].str, opt)))
613 goto skip_local;
614 locals[print_local].str = opt;
615 locals[print_local++].with_dom = c == 'L';
616 skip_local:
617 break;
618 case 'd':
619 case 'D':
620 if (print_domain >= 16)
621 {
622 fprintf (stderr, "%s: Can not enumerate from more than 16 "
623 "domains.\n", __progname);
624 return 1;
625 }
626 opt = optarg ?:
627 argv[optind] && argv[optind][0] != '-' ? argv[optind] : NULL;
628 for (i = 0; i < print_domain; ++i)
629 if ((!domains[i].str && !opt)
630 || (domains[i].str && opt && !strcmp (domains[i].str, opt)))
631 goto skip_domain;
632 domains[print_domain].str = opt;
633 domains[print_domain++].with_dom = c == 'D';
634 skip_domain:
635 break;
636 case 'S':
637 sep_char = optarg;
638 if (strlen (sep_char) > 1)
639 {
640 fprintf (stderr, "%s: Only one character allowed as domain\\user "
641 "separator character.\n", __progname);
642 return 1;
643 }
644 if (*sep_char == ':')
645 {
646 fprintf (stderr, "%s: Colon not allowed as domain\\user separator "
647 "character.\n", __progname);
648 return 1;
649 }
650 break;
651 case 'c':
652 sep_char = NULL;
653 /*FALLTHRU*/
654 case 'C':
655 print_current = 1;
656 break;
657 case 'o':
658 id_offset = strtol (optarg, NULL, 10);
659 break;
660 case 'g':
661 break;
662 case 's':
663 break;
664 case 'm':
665 print_cygpath = 0;
666 break;
667 case 'p':
668 if (optarg[0] != '/')
669 {
670 fprintf (stderr, "%s: '%s' is not a fully qualified path.\n",
671 __progname, optarg);
672 return 1;
673 }
674 strcpy (passed_home_path, optarg);
675 if (optarg[strlen (optarg)-1] != '/')
676 strcat (passed_home_path, "/");
677 break;
678 case 'u':
679 disp_username = optarg;
680 break;
681 case 'h':
682 usage (stdout);
683 return 0;
684 case 'v':
685 print_version ();
686 return 0;
687 default:
688 fprintf (stderr, "Try '%s --help' for more information.\n", __progname);
689 return 1;
690 }
691
692 if (optind < argc - 1)
693 usage (stdout);
694
695 off = 1;
696 for (i = 0; i < print_local; ++i)
697 {
698 if (locals[i].str)
699 enum_users (FALSE, locals + i, sep_char, print_cygpath,
700 passed_home_path, id_offset * off++, disp_username);
701 else
702 {
703 enum_std_accounts ();
704 enum_users (FALSE, locals + i, sep_char, print_cygpath,
705 passed_home_path, 0, disp_username);
706 }
707 }
708
709 for (i = 0; i < print_domain; ++i)
710 enum_users (TRUE, domains + i, sep_char, print_cygpath, passed_home_path,
711 id_offset * off++, disp_username);
712
713 if (print_current)
714 current_user (print_cygpath, sep_char, passed_home_path, id_offset, disp_username);
715
716 return 0;
717 }
This page took 0.068392 seconds and 6 git commands to generate.