[PATCH v3 0/3] Support deriving the current user's home directory via HOME

Johannes Schindelin johannes.schindelin@gmx.de
Wed Sep 21 11:51:47 GMT 2022


This patch mini-series supports Git for Windows' main strategy to
determine the current user's home directory by looking at the
environment variable HOME, falling back to HOMEDRIVE and HOMEPATH, and
if these variables are also unset, to USERPROFILE.

This strategy is a quick method to determine the home directory, and it
also allows users to override the home directory easily (e.g. in case
that their real home directory is a network share that is not all that
well handled by some commands such as cmd.exe's cd command).

Sorry for sending out v3 sooooo late...!

Changes since v2:
- Using `getenv()` and `cygwin_create_path()` instead of the
  `GetEnvironmentVariableW()`/`cygwin_conv_path()` dance
- Adjusted the documentation to drive home that this only affects the
  _current_ user's home directory
- Using the `PUSER_INFO_3` variant of `get_home()`
- Adjusted the commit messages
- Added another patch, to support "ad-hoc cloud accounts"

Johannes Schindelin (3):
  Allow deriving the current user's home directory via the HOME variable
  Respect `db_home` setting even for SYSTEM/Microsoft accounts
  Respect `db_home: env` even when no uid can be determined

 winsup/cygwin/local_includes/cygheap.h |  3 +-
 winsup/cygwin/uinfo.cc                 | 54 ++++++++++++++++++++++++--
 winsup/doc/ntsec.xml                   | 22 +++++++++++
 3 files changed, 75 insertions(+), 4 deletions(-)

Range-diff:
1:  047fe1d78c ! 1:  6f8fe89d9d Allow deriving the current user's home directory via the HOME variable
    @@ Metadata
      ## Commit message ##
         Allow deriving the current user's home directory via the HOME variable

    -            * uinfo.cc (cygheap_pwdgrp::get_home): Offer an option in
    -            nsswitch.conf that let's the environment variable HOME (or
    -            HOMEDRIVE & HOMEPATH, or USERPROFILE) define the home
    -            directory of the current user.
    -
    -            * ntsec.xml: Document the `env` schema.
    -
    -    Detailed comments:
    -
    -    In the context of Git for Windows, it is a well-established technique
    -    to let the `$HOME` variable define where the current user's home
    -    directory is, falling back to `$HOMEDRIVE$HOMEPATH` and `$USERPROFILE`.
    +    This patch hails from Git for Windows (where the Cygwin runtime is used
    +    in the form of a slightly modified MSYS2 runtime), where it is a
    +    well-established technique to let the `$HOME` variable define where the
    +    current user's home directory is, falling back to `$HOMEDRIVE$HOMEPATH`
    +    and `$USERPROFILE`.

         The idea is that we want to share user-specific settings between
    -    programs, whether they be Cygwin, MSys2 or not.  Unfortunately, we
    +    programs, whether they be Cygwin, MSYS2 or not.  Unfortunately, we
         cannot blindly activate the "db_home: windows" setting because in some
         setups, the user's home directory is set to a hidden directory via an
         UNC path (\\share\some\hidden\folder$) -- something many programs
    -    cannot handle correctly, e.g. cmd.exe and other native Windows
    +    cannot handle correctly, e.g. `cmd.exe` and other native Windows
         applications that users want to employ as Git helpers.

         The established technique is to allow setting the user's home directory
    -    via the environment variables mentioned above.  This has the additional
    -    advantage that it is much faster than querying the Windows user database.
    +    via the environment variables mentioned above: `$HOMEDRIVE$HOMEPATH` or
    +    `$USERPROFILE`.  This has the additional advantage that it is much
    +    faster than querying the Windows user database.

         Of course this scheme needs to be opt-in.  For that reason, it needs
         to be activated explicitly via `db_home: env` in `/etc/nsswitch.conf`.

         Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>

    - ## winsup/cygwin/cygheap.h ##
    -@@ winsup/cygwin/cygheap.h: public:
    + ## winsup/cygwin/local_includes/cygheap.h ##
    +@@ winsup/cygwin/local_includes/cygheap.h: public:
          NSS_SCHEME_UNIX,
          NSS_SCHEME_DESC,
          NSS_SCHEME_PATH,
    @@ winsup/cygwin/uinfo.cc: fetch_from_path (cyg_ldap *pldap, PUSER_INFO_3 ui, cygps
        return ret;
      }

    -+static size_t
    -+fetch_env(LPCWSTR key, char *buf, size_t size)
    -+{
    -+  WCHAR wbuf[32767];
    -+  DWORD max = sizeof wbuf / sizeof *wbuf;
    -+  DWORD len = GetEnvironmentVariableW (key, wbuf, max);
    -+
    -+  if (!len || len >= max)
    -+    return 0;
    -+
    -+  len = sys_wcstombs (buf, size, wbuf, len);
    -+  return len && len < size ? len : 0;
    -+}
    -+
     +static char *
     +fetch_home_env (void)
     +{
    -+  char home[32767];
    -+  size_t max = sizeof home / sizeof *home, len;
    ++  tmp_pathbuf tp;
    ++  char *p, *q;
    ++  const char *home, *home_drive, *home_path;
     +
    -+  if (fetch_env (L"HOME", home, max)
    -+      || ((len = fetch_env (L"HOMEDRIVE", home, max))
    -+        && fetch_env (L"HOMEPATH", home + len, max - len))
    -+      || fetch_env (L"USERPROFILE", home, max))
    -+    {
    -+      tmp_pathbuf tp;
    -+      cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_ABSOLUTE,
    -+	  home, tp.c_get(), NT_MAX_PATH);
    -+      return strdup(tp.c_get());
    -+    }
    ++  if ((home = getenv ("HOME"))
    ++      || ((home_drive = getenv ("HOMEDRIVE"))
    ++	  && (home_path = getenv ("HOMEPATH"))
    ++	  // concatenate HOMEDRIVE and HOMEPATH
    ++          && (home = p = tp.c_get ())
    ++	  && (q = stpncpy (p, home_drive, NT_MAX_PATH))
    ++          && strlcpy (q, home_path, NT_MAX_PATH - (q - p)))
    ++      || (home = getenv ("USERPROFILE")))
    ++    return (char *) cygwin_create_path (CCP_WIN_A_TO_POSIX, home);
     +
     +  return NULL;
     +}
    @@ winsup/cygwin/uinfo.cc: cygheap_pwdgrp::get_shell (PUSER_INFO_3 ui, cygpsid &sid
     +	case NSS_SCHEME_ENV:
      	  break;
      	case NSS_SCHEME_DESC:
    - 	  shell = fetch_from_description (ui->usri3_comment, L"shell=\"", 7);
    + 	  if (ui)
     @@ winsup/cygwin/uinfo.cc: cygheap_pwdgrp::get_gecos (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom,
      		sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, val);
      	    }
    @@ winsup/cygwin/uinfo.cc: cygheap_pwdgrp::get_gecos (PUSER_INFO_3 ui, cygpsid &sid
     +	case NSS_SCHEME_ENV:
      	  break;
      	case NSS_SCHEME_DESC:
    - 	  gecos = fetch_from_description (ui->usri3_comment, L"gecos=\"", 7);
    + 	  if (ui)

      ## winsup/doc/ntsec.xml ##
     @@ winsup/doc/ntsec.xml: schemata are the following:
    @@ winsup/doc/ntsec.xml: schemata are the following:
     +	      <literal>USERPROFILE</literal>, in that order).  This is faster
     +	      than the <term><literal>windows</literal></term> schema at the
     +	      expense of determining only the current user's home directory
    -+	      correctly.</listitem>
    ++	      correctly.  This schema is skipped for any other account.
    ++	      </listitem>
     +  </varlistentry>
      </variablelist>

    @@ winsup/doc/ntsec.xml: of each schema when used with <literal>db_home:</literal>
     +	      <literal>USERPROFILE</literal>, in that order).  This is faster
     +	      than the <term><literal>windows</literal></term> schema at the
     +	      expense of determining only the current user's home directory
    -+	      correctly.</listitem>
    ++	      correctly.  This schema is skipped for any other account.
    ++	      </listitem>
     +  </varlistentry>
        <varlistentry>
          <term><literal>@ad_attribute</literal></term>
