Skip to content

Commit

Permalink
config: preserve ownership and permissions on configfile
Browse files Browse the repository at this point in the history
When running `docker login` or `docker logout`, the CLI updates
the configuration file by creating a temporary file, to replace
the old one (if exists).

When using `sudo`, this caused the file to be created as `root`,
making it inaccessible to the current user.

This patch updates the CLI to fetch permissions and ownership of
the existing configuration file, and applies those permissions
to the new file, so that it has the same permissions as the
existing file (if any).

Currently, only done for "Unix-y" systems (Mac, Linux), but
can be implemented for Windows in future if there's a need.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
  • Loading branch information
thaJeztah committed Dec 17, 2019
1 parent ebca141 commit 22a291f
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 0 deletions.
3 changes: 3 additions & 0 deletions cli/config/configfile/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,9 @@ func (configFile *ConfigFile) Save() error {
os.Remove(temp.Name())
return err
}
// Try copying the current config file (if any) ownership and permissions
copyFilePermissions(configFile.Filename, temp.Name())

return os.Rename(temp.Name(), configFile.Filename)
}

Expand Down
35 changes: 35 additions & 0 deletions cli/config/configfile/file_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// +build !windows

package configfile

import (
"os"
"syscall"
)

// copyFilePermissions copies file ownership and permissions from "src" to "dst",
// ignoring any error during the process.
func copyFilePermissions(src, dst string) {
var (
mode os.FileMode = 0600
uid, gid int
)

fi, err := os.Stat(src)
if err != nil {
return
}
if fi.Mode().IsRegular() {
mode = fi.Mode()
}
if err := os.Chmod(dst, mode); err != nil {
return
}

uid = int(fi.Sys().(*syscall.Stat_t).Uid)
gid = int(fi.Sys().(*syscall.Stat_t).Gid)

if uid > 0 && gid > 0 {
_ = os.Chown(dst, uid, gid)
}
}
5 changes: 5 additions & 0 deletions cli/config/configfile/file_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package configfile

func copyFilePermissions(src, dst string) {
// TODO implement for Windows
}

0 comments on commit 22a291f

Please sign in to comment.