This file documents Become version 1.4.

Copyright (c) 1998 European Bioinformatics Institute.

Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.

Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the sections entitled `Copying' and `GNU General Public License' are included exactly as in the original, and provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.

Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the European Bioinformatics Institute.

Become
******

Become is a system for managing shared accounts.  It allows users to `become' other users in order to do useful work.  It can be managed on a central server (or a small number of central servers), or it can run standalone.

This file documents Become version 1.4.

The GNU General Public License
******************************

     [file gpl.texi not included]

Introduction
************

It's often useful to be able to share accounts between a number of users.  For example, a group maintaining an externally visible service need to be able to start and kill the server process.  Giving such a shared account a password is a fairly bad plan: such passwords tend not to get changed very often, and they have a habit of spreading beyond the group of legitimate users.

The Become program presented here offers a solution to the problems of shared accounts.  It allows the system administrator to define which users are allowed access to which accounts, on which hosts, and to execute which commands.  Such shared accounts can then, in general, have their passwords removed.

This coincidentally has another advantage: when `becoming' to a shared account, a user can retain her (Or his.  I'll choose one or the other fairly randomly throughout this manual.) own environment, which she's carefully crafted and honed over the years, rather then being presented with some lowest-common-denominator setup which probably doesn't even use the right shell.

The configuration file for Become can either be distributed to all the various hosts in a network or a few carefully set up and secure servers (see Standalone or networked).

Becoming someone else
*********************

The simplest way to become someone else is to say

     become USER

Become will check to see whether you're allowed to become USER.  If you are, it starts a shell process with the user-id set to USER.  Any commands you type are executed with the privileges of USER.

The full invocation is slightly more complicated:

     become [OPTION...] [ENV-VAR...] USER [COMMAND [ARG...]]

Actually, the OPTIONs, ENV-VARs and USER can be in any order -- the important point is that all of them appear before the COMMAND, if there is one.

Terminology
===========

The following terms get used quite a bit in the following text:

request
     An invocation of Become, asking permission to become another user.

old user
     The (real) user id of the process which invoked Become; usually, this will be your normal user id.

target user
     The user whom you want to become, named in a request.

How Become sets up the environment
==================================

There are thorny problems with handling the user's environment.  It seems that (the author's initial assessment notwithstanding) there is no single best way of handling environment variables.  As a result, Become can do just about everything you might want it to.  This gets slightly complicated. Don't worry: it's not as hard as all that.

Environment variables created by Become
---------------------------------------

To help you (and, more importantly, your startup scripts) keep track of who you are, and who you were originally, Become adds some variables to the environment of any processes it starts.

BECOME_USER
     The name of the target user (i.e., the user you are now).  It might be useful to test this value in shell startup scripts, for example.

BECOME_HOME
     The home directory of the target user.  It can be handy to read startup and other configuration files from here.

BECOME_OLD_USER
     The name of the user who invoked Become.

BECOME_OLD_HOME
     The home directory of the `old' user.

BECOME_ORIGINAL_USER
     This is intended to be the name you logged in with.  If it's unset, Become sets it to be the same as BECOME_OLD_USER; otherwise it leaves it unchanged.

BECOME_ORIGINAL_HOME
     This is intended to be the home directory you logged in with.  If it's unset, Become sets it to be the same as BECOME_OLD_HOME; otherwise, it leaves it unchanged.

Don't even think about relying on these variables as a form of authentication.  It won't work.  They're provided only to help organise startup scripts.

Login styles
------------

Originally, Become always tried to preserve your environment.  There's a rational explanation for this approach, which is given in the description of the `preserve' style below.  Unfortunately, not everyone liked this approach.  As a result, there's now a collection of different login styles.

Login styles are selected by giving command line arguments:

-e
--preserve
     The original style: try to preserve the existing user's environment as much as possible.

-s
--set-user
     Set some user-specific variables, like USER and HOME to reflect the target user rather than the old user.  All other variables are preserved.

-l
--login
     Attempts to make the `become' process as much like a real login as possible. All variables not explicitly preserved are deleted, and a new environment is built, reflecting the target user.

The various styles, and the reasons behind them, are described below.

The `preserve' login style
..........................

You've spent many hours (days? weeks, even?) customising and honing your startup files, learning how to use your shell, and tweaking your favourite text editor until it's just the way you like it.  So there can be few things more annoying than logging into a shared account to find out that the shell's wrong, your editor startup files are ignored, and nothing works quite the way you'd like it to.  Typically you can't change this without annoying the other users: the result is a horrible compromise which dissatisfies everyone equally.

