Skip to content

Commit c3fe0f6

Browse files
committed
Merge pull request #8 from dscho/home-env
Allow overriding the home directory via the HOME variable
2 parents 0d14c58 + 93d0983 commit c3fe0f6

File tree

2 files changed

+64
-4
lines changed

2 files changed

+64
-4
lines changed

winsup/cygwin/cygheap.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,8 @@ class cygheap_pwdgrp
414414
NSS_SCHEME_UNIX,
415415
NSS_SCHEME_DESC,
416416
NSS_SCHEME_PATH,
417-
NSS_SCHEME_FREEATTR
417+
NSS_SCHEME_FREEATTR,
418+
NSS_SCHEME_ENV
418419
};
419420
struct nss_scheme_t {
420421
nss_scheme_method method;

winsup/cygwin/uinfo.cc

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,8 @@ cygheap_pwdgrp::nss_init_line (const char *line)
780780
scheme[idx].method = NSS_SCHEME_UNIX;
781781
else if (NSS_CMP ("desc"))
782782
scheme[idx].method = NSS_SCHEME_DESC;
783+
else if (NSS_CMP ("env"))
784+
scheme[idx].method = NSS_SCHEME_ENV;
783785
else if (NSS_NCMP ("/"))
784786
{
785787
const char *e = c + strcspn (c, " \t");
@@ -970,6 +972,40 @@ fetch_from_path (cyg_ldap *pldap, PUSER_INFO_3 ui, cygpsid &sid, PCWSTR str,
970972
return ret;
971973
}
972974

975+
static size_t
976+
fetch_env(LPCWSTR key, char *buf, size_t size)
977+
{
978+
WCHAR wbuf[32767];
979+
DWORD max = sizeof wbuf / sizeof *wbuf;
980+
DWORD len = GetEnvironmentVariableW (key, wbuf, max);
981+
982+
if (!len || len >= max)
983+
return 0;
984+
985+
len = sys_wcstombs (buf, size, wbuf, len);
986+
return len && len < size ? len : 0;
987+
}
988+
989+
static char *
990+
fetch_home_env (void)
991+
{
992+
char home[32767];
993+
size_t max = sizeof home / sizeof *home, len;
994+
995+
if (fetch_env (L"HOME", home, max)
996+
|| ((len = fetch_env (L"HOMEDRIVE", home, max))
997+
&& fetch_env (L"HOMEPATH", home + len, max - len))
998+
|| fetch_env (L"USERPROFILE", home, max))
999+
{
1000+
tmp_pathbuf tp;
1001+
cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_ABSOLUTE,
1002+
home, tp.c_get(), NT_MAX_PATH);
1003+
return strdup(tp.c_get());
1004+
}
1005+
1006+
return NULL;
1007+
}
1008+
9731009
char *
9741010
cygheap_pwdgrp::get_home (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom,
9751011
PCWSTR dnsdomain, PCWSTR name, bool full_qualified)
@@ -1029,6 +1065,10 @@ cygheap_pwdgrp::get_home (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom,
10291065
}
10301066
}
10311067
break;
1068+
case NSS_SCHEME_ENV:
1069+
if (RtlEqualSid (sid, cygheap->user.sid ()))
1070+
home = fetch_home_env ();
1071+
break;
10321072
}
10331073
}
10341074
return home;
@@ -1042,6 +1082,8 @@ cygheap_pwdgrp::get_home (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
10421082

10431083
for (uint16_t idx = 0; !home && idx < NSS_SCHEME_MAX; ++idx)
10441084
{
1085+
if (!ui && home_scheme[idx].method != NSS_SCHEME_ENV)
1086+
continue;
10451087
switch (home_scheme[idx].method)
10461088
{
10471089
case NSS_SCHEME_FALLBACK:
@@ -1060,6 +1102,10 @@ cygheap_pwdgrp::get_home (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
10601102
home = fetch_from_path (NULL, ui, sid, home_scheme[idx].attrib,
10611103
dom, NULL, name, full_qualified);
10621104
break;
1105+
case NSS_SCHEME_ENV:
1106+
if (RtlEqualSid (sid, cygheap->user.sid ()))
1107+
home = fetch_home_env ();
1108+
break;
10631109
}
10641110
}
10651111
return home;
@@ -1079,6 +1125,7 @@ cygheap_pwdgrp::get_shell (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom,
10791125
case NSS_SCHEME_FALLBACK:
10801126
return NULL;
10811127
case NSS_SCHEME_WINDOWS:
1128+
case NSS_SCHEME_ENV:
10821129
break;
10831130
case NSS_SCHEME_CYGWIN:
10841131
if (pldap->fetch_ad_account (sid, false, dnsdomain))
@@ -1143,6 +1190,7 @@ cygheap_pwdgrp::get_shell (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
11431190
case NSS_SCHEME_CYGWIN:
11441191
case NSS_SCHEME_UNIX:
11451192
case NSS_SCHEME_FREEATTR:
1193+
case NSS_SCHEME_ENV:
11461194
break;
11471195
case NSS_SCHEME_DESC:
11481196
shell = fetch_from_description (ui->usri3_comment, L"shell=\"", 7);
@@ -1223,6 +1271,8 @@ cygheap_pwdgrp::get_gecos (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom,
12231271
sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, val);
12241272
}
12251273
break;
1274+
case NSS_SCHEME_ENV:
1275+
break;
12261276
}
12271277
}
12281278
if (gecos)
@@ -1249,6 +1299,7 @@ cygheap_pwdgrp::get_gecos (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
12491299
case NSS_SCHEME_CYGWIN:
12501300
case NSS_SCHEME_UNIX:
12511301
case NSS_SCHEME_FREEATTR:
1302+
case NSS_SCHEME_ENV:
12521303
break;
12531304
case NSS_SCHEME_DESC:
12541305
gecos = fetch_from_description (ui->usri3_comment, L"gecos=\"", 7);
@@ -2023,6 +2074,9 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
20232074
{
20242075
/* Just some fake. */
20252076
sid = csid.create (99, 1, 0);
2077+
if (arg.id == cygheap->user.real_uid)
2078+
home = cygheap->pg.get_home(NULL, cygheap->user.sid(),
2079+
NULL, NULL, false);
20262080
break;
20272081
}
20282082
else if (arg.id >= UNIX_POSIX_OFFSET)
@@ -2076,7 +2130,11 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
20762130
it to a well-known group here. */
20772131
if (acc_type == SidTypeUser
20782132
&& (sid_sub_auth_count (sid) <= 3 || sid_id_auth (sid) == 11))
2079-
acc_type = SidTypeWellKnownGroup;
2133+
{
2134+
acc_type = SidTypeWellKnownGroup;
2135+
home = cygheap->pg.get_home (pldap, sid, dom, domain, name,
2136+
fully_qualified_name);
2137+
}
20802138
switch (acc_type)
20812139
{
20822140
case SidTypeUser:
@@ -2509,10 +2567,11 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
25092567
logon. Unless it's the SYSTEM account. This conveniently allows to
25102568
logon interactively as SYSTEM for debugging purposes. */
25112569
else if (acc_type != SidTypeUser && sid != well_known_system_sid)
2512-
__small_sprintf (linebuf, "%W:*:%u:%u:U-%W\\%W,%s:/:/sbin/nologin",
2570+
__small_sprintf (linebuf, "%W:*:%u:%u:U-%W\\%W,%s:%s:/sbin/nologin",
25132571
posix_name, uid, gid,
25142572
dom, name,
2515-
sid.string ((char *) sidstr));
2573+
sid.string ((char *) sidstr),
2574+
home ? home : "/");
25162575
else
25172576
__small_sprintf (linebuf, "%W:*:%u:%u:%s%sU-%W\\%W,%s:%s%W:%s",
25182577
posix_name, uid, gid,

0 commit comments

Comments
 (0)