Comment fonctionne sudo (en dehors de setuid)?

sudo est élevé à la racine au lancement car il est activé par un setuid binary. Mais quand je donne à /bin/login les privilèges exacts de sudo , et j'essaie de l'exécuter depuis un user qui n'est pas root, j'obtiens l'erreur suivante:

 No utmp entry. You must exec "login" from the lowest level "sh" 

Ma première question est la suivante: que signifie cette erreur? Ma deuxième est, pourquoi cela fonctionne-t-il quand je lance la sudo login depuis ce même user? En plus d'utiliser un setuuid pour élever à root, comment fonctionne le sudo autrement? J'ai écrit un script de dash simple à ~/root pour exécuter whoami et quitter, mais il renvoie le nom d'user de mon user non privilégié.

 $ ls -l ./root /usr/bin/sudo -rwsr-xr-x 1 root root 29 Jul 15 02:40 ./root -rwsr-xr-x 1 root root 157760 Jan 10 2016 /usr/bin/sudo $ ./root unprivileged user 

J'ai donc trois questions:

  1. Quelle est l'erreur que je reçois avec la login ?
  2. Pourquoi la login fonctionne-t-elle avec sudo ?
  3. Pourquoi mon script simple pour exécuter whoami ne fonctionne pas?

Quelle est l'erreur que je reçois avec la login ?

Lors de la search à travers le code source de login , nous voyons ce passage:

 amroot = (getuid () == 0); [...] utent = get_current_utmp (); /* * Be picky if run by normal users (possible if installed setuid * root), but not if run by root. This way it still allows logins * even if your getty is broken, or if something corrupts utmp, * but users must "exec login" which will use the existing utmp * entry (will not overwrite remote hostname). --marekm */ if (!amroot && (NULL == utent)) { (void) puts (_("No utmp entry. You must exec \"login\" from the lowest level \"sh\"")); exit (1); } 

La partie interessante est la clause if à la fin. Le message d'erreur apparaît lorsque getuid() n'est pas 0 et s'il n'y a pas d'input utmp. getuid() renvoie l' ID user réel du process appelant. Si vous invoquez la login avec le drapeau setuid, le vrai uid et le uid réel diffèrent. login est, comme le suggère le commentaire de l'extrait de code source, "picky" dans de tels cas: il échoue et renvoie l'erreur mentionnée.


Pourquoi la login fonctionne-t-elle avec sudo ?

sudo lui-même a défini le bit setuid, donc euid et ruid diffèrent. Mais, sudo exécute le binary de login et définit à la fois le réel et le uid efficace à l'user cible. Il n'échouera donc plus.


Pourquoi mon script simple pour exécuter whoami ne fonctionne pas?

Votre script a une ligne de shebang ( #! ) Dedans (je suppose). Ce qui se passe est le suivant: le kernel ouvre l'exécutable (dans votre cas un file text) et observe un #! . Au lieu du file text, l'interpréteur donné dans la ligne shebang est appelé (par exemple /bin/bash ou /bin/sh ) avec le nom du script comme premier argument. La plupart des systèmes d'exploitation unix et linux ignorent le bit setuid lorsqu'il est défini sur un script, car il s'agit d'un problème de security.

Imaginez un script avec setuid. L'attaquant peut alors créer un lien symbolique vers ce script, invoquer ce script, puis changer le lien symbolique vers son script, juste avant que l'interpréteur ouvre le script derrière le lien symbolique (qui est le mal alors).