aboutsummaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2022-03-07 11:29:42 +0100
committerCorinna Vinschen <corinna@vinschen.de>2022-05-12 22:00:25 +0200
commit7bed18558d8f01c258b6c00a5083c2d0816724cc (patch)
tree8e8a5650b30f9518edc9ed6d547efadb274bdbc0 /winsup
parent23b5466aedf2a0beaa0ca92515274861581ea613 (diff)
downloadnewlib-7bed18558d8f01c258b6c00a5083c2d0816724cc.zip
newlib-7bed18558d8f01c258b6c00a5083c2d0816724cc.tar.gz
newlib-7bed18558d8f01c258b6c00a5083c2d0816724cc.tar.bz2
Cygwin: drop create_token and dependent functions
Given we only called create_token on W7 WOW64 anyway, we can now drop this function and all other functions only called from there entirely. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/sec_auth.cc368
-rw-r--r--winsup/cygwin/security.h2
-rw-r--r--winsup/cygwin/spawn.cc8
-rw-r--r--winsup/cygwin/syscalls.cc23
4 files changed, 9 insertions, 392 deletions
diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc
index a7610c7..a15778d 100644
--- a/winsup/cygwin/sec_auth.cc
+++ b/winsup/cygwin/sec_auth.cc
@@ -379,41 +379,6 @@ sid_in_token_groups (PTOKEN_GROUPS grps, cygpsid sid)
return false;
}
-static void
-get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps)
-{
- if (my_grps)
- {
- grp_list += well_known_local_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))
- grp_list *= well_known_network_sid;
- 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;
- }
- else
- {
- grp_list += well_known_local_sid;
- grp_list *= well_known_interactive_sid;
- grp_list *= well_known_users_sid;
- }
-}
-
bool
get_server_groups (cygsidlist &grp_list, PSID usersid,
acct_disabled_chk_t check_account_disabled)
@@ -470,180 +435,6 @@ get_server_groups (cygsidlist &grp_list, PSID usersid,
return true;
}
-static bool
-get_initgroups_sidlist (cygsidlist &grp_list, PSID usersid, PSID pgrpsid,
- PTOKEN_GROUPS my_grps)
-{
- if (well_known_system_sid != usersid)
- get_token_group_sidlist (grp_list, my_grps);
- if (!get_server_groups (grp_list, usersid, CHK_DISABLED))
- return false;
-
- /* special_pgrp true if pgrpsid is not in normal groups */
- grp_list += pgrpsid;
- return true;
-}
-
-static bool
-get_setgroups_sidlist (cygsidlist &tmp_list, PSID usersid,
- PTOKEN_GROUPS my_grps, user_groups &groups)
-{
- get_token_group_sidlist (tmp_list, my_grps);
- if (!get_server_groups (tmp_list, usersid, CHK_DISABLED))
- return false;
- for (int gidx = 0; gidx < groups.sgsids.count (); gidx++)
- tmp_list += groups.sgsids.sids[gidx];
- tmp_list += groups.pgsid;
- return true;
-}
-
-/* Fixed size TOKEN_PRIVILEGES list to reflect privileges given to the
- SYSTEM account by default. */
-const struct
-{
- DWORD PrivilegeCount;
- LUID_AND_ATTRIBUTES Privileges[28];
-} sys_privs =
-{
- 28,
- {
- { { SE_CREATE_TOKEN_PRIVILEGE, 0 },
- SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
- { { SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, 0 },
- SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
- { { SE_LOCK_MEMORY_PRIVILEGE, 0 },
- SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
- { { SE_INCREASE_QUOTA_PRIVILEGE, 0 },
- SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
- { { SE_TCB_PRIVILEGE, 0 },
- SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
- { { SE_SECURITY_PRIVILEGE, 0 },
- SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
- { { SE_TAKE_OWNERSHIP_PRIVILEGE, 0 },
- SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
- { { SE_LOAD_DRIVER_PRIVILEGE, 0 },
- SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
- { { SE_SYSTEM_PROFILE_PRIVILEGE, 0 },
- SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
- { { SE_SYSTEMTIME_PRIVILEGE, 0 },
- SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
- { { SE_PROF_SINGLE_PROCESS_PRIVILEGE, 0 },
- SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
- { { SE_INC_BASE_PRIORITY_PRIVILEGE, 0 },
- SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
- { { SE_CREATE_PAGEFILE_PRIVILEGE, 0 },
- SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
- { { SE_CREATE_PERMANENT_PRIVILEGE, 0 },
- SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
- { { SE_BACKUP_PRIVILEGE, 0 },
- SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
- { { SE_RESTORE_PRIVILEGE, 0 },
- SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
- { { SE_SHUTDOWN_PRIVILEGE, 0 },
- SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
- { { SE_DEBUG_PRIVILEGE, 0 },
- SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
- { { SE_AUDIT_PRIVILEGE, 0 },
- SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
- { { SE_SYSTEM_ENVIRONMENT_PRIVILEGE, 0 },
- SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
- { { SE_CHANGE_NOTIFY_PRIVILEGE, 0 },
- SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
- { { SE_UNDOCK_PRIVILEGE, 0 },
- SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
- { { SE_MANAGE_VOLUME_PRIVILEGE, 0 },
- SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
- { { SE_IMPERSONATE_PRIVILEGE, 0 },
- SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
- { { SE_CREATE_GLOBAL_PRIVILEGE, 0 },
- SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
- { { SE_INCREASE_WORKING_SET_PRIVILEGE, 0 },
- SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
- { { SE_TIME_ZONE_PRIVILEGE, 0 },
- SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
- { { SE_CREATE_SYMBOLIC_LINK_PRIVILEGE, 0 },
- SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT }
- }
-};
-
-static PTOKEN_PRIVILEGES
-get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list,
- size_t &size, cygpsid *mandatory_integrity_sid)
-{
- PLSA_UNICODE_STRING privstrs;
- ULONG cnt;
- PTOKEN_PRIVILEGES privs = NULL;
-
- if (usersid == well_known_system_sid)
- {
- if (mandatory_integrity_sid)
- *mandatory_integrity_sid = mandatory_system_integrity_sid;
- return (PTOKEN_PRIVILEGES) &sys_privs;
- }
-
- if (mandatory_integrity_sid)
- *mandatory_integrity_sid = mandatory_medium_integrity_sid;
-
- for (int grp = -1; grp < grp_list.count (); ++grp)
- {
- if (grp == -1)
- {
- if (LsaEnumerateAccountRights (lsa, usersid, &privstrs, &cnt)
- != STATUS_SUCCESS)
- continue;
- }
- else if (LsaEnumerateAccountRights (lsa, grp_list.sids[grp],
- &privstrs, &cnt) != STATUS_SUCCESS)
- continue;
- for (ULONG i = 0; i < cnt; ++i)
- {
- LUID priv;
- PTOKEN_PRIVILEGES tmp;
- DWORD tmp_count;
- bool high_integrity;
-
- if (!privilege_luid (privstrs[i].Buffer, priv, high_integrity))
- continue;
-
- if (privs)
- {
- 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)
- goto next_account_right;
- }
-
- tmp_count = privs ? privs->PrivilegeCount : 0;
- size = sizeof (DWORD)
- + (tmp_count + 1) * sizeof (LUID_AND_ATTRIBUTES);
- tmp = (PTOKEN_PRIVILEGES) realloc (privs, size);
- if (!tmp)
- {
- if (privs)
- free (privs);
- LsaFreeMemory (privstrs);
- debug_printf ("realloc (privs) failed.");
- return NULL;
- }
- tmp->PrivilegeCount = tmp_count;
- privs = tmp;
- privs->Privileges[privs->PrivilegeCount].Luid = priv;
- 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:
- ;
- }
- LsaFreeMemory (privstrs);
- }
- return privs;
-}
-
/* Accept a token if
- the requested usersid matches the TokenUser and
- if setgroups has been called:
@@ -654,9 +445,8 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list,
they match and verify only the primary groups.
The requested primary group must appear in the token.
The primary group in the token is a group associated with the usersid,
- except if the token is internal and the group is in the token SD
- (see create_token). In that latter case that group must match the
- requested primary group. */
+ except if the token is internal and the group is in the token SD. In
+ that latter case that group must match the requested primary group. */
bool
verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern)
{
@@ -786,160 +576,6 @@ account_restriction (NTSTATUS status)
return type;
}
-HANDLE
-create_token (cygsid &usersid, user_groups &new_groups)
-{
- NTSTATUS status;
- LSA_HANDLE lsa = NULL;
-
- cygsidlist tmp_gsids (cygsidlist_auto, 12);
-
- SECURITY_QUALITY_OF_SERVICE sqos =
- { sizeof sqos, SecurityImpersonation, SECURITY_STATIC_TRACKING, FALSE };
- OBJECT_ATTRIBUTES oa = { sizeof oa, 0, 0, 0, 0, &sqos };
- /* Up to Windows 7, when using an authentication LUID other than "Anonymous",
- Windows whoami prints the wrong username, the one from the login session,
- not the one from the actual user token of the process. This is apparently
- fixed in Windows 8. However, starting with Windows 8, access rights of
- the anonymous logon session is further restricted. Therefore we create
- the new user token with the authentication id of the local service
- account. Hopefully that's sufficient. */
- const LUID auth_luid_7 = ANONYMOUS_LOGON_LUID;
- const LUID auth_luid_8 = LOCALSERVICE_LUID;
- LUID auth_luid = wincap.has_broken_whoami () ? auth_luid_7 : auth_luid_8;
- LARGE_INTEGER exp = { QuadPart:INT64_MAX };
-
- TOKEN_USER user;
- PTOKEN_GROUPS new_tok_gsids = NULL;
- PTOKEN_PRIVILEGES privs = NULL;
- TOKEN_OWNER owner;
- TOKEN_PRIMARY_GROUP pgrp;
- TOKEN_DEFAULT_DACL dacl = {};
- TOKEN_SOURCE source;
- TOKEN_STATISTICS stats;
- memcpy (source.SourceName, "Cygwin.1", 8);
- source.SourceIdentifier.HighPart = 0;
- source.SourceIdentifier.LowPart = 0x0101;
-
- HANDLE token = NULL;
- HANDLE primary_token = NULL;
-
- tmp_pathbuf tp;
- PTOKEN_GROUPS my_tok_gsids = NULL;
- cygpsid mandatory_integrity_sid;
- ULONG size;
- size_t psize = 0;
-
- /* SE_CREATE_TOKEN_NAME privilege needed to call NtCreateToken. */
- push_self_privilege (SE_CREATE_TOKEN_PRIVILEGE, true);
-
- /* Open policy object. */
- if (!(lsa = lsa_open_policy (NULL, POLICY_EXECUTE)))
- goto out;
-
- /* User, owner, primary group. */
- user.User.Sid = usersid;
- user.User.Attributes = 0;
- owner.Owner = usersid;
-
- /* Retrieve authentication id and group list from own process. */
- if (hProcToken)
- {
- /* Switching user context to SYSTEM doesn't inherit the authentication
- id of the user account running current process. */
- if (usersid == well_known_system_sid)
- /* nothing to do */;
- else
- {
- status = NtQueryInformationToken (hProcToken, TokenStatistics,
- &stats, sizeof stats, &size);
- if (!NT_SUCCESS (status))
- debug_printf ("NtQueryInformationToken(hProcToken, "
- "TokenStatistics), %y", status);
- }
-
- /* Retrieving current processes group list to be able to inherit
- some important well known group sids. */
- my_tok_gsids = (PTOKEN_GROUPS) tp.w_get ();
- status = NtQueryInformationToken (hProcToken, TokenGroups, my_tok_gsids,
- 2 * NT_MAX_PATH, &size);
- if (!NT_SUCCESS (status))
- {
- debug_printf ("NtQueryInformationToken(hProcToken, TokenGroups), "
- "%y", status);
- my_tok_gsids = NULL;
- }
- }
-
- /* Create list of groups, the user is member in. */
- if (new_groups.issetgroups ())
- {
- if (!get_setgroups_sidlist (tmp_gsids, usersid, my_tok_gsids, new_groups))
- goto out;
- }
- else if (!get_initgroups_sidlist (tmp_gsids, usersid, new_groups.pgsid,
- my_tok_gsids))
- goto out;
-
- /* Primary group. */
- pgrp.PrimaryGroup = new_groups.pgsid;
-
- /* Create a TOKEN_GROUPS list from the above retrieved list of sids. */
- new_tok_gsids = (PTOKEN_GROUPS)
- alloca (sizeof (DWORD) + (tmp_gsids.count () + 1)
- * sizeof (SID_AND_ATTRIBUTES));
- new_tok_gsids->GroupCount = tmp_gsids.count ();
- for (DWORD i = 0; i < new_tok_gsids->GroupCount; ++i)
- {
- new_tok_gsids->Groups[i].Sid = tmp_gsids.sids[i];
- new_tok_gsids->Groups[i].Attributes = SE_GROUP_MANDATORY
- | SE_GROUP_ENABLED_BY_DEFAULT
- | SE_GROUP_ENABLED;
- }
-
- /* 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;
-
- new_tok_gsids->Groups[new_tok_gsids->GroupCount].Attributes =
- SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED;
- new_tok_gsids->Groups[new_tok_gsids->GroupCount++].Sid
- = mandatory_integrity_sid;
-
- /* Let's be heroic... */
- status = NtCreateToken (&token, TOKEN_ALL_ACCESS, &oa, TokenImpersonation,
- &auth_luid, &exp, &user, new_tok_gsids, privs, &owner,
- &pgrp, &dacl, &source);
- if (status)
- __seterrno_from_nt_status (status);
- else
- {
- /* Convert to primary token. */
- if (!DuplicateTokenEx (token, MAXIMUM_ALLOWED, &sec_none,
- SecurityImpersonation, TokenPrimary,
- &primary_token))
- {
- __seterrno ();
- debug_printf ("DuplicateTokenEx %E");
- primary_token = NULL;
- }
- }
-
-out:
- pop_self_privilege ();
- if (token != INVALID_HANDLE_VALUE)
- CloseHandle (token);
- if (privs && privs != (PTOKEN_PRIVILEGES) &sys_privs)
- free (privs);
- lsa_close_policy (lsa);
-
- debug_printf ("%p = create_token ()", primary_token);
- return primary_token;
-}
-
#define SFU_LSA_KEY_SUFFIX L"_microsoft_sfu_utility"
HANDLE
diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h
index 3e6688c..651f6d0 100644
--- a/winsup/cygwin/security.h
+++ b/winsup/cygwin/security.h
@@ -457,8 +457,6 @@ int setacl (HANDLE, path_conv &, int, struct acl *, bool &);
/* Set impersonation or restricted token. */
void set_imp_token (HANDLE token, int type);
-/* Function creating a token by calling NtCreateToken. */
-HANDLE create_token (cygsid &usersid, user_groups &groups);
/* LSA private key storage authentication, same as when using service logons. */
HANDLE lsaprivkeyauth (struct passwd *pw);
/* Kerberos or MsV1 S4U logon. */
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index c9e1fb6..98b5886 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -752,11 +752,9 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
sa = sec_user ((PSECURITY_ATTRIBUTES) alloca (1024),
::cygheap->user.sid ());
/* We're creating a window station per user, not per logon
- session First of all we might not have a valid logon session
- for the user (logon by create_token), and second, it doesn't
- make sense in terms of security to create a new window
- station for every logon of the same user. It just fills up
- the system with window stations for no good reason. */
+ session. It doesn't make sense in terms of security to
+ create a new window station for every logon of the same user.
+ It just fills up the system with window stations. */
hwst = CreateWindowStationW (::cygheap->user.get_windows_id (sid),
0, GENERIC_READ | GENERIC_WRITE, sa);
if (!hwst)
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 317cd2e..5254c26 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -3609,8 +3609,7 @@ seteuid32 (uid_t uid)
debug_printf ("Found token %p", new_token);
/* If no impersonation token is available, try to authenticate using
- LSA private data stored password, LSA authentication using our own
- LSA module, or, as last chance, NtCreateToken. */
+ LSA private data stored password, or, if that fails, S4U logon. */
if (new_token == NULL)
{
if (!(new_token = lsaprivkeyauth (pw_new)))
@@ -3623,23 +3622,9 @@ seteuid32 (uid_t uid)
extract_nt_dom_user (pw_new, domain, user);
if (!(new_token = s4uauth (true, domain, user, status)))
{
- if (status != STATUS_INVALID_PARAMETER)
- {
- debug_printf ("s4uauth failed, bail out");
- cygheap->user.reimpersonate ();
- return -1;
- }
- /* If s4uauth fails with status code STATUS_INVALID_PARAMETER,
- we're running on a system not implementing MsV1_0S4ULogon
- (Windows 7 WOW64). Fall back to create_token in this single
- case only. */
- debug_printf ("s4uauth failed, try create_token.");
- if (!(new_token = create_token (usersid, groups)))
- {
- debug_printf ("create_token failed, bail out");
- cygheap->user.reimpersonate ();
- return -1;
- }
+ debug_printf ("s4uauth failed, bail out");
+ cygheap->user.reimpersonate ();
+ return -1;
}
}