Il est parfois nécessaire de déléguer la possibilité de modifier un fichier « système » à un autre utilisateur que root, par exemple bob. Une solution serait d’ajouter une ACL au fichier (par exemple, le fichier /etc/motd), mais je trouve que la gestion des ACL est pénible… laissons-ça aux bons soins de Samba pour faire plaisir aux utilisateurs de Windows.
Si on souhaite utiliser la commande sudo, vous savez certainement que la ligne suivante ne doit pas être placée dans le fichier /etc/sudoers :
bob ALL=(ALL) NOPASSWD: /usr/bin/vi /etc/motd
Pourquoi ? Simplement parce que bob va pouvoir lancer l’éditeur vi en-tant-que-root et donc qu’il pourra éditer d’autres fichiers (avec la commande « :e » de vi) ou bien il pourra obtenir un shell bash toujours avec le compte root (avec la commande « :!bash« ).
Pour éviter l’écueil du lancement d’un shell (ou de toute autre commande), on pourrait ajouter le flag NOEXEC dans le fichier /etc/sudoers, mais cela n’évite pas l’édition d’un autre fichier.
Certains pensent que remplacer vi par nano résoud le problème :
bob ALL=(ALL) NOPASSWD: /usr/bin/nano /etc/motd
Mais avec nano, je peux sauver le contenu du fichier édité sous un nom quelconque et donc je peux changer le contenu de n’importe quel fichier ! Ce n’est pas la bonne solution.
La bonne solution consiste à utiliser la commande sudoedit, équivalente à sudo -e :
bob ALL=(ALL) NOPASSWD: sudoedit /etc/motd
L’utilisateur peut modifier le fichier /etc/motd ainsi :
bob$ sudoedit /etc/motd
Même si l’éditeur par défaut est vi, le lancement d’un shell produira un shell fonctionnant avec le compte de bob et l’édition d’un fichier protégé ne sera pas possible. Pourquoi ? Parce que sudoedit copie le fichier original dans un fichier temporaire appartenant à bob et qu’il n’a besoin des privilèges de root que pour recopier ce fichier temporaire à la place du fichier original, lors de la sauvegarde du contenu du fichier. Le reste du temps, sudoedit (l’éditeur en fait) est exécuté avec le compte de bob, ce que montre l’affichage de la commande ps -edf par exemple.