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>
21 SID_IDENTIFIER_AUTHORITY sid_world_auth
= {SECURITY_WORLD_SID_AUTHORITY
};
22 SID_IDENTIFIER_AUTHORITY sid_nt_auth
= {SECURITY_NT_AUTHORITY
};
24 NET_API_STATUS
WINAPI (*netapibufferfree
)(PVOID
);
25 NET_API_STATUS
WINAPI (*netuserenum
)(LPWSTR
,DWORD
,DWORD
,PBYTE
*,DWORD
,PDWORD
,PDWORD
,PDWORD
);
26 NET_API_STATUS
WINAPI (*netlocalgroupenum
)(LPWSTR
,DWORD
,PBYTE
*,DWORD
,PDWORD
,PDWORD
,PDWORD
);
27 NET_API_STATUS
WINAPI (*netgetdcname
)(LPWSTR
,LPWSTR
,PBYTE
*);
30 #define min(a,b) (((a)<(b))?(a):(b))
36 HANDLE h
= LoadLibrary ("netapi32.dll");
41 if (!(netapibufferfree
= GetProcAddress (h
, "NetApiBufferFree")))
43 if (!(netuserenum
= GetProcAddress (h
, "NetUserEnum")))
45 if (!(netlocalgroupenum
= GetProcAddress (h
, "NetLocalGroupEnum")))
47 if (!(netgetdcname
= GetProcAddress (h
, "NetGetDCName")))
61 sprintf(t
, "%u", GetSidIdentifierAuthority (sid
)->Value
[5]);
63 for (i
= 0; i
< *GetSidSubAuthorityCount (sid
); ++i
)
65 sprintf(t
, "-%lu", *GetSidSubAuthority (sid
, i
));
72 psx_dir (char *in
, char *out
)
74 if (isalpha (in
[0]) && in
[1] == ':')
76 sprintf (out
, "/cygdrive/%c", in
[0]);
95 uni2ansi (LPWSTR wcs
, char *mbs
)
98 wcstombs (mbs
, wcs
, (wcslen (wcs
) + 1) * sizeof (WCHAR
));
105 enum_users (LPWSTR servername
, int print_sids
, int print_cygpath
,
106 const char * passed_home_path
)
109 DWORD entriesread
= 0;
110 DWORD totalentries
= 0;
111 DWORD resume_handle
= 0;
113 char ansi_srvname
[256];
116 uni2ansi (servername
, 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
);
156 uni2ansi (buffer
[i
].usri3_full_name
, fullname
);
157 homedir_w32
[0] = homedir_psx
[0] = '\0';
158 uni2ansi (buffer
[i
].usri3_home_dir
, 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::%d:%d:%s%s%s:%s:/bin/sh\n", username
, uid
, gid
,
211 print_sids
? "," : "",
212 print_sids
? put_sid (psid
) : "",
216 netapibufferfree (buffer
);
219 while (rc
== ERROR_MORE_DATA
);
222 netapibufferfree (servername
);
228 enum_local_groups (int print_sids
)
230 LOCALGROUP_INFO_0
*buffer
;
231 DWORD entriesread
= 0;
232 DWORD totalentries
= 0;
233 DWORD resume_handle
= 0;
240 rc
= netlocalgroupenum (NULL
, 0, (LPBYTE
*) & buffer
, 1024,
241 &entriesread
, &totalentries
, &resume_handle
);
244 case ERROR_ACCESS_DENIED
:
245 fprintf (stderr
, "Access denied\n");
248 case ERROR_MORE_DATA
:
253 fprintf (stderr
, "NetLocalGroupEnum() failed with %ld\n", rc
);
257 for (i
= 0; i
< entriesread
; i
++)
259 char localgroup_name
[100];
260 char domain_name
[100];
261 DWORD domname_len
= 100;
262 char psid_buffer
[1024];
263 PSID psid
= (PSID
) psid_buffer
;
264 DWORD sid_length
= 1024;
266 SID_NAME_USE acc_type
;
267 uni2ansi (buffer
[i
].lgrpi0_name
, localgroup_name
);
269 if (!LookupAccountName (NULL
, localgroup_name
, psid
,
270 &sid_length
, domain_name
, &domname_len
,
273 fprintf (stderr
, "LookupAccountName(%s) failed with %ld\n",
274 localgroup_name
, GetLastError ());
277 else if (acc_type
== SidTypeDomain
)
281 strcpy (domname
, domain_name
);
282 strcat (domname
, "\\");
283 strcat (domname
, localgroup_name
);
286 if (!LookupAccountName (NULL
, domname
,
288 domain_name
, &domname_len
,
292 "LookupAccountName(%s) failed with error %ld\n",
293 localgroup_name
, GetLastError ());
298 gid
= *GetSidSubAuthority (psid
, *GetSidSubAuthorityCount(psid
) - 1);
300 printf ("%s:*:%ld:%ld:%s%s::\n", localgroup_name
, gid
, gid
,
301 print_sids
? "," : "",
302 print_sids
? put_sid (psid
) : "");
305 netapibufferfree (buffer
);
308 while (rc
== ERROR_MORE_DATA
);
316 fprintf (stderr
, "Usage: mkpasswd [OPTION]... [domain]\n\n");
317 fprintf (stderr
, "This program prints a /etc/passwd file to stdout\n\n");
318 fprintf (stderr
, "Options:\n");
319 fprintf (stderr
, " -l,--local print local user accounts\n");
320 fprintf (stderr
, " -d,--domain print domain accounts (from current domain\n");
321 fprintf (stderr
, " if no domain specified)\n");
322 fprintf (stderr
, " -g,--local-groups print local group information too\n");
323 fprintf (stderr
, " if no domain specified\n");
324 fprintf (stderr
, " -m,--no-mount don't use mount points for home dir\n");
325 fprintf (stderr
, " -s,--no-sids don't print SIDs in GCOS field\n");
326 fprintf (stderr
, " (this affects ntsec)\n");
327 fprintf (stderr
, " -p,--path-to-home path if user account has no home dir, use\n");
328 fprintf (stderr
, " path instead of /home/\n");
329 fprintf (stderr
, " -?,--help displays this message\n\n");
330 fprintf (stderr
, "One of `-l', `-d' or `-g' must be given on NT/W2K.\n");
334 struct option longopts
[] = {
335 {"local", no_argument
, NULL
, 'l'},
336 {"domain", no_argument
, NULL
, 'd'},
337 {"local-groups", no_argument
, NULL
, 'g'},
338 {"no-mount", no_argument
, NULL
, 'm'},
339 {"no-sids", no_argument
, NULL
, 's'},
340 {"path-to-home",required_argument
, NULL
, 'p'},
341 {"help", no_argument
, NULL
, 'h'},
342 {0, no_argument
, NULL
, 0}
345 char opts
[] = "ldgsmhp:";
348 main (int argc
, char **argv
)
350 LPWSTR servername
= NULL
;
351 DWORD rc
= ERROR_SUCCESS
;
352 WCHAR domain_name
[200];
354 int print_domain
= 0;
355 int print_local_groups
= 0;
356 int domain_name_specified
= 0;
358 int print_cygpath
= 1;
361 char name
[256], dom
[256], passed_home_path
[MAX_PATH
];
366 passed_home_path
[0] = '\0';
368 if (GetVersion () < 0x80000000)
373 while ((i
= getopt_long (argc
, argv
, opts
, longopts
, NULL
)) != EOF
)
383 print_local_groups
= 1;
392 if (optarg
[0] != '/')
394 fprintf (stderr
, "%s: `%s' is not a fully qualified path.\n",
398 strcpy (passed_home_path
, optarg
);
399 if (optarg
[strlen (optarg
)-1] != '/')
400 strcat (passed_home_path
, "/");
405 fprintf (stderr
, "Try `%s --help' for more information.\n", argv
[0]);
408 if (!print_local
&& !print_domain
&& !print_local_groups
)
410 fprintf (stderr
, "%s: Specify one of `-l', `-d' or `-g'\n", argv
[0]);
417 fprintf (stderr
, "%s: A domain name is only accepted "
418 "when `-d' is given.\n", argv
[0]);
421 mbstowcs (domain_name
, argv
[optind
], (strlen (argv
[optind
]) + 1));
422 domain_name_specified
= 1;
426 if (passed_home_path
[0] == '\0')
427 strcpy (passed_home_path
, "/home/");
429 /* This takes Windows 9x/ME into account. */
430 if (GetVersion () >= 0x80000000)
432 /* Same behaviour as in cygwin/uinfo.cc (internal_getlogin). */
433 if (!GetUserName (name
, (len
= 256, &len
)))
434 strcpy (name
, "unknown");
436 printf ("%s::%ld:%ld::%s%s:/bin/sh\n", name
,
437 DOMAIN_USER_RID_ADMIN
,
438 DOMAIN_ALIAS_RID_ADMINS
,
447 fprintf (stderr
, "Failed loading symbols from netapi32.dll "
448 "with error %lu\n", GetLastError ());
453 * Get `Everyone' group
455 if (AllocateAndInitializeSid (&sid_world_auth
, 1, SECURITY_WORLD_RID
,
456 0, 0, 0, 0, 0, 0, 0, &sid
))
458 if (LookupAccountSid (NULL
, sid
,
459 name
, (len
= 256, &len
),
460 dom
, (len2
= 256, &len
),
462 printf ("%s:*:%d:%d:%s%s::\n", name
,
465 print_sids
? "," : "",
466 print_sids
? put_sid (sid
) : "");
473 if (AllocateAndInitializeSid (&sid_nt_auth
, 1, SECURITY_LOCAL_SYSTEM_RID
,
474 0, 0, 0, 0, 0, 0, 0, &sid
))
476 if (LookupAccountSid (NULL
, sid
,
477 name
, (len
= 256, &len
),
478 dom
, (len2
= 256, &len
),
480 printf ("%s:*:%d:%d:%s%s::\n", name
,
481 SECURITY_LOCAL_SYSTEM_RID
,
482 SECURITY_LOCAL_SYSTEM_RID
,
483 print_sids
? "," : "",
484 print_sids
? put_sid (sid
) : "");
489 * Get `administrators' group
491 if (!print_local_groups
492 && AllocateAndInitializeSid (&sid_nt_auth
, 2,
493 SECURITY_BUILTIN_DOMAIN_RID
,
494 DOMAIN_ALIAS_RID_ADMINS
,
495 0, 0, 0, 0, 0, 0, &sid
))
497 if (LookupAccountSid (NULL
, sid
,
498 name
, (len
= 256, &len
),
499 dom
, (len2
= 256, &len
),
501 printf ("%s:*:%ld:%ld:%s%s::\n", name
,
502 DOMAIN_ALIAS_RID_ADMINS
,
503 DOMAIN_ALIAS_RID_ADMINS
,
504 print_sids
? "," : "",
505 print_sids
? put_sid (sid
) : "");
509 if (print_local_groups
)
510 enum_local_groups (print_sids
);
514 if (domain_name_specified
)
515 rc
= netgetdcname (NULL
, domain_name
, (LPBYTE
*) & servername
);
518 rc
= netgetdcname (NULL
, NULL
, (LPBYTE
*) & servername
);
520 if (rc
!= ERROR_SUCCESS
)
522 fprintf (stderr
, "Cannot get DC, code = %ld\n", rc
);
526 enum_users (servername
, print_sids
, print_cygpath
, passed_home_path
);
530 enum_users (NULL
, print_sids
, print_cygpath
, passed_home_path
);
533 netapibufferfree (servername
);