* Makefile.in (cygcheck.exe): Link against ntdll.

* bloda.cc: Use statically linked functions throughout.
	* cygpath.cc: Drop 9x considerations.
	* mkgroup.c: Revamp.  Redefine -l and -d options to take optional
	machine and domain parameters.  Redefine -c to work always, using
	token information.  Add -L, -D, -C to create unique groupnames in
	domain\group syntax.  Add -S option to define domain\group separator
	char.  Ignore -u and -s options.
	* mkpasswd.c: Revamp.  Redefine -l and -d options to take optional
	machine and domain parameters.  Redefine -c to work always, using
	token information.  Add -L, -D, -C to create unique usernames in
	domain\user syntax.  Add -S option to define domain\user separator
	char.  Ignore -g and -s options.  Prefer to take homedir from $HOME
	over $HOMEDRIVE/$HOMEPATH.
	* path.cc (oopts): Add "acl", "noacl", "posix=0" and "posix=1" options.
	(getmntent): Accomodate throughout.
	* ps.cc: Fix copyright dates.
	* utils.sgml: Fix text for mkgroup and mkpasswd.
This commit is contained in:
Corinna Vinschen 2008-07-22 14:40:05 +00:00
parent 737a72dd0e
commit a1e1990348
9 changed files with 936 additions and 939 deletions

View File

@ -1,3 +1,24 @@
2008-07-22 Corinna Vinschen <corinna@vinschen.de>
* Makefile.in (cygcheck.exe): Link against ntdll.
* bloda.cc: Use statically linked functions throughout.
* cygpath.cc: Drop 9x considerations.
* mkgroup.c: Revamp. Redefine -l and -d options to take optional
machine and domain parameters. Redefine -c to work always, using
token information. Add -L, -D, -C to create unique groupnames in
domain\group syntax. Add -S option to define domain\group separator
char. Ignore -u and -s options.
* mkpasswd.c: Revamp. Redefine -l and -d options to take optional
machine and domain parameters. Redefine -c to work always, using
token information. Add -L, -D, -C to create unique usernames in
domain\user syntax. Add -S option to define domain\user separator
char. Ignore -g and -s options. Prefer to take homedir from $HOME
over $HOMEDRIVE/$HOMEPATH.
* path.cc (oopts): Add "acl", "noacl", "posix=0" and "posix=1" options.
(getmntent): Accomodate throughout.
* ps.cc: Fix copyright dates.
* utils.sgml: Fix text for mkgroup and mkpasswd.
2008-07-17 Corinna Vinschen <corinna@vinschen.de> 2008-07-17 Corinna Vinschen <corinna@vinschen.de>
* mount.cc (do_mount): Remove MOUNT_ENC code. * mount.cc (do_mount): Remove MOUNT_ENC code.

View File

@ -94,7 +94,7 @@ ifdef libz
zlib_h := -include ${patsubst %/lib/mingw/libz.a,%/include/zlib.h,${patsubst %/lib/libz.a,%/include/zlib.h,$(libz)}} zlib_h := -include ${patsubst %/lib/mingw/libz.a,%/include/zlib.h,${patsubst %/lib/libz.a,%/include/zlib.h,$(libz)}}
zconf_h := ${patsubst %/zlib.h,%/zconf.h,$(zlib_h)} zconf_h := ${patsubst %/zlib.h,%/zconf.h,$(zlib_h)}
dump_setup.o: MINGW_CXXFLAGS += $(zconf_h) $(zlib_h) dump_setup.o: MINGW_CXXFLAGS += $(zconf_h) $(zlib_h)
cygcheck.exe: MINGW_LDFLAGS += $(libz) cygcheck.exe: MINGW_LDFLAGS += $(libz) -lntdll
else else
all: warn_cygcheck_zlib all: warn_cygcheck_zlib
endif endif

View File

