diff options
Diffstat (limited to 'winsup/utils')
-rw-r--r-- | winsup/utils/ChangeLog | 112 | ||||
-rwxr-xr-x | winsup/utils/configure | 50 | ||||
-rw-r--r-- | winsup/utils/configure.ac | 7 | ||||
-rw-r--r-- | winsup/utils/cygcheck.cc | 7 | ||||
-rw-r--r-- | winsup/utils/getfacl.c | 10 | ||||
-rw-r--r-- | winsup/utils/mkgroup.c | 433 | ||||
-rw-r--r-- | winsup/utils/mkpasswd.c | 468 | ||||
-rw-r--r-- | winsup/utils/passwd.c | 33 | ||||
-rw-r--r-- | winsup/utils/setfacl.c | 182 | ||||
-rw-r--r-- | winsup/utils/utils.xml | 2127 |
10 files changed, 2790 insertions, 639 deletions
diff --git a/winsup/utils/ChangeLog b/winsup/utils/ChangeLog index 09dc0bf31..8559de18d 100644 --- a/winsup/utils/ChangeLog +++ b/winsup/utils/ChangeLog @@ -1,87 +1,9 @@ -2014-11-10 Corinna Vinschen <corinna@vinschen.de> - - * cygcheck.cc (dump_sysinfo): Handle Windows 10/Server 2014(?). - -2014-11-03 Corinna Vinschen <corinna@vinschen.de> - - * mkgroup.c (enum_local_groups): Don't generate leading separator char - for builtin accounts. - -2014-10-29 Corinna Vinschen <corinna@vinschen.de> - - * setfacl.c (setfacl): Fix bracketing in expression. - -2014-10-27 Corinna Vinschen <corinna@vinschen.de> - - * setfacl.c (usage): Add -b to require options. - -2014-10-27 Corinna Vinschen <corinna@vinschen.de> - - * setfacl.c (action_t): Add DeleteAll value. - (delacl): New function to remove all ACL entries not representing POSIX - permissions. - (setfacl): Rearrange conditional expression into switch statement. - Add DeleteAll case. - (usage): Add and describe -b option. - (longopts): Add --remove-all option. - (opts): Add -b option. - (main): Handle -b option. - 2014-10-21 Corinna Vinschen <corinna@vinschen.de> * cygcheck.cc (CYGLSA64_DLL): Remove unused macro. (dump_sysinfo): If COMSPEC isn't set in the MSVCRT environment, set it. Explain why. -2014-09-03 Corinna Vinschen <corinna@vinschen.de> - - * setfacl.c (addmissing): New function to add missing acl entries to - a modified acl per the rules set by aclcheck. - (setfacl): Call addmissing unless action is Delete. - -2014-09-03 Corinna Vinschen <corinna@vinschen.de> - - * setfacl.c (getaclentry): Fix previous fix again. Allow lone 'm' as - well as any lone default entry if action is Delete. Fix comments. - (usage): Align usage text. - -2014-09-03 Corinna Vinschen <corinna@vinschen.de> - - * setfacl.c (getaclentry): Fix return value in case of a lone 'm' if - action is Delete. Drop requirement for a trailing colon if action is - Delete. - -2014-08-31 Corinna Vinschen <corinna@vinschen.de> - - * setfacl.c (usage): Drop outdated note that default ACEs are not - taken into account. - -2014-08-31 Corinna Vinschen <corinna@vinschen.de> - - * getfacl.c (usage): Add flags description. - (main): Print suid/sgid/vtx flags if available. - -2014-08-15 Corinna Vinschen <corinna@vinschen.de> - - * configure.ac: Convert to new AC_INIT style. - * configure: Regenerate. - -2014-08-14 Corinna Vinschen <corinna@vinschen.de> - - * utils.xml: Move to ../doc. - -2014-08-06 Corinna Vinschen <corinna@vinschen.de> - - * passwd.c (usage): Rename DAYS to MINDAYS and MAXDAYS. - * utils.xml (passwd): Ditto. - -2014-07-29 Corinna Vinschen <corinna@vinschen.de> - - * mkgroup.c (usage): Move info message that this /etc/group isn't really - required anymore more to the top of the usage output. - * mkpasswd.c (usage): Ditto for /etc/passwd. Drop old text from output. - * utils.xml: Fix accordingly. - 2014-06-16 Corinna Vinschen <corinna@vinschen.de> * passwd.c (main): Fix typo in error output. @@ -104,40 +26,6 @@ * minidumper.cc (minidump): Fix copy and paste error in checking result of OpenProcess(). -2014-02-24 Corinna Vinschen <corinna@vinschen.de> - - * mkgroup.c (domlist_t): Drop id_offset. - (get_dcname): Remove. - (current_group): Remove. - (enum_unix_groups): Simplify. Change space to underscore in domain - name. - (enum_local_groups): Simplify to accommodate the fact that it's only - called for foreign machines. - (enum_groups): Ditto. - (print_special_by_sid): Remove. - (print_special_by_name): Remove. - (usage): Align to new code. - (fetch_primary_domain): Remove. - (main): Use cygwin_internal CW_SETENT, CW_GETENT and CW_ENDENT method. - Call enum_local_groups, enum_groups, and enum_unix_groups only for - foreign machines. - * mkpasswd.c (get_dcname): Remove. - (current_user): Remove. - (enum_unix_users): Simplify. Change space to underscore in domain name. - (enum_users): Simplify to accommodate the fact that it's only - called for foreign machines. - (print_special_by_sid): Remove. - (usage): Align to new code. - (longopts): Add -b/--no-builtin option. - (opts): Add -b option. - (print_special_by_name): Remove. - (enum_std_accounts): Remove. - (fetch_primary_domain): Remove. - (main): Use cygwin_internal CW_SETENT, CW_GETENT and CW_ENDENT method. - Call enum_users and enum_unix_users only for foreign machines. - * utils.xml (mkgroup): Align documentation to new usage. - (mkpasswd): Ditto. - 2014-02-23 Jon TURNEY <jon.turney@dronecode.org.uk> * minidumper.cc (minidump): Fix -t option argument handling. diff --git a/winsup/utils/configure b/winsup/utils/configure index 5cf181edd..7e524e279 100755 --- a/winsup/utils/configure +++ b/winsup/utils/configure @@ -1,8 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for Cygwin Utils 0. -# -# Report bugs to <cygwin@cygwin.com>. +# Generated by GNU Autoconf 2.69. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -265,11 +263,10 @@ fi $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else - $as_echo "$0: Please tell bug-autoconf@gnu.org and cygwin@cygwin.com -$0: about your system, including any error possibly output -$0: before this message. Then install a modern shell, or -$0: manually run the script under such a shell if you do -$0: have one." + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." fi exit 1 fi @@ -577,12 +574,12 @@ MFLAGS= MAKEFLAGS= # Identity of this package. -PACKAGE_NAME='Cygwin Utils' -PACKAGE_TARNAME='cygwin' -PACKAGE_VERSION='0' -PACKAGE_STRING='Cygwin Utils 0' -PACKAGE_BUGREPORT='cygwin@cygwin.com' -PACKAGE_URL='https://cygwin.com' +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= +PACKAGE_URL= ac_unique_file="mount.cc" ac_no_link=no @@ -716,7 +713,7 @@ sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +docdir='${datarootdir}/doc/${PACKAGE}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' @@ -1216,7 +1213,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures Cygwin Utils 0 to adapt to many kinds of systems. +\`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1264,7 +1261,7 @@ Fine tuning of the installation directories: --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/cygwin] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] @@ -1286,9 +1283,7 @@ _ACEOF fi if test -n "$ac_init_help"; then - case $ac_init_help in - short | recursive ) echo "Configuration of Cygwin Utils 0:";; - esac + cat <<\_ACEOF Optional Packages: @@ -1312,8 +1307,7 @@ Some influential environment variables: Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. -Report bugs to <cygwin@cygwin.com>. -Cygwin Utils home page: <https://cygwin.com>. +Report bugs to the package provider. _ACEOF ac_status=$? fi @@ -1376,7 +1370,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -Cygwin Utils configure 0 +configure generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1469,7 +1463,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by Cygwin Utils $as_me 0, which was +It was created by $as_me, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -1817,7 +1811,6 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu - ac_aux_dir= for ac_dir in ../.. "$srcdir"/../..; do if test -f "$ac_dir/install-sh"; then @@ -3860,7 +3853,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by Cygwin Utils $as_me 0, which was +This file was extended by $as_me, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -3907,14 +3900,13 @@ Usage: $0 [OPTION]... [TAG]... Configuration files: $config_files -Report bugs to <cygwin@cygwin.com>. -Cygwin Utils home page: <https://cygwin.com>." +Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -Cygwin Utils config.status 0 +config.status configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/winsup/utils/configure.ac b/winsup/utils/configure.ac index d90c3fc6f..5f517c0d0 100644 --- a/winsup/utils/configure.ac +++ b/winsup/utils/configure.ac @@ -1,6 +1,5 @@ dnl Autoconf configure script for Cygwin utilities. -dnl Copyright 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2006, 2008, 2012, 2013, -dnl 2014 Red Hat, Inc. +dnl Copyright 1996, 1997, 1998, 1999, 2000 Cygnus Solutions. dnl dnl This file is part of Cygwin. dnl @@ -11,9 +10,7 @@ dnl details. dnl Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) -AC_INIT([Cygwin Utils], 0, - cygwin@cygwin.com, cygwin, https://cygwin.com) -AC_CONFIG_SRCDIR(mount.cc) +AC_INIT(mount.cc) AC_CONFIG_AUX_DIR(../..) AC_NO_EXECUTABLES diff --git a/winsup/utils/cygcheck.cc b/winsup/utils/cygcheck.cc index 5d823e9a3..cc400519e 100644 --- a/winsup/utils/cygcheck.cc +++ b/winsup/utils/cygcheck.cc @@ -1480,13 +1480,10 @@ dump_sysinfo () ? "8" : "2012"); break; case 3: - strcpy (osname, osversion.wProductType == VER_NT_WORKSTATION - ? "8.1" : "2012 R2"); - break; - case 4: default: + osversion.dwMinorVersion = 3; strcpy (osname, osversion.wProductType == VER_NT_WORKSTATION - ? "10" : "2014"); + ? "8.1" : "2012 R2"); break; } DWORD prod; diff --git a/winsup/utils/getfacl.c b/winsup/utils/getfacl.c index ed1adfce7..cbde4668a 100644 --- a/winsup/utils/getfacl.c +++ b/winsup/utils/getfacl.c @@ -1,6 +1,6 @@ /* getfacl.c - Copyright 2000, 2001, 2002, 2003, 2004, 2009, 2011, 2014 Red Hat Inc. + Copyright 2000, 2001, 2002, 2003, 2004, 2009, 2011 Red Hat Inc. Written by Corinna Vinschen <vinschen@redhat.com> @@ -87,15 +87,13 @@ usage (FILE * stream) "For directories getfacl displays additionally the default ACL.\n" "\n" "With no options specified, getfacl displays the filename, the\n" - "owner, the group, the setuid (s), setgid (s), and sticky (t)\n" - "bits if available, and both the ACL and the default ACL, if it\n" + "owner, the group, and both the ACL and the default ACL, if it\n" "exists.\n" "\n" "The format for ACL output is as follows:\n" " # file: filename\n" " # owner: name or uid\n" " # group: name or uid\n" - " # flags: sst\n" " user::perm\n" " user:name or uid:perm\n" " group::perm\n" @@ -198,10 +196,6 @@ main (int argc, char **argv) printf ("# owner: %s\n", username (st.st_uid)); printf ("# group: %s\n", groupname (st.st_gid)); } - if (st.st_mode & (S_ISUID | S_ISGID | S_ISVTX)) - printf ("# flags: %c%c%c\n", (st.st_mode & S_ISUID) ? 's' : '-', - (st.st_mode & S_ISGID) ? 's' : '-', - (st.st_mode & S_ISVTX) ? 't' : '-'); for (i = 0; i < num_acls; ++i) { if (acls[i].a_type & ACL_DEFAULT) diff --git a/winsup/utils/mkgroup.c b/winsup/utils/mkgroup.c index 8894b315f..05f5910b0 100644 --- a/winsup/utils/mkgroup.c +++ b/winsup/utils/mkgroup.c @@ -1,7 +1,7 @@ /* mkgroup.c: Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, - 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc. + 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc. This file is part of Cygwin. @@ -21,7 +21,6 @@ #include <inttypes.h> #include <getopt.h> #include <io.h> -#include <grp.h> #include <sys/fcntl.h> #include <sys/cygwin.h> #include <cygwin/version.h> @@ -30,7 +29,9 @@ #include <wininet.h> #include <iptypes.h> #include <ntsecapi.h> +#include <dsgetdc.h> #include <ntdef.h> +#include "loadlib.h" #define print_win_error(x) _print_win_error(x, __LINE__) @@ -46,7 +47,9 @@ SID_IDENTIFIER_AUTHORITY sid_nt_auth = {SECURITY_NT_AUTHORITY}; typedef struct { char *str; + DWORD id_offset; BOOL domain; + BOOL with_dom; } domlist_t; static void @@ -67,6 +70,31 @@ _print_win_error (DWORD code, int line) line, (unsigned int) code); } +static PWCHAR +get_dcname (char *domain) +{ + static WCHAR server[INTERNET_MAX_HOST_NAME_LENGTH + 1]; + DWORD rc; + WCHAR domain_name[MAX_DOMAIN_NAME_LEN + 1]; + PDOMAIN_CONTROLLER_INFOW pdci = NULL; + + if (domain) + { + mbstowcs (domain_name, domain, strlen (domain) + 1); + rc = DsGetDcNameW (NULL, domain_name, NULL, NULL, 0, &pdci); + } + else + rc = DsGetDcNameW (NULL, NULL, NULL, NULL, 0, &pdci); + if (rc != ERROR_SUCCESS) + { + print_win_error (rc); + return (PWCHAR) -1; + } + wcscpy (server, pdci->DomainControllerName); + NetApiBufferFree (pdci); + return server; +} + static char * put_sid (PSID psid) { @@ -121,10 +149,40 @@ fetch_current_pgrp_sid () } static void -enum_unix_groups (domlist_t *mach, const char *sep, DWORD id_offset, +current_group (const char *sep, DWORD id_offset) +{ + WCHAR grp[GNLEN + 1]; + WCHAR 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 (!curr_pgrp.psid + || !LookupAccountSidW (NULL, curr_pgrp.psid, grp, &glen, dom, &dlen, + &acc_type)) + { + print_win_error (GetLastError ()); + return; + } + gid = *GetSidSubAuthority (curr_pgrp.psid, + *GetSidSubAuthorityCount(curr_pgrp.psid) - 1); + printf ("%ls%s%ls:%s:%" PRIu32 ":\n", + sep ? dom : L"", + sep ?: "", + grp, + put_sid (curr_pgrp.psid), + (unsigned int) (id_offset + gid)); +} + +static void +enum_unix_groups (domlist_t *dom_or_machine, const char *sep, DWORD id_offset, char *unix_grp_list) { 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; SID_IDENTIFIER_AUTHORITY auth = { { 0, 0, 0, 0, 0, 22 } }; char *gstr, *grp_list; WCHAR grp[GNLEN + sizeof ("Unix Group\\") + 1]; @@ -134,13 +192,17 @@ enum_unix_groups (domlist_t *mach, const char *sep, DWORD id_offset, char psid_buffer[MAX_SID_LEN]; SID_NAME_USE acc_type; - int ret = mbstowcs (machine, mach->str, INTERNET_MAX_HOST_NAME_LENGTH + 1); + if (!d_or_m) + return; + + 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", - program_invocation_short_name, mach->str); + program_invocation_short_name, d_or_m); return; } + servername = machine; if (!AllocateAndInitializeSid (&auth, 2, 2, 0, 0, 0, 0, 0, 0, 0, &psid)) return; @@ -160,15 +222,15 @@ enum_unix_groups (domlist_t *mach, const char *sep, DWORD id_offset, if (ret < 1 || ret >= GNLEN + 1) fprintf (stderr, "%s: Invalid group name '%s'. Skipping...\n", program_invocation_short_name, gstr); - else if (LookupAccountNameW (machine, grp, + else if (LookupAccountNameW (servername, grp, psid = (PSID) psid_buffer, (sidlen = MAX_SID_LEN, &sidlen), dom, (dlen = MAX_DOMAIN_NAME_LEN + 1, &dlen), &acc_type)) printf ("%s%s%ls:%s:%" PRIu32 ":\n", - "Unix_Group", - sep, + with_dom ? "Unix Group" : "", + with_dom ? sep : "", p, put_sid (psid), (unsigned int) (id_offset + @@ -197,15 +259,15 @@ enum_unix_groups (domlist_t *mach, const char *sep, DWORD id_offset, { *GetSidSubAuthority (psid, *GetSidSubAuthorityCount(psid) - 1) = start; - if (LookupAccountSidW (machine, psid, + if (LookupAccountSidW (servername, psid, grp, (glen = GNLEN + 1, &glen), dom, (dlen = MAX_DOMAIN_NAME_LEN + 1, &dlen), &acc_type) && !iswdigit (grp[0])) printf ("%s%s%ls:%s:%" PRIu32 ":\n", - "Unix_Group", - sep, + with_dom ? "Unix Group" : "", + with_dom ? sep : "", grp, put_sid (psid), (unsigned int) (id_offset + start)); @@ -218,11 +280,14 @@ enum_unix_groups (domlist_t *mach, const char *sep, DWORD id_offset, } static int -enum_local_groups (domlist_t *mach, const char *sep, +enum_local_groups (BOOL domain, domlist_t *dom_or_machine, const char *sep, DWORD id_offset, char *disp_groupname, int print_builtin, int print_current) { 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; @@ -230,12 +295,22 @@ enum_local_groups (domlist_t *mach, const char *sep, WCHAR gname[GNLEN + 1]; DWORD rc; - int ret = mbstowcs (machine, mach->str, INTERNET_MAX_HOST_NAME_LENGTH + 1); - if (ret < 1 || ret >= INTERNET_MAX_HOST_NAME_LENGTH + 1) + if (domain) { - fprintf (stderr, "%s: Invalid machine name '%s'. Skipping...\n", - program_invocation_short_name, mach->str); - return 1; + 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", + program_invocation_short_name, d_or_m); + return 1; + } + servername = machine; } do @@ -245,7 +320,7 @@ enum_local_groups (domlist_t *mach, const char *sep, if (disp_groupname) { mbstowcs (gname, disp_groupname, GNLEN + 1); - rc = NetLocalGroupGetInfo (machine, gname, 0, (void *) &buffer); + rc = NetLocalGroupGetInfo (servername, gname, 0, (void *) &buffer); if (rc == ERROR_SUCCESS) entriesread = 1; /* Allow further searching for the group and avoid annoying @@ -255,7 +330,7 @@ enum_local_groups (domlist_t *mach, const char *sep, return 0; } else - rc = NetLocalGroupEnum (machine, 0, (void *) &buffer, + rc = NetLocalGroupEnum (servername, 0, (void *) &buffer, MAX_PREFERRED_LENGTH, &entriesread, &totalentries, &resume_handle); switch (rc) @@ -285,7 +360,7 @@ enum_local_groups (domlist_t *mach, const char *sep, PDBGSID pdsid; BOOL is_builtin = FALSE; - if (!LookupAccountNameW (machine, buffer[i].lgrpi0_name, psid, + if (!LookupAccountNameW (servername, buffer[i].lgrpi0_name, psid, &sid_length, domain_name, &domname_len, &acc_type)) { @@ -302,7 +377,7 @@ enum_local_groups (domlist_t *mach, const char *sep, wcscat (domname, buffer[i].lgrpi0_name); sid_length = MAX_SID_LEN; domname_len = MAX_DOMAIN_NAME_LEN + 1; - if (!LookupAccountNameW (machine, domname, + if (!LookupAccountNameW (servername, domname, psid, &sid_length, domain_name, &domname_len, &acc_type)) @@ -340,8 +415,8 @@ enum_local_groups (domlist_t *mach, const char *sep, gid = *GetSidSubAuthority (psid, *GetSidSubAuthorityCount(psid) - 1); printf ("%ls%s%ls:%s:%" PRIu32 ":\n", - !is_builtin ? domain_name : L"", - !is_builtin ? sep : "", + with_dom && !is_builtin ? domain_name : L"", + with_dom && !is_builtin ? sep : "", buffer[i].lgrpi0_name, put_sid (psid), (unsigned int) (gid + (is_builtin ? 0 : id_offset))); @@ -361,10 +436,13 @@ skip_group: } static void -enum_groups (domlist_t *mach, const char *sep, DWORD id_offset, - char *disp_groupname, int print_current) +enum_groups (BOOL domain, domlist_t *dom_or_machine, const char *sep, + DWORD id_offset, char *disp_groupname, int print_current) { 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; @@ -372,12 +450,22 @@ enum_groups (domlist_t *mach, const char *sep, DWORD id_offset, WCHAR gname[GNLEN + 1]; DWORD rc; - int ret = mbstowcs (machine, mach->str, INTERNET_MAX_HOST_NAME_LENGTH + 1); - if (ret < 1 || ret >= INTERNET_MAX_HOST_NAME_LENGTH + 1) + if (domain) { - fprintf (stderr, "%s: Invalid machine name '%s'. Skipping...\n", - program_invocation_short_name, mach->str); - return; + 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", + program_invocation_short_name, d_or_m); + return; + } + servername = machine; } do @@ -387,7 +475,8 @@ enum_groups (domlist_t *mach, const char *sep, DWORD id_offset, if (disp_groupname != NULL) { mbstowcs (gname, disp_groupname, GNLEN + 1); - rc = NetGroupGetInfo (machine, (LPWSTR) & gname, 2, (void *) &buffer); + rc = NetGroupGetInfo (servername, (LPWSTR) & gname, 2, + (void *) &buffer); entriesread=1; /* Avoid annoying error messages just because the group hasn't been found. */ @@ -395,8 +484,9 @@ enum_groups (domlist_t *mach, const char *sep, DWORD id_offset, return; } else - rc = NetGroupEnum (machine, 2, (void *) & buffer, MAX_PREFERRED_LENGTH, - &entriesread, &totalentries, &resume_handle); + rc = NetGroupEnum (servername, 2, (void *) & buffer, + MAX_PREFERRED_LENGTH, &entriesread, &totalentries, + &resume_handle); switch (rc) { case ERROR_ACCESS_DENIED: @@ -422,7 +512,7 @@ enum_groups (domlist_t *mach, const char *sep, DWORD id_offset, SID_NAME_USE acc_type; int gid = buffer[i].grpi2_group_id; - if (!LookupAccountNameW (machine, buffer[i].grpi2_name, + if (!LookupAccountNameW (servername, buffer[i].grpi2_name, psid, &sid_length, domain_name, &domname_len, &acc_type)) @@ -435,13 +525,16 @@ enum_groups (domlist_t *mach, const char *sep, DWORD id_offset, { WCHAR domname[MAX_DOMAIN_NAME_LEN + GNLEN + 2]; - wcscpy (domname, machine); + wcscpy (domname, domain || !servername + ? domain_name : servername); wcscat (domname, L"\\"); wcscat (domname, buffer[i].grpi2_name); sid_length = MAX_SID_LEN; domname_len = MAX_DOMAIN_NAME_LEN + 1; - if (!LookupAccountNameW (machine, domname, psid, &sid_length, - domain_name, &domname_len, &acc_type)) + if (!LookupAccountNameW (servername, domname, + psid, &sid_length, + domain_name, &domname_len, + &acc_type)) { print_win_error (GetLastError ()); fprintf(stderr, " (%ls)\n", domname); @@ -454,8 +547,8 @@ enum_groups (domlist_t *mach, const char *sep, DWORD id_offset, got_curr_pgrp = TRUE; printf ("%ls%s%ls:%s:%" PRIu32 ":\n", - domain_name, - sep, + with_dom ? domain_name : L"", + with_dom ? sep : "", buffer[i].grpi2_name, put_sid (psid), (unsigned int) (id_offset + gid)); @@ -467,42 +560,107 @@ enum_groups (domlist_t *mach, const char *sep, DWORD id_offset, while (rc == ERROR_MORE_DATA); } +static void +print_special_by_sid (PSID_IDENTIFIER_AUTHORITY auth, BYTE cnt, + DWORD sub1, DWORD sub2, DWORD sub3, DWORD sub4, + DWORD sub5, DWORD sub6, DWORD sub7, DWORD sub8) +{ + WCHAR grp[GNLEN + 1], dom[MAX_DOMAIN_NAME_LEN + 1]; + DWORD glen, dlen, rid; + PSID psid; + SID_NAME_USE acc_type; + + if (AllocateAndInitializeSid (auth, cnt, sub1, sub2, sub3, sub4, + sub5, sub6, sub7, sub8, &psid)) + { + if (LookupAccountSidW (NULL, psid, + grp, (glen = GNLEN + 1, &glen), + dom, (dlen = MAX_DOMAIN_NAME_LEN + 1, &dlen), + &acc_type)) + { + if (sub8) + rid = sub8; + else if (sub7) + rid = sub7; + else if (sub6) + rid = sub6; + else if (sub5) + rid = sub5; + else if (sub4) + rid = sub4; + else if (sub3) + rid = sub3; + else if (sub2) + rid = sub2; + else + rid = sub1; + printf ("%ls:%s:%" PRIu32 ":\n", grp, put_sid (psid), + (unsigned int) rid); + } + FreeSid (psid); + } +} + +static void +print_special_by_name (PCWSTR name, gid_t gid) +{ + DWORD size = 256, dom_size = 256; + PSID sid = (PSID) alloca (size); + WCHAR dom[dom_size]; + SID_NAME_USE use; + + PWCHAR name_only = wcschr (name, L'\\'); + if (name_only) + ++name_only; + + if (LookupAccountNameW (NULL, name, sid, &size, dom, &dom_size, &use)) + printf ("%ls:%s:%lu:\n", + name_only ?: name, put_sid (sid), (unsigned long) gid); +} + static int usage (FILE * stream) { fprintf (stream, "Usage: %s [OPTION]...\n" "\n" -"Write /etc/group-like output to stdout\n" -"\n" -"Don't use this command to generate a local /etc/group file, unless you\n" -"really need one. See the Cygwin User's Guide for more information.\n" +"Print /etc/group file to stdout\n" "\n" "Options:\n" "\n" -" -l,--local [machine] print local groups of \"machine\"\n" +" -l,--local [machine[,offset]]\n" +" print local groups with gid offset offset\n" " (from local machine if no machine specified)\n" -" -d,--domain [domain] print domain groups\n" +" -L,--Local [machine[,offset]]\n" +" ditto, but generate groupname with machine prefix\n" +" -d,--domain [domain[,offset]]\n" +" print domain groups with gid offset offset\n" " (from current domain if no domain specified)\n" +" -D,--Domain [domain[,offset]]\n" +" ditto, but generate groupname with machine prefix\n" " -c,--current print current group\n" -" -S,--separator char for -l use character char as domain\\group\n" -" separator in groupname instead of default '%s'\n" -" -o,--id-offset offset change the default offset (0x10000) added to\n" -" gids of foreign machine accounts.\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, -d must be specified, too\n" +" one of -l, -L, -d, -D must be specified, too\n" " -b,--no-builtin don't print BUILTIN groups\n" -" -U,--unix grouplist print UNIX groups when using -l on a UNIX Samba\n" -" server. grouplist is a comma-separated list of\n" -" groupnames or gid ranges (root,-25,50-100).\n" +" -U,--unix grouplist additionally print UNIX groups when using -l or -L\n" +" on a UNIX Samba server\n" +" grouplist is a comma-separated list of groupnames\n" +" or gid ranges (root,-25,50-100).\n" " (enumerating large ranges can take a long time!)\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" -"\n", program_invocation_short_name, - (const char *) cygwin_internal (CW_GETNSSSEP)); +"\n", program_invocation_short_name); return 1; } @@ -541,20 +699,44 @@ print_version () strrchr (__DATE__, ' ') + 1); } +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 *) ((void *) &p_dom)); + LsaClose (lsa); + if (!NT_SUCCESS (status)) + return FALSE; + } + return !!p_dom->Sid; +} + int main (int argc, char **argv) { int print_domlist = 0; domlist_t domlist[32]; - char *opt, *p; + char *opt, *p, *ep; int print_current = 0; + int print_system = 0; int print_builtin = 1; char *print_unix = NULL; - const char *sep_char = (const char *) cygwin_internal (CW_GETNSSSEP); - DWORD id_offset = 0x10000, off; + const char *sep_char = "\\"; + DWORD id_offset = 10000, off; int c, i; char *disp_groupname = NULL; - //BOOL in_domain; + BOOL in_domain; int optional_args = 0; if (!isatty (1)) @@ -564,21 +746,22 @@ main (int argc, char **argv) setlocale (LC_CTYPE, ""); if (!strcmp (setlocale (LC_CTYPE, NULL), "C")) setlocale (LC_CTYPE, "en_US.UTF-8"); + in_domain = fetch_primary_domain (); fetch_current_pgrp_sid (); if (argc == 1) { - int enums = ENUM_PRIMARY | ENUM_LOCAL | ENUM_BUILTIN; - uintptr_t ticket = cygwin_internal (CW_SETENT, TRUE, enums, NULL); - if (ticket) + print_special_by_sid (&sid_nt_auth, 1, SECURITY_LOCAL_SYSTEM_RID, + 0, 0, 0, 0, 0, 0, 0); + if (in_domain) { - struct group *grp; - - while ((grp = (struct group *) cygwin_internal (CW_GETENT, TRUE, - ticket))) - printf ("%s:%s:%u:\n", grp->gr_name, grp->gr_passwd, grp->gr_gid); - cygwin_internal (CW_ENDENT, TRUE, ticket); + if (!enum_local_groups (TRUE, NULL, sep_char, id_offset, + disp_groupname, print_builtin, 0)) + enum_groups (TRUE, NULL, sep_char, id_offset, disp_groupname, 0); } + else if (!enum_local_groups (FALSE, NULL, sep_char, 0, disp_groupname, + print_builtin, 0)) + enum_groups (FALSE, NULL, sep_char, 0, disp_groupname, 0); return 0; } @@ -614,12 +797,17 @@ main (int argc, char **argv) program_invocation_short_name, domlist[i].domain ? "domain" : "machine", domlist[i].str); - break; + goto skip; } - domlist[print_domlist].str = opt; + if (!(domlist[print_domlist].str = opt)) + print_system = 1; + domlist[print_domlist].id_offset = UINT32_MAX; if (opt && (p = strchr (opt, ','))) { - if (p == opt) + if (p == opt + || !isdigit ((unsigned char) p[1]) + || (domlist[print_domlist].id_offset = strtol (p + 1, &ep, 10) + , *ep)) { fprintf (stderr, "%s: Malformed machine,offset string '%s'. " "Skipping...\n", program_invocation_short_name, opt); @@ -627,27 +815,15 @@ main (int argc, char **argv) } *p = '\0'; } - if ((c == 'l' || c == 'L') && opt) - { - char cname[1024]; - DWORD csize = sizeof cname; - - /* Check if machine name is local machine. Keep it simple. */ - if (GetComputerNameExA (strchr (opt, '.') - ? ComputerNameDnsFullyQualified - : ComputerNameNetBIOS, - cname, &csize) - && strcasecmp (opt, cname) == 0) - domlist[print_domlist].str = NULL; - } - ++print_domlist; + domlist[print_domlist++].with_dom = (c == 'D' || c == 'L'); +skip: break; case 'S': sep_char = optarg; if (strlen (sep_char) > 1) { - fprintf (stderr, "%s: Only one ASCII character allowed as " - "domain\\user separator character.\n", + fprintf (stderr, "%s: Only one character allowed as domain\\user " + "separator character.\n", program_invocation_short_name); return 1; } @@ -662,6 +838,8 @@ main (int argc, char **argv) print_unix = optarg; break; case 'c': + sep_char = NULL; + /*FALLTHRU*/ case 'C': print_current = 1; break; @@ -698,77 +876,34 @@ main (int argc, char **argv) exit (1); } - struct group *pgrp = NULL; - if (print_current) - pgrp = (struct group *) cygwin_internal (CW_GETGRSID, TRUE, curr_pgrp.psid); - - int enums = ENUM_NONE; - WCHAR tdoms[print_domlist * 258]; - PWCHAR t = tdoms; - if (!disp_groupname && print_builtin && print_domlist) - enums |= ENUM_BUILTIN; - for (i = 0; i < print_domlist; ++i) - { - if (domlist[i].domain) - { - if (domlist[i].str) - { - enums |= ENUM_TDOMS; - t += mbstowcs (t, domlist[i].str, 257); - *t++ = L'\0'; - } - else - enums |= ENUM_PRIMARY; - } - else if (!domlist[i].str) - enums |= ENUM_LOCAL; - } - if (t > tdoms) - *t++ = L'\0'; - if (enums) + /* Get 'system' group */ + if (!disp_groupname && print_system && print_builtin && print_domlist) { - uintptr_t ticket = cygwin_internal (CW_SETENT, TRUE, enums, - t > tdoms ? tdoms : NULL); - if (ticket) - { - struct group *grp; - const char *nss_sep = (const char *) cygwin_internal (CW_GETNSSSEP); - - while ((grp = (struct group *) - cygwin_internal (CW_GETENT, TRUE, ticket))) - { - if (disp_groupname - && strcasecmp (disp_groupname, grp->gr_name) != 0 - && (!(p = strchr (grp->gr_name, nss_sep[0])) - || strcasecmp (disp_groupname, p + 1) != 0)) - continue; - printf ("%s:%s:%u:\n", grp->gr_name, grp->gr_passwd, - grp->gr_gid); - if (pgrp && !strcmp (grp->gr_passwd, pgrp->gr_passwd)) - got_curr_pgrp = TRUE; - } - cygwin_internal (CW_ENDENT, TRUE, ticket); - } + print_special_by_sid (&sid_nt_auth, 1, SECURITY_LOCAL_SYSTEM_RID, + 0, 0, 0, 0, 0, 0, 0); + print_special_by_name (L"NT SERVICE\\TrustedInstaller", -2); } - if (print_current && !got_curr_pgrp) - printf ("%s:%s:%u:\n", pgrp->gr_name, pgrp->gr_passwd, pgrp->gr_gid); - - off = 0xfd000000; + off = id_offset; for (i = 0; i < print_domlist; ++i) { - if (domlist[i].domain || !domlist[i].str) - continue; - if (!enum_local_groups (domlist + i, sep_char, off, disp_groupname, - print_builtin, print_current)) + DWORD my_off = (domlist[i].domain || domlist[i].str) + ? domlist[i].id_offset != UINT_MAX + ? domlist[i].id_offset : off : 0; + if (!enum_local_groups (domlist[i].domain, domlist + i, sep_char, + my_off, disp_groupname, print_builtin, print_current)) { - enum_groups (domlist + i, sep_char, off, disp_groupname, - print_current); if (!domlist[i].domain && domlist[i].str && print_unix) - enum_unix_groups (domlist + i, sep_char, 0xff000000, print_unix); - off += id_offset; + enum_unix_groups (domlist + i, sep_char, my_off, print_unix); + enum_groups (domlist[i].domain, domlist + i, sep_char, my_off, + disp_groupname, print_current); + if (my_off) + off += id_offset; } } + if (print_current && !got_curr_pgrp) + current_group (sep_char, off); + return 0; } diff --git a/winsup/utils/mkpasswd.c b/winsup/utils/mkpasswd.c index 5ff33d8a1..d080dbd70 100644 --- a/winsup/utils/mkpasswd.c +++ b/winsup/utils/mkpasswd.c @@ -1,7 +1,7 @@ /* mkpasswd.c: Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2008, 2009, - 2010, 2011, 2012, 2013, 2014 Red Hat, Inc. + 2010, 2011, 2012, 2013 Red Hat, Inc. This file is part of Cygwin. @@ -21,7 +21,6 @@ #include <inttypes.h> #include <getopt.h> #include <io.h> -#include <pwd.h> #include <sys/fcntl.h> #include <sys/cygwin.h> #include <cygwin/version.h> @@ -32,6 +31,7 @@ #include <ntsecapi.h> #include <dsgetdc.h> #include <ntdef.h> +#include "loadlib.h" #define print_win_error(x) _print_win_error(x, __LINE__) @@ -47,7 +47,9 @@ SID_IDENTIFIER_AUTHORITY sid_nt_auth = {SECURITY_NT_AUTHORITY}; typedef struct { char *str; + DWORD id_offset; BOOL domain; + BOOL with_dom; } domlist_t; static void @@ -68,6 +70,31 @@ _print_win_error(DWORD code, int line) line, (unsigned int) code); } +static PWCHAR +get_dcname (char *domain) +{ + static WCHAR server[INTERNET_MAX_HOST_NAME_LENGTH + 1]; + DWORD rc; + WCHAR domain_name[MAX_DOMAIN_NAME_LEN + 1]; + PDOMAIN_CONTROLLER_INFOW pdci = NULL; + + if (domain) + { + mbstowcs (domain_name, domain, strlen (domain) + 1); + rc = DsGetDcNameW (NULL, domain_name, NULL, NULL, 0, &pdci); + } + else + rc = DsGetDcNameW (NULL, NULL, NULL, NULL, 0, &pdci); + if (rc != ERROR_SUCCESS) + { + print_win_error (rc); + return (PWCHAR) -1; + } + wcscpy (server, pdci->DomainControllerName); + NetApiBufferFree (pdci); + return server; +} + static char * put_sid (PSID sid) { @@ -123,10 +150,72 @@ fetch_current_user_sid () } static void -enum_unix_users (domlist_t *mach, const char *sep, DWORD id_offset, +current_user (const char *sep, const char *passed_home_path, DWORD id_offset, + const char *disp_username) +{ + WCHAR user[UNLEN + 1]; + WCHAR 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}; + + if (!curr_user.psid || !curr_pgrp.psid + || !LookupAccountSidW (NULL, curr_user.psid, user, &ulen, dom, &dlen, + &acc_type)) + { + print_win_error (GetLastError ()); + return; + } + + uid = *GetSidSubAuthority (curr_user.psid, + *GetSidSubAuthorityCount(curr_user.psid) - 1); + gid = *GetSidSubAuthority (curr_pgrp.psid, + *GetSidSubAuthorityCount(curr_pgrp.psid) - 1); + if (passed_home_path[0] == '\0') + { + char *envhome = getenv ("HOME"); + + /* If $HOME exists and is non-empty, just copy it over to homedir_psx. + Otherwise, generate a new path of the form "/home/$USER". */ + if (envhome && envhome[0] != '\0') + strncat (homedir_psx, envhome, sizeof (homedir_psx) - 1); + else + { + wcstombs (stpncpy (homedir_psx, "/home/", sizeof (homedir_psx)), + user, sizeof (homedir_psx) - 6); + homedir_psx[PATH_MAX - 1] = '\0'; + } + } + else + { + char *p = stpncpy (homedir_psx, passed_home_path, sizeof (homedir_psx)); + wcstombs (p, user, sizeof (homedir_psx) - (p - homedir_psx)); + homedir_psx[PATH_MAX - 1] = '\0'; + } + + printf ("%ls%s%ls:unused:%" PRIu32 ":%" PRIu32 + ":U-%ls\\%ls,%s:%s:/bin/bash\n", + sep ? dom : L"", + sep ?: "", + user, + (unsigned int) (id_offset + uid), + (unsigned int) (id_offset + gid), + dom, + user, + put_sid (curr_user.psid), + homedir_psx); +} + +static void +enum_unix_users (domlist_t *dom_or_machine, const char *sep, DWORD id_offset, char *unix_user_list) { 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; SID_IDENTIFIER_AUTHORITY auth = { { 0, 0, 0, 0, 0, 22 } }; char *ustr, *user_list; WCHAR user[UNLEN + sizeof ("Unix User\\") + 1]; @@ -136,13 +225,17 @@ enum_unix_users (domlist_t *mach, const char *sep, DWORD id_offset, char psid_buffer[MAX_SID_LEN]; SID_NAME_USE acc_type; - int ret = mbstowcs (machine, mach->str, INTERNET_MAX_HOST_NAME_LENGTH + 1); + if (!d_or_m) + return; + + 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", - program_invocation_short_name, mach->str); + program_invocation_short_name, d_or_m); return; } + servername = machine; if (!AllocateAndInitializeSid (&auth, 2, 1, 0, 0, 0, 0, 0, 0, 0, &psid)) return; @@ -162,15 +255,15 @@ enum_unix_users (domlist_t *mach, const char *sep, DWORD id_offset, if (ret < 1 || ret >= UNLEN + 1) fprintf (stderr, "%s: Invalid user name '%s'. Skipping...\n", program_invocation_short_name, ustr); - else if (LookupAccountNameW (machine, user, + else if (LookupAccountNameW (servername, user, psid = (PSID) psid_buffer, (sidlen = MAX_SID_LEN, &sidlen), dom, (dlen = MAX_DOMAIN_NAME_LEN + 1, &dlen), &acc_type)) printf ("%s%s%ls:unused:%" PRIu32 ":99999:,%s::\n", - "Unix_User", - sep, + with_dom ? "Unix User" : "", + with_dom ? sep : "", user + 10, (unsigned int) (id_offset + *GetSidSubAuthority (psid, @@ -199,15 +292,15 @@ enum_unix_users (domlist_t *mach, const char *sep, DWORD id_offset, { *GetSidSubAuthority (psid, *GetSidSubAuthorityCount(psid) - 1) = start; - if (LookupAccountSidW (machine, psid, + if (LookupAccountSidW (servername, psid, user, (ulen = GNLEN + 1, &ulen), dom, (dlen = MAX_DOMAIN_NAME_LEN + 1, &dlen), &acc_type) && !iswdigit (user[0])) printf ("%s%s%ls:unused:%" PRIu32 ":99999:,%s::\n", - "Unix_User", - sep, + with_dom ? "Unix User" : "", + with_dom ? sep : "", user, (unsigned int) (id_offset + start), put_sid (psid)); @@ -220,23 +313,36 @@ enum_unix_users (domlist_t *mach, const char *sep, DWORD id_offset, } static int -enum_users (domlist_t *mach, const char *sep, const char *passed_home_path, - DWORD id_offset, char *disp_username, int print_current) +enum_users (BOOL domain, domlist_t *dom_or_machine, const char *sep, + const char *passed_home_path, DWORD id_offset, char *disp_username, + int print_current) { 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]; - - int ret = mbstowcs (machine, mach->str, INTERNET_MAX_HOST_NAME_LENGTH + 1); - if (ret < 1 || ret >= INTERNET_MAX_HOST_NAME_LENGTH + 1) + if (domain) { - fprintf (stderr, "%s: Invalid machine name '%s'. Skipping...\n", - program_invocation_short_name, mach->str); - return 1; + 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", + program_invocation_short_name, d_or_m); + return 1; + } + servername = machine; } do @@ -246,7 +352,7 @@ enum_users (domlist_t *mach, const char *sep, const char *passed_home_path, if (disp_username != NULL) { mbstowcs (uni_name, disp_username, UNLEN + 1); - rc = NetUserGetInfo (machine, (LPWSTR) &uni_name, 3, + rc = NetUserGetInfo (servername, (LPWSTR) &uni_name, 3, (void *) &buffer); entriesread = 1; /* Avoid annoying error messages just because the user hasn't been @@ -255,7 +361,7 @@ enum_users (domlist_t *mach, const char *sep, const char *passed_home_path, return 0; } else - rc = NetUserEnum (machine, 3, FILTER_NORMAL_ACCOUNT, + rc = NetUserEnum (servername, 3, FILTER_NORMAL_ACCOUNT, (void *) &buffer, MAX_PREFERRED_LENGTH, &entriesread, &totalentries, &resume_handle); switch (rc) @@ -301,7 +407,7 @@ enum_users (domlist_t *mach, const char *sep, const char *passed_home_path, stpcpy (homedir_psx, passed_home_path), PATH_MAX - strlen (passed_home_path)); - if (!LookupAccountNameW (machine, buffer[i].usri3_name, + if (!LookupAccountNameW (servername, buffer[i].usri3_name, psid, &sid_length, domain_name, &domname_len, &acc_type)) { @@ -313,12 +419,13 @@ enum_users (domlist_t *mach, const char *sep, const char *passed_home_path, { WCHAR domname[MAX_DOMAIN_NAME_LEN + UNLEN + 2]; - wcscpy (domname, machine); + wcscpy (domname, domain || !servername + ? domain_name : servername); wcscat (domname, L"\\"); wcscat (domname, buffer[i].usri3_name); sid_length = MAX_SID_LEN; domname_len = sizeof (domname); - if (!LookupAccountNameW (machine, domname, psid, + if (!LookupAccountNameW (servername, domname, psid, &sid_length, domain_name, &domname_len, &acc_type)) { @@ -334,8 +441,8 @@ enum_users (domlist_t *mach, const char *sep, const char *passed_home_path, printf ("%ls%s%ls:unused:%" PRIu32 ":%" PRIu32 ":%ls%sU-%ls\\%ls,%s:%s:/bin/bash\n", - domain_name, - sep, + with_dom ? domain_name : L"", + with_dom ? sep : "", buffer[i].usri3_name, (unsigned int) (id_offset + uid), (unsigned int) (id_offset + gid), @@ -356,49 +463,98 @@ enum_users (domlist_t *mach, const char *sep, const char *passed_home_path, return 0; } +static void +print_special_by_sid (PSID_IDENTIFIER_AUTHORITY auth, BYTE cnt, + DWORD sub1, DWORD sub2, DWORD sub3, DWORD sub4, + DWORD sub5, DWORD sub6, DWORD sub7, DWORD sub8) +{ + WCHAR user[UNLEN + 1], dom[MAX_DOMAIN_NAME_LEN + 1]; + DWORD len, len2, rid; + PSID sid; + SID_NAME_USE acc_type; + + if (AllocateAndInitializeSid (auth, cnt, sub1, sub2, sub3, sub4, + sub5, sub6, sub7, sub8, &sid)) + { + if (LookupAccountSidW (NULL, sid, + user, (len = UNLEN + 1, &len), + dom, (len2 = MAX_DOMAIN_NAME_LEN + 1, &len2), + &acc_type)) + { + if (sub8) + rid = sub8; + else if (sub7) + rid = sub7; + else if (sub6) + rid = sub6; + else if (sub5) + rid = sub5; + else if (sub4) + rid = sub4; + else if (sub3) + rid = sub3; + else if (sub2) + rid = sub2; + else + rid = sub1; + printf ("%ls:*:%" PRIu32 ":%" PRIu32 ":,%s::\n", + user, (unsigned int) rid, + (unsigned int) (rid == 18 ? 544 : rid), /* SYSTEM hack */ + put_sid (sid)); + } + FreeSid (sid); + } +} + static int usage (FILE * stream) { fprintf (stream, "Usage: %s [OPTIONS]...\n" "\n" -"Write /etc/passwd-like output to stdout\n" -"\n" -"Don't use this command to generate a local /etc/passwd file, unless you\n" -"really need one. See the Cygwin User's Guide for more information.\n" +"Print /etc/passwd file to stdout\n" "\n" "Options:\n" "\n" -" -l,--local [machine] print local user accounts of \"machine\"\n" +" -l,--local [machine[,offset]]\n" +" print local user accounts with uid offset offset\n" " (from local machine if no machine specified)\n" -" -d,--domain [domain] print domain accounts\n" +" -L,--Local [machine[,offset]]\n" +" ditto, but generate username with machine prefix\n" +" -d,--domain [domain[,offset]]\n" +" print domain accounts with uid offset offset\n" " (from current domain if no domain specified)\n" +" -D,--Domain [domain[,offset]]\n" +" ditto, but generate username with domain prefix\n" " -c,--current print current user\n" -" -S,--separator char for -l use character char as domain\\user\n" -" separator in username instead of the default '%s'\n" -" -o,--id-offset offset change the default offset (0x10000) added to uids\n" -" of foreign local machine accounts. Use with -l.\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, -d must be specified, too\n" -" -b,--no-builtin don't print BUILTIN users\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" -" -U,--unix userlist print UNIX users when using -l on a UNIX Samba\n" -" server. userlist is a comma-separated list of\n" -" usernames or uid ranges (root,-25,50-100).\n" +" -U,--unix userlist additionally print UNIX users when using -l or -L\n" +" on a UNIX Samba server\n" +" userlist is a comma-separated list of usernames\n" +" or uid ranges (root,-25,50-100).\n" " (enumerating large ranges can take a long time!)\n" +" -s,--no-sids (ignored)\n" +" -m,--no-mount (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" -"\n", program_invocation_short_name, - (const char *) cygwin_internal (CW_GETNSSSEP)); +"\n", program_invocation_short_name); return 1; } static struct option longopts[] = { - {"no-builtin", no_argument, NULL, 'b'}, {"current", no_argument, NULL, 'c'}, {"Current", no_argument, NULL, 'C'}, {"domain", optional_argument, NULL, 'd'}, @@ -418,7 +574,7 @@ static struct option longopts[] = { {0, no_argument, NULL, 0} }; -static char opts[] = "bcCd::D::ghl::L::mo:sS:p:u:U:V"; +static char opts[] = "cCd::D::ghl::L::mo:sS:p:u:U:V"; static void print_version () @@ -434,6 +590,66 @@ print_version () strrchr (__DATE__, ' ') + 1); } +static void +print_special_by_name (PCWSTR name, uid_t uid, gid_t gid) +{ + DWORD size = 256, dom_size = 256; + PSID sid = (PSID) alloca (size); + WCHAR dom[dom_size]; + SID_NAME_USE use; + + PWCHAR name_only = wcschr (name, L'\\'); + if (name_only) + ++name_only; + + if (LookupAccountNameW (NULL, name, sid, &size, dom, &dom_size, &use)) + printf ("%ls:*:%lu:%lu:U-%ls%s%ls,%s::\n", + name_only ?: name, + (unsigned long) uid, + (unsigned long) gid, + name_only ? dom : L"", + name_only ? "\\" : "", + name_only ?: name, + put_sid (sid)); +} + +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_by_sid (&sid_nt_auth, 2, SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0); + /* Fetch "TrustedInstaller" account starting with Vista. */ + print_special_by_name (L"NT SERVICE\\TrustedInstaller", -2, -2); +} + +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 *) ((void *) &p_dom)); + LsaClose (lsa); + if (!NT_SUCCESS (status)) + return FALSE; + } + return !!p_dom->Sid; +} + int main (int argc, char **argv) { @@ -441,14 +657,13 @@ main (int argc, char **argv) domlist_t domlist[32]; char *opt, *p, *ep; int print_current = 0; - int print_builtin = 1; char *print_unix = NULL; - const char *nss_sep = (const char *) cygwin_internal (CW_GETNSSSEP); - const char *sep_char = nss_sep; - DWORD id_offset = 0x10000, off; + const char *sep_char = "\\"; + DWORD id_offset = 10000, off; int c, i; char *disp_username = NULL; char passed_home_path[PATH_MAX]; + BOOL in_domain; int optional_args = 0; passed_home_path[0] = '\0'; @@ -459,23 +674,18 @@ main (int argc, char **argv) setlocale (LC_CTYPE, ""); if (!strcmp (setlocale (LC_CTYPE, NULL), "C")) setlocale (LC_CTYPE, "en_US.UTF-8"); + in_domain = fetch_primary_domain (); fetch_current_user_sid (); if (argc == 1) { - int enums = ENUM_PRIMARY | ENUM_LOCAL | ENUM_BUILTIN; - uintptr_t ticket = cygwin_internal (CW_SETENT, FALSE, enums, NULL); - if (ticket) - { - struct passwd *pwd; - - while ((pwd = (struct passwd *) cygwin_internal (CW_GETENT, FALSE, - ticket))) - printf ("%s:%s:%u:%u:%s:%s:%s\n", pwd->pw_name, pwd->pw_passwd, - pwd->pw_uid, pwd->pw_gid, pwd->pw_gecos, pwd->pw_dir, - pwd->pw_shell); - cygwin_internal (CW_ENDENT, FALSE, ticket); - } + enum_std_accounts (); + if (in_domain) + enum_users (TRUE, NULL, sep_char, passed_home_path, 10000, + disp_username, 0); + else + enum_users (FALSE, NULL, sep_char, passed_home_path, 0, + disp_username, 0); return 0; } @@ -511,40 +721,32 @@ main (int argc, char **argv) program_invocation_short_name, domlist[i].domain ? "domain" : "machine", domlist[i].str); - break; + goto skip; } domlist[print_domlist].str = opt; + domlist[print_domlist].id_offset = UINT32_MAX; if (opt && (p = strchr (opt, ','))) { - if (p == opt) + if (p == opt + || !isdigit ((unsigned char) p[1]) + || (domlist[print_domlist].id_offset = strtol (p + 1, &ep, 10) + , *ep)) { - fprintf (stderr, "%s: Malformed domain string '%s'. " + fprintf (stderr, "%s: Malformed domain,offset string '%s'. " "Skipping...\n", program_invocation_short_name, opt); break; } *p = '\0'; } - if ((c == 'l' || c == 'L') && opt) - { - char cname[1024]; - DWORD csize = sizeof cname; - - /* Check if machine name is local machine. Keep it simple. */ - if (GetComputerNameExA (strchr (opt, '.') - ? ComputerNameDnsFullyQualified - : ComputerNameNetBIOS, - cname, &csize) - && strcasecmp (opt, cname) == 0) - domlist[print_domlist].str = NULL; - } - ++print_domlist; + domlist[print_domlist++].with_dom = (c == 'D' || c == 'L'); +skip: break; case 'S': sep_char = optarg; if (strlen (sep_char) > 1) { - fprintf (stderr, "%s: Only one ASCII character allowed as " - "domain\\user separator character.\n", + fprintf (stderr, "%s: Only one character allowed as domain\\user " + "separator character.\n", program_invocation_short_name); return 1; } @@ -559,14 +761,19 @@ main (int argc, char **argv) print_unix = optarg; break; case 'c': + sep_char = NULL; + /*FALLTHRU*/ case 'C': print_current = 1; break; case 'o': id_offset = strtoul (optarg, &ep, 10); - break; - case 'b': - print_builtin = 0; + if (*ep) + { + fprintf (stderr, "%s: Malformed offset '%s'. " + "Skipping...\n", program_invocation_short_name, optarg); + return 1; + } break; case 'p': if (optarg[0] != '/') @@ -607,91 +814,24 @@ main (int argc, char **argv) exit (1); } - struct passwd *ppwd = NULL; - const char *ppwd_sid = NULL; - if (print_current) - { - ppwd = (struct passwd *) cygwin_internal (CW_GETPWSID, TRUE, - curr_user.psid); - if (ppwd) - ppwd_sid = strrchr (ppwd->pw_gecos, ','); - } - - int enums = ENUM_NONE; - WCHAR tdoms[print_domlist * 258]; - PWCHAR t = tdoms; - if (!disp_username && print_builtin && print_domlist) - enums |= ENUM_BUILTIN; + off = id_offset; for (i = 0; i < print_domlist; ++i) { - if (domlist[i].domain) - { - if (domlist[i].str) - { - enums |= ENUM_TDOMS; - t += mbstowcs (t, domlist[i].str, 257); - *t++ = L'\0'; - } - else - enums |= ENUM_PRIMARY; - } - else if (!domlist[i].str) - enums |= ENUM_LOCAL; - } - if (t > tdoms) - *t++ = L'\0'; - if (enums) - { - uintptr_t ticket = cygwin_internal (CW_SETENT, FALSE, enums, - t > tdoms ? tdoms : NULL); - if (ticket) - { - struct passwd *pwd; - - while ((pwd = (struct passwd *) - cygwin_internal (CW_GETENT, FALSE, ticket))) - { - p = NULL; - if (disp_username - && strcasecmp (disp_username, pwd->pw_name) != 0 - && (!(p = strchr (pwd->pw_name, nss_sep[0])) - || strcasecmp (disp_username, p + 1) != 0)) - continue; - printf ("%s:%s:%u:%u:%s:%s%s:%s\n", pwd->pw_name, pwd->pw_passwd, - pwd->pw_uid, pwd->pw_gid, pwd->pw_gecos, - passed_home_path[0] ? passed_home_path : "", - passed_home_path[0] ? (p ? p + 1 : pwd->pw_name) - : pwd->pw_dir, - pwd->pw_shell); - const char *pwd_sid = strrchr (pwd->pw_gecos, ','); - if (ppwd && ppwd_sid && pwd_sid && !strcmp (pwd_sid, ppwd_sid)) - got_curr_user = TRUE; - } - cygwin_internal (CW_ENDENT, FALSE, ticket); - } + DWORD my_off = (domlist[i].domain || domlist[i].str) + ? domlist[i].id_offset != UINT_MAX + ? domlist[i].id_offset : off : 0; + if (!domlist[i].domain && domlist[i].str && print_unix) + enum_unix_users (domlist + i, sep_char, my_off, print_unix); + if (!my_off && !disp_username) + enum_std_accounts (); + enum_users (domlist[i].domain, domlist + i, sep_char, passed_home_path, + my_off, disp_username, print_current); + if (my_off) + off += id_offset; } if (print_current && !got_curr_user) - { - p = strchr (ppwd->pw_name, nss_sep[0]); - printf ("%s:%s:%u:%u:%s:%s%s:%s\n", ppwd->pw_name, ppwd->pw_passwd, - ppwd->pw_uid, ppwd->pw_gid, ppwd->pw_gecos, - passed_home_path[0] ? passed_home_path : "", - passed_home_path[0] ? (p ? p + 1 : ppwd->pw_name) : ppwd->pw_dir, - ppwd->pw_shell); - } - - off = 0xfd000000; - for (i = 0; i < print_domlist; ++i) - { - if (domlist[i].domain || !domlist[i].str) - continue; - enum_users (domlist + i, sep_char, passed_home_path, off, disp_username, - print_current); - if (!domlist[i].domain && domlist[i].str && print_unix) - enum_unix_users (domlist + i, sep_char, 0xff000000, print_unix); - off += id_offset; - } + current_user (sep_char, passed_home_path, off, disp_username); return 0; } diff --git a/winsup/utils/passwd.c b/winsup/utils/passwd.c index 2046849a1..991935a2a 100644 --- a/winsup/utils/passwd.c +++ b/winsup/utils/passwd.c @@ -1,7 +1,7 @@ /* passwd.c: Changing passwords and managing account information Copyright 1999, 2000, 2001, 2002, 2003, 2005, 2008, 2009, 2011, 2012, - 2013, 2014 Red Hat, Inc. + 2013 Red Hat, Inc. Written by Corinna Vinschen <corinna.vinschen@cityweb.de> @@ -84,7 +84,7 @@ EvalRet (int ret, const char *user) return 0; case ERROR_ACCESS_DENIED: - if (!user) + if (! user) eprint (0, "You may not change password expiry information."); else eprint (0, "You may not change the password for %s.", user); @@ -153,7 +153,7 @@ ChangePW (const char *user, const char *oldpwd, const char *pwd, int justcheck, mbstowcs (name, user, UNLEN + 1); mbstowcs (pass, pwd, 512); - if (!oldpwd) + if (! oldpwd) { USER_INFO_1003 ui; @@ -167,8 +167,10 @@ ChangePW (const char *user, const char *oldpwd, const char *pwd, int justcheck, } if (justcheck && ret != ERROR_INVALID_PASSWORD) return 0; - if (!EvalRet (ret, user) && !justcheck) - eprint (0, "Password changed."); + if (! EvalRet (ret, user) && ! justcheck) + { + eprint (0, "Password changed."); + } return ret; } @@ -191,7 +193,7 @@ PrintPW (PUSER_INFO_3 ui, LPCWSTR server) (ui->usri3_password_expired) ? "yes\n" : "no\n"); printf ("Latest password change : %s", ctime(&t)); ret = NetUserModalsGet (server, 0, (void *) &mi); - if (!ret) + if (! ret) { if (mi->usrmod0_max_passwd_age == TIMEQ_FOREVER) mi->usrmod0_max_passwd_age = 0; @@ -220,7 +222,7 @@ SetModals (int xarg, int narg, int iarg, int Larg, LPCWSTR server) PUSER_MODALS_INFO_0 mi; ret = NetUserModalsGet (server, 0, (void *) &mi); - if (!ret) + if (! ret) { if (xarg == 0) mi->usrmod0_max_passwd_age = TIMEQ_FOREVER; @@ -275,8 +277,8 @@ usage (FILE * stream, int status) "System operations:\n" " -i, --inactive NUM set NUM of days before inactive accounts are disabled\n" " (inactive accounts are those with expired passwords).\n" - " -n, --minage MINDAYS set system minimum password age to MINDAYS days.\n" - " -x, --maxage MAXDAYS set system maximum password age to MAXDAYS days.\n" + " -n, --minage DAYS set system minimum password age to DAYS days.\n" + " -x, --maxage DAYS set system maximum password age to DAYS days.\n" " -L, --length LEN set system minimum password length to LEN.\n" "\n" "Other options:\n" @@ -591,7 +593,7 @@ main (int argc, char **argv) } ui = GetPW (user, 1, server); - if (!ui) + if (! ui) return 1; if (lopt || uopt || copt || Copt || eopt || Eopt || popt || Popt || Sopt) @@ -634,6 +636,9 @@ main (int argc, char **argv) if (!caller_is_admin () && !myself) return eprint (0, "You may not change the password for %s.", user); + eprint (0, "Enter the new password (minimum of 5, maximum of 8 characters)."); + eprint (0, "Please use a combination of upper and lower case letters and numbers."); + oldpwd[0] = '\0'; if (!caller_is_admin ()) { @@ -647,11 +652,11 @@ main (int argc, char **argv) strcpy (newpwd, getpass ("New password: ")); if (strcmp (newpwd, getpass ("Re-enter new password: "))) eprint (0, "Password is not identical."); - else if (!ChangePW (user, *oldpwd ? oldpwd : NULL, newpwd, 0, server)) + else if (! ChangePW (user, *oldpwd ? oldpwd : NULL, newpwd, 0, server)) ret = 1; - if (!ret && cnt < 2) + if (! ret && cnt < 2) eprint (0, "Try again."); } - while (!ret && ++cnt < 3); - return !ret; + while (! ret && ++cnt < 3); + return ! ret; } diff --git a/winsup/utils/setfacl.c b/winsup/utils/setfacl.c index 9051fb355..66739c043 100644 --- a/winsup/utils/setfacl.c +++ b/winsup/utils/setfacl.c @@ -1,7 +1,6 @@ /* setfacl.c - Copyright 2000, 2001, 2002, 2003, 2006, 2008, 2009, 2010, 2011, 2014 - Red Hat Inc. + Copyright 2000, 2001, 2002, 2003, 2006, 2008, 2009, 2010, 2011 Red Hat Inc. Written by Corinna Vinschen <vinschen@redhat.com> @@ -48,7 +47,6 @@ typedef enum { Modify, Delete, ModNDel, - DeleteAll, SetFromFile } action_t; @@ -109,22 +107,16 @@ getaclentry (action_t action, char *c, aclent_t *ace) return FALSE; /* Skip to next field. */ c = c2; - if (!*c) - { - /* Nothing follows. This is only valid if action is Delete and the - type is CLASS_OBJ, or if ACL_DEFAULT is set. */ - if (action != Delete - || (!(ace->a_type & (CLASS_OBJ | ACL_DEFAULT)))) - return FALSE; - } - else if (!(ace->a_type & (USER_OBJ | GROUP_OBJ))) + if (!*c && action != Delete) + return FALSE; + /* If this is a user or group entry, check if next char is a colon char. + If so, skip it, otherwise it's the name of a user or group. */ + if (!(ace->a_type & (USER_OBJ | GROUP_OBJ))) { /* Mask and other entries may contain an extra colon. */ if (*c == ':') ++c; } - /* If this is a user or group entry, check if next char is a colon char. - If so, skip it, otherwise it's the name of a user or group. */ else if (*c == ':') ++c; else if (*c) @@ -138,6 +130,8 @@ getaclentry (action_t action, char *c, aclent_t *ace) *c2++ = '\0'; else if (action != Delete) return FALSE; + else if (!(ace->a_type & ACL_DEFAULT)) + return FALSE; /* Fetch user/group id. */ if (isdigit ((unsigned char) *c)) { @@ -268,130 +262,26 @@ modacl (aclent_t *tgt, int tcnt, aclent_t *src, int scnt) } int -addmissing (aclent_t *tgt, int tcnt) -{ - int t; - int types = 0, def_types = 0; - int perm = 0, def_perm = 0; - - /* Check if we have all the required entries now. */ - for (t = 0; t < tcnt; ++t) - if (tgt[t].a_type & ACL_DEFAULT) - { - def_types |= tgt[t].a_type; - if (tgt[t].a_type & (USER | GROUP | GROUP_OBJ)) - def_perm |= tgt[t].a_perm; - } - else - { - types |= tgt[t].a_type; - if (tgt[t].a_type & (USER | GROUP | GROUP_OBJ)) - perm |= tgt[t].a_perm; - } - /* Add missing CLASS_OBJ */ - if ((types & (USER | GROUP)) && !(types & CLASS_OBJ)) - { - tgt[tcnt].a_type = CLASS_OBJ; - tgt[tcnt].a_id = (uid_t) -1; - tgt[tcnt++].a_perm = perm; - } - if (def_types) - { - /* Add missing default entries. */ - if (!(def_types & USER_OBJ) && tcnt < MAX_ACL_ENTRIES) - { - t = searchace (tgt, tcnt, USER_OBJ, -1); - tgt[tcnt].a_type = DEF_USER_OBJ; - tgt[tcnt].a_id = (uid_t) -1; - tgt[tcnt++].a_perm = t >= 0 ? tgt[t].a_perm : S_IRWXO; - } - if (!(def_types & GROUP_OBJ) && tcnt < MAX_ACL_ENTRIES) - { - t = searchace (tgt, tcnt, GROUP_OBJ, -1); - tgt[tcnt].a_type = DEF_GROUP_OBJ; - tgt[tcnt].a_id = (uid_t) -1; - tgt[tcnt].a_perm = t >= 0 ? tgt[t].a_perm : (S_IROTH | S_IXOTH); - def_perm |= tgt[tcnt++].a_perm; - } - if (!(def_types & OTHER_OBJ) && tcnt < MAX_ACL_ENTRIES) - { - t = searchace (tgt, tcnt, OTHER_OBJ, -1); - tgt[tcnt].a_type = DEF_OTHER_OBJ; - tgt[tcnt].a_id = (uid_t) -1; - tgt[tcnt++].a_perm = t >= 0 ? tgt[t].a_perm : (S_IROTH | S_IXOTH); - } - /* Add missing DEF_CLASS_OBJ */ - if ((def_types & (USER | GROUP)) && !(def_types & CLASS_OBJ)) - { - tgt[tcnt].a_type = DEF_CLASS_OBJ; - tgt[tcnt].a_id = (uid_t) -1; - tgt[tcnt++].a_perm = def_perm; - } - } - return tcnt; -} - -int -delacl (aclent_t *tgt, int tcnt) -{ - int t; - - /* Remove all extended ACL entries. */ - for (t = 0; t < tcnt; ++t) - if (tgt[t].a_type & (USER | GROUP | CLASS_OBJ)) - { - --tcnt; - if (t < tcnt) - memmove (&tgt[t], &tgt[t + 1], (tcnt - t) * sizeof (aclent_t)); - --t; - } - return tcnt; -} - -int -setfacl (action_t action, const char *path, aclent_t *acls, int cnt) +setfacl (action_t action, char *path, aclent_t *acls, int cnt) { aclent_t lacl[MAX_ACL_ENTRIES]; int lcnt; memset (lacl, 0, sizeof lacl); - switch (action) + if (action == Set) { - case Set: if (acl (path, SETACL, cnt, acls)) { perror (prog_name); return 2; } - break; - case Delete: - if ((lcnt = acl (path, GETACL, MAX_ACL_ENTRIES, lacl)) < 0 - || (lcnt = modacl (lacl, lcnt, acls, cnt)) < 0 - || (lcnt = acl (path, SETACL, lcnt, lacl)) < 0) - { - perror (prog_name); - return 2; - } - break; - case DeleteAll: - if ((lcnt = acl (path, GETACL, MAX_ACL_ENTRIES, lacl)) < 0 - || (lcnt = delacl (lacl, lcnt)) < 0 - || (lcnt = acl (path, SETACL, lcnt, lacl)) < 0) - { - perror (prog_name); - return 2; - } - break; - default: - if ((lcnt = acl (path, GETACL, MAX_ACL_ENTRIES, lacl)) < 0 - || (lcnt = modacl (lacl, lcnt, acls, cnt)) < 0 - || (lcnt = addmissing (lacl, lcnt)) < 0 - || (lcnt = acl (path, SETACL, lcnt, lacl)) < 0) - { - perror (prog_name); - return 2; - } - break; + } + else if ((lcnt = acl (path, GETACL, MAX_ACL_ENTRIES, lacl)) < 0 + || (lcnt = modacl (lacl, lcnt, acls, cnt)) < 0 + || (lcnt = acl (path, SETACL, lcnt, lacl)) < 0) + { + perror (prog_name); + return 2; } return 0; } @@ -400,12 +290,11 @@ static void usage (FILE * stream) { fprintf (stream, "" - "Usage: %s [-r] {-f ACL_FILE | -s acl_entries} FILE...\n" - " %s [-r] {-b|[-d acl_entries] [-m acl_entries]} FILE...\n" + "Usage: %s [-r] (-f ACL_FILE | -s acl_entries) FILE...\n" + " %s [-r] ([-d acl_entries] [-m acl_entries]) FILE...\n" "\n" "Modify file and directory access control lists (ACLs)\n" "\n" - " -b, --remove-all remove all extended ACL entries\n" " -d, --delete delete one or more specified ACL entries\n" " -f, --file set ACL entries for FILE to ACL entries read\n" " from a ACL_FILE\n" @@ -417,7 +306,7 @@ usage (FILE * stream) " -h, --help output usage information and exit\n" " -V, --version output version information and exit\n" "\n" - "At least one of (-b, -d, -f, -m, -s) must be specified\n" + "At least one of (-d, -f, -m, -s) must be specified\n" "\n", prog_name, prog_name); if (stream == stdout) { @@ -451,21 +340,17 @@ usage (FILE * stream) "\n" "The following options are supported:\n" "\n" - "-b Remove all extended ACL entries. The base ACL entries of the\n" - " owner, group and others are retained.\n" - "\n" "-d Delete one or more specified entries from the file's ACL.\n" " The owner, group and others entries must not be deleted.\n" " Acl_entries to be deleted should be specified without\n" " permissions, as in the following list:\n" "\n" - " u[ser]:uid[:]\n" - " g[roup]:gid[:]\n" - " m[ask][:]\n" - " d[efault]:u[ser][:uid]\n" - " d[efault]:g[roup][:gid]\n" - " d[efault]:m[ask][:]\n" - " d[efault]:o[ther][:]\n" + " u[ser]:uid\n" + " g[roup]:gid\n" + " d[efault]:u[ser]:uid\n" + " d[efault]:g[roup]:gid\n" + " d[efault]:m[ask]:\n" + " d[efault]:o[ther]:\n" "\n" "-f Take the Acl_entries from ACL_FILE one per line. Whitespace\n" " characters are ignored, and the character \"#\" may be used\n" @@ -502,14 +387,14 @@ usage (FILE * stream) "in a directory that contains default ACL entries will have\n" "permissions according to the combination of the current umask,\n" "the explicit permissions requested and the default ACL entries\n" - "\n", prog_name); + "Note: Under Cygwin, the default ACL entries are not taken into\n" + "account currently.\n\n", prog_name); } else fprintf(stream, "Try '%s --help' for more information.\n", prog_name); } struct option longopts[] = { - {"remove-all", no_argument, NULL, 'b'}, {"delete", required_argument, NULL, 'd'}, {"file", required_argument, NULL, 'f'}, {"modify", required_argument, NULL, 'm'}, @@ -519,7 +404,7 @@ struct option longopts[] = { {"version", no_argument, NULL, 'V'}, {0, no_argument, NULL, 0} }; -const char *opts = "bd:f:hm:rs:V"; +const char *opts = "d:f:hm:rs:V"; static void print_version () @@ -551,15 +436,6 @@ main (int argc, char **argv) while ((c = getopt_long (argc, argv, opts, longopts, NULL)) != EOF) switch (c) { - case 'b': - if (action == NoAction) - action = DeleteAll; - else - { - usage (stderr); - return 1; - } - break; case 'd': if (action == NoAction) action = Delete; diff --git a/winsup/utils/utils.xml b/winsup/utils/utils.xml new file mode 100644 index 000000000..b7e8ff81d --- /dev/null +++ b/winsup/utils/utils.xml @@ -0,0 +1,2127 @@ +<?xml version="1.0" encoding='UTF-8'?> +<!DOCTYPE sect1 PUBLIC "-//OASIS//DTD DocBook V4.5//EN" + "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"> + +<sect1 id="using-utils"> + <title>Cygwin Utilities</title> + + <para>Cygwin comes with a number of command-line utilities that are used to + manage the UNIX emulation portion of the Cygwin environment. While many of + these reflect their UNIX counterparts, each was written specifically for + Cygwin. You may use the long or short option names interchangeably; for + example, <literal>--help</literal> and <literal>-h</literal> function + identically. All of the Cygwin command-line utilities support the + <literal>--help</literal> and <literal>--version</literal> options. </para> + + <sect2 id="cygcheck"> + <title>cygcheck</title> + + <screen> +Usage: cygcheck [-v] [-h] PROGRAM + cygcheck -c [-d] [PACKAGE] + cygcheck -s [-r] [-v] [-h] + cygcheck -k + cygcheck -f FILE [FILE]... + cygcheck -l [PACKAGE]... + cygcheck -p REGEXP + cygcheck --delete-orphaned-installation-keys + cygcheck --enable-unique-object-names Cygwin-DLL + cygcheck --disable-unique-object-names Cygwin-DLL + cygcheck --show-unique-object-names Cygwin-DLL + cygcheck -h + +List system information, check installed packages, or query package database. + +At least one command option or a PROGRAM is required, as shown above. + + PROGRAM list library (DLL) dependencies of PROGRAM + -c, --check-setup show installed version of PACKAGE and verify integrity + (or for all installed packages if none specified) + -d, --dump-only just list packages, do not verify (with -c) + -s, --sysinfo produce diagnostic system information (implies -c -d) + -r, --registry also scan registry for Cygwin settings (with -s) + -k, --keycheck perform a keyboard check session (must be run from a + plain console only, not from a pty/rxvt/xterm) + -f, --find-package find the package to which FILE belongs + -l, --list-package list contents of PACKAGE (or all packages if none given) + -p, --package-query search for REGEXP in the entire cygwin.com package + repository (requires internet connectivity) + --delete-orphaned-installation-keys + Delete installation keys of old, now unused + installations from the registry. Requires the right + to change the registry. + --enable-unique-object-names Cygwin-DLL + --disable-unique-object-names Cygwin-DLL + --show-unique-object-names Cygwin-DLL + Enable, disable, or show the setting of the + \"unique object names\" setting in the Cygwin DLL + given as argument to this option. The DLL path must + be given as valid Windows(!) path. + See the users guide for more information. + If you don't know what this means, don't change it. + -v, --verbose produce more verbose output + -h, --help annotate output with explanatory comments when given + with another command, otherwise print this help + -V, --version print the version of cygcheck and exit + +Note: -c, -f, and -l only report on packages that are currently installed. To + search all official Cygwin packages use -p instead. The -p REGEXP matches + package names, descriptions, and names of files/paths within all packages. +</screen> + + <para> The <command>cygcheck</command> program is a diagnostic utility for + dealing with Cygwin programs. If you are familiar with + <command>dpkg</command> or <command>rpm</command>, + <command>cygcheck</command> is similar in many ways. (The major + difference is that <command>setup.exe</command> handles installing and + uninstalling packages; see <xref linkend="internet-setup"/> for more + information.) </para> + <para> The <literal>-c</literal> option checks the version and status of + installed Cygwin packages. If you specify one or more package names, + <command>cygcheck</command> will limit its output to those packages, or + with no arguments it lists all packages. A package will be marked + <literal>Incomplete</literal> if files originally installed are no longer + present. The best thing to do in that situation is reinstall the package + with <command>setup.exe</command>. To see which files are missing, use + the <literal>-v</literal> option. If you do not need to know the status + of each package and want <command>cygcheck</command> to run faster, add + the <literal>-d</literal> option and <command>cygcheck</command> will + only output the name and version for each package. </para> + <para> If you list one or more programs on the command line, + <command>cygcheck</command> will diagnose the runtime environment of that + program or programs, providing the names of DLL files on which the + program depends. If you specify the <literal>-s</literal> option, + <command>cygcheck</command> will give general system information. If you + list one or more programs on the command line and specify + <literal>-s</literal>, <command>cygcheck</command> will report on + both.</para> + <para> The <literal>-f</literal> option helps you to track down which + package a file came from, and <literal>-l</literal> lists all files in a + package. For example, to find out about + <filename>/usr/bin/less</filename> and its package: <example + id="utils-cygcheck-ex"><title>Example <command>cygcheck</command> + usage</title> + <screen> +$ cygcheck -f /usr/bin/less +less-381-1 + +$ cygcheck -l less +/usr/bin/less.exe +/usr/bin/lessecho.exe +/usr/bin/lesskey.exe +/usr/man/man1/less.1 +/usr/man/man1/lesskey.1 +</screen> + </example> </para> + + <para>The <literal>-h</literal> option prints additional helpful messages + in the report, at the beginning of each section. It also adds table + column headings. While this is useful information, it also adds some to + the size of the report, so if you want a compact report or if you know + what everything is already, just leave this out.</para> + + <para>The <literal>-v</literal> option causes the output to be more + verbose. What this means is that additional information will be reported + which is usually not interesting, such as the internal version numbers of + DLLs, additional information about recursive DLL usage, and if a file in + one directory in the PATH also occurs in other directories on the PATH. </para> + + <para>The <literal>-r</literal> option causes <command>cygcheck</command> + to search your registry for information that is relevant to Cygwin + programs. These registry entries are the ones that have "Cygwin" in the + name. If you are paranoid about privacy, you may remove information from + this report, but please keep in mind that doing so makes it harder to + diagnose your problems.</para> + + <para>In contrast to the other options that search the packages that are + installed on your local system, the <literal>-p</literal> option can be + used to search the entire official Cygwin package repository. It takes as + argument a Perl-compatible regular expression which is used to match + package names, package descriptions, and path/filenames of the contents + of packages. This feature requires an active internet connection, since + it must query the <literal>cygwin.com</literal> web site. In fact, it is + equivalent to the search that is available on the <ulink + url="http://cygwin.com/packages/">Cygwin package listing</ulink> + page.</para> + + <para>For example, perhaps you are getting an error because you are missing + a certain DLL and you want to know which package includes that file: + <example id="utils-search-ex"><title>Searching all packages for a + file</title> + <screen> +$ cygcheck -p 'cygintl-2\.dll' +Found 1 matches for 'cygintl-2\.dll'. + +libintl2-0.12.1-3 GNU Internationalization runtime library + +$ cygcheck -p 'libexpat.*\.a' +Found 2 matches for 'libexpat.*\.a'. + +expat-1.95.7-1 XML parser library written in C +expat-1.95.8-1 XML parser library written in C + +$ cygcheck -p '/ls\.exe' +Found 2 matches for '/ls\.exe'. + +coreutils-5.2.1-5 GNU core utilities (includes fileutils, sh-utils and textutils) +coreutils-5.3.0-6 GNU core utilities (includes fileutils, sh-utils and textutils) +</screen> + </example> </para> + + <para>Note that this option takes a regular expression, not a glob or + wildcard. This means that you need to use <literal>.*</literal> if you + want something similar to the wildcard <literal>*</literal> commonly used + in filename globbing. Similarly, to match the period character you should + use <literal>\.</literal> since the <literal>.</literal> character in a + regexp is a metacharacter that will match any character. Also be aware + that the characters such as <literal>\</literal> and <literal>*</literal> + are shell metacharacters, so they must be either escaped or quoted, as in + the example above.</para> + + <para>The third example above illustrates that if you want to match a whole + filename, you should include the <literal>/</literal> path seperator. In + the given example this ensures that filenames that happen to end in + <literal>ls.exe</literal> such as <literal>ncftpls.exe</literal> are not + shown. Note that this use does not mean "look for packages with + <literal>ls</literal> in the root directory," since the + <literal>/</literal> can match anywhere in the path. It's just there to + anchor the match so that it matches a full filename.</para> + + <para>By default the matching is case-sensitive. To get a case insensitive + match, begin your regexp with <literal>(?i)</literal> which is a + PCRE-specific feature. For complete documentation on Perl-compatible + regular expression syntax and options, read the <command>perlre</command> + manpage, or one of many websites such as <literal>perldoc.com</literal> + that document the Perl language.</para> + + <para>The <command>cygcheck</command> program should be used to send + information about your system for troubleshooting when requested. When + asked to run this command save the output so that you can email it, for + example:</para> + + <screen> +<prompt>$</prompt> <userinput>cygcheck -s -v -r -h > cygcheck_output.txt</userinput> +</screen> + + <para> Each Cygwin DLL stores its path and installation key in the + registry. This allows troubleshooting of problems which could be a result + of having multiple concurrent Cygwin installations. However, if you're + experimenting a lot with different Cygwin installation paths, your + registry could accumulate a lot of old Cygwin installation entries for + which the installation doesn't exist anymore. To get rid of these + orphaned registry entries, use the <command>cygcheck + --delete-orphaned-installation-keys</command> command.</para> + + <para> Each Cygwin DLL generates a key value from its installation path. + This value is not only stored in the registry, it's also used to generate + global object names used for interprocess communication. This keeps + different Cygwin installations separate. Processes running under a Cygwin + DLL installed in C:\cygwin don't see processes running under a Cygwin DLL + installed in C:\Program Files\cygwin. This allows running multiple + versions of Cygwin DLLs without these versions to interfere with each + other, or to run small third-party installations for a specific purpose + independently from a Cygwin net distribution. </para> + + <para> For debugging purposes it could be desired that the various Cygwin + DLLs use the same key, independently from their installation paths. If + the DLLs have different versions, trying to run processes under these + DLLs concurrently will result in error messages like this one:</para> + + <screen> +*** shared version mismatch detected - 0x8A88009C/0x75BE0074. +This problem is probably due to using incompatible versions of the Cygwin DLL. +Search for cygwin1.dll using the Windows Start->Find/Search facility +and delete all but the most recent version. The most recent version *should* +reside in x:\\cygwin\\bin, where 'x' is the drive on which you have +installed the cygwin distribution. Rebooting is also suggested if you +are unable to find another Cygwin DLL. +</screen> + + <para> To disable the usage of a unique key value of a certain Cygwin DLL, + use the <command>cygcheck --disable-unique-object-names + Cygwin-DLL</command> command. <literal>Cygwin-DLL</literal> is the + Windows path (*not* a Cygwin POSIX path) to the DLL for which you want to + disable this feature. Note that you have to stop all Cygwin processes + running under this DLL, before you're allowed to change this setting. For + instance, run <command>cygcheck</command> from a DOS command line for + this purpose.</para> + + <para>To re-enable the usage of a unique key, use the <command>cygcheck + --enable-unique-object-names Cygwin-DLL</command> command. This option + has the same characteristics as the + <literal>--disable-unique-object-names</literal> option</para> + + <para>Finally, you can use <command>cygcheck --show-unique-object-names + Cygwin-DLL</command> to find out if the given Cygwin DLL use unique + object names or not. In contrast to the <literal>--disable-...</literal> + and <literal>--enable-...</literal> options, the + <literal>--show-unique-object-names</literal> option also works for + Cygwin DLLs which are currently in use.</para> + + </sect2> + + <sect2 id="cygpath"> + <title>cygpath</title> + + <screen> +Usage: cygpath (-d|-m|-u|-w|-t TYPE) [-f FILE] [OPTION]... NAME... + cygpath [-c HANDLE] + cygpath [-ADHOPSW] + cygpath [-F ID] + +Convert Unix and Windows format paths, or output system path information + +Output type options: + + -d, --dos print DOS (short) form of NAMEs (C:\PROGRA~1\) + -m, --mixed like --windows, but with regular slashes (C:/WINNT) + -M, --mode report on mode of file (currently binmode or textmode) + -u, --unix (default) print Unix form of NAMEs (/cygdrive/c/winnt) + -w, --windows print Windows form of NAMEs (C:\WINNT) + -t, --type TYPE print TYPE form: 'dos', 'mixed', 'unix', or 'windows' + +Path conversion options: + + -a, --absolute output absolute path + -l, --long-name print Windows long form of NAMEs (with -w, -m only) + -p, --path NAME is a PATH list (i.e., '/bin:/usr/bin') + -s, --short-name print DOS (short) form of NAMEs (with -w, -m only) + -C, --codepage CP print DOS, Windows, or mixed pathname in Windows + codepage CP. CP can be a numeric codepage identifier, + or one of the reserved words ANSI, OEM, or UTF8. + If this option is missing, cygpath defaults to the + character set defined by the current locale. + +System information: + + -A, --allusers use `All Users' instead of current user for -D, -P + -D, --desktop output `Desktop' directory and exit + -H, --homeroot output `Profiles' directory (home root) and exit + -O, --mydocs output `My Documents' directory and exit + -P, --smprograms output Start Menu `Programs' directory and exit + -S, --sysdir output system directory and exit + -W, --windir output `Windows' directory and exit + -F, --folder ID output special folder with numeric ID and exit + +Other options: + + -f, --file FILE read FILE for input; use - to read from STDIN + -o, --option read options from FILE as well (for use with --file) + -c, --close HANDLE close HANDLE (for use in captured process) + -i, --ignore ignore missing argument + -h, --help output usage information and exit + -V, --version output version information and exit +</screen> + + <para>The <command>cygpath</command> program is a utility that converts + Windows native filenames to Cygwin POSIX-style pathnames and vice versa. + It can be used when a Cygwin program needs to pass a file name to a + native Windows program, or expects to get a file name from a native + Windows program. Alternatively, <command>cygpath</command> can output + information about the location of important system directories in either + format. </para> + + <para>The <literal>-u</literal> and <literal>-w</literal> options indicate + whether you want a conversion to UNIX (POSIX) format + (<literal>-u</literal>) or to Windows format (<literal>-w</literal>). Use + the <literal>-d</literal> to get DOS-style (8.3) file and path names. The + <literal>-m</literal> option will output Windows-style format but with + forward slashes instead of backslashes. This option is especially useful + in shell scripts, which use backslashes as an escape character.</para> + + <para> In combination with the <literal>-w</literal> option, you can use + the <literal>-l</literal> and <literal>-s</literal> options to use normal + (long) or DOS-style (short) form. The <literal>-d</literal> option is + identical to <literal>-w</literal> and <literal>-s</literal> together. </para> + + <para>The <literal>-C</literal> option allows to specify a Windows codepage + to print DOS and Windows paths created with one of the + <literal>-d</literal>, <literal>-m</literal>, or <literal>-w</literal> + options. The default is to use the character set of the current locale + defined by one of the internationalization environment variables + <envar>LC_ALL</envar>, <envar>LC_CTYPE</envar>, or <envar>LANG</envar>, + see <xref linkend="setup-locale"/>. This is sometimes not sufficient for + interaction with native Windows tools, which might expect native, + non-ASCII characters in a specific Windows codepage. Console tools, for + instance, might expect pathnames in the current OEM codepage, while + graphical tools like Windows Explorer might expect pathnames in the + current ANSI codepage.</para> + + <para>The <literal>-C</literal> option takes a single parameter:</para> + <itemizedlist spacing="compact"> + <listitem> + <para><literal>ANSI</literal>, to specify the current ANSI + codepage</para> + </listitem> + <listitem> + <para><literal>OEM</literal>, to specify the current OEM (console) + codepage</para> + </listitem> + <listitem> + <para><literal>UTF8</literal>, to specify UTF-8.</para> + </listitem> + <listitem> + <para>A numerical, decimal codepage number, for instance 936 for GBK, + 28593 for ISO-8859-3, etc. A full list of supported codepages is + listed on the Microsoft MSDN page <ulink + url="http://msdn.microsoft.com/en-us/library/dd317756(VS.85).aspx" + >Code Page Identifiers</ulink>. A codepage of 0 is the same as if the + <literal>-C</literal> hasn't been specified at all.</para> + </listitem> + </itemizedlist> + + <para>The <literal>-p</literal> option means that you want to convert a + path-style string rather than a single filename. For example, the PATH + environment variable is semicolon-delimited in Windows, but + colon-delimited in UNIX. By giving <literal>-p</literal> you are + instructing <command>cygpath</command> to convert between these + formats.</para> + + <para>The <literal>-i</literal> option supresses the print out of the usage + message if no filename argument was given. It can be used in make file + rules converting variables that may be omitted to a proper format. Note + that <command>cygpath</command> output may contain spaces (C:\Program + Files) so should be enclosed in quotes. </para> + + + <example id="utils-cygpath-ex"> + <title>Example <command>cygpath</command> usage</title> + <screen> +<![CDATA[ +#!/bin/sh +if [ "${1}" = "" ]; + then + XPATH="."; + else + XPATH="$(cygpath -C ANSI -w "${1}")"; +fi +explorer $XPATH & +]]> +</screen> + </example> + + <para>The capital options <literal>-D</literal>, <literal>-H</literal>, + <literal>-P</literal>, <literal>-S</literal>, and <literal>-W</literal> + output directories used by Windows that are not the same on all systems, + for example <literal>-S</literal> might output C:\WINNT\system32 or + C:\Windows\System32. The <literal>-H</literal> shows the Windows profiles + directory that can be used as root of home. The <literal>-A</literal> + option forces use of the "All Users" directories instead of the current + user for the <literal>-D</literal>, <literal>-O</literal> and + <literal>-P</literal> options. The <literal>-F</literal> outputs other + special folders specified by their internal numeric code (decimal or + 0x-prefixed hex). For valid codes and symbolic names, see the CSIDL_* + definitions in the include file /usr/include/w32api/shlobj.h from package + w32api. The current valid range of codes for folders is 0 (Desktop) to 59 + (CDBurn area). By default the output is in UNIX (POSIX) format; use the + <literal>-w</literal> or <literal>-d</literal> options to get other + formats.</para> + + </sect2> + + <sect2 id="dumper"> + <title>dumper</title> + + <screen> +Usage: dumper [OPTION] FILENAME WIN32PID + +Dump core from WIN32PID to FILENAME.core + +-d, --verbose be verbose while dumping +-h, --help output help information and exit +-q, --quiet be quiet while dumping (default) +-V, --version output version information and exit +</screen> + + <para>The <command>dumper</command> utility can be used to create a core + dump of running Windows process. This core dump can be later loaded to + <command>gdb</command> and analyzed. One common way to use + <command>dumper</command> is to plug it into cygwin's Just-In-Time + debugging facility by adding + <screen> +error_start=x:\path\to\dumper.exe +</screen> to the + <emphasis>CYGWIN</emphasis> environment variable. Please note that + <literal>x:\path\to\dumper.exe</literal> is Windows-style and not cygwin + path. If <literal>error_start</literal> is set this way, then dumper will + be started whenever some program encounters a fatal error. </para> + + <para> <command>dumper</command> can be also be started from the command + line to create a core dump of any running process. Unfortunately, because + of a Windows API limitation, when a core dump is created and + <command>dumper</command> exits, the target process is terminated too. </para> + + <para> To save space in the core dump, <command>dumper</command> doesn't + write those portions of target process' memory space that are loaded from + executable and dll files and are unchangeable, such as program code and + debug info. Instead, <command>dumper</command> saves paths to files which + contain that data. When a core dump is loaded into gdb, it uses these + paths to load appropriate files. That means that if you create a core + dump on one machine and try to debug it on another, you'll need to place + identical copies of the executable and dlls in the same directories as on + the machine where the core dump was created. </para> + + </sect2> + + <sect2 id="getconf"> + <title>getconf</title> + + <screen> +Usage: getconf [-v specification] variable_name [pathname] + getconf -a [pathname] + +Get configuration values + + -v specification Indicate specific version for which configuration + values shall be fetched. + -a, --all Print all known configuration values + +Other options: + + -h, --help This text + -V, --version Print program version and exit +</screen> + + <para>The <command>getconf</command> utility prints the value of the + configuration variable specified by <literal>variable_name</literal>. If + no <literal>pathname</literal> is given, <command>getconf</command> + serves as a wrapper for the <literal>confstr</literal> and + <literal>sysconf</literal> functions, supporting the symbolic constants + defined in the <literal>limits.h</literal> and + <literal>unistd.h</literal> headers, without their respective + <literal>_CS_</literal> or <literal>_SC_</literal> prefixes. </para> + + <para>If <literal>pathname</literal> is given, <command>getconf</command> + prints the value of the configuration variable for the specified + pathname. In this form, <command>getconf</command> serves as a wrapper + for the <literal>pathconf</literal> function, supporting the symbolic + constants defined in the <literal>unistd.h</literal> header, without the + <literal>_PC_</literal> prefix. </para> + + <para>If you specify the <literal>-v</literal> option, the parameter + denotes a specification for which the value of the configuration variable + should be printed. Note that the only specifications supported by Cygwin + are <literal>POSIX_V7_ILP32_OFFBIG</literal> and the legacy + <literal>POSIX_V6_ILP32_OFFBIG</literal> and + <literal>XBS5_ILP32_OFFBIG</literal> equivalents.</para> + + <para>Use the <literal>-a</literal> option to print a list of all available + configuration variables for the system, or given + <literal>pathname</literal>, and their values.</para> + + </sect2> + + <sect2 id="getfacl"> + <title>getfacl</title> + + <screen> +Usage: getfacl [-adn] FILE [FILE2...] + +Display file and directory access control lists (ACLs). + + -a, --all display the filename, the owner, the group, and + the ACL of the file + -d, --dir display the filename, the owner, the group, and + the default ACL of the directory, if it exists + -h, --help output usage information and exit + -n, --noname display user and group IDs instead of names + -V, --version output version information and exit + +When multiple files are specified on the command line, a blank +line separates the ACLs for each file. +</screen> + + <para> For each argument that is a regular file, special file or directory, + <command>getfacl</command> displays the owner, the group, and the ACL. + For directories <command>getfacl</command> displays additionally the + default ACL. With no options specified, <command>getfacl</command> + displays the filename, the owner, the group, and both the ACL and the + default ACL, if it exists. For more information on Cygwin and Windows + ACLs, see <xref linkend="ntsec"/> in the Cygwin User's Guide. The format + for ACL output is as follows: + <screen> + # file: filename + # owner: name or uid + # group: name or uid + user::perm + user:name or uid:perm + group::perm + group:name or gid:perm + mask:perm + other:perm + default:user::perm + default:user:name or uid:perm + default:group::perm + default:group:name or gid:perm + default:mask:perm + default:other:perm +</screen> + </para> + </sect2> + + <sect2 id="kill"> + <title>kill</title> + + <screen> +Usage: kill [-f] [-signal] [-s signal] pid1 [pid2 ...] + kill -l [signal] + +Send signals to processes + + -f, --force force, using win32 interface if necessary + -l, --list print a list of signal names + -s, --signal send signal (use kill --list for a list) + -h, --help output usage information and exit + -V, --version output version information and exit +</screen> + + <para>The <command>kill</command> program allows you to send arbitrary + signals to other Cygwin programs. The usual purpose is to end a running + program from some other window when ^C won't work, but you can also send + program-specified signals such as SIGUSR1 to trigger actions within the + program, like enabling debugging or re-opening log files. Each program + defines the signals they understand.</para> + + <para>You may need to specify the full path to use <command>kill</command> + from within some shells, including <command>bash</command>, the default + Cygwin shell. This is because <command>bash</command> defines a + <command>kill</command> builtin function; see the <command>bash</command> + man page under <emphasis>BUILTIN COMMANDS</emphasis> for more + information. To make sure you are using the Cygwin version, try + <screen> +$ /bin/kill --version +</screen> which should give the Cygwin + <command>kill</command> version number and copyright information. </para> + + <para>Unless you specific the <literal>-f</literal> option, the "pid" + values used by <command>kill</command> are the Cygwin pids, not the + Windows pids. To get a list of running programs and their Cygwin pids, + use the Cygwin <command>ps</command> program. <command>ps -W</command> + will display <emphasis>all</emphasis> windows pids.</para> + + <para>The <command>kill -l</command> option prints the name of the given + signal, or a list of all signal names if no signal is given.</para> + + <para>To send a specific signal, use the <literal>-signN</literal> option, + either with a signal number or a signal name (minus the "SIG" part), as + shown in these examples:</para> + + <example id="utils-kill-ex"> + <title>Using the kill command</title> + <screen> +<prompt>$</prompt> <userinput>kill 123</userinput> +<prompt>$</prompt> <userinput>kill -1 123</userinput> +<prompt>$</prompt> <userinput>kill -HUP 123</userinput> +<prompt>$</prompt> <userinput>kill -f 123</userinput> +</screen> + </example> + + <para>Here is a list of available signals, their numbers, and some + commentary on them, from the file + <literal><sys/signal.h></literal>, which should be considered the + official source of this information.</para> + + <screen> +SIGHUP 1 hangup +SIGINT 2 interrupt +SIGQUIT 3 quit +SIGILL 4 illegal instruction (not reset when caught) +SIGTRAP 5 trace trap (not reset when caught) +SIGABRT 6 used by abort +SIGEMT 7 EMT instruction +SIGFPE 8 floating point exception +SIGKILL 9 kill (cannot be caught or ignored) +SIGBUS 10 bus error +SIGSEGV 11 segmentation violation +SIGSYS 12 bad argument to system call +SIGPIPE 13 write on a pipe with no one to read it +SIGALRM 14 alarm clock +SIGTERM 15 software termination signal from kill +SIGURG 16 urgent condition on IO channel +SIGSTOP 17 sendable stop signal not from tty +SIGTSTP 18 stop signal from tty +SIGCONT 19 continue a stopped process +SIGCHLD 20 to parent on child stop or exit +SIGCLD 20 System V name for SIGCHLD +SIGTTIN 21 to readers pgrp upon background tty read +SIGTTOU 22 like TTIN for output if (tp->t_local&LTOSTOP) +SIGIO 23 input/output possible +SIGPOLL 23 System V name for SIGIO +SIGXCPU 24 exceeded CPU time limit +SIGXFSZ 25 exceeded file size limit +SIGVTALRM 26 virtual time alarm +SIGPROF 27 profiling time alarm +SIGWINCH 28 window changed +SIGLOST 29 resource lost (eg, record-lock lost) +SIGPWR 29 power failure +SIGUSR1 30 user defined signal 1 +SIGUSR2 31 user defined signal 2 +</screen> + + </sect2> + + <sect2 id="ldd"> + <title>ldd</title> + + <screen> +Usage: ldd [OPTION]... FILE... + +Print shared library dependencies + + -h, --help print this help and exit + -V, --version print version information and exit + -r, --function-relocs process data and function relocations + (currently unimplemented) + -u, --unused print unused direct dependencies + (currently unimplemented) + -v, --verbose print all information + (currently unimplemented) +</screen> + + <para><command>ldd</command> prints the shared libraries (DLLs) an + executable or DLL is linked against. No modifying option is implemented + yet.</para> + + </sect2> + + <sect2 id="locale"> + <title>locale</title> + + <screen> +Usage: locale [-amvhV] + or: locale [-ck] NAME + or: locale [-usfnU] + +Get locale-specific information. + +System information: + + -a, --all-locales List all available supported locales + -m, --charmaps List all available character maps + -v, --verbose More verbose output + +Modify output format: + + -c, --category-name List information about given category NAME + -k, --keyword-name Print information about given keyword NAME + +Default locale information: + + -u, --user Print locale of user's default UI language + -s, --system Print locale of system default UI language + -f, --format Print locale of user's regional format settings + (time, numeric & monetary) + -n, --no-unicode Print system default locale for non-Unicode programs + -U, --utf Attach \".UTF-8\" to the result + +Other options: + + -h, --help This text + -V, --version Print program version and exit +</screen> + + <para><command>locale</command> without parameters prints information about + the current locale environment settings.</para> + + <para>The <literal>-u</literal>, <literal>-s</literal>, + <literal>-f</literal>, and <literal>-n</literal> options can be used to + request the various Windows locale settings. The purpose is to use this + command in scripts to set the POSIX locale variables.</para> + + <para>The <literal>-u</literal> option prints the current user's Windows UI + locale to stdout. In Windows Vista and Windows 7 this setting is called + the "Display Language"; there was no corresponding user setting in + Windows XP. The <literal>-s</literal> option prints the systems default + instead. The <literal>-f</literal> option prints the user's setting for + time, date, number and currency. That's equivalent to the setting in the + "Formats" or "Regional Options" tab in the "Region and Language" or + "Regional and Language Options" dialog. With the <literal>-U</literal> + option <command>locale</command> appends a ".UTF-8".</para> + + <para>Usage example:</para> + + <screen> +bash$ export LANG=$(locale -uU) +bash$ echo $LANG +en_US.UTF-8 +bash$ export LC_TIME=$(locale -fU) +bash$ echo $LC_TIME +de_DE.UTF-8 +</screen> + + <para>The <literal>-a</literal> option is helpful to learn which locales + are supported by your Windows machine. It prints all available locales + and the allowed modifiers. Example:</para> + + <screen> +bash$ locale -a +C +C.utf8 +POSIX +af_ZA +af_ZA.utf8 +am_ET +am_ET.utf8 +... +be_BY +be_BY.utf8 +be_BY@latin +... +ca_ES +ca_ES.utf8 +ca_ES@euro +catalan +... +</screen> + + <para>The <literal>-v</literal> option prints more detailed information + about each available locale. Example:</para> + + <screen> +bash$ locale -av +locale: af_ZA archive: /cygdrive/c/Windows/system32/kernel32.dll +------------------------------------------------------------------------------- + language | Afrikaans +territory | South Africa + codeset | ISO-8859-1 + +locale: af_ZA.utf8 archive: /cygdrive/c/Windows/system32/kernel32.dll +------------------------------------------------------------------------------- + language | Afrikaans +territory | South Africa + codeset | UTF-8 + +... + +locale: ca_ES@euro archive: /cygdrive/c/Windows/system32/kernel32.dll +------------------------------------------------------------------------------- + language | Catalan +territory | Spain + codeset | ISO-8859-15 + +locale: catalan archive: /usr/share/locale/locale.alias +------------------------------------------------------------------------------- + language | Catalan +territory | Spain + codeset | ISO-8859-1 + +... +</screen> + + <para>The <literal>-m</literal> option prints the names of the available + charmaps supported by Cygwin to stdout.</para> + + <para>Otherwise, if arguments are given, <command>locale</command> prints + the values assigned to these arguments. Arguments can be names of locale + categories (for instance: LC_CTYPE, LC_MONETARY), or names of keywords + supported in the locale categories (for instance: thousands_sep, + charmap). The <literal>-c</literal> option prints additionally the name + of the category. The <literal>-k</literal> option prints additionally the + name of the keyword. Example:</para> + + <screen> +bash$ locale -ck LC_MESSAGES +LC_MESSAGES +yesexpr="^[yY]" +noexpr="^[nN]" +yesstr="yes" +nostr="no" +messages-codeset="UTF-8" +bash$ locale noexpr +^[nN] +</screen> + + </sect2> + + <sect2 id="minidumper"><title>minidumper</title> + + <screen> +Usage: minidumper [OPTION] FILENAME WIN32PID + +Write minidump from WIN32PID to FILENAME.dmp + +-t, --type minidump type flags +-n, --nokill don't terminate the dumped process +-d, --verbose be verbose while dumping +-h, --help output help information and exit +-q, --quiet be quiet while dumping (default) +-V, --version output version information and exit + </screen> + + <para> + The <command>minidumper</command> utility can be used to create a + minidump of a running Windows process. This minidump can be later + analysed using breakpad or Windows debugging tools. + </para> + + <para> + <command>minidumper</command> can be used with cygwin's Just-In-Time + debugging facility in exactly the same way as <command>dumper</command> + (See <xref linkend="dumper"></xref>). + </para> + + <para> + <command>minidumper</command> can also be started from the command line to + create a minidump of any running process. For compatibility with + <command>dumper</command> the target process is terminated after dumping + unless the <literal>-n</literal> option is given. + </para> + + </sect2> + + <sect2 id="mkgroup"> + <title>mkgroup</title> + + <screen> +Usage: mkgroup [OPTION]... + +Print /etc/group file to stdout + +Options: + + -l,--local [machine[,offset]] + print local groups with gid offset offset + (from local machine if no machine specified) + -L,--Local [machine[,offset]] + ditto, but generate groupname with machine prefix + -d,--domain [domain[,offset]] + print domain groups with gid offset offset + (from current domain if no domain specified) + -D,--Domain [domain[,offset]] + 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 + -b,--no-builtin don't print BUILTIN groups + -U,--unix grouplist additionally print UNIX groups when using -l or -L + on a UNIX Samba server + grouplist is a comma-separated list of groupnames + or gid ranges (root,-25,50-100). + (enumerating large ranges can take a long time!) + -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. +</screen> + + <para>The <command>mkgroup</command> program can be used to help 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/-D</literal> and <literal>-l/-L</literal> options + allow you to specify where the information comes from, the 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. Comma-separated from the machine or domain, + you can specify an offset which is used as base added to the group's RID + to compute the gid (offset + RID = gid). This allows you to create the + same gids every time you re-run <command>mkgroup</command>. 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+ > /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>-g</literal> option only prints the information for one group. + The <literal>-U</literal> option allows you to enumerate the standard + UNIX groups on a Samba machine. It's used together with <literal>-l + samba-server</literal> or <literal>-L samba-server</literal>. The normal + UNIX groups are usually not enumerated, but they can show up as a group + in <command>ls -l</command> output. </para> + + </sect2> + + <sect2 id="mkpasswd"> + <title>mkpasswd</title> + + <screen> +Usage: mkpasswd [OPTIONS]... + +Print /etc/passwd file to stdout + +Options: + + -l,--local [machine[,offset]] + print local user accounts with uid offset offset + (from local machine if no machine specified) + -L,--Local [machine[,offset]] + ditto, but generate username with machine prefix + -d,--domain [domain[,offset]] + print domain accounts with uid offset offset + (from current domain if no domain specified) + -D,--Domain [domain[,offset]] + 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 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 + -U,--unix userlist additionally print UNIX users when using -l or -L\ + on a UNIX Samba server + userlist is a comma-separated list of usernames + or uid ranges (root,-25,50-100). + (enumerating large ranges can take a long time!) + -s,--no-sids (ignored) + -m,--no-mount (ignored) + -g,--local-groups (ignored) + -h,--help displays this message + -V,--version version information and exit + +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 + 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/-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/-D</literal> options the program contacts the Domain + Controller, which may be unreachable or have restricted access. + Comma-separated from the machine or domain, you can specify an offset + which is used as base added to the user's RID to compute the uid (offset + + RID = uid). This allows to create the same uids every time you re-run + <command>mkpasswd</command>. 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, similar 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>-p</literal> option causes <command>mkpasswd</command> to use + the specified prefix instead of the account home dir or <literal>/home/ + </literal>. For example, this command: <example id="utils-althome-ex" + ><title>Using an alternate home root</title> + <screen> +<prompt>$</prompt> <userinput>mkpasswd -l -p "$(cygpath -H)" > /etc/passwd</userinput> +</screen> + </example> would put local users' home directories in the Windows + 'Profiles' directory. The <literal>-u</literal> option creates just an + entry for the specified user. The <literal>-U</literal> option allows you + to enumerate the standard UNIX users on a Samba machine. It's used + together with <literal>-l samba-server</literal> or <literal>-L + samba-server</literal>. The normal UNIX users are usually not enumerated, + but they can show up as file owners in <command>ls -l</command> output. </para> + + </sect2> + + <sect2 id="mount"> + <title>mount</title> + + <screen> +Usage: mount [OPTION] [<win32path> <posixpath>] + mount -a + mount <posixpath> + +Display information about mounted filesystems, or mount a filesystem + + -a, --all mount all filesystems mentioned in fstab + -c, --change-cygdrive-prefix change the cygdrive path prefix to <posixpath> + -f, --force force mount, don't warn about missing mount + point directories + -h, --help output usage information and exit + -m, --mount-entries write fstab entries to replicate mount points + and cygdrive prefixes + -o, --options X[,X...] specify mount options + -p, --show-cygdrive-prefix show user and/or system cygdrive path prefix + -V, --version output version information and exit +</screen> + + <para>The <command>mount</command> program is used to map your drives and + shares onto Cygwin's simulated POSIX directory tree, much like as is done + by mount commands on typical UNIX systems. However, in contrast to mount + points given in <filename>/etc/fstab</filename>, mount points created or + changed with <command>mount</command> are not persistent. They disappear + immediately after the last process of the current user exited. Please see + <xref linkend="mount-table"/> for more information on the concepts behind + the Cygwin POSIX file system and strategies for using mounts. To remove + mounts temporarily, use <command>umount</command></para> + + <sect3 id="utils-mount"> + <title>Using mount</title> + + <para>If you just type <command>mount</command> with no parameters, it + will display the current mount table for you.</para> + + <example id="utils-mount-ex"> + <title>Displaying the current set of mount points</title> + <screen> +<prompt>$</prompt> <userinput>mount</userinput> +C:/cygwin/bin on /usr/bin type ntfs (binary) +C:/cygwin/lib on /usr/lib type ntfs (binary) +C:/cygwin on / type ntfs (binary) +C: on /mnt/c type ntfs (binary,user,noumount) +D: on /mnt/d type fat (binary,user,noumount) +</screen> + </example> + + <para>In this example, c:/cygwin is the POSIX root and the D drive is + mapped to <filename>/mnt/d</filename>. Note that in this case, the root + mount is a system-wide mount point that is visible to all users running + Cygwin programs, whereas the <filename>/mnt/d</filename> mount is only + visible to the current user.</para> + + <para>The <command>mount</command> utility is also the mechanism for + adding new mounts to the mount table in memory. The following example + demonstrates how to mount the directory + <filename>//pollux/home/joe/data</filename> to + <filename>/data</filename> for the duration of the current session. </para> + + <example id="utils-mount-add-ex"> + <title>Adding mount points</title> + <screen> +<prompt>$</prompt> <userinput>ls /data</userinput> +ls: /data: No such file or directory +<prompt>$</prompt> <userinput>mount //pollux/home/joe/data /data</userinput> +mount: warning - /data does not exist! +<prompt>$</prompt> <userinput>mount</userinput> +//pollux/home/joe/data on /data type smbfs (binary) +C:/cygwin/bin on /usr/bin type ntfs (binary) +C:/cygwin/lib on /usr/lib type ntfs (binary) +C:/cygwin on / type ntfs (binary) +C: on /c type ntfs (binary,user,noumount) +D: on /d type fat (binary,user,noumount) +</screen> + </example> + + <para>A given POSIX path may only exist once in the mount table. Attempts + to replace the mount will fail with a busy error. The + <literal>-f</literal> (force) option causes the old mount to be + silently replaced with the new one, provided the old mount point was a + user mount point. It's not valid to replace system-wide mount points. + Additionally, the <literal>-f</literal> option will silence warnings + about the non-existence of directories at the Win32 path + location.</para> + + <para> The <literal>-o</literal> option is the method via which various + options about the mount point may be recorded. The following options + are available (note that most of the options are duplicates of other + mount flags):</para> + + <screen> + acl - Use the filesystem's access control lists (ACLs) to + implement real POSIX permissions (default). + binary - Files default to binary mode (default). + bind - Allows to remount part of the file hierarchy somewhere else. + Different from other mount calls, the first argument + specifies an absolute POSIX path, rather than a Win32 path. + This POSIX path is remounted to the POSIX path specified as + the second parameter. The conversion to a Win32 path is done + within Cygwin immediately at the time of the call. Note that + symlinks are ignored while performing this path conversion. + cygexec - Treat all files below mount point as cygwin executables. + dos - Always convert leading spaces and trailing dots and spaces to + characters in the UNICODE private use area. This allows to use + broken filesystems which only allow DOS filenames, even if they + are not recognized as such by Cygwin. + exec - Treat all files below mount point as executable. + ihash - Always fake inode numbers rather than using the ones returned + by the filesystem. This allows to use broken filesystems which + don't return unambiguous inode numbers, even if they are not + recognized as such by Cygwin. + noacl - Ignore ACLs and fake POSIX permissions. + nosuid - No suid files are allowed (currently unimplemented) + notexec - Treat all files below mount point as not executable. + override - Override immutable mount points. + posix=0 - Switch off case sensitivity for paths under this mount point. + posix=1 - Switch on case sensitivity for paths under this mount point + (default). + sparse - Switch on support for sparse files. This option only makes + sense on NTFS and then only if you really need sparse files. + text - Files default to CRLF text mode line endings. +</screen> + + <para>For a more complete description of the mount options and the + <filename>/etc/fstab</filename> file, see <xref linkend="mount-table" + />.</para> + + <para>Note that all mount points added with <command>mount</command> are + user mount points. System mount points can only be specified in the + <filename>/etc/fstab</filename> file.</para> + + <para>If you added mount points to <filename>/etc/fstab</filename> or + your <filename>/etc/fstab.d/<username></filename> file, you can + add these mount points to your current user session using the + <literal>-a/--all</literal> option, or by specifing the posix path + alone on the command line. As an example, consider you added a mount + point with the POSIX path <filename>/my/mount</filename>. You can add + this mount point with either one of the following two commands to your + current user session.</para> + + <screen> +<prompt>$</prompt> <userinput>mount /my/mount</userinput> +<prompt>$</prompt> <userinput>mount -a</userinput> +</screen> + + <para>The first command just adds the <filename>/my/mount</filename> + mount point to your current session, the <command>mount -a</command> + adds all new mount points to your user session.</para> + + <para>If you change a mount point to point to another native path, or if + you changed the flags of a mount point, you have to + <command>umount</command> the mount point first, before you can add it + again. Please note that all such added mount points are added as user + mount points, and that the rule that system mount points can't be + removed or replaced in a running session still applies.</para> + + <para>To bind a POSIX path to another POSIX path, use the + <literal>bind</literal> mount flag.</para> + + <screen> +<prompt>$</prompt> <userinput>mount -o bind /var /usr/var</userinput> +</screen> + + <para>This command makes the file hirarchy under + <filename>/var</filename> additionally available under + <filename>/usr/var</filename>.</para> + + <para> The <literal>-m</literal> option causes the + <command>mount</command> utility to output the current mount table in a + series of fstab entries. You can save this output as a backup when + experimenting with the mount table. Copy the output to + <filename>/etc/fstab</filename> to restore the old state. It also makes + moving your settings to a different machine much easier.</para> + + </sect3> + + <sect3 id="utils-cygdrive"> + <title>Cygdrive mount points</title> + + <para>Whenever Cygwin cannot use any of the existing mounts to convert + from a particular Win32 path to a POSIX one, Cygwin will, instead, + convert to a POSIX path using a default mount point: + <filename>/cygdrive</filename>. For example, if Cygwin accesses + <filename>z:\foo</filename> and the z drive is not currently in the + mount table, then <filename>z:\</filename> will be accessible as + <filename>/cygdrive/z</filename>. The <command>mount</command> utility + can be used to change this default automount prefix through the use of + the "--change-cygdrive-prefix" option. In the following example, we + will set the automount prefix to <filename>/mnt</filename>:</para> + + <example id="utils-cygdrive-ex"> + <title>Changing the default prefix</title> + <screen> +<prompt>$</prompt> <userinput>mount --change-cygdrive-prefix /mnt</userinput> +</screen> + </example> + + <para>Note that the cygdrive prefix can be set both per-user and + system-wide, and that as with all mounts, a user-specific mount takes + precedence over the system-wide setting. The <command>mount</command> + utility creates system-wide mounts by default if you do not specify a + type. You can always see the user and system cygdrive prefixes with the + <literal>-p</literal> option. Using the <literal>--options</literal> + flag with <literal>--change-cygdrive-prefix</literal> makes all new + automounted filesystems default to this set of options. For instance + (using the short form of the command line flags)</para> + + <example id="utils-cygdrive-ex2"> + <title>Changing the default prefix with specific mount options</title> + <screen> +<prompt>$</prompt> <userinput>mount -c /mnt -o binary,noacl</userinput> +</screen> + </example> + + + </sect3> + + <sect3 id="utils-limitations"> + <title>Limitations</title> + + <para>Limitations: there is a hard-coded limit of 64 mount points (up to + Cygwin 1.7.9: 30 mount points). Also, although you can mount to + pathnames that do not start with "/", there is no way to make use of + such mount points.</para> + + <para>Normally the POSIX mount point in Cygwin is an existing empty + directory, as in standard UNIX. If this is the case, or if there is a + place-holder for the mount point (such as a file, a symbolic link + pointing anywhere, or a non-empty directory), you will get the expected + behavior. Files present in a mount point directory before the mount + become invisible to Cygwin programs. </para> + + <para>It is sometimes desirable to mount to a non-existent directory, for + example to avoid cluttering the root directory with names such as + <filename>a</filename>, <filename>b</filename>, <filename>c</filename> + pointing to disks. Although <command>mount</command> will give you a + warning, most everything will work properly when you refer to the mount + point explicitly. Some strange effects can occur however. For example + if your current working directory is <filename>/dir</filename>, say, + and <filename>/dir/mtpt</filename> is a mount point, then + <filename>mtpt</filename> will not show up in an <command>ls</command> + or <command>echo *</command> command and <command>find .</command> will + not find <filename>mtpt</filename>. </para> + + </sect3> + + </sect2> + + <sect2 id="passwd"> + <title>passwd</title> + + <screen> +Usage: passwd [OPTION] [USER] + +Change USER's password or password attributes. + +User operations: + -l, --lock lock USER's account. + -u, --unlock unlock USER's account. + -c, --cannot-change USER can't change password. + -C, --can-change USER can change password. + -e, --never-expires USER's password never expires. + -E, --expires USER's password expires according to system's + password aging rule. + -p, --pwd-not-required no password required for USER. + -P, --pwd-required password is required for USER. + -R, --reg-store-pwd enter password to store it in the registry for + later usage by services to be able to switch + to this user context with network credentials. + +System operations: + -i, --inactive NUM set NUM of days before inactive accounts are disabled + (inactive accounts are those with expired passwords). + -n, --minage DAYS set system minimum password age to DAYS days. + -x, --maxage DAYS set system maximum password age to DAYS days. + -L, --length LEN set system minimum password length to LEN. + +Other options: + -d, --logonserver SERVER connect to SERVER (e.g. domain controller). + Default server is the local system, unless + changing the current user, in which case the + default is the content of $LOGONSERVER. + -S, --status display password status for USER (locked, expired, + etc.) plus global system password settings. + -h, --help output usage information and exit. + -V, --version output version information and exit. + +If no option is given, change USER's password. If no user name is given, +operate on current user. System operations must not be mixed with user +operations. Don't specify a USER when triggering a system operation. + +Don't specify a user or any other option together with the -R option. +Non-Admin users can only store their password if cygserver is running. +Note that storing even obfuscated passwords in the registry is not overly +secure. Use this feature only if the machine is adequately locked down. +Don't use this feature if you don't need network access within a remote +session. You can delete your stored password by using `passwd -R' and +specifying an empty password. +</screen> + + <para> <command>passwd</command> changes passwords for user accounts. A + normal user may only change the password for their own account, but + administrators may change passwords on any account. + <command>passwd</command> also changes account information, such as + password expiry dates and intervals.</para> + + <para>For password changes, the user is first prompted for their old + password, if one is present. This password is then encrypted and compared + against the stored password. The user has only one chance to enter the + correct password. The administrators are permitted to bypass this step so + that forgotten passwords may be changed.</para> + + <para>The user is then prompted for a replacement password. + <command>passwd</command> will prompt twice for this replacement and + compare the second entry against the first. Both entries are required to + match in order for the password to be changed.</para> + + <para>After the password has been entered, password aging information is + checked to see if the user is permitted to change their password at this + time. If not, <command>passwd</command> refuses to change the password + and exits.</para> + + <para> To get current password status information, use the + <literal>-S</literal> option. Administrators can use + <command>passwd</command> to perform several account maintenance + functions (users may perform some of these functions on their own + accounts). Accounts may be locked with the <literal>-l</literal> flag and + unlocked with the <literal>-u</literal> flag. Similarly, + <literal>-c</literal> disables a user's ability to change passwords, and + <literal>-C</literal> allows a user to change passwords. For password + expiry, the <literal>-e</literal> option disables expiration, while the + <literal>-E</literal> option causes the password to expire according to + the system's normal aging rules. Use <literal>-p</literal> to disable the + password requirement for a user, or <literal>-P</literal> to require a + password. </para> + + <para>Administrators can also use <command>passwd</command> to change + system-wide password expiry and length requirements with the + <literal>-i</literal>, <literal>-n</literal>, <literal>-x</literal>, and + <literal>-L</literal> options. The <literal>-i</literal> option is used + to disable an account after the password has been expired for a number of + days. After a user account has had an expired password for + <emphasis>NUM</emphasis> days, the user may no longer sign on to the + account. The <literal>-n</literal> option is used to set the minimum + number of days before a password may be changed. The user will not be + permitted to change the password until <emphasis>MINDAYS</emphasis> days + have elapsed. The <literal>-x</literal> option is used to set the maximum + number of days a password remains valid. After + <emphasis>MAXDAYS</emphasis> days, the password is required to be + changed. Allowed values for the above options are 0 to 999. The + <literal>-L</literal> option sets the minimum length of allowed passwords + for users who don't belong to the administrators group to + <emphasis>LEN</emphasis> characters. Allowed values for the minimum + password length are 0 to 14. In any of the above cases, a value of 0 + means `no restrictions'.</para> + + <para> All operations affecting the current user are by default run against + the logon server of the current user (taken from the environment variable + <envar>LOGONSERVER</envar>. When password or account information of other + users should be changed, the default server is the local system. To + change a user account on a remote machine, use the <literal>-d</literal> + option to specify the machine to run the command against. Note that the + current user must be a valid member of the administrators group on the + remote machine to perform such actions. </para> + + <para>Users can use the <command>passwd -R</command> to enter a password + which then gets stored in a special area of the registry on the local + system, which is also used by Windows to store passwords of accounts + running Windows services. When a privileged Cygwin application calls the + <command>set{e}uid(user_id)</command> system call, Cygwin checks if a + password for that user has been stored in this registry area. If so, it + uses this password to switch to this user account using that password. + This allows you to logon through, for instance, <command>ssh</command> + with public key authentication and get a full qualified user token with + all credentials for network access. However, the method has some + drawbacks security-wise. This is explained in more detail in <xref + linkend="ntsec"/>.</para> + + <para>Please note that storing passwords in that registry area is a + privileged operation which only administrative accounts are allowed to + do. Administrators can enter the password for other user accounts into + the registry by specifying the username on the commandline. If normal, + non-admin users should be allowed to enter their passwords using + <command>passwd -R</command>, it's required to run + <command>cygserver</command> as a service under the LocalSystem account + before running <command>passwd -R</command>. This only affects storing + passwords. Using passwords in privileged processes does not require + <command>cygserver</command> to run.</para> + + <para>Limitations: Users may not be able to change their password on some + systems.</para> + + </sect2> + + <sect2 id="pldd"> + <title>pldd</title> + + <screen> +Usage: pldd [OPTION...] PID + +List dynamic shared objects loaded into a process. + + -?, --help Give this help list + --usage Give a short usage message + -V, --version Print program version +</screen> + + <para><command>pldd</command> prints the shared libraries (DLLs) loaded by + the process with the given PID.</para> + + </sect2> + + <sect2 id="ps"> + <title>ps</title> + + <screen> +Usage: ps [-aefls] [-u UID] + +Report process status + + -a, --all show processes of all users + -e, --everyone show processes of all users + -f, --full show process uids, ppids + -h, --help output usage information and exit + -l, --long show process uids, ppids, pgids, winpids + -p, --process show information for specified PID + -s, --summary show process summary + -u, --user list processes owned by UID + -V, --version output version information and exit + -W, --windows show windows as well as cygwin processes +With no options, ps outputs the long format by default +</screen> + + <para>The <command>ps</command> program gives the status of all the Cygwin + processes running on the system (ps = "process status"). Due to the + limitations of simulating a POSIX environment under Windows, there is + little information to give. </para> + + <para> The PID column is the process ID you need to give to the + <command>kill</command> command. The PPID is the parent process ID, and + PGID is the process group ID. The WINPID column is the process ID + displayed by NT's Task Manager program. The TTY column gives which + pseudo-terminal a process is running on, or a <literal>'?'</literal> for + services. The UID column shows which user owns each process. STIME is the + time the process was started, and COMMAND gives the name of the program + running. Listings may also have a status flag in column zero; + <literal>S</literal> means stopped or suspended (in other words, in the + background), <literal>I</literal> means waiting for input or interactive + (foreground), and <literal>O</literal> means waiting to output. </para> + + <para> By default, <command>ps</command> will only show processes owned by + the current user. With either the <literal>-a</literal> or + <literal>-e</literal> option, all user's processes (and system processes) + are listed. There are historical UNIX reasons for the synonomous options, + which are functionally identical. The <literal>-f</literal> option + outputs a "full" listing with usernames for UIDs. The + <literal>-l</literal> option is the default display mode, showing a + "long" listing with all the above columns. The other display option is + <literal>-s</literal>, which outputs a shorter listing of just PID, TTY, + STIME, and COMMAND. The <literal>-u</literal> option allows you to show + only processes owned by a specific user. The <literal>-p</literal> option + allows you to show information for only the process with the specified + PID. The <literal>-W</literal> option causes <command>ps</command> show + non-Cygwin Windows processes as well as Cygwin processes. The WINPID is + also the PID, and they can be killed with the Cygwin + <command>kill</command> command's <literal>-f</literal> option. </para> + + </sect2> + + <sect2 id="regtool"> + <title>regtool</title> + + <screen> +Usage: regtool [OPTION] (add|check|get|list|remove|unset|load|unload|save) KEY + +View or edit the Win32 registry + +Actions: + + add KEY\SUBKEY add new SUBKEY + check KEY exit 0 if KEY exists, 1 if not + get KEY\VALUE prints VALUE to stdout + list KEY list SUBKEYs and VALUEs + remove KEY remove KEY + set KEY\VALUE [data ...] set VALUE + unset KEY\VALUE removes VALUE from KEY + load KEY\SUBKEY PATH load hive from PATH into new SUBKEY + unload KEY\SUBKEY unload hive and remove SUBKEY + save KEY\SUBKEY PATH save SUBKEY into new hive PATH + +Options for 'list' Action: + + -k, --keys print only KEYs + -l, --list print only VALUEs + -p, --postfix like ls -p, appends '\' postfix to KEY names + +Options for 'get' Action: + + -b, --binary print REG_BINARY data as hex bytes + -n, --none print data as stream of bytes as stored in registry + -x, --hex print numerical data as hex numbers + +Options for 'set' Action: + + -b, --binary set type to REG_BINARY (hex args or '-') + -D, --dword-be set type to REG_DWORD_BIG_ENDIAN + -e, --expand-string set type to REG_EXPAND_SZ + -i, --integer set type to REG_DWORD + -m, --multi-string set type to REG_MULTI_SZ + -n, --none set type to REG_NONE + -Q, --qword set type to REG_QWORD + -s, --string set type to REG_SZ + +Options for 'set' and 'unset' Actions: + + -K<c>, --key-separator[=]<c> set key separator to <c> instead of '\' + +Other Options: + + -h, --help output usage information and exit + -q, --quiet no error output, just nonzero return if KEY/VALUE missing + -v, --verbose verbose output, including VALUE contents when applicable + -w, --wow64 access 64 bit registry view (ignored on 32 bit Windows) + -W, --wow32 access 32 bit registry view (ignored on 32 bit Windows) + -V, --version output version information and exit + +KEY is in the format [host]\prefix\KEY\KEY\VALUE, where host is optional +remote host in either \\hostname or hostname: format and prefix is any of: + root HKCR HKEY_CLASSES_ROOT (local only) + config HKCC HKEY_CURRENT_CONFIG (local only) + user HKCU HKEY_CURRENT_USER (local only) + machine HKLM HKEY_LOCAL_MACHINE + users HKU HKEY_USERS + +You can use forward slash ('/') as a separator instead of backslash, in +that case backslash is treated as escape character +Example: regtool.exe get '\user\software\Microsoft\Clock\iFormat' +</screen> + + <para>The <command>regtool</command> program allows shell scripts to access + and modify the Windows registry. Note that modifying the Windows registry + is dangerous, and carelessness here can result in an unusable system. Be + careful.</para> + + <para>The <literal>-v</literal> option means "verbose". For most commands, + this causes additional or lengthier messages to be printed. Conversely, + the <literal>-q</literal> option supresses error messages, so you can use + the exit status of the program to detect if a key exists or not (for + example).</para> + + <para>The <literal>-w</literal> option allows you to access the 64 bit view + of the registry. Several subkeys exist in a 32 bit and a 64 bit version + when running on Windows 64. Since Cygwin is running in 32 bit mode, it + only has access to the 32 bit view of these registry keys. When using the + <literal>-w</literal> switch, the 64 bit view is used and + <command>regtool</command> can access the entire registry. This option is + simply ignored when running on 32 bit Windows versions. </para> + + <para>The <literal>-W</literal> option allows you to access the 32 bit view + on the registry. The purpose of this option is mainly for symmetry. It + permits creation of OS agnostic scripts which would also work in a + hypothetical 64 bit version of Cygwin.</para> + + <para>You must provide <command>regtool</command> with an + <emphasis>action</emphasis> following options (if any). Currently, the + action must be <literal>add</literal>, <literal>set</literal>, + <literal>check</literal>, <literal>get</literal>, + <literal>list</literal>, <literal>remove</literal>, + <literal>set</literal>, or <literal>unset</literal>. </para> + + <para>The <literal>add</literal> action adds a new key. The + <literal>check</literal> action checks to see if a key exists (the exit + code of the program is zero if it does, nonzero if it does not). The + <literal>get</literal> action gets the value of a key, and prints it (and + nothing else) to stdout. Note: if the value doesn't exist, an error + message is printed and the program returns a non-zero exit code. If you + give <literal>-q</literal>, it doesn't print the message but does return + the non-zero exit code.</para> + + <para> The <literal>list</literal> action lists the subkeys and values + belonging to the given key. With <literal>list</literal>, the + <literal>-k</literal> option instructs <command>regtool</command> to + print only KEYs, and the <literal>-l</literal> option to print only + VALUEs. The <literal>-p</literal> option postfixes a + <literal>'/'</literal> to each KEY, but leave VALUEs with no postfix. The + <literal>remove</literal> action removes a key. Note that you may need to + remove everything in the key before you may remove it, but don't rely on + this stopping you from accidentally removing too much. </para> + + <para>The <literal>get</literal> action prints a value within a key. With + the <literal>-b</literal> option, data is printed as hex bytes. + <literal>-n</literal> allows to print the data as a typeless stream of + bytes. Integer values (REG_DWORD, REG_QWORD) are usually printed as + decimal values. The <literal>-x</literal> option allows to print the + numbers as hexadecimal values.</para> + + <para>The <literal>set</literal> action sets a value within a key. + <literal>-b</literal> means it's binary data (REG_BINARY). The binary + values are specified as hex bytes in the argument list. If the argument + is <literal>'-'</literal>, binary data is read from stdin instead. + <literal>-d</literal> or <literal>-i</literal> means the value is a 32 + bit integer value (REG_DWORD). <literal>-D</literal> means the value is a + 32 bit integer value in Big Endian representation (REG_DWORD_BIG_ENDIAN). + <literal>-Q</literal> means the value is a 64 bit integer value + (REG_QWORD). <literal>-s</literal> means the value is a string (REG_SZ). + <literal>-e</literal> means it's an expanding string (REG_EXPAND_SZ) that + contains embedded environment variables. <literal>-m</literal> means it's + a multi-string (REG_MULTI_SZ). If you don't specify one of these, + <command>regtool</command> tries to guess the type based on the value you + give. If it looks like a number, it's a DWORD, unless it's value doesn't + fit into 32 bit, in which case it's a QWORD. If it starts with a percent, + it's an expanding string. If you give multiple values, it's a + multi-string. Else, it's a regular string.</para> + + <para>The <literal>unset</literal> action removes a value from a + key.</para> + + <para>The <literal>load</literal> action adds a new subkey and loads the + contents of a registry hive into it. The parent key must be + HKEY_LOCAL_MACHINE or HKEY_USERS. The <literal>unload</literal> action + unloads the file and removes the subkey. </para> + + <para>The <literal>save</literal> action saves a subkey into a registry + hive. </para> + + <para> By default, the last "\" or "/" is assumed to be the separator + between the key and the value. You can use the <literal>-K</literal> + option to provide an alternate key/value separator character. </para> + + </sect2> + + <sect2 id="setfacl"> + <title>setfacl</title> + + <screen> +Usage: setfacl [-r] (-f ACL_FILE | -s acl_entries) FILE... + setfacl [-r] ([-d acl_entries] [-m acl_entries]) FILE... + +Modify file and directory access control lists (ACLs) + + -d, --delete delete one or more specified ACL entries + -f, --file set ACL entries for FILE to ACL entries read + from a ACL_FILE + -m, --modify modify one or more specified ACL entries + -r, --replace replace mask entry with maximum permissions + needed for the file group class + -s, --substitute substitute specified ACL entries for the + ACL of FILE + -h, --help output usage information and exit + -V, --version output version information and exit + +At least one of (-d, -f, -m, -s) must be specified +</screen> + + <para> For each file given as parameter, <command>setfacl</command> will + either replace its complete ACL (<literal>-s</literal>, + <literal>-f</literal>), or it will add, modify, or delete ACL entries. + For more information on Cygwin and Windows ACLs, see see <xref + linkend="ntsec"/> in the Cygwin User's Guide. </para> + + <para> Acl_entries are one or more comma-separated ACL entries from the + following list: + <screen> + u[ser]::perm + u[ser]:uid:perm + g[roup]::perm + g[roup]:gid:perm + m[ask]::perm + o[ther]::perm +</screen> + Default entries are like the above with the additional default + identifier. For example: + <screen> + d[efault]:u[ser]:uid:perm +</screen> </para> + + <para> <emphasis>perm</emphasis> is either a 3-char permissions string in + the form "rwx" with the character <literal>'-'</literal> for no + permission or it is the octal representation of the permissions, a value + from 0 (equivalent to "---") to 7 ("rwx"). <emphasis>uid</emphasis> is a + user name or a numerical uid. <emphasis>gid</emphasis> is a group name or + a numerical gid. </para> + + <para> The following options are supported: </para> + + <para> <literal>-d</literal> Delete one or more specified entries from the + file's ACL. The owner, group and others entries must not be deleted. + Acl_entries to be deleted should be specified without permissions, as in + the following list: + <screen> + u[ser]:uid + g[roup]:gid + d[efault]:u[ser]:uid + d[efault]:g[roup]:gid + d[efault]:m[ask]: + d[efault]:o[ther]: +</screen> </para> + + <para> <literal>-f</literal> Take the Acl_entries from ACL_FILE one per + line. Whitespace characters are ignored, and the character "#" may be + used to start a comment. The special filename "-" indicates reading from + stdin. Note that you can use this with <command>getfacl</command> and + <command>setfacl</command> to copy ACLs from one file to another: + <screen> +$ getfacl source_file | setfacl -f - target_file +</screen> </para> + + <para> Required entries are: one user entry for the owner of the file, one + group entry for the group of the file, and one other entry. </para> + + <para> If additional user and group entries are given: a mask entry for the + file group class of the file, and no duplicate user or group entries with + the same uid/gid. </para> + + <para> If it is a directory: one default user entry for the owner of the + file, one default group entry for the group of the file, one default mask + entry for the file group class, and one default other entry. </para> + + <para> <literal>-m</literal> Add or modify one or more specified ACL + entries. Acl_entries is a comma-separated list of entries from the same + list as above. </para> + + <para> <literal>-r</literal> Causes the permissions specified in the mask + entry to be ignored and replaced by the maximum permissions needed for + the file group class. </para> + + <para> <literal>-s</literal> Like <literal>-f</literal>, but substitute the + file's ACL with Acl_entries specified in a comma-separated list on the + command line. </para> + + <para> While the <literal>-d</literal> and <literal>-m</literal> options + may be used in the same command, the <literal>-f</literal> and + <literal>-s</literal> options may be used only exclusively. </para> + + <para> Directories may contain default ACL entries. Files created in a + directory that contains default ACL entries will have permissions + according to the combination of the current umask, the explicit + permissions requested and the default ACL entries </para> + + <para> Limitations: Under Cygwin, the default ACL entries are not taken + into account currently. </para> + + </sect2> + + <sect2 id="setmetamode"> + <title>setmetamode</title> + + <screen> +Usage: setmetamode [metabit|escprefix] + +Get or set keyboard meta mode + + Without argument, it shows the current meta key mode. + metabit|meta|bit The meta key sets the top bit of the character. + escprefix|esc|prefix The meta key sends an escape prefix. + +Other options: + + -h, --help This text + -V, --version Print program version and exit +</screen> + + <para><command>setmetamode</command> can be used to determine and set the + key code sent by the meta (aka <literal>Alt</literal>) key.</para> + + </sect2> + + <sect2 id="ssp"> + <title>ssp</title> + + <screen> +Usage: ssp [options] low_pc high_pc command... + +Single-step profile COMMAND + + -c, --console-trace trace every EIP value to the console. *Lots* slower. + -d, --disable disable single-stepping by default; use + OutputDebugString ("ssp on") to enable stepping + -e, --enable enable single-stepping by default; use + OutputDebugString ("ssp off") to disable stepping + -h, --help output usage information and exit + -l, --dll enable dll profiling. A chart of relative DLL usage + is produced after the run. + -s, --sub-threads trace sub-threads too. Dangerous if you have + race conditions. + -t, --trace-eip trace every EIP value to a file TRACE.SSP. This + gets big *fast*. + -v, --verbose output verbose messages about debug events. + -V, --version output version information and exit + +Example: ssp 0x401000 0x403000 hello.exe +</screen> + + <para> SSP - The Single Step Profiler </para> + + <para> Original Author: DJ Delorie </para> + + <para> The SSP is a program that uses the Win32 debug API to run a program + one ASM instruction at a time. It records the location of each + instruction used, how many times that instruction is used, and all + function calls. The results are saved in a format that is usable by the + profiling program <command>gprof</command>, although + <command>gprof</command> will claim the values are seconds, they really + are instruction counts. More on that later. </para> + + <para> Because the SSP was originally designed to profile the Cygwin DLL, + it does not automatically select a block of code to report statistics on. + You must specify the range of memory addresses to keep track of manually, + but it's not hard to figure out what to specify. Use the "objdump" + program to determine the bounds of the target's ".text" section. Let's + say we're profiling cygwin1.dll. Make sure you've built it with debug + symbols (else <command>gprof</command> won't run) and run objdump like + this: <screen> +$ objdump -h cygwin1.dll +</screen> It will print a report + like this: + <screen> +cygwin1.dll: file format pei-i386 + +Sections: +Idx Name Size VMA LMA File off Algn + 0 .text 0007ea00 61001000 61001000 00000400 2**2 + CONTENTS, ALLOC, LOAD, READONLY, CODE, DATA + 1 .data 00008000 61080000 61080000 0007ee00 2**2 + CONTENTS, ALLOC, LOAD, DATA + . . . +</screen> </para> + + <para> The only information we're concerned with are the VMA of the .text + section and the VMA of the section after it (sections are usually + contiguous; you can also add the Size to the VMA to get the end address). + In this case, the VMA is 0x61001000 and the ending address is either + 0x61080000 (start of .data method) or 0x0x6107fa00 (VMA+Size method). </para> + + <para> There are two basic ways to use SSP - either profiling a whole + program, or selectively profiling parts of the program. </para> + + <para> To profile a whole program, just run <command>ssp</command> without + options. By default, it will step the whole program. Here's a simple + example, using the numbers above: + <screen> +$ ssp 0x61001000 0x61080000 hello.exe +</screen> This will step + the whole program. It will take at least 8 minutes on a PII/300 (yes, + really). When it's done, it will create a file called "gmon.out". You can + turn this data file into a readable report with <command>gprof</command>: + <screen> +$ gprof -b cygwin1.dll +</screen> The "-b" means 'skip the help + pages'. You can omit this until you're familiar with the report layout. + The <command>gprof</command> documentation explains a lot about this + report, but <command>ssp</command> changes a few things. For example, the + first part of the report reports the amount of time spent in each + function, like this: + <screen> +Each sample counts as 0.01 seconds. + % cumulative self self total + time seconds seconds calls ms/call ms/call name + 10.02 231.22 72.43 46 1574.57 1574.57 strcspn + 7.95 288.70 57.48 130 442.15 442.15 strncasematch +</screen> + The "seconds" columns are really CPU opcodes, 1/100 second per opcode. + So, "231.22" above means 23,122 opcodes. The ms/call values are 10x too + big; 1574.57 means 157.457 opcodes per call. Similar adjustments need to + be made for the "self" and "children" columns in the second part of the + report. </para> + + <para> OK, so now we've got a huge report that took a long time to + generate, and we've identified a spot we want to work on optimizing. + Let's say it's the time() function. We can use SSP to selectively profile + this function by using OutputDebugString() to control SSP from within the + program. Here's a sample program: + <screen> + #include <windows.h> + main() + { + time_t t; + OutputDebugString("ssp on"); + time(&t); + OutputDebugString("ssp off"); + } +</screen> </para> + + <para> Then, add the <literal>-d</literal> option to ssp to default to + *disabling* profiling. The program will run at full speed until the first + OutputDebugString, then step until the second. You can then use + <command>gprof</command> (as usual) to see the performance profile for + just that portion of the program's execution. </para> + + <para> There are many options to ssp. Since step-profiling makes your + program run about 1,000 times slower than normal, it's best to understand + all the options so that you can narrow down the parts of your program you + need to single-step. </para> + + <para> <literal>-v</literal> - verbose. This prints messages about threads + starting and stopping, OutputDebugString calls, DLLs loading, etc. </para> + + <para> <literal>-t</literal> and <literal>-c</literal> - tracing. With + <literal>-t</literal>, *every* step's address is written to the file + "trace.ssp". This can be used to help debug functions, since it can trace + multiple threads. Clever use of scripts can match addresses with + disassembled opcodes if needed. Warning: creates *huge* files, very + quickly. <literal>-c</literal> prints each address to the console, useful + for debugging key chunks of assembler. Use <literal>addr2line -C -f -s -e + foo.exe < trace.ssp > lines.ssp</literal> and then <literal>perl + cvttrace</literal> to convert to symbolic traces. </para> + + <para> <literal>-s</literal> - subthreads. Usually, you only need to trace + the main thread, but sometimes you need to trace all threads, so this + enables that. It's also needed when you want to profile a function that + only a subthread calls. However, using OutputDebugString automatically + enables profiling on the thread that called it, not the main thread. </para> + + <para> <literal>-l</literal> - dll profiling. Generates a pretty table of + how much time was spent in each dll the program used. No sense optimizing + a function in your program if most of the time is spent in the DLL. I + usually use the <literal>-v</literal>, <literal>-s</literal>, and + <literal>-l</literal> options: + <screen> +$ ssp <literal>-v</literal> <literal>-s</literal> <literal>-l</literal> <literal>-d</literal> 0x61001000 0x61080000 hello.exe +</screen> + </para> + </sect2> + + <sect2 id="strace"> + <title>strace</title> + + <screen> +Usage: strace.exe [OPTIONS] <command-line> +Usage: strace.exe [OPTIONS] -p <pid> + +Trace system calls and signals + + -b, --buffer-size=SIZE set size of output file buffer + -d, --no-delta don't display the delta-t microsecond timestamp + -f, --trace-children trace child processes (toggle - default true) + -h, --help output usage information and exit + -m, --mask=MASK set message filter mask + -n, --crack-error-numbers output descriptive text instead of error + numbers for Windows errors + -o, --output=FILENAME set output file to FILENAME + -p, --pid=n attach to executing program with cygwin pid n + -q, --quiet toggle "quiet" flag. Defaults to on if "-p", + off otherwise. + -S, --flush-period=PERIOD flush buffered strace output every PERIOD secs + -t, --timestamp use an absolute hh:mm:ss timestamp insted of + the default microsecond timestamp. Implies -d + -T, --toggle toggle tracing in a process already being + traced. Requires -p <pid> + -u, --usecs toggle printing of microseconds timestamp + -V, --version output version information and exit + -w, --new-window spawn program under test in a new window + + MASK can be any combination of the following mnemonics and/or hex values + (0x is optional). Combine masks with '+' or ',' like so: + + --mask=wm+system,malloc+0x00800 + + Mnemonic Hex Corresponding Def Description + ========================================================================= + all 0x000001 (_STRACE_ALL) All strace messages. + flush 0x000002 (_STRACE_FLUSH) Flush output buffer after each message. + inherit 0x000004 (_STRACE_INHERIT) Children inherit mask from parent. + uhoh 0x000008 (_STRACE_UHOH) Unusual or weird phenomenon. + syscall 0x000010 (_STRACE_SYSCALL) System calls. + startup 0x000020 (_STRACE_STARTUP) argc/envp printout at startup. + debug 0x000040 (_STRACE_DEBUG) Info to help debugging. + paranoid 0x000080 (_STRACE_PARANOID) Paranoid info. + termios 0x000100 (_STRACE_TERMIOS) Info for debugging termios stuff. + select 0x000200 (_STRACE_SELECT) Info on ugly select internals. + wm 0x000400 (_STRACE_WM) Trace Windows msgs (enable _strace_wm). + sigp 0x000800 (_STRACE_SIGP) Trace signal and process handling. + minimal 0x001000 (_STRACE_MINIMAL) Very minimal strace output. + pthread 0x002000 (_STRACE_PTHREAD) Pthread calls. + exitdump 0x004000 (_STRACE_EXITDUMP) Dump strace cache on exit. + system 0x008000 (_STRACE_SYSTEM) Serious error; goes to console and log. + nomutex 0x010000 (_STRACE_NOMUTEX) Don't use mutex for synchronization. + malloc 0x020000 (_STRACE_MALLOC) Trace malloc calls. + thread 0x040000 (_STRACE_THREAD) Thread-locking calls. + special 0x100000 (_STRACE_SPECIAL) Special debugging printfs for + non-checked-in code +</screen> + + <para>The <command>strace</command> program executes a program, and + optionally the children of the program, reporting any Cygwin DLL output + from the program(s) to stdout, or to a file with the + <literal>-o</literal> option. With the <literal>-w</literal> option, you + can start an strace session in a new window, for example: + <screen> +$ strace -o tracing_output -w sh -c 'while true; do echo "tracing..."; done' & +</screen> + This is particularly useful for <command>strace</command> sessions that + take a long time to complete. </para> + + <para> Note that <command>strace</command> is a standalone Windows program + and so does not rely on the Cygwin DLL itself (you can verify this with + <command>cygcheck</command>). As a result it does not understand + symlinks. This program is mainly useful for debugging the Cygwin DLL + itself.</para> + + </sect2> + + <sect2 id="tzset"> + <title>tzset</title> + + <screen> +Usage: tzset [OPTION] + +Print POSIX-compatible timezone ID from current Windows timezone setting + +Options: + -h, --help output usage information and exit. + -V, --version output version information and exit. + +Use tzset to set your TZ variable. In POSIX-compatible shells like bash, +dash, mksh, or zsh: + + export TZ=$(tzset) + +In csh-compatible shells like tcsh: + + setenv TZ `tzset` +</screen> + + <para>The <command>tzset</command> tool reads the current timezone from + Windows and generates a POSIX-compatible timezone information for the TZ + environment variable from that information. That's all there is to it. + For the way how to use it, see the above usage information.</para> + + </sect2> + + <sect2 id="umount"> + <title>umount</title> + + <screen> +Usage: umount.exe [OPTION] [<posixpath>] + +Unmount filesystems + + -h, --help output usage information and exit + -U, --remove-user-mounts remove all user mounts + -V, --version output version information and exit +</screen> + + <para>The <command>umount</command> program removes mounts from the mount + table in the current session. If you specify a POSIX path that + corresponds to a current mount point, <command>umount</command> will + remove it from the current mount table. Note that you can only remove + user mount points. The <literal>-U</literal> flag may be used to specify + removing all user mount points from the current user session.</para> + + <para>See <xref linkend="mount-table"/> for more information on the mount + table.</para> + </sect2> + +</sect1> |