Skip to content

Commit

Permalink
Merge pull request #8 from dscho/home-env
Browse files Browse the repository at this point in the history
Allow overriding the home directory via the HOME variable
  • Loading branch information
dscho committed Feb 12, 2018
2 parents 8316956 + c5cd237 commit 0861c2a
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 4 deletions.
3 changes: 2 additions & 1 deletion winsup/cygwin/cygheap.h
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,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
65 changes: 62 additions & 3 deletions winsup/cygwin/uinfo.cc
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,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 @@ -998,6 +1000,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 @@ -1057,6 +1093,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 All @@ -1070,6 +1110,8 @@ cygheap_pwdgrp::get_home (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,

for (uint16_t idx = 0; !home && idx < NSS_SCHEME_MAX; ++idx)
{
if (!ui && home_scheme[idx].method != NSS_SCHEME_ENV)
continue;
switch (home_scheme[idx].method)
{
case NSS_SCHEME_FALLBACK:
Expand All @@ -1089,6 +1131,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 @@ -1108,6 +1154,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 @@ -1172,6 +1219,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 @@ -1253,6 +1301,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 @@ -1279,6 +1329,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 Expand Up @@ -2120,6 +2171,9 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
{
/* Just some fake. */
sid = csid.create (99, 1, 0);
if (arg.id == cygheap->user.real_uid)
home = cygheap->pg.get_home(NULL, cygheap->user.sid(),
NULL, NULL, false);
break;
}
else if (arg.id >= UNIX_POSIX_OFFSET)
Expand Down Expand Up @@ -2173,7 +2227,11 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
it to a well-known group here. */
if (acc_type == SidTypeUser
&& (sid_sub_auth_count (sid) <= 3 || sid_id_auth (sid) == 11))
acc_type = SidTypeWellKnownGroup;
{
acc_type = SidTypeWellKnownGroup;
home = cygheap->pg.get_home (pldap, sid, dom, domain, name,
fully_qualified_name);
}
switch (acc_type)
{
case SidTypeUser:
Expand Down Expand Up @@ -2645,10 +2703,11 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
logon. Unless it's the SYSTEM account. This conveniently allows to
logon interactively as SYSTEM for debugging purposes. */
else if (acc_type != SidTypeUser && sid != well_known_system_sid)
__small_sprintf (linebuf, "%W:*:%u:%u:U-%W\\%W,%s:/:/sbin/nologin",
__small_sprintf (linebuf, "%W:*:%u:%u:U-%W\\%W,%s:%s:/sbin/nologin",
posix_name, uid, gid,
dom, name,
sid.string ((char *) sidstr));
sid.string ((char *) sidstr),
home ? home : "/");
else
__small_sprintf (linebuf, "%W:*:%u:%u:%s%sU-%W\\%W,%s:%s%W:%s",
posix_name, uid, gid,
Expand Down

0 comments on commit 0861c2a

Please sign in to comment.