diff --git a/lib/config/fileconf.go b/lib/config/fileconf.go index 083c6a2cd2196..0f18073cb8119 100644 --- a/lib/config/fileconf.go +++ b/lib/config/fileconf.go @@ -20,8 +20,10 @@ import ( "bytes" "crypto/tls" "encoding/base64" + "errors" "fmt" "io" + "io/fs" "io/ioutil" "net" "net/url" @@ -92,6 +94,9 @@ type FileConfig struct { func ReadFromFile(filePath string) (*FileConfig, error) { f, err := os.Open(filePath) if err != nil { + if errors.Is(err, fs.ErrPermission) { + return nil, trace.Wrap(err, "failed to open file for Teleport configuration: %v. Ensure that you are running as a user with appropriate permissions.", filePath) + } return nil, trace.Wrap(err, fmt.Sprintf("failed to open file: %v", filePath)) } defer f.Close() diff --git a/lib/service/service.go b/lib/service/service.go index 0dbf3c44be40f..dcf385bada881 100644 --- a/lib/service/service.go +++ b/lib/service/service.go @@ -24,8 +24,10 @@ import ( "crypto/tls" "crypto/x509" "encoding/hex" + "errors" "fmt" "io" + "io/fs" "io/ioutil" "net" "net/http" @@ -627,6 +629,9 @@ func NewTeleport(cfg *Config) (*TeleportProcess, error) { if os.IsNotExist(err) { err := os.MkdirAll(cfg.DataDir, os.ModeDir|0700) if err != nil { + if errors.Is(err, fs.ErrPermission) { + cfg.Log.Errorf("Teleport does not have permission to write to: %v. Ensure that you are running as a user with appropriate permissions.", cfg.DataDir) + } return nil, trace.ConvertSystemError(err) } } @@ -643,6 +648,9 @@ func NewTeleport(cfg *Config) (*TeleportProcess, error) { cfg.HostUUID, err = utils.ReadHostUUID(cfg.DataDir) if err != nil { if !trace.IsNotFound(err) { + if errors.Is(err, fs.ErrPermission) { + cfg.Log.Errorf("Teleport does not have permission to write to: %v. Ensure that you are running as a user with appropriate permissions.", cfg.DataDir) + } return nil, trace.Wrap(err) } if len(cfg.Identities) != 0 { @@ -663,6 +671,9 @@ func NewTeleport(cfg *Config) (*TeleportProcess, error) { cfg.Log.Infof("Generating new host UUID: %v.", cfg.HostUUID) } if err := utils.WriteHostUUID(cfg.DataDir, cfg.HostUUID); err != nil { + if errors.Is(err, fs.ErrPermission) { + cfg.Log.Errorf("Teleport does not have permission to write to: %v. Ensure that you are running as a user with appropriate permissions.", cfg.DataDir) + } return nil, trace.Wrap(err) } } diff --git a/lib/utils/utils.go b/lib/utils/utils.go index ee32b0bbc125c..f9a53095b3eb3 100644 --- a/lib/utils/utils.go +++ b/lib/utils/utils.go @@ -18,8 +18,10 @@ package utils import ( "context" + "errors" "fmt" "io" + "io/fs" "io/ioutil" "net" "net/url" @@ -321,10 +323,18 @@ func ReadPath(path string) ([]byte, error) { } abs, err := filepath.EvalSymlinks(s) if err != nil { + if errors.Is(err, fs.ErrPermission) { + //do not convert to system error as this loses the ability to compare that it is a permission error + return nil, err + } return nil, trace.ConvertSystemError(err) } bytes, err := ioutil.ReadFile(abs) if err != nil { + if errors.Is(err, fs.ErrPermission) { + //do not convert to system error as this loses the ability to compare that it is a permission error + return nil, err + } return nil, trace.ConvertSystemError(err) } return bytes, nil @@ -430,6 +440,10 @@ func GetFreeTCPPorts(n int, offset ...int) (PortList, error) { func ReadHostUUID(dataDir string) (string, error) { out, err := ReadPath(filepath.Join(dataDir, HostUUIDFile)) if err != nil { + if errors.Is(err, fs.ErrPermission) { + //do not convert to system error as this loses the ability to compare that it is a permission error + return "", err + } return "", trace.Wrap(err) } return strings.TrimSpace(string(out)), nil @@ -439,6 +453,10 @@ func ReadHostUUID(dataDir string) (string, error) { func WriteHostUUID(dataDir string, id string) error { err := ioutil.WriteFile(filepath.Join(dataDir, HostUUIDFile), []byte(id), os.ModeExclusive|0400) if err != nil { + if errors.Is(err, fs.ErrPermission) { + //do not convert to system error as this loses the ability to compare that it is a permission error + return err + } return trace.ConvertSystemError(err) } return nil