The `preserve' style lets you take your standard environment with you when you become someone else.  It tries hard not to modify any environment variables.

Become starts your standard shell.  If you have an environment variable SHELL defined, than this is executed.  Otherwise, the shell specified in your entry in the password file is used.  (You must have permission to execute whatever shell is chosen as the target user, or you'll just be given an error message.)

Most programs look at environment variables in preference to looking up entries in the password database; e.g., they tend to use USER or LOGNAME for the user name, and HOME for your home directory. As a result, most programs will continue to find their configuration files in your home directory.  Also, systems like RCS will use your real name, rather than the name of the user that you have become.

To make best use of this login style, you may need to adjust your login scripts to notice when BECOME_USER is someone else, and read in appropriate definitions.  For example, a `bash' user might say something like this in her .bashrc:

     if [ -n "$BECOME_HOME" ]; then . $BECOME_HOME/.bashrc

Similarly, a C shell user (either `tcsh' or `csh') might say something like

     if ($?BECOME_HOME) source ${BECOME_HOME}/.cshrc

(Note that plain Bourne shell users have a slight problem, because the Bourne shell only reads configuration things on a login, not when a normal interactive shell is started.)

The `set-user' login style
..........................

The author sees the main use of Become as allowing a user to acquire the privileges associated with a shared account without all the problems which shared accounts usually cause.  To the author's way of thinking, one of the main problems is that your environment gets replaced by something alien and wrong.  People disagree with me over this point, and for this reason the `set-user' style exists.

The objective of `set-user' style is to behave similarly to the standard su command.  Unless they've been preserved explicitly (see Tweaking the environment), `set-user' mode sets the following environment variables:

USER
LOGNAME
     The name of the target user.

HOME
     The home directory of the target user.

SHELL
     The target user's default shell

The result of this is that the shell will read the target user's configuration files and present you with the environment set up there.

I can't think of this style as being anything other than a migration aid while users are getting used to the freedom offered by the `preserve' style.

The `login' login style
.......................

The `login' style causes Become to attempt to emulate a full login.  Become will empty the environment of almost variables which aren't explicitly preserved (see Tweaking the environment).  However, the following variables are retained:

  * TERM

  * DISPLAY

  * TZ

It will set the following variables:

USER
LOGNAME
     The name of the target user.

HOME
     The home directory of the target user.

SHELL
     The target user's default shell

MAIL
     An educated guess at where the target user's mailbox is.

By default, it runs the target user's shell, informing it that this is a login by setting the first character of argv[0] to -.

Become makes no entries in the utmp and wtmp files.

Tweaking individual environment variables
-----------------------------------------

Become's login styles provide a sort of course-grained control over the environment.  Sometimes the control isn't fine enough.  Become lets you tweak individual variables: you can set, delete, or preserve named variables from modification.

There are three different things you can do with environment variables:

  * Set a variable called VAR to a value VALUE, by saying

          VAR=VALUE

     The variable is preserved from automatic deletion by the login-style rules.

  * Delete a variable called VAR from the environment, by saying

          VAR-

  * Preserve a variable VAR from being deleted or modified by Become's login-style rules, but not change its value, by saying

          VAR!

Just to try and make this slightly more sensible, here's an example.  Suppose I want my XAUTHORITY variable to be set when I become user `fred':

     become XAUTHORITY=$HOME/.Xauthority fred

should do the job nicely.  Similarly, if I want to log in as `bob', but don't want my EDITOR variable to change:

     become --login EDITOR! bob

(Of course, in this example, I'm at the mercy of Bob's shell init files as to whether his choice of editor overrides mine.)

Variables removed from the environment
--------------------------------------

Some variables are removed from the environment which Become passes to a program for security reasons:

LD_*
SHLIB_PATH
LIBPATH
_RLD_*
     These variables are used on various systems as a search path for shared libraries.  Clearly, by manipulating these search paths, an attacker could replace a standard shared library with one of his own.

IFS
     The shell input field separator.  Modifying this variable radically alters the way shells parse their inputs.  (In particular, consider the case where IFS contains /.)

ENV
BASH_ENV
     Used by some shells: it contains the name of a file to read on every shell invocation.

KRB_CONF
     Contains the name of a Kerberos configuration file.  By manipulating this variable, an attacker could persuade a program to believe the wrong authentication server.

Also note that the PATH variable is modified: any items which aren't absolute pathnames are removed from the path.  This check may become stricter in future, although getting the balance between security and convenience is particularly hard here.

How Become handles groups
=========================

As well as handling changes of user id, Become also changes group ids. The exact changes Become makes are under user control.

Choosing a new primary group
----------------------------

By default, the primary group is chosen according to the login style (see Login styles): the `preserve' style retains the current primary group, while `set-user' and `login' styles choose the target's primary group.

You can override Become's default choice using the --group (-g for short) option:

     become --group=GROUP ...

The chosen GROUP may be either a group name or a numeric gid.  The group must be one of the following:

  * Your current primary group.

  * One of your current subsidiary groups.

  * The target user's primary group.

  * One of the target user's subsidiary groups.

Become will raise an error if this isn't the case.

Handling subsidiary group memberships
-------------------------------------

Subsidiary group memberships are a powerful tool for managing permissions under Unix.  Traditionally, they tend to be tied to particular users.  Become tries to be sightly more intelligent about group memberships.

Become has a concept of group style, analogous to login style (see Login styles).  The styles are selected by giving command line arguments:

-k
--keep-groups
     Retain the existing group memberships; don't add any new groups.

-m
--merge-groups
     Merge group memberships of the target user with the exiting memberships.

-r
--replace-groups
     Replace the existing group memberships with the target user's memberships.

Again, the defaults are dependent on the chosen login style.  Both `preserve' and `set-user' merge group memberships; the `login' style replaces the set of groups.

Note that you can do perverse things like replace all the subsidiary groups but retain your primary group (using the --group option; see Primary group selection) if you like: Become won't try to stop you.

Considerations for X authority
==============================

Other users can't read your .Xauthority file, if you have one.  This is as it should be: anyone who can read it can connect to your X server and read or generate events.  However, once you've become another user, you can't open any X windows; this can be annoying if your favourite editor is X-based.

There are two basic approaches.  Either you can send the shared account a copy of your display's magic cookie, or you can retain permission to read the cookie file.

Be aware that allowing a shared account to connect to your X display is a security risk.

The user-group method for handling X authority
----------------------------------------------

This method is secure only if your site uses the `user-group' system.  In this system, each user is allocated a group containing only that user. Usually this is made the user's default primary group, although that's not necessary here.

When you start a new X session, ensure that your cookie file is owned by you and your private group.  Change the file's permissions so that it's group readable.  Finally, ensure that your private group is retained when you become someone else (see Group permissions), and that the XAUTHORITY variable is set correctly.

Note that Unix's security mechanisms aren't designed to prevent processes owned by the same user from interfering with each other.  This method does not provide complete security.

The following Bourne shell code in a .xinitrc should do most of the work:

     XAUTHORITY="$HOME/.Xauthority"
     export XAUTHORITY
     chgrp mygroup $XAUTHORITY
     chmod 640 $XAUTHORITY

In a C shell, this becomes

     setenv XAUTHORITY ${HOME}/.Xauthority
     chgrp mygroup $XAUTHORITY
     chmod 640 $XAUTHORITY

The XAUTHORITY file is preserved by both the `preserve' and `set-user' login styles, so this isn't a problem.  You can now become other users, and your X permissions will follow you around correctly.

It's probably worth noting that the xauth program annoyingly resets the permissions on the cookie file every time it writes to it.  This will be particularly irritating if you use ssh's X forwarding capabilities, because every ssh connection will reset the permissions.  You can deal with this problem by putting a line

     chmod 640 ${XAUTHORITY-$HOME/.Xauthority} 2>/dev/null

in your .bashrc or .profile (for Bourne-like shell users) or

     if ($?XAUTHORITY) then
       chmod 640 $XAUTHORITY >&/dev/null
     else
       chmod 640 ${HOME}/.Xauthority >&/dev/null
     endif

in .cshrc for C shell users.

The xauth method for handling X authority
-----------------------------------------

This method sends your X cookie to the shared account.  It's therefore intrinsically dangerous: you must be able to trust the other users of the shared account not to take undue advantage of this situation.

The following (Bourne) shell snippet illustrates how you might send an authorisation cookie to the shared account, to allow it to connect to your display:

     if test -n "$BECOME_HOME"; then
       XAUTHORITY="$BECOME_HOME/.Xauthority"; export XAUTHORITY
     elif test -n "$DISPLAY" && test -z "done_xauth_cookie"; then
       case "$DISPLAY" in
         :0.0) display=`hostname`:0.0 ;;
         *) display="$DISPLAY" ;;
       esac
       xauth extract - $display | \
         become someone -c 'xauth -f $BECOME_HOME/.Xauthority merge -'
       done_xauth_cookie=yes; export done_xauth_cookie
     fi

