Skip to content

Commit a88c376

Browse files
committed
Merge pull request #8 from dscho/home-env
Allow overriding the home directory via the HOME variable
2 parents 2b28d3e + 99f447b commit a88c376

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
@@ -819,6 +819,8 @@ cygheap_pwdgrp::nss_init_line (const char *line)
819819
scheme[idx].method = NSS_SCHEME_UNIX;
820820
else if (NSS_CMP ("desc"))
821821
scheme[idx].method = NSS_SCHEME_DESC;
822+
else if (NSS_CMP ("env"))
823+
scheme[idx].method = NSS_SCHEME_ENV;
822824
else if (NSS_NCMP ("/"))
823825
{
824826
const char *e = c + strcspn (c, " \t");
@@ -1009,6 +1011,40 @@ fetch_from_path (cyg_ldap *pldap, PUSER_INFO_3 ui, cygpsid &sid, PCWSTR str,
10091011
return ret;
10101012
}
10111013

1014+
static size_t
1015+
fetch_env(LPCWSTR key, char *buf, size_t size)
1016+
{
1017+
WCHAR wbuf[32767];
1018+
DWORD max = sizeof wbuf / sizeof *wbuf;
1019+
DWORD len = GetEnvironmentVariableW (key, wbuf, max);
1020+
1021+
if (!len || len >= max)
1022+
return 0;
1023+
1024+
len = sys_wcstombs (buf, size, wbuf, len);
1025+
return len && len < size ? len : 0;
1026+
}
1027+
1028+
static char *
1029+
fetch_home_env (void)
1030+
{
1031+
char home[32767];
1032+
size_t max = sizeof home / sizeof *home, len;
1033+
1034+
if (fetch_env (L"HOME", home, max)
1035+
|| ((len = fetch_env (L"HOMEDRIVE", home, max))
1036+
&& fetch_env (L"HOMEPATH", home + len, max - len))
1037+
|| fetch_env (L"USERPROFILE", home, max))
1038+
{
1039+
tmp_pathbuf tp;
1040+
cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_ABSOLUTE,
1041+
home, tp.c_get(), NT_MAX_PATH);
1042+
return strdup(tp.c_get());
1043+
}
1044+
1045+
return NULL;
1046+
}
1047+
10121048
char *
10131049
cygheap_pwdgrp::get_home (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom,
10141050
PCWSTR dnsdomain, PCWSTR name, bool full_qualified)
@@ -1068,6 +1104,10 @@ cygheap_pwdgrp::get_home (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom,
10681104
}
10691105
}
10701106
break;
1107+
case NSS_SCHEME_ENV:
1108+
if (RtlEqualSid (sid, cygheap->user.sid ()))
1109+
home = fetch_home_env ();
1110+
break;
10711111
}
10721112
}
10731113
return home;
@@ -1081,6 +1121,8 @@ cygheap_pwdgrp::get_home (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
10811121

10821122
for (uint16_t idx = 0; !home && idx < NSS_SCHEME_MAX; ++idx)
10831123
{
1124+
if (!ui && home_scheme[idx].method != NSS_SCHEME_ENV)
1125+
continue;
10841126
switch (home_scheme[idx].method)
10851127
{
10861128
case NSS_SCHEME_FALLBACK:
@@ -1099,6 +1141,10 @@ cygheap_pwdgrp::get_home (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
10991141
home = fetch_from_path (NULL, ui, sid, home_scheme[idx].attrib,
11001142
dom, NULL, name, full_qualified);
11011143
break;
1144+
case NSS_SCHEME_ENV:
1145+
if (RtlEqualSid (sid, cygheap->user.sid ()))
1146+
home = fetch_home_env ();
1147+
break;
11021148
}
11031149
}
11041150
return home;
@@ -1118,6 +1164,7 @@ cygheap_pwdgrp::get_shell (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom,
11181164
case NSS_SCHEME_FALLBACK:
11191165
return NULL;
11201166
case NSS_SCHEME_WINDOWS:
1167+
case NSS_SCHEME_ENV:
11211168
break;
11221169
case NSS_SCHEME_CYGWIN:
11231170
if (pldap->fetch_ad_account (sid, false, dnsdomain))
@@ -1182,6 +1229,7 @@ cygheap_pwdgrp::get_shell (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
11821229
case NSS_SCHEME_CYGWIN:
11831230
case NSS_SCHEME_UNIX:
11841231
case NSS_SCHEME_FREEATTR:
1232+
case NSS_SCHEME_ENV:
11851233
break;
11861234
case NSS_SCHEME_DESC:
11871235
shell = fetch_from_description (ui->usri3_comment, L"shell=\"", 7);
@@ -1262,6 +1310,8 @@ cygheap_pwdgrp::get_gecos (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom,
12621310
sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, val);
12631311
}
12641312
break;
1313+
case NSS_SCHEME_ENV:
1314+
break;
12651315
}
12661316
}
12671317
if (gecos)
@@ -1288,6 +1338,7 @@ cygheap_pwdgrp::get_gecos (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
12881338
case NSS_SCHEME_CYGWIN:
12891339
case NSS_SCHEME_UNIX:
12901340
case NSS_SCHEME_FREEATTR:
1341+
case NSS_SCHEME_ENV:
12911342
break;
12921343
case NSS_SCHEME_DESC:
12931344
gecos = fetch_from_description (ui->usri3_comment, L"gecos=\"", 7);
@@ -2062,6 +2113,9 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
20622113
{
20632114
/* Just some fake. */
20642115
sid = csid.create (99, 1, 0);
2116+
if (arg.id == cygheap->user.real_uid)
2117+
home = cygheap->pg.get_home(NULL, cygheap->user.sid(),
2118+
NULL, NULL, false);
20652119
break;
20662120
}
20672121
else if (arg.id >= UNIX_POSIX_OFFSET)
@@ -2115,7 +2169,11 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
21152169
it to a well-known group here. */
21162170
if (acc_type == SidTypeUser
21172171
&& (sid_sub_auth_count (sid) <= 3 || sid_id_auth (sid) == 11))
2118-
acc_type = SidTypeWellKnownGroup;
2172+
{
2173+
acc_type = SidTypeWellKnownGroup;
2174+
home = cygheap->pg.get_home (pldap, sid, dom, domain, name,
2175+
fully_qualified_name);
2176+
}
21192177
switch (acc_type)
21202178
{
21212179
case SidTypeUser:
@@ -2548,10 +2606,11 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
25482606
logon. Unless it's the SYSTEM account. This conveniently allows to
25492607
logon interactively as SYSTEM for debugging purposes. */
25502608
else if (acc_type != SidTypeUser && sid != well_known_system_sid)
2551-
__small_sprintf (linebuf, "%W:*:%u:%u:U-%W\\%W,%s:/:/sbin/nologin",
2609+
__small_sprintf (linebuf, "%W:*:%u:%u:U-%W\\%W,%s:%s:/sbin/nologin",
25522610
posix_name, uid, gid,
25532611
dom, name,
2554-
sid.string ((char *) sidstr));
2612+
sid.string ((char *) sidstr),
2613+
home ? home : "/");
25552614
else
25562615
__small_sprintf (linebuf, "%W:*:%u:%u:%s%sU-%W\\%W,%s:%s%W:%s",
25572616
posix_name, uid, gid,

0 commit comments

Comments
 (0)