Bug Summary

File:mkpasswd.c
Location:line 476, column 15
Description:Value stored to 'len2' is never read

Annotated Source Code

1/* mkpasswd.c:
2
3 Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
4 2008, 2009, 2010, 2011, 2012 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_WINNT0x0600 0x0600
13#include <errno(*__errno()).h>
14#include <ctype.h>
15#include <stdlib.h>
16#include <wchar.h>
17#include <wctype.h>
18#include <locale.h>
19#include <stdio.h>
20#include <unistd.h>
21#include <getopt.h>
22#include <io.h>
23#include <sys/fcntl.h>
24#include <sys/cygwin.h>
25#include <cygwin/version.h>
26#include <windows.h>
27#include <lm.h>
28#include <iptypes.h>
29#include <wininet.h>
30#include <ntsecapi.h>
31#include <dsgetdc.h>
32#include <ntdef.h>
33#include "loadlib.h"
34
35#define print_win_error(x)_print_win_error(x, 35) _print_win_error(x, __LINE__35)
36
37#define MAX_SID_LEN40 40
38
39SID_IDENTIFIER_AUTHORITY sid_world_auth = {SECURITY_WORLD_SID_AUTHORITY{0,0,0,0,0,1}};
40SID_IDENTIFIER_AUTHORITY sid_nt_auth = {SECURITY_NT_AUTHORITY{0,0,0,0,0,5}};
41
42#ifndef min
43#define min(a,b)((a)<(b)?(a):(b)) (((a)<(b))?(a):(b))
44#endif
45
46typedef struct
47{
48 char *str;
49 DWORD id_offset;
50 BOOL domain;
51 BOOL with_dom;
52} domlist_t;
53
54static void
55_print_win_error(DWORD code, int line)
56{
57 char buf[4096];
58
59 if (FormatMessageFormatMessageA (FORMAT_MESSAGE_FROM_SYSTEM4096
60 | FORMAT_MESSAGE_IGNORE_INSERTS512,
61 NULL((void*)0),
62 code,
63 MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT)((((WORD)(0x01))<<10)|(WORD)(0x00)),
64 (LPTSTR) buf, sizeof (buf), NULL((void*)0)))
65 fprintf (stderr((__getreent())->_stderr), "mkpasswd (%d): [%lu] %s", line, code, buf);
66 else
67 fprintf (stderr((__getreent())->_stderr), "mkpasswd (%d): error %lu", line, code);
68}
69
70static PWCHAR
71get_dcname (char *domain)
72{
73 static WCHAR server[INTERNET_MAX_HOST_NAME_LENGTH256 + 1];
74 DWORD rc;
75 WCHAR domain_name[MAX_DOMAIN_NAME_LEN128 + 1];
76 PDOMAIN_CONTROLLER_INFOW pdci = NULL((void*)0);
77
78 if (domain)
79 {
80 mbstowcs (domain_name, domain, strlen (domain) + 1);
81 rc = DsGetDcNameW (NULL((void*)0), domain_name, NULL((void*)0), NULL((void*)0), 0, &pdci);
82 }
83 else
84 rc = DsGetDcNameW (NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), 0, &pdci);
85 if (rc != ERROR_SUCCESS0L)
86 {
87 print_win_error (rc)_print_win_error(rc, 87);
88 return (PWCHAR) -1;
89 }
90 wcscpy (server, pdci->DomainControllerName);
91 NetApiBufferFree (pdci);
92 return server;
93}
94
95static char *
96put_sid (PSID sid)
97{
98 static char s[512];
99 char t[32];
100 DWORD i;
101
102 strcpy (s, "S-1-");
103 sprintf(t, "%u", GetSidIdentifierAuthority (sid)->Value[5]);
104 strcat (s, t);
105 for (i = 0; i < *GetSidSubAuthorityCount (sid); ++i)
106 {
107 sprintf(t, "-%lu", *GetSidSubAuthority (sid, i));
108 strcat (s, t);
109 }
110 return s;
111}
112
113static void
114uni2ansi (LPWSTR wcs, char *mbs, int size)
115{
116 if (wcs)
117 wcstombs (mbs, wcs, size);
118 else
119 *mbs = '\0';
120}
121
122typedef struct {
123 PSID psid;
124 int buffer[10];
125} sidbuf;
126
127static sidbuf curr_user;
128static sidbuf curr_pgrp;
129static BOOL got_curr_user = FALSE0;
130
131static void
132fetch_current_user_sid ()
133{
134 DWORD len;
135 HANDLE ptok;
136
137 if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY(0x0008), &ptok)
138 || !GetTokenInformation (ptok, TokenUser, &curr_user, sizeof curr_user,
139 &len)
140 || !GetTokenInformation (ptok, TokenPrimaryGroup, &curr_pgrp,
141 sizeof curr_pgrp, &len)
142 || !CloseHandle (ptok))
143 {
144 print_win_error (GetLastError ())_print_win_error(GetLastError (), 144);
145 return;
146 }
147}
148
149static void
150current_user (const char *sep, const char *passed_home_path, DWORD id_offset,
151 const char *disp_username)
152{
153 WCHAR user[UNLEN256 + 1];
154 WCHAR dom[MAX_DOMAIN_NAME_LEN128 + 1];
155 DWORD ulen = UNLEN256 + 1;
156 DWORD dlen = MAX_DOMAIN_NAME_LEN128 + 1;
157 SID_NAME_USE acc_type;
158 int uid, gid;
159 char homedir_psx[PATH_MAX4096] = {0};
160
161 if (!curr_user.psid || !curr_pgrp.psid
162 || !LookupAccountSidW (NULL((void*)0), curr_user.psid, user, &ulen, dom, &dlen,
163 &acc_type))
164 {
165 print_win_error (GetLastError ())_print_win_error(GetLastError (), 165);
166 return;
167 }
168
169 uid = *GetSidSubAuthority (curr_user.psid,
170 *GetSidSubAuthorityCount(curr_user.psid) - 1);
171 gid = *GetSidSubAuthority (curr_pgrp.psid,
172 *GetSidSubAuthorityCount(curr_pgrp.psid) - 1);
173 if (passed_home_path[0] == '\0')
174 {
175 char *envhome = getenv ("HOME");
176
177 /* If $HOME exists and is non-empty, just copy it over to homedir_psx.
178 Otherwise, generate a new path of the form "/home/$USER". */
179 if (envhome && envhome[0] != '\0')
180 strncat (homedir_psx, envhome, sizeof (homedir_psx) - 1);
181 else
182 {
183 wcstombs (stpncpy (homedir_psx, "/home/", sizeof (homedir_psx)),
184 user, sizeof (homedir_psx) - 6);
185 homedir_psx[PATH_MAX4096 - 1] = '\0';
186 }
187 }
188 else
189 {
190 char *p = stpncpy (homedir_psx, passed_home_path, sizeof (homedir_psx));
191 wcstombs (p, user, sizeof (homedir_psx) - (p - homedir_psx));
192 homedir_psx[PATH_MAX4096 - 1] = '\0';
193 }
194
195 printf ("%ls%s%ls:unused:%lu:%lu:U-%ls\\%ls,%s:%s:/bin/bash\n",
196 sep ? dom : L"",
197 sep ?: "",
198 user,
199 id_offset + uid,
200 id_offset + gid,
201 dom,
202 user,
203 put_sid (curr_user.psid),
204 homedir_psx);
205}
206
207static void
208enum_unix_users (domlist_t *dom_or_machine, const char *sep, DWORD id_offset,
209 char *unix_user_list)
210{
211 WCHAR machine[INTERNET_MAX_HOST_NAME_LENGTH256 + 1];
212 PWCHAR servername = NULL((void*)0);
213 char *d_or_m = dom_or_machine ? dom_or_machine->str : NULL((void*)0);
214 BOOL with_dom = dom_or_machine ? dom_or_machine->with_dom : FALSE0;
215 SID_IDENTIFIER_AUTHORITY auth = { { 0, 0, 0, 0, 0, 22 } };
216 char *ustr, *user_list;
217 WCHAR user[UNLEN256 + sizeof ("Unix User\\") + 1];
218 WCHAR dom[MAX_DOMAIN_NAME_LEN128 + 1];
219 DWORD ulen, dlen, sidlen;
220 PSID psid;
221 char psid_buffer[MAX_SID_LEN40];
222 SID_NAME_USE acc_type;
223
224 if (!d_or_m)
225 return;
226
227 int ret = mbstowcs (machine, d_or_m, INTERNET_MAX_HOST_NAME_LENGTH256 + 1);
228 if (ret < 1 || ret >= INTERNET_MAX_HOST_NAME_LENGTH256 + 1)
229 {
230 fprintf (stderr((__getreent())->_stderr), "%s: Invalid machine name '%s'. Skipping...\n",
231 program_invocation_short_name, d_or_m);
232 return;
233 }
234 servername = machine;
235
236 if (!AllocateAndInitializeSid (&auth, 2, 1, 0, 0, 0, 0, 0, 0, 0, &psid))
237 return;
238
239 if (!(user_list = strdup (unix_user_list)))
240 {
241 FreeSid (psid);
242 return;
243 }
244
245 for (ustr = strtok (user_list, ","); ustr; ustr = strtok (NULL((void*)0), ","))
246 {
247 if (!isdigit ((unsigned char) ustr[0])(((__ctype_ptr__+sizeof(""[(unsigned char) ustr[0]]))[(int)((
unsigned char) ustr[0])])&04)
&& ustr[0] != '-')
248 {
249 PWCHAR p = wcpcpy (user, L"Unix User\\");
250 ret = mbstowcs (p, ustr, UNLEN256 + 1);
251 if (ret < 1 || ret >= UNLEN256 + 1)
252 fprintf (stderr((__getreent())->_stderr), "%s: Invalid user name '%s'. Skipping...\n",
253 program_invocation_short_name, ustr);
254 else if (LookupAccountNameW (servername, user,
255 psid = (PSID) psid_buffer,
256 (sidlen = MAX_SID_LEN40, &sidlen),
257 dom,
258 (dlen = MAX_DOMAIN_NAME_LEN128 + 1, &dlen),
259 &acc_type))
260 printf ("%s%s%ls:unused:%lu:99999:,%s::\n",
261 with_dom ? "Unix User" : "",
262 with_dom ? sep : "",
263 user + 10,
264 id_offset +
265 *GetSidSubAuthority (psid,
266 *GetSidSubAuthorityCount(psid) - 1),
267 put_sid (psid));
268 }
269 else
270 {
271 DWORD start, stop;
272 char *p = ustr;
273 if (*p == '-')
274 start = 0;
275 else
276 start = strtol (p, &p, 10);
277 if (!*p)
278 stop = start;
279 else if (*p++ != '-' || !isdigit ((unsigned char) *p)(((__ctype_ptr__+sizeof(""[(unsigned char) *p]))[(int)((unsigned
char) *p)])&04)
280 || (stop = strtol (p, &p, 10)) < start || *p)
281 {
282 fprintf (stderr((__getreent())->_stderr), "%s: Malformed unix user list entry '%s'. "
283 "Skipping...\n",
284 program_invocation_short_name, ustr);
285 continue;
286 }
287 for (; start <= stop; ++ start)
288 {
289 *GetSidSubAuthority (psid, *GetSidSubAuthorityCount(psid) - 1)
290 = start;
291 if (LookupAccountSidW (servername, psid,
292 user, (ulen = GNLEN256 + 1, &ulen),
293 dom,
294 (dlen = MAX_DOMAIN_NAME_LEN128 + 1, &dlen),
295 &acc_type)
296 && !iswdigit (user[0]))
297 printf ("%s%s%ls:unused:%lu:99999:,%s::\n",
298 with_dom ? "Unix User" : "",
299 with_dom ? sep : "",
300 user,
301 id_offset + start,
302 put_sid (psid));
303 }
304 }
305 }
306
307 free (user_list);
308 FreeSid (psid);
309}
310
311static int
312enum_users (BOOL domain, domlist_t *dom_or_machine, const char *sep,
313 const char *passed_home_path, DWORD id_offset, char *disp_username,
314 int print_current)
315{
316 WCHAR machine[INTERNET_MAX_HOST_NAME_LENGTH256 + 1];
317 PWCHAR servername = NULL((void*)0);
318 char *d_or_m = dom_or_machine ? dom_or_machine->str : NULL((void*)0);
319 BOOL with_dom = dom_or_machine ? dom_or_machine->with_dom : FALSE0;
320 USER_INFO_3 *buffer;
321 DWORD entriesread = 0;
322 DWORD totalentries = 0;
323 DWORD resume_handle = 0;
324 DWORD rc;
325 WCHAR uni_name[UNLEN256 + 1];
326 if (domain)
327 {
328 servername = get_dcname (d_or_m);
329 if (servername == (PWCHAR) -1)
330 return 1;
331 }
332 else if (d_or_m)
333 {
334 int ret = mbstowcs (machine, d_or_m, INTERNET_MAX_HOST_NAME_LENGTH256 + 1);
335 if (ret < 1 || ret >= INTERNET_MAX_HOST_NAME_LENGTH256 + 1)
336 {
337 fprintf (stderr((__getreent())->_stderr), "%s: Invalid machine name '%s'. Skipping...\n",
338 program_invocation_short_name, d_or_m);
339 return 1;
340 }
341 servername = machine;
342 }
343
344 do
345 {
346 DWORD i;
347
348 if (disp_username != NULL((void*)0))
349 {
350 mbstowcs (uni_name, disp_username, UNLEN256 + 1);
351 rc = NetUserGetInfo (servername, (LPWSTR) &uni_name, 3,
352 (void *) &buffer);
353 entriesread = 1;
354 /* Avoid annoying error messages just because the user hasn't been
355 found. */
356 if (rc == NERR_UserNotFound(2100 +121))
357 return 0;
358 }
359 else
360 rc = NetUserEnum (servername, 3, FILTER_NORMAL_ACCOUNT2,
361 (void *) &buffer, MAX_PREFERRED_LENGTH((DWORD)-1),
362 &entriesread, &totalentries, &resume_handle);
363 switch (rc)
364 {
365 case ERROR_ACCESS_DENIED5L:
366 print_win_error(rc)_print_win_error(rc, 366);
367 return 1;
368
369 case ERROR_MORE_DATA234L:
370 case ERROR_SUCCESS0L:
371 break;
372
373 default:
374 print_win_error(rc)_print_win_error(rc, 374);
375 return 1;
376 }
377
378 for (i = 0; i < entriesread; i++)
379 {
380 char homedir_psx[PATH_MAX4096];
381 WCHAR domain_name[MAX_DOMAIN_NAME_LEN128 + 1];
382 DWORD domname_len = MAX_DOMAIN_NAME_LEN128 + 1;
383 char psid_buffer[MAX_SID_LEN40];
384 PSID psid = (PSID) psid_buffer;
385 DWORD sid_length = MAX_SID_LEN40;
386 SID_NAME_USE acc_type;
387
388 int uid = buffer[i].usri3_user_id;
389 int gid = buffer[i].usri3_primary_group_id;
390 homedir_psx[0] = '\0';
391 if (passed_home_path[0] == '\0')
392 {
393 if (buffer[i].usri3_home_dir[0] != L'\0')
394 cygwin_conv_path (CCP_WIN_W_TO_POSIX | CCP_ABSOLUTE,
395 buffer[i].usri3_home_dir, homedir_psx,
396 PATH_MAX4096);
397 else
398 uni2ansi (buffer[i].usri3_name,
399 stpcpy (homedir_psx, "/home/"), PATH_MAX4096 - 6);
400 }
401 else
402 uni2ansi (buffer[i].usri3_name,
403 stpcpy (homedir_psx, passed_home_path),
404 PATH_MAX4096 - strlen (passed_home_path));
405
406 if (!LookupAccountNameW (servername, buffer[i].usri3_name,
407 psid, &sid_length, domain_name,
408 &domname_len, &acc_type))
409 {
410 print_win_error(GetLastError ())_print_win_error(GetLastError (), 410);
411 fprintf(stderr((__getreent())->_stderr), " (%ls)\n", buffer[i].usri3_name);
412 continue;
413 }
414 else if (acc_type == SidTypeDomain)
415 {
416 WCHAR domname[MAX_DOMAIN_NAME_LEN128 + UNLEN256 + 2];
417
418 wcscpy (domname, domain || !servername
419 ? domain_name : servername);
420 wcscat (domname, L"\\");
421 wcscat (domname, buffer[i].usri3_name);
422 sid_length = MAX_SID_LEN40;
423 domname_len = sizeof (domname);
424 if (!LookupAccountNameW (servername, domname, psid,
425 &sid_length, domain_name,
426 &domname_len, &acc_type))
427 {
428 print_win_error(GetLastError ())_print_win_error(GetLastError (), 428);
429 fprintf(stderr((__getreent())->_stderr), " (%ls)\n", domname);
430 continue;
431 }
432 }
433 if (!print_current)
434 /* fall through */;
435 else if (EqualSid (curr_user.psid, psid))
436 got_curr_user = TRUE1;
437
438 printf ("%ls%s%ls:unused:%lu:%lu:%ls%sU-%ls\\%ls,%s:%s:/bin/bash\n",
439 with_dom ? domain_name : L"",
440 with_dom ? sep : "",
441 buffer[i].usri3_name,
442 id_offset + uid,
443 id_offset + gid,
444 buffer[i].usri3_full_name ?: L"",
445 buffer[i].usri3_full_name
446 && buffer[i].usri3_full_name[0] ? "," : "",
447 domain_name,
448 buffer[i].usri3_name,
449 put_sid (psid),
450 homedir_psx);
451 }
452
453 NetApiBufferFree (buffer);
454
455 }
456 while (rc == ERROR_MORE_DATA234L);
457
458 return 0;
459}
460
461static void
462print_special_by_sid (PSID_IDENTIFIER_AUTHORITY auth, BYTE cnt,
463 DWORD sub1, DWORD sub2, DWORD sub3, DWORD sub4,
464 DWORD sub5, DWORD sub6, DWORD sub7, DWORD sub8)
465{
466 WCHAR user[UNLEN256 + 1], dom[MAX_DOMAIN_NAME_LEN128 + 1];
467 DWORD len, len2, rid;
468 PSID sid;
469 SID_NAME_USE acc_type;
470
471 if (AllocateAndInitializeSid (auth, cnt, sub1, sub2, sub3, sub4,
472 sub5, sub6, sub7, sub8, &sid))
473 {
474 if (LookupAccountSidW (NULL((void*)0), sid,
475 user, (len = UNLEN256 + 1, &len),
476 dom, (len2 = MAX_DOMAIN_NAME_LEN128 + 1, &len),
Value stored to 'len2' is never read
477 &acc_type))
478 {
479 if (sub8)
480 rid = sub8;
481 else if (sub7)
482 rid = sub7;
483 else if (sub6)
484 rid = sub6;
485 else if (sub5)
486 rid = sub5;
487 else if (sub4)
488 rid = sub4;
489 else if (sub3)
490 rid = sub3;
491 else if (sub2)
492 rid = sub2;
493 else
494 rid = sub1;
495 printf ("%ls:*:%lu:%lu:,%s::\n",
496 user, rid, rid == 18 ? 544 : rid, /* SYSTEM hack */
497 put_sid (sid));
498 }
499 FreeSid (sid);
500 }
501}
502
503static int
504usage (FILE * stream)
505{
506 fprintf (stream,
507"Usage: %s [OPTIONS]...\n"
508"\n"
509"Print /etc/passwd file to stdout\n"
510"\n"
511"Options:\n"
512"\n"
513" -l,--local [machine[,offset]]\n"
514" print local user accounts with uid offset offset\n"
515" (from local machine if no machine specified)\n"
516" -L,--Local [machine[,offset]]\n"
517" ditto, but generate username with machine prefix\n"
518" -d,--domain [domain[,offset]]\n"
519" print domain accounts with uid offset offset\n"
520" (from current domain if no domain specified)\n"
521" -D,--Domain [domain[,offset]]\n"
522" ditto, but generate username with domain prefix\n"
523" -c,--current print current user\n"
524" -C,--Current ditto, but generate username with machine or\n"
525" domain prefix\n"
526" -S,--separator char for -L, -D, -C use character char as domain\\user\n"
527" separator in username instead of the default '\\'\n"
528" -o,--id-offset offset change the default offset (10000) added to uids\n"
529" in domain or foreign server accounts.\n"
530" -u,--username username only return information for the specified user\n"
531" one of -l, -L, -d, -D must be specified, too\n"
532" -p,--path-to-home path use specified path instead of user account home dir\n"
533" or /home prefix\n"
534" -U,--unix userlist additionally print UNIX users when using -l or -L\n"
535" on a UNIX Samba server\n"
536" userlist is a comma-separated list of usernames\n"
537" or uid ranges (root,-25,50-100).\n"
538" (enumerating large ranges can take a long time!)\n"
539" -s,--no-sids (ignored)\n"
540" -m,--no-mount (ignored)\n"
541" -g,--local-groups (ignored)\n"
542" -h,--help displays this message\n"
543" -V,--version version information and exit\n"
544"\n"
545"Default is to print local accounts on stand-alone machines, domain accounts\n"
546"on domain controllers and domain member machines.\n"
547"\n", program_invocation_short_name);
548 return 1;
549}
550
551static struct option longopts[] = {
552 {"current", no_argument0, NULL((void*)0), 'c'},
553 {"Current", no_argument0, NULL((void*)0), 'C'},
554 {"domain", optional_argument2, NULL((void*)0), 'd'},
555 {"Domain", optional_argument2, NULL((void*)0), 'D'},
556 {"local-groups", no_argument0, NULL((void*)0), 'g'},
557 {"help", no_argument0, NULL((void*)0), 'h'},
558 {"local", optional_argument2, NULL((void*)0), 'l'},
559 {"Local", optional_argument2, NULL((void*)0), 'L'},
560 {"no-mount", no_argument0, NULL((void*)0), 'm'},
561 {"id-offset", required_argument1, NULL((void*)0), 'o'},
562 {"path-to-home", required_argument1, NULL((void*)0), 'p'},
563 {"no-sids", no_argument0, NULL((void*)0), 's'},
564 {"separator", required_argument1, NULL((void*)0), 'S'},
565 {"username", required_argument1, NULL((void*)0), 'u'},
566 {"unix", required_argument1, NULL((void*)0), 'U'},
567 {"version", no_argument0, NULL((void*)0), 'V'},
568 {0, no_argument0, NULL((void*)0), 0}
569};
570
571static char opts[] = "cCd::D::ghl::L::mo:sS:p:u:U:V";
572
573static void
574print_version ()
575{
576 printf ("mkpasswd (cygwin) %d.%d.%d\n"
577 "Passwd File Generator\n"
578 "Copyright (C) 1997 - %s Red Hat, Inc.\n"
579 "This is free software; see the source for copying conditions. There is NO\n"
580 "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",
581 CYGWIN_VERSION_DLL_MAJOR1007 / 1000,
582 CYGWIN_VERSION_DLL_MAJOR1007 % 1000,
583 CYGWIN_VERSION_DLL_MINOR16,
584 strrchr (__DATE__"Jul 3 2012", ' ') + 1);
585}
586
587static void
588print_special_by_name (PCWSTR name, uid_t uid, gid_t gid)
589{
590 DWORD size = 256, dom_size = 256;
591 PSID sid = (PSID) alloca (size)__builtin_alloca(size);
592 WCHAR dom[dom_size];
593 SID_NAME_USE use;
594
595 PWCHAR name_only = wcschr (name, L'\\');
596 if (name_only)
597 ++name_only;
598
599 if (LookupAccountNameW (NULL((void*)0), name, sid, &size, dom, &dom_size, &use))
600 printf ("%ls:*:%lu:%lu:U-%ls%s%ls,%s::\n",
601 name_only ?: name,
602 (unsigned long) uid,
603 (unsigned long) gid,
604 name_only ? dom : L"",
605 name_only ? "\\" : "",
606 name_only ?: name,
607 put_sid (sid));
608}
609
610static void
611enum_std_accounts ()
612{
613 /* Generate service starter account entries. */
614 printf ("SYSTEM:*:18:544:,S-1-5-18::\n");
615 printf ("LocalService:*:19:544:U-NT AUTHORITY\\LocalService,S-1-5-19::\n");
616 printf ("NetworkService:*:20:544:U-NT AUTHORITY\\NetworkService,S-1-5-20::\n");
617 /* Get 'administrators' group (has localized name). */
618 print_special_by_sid (&sid_nt_auth, 2, SECURITY_BUILTIN_DOMAIN_RID32,
619 DOMAIN_ALIAS_RID_ADMINS0x220L, 0, 0, 0, 0, 0, 0);
620 /* Fetch "TrustedInstaller" account starting with Vista. */
621 print_special_by_name (L"NT SERVICE\\TrustedInstaller", -2, -2);
622}
623
624static PPOLICY_PRIMARY_DOMAIN_INFO p_dom;
625
626static BOOL
627fetch_primary_domain ()
628{
629 NTSTATUS status;
630 LSA_OBJECT_ATTRIBUTES oa = { 0, 0, 0, 0, 0, 0 };
631 LSA_HANDLE lsa;
632
633 if (!p_dom)
634 {
635 status = LsaOpenPolicy (NULL((void*)0), &oa, POLICY_VIEW_LOCAL_INFORMATION1, &lsa);
636 if (!NT_SUCCESS (status)((status)>=0))
637 return FALSE0;
638 status = LsaQueryInformationPolicy (lsa, PolicyPrimaryDomainInformation,
639 (PVOID *) ((void *) &p_dom));
640 LsaClose (lsa);
641 if (!NT_SUCCESS (status)((status)>=0))
642 return FALSE0;
643 }
644 return !!p_dom->Sid;
645}
646
647int
648main (int argc, char **argv)
649{
650 int print_domlist = 0;
651 domlist_t domlist[32];
652 char *opt, *p, *ep;
653 int print_current = 0;
654 char *print_unix = NULL((void*)0);
655 const char *sep_char = "\\";
656 DWORD id_offset = 10000, off;
657 int c, i;
658 char *disp_username = NULL((void*)0);
659 char passed_home_path[PATH_MAX4096];
660 BOOL in_domain;
661 int optional_args = 0;
662
663 passed_home_path[0] = '\0';
664 if (!isatty (1))
665 setmode (1, O_BINARY0x10000);
666
667 /* Use locale from environment. If not set or set to "C", use UTF-8. */
668 setlocale (LC_CTYPE2, "");
669 if (!strcmp (setlocale (LC_CTYPE2, NULL((void*)0)), "C"))
670 setlocale (LC_CTYPE2, "en_US.UTF-8");
671 in_domain = fetch_primary_domain ();
672 fetch_current_user_sid ();
673
674 if (argc == 1)
675 {
676 enum_std_accounts ();
677 if (in_domain)
678 enum_users (TRUE1, NULL((void*)0), sep_char, passed_home_path, 10000,
679 disp_username, 0);
680 else
681 enum_users (FALSE0, NULL((void*)0), sep_char, passed_home_path, 0,
682 disp_username, 0);
683 return 0;
684 }
685
686 unsetenv ("POSIXLY_CORRECT"); /* To get optional arg processing right. */
687 while ((c = getopt_long (argc, argv, opts, longopts, NULL((void*)0))) != EOF(-1))
688 switch (c)
689 {
690 case 'd':
691 case 'D':
692 case 'l':
693 case 'L':
694 if (print_domlist >= 32)
695 {
696 fprintf (stderr((__getreent())->_stderr), "%s: Can not enumerate from more than 32 "
697 "domains and machines.\n",
698 program_invocation_short_name);
699 return 1;
700 }
701 domlist[print_domlist].domain = (c == 'd' || c == 'D');
702 opt = optarg ?:
703 argv[optind] && argv[optind][0] != '-' ? argv[optind] : NULL((void*)0);
704 if (argv[optind] && opt == argv[optind])
705 ++optional_args;
706 for (i = 0; i < print_domlist; ++i)
707 if (domlist[i].domain == domlist[print_domlist].domain
708 && ((!domlist[i].str && !opt)
709 || (domlist[i].str && opt
710 && (off = strlen (domlist[i].str))
711 && !strncmp (domlist[i].str, opt, off)
712 && (!opt[off] || opt[off] == ','))))
713 {
714 fprintf (stderr((__getreent())->_stderr), "%s: Duplicate %s '%s'. Skipping...\n",
715 program_invocation_short_name,
716 domlist[i].domain ? "domain" : "machine",
717 domlist[i].str);
718 goto skip;
719 }
720 domlist[print_domlist].str = opt;
721 domlist[print_domlist].id_offset = ULONG_MAX(2147483647L * 2UL + 1);
722 if (opt && (p = strchr (opt, ',')))
723 {
724 if (p == opt
725 || !isdigit ((unsigned char) p[1])(((__ctype_ptr__+sizeof(""[(unsigned char) p[1]]))[(int)((unsigned
char) p[1])])&04)
726 || (domlist[print_domlist].id_offset = strtol (p + 1, &ep, 10)
727 , *ep))
728 {
729 fprintf (stderr((__getreent())->_stderr), "%s: Malformed domain,offset string '%s'. "
730 "Skipping...\n", program_invocation_short_name, opt);
731 break;
732 }
733 *p = '\0';
734 }
735 domlist[print_domlist++].with_dom = (c == 'D' || c == 'L');
736skip:
737 break;
738 case 'S':
739 sep_char = optarg;
740 if (strlen (sep_char) > 1)
741 {
742 fprintf (stderr((__getreent())->_stderr), "%s: Only one character allowed as domain\\user "
743 "separator character.\n",
744 program_invocation_short_name);
745 return 1;
746 }
747 if (*sep_char == ':')
748 {
749 fprintf (stderr((__getreent())->_stderr), "%s: Colon not allowed as domain\\user separator "
750 "character.\n", program_invocation_short_name);
751 return 1;
752 }
753 break;
754 case 'U':
755 print_unix = optarg;
756 break;
757 case 'c':
758 sep_char = NULL((void*)0);
759 /*FALLTHRU*/
760 case 'C':
761 print_current = 1;
762 break;
763 case 'o':
764 id_offset = strtoul (optarg, &ep, 10);
765 if (*ep)
766 {
767 fprintf (stderr((__getreent())->_stderr), "%s: Malformed offset '%s'. "
768 "Skipping...\n", program_invocation_short_name, optarg);
769 return 1;
770 }
771 break;
772 case 'p':
773 if (optarg[0] != '/')
774 {
775 fprintf (stderr((__getreent())->_stderr), "%s: '%s' is not a fully qualified path.\n",
776 program_invocation_short_name, optarg);
777 return 1;
778 }
779 strcpy (passed_home_path, optarg);
780 if (optarg[strlen (optarg)-1] != '/')
781 strcat (passed_home_path, "/");
782 break;
783 case 'u':
784 disp_username = optarg;
785 break;
786 case 'h':
787 usage (stdout((__getreent())->_stdout));
788 return 0;
789 case 'V':
790 print_version ();
791 return 0;
792 case 'g': /* deprecated */
793 case 's': /* deprecated */
794 case 'm': /* deprecated */
795 break;
796 default:
797 fprintf (stderr((__getreent())->_stderr), "Try `%s --help' for more information.\n",
798 program_invocation_short_name);
799 return 1;
800 }
801
802 optind += optional_args;
803 if (argv[optind])
804 {
805 fprintf (stderr((__getreent())->_stderr),
806 "mkpasswd: non-option command line argument `%s' is not allowed.\n"
807 "Try `mkpasswd --help' for more information.\n", argv[optind]);
808 exit (1);
809 }
810
811 off = id_offset;
812 for (i = 0; i < print_domlist; ++i)
813 {
814 DWORD my_off = (domlist[i].domain || domlist[i].str)
815 ? domlist[i].id_offset != ULONG_MAX(2147483647L * 2UL + 1)
816 ? domlist[i].id_offset : off : 0;
817 if (!domlist[i].domain && domlist[i].str && print_unix)
818 enum_unix_users (domlist + i, sep_char, my_off, print_unix);
819 if (!my_off && !disp_username)
820 enum_std_accounts ();
821 enum_users (domlist[i].domain, domlist + i, sep_char, passed_home_path,
822 my_off, disp_username, print_current);
823 if (my_off)
824 off += id_offset;
825 }
826
827 if (print_current && !got_curr_user)
828 current_user (sep_char, passed_home_path, off, disp_username);
829
830 return 0;
831}