[PATCH v5 3/3] Respect `db_home: env` even when no uid can be determined

Johannes Schindelin johannes.schindelin@gmx.de
Mon Apr 3 14:45:11 GMT 2023


When we cannot figure out a uid for the current user, we should still
respect the `db_home: env` setting.

This is particularly important when programs like `ssh` look for the
home directory of the usr, the user overrode `HOME` to "help" Cygwin
determine where the home directory is. Cygwin should not ignore this.

One situation where we cannot determine a uid is when the domain
returned by `LookupAccountSid()` is not our machine name and at the same
time our machine is no domain member: In that case, we have nobody to
ask for the POSIX offset necessary to come up with the uid.

Azure Web Apps represent such a scenario, which can be verified e.g. in
a Kudu console (for details about Kudu consoles, see
https://github.com/projectkudu/kudu/wiki/Kudu-console): the domain is
`IIS APPPOOL`, the account name is the name of the Azure Web App, the
SID starts with 'S-1-5-82-`, and `pwdgrp::fetch_account_from_windows()`
runs into the code path where "[...] the domain returned by
LookupAccountSid is not our machine name, and if our machine is no
domain member, we lose.  We have nobody to ask for the POSIX offset."

In such a scenario, OpenSSH's `getuid()` call will receive the return
value -1, and the subsequent `getpwuid()` call (whose return value's
`pw_dir` is used as home directory) needs to be forced to respect
`db_home: env`, which this here patch does.

Reported-by: David Ebbo <david.ebbo@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 winsup/cygwin/uinfo.cc | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc
index d493d29b3b..b01bcff5cb 100644
--- a/winsup/cygwin/uinfo.cc
+++ b/winsup/cygwin/uinfo.cc
@@ -883,6 +883,8 @@ fetch_from_path (cyg_ldap *pldap, PUSER_INFO_3 ui, cygpsid &sid, PCWSTR str,
 	    case L'u':
 	      if (full_qualified)
 		{
+		  if (!dom)
+		    break;
 		  w = wcpncpy (w, dom, we - w);
 		  if (w < we)
 		    *w++ = NSS_SEPARATOR_CHAR;
@@ -893,6 +895,8 @@ fetch_from_path (cyg_ldap *pldap, PUSER_INFO_3 ui, cygpsid &sid, PCWSTR str,
 	      w = wcpncpy (w, name, we - w);
 	      break;
 	    case L'D':
+	      if (!dom)
+		break;
 	      w = wcpncpy (w, dom, we - w);
 	      break;
 	    case L'H':
@@ -2181,6 +2185,10 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
 	{
 	  /* Just some fake. */
 	  sid = csid.create (99, 1, 0);
+	  if (arg.id == cygheap->user.real_uid)
+	    home = cygheap->pg.get_home ((PUSER_INFO_3) NULL,
+					 cygheap->user.sid(),
+					 NULL, NULL, false);
 	  break;
 	}
       else if (arg.id >= UNIX_POSIX_OFFSET)
@@ -2710,10 +2718,11 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
      logon.  Unless it's the SYSTEM account.  This conveniently allows to
      logon interactively as SYSTEM for debugging purposes. */
   else if (acc_type != SidTypeUser && sid != well_known_system_sid)
-    __small_sprintf (linebuf, "%W:*:%u:%u:U-%W\\%W,%s:/:/sbin/nologin",
+    __small_sprintf (linebuf, "%W:*:%u:%u:U-%W\\%W,%s:%s:/sbin/nologin",
 		     posix_name, uid, gid,
 		     dom, name,
-		     sid.string ((char *) sidstr));
+		     sid.string ((char *) sidstr),
+		     home ? home : "/");
   else
     __small_sprintf (linebuf, "%W:*:%u:%u:%s%sU-%W\\%W,%s:%s%W:%s",
 		     posix_name, uid, gid,
--
2.40.0.windows.1


More information about the Cygwin-patches mailing list