From d17464835124054ef58f53b3fb28c80443c162e6 Mon Sep 17 00:00:00 2001 From: mattn Date: Thu, 20 Oct 2022 11:22:52 +0900 Subject: [PATCH] Check privileges for symlink tests on Windows (#530) Tests for symlink always fail when run the tests as non-admin users on Windows since Windows require privileges to create symlinks. This CL change to check the privileges. --- fsnotify_test.go | 16 ++++++++++++++++ internal/unix2.go | 8 ++++++++ internal/windows.go | 23 +++++++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 internal/unix2.go diff --git a/fsnotify_test.go b/fsnotify_test.go index 16431f5..beb2c62 100644 --- a/fsnotify_test.go +++ b/fsnotify_test.go @@ -166,6 +166,9 @@ func TestWatch(t *testing.T) { // behaviour too. t.Skip("broken on macOS") } + if !internal.HasPrivilegesForSymlink() { + t.Skip("does not have privileges for symlink on this OS") + } file := join(tmp, "file") link := join(tmp, "link") @@ -195,6 +198,9 @@ func TestWatch(t *testing.T) { // behaviour too. t.Skip("broken on macOS") } + if !internal.HasPrivilegesForSymlink() { + t.Skip("does not have privileges for symlink on this OS") + } dir := join(tmp, "dir") link := join(tmp, "link") @@ -246,6 +252,9 @@ func TestWatchCreate(t *testing.T) { // Links {"create new symlink to file", func(t *testing.T, w *Watcher, tmp string) { + if !internal.HasPrivilegesForSymlink() { + t.Skip("does not have privileges for symlink on this OS") + } touch(t, tmp, "file") addWatch(t, w, tmp) symlink(t, join(tmp, "file"), tmp, "link") @@ -253,6 +262,9 @@ func TestWatchCreate(t *testing.T) { create /link `}, {"create new symlink to directory", func(t *testing.T, w *Watcher, tmp string) { + if !internal.HasPrivilegesForSymlink() { + t.Skip("does not have privileges for symlink on this OS") + } addWatch(t, w, tmp) symlink(t, tmp, tmp, "link") }, ` @@ -505,6 +517,10 @@ func TestWatchRename(t *testing.T) { } func TestWatchSymlink(t *testing.T) { + if !internal.HasPrivilegesForSymlink() { + t.Skip("does not have privileges for symlink on this OS") + } + tests := []testCase{ {"create unresolvable symlink", func(t *testing.T, w *Watcher, tmp string) { addWatch(t, w, tmp) diff --git a/internal/unix2.go b/internal/unix2.go new file mode 100644 index 0000000..dc40459 --- /dev/null +++ b/internal/unix2.go @@ -0,0 +1,8 @@ +//go:build !windows +// +build !windows + +package internal + +func HasPrivilegesForSymlink() bool { + return true +} diff --git a/internal/windows.go b/internal/windows.go index 0e9b3b2..62d1d17 100644 --- a/internal/windows.go +++ b/internal/windows.go @@ -5,6 +5,8 @@ package internal import ( "errors" + + "golang.org/x/sys/windows" ) // Just a dummy. @@ -17,3 +19,24 @@ func SetRlimit() {} func Maxfiles() uint64 { return 1<<64 - 1 } func Mkfifo(path string, mode uint32) error { return errors.New("no FIFOs on Windows") } func Mknod(path string, mode uint32, dev int) error { return errors.New("no device nodes on Windows") } + +func HasPrivilegesForSymlink() bool { + var sid *windows.SID + err := windows.AllocateAndInitializeSid( + &windows.SECURITY_NT_AUTHORITY, + 2, + windows.SECURITY_BUILTIN_DOMAIN_RID, + windows.DOMAIN_ALIAS_RID_ADMINS, + 0, 0, 0, 0, 0, 0, + &sid) + if err != nil { + return false + } + defer windows.FreeSid(sid) + token := windows.Token(0) + member, err := token.IsMember(sid) + if err != nil { + return false + } + return member || token.IsElevated() +} -- 2.50.1