* 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.
This commit is contained in:
@ -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)
|
||||
bool
|
||||
privilege_luid (const char *pname, LUID *luid)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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))
|
||||
status = NtAdjustPrivilegesToken (token, FALSE, &new_priv, sizeof orig_priv,
|
||||
&orig_priv, &size);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
__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)
|
||||
{
|
||||
__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
|
||||
|
Reference in New Issue
Block a user