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 ¶
const HelperArg = "__scriptling-provision-helper"
HelperArg, as a program's first argument, makes ServeIfHelper run the helper.
Variables ¶
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 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.
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 ¶
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 ¶
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.
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.