The equivalent C shell code is

     if ($?BECOME_HOME) then
       setenv XAUTHORITY "${BECOME_HOME}/.Xauthority
     else if ($?DISPLAY && ! $?done_xauth_cookie) then
       if ($DISPLAY == :0.0) then
         set display="`hostname`:0.0"
       else
         set display="$DISPLAY"
       endif
       xauth extract - $display | \
         become someone -c 'xauth -f $BECOME_HOME/.Xauthority merge -'
     endif

It works as follows:

  * If the variable BECOME_HOME is set, then we're probably really someone else, so point to the shared account's authority file.

  * Otherwise, check to see whether we have a display, and the authorisation has not already been sent.  If this is so, resolve a local display name into a remote one (just in case) and then send it to the shared account.

Executing specific commands
===========================

As well as starting shells, Become can run single commands.  This can be useful in two ways:

  * It enables Become to be used in scripts.

  * It allows access to shared accounts to be controlled on the basis of the command to be run.

To run a command as another user, say:

     become USER COMMAND [ARGUMENT...]

If the request is granted, Become runs COMMAND, passing it any arguments following the command name.  Become doesn't run a shell, so there's no extra escaping which needs to be done.

If you really want to run a shell command as another user, you can use the -c option:

     become USER -c SHELL-COMMAND

