@@ -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+
10121048char *
10131049cygheap_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