3 Copyright 1997, 1998, 1999, 2000 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>
23 SID_IDENTIFIER_AUTHORITY sid_world_auth
= {SECURITY_WORLD_SID_AUTHORITY
};
24 SID_IDENTIFIER_AUTHORITY sid_nt_auth
= {SECURITY_NT_AUTHORITY
};
26 NET_API_STATUS
WINAPI (*netapibufferfree
)(PVOID
);
27 NET_API_STATUS
WINAPI (*netuserenum
)(LPWSTR
,DWORD
,DWORD
,PBYTE
*,DWORD
,PDWORD
,PDWORD
,PDWORD
);
28 NET_API_STATUS
WINAPI (*netlocalgroupenum
)(LPWSTR
,DWORD
,PBYTE
*,DWORD
,PDWORD
,PDWORD
,PDWORD
);
29 NET_API_STATUS
WINAPI (*netgetdcname
)(LPWSTR
,LPWSTR
,PBYTE
*);
32 #define min(a,b) (((a)<(b))?(a):(b))
38 HANDLE h
= LoadLibrary ("netapi32.dll");
43 if (!(netapibufferfree
= (void *) GetProcAddress (h
, "NetApiBufferFree")))
45 if (!(netuserenum
= (void *) GetProcAddress (h
, "NetUserEnum")))
47 if (!(netlocalgroupenum
= (void *) GetProcAddress (h
, "NetLocalGroupEnum")))
49 if (!(netgetdcname
= (void *) GetProcAddress (h
, "NetGetDCName")))
63 sprintf(t
, "%u", GetSidIdentifierAuthority (sid
)->Value
[5]);
65 for (i
= 0; i
< *GetSidSubAuthorityCount (sid
); ++i
)
67 sprintf(t
, "-%lu", *GetSidSubAuthority (sid
, i
));
74 psx_dir (char *in
, char *out
)
76 if (isalpha (in
[0]) && in
[1] == ':')
78 sprintf (out
, "/cygdrive/%c", in
[0]);
97 uni2ansi (LPWSTR wcs
, char *mbs
, int size
)
100 WideCharToMultiByte (CP_ACP
, 0, wcs
, -1, mbs
, size
, NULL
, NULL
);
106 enum_users (LPWSTR servername
, int print_sids
, int print_cygpath
,
107 const char * passed_home_path
, int id_offset
)
110 DWORD entriesread
= 0;
111 DWORD totalentries
= 0;
112 DWORD resume_handle
= 0;
114 char ansi_srvname
[256];
117 uni2ansi (servername
, ansi_srvname
, sizeof (ansi_srvname
));
123 rc
= netuserenum (servername
, 3, FILTER_NORMAL_ACCOUNT
,
124 (LPBYTE
*) & buffer
, 1024,
125 &entriesread
, &totalentries
, &resume_handle
);
128 case ERROR_ACCESS_DENIED
:
129 fprintf (stderr
, "Access denied\n");
132 case ERROR_MORE_DATA
:
137 fprintf (stderr
, "NetUserEnum() failed with %ld\n", rc
);
141 for (i
= 0; i
< entriesread
; i
++)
145 char homedir_psx
[MAX_PATH
];
146 char homedir_w32
[MAX_PATH
];
147 char domain_name
[100];
148 DWORD domname_len
= 100;
149 char psid_buffer
[1024];
150 PSID psid
= (PSID
) psid_buffer
;
151 DWORD sid_length
= 1024;
152 SID_NAME_USE acc_type
;
154 int uid
= buffer
[i
].usri3_user_id
;
155 int gid
= buffer
[i
].usri3_primary_group_id
;
156 uni2ansi (buffer
[i
].usri3_name
, username
, sizeof (username
));
157 uni2ansi (buffer
[i
].usri3_full_name
, fullname
, sizeof (fullname
));
158 homedir_w32
[0] = homedir_psx
[0] = '\0';
159 uni2ansi (buffer
[i
].usri3_home_dir
, homedir_w32
, sizeof (homedir_w32
));
161 cygwin_conv_to_posix_path (homedir_w32
, homedir_psx
);
163 psx_dir (homedir_w32
, homedir_psx
);
165 if (homedir_psx
[0] == '\0')
167 strcat (homedir_psx
, passed_home_path
);
168 strcat (homedir_psx
, username
);
173 if (!LookupAccountName (servername
? ansi_srvname
: NULL
,
176 domain_name
, &domname_len
,
180 "LookupAccountName(%s,%s) failed with error %ld\n",
181 servername
? ansi_srvname
: "NULL",
186 else if (acc_type
== SidTypeDomain
)
190 strcpy (domname
, domain_name
);
191 strcat (domname
, "\\");
192 strcat (domname
, username
);
195 if (!LookupAccountName (servername
? ansi_srvname
: NULL
,
198 domain_name
, &domname_len
,
202 "LookupAccountName(%s,%s) failed with error %ld\n",
203 servername
? ansi_srvname
: "NULL",
210 printf ("%s:unused_by_nt/2000/xp:%d:%d:%s%s%s%s%s%s%s%s:%s:/bin/bash\n",
215 print_sids
&& fullname
[0] ? "," : "",
216 print_sids
? "U-" : "",
217 print_sids
? domain_name
: "",
218 print_sids
&& domain_name
[0] ? "\\" : "",
219 print_sids
? username
: "",
220 print_sids
? "," : "",
221 print_sids
? put_sid (psid
) : "",
225 netapibufferfree (buffer
);
228 while (rc
== ERROR_MORE_DATA
);
231 netapibufferfree (servername
);
237 enum_local_groups (int print_sids
)
239 LOCALGROUP_INFO_0
*buffer
;
240 DWORD entriesread
= 0;
241 DWORD totalentries
= 0;
242 DWORD resume_handle
= 0;
249 rc
= netlocalgroupenum (NULL
, 0, (LPBYTE
*) & buffer
, 1024,
250 &entriesread
, &totalentries
, &resume_handle
);
253 case ERROR_ACCESS_DENIED
:
254 fprintf (stderr
, "Access denied\n");
257 case ERROR_MORE_DATA
:
262 fprintf (stderr
, "NetLocalGroupEnum() failed with %ld\n", rc
);
266 for (i
= 0; i
< entriesread
; i
++)
268 char localgroup_name
[100];
269 char domain_name
[100];
270 DWORD domname_len
= 100;
271 char psid_buffer
[1024];
272 PSID psid
= (PSID
) psid_buffer
;
273 DWORD sid_length
= 1024;
275 SID_NAME_USE acc_type
;
276 uni2ansi (buffer
[i
].lgrpi0_name
, localgroup_name
, sizeof (localgroup_name
));
278 if (!LookupAccountName (NULL
, localgroup_name
, psid
,
279 &sid_length
, domain_name
, &domname_len
,
282 fprintf (stderr
, "LookupAccountName(%s) failed with %ld\n",
283 localgroup_name
, GetLastError ());
286 else if (acc_type
== SidTypeDomain
)
290 strcpy (domname
, domain_name
);
291 strcat (domname
, "\\");
292 strcat (domname
, localgroup_name
);
295 if (!LookupAccountName (NULL
, domname
,
297 domain_name
, &domname_len
,
301 "LookupAccountName(%s) failed with error %ld\n",
302 localgroup_name
, GetLastError ());
307 gid
= *GetSidSubAuthority (psid
, *GetSidSubAuthorityCount(psid
) - 1);
309 printf ("%s:*:%ld:%ld:%s%s::\n", localgroup_name
, gid
, gid
,
310 print_sids
? "," : "",
311 print_sids
? put_sid (psid
) : "");
314 netapibufferfree (buffer
);
317 while (rc
== ERROR_MORE_DATA
);
323 print_special (int print_sids
,
324 PSID_IDENTIFIER_AUTHORITY auth
, BYTE cnt
,
325 DWORD sub1
, DWORD sub2
, DWORD sub3
, DWORD sub4
,
326 DWORD sub5
, DWORD sub6
, DWORD sub7
, DWORD sub8
)
328 char name
[256], dom
[256];
329 DWORD len
, len2
, rid
;
333 if (AllocateAndInitializeSid (auth
, cnt
, sub1
, sub2
, sub3
, sub4
,
334 sub5
, sub6
, sub7
, sub8
, &sid
))
336 if (LookupAccountSid (NULL
, sid
,
337 name
, (len
= 256, &len
),
338 dom
, (len2
= 256, &len
),
357 printf ("%s:*:%lu:%lu:%s%s::\n",
359 print_sids
? "," : "",
360 print_sids
? put_sid (sid
) : "");
369 fprintf (stderr
, "Usage: mkpasswd [OPTION]... [domain]\n\n");
370 fprintf (stderr
, "This program prints a /etc/passwd file to stdout\n\n");
371 fprintf (stderr
, "Options:\n");
372 fprintf (stderr
, " -l,--local print local user accounts\n");
373 fprintf (stderr
, " -d,--domain print domain accounts (from current domain\n");
374 fprintf (stderr
, " if no domain specified)\n");
375 fprintf (stderr
, " -o,--id-offset offset change the default offset (10000) added to uids\n");
376 fprintf (stderr
, " in domain accounts.\n");
377 fprintf (stderr
, " -g,--local-groups print local group information too\n");
378 fprintf (stderr
, " if no domain specified\n");
379 fprintf (stderr
, " -m,--no-mount don't use mount points for home dir\n");
380 fprintf (stderr
, " -s,--no-sids don't print SIDs in GCOS field\n");
381 fprintf (stderr
, " (this affects ntsec)\n");
382 fprintf (stderr
, " -p,--path-to-home path if user account has no home dir, use\n");
383 fprintf (stderr
, " path instead of /home/\n");
384 fprintf (stderr
, " -?,--help displays this message\n\n");
385 fprintf (stderr
, "One of `-l', `-d' or `-g' must be given on NT/W2K.\n");
389 struct option longopts
[] = {
390 {"local", no_argument
, NULL
, 'l'},
391 {"domain", no_argument
, NULL
, 'd'},
392 {"id-offset", required_argument
, NULL
, 'o'},
393 {"local-groups", no_argument
, NULL
, 'g'},
394 {"no-mount", no_argument
, NULL
, 'm'},
395 {"no-sids", no_argument
, NULL
, 's'},
396 {"path-to-home",required_argument
, NULL
, 'p'},
397 {"help", no_argument
, NULL
, 'h'},
398 {0, no_argument
, NULL
, 0}
401 char opts
[] = "ldo:gsmhp:";
404 main (int argc
, char **argv
)
406 LPWSTR servername
= NULL
;
407 DWORD rc
= ERROR_SUCCESS
;
408 WCHAR domain_name
[200];
410 int print_domain
= 0;
411 int print_local_groups
= 0;
412 int domain_name_specified
= 0;
414 int print_cygpath
= 1;
415 int id_offset
= 10000;
418 char name
[256], passed_home_path
[MAX_PATH
];
421 passed_home_path
[0] = '\0';
422 setmode (1, O_BINARY
);
424 if (GetVersion () < 0x80000000)
430 while ((i
= getopt_long (argc
, argv
, opts
, longopts
, NULL
)) != EOF
)
440 id_offset
= strtol (optarg
, NULL
, 10);
443 print_local_groups
= 1;
452 if (optarg
[0] != '/')
454 fprintf (stderr
, "%s: `%s' is not a fully qualified path.\n",
458 strcpy (passed_home_path
, optarg
);
459 if (optarg
[strlen (optarg
)-1] != '/')
460 strcat (passed_home_path
, "/");
465 fprintf (stderr
, "Try `%s --help' for more information.\n", argv
[0]);
468 if (!print_local
&& !print_domain
&& !print_local_groups
)
470 fprintf (stderr
, "%s: Specify one of `-l', `-d' or `-g'\n", argv
[0]);
477 fprintf (stderr
, "%s: A domain name is only accepted "
478 "when `-d' is given.\n", argv
[0]);
481 mbstowcs (domain_name
, argv
[optind
], (strlen (argv
[optind
]) + 1));
482 domain_name_specified
= 1;
487 if (passed_home_path
[0] == '\0')
488 strcpy (passed_home_path
, "/home/");
490 /* This takes Windows 9x/ME into account. */
491 if (GetVersion () >= 0x80000000)
493 /* Same behaviour as in cygwin/uinfo.cc (internal_getlogin). */
494 if (!GetUserName (name
, (len
= 256, &len
)))
495 strcpy (name
, "unknown");
497 printf ("%s::%ld:%ld::%s%s:/bin/bash\n", name
,
498 DOMAIN_USER_RID_ADMIN
,
499 DOMAIN_ALIAS_RID_ADMINS
,
508 fprintf (stderr
, "Failed loading symbols from netapi32.dll "
509 "with error %lu\n", GetLastError ());
514 * Get `Everyone' group
516 print_special (print_sids
, &sid_world_auth
, 1, SECURITY_WORLD_RID
, 0, 0, 0, 0, 0, 0, 0);
520 print_special (print_sids
, &sid_nt_auth
, 1, SECURITY_LOCAL_SYSTEM_RID
, 0, 0, 0, 0, 0, 0, 0);
522 * Get `administrators' group
524 if (!print_local_groups
)
525 print_special (print_sids
, &sid_nt_auth
, 2, SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_ADMINS
, 0, 0, 0, 0, 0, 0);
527 if (print_local_groups
)
528 enum_local_groups (print_sids
);
532 if (domain_name_specified
)
533 rc
= netgetdcname (NULL
, domain_name
, (LPBYTE
*) & servername
);
536 rc
= netgetdcname (NULL
, NULL
, (LPBYTE
*) & servername
);
538 if (rc
!= ERROR_SUCCESS
)
540 fprintf (stderr
, "Cannot get DC, code = %ld\n", rc
);
544 enum_users (servername
, print_sids
, print_cygpath
, passed_home_path
, id_offset
);
548 enum_users (NULL
, print_sids
, print_cygpath
, passed_home_path
, 0);
551 netapibufferfree (servername
);