OSDN Git Service

* sec_auth.cc (get_token_group_sidlist): Add CONSOLE LOGON SID on
authorcorinna <corinna>
Sat, 15 Oct 2011 16:31:55 +0000 (16:31 +0000)
committercorinna <corinna>
Sat, 15 Oct 2011 16:31:55 +0000 (16:31 +0000)
systems supporting it.  Never add SERVICE SID but keep code in for
future reference.  Explain why.
(get_priv_list): Add cygpsid pointer parameter.  Point it to the
mandatory integrity SID which matches account and privileges.
(create_token): Fetch mandatory integrity SID from call to
get_priv_list.
(lsaauth): Call get_priv_list with additional NULL pointer.  Change
comment accordingly.
* sec_helper.cc (well_known_console_logon_sid): New static SID.
(cygpriv): Change to structure containing extra flag to store info
about required integrity level.
(privilege_luid): Accommodate changes to cygpriv.  Return integrity
level in new high_integrity parameter.
(privilege_name): Accommodate changes to cygpriv.
(set_privilege): Drop trailing \n from debug output.
(set_cygwin_privileges): Don't set SE_CREATE_GLOBAL_PRIVILEGE anymore
since it's just not needed, but keep code in for future reference.
Change comment accordingly.
* security.h (well_known_console_logon_sid): Declare.
(privilege_luid): Align declaration to above change.
* wincap.h (wincaps::has_console_logon_sid): New element.
* wincap.cc: Implement above element throughout.

winsup/cygwin/ChangeLog
winsup/cygwin/sec_auth.cc
winsup/cygwin/sec_helper.cc
winsup/cygwin/security.h
winsup/cygwin/wincap.cc
winsup/cygwin/wincap.h

index afd6fde..d715b51 100644 (file)
@@ -1,3 +1,29 @@
+2011-10-15  Corinna Vinschen  <corinna@vinschen.de>
+
+       * sec_auth.cc (get_token_group_sidlist): Add CONSOLE LOGON SID on
+       systems supporting it.  Never add SERVICE SID but keep code in for
+       future reference.  Explain why.
+       (get_priv_list): Add cygpsid pointer parameter.  Point it to the
+       mandatory integrity SID which matches account and privileges.
+       (create_token): Fetch mandatory integrity SID from call to
+       get_priv_list.
+       (lsaauth): Call get_priv_list with additional NULL pointer.  Change
+       comment accordingly.
+       * sec_helper.cc (well_known_console_logon_sid): New static SID.
+       (cygpriv): Change to structure containing extra flag to store info
+       about required integrity level.
+       (privilege_luid): Accommodate changes to cygpriv.  Return integrity
+       level in new high_integrity parameter.
+       (privilege_name): Accommodate changes to cygpriv.
+       (set_privilege): Drop trailing \n from debug output.
+       (set_cygwin_privileges): Don't set SE_CREATE_GLOBAL_PRIVILEGE anymore
+       since it's just not needed, but keep code in for future reference.
+       Change comment accordingly.
+       * security.h (well_known_console_logon_sid): Declare.
+       (privilege_luid): Align declaration to above change.
+       * wincap.h (wincaps::has_console_logon_sid): New element.
+       * wincap.cc: Implement above element throughout.
+
 2011-10-13  Corinna Vinschen  <corinna@vinschen.de>
 
        * path.cc (find_fast_cwd_pointer): Allow 'push crit-sect-addr' instead
