Page suivante   Page précédente   Table des matières  

3. J'ai résolu ce problème : Impossible d'exécuter bin/bash : Permission non accordée./

Par Ben Okopnik ben-fuzzybear@yahoo.com

Peu de temps avant de commencer à écrire cet article, j'ai réussi à résoudre un problème qui a été ma bête noire pendant ces deux dernières semaines. Étant donné que c'est un problème que j'ai vu souvent réapparaître dans la Linux Gazette, en général rédigé d'une manière laissant penser que l'auteur l'a écrit avec les doigts de pieds parce que debout sur une chaise et la corde au coup, j'ai décidé de partager mon expérience avec les autres lecteurs, leur évitant ainsi le gaspillage d'une bonne corde. Ca peut être également vu comme un bon guide pour se sortir des problèmes logiciels en général. Mais soyez cependant prévenu qu'un problème de login peut mettre en jeu n'importe lequel des domaines couverts ici -- ce qui a servi à résoudre mon problème n'est peut-être pas une solution pour vous.

Il y a quelques semaines de ça j'ai pris la décision d'installer un MUA (Mail User Agent -- un logiciel pour lire son courrier) sur ma machine. C'est quelque chose d'étonnant quand on sait que je vis sur un bateau ancré bien loin de toute ligne téléphonique ou même électrique, mais j'ai mes raisons. J'avais déjà fait ça à terre avant ; je voulais juste essayer quelques trucs.

En fait, à l'instar des troupeaux de lemmings qui se dirigent vers la falaise avant d'en tomber, un MUA n'est rien sans un logiciel qui distribue le courrier (un MTA : Mail Transfert Agent). Il faut donc faire une installation conjointe MTA/MUA. Pas de problème, j'ai toujours la distribution Debian complète sur une partition Linux de mon disque dur. Ça accélère les installations et ça rend les recherches de paquetages triviales.

Pour vous dire la vérité, je n'aime pas la commande su ou tout du moins pour tout ce qui touche à des opérations majeures. Le fait que cette commande conserve l'environnement de l'utilisateur original plutôt que de prendre celui de la personne qui est su-dé m'a rendu certains moments intéressants. C'est bon pour faire des petites modifications de permissions ou des changements dans les fichiers de /etc, mais, dès qu'il s'agit de travail sérieux comme l'installation ou la désinstallation de plusieurs paquetages majeurs (je n'était pas sûr du MTA que je voulais installer), je me logue en tant que root.

Au travail. Midnight Commander permet, en quelques frappes de touches, de parcourir et d'explorer des répertoires mais également de regarder le contenu (et d'installer) des paquetages Debian ou RedHat. Voyons voir... sendmail (lire la page de manuel à l'intérieur du paquetage, regarder les docs, installer...) Non, trop gros et trop compliqué. J'ai besoin de quelque chose de plus simple. (Je désinstalle sendmail). exim ?... exmh ?... mh ?... nmh ? Tous ont eu droit au même sort d'installation et de désinstallation. Ceci à l'exception des bibliothèques : si j'installe une bibliothèque, elle reste installée. En faisant ça sur un nouveau système, on arrive rapidement au moment où on ne se voit plus importuné par des problèmes de bibliothèques non trouvées. Si certaines bibliothèques n'étaient pas mutellement exclusives sur certaines distributions, je les installerais toutes pour ne plus jamais avoir à m'en soucier !

Cependant, il me restait toujours à trouver un MTA. Ah, smail ! Facile à installer, se configure sans peine, voilà, c'est fait. Le choix du MUA a été facile vu que j'aime beaucoup les possibilités de configuration de mutt. Et c'est terminé ! (des mots proophétiques...)

SAUF QUE : je ne pouvais plus me loger en tant qu'utilisateur non-root. Le message que j'avais était :

Impossible d'exécuter /bin/bash : permission non accordée.

Qu'est-ce que diable c'était que cela ?

« Était-ce là quelque illusion occulte ?
Quelque intrusion démente ?
C'etait là des choix que Salomon
Lui même n'avait encore jamais eu à faire... »

Je savais que je n'avais rien touché dans /etc/password et pour cause, je n'avais rien touché à ce qu'il y avait dans /etc. Mais je n'étais pas à 100% sûr de ce que ces paquetages, sécurisés comme ils sont sensés l'être, avaient fait avec mes privilèges root. J'ai tout de suite fait une vérification. Oui l'utisateur ben existe encore dans /etc/password ; idem pour le groupe ben dans /etc/group et le fait d'entrer un mauvais mot de passe me donnait bien le message « Login incorrect » au lieu du « Impossible d'exécuter ». Mouais !

Autre vérification : je crée un nouvel utilisateur (joe) avec un mot de passe (joe) :)) et je tente de me loguer sous ce nom. Rien à faire, même erreur. Quelque chose était foutu dans la séquence de login, pour je ne sais quelle raison. (Adieu joe...)

