From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2155) id 386C13858D33; Tue, 6 Jun 2023 13:32:35 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 386C13858D33 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1686058355; bh=Msc/Z3kf16Zc7oAjIX09PfKrZJ2mQG/zl2azJMW3IMg=; h=From:To:Subject:Date:From; b=KTieKt7AfcqIbowDE9Gr+UrOodOBzJ8hnMUrVZ/5bQ1ddUFJzdsOKJhB90bboCof6 hTNguy7DRZjaDtXjwxPhjIa0kcLmvS+/FJwVJjRKfDZvFMWd2kuTapGmWQs5v5fVBC ZjjcEa5yZwuIZKVFGrc7l7NtGSidTLPI8R41Fdaw= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Corinna Vinschen To: cygwin-cvs@sourceware.org Subject: [newlib-cygwin/main] uinfo: special-case IIS APPPOOL accounts X-Act-Checkin: newlib-cygwin X-Git-Author: Johannes Schindelin X-Git-Refname: refs/heads/main X-Git-Oldrev: a9038789488e7cdac5a30898fc3b064782646108 X-Git-Newrev: e9dd5d8f2585293cb5fa0d86fc14e06156b65e19 Message-Id: <20230606133235.386C13858D33@sourceware.org> Date: Tue, 6 Jun 2023 13:32:35 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=3Dnewlib-cygwin.git;h=3De9dd5d8f258= 5293cb5fa0d86fc14e06156b65e19 commit e9dd5d8f2585293cb5fa0d86fc14e06156b65e19 Author: Johannes Schindelin AuthorDate: Mon May 22 13:12:56 2023 +0200 Commit: Corinna Vinschen CommitDate: Tue Jun 6 15:18:53 2023 +0200 uinfo: special-case IIS APPPOOL accounts =20 The account under which Azure Web Apps run is an IIS APPOOL account that is generated on the fly. =20 These are special because the virtual machines on which thes Apps run are not domain-joined, yet the accounts are domain accounts. =20 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. =20 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`). =20 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." =20 Since these IIS APPPOOL accounts are relatively similar to AzureAD accounts in this scenario, let's imitate the latter to support also the former. =20 Reported-by: David Ebbo Helped-by: Corinna Vinschen Signed-off-by: Johannes Schindelin Diff: --- 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 d493d29b3bd3..5e2d88bcd7ab 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -1485,9 +1485,9 @@ get_logon_sid () } } =20 -/* 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 tok= en + group list but *not* recognized by LookupAccountSid (ERROR_NONE_MAPPED)= . */ +static cygsid azure_grp_sid (""), iis_apppool_grp_sid (""); =20 static void get_azure_grp_sid () @@ -1515,6 +1515,36 @@ get_azure_grp_sid () } } =20 +static void +get_iis_apppool_grp_sid () +{ + if (PSID (iis_apppool_grp_sid) =3D=3D NO_SID) + { + NTSTATUS status; + ULONG size; + tmp_pathbuf tp; + PTOKEN_GROUPS groups =3D (PTOKEN_GROUPS) tp.w_get (); + + status =3D NtQueryInformationToken (hProcToken, TokenGroups, groups, + 2 * NT_MAX_PATH, &size); + if (!NT_SUCCESS (status)) + debug_printf ("NtQueryInformationToken (TokenGroups) %y", status); + else + { + for (DWORD pg =3D 0; pg < groups->GroupCount; ++pg) + { + PSID sid =3D groups->Groups[pg].Sid; + if (sid_id_auth (sid) =3D=3D 5 && + sid_sub_auth (sid, 0) =3D=3D SECURITY_APPPOOL_ID_BASE_RID) + { + iis_apppool_grp_sid =3D 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") =3D=3D 0) + { + get_iis_apppool_grp_sid (); + if (PSID (logon_sid) !=3D NO_SID) + { + sid =3D iis_apppool_grp_sid; + return true; + } + return false; + } if (!sep && wcscmp (name, L"CurrentSession") =3D=3D 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) =3D=3D 12) + /* AzureAD and IIS APPPOOL users must be prepended by "domain" + name. */ + if (sid_id_auth (sid) =3D=3D 12 || + (sid_id_auth (sid) =3D=3D 5 && + sid_sub_auth (sid, 0) =3D=3D 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) =3D=3D 12) + /* AzureAD and IIS APPPOOL accounts should be fully qualifed either. */ + if (sid_id_auth (sid) =3D=3D 12 || + (sid_id_auth (sid) =3D=3D 5 && + sid_sub_auth (sid, 0) =3D=3D 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 =3D csid =3D azure_grp_sid; break; } + else if (arg.id =3D=3D 0x1002) + { + /* IIS APPPOOL S-1-5-82-* user */ + csid =3D cygheap->user.saved_sid (); + } + else if (arg.id =3D=3D 0x1003) + { + /* Special IIS APPPOOL group SID */ + get_iis_apppool_grp_sid (); + /* LookupAccountSidW will fail. */ + sid =3D csid =3D iis_apppool_grp_sid; + break; + } else if (arg.id =3D=3D 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) =20 Those we let pass, but no others. */ bool its_ok =3D false; - if (sid_id_auth (sid) =3D=3D 12) + if (sid_id_auth (sid) =3D=3D 12 || + (sid_id_auth (sid) =3D=3D 5 && + sid_sub_auth (sid, 0) =3D=3D SECURITY_APPPOOL_ID_BASE_RID)) its_ok =3D true; else /* Microsoft Account */ { @@ -2342,7 +2402,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t = &arg, cyg_ldap *pldap) posix_offset =3D 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) =3D=3D 12) { uid =3D gid =3D 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) =3D=3D 5 && + sid_sub_auth (sid, 0) =3D=3D SECURITY_APPPOOL_ID_BASE_RID) + { + uid =3D 0x1002; + gid =3D 0x1003; + fully_qualified_name =3D true; + home =3D cygheap->pg.get_home ((PUSER_INFO_3) NULL, sid, dom, name, + fully_qualified_name); + shell =3D cygheap->pg.get_shell ((PUSER_INFO_3) NULL, sid, dom, + name, fully_qualified_name); + gecos =3D 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 =3D true; acc_type =3D SidTypeUnknown; } + else if (sid_id_auth (sid) =3D=3D 5 && + sid_sub_auth (sid, 0) =3D=3D 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 =3D gid =3D 0x1003; + wcpcpy (dom, L"IIS APPPOOL"); + wcpcpy (name =3D namebuf, L"Group"); + fully_qualified_name =3D true; + acc_type =3D SidTypeUnknown; + } else if (sid_id_auth (sid) =3D=3D 5 /* SECURITY_NT_AUTHORITY */ && sid_sub_auth (sid, 0) =3D=3D SECURITY_LOGON_IDS_RID) {