# TaBr - tabr_adduser pour ajouter un utilisateur au serveur familial
2023-05-13T13:22:25Z

Le rôle de tabr_adduser sera non seulement de créer un un nouvel utilisateur, mais aussi de produire une fiche qui contiendra des explications et des codes de récupération afin de permettre à ce dernier de modifier son mot de passe.

Par exemple, elle ressemblera à ça : 

```
# Notice d'utilisation de ton compte sur si3t.ch

Ton nom d'utilisateur est: hseldon
Ton mot de passe est: nat#)AUcG#72)uxF


## SERVICES

Tu disposes d'un accès au serveur si3t.ch comprenant:

* une adresse mail: hseldon@si3t.ch
* un compte de messagerie instantanée XMPP: hseldon@si3t.ch


## CHANGER DE MOT DE PASSE

Tu peux changer ton mot de passe à l'adresse suivante:
	https://si3t.ch/tabr/oubli

Tu auras besoin de ton code de récupération.
NOTE-LE SOIGNEUSEMENT:

	MPw9XP-oMs%aU-zk*cX2-fhJGh2-kIQQd0


## QRCODE
Scanne ce QR code pour retrouver toutes les informations importantes:

[...snip...]


## ADRESSE MAIL

Tu peux utiliser ton adresse mail avec n'importe quel client de
messagerie et les paramètres suivants:

* Identifiant: ton nom d'utilisateur
* Serveur IMAP: si3t.ch - port 993
* Serveur SMTP: si3t.ch - port 587 - STARTTLS

Tu peux aussi utiliser le webmail en ouvrant ce lien:
	https://webmail.si3t.ch


## MESSAGERIE INSTANTANÉE XMPP

Tu disposes d'un compte XMPP te permettant de communiquer en temps
réel, partager des photos, vidéos...

Pour cela, tu auras besoin d'un client XMPP.
Sur smartphone, je te conseille l'appli Conversations:

* Sur F-Droid:
https://f-droid.org/packages/eu.siacs.conversations/
* Sur Google Play:
	https://play.google.com/store/apps/details?id=eu.siacs.conversations

Tu peux aussi utiliser le client en ligne en ouvrant le lien suivant:
	https://si3t.ch:5281/conversejs
```

Le script sera lancé ainsi : 

```
doas -u _tabr_admin tabr_adduser hseldon
```

Il fera appel à doas pour obtenir les permissions superutilisateur. Il faudra donc avoir au préalable configuré "/etc/doas.conf" avec : 

```
permit nopass _tabr_admin cmd /usr/sbin/useradd
permit nopass _tabr_admin cmd /usr/local/sbin/prosodyctl
```

Avant d'aller plus loin, il faut comprendre que de quelques variables sont définies dans le fichier "/etc/tabr.conf" que voici:

```
# TaBr configuration file
# edit to suit your preferences

data=/var/_tabr_admin/tabr-data
data_instructions=/var/_tabr_admin/tabr-data/instructions
usergroup="_tabr_users"
admin=_tabr_admin
domain="si3t.ch"
recovery_url="https://${domain}/tabr/oubli"

print_notice() {

	u="${1}" # user
	pw="${2}" # password
	recovery="${3}" # recovery code

	cat << EOF
# Notice d'utilisation de ton compte sur $domain

Ton nom d'utilisateur est: ${u}
Ton mot de passe est: ${pw}

[...]
```

## Le script à la loupe

Tout d'abord, on veille à ce que le script s'arrête à la moindre erreur.

```
#!/bin/sh -e
```

On charge le fichier de configuration pour avoir accès aux variables:

```
. /etc/tabr.conf
```

C'est parti pour définir quelques fonctions.
La première permettra de fermer le script avec un code d'erreur après avoir affiché un message expliquant la raison.

```
die()
{
	printf "%s\n" "$*"
	exit 1
}
```

On continue avec les classiques, on explique comment se servir du script:

```
usage()
{
	printf "%s <username> <recovery-passphrase>\n" "$0"
	printf "if not specified, a random recovery-passphrase will be generated\n"
	exit 1
}
```

Voici une fonction pour générer un mot de passe aléatoire:

```
genpw()
{
	#jot -rcs '' $1 33 126
	tr -cd '[:alnum:]~#()%@,?;.!*' < /dev/urandom |\
		fold -w $1 | head -n 1
}
```

