Skip to content

Commit

Permalink
Allow overriding the home directory via the HOME variable
Browse files Browse the repository at this point in the history
In Git for Windows, it is a well-established technique to use the
`$HOME` variable to define where the current user's home directory is,
falling back to `$HOMEDRIVE$HOMEPATH` and `$USERPROFILE`.

This strategy is particular important when Cygwin, or command-line
programs depending on the HOME variable, cannot cope with the Windows'
idea of the user's home directory e.g. when it is set to a hidden
directory via an UNC path (\\share\some\hidden\folder$).

Of course this strategy needs to be opt-in. For that reason, this
strategy is activated via the `env` keyword in the `db_home` line in
`/etc/nsswitch.conf`.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
  • Loading branch information
dscho committed Nov 29, 2023
1 parent 5b45686 commit 81a0e5d
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 1 deletion.
3 changes: 2 additions & 1 deletion winsup/cygwin/local_includes/cygheap.h
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,8 @@ class cygheap_pwdgrp
NSS_SCHEME_UNIX,
NSS_SCHEME_DESC,
NSS_SCHEME_PATH,
NSS_SCHEME_FREEATTR
NSS_SCHEME_FREEATTR,
NSS_SCHEME_ENV
};
struct nss_scheme_t {
nss_scheme_method method;
Expand Down
49 changes: 49 additions & 0 deletions winsup/cygwin/uinfo.cc
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,8 @@ cygheap_pwdgrp::nss_init_line (const char *line)
scheme[idx].method = NSS_SCHEME_UNIX;
else if (NSS_CMP ("desc"))
scheme[idx].method = NSS_SCHEME_DESC;
else if (NSS_CMP ("env"))
scheme[idx].method = NSS_SCHEME_ENV;
else if (NSS_NCMP ("/"))
{
const char *e = c + strcspn (c, " \t");
Expand Down Expand Up @@ -921,6 +923,40 @@ fetch_from_path (cyg_ldap *pldap, PUSER_INFO_3 ui, cygpsid &sid, PCWSTR str,
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;

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());
}

return NULL;
}

char *
cygheap_pwdgrp::get_home (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom,
PCWSTR dnsdomain, PCWSTR name, bool full_qualified)
Expand Down Expand Up @@ -980,6 +1016,10 @@ cygheap_pwdgrp::get_home (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom,
}
}
break;
case NSS_SCHEME_ENV:
if (RtlEqualSid (sid, cygheap->user.sid ()))
home = fetch_home_env ();
break;
}
}
return home;
Expand Down Expand Up @@ -1012,6 +1052,10 @@ cygheap_pwdgrp::get_home (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
home = fetch_from_path (NULL, ui, sid, home_scheme[idx].attrib,
dom, NULL, name, full_qualified);
break;
case NSS_SCHEME_ENV:
if (RtlEqualSid (sid, cygheap->user.sid ()))
home = fetch_home_env ();
break;
}
}
return home;
Expand All @@ -1031,6 +1075,7 @@ cygheap_pwdgrp::get_shell (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom,
case NSS_SCHEME_FALLBACK:
return NULL;
case NSS_SCHEME_WINDOWS:
case NSS_SCHEME_ENV:
break;
case NSS_SCHEME_CYGWIN:
if (pldap->fetch_ad_account (sid, false, dnsdomain))
Expand Down Expand Up @@ -1095,6 +1140,7 @@ cygheap_pwdgrp::get_shell (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
case NSS_SCHEME_CYGWIN:
case NSS_SCHEME_UNIX:
case NSS_SCHEME_FREEATTR:
case NSS_SCHEME_ENV:
break;
case NSS_SCHEME_DESC:
if (ui)
Expand Down Expand Up @@ -1176,6 +1222,8 @@ cygheap_pwdgrp::get_gecos (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom,
sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, val);
}
break;
case NSS_SCHEME_ENV:
break;
}
}
if (gecos)
Expand All @@ -1202,6 +1250,7 @@ cygheap_pwdgrp::get_gecos (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
case NSS_SCHEME_CYGWIN:
case NSS_SCHEME_UNIX:
case NSS_SCHEME_FREEATTR:
case NSS_SCHEME_ENV:
break;
case NSS_SCHEME_DESC:
if (ui)
Expand Down

0 comments on commit 81a0e5d

Please sign in to comment.