3 Copyright 1997, 1998, 1999, 2000 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>
20 #include <sys/fcntl.h>
22 SID_IDENTIFIER_AUTHORITY sid_world_auth
= {SECURITY_WORLD_SID_AUTHORITY
};
23 SID_IDENTIFIER_AUTHORITY sid_nt_auth
= {SECURITY_NT_AUTHORITY
};
25 NET_API_STATUS
WINAPI (*netapibufferfree
)(PVOID
);
26 NET_API_STATUS
WINAPI (*netuserenum
)(LPWSTR
,DWORD
,DWORD
,PBYTE
*,DWORD
,PDWORD
,PDWORD
,PDWORD
);
27 NET_API_STATUS
WINAPI (*netlocalgroupenum
)(LPWSTR
,DWORD
,PBYTE
*,DWORD
,PDWORD
,PDWORD
,PDWORD
);
28 NET_API_STATUS
WINAPI (*netgetdcname
)(LPWSTR
,LPWSTR
,PBYTE
*);
31 #define min(a,b) (((a)<(b))?(a):(b))
37 HANDLE h
= LoadLibrary ("netapi32.dll");
42 if (!(netapibufferfree
= GetProcAddress (h
, "NetApiBufferFree")))
44 if (!(netuserenum
= GetProcAddress (h
, "NetUserEnum")))
46 if (!(netlocalgroupenum
= GetProcAddress (h
, "NetLocalGroupEnum")))
48 if (!(netgetdcname
= GetProcAddress (h
, "NetGetDCName")))
62 sprintf(t
, "%u", GetSidIdentifierAuthority (sid
)->Value
[5]);
64 for (i
= 0; i
< *GetSidSubAuthorityCount (sid
); ++i
)
66 sprintf(t
, "-%lu", *GetSidSubAuthority (sid
, i
));
73 psx_dir (char *in
, char *out
)
75 if (isalpha (in
[0]) && in
[1] == ':')
77 sprintf (out
, "/cygdrive/%c", in
[0]);
96 uni2ansi (LPWSTR wcs
, char *mbs
, int size
)
99 WideCharToMultiByte (CP_ACP
, 0, wcs
, -1, mbs
, size
, NULL
, NULL
);
105 enum_users (LPWSTR servername
, int print_sids
, int print_cygpath
,
106 const char * passed_home_path
, int id_offset
)
109 DWORD entriesread
= 0;
110 DWORD totalentries
= 0;
111 DWORD resume_handle
= 0;
113 char ansi_srvname
[256];
116 uni2ansi (servername
, ansi_srvname
, sizeof (ansi_srvname
));
122 rc
= netuserenum (servername
, 3, FILTER_NORMAL_ACCOUNT
,
123 (LPBYTE
*) & buffer
, 1024,
124 &entriesread
, &totalentries
, &resume_handle
);
127 case ERROR_ACCESS_DENIED
:
128 fprintf (stderr
, "Access denied\n");
131 case ERROR_MORE_DATA
:
136 fprintf (stderr
, "NetUserEnum() failed with %ld\n", rc
);
140 for (i
= 0; i
< entriesread
; i
++)
144 char homedir_psx
[MAX_PATH
];
145 char homedir_w32
[MAX_PATH
];
146 char domain_name
[100];
147 DWORD domname_len
= 100;
148 char psid_buffer
[1024];
149 PSID psid
= (PSID
) psid_buffer
;
150 DWORD sid_length
= 1024;
151 SID_NAME_USE acc_type
;
153 int uid
= buffer
[i
].usri3_user_id
;
154 int gid
= buffer
[i
].usri3_primary_group_id
;
155 uni2ansi (buffer
[i
].usri3_name
, username
, sizeof (username
));
156 uni2ansi (buffer
[i
].usri3_full_name
, fullname
, sizeof (fullname
));
157 homedir_w32
[0] = homedir_psx
[0] = '\0';
158 uni2ansi (buffer
[i
].usri3_home_dir
, homedir_w32
, sizeof (homedir_w32
));
160 cygwin_conv_to_posix_path (homedir_w32
, homedir_psx
);
162 psx_dir (homedir_w32
, homedir_psx
);
164 if (homedir_psx
[0] == '\0')
166 strcat (homedir_psx
, passed_home_path
);
167 strcat (homedir_psx
, username
);
172 if (!LookupAccountName (servername
? ansi_srvname
: NULL
,
175 domain_name
, &domname_len
,
179 "LookupAccountName(%s,%s) failed with error %ld\n",
180 servername
? ansi_srvname
: "NULL",
185 else if (acc_type
== SidTypeDomain
)
189 strcpy (domname
, domain_name
);
190 strcat (domname
, "\\");
191 strcat (domname
, username
);
194 if (!LookupAccountName (servername
? ansi_srvname
: NULL
,
197 domain_name
, &domname_len
,
201 "LookupAccountName(%s,%s) failed with error %ld\n",
202 servername
? ansi_srvname
: "NULL",
209 printf ("%s:unused_by_nt/2000/xp:%d:%d:%s%s%s:%s:/bin/bash\n", username
,
213 print_sids
? "," : "",
214 print_sids
? put_sid (psid
) : "",
218 netapibufferfree (buffer
);
221 while (rc
== ERROR_MORE_DATA
);
224 netapibufferfree (servername
);
230 enum_local_groups (int print_sids
)
232 LOCALGROUP_INFO_0
*buffer
;
233 DWORD entriesread
= 0;
234 DWORD totalentries
= 0;
235 DWORD resume_handle
= 0;
242 rc
= netlocalgroupenum (NULL
, 0, (LPBYTE
*) & buffer
, 1024,
243 &entriesread
, &totalentries
, &resume_handle
);
246 case ERROR_ACCESS_DENIED
:
247 fprintf (stderr
, "Access denied\n");
250 case ERROR_MORE_DATA
:
255 fprintf (stderr
, "NetLocalGroupEnum() failed with %ld\n", rc
);
259 for (i
= 0; i
< entriesread
; i
++)
261 char localgroup_name
[100];
262 char domain_name
[100];
263 DWORD domname_len
= 100;
264 char psid_buffer
[1024];
265 PSID psid
= (PSID
) psid_buffer
;
266 DWORD sid_length
= 1024;
268 SID_NAME_USE acc_type
;
269 uni2ansi (buffer
[i
].lgrpi0_name
, localgroup_name
, sizeof (localgroup_name
));
271 if (!LookupAccountName (NULL
, localgroup_name
, psid
,
272 &sid_length
, domain_name
, &domname_len
,
275 fprintf (stderr
, "LookupAccountName(%s) failed with %ld\n",
276 localgroup_name
, GetLastError ());
279 else if (acc_type
== SidTypeDomain
)
283 strcpy (domname
, domain_name
);
284 strcat (domname
, "\\");
285 strcat (domname
, localgroup_name
);
288 if (!LookupAccountName (NULL
, domname
,
290 domain_name
, &domname_len
,
294 "LookupAccountName(%s) failed with error %ld\n",
295 localgroup_name
, GetLastError ());
300 gid
= *GetSidSubAuthority (psid
, *GetSidSubAuthorityCount(psid
) - 1);
302 printf ("%s:*:%ld:%ld:%s%s::\n", localgroup_name
, gid
, gid
,
303 print_sids
? "," : "",
304 print_sids
? put_sid (psid
) : "");
307 netapibufferfree (buffer
);
310 while (rc
== ERROR_MORE_DATA
);
318 fprintf (stderr
, "Usage: mkpasswd [OPTION]... [domain]\n\n");
319 fprintf (stderr
, "This program prints a /etc/passwd file to stdout\n\n");
320 fprintf (stderr
, "Options:\n");
321 fprintf (stderr
, " -l,--local print local user accounts\n");
322 fprintf (stderr
, " -d,--domain print domain accounts (from current domain\n");
323 fprintf (stderr
, " if no domain specified)\n");
324 fprintf (stderr
, " -o,--id-offset offset change the default offset (10000) added to uids\n");
325 fprintf (stderr
, " in domain accounts.\n");
326 fprintf (stderr
, " -g,--local-groups print local group information too\n");
327 fprintf (stderr
, " if no domain specified\n");
328 fprintf (stderr
, " -m,--no-mount don't use mount points for home dir\n");
329 fprintf (stderr
, " -s,--no-sids don't print SIDs in GCOS field\n");
330 fprintf (stderr
, " (this affects ntsec)\n");
331 fprintf (stderr
, " -p,--path-to-home path if user account has no home dir, use\n");
332 fprintf (stderr
, " path instead of /home/\n");
333 fprintf (stderr
, " -?,--help displays this message\n\n");
334 fprintf (stderr
, "One of `-l', `-d' or `-g' must be given on NT/W2K.\n");
338 struct option longopts
[] = {
339 {"local", no_argument
, NULL
, 'l'},
340 {"domain", no_argument
, NULL
, 'd'},
341 {"id-offset", required_argument
, NULL
, 'o'},
342 {"local-groups", no_argument
, NULL
, 'g'},
343 {"no-mount", no_argument
, NULL
, 'm'},
344 {"no-sids", no_argument
, NULL
, 's'},
345 {"path-to-home",required_argument
, NULL
, 'p'},
346 {"help", no_argument
, NULL
, 'h'},
347 {0, no_argument
, NULL
, 0}
350 char opts
[] = "ldo:gsmhp:";
353 main (int argc
, char **argv
)
355 LPWSTR servername
= NULL
;
356 DWORD rc
= ERROR_SUCCESS
;
357 WCHAR domain_name
[200];
359 int print_domain
= 0;
360 int print_local_groups
= 0;
361 int domain_name_specified
= 0;
363 int print_cygpath
= 1;
364 int id_offset
= 10000;
367 char name
[256], dom
[256], passed_home_path
[MAX_PATH
];
372 passed_home_path
[0] = '\0';
373 setmode (1, O_BINARY
);
375 if (GetVersion () < 0x80000000)
380 while ((i
= getopt_long (argc
, argv
, opts
, longopts
, NULL
)) != EOF
)
390 id_offset
= strtol (optarg
, NULL
, 10);
393 print_local_groups
= 1;
402 if (optarg
[0] != '/')
404 fprintf (stderr
, "%s: `%s' is not a fully qualified path.\n",
408 strcpy (passed_home_path
, optarg
);
409 if (optarg
[strlen (optarg
)-1] != '/')
410 strcat (passed_home_path
, "/");
415 fprintf (stderr
, "Try `%s --help' for more information.\n", argv
[0]);
418 if (!print_local
&& !print_domain
&& !print_local_groups
)
420 fprintf (stderr
, "%s: Specify one of `-l', `-d' or `-g'\n", argv
[0]);
427 fprintf (stderr
, "%s: A domain name is only accepted "
428 "when `-d' is given.\n", argv
[0]);
431 mbstowcs (domain_name
, argv
[optind
], (strlen (argv
[optind
]) + 1));
432 domain_name_specified
= 1;
436 if (passed_home_path
[0] == '\0')
437 strcpy (passed_home_path
, "/home/");
439 /* This takes Windows 9x/ME into account. */
440 if (GetVersion () >= 0x80000000)
442 /* Same behaviour as in cygwin/uinfo.cc (internal_getlogin). */
443 if (!GetUserName (name
, (len
= 256, &len
)))
444 strcpy (name
, "unknown");
446 printf ("%s::%ld:%ld::%s%s:/bin/bash\n", name
,
447 DOMAIN_USER_RID_ADMIN
,
448 DOMAIN_ALIAS_RID_ADMINS
,
457 fprintf (stderr
, "Failed loading symbols from netapi32.dll "
458 "with error %lu\n", GetLastError ());
463 * Get `Everyone' group
465 if (AllocateAndInitializeSid (&sid_world_auth
, 1, SECURITY_WORLD_RID
,
466 0, 0, 0, 0, 0, 0, 0, &sid
))
468 if (LookupAccountSid (NULL
, sid
,
469 name
, (len
= 256, &len
),
470 dom
, (len2
= 256, &len
),
472 printf ("%s:*:%d:%d:%s%s::\n", name
,
475 print_sids
? "," : "",
476 print_sids
? put_sid (sid
) : "");
483 if (AllocateAndInitializeSid (&sid_nt_auth
, 1, SECURITY_LOCAL_SYSTEM_RID
,
484 0, 0, 0, 0, 0, 0, 0, &sid
))
486 if (LookupAccountSid (NULL
, sid
,
487 name
, (len
= 256, &len
),
488 dom
, (len2
= 256, &len
),
490 printf ("%s:*:%d:%d:%s%s::\n", name
,
491 SECURITY_LOCAL_SYSTEM_RID
,
492 SECURITY_LOCAL_SYSTEM_RID
,
493 print_sids
? "," : "",
494 print_sids
? put_sid (sid
) : "");
499 * Get `administrators' group
501 if (!print_local_groups
502 && AllocateAndInitializeSid (&sid_nt_auth
, 2,
503 SECURITY_BUILTIN_DOMAIN_RID
,
504 DOMAIN_ALIAS_RID_ADMINS
,
505 0, 0, 0, 0, 0, 0, &sid
))
507 if (LookupAccountSid (NULL
, sid
,
508 name
, (len
= 256, &len
),
509 dom
, (len2
= 256, &len
),
511 printf ("%s:*:%ld:%ld:%s%s::\n", name
,
512 DOMAIN_ALIAS_RID_ADMINS
,
513 DOMAIN_ALIAS_RID_ADMINS
,
514 print_sids
? "," : "",
515 print_sids
? put_sid (sid
) : "");
519 if (print_local_groups
)
520 enum_local_groups (print_sids
);
524 if (domain_name_specified
)
525 rc
= netgetdcname (NULL
, domain_name
, (LPBYTE
*) & servername
);
528 rc
= netgetdcname (NULL
, NULL
, (LPBYTE
*) & servername
);
530 if (rc
!= ERROR_SUCCESS
)
532 fprintf (stderr
, "Cannot get DC, code = %ld\n", rc
);
536 enum_users (servername
, print_sids
, print_cygpath
, passed_home_path
, id_offset
);
540 enum_users (NULL
, print_sids
, print_cygpath
, passed_home_path
, 0);
543 netapibufferfree (servername
);