diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2001-05-20 12:10:47 +0400 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2001-05-20 12:10:47 +0400 |
commit | 1fcc912f135e11aa78a4ed529c70d6887cfcb317 (patch) | |
tree | c4b324e704e1744bea60ee46e6695c67665549c7 /winsup/cygwin/syscalls.cc | |
parent | df7cd7fb0c3a857b652238573fb303ffce7eeb12 (diff) |
* 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'.
Diffstat (limited to 'winsup/cygwin/syscalls.cc')
-rw-r--r-- | winsup/cygwin/syscalls.cc | 223 |
1 files changed, 135 insertions, 88 deletions
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index e4df8eb3b..48a8d72d2 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -1954,109 +1954,156 @@ seteuid (uid_t uid) sigframe thisframe (mainthread); if (os_being_run == winNT) { - if (uid != (uid_t) -1) + if (uid == (uid_t) -1 || uid == myself->uid) { - struct passwd *pw_new = getpwuid (uid); - if (!pw_new) - { - set_errno (EINVAL); - return -1; - } + debug_printf ("new euid == current euid, nothing happens"); + return 0; + } + struct passwd *pw_new = getpwuid (uid); + if (!pw_new) + { + set_errno (EINVAL); + return -1; + } + + if (uid == cygheap->user.orig_uid) + { + debug_printf ("RevertToSelf () (uid == orig_uid, token=%d)", + cygheap->user.token); + RevertToSelf (); + if (cygheap->user.token != INVALID_HANDLE_VALUE) + cygheap->user.impersonated = FALSE; + } + else + { + cygsid usersid, pgrpsid, tok_usersid, tok_pgrpsid; + DWORD siz; + HANDLE sav_token = INVALID_HANDLE_VALUE; + BOOL sav_impersonation; + BOOL explicitely_created_token = FALSE; + + struct group *gr = getgrgid (myself->gid); + debug_printf ("myself->gid: %d, gr: %d", myself->gid, gr); - if (uid != myself->uid) + usersid.getfrompw (pw_new); + pgrpsid.getfromgr (gr); + + /* Check if new user == user of impersonation token and + - if available - new pgrp == pgrp of impersonation token. */ + if (cygheap->user.token != INVALID_HANDLE_VALUE) { - if (uid == cygheap->user.orig_uid) + if (!GetTokenInformation (cygheap->user.token, TokenUser, + &tok_usersid, sizeof tok_usersid, &siz)) + { + debug_printf ("GetTokenInformation(): %E"); + tok_usersid = NO_SID; + } + if (!GetTokenInformation (cygheap->user.token, TokenPrimaryGroup, + &tok_pgrpsid, sizeof tok_pgrpsid, &siz)) { - debug_printf ("RevertToSelf () (uid == orig_uid, token=%d)", - cygheap->user.token); + debug_printf ("GetTokenInformation(): %E"); + tok_pgrpsid = NO_SID; + } + if ((usersid && tok_usersid && usersid != tok_usersid) || + (pgrpsid && tok_pgrpsid && pgrpsid != tok_pgrpsid)) + { + /* If not, RevertToSelf and close old token. */ + debug_printf ("tsid != usersid"); RevertToSelf (); - if (cygheap->user.token != INVALID_HANDLE_VALUE) - cygheap->user.impersonated = FALSE; + sav_token = cygheap->user.token; + sav_impersonation = cygheap->user.impersonated; + cygheap->user.token = INVALID_HANDLE_VALUE; + cygheap->user.impersonated = FALSE; } + } + + /* If no impersonation token is available, try to + authenticate using NtCreateToken() or subauthentication. */ + if (cygheap->user.token == INVALID_HANDLE_VALUE) + { + HANDLE ptok = INVALID_HANDLE_VALUE; + + ptok = create_token (usersid, pgrpsid); + if (ptok != INVALID_HANDLE_VALUE) + explicitely_created_token = TRUE; else { - cygsid tsid, psid, gsid; - DWORD siz; - - /* Check if new user == user of impersonation token. */ - if (cygheap->user.token != INVALID_HANDLE_VALUE) + /* create_token failed. Try subauthentication. */ + debug_printf ("create token failed, try subauthentication."); + ptok = subauth (pw_new); + } + if (ptok != INVALID_HANDLE_VALUE) + { + cygwin_set_impersonation_token (ptok); + /* If sav_token was internally created, destroy it. */ + if (sav_token != INVALID_HANDLE_VALUE) { - if (!GetTokenInformation (cygheap->user.token, TokenUser, - &tsid, sizeof tsid, &siz)) + TOKEN_SOURCE ts; + if (!GetTokenInformation (sav_token, TokenSource, + &ts, sizeof ts, &siz)) debug_printf ("GetTokenInformation(): %E"); - else if (psid.getfrompw (pw_new) && tsid != psid) - { - /* If not, RevertToSelf and close old token. */ - char tstr[256], pstr[256]; - debug_printf ("tsid (%s) != psid (%s)", - tsid.string (tstr), psid.string (pstr)); - RevertToSelf (); - cygwin_set_impersonation_token (INVALID_HANDLE_VALUE); - } + else if (!memcmp (ts.SourceName, "Cygwin.1", 8)) + CloseHandle (sav_token); } - /* If no impersonation token is available, try to - authenticate using subauthentication. */ - if (cygheap->user.token == INVALID_HANDLE_VALUE) - { - HANDLE ptok = subauth (pw_new); - if (ptok != INVALID_HANDLE_VALUE) - cygwin_set_impersonation_token (ptok); - else - cygheap->user.impersonated = TRUE; - } - /* If no impersonation is active but an impersonation - token is available, try to impersonate. */ - if (cygheap->user.token != INVALID_HANDLE_VALUE && - !cygheap->user.impersonated) - { - debug_printf ("Impersonate (uid == %d)", uid); - RevertToSelf (); - - struct group *gr; - - /* Try setting owner to same value as user. */ - if (!SetTokenInformation (cygheap->user.token, - TokenOwner, - &tsid, sizeof tsid)) - debug_printf ("SetTokenInformation(user.token, " - "TokenOwner): %E"); - /* Try setting primary group in token to current group. */ - if ((gr = getgrgid (myself->gid)) && - gsid.getfromgr (gr) && - !SetTokenInformation (cygheap->user.token, - TokenPrimaryGroup, - &gsid, sizeof gsid)) - debug_printf ("SetTokenInformation(user.token, " - "TokenPrimaryGroup): %E"); + } + else if (sav_token != INVALID_HANDLE_VALUE) + cygheap->user.token = sav_token; + } + /* If no impersonation is active but an impersonation + token is available, try to impersonate. */ + if (cygheap->user.token != INVALID_HANDLE_VALUE && + !cygheap->user.impersonated) + { + debug_printf ("Impersonate (uid == %d)", uid); + RevertToSelf (); - /* Now try to impersonate. */ - if (!ImpersonateLoggedOnUser (cygheap->user.token)) - system_printf ("Impersonating (%d) in set(e)uid " - "failed: %E", cygheap->user.token); - else - cygheap->user.impersonated = TRUE; - } - } + /* If the token was explicitely created, all information has + already been set correctly. */ + if (!explicitely_created_token) + { + /* Try setting owner to same value as user. */ + if (usersid && + !SetTokenInformation (cygheap->user.token, TokenOwner, + &usersid, sizeof usersid)) + debug_printf ("SetTokenInformation(user.token, " + "TokenOwner): %E"); + /* Try setting primary group in token to current group + if token not explicitely created. */ + if (pgrpsid && + !SetTokenInformation (cygheap->user.token, + TokenPrimaryGroup, + &pgrpsid, sizeof pgrpsid)) + debug_printf ("SetTokenInformation(user.token, " + "TokenPrimaryGroup): %E"); - cygheap_user user; - /* user.token is used in internal_getlogin () to determine if - impersonation is active. If so, the token is used for - retrieving user's SID. */ - user.token = cygheap->user.impersonated ? cygheap->user.token - : INVALID_HANDLE_VALUE; - struct passwd *pw_cur = internal_getlogin (user); - if (pw_cur != pw_new) - { - debug_printf ("Diffs!!! token: %d, cur: %d, new: %d, orig: %d", - cygheap->user.token, pw_cur->pw_uid, - pw_new->pw_uid, cygheap->user.orig_uid); - set_errno (EPERM); - return -1; - } - myself->uid = uid; - cygheap->user = user; + } + + /* Now try to impersonate. */ + if (!ImpersonateLoggedOnUser (cygheap->user.token)) + system_printf ("Impersonating (%d) in set(e)uid failed: %E", + cygheap->user.token); + else + cygheap->user.impersonated = TRUE; } } + + cygheap_user user; + /* user.token is used in internal_getlogin () to determine if + impersonation is active. If so, the token is used for + retrieving user's SID. */ + user.token = cygheap->user.impersonated ? cygheap->user.token + : INVALID_HANDLE_VALUE; + struct passwd *pw_cur = internal_getlogin (user); + if (pw_cur != pw_new) + { + debug_printf ("Diffs!!! token: %d, cur: %d, new: %d, orig: %d", + cygheap->user.token, pw_cur->pw_uid, + pw_new->pw_uid, cygheap->user.orig_uid); + set_errno (EPERM); + return -1; + } + myself->uid = uid; + cygheap->user = user; } else set_errno (ENOSYS); |