2017-10-17 14 views
1

J'écris une application en utilisant C sous Linux. Dans mon application, j'ai besoin de faire quelques tâches au début avec un utilisateur normal (utilisateur non root) alors que j'ai besoin de faire certaines tâches avec l'utilisateur root au milieu de l'exécution. Par ailleurs, je ne peux pas modifier les configurations de l'utilisateur normal. Donc, je ne peux pas ajouter un utilisateur normal à sudoers. Je ne peux pas non plus modifier les configurations de système d'exploitation.Comment changer d'utilisateur pendant l'exécution en utilisant C sous Linux?

Ce que mon application fait vraiment est d'exécuter des applications, obtenir leurs sorties pour l'analyse.

Certaines applications doivent être exécutées avec root. J'utilise des multi-threads pour exécuter et analyser les sorties de ces applications en parallèle puis stocke le rapport de chaque application dans un singleton appelé Report. J'appelle ces applications en utilisant execvp en sous-processus.

Le but principal de mon application est d'automatiser les tests de logiciels. Et la plupart des tâches sont nécessaires pour exécuter dans le propriétaire du logiciel qui ne doit pas être root.

Ainsi, le problème est

  • comment puis-je changer d'utilisateur lors de l'exécution?
  • Y at-il de toute façon que je peux implémenter cela dans 1 exécutable?
  • Pour ce faire avec les API POSIX, c'est mieux.
  • Exécuter mon application avec un utilisateur normal, fournir le mot de passe root à mon application, passer à root en utilisant le mot de passe root.
+1

http://man7.org/linux/man-pages/man2/setuid.2.html – oakad

+0

@oakad Merci, mais est-ce possible de lancer mon application avec un utilisateur normal, puis passer en root en utilisant le mot de passe root? –

+2

Non, bien que vous puissiez générer un processus d'assistance séparé qui s'exécute en tant que root et communiquer avec lui via IPC. Une façon de faire est de définir le bit setuid sur l'assistant. Rendre l'assistant aussi minimal que possible, en lui donnant seulement les fonctions de base qui ont réellement besoin d'un accès root, et laissez votre application principale faire le reste. –

Répondre

4

En savoir plus sur setuid executables et setreuid(2) et execve(2) syscalls. Soyez prudent, vous devrez mettre le drapeau setuid sur l'exécutable avec chmod u+s (voir chmod(1)) après avoir changé sa propriété (avec chown(1)) et code soigneusement pour éviter security holes.

(donc je vous recommande d'avoir votre code examiné par une personne connaissant le mécanisme setuid et conscient des problèmes de sécurité)

Setuid est le mécanisme de base (utilisé par su, sudo, super, login etc ...) des programmes pour obtenir (ou révoquer) des privilèges. Voir credentials(7) & capabilities(7).

Il pourrait être plus sûr de commencer un processus d'aide (en tant que root, ou lancer certains exécutables setuid peut-être /usr/libexec/ ...) et de communiquer avec elle en utilisant des installations inter-process communication (comme pipe(7) ...). Par exemple, il est déconseillé d'utiliser des boîtes à outils graphiques comme GTK ou Qt dans les processus racine. Si votre application a une interface graphique, il est raisonnable d'exécuter son interface utilisateur graphique dans un processus non root (utilisateur ordinaire) et d'exécuter en tant que root le processus d'assistance (espérons-le petit) effectuant le vrai travail nécessitant des privilèges spéciaux. Avant de coder, je recommande de lire un bon livre comme Advanced Linux Programming et syscalls(2) et la documentation de chaque system call que vous utiliseriez. Security aspects sont particulièrement importants.

Les exécutables Setuid ne nécessitent pas nécessairement ou n'utilisent aucun mot de passe; c'est l'inverse: les programmes nécessitant des mots de passe (notamment login, su, sudo etc ....) sont setuid (et ils sont free software sous Linux, donc vous pouvez étudier leur code source); essayez ls -l /bin/su /usr/bin/sudo /bin/login pour vérifier cela.

Étant donné que vous souhaitez émuler divers environnements utilisateur, notez environ(7).