* 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>
* 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)}}
zconf_h := ${patsubst %/zlib.h,%/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
all: warn_cygcheck_zlib
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]);
/* 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
get_process_list (void)
{
int n_procs = 0x100;
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)
{
n_procs *= 2;
@ -141,7 +130,7 @@ get_module_list (void)
int modsize = 0x1000;
PSYSTEM_MODULE_INFORMATION modlist = (PSYSTEM_MODULE_INFORMATION) malloc (modsize);
while (pNtQuerySystemInformation (SystemModuleInformation,
while (NtQuerySystemInformation (SystemModuleInformation,
modlist, modsize, NULL) == STATUS_INFO_LENGTH_MISMATCH)
{
modsize *= 2;
@ -299,14 +288,14 @@ detect_dodgy_app (const struct bad_app_det *det, PSYSTEM_PROCESSES pslist, PSYST
/* Equivalent of RtlInitAnsiString. */
ansiname.Length = ansiname.MaximumLength = strlen (det->param);
ansiname.Buffer = (CHAR *) det->param;
rv = pRtlAnsiStringToUnicodeString (&unicodename, &ansiname, TRUE);
rv = RtlAnsiStringToUnicodeString (&unicodename, &ansiname, TRUE);
if (rv != STATUS_SUCCESS)
{
printf ("Ansi to unicode conversion failure $%08x\n", (unsigned int) rv);
break;
}
found = find_process_in_list (pslist, &unicodename);
pRtlFreeUnicodeString (&unicodename);
RtlFreeUnicodeString (&unicodename);
if (found)
{
dbg_printf (("found!\n"));
@ -347,25 +336,6 @@ dump_dodgy_apps (int verbose)
size_t i, n_det = 0;
PSYSTEM_PROCESSES pslist;
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. */
pslist = get_process_list ();

View File

@ -1,6 +1,6 @@
/* cygpath.cc -- convert pathnames between Windows and Unix format
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.
@ -529,8 +529,7 @@ get_special_folder (char* path, int id)
static void
get_user_folder (char* path, int id, int allid)
{
if (!get_special_folder (path, allusers_flag ? allid : id) && allusers_flag)
get_special_folder (path, id); // Fix for Win9x without any "All Users"
get_special_folder (path, allusers_flag ? allid : id);
}
static void
@ -740,7 +739,7 @@ print_version ()
cygpath (cygwin) %.*s\n\
Path Conversion Utility\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\
", len, v, __DATE__);
}

View File

@ -9,37 +9,31 @@
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#define _WIN32_WINNT 0x0600
#include <ctype.h>
#include <stdlib.h>
#include <wchar.h>
#include <stdio.h>
#include <windows.h>
#include <sys/cygwin.h>
#include <unistd.h>
#include <getopt.h>
#include <lmaccess.h>
#include <lmapibuf.h>
#include <io.h>
#include <sys/fcntl.h>
#include <sys/cygwin.h>
#include <windows.h>
#include <lm.h>
#include <wininet.h>
#include <iptypes.h>
#include <ntsecapi.h>
#include <dsgetdc.h>
#include <ntdef.h>
#define print_win_error(x) _print_win_error(x, __LINE__)
static const char version[] = "$Revision$";
#define MAX_SID_LEN 40
typedef struct {
LPWSTR DomainControllerName;
LPWSTR DomainControllerAddress;
ULONG DomainControllerAddressType;
GUID DomainGuid;
LPWSTR DomainName;
LPWSTR DnsForestName;
ULONG Flags;
LPWSTR DcSiteName;
LPWSTR ClientSiteName;
} *PDOMAIN_CONTROLLER_INFOW;
static const char version[] = "$Revision$";
extern char *__progname;
SID_IDENTIFIER_AUTHORITY sid_world_auth = {SECURITY_WORLD_SID_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))
#endif
typedef struct
{
char *str;
BOOL with_dom;
} domlist_t;
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");
if (h)
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 *
put_sid (PSID sid)
{
@ -76,48 +139,6 @@ put_sid (PSID sid)
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 {
BYTE Revision;
BYTE SubAuthorityCount;
@ -130,26 +151,48 @@ DBGSID builtin_sid_list[MAX_BUILTIN_SIDS];
DWORD builtin_sid_cnt;
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)
{
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;
DWORD entriesread = 0;
DWORD totalentries = 0;
DWORD resume_handle = 0;
WCHAR uni_name[GNLEN + 1];
WCHAR gname[GNLEN + 1];
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
{
DWORD i;
if (disp_groupname != NULL)
{
mbstowcs (uni_name, disp_groupname, GNLEN + 1);
mbstowcs (gname, disp_groupname, GNLEN + 1);
rc = NetApiBufferAllocate (sizeof (LOCALGROUP_INFO_0),
(void *) &buffer);
buffer[0].lgrpi0_name = uni_name;
buffer[0].lgrpi0_name = gname;
entriesread = 1;
}
else
@ -159,16 +202,16 @@ enum_local_groups (LPWSTR servername, int print_sids, int print_users,
switch (rc)
{
case ERROR_ACCESS_DENIED:
print_win_error(rc);
exit (1);
print_win_error (rc);
return 1;
case ERROR_MORE_DATA:
case ERROR_SUCCESS:
break;
default:
print_win_error(rc);
exit (1);
print_win_error (rc);
return 1;
}
for (i = 0; i < entriesread; i++)
@ -187,7 +230,7 @@ enum_local_groups (LPWSTR servername, int print_sids, int print_users,
&sid_length, domain_name, &domname_len,
&acc_type))
{
print_win_error(rc);
print_win_error (rc);
fprintf (stderr, " (%ls)\n", buffer[i].lgrpi0_name);
continue;
}
@ -205,7 +248,7 @@ enum_local_groups (LPWSTR servername, int print_sids, int print_users,
domain_name, &domname_len,
&acc_type))
{
print_win_error(rc);
print_win_error (rc);
fprintf(stderr, " (%ls)\n", domname);
continue;
}
@ -232,12 +275,12 @@ enum_local_groups (LPWSTR servername, int print_sids, int print_users,
gid = *GetSidSubAuthority (psid, *GetSidSubAuthorityCount(psid) - 1);
printf ("%ls:%s:%ld:", buffer[i].lgrpi0_name,
print_sids ? put_sid (psid) : "",
gid + (is_builtin ? 0 : id_offset));
if (print_users)
enum_local_users (servername, buffer[i].lgrpi0_name);
printf ("\n");
printf ("%ls%s%ls:%s:%ld:\n",
with_dom ? domain_name : L"",
with_dom ? sep : "",
buffer[i].lgrpi0_name,
put_sid (psid),
gid + (is_builtin ? 0 : id_offset));
skip_group:
;
}
@ -251,48 +294,46 @@ skip_group:
}
void
enum_users (LPWSTR servername, LPWSTR 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)
enum_groups (BOOL domain, domlist_t *dom_or_machine, const char *sep,
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;
DWORD entriesread = 0;
DWORD totalentries = 0;
DWORD resume_handle = 0;
WCHAR uni_name[GNLEN + 1];
WCHAR gname[GNLEN + 1];
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
{
DWORD i;
if (disp_groupname != NULL)
{
mbstowcs (uni_name, disp_groupname, GNLEN + 1);
rc = NetGroupGetInfo (servername, (LPWSTR) & uni_name, 2,
mbstowcs (gname, disp_groupname, GNLEN + 1);
rc = NetGroupGetInfo (servername, (LPWSTR) & gname, 2,
(void *) &buffer);
entriesread=1;
}
@ -303,16 +344,16 @@ enum_groups (LPWSTR servername, int print_sids, int print_users, int id_offset,
switch (rc)
{
case ERROR_ACCESS_DENIED:
print_win_error(rc);
exit (1);
print_win_error (rc);
return;
case ERROR_MORE_DATA:
case ERROR_SUCCESS:
break;
default:
print_win_error(rc);
exit (1);
print_win_error (rc);
return;
}
for (i = 0; i < entriesread; i++)
@ -325,43 +366,40 @@ enum_groups (LPWSTR servername, int print_sids, int print_users, int id_offset,
SID_NAME_USE acc_type;
int gid = buffer[i].grpi2_group_id;
if (print_sids)
{
if (!LookupAccountNameW (servername, buffer[i].grpi2_name,
psid, &sid_length,
domain_name, &domname_len,
&acc_type))
{
print_win_error(rc);
fprintf(stderr, " (%ls)\n", buffer[i].grpi2_name);
continue;
}
else if (acc_type == SidTypeDomain)
{
WCHAR domname[MAX_DOMAIN_NAME_LEN + GNLEN + 2];
if (!LookupAccountNameW (servername, buffer[i].grpi2_name,
psid, &sid_length,
domain_name, &domname_len,
&acc_type))
{
print_win_error (rc);
fprintf(stderr, " (%ls)\n", buffer[i].grpi2_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].grpi2_name);
sid_length = MAX_SID_LEN;
domname_len = MAX_DOMAIN_NAME_LEN + 1;
if (!LookupAccountNameW (servername, domname,
psid, &sid_length,
domain_name, &domname_len,
&acc_type))
{
print_win_error(rc);
fprintf(stderr, " (%ls)\n", domname);
continue;
}
}
}
printf ("%ls:%s:%u:", buffer[i].grpi2_name,
print_sids ? put_sid (psid) : "",
gid + id_offset);
if (print_users)
enum_users (servername, buffer[i].grpi2_name);
printf ("\n");
wcscpy (domname, domain_name);
wcscat (domname, L"\\");
wcscat (domname, buffer[i].grpi2_name);
sid_length = MAX_SID_LEN;
domname_len = MAX_DOMAIN_NAME_LEN + 1;
if (!LookupAccountNameW (servername, domname,
psid, &sid_length,
domain_name, &domname_len,
&acc_type))
{
print_win_error (rc);
fprintf(stderr, " (%ls)\n", domname);
continue;
}
}
printf ("%ls%s%ls:%s:%u:\n",
with_dom ? domain_name : L"",
with_dom ? sep : "",
buffer[i].grpi2_name,
put_sid (psid),
gid + id_offset);
}
NetApiBufferFree (buffer);
@ -371,8 +409,7 @@ enum_groups (LPWSTR servername, int print_sids, int print_users, int id_offset,
}
void
print_special (int print_sids,
PSID_IDENTIFIER_AUTHORITY auth, BYTE cnt,
print_special (PSID_IDENTIFIER_AUTHORITY auth, BYTE cnt,
DWORD sub1, DWORD sub2, DWORD sub3, DWORD sub4,
DWORD sub5, DWORD sub6, DWORD sub7, DWORD sub8)
{
@ -405,97 +442,96 @@ print_special (int print_sids,
rid = sub2;
else
rid = sub1;
printf ("%s:%s:%lu:\n", name,
print_sids ? put_sid (sid) : "",
rid);
printf ("%s:%s:%lu:\n", name, put_sid (sid), rid);
}
FreeSid (sid);
}
}
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;
HANDLE ptok;
int errpos = 0;
struct {
PSID psid;
char buffer[MAX_SID_LEN];
} 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 ((!GetUserName (name, (len = sizeof (name), &len)) && (errpos = __LINE__))
|| !name[0]
|| !(envname = getenv("USERNAME"))
|| 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 (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &ptok)
|| !GetTokenInformation (ptok, TokenPrimaryGroup, &tg, sizeof tg, &len)
|| !CloseHandle (ptok)
|| !LookupAccountSidA (NULL, tg.psid, grp, &glen, dom, &dlen, &acc_type))
{
if (errpos)
{
print_win_error (GetLastError ());
}
print_win_error (GetLastError ());
return;
}
int gid = *GetSidSubAuthority (tg.psid, *GetSidSubAuthorityCount(tg.psid) - 1);
printf ("mkgroup_l_d:%s:%u:", print_sids ? put_sid (tg.psid) : "",
gid + id_offset);
if (print_users)
printf("%s", envname);
printf ("\n");
gid = *GetSidSubAuthority (tg.psid, *GetSidSubAuthorityCount(tg.psid) - 1);
printf ("%s%s%s:%s:%u:\n",
sep ? dom : "",
sep ?: "",
grp,
put_sid (tg.psid),
gid + id_offset);
}
int
usage (FILE * stream, int isNT)
usage (FILE * stream)
{
fprintf (stream, "Usage: mkgroup [OPTION]... [domain]...\n"
"Print /etc/group file to stdout\n\n"
"Options:\n");
if (isNT)
fprintf (stream, " -l,--local print machine local group information\n"
" -c,--current print current group, if a domain account\n"
" -d,--domain print domain group information (from current\n"
" domain if no domains specified)\n"
" -o,--id-offset offset change the default offset (10000) added to gids\n"
" in domain accounts.\n"
" -s,--no-sids don't print SIDs in pwd field\n"
" (this affects ntsec)\n"
" -u,--users print user list in gr_mem field\n"
" -g,--group groupname only return information for the specified group\n");
fprintf (stream, " -h,--help print this message\n"
" -v,--version print version information and exit\n\n");
if (isNT)
fprintf (stream, "One of '-l' or '-d' must be given.\n");
fprintf (stream,
"Usage: mkgroup [OPTION]...\n"
"Print /etc/group file to stdout\n"
"\n"
"Options:\n"
" -l,--local [machine] print local groups (from local machine if no\n"
" machine 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"
" in domain or foreign server accounts.\n"
" -g,--group groupname only return information for the specified group\n"
" one of -l, -L, -d, -D must be specified, too\n"
" -s,--no-sids (ignored)\n"
" -u,--users (ignored)\n"
" -h,--help print this message\n"
" -v,--version print version information and exit\n"
"\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;
}
struct option longopts[] = {
{"local", no_argument, NULL, 'l'},
{"current", no_argument, NULL, 'c'},
{"domain", no_argument, NULL, 'd'},
{"id-offset", required_argument, NULL, 'o'},
{"no-sids", no_argument, NULL, 's'},
{"users", no_argument, NULL, 'u'},
{"Current", no_argument, NULL, 'C'},
{"domain", optional_argument, NULL, 'd'},
{"Domain", optional_argument, NULL, 'D'},
{"group", required_argument, NULL, 'g'},
{"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'},
{0, no_argument, NULL, 0}
};
char opts[] = "lcdo:sug:hv";
char opts[] = "cCd::D::g:hl::L::o:sS:uv";
void
print_version ()
@ -520,219 +556,188 @@ Compiled on %s\n\
", 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
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_current = 0;
domlist_t locals[16];
int print_domain = 0;
int print_sids = 1;
int print_users = 0;
int domain_specified = 0;
domlist_t domains[16];
char *opt;
int print_current = 0;
const char *sep_char = "\\";
int id_offset = 10000;
int c, i, off;
char *disp_groupname = NULL;
int isRoot = 0;
int isNT;
int i;
BOOL in_domain;
char dom[MAX_DOMAIN_NAME_LEN + 1];
DWORD len, len2;
PSID psid = NULL;
SID_NAME_USE use;
if (!isatty (1))
setmode (1, O_BINARY);
LSA_OBJECT_ATTRIBUTES oa = { 0, 0, 0, 0, 0, 0 };
LSA_HANDLE lsa = INVALID_HANDLE_VALUE;
NTSTATUS ret;
PPOLICY_PRIMARY_DOMAIN_INFO pdi;
isNT = (GetVersion () < 0x80000000);
if (isNT && argc == 1)
return usage(stderr, isNT);
else
load_dsgetdcname ();
in_domain = fetch_primary_domain ();
if (argc == 1)
{
while ((i = getopt_long (argc, argv, opts, longopts, NULL)) != EOF)
switch (i)
print_special (&sid_nt_auth, 1, SECURITY_LOCAL_SYSTEM_RID,
0, 0, 0, 0, 0, 0, 0);
if (in_domain)
{
case 'l':
print_local = 1;
break;
case 'c':
print_current = 1;
break;
case 'd':
print_domain = 1;
break;
case 'o':
id_offset = strtol (optarg, NULL, 10);
break;
case 's':
print_sids = 0;
break;
case 'u':
print_users = 1;
break;
case 'g':
disp_groupname = optarg;
isRoot = !strcmp(disp_groupname, "root");
break;
case 'h':
usage (stdout, isNT);
return 0;
case 'v':
print_version ();
return 0;
default:
fprintf (stderr, "Try '%s --help' for more information.\n", argv[0]);
return 1;
if (!enum_local_groups (TRUE, NULL, sep_char, id_offset,
disp_groupname))
enum_groups (TRUE, NULL, sep_char, id_offset, disp_groupname);
}
}
/* This takes Windows 9x/ME into account. */
if (!isNT)
{
printf ("all::%ld:\n", DOMAIN_ALIAS_RID_ADMINS);
else if (!enum_local_groups (FALSE, NULL, sep_char, 0, disp_groupname))
enum_groups (FALSE, NULL, sep_char, 0, disp_groupname);
return 0;
}
if (!print_local && !print_domain)
{
fprintf (stderr, "%s: Specify one of '-l' or '-d'\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 (print_local)
{
char machine[INTERNET_MAX_HOST_NAME_LENGTH + 1];
char sid[MAX_SID_LEN];
if (isRoot)
{
/*
* Very special feature for the oncoming future:
* Create a "root" group account, being actually the local
* 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");
}
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
{
ret = LsaOpenPolicy (NULL, &oa, POLICY_VIEW_LOCAL_INFORMATION, &lsa);
if (ret == STATUS_SUCCESS && lsa != INVALID_HANDLE_VALUE)
{
ret = LsaQueryInformationPolicy (lsa,
PolicyPrimaryDomainInformation,
(void *) &pdi);
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
while ((c = getopt_long (argc, argv, opts, longopts, NULL)) != EOF)
switch (c)
{
PDOMAIN_CONTROLLER_INFOW pdci = NULL;
if (dsgetdcname)
case 'l':
case 'L':
if (print_local >= 16)
{
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;
fprintf (stderr, "%s: Can not enumerate from more than 16 "
"servers.\n", __progname);
return 1;
}
else
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;
case 'd':
case 'D':
if (print_domain >= 16)
{
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;
}
fprintf (stderr, "%s: Can not enumerate from more than 16 "
"domains.\n", __progname);
return 1;
}
enum_groups (servername, print_sids, print_users, id_offset * i,
disp_groupname);
enum_local_groups (servername, print_sids, print_users, id_offset * i++,
disp_groupname);
NetApiBufferFree (pdci ? (PVOID) pdci : (PVOID) servername);
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;
case 'o':
id_offset = strtol (optarg, NULL, 10);
break;
case 's':
break;
case 'u':
break;
case 'g':
disp_groupname = optarg;
isRoot = !strcmp(disp_groupname, "root");
break;
case 'h':
usage (stdout);
return 0;
case 'v':
print_version ();
return 0;
default:
fprintf (stderr, "Try '%s --help' for more information.\n", argv[0]);
return 1;
}
while (++optind < argc);
if (print_current && !print_domain)
current_group (print_sids, print_users, id_offset);
if (optind < argc - 1)
usage (stdout);
/* Get 'system' group */
if (!disp_groupname && (print_local > 0 || print_domain > 0))
print_special (&sid_nt_auth, 1, SECURITY_LOCAL_SYSTEM_RID,
0, 0, 0, 0, 0, 0, 0);
off = 1;
if (isRoot)
{
/* Very special feature for the oncoming future:
Create a "root" group being actually the local Administrators group.
Printing root disables printing any other "real" local group. */
printf ("root:S-1-5-32-544:0:\n");
}
else
for (i = 0; i < print_local; ++i)
{
if (locals[i].str)
{
if (!enum_local_groups (FALSE, locals + i, sep_char,
id_offset * off, disp_groupname))
enum_groups (FALSE, locals + i, sep_char, id_offset * off++,
disp_groupname);
}
else if (!enum_local_groups (FALSE, locals + i, sep_char, 0,
disp_groupname))
enum_groups (FALSE, locals + i, sep_char, 0, disp_groupname);
}
for (i = 0; i < print_domain; ++i)
{
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;
}

View File

@ -9,21 +9,23 @@
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#define _WIN32_WINNT 0x0600
#include <ctype.h>
#include <stdlib.h>
#include <wchar.h>
#include <stdio.h>
#include <windows.h>
#include <io.h>
#include <unistd.h>
#include <sys/cygwin.h>
#include <getopt.h>
#include <lmaccess.h>
#include <lmapibuf.h>
#include <io.h>
#include <sys/fcntl.h>
#include <lmerr.h>
#include <lmcons.h>
#include <sys/cygwin.h>
#include <windows.h>
#include <lm.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__)
@ -31,29 +33,41 @@
static const char version[] = "$Revision$";
extern char *__progname;
SID_IDENTIFIER_AUTHORITY sid_world_auth = {SECURITY_WORLD_SID_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*);
#ifndef min
#define min(a,b) (((a)<(b))?(a):(b))
#endif
typedef struct
{
char *str;
BOOL with_dom;
} domlist_t;
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");
@ -61,6 +75,53 @@ load_netapi ()
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 *
put_sid (PSID sid)
{
@ -112,68 +173,50 @@ uni2ansi (LPWSTR wcs, char *mbs, int size)
}
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;
HANDLE ptok;
int errpos = 0;
struct {
PSID psid;
int buffer[10];
} 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 ((!GetUserName (name, (len = sizeof (name), &len)) && (errpos = __LINE__))
|| !name[0]
|| !(envname = getenv("USERNAME"))
|| strcasecmp (envname, name)
|| (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 (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &ptok)
|| !GetTokenInformation (ptok, TokenUser, &tu, sizeof tu, &len)
|| !GetTokenInformation (ptok, TokenPrimaryGroup, &tg, sizeof tg, &len)
|| !CloseHandle (ptok)
|| !LookupAccountSidA (NULL, tu.psid, user, &ulen, dom, &dlen, &acc_type))
{
if (errpos)
_print_win_error (GetLastError (), errpos);
print_win_error (GetLastError ());
return;
}
int uid = *GetSidSubAuthority (tu.psid, *GetSidSubAuthorityCount(tu.psid) - 1);
int gid = *GetSidSubAuthority (tg.psid, *GetSidSubAuthorityCount(tg.psid) - 1);
char homedir_psx[MAX_PATH] = {0}, homedir_w32[MAX_PATH] = {0};
char *envhomedrive = getenv ("HOMEDRIVE");
char *envhomepath = getenv ("HOMEPATH");
uid = *GetSidSubAuthority (tu.psid, *GetSidSubAuthorityCount(tu.psid) - 1);
gid = *GetSidSubAuthority (tg.psid, *GetSidSubAuthorityCount(tg.psid) - 1);
if (passed_home_path[0] == '\0')
{
if (envhomepath && envhomepath[0])
char *envhome = getenv ("HOME");
char *envhomedrive = getenv ("HOMEDRIVE");
char *envhomepath = getenv ("HOMEPATH");
if (envhome && envhome[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)
strlcpy (homedir_w32, envhomedrive, sizeof (homedir_w32));
@ -182,47 +225,67 @@ current_user (int print_sids, int print_cygpath,
strlcat (homedir_w32, envhomepath, sizeof (homedir_w32));
if (print_cygpath)
cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_ABSOLUTE, homedir_w32,
homedir_psx, MAX_PATH);
homedir_psx, PATH_MAX);
else
psx_dir (homedir_w32, homedir_psx);
}
else
{
strlcpy (homedir_psx, "/home/", sizeof (homedir_psx));
strlcat (homedir_psx, envname, sizeof (homedir_psx));
strlcat (homedir_psx, user, sizeof (homedir_psx));
}
}
else
{
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",
envname,
printf ("%s%s%s:unused:%u:%u:U-%s\\%s,%s:%s:/bin/bash\n",
sep ? dom : "",
sep ?: "",
user,
uid + id_offset,
gid + id_offset,
envname,
print_sids ? "," : "",
print_sids ? "U-" : "",
print_sids ? envdomain : "",
print_sids ? "\\" : "",
print_sids ? envname : "",
print_sids ? "," : "",
print_sids ? put_sid (tu.psid) : "",
dom,
user,
put_sid (tu.psid),
homedir_psx);
}
int
enum_users (LPWSTR servername, int print_sids, int print_cygpath,
const char * passed_home_path, int id_offset, char *disp_username)
enum_users (BOOL domain, domlist_t *dom_or_machine, const char *sep,
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;
DWORD entriesread = 0;
DWORD totalentries = 0;
DWORD resume_handle = 0;
DWORD rc;
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
{
@ -243,7 +306,7 @@ enum_users (LPWSTR servername, int print_sids, int print_cygpath,
{
case ERROR_ACCESS_DENIED:
print_win_error(rc);
exit (1);
return 1;
case ERROR_MORE_DATA:
case ERROR_SUCCESS:
@ -251,7 +314,7 @@ enum_users (LPWSTR servername, int print_sids, int print_cygpath,
default:
print_win_error(rc);
exit (1);
return 1;
}
for (i = 0; i < entriesread; i++)
@ -289,48 +352,45 @@ enum_users (LPWSTR servername, int print_sids, int print_cygpath,
stpcpy (homedir_psx, passed_home_path),
PATH_MAX - strlen (passed_home_path));
if (print_sids)
if (!LookupAccountNameW (servername, buffer[i].usri3_name,
psid, &sid_length, domain_name,
&domname_len, &acc_type))
{
if (!LookupAccountNameW (servername, buffer[i].usri3_name,
psid, &sid_length, domain_name,
print_win_error(GetLastError ());
fprintf(stderr, " (%ls)\n", buffer[i].usri3_name);
continue;
}
else if (acc_type == SidTypeDomain)
{
WCHAR domname[MAX_DOMAIN_NAME_LEN + UNLEN + 2];
wcscpy (domname, domain_name);
wcscat (domname, L"\\");
wcscat (domname, buffer[i].usri3_name);
sid_length = MAX_SID_LEN;
domname_len = sizeof (domname);
if (!LookupAccountNameW (servername, domname, psid,
&sid_length, domain_name,
&domname_len, &acc_type))
{
print_win_error(GetLastError ());
fprintf(stderr, " (%ls)\n", buffer[i].usri3_name);
print_win_error(GetLastError ());
fprintf(stderr, " (%ls)\n", domname);
continue;
}
else if (acc_type == SidTypeDomain)
{
WCHAR domname[MAX_DOMAIN_NAME_LEN + UNLEN + 2];
wcscpy (domname, domain_name);
wcscat (domname, L"\\");
wcscat (domname, buffer[i].usri3_name);
sid_length = MAX_SID_LEN;
domname_len = sizeof (domname);
if (!LookupAccountNameW (servername, domname, psid,
&sid_length, domain_name,
&domname_len, &acc_type))
{
print_win_error(GetLastError ());
fprintf(stderr, " (%ls)\n", domname);
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,
uid + id_offset,
gid + id_offset,
buffer[i].usri3_full_name ?: L"",
print_sids && buffer[i].usri3_full_name
buffer[i].usri3_full_name
&& buffer[i].usri3_full_name[0] ? "," : "",
print_sids ? "U-" : "",
print_sids ? domain_name : L"",
print_sids && domain_name[0] ? "\\" : "",
print_sids ? buffer[i].usri3_full_name : L"",
print_sids ? "," : "",
print_sids ? put_sid (psid) : "",
domain_name,
buffer[i].usri3_name,
put_sid (psid),
homedir_psx);
}
@ -342,90 +402,8 @@ enum_users (LPWSTR servername, int print_sids, int print_cygpath,
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
print_special (int print_sids,
PSID_IDENTIFIER_AUTHORITY auth, BYTE cnt,
print_special (PSID_IDENTIFIER_AUTHORITY auth, BYTE cnt,
DWORD sub1, DWORD sub2, DWORD sub3, DWORD sub4,
DWORD sub5, DWORD sub6, DWORD sub7, DWORD sub8)
{
@ -458,58 +436,70 @@ print_special (int print_sids,
rid = sub2;
else
rid = sub1;
printf ("%s:*:%lu:%lu:%s%s::\n",
printf ("%s:*:%lu:%lu:,%s::\n",
name, rid, rid == 18 ? 544 : rid, /* SYSTEM hack */
print_sids ? "," : "",
print_sids ? put_sid (sid) : "");
put_sid (sid));
}
FreeSid (sid);
}
}
int
usage (FILE * stream, int isNT)
usage (FILE * stream)
{
fprintf (stream, "Usage: mkpasswd [OPTION]... [domain]...\n"
"Print /etc/passwd file to stdout\n\n"
"Options:\n");
if (isNT)
fprintf (stream, " -l,--local print local user accounts\n"
" -c,--current print current account, if a domain account\n"
" -d,--domain print domain accounts (from current domain\n"
" if no domains specified)\n"
" -o,--id-offset offset change the default offset (10000) added to uids\n"
" in domain 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"
" -h,--help displays this message\n"
" -v,--version version information and exit\n\n");
if (isNT)
fprintf (stream, "One of '-l', '-d' or '-g' must be given.\n");
fprintf (stream,
"Usage: mkpasswd [OPTIONS]...\n"
"Print /etc/passwd file to stdout\n"
"\n"
"Options:\n"
" -l,--local [machine] print local user accounts (from local machine\n"
" if no machine 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"
" in domain or foreign server accounts.\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"
" -v,--version version information and exit\n"
"\n"
"Default is to print local accounts on stand-alone machines, domain accounts\n"
"on domain controllers and domain member machines.\n");
return 1;
}
struct option longopts[] = {
{"local", no_argument, NULL, 'l'},
{"current", no_argument, NULL, 'c'},
{"domain", no_argument, NULL, 'd'},
{"id-offset", required_argument, NULL, 'o'},
{"Current", no_argument, NULL, 'C'},
{"domain", optional_argument, NULL, 'd'},
{"Domain", optional_argument, NULL, 'D'},
{"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'},
{"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'},
{0, no_argument, NULL, 0}
};
char opts[] = "lcdo:gsmhp:u:v";
char opts[] = "cCd::D::ghl::L::mo:sS:p:u:v";
static void
print_version ()
@ -534,202 +524,194 @@ Compiled on %s\n\
", 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
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_current = 0;
domlist_t locals[16];
int print_domain = 0;
int print_local_groups = 0;
int domain_specified = 0;
int print_sids = 1;
domlist_t domains[16];
char *opt;
int print_cygpath = 1;
int print_current = 0;
const char *sep_char = "\\";
int id_offset = 10000;
int i;
int isNT;
int c, i, off;
char *disp_username = NULL;
char name[256], passed_home_path[MAX_PATH];
DWORD len;
char passed_home_path[PATH_MAX];
BOOL in_domain;
isNT = (GetVersion () < 0x80000000);
passed_home_path[0] = '\0';
if (!isatty (1))
setmode (1, O_BINARY);
if (isNT && argc == 1)
return usage (stderr, isNT);
else
load_dsgetdcname ();
in_domain = fetch_primary_domain ();
if (argc == 1)
{
while ((i = getopt_long (argc, argv, opts, longopts, NULL)) != EOF)
switch (i)
{
case 'l':
print_local = 1;
break;
case 'c':
print_current = 1;
break;
case 'd':
print_domain = 1;
break;
case 'o':
id_offset = strtol (optarg, NULL, 10);
break;
case 'g':
print_local_groups = 1;
break;
case 's':
print_sids = 0;
break;
case 'm':
print_cygpath = 0;
break;
case 'p':
if (optarg[0] != '/')
{
fprintf (stderr, "%s: '%s' is not a fully qualified path.\n",
argv[0], optarg);
return 1;
}
strcpy (passed_home_path, optarg);
if (optarg[strlen (optarg)-1] != '/')
strcat (passed_home_path, "/");
break;
case 'u':
disp_username = optarg;
break;
case 'h':
usage (stdout, isNT);
return 0;
case 'v':
print_version ();
return 0;
default:
fprintf (stderr, "Try '%s --help' for more information.\n", argv[0]);
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",
disp_username,
uid,
DOMAIN_ALIAS_RID_ADMINS,
disp_username,
passed_home_path,
disp_username);
}
enum_std_accounts ();
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;
}
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]);
while ((c = getopt_long (argc, argv, opts, longopts, NULL)) != EOF)
switch (c)
{
case 'l':
case 'L':
if (print_local >= 16)
{
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;
case 'd':
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;
case 'o':
id_offset = strtol (optarg, NULL, 10);
break;
case 'g':
break;
case 's':
break;
case 'm':
print_cygpath = 0;
break;
case 'p':
if (optarg[0] != '/')
{
fprintf (stderr, "%s: '%s' is not a fully qualified path.\n",
__progname, optarg);
return 1;
}
domain_specified = 1;
}
load_netapi ();
if (disp_username == NULL)
{
if (print_local)
{
/* 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). */
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
{
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 (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);
strcpy (passed_home_path, optarg);
if (optarg[strlen (optarg)-1] != '/')
strcat (passed_home_path, "/");
break;
case 'u':
disp_username = optarg;
break;
case 'h':
usage (stdout);
return 0;
case 'v':
print_version ();
return 0;
default:
fprintf (stderr, "Try '%s --help' for more information.\n", __progname);
return 1;
}
while (++optind < argc);
if (print_current && !print_domain)
current_user(print_sids, print_cygpath, passed_home_path,
id_offset, disp_username);
if (optind < argc - 1)
usage (stdout);
off = 1;
for (i = 0; i < print_local; ++i)
{
if (locals[i].str)
enum_users (FALSE, locals + i, sep_char, print_cygpath,
passed_home_path, id_offset * off++, disp_username);
else
{
enum_std_accounts ();
enum_users (FALSE, locals + i, sep_char, print_cygpath,
passed_home_path, 0, disp_username);
}
}
for (i = 0; i < print_domain; ++i)
enum_users (TRUE, domains + i, sep_char, print_cygpath, passed_home_path,
id_offset * off++, disp_username);
if (print_current)
current_user (print_cygpath, sep_char, passed_home_path, id_offset, disp_username);
return 0;
}

View File

@ -298,7 +298,11 @@ struct opt
{"exec", MOUNT_EXEC, 0},
{"notexec", MOUNT_NOTEXEC, 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
@ -844,6 +848,10 @@ getmntent (FILE *)
strcat (mnt.mnt_opts, (char *) ",noexec");
if ((m->flags & MOUNT_CYGDRIVE)) /* 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_passno = 1;
m++;

View File

@ -1,6 +1,7 @@
/* 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.

View File

@ -505,69 +505,75 @@ SIGUSR2 31 user defined signal 2
<sect2 id="mkgroup"><title>mkgroup</title>
<screen>
Usage: mkgroup [OPTION]... [domain]...
Prints /etc/group file to stdout
Usage: mkgroup [OPTION]...
Print /etc/group file to stdout
Options:
-l,--local print local group information
-c,--current print current group, if a domain account
-d,--domain print global group information (from current
domain if no domains specified).
-o,--id-offset offset change the default offset (10000) added to gids
in domain accounts.
-s,--no-sids don't print SIDs in pwd field
(this affects ntsec)
-u,--users print user list in gr_mem field
-g,--group groupname only return information for the specified group\n");
-h,--help print this message
-l,--local [machine] print local groups (from local machine if no
machine specified)
-L,--Local [machine] ditto, but generate groupname with machine prefix
-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
in domain or foreign server accounts.
-g,--group groupname only return information for the specified group
one of -l, -L, -d, -D must be specified, too
-s,--no-sids (ignored)
-u,--users (ignored)
-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>
<para>The <command>mkgroup</command> program can be used to help
configure your Windows system to be more UNIX-like by creating an
initial <filename>/etc/group</filename>.
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>
<screen>
<prompt>$</prompt> <userinput>mkdir /etc</userinput>
<prompt>$</prompt> <userinput>mkgroup -l &gt; /etc/group</userinput>
</screen>
</example>
configure Cygwin by creating a <filename>/etc/group</filename>
file. Its use is essential to include Windows security information.</para>
<para>The command is initially called by <command>setup.exe</command> to
create a default <filename>/etc/group</filename>. This should be
sufficient in most circumstances. However, especially when working
in a multi-domain environment, you can use <command>mkgroup</command>
manually to create a more complete <filename>/etc/group</filename> file for
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
information in your system, you'll need to regenerate the group file
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
local machine or the domain (default or given), or both.
With the <literal>-d</literal> option the program contacts the Domain
local SAM of a machine or from the domain, or both.
With the <literal>-d/-D</literal> options the program contacts a Domain
Controller, which my be unreachable or have restricted access.
An entry for the current domain user can then be created by using the
option <literal>-c</literal> together with <literal>-l</literal>,
but <literal>-c</literal> has no effect when used with <literal>-d</literal>.
The <literal>-o</literal> option allows for special cases
For very simple needs, an entry for the current user's group can be
created by using the option <literal>-c</literal> or <literal>-C</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, 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.
The <literal>-s</literal>
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.
The <literal>-g</literal> option only prints the information for one group.
</para>
</sect2>
@ -575,68 +581,74 @@ one group.
<sect2 id="mkpasswd"><title>mkpasswd</title>
<screen>
Usage: mkpasswd [OPTION]... [domain]...
Prints /etc/passwd file to stdout
Usage: mkpasswd [OPTIONS]...
Print /etc/passwd file to stdout
Options:
-l,--local print local user accounts
-c,--current print current account, if a domain account
-d,--domain print domain accounts (from current domain
if no domains specified)
-l,--local [machine] print local user accounts (from local machine
if no machine specified)
-L,--Local [machine] ditto, but generate username with machine prefix
-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
in domain 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
in domain or foreign server accounts.
-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
-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>
<para>The <command>mkpasswd</command> program can be used to help
configure your Windows system to be more UNIX-like by creating an
initial <filename>/etc/passwd</filename> from your system information.
Its use is essential on the NT series (Windows NT, 2000, and XP) to
include Windows security information, but the actual passwords are
determined by Windows, not by the content of <filename>/etc/passwd</filename>.
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>
<screen>
<prompt>$</prompt> <userinput>mkdir /etc</userinput>
<prompt>$</prompt> <userinput>mkpasswd -l &gt; /etc/passwd</userinput>
</screen>
</example>
configure Cygwin by creating a <filename>/etc/passwd</filename> from
your system information.
Its use is essential to include Windows security information. However,
the actual passwords are determined by Windows, not by the content of
<filename>/etc/passwd</filename>.</para>
<para>The command is initially called by <command>setup.exe</command> to
create a default <filename>/etc/passwd</filename>. This should be
sufficient in most circumstances. However, especially when working
in a multi-domain environment, you can use <command>mkpasswd</command>
manually to create a more complete <filename>/etc/passwd</filename> file for
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
information in your system, you'll need to regenerate the passwd file
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
local machine or the domain (default or given), or both.
With the <literal>-d</literal> option the program contacts the Domain
Controller, which my be unreachable or have restricted access.
An entry for the current domain user can then be created by using the
option <literal>-c</literal> together with <literal>-l</literal>,
but <literal>-c</literal> has no effect when used with <literal>-d</literal>.
With the <literal>-d/-D</literal> options the program contacts the Domain
Controller, which may be unreachable or have restricted access.
An entry for the current user can be created by using the
option <literal>-c</literal> or <literal>-C</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
(such as multiple domains) where the UIDs might match otherwise.
The <literal>-g</literal> option creates a local
user that corresponds to each local group. This is because NT assigns groups
file ownership. The <literal>-m</literal> option bypasses the current
The <literal>-m</literal> option bypasses the current
mount table so that, for example, two users who have a Windows home
directory of H: could mount them differently. The <literal>-s</literal>
option omits the NT Security Identifier (SID). For more information on
directory of H: could mount them differently. For more information on
SIDs, see <xref linkend="ntsec"></xref> in the Cygwin User's Guide. The
<literal>-p</literal> option causes <command>mkpasswd</command> to
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>
would put local users' home directories in the Windows 'Profiles' directory.
On Win9x machines the <literal>-u</literal> option creates an entry for
the specified user. On the NT series it restricts the output to that user,
greatly reducing the amount of time it takes in a large domain.</para>
The <literal>-u</literal> option creates just an entry for
the specified user.</para>
</sect2>