Browse Source

feat(su): deelevate if ran as su using a privilege elevation tool

jguer 3 years ago
parent
commit
bc1d900fa9
3 changed files with 37 additions and 5 deletions
  1. 1 1
      install.go
  2. 5 3
      pkg/settings/dirs.go
  3. 31 1
      pkg/settings/exe/cmd_builder.go

+ 1 - 1
install.go

@@ -176,7 +176,7 @@ 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 {
+	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"))
 	}
 

+ 5 - 3
pkg/settings/dirs.go

@@ -33,19 +33,21 @@ func getConfigPath() string {
 }
 
 func getCacheHome() string {
-	if cacheHome := os.Getenv("XDG_CACHE_HOME"); cacheHome != "" {
+	uid := os.Geteuid()
+
+	if cacheHome := os.Getenv("XDG_CACHE_HOME"); cacheHome != "" && uid != 0 {
 		if err := initDir(cacheHome); err == nil {
 			return filepath.Join(cacheHome, "yay")
 		}
 	}
 
-	if cacheHome := os.Getenv("HOME"); cacheHome != "" {
+	if cacheHome := os.Getenv("HOME"); cacheHome != "" && uid != 0 {
 		if err := initDir(cacheHome); err == nil {
 			return filepath.Join(cacheHome, ".cache", "yay")
 		}
 	}
 
-	return "/tmp"
+	return os.TempDir()
 }
 
 func initDir(dir string) error {

+ 31 - 1
pkg/settings/exe/cmd_builder.go

@@ -5,8 +5,11 @@ import (
 	"fmt"
 	"os"
 	"os/exec"
+	"os/user"
 	"path/filepath"
+	"strconv"
 	"strings"
+	"syscall"
 	"time"
 
 	"github.com/leonelquinteros/gotext"
@@ -63,6 +66,8 @@ func (c *CmdBuilder) BuildGitCmd(ctx context.Context, dir string, extraArgs ...s
 
 	cmd.Env = append(os.Environ(), "GIT_TERMINAL_PROMPT=0")
 
+	c.deElevateCommand(cmd)
+
 	return cmd
 }
 
@@ -85,6 +90,8 @@ func (c *CmdBuilder) BuildMakepkgCmd(ctx context.Context, dir string, extraArgs
 	cmd := exec.CommandContext(ctx, c.MakepkgBin, args...)
 	cmd.Dir = dir
 
+	c.deElevateCommand(cmd)
+
 	return cmd
 }
 
@@ -92,6 +99,26 @@ func (c *CmdBuilder) SetPacmanDBPath(dbPath string) {
 	c.PacmanDBPath = dbPath
 }
 
+func (c *CmdBuilder) deElevateCommand(cmd *exec.Cmd) {
+	if os.Geteuid() != 0 {
+		return
+	}
+
+	ogCaller := ""
+	if caller := os.Getenv("SUDO_USER"); caller != "" {
+		ogCaller = caller
+	} else if caller := os.Getenv("DOAS_USER"); caller != "" {
+		ogCaller = caller
+	}
+
+	if userFound, err := user.Lookup(ogCaller); err == nil {
+		cmd.SysProcAttr = &syscall.SysProcAttr{}
+		uid, _ := strconv.Atoi(userFound.Uid)
+		gid, _ := strconv.Atoi(userFound.Gid)
+		cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
+	}
+}
+
 func (c *CmdBuilder) buildPrivilegeElevatorCommand(ctx context.Context, ogArgs []string) *exec.Cmd {
 	if c.SudoBin == "su" {
 		return exec.CommandContext(ctx, c.SudoBin, "-c", strings.Join(ogArgs, " "))
@@ -121,7 +148,10 @@ func (c *CmdBuilder) BuildPacmanCmd(ctx context.Context, args *parser.Arguments,
 
 	if needsRoot {
 		waitLock(c.PacmanDBPath)
-		return c.buildPrivilegeElevatorCommand(ctx, argArr)
+
+		if os.Geteuid() != 0 {
+			return c.buildPrivilegeElevatorCommand(ctx, argArr)
+		}
 	}
 
 	return exec.CommandContext(ctx, argArr[0], argArr[1:]...)