From eb1355e624c1567335c9f527925fb0fc6a134fdc Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Fri, 29 Sep 2023 18:49:44 +0100 Subject: [PATCH] Add HOMEBREW_SUDO_THROUGH_SUDO_USER This environment variable allows telling Homebrew to use the `SUDO_USER` variable to `sudo` through that user when Homebrew (Cask) attempts to run `sudo`. While we're here, clarify in some messaging that we're running `sudo` and that that's the password we're asking for; the specific password is configuration dependent and not the specific password for the user. Similarly, remove the `Package installers may write to any location` output; it's kinda spammy and doesn't feel like the right place. --- .../cask/artifact/abstract_uninstall.rb | 2 +- Library/Homebrew/cask/artifact/pkg.rb | 3 +-- Library/Homebrew/cask/staged.rb | 2 +- Library/Homebrew/env_config.rb | 5 +++++ Library/Homebrew/env_config.rbi | 3 +++ Library/Homebrew/system_command.rb | 18 ++++++++++++++++-- docs/Manpage.md | 3 +++ manpages/brew.1 | 6 ++++++ 8 files changed, 36 insertions(+), 6 deletions(-) diff --git a/Library/Homebrew/cask/artifact/abstract_uninstall.rb b/Library/Homebrew/cask/artifact/abstract_uninstall.rb index 234a7a5d8b3f8..78547326b5d80 100644 --- a/Library/Homebrew/cask/artifact/abstract_uninstall.rb +++ b/Library/Homebrew/cask/artifact/abstract_uninstall.rb @@ -379,7 +379,7 @@ def uninstall_script(directives, directive_name: :script, force: false, command: 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 61cd142ec01d7..0d2610f29f620 100644 --- a/Library/Homebrew/cask/artifact/pkg.rb +++ b/Library/Homebrew/cask/artifact/pkg.rb @@ -36,8 +36,7 @@ def install_phase(**options) 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 bd7b2f2a53e73..74df26ec2165c 100644 --- a/Library/Homebrew/cask/staged.rb +++ b/Library/Homebrew/cask/staged.rb @@ -27,7 +27,7 @@ def set_ownership(paths, user: T.must(User.current), group: "staff") 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 b7a0aba96a6de..ae7b7e6c756b5 100644 --- a/Library/Homebrew/env_config.rb +++ b/Library/Homebrew/env_config.rb @@ -373,6 +373,11 @@ module EnvConfig "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 b61b8e519d9c8..1fa98249b3404 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 2a2d7bd6b6265..afe55309216d2 100644 --- a/Library/Homebrew/system_command.rb +++ b/Library/Homebrew/system_command.rb @@ -157,11 +157,25 @@ def env_args 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 c660eb7c32ec1..a643b40a43954 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 3f905a50456e5..d2eaee580d905 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