aboutsummaryrefslogtreecommitdiff
path: root/winsup/cygwin/syscalls.cc
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/syscalls.cc')
-rw-r--r--winsup/cygwin/syscalls.cc197
1 files changed, 97 insertions, 100 deletions
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 7cca8b6..25c4a00 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -1698,6 +1698,7 @@ get_osfhandle (int fd)
extern "C" int
statvfs (const char *fname, struct statvfs *sfs)
{
+ int ret = -1;
char root[CYG_MAX_PATH];
if (check_null_empty_str_errno (fname)
@@ -1716,47 +1717,47 @@ statvfs (const char *fname, struct statvfs *sfs)
if (!rootdir (full_path, root))
return -1;
- /* GetDiskFreeSpaceEx must be called before GetDiskFreeSpace on
- WinME, to avoid the MS KB 314417 bug */
ULARGE_INTEGER availb, freeb, totalb;
- BOOL status = GetDiskFreeSpaceEx (root, &availb, &totalb, &freeb);
-
- DWORD spc, bps, availc, freec, totalc;
+ DWORD spc, bps, availc, freec, totalc, vsn, maxlen, flags;
+ BOOL status;
- if (!GetDiskFreeSpace (root, &spc, &bps, &freec, &totalc))
- {
- __seterrno ();
- return -1;
- }
+ push_thread_privilege (SE_CHANGE_NOTIFY_PRIV, true);
- if (status)
+ /* GetDiskFreeSpaceEx must be called before GetDiskFreeSpace on
+ WinME, to avoid the MS KB 314417 bug */
+ status = GetDiskFreeSpaceEx (root, &availb, &totalb, &freeb);
+ if (GetDiskFreeSpace (root, &spc, &bps, &freec, &totalc))
{
- availc = availb.QuadPart / (spc*bps);
- totalc = totalb.QuadPart / (spc*bps);
- freec = freeb.QuadPart / (spc*bps);
+ if (status)
+ {
+ availc = availb.QuadPart / (spc*bps);
+ totalc = totalb.QuadPart / (spc*bps);
+ freec = freeb.QuadPart / (spc*bps);
+ }
+ else
+ availc = freec;
+ if (GetVolumeInformation (root, NULL, 0, &vsn, &maxlen, &flags, NULL, 0))
+ {
+ sfs->f_bsize = spc*bps;
+ sfs->f_frsize = spc*bps;
+ sfs->f_blocks = totalc;
+ sfs->f_bfree = freec;
+ sfs->f_bavail = availc;
+ sfs->f_files = ULONG_MAX;
+ sfs->f_ffree = ULONG_MAX;
+ sfs->f_favail = ULONG_MAX;
+ sfs->f_fsid = vsn;
+ sfs->f_flag = flags;
+ sfs->f_namemax = maxlen;
+ ret = 0;
+ }
}
- else
- availc = freec;
+ if (ret)
+ __seterrno ();
- DWORD vsn, maxlen, flags;
+ pop_thread_privilege ();
- if (!GetVolumeInformation (root, NULL, 0, &vsn, &maxlen, &flags, NULL, 0))
- {
- __seterrno ();
- return -1;
- }
- sfs->f_bsize = spc*bps;
- sfs->f_frsize = spc*bps;
- sfs->f_blocks = totalc;
- sfs->f_bfree = freec;
- sfs->f_bavail = availc;
- sfs->f_files = ULONG_MAX;
- sfs->f_ffree = ULONG_MAX;
- sfs->f_favail = ULONG_MAX;
- sfs->f_fsid = vsn;
- sfs->f_flag = flags;
- sfs->f_namemax = maxlen;
- return 0;
+ return ret;
}
extern "C" int
@@ -1968,11 +1969,9 @@ seteuid32 (__uid32_t uid)
cygsid usersid;
user_groups &groups = cygheap->user.groups;
- HANDLE ptok, new_token = INVALID_HANDLE_VALUE;
+ HANDLE new_token = INVALID_HANDLE_VALUE;
struct passwd * pw_new;
bool token_is_internal, issamesid = false;
- char dacl_buf[MAX_DACL_LEN (5)];
- TOKEN_DEFAULT_DACL tdacl = {};
pw_new = internal_getpwuid (uid);
if (!wincap.has_security () && pw_new)
@@ -1986,29 +1985,24 @@ seteuid32 (__uid32_t uid)
return -1;
}
- RevertToSelf ();
- if (!OpenProcessToken (hMainProc, TOKEN_QUERY | TOKEN_ADJUST_DEFAULT, &ptok))
- {
- __seterrno ();
- goto failed_ptok;;
- }
+ cygheap->user.deimpersonate ();
/* Verify if the process token is suitable. */
- if (verify_token (ptok, usersid, groups))
- new_token = ptok;
+ if (verify_token (hProcToken, usersid, groups))
+ new_token = hProcToken;
/* Verify if the external token is suitable */
else if (cygheap->user.external_token != NO_IMPERSONATION
&& verify_token (cygheap->user.external_token, usersid, groups))
new_token = cygheap->user.external_token;
/* Verify if the current token (internal or former external) is suitable */
- else if (cygheap->user.current_token != NO_IMPERSONATION
- && cygheap->user.current_token != cygheap->user.external_token
- && verify_token (cygheap->user.current_token, usersid, groups,
+ else if (cygheap->user.curr_primary_token != NO_IMPERSONATION
+ && cygheap->user.curr_primary_token != cygheap->user.external_token
+ && verify_token (cygheap->user.curr_primary_token, usersid, groups,
&token_is_internal))
- new_token = cygheap->user.current_token;
+ new_token = cygheap->user.curr_primary_token;
/* Verify if the internal token is suitable */
else if (cygheap->user.internal_token != NO_IMPERSONATION
- && cygheap->user.internal_token != cygheap->user.current_token
+ && cygheap->user.internal_token != cygheap->user.curr_primary_token
&& verify_token (cygheap->user.internal_token, usersid, groups,
&token_is_internal))
new_token = cygheap->user.internal_token;
@@ -2026,7 +2020,10 @@ seteuid32 (__uid32_t uid)
debug_printf ("create token failed, try subauthentication.");
new_token = subauth (pw_new);
if (new_token == INVALID_HANDLE_VALUE)
- goto failed;
+ {
+ cygheap->user.reimpersonate ();
+ return -1;
+ }
}
/* Keep at most one internal token */
if (cygheap->user.internal_token != NO_IMPERSONATION)
@@ -2034,17 +2031,7 @@ seteuid32 (__uid32_t uid)
cygheap->user.internal_token = new_token;
}
- /* Set process def dacl to allow access to impersonated token */
- if (sec_acl ((PACL) dacl_buf, true, true, usersid))
- {
- tdacl.DefaultDacl = (PACL) dacl_buf;
- if (!SetTokenInformation (ptok, TokenDefaultDacl,
- &tdacl, sizeof dacl_buf))
- debug_printf ("SetTokenInformation"
- "(TokenDefaultDacl), %E");
- }
-
- if (new_token != ptok)
+ if (new_token != hProcToken)
{
/* Avoid having HKCU use default user */
char name[128];
@@ -2053,26 +2040,48 @@ seteuid32 (__uid32_t uid)
/* Try setting owner to same value as user. */
if (!SetTokenInformation (new_token, TokenOwner,
&usersid, sizeof usersid))
- debug_printf ("SetTokenInformation(user.token, "
- "TokenOwner), %E");
+ debug_printf ("SetTokenInformation(user.token, TokenOwner), %E");
/* Try setting primary group in token to current group */
if (!SetTokenInformation (new_token, TokenPrimaryGroup,
&groups.pgsid, sizeof (cygsid)))
- debug_printf ("SetTokenInformation(user.token, "
- "TokenPrimaryGroup), %E");
+ debug_printf ("SetTokenInformation(user.token, TokenPrimaryGroup), %E");
/* Try setting default DACL */
- if (tdacl.DefaultDacl
- && !SetTokenInformation (new_token, TokenDefaultDacl,
- &tdacl, sizeof (tdacl)))
- debug_printf ("SetTokenInformation (TokenDefaultDacl), %E");
+ char dacl_buf[MAX_DACL_LEN (5)];
+ if (sec_acl ((PACL) dacl_buf, true, true, usersid))
+ {
+ TOKEN_DEFAULT_DACL tdacl = { (PACL) dacl_buf };
+ if (!SetTokenInformation (new_token, TokenDefaultDacl,
+ &tdacl, sizeof (tdacl)))
+ debug_printf ("SetTokenInformation (TokenDefaultDacl), %E");
+ }
}
- CloseHandle (ptok);
issamesid = (usersid == cygheap->user.sid ());
cygheap->user.set_sid (usersid);
- cygheap->user.current_token = new_token == ptok ? NO_IMPERSONATION
- : new_token;
- cygheap->user.reimpersonate ();
+ cygheap->user.curr_primary_token = new_token == hProcToken ? NO_IMPERSONATION
+ : new_token;
+ if (cygheap->user.current_token != NO_IMPERSONATION)
+ {
+ CloseHandle (cygheap->user.current_token);
+ cygheap->user.current_token = NO_IMPERSONATION;
+ }
+ if (cygheap->user.curr_primary_token != NO_IMPERSONATION)
+ {
+ if (!DuplicateTokenEx (cygheap->user.curr_primary_token, MAXIMUM_ALLOWED,
+ &sec_none, SecurityImpersonation,
+ TokenImpersonation, &cygheap->user.current_token))
+ {
+ __seterrno ();
+ cygheap->user.curr_primary_token = NO_IMPERSONATION;
+ return -1;
+ }
+ set_cygwin_privileges (cygheap->user.current_token);
+ }
+ if (!cygheap->user.reimpersonate ())
+ {
+ __seterrno ();
+ return -1;
+ }
success_9x:
cygheap->user.set_name (pw_new->pw_name);
@@ -2081,12 +2090,6 @@ success_9x:
if (!issamesid)
user_shared_initialize (true);
return 0;
-
-failed:
- CloseHandle (ptok);
-failed_ptok:
- cygheap->user.reimpersonate ();
- return -1;
}
extern "C" int
@@ -2151,7 +2154,6 @@ setegid32 (__gid32_t gid)
user_groups * groups = &cygheap->user.groups;
cygsid gsid;
- HANDLE ptok;
struct __group32 * gr = internal_getgrgid (gid);
if (!gsid.getfromgr (gr))
@@ -2162,29 +2164,24 @@ setegid32 (__gid32_t gid)
myself->gid = gid;
groups->update_pgrp (gsid);
- /* If impersonated, update primary group and revert */
if (cygheap->user.issetuid ())
{
- if (!SetTokenInformation (cygheap->user.token (),
- TokenPrimaryGroup,
- &gsid, sizeof gsid))
- debug_printf ("SetTokenInformation(thread, "
+ /* If impersonated, update impersonation token... */
+ if (!SetTokenInformation (cygheap->user.primary_token (),
+ TokenPrimaryGroup, &gsid, sizeof gsid))
+ debug_printf ("SetTokenInformation(primary_token, "
"TokenPrimaryGroup), %E");
- RevertToSelf ();
- }
- if (!OpenProcessToken (hMainProc, TOKEN_ADJUST_DEFAULT, &ptok))
- debug_printf ("OpenProcessToken(), %E");
- else
- {
- if (!SetTokenInformation (ptok, TokenPrimaryGroup,
+ if (!SetTokenInformation (cygheap->user.token (), TokenPrimaryGroup,
&gsid, sizeof gsid))
- debug_printf ("SetTokenInformation(process, "
- "TokenPrimaryGroup), %E");
- CloseHandle (ptok);
- }
- if (cygheap->user.issetuid ()
- && !ImpersonateLoggedOnUser (cygheap->user.token ()))
- system_printf ("Impersonating in setegid failed, %E");
+ debug_printf ("SetTokenInformation(token, TokenPrimaryGroup), %E");
+ }
+ cygheap->user.deimpersonate ();
+ if (!SetTokenInformation (hProcToken, TokenPrimaryGroup, &gsid, sizeof gsid))
+ debug_printf ("SetTokenInformation(hProcToken, TokenPrimaryGroup), %E");
+ if (!SetTokenInformation (hProcImpToken, TokenPrimaryGroup, &gsid,
+ sizeof gsid))
+ debug_printf ("SetTokenInformation(hProcImpToken, TokenPrimaryGroup), %E");
+ cygheap->user.reimpersonate ();
return 0;
}