Skip to content

home-env-cygwin-v5

This patch mini-series supports Git for Windows' default 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,
certainly quicker than looking at LDAP, even more so when a domain
controller is unreachable and causes long hangs in Cygwin's startup.

This strategy 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 v4 sooooo late...!

Changes since v3:

- Fixed the bug in v2 where `getenv("HOME")` would convert the value to
  a Unix-y path and the `fetch_home_env()` function would then try to
  convert it _again_.

- Disentangled the logic in `fetch_home_env()` instead of doing
  everything in one big, honking, unreadable `if` condition.

- Commented the code in `fetch_home_env()`.

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                 | 70 ++++++++++++++++++++++++--
 winsup/doc/ntsec.xml                   | 20 +++++++-
 3 files changed, 88 insertions(+), 5 deletions(-)

Range-diff:
1:  7a074997ea ! 1:  e26cae9439 Allow deriving the current user's home directory via the HOME variable
    @@ Commit message
         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`.

    +    Documentation-fixes-by: Corinna Vinschen <corinna@vinschen.de>
         Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>

      ## winsup/cygwin/local_includes/cygheap.h ##
    @@ winsup/cygwin/uinfo.cc: cygheap_pwdgrp::get_gecos (PUSER_INFO_3 ui, cygpsid &sid
      	  if (ui)

      ## winsup/doc/ntsec.xml ##
    +@@ winsup/doc/ntsec.xml: and on non-AD machines.
    + </para>
    +
    + <para>
    +-Four schemata are predefined, two schemata are variable.  The predefined
    ++Five schemata are predefined, two schemata are variable.  The predefined
    + schemata are the following:
    + </para>
    +
     @@ winsup/doc/ntsec.xml: schemata are the following:
      	      See <xref linkend="ntsec-mapping-nsswitch-desc"></xref>
      	      for a more detailed description.</listitem>
        </varlistentry>
     +  <varlistentry>
     +    <term><literal>env</literal></term>
    -+    <listitem>Derives the home directory of the current user from the
    -+	      environment variable <literal>HOME</literal> (falling back to
    -+	      <literal>HOMEDRIVE\HOMEPATH</literal> and
    -+	      <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.  This schema is skipped for any other account.
    -+	      </listitem>
    ++    <listitem>Utilizes the user's environment.  This schema is only supported
    ++	      for setting the home directory yet.
    ++	      See <xref linkend="ntsec-mapping-nsswitch-home"></xref> for
    ++	      the description.</listitem>
     +  </varlistentry>
      </variablelist>

    @@ winsup/doc/ntsec.xml: of each schema when used with <literal>db_home:</literal>
     +	      environment variable <literal>HOME</literal> (falling back to
     +	      <literal>HOMEDRIVE\HOMEPATH</literal> and
     +	      <literal>USERPROFILE</literal>, in that order).  This is faster
    -+	      than the <term><literal>windows</literal></term> schema at the
    ++	      than the <literal>windows</literal> schema at the
     +	      expense of determining only the current user's home directory
     +	      correctly.  This schema is skipped for any other account.
     +	      </listitem>
2:  a70c77dc8f ! 2:  085d4dd8b6 Respect `db_home` setting even for SYSTEM/Microsoft accounts
    @@ Commit message
         Respect `db_home` setting even for SYSTEM/Microsoft accounts

         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.
    +    of Microsoft accounts) to `/home/<name>`, especially
    +    `/etc/nsswitch.conf` defines `db_home: env`, in which case we want to
    +    respect the `HOME` variable.

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

3:  4cd6ae7307 ! 3:  cf47afceba Respect `db_home: env` even when no uid can be determined
    @@ Metadata
      ## Commit message ##
         Respect `db_home: env` even when no uid can be determined

    -    In particular when we cannot figure out a uid for the current user, we
    -    should still respect the `db_home: env` setting. Such a situation occurs
    -    for example when the domain returned by `LookupAccountSid()` is not our
    -    machine name and at the same time our machine is no domain member: In
    -    that case, we have nobody to ask for the POSIX offset necessary to come
    -    up with the uid.
    +    When we cannot figure out a uid for the current user, we should still
    +    respect the `db_home: env` setting.

    -    It is important that even in such cases, the `HOME` environment variable
    -    can be used to override the home directory, e.g. when Git for Windows is
    -    used by an account that was generated on the fly, e.g. for transient use
    -    in a cloud scenario.
    +    This is particularly important when programs like `ssh` look for the
    +    home directory of the usr, the user overrode `HOME` to "help" Cygwin
    +    determine where the home directory is. Cygwin should not ignore this.

    -    Reported by David Ebbo.
    +    One situation where we cannot determine a uid is when the domain
    +    returned by `LookupAccountSid()` is not our machine name and at the same
    +    time our machine is no domain member: In that case, we have nobody to
    +    ask for the POSIX offset necessary to come up with the uid.

    +    Azure Web Apps represent such a scenario, which can be verified e.g. in
    +    a Kudu console (for details about Kudu consoles, see
    +    https://github.com/projectkudu/kudu/wiki/Kudu-console): the domain is
    +    `IIS APPPOOL`, the account name is the name of the Azure Web App, the
    +    SID starts with 'S-1-5-82-`, and `pwdgrp::fetch_account_from_windows()`
    +    runs into the code path where "[...] the domain returned by
    +    LookupAccountSid is not our machine name, and if our machine is no
    +    domain member, we lose.  We have nobody to ask for the POSIX offset."
    +
    +    In such a scenario, OpenSSH's `getuid()` call will receive the return
    +    value -1, and the subsequent `getpwuid()` call (whose return value's
    +    `pw_dir` is used as home directory) needs to be forced to respect
    +    `db_home: env`, which this here patch does.
    +
    +    Reported-by: David Ebbo <david.ebbo@gmail.com>
         Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>

      ## winsup/cygwin/uinfo.cc ##

base-commit: a9a17f5fe51498b182d4a11ac48207b8c7ffe8ec

Submitted-As: https://inbox.sourceware.org/cygwin-patches/cover.1680532960.git.johannes.schindelin@gmx.de
In-Reply-To: https://inbox.sourceware.org/cygwin-patches/cover.1663761086.git.johannes.schindelin@gmx.de
In-Reply-To: https://inbox.sourceware.org/cygwin-patches/0Lg1Tn-1YnzUw0ScN-00pcgi@mail.gmx.com
In-Reply-To: https://inbox.sourceware.org/cygwin-patches/cover.1450375424.git.johannes.schindelin@gmx.de
In-Reply-To: https://inbox.sourceware.org/cygwin-patches/cover.1679991274.git.johannes.schindelin@gmx.de
Assets 2