This is exactly equivalent to

     become USER /bin/sh -c SHELL-COMMAND

in every way.  In particular, you must have permission to run /bin/sh as USER for it to work: Become doesn't attempt to interpret the shell command in any way.  Also note that Become always uses the Bourne shell, regardless of your current shell preference, or USER's default shell. (This is done to provide a stable programming interface which works irrespective of changes to the shared account's configuration.)

Become administration
*********************

This chapter will explain how Become is administrated and maintained.

Configuration files
===================

Become keeps its configuration and administrative files in a directory usually named /etc/become, although this can be changed with the --with-etcdir option to the configuration script when you build Become.

Not all of the files are needed on all machines.

become.conf
     The main configuration file, containing a description of which users are allowed to become which other users, where, and what they're allowed to run when they get there.  Only needed on servers or standalone machines.

become.server
     A list of servers to contact.  Only needed on client machines.

become.key
     The signing key to use when sending requests to servers.  Needed on servers, but not on standalone machines.

become.pubkey
     The verification keys to use when checking server responses.  Needed on clients, but not on standalone machines.

become.pid
     The process id of the server.  Created automatically by Become's server when in starts up.

Installation types
==================

Become can be installed in two different ways, depending on how you want to administer it:

  * In a standalone installation, each Become request is dealt with locally: the program reads the configuration file, and decides whether it should grant or deny permission.

     Standalone installations don't depend on servers being available, or even on the existence of a network.  They're useful for small sites, or sites with a small number of users.  The disadvantages are that reading the configuration file takes a while, so the program doesn't feel as responsive as it should, and ensuring that all the hosts' configuration files are synchronised becomes difficult when you have lots of machines.

  * In a network installation, any Become requests are sent on to a collection of servers.  The servers analyse the request and send a reply back which either authorises or forbids access.

     A networked installation clearly depends on the servers' reliability.  The client reacts only to the first reply it receives, so as long as there is one server running, everything should continue as normal.

     A networked installation is useful when you have a large number of client machines, particularly ones which may not be awake all the time.  The full configuration file only needs to be installed on a small number of servers; the clients require only a list of server machines to contact, and an encryption key to use.

The configuration file
======================

The main configuration file, usually called /etc/become/become.conf, contains all the rules which Become uses to decide whether to grant or deny requests.  It may also contain additional information for the benefit of Become daemons, if you're using a networked installation.

Requests and rules
------------------

Become looks at four pieces of information when it's analysing a request:

  * the user's current identity;

  * the identity the user wishes to assume;

  * the host which generated the request; and

  * the command the user wishes to run.

Each of these pieces of information is looked at when Become decides whether to honour a request.

The configuration file's main purpose is to describe the conditions under which Become should honour a request.  These conditions are described by a number of rules.  A rule consists of two lists of users (called `from' and `to'), a list of hosts, and a list of commands.  A rule matches a request if:

  * the user's current identity is in the rule's `from' list;

  * the target user's identity is in the rule's `to' list;

  * the host is in the rule's host list; and

  * the command to be run is in the rule's command list.

A request is honoured if there is a rule which matches the request.

Basic configuration file syntax
-------------------------------

The configuration file consists of a sequence of statements, each terminated by a semicolon.

Comments begin with a # character, and continue to the end of the line.  This is the only time newlines behave specially: newlines behave just like any other whitespace characters within statements.

Strings are enclosed in double-quote characters (").  Within a string, a backslash causes the following character to be treated literally, whatever it may be (including quotes, backslashes and newlines).

Names begin with an alphabetic character or an underscore, and consist of letters, digits and underscores.

Classes
-------

A class in Become is a set of users, hosts or commands.  You can define and name your own classes using statements of the form:

     user NAME = CLASS-EXPR ;
     command NAME = CLASS-EXPR ;
     host NAME = CLASS-EXPR ;

A CLASS-EXPR is an expression defining a class.  You can build a complex class out of simple classes using the operators (in ascending precedence order) ,, -, | and &, which represent the set options `union', `subtraction', `union' (again!), and `intersection'. Subexpressions can be parenthesised to override the default precedence. Once a class name has been defined, as shown above, it can be used in subsequent class expressions.

A single user may be designated by either a user name (in quotes) or an integer uid.  Commands and hosts may be designated by quoted strings which may contain wildcards.  Host strings are matched against both numeric (dotted quad) IP addresses and the reverse-resolved hostname.  Command strings are matched against the absolute pathname of the command the user wants to execute.

Predefined classes
------------------

In an attempt to make life a bit easier, Become creates a collection of predefined classes.

The standard classes all and none match anything and nothing respectively.  The all class is useful in some contexts: it gives you a way of saying `everything except...', for example:

     user MUNDANES = all - SYSHACKS;

The none class is provided because it's needed internally anyway and someone might come up with a use for it.

Become also defines some other classes:

  * For each username USER, Become adds a class called USER which matches just that user.

  * For each group name GROUP, Become creates a class called GROUP which matches any user who is a member of that group.

  * For each netgroup NETGROUP, Become creates two classes: u_NETGROUP which matches any user listed in the netgroup, and h_NETGROUP which matches any host listed in the netgroup.

If a name is used for both a user and a group, then corresponding class ends up containing the user together with all of the group members. For this reason, it's probably better to use the predefined classes for groups rather than individual users -- use quoted user names for individual users.

Note that users and groups are read using the standard get*ent calls and directly from the NIS server (if there is one).  The idea here is that a Become server can be run on a machine which allows restricted logins. It still needs to know about all the users known to the outside world.

Netgroups are read only from the NIS servers.  In particular, although GNU systems allow netgroup databases to be stored in local files, Become won't read them because there's no defined interface for enumerating netgroups.

Allow statements
----------------

The allow statement defines the rules Become uses when deciding whether to grant a request; see Requests and rules.

     allow [[HOST-CLASS]] [USER-CLASS] -> [USER-CLASS] [ : COMMAND-CLASS]

(The HOST-CLASS is optional, but must be enclosed in square brackets if present.)

The four classes in an allow statement are called, respectively, the `host', the `to-user', the `from-user' and the `command'.  Any of the four classes may be omitted, and an omitted class defaults to `all'.

When a request is received, Become checks the fields in the request against the classes in each allow statement of the configuration file.  If a statement matches, the request is granted; if there are no full matches, the request is denied.

Other statements
----------------

Two other statement types are defined.  They only have an effect on Become in daemon mode:

     port PORT ;
     keyfile KEY-FILE ;

The port statement specifies the port to which the server should listen; the PORT may be be an integer or a quoted service name.  The keyfile statement instructs Become to use the key from the file named KEY-FILE, which must be a quoted string.

An example configuration file
-----------------------------

     #
     # become.conf
     #
     # Example configuration file
     #

     allow wheel -> "root";

     user NEWS = "fred", "jim";
     allow NEWS -> "news";

     user HTTP = "jim", "bob";
     allow ["www.somewhere.com"]
             HTTP -> "httpd" : "/bin/kill", "/etc/init.d/httpd";

Checking and querying the configuration file
--------------------------------------------

At a reasonably sized site, Become configuration files can get rather large, and becomes tricky to work out exactly who's allowed to do what and where.

The bcquery tool provided allows Become configuration files to be verified and queried.  It can be used to ensure that a file is syntactically correct before it is deployed, or to enquire about privileges granted.

Verifying configuration files
.............................

A common use of bcquery is to ensure that a configuration file is actually valid.  The command

     bcquery [-file FILE] -check

verifies that a configuration file conforms to Become's expectations.  If there are any errors in FILE, they are reported, and bcquery will return a nonzero exit code.

If no FILE is specified, bcquery will read the configuration file which Become itself reads by default, usually /etc/become/become.conf.

Querying configuration files
............................

The bcquery program will list all rules which match a selected request pattern.  For example, you can display all rules which allow a particular user to change identity, or all rules which allow people to assume root privileges on a particular host.

     bcquery [-file FILE] QUERY

The following simple queries are supported:

-from USER
     Matches any rule containing USER in its `from' list.

-to USER
     Matches any rule containing USER in its `to' list.

-host HOST
     Matches any rule containing HOST in its host list.

-command CMD
     Matches any rule containing CMD in its `command' list.

Simple queries can be combined using the following operators:

QUERY-A -or QUERY-B
     Matches a rule matched by either QUERY-A or QUERY-B.

QUERY-A -and QUERY-B
     Matches a rule matched by both QUERY-A and QUERY-B.

-not QUERY
     Matches a rule which is not matched by QUERY.

( QUERY )
     Matches a rule matched by QUERY (overrides default precedence).

The -and, -or and -not operators may be written &, | and ! respectively, if you prefer, and the -and operator is optional.  These characters (and the parentheses ( and )) may need to be quoted to prevent interpretation by the shell.

Some examples may explain what's going on:

bcquery -from hacker
     Displays all rules applying to user `hacker'.

bcquery -host somehost -to root
     Displays rules allowing people to become root on somehost.

Output formats
..............

The bcquery program has two distinct output formats: `rows' and `columns'.

The `columns' format is probably the simpler to understand, and certainly the easier to read.  Each matching record is displayed with the lists of users, hosts and commands in columns.  A query on the example configuration file (see Example configuration file) is shown below:

     FROM            TO              HOST                     COMMAND

     frankie         root            ALL                      ALL
     selina

     fred            news            ALL                      ALL
     jim

     jim             httpd           www.somewhere.com        /bin/kill
     bob                                                      /etc/init.d/httpd

The `columns' format can only show simple lists.  A more complex class definition will show up as <complex> in a `columns' format listing.

The `rows' format is capable of displaying classes in their full generality, but is harder to parse and read.  It displays each list in the form of an expression, in more or less the same syntax as a class definition (see Classes).

The default behaviour is to use `columns' format where possible, or `rows' format if some of the lists are too complex to be represented in columns. You can select a format explicitly using the -columns or -rows options, which is useful if you're trying to parse the output of bcquery with a script.

Restricting output
..................

It's also possible to suppress bits of information about each matched rule. For example, you can show only the `from' list, or just the `to' and `host' lists.  This is done with the -output option.

Each list is given a letter; the `from' list is called f, the `to' list t, the host list h and the command list c.  You can select which lists are displayed by giving the corresponding letters (the order isn't important).  You can also turn individual lists on or off by preceding the characters with + or - characters.  If you start with a + or -, then the last-set selection (or the initial default of all-lists-enabled) is modified.

