@@ -780,6 +780,8 @@ cygheap_pwdgrp::nss_init_line (const char *line)
780
780
scheme[idx].method = NSS_SCHEME_UNIX;
781
781
else if (NSS_CMP (" desc" ))
782
782
scheme[idx].method = NSS_SCHEME_DESC;
783
+ else if (NSS_CMP (" env" ))
784
+ scheme[idx].method = NSS_SCHEME_ENV;
783
785
else if (NSS_NCMP (" /" ))
784
786
{
785
787
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,
970
972
return ret;
971
973
}
972
974
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
+
973
1009
char *
974
1010
cygheap_pwdgrp::get_home (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom,
975
1011
PCWSTR dnsdomain, PCWSTR name, bool full_qualified)
@@ -1029,6 +1065,10 @@ cygheap_pwdgrp::get_home (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom,
1029
1065
}
1030
1066
}
1031
1067
break ;
1068
+ case NSS_SCHEME_ENV:
1069
+ if (RtlEqualSid (sid, cygheap->user .sid ()))
1070
+ home = fetch_home_env ();
1071
+ break ;
1032
1072
}
1033
1073
}
1034
1074
return home;
@@ -1042,6 +1082,8 @@ cygheap_pwdgrp::get_home (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
1042
1082
1043
1083
for (uint16_t idx = 0 ; !home && idx < NSS_SCHEME_MAX; ++idx)
1044
1084
{
1085
+ if (!ui && home_scheme[idx].method != NSS_SCHEME_ENV)
1086
+ continue ;
1045
1087
switch (home_scheme[idx].method )
1046
1088
{
1047
1089
case NSS_SCHEME_FALLBACK:
@@ -1060,6 +1102,10 @@ cygheap_pwdgrp::get_home (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
1060
1102
home = fetch_from_path (NULL , ui, sid, home_scheme[idx].attrib ,
1061
1103
dom, NULL , name, full_qualified);
1062
1104
break ;
1105
+ case NSS_SCHEME_ENV:
1106
+ if (RtlEqualSid (sid, cygheap->user .sid ()))
1107
+ home = fetch_home_env ();
1108
+ break ;
1063
1109
}
1064
1110
}
1065
1111
return home;
@@ -1079,6 +1125,7 @@ cygheap_pwdgrp::get_shell (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom,
1079
1125
case NSS_SCHEME_FALLBACK:
1080
1126
return NULL ;
1081
1127
case NSS_SCHEME_WINDOWS:
1128
+ case NSS_SCHEME_ENV:
1082
1129
break ;
1083
1130
case NSS_SCHEME_CYGWIN:
1084
1131
if (pldap->fetch_ad_account (sid, false , dnsdomain))
@@ -1143,6 +1190,7 @@ cygheap_pwdgrp::get_shell (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
1143
1190
case NSS_SCHEME_CYGWIN:
1144
1191
case NSS_SCHEME_UNIX:
1145
1192
case NSS_SCHEME_FREEATTR:
1193
+ case NSS_SCHEME_ENV:
1146
1194
break ;
1147
1195
case NSS_SCHEME_DESC:
1148
1196
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,
1223
1271
sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, val);
1224
1272
}
1225
1273
break ;
1274
+ case NSS_SCHEME_ENV:
1275
+ break ;
1226
1276
}
1227
1277
}
1228
1278
if (gecos)
@@ -1249,6 +1299,7 @@ cygheap_pwdgrp::get_gecos (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
1249
1299
case NSS_SCHEME_CYGWIN:
1250
1300
case NSS_SCHEME_UNIX:
1251
1301
case NSS_SCHEME_FREEATTR:
1302
+ case NSS_SCHEME_ENV:
1252
1303
break ;
1253
1304
case NSS_SCHEME_DESC:
1254
1305
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)
2023
2074
{
2024
2075
/* Just some fake. */
2025
2076
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 );
2026
2080
break ;
2027
2081
}
2028
2082
else if (arg.id >= UNIX_POSIX_OFFSET)
@@ -2076,7 +2130,11 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
2076
2130
it to a well-known group here. */
2077
2131
if (acc_type == SidTypeUser
2078
2132
&& (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
+ }
2080
2138
switch (acc_type)
2081
2139
{
2082
2140
case SidTypeUser:
@@ -2509,10 +2567,11 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
2509
2567
logon. Unless it's the SYSTEM account. This conveniently allows to
2510
2568
logon interactively as SYSTEM for debugging purposes. */
2511
2569
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" ,
2513
2571
posix_name, uid, gid,
2514
2572
dom, name,
2515
- sid.string ((char *) sidstr));
2573
+ sid.string ((char *) sidstr),
2574
+ home ? home : " /" );
2516
2575
else
2517
2576
__small_sprintf (linebuf, " %W:*:%u:%u:%s%sU-%W\\ %W,%s:%s%W:%s" ,
2518
2577
posix_name, uid, gid,
0 commit comments