[service] Fix file permission in the updates

This commit is contained in:
Vladimir Stoilov
2025-01-14 18:13:31 +02:00
parent 5039e9efca
commit 9829136b8c
11 changed files with 68 additions and 111 deletions

View File

@@ -3,7 +3,6 @@ package database
import (
"errors"
"fmt"
"os"
"path/filepath"
"github.com/safing/portmaster/base/utils"
@@ -24,15 +23,11 @@ func Initialize(databasesRootDir string) error {
if initialized.SetToIf(false, true) {
rootDir = databasesRootDir
err := os.MkdirAll(rootDir, 0o0700)
// ensure root and databases dirs
err := utils.EnsureDirectory(rootDir, utils.AdminOnlyExecPermission)
if err != nil {
return fmt.Errorf("failed to create/check database dir %q: %w", rootDir, err)
}
// ensure root and databases dirs
err = utils.EnsureDirectory(rootDir, utils.AdminOnlyPermission)
if err != nil {
return fmt.Errorf("could not set permissions to database directory (%s): %w", rootDir, err)
}
return nil
}
@@ -64,13 +59,9 @@ func getLocation(name, storageType string) (string, error) {
location := filepath.Join(rootDir, name, storageType)
// Make sure location exists.
err := os.MkdirAll(location, 0o0700)
err := utils.EnsureDirectory(location, utils.AdminOnlyExecPermission)
if err != nil {
return "", fmt.Errorf("failed to create/check database dir %q: %w", location, err)
}
err = utils.EnsureDirectory(location, utils.AdminOnlyPermission)
if err != nil {
return "", fmt.Errorf("could not set permissions to directory (%s): %w", location, err)
}
return location, nil
}

View File

@@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"io/fs"
"log/slog"
"os"
"runtime"
)
@@ -13,6 +14,10 @@ const isWindows = runtime.GOOS == "windows"
// EnsureDirectory ensures that the given directory exists and that is has the given permissions set.
// If path is a file, it is deleted and a directory created.
func EnsureDirectory(path string, perm FSPermission) error {
if !perm.IsExecPermission() {
slog.Warn("utils: setting not executable permission for directory", "dir", path)
}
// open path
f, err := os.Stat(path)
if err == nil {
@@ -21,10 +26,10 @@ func EnsureDirectory(path string, perm FSPermission) error {
// directory exists, check permissions
if isWindows {
// Ignore windows permission error. For none admin users it will always fail.
_ = SetDirPermission(path, perm)
_ = SetFilePermission(path, perm)
return nil
} else if f.Mode().Perm() != perm.AsUnixDirExecPermission() {
return SetDirPermission(path, perm)
} else if f.Mode().Perm() != perm.AsUnixPermission() {
return SetFilePermission(path, perm)
}
return nil
}
@@ -35,12 +40,12 @@ func EnsureDirectory(path string, perm FSPermission) error {
}
// file does not exist (or has been deleted)
if err == nil || errors.Is(err, fs.ErrNotExist) {
err = os.MkdirAll(path, perm.AsUnixDirExecPermission())
err = os.MkdirAll(path, perm.AsUnixPermission())
if err != nil {
return fmt.Errorf("could not create dir %s: %w", path, err)
}
// Set permissions.
err = SetDirPermission(path, perm)
err = SetFilePermission(path, perm)
// Ignore windows permission error. For none admin users it will always fail.
if !isWindows {
return err

View File

@@ -4,17 +4,7 @@ package utils
import "os"
// SetDirPermission sets the permission of a directory.
func SetDirPermission(path string, perm FSPermission) error {
return os.Chmod(path, perm.AsUnixDirExecPermission())
}
// SetExecPermission sets the permission of an executable file.
func SetExecPermission(path string, perm FSPermission) error {
return SetDirPermission(path, perm)
}
// SetFilePermission sets the permission of a non executable file.
// SetFilePermission sets the permission of a file or directory.
func SetFilePermission(path string, perm FSPermission) error {
return os.Chmod(path, perm.AsUnixFilePermission())
return os.Chmod(path, perm.AsUnixPermission())
}

View File

@@ -31,22 +31,10 @@ func init() {
}
}
// SetDirPermission sets the permission of a directory.
func SetDirPermission(path string, perm FSPermission) error {
SetFilePermission(path, perm)
return nil
}
// SetExecPermission sets the permission of an executable file.
func SetExecPermission(path string, perm FSPermission) error {
SetFilePermission(path, perm)
return nil
}
// SetFilePermission sets the permission of a non executable file.
func SetFilePermission(path string, perm FSPermission) {
// SetFilePermission sets the permission of a file or directory.
func SetFilePermission(path string, perm FSPermission) error {
switch perm {
case AdminOnlyPermission:
case AdminOnlyPermission, AdminOnlyExecPermission:
// Set only admin rights, remove all others.
acl.Apply(
path,
@@ -55,7 +43,7 @@ func SetFilePermission(path string, perm FSPermission) {
acl.GrantSid(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, systemSID),
acl.GrantSid(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, adminsSID),
)
case PublicReadPermission:
case PublicReadPermission, PublicReadExecPermission:
// Set admin rights and read/execute rights for users, remove all others.
acl.Apply(
path,
@@ -65,7 +53,7 @@ func SetFilePermission(path string, perm FSPermission) {
acl.GrantSid(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, adminsSID),
acl.GrantSid(windows.GENERIC_READ|windows.GENERIC_EXECUTE, usersSID),
)
case PublicWritePermission:
case PublicWritePermission, PublicWriteExecPermission:
// Set full control to admin and regular users. Guest users will not have access.
acl.Apply(
path,
@@ -76,4 +64,5 @@ func SetFilePermission(path string, perm FSPermission) {
acl.GrantSid(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, usersSID),
)
}
return nil
}

View File

@@ -12,36 +12,39 @@ type FSPermission uint8
const (
AdminOnlyPermission FSPermission = iota
AdminOnlyExecPermission
PublicReadPermission
PublicReadExecPermission
PublicWritePermission
PublicWriteExecPermission
)
// AsUnixDirExecPermission return the corresponding unix permission for a directory or executable.
func (perm FSPermission) AsUnixDirExecPermission() fs.FileMode {
func (perm FSPermission) AsUnixPermission() fs.FileMode {
switch perm {
case AdminOnlyPermission:
return 0o600
case AdminOnlyExecPermission:
return 0o700
case PublicReadPermission:
return 0o644
case PublicReadExecPermission:
return 0o755
case PublicWritePermission:
return 0o666
case PublicWriteExecPermission:
return 0o777
}
return 0
}
// AsUnixFilePermission return the corresponding unix permission for a regular file.
func (perm FSPermission) AsUnixFilePermission() fs.FileMode {
func (perm FSPermission) IsExecPermission() bool {
switch perm {
case AdminOnlyPermission:
return 0o600
case PublicReadPermission:
return 0o644
case PublicWritePermission:
return 0o666
case AdminOnlyExecPermission, PublicReadExecPermission, PublicWriteExecPermission:
return true
}
return 0
return false
}
// DirStructure represents a directory structure with permissions that should be enforced.