From 2a9366ff49627dc65e265c14485d892c9352e256 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 15 Aug 2001 10:21:39 +0000 Subject: [PATCH] * security.cc (set_nt_attribute): Return always -1 in case of a failure. * times.cc (utimes): On NTFS with ntsec ON, change the file's security descriptor temporarily to acquire write access if opening the file failed. --- winsup/cygwin/ChangeLog | 8 ++++++++ winsup/cygwin/security.cc | 2 +- winsup/cygwin/times.cc | 32 +++++++++++++++++++++++++++++++- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 16874fed7..aafe076b1 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,11 @@ +Wed Aug 15 12:18:00 2001 Corinna Vinschen + + * security.cc (set_nt_attribute): Return always -1 in case of + a failure. + * times.cc (utimes): On NTFS with ntsec ON, change the file's + security descriptor temporarily to acquire write access if + opening the file failed. + Wed Aug 15 9:42:00 2001 Corinna Vinschen * fhandler.cc (fhandler_base::is_nonblocking): New method. diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc index 9b5a1e394..4e8e7b933 100644 --- a/winsup/cygwin/security.cc +++ b/winsup/cygwin/security.cc @@ -1570,7 +1570,7 @@ set_nt_attribute (const char *file, uid_t uid, gid_t gid, if ((ret = read_sd (file, psd, &sd_size)) <= 0) { debug_printf ("read_sd %E"); - return ret; + return -1; } sd_size = 4096; diff --git a/winsup/cygwin/times.cc b/winsup/cygwin/times.cc index 0cd7f4e00..29327e213 100644 --- a/winsup/cygwin/times.cc +++ b/winsup/cygwin/times.cc @@ -449,6 +449,8 @@ utimes (const char *path, struct timeval *tvp) int res = 0; struct timeval tmp[2]; path_conv win32 (path); + PSECURITY_DESCRIPTOR sd = NULL; + DWORD sd_size; if (win32.error) { @@ -475,13 +477,38 @@ utimes (const char *path, struct timeval *tvp) /* What we can do with directories more? */ res = 0; } + else if (allow_ntsec && win32.has_acls ()) + { + /* The following hack allows setting the correct filetime + on NTFS with ntsec ON even when the file is R/O for the + current user. This solves the `cp -p' problem and allows + a more UNIX like behaviour. Basically we save the file's + current security descriptor, change the file access so + that we have write access (if possible) and if that worked + fine, reset the old security descriptor at the end of the + function. */ + sd_size = 4096; + sd = (PSECURITY_DESCRIPTOR) alloca (sd_size); + if (read_sd (win32.get_win32 (), sd, &sd_size) <= 0) + sd = NULL; + else if (set_file_attribute (TRUE, win32.get_win32 (), 0600)) + sd = NULL; + else + h = CreateFileA (win32.get_win32 (), + GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + &sec_none_nih, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, + 0); + } else { res = -1; __seterrno (); } } - else + if (h != INVALID_HANDLE_VALUE) { if (tvp == 0) { @@ -517,6 +544,9 @@ utimes (const char *path, struct timeval *tvp) CloseHandle (h); } + if (sd) + write_sd (win32.get_win32 (), sd, sd_size); + syscall_printf ("%d = utimes (%s, %x); (h%d)", res, path, tvp, h); return res;