become

package
v0.38.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 10, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package become runs provisioning work as root for a script that runs as an ordinary user.

The first operation a script asks for with become=True starts one helper: this program again, run through sudo. sudo is first asked not to prompt (sudo -n), so a user with passwordless sudo is never asked anything; when sudo wants a password and there is a terminal, it asks once on it. Every later root operation goes to that helper over a pipe, and it ends with the program (or when Close is called).

The helper does the same work as the unprivileged path, with the same functions (registered with Handle), and holds paths to the same allowed directories. A program that offers become must let the helper start: call ServeIfHelper first thing in main.

Index

Constants

View Source
const HelperArg = "__scriptling-provision-helper"

HelperArg, as a program's first argument, makes ServeIfHelper run the helper.

Variables

View Source
var ErrNotEnabled = errors.New("become=True needs root, and running as root is turned off here " +
	"(the scriptling CLI turns it off with --deny-become, or when the subprocess library is disabled)")

ErrNotEnabled is returned for a root operation where become is not enabled.

Functions

func Do

func Do[A, R any](ctx context.Context, b *Become, asRoot bool, paths fssecurity.Config, op string, a A) (R, error)

Do runs op with a. As root it runs in the helper when asRoot is set and this process is not root already; otherwise here, confined to paths. b may be nil when become is not enabled: an operation as root then fails with ErrNotEnabled, unless this process is root.

func Handle

func Handle[A, R any](op string, fn func(ctx context.Context, paths fssecurity.Config, a A) (R, error))

Handle registers op, so Do can run it here or in the helper. Call it from an init function: the helper knows the operations its program registered. A and R must be gob-encodable.

func IsRoot

func IsRoot() bool

IsRoot reports whether this process runs as root.

func ServeIfHelper

func ServeIfHelper()

ServeIfHelper runs the helper and exits when this program was started as one (its first argument is HelperArg); otherwise it returns at once. A program that enables become calls it first thing in main.

Types

type Become

type Become struct {
	// contains filtered or unexported fields
}

Become hands root operations to a helper running as root. Its methods are safe to call from several goroutines; operations run one at a time.

func New

func New(cfg Config) *Become

New returns a Become that starts its helper when it is first needed.

func (*Become) Close

func (b *Become) Close() error

Close stops the helper, if it runs. Later operations fail.

type Config

type Config struct {
	// Paths confines the helper's file operations, as the libraries'.
	Paths fssecurity.Config
	// Command is the helper's command line, without sudo. Empty: this
	// program with HelperArg.
	Command []string
	// Sudo runs Command as root. Empty: "sudo". Its -n option must make it
	// fail instead of prompting, as sudo's and doas's do.
	Sudo []string
	// NonRootHelper accepts a helper that is not root. For tests, which run
	// the helper without sudo.
	NonRootHelper bool
}

Config says how to start the helper.

type Owner

type Owner struct {
	User  string
	Group string
}

Owner names who a file belongs to: a user and a group, by name or number. Empty leaves that part as it is.

func (Owner) Apply

func (o Owner) Apply(paths fssecurity.Config, path string) (bool, error)

Apply gives path the named owner and group, if it has not got them, and reports whether it changed anything. path must be within paths.

func (Owner) Check

func (o Owner) Check() error

Check resolves the names, so a bad one fails before anything is written.

func (Owner) Given

func (o Owner) Given() bool

Given reports whether an owner or a group is named.

type RunArgs

type RunArgs struct {
	Argv    []string // the program and its arguments; or
	Shell   string   // a command line for /bin/sh -c
	Dir     string   // working directory; empty: the current one
	Env     []string // KEY=value entries added to the environment
	Input   []byte   // standard input; nil: none
	Timeout time.Duration
}

RunArgs is a command to run.

type RunResult

type RunResult struct {
	Code   int
	Stdout []byte
	Stderr []byte
}

RunResult is how a command ended.

func Run

func Run(ctx context.Context, b *Become, asRoot bool, a RunArgs) (RunResult, error)

Run runs a command, as root when asRoot is set.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL