public inbox for cygwin-patches@cygwin.com
 help / color / mirror / Atom feed
From: Johannes Schindelin <johannes.schindelin@gmx.de>
To: cygwin-patches@cygwin.com
Subject: [PATCH v6 3/4] uinfo: special-case IIS APPPOOL accounts
Date: Tue, 4 Apr 2023 17:07:54 +0200 (CEST)	[thread overview]
Message-ID: <9b79624368e13aef1e71eaee17c422df794ebe5d.1680620830.git.johannes.schindelin@gmx.de> (raw)
In-Reply-To: <cover.1680620830.git.johannes.schindelin@gmx.de>

The account under which Azure Web Apps run is an IIS APPOOL account that
is generated on the fly.

These are special because the virtual machines on which thes Apps run
are not domain-joined, yet the accounts are domain accounts.

To support the use case where such a Web App needs to call `ssh` (e.g.
to deploy from a Git repository that is accessible only via SSH), we do
need OpenSSH's `getpwuid (getuid ())` invocation to work.

But currently it does not. Concretely, `getuid ()` returns -1 for these
accounts, and OpenSSH fails to find the correct home directory
(_especially_ when that home directory was overridden via a `db_home:
env` line in `/etc/nsswitch.conf`).

This 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."

Since these IIS APPPOOL accounts are relatively similar to AzureAD
accounts in this scenario, let's imitate the latter to support also the
former.

Reported-by: David Ebbo <david.ebbo@gmail.com>
Helped-by: Corinna Vinschen <corinna@vinschen.de>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 winsup/cygwin/uinfo.cc | 107 +++++++++++++++++++++++++++++++++++++----
 1 file changed, 98 insertions(+), 9 deletions(-)

diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc
index d493d29b3b..5e2d88bcd7 100644
--- a/winsup/cygwin/uinfo.cc
+++ b/winsup/cygwin/uinfo.cc
@@ -1485,9 +1485,9 @@ get_logon_sid ()
     }
 }

-/* Fetch special AzureAD group, which is part of the token group list but
-   *not* recognized by LookupAccountSid (ERROR_NONE_MAPPED). */
-static cygsid azure_grp_sid ("");
+/* Fetch special AzureAD and IIS APPPOOL groups, which are part of the token
+   group list but *not* recognized by LookupAccountSid (ERROR_NONE_MAPPED). */
+static cygsid azure_grp_sid (""), iis_apppool_grp_sid ("");

 static void
 get_azure_grp_sid ()
@@ -1515,6 +1515,36 @@ get_azure_grp_sid ()
     }
 }

+static void
+get_iis_apppool_grp_sid ()
+{
+  if (PSID (iis_apppool_grp_sid) == NO_SID)
+    {
+      NTSTATUS status;
+      ULONG size;
+      tmp_pathbuf tp;
+      PTOKEN_GROUPS groups = (PTOKEN_GROUPS) tp.w_get ();
+
+      status = NtQueryInformationToken (hProcToken, TokenGroups, groups,
+					2 * NT_MAX_PATH, &size);
+      if (!NT_SUCCESS (status))
+	debug_printf ("NtQueryInformationToken (TokenGroups) %y", status);
+      else
+	{
+	  for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
+	    {
+	      PSID sid = groups->Groups[pg].Sid;
+	      if (sid_id_auth (sid) == 5 &&
+		  sid_sub_auth (sid, 0) == SECURITY_APPPOOL_ID_BASE_RID)
+		{
+		  iis_apppool_grp_sid = sid;
+		  break;
+		}
+	    }
+	}
+    }
+}
+
 void *
 pwdgrp::add_account_post_fetch (char *line, bool lock)
 {
@@ -1796,6 +1826,16 @@ pwdgrp::construct_sid_from_name (cygsid &sid, wchar_t *name, wchar_t *sep)
 	}
       return false;
     }
