This is the mail archive of the cygwin-cvs@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[newlib-cygwin] Workaround AzureAD shortcomings


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=eb61113daf84bea95b81551b4c3826d4574c5688

commit eb61113daf84bea95b81551b4c3826d4574c5688
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Mon Aug 8 09:45:34 2016 +0200

    Workaround AzureAD shortcomings
    
    No real domain, no DC, no infos via NetUserGetInfo... nothing.  Just nothing.
    
    Use fixed uid 0x1000 (4096) for AzureAD user and gid 0x1001 (4097) for
    AzureAD group.  Note that this group is part of the user token, but it's
    not the primary group.  The primary group SID is, unfortunately, the
    user's SID.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/uinfo.cc | 100 ++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 90 insertions(+), 10 deletions(-)

diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc
index 77e8e8d..1a2a6aa 100644
--- a/winsup/cygwin/uinfo.cc
+++ b/winsup/cygwin/uinfo.cc
@@ -1082,7 +1082,8 @@ cygheap_pwdgrp::get_home (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
 	case NSS_SCHEME_FREEATTR:
 	  break;
 	case NSS_SCHEME_DESC:
-	  home = fetch_from_description (ui->usri3_comment, L"home=\"", 6);
+	  if (ui)
+	    home = fetch_from_description (ui->usri3_comment, L"home=\"", 6);
 	  break;
 	case NSS_SCHEME_PATH:
 	  home = fetch_from_path (NULL, ui, sid, home_scheme[idx].attrib,
@@ -1173,7 +1174,8 @@ cygheap_pwdgrp::get_shell (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
 	case NSS_SCHEME_FREEATTR:
 	  break;
 	case NSS_SCHEME_DESC:
-	  shell = fetch_from_description (ui->usri3_comment, L"shell=\"", 7);
+	  if (ui)
+	    shell = fetch_from_description (ui->usri3_comment, L"shell=\"", 7);
 	  break;
 	case NSS_SCHEME_PATH:
 	  shell = fetch_from_path (NULL, ui, sid, shell_scheme[idx].attrib,
@@ -1271,7 +1273,7 @@ cygheap_pwdgrp::get_gecos (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
 	case NSS_SCHEME_FALLBACK:
 	  return NULL;
 	case NSS_SCHEME_WINDOWS:
-	  if (ui->usri3_full_name && *ui->usri3_full_name)
+	  if (ui && ui->usri3_full_name && *ui->usri3_full_name)
 	    sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, ui->usri3_full_name);
 	  break;
 	case NSS_SCHEME_CYGWIN:
@@ -1279,7 +1281,8 @@ cygheap_pwdgrp::get_gecos (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
 	case NSS_SCHEME_FREEATTR:
 	  break;
 	case NSS_SCHEME_DESC:
-	  gecos = fetch_from_description (ui->usri3_comment, L"gecos=\"", 7);
+	  if (ui)
+	    gecos = fetch_from_description (ui->usri3_comment, L"gecos=\"", 7);
 	  break;
 	case NSS_SCHEME_PATH:
 	  gecos = fetch_from_path (NULL, ui, sid, gecos_scheme[idx].attrib + 1,
@@ -1508,6 +1511,36 @@ 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 ("");
+
+static void
+get_azure_grp_sid ()
+{
+  if (PSID (azure_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)
+	    if (sid_id_auth (groups->Groups[pg].Sid) == 12)
+	      {
+		azure_grp_sid = groups->Groups[pg].Sid;
+		break;
+	      }
+	}
+    }
+}
+
 void *
 pwdgrp::add_account_post_fetch (char *line, bool lock)
 {
@@ -1911,6 +1944,9 @@ 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)
+	    return NULL;
 	  /* name_only only if db_prefix is auto. */
 	  if (!cygheap->pg.nss_prefix_auto ())
 	    {
@@ -1945,6 +1981,9 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
 	  /* All is well if db_prefix is always. */
 	  if (cygheap->pg.nss_prefix_always ())
 	    break;
+	  /* AzureAD accounts should be fully qualifed either. */
+	  if (sid_id_auth (sid) == 12)
+	    break;
 	  /* Otherwise, no fully_qualified for builtin accounts, except for
 	     NT SERVICE, for which we require the prefix.  Note that there's
 	     no equivalent test in the `if (!fq_name)' branch above, because
@@ -2012,6 +2051,19 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
 	  sid = logon_sid;
 	  break;
 	}
+      else if (arg.id == 0x1000)
+        {
+	  /* AzureAD S-1-12-1-W-X-Y-Z user */
+	  csid = cygheap->user.saved_sid ();
+	}
+      else if (arg.id == 0x1001)
+        {
+	  /* Special AzureAD group SID */
+	  get_azure_grp_sid ();
+	  /* LookupAccountSidW will fail. */
+	  sid = csid = azure_grp_sid;
+	  break;
+	}
       else if (arg.id == 0xfffe)
 	{
 	  /* Special case "nobody" for reproducible construction of a
@@ -2130,13 +2182,15 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
 	      /* Don't allow users as group.  While this is technically
 		 possible, it doesn't make sense in a POSIX scenario.
 	 
-		 And then there are the so-called Microsoft Accounts.  The
-		 special SID with security authority 11 is converted to a
-		 well known group above, but additionally, when logging in
-		 with such an account, the user's primary group SID is the
-		 user's SID.  Those we let pass, but no others. */
+		 Microsoft Accounts as well as AzureAD accounts have the
+		 primary group SID in their user token set to their own
+		 user SID.
+
+		 Those we let pass, but no others. */
 	      bool its_ok = false;
-	      if (wincap.has_microsoft_accounts ())
+	      if (sid_id_auth (sid) == 12)
+		its_ok = true;
+	      else if (wincap.has_microsoft_accounts ())
 		{
 		  struct cyg_USER_INFO_24 *ui24;
 		  if (NetUserGetInfo (NULL, name, 24, (PBYTE *) &ui24)
@@ -2227,6 +2281,19 @@ 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 */
+	  else if (sid_id_auth (sid) == 12)
+	    {
+	      uid = gid = 0x1000;
+	      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. */
@@ -2456,6 +2523,19 @@ 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) == 12 && sid_sub_auth (sid, 0) == 1)
+    {
+      /* Special AzureAD 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 = 0x1001;
+      wcpcpy (dom, L"AzureAD");
+      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)
     {


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]