Procédure de programmation pour obtenir les privilèges root?
Je suis en train d'écrire un logiciel (en C++, pour Linux/Mac OSX) qui s'exécute en tant qu'utilisateur non privilégié, mais a besoin des privilèges root à un certain point (pour créer un nouveau périphérique virtuel).
Exécuter ce programme en tant que root n'est pas une option (principalement pour des questions de sécurité) et j'ai besoin de connaître l'identité (uid) de la "vraie" de l'utilisateur.
Est-il un moyen pour imiter la commande "sudo" comportement (demander le mot de passe utilisateur) temporairement obtenir les privilèges root et exécuter la tâche particulière ? Si oui, quelles sont les fonctions qui dois-je utiliser ?
Merci beaucoup pour votre aide !
Vous devez vous connecter pour publier un commentaire.
Réponse originale à cette question
Vous pourriez envisager de le setuid basculer sur l'exécutable lui-même. Wikipédia a un l'article qui vous montre même la différence entre
geteuid()
etgetuid()
de manière assez efficace, la première étant de trouver qui vous êtes "l'émulation", et le second pour qui vous "êtes". Le sudo processus, par exemple, geteuid doit retourner 0 (root) et getuid votre id de l'utilisateur, cependant, de ses sous-processus sont réellement exécuté en tant que root (vous pouvez le vérifier avecsudo id -u -r
).Je ne pense pas qu'il y a moyen de facilement par programmation obtenir un accès root - après tout, l'application du principe de moindre privilège, pourquoi auriez-vous besoin? Une pratique courante consiste à exécuter seulement limitée des parties de code avec des privilèges élevés. Beaucoup de démons, etc sont également mis en place dans le cadre des systèmes à exécuter en tant qu'utilisateur propre à la plupart des privilèges dont ils ont besoin. C'est que pour des opérations spécifiques (montage, etc) que les privilèges root sont vraiment nécessaires.
2013 mise à jour
Ma réponse originale à cette question stands (bien que mon 2013 auto pourrait faire un meilleur travail que mon 2010), mais si vous êtes à la conception d'une application qui nécessite un accès root, vous pouvez envisager exactement ce que sorte de l'accès root est nécessaire et d'envisager l'utilisation de POSIX Capacités (page de man). Ceux-ci sont différents pour axée sur les capacités de sécurité mis en L4 et coll. POSIX capacités de permettre à votre application d'être accordés à un sous-ensemble de la racine de ses pouvoirs. Par exemple
CAP_SYS_MODULE
vous permettra d'insérer des modules de noyau, mais de vous donner pas d'autres droits root. C'est en usage dans les distributions par exemple Fedora a une fonction pour supprimer complètement binaires setuid aveugle avec un accès root.C'est important, car en tant que programmeur, votre code est évidemment parfait! Mais, les bibliothèques dont vous dépendez (soupir, si seulement tu avais écrit pour eux!) pourrait avoir des vulnérabilités dans les. À l'aide de capacités, vous pouvez limiter l'utilisation de cet exploit, et enregistrer vous-même et votre entreprise de la sécurité liés à l'examen. Cela rend tout le monde plus heureux.
Under sudo, for example, geteuid should return 0 (root) and getuid your user's id.
C'est faux. Voir ma question au sujet de exactement ce problème: stackoverflow.com/questions/10272784/...plugdev
oudisk
groupesSi vous avez besoin des privilèges root à chaque fois, la meilleure chose est de commencer votre programme en tant que root et de les déposer (dans un sous-processus) avec setuid et setgid. C'est ce que apache ne quand il a besoin de se lier aux restrictions sur le port 80.
Si acquérir les droits root est l'exception plutôt que la règle et le programme est exécuté de manière interactive, une autre façon est d'écrire un programme add_interface et exécuter
et laissez sudo gérer l'authentification pour vous. Au lieu de sudo, vous souhaiterez peut-être utiliser une interface graphique comme gksu, gksudo, kdesu, ou kdesudo. Je ne voudrais pas essayer de mettre en œuvre sécurisée de saisie de mot de moi-même; il peut être un problème délicat et vous aurez probablement quitter béants trous de sécurité et des problèmes de fonctionnalité (pensez-vous, lecteurs d'empreintes digitales?).
Une autre alternative est polkit, précédemment appelé PolicyKit.
Vous ne pouvez pas obtenir les privilèges root, vous devez commencer avec eux et de réduire vos privilèges en tant que de besoin. La manière habituelle de le faire est d'installer le programme avec le "setuid" ensemble de bits: il exécute le programme avec l'uid du propriétaire du fichier. Si vous exécutez
ls -l
sursudo
, vous verrez qu'il est installé de cette façon:Pendant que votre programme est exécuté avec les privilèges de root, vous pouvez appeler la
setuid(2)
appel système à changement effectif de votre code d'utilisateur pour certains d'utilisateur non privilégié. Je crois (mais je n'ai pas essayé) que vous pouvez installer votre programme en tant que root avec le bit setuid sur, réduire immédiatement privilège, et puis privilège de restauration en tant que de besoin (c'est possible, cependant, qu'une fois que vous réduisez votre privilège vous ne serez pas en mesure de le restaurer).Une meilleure solution est de sortir le morceau de votre programme qui doit s'exécuter en tant que root, et de l'installer avec le bit setuid est allumé. Vous aurez, bien sûr, besoin de prendre des précautions raisonnables qu'il ne peut pas être invoquée à l'extérieur de votre programme de master.
Normalement cela se fait en faisant votre binaire suid-root.
Une façon de gérer le présent, afin que les attaques à l'encontre de votre programme sont dur est de minimiser le code qui s'exécute en tant que root comme suit:
Maintenant le second code parle de code privilégié par la fd comlink (qui est un socket connecté). Le correspondant privilégié de code utilise stdin/stdout comme la fin de la comlink.
Le code privilégié besoin de vérifier la sécurité de toutes les opérations qu'il doit faire, mais comme ce code est petit par rapport à la non-privilégié code, cela devrait être assez facile.
child > 0
else if (child == 0)
-- leelse
blocwait
s pour l'enfant, de sorte que l'enfant doit être le moyenelse if
bloc.AF_UNIX
si vous souhaitez passer des descripteurs de fichiers à travers le support.Vous voudrez peut-être jeter un oeil à ces Api:
Elles sont définies dans l'en-tête
<unistd.h>
dans les systèmes Linux (je ne sais pas beaucoup sur MAC, mais vous devriez avoir un en-tête similaire il y a trop).Un problème que je peux voir, c'est que le processus doit avoir les droits suffisants pour modifier son utilisateur/groupe - Id. Sinon, les appels aux fonctions ci-dessus entraînera une erreur avec
errorno
ensemble deEPERM
.Je voudrais suggérer que vous exécutez votre programme comme le
root
de l'utilisateur, le changement effectif de l'ID d'utilisateur (à l'aide deseteuid
) à défavorisés d'un utilisateur au tout début. Ensuite, chaque fois que vous avez besoin pour élever les autorisations, demander un mot de passe puis utilisezseteuid
de nouveau pour revenir à laroot
utilisateur.Sur OS X, vous pouvez utiliser le
AuthorizationExecuteWithPrivileges
fonction. La page sur Services D'Autorisation Des Tâches a quelques élaborer la discussion de ce (et apparentés) fonctions.Voici un peu de code C++ pour exécuter un programme avec des privilèges d'administrateur:
Vous pouvez essayer de lancer la commande pour créer le périphérique virtuel (y compris sudo) par le biais d'un fond de coque. Demander le mot de passe des utilisateurs dans une boîte de dialogue de votre propre et la pipe que dans le shell lorsque sudo demande. Il y a d'autres solutions comme l'utilisation de gksu, mais ceux ne sont pas garantis pour être disponible sur chaque machine.
Vous n'avez pas exécuté l'ensemble de votre programme en tant que root, mais seulement une petite partie de ce que les besoins de la racine. Vous devez vous frayer un processus distinct pour que et sudo peut être de vous venir en aide.
wheel
de l'utilisation de sudo ou su que une extension de unix traditionnel comportement.