3 Copyright 1997, 1998, 1999, 2000, 2001 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
17 #include <sys/cygwin.h>
21 #include <sys/fcntl.h>
24 SID_IDENTIFIER_AUTHORITY sid_world_auth
= {SECURITY_WORLD_SID_AUTHORITY
};
25 SID_IDENTIFIER_AUTHORITY sid_nt_auth
= {SECURITY_NT_AUTHORITY
};
27 NET_API_STATUS
WINAPI (*netapibufferfree
)(PVOID
);
28 NET_API_STATUS
WINAPI (*netuserenum
)(LPWSTR
,DWORD
,DWORD
,PBYTE
*,DWORD
,PDWORD
,PDWORD
,PDWORD
);
29 NET_API_STATUS
WINAPI (*netlocalgroupenum
)(LPWSTR
,DWORD
,PBYTE
*,DWORD
,PDWORD
,PDWORD
,PDWORD
);
30 NET_API_STATUS
WINAPI (*netgetdcname
)(LPWSTR
,LPWSTR
,PBYTE
*);
31 NET_API_STATUS
WINAPI (*netusergetinfo
)(LPWSTR
,LPWSTR
,DWORD
,PBYTE
*);
34 #define min(a,b) (((a)<(b))?(a):(b))
40 HANDLE h
= LoadLibrary ("netapi32.dll");
45 if (!(netapibufferfree
= (void *) GetProcAddress (h
, "NetApiBufferFree")))
47 if (!(netuserenum
= (void *) GetProcAddress (h
, "NetUserEnum")))
49 if (!(netlocalgroupenum
= (void *) GetProcAddress (h
, "NetLocalGroupEnum")))
51 if (!(netgetdcname
= (void *) GetProcAddress (h
, "NetGetDCName")))
53 if (!(netusergetinfo
= (void *) GetProcAddress (h
, "NetUserGetInfo")))
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_users (LPWSTR servername
, int print_sids
, int print_cygpath
,
111 const char * passed_home_path
, int id_offset
, char *disp_username
)
114 DWORD entriesread
= 0;
115 DWORD totalentries
= 0;
116 DWORD resume_handle
= 0;
118 char ansi_srvname
[256];
122 uni2ansi (servername
, ansi_srvname
, sizeof (ansi_srvname
));
128 if (disp_username
!= NULL
)
130 MultiByteToWideChar (CP_ACP
, 0, disp_username
, -1, uni_name
, 512 );
131 rc
= netusergetinfo(servername
, (LPWSTR
) & uni_name
, 3,
132 (LPBYTE
*) &buffer
);
136 rc
= netuserenum (servername
, 3, FILTER_NORMAL_ACCOUNT
,
137 (LPBYTE
*) & buffer
, 1024,
138 &entriesread
, &totalentries
, &resume_handle
);
141 case ERROR_ACCESS_DENIED
:
142 fprintf (stderr
, "Access denied\n");
145 case ERROR_MORE_DATA
:
150 fprintf (stderr
, "NetUserEnum() failed with error %ld.\n", rc
);
151 if (rc
== NERR_UserNotFound
)
152 fprintf (stderr
, "That user doesn't exist.\n");
156 for (i
= 0; i
< entriesread
; i
++)
160 char homedir_psx
[MAX_PATH
];
161 char homedir_w32
[MAX_PATH
];
162 char domain_name
[100];
163 DWORD domname_len
= 100;
164 char psid_buffer
[1024];
165 PSID psid
= (PSID
) psid_buffer
;
166 DWORD sid_length
= 1024;
167 SID_NAME_USE acc_type
;
169 int uid
= buffer
[i
].usri3_user_id
;
170 int gid
= buffer
[i
].usri3_primary_group_id
;
171 uni2ansi (buffer
[i
].usri3_name
, username
, sizeof (username
));
172 uni2ansi (buffer
[i
].usri3_full_name
, fullname
, sizeof (fullname
));
173 homedir_w32
[0] = homedir_psx
[0] = '\0';
174 if (passed_home_path
[0] == '\0')
176 uni2ansi (buffer
[i
].usri3_home_dir
, homedir_w32
,
177 sizeof (homedir_w32
));
178 if (homedir_w32
[0] != '\0')
181 cygwin_conv_to_posix_path (homedir_w32
, homedir_psx
);
183 psx_dir (homedir_w32
, homedir_psx
);
187 strcpy (homedir_psx
, "/home/");
188 strcat (homedir_psx
, username
);
193 strcpy (homedir_psx
, passed_home_path
);
194 strcat (homedir_psx
, username
);
199 if (!LookupAccountName (servername
? ansi_srvname
: NULL
,
202 domain_name
, &domname_len
,
206 "LookupAccountName(%s,%s) failed with error %ld\n",
207 servername
? ansi_srvname
: "NULL",
212 else if (acc_type
== SidTypeDomain
)
216 strcpy (domname
, domain_name
);
217 strcat (domname
, "\\");
218 strcat (domname
, username
);
221 if (!LookupAccountName (servername
? ansi_srvname
: NULL
,
224 domain_name
, &domname_len
,
228 "LookupAccountName(%s,%s) failed with error %ld\n",
229 servername
? ansi_srvname
: "NULL",
236 printf ("%s:unused_by_nt/2000/xp:%d:%d:%s%s%s%s%s%s%s%s:%s:/bin/bash\n",
241 print_sids
&& fullname
[0] ? "," : "",
242 print_sids
? "U-" : "",
243 print_sids
? domain_name
: "",
244 print_sids
&& domain_name
[0] ? "\\" : "",
245 print_sids
? username
: "",
246 print_sids
? "," : "",
247 print_sids
? put_sid (psid
) : "",
251 netapibufferfree (buffer
);
254 while (rc
== ERROR_MORE_DATA
);
257 netapibufferfree (servername
);
263 enum_local_groups (int print_sids
)
265 LOCALGROUP_INFO_0
*buffer
;
266 DWORD entriesread
= 0;
267 DWORD totalentries
= 0;
268 DWORD resume_handle
= 0;
275 rc
= netlocalgroupenum (NULL
, 0, (LPBYTE
*) & buffer
, 1024,
276 &entriesread
, &totalentries
, &resume_handle
);
279 case ERROR_ACCESS_DENIED
:
280 fprintf (stderr
, "Access denied\n");
283 case ERROR_MORE_DATA
:
288 fprintf (stderr
, "NetLocalGroupEnum() failed with %ld\n", rc
);
292 for (i
= 0; i
< entriesread
; i
++)
294 char localgroup_name
[100];
295 char domain_name
[100];
296 DWORD domname_len
= 100;
297 char psid_buffer
[1024];
298 PSID psid
= (PSID
) psid_buffer
;
299 DWORD sid_length
= 1024;
301 SID_NAME_USE acc_type
;
302 uni2ansi (buffer
[i
].lgrpi0_name
, localgroup_name
, sizeof (localgroup_name
));
304 if (!LookupAccountName (NULL
, localgroup_name
, psid
,
305 &sid_length
, domain_name
, &domname_len
,
308 fprintf (stderr
, "LookupAccountName(%s) failed with %ld\n",
309 localgroup_name
, GetLastError ());
312 else if (acc_type
== SidTypeDomain
)
316 strcpy (domname
, domain_name
);
317 strcat (domname
, "\\");
318 strcat (domname
, localgroup_name
);
321 if (!LookupAccountName (NULL
, domname
,
323 domain_name
, &domname_len
,
327 "LookupAccountName(%s) failed with error %ld\n",
328 localgroup_name
, GetLastError ());
333 gid
= *GetSidSubAuthority (psid
, *GetSidSubAuthorityCount(psid
) - 1);
335 printf ("%s:*:%ld:%ld:%s%s::\n", localgroup_name
, gid
, gid
,
336 print_sids
? "," : "",
337 print_sids
? put_sid (psid
) : "");
340 netapibufferfree (buffer
);
343 while (rc
== ERROR_MORE_DATA
);
349 print_special (int print_sids
,
350 PSID_IDENTIFIER_AUTHORITY auth
, BYTE cnt
,
351 DWORD sub1
, DWORD sub2
, DWORD sub3
, DWORD sub4
,
352 DWORD sub5
, DWORD sub6
, DWORD sub7
, DWORD sub8
)
354 char name
[256], dom
[256];
355 DWORD len
, len2
, rid
;
359 if (AllocateAndInitializeSid (auth
, cnt
, sub1
, sub2
, sub3
, sub4
,
360 sub5
, sub6
, sub7
, sub8
, &sid
))
362 if (LookupAccountSid (NULL
, sid
,
363 name
, (len
= 256, &len
),
364 dom
, (len2
= 256, &len
),
383 printf ("%s:*:%lu:%lu:%s%s::\n",
385 print_sids
? "," : "",
386 print_sids
? put_sid (sid
) : "");
395 fprintf (stderr
, "Usage: mkpasswd [OPTION]... [domain]\n\n");
396 fprintf (stderr
, "This program prints a /etc/passwd file to stdout\n\n");
397 fprintf (stderr
, "Options:\n");
398 fprintf (stderr
, " -l,--local print local user accounts\n");
399 fprintf (stderr
, " -d,--domain print domain accounts (from current domain\n");
400 fprintf (stderr
, " if no domain specified)\n");
401 fprintf (stderr
, " -o,--id-offset offset change the default offset (10000) added to uids\n");
402 fprintf (stderr
, " in domain accounts.\n");
403 fprintf (stderr
, " -g,--local-groups print local group information too\n");
404 fprintf (stderr
, " if no domain specified\n");
405 fprintf (stderr
, " -m,--no-mount don't use mount points for home dir\n");
406 fprintf (stderr
, " -s,--no-sids don't print SIDs in GCOS field\n");
407 fprintf (stderr
, " (this affects ntsec)\n");
408 fprintf (stderr
, " -p,--path-to-home path use specified path instead of user account home dir\n");
409 fprintf (stderr
, " -u,--username username only return information for the specified user\n");
410 fprintf (stderr
, " -?,--help displays this message\n\n");
411 fprintf (stderr
, "One of `-l', `-d' or `-g' must be given on NT/W2K.\n");
415 struct option longopts
[] = {
416 {"local", no_argument
, NULL
, 'l'},
417 {"domain", no_argument
, NULL
, 'd'},
418 {"id-offset", required_argument
, NULL
, 'o'},
419 {"local-groups", no_argument
, NULL
, 'g'},
420 {"no-mount", no_argument
, NULL
, 'm'},
421 {"no-sids", no_argument
, NULL
, 's'},
422 {"path-to-home", required_argument
, NULL
, 'p'},
423 {"username", required_argument
, NULL
, 'u'},
424 {"help", no_argument
, NULL
, 'h'},
425 {0, no_argument
, NULL
, 0}
428 char opts
[] = "ldo:gsmhp:u:";
431 main (int argc
, char **argv
)
433 LPWSTR servername
= NULL
;
434 DWORD rc
= ERROR_SUCCESS
;
435 WCHAR domain_name
[200];
437 int print_domain
= 0;
438 int print_local_groups
= 0;
439 int domain_name_specified
= 0;
441 int print_cygpath
= 1;
442 int id_offset
= 10000;
444 char *disp_username
= NULL
;
446 char name
[256], passed_home_path
[MAX_PATH
];
449 passed_home_path
[0] = '\0';
450 setmode (1, O_BINARY
);
452 if (GetVersion () < 0x80000000)
458 while ((i
= getopt_long (argc
, argv
, opts
, longopts
, NULL
)) != EOF
)
468 id_offset
= strtol (optarg
, NULL
, 10);
471 print_local_groups
= 1;
480 if (optarg
[0] != '/')
482 fprintf (stderr
, "%s: `%s' is not a fully qualified path.\n",
486 strcpy (passed_home_path
, optarg
);
487 if (optarg
[strlen (optarg
)-1] != '/')
488 strcat (passed_home_path
, "/");
491 disp_username
= optarg
;
496 fprintf (stderr
, "Try `%s --help' for more information.\n", argv
[0]);
499 if (!print_local
&& !print_domain
&& !print_local_groups
)
501 fprintf (stderr
, "%s: Specify one of `-l', `-d' or `-g'\n", argv
[0]);
508 fprintf (stderr
, "%s: A domain name is only accepted "
509 "when `-d' is given.\n", argv
[0]);
512 mbstowcs (domain_name
, argv
[optind
], (strlen (argv
[optind
]) + 1));
513 domain_name_specified
= 1;
518 /* This takes Windows 9x/ME into account. */
519 if (GetVersion () >= 0x80000000)
521 /* Same behaviour as in cygwin/uinfo.cc (internal_getlogin). */
522 if (!GetUserName (name
, (len
= 256, &len
)))
523 strcpy (name
, "unknown");
525 printf ("%s::%ld:%ld::%s%s:/bin/bash\n", name
,
526 DOMAIN_USER_RID_ADMIN
,
527 DOMAIN_ALIAS_RID_ADMINS
,
536 fprintf (stderr
, "Failed loading symbols from netapi32.dll "
537 "with error %lu\n", GetLastError ());
542 * Get `Everyone' group
544 if (disp_username
== NULL
)
546 print_special (print_sids
, &sid_world_auth
, 1, SECURITY_WORLD_RID
,
547 0, 0, 0, 0, 0, 0, 0);
551 print_special (print_sids
, &sid_nt_auth
, 1, SECURITY_LOCAL_SYSTEM_RID
,
552 0, 0, 0, 0, 0, 0, 0);
554 * Get `administrators' group
556 if (!print_local_groups
)
557 print_special (print_sids
, &sid_nt_auth
, 2, SECURITY_BUILTIN_DOMAIN_RID
,
558 DOMAIN_ALIAS_RID_ADMINS
, 0, 0, 0, 0, 0, 0);
560 if (print_local_groups
)
561 enum_local_groups (print_sids
);
566 if (domain_name_specified
)
567 rc
= netgetdcname (NULL
, domain_name
, (LPBYTE
*) & servername
);
570 rc
= netgetdcname (NULL
, NULL
, (LPBYTE
*) & servername
);
572 if (rc
!= ERROR_SUCCESS
)
574 fprintf (stderr
, "Cannot get DC, code = %ld\n", rc
);
578 enum_users (servername
, print_sids
, print_cygpath
, passed_home_path
,
579 id_offset
, disp_username
);
583 enum_users (NULL
, print_sids
, print_cygpath
, passed_home_path
, 0,
587 netapibufferfree (servername
);