A ce moment là, j'ai eu un peu peur ; j'ai sauté sur un autre terminal et j'ai essayé de me loguer en tant que root. OUF ! Pas de problème de ce côté. J'aurai au moins encore accès à la machine la prochaine fois que je la remettrai en route... J'aurai détesté avoir eu à faire une sauvegarde à la volée et avoir tout à réinstaller !

Voyons voir dans /bin. À quoi ressemblent les permissions des fichiers ? Ha, tout est à 755 (-rwxr-xr-x) ; en plus login, mount, umount, ping et su sont tous SETUID (-rwsr-xr-x). Jusque là tout va bien. Qu'en est-il des permissions de /etc ? Elles ont toutes l'air OK. 644 pour la plupart (-rw-r--r--), avec de temps en temps un 600 (-rw-------) ici et là pour les fichiers interdits à tous sauf à root. Bien, essayons quelque chose de stupide ; j'écrase login et bash avec de toutes nouvelles version à peine sorties de leur paquetage, juste pour être sûr qu'ils n'étaient pas corrompus. Ben non : toujours pas de chance.

Attendez, et /home ? Si les permissions de ce répertoire étaient fausses et que l'utilisateur ne pouvait y accéder... Zut, c'était bon aussi : 6775 (drwxrwsr-s). Je n'ai rien trouvé de plus en vérifiant les fichiers .bashrc et .bash_profile ; de plus leurs permissions étaient correctes. Juste pour voir, j'ai vérifié tous les répertoires de / ; tous sauf root étaient lisibles par tout le monde, c'est ce qu'il faut.

Dans /var il y a des fichiers qui conservent une trace des personnes qui se sont connectées, du moment où elles se sont déconnectées et du reste. Si ces fichiers sont corrompus, toutes sortes de choses étranges et imprévisibles arrivent. Donc, mesure d'urgence, je tape :


cat >/var/log/wtmp
cat >/var/run/utmp
Ceci a pour effet de détruire le contenu de ces fichiers et de les laisser vide avec une taille nulle.

