OSDN Git Service

* cygheap.h (init_cygheap::luid): Remove.
authorcorinna <corinna>
Thu, 19 Jul 2007 08:33:22 +0000 (08:33 +0000)
committercorinna <corinna>
Thu, 19 Jul 2007 08:33:22 +0000 (08:33 +0000)
* mmap.cc (mlock): Accommodate parameter change in call to
push_thread_privilege.
(munlock): Ditto.
* ntdll.h (STATUS_NOT_ALL_ASSIGNED): Define.
(NtAdjustPrivilegesToken): Declare.
* sec_helper.cc (cygpriv): Reorder to match numerical privilege order.
(privilege_luid): Take job of privilege_luid_by_name, using new
cygpriv.
(privilege_luid_by_name): Remove.
(privilege_name): Accommodate new cygpriv array.
(set_privilege): Call NtAdjustPrivilegesToken to avoid using advapi32.
Accommodate changes to privilege_name.
(set_cygwin_privileges): Simplify.  Don't try to set
SE_CREATE_GLOBAL_PRIVILEGE on systems not supporting it.
* security.cc (sys_privs): Reorder to match numerical privilege order.
Use real privilege values as defined in security.h.
(get_system_priv_list): Drop unused grp_list argument.  Create
list of privileges according to new wincapc::max_sys_priv value.
(get_priv_list): Call privilege_luid instead of privilege_luid_by_name.
Make priv a local value instead of a pointer.
(create_token): Accommodate parameter change in call to
push_self_privilege.
(lsaauth): Ditto.
(check_access): Use privilege values directly instead of calling
privilege_luid.
* security.h: Define real privilege values.
(cygpriv_idx): Remove.
(privilege_luid): Change declaration.
(privilege_luid_by_name): Drop declaration.
(set_privilege): Change declaration.
(set_process_privilege): Drop definition.
(_push_thread_privilege): Accomodate new set_privilege parameters.
* wincap.h (wincapc::max_sys_priv): New element.
* wincap.cc: Implement above element throughout.
(wincap_2000sp4): New wincaps structure.
(wincap_xpsp1): Ditto.
(wincap_xpsp2): Ditto.
(wincapc::init): Use new wincaps.
(wincapc::max_sys_priv): New element.

winsup/cygwin/ChangeLog
winsup/cygwin/cygheap.h
winsup/cygwin/mmap.cc
winsup/cygwin/ntdll.h
winsup/cygwin/sec_helper.cc
winsup/cygwin/security.cc
winsup/cygwin/security.h
winsup/cygwin/wincap.cc
winsup/cygwin/wincap.h

index c47df01..2a879fb 100644 (file)
@@ -1,5 +1,48 @@
 2007-07-19  Corinna Vinschen  <corinna@vinschen.de>
 
+       * cygheap.h (init_cygheap::luid): Remove.
+       * mmap.cc (mlock): Accommodate parameter change in call to
+       push_thread_privilege.
+       (munlock): Ditto.
+       * ntdll.h (STATUS_NOT_ALL_ASSIGNED): Define.
+       (NtAdjustPrivilegesToken): Declare.
+       * sec_helper.cc (cygpriv): Reorder to match numerical privilege order.
+       (privilege_luid): Take job of privilege_luid_by_name, using new
+       cygpriv.
+       (privilege_luid_by_name): Remove.
+       (privilege_name): Accommodate new cygpriv array.
+       (set_privilege): Call NtAdjustPrivilegesToken to avoid using advapi32.
+       Accommodate changes to privilege_name.
+       (set_cygwin_privileges): Simplify.  Don't try to set
+       SE_CREATE_GLOBAL_PRIVILEGE on systems not supporting it.
+       * security.cc (sys_privs): Reorder to match numerical privilege order.
+       Use real privilege values as defined in security.h.
+       (get_system_priv_list): Drop unused grp_list argument.  Create
+       list of privileges according to new wincapc::max_sys_priv value.
+       (get_priv_list): Call privilege_luid instead of privilege_luid_by_name.
+       Make priv a local value instead of a pointer.
+       (create_token): Accommodate parameter change in call to
+       push_self_privilege.
+       (lsaauth): Ditto.
+       (check_access): Use privilege values directly instead of calling
+       privilege_luid.
+       * security.h: Define real privilege values.
+       (cygpriv_idx): Remove.
+       (privilege_luid): Change declaration.
+       (privilege_luid_by_name): Drop declaration.
+       (set_privilege): Change declaration.
+       (set_process_privilege): Drop definition.
+       (_push_thread_privilege): Accomodate new set_privilege parameters.
+       * wincap.h (wincapc::max_sys_priv): New element.
+       * wincap.cc: Implement above element throughout.
+       (wincap_2000sp4): New wincaps structure.
+       (wincap_xpsp1): Ditto.
+       (wincap_xpsp2): Ditto.
+       (wincapc::init): Use new wincaps.
+       (wincapc::max_sys_priv): New element.
+
+2007-07-19  Corinna Vinschen  <corinna@vinschen.de>
+
        * dcrt0.cc (dll_crt0_0): Call set_cygwin_privileges here, after
        initializing hProcToken.
        * sec_helper.cc (init_global_security): Don't call set_cygwin_privileges        here.
