diff options
author | Christopher Faylor <cgf@redhat.com> | 2003-09-11 04:47:22 +0000 |
---|---|---|
committer | Christopher Faylor <cgf@redhat.com> | 2003-09-11 04:47:22 +0000 |
commit | e110d2668a3cb21ede13338d5e87364685a74ab4 (patch) | |
tree | 7f2fd093880c2a8af04172684c5a013592a5cc6a | |
parent | 93fac648a6e9ed2284823fab85ae1acec15c73be (diff) | |
download | gdb-e110d2668a3cb21ede13338d5e87364685a74ab4.tar.gz |
merge from trunk
-rw-r--r-- | winsup/cygwin/ChangeLog | 301 | ||||
-rw-r--r-- | winsup/cygwin/Makefile.in | 20 | ||||
-rw-r--r-- | winsup/cygwin/cygheap.h | 1 | ||||
-rw-r--r-- | winsup/cygwin/cygwin.din | 11 | ||||
-rw-r--r-- | winsup/cygwin/dir.cc | 2 | ||||
-rw-r--r-- | winsup/cygwin/fhandler_disk_file.cc | 27 | ||||
-rw-r--r-- | winsup/cygwin/include/cygwin/version.h | 4 | ||||
-rw-r--r-- | winsup/cygwin/include/getopt.h | 86 | ||||
-rw-r--r-- | winsup/cygwin/libc/getopt.c (renamed from winsup/cygwin/lib/getopt.c) | 13 | ||||
-rw-r--r-- | winsup/cygwin/libc/iruserok.c (renamed from winsup/cygwin/lib/iruserok.c) | 301 | ||||
-rw-r--r-- | winsup/cygwin/registry.cc | 252 | ||||
-rw-r--r-- | winsup/cygwin/security.h | 6 | ||||
-rw-r--r-- | winsup/cygwin/shared.cc | 93 | ||||
-rw-r--r-- | winsup/cygwin/shared_info.h | 10 | ||||
-rw-r--r-- | winsup/cygwin/spawn.cc | 3 | ||||
-rw-r--r-- | winsup/cygwin/syscalls.cc | 21 | ||||
-rw-r--r-- | winsup/cygwin/uinfo.cc | 80 | ||||
-rw-r--r-- | winsup/cygwin/winsup.h | 8 |
18 files changed, 950 insertions, 289 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index a1e8650512c..6522e5124a7 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,304 @@ +2003-09-10 Pierre Humblet <pierre.humblet@ieee.org> + + * shared_info.h (shared_info::initialize): Remove argument. + * cygheap.h (cygheap_user::init): New declaration. + * uinfo.cc (cygheap_user::init): New. + (internal_getlogin): Move functionality to cygheap_user::init. Open + the process token to update the group sid. + * shared.cc (user_shared_initialize): Get the user information from + cygheap->user. + (shared_info::initialize): Remove argument. Call cygheap->user.init + instead of cygheap->user.set_name. + (memory_init): Do not get the user name and do not pass it to + shared_info::initialize. + * registry.cc (get_registry_hive_path): Make csid a cygpsid. + (load_registry_hive): Ditto. + +2003-09-10 Christopher Faylor <cgf@redhat.com> + + * fhandler_disk_file.cc (num_entries): Take . and .. into account if + they do not exist since cygwin simulates them. + (fhandler_cygdrive::fstat): Ditto. + (fhandler_cygdrive::readdir): Don't do any specific tests on + __d_position when seeing if a drive exists. + +2003-09-10 Corinna Vinschen <corinna@vinschen.de> + + * Makefile.in (DLL_OFILES): Add getopt.o and iruserok.o. + * cygwin.din: Export __check_rhosts_file, __rcmd_errstr, optarg, + opterr, optind, optopt, optreset, getopt, getopt_long, iruserok + and ruserok. + * getopt.c: Moved from lib to here. Define opt* variables as + dllexport. + * iruserok.c: Moved from lib to here. Rearrange function order. + Prefer using 64/32 bit functions. + * syscalls.cc (shell_fp): Define as struct __sFILE64. + (getusershell): Use fopen64 instead of fopen. + * winsup.h: Add declarations for seteuid32, fopen64, + cygwin_gethostbyname and cygwin_inet_addr. + * include/getopt.h: Declare opt* variables dllimport. + * include/cygwin/version.h: Bump API minor number. + +2003-09-10 Christopher Faylor <cgf@redhat.com> + + * exceptions.cc (sig_handle_tty_stop): Check parent PID_NOCLDSTOP + rather than erroneously checking *my own* sigtodo. + +2003-09-10 Christopher Faylor <cgf@redhat.com> + + * Makefile.in: Add some more -fomit-frame-pointer files. + + * path.cc (conv_path_list_buf_size): Free normalized_path or suffer + memory leak. + * syscalls.cc (chroot): Ditto. + +2003-09-10 Corinna Vinschen <corinna@vinschen.de> + + * Makefile.in (DLL_OFILES): Add bsdlib.o. + * autoload.cc (RegisterServiceProcess): Add. + * bsdlib.cc: New file. + (daemon): New function. + (login_tty): Ditto. + (openpty): Ditto. + (forkpty): Ditto. + * cygwin.din: Export daemon, forkpty, login_tty, logwtmp, updwtmp, + openpty and revoke. + * syscalls.cc (updwtmp): New function, writing to wtmp exclusively. + (logwtmp): Ditto. + (login): Call updwtmp instead of writing to wtmp by itself. + (logout): Ditto. + * tty.cc (revoke): New funtion. + * include/paths.h: Define _PATH_DEVNULL. + * include/pty.h: New header. + * include/cygwin/version.h: Bump API minor number. + * include/sys/utmp.h: Declare logwtmp with const arguments. + Declare updwtmp. + * lib/iruserok.c: New file. + (ruserok): New function. + (iruserok): Ditto. + (__ivaliduser): Ditto. + (__icheckhost): Ditto. + +2003-09-10 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_socket.cc (fhandler_socket::fstat): Don't use PC_POSIX. + +2003-09-09 Pierre Humblet <pierre.humblet@ieee.org> + + * 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 <corinna@vinschen.de> + + * mmap.cc (mmap64): Change address types from caddr_t to void * + according to SUSv3. + (mmap): Ditto. + (munmap): Ditto. + (msync): Ditto. + (mprotect): Ditto. Move to before the fhandler methods. + * include/sys/mman.h: Change prototypes accordingly. + +2003-09-08 Christopher Faylor <cgf@redhat.com> + + * dcrt0.cc (dlL_crt0_1): Set __argc_safe after __argc is absolutely + know to be set. + * exceptions.cc (sig_handle_tty_stop): Don't reset sigCONT event since + it is reset automatically. + * fork.cc (fork): Remove obsolete usage of PID_SPLIT_HEAP. + * include/sys/cygwin.h: Ditto. + * sigproc.cc (sig_send): Use sigframe init method to set frame since it + checks for previous ownership of the frame. + * sigproc.h (sigframe::init): Accept an "is_exception" argument. + +2003-09-08 Christopher Faylor <cgf@redhat.com> + + * dir.cc (readdir): Reinstate setting of old ino field for legacy + applications. + * dirent.h (dirent): Rename unused field to __ino32. + +2003-09-08 Christopher Faylor <cgf@redhat.com> + + * passwd.cc (getpwnam_r): Initialize pw_comment field. + +2003-09-08 Christopher Faylor <cgf@redhat.com> + + * passwd.cc (getpwuid_r32): Initialize pw_comment field. + +2003-09-08 Christopher Faylor <cgf@redhat.com> + + * sigproc.cc (wait_sig_inited): Remove assertion since it is racy. + +2003-09-08 Corinna Vinschen <corinna@vinschen.de> + + * cygwin.din: Export endusershell, getusershell and setusershell. + * syscalls.cc (getusershell): New function. + (setusershell): Ditto. + (endusershell): Ditto. + * include/cygwin/version.h: Bump API minor number. + +2003-09-08 Nicholas Wourms <nwourms@netscape.net> + + * cygwin.din: Export argz_add argz_add_sep argz_append argz_count + argz_create argz_create_sep argz_delete argz_extract argz_insert + argz_next argz_replace argz_stringify envz_add envz_entry envz_get + envz_merge envz_remove envz_strip + * include/cygwin/version.h: Bump api minor number. + +2003-09-07 Christopher Faylor <cgf@redhat.com> + + Throughout, remove __d_u.__d_data fields from DIR structure. + * include/sys/dirent.h (dirent): Remvoe old_d_ino. + (DIR): Make __d_dirhash a 64 bit value. Remove __d_data and __d_u. + Add __flags. + * dir.cc (opendir_states): New enum. + (opendir): Clear new DIR __flags field. + (readdir): Fill in '.' and '..' entries if we hit EOF and we haven't + seen them already. Nuke setting of old_d_ino. + (rewinddir): Reset DIR __flags field. + (seekdir64): Ditto. + * fhandler_disk_file.cc (fhandler_cygdrive::fhandler_cygdrive): Remove + special handling of "." and ".." since they are now handled + automatically. + +2003-09-07 Christopher Faylor <cgf@redhat.com> + + * include/cygwin/in.h: Don't define ipv6 stuff unless we call for it + specifically since it isn't really implemented yet. + +2003-09-07 Christopher Faylor <cgf@redhat.com> + + * cygheap.cc (_csbrk): More left coercion cleanup. + * fhandler_tty.cc (fhandler_tty_slave::read): Ditto. + (fhandler_tty_slave::write): Ditto. + * fhandler_windows.cc (fhandler_windows::read): Ditto. + * heap.cc (sbrk): Ditto. + +2003-09-07 Pierre Humblet <pierre.humblet@ieee.org> + + * signal.cc (nanosleep): Improve test for valid values. Round delay up + to resolution. Fix test for negative remainder. Use timeGetTime + through gtod. + (sleep): Round up return value. + +2003-09-07 Pierre Humblet <pierre.humblet@ieee.org> + Christopher Faylor <cgf@redhat.com> + + * hires.h (HIRES_DELAY_MAX): Define. + (hires_ms::minperiod): Declare static. + (hires_ms::resolution): New. + (hires_ms::dmsecs): New. + (hires_ms::prime): Return UINT. + (gtod): Declare. + * times.cc (hires_ms::prime): Always calculate minperiod and set it to + 1 in case of failure. Return minperiod. + (hires_ms::resolution): Define. + (hires_ms::~hires_ms): Delete. + (hires_ms::usecs): Check minperiod to prime. + (gtod) Define as global. + +2003-09-06 Christopher Faylor <cgf@redhat.com> + + Remove left coercion throughout. + +2003-09-04 Pierre Humblet <pierre.humblet@ieee.org> + + * hires.h (hires_ms::~hires_ms): Delete declaration. + * times.cc (hires_ms::~hires_ms): Delete definition.. + +2003-09-04 Christopher Faylor <cgf@redhat.com> + + * dcrt0.cc (__argc_safe): New variable. + (dll_crt0_1): Store argc in __argc_safe, which will theoretically + remain untouched by the user. + * fhandler_console.cc (fhandler_console::read): Silence some compiler + warnings. + * fhandler_raw.cc (fhandler_dev_raw::raw_read): Ditto. + * pinfo.cc (_pinfo::commune_recv): Carefully bound argv scan and check + for potentially bad pointers since user could have set argv cell to + anythinw. + * cygheap.h (CYGHEAPSIZE): Bump up size. + +2003-09-04 Corinna Vinschen <corinna@vinschen.de> + + * sysconf.cc (sysconf): Return more accurate value for _SC_AVPHYS_PAGES. + +2003-09-04 Corinna Vinschen <corinna@vinschen.de> + + * mmap.cc: Restructure. Add, remove and rewrite comments throughout + for better readability. Change function names for better + understanding. + (MAP_SET): Accomodate name change from map_map_ to page_map_. + (MAP_CLR): Ditto. + (MAP_ISSET): Ditto. + (mmap_record::page_map_): Rename from page_map_. + (mmap_record::get_map): Remove. + (mmap_record::alloc_page_map): Rename from alloc_map. Return bool + indicating success of cygheap memory allocation. + (mmap_record::free_page_map): Rename from free_map. + (mmap_record::fixup_page_map): Rename from fixup_map. + (mmap_record::find_unused_pages): Rename from find_empty. + (mmap_record::map_pages): Rename from map_map. + (mmap_record::unmap_pages): Rename from unmap_map. + (class list): Make all class members private. + (list::list): Remove. + (list::~list): Remove. + (list::get_fd): New attribute reader. + (list::get_hash): Ditto. + (list::get_record): Ditto. + (list::add_record): Manage all allocation for mmap_records. Check + for failed memory allocation and return NULL if so. + (list::set): New function. + (list::del_record): Rename from erase. Return true if last mmap_record + has been deleted, false otherwise. Check for legal incoming index + value. + (list::erase): Remove erase/0. + (list::search_record): Rename from match. + (map::map): Remove. + (map::~map): Remove. + (map::add_list): Manage all allocation for lists. Check for failed + memory allocation and return NULL if so. + (map::get_list): New method. + (map::del_list): Rename from erase. Check for legal incoming index + value. + (mmap64): Check for failed mmap_record memory allocation. Return + with MAP_FAILED and errno set to ENOMEM if so. + (munmap): Rearrange loop using new list and mmap_record accessor + functions. Rename loop index variables for better understanding. + Check if list can be deleted after last mmap_record in it has been + deleted. + (msync): Rearrange loop using new list and mmap_record accessor + functions. Rename loop index variables for better understanding. + (fixup_mmaps_after_fork): Ditto. + +2003-09-03 Christopher Faylor <cgf@redhat.com> + + * cxx.cc (new): Fix formatting. Just return result of ccalloc rather + than calling memset explicitly. + +2003-09-03 Christopher Faylor <cgf@redhat.com> + + * exceptions.cc (set_process_mask): Set pending signals only when + signals become unmasked. + * sigproc.cc (pending_signals): Flip back to a global. + (wait_sig): Don't set pending signals when there is an armed semaphore + or signal is blocked. + + * shared.cc (shared_info::initialize): Add a username parameter for + user-mode mounts. Reorganize to try to avoid startup race. + (memory_init): Move some stuff into shared_info::initialize. + * shared_info.h (shared_info::initialize): Change declaration. + (CURR_SHARED_MAGIC): Update. + 2003-09-01 Christopher Faylor <cgf@redhat.com> * include/cygwin/version.h: Bump DLL minor number to 4. diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index 30a75226550..a0611c870db 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -148,7 +148,7 @@ DLL_IMPORTS:=$(w32api_lib)/libkernel32.a MT_SAFE_OBJECTS:= # Please maintain this list in sorted order, with maximum files per 80 col line -DLL_OFILES:=assert.o autoload.o cxx.o bsdlib.o cygheap.o cygthread.o dcrt0.o \ +DLL_OFILES:=assert.o autoload.o bsdlib.o cxx.o cygheap.o cygthread.o dcrt0.o \ debug.o delqueue.o devices.o dir.o dlfcn.o dll_init.o dtable.o environ.o \ errno.o exceptions.o exec.o external.o fcntl.o fhandler.o \ fhandler_clipboard.o fhandler_console.o fhandler_disk_file.o \ @@ -157,15 +157,15 @@ DLL_OFILES:=assert.o autoload.o cxx.o bsdlib.o cygheap.o cygthread.o dcrt0.o \ fhandler_random.o fhandler_raw.o fhandler_registry.o fhandler_serial.o \ fhandler_socket.o fhandler_tape.o fhandler_termios.o \ fhandler_tty.o fhandler_virtual.o fhandler_windows.o \ - fhandler_zero.o fnmatch.o fork.o glob.o grp.o heap.o init.o ioctl.o \ - ipc.o localtime.o malloc_wrapper.o miscfuncs.o mmap.o msg.o \ - net.o netdb.o ntea.o passwd.o path.o pinfo.o pipe.o poll.o pthread.o \ - regcomp.o regerror.o regexec.o regfree.o registry.o resource.o \ - scandir.o sched.o sec_acl.o sec_helper.o security.o select.o sem.o \ - shared.o shm.o signal.o sigproc.o smallprint.o spawn.o strace.o \ - strsep.o sync.o syscalls.o sysconf.o syslog.o termios.o thread.o \ - times.o tty.o uinfo.o uname.o v8_regexp.o v8_regerror.o v8_regsub.o \ - wait.o wincap.o window.o \ + fhandler_zero.o fnmatch.o fork.o getopt.o glob.o grp.o heap.o init.o \ + ioctl.o ipc.o iruserok.o localtime.o malloc_wrapper.o miscfuncs.o \ + mmap.o msg.o net.o netdb.o ntea.o passwd.o path.o pinfo.o pipe.o \ + poll.o pthread.o regcomp.o regerror.o regexec.o regfree.o registry.o \ + resource.o scandir.o sched.o sec_acl.o sec_helper.o security.o \ + select.o sem.o shared.o shm.o signal.o sigproc.o smallprint.o spawn.o \ + strace.o strsep.o sync.o syscalls.o sysconf.o syslog.o termios.o \ + thread.o times.o tty.o uinfo.o uname.o v8_regexp.o v8_regerror.o \ + v8_regsub.o wait.o wincap.o window.o \ $(EXTRA_DLL_OFILES) $(EXTRA_OFILES) $(MALLOC_OFILES) $(MT_SAFE_OBJECTS) GMON_OFILES:=gmon.o mcount.o profil.o diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h index a06ee9260b0..84d983e3344 100644 --- a/winsup/cygwin/cygheap.h +++ b/winsup/cygwin/cygheap.h @@ -134,6 +134,7 @@ public: ~cygheap_user (); + void init (); void set_name (const char *new_name); const char *name () const { return pname; } diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din index 227d13569b4..a61edbdb678 100644 --- a/winsup/cygwin/cygwin.din +++ b/winsup/cygwin/cygwin.din @@ -3,10 +3,12 @@ LIBRARY "cygwin1.dll" BASE=0x61000000 EXPORTS __argc DATA __argv DATA +__check_rhosts_file DATA __cygwin_environ DATA __cygwin_user_data DATA __mb_cur_max DATA __progname DATA +__rcmd_errstr DATA _check_for_executable DATA _ctype_ DATA _daylight DATA @@ -17,6 +19,11 @@ sys_nerr = _sys_nerr DATA _timezone DATA _tzname DATA h_errno DATA +optarg DATA +opterr DATA +optind DATA +optopt DATA +optreset DATA reent_data DATA @ALLOCA@ @DEF_DLL_ENTRY@ @@ -617,6 +624,8 @@ getmntent _getmntent = getmntent getmode _getmode = getmode +getopt +getopt_long getpagesize _getpagesize = getpagesize getpass @@ -704,6 +713,8 @@ ioctl _ioctl = ioctl iprintf _iprintf = iprintf +iruserok +ruserok isalnum _isalnum = isalnum isalpha diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc index 902746edf6f..36cabbd72dd 100644 --- a/winsup/cygwin/dir.cc +++ b/winsup/cygwin/dir.cc @@ -127,12 +127,14 @@ readdir (DIR *dir) res = dir->__d_dirent; strcpy (res->d_name, "."); dir->__flags |= opendir_saw_dot; + dir->__d_position++; } else if (!(dir->__flags & opendir_saw_dot_dot)) { res = dir->__d_dirent; strcpy (res->d_name, ".."); dir->__flags |= opendir_saw_dot_dot; + dir->__d_position++; } } diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index b034e1f54de..93b06061558 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -53,14 +53,18 @@ num_entries (const char *win32_name) if (handle == INVALID_HANDLE_VALUE) return 2; /* 2 is the minimum number of links to a dir, so... */ - count ++; + int saw_dot = 2; while (FindNextFileA (handle, &buf)) { - if ((buf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) - count ++; + if (buf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + count++; + if (buf.cFileName[0] == '.' + && (buf.cFileName[1] == '\0' + || (buf.cFileName[1] == '.' && buf.cFileName[2] == '\0'))) + saw_dot--; } FindClose (handle); - return count; + return count + saw_dot; } int __stdcall @@ -761,7 +765,7 @@ fhandler_cygdrive::fstat (struct __stat64 *buf) buf->st_mode = S_IFDIR | 0555; if (!ndrives) set_drives (); - buf->st_nlink = ndrives; + buf->st_nlink = ndrives + 2; return 0; } @@ -784,19 +788,14 @@ fhandler_cygdrive::readdir (DIR *dir) return fhandler_disk_file::readdir (dir); if (!pdrive || !*pdrive) return NULL; - else if (dir->__d_position > 1 - && GetFileAttributes (pdrive) == INVALID_FILE_ATTRIBUTES) + if (GetFileAttributes (pdrive) == INVALID_FILE_ATTRIBUTES) { pdrive = strchr (pdrive, '\0') + 1; return readdir (dir); } - else if (*pdrive == '.') - strcpy (dir->__d_dirent->d_name, pdrive); - else - { - *dir->__d_dirent->d_name = cyg_tolower (*pdrive); - dir->__d_dirent->d_name[1] = '\0'; - } + + *dir->__d_dirent->d_name = cyg_tolower (*pdrive); + dir->__d_dirent->d_name[1] = '\0'; dir->__d_position++; pdrive = strchr (pdrive, '\0') + 1; syscall_printf ("%p = readdir (%p) (%s)", &dir->__d_dirent, dir, diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index c37f52910d8..1c92343d910 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -217,13 +217,15 @@ details. */ 92: Export getusershell, setusershell, endusershell 93: Export daemon, forkpty, openpty, iruserok, ruserok, login_tty, openpty, forkpty, revoke, logwtmp, updwtmp + 94: Export getopt, getopt_long, optarg, opterr, optind, optopt, + optreset, __check_rhosts_file, __rcmd_errstr. */ /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 93 +#define CYGWIN_VERSION_API_MINOR 94 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible diff --git a/winsup/cygwin/include/getopt.h b/winsup/cygwin/include/getopt.h new file mode 100644 index 00000000000..ba095ba2f5c --- /dev/null +++ b/winsup/cygwin/include/getopt.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 1987, 1993, 1994, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __GETOPT_H__ +#define __GETOPT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __INSIDE_CYGWIN__ +extern int __declspec(dllimport) opterr; /* if error message should be printed */ +extern int __declspec(dllimport) optind; /* index into parent argv vector */ +extern int __declspec(dllimport) optopt; /* character checked for validity */ +extern int __declspec(dllimport) optreset; /* reset getopt */ +extern char __declspec(dllimport) *optarg; /* argument associated with option */ +#endif + +int getopt (int, char * const *, const char *); + +#ifdef __cplusplus +} +#endif + +#endif /* __GETOPT_H__ */ + +#ifndef __UNISTD_GETOPT__ +#ifndef __GETOPT_LONG_H__ +#define __GETOPT_LONG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +struct option { + const char *name; + int has_arg; + int *flag; + int val; +}; + +int getopt_long (int, char *const *, const char *, const struct option *, int *); +#ifndef HAVE_DECL_GETOPT +#define HAVE_DECL_GETOPT 1 +#endif + +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +#ifdef __cplusplus +} +#endif + +#endif /* __GETOPT_LONG_H__ */ +#endif /* __UNISTD_GETOPT__ */ diff --git a/winsup/cygwin/lib/getopt.c b/winsup/cygwin/libc/getopt.c index b5d5a23b91d..5d97945fa93 100644 --- a/winsup/cygwin/lib/getopt.c +++ b/winsup/cygwin/libc/getopt.c @@ -36,6 +36,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include "winsup.h" #include <assert.h> #include <errno.h> #include <stdlib.h> @@ -52,11 +53,11 @@ #ifdef __weak_alias __weak_alias(getopt,_getopt) #endif -int opterr = 1; /* if error message should be printed */ -int optind = 1; /* index into parent argv vector */ -int optopt = '?'; /* character checked for validity */ -int optreset; /* reset getopt */ -char *optarg; /* argument associated with option */ +int __declspec(dllexport) opterr; /* if error message should be printed */ +int __declspec(dllexport) optind; /* index into parent argv vector */ +int __declspec(dllexport) optopt; /* character checked for validity */ +int __declspec(dllexport) optreset; /* reset getopt */ +char __declspec(dllexport) *optarg; /* argument associated with option */ #endif #ifdef __weak_alias @@ -66,7 +67,7 @@ __weak_alias(getopt_long,_getopt_long) #ifndef __CYGWIN__ #define __progname __argv[0] #else -extern char __declspec(dllimport) *__progname; +extern char *__progname; #endif #define IGNORE_FIRST (*options == '-' || *options == '+') diff --git a/winsup/cygwin/lib/iruserok.c b/winsup/cygwin/libc/iruserok.c index 5e957184ed9..8326dd0a549 100644 --- a/winsup/cygwin/lib/iruserok.c +++ b/winsup/cygwin/libc/iruserok.c @@ -36,174 +36,52 @@ * SUCH DAMAGE. */ -#ifdef __CYGWIN__ -#define HAVE_MALLOC_H -#define HAVE_STDLIB_H -#define HAVE_STRING_H -#define TIME_WITH_SYS_TIME -#define PATH_HEQUIV "/etc/hosts.equiv" - -static int __ivaliduser(); -static int __icheckhost(); - -struct hostent *cygwin_gethostbyname (const char *name); -unsigned long cygwin_inet_addr (const char *cp); - -#define gethostbyname cygwin_gethostbyname -#define inet_addr cygwin_inet_addr -#endif - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif +#include "winsup.h" #include <pwd.h> -#include <sys/file.h> -#include <sys/signal.h> #include <sys/stat.h> -#include <sys/types.h> -#include <sys/uio.h> -#include <sys/param.h> -#include <sys/socket.h> -#ifdef HAVE_MALLOC_H #include <malloc.h> -#endif -#if defined(STDC_HEADERS) || defined(HAVE_STDLIB_H) -#include <stdlib.h> -#endif -#ifdef HAVE_STRING_H -# include <string.h> -#endif -#include <netinet/in.h> -#ifdef HAVE_ARPA_NAMESER_H -# include <arpa/nameser.h> -#endif +#include <string.h> #include <netdb.h> -#include <unistd.h> #include <ctype.h> #include <stdio.h> #include <errno.h> -#ifdef TIME_WITH_SYS_TIME -# include <sys/time.h> -# include <time.h> -#else -# ifdef HAVE_SYS_TIME_H -# include <sys/time.h> -# else -# include <time.h> -# endif -#endif -#ifndef __CYGWIN__ -#include <resolv.h> +#include <sys/time.h> +#include <time.h> + +#ifndef PATH_HEQUIV +# define PATH_HEQUIV "/etc/hosts.equiv" #endif -int __check_rhosts_file = 1; +int __check_rhosts_file = 1; const char *__rcmd_errstr; -int -ruserok(rhost, superuser, ruser, luser) - const char *rhost; - int superuser; - const char *ruser; - const char *luser; -{ - struct hostent *hp; - u_long addr; - char **ap; - - if ((hp = gethostbyname(rhost)) == NULL) - return (-1); - for (ap = hp->h_addr_list; *ap; ++ap) { - bcopy(*ap, &addr, sizeof(addr)); - if (iruserok(addr, superuser, ruser, luser) == 0) - return (0); - } - return (-1); -} - /* - * New .rhosts strategy: We are passed an ip address. We spin through - * hosts.equiv and .rhosts looking for a match. When the .rhosts only - * has ip addresses, we don't have to trust a nameserver. When it - * contains hostnames, we spin through the list of addresses the nameserver - * gives us and look for a match. - * - * Returns 0 if ok, -1 if not ok. + * Returns "true" if match, 0 if no match. */ -int -iruserok(raddr, superuser, ruser, luser) +static int +__icheckhost(raddr, lhost) u_long raddr; - int superuser; - const char *ruser; - const char *luser; + register char *lhost; { - register const char *cp; - struct stat sbuf; - struct passwd *pwd; - FILE *hostf; - uid_t uid; - int first = 1; - char *pbuf; + register struct hostent *hp; + register u_long laddr; + register char **pp; - first = 1; - hostf = superuser ? NULL : fopen(PATH_HEQUIV, "r"); -again: - if (hostf) { - if (__ivaliduser(hostf, raddr, luser, ruser) == 0) { - (void) fclose(hostf); - return(0); - } - (void) fclose(hostf); - } - if (first == 1 && (__check_rhosts_file || superuser)) { - first = 0; - if ((pwd = getpwnam(luser)) == NULL) - return(-1); + /* Try for raw ip address first. */ + if (isdigit(*lhost) && (long)(laddr = cygwin_inet_addr(lhost)) != -1) + return (raddr == laddr); - pbuf = malloc (strlen (pwd->pw_dir) + sizeof "/.rhosts"); - if (! pbuf) - { - errno = ENOMEM; - return -1; - } - strcpy (pbuf, pwd->pw_dir); - strcat (pbuf, "/.rhosts"); + /* Better be a hostname. */ + if ((hp = cygwin_gethostbyname(lhost)) == NULL) + return (0); - /* - * Change effective uid while opening .rhosts. If root and - * reading an NFS mounted file system, can't read files that - * are protected read/write owner only. - */ - uid = geteuid(); - (void)seteuid(pwd->pw_uid); - hostf = fopen(pbuf, "r"); - (void)seteuid(uid); + /* Spin through ip addresses. */ + for (pp = hp->h_addr_list; *pp; ++pp) + if (!bcmp(&raddr, *pp, sizeof(u_long))) + return (1); - if (hostf == NULL) - return(-1); - /* - * If not a regular file, or is owned by someone other than - * user or root or if writeable by anyone but the owner, quit. - */ - cp = NULL; - if (lstat(pbuf, &sbuf) < 0) - cp = ".rhosts not regular file"; - else if (!S_ISREG(sbuf.st_mode)) - cp = ".rhosts not regular file"; - else if (fstat(fileno(hostf), &sbuf) < 0) - cp = ".rhosts fstat failed"; - else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid) - cp = "bad .rhosts owner"; - else if (sbuf.st_mode & (S_IWGRP|S_IWOTH)) - cp = ".rhosts writeable by other than owner"; - /* If there were any problems, quit. */ - if (cp) { - __rcmd_errstr = (char *) cp; - fclose(hostf); - return(-1); - } - goto again; - } - return (-1); + /* No match. */ + return (0); } /* @@ -212,12 +90,9 @@ again: * * Returns 0 if ok, -1 if not ok. */ -#ifdef __CYGWIN__ -static -#endif -int +static int __ivaliduser(hostf, raddr, luser, ruser) - FILE *hostf; + struct __sFILE64 *hostf; u_long raddr; const char *luser; const char *ruser; @@ -287,33 +162,109 @@ __ivaliduser(hostf, raddr, luser, ruser) } /* - * Returns "true" if match, 0 if no match. + * New .rhosts strategy: We are passed an ip address. We spin through + * hosts.equiv and .rhosts looking for a match. When the .rhosts only + * has ip addresses, we don't have to trust a nameserver. When it + * contains hostnames, we spin through the list of addresses the nameserver + * gives us and look for a match. + * + * Returns 0 if ok, -1 if not ok. */ -#ifdef __CYGWIN__ -static -#endif int -__icheckhost(raddr, lhost) +iruserok(raddr, superuser, ruser, luser) u_long raddr; - register char *lhost; + int superuser; + const char *ruser; + const char *luser; { - register struct hostent *hp; - register u_long laddr; - register char **pp; + register const char *cp; + struct __stat64 sbuf; + struct passwd *pwd; + struct __sFILE64 *hostf; - /* Try for raw ip address first. */ - if (isdigit(*lhost) && (long)(laddr = inet_addr(lhost)) != -1) - return (raddr == laddr); + uid_t uid; + int first = 1; + char *pbuf; - /* Better be a hostname. */ - if ((hp = gethostbyname(lhost)) == NULL) - return (0); + first = 1; + hostf = superuser ? NULL : fopen64(PATH_HEQUIV, "rt"); +again: + if (hostf) { + if (__ivaliduser(hostf, raddr, luser, ruser) == 0) { + (void) fclose(hostf); + return(0); + } + (void) fclose(hostf); + } + if (first == 1 && (__check_rhosts_file || superuser)) { + first = 0; + if ((pwd = getpwnam(luser)) == NULL) + return(-1); - /* Spin through ip addresses. */ - for (pp = hp->h_addr_list; *pp; ++pp) - if (!bcmp(&raddr, *pp, sizeof(u_long))) - return (1); + pbuf = malloc (strlen (pwd->pw_dir) + sizeof "/.rhosts"); + if (! pbuf) + { + errno = ENOMEM; + return -1; + } + strcpy (pbuf, pwd->pw_dir); + strcat (pbuf, "/.rhosts"); - /* No match. */ - return (0); + /* + * Change effective uid while opening .rhosts. If root and + * reading an NFS mounted file system, can't read files that + * are protected read/write owner only. + */ + uid = geteuid32(); + (void)seteuid32(pwd->pw_uid); + hostf = fopen64(pbuf, "rt"); + (void)seteuid32(uid); + + if (hostf == NULL) + return(-1); + /* + * If not a regular file, or is owned by someone other than + * user or root or if writeable by anyone but the owner, quit. + */ + cp = NULL; + if (lstat64(pbuf, &sbuf) < 0) + cp = ".rhosts not regular file"; + else if (!S_ISREG(sbuf.st_mode)) + cp = ".rhosts not regular file"; + else if (fstat64(fileno(hostf), &sbuf) < 0) + cp = ".rhosts fstat failed"; + else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid) + cp = "bad .rhosts owner"; + else if (sbuf.st_mode & (S_IWGRP|S_IWOTH)) + cp = ".rhosts writeable by other than owner"; + /* If there were any problems, quit. */ + if (cp) { + __rcmd_errstr = (char *) cp; + fclose(hostf); + return(-1); + } + goto again; + } + return (-1); +} + +int +ruserok(rhost, superuser, ruser, luser) + const char *rhost; + int superuser; + const char *ruser; + const char *luser; +{ + struct hostent *hp; + u_long addr; + char **ap; + + if ((hp = cygwin_gethostbyname(rhost)) == NULL) + return (-1); + for (ap = hp->h_addr_list; *ap; ++ap) { + bcopy(*ap, &addr, sizeof(addr)); + if (iruserok(addr, superuser, ruser, luser) == 0) + return (0); + } + return (-1); } diff --git a/winsup/cygwin/registry.cc b/winsup/cygwin/registry.cc new file mode 100644 index 00000000000..d1443eee7a5 --- /dev/null +++ b/winsup/cygwin/registry.cc @@ -0,0 +1,252 @@ +/* registry.cc: registry interface + + Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +#include "winsup.h" +#include "shared_info.h" +#include "registry.h" +#include "security.h" +#include <cygwin/version.h> + +static char NO_COPY cygnus_class[] = "cygnus"; + +reg_key::reg_key (HKEY top, REGSAM access, ...) +{ + va_list av; + va_start (av, access); + build_reg (top, access, av); + va_end (av); +} + +reg_key::reg_key (REGSAM access, ...) +{ + va_list av; + + new (this) reg_key (HKEY_CURRENT_USER, access, "SOFTWARE", + CYGWIN_INFO_CYGNUS_REGISTRY_NAME, + CYGWIN_INFO_CYGWIN_REGISTRY_NAME, NULL); + + HKEY top = key; + va_start (av, access); + build_reg (top, KEY_READ, av); + va_end (av); + if (top != key) + RegCloseKey (top); +} + +reg_key::reg_key (REGSAM access) +{ + new (this) reg_key (HKEY_CURRENT_USER, access, "SOFTWARE", + CYGWIN_INFO_CYGNUS_REGISTRY_NAME, + CYGWIN_INFO_CYGWIN_REGISTRY_NAME, + CYGWIN_INFO_CYGWIN_MOUNT_REGISTRY_NAME, NULL); +} + +void +reg_key::build_reg (HKEY top, REGSAM access, va_list av) +{ + char *name; + HKEY r = top; + key_is_invalid = 0; + + /* FIXME: Most of the time a valid mount area should exist. Perhaps + we should just try an open of the correct key first and only resort + to this method in the unlikely situation that it's the first time + the current mount areas are being used. */ + + while ((name = va_arg (av, char *)) != NULL) + { + DWORD disp; + int res = RegCreateKeyExA (r, + name, + 0, + cygnus_class, + REG_OPTION_NON_VOLATILE, + access, + &sec_none_nih, + &key, + &disp); + if (r != top) + RegCloseKey (r); + r = key; + if (res != ERROR_SUCCESS) + { + key_is_invalid = res; + debug_printf ("failed to create key %s in the registry", name); + break; + } + + /* If we're considering the mounts key, check if it had to + be created and set had_to_create appropriately. */ + if (strcmp (name, CYGWIN_INFO_CYGWIN_MOUNT_REGISTRY_NAME) == 0) + if (disp == REG_CREATED_NEW_KEY) + mount_table->had_to_create_mount_areas++; + } +} + +/* Given the current registry key, return the specific int value + requested. Return def on failure. */ + +int +reg_key::get_int (const char *name, int def) +{ + DWORD type; + DWORD dst; + DWORD size = sizeof (dst); + + if (key_is_invalid) + return def; + + LONG res = RegQueryValueExA (key, name, 0, &type, (unsigned char *) &dst, + &size); + + if (type != REG_DWORD || res != ERROR_SUCCESS) + return def; + + return dst; +} + +/* Given the current registry key, set a specific int value. */ + +int +reg_key::set_int (const char *name, int val) +{ + DWORD value = val; + if (key_is_invalid) + return key_is_invalid; + + return (int) RegSetValueExA (key, name, 0, REG_DWORD, + (unsigned char *) &value, sizeof (value)); +} + +/* Given the current registry key, return the specific string value + requested. Return zero on success, non-zero on failure. */ + +int +reg_key::get_string (const char *name, char *dst, size_t max, const char * def) +{ + DWORD size = max; + DWORD type; + LONG res; + + if (key_is_invalid) + res = key_is_invalid; + else + res = RegQueryValueExA (key, name, 0, &type, (unsigned char *) dst, &size); + + if ((def != 0) && ((type != REG_SZ) || (res != ERROR_SUCCESS))) + strcpy (dst, def); + return (int) res; +} + +/* Given the current registry key, set a specific string value. */ + +int +reg_key::set_string (const char *name, const char *src) +{ + if (key_is_invalid) + return key_is_invalid; + return (int) RegSetValueExA (key, name, 0, REG_SZ, (unsigned char*) src, + strlen (src) + 1); +} + +/* Return the handle to key. */ + +HKEY +reg_key::get_key () +{ + return key; +} + +/* Delete subkey of current key. Returns the error code from the + RegDeleteKeyA invocation. */ + +int +reg_key::kill (const char *name) +{ + if (key_is_invalid) + return key_is_invalid; + return RegDeleteKeyA (key, name); +} + +/* Delete the value specified by name of current key. Returns the error code + from the RegDeleteValueA invocation. */ + +int +reg_key::killvalue (const char *name) +{ + if (key_is_invalid) + return key_is_invalid; + return RegDeleteValueA (key, name); +} + +reg_key::~reg_key () +{ + if (!key_is_invalid) + RegCloseKey (key); + key_is_invalid = 1; +} + +char * +get_registry_hive_path (const PSID psid, char *path) +{ + char sid[256]; + char key[256]; + HKEY hkey; + + if (!psid || !path) + return NULL; + cygpsid csid (psid); + csid.string (sid); + strcpy (key,"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\"); + strcat (key, sid); + if (!RegOpenKeyExA (HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hkey)) + { + char buf[256]; + DWORD type, siz; + + key[0] = '\0'; + if (!RegQueryValueExA (hkey, "ProfileImagePath", 0, &type, + (BYTE *)buf, (siz = 256, &siz))) + ExpandEnvironmentStringsA (buf, key, 256); + RegCloseKey (hkey); + if (key[0]) + return strcpy (path, key); + } + return NULL; +} + +void +load_registry_hive (PSID psid) +{ + char sid[256]; + char path[MAX_PATH + 1]; + HKEY hkey; + LONG ret; + + if (!psid) + return; + /* Check if user hive is already loaded. */ + cygpsid csid (psid); + csid.string (sid); + if (!RegOpenKeyExA (HKEY_USERS, sid, 0, KEY_READ, &hkey)) + { + debug_printf ("User registry hive for %s already exists", sid); + RegCloseKey (hkey); + return; + } + set_process_privilege (SE_RESTORE_NAME); + if (get_registry_hive_path (psid, path)) + { + strcat (path, "\\NTUSER.DAT"); + if ((ret = RegLoadKeyA (HKEY_USERS, sid, path)) != ERROR_SUCCESS) + debug_printf ("Loading user registry hive for %s failed: %d", sid, ret); + } +} + diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h index 71ffe4cecaa..0112341a308 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 <accctrl.h> #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 997e0f622cd..0862ef71ae9 100644 --- a/winsup/cygwin/shared.cc +++ b/winsup/cygwin/shared.cc @@ -1,6 +1,6 @@ /* shared.cc: shared data area support. - Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. + Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc. This file is part of Cygwin. @@ -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."); } @@ -145,7 +146,54 @@ open_shared (const char *name, int n, HANDLE &shared_h, DWORD size, shared_locat } void -shared_info::initialize (const char *user_name) +user_shared_initialize () +{ + char name[UNLEN > 127 ? UNLEN + 1 : 128] = ""; + + if (wincap.has_security ()) + { + cygsid tu (cygheap->user.sid ()); + tu.string (name); + } + else + strcpy (name, cygheap->user.name ()); + + if (cygwin_mount_h) /* Reinit */ + { + 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 () { DWORD sversion = (DWORD) InterlockedExchange ((LONG *) &version, SHARED_VERSION_MAGIC); if (!sversion) @@ -171,7 +219,7 @@ shared_info::initialize (const char *user_name) if (!cygheap) { cygheap_init (); - cygheap->user.set_name (user_name); + cygheap->user.init (); } heap_init (); @@ -189,12 +237,6 @@ memory_init () { getpagesize (); - char user_name[UNLEN + 1]; - DWORD user_name_len = UNLEN + 1; - - if (!GetUserName (user_name, &user_name_len)) - strcpy (user_name, "unknown"); - /* Initialize general shared memory */ HANDLE shared_h = cygheap ? cygheap->shared_h : NULL; cygwin_shared = (shared_info *) open_shared ("shared", @@ -203,36 +245,11 @@ memory_init () sizeof (*cygwin_shared), SH_CYGWIN_SHARED); - cygwin_shared->initialize (user_name); - + cygwin_shared->initialize (); 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 b11ecb3ac76..4ae79ded9c0 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 */ @@ -141,7 +142,7 @@ public: #define SHARED_INFO_CB 47112 -#define CURR_SHARED_MAGIC 0x53f1a7f4U +#define CURR_SHARED_MAGIC 0x359218a2U /* NOTE: Do not make gratuitous changes to the names or organization of the below class. The layout is checksummed to determine compatibility between @@ -156,7 +157,7 @@ class shared_info tty_list tty; delqueue_list delqueue; - void initialize (const char *); + void initialize (); unsigned heap_chunk_size (); }; @@ -190,4 +191,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 fe4efbad0e5..402dd07448b 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 a3d7a81558e..54116caf7c3 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -2141,9 +2141,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; @@ -2219,6 +2219,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)) @@ -2233,10 +2236,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; @@ -2975,7 +2984,7 @@ long gethostid(void) #define ETC_SHELLS "/etc/shells" static int shell_index; -static FILE *shell_fp; +static struct __sFILE64 *shell_fp; extern "C" char * getusershell () @@ -2994,7 +3003,7 @@ getusershell () static char buf[MAX_PATH]; int ch, buf_idx; - if (!shell_fp && !(shell_fp = fopen (ETC_SHELLS, "rt"))) + if (!shell_fp && !(shell_fp = fopen64 (ETC_SHELLS, "rt"))) { if (def_shells[shell_index]) return strcpy (buf, def_shells[shell_index++]); diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index 29daca13dec..8cd1a42d9d2 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -30,42 +30,55 @@ details. */ #include "environ.h" #include "pwdgrp.h" +/* Initialize the part of cygheap_user that does not depend on files. + The information is used in shared.cc for the user shared. + Final initialization occurs in uinfo_init */ void -internal_getlogin (cygheap_user &user) +cygheap_user::init() { - struct passwd *pw = NULL; - HANDLE ptok = INVALID_HANDLE_VALUE; + char user_name[UNLEN + 1]; + DWORD user_name_len = UNLEN + 1; + + set_name (GetUserName (user_name, &user_name_len) ? user_name : "unknown"); - myself->gid = UNKNOWN_GID; if (wincap.has_security ()) { - DWORD siz; + HANDLE ptok = NULL; + DWORD siz, ret; cygsid tu; - DWORD ret = 0; - /* Try to get the SID either from current process and - store it in user.psid */ + /* Get the SID from current process and store it in user.psid */ 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 if (!(ret = user.set_sid (tu))) - system_printf ("Couldn't retrieve SID from access token!"); - else if (!GetTokenInformation (ptok, TokenPrimaryGroup, - &user.groups.pgsid, sizeof tu, &siz)) - system_printf ("GetTokenInformation (TokenPrimaryGroup): %E"); - /* We must set the user name, uid and gid. - If we have a SID, try to get the corresponding Cygwin - password entry. Set user name which can be different - from the Windows user name */ - if (ret) + else { - pw = internal_getpwsid (tu); + if (!GetTokenInformation (ptok, TokenUser, &tu, sizeof tu, &siz)) + system_printf ("GetTokenInformation (TokenUser): %E"); + else if (!(ret = set_sid (tu))) + system_printf ("Couldn't retrieve SID from access token!"); /* Set token owner to the same value as token user */ - if (!SetTokenInformation (ptok, TokenOwner, &tu, sizeof tu)) + else if (!SetTokenInformation (ptok, TokenOwner, &tu, sizeof tu)) debug_printf ("SetTokenInformation(TokenOwner): %E"); - } + if (!GetTokenInformation (ptok, TokenPrimaryGroup, + &groups.pgsid, sizeof tu, &siz)) + system_printf ("GetTokenInformation (TokenPrimaryGroup): %E"); + CloseHandle (ptok); + } + } +} + +void +internal_getlogin (cygheap_user &user) +{ + struct passwd *pw = NULL; + + myself->gid = UNKNOWN_GID; + + if (wincap.has_security ()) + { + cygpsid psid = user.sid (); + pw = internal_getpwsid (psid); } if (!pw && !(pw = internal_getpwnam (user.name ())) @@ -81,19 +94,24 @@ internal_getlogin (cygheap_user &user) cygsid gsid; if (gsid.getfromgr (internal_getgrgid (pw->pw_gid))) { - /* Set primary group to the group in /etc/passwd. */ - if (!SetTokenInformation (ptok, TokenPrimaryGroup, - &gsid, sizeof gsid)) - debug_printf ("SetTokenInformation(TokenPrimaryGroup): %E"); - else - user.groups.pgsid = gsid; + HANDLE ptok; + if (gsid != user.groups.pgsid + && OpenProcessToken (hMainProc, TOKEN_ADJUST_DEFAULT | TOKEN_QUERY, + &ptok)) + { + /* Set primary group to the group in /etc/passwd. */ + if (!SetTokenInformation (ptok, TokenPrimaryGroup, + &gsid, sizeof gsid)) + debug_printf ("SetTokenInformation(TokenPrimaryGroup): %E"); + else + user.groups.pgsid = gsid; + CloseHandle (ptok); + } } else debug_printf ("gsid not found in augmented /etc/group"); } } - if (ptok != INVALID_HANDLE_VALUE) - CloseHandle (ptok); (void) cygheap->user.ontherange (CH_HOME, pw); return; diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h index fc9de77a25c..677d498f8c8 100644 --- a/winsup/cygwin/winsup.h +++ b/winsup/cygwin/winsup.h @@ -37,14 +37,20 @@ details. */ #include <sys/types.h> #include <sys/strace.h> +/* Declarations for functions used in C and C++ code. */ #ifdef __cplusplus extern "C" { #endif extern __uid32_t getuid32 (void); extern __uid32_t geteuid32 (void); +extern int seteuid32 (__uid32_t); extern __gid32_t getegid32 (void); extern struct passwd *getpwuid32 (__uid32_t); -struct passwd *getpwnam (const char *); +extern struct passwd *getpwnam (const char *); +extern struct __sFILE64 *fopen64 (const char *, const char *); +extern struct hostent *cygwin_gethostbyname (const char *name); +extern unsigned long cygwin_inet_addr (const char *cp); + #ifdef __cplusplus } #endif |