+  if (sep && wcscmp (name, L"IIS APPPOOL\\Group") == 0)
+    {
+      get_iis_apppool_grp_sid ();
+      if (PSID (logon_sid) != NO_SID)
+	{
+	  sid = iis_apppool_grp_sid;
+	  return true;
+	}
+      return false;
+    }
   if (!sep && wcscmp (name, L"CurrentSession") == 0)
     {
       get_logon_sid ();
@@ -2018,8 +2058,11 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
       /* Last but not least, some validity checks on the name style. */
       if (!fq_name)
 	{
-	  /* AzureAD user must be prepended by "domain" name. */
-	  if (sid_id_auth (sid) == 12)
+	  /* AzureAD and IIS APPPOOL users must be prepended by "domain"
+	     name. */
+	  if (sid_id_auth (sid) == 12 ||
+	      (sid_id_auth (sid) == 5 &&
+	       sid_sub_auth (sid, 0) == SECURITY_APPPOOL_ID_BASE_RID))
 	    return NULL;
 	  /* name_only account is either builtin or primary domain, or
 	     account domain on non-domain machines. */
@@ -2045,8 +2088,10 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
 	}
       else
 	{
-	  /* AzureAD accounts should be fully qualifed either. */
-	  if (sid_id_auth (sid) == 12)
+	  /* AzureAD and IIS APPPOOL accounts should be fully qualifed either. */
+	  if (sid_id_auth (sid) == 12 ||
+	      (sid_id_auth (sid) == 5 &&
+	       sid_sub_auth (sid, 0) == SECURITY_APPPOOL_ID_BASE_RID))
 	    break;
 	  /* Otherwise, no fully_qualified for builtin accounts, except for
 	     NT SERVICE, for which we require the prefix.  Note that there's
@@ -2125,6 +2170,19 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
 	  sid = csid = azure_grp_sid;
 	  break;
 	}
+      else if (arg.id == 0x1002)
+        {
+	  /* IIS APPPOOL S-1-5-82-* user */
+	  csid = cygheap->user.saved_sid ();
+	}
+      else if (arg.id == 0x1003)
+        {
+	  /* Special IIS APPPOOL group SID */
+	  get_iis_apppool_grp_sid ();
+	  /* LookupAccountSidW will fail. */
+	  sid = csid = iis_apppool_grp_sid;
+	  break;
+	}
       else if (arg.id == 0xfffe)
 	{
 	  /* Special case "nobody" for reproducible construction of a
@@ -2253,7 +2311,9 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)

 		 Those we let pass, but no others. */
 	      bool its_ok = false;
-	      if (sid_id_auth (sid) == 12)
+	      if (sid_id_auth (sid) == 12 ||
+		  (sid_id_auth (sid) == 5 &&
+		   sid_sub_auth (sid, 0) == SECURITY_APPPOOL_ID_BASE_RID))
 		its_ok = true;
 	      else /* Microsoft Account */
 		{
@@ -2342,7 +2402,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
 		    posix_offset = fetch_posix_offset (td, &loc_ldap);
 		}
 	    }
-	  /* AzureAD S-1-12-1-W-X-Y-Z user */
+	  /* AzureAD S-1-12-1-W-X-Y-Z and IIS APPOOL S-1-5-82-* user */
 	  else if (sid_id_auth (sid) == 12)
 	    {
 	      uid = gid = 0x1000;
@@ -2355,6 +2415,21 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
 					     name, fully_qualified_name);
 	      break;
 	    }
+	  /* IIS APPOOL S-1-5-82-* user */
+	  else if (sid_id_auth (sid) == 5 &&
+		   sid_sub_auth (sid, 0) == SECURITY_APPPOOL_ID_BASE_RID)
+	    {
+	      uid = 0x1002;
+	      gid = 0x1003;
+	      fully_qualified_name = true;
+	      home = cygheap->pg.get_home ((PUSER_INFO_3) NULL, sid, dom, name,
+					   fully_qualified_name);
+	      shell = cygheap->pg.get_shell ((PUSER_INFO_3) NULL, sid, dom,
+					     name, fully_qualified_name);
+	      gecos = cygheap->pg.get_gecos ((PUSER_INFO_3) NULL, sid, dom,
+					     name, fully_qualified_name);
+	      break;
+	    }
 	  /* If 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. */
