Browse Source

feat(su): deelevate if ran as su without tool

jguer 3 years ago
parent
commit
ffb17fd2e3
17 changed files with 97 additions and 54 deletions
  1. 0 4
      install.go
  2. 0 4
      pkg/settings/config.go
  3. 17 12
      pkg/settings/dirs.go
  4. 14 1
      pkg/settings/errors.go
  5. 37 4
      pkg/settings/exe/cmd_builder.go
  6. 2 2
      po/en.po
  7. 3 3
      po/es.po
  8. 3 3
      po/eu.po
  9. 3 3
      po/fr_FR.po
  10. 3 3
      po/ja.po
  11. 3 3
      po/ko.po
  12. 1 1
      po/pl_PL.po
  13. 1 1
      po/pt.po
  14. 3 3
      po/pt_BR.po
  15. 3 3
      po/ru_RU.po
  16. 3 3
      po/sv.po
  17. 1 1
      po/zh_CN.po

+ 0 - 4
install.go

@@ -176,10 +176,6 @@ func install(ctx context.Context, cmdArgs *parser.Arguments, dbExecutor db.Execu
 			cmdArgs, config.Runtime.Mode, settings.NoConfirm))
 	}
 
-	if len(dp.Aur) > 0 && os.Geteuid() == 0 && os.Getenv("SUDO_USER") == "" && os.Getenv("DOAS_USER") == "" {
-		return fmt.Errorf(gotext.Get("refusing to install AUR packages as root, aborting"))
-	}
-
 	conflicts, errCC := dp.CheckConflicts(config.UseAsk, settings.NoConfirm, noDeps)
 	if errCC != nil {
 		return errCC

+ 0 - 4
pkg/settings/config.go

@@ -264,10 +264,6 @@ func NewConfig(version string) (*Configuration, error) {
 	newConfig.Runtime.VCSStore = vcs.NewInfoStore(
 		filepath.Join(cacheHome, vcsFileName), newConfig.Runtime.CmdBuilder)
 
-	if err := initDir(newConfig.BuildDir); err != nil {
-		return nil, err
-	}
-
 	err := newConfig.Runtime.VCSStore.Load()
 
 	return newConfig, err

+ 17 - 12
pkg/settings/dirs.go

@@ -3,9 +3,6 @@ package settings
 import (
 	"os"
 	"path/filepath"
-
-	"github.com/leonelquinteros/gotext"
-	"github.com/pkg/errors"
 )
 
 // configFileName holds the name of the config file.
@@ -18,14 +15,16 @@ const completionFileName string = "completion.cache"
 
 func getConfigPath() string {
 	if configHome := os.Getenv("XDG_CONFIG_HOME"); configHome != "" {
-		if err := initDir(configHome); err == nil {
-			return filepath.Join(configHome, "yay", configFileName)
+		configDir := filepath.Join(configHome, "yay")
+		if err := initDir(configDir); err == nil {
+			return filepath.Join(configDir, configFileName)
 		}
 	}
 
 	if configHome := os.Getenv("HOME"); configHome != "" {
-		if err := initDir(configHome); err == nil {
-			return filepath.Join(configHome, ".config", "yay", configFileName)
+		configDir := filepath.Join(configHome, ".config", "yay")
+		if err := initDir(configDir); err == nil {
+			return filepath.Join(configDir, configFileName)
 		}
 	}
 
@@ -36,24 +35,30 @@ func getCacheHome() string {
 	uid := os.Geteuid()
 
 	if cacheHome := os.Getenv("XDG_CACHE_HOME"); cacheHome != "" && uid != 0 {
-		if err := initDir(cacheHome); err == nil {
-			return filepath.Join(cacheHome, "yay")
+		cacheDir := filepath.Join(cacheHome, "yay")
+		if err := initDir(cacheDir); err == nil {
+			return cacheDir
 		}
 	}
 
 	if cacheHome := os.Getenv("HOME"); cacheHome != "" && uid != 0 {
-		if err := initDir(cacheHome); err == nil {
-			return filepath.Join(cacheHome, ".cache", "yay")
+		cacheDir := filepath.Join(cacheHome, ".cache", "yay")
+		if err := initDir(cacheDir); err == nil {
+			return cacheDir
 		}
 	}
 
+	if uid == 0 && os.Getenv("SUDO_USER") == "" && os.Getenv("DOAS_USER") == "" {
+		return "/var/cache/yay" // Don't create directory if systemd-run takes care of it
+	}
+
 	return os.TempDir()
 }
 
 func initDir(dir string) error {
 	if _, err := os.Stat(dir); os.IsNotExist(err) {
 		if err = os.MkdirAll(dir, 0o755); err != nil {
-			return errors.New(gotext.Get("failed to create config directory '%s': %s", dir, err))
+			return &ErrRuntimeDir{inner: err, dir: dir}
 		}
 	} else if err != nil {
 		return err

+ 14 - 1
pkg/settings/errors.go

@@ -1,6 +1,10 @@
 package settings
 
-import "fmt"
+import (
+	"fmt"
+
+	"github.com/leonelquinteros/gotext"
+)
 
 type ErrPrivilegeElevatorNotFound struct {
 	confValue string
@@ -9,3 +13,12 @@ type ErrPrivilegeElevatorNotFound struct {
 func (e *ErrPrivilegeElevatorNotFound) Error() string {
 	return fmt.Sprintf("unable to find a privilege elevator, config value: %s", e.confValue)
 }
+
+type ErrRuntimeDir struct {
+	inner error
+	dir   string
+}
+
+func (e *ErrRuntimeDir) Error() string {
+	return gotext.Get("failed to create directory '%s': %s", e.dir, e.inner)
+}

+ 37 - 4
pkg/settings/exe/cmd_builder.go

@@ -66,7 +66,7 @@ func (c *CmdBuilder) BuildGitCmd(ctx context.Context, dir string, extraArgs ...s
 
 	cmd.Env = append(os.Environ(), "GIT_TERMINAL_PROMPT=0")
 
-	c.deElevateCommand(cmd)
+	cmd = c.deElevateCommand(ctx, cmd)
 
 	return cmd
 }
@@ -90,7 +90,7 @@ func (c *CmdBuilder) BuildMakepkgCmd(ctx context.Context, dir string, extraArgs
 	cmd := exec.CommandContext(ctx, c.MakepkgBin, args...)
 	cmd.Dir = dir
 
-	c.deElevateCommand(cmd)
+	cmd = c.deElevateCommand(ctx, cmd)
 
 	return cmd
 }
@@ -99,9 +99,10 @@ func (c *CmdBuilder) SetPacmanDBPath(dbPath string) {
 	c.PacmanDBPath = dbPath
 }
 
-func (c *CmdBuilder) deElevateCommand(cmd *exec.Cmd) {
+// deElevateCommand, `systemd-run` code based on pikaur.
+func (c *CmdBuilder) deElevateCommand(ctx context.Context, cmd *exec.Cmd) *exec.Cmd {
 	if os.Geteuid() != 0 {
-		return
+		return cmd
 	}
 
 	ogCaller := ""
@@ -116,7 +117,39 @@ func (c *CmdBuilder) deElevateCommand(cmd *exec.Cmd) {
 		uid, _ := strconv.Atoi(userFound.Uid)
 		gid, _ := strconv.Atoi(userFound.Gid)
 		cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
+
+		return cmd
+	}
+
+	cmdArgs := []string{
+		"--service-type=oneshot",
+		"--pipe", "--wait", "--pty",
+		"-p", "DynamicUser=yes",
+		"-p", "CacheDirectory=yay",
+		"-E", "HOME=/tmp",
+	}
+
+	if cmd.Dir != "" {
+		cmdArgs = append(cmdArgs, "-p", fmt.Sprintf("WorkingDirectory=%s", cmd.Dir))
+	}
+
+	for _, envVarName := range [...]string{"http_proxy", "https_proxy", "ftp_proxy"} {
+		if env := os.Getenv(envVarName); env != "" {
+			cmdArgs = append(cmdArgs, "-E", fmt.Sprintf("%s=%s", envVarName, env))
+		}
+	}
+
+	path, err := exec.LookPath(cmd.Args[0])
+	if err != nil {
+		panic("path should have already been validated")
 	}
+
+	cmdArgs = append(cmdArgs, path)
+	cmdArgs = append(cmdArgs, cmd.Args[1:]...)
+
+	systemdCmd := exec.CommandContext(ctx, "systemd-run", cmdArgs...)
+
+	return systemdCmd
 }
 
 func (c *CmdBuilder) buildPrivilegeElevatorCommand(ctx context.Context, ogArgs []string) *exec.Cmd {

+ 2 - 2
po/en.po

@@ -523,7 +523,7 @@ msgid "error updating package install reason to explicit"
 msgstr ""
 
 #: pkg/settings/dirs.go:54
-msgid "failed to create config directory '%s': %s"
+msgid "failed to create directory '%s': %s"
 msgstr ""
 
 #: pkg/settings/config.go:252
@@ -646,4 +646,4 @@ msgstr ""
 
 #: pkg/text/text.go:59
 msgid "yes"
-msgstr ""
+msgstr ""

+ 3 - 3
po/es.po

@@ -1,7 +1,7 @@
-# 
+#
 # Translators:
 # J G <transifex@jguer.space>, 2021
-# 
+#
 msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
@@ -520,7 +520,7 @@ msgid "failed to create BuildDir directory '%s': %s"
 msgstr "fracaso al crear carpeta de compilación (BuildDir) '%s': %s"
 
 #: pkg/settings/runtime.go:79
-msgid "failed to create config directory '%s': %s"
+msgid "failed to create directory '%s': %s"
 msgstr "fracaso al crear carpeta de configuración '%s': %s"
 
 #: download.go:288

+ 3 - 3
po/eu.po

@@ -1,7 +1,7 @@
-# 
+#
 # Translators:
 # J G <transifex@jguer.space>, 2021
-# 
+#
 msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
@@ -518,7 +518,7 @@ msgid "failed to create BuildDir directory '%s': %s"
 msgstr "'%s' BuildDir direktorioa sortzeak huts egin du: %s"
 
 #: pkg/settings/runtime.go:79
-msgid "failed to create config directory '%s': %s"
+msgid "failed to create directory '%s': %s"
 msgstr "'%s' konfigurazio direktorioa sortzeak huts egin du: %s"
 
 #: download.go:288

+ 3 - 3
po/fr_FR.po

@@ -1,7 +1,7 @@
-# 
+#
 # Translators:
 # J G <transifex@jguer.space>, 2021
-# 
+#
 msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
@@ -522,7 +522,7 @@ msgstr ""
 "échec lors de la création du répertoire de construction (BuildDir) '%s' : %s"
 
 #: pkg/settings/runtime.go:79
-msgid "failed to create config directory '%s': %s"
+msgid "failed to create directory '%s': %s"
 msgstr "échec lors de la récation du répertoire de configuration '%s' : %s"
 
 #: download.go:288

+ 3 - 3
po/ja.po

@@ -1,7 +1,7 @@
-# 
+#
 # Translators:
 # J G <transifex@jguer.space>, 2021
-# 
+#
 msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
@@ -516,7 +516,7 @@ msgid "failed to create BuildDir directory '%s': %s"
 msgstr "BuildDir ディレクトリ '%s' の作成に失敗: %s"
 
 #: pkg/settings/runtime.go:79
-msgid "failed to create config directory '%s': %s"
+msgid "failed to create directory '%s': %s"
 msgstr "設定ディレクトリ '%s' の作成に失敗: %s"
 
 #: download.go:288

+ 3 - 3
po/ko.po

@@ -1,7 +1,7 @@
-# 
+#
 # Translators:
 # J G <transifex@jguer.space>, 2021
-# 
+#
 msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
@@ -516,7 +516,7 @@ msgid "failed to create BuildDir directory '%s': %s"
 msgstr "BuildDir 디렉토리 '%s' 생성 실패: %s"
 
 #: pkg/settings/runtime.go:79
-msgid "failed to create config directory '%s': %s"
+msgid "failed to create directory '%s': %s"
 msgstr "설정 디렉토리 '%s' 생성 실패: %s"
 
 #: download.go:288

+ 1 - 1
po/pl_PL.po

@@ -523,7 +523,7 @@ msgid "failed to create BuildDir directory '%s': %s"
 msgstr "nie udało się stworzyć katalogu kompilacji '%s': %s"
 
 #: pkg/settings/runtime.go:79
-msgid "failed to create config directory '%s': %s"
+msgid "failed to create directory '%s': %s"
 msgstr "nie udało się stworzyć katalogu konfiguracyjnego '%s': %s"
 
 #: download.go:288

+ 1 - 1
po/pt.po

@@ -513,7 +513,7 @@ msgid "failed to create BuildDir directory '%s': %s"
 msgstr "falha ao criar pasta BuildDir: '%s': %s"
 
 #: pkg/settings/runtime.go:79
-msgid "failed to create config directory '%s': %s"
+msgid "failed to create directory '%s': %s"
 msgstr "falha ao crear pasta de configuração '%s': %s"
 
 #: download.go:288

+ 3 - 3
po/pt_BR.po

@@ -1,7 +1,7 @@
-# 
+#
 # Translators:
 # J G <transifex@jguer.space>, 2021
-# 
+#
 msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
@@ -517,7 +517,7 @@ msgid "failed to create BuildDir directory '%s': %s"
 msgstr "falha ao criar diretório BuildDir '%s': %s"
 
 #: pkg/settings/runtime.go:79
-msgid "failed to create config directory '%s': %s"
+msgid "failed to create directory '%s': %s"
 msgstr "falha ao criar diretório de configurações '%s': %s"
 
 #: download.go:288

+ 3 - 3
po/ru_RU.po

@@ -1,7 +1,7 @@
-# 
+#
 # Translators:
 # J G <transifex@jguer.space>, 2021
-# 
+#
 msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
@@ -519,7 +519,7 @@ msgid "failed to create BuildDir directory '%s': %s"
 msgstr "ошибка создания каталога BuildDir '%s': %s"
 
 #: pkg/settings/runtime.go:79
-msgid "failed to create config directory '%s': %s"
+msgid "failed to create directory '%s': %s"
 msgstr "ошибка создания каталога конфигурации '%s': %s"
 
 #: download.go:288

+ 3 - 3
po/sv.po

@@ -1,7 +1,7 @@
-# 
+#
 # Translators:
 # J G <transifex@jguer.space>, 2021
-# 
+#
 msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
@@ -518,7 +518,7 @@ msgid "failed to create BuildDir directory '%s': %s"
 msgstr "misslyckades med att skapa BuildDir-katalog '%s': %s"
 
 #: pkg/settings/runtime.go:79
-msgid "failed to create config directory '%s': %s"
+msgid "failed to create directory '%s': %s"
 msgstr "misslyckades med att skapa konfigurationskatalog '%s': %s"
 
 #: download.go:288

+ 1 - 1
po/zh_CN.po

@@ -513,7 +513,7 @@ msgid "failed to create BuildDir directory '%s': %s"
 msgstr "无法创建 BuildDir 目录 '%s': %s"
 
 #: pkg/settings/runtime.go:79
-msgid "failed to create config directory '%s': %s"
+msgid "failed to create directory '%s': %s"
 msgstr "无法创建配置目录 '%s': %s"
 
 #: download.go:288