aboutsummaryrefslogtreecommitdiff
path: root/src/internal/syscall/windows/at_windows.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/internal/syscall/windows/at_windows.go')
-rw-r--r--src/internal/syscall/windows/at_windows.go23
1 files changed, 20 insertions, 3 deletions
diff --git a/src/internal/syscall/windows/at_windows.go b/src/internal/syscall/windows/at_windows.go
index de733c523c..81361c98e4 100644
--- a/src/internal/syscall/windows/at_windows.go
+++ b/src/internal/syscall/windows/at_windows.go
@@ -246,14 +246,31 @@ func Deleteat(dirfd syscall.Handle, name string, options uint32) error {
var h syscall.Handle
err := NtOpenFile(
&h,
- SYNCHRONIZE|FILE_READ_ATTRIBUTES|DELETE,
+ FILE_READ_ATTRIBUTES|DELETE,
objAttrs,
&IO_STATUS_BLOCK{},
FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE,
- FILE_OPEN_REPARSE_POINT|FILE_OPEN_FOR_BACKUP_INTENT|FILE_SYNCHRONOUS_IO_NONALERT|options,
+ FILE_OPEN_REPARSE_POINT|FILE_OPEN_FOR_BACKUP_INTENT|options,
)
if err != nil {
- return ntCreateFileError(err, 0)
+ if ntStatus, ok := err.(NTStatus); !ok || ntStatus != STATUS_ACCESS_DENIED {
+ return ntCreateFileError(err, 0)
+ }
+
+ // Access denied, try opening with DELETE only.
+ // This may succeed if the file has restrictive permissions
+ // but the caller has delete child permission on the parent directory.
+ err = NtOpenFile(
+ &h,
+ DELETE,
+ objAttrs,
+ &IO_STATUS_BLOCK{},
+ FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE,
+ FILE_OPEN_REPARSE_POINT|FILE_OPEN_FOR_BACKUP_INTENT|options,
+ )
+ if err != nil {
+ return ntCreateFileError(err, 0)
+ }
}
defer syscall.CloseHandle(h)