Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2003-06-30 17:07:36 +0400
committerCorinna Vinschen <corinna@vinschen.de>2003-06-30 17:07:36 +0400
commit70249d5687c6020064b70431e115fe1c0161cfa3 (patch)
tree64e9bd4e8db6308fd1c748266a00901b5e45b8d3 /winsup/cygwin/syscalls.cc
parent3fbdb70ec68d30d36bda2dd186b9a1ce8b4d579b (diff)
* cygheap.h (enum impersonation): New enum.
(cygheap_user::token): Delete. (cygheap_user::impersonated): Delete. (cygheap_user::external_token): New member. (cygheap_user::internal_token): New member. (cygheap_user::impersonation_state): New member. (cygheap_user::issetuid): Modify. (cygheap_user::token): New method. (cygheap_user::deimpersonate): New method. (cygheap_user::reimpersonate): New method. (cygheap_user::has_impersonation_tokens): New method. (cygheap_user::close_impersonation_tokens): New method. * dtable.cc (dtable::vfork_child_dup): Use new cygheap_user methods. * fhandler_socket.cc (fhandler_socket::dup): Ditto. * fork.cc (fork_child): Ditto. (fork_parent): Ditto. * grp.cc (internal_getgroups): Ditto. * security.cc (verify_token): Ditto. (check_file_access): Ditto. (cygwin_set_impersonation_token): Detect conflicts. Set user.external_token. * spawn.cc (spawn_guts): Use new cygheap_user methods. * syscalls.cc (seteuid32): Rearrange to use the two tokens in cygheap_user. (setegid32): Use new cygheap_user methods. * uinfo.cc: (internal_getlogin): Ditto.
Diffstat (limited to 'winsup/cygwin/syscalls.cc')
-rw-r--r--winsup/cygwin/syscalls.cc122
1 files changed, 54 insertions, 68 deletions
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index ad6a66fb9..8e545c4af 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -2057,66 +2057,52 @@ seteuid32 (__uid32_t uid)
sigframe thisframe (mainthread);
cygsid usersid;
user_groups &groups = cygheap->user.groups;
- HANDLE ptok, sav_token;
- BOOL sav_impersonated, sav_token_is_internal_token;
- BOOL process_ok, explicitly_created_token = FALSE;
+ HANDLE ptok, new_token = INVALID_HANDLE_VALUE;
struct passwd * pw_new;
PSID origpsid, psid2 = NO_SID;
+ enum impersonation new_state = IMP_BAD;
+ BOOL token_is_internal;
pw_new = internal_getpwuid (uid);
if (!wincap.has_security () && pw_new)
- goto success;
+ goto success_9x;
if (!usersid.getfrompw (pw_new))
{
set_errno (EINVAL);
return -1;
}
- /* Save current information */
- sav_token = cygheap->user.token;
- sav_impersonated = cygheap->user.impersonated;
RevertToSelf ();
if (!OpenProcessToken (hMainProc, TOKEN_QUERY | TOKEN_ADJUST_DEFAULT, &ptok))
{
__seterrno ();
- goto failed;
+ goto failed_ptok;;
}
- /* Verify if the process token is suitable.
- Currently we do not try to differentiate between
- internal tokens and others */
- process_ok = verify_token (ptok, usersid, groups);
- debug_printf ("Process token %sverified", process_ok ? "" : "not ");
- if (process_ok)
+
+ /* Verify if the process token is suitable. */
+ if (verify_token (ptok, usersid, groups))
+ new_state = IMP_NONE;
+ /* Verify if a current token is suitable */
+ else if (cygheap->user.external_token
+ && verify_token (cygheap->user.external_token, usersid, groups))
{
- if (cygheap->user.issetuid ())
- cygheap->user.impersonated = FALSE;
- else
- {
- CloseHandle (ptok);
- goto success; /* No change */
- }
+ new_token = cygheap->user.external_token;
+ new_state = IMP_EXTERNAL;
+ }
+ else if (cygheap->user.internal_token
+ && verify_token (cygheap->user.internal_token, usersid, groups,
+ &token_is_internal))
+ {
+ new_token = cygheap->user.internal_token;
+ new_state = IMP_INTERNAL;
}
- if (!process_ok && cygheap->user.token != INVALID_HANDLE_VALUE)
+ debug_printf ("New token %d, state %d", new_token, new_state);
+ /* Return if current token is valid */
+ if (cygheap->user.impersonation_state == new_state)
{
- /* Verify if the current tokem is suitable */
- BOOL token_ok = verify_token (cygheap->user.token, usersid, groups,
- &sav_token_is_internal_token);
- debug_printf ("Thread token %d %sverified",
- cygheap->user.token, token_ok?"":"not ");
- if (!token_ok)
- cygheap->user.token = INVALID_HANDLE_VALUE;
- else
- {
- /* Return if current token is valid */
- if (cygheap->user.impersonated)
- {
- CloseHandle (ptok);
- if (!ImpersonateLoggedOnUser (cygheap->user.token))
- system_printf ("Impersonating in seteuid failed: %E");
- goto success; /* No change */
- }
- }
+ cygheap->user.reimpersonate ();
+ goto success; /* No change */
}
/* Set process def dacl to allow access to impersonated token */
@@ -2132,72 +2118,72 @@ seteuid32 (__uid32_t uid)
debug_printf ("SetTokenInformation"
"(TokenDefaultDacl): %E");
}
- CloseHandle (ptok);
- if (!process_ok && cygheap->user.token == INVALID_HANDLE_VALUE)
+ if (new_state == IMP_BAD)
{
/* If no impersonation token is available, try to
authenticate using NtCreateToken () or subauthentication. */
- cygheap->user.token = create_token (usersid, groups, pw_new);
- if (cygheap->user.token != INVALID_HANDLE_VALUE)
- explicitly_created_token = TRUE;
- else
+ new_token = create_token (usersid, groups, pw_new);
+ if (new_token == INVALID_HANDLE_VALUE)
{
/* create_token failed. Try subauthentication. */
debug_printf ("create token failed, try subauthentication.");
- cygheap->user.token = subauth (pw_new);
- if (cygheap->user.token == INVALID_HANDLE_VALUE)
+ new_token = subauth (pw_new);
+ if (new_token == INVALID_HANDLE_VALUE)
goto failed;
}
+ new_state = IMP_INTERNAL;
}
/* If using the token, set info and impersonate */
- if (!process_ok)
+ if (new_state != IMP_NONE)
{
/* If the token was explicitly created, all information has
already been set correctly. */
- if (!explicitly_created_token)
+ if (new_state == IMP_EXTERNAL)
{
/* Try setting owner to same value as user. */
- if (!SetTokenInformation (cygheap->user.token, TokenOwner,
+ if (!SetTokenInformation (new_token, TokenOwner,
&usersid, sizeof usersid))
debug_printf ("SetTokenInformation(user.token, "
"TokenOwner): %E");
/* Try setting primary group in token to current group */
- if (!SetTokenInformation (cygheap->user.token,
+ if (!SetTokenInformation (new_token,
TokenPrimaryGroup,
&groups.pgsid, sizeof (cygsid)))
debug_printf ("SetTokenInformation(user.token, "
"TokenPrimaryGroup): %E");
}
- /* Now try to impersonate. */
- if (!ImpersonateLoggedOnUser (cygheap->user.token))
+ /* Try to impersonate. */
+ if (!ImpersonateLoggedOnUser (new_token))
{
debug_printf ("ImpersonateLoggedOnUser %E");
__seterrno ();
goto failed;
}
- cygheap->user.impersonated = TRUE;
+ /* Keep at most one internal token */
+ if (new_state == IMP_INTERNAL)
+ {
+ if (cygheap->user.internal_token)
+ CloseHandle (cygheap->user.internal_token);
+ cygheap->user.internal_token = new_token;
+ }
}
-
- /* If sav_token was internally created and is replaced, destroy it. */
- if (sav_token != INVALID_HANDLE_VALUE &&
- sav_token != cygheap->user.token &&
- sav_token_is_internal_token)
- CloseHandle (sav_token);
cygheap->user.set_sid (usersid);
+
success:
+ CloseHandle (ptok);
+ cygheap->user.impersonation_state = new_state;
+success_9x:
cygheap->user.set_name (pw_new->pw_name);
myself->uid = uid;
groups.ischanged = FALSE;
return 0;
failed:
- cygheap->user.token = sav_token;
- cygheap->user.impersonated = sav_impersonated;
- if (cygheap->user.issetuid ()
- && !ImpersonateLoggedOnUser (cygheap->user.token))
- system_printf ("Impersonating in seteuid failed: %E");
+ CloseHandle (ptok);
+failed_ptok:
+ cygheap->user.reimpersonate ();
return -1;
}
@@ -2278,7 +2264,7 @@ setegid32 (__gid32_t gid)
/* If impersonated, update primary group and revert */
if (cygheap->user.issetuid ())
{
- if (!SetTokenInformation (cygheap->user.token,
+ if (!SetTokenInformation (cygheap->user.token (),
TokenPrimaryGroup,
&gsid, sizeof gsid))
debug_printf ("SetTokenInformation(thread, "
@@ -2296,7 +2282,7 @@ setegid32 (__gid32_t gid)
CloseHandle (ptok);
}
if (cygheap->user.issetuid ()
- && !ImpersonateLoggedOnUser (cygheap->user.token))
+ && !ImpersonateLoggedOnUser (cygheap->user.token ()))
system_printf ("Impersonating in setegid failed: %E");
return 0;
}