Skip to content

Commit a27f72f

Browse files
committed
Merge pull request #8 from dscho/home-env
Allow overriding the home directory via the HOME variable
2 parents db68342 + 6354d7a commit a27f72f

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
@@ -408,7 +408,8 @@ class cygheap_pwdgrp
408408
NSS_SCHEME_UNIX,
409409
NSS_SCHEME_DESC,
410410
NSS_SCHEME_PATH,
411-
NSS_SCHEME_FREEATTR
411+
NSS_SCHEME_FREEATTR,
412+
NSS_SCHEME_ENV
412413
};
413414
struct nss_scheme_t {
414415
nss_scheme_method method;

winsup/cygwin/uinfo.cc

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,8 @@ cygheap_pwdgrp::nss_init_line (const char *line)
808808
scheme[idx].method = NSS_SCHEME_UNIX;
809809
else if (NSS_CMP ("desc"))
810810
scheme[idx].method = NSS_SCHEME_DESC;
811+
else if (NSS_CMP ("env"))
812+
scheme[idx].method = NSS_SCHEME_ENV;
811813
else if (NSS_NCMP ("/"))
812814
{
813815
const char *e = c + strcspn (c, " \t");
@@ -998,6 +1000,40 @@ fetch_from_path (cyg_ldap *pldap, PUSER_INFO_3 ui, cygpsid &sid, PCWSTR str,
9981000
return ret;
9991001
}
10001002

1003+
static size_t
1004+
fetch_env(LPCWSTR key, char *buf, size_t size)
1005+
{
1006+
WCHAR wbuf[32767];
1007+
DWORD max = sizeof wbuf / sizeof *wbuf;
1008+
DWORD len = GetEnvironmentVariableW (key, wbuf, max);
1009+
1010+
if (!len || len >= max)
1011+
return 0;
1012+
1013+
len = sys_wcstombs (buf, size, wbuf, len);
1014+
return len && len < size ? len : 0;
1015+
}
1016+
1017+
static char *
1018+
fetch_home_env (void)
1019+
{
1020+
char home[32767];
1021+
size_t max = sizeof home / sizeof *home, len;
1022+
1023+
if (fetch_env (L"HOME", home, max)
1024+
|| ((len = fetch_env (L"HOMEDRIVE", home, max))
1025+
&& fetch_env (L"HOMEPATH", home + len, max - len))
1026+
|| fetch_env (L"USERPROFILE", home, max))
1027+
{
1028+
tmp_pathbuf tp;
1029+
cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_ABSOLUTE,
1030+
home, tp.c_get(), NT_MAX_PATH);
1031+
return strdup(tp.c_get());
1032+
}
1033+
1034+
return NULL;
1035+
}
1036+
10011037
char *
10021038
cygheap_pwdgrp::get_home (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom,
10031039
PCWSTR dnsdomain, PCWSTR name, bool full_qualified)
@@ -1057,6 +1093,10 @@ cygheap_pwdgrp::get_home (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom,
10571093
}
10581094
}
10591095
break;
1096+
case NSS_SCHEME_ENV:
1097+
if (RtlEqualSid (sid, cygheap->user.sid ()))
1098+
home = fetch_home_env ();
1099+
break;
10601100
}
10611101
}
10621102
return home;
@@ -1070,6 +1110,8 @@ cygheap_pwdgrp::get_home (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
10701110

10711111
for (uint16_t idx = 0; !home && idx < NSS_SCHEME_MAX; ++idx)
10721112
{
1113+
if (!ui && home_scheme[idx].method != NSS_SCHEME_ENV)
1114+
continue;
10731115
switch (home_scheme[idx].method)
10741116
{
10751117
case NSS_SCHEME_FALLBACK:
@@ -1089,6 +1131,10 @@ cygheap_pwdgrp::get_home (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
10891131
home = fetch_from_path (NULL, ui, sid, home_scheme[idx].attrib,
10901132
dom, NULL, name, full_qualified);
10911133
break;
1134+
case NSS_SCHEME_ENV:
1135+
if (RtlEqualSid (sid, cygheap->user.sid ()))
1136+
home = fetch_home_env ();
1137+
break;
10921138
}
10931139
}
10941140
return home;
@@ -1108,6 +1154,7 @@ cygheap_pwdgrp::get_shell (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom,
11081154
case NSS_SCHEME_FALLBACK:
11091155
return NULL;
11101156
case NSS_SCHEME_WINDOWS:
1157+
case NSS_SCHEME_ENV:
11111158
break;
11121159
case NSS_SCHEME_CYGWIN:
11131160
if (pldap->fetch_ad_account (sid, false, dnsdomain))
@@ -1172,6 +1219,7 @@ cygheap_pwdgrp::get_shell (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
11721219
case NSS_SCHEME_CYGWIN:
11731220
case NSS_SCHEME_UNIX:
11741221
case NSS_SCHEME_FREEATTR:
1222+
case NSS_SCHEME_ENV:
11751223
break;
11761224
case NSS_SCHEME_DESC:
11771225
if (ui)
@@ -1253,6 +1301,8 @@ cygheap_pwdgrp::get_gecos (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom,
12531301
sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, val);
12541302
}
12551303
break;
1304+
case NSS_SCHEME_ENV:
1305+
break;
12561306
}
12571307
}
12581308
if (gecos)
@@ -1279,6 +1329,7 @@ cygheap_pwdgrp::get_gecos (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
12791329
case NSS_SCHEME_CYGWIN:
12801330
case NSS_SCHEME_UNIX:
12811331
case NSS_SCHEME_FREEATTR:
1332+
case NSS_SCHEME_ENV:
12821333
break;
12831334
case NSS_SCHEME_DESC:
12841335
if (ui)
@@ -2120,6 +2171,9 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
21202171
{
21212172
/* Just some fake. */
21222173
sid = csid.create (99, 1, 0);
2174+
if (arg.id == cygheap->user.real_uid)
2175+
home = cygheap->pg.get_home(NULL, cygheap->user.sid(),
2176+
NULL, NULL, false);
21232177
break;
21242178
}
21252179
else if (arg.id >= UNIX_POSIX_OFFSET)
@@ -2173,7 +2227,11 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
21732227
it to a well-known group here. */
21742228
if (acc_type == SidTypeUser
21752229
&& (sid_sub_auth_count (sid) <= 3 || sid_id_auth (sid) == 11))
2176-
acc_type = SidTypeWellKnownGroup;
2230+
{
2231+
acc_type = SidTypeWellKnownGroup;
2232+
home = cygheap->pg.get_home (pldap, sid, dom, domain, name,
2233+
fully_qualified_name);
2234+
}
21772235
switch (acc_type)
21782236
{
21792237
case SidTypeUser:
@@ -2645,10 +2703,11 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
26452703
logon. Unless it's the SYSTEM account. This conveniently allows to
26462704
logon interactively as SYSTEM for debugging purposes. */
26472705
else if (acc_type != SidTypeUser && sid != well_known_system_sid)
2648-
__small_sprintf (linebuf, "%W:*:%u:%u:U-%W\\%W,%s:/:/sbin/nologin",
2706+
__small_sprintf (linebuf, "%W:*:%u:%u:U-%W\\%W,%s:%s:/sbin/nologin",
26492707
posix_name, uid, gid,
26502708
dom, name,
2651-
sid.string ((char *) sidstr));
2709+
sid.string ((char *) sidstr),
2710+
home ? home : "/");
26522711
else
26532712
__small_sprintf (linebuf, "%W:*:%u:%u:%s%sU-%W\\%W,%s:%s%W:%s",
26542713
posix_name, uid, gid,

0 commit comments

Comments
 (0)