diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2019-02-23 17:30:44 +0100 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2019-02-23 17:30:44 +0100 |
commit | 71b8777a7140b79942d6e5079818cad2c3f5f07f (patch) | |
tree | dde21636f4bc50a0f01a659445ba806204615105 | |
parent | 331653a215a054688308236e595bd0dfba08450f (diff) | |
download | cygnal-71b8777a7140b79942d6e5079818cad2c3f5f07f.tar.gz cygnal-71b8777a7140b79942d6e5079818cad2c3f5f07f.tar.bz2 cygnal-71b8777a7140b79942d6e5079818cad2c3f5f07f.zip |
Cygwin: user profile: Make an effort to unload unused user profiles
Does this work? There's not much feedback given.
TODO: We might want to try unloading the user profile at process
exit as well, FWIW.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
-rw-r--r-- | winsup/cygwin/autoload.cc | 1 | ||||
-rw-r--r-- | winsup/cygwin/cygheap.h | 3 | ||||
-rw-r--r-- | winsup/cygwin/sec_auth.cc | 6 | ||||
-rw-r--r-- | winsup/cygwin/security.h | 1 | ||||
-rw-r--r-- | winsup/cygwin/syscalls.cc | 15 | ||||
-rw-r--r-- | winsup/cygwin/uinfo.cc | 2 |
6 files changed, 25 insertions, 3 deletions
diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index 056fac7dc..c04e25c95 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -699,6 +699,7 @@ LoadDLLfuncEx (CreateEnvironmentBlock, 12, userenv, 1) LoadDLLfuncEx2 (CreateProfile, 16, userenv, 1, 1) LoadDLLfunc (DestroyEnvironmentBlock, 4, userenv) LoadDLLfunc (LoadUserProfileW, 8, userenv) +LoadDLLfunc (UnloadUserProfile, 8, userenv) LoadDLLfuncEx3 (waveInAddBuffer, 12, winmm, 1, 0, 1) LoadDLLfuncEx3 (waveInClose, 4, winmm, 1, 0, 1) diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h index 8877cc358..5c5e3cd1e 100644 --- a/winsup/cygwin/cygheap.h +++ b/winsup/cygwin/cygheap.h @@ -106,6 +106,9 @@ public: HANDLE curr_primary_token; /* Just a copy of external or internal token */ HANDLE curr_imp_token; /* impersonation token derived from primary token */ + HANDLE imp_profile_token; /* Handle to the token used to load the + user profile in "imp_profile" */ + HANDLE imp_profile; /* Handle to the user profile */ bool ext_token_is_restricted; /* external_token is restricted token */ bool curr_token_is_restricted; /* curr_primary_token is restricted token */ bool setuid_to_restricted; /* switch to restricted token by setuid () */ diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index c96011d6d..59ee55339 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -306,6 +306,12 @@ load_user_profile (HANDLE token, struct passwd *pw, cygpsid &usersid) return pi.hProfile; } +bool +unload_user_profile (HANDLE token, HANDLE profile) +{ + return UnloadUserProfile (token, profile); +} + HANDLE lsa_open_policy (PWCHAR server, ACCESS_MASK access) { diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h index 483a527e7..0ce7e8d7a 100644 --- a/winsup/cygwin/security.h +++ b/winsup/cygwin/security.h @@ -502,6 +502,7 @@ PWCHAR get_user_profile_directory (PCWSTR sidstr, PWCHAR path, SIZE_T path_len); /* Load user profile if it's not already loaded. */ HANDLE load_user_profile (HANDLE token, struct passwd *pw, cygpsid &sid); +bool unload_user_profile (HANDLE token, HANDLE profile); HANDLE lsa_open_policy (PWCHAR server, ACCESS_MASK access); void lsa_close_policy (HANDLE lsa); diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 172b7c4f6..b1039762d 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -3603,8 +3603,17 @@ seteuid32 (uid_t uid) { NTSTATUS status; - if (!request_restricted_uid_switch) - load_user_profile (new_token, pw_new, usersid); + if (!request_restricted_uid_switch + && new_token != cygheap->user.imp_profile_token) + { + if (cygheap->user.imp_profile_token && cygheap->user.imp_profile) + unload_user_profile (cygheap->user.imp_profile_token, + cygheap->user.imp_profile); + cygheap->user.imp_profile = load_user_profile (new_token, pw_new, + usersid); + if (cygheap->user.imp_profile) + cygheap->user.imp_profile_token = new_token; + } /* Try setting owner to same value as user. */ status = NtSetInformationToken (new_token, TokenOwner, @@ -3634,7 +3643,7 @@ seteuid32 (uid_t uid) issamesid = (usersid == cygheap->user.sid ()); cygheap->user.set_sid (usersid); cygheap->user.curr_primary_token = new_token == hProcToken ? NO_IMPERSONATION - : new_token; + : new_token; cygheap->user.curr_token_is_restricted = false; cygheap->user.setuid_to_restricted = false; if (cygheap->user.curr_imp_token != NO_IMPERSONATION) diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index bfcce00da..49614cb45 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -239,6 +239,8 @@ uinfo_init () cygheap->user.internal_token = NO_IMPERSONATION; cygheap->user.curr_primary_token = NO_IMPERSONATION; cygheap->user.curr_imp_token = NO_IMPERSONATION; + cygheap->user.imp_profile_token = NO_IMPERSONATION; + cygheap->user.imp_profile = NULL; cygheap->user.ext_token_is_restricted = false; cygheap->user.curr_token_is_restricted = false; cygheap->user.setuid_to_restricted = false; |