@ -108,24 +108,13 @@ static struct bad_app_info big_list_of_dodgy_apps[] =
static const size_t num_of_dodgy_apps = sizeof (big_list_of_dodgy_apps) / sizeof (big_list_of_dodgy_apps[0]); static const size_t num_of_dodgy_apps = sizeof (big_list_of_dodgy_apps) / sizeof (big_list_of_dodgy_apps[0]);
/* This function is not in the ntdll export lib, so it has
to be looked up at runtime and called through a pointer. */
VOID NTAPI (*pRtlFreeUnicodeString)(PUNICODE_STRING) = NULL;
NTSTATUS NTAPI (*pNtQuerySystemInformation) (SYSTEM_INFORMATION_CLASS,
PVOID, ULONG, PULONG) = NULL;
NTSTATUS NTAPI (*pRtlAnsiStringToUnicodeString) (PUNICODE_STRING, PANSI_STRING,
BOOLEAN) = NULL;
static PSYSTEM_PROCESSES static PSYSTEM_PROCESSES
get_process_list (void) get_process_list (void)
{ {
int n_procs = 0x100; int n_procs = 0x100;
PSYSTEM_PROCESSES pslist = (PSYSTEM_PROCESSES) malloc (n_procs * sizeof *pslist); PSYSTEM_PROCESSES pslist = (PSYSTEM_PROCESSES) malloc (n_procs * sizeof *pslist);
while (pNtQuerySystemInformation (SystemProcessesAndThreadsInformation, while (NtQuerySystemInformation (SystemProcessesAndThreadsInformation,
pslist, n_procs * sizeof *pslist, 0) == STATUS_INFO_LENGTH_MISMATCH) pslist, n_procs * sizeof *pslist, 0) == STATUS_INFO_LENGTH_MISMATCH)
{ {
n_procs *= 2; n_procs *= 2;
@ -141,7 +130,7 @@ get_module_list (void)
int modsize = 0x1000; int modsize = 0x1000;
PSYSTEM_MODULE_INFORMATION modlist = (PSYSTEM_MODULE_INFORMATION) malloc (modsize); PSYSTEM_MODULE_INFORMATION modlist = (PSYSTEM_MODULE_INFORMATION) malloc (modsize);
while (pNtQuerySystemInformation (SystemModuleInformation, while (NtQuerySystemInformation (SystemModuleInformation,
modlist, modsize, NULL) == STATUS_INFO_LENGTH_MISMATCH) modlist, modsize, NULL) == STATUS_INFO_LENGTH_MISMATCH)
{ {
modsize *= 2; modsize *= 2;
@ -299,14 +288,14 @@ detect_dodgy_app (const struct bad_app_det *det, PSYSTEM_PROCESSES pslist, PSYST
/* Equivalent of RtlInitAnsiString. */ /* Equivalent of RtlInitAnsiString. */
ansiname.Length = ansiname.MaximumLength = strlen (det->param); ansiname.Length = ansiname.MaximumLength = strlen (det->param);
ansiname.Buffer = (CHAR *) det->param; ansiname.Buffer = (CHAR *) det->param;
rv = pRtlAnsiStringToUnicodeString (&unicodename, &ansiname, TRUE); rv = RtlAnsiStringToUnicodeString (&unicodename, &ansiname, TRUE);
if (rv != STATUS_SUCCESS) if (rv != STATUS_SUCCESS)
{ {
printf ("Ansi to unicode conversion failure $%08x\n", (unsigned int) rv); printf ("Ansi to unicode conversion failure $%08x\n", (unsigned int) rv);
break; break;
} }
found = find_process_in_list (pslist, &unicodename); found = find_process_in_list (pslist, &unicodename);
pRtlFreeUnicodeString (&unicodename); RtlFreeUnicodeString (&unicodename);
if (found) if (found)
{ {
dbg_printf (("found!\n")); dbg_printf (("found!\n"));
@ -347,25 +336,6 @@ dump_dodgy_apps (int verbose)
size_t i, n_det = 0; size_t i, n_det = 0;
PSYSTEM_PROCESSES pslist; PSYSTEM_PROCESSES pslist;
PSYSTEM_MODULE_INFORMATION modlist; PSYSTEM_MODULE_INFORMATION modlist;
HMODULE ntdll;
if ((ntdll = LoadLibrary ("ntdll.dll")) == NULL)
{
puts ("Skipping dodgy app check on Win9x/ME.");
return;
}
#define GPA(func,rv) \
if ((p##func = (rv) GetProcAddress (ntdll, #func)) == NULL) \
{ \
puts ("Can't GetProcAddress() for " #func ", " \
"skipping dodgy app check."); \
return; \
}
GPA(NtQuerySystemInformation, NTSTATUS NTAPI (*) (SYSTEM_INFORMATION_CLASS,PVOID,ULONG,PULONG));
GPA(RtlFreeUnicodeString, VOID NTAPI (*)(PUNICODE_STRING));
GPA(RtlAnsiStringToUnicodeString, NTSTATUS NTAPI (*)(PUNICODE_STRING,PANSI_STRING,BOOLEAN));
#undef GPA
/* Read system info for detect testing. */ /* Read system info for detect testing. */
pslist = get_process_list (); pslist = get_process_list ();

View File

@ -1,6 +1,6 @@
/* cygpath.cc -- convert pathnames between Windows and Unix format /* cygpath.cc -- convert pathnames between Windows and Unix format
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
2006, 2007 Red Hat, Inc. 2006, 2007, 2008 Red Hat, Inc.
This file is part of Cygwin. This file is part of Cygwin.
@ -529,8 +529,7 @@ get_special_folder (char* path, int id)
static void static void
get_user_folder (char* path, int id, int allid) get_user_folder (char* path, int id, int allid)
{ {
if (!get_special_folder (path, allusers_flag ? allid : id) && allusers_flag) get_special_folder (path, allusers_flag ? allid : id);
get_special_folder (path, id); // Fix for Win9x without any "All Users"
} }
static void static void
@ -740,7 +739,7 @@ print_version ()
cygpath (cygwin) %.*s\n\ cygpath (cygwin) %.*s\n\
Path Conversion Utility\n\ Path Conversion Utility\n\
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, \n\ Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, \n\
2007 Red Hat, Inc.\n\ 2007, 2008 Red Hat, Inc.\n\
Compiled on %s\n\ Compiled on %s\n\
", len, v, __DATE__); ", len, v, __DATE__);
} }

View File

@ -9,37 +9,31 @@
Cygwin license. Please consult the file "CYGWIN_LICENSE" for Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */ details. */
#define _WIN32_WINNT 0x0600
#include <ctype.h> #include <ctype.h>
#include <stdlib.h> #include <stdlib.h>
#include <wchar.h> #include <wchar.h>
#include <stdio.h> #include <stdio.h>
#include <windows.h> #include <unistd.h>
#include <sys/cygwin.h>
#include <getopt.h> #include <getopt.h>
#include <lmaccess.h> #include <io.h>
#include <lmapibuf.h> #include <sys/fcntl.h>
#include <sys/cygwin.h>
#include <windows.h>
#include <lm.h>
#include <wininet.h> #include <wininet.h>
#include <iptypes.h> #include <iptypes.h>
#include <ntsecapi.h> #include <ntsecapi.h>
#include <dsgetdc.h>
#include <ntdef.h> #include <ntdef.h>
#define print_win_error(x) _print_win_error(x, __LINE__) #define print_win_error(x) _print_win_error(x, __LINE__)
static const char version[] = "$Revision$";
#define MAX_SID_LEN 40 #define MAX_SID_LEN 40
typedef struct { static const char version[] = "$Revision$";
LPWSTR DomainControllerName;
LPWSTR DomainControllerAddress; extern char *__progname;
ULONG DomainControllerAddressType;
GUID DomainGuid;
LPWSTR DomainName;
LPWSTR DnsForestName;
ULONG Flags;
LPWSTR DcSiteName;
LPWSTR ClientSiteName;
} *PDOMAIN_CONTROLLER_INFOW;
SID_IDENTIFIER_AUTHORITY sid_world_auth = {SECURITY_WORLD_SID_AUTHORITY}; SID_IDENTIFIER_AUTHORITY sid_world_auth = {SECURITY_WORLD_SID_AUTHORITY};
SID_IDENTIFIER_AUTHORITY sid_nt_auth = {SECURITY_NT_AUTHORITY}; SID_IDENTIFIER_AUTHORITY sid_nt_auth = {SECURITY_NT_AUTHORITY};
@ -50,14 +44,83 @@ NET_API_STATUS WINAPI (*dsgetdcname)(LPWSTR,LPWSTR,GUID*,LPWSTR,ULONG,PDOMAIN_CO
#define min(a,b) (((a)<(b))?(a):(b)) #define min(a,b) (((a)<(b))?(a):(b))
#endif #endif
typedef struct
{
char *str;
BOOL with_dom;
} domlist_t;
void void
load_netapi () _print_win_error (DWORD code, int line)
{
char buf[4096];
if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
code,
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) buf, sizeof (buf), NULL))
fprintf (stderr, "mkgroup (%d): [%lu] %s", line, code, buf);
else
fprintf (stderr, "mkgroup (%d): error %lu", line, code);
}
void
load_dsgetdcname ()
{ {
HANDLE h = LoadLibrary ("netapi32.dll"); HANDLE h = LoadLibrary ("netapi32.dll");
if (h) if (h)
dsgetdcname = (void *) GetProcAddress (h, "DsGetDcNameW"); dsgetdcname = (void *) GetProcAddress (h, "DsGetDcNameW");
} }
static PWCHAR
get_dcname (char *domain)
{
static WCHAR server[INTERNET_MAX_HOST_NAME_LENGTH + 1];
DWORD rc;
PWCHAR servername;
WCHAR domain_name[MAX_DOMAIN_NAME_LEN + 1];
PDOMAIN_CONTROLLER_INFOW pdci = NULL;
if (dsgetdcname)
{
if (domain)
{
mbstowcs (domain_name, domain, strlen (domain) + 1);
rc = dsgetdcname (NULL, domain_name, NULL, NULL, 0, &pdci);
}
else
rc = dsgetdcname (NULL, NULL, NULL, NULL, 0, &pdci);
if (rc != ERROR_SUCCESS)
{
print_win_error (rc);
return (PWCHAR) -1;
}
wcscpy (server, pdci->DomainControllerName);
NetApiBufferFree (pdci);
}
else
{
rc = NetGetDCName (NULL, NULL, (void *) &servername);
if (rc == ERROR_SUCCESS && domain)
{
LPWSTR server = servername;
mbstowcs (domain_name, domain, strlen (domain) + 1);
rc = NetGetDCName (server, domain_name, (void *) &servername);
NetApiBufferFree (server);
}
if (rc != ERROR_SUCCESS)
{
print_win_error(rc);
return (PWCHAR) -1;
}
wcscpy (server, servername);
NetApiBufferFree ((PVOID) servername);
}
return server;
}
char * char *
put_sid (PSID sid) put_sid (PSID sid)
{ {
@ -76,48 +139,6 @@ put_sid (PSID sid)
return s; return s;
} }
void
_print_win_error(DWORD code, int line)
{
char buf[4096];
if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
code,
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) buf, sizeof (buf), NULL))
fprintf (stderr, "mkgroup (%d): [%lu] %s", line, code, buf);
else
fprintf (stderr, "mkgroup (%d): error %lu", line, code);
}
void
enum_local_users (LPWSTR servername, LPWSTR groupname)
{
LOCALGROUP_MEMBERS_INFO_1 *buf1;
DWORD entries = 0;
DWORD total = 0;
DWORD reshdl = 0;
if (!NetLocalGroupGetMembers (servername, groupname, 1, (void *) &buf1,
MAX_PREFERRED_LENGTH,
&entries, &total, &reshdl))
{
unsigned i, first = 1;
for (i = 0; i < entries; ++i)
if (buf1[i].lgrmi1_sidusage == SidTypeUser)
{
if (!first)
printf (",");
first = 0;
printf ("%ls", buf1[i].lgrmi1_name);
}
NetApiBufferFree (buf1);
}
}
typedef struct { typedef struct {
BYTE Revision; BYTE Revision;
BYTE SubAuthorityCount; BYTE SubAuthorityCount;
@ -130,26 +151,48 @@ DBGSID builtin_sid_list[MAX_BUILTIN_SIDS];
DWORD builtin_sid_cnt; DWORD builtin_sid_cnt;
int int
enum_local_groups (LPWSTR servername, int print_sids, int print_users, enum_local_groups (BOOL domain, domlist_t *dom_or_machine, const char *sep,
int id_offset, char *disp_groupname) int id_offset, char *disp_groupname)
{ {
WCHAR machine[INTERNET_MAX_HOST_NAME_LENGTH + 1];
PWCHAR servername = NULL;
char *d_or_m = dom_or_machine ? dom_or_machine->str : NULL;
BOOL with_dom = dom_or_machine ? dom_or_machine->with_dom : FALSE;
LOCALGROUP_INFO_0 *buffer; LOCALGROUP_INFO_0 *buffer;
DWORD entriesread = 0; DWORD entriesread = 0;
DWORD totalentries = 0; DWORD totalentries = 0;
DWORD resume_handle = 0; DWORD resume_handle = 0;
WCHAR uni_name[GNLEN + 1]; WCHAR gname[GNLEN + 1];
DWORD rc; DWORD rc;
if (domain)
{
servername = get_dcname (d_or_m);
if (servername == (PWCHAR) -1)
return 1;
}
else if (d_or_m)
{
int ret = mbstowcs (machine, d_or_m, INTERNET_MAX_HOST_NAME_LENGTH + 1);
if (ret < 1 || ret >= INTERNET_MAX_HOST_NAME_LENGTH + 1)
{
fprintf (stderr, "%s: Invalid machine name '%s'. Skipping...\n",
__progname, d_or_m);
return 1;
}
servername = machine;
}
do do
{ {
DWORD i; DWORD i;
if (disp_groupname != NULL) if (disp_groupname != NULL)
{ {
mbstowcs (uni_name, disp_groupname, GNLEN + 1); mbstowcs (gname, disp_groupname, GNLEN + 1);
rc = NetApiBufferAllocate (sizeof (LOCALGROUP_INFO_0), rc = NetApiBufferAllocate (sizeof (LOCALGROUP_INFO_0),
(void *) &buffer); (void *) &buffer);
buffer[0].lgrpi0_name = uni_name; buffer[0].lgrpi0_name = gname;
entriesread = 1; entriesread = 1;
} }
else else
@ -160,7 +203,7 @@ enum_local_groups (LPWSTR servername, int print_sids, int print_users,
{ {
case ERROR_ACCESS_DENIED: case ERROR_ACCESS_DENIED:
print_win_error (rc); print_win_error (rc);
exit (1); return 1;
case ERROR_MORE_DATA: case ERROR_MORE_DATA:
case ERROR_SUCCESS: case ERROR_SUCCESS:
@ -168,7 +211,7 @@ enum_local_groups (LPWSTR servername, int print_sids, int print_users,
default: default:
print_win_error (rc); print_win_error (rc);
exit (1); return 1;
} }
for (i = 0; i < entriesread; i++) for (i = 0; i < entriesread; i++)
@ -232,12 +275,12 @@ enum_local_groups (LPWSTR servername, int print_sids, int print_users,
gid = *GetSidSubAuthority (psid, *GetSidSubAuthorityCount(psid) - 1); gid = *GetSidSubAuthority (psid, *GetSidSubAuthorityCount(psid) - 1);
printf ("%ls:%s:%ld:", buffer[i].lgrpi0_name, printf ("%ls%s%ls:%s:%ld:\n",
print_sids ? put_sid (psid) : "", with_dom ? domain_name : L"",
with_dom ? sep : "",
buffer[i].lgrpi0_name,
put_sid (psid),
gid + (is_builtin ? 0 : id_offset)); gid + (is_builtin ? 0 : id_offset));
if (print_users)
enum_local_users (servername, buffer[i].lgrpi0_name);
printf ("\n");
skip_group: skip_group:
; ;
} }
@ -251,48 +294,46 @@ skip_group:
} }
void void
enum_users (LPWSTR servername, LPWSTR groupname) enum_groups (BOOL domain, domlist_t *dom_or_machine, const char *sep,
{ int id_offset, char *disp_groupname)
GROUP_USERS_INFO_0 *buf1;
DWORD entries = 0;
DWORD total = 0;
DWORD reshdl = 0;
if (!NetGroupGetUsers (servername, groupname, 0, (void *) &buf1,
MAX_PREFERRED_LENGTH, &entries, &total, &reshdl))
{
unsigned i, first = 1;
for (i = 0; i < entries; ++i)
{
if (!first)
printf (",");
first = 0;
printf ("%ls", buf1[i].grui0_name);
}
NetApiBufferFree (buf1);
}
}
void
enum_groups (LPWSTR servername, int print_sids, int print_users, int id_offset,
char *disp_groupname)
{ {
WCHAR machine[INTERNET_MAX_HOST_NAME_LENGTH + 1];
PWCHAR servername = NULL;
char *d_or_m = dom_or_machine ? dom_or_machine->str : NULL;
BOOL with_dom = dom_or_machine ? dom_or_machine->with_dom : FALSE;
GROUP_INFO_2 *buffer; GROUP_INFO_2 *buffer;
DWORD entriesread = 0; DWORD entriesread = 0;
DWORD totalentries = 0; DWORD totalentries = 0;
DWORD resume_handle = 0; DWORD resume_handle = 0;
WCHAR uni_name[GNLEN + 1]; WCHAR gname[GNLEN + 1];
DWORD rc; DWORD rc;
if (domain)
{
servername = get_dcname (d_or_m);
if (servername == (PWCHAR) -1)
return;
}
else if (d_or_m)
{
int ret = mbstowcs (machine, d_or_m, INTERNET_MAX_HOST_NAME_LENGTH + 1);
if (ret < 1 || ret >= INTERNET_MAX_HOST_NAME_LENGTH + 1)
{
fprintf (stderr, "%s: Invalid machine name '%s'. Skipping...\n",
__progname, d_or_m);
return;
}
servername = machine;
}
do do
{ {
DWORD i; DWORD i;
if (disp_groupname != NULL) if (disp_groupname != NULL)
{ {
mbstowcs (uni_name, disp_groupname, GNLEN + 1); mbstowcs (gname, disp_groupname, GNLEN + 1);
rc = NetGroupGetInfo (servername, (LPWSTR) & uni_name, 2, rc = NetGroupGetInfo (servername, (LPWSTR) & gname, 2,
(void *) &buffer); (void *) &buffer);
entriesread=1; entriesread=1;
} }
@ -304,7 +345,7 @@ enum_groups (LPWSTR servername, int print_sids, int print_users, int id_offset,
{ {
case ERROR_ACCESS_DENIED: case ERROR_ACCESS_DENIED:
print_win_error (rc); print_win_error (rc);
exit (1); return;
case ERROR_MORE_DATA: case ERROR_MORE_DATA:
case ERROR_SUCCESS: case ERROR_SUCCESS:
@ -312,7 +353,7 @@ enum_groups (LPWSTR servername, int print_sids, int print_users, int id_offset,
default: default:
print_win_error (rc); print_win_error (rc);
exit (1); return;
} }
for (i = 0; i < entriesread; i++) for (i = 0; i < entriesread; i++)
@ -325,8 +366,6 @@ enum_groups (LPWSTR servername, int print_sids, int print_users, int id_offset,
SID_NAME_USE acc_type; SID_NAME_USE acc_type;
int gid = buffer[i].grpi2_group_id; int gid = buffer[i].grpi2_group_id;
if (print_sids)
{
if (!LookupAccountNameW (servername, buffer[i].grpi2_name, if (!LookupAccountNameW (servername, buffer[i].grpi2_name,
psid, &sid_length, psid, &sid_length,
domain_name, &domname_len, domain_name, &domname_len,
@ -355,13 +394,12 @@ enum_groups (LPWSTR servername, int print_sids, int print_users, int id_offset,
continue; continue;
} }
} }
} printf ("%ls%s%ls:%s:%u:\n",
printf ("%ls:%s:%u:", buffer[i].grpi2_name, with_dom ? domain_name : L"",
print_sids ? put_sid (psid) : "", with_dom ? sep : "",
buffer[i].grpi2_name,
put_sid (psid),
gid + id_offset); gid + id_offset);
if (print_users)
enum_users (servername, buffer[i].grpi2_name);
printf ("\n");
} }
NetApiBufferFree (buffer); NetApiBufferFree (buffer);
@ -371,8 +409,7 @@ enum_groups (LPWSTR servername, int print_sids, int print_users, int id_offset,
} }
void void
print_special (int print_sids, print_special (PSID_IDENTIFIER_AUTHORITY auth, BYTE cnt,
PSID_IDENTIFIER_AUTHORITY auth, BYTE cnt,
DWORD sub1, DWORD sub2, DWORD sub3, DWORD sub4, DWORD sub1, DWORD sub2, DWORD sub3, DWORD sub4,
DWORD sub5, DWORD sub6, DWORD sub7, DWORD sub8) DWORD sub5, DWORD sub6, DWORD sub7, DWORD sub8)
{ {
@ -405,97 +442,96 @@ print_special (int print_sids,
rid = sub2; rid = sub2;
else else
rid = sub1; rid = sub1;
printf ("%s:%s:%lu:\n", name, printf ("%s:%s:%lu:\n", name, put_sid (sid), rid);
print_sids ? put_sid (sid) : "",
rid);
} }
FreeSid (sid); FreeSid (sid);
} }
} }
void void
current_group (int print_sids, int print_users, int id_offset) current_group (const char *sep, int id_offset)
{ {
char name[UNLEN + 1], *envname, *envdomain;
DWORD len; DWORD len;
HANDLE ptok; HANDLE ptok;
int errpos = 0;
struct { struct {
PSID psid; PSID psid;
char buffer[MAX_SID_LEN]; char buffer[MAX_SID_LEN];
} tg; } tg;
char grp[GNLEN + 1];
char dom[MAX_DOMAIN_NAME_LEN + 1];
DWORD glen = GNLEN + 1;
DWORD dlen = MAX_DOMAIN_NAME_LEN + 1;
int gid;
SID_NAME_USE acc_type;
if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &ptok)
if ((!GetUserName (name, (len = sizeof (name), &len)) && (errpos = __LINE__)) || !GetTokenInformation (ptok, TokenPrimaryGroup, &tg, sizeof tg, &len)
|| !name[0] || !CloseHandle (ptok)
|| !(envname = getenv("USERNAME")) || !LookupAccountSidA (NULL, tg.psid, grp, &glen, dom, &dlen, &acc_type))
|| strcasecmp (envname, name)
|| (!GetComputerName (name, (len = sizeof (name), &len))
&& (errpos = __LINE__))
|| !(envdomain = getenv("USERDOMAIN"))
|| !envdomain[0]
|| !strcasecmp (envdomain, name)
|| (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &ptok)
&& (errpos = __LINE__))
|| (!GetTokenInformation (ptok, TokenPrimaryGroup, &tg, sizeof tg, &len)
&& (errpos = __LINE__))
|| (!CloseHandle (ptok) && (errpos = __LINE__)))
{
if (errpos)
{ {
print_win_error (GetLastError ()); print_win_error (GetLastError ());
}
return; return;
} }
gid = *GetSidSubAuthority (tg.psid, *GetSidSubAuthorityCount(tg.psid) - 1);
int gid = *GetSidSubAuthority (tg.psid, *GetSidSubAuthorityCount(tg.psid) - 1); printf ("%s%s%s:%s:%u:\n",
sep ? dom : "",
printf ("mkgroup_l_d:%s:%u:", print_sids ? put_sid (tg.psid) : "", sep ?: "",
grp,
put_sid (tg.psid),
gid + id_offset); gid + id_offset);
if (print_users)
printf("%s", envname);
printf ("\n");
} }
int int
usage (FILE * stream, int isNT) usage (FILE * stream)
{ {
fprintf (stream, "Usage: mkgroup [OPTION]... [domain]...\n" fprintf (stream,
"Print /etc/group file to stdout\n\n" "Usage: mkgroup [OPTION]...\n"
"Options:\n"); "Print /etc/group file to stdout\n"
if (isNT) "\n"
fprintf (stream, " -l,--local print machine local group information\n" "Options:\n"
" -c,--current print current group, if a domain account\n" " -l,--local [machine] print local groups (from local machine if no\n"
" -d,--domain print domain group information (from current\n" " machine specified)\n"
" domain if no domains specified)\n" " -L,--Local [machine] ditto, but generate groupname with machine prefix\n"
" -d,--domain [domain] print domain groups (from current domain if no\n"
" domain specified)\n"
" -D,--Domain [domain] ditto, but generate groupname with machine prefix\n"
" -c,--current print current group\n"
" -C,--Current ditto, but generate groupname with machine or\n"
" domain prefix\n"
" -S,--separator char for -L, -D, -C use character char as domain\\group\n"
" separator in groupname instead of the default '\\'\n"
" -o,--id-offset offset change the default offset (10000) added to gids\n" " -o,--id-offset offset change the default offset (10000) added to gids\n"
" in domain accounts.\n" " in domain or foreign server accounts.\n"
" -s,--no-sids don't print SIDs in pwd field\n" " -g,--group groupname only return information for the specified group\n"
" (this affects ntsec)\n" " one of -l, -L, -d, -D must be specified, too\n"
" -u,--users print user list in gr_mem field\n" " -s,--no-sids (ignored)\n"
" -g,--group groupname only return information for the specified group\n"); " -u,--users (ignored)\n"
fprintf (stream, " -h,--help print this message\n" " -h,--help print this message\n"
" -v,--version print version information and exit\n\n"); " -v,--version print version information and exit\n"
if (isNT) "\n"
fprintf (stream, "One of '-l' or '-d' must be given.\n"); "Default is to print local groups on stand-alone machines, plus domain\n"
"groups on domain controllers and domain member machines.\n");
return 1; return 1;
} }
struct option longopts[] = { struct option longopts[] = {
{"local", no_argument, NULL, 'l'},
{"current", no_argument, NULL, 'c'}, {"current", no_argument, NULL, 'c'},
{"domain", no_argument, NULL, 'd'}, {"Current", no_argument, NULL, 'C'},
{"id-offset", required_argument, NULL, 'o'}, {"domain", optional_argument, NULL, 'd'},
{"no-sids", no_argument, NULL, 's'}, {"Domain", optional_argument, NULL, 'D'},
{"users", no_argument, NULL, 'u'},
{"group", required_argument, NULL, 'g'}, {"group", required_argument, NULL, 'g'},
{"help", no_argument, NULL, 'h'}, {"help", no_argument, NULL, 'h'},
{"local", optional_argument, NULL, 'l'},
{"Local", optional_argument, NULL, 'L'},
{"id-offset", required_argument, NULL, 'o'},
{"no-sids", no_argument, NULL, 's'},
{"separator", required_argument, NULL, 'S'},
{"users", no_argument, NULL, 'u'},
{"version", no_argument, NULL, 'v'}, {"version", no_argument, NULL, 'v'},
{0, no_argument, NULL, 0} {0, no_argument, NULL, 0}
}; };
char opts[] = "lcdo:sug:hv"; char opts[] = "cCd::D::g:hl::L::o:sS:uv";
void void
print_version () print_version ()
@ -520,67 +556,138 @@ Compiled on %s\n\
", len, v, __DATE__); ", len, v, __DATE__);
} }
static PPOLICY_PRIMARY_DOMAIN_INFO p_dom;
static BOOL
fetch_primary_domain ()
{
NTSTATUS status;
LSA_OBJECT_ATTRIBUTES oa = { 0, 0, 0, 0, 0, 0 };
LSA_HANDLE lsa;
if (!p_dom)
{
status = LsaOpenPolicy (NULL, &oa, POLICY_EXECUTE, &lsa);
if (!NT_SUCCESS (status))
return FALSE;
status = LsaQueryInformationPolicy (lsa, PolicyPrimaryDomainInformation,
(PVOID *) &p_dom);
LsaClose (lsa);
if (!NT_SUCCESS (status))
return FALSE;
}
return !!p_dom->Sid;
}
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
LPWSTR servername;
DWORD rc = ERROR_SUCCESS;
WCHAR domain_name[MAX_DOMAIN_NAME_LEN + 1];
int print_local = 0; int print_local = 0;
int print_current = 0; domlist_t locals[16];
int print_domain = 0; int print_domain = 0;
int print_sids = 1; domlist_t domains[16];
int print_users = 0; char *opt;
int domain_specified = 0; int print_current = 0;
const char *sep_char = "\\";
int id_offset = 10000; int id_offset = 10000;
int c, i, off;
char *disp_groupname = NULL; char *disp_groupname = NULL;
int isRoot = 0; int isRoot = 0;
int isNT; BOOL in_domain;
int i;
char dom[MAX_DOMAIN_NAME_LEN + 1]; if (!isatty (1))
DWORD len, len2; setmode (1, O_BINARY);
PSID psid = NULL;
SID_NAME_USE use;
LSA_OBJECT_ATTRIBUTES oa = { 0, 0, 0, 0, 0, 0 }; load_dsgetdcname ();
LSA_HANDLE lsa = INVALID_HANDLE_VALUE; in_domain = fetch_primary_domain ();
NTSTATUS ret; if (argc == 1)
PPOLICY_PRIMARY_DOMAIN_INFO pdi;
isNT = (GetVersion () < 0x80000000);
if (isNT && argc == 1)
return usage(stderr, isNT);
else
{ {
while ((i = getopt_long (argc, argv, opts, longopts, NULL)) != EOF) print_special (&sid_nt_auth, 1, SECURITY_LOCAL_SYSTEM_RID,
switch (i) 0, 0, 0, 0, 0, 0, 0);
if (in_domain)
{
if (!enum_local_groups (TRUE, NULL, sep_char, id_offset,
disp_groupname))
enum_groups (TRUE, NULL, sep_char, id_offset, disp_groupname);
}
else if (!enum_local_groups (FALSE, NULL, sep_char, 0, disp_groupname))
enum_groups (FALSE, NULL, sep_char, 0, disp_groupname);
return 0;
}
while ((c = getopt_long (argc, argv, opts, longopts, NULL)) != EOF)
switch (c)
{ {
case 'l': case 'l':
print_local = 1; case 'L':
break; if (print_local >= 16)
case 'c': {
print_current = 1; fprintf (stderr, "%s: Can not enumerate from more than 16 "
"servers.\n", __progname);
return 1;
}
opt = optarg ?:
argv[optind] && argv[optind][0] != '-' ? argv[optind] : NULL;
for (i = 0; i < print_local; ++i)
if ((!locals[i].str && !opt)
|| (locals[i].str && opt && !strcmp (locals[i].str, opt)))
goto skip_local;
locals[print_local].str = opt;
locals[print_local++].with_dom = c == 'L';
skip_local:
break; break;
case 'd': case 'd':
print_domain = 1; case 'D':
if (print_domain >= 16)
{
fprintf (stderr, "%s: Can not enumerate from more than 16 "
"domains.\n", __progname);
return 1;
}
opt = optarg ?:
argv[optind] && argv[optind][0] != '-' ? argv[optind] : NULL;
for (i = 0; i < print_domain; ++i)
if ((!domains[i].str && !opt)
|| (domains[i].str && opt && !strcmp (domains[i].str, opt)))
goto skip_domain;
domains[print_domain].str = opt;
domains[print_domain++].with_dom = c == 'D';
skip_domain:
break;
case 'S':
sep_char = optarg;
if (strlen (sep_char) > 1)
{
fprintf (stderr, "%s: Only one character allowed as domain\\user "
"separator character.\n", __progname);
return 1;
}
if (*sep_char == ':')
{
fprintf (stderr, "%s: Colon not allowed as domain\\user separator "
"character.\n", __progname);
return 1;
}
break;
case 'c':
sep_char = NULL;
/*FALLTHRU*/
case 'C':
print_current = 1;
break; break;
case 'o': case 'o':
id_offset = strtol (optarg, NULL, 10); id_offset = strtol (optarg, NULL, 10);
break; break;
case 's': case 's':
print_sids = 0;
break; break;
case 'u': case 'u':
print_users = 1;
break; break;
case 'g': case 'g':
disp_groupname = optarg; disp_groupname = optarg;
isRoot = !strcmp(disp_groupname, "root"); isRoot = !strcmp(disp_groupname, "root");
break; break;
case 'h': case 'h':
usage (stdout, isNT); usage (stdout);
return 0; return 0;
case 'v': case 'v':
print_version (); print_version ();
@ -589,150 +696,48 @@ main (int argc, char **argv)
fprintf (stderr, "Try '%s --help' for more information.\n", argv[0]); fprintf (stderr, "Try '%s --help' for more information.\n", argv[0]);
return 1; return 1;
} }
}
/* This takes Windows 9x/ME into account. */ if (optind < argc - 1)
if (!isNT) usage (stdout);
{
printf ("all::%ld:\n", DOMAIN_ALIAS_RID_ADMINS);
return 0;
}
if (!print_local && !print_domain) /* Get 'system' group */
{ if (!disp_groupname && (print_local > 0 || print_domain > 0))
fprintf (stderr, "%s: Specify one of '-l' or '-d'\n", argv[0]); print_special (&sid_nt_auth, 1, SECURITY_LOCAL_SYSTEM_RID,
return 1; 0, 0, 0, 0, 0, 0, 0);
}
if (optind < argc)
{
if (!print_domain)
{
fprintf (stderr, "%s: A domain name is only accepted "
"when '-d' is given.\n", argv[0]);
return 1;
}
domain_specified = 1;
}
load_netapi ();
if (print_local)
{
char machine[INTERNET_MAX_HOST_NAME_LENGTH + 1];
char sid[MAX_SID_LEN];
off = 1;
if (isRoot) if (isRoot)
{ {
/* /* Very special feature for the oncoming future:
* Very special feature for the oncoming future: Create a "root" group being actually the local Administrators group.
* Create a "root" group account, being actually the local Printing root disables printing any other "real" local group. */
* Administrators group. Since user name, sid and gid are
* fixed, there's no need to call print_special() for this.
*/
printf ("root:S-1-5-32-544:0:\n"); printf ("root:S-1-5-32-544:0:\n");
} }
if (disp_groupname == NULL)
{
/*
* Get 'system' group
*/
print_special (print_sids, &sid_nt_auth, 1, SECURITY_LOCAL_SYSTEM_RID,
0, 0, 0, 0, 0, 0, 0);
/*
* Get 'None' group
*/
len = INTERNET_MAX_HOST_NAME_LENGTH + 1;
GetComputerName (machine, &len);
len = MAX_SID_LEN;
len2 = MAX_DOMAIN_NAME_LEN + 1;
if (LookupAccountName (NULL, machine, (PSID) sid, &len, dom, &len2, &use))
psid = (PSID) sid;
else else
for (i = 0; i < print_local; ++i)
{ {
ret = LsaOpenPolicy (NULL, &oa, POLICY_VIEW_LOCAL_INFORMATION, &lsa); if (locals[i].str)
if (ret == STATUS_SUCCESS && lsa != INVALID_HANDLE_VALUE)
{ {
ret = LsaQueryInformationPolicy (lsa, if (!enum_local_groups (FALSE, locals + i, sep_char,
PolicyPrimaryDomainInformation, id_offset * off, disp_groupname))
(void *) &pdi); enum_groups (FALSE, locals + i, sep_char, id_offset * off++,
if (ret == STATUS_SUCCESS)
{
if (pdi->Sid)
{
CopySid (MAX_SID_LEN, (PSID) sid, pdi->Sid);
psid = (PSID) sid;
}
LsaFreeMemory (pdi);
}
LsaClose (lsa);
}
}
if (!psid)
fprintf (stderr,
"WARNING: Machine local group 513 couldn't get retrieved. Try mkgroup -d\n");
else
print_special (print_sids, GetSidIdentifierAuthority (psid), 5,
*GetSidSubAuthority (psid, 0),
*GetSidSubAuthority (psid, 1),
*GetSidSubAuthority (psid, 2),
*GetSidSubAuthority (psid, 3),
513,
0,
0,
0);
}
if (!isRoot)
enum_local_groups (NULL, print_sids, print_users, 0, disp_groupname);
}
i = 1;
if (print_domain)
do
{
PDOMAIN_CONTROLLER_INFOW pdci = NULL;
if (dsgetdcname)
{
if (domain_specified)
{
mbstowcs (domain_name, argv[optind], strlen (argv[optind]) + 1);
rc = dsgetdcname (NULL, domain_name, NULL, NULL, 0, &pdci);
}
else
rc = dsgetdcname (NULL, NULL, NULL, NULL, 0, &pdci);
if (rc != ERROR_SUCCESS)
{
print_win_error(rc);
return 1;
}
servername = pdci->DomainControllerName;
}
else
{
rc = NetGetDCName (NULL, NULL, (void *) &servername);
if (rc == ERROR_SUCCESS && domain_specified)
{
LPWSTR server = servername;
mbstowcs (domain_name, argv[optind], strlen (argv[optind]) + 1);
rc = NetGetDCName (NULL, domain_name, (void *) &servername);
NetApiBufferFree (server);
}
if (rc != ERROR_SUCCESS)
{
print_win_error(rc);
return 1;
}
}
enum_groups (servername, print_sids, print_users, id_offset * i,
disp_groupname); disp_groupname);
enum_local_groups (servername, print_sids, print_users, id_offset * i++,
disp_groupname);
NetApiBufferFree (pdci ? (PVOID) pdci : (PVOID) servername);
} }
while (++optind < argc); else if (!enum_local_groups (FALSE, locals + i, sep_char, 0,
disp_groupname))
enum_groups (FALSE, locals + i, sep_char, 0, disp_groupname);
}
if (print_current && !print_domain) for (i = 0; i < print_domain; ++i)
current_group (print_sids, print_users, id_offset); {
if (!enum_local_groups (TRUE, domains + i, sep_char, id_offset * off,
disp_groupname))
enum_groups (TRUE, domains + i, sep_char, id_offset * off++,
disp_groupname);
}
if (print_current)
current_group (sep_char, id_offset);
return 0; return 0;
} }

View File

@ -9,21 +9,23 @@
Cygwin license. Please consult the file "CYGWIN_LICENSE" for Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */ details. */
#define _WIN32_WINNT 0x0600
#include <ctype.h> #include <ctype.h>
#include <stdlib.h> #include <stdlib.h>
#include <wchar.h> #include <wchar.h>
#include <stdio.h> #include <stdio.h>
#include <windows.h>
#include <io.h>
#include <unistd.h> #include <unistd.h>
#include <sys/cygwin.h>
#include <getopt.h> #include <getopt.h>
#include <lmaccess.h> #include <io.h>
#include <lmapibuf.h>
#include <sys/fcntl.h> #include <sys/fcntl.h>
#include <lmerr.h> #include <sys/cygwin.h>
#include <lmcons.h> #include <windows.h>
#include <lm.h>
#include <iptypes.h> #include <iptypes.h>
#include <wininet.h>
#include <ntsecapi.h>
#include <dsgetdc.h>
#include <ntdef.h>
#define print_win_error(x) _print_win_error(x, __LINE__) #define print_win_error(x) _print_win_error(x, __LINE__)
@ -31,29 +33,41 @@
static const char version[] = "$Revision$"; static const char version[] = "$Revision$";
extern char *__progname;
SID_IDENTIFIER_AUTHORITY sid_world_auth = {SECURITY_WORLD_SID_AUTHORITY}; SID_IDENTIFIER_AUTHORITY sid_world_auth = {SECURITY_WORLD_SID_AUTHORITY};
SID_IDENTIFIER_AUTHORITY sid_nt_auth = {SECURITY_NT_AUTHORITY}; SID_IDENTIFIER_AUTHORITY sid_nt_auth = {SECURITY_NT_AUTHORITY};
typedef struct {
LPWSTR DomainControllerName;
LPWSTR DomainControllerAddress;
ULONG DomainControllerAddressType;
GUID DomainGuid;
LPWSTR DomainName;
LPWSTR DnsForestName;
ULONG Flags;
LPWSTR DcSiteName;
LPWSTR ClientSiteName;
} *PDOMAIN_CONTROLLER_INFOW;
NET_API_STATUS WINAPI (*dsgetdcname)(LPWSTR,LPWSTR,GUID*,LPWSTR,ULONG,PDOMAIN_CONTROLLER_INFOW*); NET_API_STATUS WINAPI (*dsgetdcname)(LPWSTR,LPWSTR,GUID*,LPWSTR,ULONG,PDOMAIN_CONTROLLER_INFOW*);
#ifndef min #ifndef min
#define min(a,b) (((a)<(b))?(a):(b)) #define min(a,b) (((a)<(b))?(a):(b))
#endif #endif
typedef struct
{
char *str;
BOOL with_dom;
} domlist_t;
void void
load_netapi () _print_win_error(DWORD code, int line)
{
char buf[4096];
if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
code,
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) buf, sizeof (buf), NULL))
fprintf (stderr, "mkpasswd (%d): [%lu] %s", line, code, buf);
else
fprintf (stderr, "mkpasswd (%d): error %lu", line, code);
}
void
load_dsgetdcname ()
{ {
HANDLE h = LoadLibrary ("netapi32.dll"); HANDLE h = LoadLibrary ("netapi32.dll");
@ -61,6 +75,53 @@ load_netapi ()
dsgetdcname = (void *) GetProcAddress (h, "DsGetDcNameW"); dsgetdcname = (void *) GetProcAddress (h, "DsGetDcNameW");
} }
static PWCHAR
get_dcname (char *domain)
{
static WCHAR server[INTERNET_MAX_HOST_NAME_LENGTH + 1];
DWORD rc;
PWCHAR servername;
WCHAR domain_name[MAX_DOMAIN_NAME_LEN + 1];
PDOMAIN_CONTROLLER_INFOW pdci = NULL;
if (dsgetdcname)
{
if (domain)
{
mbstowcs (domain_name, domain, strlen (domain) + 1);
rc = dsgetdcname (NULL, domain_name, NULL, NULL, 0, &pdci);
}
else
rc = dsgetdcname (NULL, NULL, NULL, NULL, 0, &pdci);
if (rc != ERROR_SUCCESS)
{
print_win_error(rc);
return (PWCHAR) -1;
}
wcscpy (server, pdci->DomainControllerName);
NetApiBufferFree (pdci);
}
else
{
rc = NetGetDCName (NULL, NULL, (void *) &servername);
if (rc == ERROR_SUCCESS && domain)
{
LPWSTR server = servername;
mbstowcs (domain_name, domain, strlen (domain) + 1);
rc = NetGetDCName (server, domain_name, (void *) &servername);
NetApiBufferFree (server);
}
if (rc != ERROR_SUCCESS)
{
print_win_error(rc);
return (PWCHAR) -1;
}
wcscpy (server, servername);
NetApiBufferFree ((PVOID) servername);
}
return server;
}
char * char *
put_sid (PSID sid) put_sid (PSID sid)
{ {
@ -112,68 +173,50 @@ uni2ansi (LPWSTR wcs, char *mbs, int size)
} }
void void
_print_win_error(DWORD code, int line) current_user (int print_cygpath, const char *sep, const char *passed_home_path,
int id_offset, const char *disp_username)
{ {
char buf[4096];
if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
code,
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) buf, sizeof (buf), NULL))
fprintf (stderr, "mkpasswd (%d): [%lu] %s", line, code, buf);
else
fprintf (stderr, "mkpasswd (%d): error %lu", line, code);
}
void
current_user (int print_sids, int print_cygpath,
const char * passed_home_path, int id_offset, const char * disp_username)
{
char name[UNLEN + 1], *envname, *envdomain;
DWORD len; DWORD len;
HANDLE ptok; HANDLE ptok;
int errpos = 0;
struct { struct {
PSID psid; PSID psid;
int buffer[10]; int buffer[10];
} tu, tg; } tu, tg;
char user[UNLEN + 1];
char dom[MAX_DOMAIN_NAME_LEN + 1];
DWORD ulen = UNLEN + 1;
DWORD dlen = MAX_DOMAIN_NAME_LEN + 1;
SID_NAME_USE acc_type;
int uid, gid;
char homedir_psx[PATH_MAX] = {0}, homedir_w32[MAX_PATH] = {0};
if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &ptok)
if ((!GetUserName (name, (len = sizeof (name), &len)) && (errpos = __LINE__)) || !GetTokenInformation (ptok, TokenUser, &tu, sizeof tu, &len)
|| !name[0] || !GetTokenInformation (ptok, TokenPrimaryGroup, &tg, sizeof tg, &len)
|| !(envname = getenv("USERNAME")) || !CloseHandle (ptok)
|| strcasecmp (envname, name) || !LookupAccountSidA (NULL, tu.psid, user, &ulen, dom, &dlen, &acc_type))
|| (disp_username && strcasecmp(envname, disp_username))
|| (!GetComputerName (name, (len = sizeof (name), &len))
&& (errpos = __LINE__))
|| !(envdomain = getenv("USERDOMAIN"))
|| !envdomain[0]
|| !strcasecmp (envdomain, name)
|| (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &ptok)
&& (errpos = __LINE__))
|| (!GetTokenInformation (ptok, TokenUser, &tu, sizeof tu, &len)
&& (errpos = __LINE__))
|| (!GetTokenInformation (ptok, TokenPrimaryGroup, &tg, sizeof tg, &len)
&& (errpos = __LINE__))
|| (!CloseHandle (ptok) && (errpos = __LINE__)))
{ {
if (errpos) print_win_error (GetLastError ());
_print_win_error (GetLastError (), errpos);
return; return;
} }
int uid = *GetSidSubAuthority (tu.psid, *GetSidSubAuthorityCount(tu.psid) - 1); uid = *GetSidSubAuthority (tu.psid, *GetSidSubAuthorityCount(tu.psid) - 1);
int gid = *GetSidSubAuthority (tg.psid, *GetSidSubAuthorityCount(tg.psid) - 1); gid = *GetSidSubAuthority (tg.psid, *GetSidSubAuthorityCount(tg.psid) - 1);
char homedir_psx[MAX_PATH] = {0}, homedir_w32[MAX_PATH] = {0}; if (passed_home_path[0] == '\0')
{
char *envhome = getenv ("HOME");
char *envhomedrive = getenv ("HOMEDRIVE"); char *envhomedrive = getenv ("HOMEDRIVE");
char *envhomepath = getenv ("HOMEPATH"); char *envhomepath = getenv ("HOMEPATH");
if (passed_home_path[0] == '\0') if (envhome && envhome[0])
{ {
if (envhomepath && envhomepath[0]) if (print_cygpath)
cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_ABSOLUTE, envhome,
homedir_psx, PATH_MAX);
else
psx_dir (envhome, homedir_psx);
}
else if (envhomepath && envhomepath[0])
{ {
if (envhomedrive) if (envhomedrive)
strlcpy (homedir_w32, envhomedrive, sizeof (homedir_w32)); strlcpy (homedir_w32, envhomedrive, sizeof (homedir_w32));
@ -182,41 +225,43 @@ current_user (int print_sids, int print_cygpath,
strlcat (homedir_w32, envhomepath, sizeof (homedir_w32)); strlcat (homedir_w32, envhomepath, sizeof (homedir_w32));
if (print_cygpath) if (print_cygpath)
cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_ABSOLUTE, homedir_w32, cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_ABSOLUTE, homedir_w32,
homedir_psx, MAX_PATH); homedir_psx, PATH_MAX);
else else
psx_dir (homedir_w32, homedir_psx); psx_dir (homedir_w32, homedir_psx);
} }
else else
{ {
strlcpy (homedir_psx, "/home/", sizeof (homedir_psx)); strlcpy (homedir_psx, "/home/", sizeof (homedir_psx));
strlcat (homedir_psx, envname, sizeof (homedir_psx)); strlcat (homedir_psx, user, sizeof (homedir_psx));
} }
} }
else else
{ {
strlcpy (homedir_psx, passed_home_path, sizeof (homedir_psx)); strlcpy (homedir_psx, passed_home_path, sizeof (homedir_psx));
strlcat (homedir_psx, envname, sizeof (homedir_psx)); strlcat (homedir_psx, user, sizeof (homedir_psx));
} }
printf ("%s:unused:%u:%u:%s%s%s%s%s%s%s%s:%s:/bin/bash\n", printf ("%s%s%s:unused:%u:%u:U-%s\\%s,%s:%s:/bin/bash\n",
envname, sep ? dom : "",
sep ?: "",
user,
uid + id_offset, uid + id_offset,
gid + id_offset, gid + id_offset,
envname, dom,
print_sids ? "," : "", user,
print_sids ? "U-" : "", put_sid (tu.psid),
print_sids ? envdomain : "",
print_sids ? "\\" : "",
print_sids ? envname : "",
print_sids ? "," : "",
print_sids ? put_sid (tu.psid) : "",
homedir_psx); homedir_psx);
} }
int int
enum_users (LPWSTR servername, int print_sids, int print_cygpath, enum_users (BOOL domain, domlist_t *dom_or_machine, const char *sep,
const char * passed_home_path, int id_offset, char *disp_username) int print_cygpath, const char *passed_home_path, int id_offset,
char *disp_username)
{ {
WCHAR machine[INTERNET_MAX_HOST_NAME_LENGTH + 1];
PWCHAR servername = NULL;
char *d_or_m = dom_or_machine ? dom_or_machine->str : NULL;
BOOL with_dom = dom_or_machine ? dom_or_machine->with_dom : FALSE;
USER_INFO_3 *buffer; USER_INFO_3 *buffer;
DWORD entriesread = 0; DWORD entriesread = 0;
DWORD totalentries = 0; DWORD totalentries = 0;
@ -224,6 +269,24 @@ enum_users (LPWSTR servername, int print_sids, int print_cygpath,
DWORD rc; DWORD rc;
WCHAR uni_name[UNLEN + 1]; WCHAR uni_name[UNLEN + 1];
if (domain)
{
servername = get_dcname (d_or_m);
if (servername == (PWCHAR) -1)
return 1;
}
else if (d_or_m)
{
int ret = mbstowcs (machine, d_or_m, INTERNET_MAX_HOST_NAME_LENGTH + 1);
if (ret < 1 || ret >= INTERNET_MAX_HOST_NAME_LENGTH + 1)
{
fprintf (stderr, "%s: Invalid machine name '%s'. Skipping...\n",
__progname, d_or_m);
return 1;
}
servername = machine;
}
do do
{ {
DWORD i; DWORD i;
@ -243,7 +306,7 @@ enum_users (LPWSTR servername, int print_sids, int print_cygpath,
{ {
case ERROR_ACCESS_DENIED: case ERROR_ACCESS_DENIED:
print_win_error(rc); print_win_error(rc);
exit (1); return 1;
case ERROR_MORE_DATA: case ERROR_MORE_DATA:
case ERROR_SUCCESS: case ERROR_SUCCESS:
@ -251,7 +314,7 @@ enum_users (LPWSTR servername, int print_sids, int print_cygpath,
default: default:
print_win_error(rc); print_win_error(rc);
exit (1); return 1;
} }
for (i = 0; i < entriesread; i++) for (i = 0; i < entriesread; i++)
@ -289,8 +352,6 @@ enum_users (LPWSTR servername, int print_sids, int print_cygpath,
stpcpy (homedir_psx, passed_home_path), stpcpy (homedir_psx, passed_home_path),
PATH_MAX - strlen (passed_home_path)); PATH_MAX - strlen (passed_home_path));
if (print_sids)
{
if (!LookupAccountNameW (servername, buffer[i].usri3_name, if (!LookupAccountNameW (servername, buffer[i].usri3_name,
psid, &sid_length, domain_name, psid, &sid_length, domain_name,
&domname_len, &acc_type)) &domname_len, &acc_type))
@ -317,20 +378,19 @@ enum_users (LPWSTR servername, int print_sids, int print_cygpath,
continue; continue;
} }
} }
}
printf ("%ls:unused:%u:%u:%ls%s%s%ls%s%ls%s%s:%s:/bin/bash\n", printf ("%ls%s%ls:unused:%u:%u:%ls%sU-%ls\\%ls,%s:%s:/bin/bash\n",
with_dom ? domain_name : L"",
with_dom ? sep : "",
buffer[i].usri3_name, buffer[i].usri3_name,
uid + id_offset, uid + id_offset,
gid + id_offset, gid + id_offset,
buffer[i].usri3_full_name ?: L"", buffer[i].usri3_full_name ?: L"",
print_sids && buffer[i].usri3_full_name buffer[i].usri3_full_name
&& buffer[i].usri3_full_name[0] ? "," : "", && buffer[i].usri3_full_name[0] ? "," : "",
print_sids ? "U-" : "", domain_name,
print_sids ? domain_name : L"", buffer[i].usri3_name,
print_sids && domain_name[0] ? "\\" : "", put_sid (psid),
print_sids ? buffer[i].usri3_full_name : L"",
print_sids ? "," : "",
print_sids ? put_sid (psid) : "",
homedir_psx); homedir_psx);
} }
@ -342,90 +402,8 @@ enum_users (LPWSTR servername, int print_sids, int print_cygpath,
return 0; return 0;
} }
int
enum_local_groups (int print_sids)
{
LOCALGROUP_INFO_0 *buffer;
DWORD entriesread = 0;
DWORD totalentries = 0;
DWORD resume_handle = 0;
DWORD rc ;
do
{
DWORD i;
rc = NetLocalGroupEnum (NULL, 0, (void *) &buffer, 1024,
&entriesread, &totalentries, &resume_handle);
switch (rc)
{
case ERROR_ACCESS_DENIED:
print_win_error(rc);
exit (1);
case ERROR_MORE_DATA:
case ERROR_SUCCESS:
break;
default:
print_win_error(rc);
exit (1);
}
for (i = 0; i < entriesread; i++)
{
WCHAR domain_name[MAX_DOMAIN_NAME_LEN + 1];
DWORD domname_len = MAX_DOMAIN_NAME_LEN + 1;
char psid_buffer[MAX_SID_LEN];
PSID psid = (PSID) psid_buffer;
DWORD sid_length = MAX_SID_LEN;
DWORD gid;
SID_NAME_USE acc_type;
if (!LookupAccountNameW (NULL, buffer[i].lgrpi0_name, psid,
&sid_length, domain_name, &domname_len,
&acc_type))
{
print_win_error(GetLastError ());
fprintf(stderr, " (%ls)\n", buffer[i].lgrpi0_name);
continue;
}
else if (acc_type == SidTypeDomain)
{
WCHAR domname[MAX_DOMAIN_NAME_LEN + GNLEN + 2];
wcscpy (domname, domain_name);
wcscat (domname, L"\\");
wcscat (domname, buffer[i].lgrpi0_name);
sid_length = MAX_SID_LEN;
domname_len = MAX_DOMAIN_NAME_LEN + 1;
if (!LookupAccountNameW (NULL, domname, psid, &sid_length,
domain_name, &domname_len, &acc_type))
{
print_win_error(GetLastError ());
fprintf(stderr, " (%ls)\n", domname);
continue;
}
}
gid = *GetSidSubAuthority (psid, *GetSidSubAuthorityCount(psid) - 1);
printf ("%ls:*:%ld:%ld:%s%s::\n", buffer[i].lgrpi0_name, gid, gid,
print_sids ? "," : "",
print_sids ? put_sid (psid) : "");
}
NetApiBufferFree (buffer);
}
while (rc == ERROR_MORE_DATA);
return 0;
}
void void
print_special (int print_sids, print_special (PSID_IDENTIFIER_AUTHORITY auth, BYTE cnt,
PSID_IDENTIFIER_AUTHORITY auth, BYTE cnt,
DWORD sub1, DWORD sub2, DWORD sub3, DWORD sub4, DWORD sub1, DWORD sub2, DWORD sub3, DWORD sub4,
DWORD sub5, DWORD sub6, DWORD sub7, DWORD sub8) DWORD sub5, DWORD sub6, DWORD sub7, DWORD sub8)
{ {
@ -458,58 +436,70 @@ print_special (int print_sids,
rid = sub2; rid = sub2;
else else
rid = sub1; rid = sub1;
printf ("%s:*:%lu:%lu:%s%s::\n", printf ("%s:*:%lu:%lu:,%s::\n",
name, rid, rid == 18 ? 544 : rid, /* SYSTEM hack */ name, rid, rid == 18 ? 544 : rid, /* SYSTEM hack */
print_sids ? "," : "", put_sid (sid));
print_sids ? put_sid (sid) : "");
} }
FreeSid (sid); FreeSid (sid);
} }
} }
int int
usage (FILE * stream, int isNT) usage (FILE * stream)
{ {
fprintf (stream, "Usage: mkpasswd [OPTION]... [domain]...\n" fprintf (stream,
"Print /etc/passwd file to stdout\n\n" "Usage: mkpasswd [OPTIONS]...\n"
"Options:\n"); "Print /etc/passwd file to stdout\n"
if (isNT) "\n"
fprintf (stream, " -l,--local print local user accounts\n" "Options:\n"
" -c,--current print current account, if a domain account\n" " -l,--local [machine] print local user accounts (from local machine\n"
" -d,--domain print domain accounts (from current domain\n" " if no machine specified)\n"
" if no domains specified)\n" " -L,--Local [machine] ditto, but generate username with machine prefix\n"
" -d,--domain [domain] print domain accounts (from current domain\n"
" if no domain specified)\n"
" -D,--Domain [domain] ditto, but generate username with domain prefix\n"
" -c,--current print current user\n"
" -C,--Current ditto, but generate username with machine or\n"
" domain prefix\n"
" -S,--separator char for -L, -D, -C use character char as domain\\user\n"
" separator in username instead of the default '\\'\n"
" -o,--id-offset offset change the default offset (10000) added to uids\n" " -o,--id-offset offset change the default offset (10000) added to uids\n"
" in domain accounts.\n" " in domain or foreign server accounts.\n"
" -g,--local-groups print local group information too\n"
" if no domain specified\n"
" -m,--no-mount don't use mount points for home dir\n"
" -s,--no-sids don't print SIDs in GCOS field\n"
" (this affects ntsec)\n");
fprintf (stream, " -p,--path-to-home path use specified path and not user account home dir or /home\n"
" -u,--username username only return information for the specified user\n" " -u,--username username only return information for the specified user\n"
" one of -l, -L, -d, -D must be specified, too\n"
" -p,--path-to-home path use specified path instead of user account home dir\n"
" or /home prefix\n"
" -m,--no-mount don't use mount points for home dir\n"
" -s,--no-sids (ignored)\n"
" -g,--local-groups (ignored)\n"
" -h,--help displays this message\n" " -h,--help displays this message\n"
" -v,--version version information and exit\n\n"); " -v,--version version information and exit\n"
if (isNT) "\n"
fprintf (stream, "One of '-l', '-d' or '-g' must be given.\n"); "Default is to print local accounts on stand-alone machines, domain accounts\n"
"on domain controllers and domain member machines.\n");
return 1; return 1;
} }
struct option longopts[] = { struct option longopts[] = {
{"local", no_argument, NULL, 'l'},
{"current", no_argument, NULL, 'c'}, {"current", no_argument, NULL, 'c'},
{"domain", no_argument, NULL, 'd'}, {"Current", no_argument, NULL, 'C'},
{"id-offset", required_argument, NULL, 'o'}, {"domain", optional_argument, NULL, 'd'},
{"Domain", optional_argument, NULL, 'D'},
{"local-groups", no_argument, NULL, 'g'}, {"local-groups", no_argument, NULL, 'g'},
{"no-mount", no_argument, NULL, 'm'},
{"no-sids", no_argument, NULL, 's'},
{"path-to-home", required_argument, NULL, 'p'},
{"username", required_argument, NULL, 'u'},
{"help", no_argument, NULL, 'h'}, {"help", no_argument, NULL, 'h'},
{"local", optional_argument, NULL, 'l'},
{"Local", optional_argument, NULL, 'L'},
{"no-mount", no_argument, NULL, 'm'},
{"id-offset", required_argument, NULL, 'o'},
{"path-to-home", required_argument, NULL, 'p'},
{"no-sids", no_argument, NULL, 's'},
{"separator", required_argument, NULL, 'S'},
{"username", required_argument, NULL, 'u'},
{"version", no_argument, NULL, 'v'}, {"version", no_argument, NULL, 'v'},
{0, no_argument, NULL, 0} {0, no_argument, NULL, 0}
}; };
char opts[] = "lcdo:gsmhp:u:v"; char opts[] = "cCd::D::ghl::L::mo:sS:p:u:v";
static void static void
print_version () print_version ()
@ -534,55 +524,142 @@ Compiled on %s\n\
", len, v, __DATE__); ", len, v, __DATE__);
} }
static void
enum_std_accounts ()
{
/* Generate service starter account entries. */
printf ("SYSTEM:*:18:544:,S-1-5-18::\n");
printf ("LocalService:*:19:544:U-NT AUTHORITY\\LocalService,S-1-5-19::\n");
printf ("NetworkService:*:20:544:U-NT AUTHORITY\\NetworkService,S-1-5-20::\n");
/* Get 'administrators' group (has localized name). */
print_special (&sid_nt_auth, 2, SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0);
}
static PPOLICY_PRIMARY_DOMAIN_INFO p_dom;
static BOOL
fetch_primary_domain ()
{
NTSTATUS status;
LSA_OBJECT_ATTRIBUTES oa = { 0, 0, 0, 0, 0, 0 };
LSA_HANDLE lsa;
if (!p_dom)
{
status = LsaOpenPolicy (NULL, &oa, POLICY_VIEW_LOCAL_INFORMATION, &lsa);
if (!NT_SUCCESS (status))
return FALSE;
status = LsaQueryInformationPolicy (lsa, PolicyPrimaryDomainInformation,
(PVOID *) &p_dom);
LsaClose (lsa);
if (!NT_SUCCESS (status))
return FALSE;
}
return !!p_dom->Sid;
}
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
LPWSTR servername = NULL;
DWORD rc = ERROR_SUCCESS;
WCHAR domain_name[MAX_DOMAIN_NAME_LEN + 1];
int print_local = 0; int print_local = 0;
int print_current = 0; domlist_t locals[16];
int print_domain = 0; int print_domain = 0;
int print_local_groups = 0; domlist_t domains[16];
int domain_specified = 0; char *opt;
int print_sids = 1;
int print_cygpath = 1; int print_cygpath = 1;
int print_current = 0;
const char *sep_char = "\\";
int id_offset = 10000; int id_offset = 10000;
int i; int c, i, off;
int isNT;
char *disp_username = NULL; char *disp_username = NULL;
char name[256], passed_home_path[MAX_PATH]; char passed_home_path[PATH_MAX];
DWORD len; BOOL in_domain;
isNT = (GetVersion () < 0x80000000);
passed_home_path[0] = '\0'; passed_home_path[0] = '\0';
if (!isatty (1)) if (!isatty (1))
setmode (1, O_BINARY); setmode (1, O_BINARY);
if (isNT && argc == 1) load_dsgetdcname ();
return usage (stderr, isNT); in_domain = fetch_primary_domain ();
else if (argc == 1)
{ {
while ((i = getopt_long (argc, argv, opts, longopts, NULL)) != EOF) enum_std_accounts ();
switch (i) if (in_domain)
enum_users (TRUE, NULL, sep_char, print_cygpath, passed_home_path,
10000, disp_username);
else
enum_users (FALSE, NULL, sep_char, print_cygpath, passed_home_path, 0,
disp_username);
return 0;
}
while ((c = getopt_long (argc, argv, opts, longopts, NULL)) != EOF)
switch (c)
{ {
case 'l': case 'l':
print_local = 1; case 'L':
break; if (print_local >= 16)
case 'c': {
print_current = 1; fprintf (stderr, "%s: Can not enumerate from more than 16 "
"servers.\n", __progname);
return 1;
}
opt = optarg ?:
argv[optind] && argv[optind][0] != '-' ? argv[optind] : NULL;
for (i = 0; i < print_local; ++i)
if ((!locals[i].str && !opt)
|| (locals[i].str && opt && !strcmp (locals[i].str, opt)))
goto skip_local;
locals[print_local].str = opt;
locals[print_local++].with_dom = c == 'L';
skip_local:
break; break;
case 'd': case 'd':
print_domain = 1; case 'D':
if (print_domain >= 16)
{
fprintf (stderr, "%s: Can not enumerate from more than 16 "
"domains.\n", __progname);
return 1;
}
opt = optarg ?:
argv[optind] && argv[optind][0] != '-' ? argv[optind] : NULL;
for (i = 0; i < print_domain; ++i)
if ((!domains[i].str && !opt)
|| (domains[i].str && opt && !strcmp (domains[i].str, opt)))
goto skip_domain;
domains[print_domain].str = opt;
domains[print_domain++].with_dom = c == 'D';
skip_domain:
break;
case 'S':
sep_char = optarg;
if (strlen (sep_char) > 1)
{
fprintf (stderr, "%s: Only one character allowed as domain\\user "
"separator character.\n", __progname);
return 1;
}
if (*sep_char == ':')
{
fprintf (stderr, "%s: Colon not allowed as domain\\user separator "
"character.\n", __progname);
return 1;
}
break;
case 'c':
sep_char = NULL;
/*FALLTHRU*/
case 'C':
print_current = 1;
break; break;
case 'o': case 'o':
id_offset = strtol (optarg, NULL, 10); id_offset = strtol (optarg, NULL, 10);
break; break;
case 'g': case 'g':
print_local_groups = 1;
break; break;
case 's': case 's':
print_sids = 0;
break; break;
case 'm': case 'm':
print_cygpath = 0; print_cygpath = 0;
@ -591,7 +668,7 @@ main (int argc, char **argv)
if (optarg[0] != '/') if (optarg[0] != '/')
{ {
fprintf (stderr, "%s: '%s' is not a fully qualified path.\n", fprintf (stderr, "%s: '%s' is not a fully qualified path.\n",
argv[0], optarg); __progname, optarg);
return 1; return 1;
} }
strcpy (passed_home_path, optarg); strcpy (passed_home_path, optarg);
@ -602,134 +679,39 @@ main (int argc, char **argv)
disp_username = optarg; disp_username = optarg;
break; break;
case 'h': case 'h':
usage (stdout, isNT); usage (stdout);
return 0; return 0;
case 'v': case 'v':
print_version (); print_version ();
return 0; return 0;
default: default:
fprintf (stderr, "Try '%s --help' for more information.\n", argv[0]); fprintf (stderr, "Try '%s --help' for more information.\n", __progname);
return 1; return 1;
} }
}
if (!isNT)
{
/* This takes Windows 9x/ME into account. */
if (passed_home_path[0] == '\0')
strcpy (passed_home_path, "/home/");
if (!disp_username)
{
printf ("admin:use_crypt:%lu:%lu:Administrator:%sadmin:/bin/bash\n",
DOMAIN_USER_RID_ADMIN,
DOMAIN_ALIAS_RID_ADMINS,
passed_home_path);
if (GetUserName (name, (len = 256, &len)))
disp_username = name;
}
if (disp_username && disp_username[0])
{
/* Create a pseudo random uid */
unsigned long uid = 0, i;
for (i = 0; disp_username[i]; i++)
uid += toupper (disp_username[i]) << ((6 * i) % 25);
uid = (uid % (1000 - DOMAIN_USER_RID_ADMIN - 1))
+ DOMAIN_USER_RID_ADMIN + 1;
printf ("%s:use_crypt:%lu:%lu:%s:%s%s:/bin/bash\n", if (optind < argc - 1)
disp_username, usage (stdout);
uid,
DOMAIN_ALIAS_RID_ADMINS,
disp_username,
passed_home_path,
disp_username);
}
return 0;
}
if (!print_local && !print_domain && !print_local_groups)
{
fprintf (stderr, "%s: Specify one of '-l', '-d' or '-g'\n", argv[0]);
return 1;
}
if (optind < argc)
{
if (!print_domain)
{
fprintf (stderr, "%s: A domain name is only accepted "
"when '-d' is given.\n", argv[0]);
return 1;
}
domain_specified = 1;
}
load_netapi ();
if (disp_username == NULL) off = 1;
for (i = 0; i < print_local; ++i)
{ {
if (print_local) if (locals[i].str)
{ enum_users (FALSE, locals + i, sep_char, print_cygpath,
/* Generate service starter account entries. */ passed_home_path, id_offset * off++, disp_username);
printf ("SYSTEM:*:18:544:,S-1-5-18::\n");
printf ("LocalService:*:19:544:U-NT AUTHORITY\\LocalService,S-1-5-19::\n");
printf ("NetworkService:*:20:544:U-NT AUTHORITY\\NetworkService,S-1-5-20::\n");
/* Get 'administrators' group (has localized name). */
if (!print_local_groups)
print_special (print_sids, &sid_nt_auth, 2, SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0);
}
if (print_local_groups)
enum_local_groups (print_sids);
}
if (print_local)
enum_users (NULL, print_sids, print_cygpath, passed_home_path, 0,
disp_username);
i = 1;
if (print_domain)
do
{
PDOMAIN_CONTROLLER_INFOW pdci = NULL;
if (dsgetdcname)
{
if (domain_specified)
{
mbstowcs (domain_name, argv[optind], strlen (argv[optind]) + 1);
rc = dsgetdcname (NULL, domain_name, NULL, NULL, 0, &pdci);
}
else
rc = dsgetdcname (NULL, NULL, NULL, NULL, 0, &pdci);
if (rc != ERROR_SUCCESS)
{
print_win_error(rc);
return 1;
}
servername = pdci->DomainControllerName;
}
else else
{ {
rc = NetGetDCName (NULL, NULL, (void *) &servername); enum_std_accounts ();
if (rc == ERROR_SUCCESS && domain_specified) enum_users (FALSE, locals + i, sep_char, print_cygpath,
{ passed_home_path, 0, disp_username);
LPWSTR server = servername;
mbstowcs (domain_name, argv[optind], strlen (argv[optind]) + 1);
rc = NetGetDCName (server, domain_name, (void *) &servername);
NetApiBufferFree (server);
}
if (rc != ERROR_SUCCESS)
{
print_win_error(rc);
return 1;
} }
} }
enum_users (servername, print_sids, print_cygpath, passed_home_path,
id_offset * i++, disp_username);
NetApiBufferFree (pdci ? (PVOID) pdci : (PVOID) servername);
}
while (++optind < argc);
if (print_current && !print_domain) for (i = 0; i < print_domain; ++i)
current_user(print_sids, print_cygpath, passed_home_path, enum_users (TRUE, domains + i, sep_char, print_cygpath, passed_home_path,
id_offset, disp_username); id_offset * off++, disp_username);
if (print_current)
current_user (print_cygpath, sep_char, passed_home_path, id_offset, disp_username);
return 0; return 0;
} }

