54 votes

Suppression des privilèges root

J'ai un démon qui est lancé en tant que root (il peut s'attacher à des ports). Après l'initialisation, j'aimerais bien que à ce qu'il descende des privilèges root pour des raisons de sécurité.

Quelqu'un peut me pointer à une correcte connue morceau de code en C qui va le faire?

J'ai lu les pages de man, j'ai regardé les différentes implémentations de ce dans différentes applications, et ils sont tous différents, et certains d'entre eux sont vraiment complexe. Ceci est lié à la sécurité du code, et je ne veux vraiment pas à réinventer les mêmes erreurs que d'autres personnes font. Ce que je suis à la recherche d'une meilleure pratique, bien connu, bibliothèque portable de fonction que je peux utiliser dans la connaissance qu'il va obtenir la droite. Est-ce une telle chose existe?

Pour référence: je me lance en tant que root, j'ai besoin de changer pour s'exécuter sous un autre uid et gid; j'ai besoin d'avoir la complémentaire les groupes mis en place correctement; je n'ai pas besoin de revenir à la racine de privilèges par la suite.

46voto

Juliano Points 13802

Afin de supprimer tous les privilèges de l'utilisateur et de groupe), vous avez besoin de déplacer le groupe de l'utilisateur avant de. Étant donné qu' userid et groupid contient l'Id de l'utilisateur et le groupe que vous voulez supprimer, et en supposant que les Id sont aussi racine, ceci est accompli en appelant setuid() et setgid():

if (getuid() == 0) {
    /* process is running as root, drop privileges */
    if (setgid(groupid) != 0)
        fatal("setgid: Unable to drop group privileges: %s", strerror(errno));
    if (setuid(userid) != 0)
        fatal("setuid: Unable to drop user privileges: %S", strerror(errno));
}

Si vous êtes paranoïaque, vous pouvez essayer d'obtenir les privilèges de root en arrière, ce qui devrait échouer. Si il n'a pas manqué, vous de sauvetage:

 if (setuid(0) != -1)
     fatal("ERROR: Managed to regain root privileges?");

Aussi, si vous êtes toujours paranoïaque, vous pouvez seteuid() et setegid() aussi, mais il ne devrait pas être nécessaire, car setuid() et setgid() déjà mis tous les Id si le processus est détenue par la racine.

Le groupe supplémentaire de la liste est un problème, car il n'est pas POSIX fonction pour définir supplémentaire groupes (il y a getgroups(), mais pas de setgroups()). Il y a un BSD et Linux extension setgroups() que vous pouvez utiliser, il cela vous concerne.

Vous devez également chdir("/") ou pour tout autre répertoire, afin que le processus ne pas rester dans une racine appartenant à l'annuaire.

Étant donné que votre question est sur Unix en général, c'est l'approche très générale. Notez que sous Linux ce n'est plus l'approche privilégiée. Dans le courant de versions de Linux, vous devez définir l' CAP_NET_BIND_SERVICE de la capacité sur le fichier exécutable et de le lancer en tant qu'utilisateur normal. Pas d'accès root est nécessaire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X