diff --git a/command/cliconfig/credentials.go b/command/cliconfig/credentials.go index 907978407..9d394bf29 100644 --- a/command/cliconfig/credentials.go +++ b/command/cliconfig/credentials.go @@ -317,23 +317,18 @@ func (s *CredentialsSource) updateLocalHostCredentials(host svchost.Hostname, ne tmpName := f.Name() moved := false defer func(f *os.File, name string) { - // Always close our file, and remove it if it's still at its - // temporary name. We're ignoring errors here because there's - // nothing we can do about them anyway. - f.Close() + // Remove the temporary file if it hasn't been moved yet. We're + // ignoring errors here because there's nothing we can do about + // them anyway. if !moved { os.Remove(name) } }(f, tmpName) - // Credentials file should be readable only by its owner. (This may - // not be effective on all platforms, but should at least work on - // Unix-like targets and should be harmless elsewhere.) - if err := f.Chmod(0600); err != nil { - return fmt.Errorf("cannot set mode for temporary file %s: %s", tmpName, err) - } - + // Write the credentials to the temporary file, then immediately close + // it, whether or not the write succeeds. _, err = f.Write(newSrc) + f.Close() if err != nil { return fmt.Errorf("cannot write to temporary file %s: %s", tmpName, err) } @@ -345,6 +340,14 @@ func (s *CredentialsSource) updateLocalHostCredentials(host svchost.Hostname, ne if err != nil { return fmt.Errorf("failed to replace %s with temporary file %s: %s", filename, tmpName, err) } + + // Credentials file should be readable only by its owner. (This may + // not be effective on all platforms, but should at least work on + // Unix-like targets and should be harmless elsewhere.) + if err := os.Chmod(filename, 0600); err != nil { + return fmt.Errorf("cannot set mode for credentials file %s: %s", filename, err) + } + moved = true }