* autoload.cc: Add load statements for `LookupAccountNameW',
`LsaClose', `LsaEnumerateAccountRights', `LsaFreeMemory', `LsaOpenPolicy', `LsaQueryInformationPolicy', `NetLocalGroupEnum', `NetLocalGroupGetMembers', `NetServerEnum', `NetUserGetGroups' and `NtCreateToken'. * ntdll.h: Add declaration for `NtCreateToken'. * sec_helper.cc: Add `well_known_local_sid', `well_known_dialup_sid', `well_known_network_sid', `well_known_batch_sid', `well_known_interactive_sid', `well_known_service_sid' and `well_known_authenticated_users_sid'. (cygsid::string): Define as const method. (cygsid::get_sid): Set psid to NO_SID on error. (cygsid::getfromstr): Ditto. (cygsid::getfrompw): Simplify. (cygsid::getfromgr): Check for gr == NULL. (legal_sid_type): Move to security.h. (set_process_privilege): Return -1 on error, otherwise 0 or 1 related to previous privilege setting. * security.cc (extract_nt_dom_user): Remove `static'. (lsa2wchar): New function. (open_local_policy): Ditto. (close_local_policy): Ditto. (get_lsa_srv_inf): Ditto. (get_logon_server): Ditto. (get_logon_server_and_user_domain): Ditto. (get_user_groups): Ditto. (is_group_member): Ditto. (get_user_local_groups): Ditto. (sid_in_token_groups): Ditto. (get_user_primary_group): Ditto. (get_group_sidlist): Ditto. (get_system_priv_list): Ditto. (get_priv_list): Ditto. (get_dacl): Ditto. (create_token): Ditto. (subauth): Return immediately if SE_TCB_NAME can't be assigned. Change all return statements in case of error to jumps to `out' label. Add `out' label to support cleanup. * security.h: Add extern declarations for `well_known_local_sid', `well_known_dialup_sid', `well_known_network_sid', `well_known_batch_sid', `well_known_interactive_sid', `well_known_service_sid' and `well_known_authenticated_users_sid'. Add extern declarations for functions `create_token', `extract_nt_dom_user' and `get_logon_server_and_user_domain'. (class cygsid): Add method `assign'. Change operator= to call new `assign' method. Add `debug_print' method. (class cygsidlist): New class. (legal_sid_type): Moved from sec_helper.cc to here. * spawn.cc (spawn_guts) Revert reversion of previous patch. Call `RevertToSelf' and `ImpersonateLoggedOnUser' instead of `seteuid' again. * syscalls.cc (seteuid): Rearranged. Call `create_token' now when needed. Call `subauth' if `create_token' fails. Try setting token owner and primary group only if token was not explicitely created by `create_token'. * uinfo.cc (internal_getlogin): Try harder to generate correct user information. Especially don't trust return value of `GetUserName'.
This commit is contained in:
@@ -44,13 +44,20 @@ SID_IDENTIFIER_AUTHORITY sid_auth[] = {
|
||||
{SECURITY_NT_AUTHORITY}
|
||||
};
|
||||
|
||||
cygsid well_known_admin_sid ("S-1-5-32-544");
|
||||
cygsid well_known_system_sid ("S-1-5-18");
|
||||
cygsid well_known_creator_owner_sid ("S-1-3-0");
|
||||
cygsid well_known_world_sid ("S-1-1-0");
|
||||
cygsid well_known_local_sid ("S-1-2-0");
|
||||
cygsid well_known_creator_owner_sid ("S-1-3-0");
|
||||
cygsid well_known_dialup_sid ("S-1-5-1");
|
||||
cygsid well_known_network_sid ("S-1-5-2");
|
||||
cygsid well_known_batch_sid ("S-1-5-3");
|
||||
cygsid well_known_interactive_sid ("S-1-5-4");
|
||||
cygsid well_known_service_sid ("S-1-5-6");
|
||||
cygsid well_known_authenticated_users_sid ("S-1-5-11");
|
||||
cygsid well_known_system_sid ("S-1-5-18");
|
||||
cygsid well_known_admin_sid ("S-1-5-32-544");
|
||||
|
||||
char *
|
||||
cygsid::string (char *nsidstr)
|
||||
cygsid::string (char *nsidstr) const
|
||||
{
|
||||
char t[32];
|
||||
DWORD i;
|
||||
@@ -74,7 +81,10 @@ cygsid::get_sid (DWORD s, DWORD cnt, DWORD *r)
|
||||
DWORD i;
|
||||
|
||||
if (s > 5 || cnt < 1 || cnt > 8)
|
||||
return NULL;
|
||||
{
|
||||
psid = NO_SID;
|
||||
return NULL;
|
||||
}
|
||||
set ();
|
||||
InitializeSid(psid, &sid_auth[s], cnt);
|
||||
for (i = 0; i < cnt; ++i)
|
||||
@@ -92,7 +102,10 @@ cygsid::getfromstr (const char *nsidstr)
|
||||
DWORD i, r[8];
|
||||
|
||||
if (!nsidstr || strncmp (nsidstr, "S-1-", 4))
|
||||
return NULL;
|
||||
{
|
||||
psid = NO_SID;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strcpy (sid_buf, nsidstr);
|
||||
|
||||
@@ -110,17 +123,15 @@ cygsid::getfromstr (const char *nsidstr)
|
||||
BOOL
|
||||
cygsid::getfrompw (struct passwd *pw)
|
||||
{
|
||||
char *sp = pw->pw_gecos ? strrchr (pw->pw_gecos, ',') : NULL;
|
||||
|
||||
if (!sp)
|
||||
return FALSE;
|
||||
return (*this = ++sp) != NULL;
|
||||
char *sp = (pw && pw->pw_gecos) ? strrchr (pw->pw_gecos, ',') : NULL;
|
||||
return (*this = sp ? sp + 1 : "") != NULL;
|
||||
}
|
||||
|
||||
BOOL
|
||||
cygsid::getfromgr (struct group *gr)
|
||||
{
|
||||
return (*this = gr->gr_passwd) != NULL;
|
||||
char *sp = (gr && gr->gr_passwd) ? gr->gr_passwd : NULL;
|
||||
return (*this = sp ?: "") != NULL;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -238,13 +249,6 @@ cygsid::get_id (BOOL search_grp, int *type)
|
||||
return id;
|
||||
}
|
||||
|
||||
static inline BOOL
|
||||
legal_sid_type (SID_NAME_USE type)
|
||||
{
|
||||
return type == SidTypeUser || type == SidTypeGroup
|
||||
|| type == SidTypeAlias || type == SidTypeWellKnownGroup;
|
||||
}
|
||||
|
||||
BOOL
|
||||
is_grp_member (uid_t uid, gid_t gid)
|
||||
{
|
||||
@@ -338,10 +342,12 @@ set_process_privilege (const char *privilege, BOOL enable)
|
||||
{
|
||||
HANDLE hToken = NULL;
|
||||
LUID restore_priv;
|
||||
TOKEN_PRIVILEGES new_priv;
|
||||
TOKEN_PRIVILEGES new_priv, orig_priv;
|
||||
int ret = -1;
|
||||
DWORD size;
|
||||
|
||||
if (!OpenProcessToken (hMainProc, TOKEN_ADJUST_PRIVILEGES, &hToken))
|
||||
if (!OpenProcessToken (hMainProc, TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
|
||||
&hToken))
|
||||
{
|
||||
__seterrno ();
|
||||
goto out;
|
||||
@@ -357,13 +363,22 @@ set_process_privilege (const char *privilege, BOOL enable)
|
||||
new_priv.Privileges[0].Luid = restore_priv;
|
||||
new_priv.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
|
||||
|
||||
if (!AdjustTokenPrivileges (hToken, FALSE, &new_priv, 0, NULL, NULL))
|
||||
if (!AdjustTokenPrivileges (hToken, 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)
|
||||
{
|
||||
debug_printf ("Privilege %s couldn't be assigned", privilege);
|
||||
__seterrno ();
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
ret = orig_priv.Privileges[0].Attributes == SE_PRIVILEGE_ENABLED ? 1 : 0;
|
||||
|
||||
out:
|
||||
if (hToken)
|
||||
|
Reference in New Issue
Block a user