index 6fc3f5a..545f7d3 100644 (file)
@@ -416,6 +416,8 @@ get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps,
   if (my_grps)
     {
       grp_list += well_known_local_sid;
+      if (wincap.has_console_logon_sid ())
+       grp_list += well_known_console_logon_sid;
       if (sid_in_token_groups (my_grps, well_known_dialup_sid))
        grp_list *= well_known_dialup_sid;
       if (sid_in_token_groups (my_grps, well_known_network_sid))
@@ -423,8 +425,15 @@ get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps,
       if (sid_in_token_groups (my_grps, well_known_batch_sid))
        grp_list *= well_known_batch_sid;
       grp_list *= well_known_interactive_sid;
+#if 0
+      /* Don't add the SERVICE group when switching the user context.
+        That's much too dangerous, since the service group adds the
+        SE_IMPERSONATE_NAME privilege to the user.  After all, the
+        process started with this token is not the service process
+        anymore anyway. */
       if (sid_in_token_groups (my_grps, well_known_service_sid))
        grp_list *= well_known_service_sid;
+#endif
       if (sid_in_token_groups (my_grps, well_known_this_org_sid))
        grp_list *= well_known_this_org_sid;
       grp_list *= well_known_users_sid;
@@ -578,7 +587,7 @@ get_system_priv_list (size_t &size)
 
 static PTOKEN_PRIVILEGES
 get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list,
-              size_t &size)
+              size_t &size, cygpsid *mandatory_integrity_sid)
 {
   PLSA_UNICODE_STRING privstrs;
   ULONG cnt;
@@ -586,7 +595,14 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list,
   NTSTATUS ret;
 
   if (usersid == well_known_system_sid)
-    return get_system_priv_list (size);
+    {
+      if (mandatory_integrity_sid)
+       *mandatory_integrity_sid = mandatory_system_integrity_sid;
+      return get_system_priv_list (size);
+    }
+
+  if (mandatory_integrity_sid)
+    *mandatory_integrity_sid = mandatory_medium_integrity_sid;
 
   for (int grp = -1; grp < grp_list.count (); ++grp)
     {
@@ -605,8 +621,9 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list,
          LUID priv;
          PTOKEN_PRIVILEGES tmp;
          DWORD tmp_count;
+         bool high_integrity;
 
-         if (!privilege_luid (privstrs[i].Buffer, &priv))
+         if (!privilege_luid (privstrs[i].Buffer, priv, high_integrity))
            continue;
 
          if (privs)
@@ -637,6 +654,8 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list,
          privs->Privileges[privs->PrivilegeCount].Attributes =
            SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT;
          ++privs->PrivilegeCount;
+         if (mandatory_integrity_sid && high_integrity)
+           *mandatory_integrity_sid = mandatory_high_integrity_sid;
 
        next_account_right:
          ;
@@ -805,6 +824,7 @@ create_token (cygsid &usersid, user_groups &new_groups, struct passwd *pw)
   HANDLE primary_token = INVALID_HANDLE_VALUE;
 
   PTOKEN_GROUPS my_tok_gsids = NULL;
+  cygpsid mandatory_integrity_sid;
   ULONG size;
   size_t psize = 0;
 
@@ -888,26 +908,22 @@ create_token (cygsid &usersid, user_groups &new_groups, struct passwd *pw)
   if (auth_pos >= 0)
     new_tok_gsids->Groups[auth_pos].Attributes |= SE_GROUP_LOGON_ID;
 
-  /* On systems supporting Mandatory Integrity Control, add a MIC SID. */
+  /* Retrieve list of privileges of that user.  Based on the usersid and
+     the returned privileges, get_priv_list sets the mandatory_integrity_sid
+     pointer to the correct MIC SID for UAC. */
+  if (!(privs = get_priv_list (lsa, usersid, tmp_gsids, psize,
+                              &mandatory_integrity_sid)))
+    goto out;
+
+  /* On systems supporting Mandatory Integrity Control, add the MIC SID. */
   if (wincap.has_mandatory_integrity_control ())
     {
       new_tok_gsids->Groups[new_tok_gsids->GroupCount].Attributes =
        SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED;
-      if (usersid == well_known_system_sid)
-       new_tok_gsids->Groups[new_tok_gsids->GroupCount++].Sid
-         = mandatory_system_integrity_sid;
-      else if (tmp_gsids.contains (well_known_admins_sid))
-       new_tok_gsids->Groups[new_tok_gsids->GroupCount++].Sid
-         = mandatory_high_integrity_sid;
-      else
-       new_tok_gsids->Groups[new_tok_gsids->GroupCount++].Sid
-         = mandatory_medium_integrity_sid;
+      new_tok_gsids->Groups[new_tok_gsids->GroupCount++].Sid
+       = mandatory_integrity_sid;
     }
 
-  /* Retrieve list of privileges of that user. */
-  if (!(privs = get_priv_list (lsa, usersid, tmp_gsids, psize)))
-    goto out;
-
   /* Let's be heroic... */
   status = NtCreateToken (&token, TOKEN_ALL_ACCESS, &oa, TokenImpersonation,
                          &auth_luid, &exp, &user, new_tok_gsids, privs, &owner,
@@ -1035,8 +1051,9 @@ lsaauth (cygsid &usersid, user_groups &new_groups, struct passwd *pw)
     if ((tmpidx = tmp_gsids.next_non_well_known_sid (tmpidx)) >= 0)
       gsize += RtlLengthSid (tmp_gsids.sids[tmpidx]);
 
-  /* Retrieve list of privileges of that user. */
-  if (!(privs = get_priv_list (lsa, usersid, tmp_gsids, psize)))
+  /* Retrieve list of privileges of that user.  The MIC SID is created by
+     the LSA here. */
+  if (!(privs = get_priv_list (lsa, usersid, tmp_gsids, psize, NULL)))
     goto out;
 
   /* Create DefaultDacl. */
index c3531d3..d72c66b 100644 (file)
@@ -37,6 +37,8 @@ MKSID (well_known_world_sid, "S-1-1-0",
        SECURITY_WORLD_SID_AUTHORITY, 1, SECURITY_WORLD_RID);
 MKSID (well_known_local_sid, "S-1-2-0",
        SECURITY_LOCAL_SID_AUTHORITY, 1, SECURITY_LOCAL_RID);
+MKSID (well_known_console_logon_sid, "S-1-2-1",
+       SECURITY_LOCAL_SID_AUTHORITY, 1, 1);
 MKSID (well_known_creator_owner_sid, "S-1-3-0",
        SECURITY_CREATOR_SID_AUTHORITY, 1, SECURITY_CREATOR_OWNER_RID);
 MKSID (well_known_creator_group_sid, "S-1-3-1",
@@ -331,58 +333,64 @@ security_descriptor::free ()
 #undef TEXT
 #define TEXT(q) L##q
 
-/* Index must match the correspoding foo_PRIVILEGE value, see security.h. */
-static const wchar_t *cygpriv[] =
+/* Index must match the corresponding foo_PRIVILEGE value, see security.h. */
+static const struct {
+  const wchar_t *name;
+  bool          high_integrity; /* UAC: High Mandatory Label required to 
+                                   be allowed to enable this privilege in
+                                   the user token. */
+} cygpriv[] =
 {
-  L"",
-  L"",
-  SE_CREATE_TOKEN_NAME,
-  SE_ASSIGNPRIMARYTOKEN_NAME,
-  SE_LOCK_MEMORY_NAME,
-  SE_INCREASE_QUOTA_NAME,
-  SE_MACHINE_ACCOUNT_NAME,
-  SE_TCB_NAME,
-  SE_SECURITY_NAME,
-  SE_TAKE_OWNERSHIP_NAME,
-  SE_LOAD_DRIVER_NAME,
-  SE_SYSTEM_PROFILE_NAME,
-  SE_SYSTEMTIME_NAME,
-  SE_PROF_SINGLE_PROCESS_NAME,
-  SE_INC_BASE_PRIORITY_NAME,
-  SE_CREATE_PAGEFILE_NAME,
-  SE_CREATE_PERMANENT_NAME,
-  SE_BACKUP_NAME,
-  SE_RESTORE_NAME,
-  SE_SHUTDOWN_NAME,
-  SE_DEBUG_NAME,
-  SE_AUDIT_NAME,
-  SE_SYSTEM_ENVIRONMENT_NAME,
-  SE_CHANGE_NOTIFY_NAME,
-  SE_REMOTE_SHUTDOWN_NAME,
-  SE_UNDOCK_NAME,
-  SE_SYNC_AGENT_NAME,
-  SE_ENABLE_DELEGATION_NAME,
-  SE_MANAGE_VOLUME_NAME,
-  SE_IMPERSONATE_NAME,
-  SE_CREATE_GLOBAL_NAME,
-  SE_TRUSTED_CREDMAN_ACCESS_NAME,
-  SE_RELABEL_NAME,
-  SE_INCREASE_WORKING_SET_NAME,
-  SE_TIME_ZONE_NAME,
-  SE_CREATE_SYMBOLIC_LINK_NAME
+  { L"",                               false },
+  { L"",                               false },
+  { SE_CREATE_TOKEN_NAME,              true  },
+  { SE_ASSIGNPRIMARYTOKEN_NAME,                true  },
+  { SE_LOCK_MEMORY_NAME,               false },
+  { SE_INCREASE_QUOTA_NAME,            true  },
+  { SE_MACHINE_ACCOUNT_NAME,           false },
+  { SE_TCB_NAME,                       true  },
+  { SE_SECURITY_NAME,                  true  },
+  { SE_TAKE_OWNERSHIP_NAME,            true  },
+  { SE_LOAD_DRIVER_NAME,               true  },
+  { SE_SYSTEM_PROFILE_NAME,            true  },
+  { SE_SYSTEMTIME_NAME,                        true  },
+  { SE_PROF_SINGLE_PROCESS_NAME,       true  },
+  { SE_INC_BASE_PRIORITY_NAME,         true  },
+  { SE_CREATE_PAGEFILE_NAME,           true  },
+  { SE_CREATE_PERMANENT_NAME,          false },
+  { SE_BACKUP_NAME,                    true  },
+  { SE_RESTORE_NAME,                   true  },
+  { SE_SHUTDOWN_NAME,                  false },
+  { SE_DEBUG_NAME,                     true  },
+  { SE_AUDIT_NAME,                     false },
+  { SE_SYSTEM_ENVIRONMENT_NAME,                true  },
+  { SE_CHANGE_NOTIFY_NAME,             false },
+  { SE_REMOTE_SHUTDOWN_NAME,           true  },
+  { SE_UNDOCK_NAME,                    false },
+  { SE_SYNC_AGENT_NAME,                        false },
+  { SE_ENABLE_DELEGATION_NAME,         false },
+  { SE_MANAGE_VOLUME_NAME,             true  },
+  { SE_IMPERSONATE_NAME,               true  },
+  { SE_CREATE_GLOBAL_NAME,             false },
+  { SE_TRUSTED_CREDMAN_ACCESS_NAME,    false },
+  { SE_RELABEL_NAME,                   true  },
+  { SE_INCREASE_WORKING_SET_NAME,      false },
+  { SE_TIME_ZONE_NAME,                 true  },
+  { SE_CREATE_SYMBOLIC_LINK_NAME,      true  }
 };
 
 bool
-privilege_luid (const PWCHAR pname, LUID *luid)
+privilege_luid (const PWCHAR pname, LUID &luid, bool &high_integrity)
 {
   ULONG idx;
   for (idx = SE_CREATE_TOKEN_PRIVILEGE;
        idx <= SE_MAX_WELL_KNOWN_PRIVILEGE;
        ++idx)
-    if (!wcscmp (cygpriv[idx], pname))
+    if (!wcscmp (cygpriv[idx].name, pname))
       {
-       luid->HighPart = 0;
-       luid->LowPart = idx;
+       luid.HighPart = 0;
+       luid.LowPart = idx;
+       high_integrity = cygpriv[idx].high_integrity;
        return true;
       }
   return false;
@@ -394,7 +402,7 @@ privilege_name (const LUID &priv_luid)
   if (priv_luid.HighPart || priv_luid.LowPart < SE_CREATE_TOKEN_PRIVILEGE
       || priv_luid.LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE)
     return L"<unknown privilege>";
-  return cygpriv[priv_luid.LowPart];
+  return cygpriv[priv_luid.LowPart].name;
 }
 
 int
@@ -426,7 +434,7 @@ set_privilege (HANDLE token, DWORD privilege, bool enable)
 
 out:
   if (ret < 0)
-    debug_printf ("%d = set_privilege ((token %x) %W, %d)\n", ret, token,
+    debug_printf ("%d = set_privilege ((token %x) %W, %d)", ret, token,
                  privilege_name (new_priv.Privileges[0].Luid), enable);
   return ret;
 }
@@ -444,12 +452,13 @@ set_cygwin_privileges (HANDLE token)
   set_privilege (token, SE_BACKUP_PRIVILEGE, true);
   /* Allow full access to other user's processes. */
   set_privilege (token, SE_DEBUG_PRIVILEGE, true);
-  /* Allow to create global shared memory.  This shouldn't be required since
+#if 0
+  /* Allow to create global shared memory.  This isn't required anymore since
      Cygwin 1.7.  It uses its own subdirectories in the global NT namespace
-     which isn't affected by the SE_CREATE_GLOBAL_PRIVILEGE restriction.
-     Anyway, better safe than sorry. */
+     which isn't affected by the SE_CREATE_GLOBAL_PRIVILEGE restriction. */
   if (wincap.has_create_global_privilege ())
     set_privilege (token, SE_CREATE_GLOBAL_PRIVILEGE, true);
+#endif
 }
 
 /* Function to return a common SECURITY_DESCRIPTOR that
index 0a71221..6629260 100644 (file)
@@ -330,6 +330,7 @@ public:
 extern cygpsid well_known_null_sid;
 extern cygpsid well_known_world_sid;
 extern cygpsid well_known_local_sid;
+extern cygpsid well_known_console_logon_sid;
 extern cygpsid well_known_creator_owner_sid;
 extern cygpsid well_known_creator_group_sid;
 extern cygpsid well_known_dialup_sid;
@@ -349,7 +350,7 @@ extern cygpsid mandatory_high_integrity_sid;
 extern cygpsid mandatory_system_integrity_sid;
 extern cygpsid well_known_samba_unix_user_fake_sid;
 
-bool privilege_luid (const PWCHAR pname, LUID *luid);
+bool privilege_luid (const PWCHAR pname, LUID &luid, bool &high_integrity);
 
 inline BOOL
 well_known_sid_type (SID_NAME_USE type)
index 25acbf3..338350f 100644 (file)
@@ -51,6 +51,7 @@ wincaps wincap_2000 __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_restricted_raw_disk_access:false,
   use_dont_resolve_hack:false,
   has_stack_size_param_is_a_reservation:false,
+  has_console_logon_sid:false,
 };
 
 wincaps wincap_2000sp4 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -81,6 +82,7 @@ wincaps wincap_2000sp4 __attribute__((section (".cygwin_dll_common"), shared)) =
   has_restricted_raw_disk_access:false,
   use_dont_resolve_hack:false,
   has_stack_size_param_is_a_reservation:false,
+  has_console_logon_sid:false,
 };
 
 wincaps wincap_xp __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -111,6 +113,7 @@ wincaps wincap_xp __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_restricted_raw_disk_access:false,
   use_dont_resolve_hack:true,
   has_stack_size_param_is_a_reservation:true,
+  has_console_logon_sid:false,
 };
 
 wincaps wincap_xpsp1 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -141,6 +144,7 @@ wincaps wincap_xpsp1 __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_restricted_raw_disk_access:false,
   use_dont_resolve_hack:true,
   has_stack_size_param_is_a_reservation:true,
+  has_console_logon_sid:false,
 };
 
 wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -171,6 +175,7 @@ wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_restricted_raw_disk_access:false,
   use_dont_resolve_hack:true,
   has_stack_size_param_is_a_reservation:true,
+  has_console_logon_sid:false,
 };
 
 wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -201,6 +206,7 @@ wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_restricted_raw_disk_access:false,
   use_dont_resolve_hack:true,
   has_stack_size_param_is_a_reservation:true,
+  has_console_logon_sid:false,
 };
 
 wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -231,6 +237,7 @@ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_restricted_raw_disk_access:true,
   use_dont_resolve_hack:false,
   has_stack_size_param_is_a_reservation:true,
+  has_console_logon_sid:false,
 };
 
 wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -261,6 +268,7 @@ wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_restricted_raw_disk_access:true,
   use_dont_resolve_hack:false,
   has_stack_size_param_is_a_reservation:true,
+  has_console_logon_sid:true,
 };
 
 wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
index eab78fd..32f9586 100644 (file)
@@ -41,6 +41,7 @@ struct wincaps
   unsigned has_restricted_raw_disk_access              : 1;
   unsigned use_dont_resolve_hack                       : 1;
   unsigned has_stack_size_param_is_a_reservation       : 1;
+  unsigned has_console_logon_sid                       : 1;
 };
 
 class wincapc
@@ -90,6 +91,7 @@ public:
   bool IMPLEMENT (has_restricted_raw_disk_access)
   bool IMPLEMENT (use_dont_resolve_hack)
   bool IMPLEMENT (has_stack_size_param_is_a_reservation)
+  bool IMPLEMENT (has_console_logon_sid)
 
 #undef IMPLEMENT
 };