[NdE : En fait, l'auteur a écrit ces commandes sans le « cat », mais je l'ai rajouté pour faire ressortir le fait que le « > » fait bel et bien partie de la commande et non de l'invite du shell.]

Je me suis délogué de tous les terminaux (comme ça, utmp et wtmp vont recevoir quelques infos) et... argh, le résultat habitue!.

Qu'en est-il des permissions de /dev/ttyX et de /dev/vcsX (terminaux et consoles virtuelles) ? Elles étaient également toutes bonnes. Je commençais à perdre espoir.

Bon, et si je faisais une approcoche systématique ? Essayons d'avoir une idée de ce qui se passe exactement avant de faire tout et n'importe quoi. Je jette un oeil, pour me rafraîchir la mémoire, au Guide de l'Administrateur Système et, ah, voilà, le processus de login :

Tiré du « Guide de l'Administrateur Système » de Lars Wirzenius :

« Tout d'abord init s'assure qu'il existe un programme getty pour se loguer sur le terminal (ou sur la console). getty surveille le terminal et attend que l'utilisateur signale qu'il est prêt à se loguer (cela signifie en général que l'utilisateur doit taper quelque chose). Quand un utilisateur est détecté, getty affiche un message de bienvenue (stocké dans /etc/issue), demande le nom d'utilisateur et enfin le mot de passe. Si tout correspond, login lance le shell configuré pour l'utilisateur ; sinon, il sort tout simplement et met fin au processus (après peut-être avoir donné à l'utilisateur une autre chance pour entrer son nom d'utilisateur et son mot de passe). init se rend compte que le processus est terminé et lance un nouveau getty pour le terminal.


                                                        ' ' ' ' ' ' ' ' '
                       ------------                    '    GIF2ASCII    '
                      |   Début    |                   '  conversion par '
                       ------------                    '  "fastfingers"  '
                   -------------------                 '  Copyleft 2000  '
       ___________| init: fork + exec |_______         '                 '
      |           | "/sbin/getty"     |       |        '     Revu par    '
      |            -------------------        |        ' Xavier Serpaggi '
      ^                     V                 ^         ' ' ' ' ' ' ' ' '
      |   ---------------------------------   |
      |  | getty: en attente d'utilisateur |  |
      |   ---------------------------------   |
      ^                     V                 ^
      |   ----------------------------------  |
      |  |     getty: lecture du nom        | |
      |  | d'utilisateur, exec "/bin/login" | |
      |   ----------------------------------  |
      ^                     V                 ^
      |   --------------------------------    |
      |  | login: lecture du mot de passe |   |
      |   --------------------------------    |
      ^                     V                 ^
      |                    / \                |
      |                   /   \               |
 -------------           / est-\              |
| Login: fin  |--<-Non- /  ce   \             |
 -------------          \ bon ? /             ^
                         \     /              |
                          \   /               |
                           \ /                |
                            | Oui             ^
                            V                 |
                ------------------------      |
               | login: exec("/bin/sh") |     |
                ------------------------      ^
                            V                 |
               --------------------------     |
              | sh: lecture et exécution |    |
              | des commandes            |    ^
               --------------------------     |
                            V                 |
                        ----------            |
                       | sh: fin  |-----------
                        ----------

Figure 8.1 : Connexion via des terminaux : interaction entre init, getty login et le shell.

Notez que le seul processus nouveau est celui créé par init (en utilisant l'appel système fork)  getty et login se contentent de remplacer le programme qui tourne dans le processus (en utilisant l'appel système exec). »

Si on suit le diagramme, on peut voir que tout semble bon au moins jusqu'à la dernière partie, le exec("/bin/sh"). C'est pendant, ou après cet appel, que tout fout le camp. Le problème était à présent au niveau des appels système, quelque chose que je ne savais pas comment approcher... et pourtant c'est là que se trouvait la solution ; seulement je ne savais pas comment l'appliquer. Plus tard ça deviendra évident.

Pendant à peu prés les dix jours qui suivirent, chaque fois que je me loguais, j'essayais quelque chose de nouveau ; des trucs complètement incongrus et très peu aptes à fonctionner ; parfois j'avais des idées géniales qui conduisirent à de grandes déceptions quand, encore une fois, ce satané message apparaissait. Rien ne fonctionnait. J'ai remplacé getty, j'ai essayé d'autres shells que /bin/bash, j'ai essayé de su-dé à ben, j'ai vérifié les fichiers de log (ils montraient que ben avait réussi à se connecter avec succès (!), ce qui m'appris que login fonctionnait correctement et que le problème venait de la prise en main de bash : je m'en doutais !)...

