@@ -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+
10011037char *
10021038cygheap_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