diff --git a/pkg/configuration/config.go b/pkg/configuration/config.go index 2ce67dec..6441e72b 100644 --- a/pkg/configuration/config.go +++ b/pkg/configuration/config.go @@ -49,6 +49,8 @@ var CanReadEnv = true var configFileName = ".doppler.yaml" var configContents models.ConfigFile +var configUid = -1 +var configGid = -1 func init() { baseConfigDir = utils.HomeDir() @@ -102,7 +104,7 @@ func Setup() { // LoadConfig load the configuration file func LoadConfig() { - configContents = readConfig() + configContents, configUid, configGid = readConfig() } // VersionCheck the last version check @@ -410,11 +412,23 @@ func writeConfig(config models.ConfigFile) { if err := utils.WriteFile(UserConfigFile, bytes, os.FileMode(0600)); err != nil { utils.HandleError(err) } + + // restore file's original ownership, in case doppler has been subsequently run with 'sudo' + if !utils.IsWindows() && configUid != -1 && configGid != -1 { + if err := os.Chown(UserConfigFile, configUid, configGid); err != nil { + utils.HandleError(err, "Unable to modify config file ownership") + } + } } -func readConfig() models.ConfigFile { +func readConfig() (models.ConfigFile, int, int) { utils.LogDebug("Reading config file") + uid, gid, err := utils.FileOwnership(UserConfigFile) + if err != nil { + utils.HandleError(err, "Unable to stat user config file") + } + fileContents, err := ioutil.ReadFile(UserConfigFile) // #nosec G304 if err != nil { utils.HandleError(err, "Unable to read user config file") @@ -467,7 +481,7 @@ func readConfig() models.ConfigFile { } config.Scoped = normalizedOptions - return config + return config, uid, gid } // IsValidConfigOption whether the specified key is a valid config option diff --git a/pkg/utils/io_nonwindows.go b/pkg/utils/io_nonwindows.go new file mode 100644 index 00000000..8e34f0b5 --- /dev/null +++ b/pkg/utils/io_nonwindows.go @@ -0,0 +1,38 @@ +// +build !windows + +/* +Copyright © 2021 Doppler + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package utils + +import ( + "errors" + "os" + "syscall" +) + +func FileOwnership(path string) (int, int, error) { + info, err := os.Stat(path) + if err != nil { + return -1, -1, err + } + + stat, ok := info.Sys().(*syscall.Stat_t) + if !ok { + return -1, -1, errors.New("Unable to stat file") + } + + return int(stat.Uid), int(stat.Gid), nil +} diff --git a/pkg/utils/io_windows.go b/pkg/utils/io_windows.go new file mode 100644 index 00000000..8f1e3644 --- /dev/null +++ b/pkg/utils/io_windows.go @@ -0,0 +1,20 @@ +/* +Copyright © 2021 Doppler + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package utils + +func FileOwnership(path string) (int, int, error) { + return -1, -1, nil +}