connexion et su internes

10

J'essaie de comprendre comment les autorisations utilisateur fonctionnent sous Linux. Le noyau démarre et démarre en inittant que root, non? Init exécute ensuite les scripts de démarrage et s'exécute getty( agetty), à nouveau en tant que root. Agetty lit simplement le nom d'utilisateur et s'exécute login, toujours en tant que root, je pense. Rien d'intéressant pour le moment. Mais que fait la connexion ? Je n'ai pas pu trouver mieux que "il essaie de se connecter". Supposons que la connexion trouve que le mot de passe correspond (et que nous essayons de nous connecter en tant qu'utilisateur habituel), comment change-t-il l'ID utilisateur? Je pensais qu'il devrait y avoir un appel système pour cela, mais je n'ai pas pu le trouver (peut-être que je suis simplement aveugle?)


Aussi, environ su. sua le bit 'setuid' positionné donc quand on l'exécute, il s'exécute toujours en tant que root. Mais lorsque nous lui demandons de se connecter en tant qu'utilisateur habituel, il doit à nouveau changer l'ID utilisateur. Dois-je bien comprendre que la même "magie" se produit dans suet loginquand ils doivent changer d'utilisateur? Si oui, pourquoi avoir deux programmes différents? Existe-t-il d'autres types de problèmes sérieux lors de l'exécution de la connexion?

Anton Barkovsky
la source

Réponses:

9

Les programmes de connexion comportent plusieurs parties. Les programmes de connexion diffèrent dans la façon dont ils interagissent avec l'utilisateur qui essaie de se connecter. Voici quelques exemples:

  • login: lit l'entrée sur un terminal texte
  • su: invoqué par un utilisateur déjà connecté, obtient la plupart des données de ses arguments de ligne de commande, ainsi que les données d'authentification (mot de passe) d'un terminal
  • gksu: similaire à su, mais lit les données d'authentification dans X
  • rlogind: obtient une entrée via une connexion TCP via le protocole rlogin
  • sshd: obtient une entrée via une connexion TCP via le protocole SSH
  • Gestionnaires d'affichage X (xdm, gdm, kdm,…): similaires login, mais lisent les entrées sur un écran X

Ces programmes fonctionnent de manière similaire.

  1. La première partie est l' authentification : le programme lit certaines entrées de l'utilisateur et décide si l'utilisateur est autorisé à se connecter. La méthode traditionnelle consiste à lire un nom d'utilisateur et un mot de passe, et à vérifier que l'utilisateur est mentionné dans la base de données utilisateur du système et que le mot de passe que l'utilisateur a tapé est celui de la base de données. Mais il existe de nombreuses autres possibilités (mots de passe à usage unique, authentification biométrique, transfert d'autorisation,…).

  2. Une fois qu'il a été établi que l'utilisateur est autorisé à se connecter et à quel compte, le programme de connexion établit l'autorisation de l'utilisateur, par exemple à quels groupes l'utilisateur appartiendra dans cette session.

  3. Le programme de connexion peut également vérifier les restrictions de compte. Par exemple, il peut imposer une heure de connexion, ou un nombre maximal d'utilisateurs connectés, ou refuser certains utilisateurs sur certaines connexions.

  4. Enfin, le programme de connexion configure la session de l'utilisateur. Il existe plusieurs sous-étapes:

    1. Définissez les autorisations de processus sur ce qui a été décidé dans l'autorisation: utilisateur, groupes, limites,… Vous pouvez voir un exemple simple de cette sous-étape ici (elle ne gère que l'utilisateur et les groupes). L'idée de base est que le programme de connexion fonctionne toujours en tant que root à ce stade, il dispose donc de privilèges maximaux; il supprime d'abord tous les privilèges autres que d'être l'utilisateur root, et enfin appelle setuidà supprimer ce dernier mais non le moindre privilège.
    2. Montez éventuellement le répertoire personnel de l'utilisateur, affichez un message «vous avez du courrier», etc.
    3. Appelez un programme en tant qu'utilisateur, généralement le shell de l'utilisateur (pour loginet su, ou sshdsi aucune commande n'a été spécifiée; un gestionnaire d'affichage X appelle un gestionnaire de session X ou un gestionnaire de fenêtres).

De nos jours, la plupart des unités utilisent des modules PAM (Pluggable Authentication Modules) pour fournir une manière uniforme de gérer les services de connexion. PAM divise sa fonctionnalité en 4 parties : «auth» englobe à la fois l'authentification (1 ci-dessus) et l'autorisation (2 ci-dessus); «Compte» et «session» sont comme 3 et 4 ci-dessus; et il y a aussi le «mot de passe», qui n'est pas utilisé pour les connexions mais pour mettre à jour les jetons d'authentification (par exemple les mots de passe).

Gilles 'SO- arrête d'être méchant'
la source
4

Les appels système que vous recherchez s'appellent des choses comme setuidet seteuidbien qu'il y ait en fait toute une famille d'ourlets selon exactement les variantes d'identité d'utilisateur que vous essayez de changer.

Il existe également des appels parallèles comme setgidpour changer le groupe sous lequel s'exécute un processus.

TomH
la source
4

loginsupprimera les privilèges root si nécessaire. De nombreux programmes qui n'ont besoin des privilèges root qu'au début démarrent en tant que root, font ce qu'ils doivent faire, puis descendent vers un compte utilisateur normal afin de ne pas avoir à se soucier de l'utilisation d'un bogue dans le binaire pour accéder à un coquille de racine. logindétient naturellement les privilèges plus longtemps, mais le principe est le même.

La suppression des privilèges root est en fait assez banale. POSIX définit setuid()et setgid()fonctions, qui modifient respectivement vos identifiants d'utilisateur et de groupe (réels et efficaces, si vous commencez en tant que root). loginappelle les deux, ainsi que initgroups()pour configurer les groupes supplémentaires que vous pourriez avoir (puisque setgidc'est juste pour définir votre ID de groupe principal)

Naturellement, c'est le noyau qui gère réellement la modification de l'UID / GID du processus. Comment puis-je trouver les implémentations des appels système du noyau Linux? explique beaucoup de choses sur les appels système; dans ma source de noyau, j'ai:

#define __NR_setgid 144
__SYSCALL(__NR_setgid, sys_setgid)
#define __NR_setuid 146
__SYSCALL(__NR_setuid, sys_setuid)

donc 144 et 146 sont les numéros d'appel système pour ces fonctions sur ma machine


Je n'ai pas vérifié la susource pour voir ce qu'il fait, mais je soupçonne qu'il supprime également les privilèges root juste avant l' exec()ing un shell, en utilisant la même méthode

Michael Mrozek
la source