убрана лишняя зависимость bindfs и избыточное использование дополнительного пользователя alr
This commit is contained in:
163
internal.go
163
internal.go
@@ -17,14 +17,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
|
||||
"github.com/hashicorp/go-hclog"
|
||||
@@ -36,7 +30,6 @@ import (
|
||||
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
|
||||
appbuilder "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils/app_builder"
|
||||
"gitea.plemya-x.ru/Plemya-x/ALR/internal/config"
|
||||
"gitea.plemya-x.ru/Plemya-x/ALR/internal/constants"
|
||||
"gitea.plemya-x.ru/Plemya-x/ALR/internal/logger"
|
||||
"gitea.plemya-x.ru/Plemya-x/ALR/internal/manager"
|
||||
"gitea.plemya-x.ru/Plemya-x/ALR/internal/utils"
|
||||
@@ -52,9 +45,6 @@ func InternalBuildCmd() *cli.Command {
|
||||
|
||||
slog.Debug("start _internal-safe-script-executor", "uid", syscall.Getuid(), "gid", syscall.Getgid())
|
||||
|
||||
if err := utils.ExitIfCantDropCapsToAlrUser(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg := config.New()
|
||||
err := cfg.Load()
|
||||
@@ -92,9 +82,6 @@ func InternalReposCmd() *cli.Command {
|
||||
Action: utils.RootNeededAction(func(ctx *cli.Context) error {
|
||||
logger.SetupForGoPlugin()
|
||||
|
||||
if err := utils.ExitIfCantDropCapsToAlrUser(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
deps, err := appbuilder.
|
||||
New(ctx.Context).
|
||||
@@ -129,16 +116,7 @@ func InternalInstallCmd() *cli.Command {
|
||||
Action: func(c *cli.Context) error {
|
||||
logger.SetupForGoPlugin()
|
||||
|
||||
if err := utils.EnsureIsAlrUser(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Before escalating the rights, we made sure that
|
||||
// this is an ALR user, so it looks safe.
|
||||
err := utils.EscalateToRootUid()
|
||||
if err != nil {
|
||||
return cliutils.FormatCliExit("cannot escalate to root", err)
|
||||
}
|
||||
// Запуск от текущего пользователя, повышение прав будет через sudo при необходимости
|
||||
|
||||
deps, err := appbuilder.
|
||||
New(c.Context).
|
||||
@@ -175,143 +153,4 @@ func InternalInstallCmd() *cli.Command {
|
||||
}
|
||||
}
|
||||
|
||||
func Mount(target string) (string, func(), error) {
|
||||
exe, err := os.Executable()
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("failed to get executable path: %w", err)
|
||||
}
|
||||
|
||||
cmd := exec.Command(exe, "_internal-temporary-mount", target)
|
||||
|
||||
stdoutPipe, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("failed to get stdout pipe: %w", err)
|
||||
}
|
||||
|
||||
stdinPipe, err := cmd.StdinPipe()
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("failed to get stdin pipe: %w", err)
|
||||
}
|
||||
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
if err := cmd.Start(); err != nil {
|
||||
return "", nil, fmt.Errorf("failed to start mount: %w", err)
|
||||
}
|
||||
|
||||
scanner := bufio.NewScanner(stdoutPipe)
|
||||
var mountPath string
|
||||
if scanner.Scan() {
|
||||
mountPath = scanner.Text()
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
_ = cmd.Process.Kill()
|
||||
return "", nil, fmt.Errorf("failed to read mount output: %w", err)
|
||||
}
|
||||
|
||||
if mountPath == "" {
|
||||
_ = cmd.Process.Kill()
|
||||
return "", nil, errors.New("mount failed: no target path returned")
|
||||
}
|
||||
|
||||
cleanup := func() {
|
||||
slog.Debug("cleanup triggered")
|
||||
_, _ = fmt.Fprintln(stdinPipe, "")
|
||||
_ = cmd.Wait()
|
||||
}
|
||||
|
||||
return mountPath, cleanup, nil
|
||||
}
|
||||
|
||||
func InternalMountCmd() *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "_internal-temporary-mount",
|
||||
HideHelp: true,
|
||||
Hidden: true,
|
||||
Action: func(c *cli.Context) error {
|
||||
logger.SetupForGoPlugin()
|
||||
|
||||
sourceDir := c.Args().First()
|
||||
|
||||
u, err := user.Current()
|
||||
if err != nil {
|
||||
return cliutils.FormatCliExit("cannot get current user", err)
|
||||
}
|
||||
|
||||
_, alrGid, err := utils.GetUidGidAlrUser()
|
||||
if err != nil {
|
||||
return cliutils.FormatCliExit("cannot get alr user", err)
|
||||
}
|
||||
|
||||
if _, err := os.Stat(sourceDir); err != nil {
|
||||
return cliutils.FormatCliExit(fmt.Sprintf("cannot read %s", sourceDir), err)
|
||||
}
|
||||
|
||||
if err := utils.EnuseIsPrivilegedGroupMember(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Before escalating the rights, we made sure that
|
||||
// 1. user in wheel group
|
||||
// 2. user can access sourceDir
|
||||
if err := utils.EscalateToRootUid(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := syscall.Setgid(alrGid); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(constants.AlrRunDir, 0o770); err != nil {
|
||||
return cliutils.FormatCliExit(fmt.Sprintf("failed to create %s", constants.AlrRunDir), err)
|
||||
}
|
||||
|
||||
if err := os.Chown(constants.AlrRunDir, 0, alrGid); err != nil {
|
||||
return cliutils.FormatCliExit(fmt.Sprintf("failed to chown %s", constants.AlrRunDir), err)
|
||||
}
|
||||
|
||||
targetDir := filepath.Join(constants.AlrRunDir, fmt.Sprintf("bindfs-%d", os.Getpid()))
|
||||
// 0750: owner (root) and group (alr)
|
||||
if err := os.MkdirAll(targetDir, 0o750); err != nil {
|
||||
return cliutils.FormatCliExit("error creating bindfs target directory", err)
|
||||
}
|
||||
|
||||
// chown AlrRunDir/mounts/bindfs-* to (root:alr),
|
||||
// so alr user can access dir
|
||||
if err := os.Chown(targetDir, 0, alrGid); err != nil {
|
||||
return cliutils.FormatCliExit("failed to chown bindfs directory", err)
|
||||
}
|
||||
|
||||
bindfsCmd := exec.Command(
|
||||
"bindfs",
|
||||
fmt.Sprintf("--map=%s/alr:@%s/@alr", u.Uid, u.Gid),
|
||||
sourceDir,
|
||||
targetDir,
|
||||
)
|
||||
|
||||
bindfsCmd.Stderr = os.Stderr
|
||||
|
||||
if err := bindfsCmd.Run(); err != nil {
|
||||
return cliutils.FormatCliExit("failed to strart bindfs", err)
|
||||
}
|
||||
|
||||
fmt.Println(targetDir)
|
||||
|
||||
_, _ = bufio.NewReader(os.Stdin).ReadString('\n')
|
||||
|
||||
slog.Debug("start unmount", "dir", targetDir)
|
||||
|
||||
umountCmd := exec.Command("umount", targetDir)
|
||||
umountCmd.Stderr = os.Stderr
|
||||
if err := umountCmd.Run(); err != nil {
|
||||
return cliutils.FormatCliExit(fmt.Sprintf("failed to unmount %s", targetDir), err)
|
||||
}
|
||||
|
||||
if err := os.Remove(targetDir); err != nil {
|
||||
return cliutils.FormatCliExit(fmt.Sprintf("error removing directory %s", targetDir), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user