From a1e199034882ebf25918021d2d30962928e997d6 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 22 Jul 2008 14:40:05 +0000 Subject: [PATCH] * 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. --- winsup/utils/ChangeLog | 21 ++ winsup/utils/Makefile.in | 2 +- winsup/utils/bloda.cc | 38 +- winsup/utils/cygpath.cc | 7 +- winsup/utils/mkgroup.c | 795 ++++++++++++++++++++------------------- winsup/utils/mkpasswd.c | 776 +++++++++++++++++++------------------- winsup/utils/path.cc | 10 +- winsup/utils/ps.cc | 3 +- winsup/utils/utils.sgml | 201 +++++----- 9 files changed, 925 insertions(+), 928 deletions(-) diff --git a/winsup/utils/ChangeLog b/winsup/utils/ChangeLog index c425e6f34..8a8137d05 100644 --- a/winsup/utils/ChangeLog +++ b/winsup/utils/ChangeLog @@ -1,3 +1,24 @@ +2008-07-22 Corinna Vinschen + + * 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 * mount.cc (do_mount): Remove MOUNT_ENC code. diff --git a/winsup/utils/Makefile.in b/winsup/utils/Makefile.in index fda8511a7..c4ec9e0c4 100644 --- a/winsup/utils/Makefile.in +++ b/winsup/utils/Makefile.in @@ -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 diff --git a/winsup/utils/bloda.cc b/winsup/utils/bloda.cc index 5c977cec1..c6443184f 100644 --- a/winsup/utils/bloda.cc +++ b/winsup/utils/bloda.cc @@ -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 (); diff --git a/winsup/utils/cygpath.cc b/winsup/utils/cygpath.cc index b9eb13698..6f8eb6b30 100644 --- a/winsup/utils/cygpath.cc +++ b/winsup/utils/cygpath.cc @@ -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__); } diff --git a/winsup/utils/mkgroup.c b/winsup/utils/mkgroup.c index 63408cd8a..a82ae3b1b 100644 --- a/winsup/utils/mkgroup.c +++ b/winsup/utils/mkgroup.c @@ -9,37 +9,31 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ +#define _WIN32_WINNT 0x0600 #include #include #include #include -#include -#include +#include #include -#include -#include +#include +#include +#include +#include +#include #include #include #include +#include #include #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 +_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_netapi () +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]; - - 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"); + 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%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; - - - 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__))) + 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) + || !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'}, + {"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'}, - {"group", required_argument, NULL, 'g'}, - {"help", no_argument, NULL, 'h'}, {"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; - - char dom[MAX_DOMAIN_NAME_LEN + 1]; - DWORD len, len2; - PSID psid = NULL; - SID_NAME_USE use; - - LSA_OBJECT_ATTRIBUTES oa = { 0, 0, 0, 0, 0, 0 }; - LSA_HANDLE lsa = INVALID_HANDLE_VALUE; - NTSTATUS ret; - PPOLICY_PRIMARY_DOMAIN_INFO pdi; + BOOL in_domain; - isNT = (GetVersion () < 0x80000000); + 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) + 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 (); + 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 '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; + } - 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 (optind < argc - 1) + usage (stdout); - 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); - } + /* 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); - if (!isRoot) - enum_local_groups (NULL, print_sids, print_users, 0, disp_groupname); + 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"); } - i = 1; - if (print_domain) - do + else + for (i = 0; i < print_local; ++i) { - PDOMAIN_CONTROLLER_INFOW pdci = NULL; - - if (dsgetdcname) + if (locals[i].str) { - 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); - enum_local_groups (servername, print_sids, print_users, id_offset * i++, + 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); - NetApiBufferFree (pdci ? (PVOID) pdci : (PVOID) servername); + } + else if (!enum_local_groups (FALSE, locals + i, sep_char, 0, + disp_groupname)) + enum_groups (FALSE, locals + i, sep_char, 0, disp_groupname); } - while (++optind < argc); - if (print_current && !print_domain) - current_group (print_sids, print_users, id_offset); + 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; } diff --git a/winsup/utils/mkpasswd.c b/winsup/utils/mkpasswd.c index 953202a8b..0a1277f2a 100644 --- a/winsup/utils/mkpasswd.c +++ b/winsup/utils/mkpasswd.c @@ -9,21 +9,23 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ +#define _WIN32_WINNT 0x0600 #include #include #include #include -#include -#include #include -#include #include -#include -#include +#include #include -#include -#include +#include +#include +#include #include +#include +#include +#include +#include #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; - - - 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__))) + 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) + || !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,118 +352,26 @@ 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)) - { - 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", domname); - continue; - } - } - } - printf ("%ls:unused:%u:%u:%ls%s%s%ls%s%ls%s%s:%s:/bin/bash\n", - 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[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) : "", - homedir_psx); - } - - NetApiBufferFree (buffer); - - } - while (rc == ERROR_MORE_DATA); - - 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)) + if (!LookupAccountNameW (servername, buffer[i].usri3_name, + psid, &sid_length, domain_name, + &domname_len, &acc_type)) { print_win_error(GetLastError ()); - fprintf(stderr, " (%ls)\n", buffer[i].lgrpi0_name); + fprintf(stderr, " (%ls)\n", buffer[i].usri3_name); continue; } else if (acc_type == SidTypeDomain) { - WCHAR domname[MAX_DOMAIN_NAME_LEN + GNLEN + 2]; + WCHAR domname[MAX_DOMAIN_NAME_LEN + UNLEN + 2]; wcscpy (domname, domain_name); wcscat (domname, L"\\"); - wcscat (domname, buffer[i].lgrpi0_name); + wcscat (domname, buffer[i].usri3_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)) + 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); @@ -408,11 +379,19 @@ enum_local_groups (int print_sids) } } - 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) : ""); + 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"", + buffer[i].usri3_full_name + && buffer[i].usri3_full_name[0] ? "," : "", + domain_name, + buffer[i].usri3_name, + put_sid (psid), + homedir_psx); } NetApiBufferFree (buffer); @@ -424,8 +403,7 @@ enum_local_groups (int print_sids) } 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'}, + {"help", no_argument, NULL, 'h'}, + {"local", optional_argument, NULL, 'l'}, + {"Local", optional_argument, NULL, 'L'}, {"no-mount", no_argument, NULL, 'm'}, - {"no-sids", no_argument, NULL, 's'}, + {"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'}, - {"help", no_argument, NULL, 'h'}, {"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) + 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; + } + + while ((c = getopt_long (argc, argv, opts, longopts, NULL)) != EOF) + switch (c) + { + case 'l': + case 'L': + if (print_local >= 16) { - 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]); + fprintf (stderr, "%s: Can not enumerate from more than 16 " + "servers.\n", __progname); 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); - } - 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]); + 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 (); + 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; + } - if (disp_username == NULL) + if (optind < argc - 1) + usage (stdout); + + off = 1; + for (i = 0; i < print_local; ++i) { - 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 (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); } - 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); - } - while (++optind < argc); + 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 && !print_domain) - current_user(print_sids, print_cygpath, passed_home_path, - id_offset, disp_username); + if (print_current) + current_user (print_cygpath, sep_char, passed_home_path, id_offset, disp_username); return 0; } diff --git a/winsup/utils/path.cc b/winsup/utils/path.cc index 5a6fe3bb7..396badb79 100644 --- a/winsup/utils/path.cc +++ b/winsup/utils/path.cc @@ -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++; diff --git a/winsup/utils/ps.cc b/winsup/utils/ps.cc index 5d7559305..091e7413a 100644 --- a/winsup/utils/ps.cc +++ b/winsup/utils/ps.cc @@ -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. diff --git a/winsup/utils/utils.sgml b/winsup/utils/utils.sgml index a016b85a3..2cb391b3e 100644 --- a/winsup/utils/utils.sgml +++ b/winsup/utils/utils.sgml @@ -505,69 +505,75 @@ SIGUSR2 31 user defined signal 2 mkgroup -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 - - -v,--version print version information and exit - -One of `-l' or `-d' must be given on NT/W2K. + -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 + +Default is to print local groups on stand-alone machines, plus domain +groups on domain controllers and domain member machines. The mkgroup program can be used to help -configure your Windows system to be more UNIX-like by creating an -initial /etc/group. -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: +configure Cygwin by creating a /etc/group +file. Its use is essential to include Windows security information. + +The command is initially called by setup.exe to +create a default /etc/group. This should be +sufficient in most circumstances. However, especially when working +in a multi-domain environment, you can use mkgroup +manually to create a more complete /etc/group file for +all domains. Especially when you have the same group name used on +multiple machines or in multiple domains, you can use the -D, +-L and -C options to create unique +domain\group style groupnames. -Setting up the groups file for local accounts - -$ mkdir /etc -$ mkgroup -l > /etc/group - - - 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. -The -d and -l options +The -d/-D and -l/-L options allow you to specify where the information comes from, the -local machine or the domain (default or given), or both. -With the -d option the program contacts the Domain +local SAM of a machine or from the domain, or both. +With the -d/-D 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 -c together with -l, -but -c has no effect when used with -d. -The -o option allows for special cases +For very simple needs, an entry for the current user's group can be +created by using the option -c or -C. +If you want to use one of the -D, -L +or -C options, but you don't like the backslash as +domain/group separator, you can specify another separator using the +-S option, for instance + +Setting up group entry for current user with different domain/group separator + +$ mkgroup -C -S+ > /etc/group +$ cat /etc/group +DOMAIN+my_group:S-1-5-21-2913048732-1697188782-3448811101-1144:11144: + + + +The -o option allows for special cases (such as multiple domains) where the GIDs might match otherwise. -The -s -option omits the NT Security Identifier (SID). For more information on -SIDs, see in the Cygwin User's Guide. The --u option causes mkgroup 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 mkgroup 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 -g option only prints the information for -one group. +The -g option only prints the information for one group. @@ -575,68 +581,74 @@ one group. mkpasswd -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. The mkpasswd program can be used to help -configure your Windows system to be more UNIX-like by creating an -initial /etc/passwd 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 /etc/passwd. -On the Win9x series (Windows 95, 98, and Me) the password field must be -replaced by the output of crypt your_password -if remote access is desired. -To initially set up your machine if you are a local user, you'd do -something like this: +configure Cygwin by creating a /etc/passwd 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 +/etc/passwd. + +The command is initially called by setup.exe to +create a default /etc/passwd. This should be +sufficient in most circumstances. However, especially when working +in a multi-domain environment, you can use mkpasswd +manually to create a more complete /etc/passwd file for +all domains. Especially when you have the same user name used on +multiple machines or in multiple domains, you can use the -D, +-L and -C options to create unique +domain\user style usernames. -Setting up the passwd file for local accounts - -$ mkdir /etc -$ mkpasswd -l > /etc/passwd - - - 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. -The -d and -l options +The -d/-D and -l/-L options allow you to specify where the information comes from, the local machine or the domain (default or given), or both. -With the -d 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 -c together with -l, -but -c has no effect when used with -d. +With the -d/-D 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 -c or -C. +If you want to use one of the -D, -L +or -C options, but you don't like the backslash as +domain/group separator, you can specify another separator using the +-S option, simialar to the mkgroup. The -o option allows for special cases (such as multiple domains) where the UIDs might match otherwise. -The -g option creates a local -user that corresponds to each local group. This is because NT assigns groups -file ownership. The -m option bypasses the current +The -m 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 -s -option omits the NT Security Identifier (SID). For more information on +directory of H: could mount them differently. For more information on SIDs, see in the Cygwin User's Guide. The -p option causes mkpasswd to use the specified prefix instead of the account home dir or /home/ @@ -649,9 +661,8 @@ use the specified prefix instead of the account home dir or /home/ would put local users' home directories in the Windows 'Profiles' directory. -On Win9x machines the -u 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. +The -u option creates just an entry for +the specified user. -- 2.43.5