Fix file permissions on windows (#1758)

* [service] Set file permissions on windows

* [service] Fix minor windows permission bugs

* [service] Fix permission bugs

* [service] Fix windows non admin user start
This commit is contained in:
Vladimir Stoilov 2024-11-26 17:00:01 +02:00
parent 85031e861b
commit 35d1e4d2e3
No known key found for this signature in database
GPG key ID: 2F190B67A43A81AF
5 changed files with 36 additions and 9 deletions

View file

@ -15,6 +15,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/hectane/go-acl"
"github.com/safing/portmaster/base/database/iterator" "github.com/safing/portmaster/base/database/iterator"
"github.com/safing/portmaster/base/database/query" "github.com/safing/portmaster/base/database/query"
"github.com/safing/portmaster/base/database/record" "github.com/safing/portmaster/base/database/record"
@ -288,10 +289,13 @@ func writeFile(filename string, data []byte, perm os.FileMode) error {
defer t.Cleanup() //nolint:errcheck defer t.Cleanup() //nolint:errcheck
// Set permissions before writing data, in case the data is sensitive. // Set permissions before writing data, in case the data is sensitive.
if !onWindows { if onWindows {
if err := t.Chmod(perm); err != nil { err = acl.Chmod(filename, perm)
return err } else {
} err = t.Chmod(perm)
}
if err != nil {
return err
} }
if _, err := t.Write(data); err != nil { if _, err := t.Write(data); err != nil {

View file

@ -6,6 +6,8 @@ import (
"io/fs" "io/fs"
"os" "os"
"runtime" "runtime"
"github.com/hectane/go-acl"
) )
const isWindows = runtime.GOOS == "windows" const isWindows = runtime.GOOS == "windows"
@ -20,8 +22,9 @@ func EnsureDirectory(path string, perm os.FileMode) error {
if f.IsDir() { if f.IsDir() {
// directory exists, check permissions // directory exists, check permissions
if isWindows { if isWindows {
// TODO: set correct permission on windows // Ignore windows permission error. For none admin users it will always fail.
// acl.Chmod(path, perm) acl.Chmod(path, perm)
return nil
} else if f.Mode().Perm() != perm { } else if f.Mode().Perm() != perm {
return os.Chmod(path, perm) return os.Chmod(path, perm)
} }
@ -38,7 +41,13 @@ func EnsureDirectory(path string, perm os.FileMode) error {
if err != nil { if err != nil {
return fmt.Errorf("could not create dir %s: %w", path, err) return fmt.Errorf("could not create dir %s: %w", path, err)
} }
return os.Chmod(path, perm) if isWindows {
// Ignore windows permission error. For none admin users it will always fail.
acl.Chmod(path, perm)
return nil
} else {
return os.Chmod(path, perm)
}
} }
// other error opening path // other error opening path
return fmt.Errorf("failed to access %s: %w", path, err) return fmt.Errorf("failed to access %s: %w", path, err)

View file

@ -1,6 +1,11 @@
package renameio package renameio
import "os" import (
"os"
"runtime"
"github.com/hectane/go-acl"
)
// WriteFile mirrors os.WriteFile, replacing an existing file with the same // WriteFile mirrors os.WriteFile, replacing an existing file with the same
// name atomically. // name atomically.
@ -14,7 +19,12 @@ func WriteFile(filename string, data []byte, perm os.FileMode) error {
}() }()
// Set permissions before writing data, in case the data is sensitive. // Set permissions before writing data, in case the data is sensitive.
if err := t.Chmod(perm); err != nil { if runtime.GOOS == "windows" {
err = acl.Chmod(t.path, perm)
} else {
err = t.Chmod(perm)
}
if err != nil {
return err return err
} }

1
go.mod
View file

@ -31,6 +31,7 @@ require (
github.com/gorilla/websocket v1.5.3 github.com/gorilla/websocket v1.5.3
github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/go-multierror v1.1.1
github.com/hashicorp/go-version v1.7.0 github.com/hashicorp/go-version v1.7.0
github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb
github.com/jackc/puddle/v2 v2.2.2 github.com/jackc/puddle/v2 v2.2.2
github.com/lmittmann/tint v1.0.5 github.com/lmittmann/tint v1.0.5
github.com/maruel/panicparse/v2 v2.3.1 github.com/maruel/panicparse/v2 v2.3.1

3
go.sum
View file

@ -129,6 +129,8 @@ github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKe
github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/hcl v0.0.0-20170914154624-68e816d1c783/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= github.com/hashicorp/hcl v0.0.0-20170914154624-68e816d1c783/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM=
github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E=
github.com/inconshreveable/log15 v0.0.0-20170622235902-74a0988b5f80/go.mod h1:cOaXtrgN4ScfRrD9Bre7U1thNq5RtJ8ZoP4iXVGRj6o= github.com/inconshreveable/log15 v0.0.0-20170622235902-74a0988b5f80/go.mod h1:cOaXtrgN4ScfRrD9Bre7U1thNq5RtJ8ZoP4iXVGRj6o=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
@ -377,6 +379,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190411185658-b44545bcd369/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190411185658-b44545bcd369/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190529164535-6a60838ec259/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=