Comment effectuer la manipulation de fichier / répertoire avec les privilèges de l'utilisateur à l'esprit?

StackOverflow https://stackoverflow.com/questions/4847753

Question

J'ai une application de serveur qui sera en cours d'exécution sous un compte système, car à un moment donné, il sera le traitement des demandes au nom d'un utilisateur sur le système. Ces demandes consistent en des instructions de manipulation du système de fichiers.

Voici la capture: le programme a besoin de garder que les privilèges d'un utilisateur particulier à l'esprit lors de l'exécution des actions. Par exemple, joe ne devrait pas être en mesure de modifier /home/larry si ses autorisations sont 755.

À l'heure actuelle ma stratégie est la suivante

  • Obtenir le propriétaire / groupe du fichier
  • Comparer à l'ID ID utilisateur / groupe de l'utilisateur qui tente d'exécuter l'action
  • Si l'une correspondance (ou si aucun jeu), utilisez la partie appropriée du champ d'autorisation dans le fichier à autoriser ou de refuser l'action

Est-ce sage? Y at-il un moyen plus facile de le faire?

Dans un premier temps, je pensais avoir plusieurs instances de l'application en cours d'exécution dans les comptes de l'utilisateur - mais ce n'est pas une option, car alors seulement l'une des instances peut écouter sur un port TCP donné

.
Était-ce utile?

La solution

Jetez un oeil à samba pour un exemple de ce qui peut être fait. Le démon samba fonctionne en tant que root mais fourches et assume les pouvoirs d'un utilisateur normal le plus rapidement possible.

systèmes Unix ont deux ensembles distincts des pouvoirs: l'utilisateur réel / GID et les ids utilisateur / groupe efficace. L'ensemble réel identifie qui vous êtes réellement, et les définit ensemble efficace ce que vous pouvez accéder. Vous pouvez modifier l'efficacité uid / gid comme bon vous si vous êtes root, y compris à un utilisateur ordinaire et à nouveau, comme votre utilisateur réel / ids de groupe restent racine pendant la transition. Donc, une autre façon de le faire dans un seul processus est d'utiliser seteuid/gid pour appliquer les autorisations des différents utilisateurs avant et en arrière au besoin. Si votre démon serveur est exécuté en tant que root ou a CAP_SETUID alors ce sera autorisée.

Cependant, notez que si vous avez la possibilité de changer l'efficacité uid / gid au gré et votre application est perverti, alors que la subversion pourrait par exemple changer l'arrière uid / gid à 0 et vous pourriez avoir une faille de sécurité grave . Voilà pourquoi il est prudent d'abandonner tous les privilèges de façon permanente le plus tôt possible, y compris votre uid / gid utilisateur réel.

Pour cette raison, il est normal et plus sûr d'avoir une seule prise d'écoute en tant que root, puis bifurquer hors tension et changer à la fois l'utilisateur réel et efficace ids en appelant setuid. Ensuite, il ne peut pas revenir en arrière. Votre processus fourchue aurait la prise qui a été accept()ed comme il est une fourchette. Chaque processus se ferme tout simplement les descripteurs de fichiers, ils ne ont pas besoin; les prises restent en vie car ils sont référencés par les descripteurs de fichiers dans les processus opposés.

Vous pouvez également essayer de faire appliquer les autorisations, en examinant vous-même individuellement, mais je l'espère, il est évident que ce qui est potentiellement sujette à l'erreur, a beaucoup de cas de pointe et plus susceptibles d'aller mal (par exemple. Il ne fonctionnera pas avec moins que vous ACLs Posix mettre en œuvre spécifiquement aussi).

Alors, vous avez trois options:

  1. fourche et setgid() / setuid() à l'utilisateur que vous souhaitez. Si la communication est nécessaire, l'utilisation pipe(2) ou socketpair(2) avant de la fourchette.
  2. Ne pas fourche et seteuid() / setegid() autour au besoin (moins sûr: plus susceptibles de compromettre votre serveur par hasard).
  3. Ne salissez pas avec les informations d'identification du système; faire application de l'autorisation manuellement (moins sûr: plus de chances de se tromper d'autorisation).

Si vous devez communiquer avec le démon, alors bien qu'il pourrait être plus difficile de le faire une socket ou un tuyau, la première option est vraiment la façon sécuritaire correcte d'aller à ce sujet. Voir comment ssh fait la séparation des privilèges, par exemple. Vous pouvez également envisager si peut changer votre architecture donc au lieu de toute communication, le processus peut simplement partager l'espace au lieu de mémoire ou d'un disque.

Vous mentionnez que vous envisagé d'avoir un processus distinct exécuter pour chaque utilisateur, mais besoin d'un seul port TCP d'écoute. Vous pouvez toujours le faire. Il suffit de disposer d'un démon maître écouter les demandes de port TCP et expédition à chaque démon utilisateur et communiquer au besoin (par exemple. Via les sockets de domaine Unix). Ce serait en fait presque la même chose que d'avoir un démon maître bifurquer; Je pense que ce dernier allait se révéler être plus facile à mettre en œuvre.

Pour en savoir plus: la page de manuel credentials(7). Notez également que Linux dispose d'un système de fichiers uid / gid; ce qui est presque le même que uid / gid efficaces, sauf pour d'autres choses comme l'envoi de signaux. Si vos utilisateurs n'ont pas accès shell et ne peuvent pas exécuter du code arbitraire alors vous n'avez pas à vous soucier de la différence.

Autres conseils

j'aurais ma fourchette de serveur () et immédiatement setuid(uid) abandonner les privilèges root. Puis toute manipulation de fichiers serait au nom de l'utilisateur que vous êtes devenu. Puisque vous êtes un enfant du serveur auquel vous souhaitez toujours maintenir la douille de l'enfant ed accept () que la demande (et je suppose que la réponse) continuerait. Ce (évidemment) nécessite des privilèges root sur le démon.

Passage des descripteurs de fichiers entre les processus semble inutilement compliqué dans ce cas, que l'enfant a déjà le descripteur « demande ».

Laissez un run serveur sur le port du serveur previlegued et processus enfants spawn pour utilisateurs qui se connectent dans le système. Les processus enfants doivent déposer privilegues et inpersonate l'utilisateur connecté. Maintenant, les Childs ne peuvent plus faire du mal.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top