View File

@ -298,7 +298,11 @@ struct opt
{"exec", MOUNT_EXEC, 0}, {"exec", MOUNT_EXEC, 0},
{"notexec", MOUNT_NOTEXEC, 0}, {"notexec", MOUNT_NOTEXEC, 0},
{"cygexec", MOUNT_CYGWIN_EXEC, 0}, {"cygexec", MOUNT_CYGWIN_EXEC, 0},
{"nosuid", 0, 0} {"nosuid", 0, 0},
{"acl", MOUNT_NOACL, 1},
{"noacl", MOUNT_NOACL, 0},
{"posix=1", MOUNT_NOPOSIX, 1},
{"posix=0", MOUNT_NOPOSIX, 0}
}; };
static bool static bool
@ -844,6 +848,10 @@ getmntent (FILE *)
strcat (mnt.mnt_opts, (char *) ",noexec"); strcat (mnt.mnt_opts, (char *) ",noexec");
if ((m->flags & MOUNT_CYGDRIVE)) /* cygdrive */ if ((m->flags & MOUNT_CYGDRIVE)) /* cygdrive */
strcat (mnt.mnt_opts, (char *) ",cygdrive"); strcat (mnt.mnt_opts, (char *) ",cygdrive");
if ((m->flags & MOUNT_NOACL))
strcat (mnt.mnt_opts, (char *) ",noacl");
if ((m->flags & MOUNT_NOPOSIX))
strcat (mnt.mnt_opts, (char *) ",posix=0");
mnt.mnt_freq = 1; mnt.mnt_freq = 1;
mnt.mnt_passno = 1; mnt.mnt_passno = 1;
m++; m++;

