85.1.56. pepsi-helper-dot-forward¶
run a single user’s ~/.forward as that user
- Section du manuel:
1
85.1.56.1.1. Nom¶
pepsi-helper-dot-forward - helper privilégié qui traite le ~/.forward d’un utilisateur local unique après avoir abandonné ses privilèges vers cet utilisateur.
85.1.56.1.2. Synopsis¶
pepsi-helper-dot-forward TARGET-UID [–pipe] [–file] < message
85.1.56.1.3. Description¶
pepsi-helper-dot-forward est un helper minimal, durci pour la sécurité, qui exécute le fichier ~/.forward d’exactement un utilisateur local. Il existe afin qu’un appelant de confiance mais non privilégié (un membre du groupe pepsi-forward, en pratique pepsi-stage-dot-forward(1)) puisse faire traiter le ~/.forward de n’importe quel utilisateur local en tant que cet utilisateur — et ne rien faire d’autre.
Le helper est installé setuid-root, de propriétaire root:pepsi-forward et de mode 4750. Seuls les membres du groupe pepsi-forward peuvent l’exécuter ; lorsqu’ils le font, le noyau l’exécute avec un uid effectif de root. Recevant l’uid numérique de l’utilisateur cible comme unique argument positionnel, et le message brut sur l’entrée standard, le helper :
résout l’entrée passwd de l’utilisateur cible, refusant l’uid
0/ le loginrootet tout uid inférieur à/etc/login.defsUID_MIN(par défaut1000) ;abandonne complètement et irréversiblement ses privilèges vers l’utilisateur cible — installant les groupes supplémentaires de l’utilisateur, puis le gid, puis l’uid (réel, effectif et sauvegardé) — et vérifie que root ne peut être regagné, exactement comme le font pepsi-helper-maildir-writer(1) et pepsi-helper-auto-pay(1) ;
refuse d’agir — sortie
3— lorsque le répertoire personnel, ou le~/.forwardlui-même, n’appartient pas à l’uid cible ou est accessible en écriture au groupe ou à tous (mode & 0o022). C’est la règle de sendmail et de postfix-local : le fichier nomme des directives|commandet/fileque le helper exécute en tant que cet utilisateur, si bien que quiconque d’autre peut écrire dans le répertoire pourrait en planter une. Notez que cela est vérifié sur le répertoire personnel avant que le~/.forwardne soit cherché : sur un hôte dont les répertoires personnels sont accessibles en écriture au groupe, le compte est donc refusé même lorsqu’il n’a aucun~/.forward;si l’utilisateur n’a pas de fichier
~/.forward, quitte avec1(l’étape passe alors à son étape suivante) ;sinon lit
~/.forwardet agit sur chaque ligne non vide et non-#en tant que l’utilisateur : une adresse nue est collectée comme adresse de redirection, et une adresse écrite\nameest collectée avec son marqueur, que l’étape appelante lit comme le « remettre à ce nom et ne pas l’étendre davantage » de sendmail ;|commandenvoie le message par tube à/bin/sh -c command(seulement avec –pipe) ;/absolute/pathajoute le message à ce fichier (seulement avec –file). Une directive dont le type n’était pas activé, ou dont l’exécution échoue, est un échec. Un|commandest exécuté avec un environnement assaini —HOMEetUSER/LOGNAMEréglés sur l’utilisateur cible, unPATHfixe, et les variables de détournement de shellIFS/BASH_ENV/ENV/CDPATHsupprimées — afin que l’environnement hérité de l’agent de remise ne puisse pas influencer la commande.
Un |command s’exécute dans son propre groupe de processus et dispose de 300 secondes ; à l’expiration, le groupe entier reçoit un SIGKILL (le groupe, car une directive de tube crée couramment des processus fils) et l’exécution est rapportée comme un échec. Une directive /path ouvre la cible avec O_NOFOLLOW|O_NONBLOCK et refuse tout ce qui n’est pas un fichier ordinaire, de sorte qu’un FIFO ou un lien symbolique ne peut pas bloquer le helper indéfiniment. Sans ces bornes, n’importe quel compte local pourrait coincer un worker du dispatcher pour toute la durée de vie du pipeline, simplement en écrivant |sleep infinity dans son ~/.forward.
Une directive peut être écrite entre guillemets doubles — la forme que les documentations de procmail et de maildrop indiquent aux utilisateurs, "|IFS=' ' && exec /usr/bin/procmail -f- || exit 75 #bob" — et une ligne peut porter plusieurs entrées séparées par des virgules, comme le permet la grammaire de membre droit de la base d’alias dont .forward hérite. Une couche de guillemets doubles entourants est retirée avant que la directive ne soit classée, et une virgule placée à l’intérieur de guillemets doubles ne découpe pas la ligne.
Le message n’est lu depuis l’entrée standard que lorsqu’une directive |pipe//file qui le consomme peut s’exécuter (c’est-à-dire lorsque –pipe ou –file est fourni).
85.1.56.1.4. Arguments¶
- TARGET-UID
L’identifiant numérique d’utilisateur dont le
~/.forwardest traité. Il doit avoir une entrée passwd ; l’uid0/ le compterootet tout uid inférieur à/etc/login.defsUID_MINsont refusés.- –pipe
Permet les directives
|command(l’étape passe ceci lorsque sonALLOW_PIPEest activé).- –file
Permet les directives d’ajout de fichier
/path(l’étape passe ceci lorsque sonALLOW_FILEest activé).
85.1.56.1.5. Code de sortie¶
- 0
Le
~/.forwarda été traité avec succès. Les adresses de redirection qu’il a nommées (éventuellement aucune) sont écrites une par ligne sur la sortie standard.- 1
L’utilisateur n’a pas de
~/.forward. L’appelant passe à son étape suivante.- 2
Le traitement a échoué — une commande de tube a quitté avec un code non nul (autre que
75) ou a été tuée par un signal, un fichier n’a pu être écrit, ou une directive désactivée a été demandée. Un diagnostic lisible par un humain est écrit sur la sortie standard pour inclusion dans le rebond. C’est un échec permanent de ce destinataire.- 3
Un échec opérationnel de l’hôte, non de la remise : le helper n’est pas installé setuid-root, l’uid cible n’a pas d’entrée passwd ou la consultation passwd elle-même a échoué (une panne NSS/LDAP), le compte est
rootou se situe sousUID_MIN, le répertoire personnel n’est pas absolu, ou le répertoire personnel ou le~/.forwardlui-même n’est pas exclusivement celui de l’utilisateur cible (il ne lui appartient pas, ou il est accessible en écriture au groupe ou à tous). Le diagnostic va à la fois sur la sortie standard et sur la sortie d’erreur standard. L’appelant doit traiter cela comme réessayable — le message reste en file plutôt que de rebondir pour une condition que l’opérateur peut corriger.Le cas du répertoire personnel non sûr est une propriété du compte plutôt que du message : avec
chmod 0775 ~alice, chaque message destiné àalices’arrête ici et reste en file, et aucun n’atteint la remise locale.chmod g-w,o-wsur le répertoire personnel (et sur~/.forward) est le correctif.Une
|commandqui demande à être réessayée quitte aussi avec 3 : celle qui quitte avec75(EX_TEMPFAIL, ce que procmail et maildrop signalent pour une boîte aux lettres verrouillée ou un disque plein), celle qui dépasse la limite de 300 secondes, et celle qui ne peut pas être démarrée du tout. Le diagnostic propre de la commande va sur les deux flux de sortie. Les directives situées plus haut dans le fichier ont alors déjà agi et agissent de nouveau lors du réessai, comme elles le feraient sous n’importe quel agent de remise qui diffère en cours de traitement d’un.forward.
Lorsqu’il est invoqué par un utilisateur qui n’est pas membre du groupe pepsi-forward, le noyau refuse purement et simplement d’exécuter le binaire ; le helper lui-même ne s’exécute jamais.
85.1.56.1.6. Sécurité¶
L’appartenance au groupe pepsi-forward est la barrière de contrôle d’accès. Le helper exécute des commandes arbitraires et écrit des fichiers arbitraires uniquement en tant que l’utilisateur cible non privilégié, jamais en tant que root : il abandonne complètement ses privilèges avant de lire le ~/.forward ou de toucher à l’un des fichiers de l’utilisateur, et refuse d’agir pour le compte root.
85.1.56.1.7. Voir aussi¶
pepsi-stage-dot-forward(1), pepsi-helper-maildir-writer(1), pepsi-dispatch(1), pepsi.conf(5)
85.1.56.1.8. Bogues¶
Signalez les bogues au gestionnaire de tickets de Pepsi.