Comme on peut le voir, j'ai commenté une version avec "jot" qui proposait une suite aléatoire de tous les caractères entre le n°33 et le 126 (voir man ascii).
Cependant, j'ai opté pour une solution avec "tr" me laissant le choix des caractères possibles. J'en reste donc aux lettres, chiffres et ponctuation habituelle. Cela évite pour les utilisateurs moins à l'aise de devoir fouiller dans le clavier de leur smartphone.

Ensuite, on génère un code de récupération aléatoire:

```
rdm-recovery-pass()
{
	genpw 30 |
		sed -E 's/^(.{6})(.{6})(.{6})(.{6})/\1-\2-\3-\4-/'
}
```

L'appel de "sed" permet d'insérer des tirets "-" à intervalles réguliers pour faciliter la saisie ensuite.

On s'assure ensuite qu'on a bien le bon nombre d'arguments pour le bon fonctionnement du script:

```
## get arguments into variables
[[ $# -ge 1 ]] && [[ $# -lt 3 ]] || usage
```

On met le nom d'utilisateur dans une variable plus facile à identifier:

```
u="${1}"
```

S'ensuit un test pour vérifier si une phrase de récupération a été précisée. Je pense notamment à ma famille pour qui il serait facile de proposer des phrases faciles à retenir en référence à un vécu commun. Sinon, un code de récupération est généré.

```
[[ -z "${2}" ]] && recovery="$(rdm-recovery-pass)" || recovery="${2}"
```

On vérifie si un utilisateur au nom de celui demandé existe déjà:

```
## check if user already exist
id -u $u > /dev/null 2>&1 && die "User already exists"
#[[ -e $data/$u ]] && die "User already exists" # commented, previous is safer
```

On génère un mot de passe totalement aléatoire. J'ai choisi une longueur de 16 caractères. On peut bien sûr faire mieux, mais si j'en rajoute, on va m'envoyer des cailloux.

```
## generate random password
pw="$(genpw 16)"
```

On enregistre le code de récupération dans un fichier portant le nom de l'utilisateur (unique), situé dans un dossier qui appartient à _tabr_admin, dont seul _tabr_admin a accès. C'est en réalité dans un dossier de son répertoire personnel, dont j'ai ajusté le spermissions en 0700.

```
## store recovery pass
encrypt -b a ${recovery} > $data/$u
```

On crée l'utilisateur système.

```
## create system user
doas /usr/sbin/useradd -m -g $usergroup -s /sbin/nologin -p "$(encrypt -b a "${pw}")" "$u"
```

Cet utilisateur peut recevoir des mails puisque dovecot et smtpd sont configurés pour utiliser le processus de login de l'OS.
On remarque plusieurs choses dans cette commande:

* On crée un $HOME à l'utilisateur (-m)
* On demande à ce qu'il appartienne au groupe _tabr_users
* On lui attribue le shell /sbin/nologin. Autrement dit, il est désactivé.
* On définit aussitôt son mot de passe en passant le hash de ce dernier avec la commande "encrypt" .

On peut désormais créer le compte xmpp. Ici, il y a une petite bidouille pour passer le mot de passe avec printf:

```
## create xmpp account
printf "%s\n%s\n" "${pw}" "${pw}" | doas /usr/local/sbin/prosodyctl adduser "${u}@${domain}"
```

On termine par générer les instructions à envoyer qui seront stockées dans un fichier puis affichée.
Libre à l'admin d'envoyer/imprimer/...? ce fichier texte.

```
## generate notice with qr code
print_notice "${u}" "${pw}" "${recovery}" > ${data_instructions}/${u}.txt
cat ${data_instructions}/${u}.txt
```

Enfin, on rappelle à l'admin de supprimer le fichier contenant les données du nouvel utilisateur rapidement, une fois qu'elles ont été transmises:

```
print "*** WARNING ***\n%s\n" \
        "You probably should delete ${data_instructions}/${u}.txt very soon"
```


## Une réaction?

=> mailto:bla@bla.si3t.ch?subject=TaBr-tabr_adduser-part1 Envoyez votre commentaire par mail (anonyme).
=> /log/commentaires/ Mode d'emploi de la liste de diffusion pour recevoir les réponses.