2:  90c5b45fbe ! 2:  1b4ee89aa7 Respect `db_home` setting even for the SYSTEM account
    @@ Metadata
     Author: Johannes Schindelin <johannes.schindelin@gmx.de>

      ## Commit message ##
    -    Respect `db_home` setting even for the SYSTEM account
    +    Respect `db_home` setting even for SYSTEM/Microsoft accounts

    -    We should not blindly set the home directory of the SYSTEM account to
    -    /home/SYSTEM, especially not when that value disagrees with what is
    -    configured via the `db_home` line in the `/etc/nsswitch.conf` file.
    -
    -    This fixes https://github.com/git-for-windows/git/issues/435
    +    We should not blindly set the home directory of the SYSTEM account (or
    +    of Microsoft accounts) to /home/SYSTEM, especially not when that value
    +    disagrees with what is configured via the `db_home` line in the
    +    `/etc/nsswitch.conf` file.

         Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>

    @@ winsup/cygwin/uinfo.cc: pwdgrp::fetch_account_from_windows (fetch_user_arg_t &ar
     -	acc_type = SidTypeWellKnownGroup;
     +	{
     +	  acc_type = SidTypeWellKnownGroup;
    -+	  home = cygheap->pg.get_home (pldap, sid, dom, domain, name,
    ++	  home = cygheap->pg.get_home ((PUSER_INFO_3) NULL, sid, dom, name,
     +				       fully_qualified_name);
     +	}
    -       switch (acc_type)
    -       	{
    +       switch ((int) acc_type)
    + 	{
      	case SidTypeUser:
-:  ---------- > 3:  4d90319e44 Respect `db_home: env` even when no uid can be determined

base-commit: a68e99f8839e4697790077c8a77b506d528cc674
Published-As: https://github.com/dscho/msys2-runtime/releases/tag/home-env-cygwin-v3
Fetch-It-Via: git fetch https://github.com/dscho/msys2-runtime home-env-cygwin-v3

--
2.38.0.rc0.windows.1



More information about the Cygwin-patches mailing list