View File

@ -1,6 +1,7 @@
/* ps.cc /* ps.cc
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc. Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2008 Red Hat, Inc.
This file is part of Cygwin. This file is part of Cygwin.

View File

@ -505,69 +505,75 @@ SIGUSR2 31 user defined signal 2
<sect2 id="mkgroup"><title>mkgroup</title> <sect2 id="mkgroup"><title>mkgroup</title>
<screen> <screen>
Usage: mkgroup [OPTION]... [domain]... Usage: mkgroup [OPTION]...
Prints /etc/group file to stdout Print /etc/group file to stdout
Options: Options:
-l,--local print local group information -l,--local [machine] print local groups (from local machine if no
-c,--current print current group, if a domain account machine specified)
-d,--domain print global group information (from current -L,--Local [machine] ditto, but generate groupname with machine prefix
domain if no domains specified). -d,--domain [domain] print domain groups (from current domain if no
domain specified)
-D,--Domain [domain] ditto, but generate groupname with machine prefix
-c,--current print current group
-C,--Current ditto, but generate groupname with machine or
domain prefix
-S,--separator char for -L, -D, -C use character char as domain\group
separator in groupname instead of the default '\'
-o,--id-offset offset change the default offset (10000) added to gids -o,--id-offset offset change the default offset (10000) added to gids
in domain accounts. in domain or foreign server accounts.
-s,--no-sids don't print SIDs in pwd field -g,--group groupname only return information for the specified group
(this affects ntsec) one of -l, -L, -d, -D must be specified, too
-u,--users print user list in gr_mem field -s,--no-sids (ignored)
-g,--group groupname only return information for the specified group\n"); -u,--users (ignored)
-h,--help print this message -h,--help print this message
-v,--version print version information and exit -v,--version print version information and exit
One of `-l' or `-d' must be given on NT/W2K. Default is to print local groups on stand-alone machines, plus domain
groups on domain controllers and domain member machines.
</screen> </screen>
<para>The <command>mkgroup</command> program can be used to help <para>The <command>mkgroup</command> program can be used to help
configure your Windows system to be more UNIX-like by creating an configure Cygwin by creating a <filename>/etc/group</filename>
initial <filename>/etc/group</filename>. file. Its use is essential to include Windows security information.</para>
Its use is essential on the NT series (Windows NT, 2000, and XP) to
include Windows security information.
It can also be used on the Win9x series (Windows 95, 98, and Me) to
create a file with the correct format.
To initially set up your machine if you are a local user, you'd do
something like this:</para>
<example id="utils-mkgroup-ex"><title>Setting up the groups file for local accounts</title> <para>The command is initially called by <command>setup.exe</command> to
<screen> create a default <filename>/etc/group</filename>. This should be
<prompt>$</prompt> <userinput>mkdir /etc</userinput> sufficient in most circumstances. However, especially when working
<prompt>$</prompt> <userinput>mkgroup -l &gt; /etc/group</userinput> in a multi-domain environment, you can use <command>mkgroup</command>
</screen> manually to create a more complete <filename>/etc/group</filename> file for
</example> all domains. Especially when you have the same group name used on
multiple machines or in multiple domains, you can use the <literal>-D</literal>,
<literal>-L</literal> and <literal>-C</literal> options to create unique
domain\group style groupnames.</para>
<para>Note that this information is static. If you change the group <para>Note that this information is static. If you change the group
information in your system, you'll need to regenerate the group file information in your system, you'll need to regenerate the group file
for it to have the new information.</para> for it to have the new information.</para>
<para>The <literal>-d</literal> and <literal>-l</literal> options <para>The <literal>-d/-D</literal> and <literal>-l/-L</literal> options
allow you to specify where the information comes from, the allow you to specify where the information comes from, the
local machine or the domain (default or given), or both. local SAM of a machine or from the domain, or both.
With the <literal>-d</literal> option the program contacts the Domain With the <literal>-d/-D</literal> options the program contacts a Domain
Controller, which my be unreachable or have restricted access. Controller, which my be unreachable or have restricted access.
An entry for the current domain user can then be created by using the For very simple needs, an entry for the current user's group can be
option <literal>-c</literal> together with <literal>-l</literal>, created by using the option <literal>-c</literal> or <literal>-C</literal>.
but <literal>-c</literal> has no effect when used with <literal>-d</literal>. If you want to use one of the <literal>-D</literal>, <literal>-L</literal>
The <literal>-o</literal> option allows for special cases or <literal>-C</literal> options, but you don't like the backslash as
domain/group separator, you can specify another separator using the
<literal>-S</literal> option, for instance</para>
<example id="utils-mkgroup-ex"><title>Setting up group entry for current user with different domain/group separator</title>
<screen>
<prompt>$</prompt> <userinput>mkgroup -C -S+ &gt; /etc/group</userinput>
<prompt>$</prompt> <userinput>cat /etc/group</userinput>
DOMAIN+my_group:S-1-5-21-2913048732-1697188782-3448811101-1144:11144:
</screen>
</example>
<para>The <literal>-o</literal> option allows for special cases
(such as multiple domains) where the GIDs might match otherwise. (such as multiple domains) where the GIDs might match otherwise.
The <literal>-s</literal> The <literal>-g</literal> option only prints the information for one group.
option omits the NT Security Identifier (SID). For more information on
SIDs, see <xref linkend="ntsec"></xref> in the Cygwin User's Guide. The
<literal>-u</literal> option causes <command>mkgroup</command> to
enumerate the users for each group, placing the group members in the
gr_mem (last) field. Note that this can greatly increase
the time for <command>mkgroup</command> to run in a large domain.
Having gr_mem fields is helpful when a domain user logs in remotely
while the local machine is disconnected from the Domain Controller.
The <literal>-g</literal> option only prints the information for
one group.
</para> </para>
</sect2> </sect2>
@ -575,68 +581,74 @@ one group.
<sect2 id="mkpasswd"><title>mkpasswd</title> <sect2 id="mkpasswd"><title>mkpasswd</title>
<screen> <screen>
Usage: mkpasswd [OPTION]... [domain]... Usage: mkpasswd [OPTIONS]...
Prints /etc/passwd file to stdout Print /etc/passwd file to stdout
Options: Options:
-l,--local print local user accounts -l,--local [machine] print local user accounts (from local machine
-c,--current print current account, if a domain account if no machine specified)
-d,--domain print domain accounts (from current domain -L,--Local [machine] ditto, but generate username with machine prefix
if no domains specified) -d,--domain [domain] print domain accounts (from current domain
if no domain specified)
-D,--Domain [domain] ditto, but generate username with domain prefix
-c,--current print current user
-C,--Current ditto, but generate username with machine or
domain prefix
-S,--separator char for -L, -D, -C use character char as domain\user
separator in username instead of the default '\'
-o,--id-offset offset change the default offset (10000) added to uids -o,--id-offset offset change the default offset (10000) added to uids
in domain accounts. in domain or foreign server accounts.
-g,--local-groups print local group information too
if no domains specified
-m,--no-mount don't use mount points for home dir
-s,--no-sids don't print SIDs in GCOS field
(this affects ntsec)
-p,--path-to-home path use specified path and not user account home dir or /home
-u,--username username only return information for the specified user -u,--username username only return information for the specified user
one of -l, -L, -d, -D must be specified, too
-p,--path-to-home path use specified path instead of user account home dir
or /home prefix
-m,--no-mount don't use mount points for home dir
-s,--no-sids (ignored)
-g,--local-groups (ignored)
-h,--help displays this message -h,--help displays this message
-v,--version version information and exit -v,--version version information and exit
One of `-l', `-d' or `-g' must be given on NT/W2K. Default is to print local accounts on stand-alone machines, domain accounts
on domain controllers and domain member machines.
</screen> </screen>
<para>The <command>mkpasswd</command> program can be used to help <para>The <command>mkpasswd</command> program can be used to help
configure your Windows system to be more UNIX-like by creating an configure Cygwin by creating a <filename>/etc/passwd</filename> from
initial <filename>/etc/passwd</filename> from your system information. your system information.
Its use is essential on the NT series (Windows NT, 2000, and XP) to Its use is essential to include Windows security information. However,
include Windows security information, but the actual passwords are the actual passwords are determined by Windows, not by the content of
determined by Windows, not by the content of <filename>/etc/passwd</filename>. <filename>/etc/passwd</filename>.</para>
On the Win9x series (Windows 95, 98, and Me) the password field must be
replaced by the output of <userinput>crypt your_password</userinput>
if remote access is desired.
To initially set up your machine if you are a local user, you'd do
something like this:</para>
<example id="utils-mkpasswd-ex"><title>Setting up the passwd file for local accounts</title> <para>The command is initially called by <command>setup.exe</command> to
<screen> create a default <filename>/etc/passwd</filename>. This should be
<prompt>$</prompt> <userinput>mkdir /etc</userinput> sufficient in most circumstances. However, especially when working
<prompt>$</prompt> <userinput>mkpasswd -l &gt; /etc/passwd</userinput> in a multi-domain environment, you can use <command>mkpasswd</command>
</screen> manually to create a more complete <filename>/etc/passwd</filename> file for
</example> all domains. Especially when you have the same user name used on
multiple machines or in multiple domains, you can use the <literal>-D</literal>,
<literal>-L</literal> and <literal>-C</literal> options to create unique
domain\user style usernames.</para>
<para>Note that this information is static. If you change the user <para>Note that this information is static. If you change the user
information in your system, you'll need to regenerate the passwd file information in your system, you'll need to regenerate the passwd file
for it to have the new information.</para> for it to have the new information.</para>
<para>The <literal>-d</literal> and <literal>-l</literal> options <para>The <literal>-d/-D</literal> and <literal>-l/-L</literal> options
allow you to specify where the information comes from, the allow you to specify where the information comes from, the
local machine or the domain (default or given), or both. local machine or the domain (default or given), or both.
With the <literal>-d</literal> option the program contacts the Domain With the <literal>-d/-D</literal> options the program contacts the Domain
Controller, which my be unreachable or have restricted access. Controller, which may be unreachable or have restricted access.
An entry for the current domain user can then be created by using the An entry for the current user can be created by using the
option <literal>-c</literal> together with <literal>-l</literal>, option <literal>-c</literal> or <literal>-C</literal>.
but <literal>-c</literal> has no effect when used with <literal>-d</literal>. If you want to use one of the <literal>-D</literal>, <literal>-L</literal>
or <literal>-C</literal> options, but you don't like the backslash as
domain/group separator, you can specify another separator using the
<literal>-S</literal> option, simialar to the <command>mkgroup</command>.
The <literal>-o</literal> option allows for special cases The <literal>-o</literal> option allows for special cases
(such as multiple domains) where the UIDs might match otherwise. (such as multiple domains) where the UIDs might match otherwise.
The <literal>-g</literal> option creates a local The <literal>-m</literal> option bypasses the current
user that corresponds to each local group. This is because NT assigns groups
file ownership. The <literal>-m</literal> option bypasses the current
mount table so that, for example, two users who have a Windows home mount table so that, for example, two users who have a Windows home
directory of H: could mount them differently. The <literal>-s</literal> directory of H: could mount them differently. For more information on
option omits the NT Security Identifier (SID). For more information on
SIDs, see <xref linkend="ntsec"></xref> in the Cygwin User's Guide. The SIDs, see <xref linkend="ntsec"></xref> in the Cygwin User's Guide. The
<literal>-p</literal> option causes <command>mkpasswd</command> to <literal>-p</literal> option causes <command>mkpasswd</command> to
use the specified prefix instead of the account home dir or <literal>/home/ use the specified prefix instead of the account home dir or <literal>/home/
@ -649,9 +661,8 @@ use the specified prefix instead of the account home dir or <literal>/home/
</example> </example>
would put local users' home directories in the Windows 'Profiles' directory. would put local users' home directories in the Windows 'Profiles' directory.
On Win9x machines the <literal>-u</literal> option creates an entry for The <literal>-u</literal> option creates just an entry for
the specified user. On the NT series it restricts the output to that user, the specified user.</para>
greatly reducing the amount of time it takes in a large domain.</para>
</sect2> </sect2>