@@ -2614,6 +2689,20 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
       fully_qualified_name = true;
       acc_type = SidTypeUnknown;
     }
+  else if (sid_id_auth (sid) == 5 &&
+	   sid_sub_auth (sid, 0) == SECURITY_APPPOOL_ID_BASE_RID)
+    {
+      /* Special IIS APPPOOL group SID which can't be resolved by
+         LookupAccountSid (ERROR_NONE_MAPPED).  This is only allowed
+	 as group entry, not as passwd entry. */
+      if (is_passwd ())
+	return NULL;
+      uid = gid = 0x1003;
+      wcpcpy (dom, L"IIS APPPOOL");
+      wcpcpy (name = namebuf, L"Group");
+      fully_qualified_name = true;
+      acc_type = SidTypeUnknown;
+    }
   else if (sid_id_auth (sid) == 5 /* SECURITY_NT_AUTHORITY */
 	   && sid_sub_auth (sid, 0) == SECURITY_LOGON_IDS_RID)
     {
--
2.40.0.windows.1



  parent reply	other threads:[~2023-04-04 15:07 UTC|newest]

Thread overview: 69+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-16 13:06 [PATCH] Allow overriding the home directory via the HOME variable Johannes Schindelin
2015-10-21 18:32 ` Corinna Vinschen
2015-10-22 15:38   ` Johannes Schindelin
2015-10-23  9:10     ` Corinna Vinschen
2015-10-23  9:41       ` Corinna Vinschen
2015-10-23 12:00         ` Johannes Schindelin
2015-12-17 18:05 ` [PATCH v2 0/2] Support deriving the current user's home directory via HOME Johannes Schindelin
2015-12-17 18:05   ` [PATCH v2 1/2] Allow deriving the current user's home directory via the HOME variable Johannes Schindelin
2015-12-17 20:20     ` Corinna Vinschen
2022-09-21 11:58       ` Johannes Schindelin
2022-10-18 17:02         ` Corinna Vinschen
2022-10-23 21:04           ` Johannes Schindelin
2022-10-24 11:37             ` Corinna Vinschen
2022-11-10 15:16               ` Johannes Schindelin
2022-11-10 15:22                 ` Corinna Vinschen
2022-11-18  8:18                   ` Johannes Schindelin
2022-11-21 11:41                     ` Corinna Vinschen
2023-03-28  8:21                       ` Johannes Schindelin
2015-12-17 18:05   ` [PATCH v2 2/2] Respect `db_home` setting even for the SYSTEM account Johannes Schindelin
2015-12-17 20:49     ` Corinna Vinschen
2015-12-17 21:02       ` Corinna Vinschen
2022-09-21 12:00       ` Johannes Schindelin
2022-09-21 11:51   ` [PATCH v3 0/3] Support deriving the current user's home directory via HOME Johannes Schindelin
2022-09-21 11:51     ` [PATCH v3 1/3] Allow deriving the current user's home directory via the HOME variable Johannes Schindelin
2022-09-21 11:52     ` [PATCH v3 2/3] Respect `db_home` setting even for SYSTEM/Microsoft accounts Johannes Schindelin
2022-09-21 11:52     ` [PATCH v3 3/3] Respect `db_home: env` even when no uid can be determined Johannes Schindelin
2023-03-28  8:17     ` [PATCH v4 0/3] Support deriving the current user's home directory via HOME Johannes Schindelin
2023-03-28  8:17       ` [PATCH v4 1/3] Allow deriving the current user's home directory via the HOME variable Johannes Schindelin
2023-03-28 10:35         ` Corinna Vinschen
2023-03-28 12:34           ` Jon Turney
2023-03-28 13:31             ` Corinna Vinschen
2023-03-29  8:36               ` Corinna Vinschen
2023-04-03  6:39                 ` Johannes Schindelin
2023-03-28  8:17       ` [PATCH v4 2/3] Respect `db_home` setting even for SYSTEM/Microsoft accounts Johannes Schindelin
2023-03-28 10:16         ` Corinna Vinschen
2023-04-03  6:36           ` Johannes Schindelin
2023-04-03 10:59             ` Corinna Vinschen
2023-04-03 13:32               ` Johannes Schindelin
2023-03-28  8:17       ` [PATCH v4 3/3] Respect `db_home: env` even when no uid can be determined Johannes Schindelin
2023-03-28 10:17         ` Corinna Vinschen
2023-04-03  6:45           ` Johannes Schindelin
2023-04-03 13:12             ` Johannes Schindelin
2023-04-03 13:29               ` Corinna Vinschen
2023-04-03 13:57                 ` Johannes Schindelin
2023-04-03 19:23                   ` Corinna Vinschen
2023-04-04 15:11                     ` Johannes Schindelin
2023-04-03 13:19             ` Johannes Schindelin
2023-04-03 14:44       ` [PATCH v5 0/3] Support deriving the current user's home directory via HOME Johannes Schindelin
2023-04-03 14:44         ` [PATCH v5 1/3] Allow deriving the current user's home directory via the HOME variable Johannes Schindelin
2023-04-03 18:36           ` Corinna Vinschen
2023-04-04 15:12             ` Johannes Schindelin
2023-04-03 14:45         ` [PATCH v5 2/3] Respect `db_home` setting even for SYSTEM/Microsoft accounts Johannes Schindelin
2023-04-03 18:37           ` Corinna Vinschen
2023-04-04 15:12             ` Johannes Schindelin
2023-04-03 14:45         ` [PATCH v5 3/3] Respect `db_home: env` even when no uid can be determined Johannes Schindelin
2023-04-04 15:07         ` [PATCH v6 0/4] Support deriving the current user's home directory via HOME Johannes Schindelin
2023-04-04 15:07           ` [PATCH v6 1/4] Allow deriving the current user's home directory via the HOME variable Johannes Schindelin
2023-04-04 15:07           ` [PATCH v6 2/4] Respect `db_home` setting even for SYSTEM/Microsoft accounts Johannes Schindelin
2023-04-04 15:07           ` Johannes Schindelin [this message]
2023-04-04 15:07           ` [PATCH v6 4/4] Do not rely on `getenv ("HOME")`'s path conversion Johannes Schindelin
2023-04-06  8:37             ` Corinna Vinschen
2023-04-06  9:54               ` Johannes Schindelin
2023-04-06 10:28                 ` Corinna Vinschen
2023-05-22 11:12           ` [PATCH v7 0/4] Support deriving the current user's home directory via HOME Johannes Schindelin
2023-05-22 11:12             ` [PATCH v7 1/4] Allow deriving the current user's home directory via the HOME variable Johannes Schindelin
2023-05-22 11:12             ` [PATCH v7 2/4] Respect `db_home` setting even for SYSTEM/Microsoft accounts Johannes Schindelin
2023-05-22 11:12             ` [PATCH v7 3/4] uinfo: special-case IIS APPPOOL accounts Johannes Schindelin
2023-05-22 11:13             ` [PATCH v7 4/4] Do not rely on `getenv ("HOME")`'s path conversion Johannes Schindelin
2023-06-06 13:33             ` [PATCH v7 0/4] Support deriving the current user's home directory via HOME Corinna Vinschen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=9b79624368e13aef1e71eaee17c422df794ebe5d.1680620830.git.johannes.schindelin@gmx.de \
    --to=johannes.schindelin@gmx.de \
    --cc=cygwin-patches@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).