summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <cgf@redhat.com>2003-09-11 04:47:22 +0000
committerChristopher Faylor <cgf@redhat.com>2003-09-11 04:47:22 +0000
commite110d2668a3cb21ede13338d5e87364685a74ab4 (patch)
tree7f2fd093880c2a8af04172684c5a013592a5cc6a
parent93fac648a6e9ed2284823fab85ae1acec15c73be (diff)
downloadgdb-e110d2668a3cb21ede13338d5e87364685a74ab4.tar.gz
merge from trunk
-rw-r--r--winsup/cygwin/ChangeLog301
-rw-r--r--winsup/cygwin/Makefile.in20
-rw-r--r--winsup/cygwin/cygheap.h1
-rw-r--r--winsup/cygwin/cygwin.din11
-rw-r--r--winsup/cygwin/dir.cc2
-rw-r--r--winsup/cygwin/fhandler_disk_file.cc27
-rw-r--r--winsup/cygwin/include/cygwin/version.h4
-rw-r--r--winsup/cygwin/include/getopt.h86
-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.cc252
-rw-r--r--winsup/cygwin/security.h6
-rw-r--r--winsup/cygwin/shared.cc93
-rw-r--r--winsup/cygwin/shared_info.h10
-rw-r--r--winsup/cygwin/spawn.cc3
-rw-r--r--winsup/cygwin/syscalls.cc21
-rw-r--r--winsup/cygwin/uinfo.cc80
-rw-r--r--winsup/cygwin/winsup.h8
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