For example, -output ftc shows only the `from', `to' and `command' lists.  This could be written -output -h too, to turn the hosts list off.

This option is mainly useful with the `columns' output format (see Output formats) to save scripts having to select columns out themselves.

bcquery options summary
.......................

     bcquery [OPTION...] [QUERY]

The OPTIONs available are:

-help
     Displays a summary of the available options, and exits.

-file FILE
     Read FILE, rather than the compiled-in default (usually /etc/become/become.conf).

-dump
     Don't read a configuration file.  Instead, display the query tree parsed from the command line.  This is a debugging feature.

-check
     Don't attempt to output any rules.  Instead, just check the configuration file for validity.

-output SPEC
     Selects which columns are to be displayed for each matching rule. For full details, see Restricting output.

-columns
-rows
     Forces `columns' or `rows' output format.  See Output formats.

-nohead
     Suppress the header line at the top of the output in `columns' mode.  Makes the output more amenable to automatic processing (but harder to read).

-from USER
-to USER
-host HOSTNAME
-command CMD
     Simple queries for selecting rules.  See Querying config files.

-and
-or
-not
     Operators for combining queries into something useful.  See Querying config files.

Complete grammar for configuration files
----------------------------------------

     FILE ::= FILE STATEMENT

     STATEMENT ::= CLASS-DEF
             | ALLOW-SPEC
             | PORT-SPEC
             | KEY-SPEC

     CLASS-DEF ::= user NAME = CLASS-EXPR ;
             | command NAME = CLASS-EXPR ;
             | host NAME = CLASS-EXPR ;

     ALLOW-SPEC ::= allow OPT-HOST-SPEC OPT-USER-SPEC
                     -> OPT-USER-SPEC OPT-COMMAND-SPEC ;

     OPT-HOST-SPEC ::= [ CLASS-EXPR ]
             | EMPTY

     OPT-USER-SPEC ::= CLASS-EXPR
             | EMPTY

     OPT-COMMAND-SPEC ::= : CLASS-EXPR
             | EMPTY

     PORT-SPEC ::= port INTEGER ;
             | port STRING ;

     KEY-SPEC ::= keyfile STRING ;

     CLASS-EXPR ::= CLASS-DIFF-EXPR
             | CLASS-EXPR , CLASS-DIFF-EXPR

     CLASS-DIFF-EXPR ::= CLASS-ISECT-EXPR
             | CLASS-DIFF-EXPR - CLASS-UNION-EXPR

     CLASS-UNION-EXPR ::= CLASS-ISECT-EXPR
             | CLASS-UNION-EXPR | CLASS-ISECT-EXPR

     CLASS-ISECT-EXPR ::= CLASS-PRIMARY
             | CLASS-ISECT-EXPR & CLASS-PRIMARY

     CLASS-PRIMARY ::= ( CLASS-EXPR )
             | STRING
             | INTEGER

     INTEGER ::= one or more digits (0--9)

     NAME ::= an alphabetic character or underscore, followed by zero or
                     more alphanumeric characters or underscores

     STRING ::= " STRING-CHARS "

     STRING-CHARS ::= STRING-CHARS STRING-CHAR
             | EMPTY

     STRING-CHAR ::= a \ followed by any character
             | any character other than ", \ or newline

     EMPTY ::=

Networked configuration
=======================

If you're planning to use Become in a standalone way, you can skip this section.

Choosing servers
----------------

Become notices that it's meant to send requests to a server if it finds a become.server file.  This file contains entries of the form

     HOST [: PORT]

If the PORT is omitted, Become chooses a port by looking at the services database for a service which matches the name by which Become was invoked: normally this will be become.

Become sends a request to all of the servers and believes the first valid reply it receives.  Since servers ignore requests they believe to be invalid, this enables you to change Become's key without disrupting service (see Issuing a new key).

If you're using NIS, you should try to ensure that Become servers runs only on NIS servers; the NIS master is probably a good choice.

Become isn't particularly processor-intensive, and doesn't seem to require very much memory.

Setting up keys
---------------

Communication between Become clients and the server is encrypted to ensure that it's not feasible to gain unauthorised privilege by subverting the network.  Become uses the DSA algorithm to ensure authenticity of replies.

Each client machine, and the server, must have a copy of the same key.  The key is usually stored in /etc/become/become.key.  Become's keys are 128 bits long.

The key file can be generated using Catacomb's key program.  The commands

     key -k /etc/become/become.key add -adsa -e"now + 1 year" become-dsa
     key -k /etc/become/become.key extract -f -secret /etc/become/become.pubkey

will generate a suitable DSA key, and extract the public part.  You should install the public key on all of your client computers, writable only by root.  The private key should be only on the server, and readable or writable only by root.

If you have multiple servers, they can all have different private keys. You'll need to put all of the public keys in the /etc/become/become.pubkey file.

Issuing a new key
-----------------

When you're sending out a new key, you run a risk of disrupting service.  The server reads a new key; the clients still have the old one.

We used to recommend running two servers.  Now, however, you can generate the new key, install the new public key on the clients in addition to the old one, and then install the new private key on the server.  The clients try all valid public keys when attempting to authenticate a response, so this approach will work.

Invoking Become
***************

This chapter provides an exhaustive description of Become's command line options, organised in a reference-manual sort of way.

Becoming another user
=====================

Synopsis
--------

     become [OPTION...] [ENV-VAR...] USER [COMMAND [ARGUMENT...]]

Actually, you can put the OPTIONs, ENV-VARs and USER in any order you like; the important thing is that all of them appear before the command, if any.

Usage
-----

The OPTIONs appropriate for this mode are as follows:

-h
--help
     Display a (fairly verbose) help message describing the various command line options and exits successfully.

-u
--usage
     Display a terse summary of the command line options and exits successfully.

-v

     Display's Become's version number and exits successfully.

-e

--preserve-environment
     Selects the `preserve' login style (see The preserve style).  All environment variables are preserved.  The default command is the current user's own shell.  The default primary group becomes the current primary group; the default group style is set to `merge'.

-s
--su
--set-user
     Selects the `set-user' login style (see The set-user style).  Most environment variables are preserved, but USER, LOGNAME, HOME and other user-specific variables are altered to reflect the target user's configuration.  The default command is the target user's shell. The default primary group becomes the target user's primary group; the default group style is set to `merge'.

-l
--login
     Selects the `login' login style (see The login style).  The environment is cleared and rebuilt, in a similar way to the behaviour of login. The default command is the target user's shell.  The default primary group becomes the target user's primary group; the default group style is set to `replace'.

