diff --git a/Library/Homebrew/cask/artifact/abstract_uninstall.rb b/Library/Homebrew/cask/artifact/abstract_uninstall.rb index 234a7a5d8b..78547326b5 100644 --- a/Library/Homebrew/cask/artifact/abstract_uninstall.rb +++ b/Library/Homebrew/cask/artifact/abstract_uninstall.rb @@ -379,7 +379,7 @@ module Cask end def uninstall_pkgutil(*pkgs, command: nil, **_) - ohai "Uninstalling packages; your password may be necessary:" + ohai "Uninstalling packages with sudo; the password may be necessary:" pkgs.each do |regex| ::Cask::Pkg.all_matching(regex, command).each do |pkg| puts pkg.package_id diff --git a/Library/Homebrew/cask/artifact/pkg.rb b/Library/Homebrew/cask/artifact/pkg.rb index 61cd142ec0..0d2610f29f 100644 --- a/Library/Homebrew/cask/artifact/pkg.rb +++ b/Library/Homebrew/cask/artifact/pkg.rb @@ -36,8 +36,7 @@ module Cask private def run_installer(command: nil, verbose: false, **_options) - ohai "Running installer for #{cask}; your password may be necessary.", - "Package installers may write to any location; options such as `--appdir` are ignored." + ohai "Running installer for #{cask} with sudo; the password may be necessary." unless path.exist? pkg = path.relative_path_from(cask.staged_path) pkgs = Pathname.glob(cask.staged_path/"**"/"*.pkg").map { |path| path.relative_path_from(cask.staged_path) } diff --git a/Library/Homebrew/cask/staged.rb b/Library/Homebrew/cask/staged.rb index bd7b2f2a53..74df26ec21 100644 --- a/Library/Homebrew/cask/staged.rb +++ b/Library/Homebrew/cask/staged.rb @@ -27,7 +27,7 @@ module Cask full_paths = remove_nonexistent(paths) return if full_paths.empty? - ohai "Changing ownership of paths required by #{@cask}; your password may be necessary." + ohai "Changing ownership of paths required by #{@cask} with sudo; the password may be necessary." @command.run!("/usr/sbin/chown", args: ["-R", "--", "#{user}:#{group}", *full_paths], sudo: true) end diff --git a/Library/Homebrew/env_config.rb b/Library/Homebrew/env_config.rb index b7a0aba96a..ae7b7e6c75 100644 --- a/Library/Homebrew/env_config.rb +++ b/Library/Homebrew/env_config.rb @@ -373,6 +373,11 @@ module Homebrew "the system-wide environment file will be loaded last to override any prefix or user settings.", boolean: true, }, + HOMEBREW_SUDO_THROUGH_SUDO_USER: { + description: "If set, Homebrew will use the `SUDO_USER` environment variable to define the user to " \ + "`sudo`(8) through when running `sudo`(8).", + boolean: true, + }, HOMEBREW_TEMP: { description: "Use this path as the temporary directory for building packages. Changing " \ "this may be needed if your system temporary directory and Homebrew prefix are on " \ diff --git a/Library/Homebrew/env_config.rbi b/Library/Homebrew/env_config.rbi index b61b8e519d..1fa98249b3 100644 --- a/Library/Homebrew/env_config.rbi +++ b/Library/Homebrew/env_config.rbi @@ -217,6 +217,9 @@ module Homebrew::EnvConfig sig { returns(T.nilable(String)) } def self.sudo_askpass; end + sig { returns(T::Boolean) } + def self.sudo_through_sudo_user?; end + sig { returns(T.nilable(String)) } def self.svn; end diff --git a/Library/Homebrew/system_command.rb b/Library/Homebrew/system_command.rb index 2a2d7bd6b6..afe5530921 100644 --- a/Library/Homebrew/system_command.rb +++ b/Library/Homebrew/system_command.rb @@ -157,11 +157,25 @@ class SystemCommand set_variables end + sig { returns(T.nilable(String)) } + def homebrew_sudo_user + ENV.fetch("HOMEBREW_SUDO_USER", nil) + end + sig { returns(T::Array[String]) } def sudo_prefix - user_flags = [] - user_flags += ["-u", "root"] if sudo_as_root? askpass_flags = ENV.key?("SUDO_ASKPASS") ? ["-A"] : [] + user_flags = [] + if Homebrew::EnvConfig.sudo_through_sudo_user? + raise ArgumentError, "HOMEBREW_SUDO_THROUGH_SUDO_USER set but SUDO_USER unset!" if homebrew_sudo_user.blank? + + user_flags += ["--prompt", "Password for %p:", "-u", homebrew_sudo_user, + *askpass_flags, + "-E", *env_args, + "--", "/usr/bin/sudo"] + elsif sudo_as_root? + user_flags += ["-u", "root"] + end ["/usr/bin/sudo", *user_flags, *askpass_flags, "-E", *env_args, "--"] end diff --git a/docs/Manpage.md b/docs/Manpage.md index c660eb7c32..a643b40a43 100644 --- a/docs/Manpage.md +++ b/docs/Manpage.md @@ -2362,6 +2362,9 @@ command execution e.g. `$(cat file)`. - `HOMEBREW_SYSTEM_ENV_TAKES_PRIORITY`
If set in Homebrew's system-wide environment file (`/etc/homebrew/brew.env`), the system-wide environment file will be loaded last to override any prefix or user settings. +- `HOMEBREW_SUDO_THROUGH_SUDO_USER` +
If set, Homebrew will use the `SUDO_USER` environment variable to define the user to `sudo`(8) through when running `sudo`(8). + - `HOMEBREW_TEMP`
Use this path as the temporary directory for building packages. Changing this may be needed if your system temporary directory and Homebrew prefix are on different volumes, as macOS has trouble moving symlinks across volumes when the target does not yet exist. This issue typically occurs when using FileVault or custom SSD configurations. diff --git a/manpages/brew.1 b/manpages/brew.1 index 3f905a5045..d2eaee580d 100644 --- a/manpages/brew.1 +++ b/manpages/brew.1 @@ -3483,6 +3483,12 @@ Use this as the \fBsvn\fR(1) binary\. If set in Homebrew\'s system\-wide environment file (\fB/etc/homebrew/brew\.env\fR), the system\-wide environment file will be loaded last to override any prefix or user settings\. . .TP +\fBHOMEBREW_SUDO_THROUGH_SUDO_USER\fR +. +.br +If set, Homebrew will use the \fBSUDO_USER\fR environment variable to define the user to \fBsudo\fR(8) through when running \fBsudo\fR(8)\. +. +.TP \fBHOMEBREW_TEMP\fR . .br