index 3ac43ba..2125786 100644 (file)
@@ -278,7 +278,6 @@ struct init_cygheap
   HANDLE console_h;
   cwdstuff cwd;
   dtable fdtab;
-  LUID luid[SE_NUM_PRIVS];
   char *shared_prefix;
   char shared_prefix_buf[8];
 #ifdef DEBUGGING
index 18c8ec8..5a37894 100644 (file)
@@ -1309,7 +1309,7 @@ mlock (const void *addr, size_t len)
      POSIX systems does.  On NT, this requires SeLockMemoryPrivilege,
      which is given only to SYSTEM by default. */
 
-  push_thread_privilege (SE_LOCK_MEMORY_PRIV, true);
+  push_thread_privilege (SE_LOCK_MEMORY_PRIVILEGE, true);
 
   /* Align address and length values to page size. */
   size_t pagesize = getpagesize ();
@@ -1368,7 +1368,7 @@ munlock (const void *addr, size_t len)
 {
   int ret = -1;
 
-  push_thread_privilege (SE_LOCK_MEMORY_PRIV, true);
+  push_thread_privilege (SE_LOCK_MEMORY_PRIVILEGE, true);
 
   /* Align address and length values to page size. */
   size_t pagesize = getpagesize ();
index 0bbb5a5..a509f1f 100644 (file)
@@ -19,6 +19,7 @@
 #define STATUS_SHARING_VIOLATION    ((NTSTATUS) 0xc0000043)
 #define STATUS_DELETE_PENDING       ((NTSTATUS) 0xc0000056)
 #define STATUS_WORKING_SET_QUOTA    ((NTSTATUS) 0xc00000a1)
+#define STATUS_NOT_ALL_ASSIGNED     ((NTSTATUS) 0x00000106)
 #define STATUS_INVALID_LEVEL        ((NTSTATUS) 0xc0000148)
 #define STATUS_NO_MORE_FILES        ((NTSTATUS) 0x80000006)
 #define PDI_MODULES 0x01
@@ -685,6 +686,8 @@ typedef struct _FILE_FULL_EA_INFORMATION
    standard Win32 header.  */
 extern "C"
 {
+  NTSTATUS NTAPI NtAdjustPrivilegesToken (HANDLE, BOOLEAN, PTOKEN_PRIVILEGES,
+                                         ULONG, PTOKEN_PRIVILEGES, PULONG);
   NTSTATUS NTAPI NtClose (HANDLE);
   NTSTATUS NTAPI NtCreateFile (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
                             PIO_STATUS_BLOCK, PLARGE_INTEGER, ULONG, ULONG,
index 416488a..6667357 100644 (file)
@@ -31,6 +31,7 @@ details. */
 #include "cygheap.h"
 #include "cygtls.h"
 #include "pwdgrp.h"
+#include "ntdll.h"
 
 /* General purpose security attribute objects for global use. */
 SECURITY_ATTRIBUTES NO_COPY sec_none;
@@ -361,14 +362,15 @@ got_it:
 #undef DOMLEN
 #endif //unused
 
-/* Order must be same as cygpriv_idx in security.h. */
+/* Index must match the correspoding foo_PRIVILEGE value, see security.h. */
 static const char *cygpriv[] =
 {
+  "",
+  "",
   SE_CREATE_TOKEN_NAME,
   SE_ASSIGNPRIMARYTOKEN_NAME,
   SE_LOCK_MEMORY_NAME,
   SE_INCREASE_QUOTA_NAME,
-  SE_UNSOLICITED_INPUT_NAME,
   SE_MACHINE_ACCOUNT_NAME,
   SE_TCB_NAME,
   SE_SECURITY_NAME,
@@ -388,81 +390,62 @@ static const char *cygpriv[] =
   SE_SYSTEM_ENVIRONMENT_NAME,
   SE_CHANGE_NOTIFY_NAME,
   SE_REMOTE_SHUTDOWN_NAME,
-  SE_CREATE_GLOBAL_NAME,
   SE_UNDOCK_NAME,
+  SE_SYNC_AGENT_NAME,
+  SE_ENABLE_DELEGATION_NAME,
   SE_MANAGE_VOLUME_NAME,
   SE_IMPERSONATE_NAME,
-  SE_ENABLE_DELEGATION_NAME,
-  SE_SYNC_AGENT_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
 };
 
-const LUID *
-privilege_luid (cygpriv_idx idx)
-{
-  if (idx < 0 || idx >= SE_NUM_PRIVS)
-    return NULL;
-  if (!cygheap->luid[idx].LowPart && !cygheap->luid[idx].HighPart
-      && !LookupPrivilegeValue (NULL, cygpriv[idx], &cygheap->luid[idx]))
-    {
-      __seterrno ();
-      return NULL;
-    }
-  return &cygheap->luid[idx];
-}
-
-const LUID *
-privilege_luid_by_name (const char *pname)
+bool
+privilege_luid (const char *pname, LUID *luid)
 {
-  int idx;
-
-  if (!pname)
-    return NULL;
-  for (idx = 0; idx < SE_NUM_PRIVS; ++idx)
-    if (!strcmp (pname, cygpriv[idx]))
-      return privilege_luid ((cygpriv_idx) idx);
-  return NULL;
+  ULONG idx;
+  for (idx = SE_CREATE_TOKEN_PRIVILEGE;
+       idx <= SE_MAX_WELL_KNOWN_PRIVILEGE;
+       ++idx)
+    if (!strcmp (cygpriv[idx], pname))
+      {
+       luid->HighPart = 0;
+       luid->LowPart = idx;
+       return true;
+      }
+  return false;
 }
 
 static const char *
-privilege_name (const LUID *priv_luid, char *buf, DWORD *size)
+privilege_name (const LUID &priv_luid)
 {
-  if (!priv_luid || !LookupPrivilegeName (NULL, (LUID *) priv_luid, buf, size))
+  if (priv_luid.HighPart || priv_luid.LowPart < SE_CREATE_TOKEN_PRIVILEGE
+      || priv_luid.LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE)
     return "<unknown privilege>";
-  return buf;
+  return cygpriv[priv_luid.LowPart];
 }
 
 int
-set_privilege (HANDLE token, const LUID *priv_luid, bool enable)
+set_privilege (HANDLE token, DWORD privilege, bool enable)
 {
   int ret = -1;
   TOKEN_PRIVILEGES new_priv, orig_priv;
-  DWORD size;
-
-  if (!priv_luid)
-    {
-      __seterrno ();
-      goto out;
-    }
+  ULONG size;
+  NTSTATUS status;
 
   new_priv.PrivilegeCount = 1;
-  new_priv.Privileges[0].Luid = *priv_luid;
+  new_priv.Privileges[0].Luid.HighPart = 0L;
+  new_priv.Privileges[0].Luid.LowPart = privilege;
   new_priv.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
 
-  if (!AdjustTokenPrivileges (token, FALSE, &new_priv,
-                             sizeof orig_priv, &orig_priv, &size))
-    {
-      __seterrno ();
-      goto out;
-    }
-  /* AdjustTokenPrivileges returns TRUE even if the privilege could not
-     be enabled. GetLastError () returns an correct error code, though. */
-  if (enable && GetLastError () == ERROR_NOT_ALL_ASSIGNED)
+  status = NtAdjustPrivilegesToken (token, FALSE, &new_priv, sizeof orig_priv,
+                                   &orig_priv, &size);
+  if (!NT_SUCCESS (status))
     {
-      __seterrno ();
+      __seterrno_from_nt_status (status);
       goto out;
     }
 
@@ -474,12 +457,8 @@ set_privilege (HANDLE token, const LUID *priv_luid, bool enable)
 
 out:
   if (ret < 0)
-    {
-      DWORD siz = 256;
-      char buf[siz];
-      debug_printf ("%d = set_privilege ((token %x) %s, %d)",
-                   ret, token, privilege_name (priv_luid, buf, &siz), enable);
-    }
+    debug_printf ("%d = set_privilege ((token %x) %s, %d)\n", ret, token,
+                 privilege_name (new_priv.Privileges[0].Luid), enable);
   return ret;
 }
 
@@ -488,14 +467,10 @@ out:
 void
 set_cygwin_privileges (HANDLE token)
 {
-  LUID priv_luid;
-
-  if (LookupPrivilegeValue (NULL, SE_RESTORE_NAME, &priv_luid))
-    set_privilege (token, &priv_luid, true);
-  if (LookupPrivilegeValue (NULL, SE_BACKUP_NAME, &priv_luid))
-    set_privilege (token, &priv_luid, true);
-  if (LookupPrivilegeValue (NULL, SE_CREATE_GLOBAL_NAME, &priv_luid))
-    set_privilege (token, &priv_luid, true);
+  set_privilege (token, SE_RESTORE_PRIVILEGE, true);
+  set_privilege (token, SE_BACKUP_PRIVILEGE, true);
+  if (wincap.has_create_global_privilege ())
+    set_privilege (token, SE_CREATE_GLOBAL_PRIVILEGE, true);
 }
 
 /* Function to return a common SECURITY_DESCRIPTOR that
index 2c3cb14..d76bbb1 100644 (file)
@@ -562,46 +562,50 @@ get_setgroups_sidlist (cygsidlist &tmp_list, PSID usersid, struct passwd *pw,
   tmp_list += groups.pgsid;
 }
 
-static const cygpriv_idx sys_privs[] = {
-  SE_TCB_PRIV,
-  SE_ASSIGNPRIMARYTOKEN_PRIV,
-  SE_CREATE_TOKEN_PRIV,
-  SE_CHANGE_NOTIFY_PRIV,
-  SE_SECURITY_PRIV,
-  SE_BACKUP_PRIV,
-  SE_RESTORE_PRIV,
-  SE_SYSTEMTIME_PRIV,
-  SE_SHUTDOWN_PRIV,
-  SE_REMOTE_SHUTDOWN_PRIV,
-  SE_TAKE_OWNERSHIP_PRIV,
-  SE_DEBUG_PRIV,
-  SE_SYSTEM_ENVIRONMENT_PRIV,
-  SE_SYSTEM_PROFILE_PRIV,
-  SE_PROF_SINGLE_PROCESS_PRIV,
-  SE_INC_BASE_PRIORITY_PRIV,
-  SE_LOAD_DRIVER_PRIV,
-  SE_CREATE_PAGEFILE_PRIV,
-  SE_INCREASE_QUOTA_PRIV,
-  SE_LOCK_MEMORY_PRIV,
-  SE_CREATE_PERMANENT_PRIV,
-  SE_AUDIT_PRIV,
-  SE_UNDOCK_PRIV,
-  SE_MANAGE_VOLUME_PRIV,
-  SE_IMPERSONATE_PRIV,
-  SE_CREATE_GLOBAL_PRIV,
-  SE_INCREASE_WORKING_SET_PRIV,
-  SE_TIME_ZONE_PRIV,
-  SE_CREATE_SYMBOLIC_LINK_PRIV
+static ULONG sys_privs[] = {
+  SE_CREATE_TOKEN_PRIVILEGE,
+  SE_ASSIGNPRIMARYTOKEN_PRIVILEGE,             
+  SE_LOCK_MEMORY_PRIVILEGE,            
+  SE_INCREASE_QUOTA_PRIVILEGE,         
+  SE_TCB_PRIVILEGE,            
+  SE_SECURITY_PRIVILEGE,               
+  SE_TAKE_OWNERSHIP_PRIVILEGE,         
+  SE_LOAD_DRIVER_PRIVILEGE,            
+  SE_SYSTEM_PROFILE_PRIVILEGE,         /* Vista ONLY */
+  SE_SYSTEMTIME_PRIVILEGE,             
+  SE_PROF_SINGLE_PROCESS_PRIVILEGE,            
+  SE_INC_BASE_PRIORITY_PRIVILEGE,              
+  SE_CREATE_PAGEFILE_PRIVILEGE,                
+  SE_CREATE_PERMANENT_PRIVILEGE,               
+  SE_BACKUP_PRIVILEGE,         
+  SE_RESTORE_PRIVILEGE,                
+  SE_SHUTDOWN_PRIVILEGE,               
+  SE_DEBUG_PRIVILEGE,          
+  SE_AUDIT_PRIVILEGE,          
+  SE_SYSTEM_ENVIRONMENT_PRIVILEGE,             
+  SE_CHANGE_NOTIFY_PRIVILEGE,          
+  SE_UNDOCK_PRIVILEGE,
+  SE_MANAGE_VOLUME_PRIVILEGE,
+  SE_IMPERSONATE_PRIVILEGE,
+  SE_CREATE_GLOBAL_PRIVILEGE,
+  SE_INCREASE_WORKING_SET_PRIVILEGE,
+  SE_TIME_ZONE_PRIVILEGE,
+  SE_CREATE_SYMBOLIC_LINK_PRIVILEGE
 };
 
 #define SYSTEM_PRIVILEGES_COUNT (sizeof sys_privs / sizeof *sys_privs)
 
 static PTOKEN_PRIVILEGES
-get_system_priv_list (cygsidlist &grp_list, size_t &size)
+get_system_priv_list (size_t &size)
 {
-  const LUID *priv;
-  size = sizeof (ULONG)
-        + SYSTEM_PRIVILEGES_COUNT * sizeof (LUID_AND_ATTRIBUTES);
+  ULONG max_idx = 0;
+  while (max_idx < SYSTEM_PRIVILEGES_COUNT
+        && sys_privs[max_idx] != wincap.max_sys_priv ())
+    ++max_idx;
+  if (max_idx >= SYSTEM_PRIVILEGES_COUNT)
+    api_fatal ("Coding error: wincap privilege %u doesn't exist in sys_privs",
+              wincap.max_sys_priv ());
+  size = sizeof (ULONG) + (max_idx + 1) * sizeof (LUID_AND_ATTRIBUTES);
   PTOKEN_PRIVILEGES privs = (PTOKEN_PRIVILEGES) malloc (size);
   if (!privs)
     {
@@ -609,15 +613,14 @@ get_system_priv_list (cygsidlist &grp_list, size_t &size)
       return NULL;
     }
   privs->PrivilegeCount = 0;
-
-  for (DWORD i = 0; i < SYSTEM_PRIVILEGES_COUNT; ++i)
-    if ((priv = privilege_luid (sys_privs[i])))
-      {
-       privs->Privileges[privs->PrivilegeCount].Luid = *priv;
-       privs->Privileges[privs->PrivilegeCount].Attributes =
-         SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT;
-       ++privs->PrivilegeCount;
-      }
+  for (ULONG i = 0; i <= max_idx; ++i)
+    {
+      privs->Privileges[privs->PrivilegeCount].Luid.HighPart = 0L;
+      privs->Privileges[privs->PrivilegeCount].Luid.LowPart = sys_privs[i];
+      privs->Privileges[privs->PrivilegeCount].Attributes =
+       SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT;
+      ++privs->PrivilegeCount;
+    }
   return privs;
 }
 
@@ -632,7 +635,7 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list,
   char buf[INTERNET_MAX_HOST_NAME_LENGTH + 1];
 
   if (usersid == well_known_system_sid)
-    return get_system_priv_list (grp_list, size);
+    return get_system_priv_list (size);
 
   for (int grp = -1; grp < grp_list.count (); ++grp)
     {
@@ -648,13 +651,13 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list,
        continue;
       for (ULONG i = 0; i < cnt; ++i)
        {
-         const LUID *priv;
+         LUID priv;
          PTOKEN_PRIVILEGES tmp;
          DWORD tmp_count;
 
          sys_wcstombs (buf, sizeof (buf),
                        privstrs[i].Buffer, privstrs[i].Length / 2);
-         if (!(priv = privilege_luid_by_name (buf)))
+         if (!privilege_luid (buf, &priv))
            continue;
 
          if (privs)
@@ -662,8 +665,8 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list,
              DWORD pcnt = privs->PrivilegeCount;
              LUID_AND_ATTRIBUTES *p = privs->Privileges;
              for (; pcnt > 0; --pcnt, ++p)
-               if (priv->HighPart == p->Luid.HighPart
-                   && priv->LowPart == p->Luid.LowPart)
+               if (priv.HighPart == p->Luid.HighPart
+                   && priv.LowPart == p->Luid.LowPart)
                  goto next_account_right;
            }
 
@@ -681,7 +684,7 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list,
            }
          tmp->PrivilegeCount = tmp_count;
          privs = tmp;
-         privs->Privileges[privs->PrivilegeCount].Luid = *priv;
+         privs->Privileges[privs->PrivilegeCount].Luid = priv;
          privs->Privileges[privs->PrivilegeCount].Attributes =
            SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT;
          ++privs->PrivilegeCount;
@@ -827,7 +830,7 @@ create_token (cygsid &usersid, user_groups &new_groups, struct passwd *pw)
   size_t psize = 0;
 
   /* SE_CREATE_TOKEN_NAME privilege needed to call NtCreateToken. */
-  push_self_privilege (SE_CREATE_TOKEN_PRIV, true);
+  push_self_privilege (SE_CREATE_TOKEN_PRIVILEGE, true);
 
   /* Open policy object. */
   if ((lsa = open_local_policy ()) == INVALID_HANDLE_VALUE)
@@ -964,7 +967,7 @@ lsaauth (cygsid &usersid, user_groups &new_groups, struct passwd *pw)
 
   HANDLE user_token = NULL;
 
-  push_self_privilege (SE_TCB_PRIV, true);
+  push_self_privilege (SE_TCB_PRIVILEGE, true);
 
   /* Register as logon process. */
   str2lsa (name, "Cygwin");
@@ -1978,7 +1981,8 @@ check_access (security_descriptor &sd, GENERIC_MAPPING &mapping,
        {
          pset->PrivilegeCount = 1;
          pset->Control = 0;
-         pset->Privilege[0].Luid = *privilege_luid (SE_BACKUP_PRIV);
+         pset->Privilege[0].Luid.HighPart = 0L;
+         pset->Privilege[0].Luid.LowPart = SE_BACKUP_PRIVILEGE;
          pset->Privilege[0].Attributes = 0;
          if (PrivilegeCheck (tok, pset, &status) && status)
            granted_flags |= R_OK;
@@ -1987,7 +1991,8 @@ check_access (security_descriptor &sd, GENERIC_MAPPING &mapping,
        {
          pset->PrivilegeCount = 1;
          pset->Control = 0;
-         pset->Privilege[0].Luid = *privilege_luid (SE_RESTORE_PRIV);
+         pset->Privilege[0].Luid.HighPart = 0L;
+         pset->Privilege[0].Luid.LowPart = SE_RESTORE_PRIVILEGE;
          pset->Privilege[0].Attributes = 0;
          if (PrivilegeCheck (tok, pset, &status) && status)
            granted_flags |= W_OK;
index 861f532..9aaaadb 100644 (file)
@@ -23,6 +23,49 @@ details. */
 #define ACL_DEFAULT_SIZE 3072
 #define NO_SID ((PSID)NULL)
 
+#ifndef SE_CREATE_TOKEN_PRIVILEGE
+#define SE_CREATE_TOKEN_PRIVILEGE            2UL
+#define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE      3UL
+#define SE_LOCK_MEMORY_PRIVILEGE             4UL
+#define SE_INCREASE_QUOTA_PRIVILEGE          5UL
+#define SE_MACHINE_ACCOUNT_PRIVILEGE         6UL
+#define SE_TCB_PRIVILEGE                     7UL
+#define SE_SECURITY_PRIVILEGE                8UL
+#define SE_TAKE_OWNERSHIP_PRIVILEGE          9UL
+#define SE_LOAD_DRIVER_PRIVILEGE            10UL
+#define SE_SYSTEM_PROFILE_PRIVILEGE         11UL
+#define SE_SYSTEMTIME_PRIVILEGE             12UL
+#define SE_PROF_SINGLE_PROCESS_PRIVILEGE    13UL
+#define SE_INC_BASE_PRIORITY_PRIVILEGE      14UL
+#define SE_CREATE_PAGEFILE_PRIVILEGE        15UL
+#define SE_CREATE_PERMANENT_PRIVILEGE       16UL
+#define SE_BACKUP_PRIVILEGE                 17UL
+#define SE_RESTORE_PRIVILEGE                18UL
+#define SE_SHUTDOWN_PRIVILEGE               19UL
+#define SE_DEBUG_PRIVILEGE                  20UL
+#define SE_AUDIT_PRIVILEGE                  21UL
+#define SE_SYSTEM_ENVIRONMENT_PRIVILEGE     22UL
+#define SE_CHANGE_NOTIFY_PRIVILEGE          23UL
+#define SE_REMOTE_SHUTDOWN_PRIVILEGE        24UL
+/* Starting with Windows 2000 */
+#define SE_UNDOCK_PRIVILEGE                 25UL
+#define SE_SYNC_AGENT_PRIVILEGE             26UL
+#define SE_ENABLE_DELEGATION_PRIVILEGE      27UL
+#define SE_MANAGE_VOLUME_PRIVILEGE          28UL
+/* Starting with Windows 2000 SP4, XP SP2, 2003 Server */
+#define SE_IMPERSONATE_PRIVILEGE            29UL
+#define SE_CREATE_GLOBAL_PRIVILEGE          30UL
+/* Starting with Vista */
+#define SE_TRUSTED_CREDMAN_ACCESS_PRIVILEGE 31UL
+#define SE_RELABEL_PRIVILEGE                32UL
+#define SE_INCREASE_WORKING_SET_PRIVILEGE   33UL
+#define SE_TIME_ZONE_PRIVILEGE              34UL
+#define SE_CREATE_SYMBOLIC_LINK_PRIVILEGE   35UL
+
+#define SE_MAX_WELL_KNOWN_PRIVILEGE SE_CREATE_SYMBOLIC_LINK_PRIVILEGE
+
+#endif /* ! SE_CREATE_TOKEN_PRIVILEGE */
+
 /* Added for debugging purposes. */
 typedef struct {
   BYTE  Revision;
@@ -279,48 +322,7 @@ extern cygpsid well_known_system_sid;
 extern cygpsid well_known_admins_sid;
 extern cygpsid fake_logon_sid;
 
-/* Order must be same as cygpriv in sec_helper.cc. */
-enum cygpriv_idx {
-  SE_CREATE_TOKEN_PRIV = 0,
-  SE_ASSIGNPRIMARYTOKEN_PRIV,
-  SE_LOCK_MEMORY_PRIV,
-  SE_INCREASE_QUOTA_PRIV,
-  SE_UNSOLICITED_INPUT_PRIV,
-  SE_MACHINE_ACCOUNT_PRIV,
-  SE_TCB_PRIV,
-  SE_SECURITY_PRIV,
-  SE_TAKE_OWNERSHIP_PRIV,
-  SE_LOAD_DRIVER_PRIV,
-  SE_SYSTEM_PROFILE_PRIV,
-  SE_SYSTEMTIME_PRIV,
-  SE_PROF_SINGLE_PROCESS_PRIV,
-  SE_INC_BASE_PRIORITY_PRIV,
-  SE_CREATE_PAGEFILE_PRIV,
-  SE_CREATE_PERMANENT_PRIV,
-  SE_BACKUP_PRIV,
-  SE_RESTORE_PRIV,
-  SE_SHUTDOWN_PRIV,
-  SE_DEBUG_PRIV,
-  SE_AUDIT_PRIV,
-  SE_SYSTEM_ENVIRONMENT_PRIV,
-  SE_CHANGE_NOTIFY_PRIV,
-  SE_REMOTE_SHUTDOWN_PRIV,
-  SE_CREATE_GLOBAL_PRIV,
-  SE_UNDOCK_PRIV,
-  SE_MANAGE_VOLUME_PRIV,
-  SE_IMPERSONATE_PRIV,
-  SE_ENABLE_DELEGATION_PRIV,
-  SE_SYNC_AGENT_PRIV,
-  SE_RELABEL_PRIV,
-  SE_INCREASE_WORKING_SET_PRIV,
-  SE_TIME_ZONE_PRIV,
-  SE_CREATE_SYMBOLIC_LINK_PRIV,
-
-  SE_NUM_PRIVS
-};
-
-const LUID *privilege_luid (enum cygpriv_idx idx);
-const LUID *privilege_luid_by_name (const char *pname);
+bool privilege_luid (const char *pname, LUID *luid);
 
 inline BOOL
 legal_sid_type (SID_NAME_USE type)
@@ -380,11 +382,9 @@ bool get_logon_server (const char * domain, char * server, WCHAR *wserver,
                       bool rediscovery);
 
 /* sec_helper.cc: Security helper functions. */
-int set_privilege (HANDLE token, const LUID *priv_luid, bool enable);
+int set_privilege (HANDLE token, DWORD privilege, bool enable);
 void set_cygwin_privileges (HANDLE token);
 
-#define set_process_privilege(p,v) set_privilege (hProcToken, privilege_luid (p), (v))
-
 #define _push_thread_privilege(_priv, _val, _check) { \
     HANDLE _dup_token = NULL; \
     HANDLE _token = (cygheap->user.issetuid () && (_check)) \
@@ -396,7 +396,7 @@ void set_cygwin_privileges (HANDLE token);
     else if (!ImpersonateLoggedOnUser (_dup_token)) \
       debug_printf ("ImpersonateLoggedOnUser: %E"); \
     else \
-      set_privilege (_dup_token, privilege_luid (_priv), (_val));
+      set_privilege (_dup_token, (_priv), (_val));
 
 #define push_thread_privilege(_priv, _val) _push_thread_privilege(_priv,_val,1)
 #define push_self_privilege(_priv, _val)   _push_thread_privilege(_priv,_val,0)
index 7923d5a..ef43768 100644 (file)
@@ -10,11 +10,13 @@ Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
 details. */
 
 #include "winsup.h"
+#include "security.h"
 
 /* Minimal set of capabilities which is equivalent to NT4. */
 static NO_COPY wincaps wincap_unknown = {
   chunksize:0,
   heapslop:0x0,
+  max_sys_priv:SE_CHANGE_NOTIFY_PRIVILEGE,
   is_server:false,
   has_security_descriptor_control:false,
   has_ip_helper_lib:false,
@@ -43,6 +45,7 @@ static NO_COPY wincaps wincap_unknown = {
 static NO_COPY wincaps wincap_nt4 = {
   chunksize:0,
   heapslop:0x0,
+  max_sys_priv:SE_CHANGE_NOTIFY_PRIVILEGE,
   is_server:false,
   has_security_descriptor_control:false,
   has_ip_helper_lib:false,
@@ -71,6 +74,7 @@ static NO_COPY wincaps wincap_nt4 = {
 static NO_COPY wincaps wincap_nt4sp4 = {
   chunksize:0,
   heapslop:0x0,
+  max_sys_priv:SE_CHANGE_NOTIFY_PRIVILEGE,
   is_server:false,
   has_security_descriptor_control:false,
   has_ip_helper_lib:true,
@@ -99,6 +103,7 @@ static NO_COPY wincaps wincap_nt4sp4 = {
 static NO_COPY wincaps wincap_2000 = {
   chunksize:0,
   heapslop:0x0,
+  max_sys_priv:SE_MANAGE_VOLUME_PRIVILEGE,
   is_server:false,
   has_security_descriptor_control:true,
   has_ip_helper_lib:true,
@@ -124,9 +129,39 @@ static NO_COPY wincaps wincap_2000 = {
   supports_all_posix_ai_flags:false,
 };
 
+static NO_COPY wincaps wincap_2000sp4 = {
+  chunksize:0,
+  heapslop:0x0,
+  max_sys_priv:SE_CREATE_GLOBAL_PRIVILEGE,
+  is_server:false,
+  has_security_descriptor_control:true,
+  has_ip_helper_lib:true,
+  has_broken_if_oper_status:false,
+  has_physical_mem_access:true,
+  has_process_io_counters:true,
+  has_terminal_services:true,
+  has_create_global_privilege:true,
+  has_ioctl_storage_get_media_types_ex:false,
+  has_extended_priority_class:true,
+  has_guid_volumes:true,
+  has_disk_ex_ioctls:false,
+  has_disabled_user_tos_setting:true,
+  has_fileid_dirinfo:true,
+  has_exclusiveaddruse:true,
+  has_buggy_restart_scan:true,
+  has_mandatory_integrity_control:false,
+  needs_logon_sid_in_sid_list:true,
+  needs_count_in_si_lpres2:false,
+  has_recycle_dot_bin:false,
+  has_gaa_prefixes:false,
+  has_gaa_on_link_prefix:false,
+  supports_all_posix_ai_flags:false,
+};
+
 static NO_COPY wincaps wincap_xp = {
   chunksize:0,
   heapslop:0x0,
+  max_sys_priv:SE_MANAGE_VOLUME_PRIVILEGE,
   is_server:false,
   has_security_descriptor_control:true,
   has_ip_helper_lib:true,
@@ -147,6 +182,64 @@ static NO_COPY wincaps wincap_xp = {
   needs_logon_sid_in_sid_list:false,
   needs_count_in_si_lpres2:false,
   has_recycle_dot_bin:false,
+  has_gaa_prefixes:false,
+  has_gaa_on_link_prefix:false,
+  supports_all_posix_ai_flags:false,
+};
+
+static NO_COPY wincaps wincap_xpsp1 = {
+  chunksize:0,
+  heapslop:0x0,
+  max_sys_priv:SE_MANAGE_VOLUME_PRIVILEGE,
+  is_server:false,
+  has_security_descriptor_control:true,
+  has_ip_helper_lib:true,
+  has_broken_if_oper_status:false,
+  has_physical_mem_access:true,
+  has_process_io_counters:true,
+  has_terminal_services:true,
+  has_create_global_privilege:false,
+  has_ioctl_storage_get_media_types_ex:true,
+  has_extended_priority_class:true,
+  has_guid_volumes:true,
+  has_disk_ex_ioctls:true,
+  has_disabled_user_tos_setting:true,
+  has_fileid_dirinfo:true,
+  has_exclusiveaddruse:true,
+  has_buggy_restart_scan:false,
+  has_mandatory_integrity_control:false,
+  needs_logon_sid_in_sid_list:false,
+  needs_count_in_si_lpres2:false,
+  has_recycle_dot_bin:false,
+  has_gaa_prefixes:true,
+  has_gaa_on_link_prefix:false,
+  supports_all_posix_ai_flags:false,
+};
+
+static NO_COPY wincaps wincap_xpsp2 = {
+  chunksize:0,
+  heapslop:0x0,
+  max_sys_priv:SE_CREATE_GLOBAL_PRIVILEGE,
+  is_server:false,
+  has_security_descriptor_control:true,
+  has_ip_helper_lib:true,
+  has_broken_if_oper_status:false,
+  has_physical_mem_access:true,
+  has_process_io_counters:true,
+  has_terminal_services:true,
+  has_create_global_privilege:true,
+  has_ioctl_storage_get_media_types_ex:true,
+  has_extended_priority_class:true,
+  has_guid_volumes:true,
+  has_disk_ex_ioctls:true,
+  has_disabled_user_tos_setting:true,
+  has_fileid_dirinfo:true,
+  has_exclusiveaddruse:true,
+  has_buggy_restart_scan:false,
+  has_mandatory_integrity_control:false,
+  needs_logon_sid_in_sid_list:false,
+  needs_count_in_si_lpres2:false,
+  has_recycle_dot_bin:false,
   has_gaa_prefixes:true,
   has_gaa_on_link_prefix:false,
   supports_all_posix_ai_flags:false,
@@ -155,6 +248,7 @@ static NO_COPY wincaps wincap_xp = {
 static NO_COPY wincaps wincap_2003 = {
   chunksize:0,
   heapslop:0x4,
+  max_sys_priv:SE_CREATE_GLOBAL_PRIVILEGE,
   is_server:true,
   has_security_descriptor_control:true,
   has_ip_helper_lib:true,
@@ -183,6 +277,7 @@ static NO_COPY wincaps wincap_2003 = {
 static NO_COPY wincaps wincap_vista = {
   chunksize:0,
   heapslop:0x4,
+  max_sys_priv:SE_CREATE_SYMBOLIC_LINK_PRIVILEGE,
   is_server:false,
   has_security_descriptor_control:true,
   has_ip_helper_lib:true,
@@ -248,13 +343,23 @@ wincapc::init ()
              switch (version.dwMinorVersion)
                {
                  case 0:
-                   caps = &wincap_2000;
+                   if (version.wServicePackMajor < 4)
+                     caps = &wincap_2000;
+                   else
+                     caps = &wincap_2000sp4;
                    break;
 
                  case 1:
                    caps = &wincap_xp;
-                   if (version.wServicePackMajor < 1)
-                     ((wincaps *)this->caps)->has_gaa_prefixes = false;
+                   switch (version.wServicePackMajor)
+                     {
+                     case 0:
+                       caps = &wincap_xp;
+                     case 1:
+                       caps = &wincap_xpsp1;
+                     default:
+                       caps = &wincap_xpsp2;
+                     }
                    break;
 
                  default:
index 2215bf9..903e531 100644 (file)
@@ -15,6 +15,7 @@ struct wincaps
 {
   DWORD    chunksize;
   DWORD    heapslop;
+  DWORD    max_sys_priv;
   unsigned is_server                                    : 1;
   unsigned has_security_descriptor_control              : 1;
   unsigned has_ip_helper_lib                            : 1;
@@ -59,6 +60,7 @@ public:
 
   DWORD IMPLEMENT (chunksize)
   DWORD IMPLEMENT (heapslop)
+  DWORD IMPLEMENT (max_sys_priv)
   bool  IMPLEMENT (is_server)
   bool  IMPLEMENT (has_security_descriptor_control)
   bool  IMPLEMENT (has_ip_helper_lib)