From 796e3b20bc861bdd8ca4da24b807582fb783e16a Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 2 Apr 2000 20:42:42 +0000 Subject: [PATCH] * newlib/libc/include/sys/unistd.h: Add prototypes for fchmod, fchown, lchown. * winsup/cygwin/syscalls.cc (chown_worker): Use previous uid/gid if new uid/gid is -1. New static function with chown functionality. (chown): Call chown_worker with SYMLINK_FOLLOW. (fchown): New function. Call chown_worker with SYMLINK_FOLLOW. (lchown): New function. Call chown_worker with SYMLINK_IGNORE. * cygwin.din: Add symbols for fchown, lchown. * path.cc (symlink): Call `set_file_attribute()' and `SetFileAttributeA()' instead of `chmod()' to set uid/gid correct. --- newlib/ChangeLog | 5 +++ newlib/libc/include/sys/unistd.h | 3 ++ winsup/cygwin/ChangeLog | 20 +++++++++ winsup/cygwin/cygwin.din | 4 ++ winsup/cygwin/path.cc | 5 ++- winsup/cygwin/syscalls.cc | 77 +++++++++++++++++++++++++------- 6 files changed, 96 insertions(+), 18 deletions(-) diff --git a/newlib/ChangeLog b/newlib/ChangeLog index 37a917553..33b0ef33d 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,8 @@ +Fri Mar 31 20:39:00 2000 Corinna Vinschen + + * libc/include/sys/unistd.h: Add prototypes for + fchmod, fchown, lchown. + Fri Mar 24 15:34:00 2000 Jeff Johnston * acinclude.m4: Changed release to 1.8.2. diff --git a/newlib/libc/include/sys/unistd.h b/newlib/libc/include/sys/unistd.h index 98d1e1f2a..2b8c6a0f0 100644 --- a/newlib/libc/include/sys/unistd.h +++ b/newlib/libc/include/sys/unistd.h @@ -30,6 +30,8 @@ int _EXFUN(execlp, (const char *__file, const char *, ... )); int _EXFUN(execv, (const char *__path, char * const __argv[] )); int _EXFUN(execve, (const char *__path, char * const __argv[], char * const __envp[] )); int _EXFUN(execvp, (const char *__file, char * const __argv[] )); +int _EXFUN(fchmod, (int __fildes, mode_t __mode )); +int _EXFUN(fchown, (int __fildes, uid_t __owner, gid_t __group )); pid_t _EXFUN(fork, (void )); long _EXFUN(fpathconf, (int __fd, int __name )); int _EXFUN(fsync, (int __fd)); @@ -46,6 +48,7 @@ pid_t _EXFUN(getpid, (void )); pid_t _EXFUN(getppid, (void )); uid_t _EXFUN(getuid, (void )); int _EXFUN(isatty, (int __fildes )); +int _EXFUN(lchown, (const char *__path, uid_t __owner, gid_t __group )); int _EXFUN(link, (const char *__path1, const char *__path2 )); int _EXFUN(nice, (int __nice_value )); off_t _EXFUN(lseek, (int __fildes, off_t __offset, int __whence )); diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 7520d6ee4..dcd493c20 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,23 @@ +Sun Apr 02 16:02:00 2000 Corinna Vinschen + + * syscalls.cc (chown_worker): Use previous uid/gid if + new uid/gid is -1. + +Fry Mar 31 22:55:00 2000 Corinna Vinschen + + * syscalls.cc (chown_worker): New static function with + chown functionality. + (chown): Call chown_worker with SYMLINK_FOLLOW. + (fchown): New function. Call chown_worker with SYMLINK_FOLLOW. + (lchown): New function. Call chown_worker with SYMLINK_IGNORE. + * cygwin.din: Add symbols for fchown, lchown. + +Fry Mar 31 11:18:00 2000 Corinna Vinschen + + * path.cc (symlink): Call `set_file_attribute()' and + `SetFileAttributeA()' instead of `chmod()' to set + uid/gid correct. + Wed Mar 29 22:49:56 2000 Christopher Faylor * fhandler.h (select_record): Explicitly zero elements of this class. diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din index 4abde7c95..d809a1ca3 100644 --- a/winsup/cygwin/cygwin.din +++ b/winsup/cygwin/cygwin.din @@ -186,6 +186,8 @@ _f_atan2f __f_atan2f = _f_atan2f fchmod _fchmod = fchmod +fchown +_fchown = fchown fclose _fclose = fclose fcntl @@ -425,6 +427,8 @@ kill _kill = kill labs _labs = labs +lchown +_lchown = lchown ldexp _ldexp = ldexp ldexpf diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index a58a1b445..28c7b4e73 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -2048,7 +2048,10 @@ symlink (const char *topath, const char *frompath) else { CloseHandle (h); - chmod (frompath, S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO); + set_file_attribute (win32_path.has_acls (), + win32_path.get_win32 (), + S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO); + SetFileAttributesA (win32_path.get_win32 (), FILE_ATTRIBUTE_SYSTEM); res = 0; } } diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index a4c725368..b2ac1e262 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -641,22 +641,20 @@ rel2abssd (PSECURITY_DESCRIPTOR psd_rel, PSECURITY_DESCRIPTOR psd_abs, /* * chown() is only implemented for Windows NT. Under other operating * systems, it is only a stub that always returns zero. - * - * Note: the SetFileSecurity API in NT can only set the current - * user as file owner so we have to use the Backup API instead. */ -extern "C" -int -chown (const char * name, uid_t uid, gid_t gid) +static int +chown_worker (const char *name, symlink_follow fmode, uid_t uid, gid_t gid) { int res; + uid_t old_uid; + gid_t old_gid; if (os_being_run != winNT) // real chown only works on NT res = 0; // return zero (and do nothing) under Windows 9x else { /* we need Win32 path names because of usage of Win32 API functions */ - path_conv win32_path (name); + path_conv win32_path (name, fmode); if (win32_path.error) { @@ -676,17 +674,22 @@ chown (const char * name, uid_t uid, gid_t gid) DWORD attrib = 0; if (win32_path.file_attributes () & FILE_ATTRIBUTE_DIRECTORY) attrib |= S_IFDIR; - int has_acls; - has_acls = allow_ntsec && win32_path.has_acls (); - res = get_file_attribute (has_acls, + res = get_file_attribute (win32_path.has_acls (), win32_path.get_win32 (), - (int *) &attrib); + (int *) &attrib, + &old_uid, + &old_gid); if (!res) - res = set_file_attribute (win32_path.has_acls (), - win32_path.get_win32 (), - uid, gid, attrib, - myself->logsrv); - + { + if (uid == (uid_t) -1) + uid = old_uid; + if (gid == (gid_t) -1) + gid = old_gid; + res = set_file_attribute (win32_path.has_acls (), + win32_path.get_win32 (), + uid, gid, attrib, + myself->logsrv); + } if (res != 0 && get_errno () == ENOSYS) { /* fake - if not supported, pretend we're like win95 @@ -696,10 +699,50 @@ chown (const char * name, uid_t uid, gid_t gid) } done: - syscall_printf ("%d = chown (%s,...)", res, name); + syscall_printf ("%d = %schown (%s,...)", + res, fmode == SYMLINK_IGNORE ? "l" : "", name); return res; } +extern "C" +int +chown (const char * name, uid_t uid, gid_t gid) +{ + return chown_worker (name, SYMLINK_FOLLOW, uid, gid); +} + +extern "C" +int +lchown (const char * name, uid_t uid, gid_t gid) +{ + return chown_worker (name, SYMLINK_IGNORE, uid, gid); +} + +extern "C" +int +fchown (int fd, uid_t uid, gid_t gid) +{ + if (dtable.not_open (fd)) + { + syscall_printf ("-1 = fchown (%d,...)", fd); + set_errno (EBADF); + return -1; + } + + const char *path = dtable[fd]->get_name (); + + if (path == NULL) + { + syscall_printf ("-1 = fchown (%d,...) (no name)", fd); + set_errno (ENOSYS); + return -1; + } + + syscall_printf ("fchown (%d,...): calling chown_worker (%s,FOLLOW,...)", + fd, path); + return chown_worker (path, SYMLINK_FOLLOW, uid, gid); +} + /* umask: POSIX 5.3.3.1 */ extern "C" mode_t