[[_TOC_]]

This document explains how to create new shell (and email) accounts.
See also [doc/accounts](doc/accounts) to evaluate new account requests.

Note that this documentation needs work, as it overlaps with
user-facing user management procedures ([doc/accounts](doc/accounts)), see [issue
40129](https://gitlab.torproject.org/tpo/tpa/team/-/issues/40129).

# Configuration

This should be done only once.

    git clone git@git-rw.torproject.org:admin/account-keyring.git
    git -C account-keyring remote add alberti alberti.torproject.org:/srv/db.torproject.org/keyrings/keyring.git

It downloads the git repository that manages the OpenPGP keyring. This
keyring is essential as it allows users to interact with the LDAP
database securely to perform password changes and is also used to send
the initial password for new accounts.

# Creating a new user

This procedure can be used to create a real account for a human
being. If this is for a machine or another automated thing, create a
role account (see below).

To create a new user, specific information need to be provided by the
requestee, as detailed in [doc/accounts](doc/accounts).

The short version is:

    # THIS KEY SHOULD BE CHECKED, SEE BELOW FOR DETAILS
    FINGERPRINT=0123456789ABCDEF0123456789ABCDEF01234567 &&
    NEW_USER=alice &&
    REQUESTOR="bob in ticket #..." &&
    ./NEW "$FINGERPRINT" "$NEW_USER" &&
    git add torproject-keyring/"${NEW_USER}-${FINGERPRINT}.gpg" &&
    git commit -m"new user ${NEW_USER} requested by ${REQUESTOR}" &&
    git push &&
    git push alberti &&
    ssh -tt $USER@alberti.torproject.org "ud-useradd -n && sudo -u sshdist ud-generate && sudo -H ud-replicate"

The last line will create the user on the LDAP server. If you are interested about
the details see below for detailed instructions.
Notice that when prompted for whom to add (`a GPG search`), enter the full
`$FINGERPRINT` verified above

## on your own machine

For example, your laptop.

  1. verify the OpenPGP key provided

     It should be signed by a trusted key in the keyring or in a
     message signed by a trusted key. See [doc/accounts](doc/accounts) when
     unsure.

  2. add pgp key to the `account-keyring` repository:

         FINGERPRINT=0123456789ABCDEF0123456789ABCDEF01234567
         NEW_USER=alice
         REQUESTOR=bob
         ./NEW "$FINGERPRINT" "$NEW_USER" &&
         git add torproject-keyring/"${NEW_USER}-${FINGERPRINT}.gpg" &&
         git commit -m"new user ${NEW_USER} requested by ${REQUESTOR}"

  3. push to both repositories:

         git push && git push alberti

## on the LDAP server

This is currently `alberti`. Make sure you run as a regular user with
LDAP write access.

  1. create the user:

         ud-useradd -n

     This command asks a bunch of questions interactively that have
     good defaults, mostly taken from the OpenPGP key material, but
     it's important to review them anyways. in particular:

     * when prompted for whom to add (`a GPG search`), enter the full
       `$FINGERPRINT` verified above

     * the email forward is likely to be incorrect if the key has
       multiple email address as UIDs

     * the user might already be present in the Postfix alias file
       (`tor-puppet/modules/postfix/files/virtual`) - in that case,
       use that email as the `Email forwarding address` if present and
       remove it from Puppet

  2. synchronize the change:

          sudo -u sshdist ud-generate && sudo -H ud-replicate

## on other servers

This step is optional and can be used to force replication of the
change to another server manually. In this case, we force the change
to propagate to the email server, which is currently `eugeni`.

  1. synchronize the change:

         sudo -H ud-replicate

  2. verify the email alias was correctly created:

         egrep -q "${NEW_USER}@torproject.org" /etc/postfix/debian || echo "new user missing, please fix"

  3. run puppet:

         sudo puppet agent -t

# Creating a role

A "role" account is like a normal user, except it's for machines or
services, not real people. It's useful to run different services with
different privileges and isolation.

Here's how to create a role account:

1. Do _not_ use `ud-groupadd` and `ud-roleadd`. They are partly broken.

2. On LDAP host (currently alberti.tpo), as a user with LDAP write
   access, do:

        ldapvi -ZZ --encoding=ASCII --ldap-conf -h db.torproject.org -D uid=${USER},ou=users,dc=torproject,dc=org

3. Create a new `group` role for the new account:

   * Copy-paste a previous `gid` that is also a `debianGroup`
   * Change the first word of the copy-pasted block to `add` instead
     of the integer
   * Bump the `gidNumber` to the latest `gidNumber` in the file plus
     one

4. Create the actual `user` role:

   * Copy-paste a previous `uid` role entry (with a `objectClass: debianRoleAccount`).
   * Change the first word of the copy-pasted block to `add` instead
     of the integer
   * Change the `uid=`, `uid:`, `gecos:` and `cn:` lines.
   * Bump the `uidNumber` to the latest `uidNumber` in the file plus
     one.
   * Use the same `gidNumber` as the one generated in the first step.

5. Add the role to the right host:

   * Add a `allowedGroups: NEW-GROUP` line to host entries that should
     have this role account deployed.

6. Save the file, and accept the changes

7. propagate the changes from the LDAP host:

        sudo -u sshdist ud-generate && sudo -H ud-replicate

8. (sometimes) create the home directory on the server, in Puppet:

        file { '/home/bridgescan':
          ensure => 'directory',
          mode   => '0755',
          owner  => 'bridgescan',
          group  => 'bridgescan';
        }

Sometimes a role account is made to start services, see the
[doc/services](doc/services) page for instructions on how to do that.

# Sudo configuration

A user will often need to more permissions than its regular scope. For
example, a user might need to be able to access a specific role
account, as above, or run certain commands as root.

We have `sudo` configuration that enable us to give piecemeal accesses
like this. We often give accesses to *groups* instead of specific
users for easier maintenance.

There's this one large `sudoers` file that contains a lot of per-host
configuration. But newer `sudoers` entries should be done by adding
files in `/etc/sudoers.d/` on the right host instead of relying on
`sudo`'s per-host capabilities. For example, this is a simple sudoers
configuration:

    file { '/etc/sudoers.d/gettor':
      mode    => '0440',
      content => '%gettor			ALL=(gettor)			ALL',
    }

## Sudo primer

As a reminder, the [sudoers](https://manpages.debian.org/sudoers) file syntax can be distilled to this:

    FROMWHO HOST=(TOWHO) COMMAND

For example, this allows the group `wheel` (`FROMWHO`) to run the
`service apache reload` `COMMAND` as `root` (`TOWHO`) on the `HOST`
`example`:

    %wheel example=(root) service apache reload

The `HOST`, `TOWHO` and `COMMAND` entries can be set to `ALL`. Aliases
can also be defined and many more keywords. In particular, the
`NOPASSWD:` prefix before a `COMMAND` will allow users to `sudo`
without entering their password.

## Granting access to a role account

That being said, you can simply grant access to a role account by
adding users in the role account's group (through LDAP) then adding a
line like this in the `sudoers` file:

    %roleGroup example=(roleAccount) ALL

Multiple role accounts can be specified. This is a real-world example
of the users in the `bridgedb` group having full access to the
`bridgedb` and `bridgescan` user accounts:

    %bridgedb		polyanthum=(bridgedb,bridgescan)			ALL

Another real-world example, where members of the `%metrics` group can
run two different commands, without password, on the `STATICMASTER`
group of machines, as the `mirroradm` user:

    %metrics		STATICMASTER=(mirroradm)	NOPASSWD: /usr/local/bin/static-master-update-component onionperf.torproject.org, /usr/local/bin/static-update-component onionperf.torproject.org

## Update a user's GPG key

The account-keyring repository contains an update script `./UPDATE` which takes
the ldap username as argument and automatically updates the key.

If you /change/ a user's key (to a new primary key), you also need to update
the user's ``keyFingerPrint`` attribute in LDAP.

# Other documentation

Note that a lot more documentation about how to manage users is
available in [the LDAP documentation](howto/ldap).
