From 7119fc0d0b59a8fe8e5a6f25dd3b8162a8b8337a Mon Sep 17 00:00:00 2001 From: Pierre Humblet Date: Wed, 10 Sep 2003 02:12:26 +0000 Subject: 2003-09-09 Pierre Humblet * shared_info.h: Include security.h. (open_shared): Add psa argument. (user_shared_initialize): New declaration. * security.h: Add _SECURITY_H guard. (sec_user): Use sec_none in the no ntsec case. * spawn.cc (spawn_guts): Remove call to load_registry_hive. * syscalls (seteuid32): If warranted, call load_registry_hive, user_shared_initialize and RegCloseKey(HKEY_CURRENT_USER). * shared.cc (user_shared_initialize): New. (open_shared): Add and use psa argument. (memory_init): Move mount table initialization to user_shared_initialize. Call it. --- winsup/cygwin/ChangeLog | 15 +++++++ winsup/cygwin/security.h | 6 ++- winsup/cygwin/shared.cc | 96 ++++++++++++++++++++++++++++++++------------- winsup/cygwin/shared_info.h | 6 ++- winsup/cygwin/spawn.cc | 3 -- winsup/cygwin/syscalls.cc | 17 ++++++-- 6 files changed, 107 insertions(+), 36 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 80da78a..71aa6e5 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,18 @@ +2003-09-09 Pierre Humblet + + * shared_info.h: Include security.h. + (open_shared): Add psa argument. + (user_shared_initialize): New declaration. + * security.h: Add _SECURITY_H guard. + (sec_user): Use sec_none in the no ntsec case. + * spawn.cc (spawn_guts): Remove call to load_registry_hive. + * syscalls (seteuid32): If warranted, call load_registry_hive, + user_shared_initialize and RegCloseKey(HKEY_CURRENT_USER). + * shared.cc (user_shared_initialize): New. + (open_shared): Add and use psa argument. + (memory_init): Move mount table initialization to + user_shared_initialize. Call it. + 2003-09-09 Corinna Vinschen * mmap.cc (mmap64): Change address types from caddr_t to void * diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h index 71ffe4c..0112341 100644 --- a/winsup/cygwin/security.h +++ b/winsup/cygwin/security.h @@ -8,6 +8,9 @@ This software is a copyrighted work licensed under the terms of the Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ +#ifndef _SECURITY_H +#define _SECURITY_H + #include #define DEFAULT_UID DOMAIN_USER_RID_ADMIN @@ -271,5 +274,6 @@ sec_user_nih (char sa_buf[], PSID sid = NULL) extern inline SECURITY_ATTRIBUTES * sec_user (char sa_buf[], PSID sid = NULL) { - return allow_ntsec ? __sec_user (sa_buf, sid, TRUE) : &sec_none_nih; + return allow_ntsec ? __sec_user (sa_buf, sid, TRUE) : &sec_none; } +#endif /*_SECURITY_H*/ diff --git a/winsup/cygwin/shared.cc b/winsup/cygwin/shared.cc index 654ac57..4f9acc1 100644 --- a/winsup/cygwin/shared.cc +++ b/winsup/cygwin/shared.cc @@ -67,7 +67,8 @@ static char *offsets[] = }; void * __stdcall -open_shared (const char *name, int n, HANDLE &shared_h, DWORD size, shared_locations m) +open_shared (const char *name, int n, HANDLE &shared_h, DWORD size, + shared_locations m, PSECURITY_ATTRIBUTES psa) { void *shared; @@ -96,7 +97,7 @@ open_shared (const char *name, int n, HANDLE &shared_h, DWORD size, shared_locat TRUE, mapname); } if (!shared_h && - !(shared_h = CreateFileMapping (INVALID_HANDLE_VALUE, &sec_all, + !(shared_h = CreateFileMapping (INVALID_HANDLE_VALUE, psa, PAGE_READWRITE, 0, size, mapname))) api_fatal ("CreateFileMapping, %E. Terminating."); } @@ -144,6 +145,71 @@ open_shared (const char *name, int n, HANDLE &shared_h, DWORD size, shared_locat return shared; } +void +user_shared_initialize () +{ + char name[UNLEN + 1] = ""; + + /* Temporary code. Will be cleaned up later */ + if (wincap.has_security ()) + { + HANDLE ptok = NULL; + DWORD siz; + cygsid tu; + + if (cygwin_mount_h) /* Reinit */ + tu = cygheap->user.sid (); + else + { + if (!OpenProcessToken (hMainProc, TOKEN_ADJUST_DEFAULT | TOKEN_QUERY, + &ptok)) + system_printf ("OpenProcessToken(): %E"); + else if (!GetTokenInformation (ptok, TokenUser, &tu, sizeof tu, &siz)) + system_printf ("GetTokenInformation (TokenUser): %E"); + else + tu.string (name); + if (ptok) + CloseHandle (ptok); + } + tu.string (name); + } + else + strcpy (name, cygheap->user.name ()); + + if (cygwin_mount_h) + { + if (!UnmapViewOfFile (mount_table)) + debug_printf("UnmapViewOfFile %E"); + if (!ForceCloseHandle (cygwin_mount_h)) + debug_printf("CloseHandle %E"); + cygwin_mount_h = NULL; + } + + mount_table = (mount_info *) open_shared (name, MOUNT_VERSION, + cygwin_mount_h, sizeof (mount_info), + SH_MOUNT_TABLE, &sec_none); + debug_printf ("opening mount table for '%s' at %p", name, + mount_table); + ProtectHandleINH (cygwin_mount_h); + debug_printf ("mount table version %x at %p", mount_table->version, mount_table); + + /* Initialize the Cygwin per-user mount table, if necessary */ + if (!mount_table->version) + { + mount_table->version = MOUNT_VERSION_MAGIC; + debug_printf ("initializing mount table"); + mount_table->cb = sizeof (*mount_table); + if (mount_table->cb != MOUNT_INFO_CB) + system_printf ("size of mount table region changed from %u to %u", + MOUNT_INFO_CB, mount_table->cb); + mount_table->init (); /* Initialize the mount table. */ + } + else if (mount_table->version != MOUNT_VERSION_MAGIC) + multiple_cygwin_problem ("mount", mount_table->version, MOUNT_VERSION); + else if (mount_table->cb != MOUNT_INFO_CB) + multiple_cygwin_problem ("mount table size", mount_table->cb, MOUNT_INFO_CB); +} + void shared_info::initialize (const char *user_name) { @@ -208,31 +274,7 @@ memory_init () cygheap->shared_h = shared_h; ProtectHandleINH (cygheap->shared_h); - /* Allocate memory for the per-user mount table */ - mount_table = (mount_info *) open_shared (user_name, MOUNT_VERSION, - cygwin_mount_h, sizeof (mount_info), - SH_MOUNT_TABLE); - debug_printf ("opening mount table for '%s' at %p", cygheap->user.name (), - mount_table); - ProtectHandleINH (cygwin_mount_h); - debug_printf ("mount table version %x at %p", mount_table->version, mount_table); - - /* Initialize the Cygwin per-user mount table, if necessary */ - if (!mount_table->version) - { - mount_table->version = MOUNT_VERSION_MAGIC; - debug_printf ("initializing mount table"); - mount_table->cb = sizeof (*mount_table); - if (mount_table->cb != MOUNT_INFO_CB) - system_printf ("size of mount table region changed from %u to %u", - MOUNT_INFO_CB, mount_table->cb); - mount_table->init (); /* Initialize the mount table. */ - } - else if (mount_table->version != MOUNT_VERSION_MAGIC) - multiple_cygwin_problem ("mount", mount_table->version, MOUNT_VERSION); - else if (mount_table->cb != MOUNT_INFO_CB) - multiple_cygwin_problem ("mount table size", mount_table->cb, MOUNT_INFO_CB); - + user_shared_initialize (); } unsigned diff --git a/winsup/cygwin/shared_info.h b/winsup/cygwin/shared_info.h index d73d0b0..eb1ae71 100644 --- a/winsup/cygwin/shared_info.h +++ b/winsup/cygwin/shared_info.h @@ -9,6 +9,7 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ #include "tty.h" +#include "security.h" /* Mount table entry */ @@ -189,4 +190,7 @@ struct console_state #endif char *__stdcall shared_name (char *, const char *, int); -void *__stdcall open_shared (const char *name, int n, HANDLE &shared_h, DWORD size, shared_locations); +void *__stdcall open_shared (const char *name, int n, HANDLE &shared_h, DWORD size, + shared_locations, PSECURITY_ATTRIBUTES psa = &sec_all); +extern void user_shared_initialize (); + diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index be469ef..7b05a5c 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -654,9 +654,6 @@ spawn_guts (const char * prog_arg, const char *const *argv, /* Set security attributes with sid */ PSECURITY_ATTRIBUTES sec_attribs = sec_user_nih (sa_buf, sid); - /* Load users registry hive. */ - load_registry_hive (sid); - /* allow the child to interact with our window station/desktop */ HANDLE hwst, hdsk; SECURITY_INFORMATION dsi = DACL_SECURITY_INFORMATION; diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index d153842..b325347 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -2076,9 +2076,9 @@ seteuid32 (__uid32_t uid) user_groups &groups = cygheap->user.groups; HANDLE ptok, new_token = INVALID_HANDLE_VALUE; struct passwd * pw_new; - PSID origpsid, psid2 = NO_SID; - BOOL token_is_internal; - + cygpsid origpsid, psid2 (NO_SID); + BOOL token_is_internal, issamesid; + pw_new = internal_getpwuid (uid); if (!wincap.has_security () && pw_new) goto success_9x; @@ -2154,6 +2154,9 @@ seteuid32 (__uid32_t uid) } else if (new_token != ptok) { + /* Avoid having HKCU use default user */ + load_registry_hive (usersid); + /* Try setting owner to same value as user. */ if (!SetTokenInformation (new_token, TokenOwner, &usersid, sizeof usersid)) @@ -2168,10 +2171,16 @@ seteuid32 (__uid32_t uid) } CloseHandle (ptok); + issamesid = (usersid == (psid2 = cygheap->user.sid ())); cygheap->user.set_sid (usersid); cygheap->user.current_token = new_token == ptok ? INVALID_HANDLE_VALUE - : new_token; + : new_token; + if (!issamesid) /* MS KB 199190 */ + RegCloseKey(HKEY_CURRENT_USER); cygheap->user.reimpersonate (); + if (!issamesid) + user_shared_initialize (); + success_9x: cygheap->user.set_name (pw_new->pw_name); myself->uid = uid; -- cgit v1.1