@@ -808,6 +808,8 @@ cygheap_pwdgrp::nss_init_line (const char *line)
808
808
scheme[idx].method = NSS_SCHEME_UNIX;
809
809
else if (NSS_CMP (" desc" ))
810
810
scheme[idx].method = NSS_SCHEME_DESC;
811
+ else if (NSS_CMP (" env" ))
812
+ scheme[idx].method = NSS_SCHEME_ENV;
811
813
else if (NSS_NCMP (" /" ))
812
814
{
813
815
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,
998
1000
return ret;
999
1001
}
1000
1002
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
+
1001
1037
char *
1002
1038
cygheap_pwdgrp::get_home (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom,
1003
1039
PCWSTR dnsdomain, PCWSTR name, bool full_qualified)
@@ -1057,6 +1093,10 @@ cygheap_pwdgrp::get_home (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom,
1057
1093
}
1058
1094
}
1059
1095
break ;
1096
+ case NSS_SCHEME_ENV:
1097
+ if (RtlEqualSid (sid, cygheap->user .sid ()))
1098
+ home = fetch_home_env ();
1099
+ break ;
1060
1100
}
1061
1101
}
1062
1102
return home;
@@ -1070,6 +1110,8 @@ cygheap_pwdgrp::get_home (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
1070
1110
1071
1111
for (uint16_t idx = 0 ; !home && idx < NSS_SCHEME_MAX; ++idx)
1072
1112
{
1113
+ if (!ui && home_scheme[idx].method != NSS_SCHEME_ENV)
1114
+ continue ;
1073
1115
switch (home_scheme[idx].method )
1074
1116
{
1075
1117
case NSS_SCHEME_FALLBACK:
@@ -1089,6 +1131,10 @@ cygheap_pwdgrp::get_home (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
1089
1131
home = fetch_from_path (NULL , ui, sid, home_scheme[idx].attrib ,
1090
1132
dom, NULL , name, full_qualified);
1091
1133
break ;
1134
+ case NSS_SCHEME_ENV:
1135
+ if (RtlEqualSid (sid, cygheap->user .sid ()))
1136
+ home = fetch_home_env ();
1137
+ break ;
1092
1138
}
1093
1139
}
1094
1140
return home;
@@ -1108,6 +1154,7 @@ cygheap_pwdgrp::get_shell (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom,
1108
1154
case NSS_SCHEME_FALLBACK:
1109
1155
return NULL ;
1110
1156
case NSS_SCHEME_WINDOWS:
1157
+ case NSS_SCHEME_ENV:
1111
1158
break ;
1112
1159
case NSS_SCHEME_CYGWIN:
1113
1160
if (pldap->fetch_ad_account (sid, false , dnsdomain))
@@ -1172,6 +1219,7 @@ cygheap_pwdgrp::get_shell (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
1172
1219
case NSS_SCHEME_CYGWIN:
1173
1220
case NSS_SCHEME_UNIX:
1174
1221
case NSS_SCHEME_FREEATTR:
1222
+ case NSS_SCHEME_ENV:
1175
1223
break ;
1176
1224
case NSS_SCHEME_DESC:
1177
1225
if (ui)
@@ -1253,6 +1301,8 @@ cygheap_pwdgrp::get_gecos (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom,
1253
1301
sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, val);
1254
1302
}
1255
1303
break ;
1304
+ case NSS_SCHEME_ENV:
1305
+ break ;
1256
1306
}
1257
1307
}
1258
1308
if (gecos)
@@ -1279,6 +1329,7 @@ cygheap_pwdgrp::get_gecos (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
1279
1329
case NSS_SCHEME_CYGWIN:
1280
1330
case NSS_SCHEME_UNIX:
1281
1331
case NSS_SCHEME_FREEATTR:
1332
+ case NSS_SCHEME_ENV:
1282
1333
break ;
1283
1334
case NSS_SCHEME_DESC:
1284
1335
if (ui)
@@ -2120,6 +2171,9 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
2120
2171
{
2121
2172
/* Just some fake. */
2122
2173
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 );
2123
2177
break ;
2124
2178
}
2125
2179
else if (arg.id >= UNIX_POSIX_OFFSET)
@@ -2173,7 +2227,11 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
2173
2227
it to a well-known group here. */
2174
2228
if (acc_type == SidTypeUser
2175
2229
&& (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
+ }
2177
2235
switch (acc_type)
2178
2236
{
2179
2237
case SidTypeUser:
@@ -2645,10 +2703,11 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
2645
2703
logon. Unless it's the SYSTEM account. This conveniently allows to
2646
2704
logon interactively as SYSTEM for debugging purposes. */
2647
2705
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" ,
2649
2707
posix_name, uid, gid,
2650
2708
dom, name,
2651
- sid.string ((char *) sidstr));
2709
+ sid.string ((char *) sidstr),
2710
+ home ? home : " /" );
2652
2711
else
2653
2712
__small_sprintf (linebuf, " %W:*:%u:%u:%s%sU-%W\\ %W,%s:%s%W:%s" ,
2654
2713
posix_name, uid, gid,
0 commit comments