Après n'avoir trouvé que quelques références sur l'Internet, la plupart en japonais, suédois et allemand (j'ai réussi à faire quelque chose des deux derniers dont un suggerait de vérifier les permissions de / ! Excellente idée... qui ne mena à rien dans mon cas), j'ai lancé un appel au secours sur The Answer Guy... Salut ! :)). Malheureusement, il a dû être noyé dans toutes ces questions sur Windows2000 auquel il adore répondre... Ainsi j'étais mon seul espoir.

Ah ! strace ! Vous vous souvenez de strace ; strace est votre ami... Un super programme qui trace l'exécution d'un programme et en fait un rapport pas à pas. C'est parti !

Comme vous devez être logué pour lancer un programme, j'ai exécuté


strace -s 10000 -vfo login.ben login ben

depuis le terminal courant. Ceci signifiait « Lance strace sur login ben ; affiche toutes les lignes de moins de 10000 caractères (je ne voulais pas rater de message, peu importe s'ils étaient très longs) ; soit bavard ; fait un rapport de n'importe quel processus fork-é  et met le résultat dans le fichier login.ben ». Et pour avoir une base de comparaison, j'ai lancé:


strace -s 10000 -vfo login.root login root

À présent, j'avais deux fichiers à comparer. Celui de root était à peu prés deux fois plus long que celui de ben. Cela semblait correct vu qu'un login fructueux mène à l'exécution de tout dans les fichiers ~/.bash*.

Le résultat de strace login est très intéressant à lire. Si je n'avais pas lu le Guide de l'Administrateur Système avant, ça m'aurait donné toutes les informations précisément -- avec bien plus de détails. Il montre toutes les bibliothèques qui sont lues, tous les fichiers qui sont examinés par login, les procédures de comparaison pour group et password... La seule chose qu'il ne montrait pas était la raison de l'échec ; uniquement le fait lui-même, exactement où je l'attendais :


(300+ lines elided)
execve("/bin/bash", ["-bash"], ["TERM=linux", "HZ=100", "HOME=/home/ben", 
    "SHELL=/bin/bash", "PATH=/bin:/usr/bin", "USER=ben", "LOGNAME=ben", 
    "MAIL=/var/spool/mail/ben", "LANG=C", "HUSHLOGIN=FALSE"]) = -1 EACCES 
    (Permission denied)            
write(2, "Cannot execute /bin/bash: Permission denied\n", 44) = 44

Super. Le dernière chose que ce pauvre login essaye de faire avant de se retrouver les quatre fers en l'air est execve bash avec les variables définies à partir de /etc/password, de /etc/login.defs et ainsi de suite -- toutes paraissant OK -- et d'écrire ces 44 caractères détestables sur stderr (descripteur de sortie numéro 2). En gros, ce dont je m'étais déjà rendu compte.

Cependant, j'ai remarqué que login ouvrait un certain nombre de bibliothèques dans /lib qui étaient nécessaires au fichier de configuration du Name Service Switch (littéralement le service de commutation de noms) : /etc/nsswitch.conf. Et si une des bibliothèques mentionnées était corrompue ? Ce serait en ligne directe avec la thèorie des appels système puisque les bibliothèques sont le point de départ de ces appels système ! Vérifions les bibliothèques qui se chargent des logins locaux pour NSS (reportez-vous à la page de manuel de nsswitch) :


dpkg -S libnss_compat-2.0.7.so 

(« Dis moi, Ô puissant gestionnaire de paquetages Debian d'où vient le dit programme ? »), et l'Oracle Debian dans son infinie sagesse répondit :


libc6: /lib/libnss_compat-2.0.7.so

Mouais. Le coeur même des bibliothèques de Linux. Bon... je tente un rapide remplacement de toutes les bibliothèques /lib/libnss*... et pas de changement. Idée suivante.

Cependant cela me fit réfléchir. Il y avait vraiment « quelque chose de pourri au royaume du Danemark ». Peut-être devrais-je vérifier les permissions des fichiers dans /lib ?

Le seul problème était que je ne connaissais pas les valeurs qu'elles étaient sensées avoir. Vous voyez, la plupart des bibliothèques ont les attributs root.root 644 (propriétaire root, groupe root, utilisateur autorisé en lecture/écriture, groupe autorisé en lecture seule, les autres autorisés en lecture seule). Cependant certaines avaient des droits root.root 755, soit la même chose que précédemment mis à part une possibilité d'exécution pour tout le monde. Sans pouvoir jeter un oeil à une installation récente de Linux, je n'avais aucune idée de ce qui était bon.

Mais, une seconde ! Comme je l'avais écrit dans un conseil à 3 sous que j'avais envoyé à la Linux Gazette, j'aime bien garder des fichiers copie de l'installation Debian de base (7 fichiers pour à peu prés 15 Mo) sur ma partition DOS à des fins de sauvetage. Ça devrait contenir tout ce dont j'ai besoin !

Et tel fut le cas. Midnight Commander, par le biais de son Système de Fichiers Virtuel (VFS en anglais) vous permet d'explorer les fichiers compressés comme s'ils étaient des répertoires ; un coup d'oeil à base2_1.tgz#utar/lib (la syntaxe VFS utilisée pas MC) me montra que l'une des toutes premières bibliothèques (ld-2.0.7.so) était sensée avoir des permissions positionnées à 755. Dix secondes plus tard, j'étais le propriétaire d'un tout nouveau VT en tant qu'utilisateur ben.

J'ai bien sûr vérifié les permissions de toutes les autres bibliothèques et ld-2.0.7.so avait éte la seule à être affectée. La seule inconnue était de savoir comment les permissions ont changé... mais je devine que cette question ne trouvera jamais de réponse.

Comme d'habitude, les leçons que Linux nous enseigne sont dures, mais justes. Il y a toujours un moyen de résoudre un problème ; il faut bien admettre que parfois, la manière la plus simple est de réinstaller tout le système mais cela nous vous montre pas le « coeur » d'un OS , ce à quoi le fait de rechercher la cause d'un problème aboutira. Dans mon cas la réinstallation aurait été assez facile : j'ai quelques disques durs de rechange, assez gros pour contenir toutes mes données, même les plus récentes, pour ne pas avoir à toucher à mes sauvegardes. De plus, l'installation basique d'une Debian ne me prend pas plus de 10 minutes. Mais cela ne m'intéressait pas. Ce qui me venait constamment à l'esprit était : « Que se passerait-il si cela arrivait à un de mes utilisateurs ? » Je devais savoir comment m'en sortir... et grace à la persévérance -- non, uniquement pour emmerder le monde -- j'ai réussi.

Je ne suis pas en train de vous conseiller de vous prendre la tête sur un problème une fois par semaine juste pour garder la forme, mais je suggère que vous utilisiez une approche méthodique, basée sur le savoir que vous avez acquis par la lecture des HOWTO appropriés ainsi que d'autres documentations que vous auriez pu vous procurer avant d'avoir recours, une fois de plus, au CD d'installation. Il y aura des moments où vous ne rêverez pas de quelque chose de mieux que de rire comme un maniaque en voyant votre système devenir gros comme une tête d'épingle aprés que vous l'ayez lâché du haut de l'Empire State Building... Et il y aura également des moments où la satisfaction d'avoir résolu un problème épineux comme celui-là vous fera bomber le torse et vous lancer dans une imitation de Tarzan.

Et à présent, si vous voulez bien m'excuser, il y a un chimpanzé et un éléphant que je suis sensé rencontrer...

Joyeuses Linuxations à tous.

Copyright 2000, Ben Okopnik. Paru dans le numéro 52 de la Linux Gazette d'Avril 2000.

Traduction française de Xavier Serpaggi.


Page suivante   Page précédente   Table des matières