blob: f14db6b9c8bf1519664a9024e0e5ca442a5b30bb [file] [log] [blame]
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package osutil
import (
"fmt"
"io/fs"
"os"
)
func IsWriteGroup(mode os.FileMode) bool {
return mode&0o20 != 0
}
func IsWriteOther(mode os.FileMode) bool {
return mode&0o02 != 0
}
func checkPathInfo(info fs.FileInfo, path string, uid int, permissions int) error {
err := FileUidMatch(info, path, uid)
if err != nil {
return err
}
err = FilePermissionsMatch(info, path, permissions)
if err != nil {
return err
}
return nil
}
func FilePermissionsMatch(info fs.FileInfo, path string, permissions int) error {
if permissions != 0 && int(info.Mode().Perm()) != permissions {
return fmt.Errorf("path %q does not have permissions %o", path, permissions)
}
if permissions == 0 && (IsWriteOther(info.Mode()) || IsWriteGroup(info.Mode())) {
return fmt.Errorf("path %q has insecure permissions %o. Vault expects no write permissions for group or others", path, info.Mode().Perm())
}
return nil
}
// OwnerPermissionsMatch checks if vault user is the owner and permissions are secure for input path
func OwnerPermissionsMatch(path string, uid int, permissions int) error {
if path == "" {
return fmt.Errorf("could not verify permissions for path. No path provided ")
}
info, err := os.Stat(path)
if err != nil {
return fmt.Errorf("error stating %q: %w", path, err)
}
if info.Mode()&os.ModeSymlink != 0 {
symLinkInfo, err := os.Lstat(path)
if err != nil {
return fmt.Errorf("error stating %q: %w", path, err)
}
err = checkPathInfo(symLinkInfo, path, uid, permissions)
if err != nil {
return err
}
}
err = checkPathInfo(info, path, uid, permissions)
if err != nil {
return err
}
return nil
}
// OwnerPermissionsMatchFile checks if vault user is the owner and permissions are secure for the input file
func OwnerPermissionsMatchFile(file *os.File, uid int, permissions int) error {
info, err := file.Stat()
if err != nil {
return fmt.Errorf("file stat error on path %q: %w", file.Name(), err)
}
err = checkPathInfo(info, file.Name(), uid, permissions)
if err != nil {
return err
}
return nil
}