-g GROUP
--group=GROUP
     Selects GROUP as the primary group; it may be either a group name or a numeric group id.  Note that GROUP must be the primary group or a subsidiary group of either the current user or the target user.

-k
--keep-groups
     Selects the `keep' group style (see Subsidiary groups).  The current set of subsidiary group memberships are passed on unchanged.

-m
--merge-groups
     Selects the `merge' group style (see Subsidiary groups).  The current set of subsidiary group memberships are merged with the subsidiary groups of the target user.

-r
--replace-groups
     Selects the `replace' group style (see Subsidiary groups).  The target user's subsidiary group memberships are passed on; the current subsidiary groups are discarded.

-c SHELL-CMD
--command=SHELL-CMD
     Sets the COMMAND and ARGUMENTs to invoke /bin/sh -c SHELL-CMD; i.e., to execute a Bourne shell command instead of just execing a program.  Note that permissions are checked for executing the Bourne shell /bin/sh; the contents of the SHELL-CMD are not inspected.

The ENV-VAR arguments fine-tune the environment passed to the command. Each ENV-VAR setting must be one of the following:

VAR=VALUE
     Assign the variable named VAR the value VALUE.  Protect the variable VAR from modifications by the login style.

VAR!
     Protect the variable VAR from modifications by the login style, but don't change its value.

VAR-
     Remove the variable VAR from the environment; do not pass it on.

The USER specifies the user as whom the COMMAND should be executed (i.e., the target user).  It may be a user name or a numeric user id.

The COMMAND specifies a command to execute.  If COMMAND does not contain a path, it is looked for using the current PATH environment variable.  The resulting pathname is canonified if necessary, to produce an absolute pathname.  Note that symbolic links are not resolved -- this prevents an attack whereby a user could invoke a program, passing it an unusual argv[0] which might cause unusual behaviour.

The COMMAND name is used both as the command to execute and passed to the command as argv[0].  It is not possible to specify an alternative value to be passed as argv[0].  Subsequent arguments, if supplied, are passed as argv[1] upwards.

If no COMMAND is given, a shell is invoked; the particulars of the shell are determined by the login style (see above).

The COMMAND is executed as follows:

  * The subsidiary groups are chosen as determined by the group style.

  * The real and effective gids are set.

  * The real and effective uids are set.

  * The COMMAND is called using the standard execve system call.

Starting Become daemons
=======================

Synopsis
--------

     become --daemon [OPTION...]

Usage
-----

The following options are appropriate to this mode:

-h
--help
     Display a (fairly verbose) help message describing the various command line options and exits successfully.

-u
--usage
     Display a terse summary of the command line options and exits successfully.

-v

     Display's Become's version number and exits successfully.

-d
--daemon
     Start a Become server, instead of processing a request.  Become will read its command line options, read in the configuration file (and verify that it's correct) and then fork into the background to wait for incoming requests. Become relinquishes all setuid privileges (by setting all uids to the real uid) when it enters daemon mode.  It is therefore only really useful to run a daemon as the superuser.

-p PORT
--port=PORT
     Listen for requests on PORT.  This option is overridden by the port option in the configuration file.

-f FILE
--config-file=FILE
     Read configuration from FILE, instead of the default (set at compile time, usually /etc/become/become.conf).

The syntax of the configuration file is described in The configuration file.

Debugging options
=================

Some options are only useful when trying to find out why Become is misbehaving.  Of course, this never happens, so here are the options which you won't need to use:

-T[FILE]
--trace[=FILE]
     Write trace information to FILE (or to standard output, if no FILE is specified).  You must be able to create the file and open it for writing.

-L[FEATURE...]
--trace-level[=FEATURE]
     Selects which features Become ought to trace.  Each feature is allocated a letter; simply string together the letters for the features you want to debug.  The letters D and A stand respectively for `default' and `all' features; you can subtract from them by saying, for example, A-xyz to select all features except x, y and z. The exact list of features supported at any one time can be listed by giving the --trace-level option without an argument.

-I USER
--impersonate=USER
     Pretend to be USER instead of yourself when the request is checked. This option can only be used if it wasn't disabled at compile-time and if Become is not running setuid.  Even so, Become will only inform you of the outcome; it will not execute any commands.