* 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:
Corinna Vinschen
2001-05-20 08:10:47 +00:00
parent df7cd7fb0c
commit 1fcc912f13
9 changed files with 1041 additions and 161 deletions

View File

@@ -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)
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);
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)
{
set_errno (EINVAL);
return -1;
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 ("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 ();
sav_token = cygheap->user.token;
sav_impersonation = cygheap->user.impersonated;
cygheap->user.token = INVALID_HANDLE_VALUE;
cygheap->user.impersonated = FALSE;
}
}
if (uid != myself->uid)
/* If no impersonation token is available, try to
authenticate using NtCreateToken() or subauthentication. */
if (cygheap->user.token == INVALID_HANDLE_VALUE)
{
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;
}
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 ();
}
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 ();
struct group *gr;
/* 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");
/* 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");
}
/* 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;
/* 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);