Outils pour utilisateurs

Outils du site


droits_linux

Table des matières

Droits d'accès sur les fichiers et répertoires linux

Introduction

UNIX, “papa” de linux, a été conçu dès le départ comme un système d'exploitation multi-utilisateurs, et pas seulement multi-tâches. Il a donc fallu penser à protéger les fichiers de chaque utilisateur ainsi que ceux du système pour, par exemple, en empécher la lecture, la modification ou la destruction par les utilisateurs non autorisés. Cette capacité est devenue encore plus importante maintenant avec la généralisation des réseaux (et Internet) dans lesquels les “utilisateurs non autorisés” sont devenus très très nombreux…

De ce fait, les“droits d'accès” sur les fichiers font partie des techniques parmi les plus puissantes et les plus complexes de linux.

Quand on commence avec linux, il y a des connaissances de base indispensables à aquérir sans lesquelles de nombreuses actions d'utilisation ou d'administration ne sont tout simplement pas possible, et, pire encore, sont incompréhensibles.

Mais même si on a les bases minimales, qu'on trouve un peu partout sur le web, il subsiste encore de nombreuses questions dont les réponses sont tout sauf évidentes. Par exemple:

  • Peut-on affecter à quelqu'un d'autre un fichier dont on est propriétaire?
  • Le “groupe” du fichier est-il forcément l'un des groupes auquel appartient son “propriétaire”?
  • Un utilisateur “normal” peut-il supprimer un fichier qui ne lui appartient pas, et sur lequel il n'a aucun droit (ni de lecture ni d'écriture)?
  • Un programme quelconque, lancé par un utilisateur, crée un nouveau fichier: à qui appartiendra-t-il?
  • Dans quel cas puis-je renommer un fichier, alors que je n'ai pas le droit d'écrire dedans?
  • Puis-je copier n'importe quel fichier n'importe où?
  • La copie normale, quand elle est possible, transmet-elle tous les droits des fichiers?
  • Pourquoi le droit “suid” ne marche-t-il pas avec des scripts shell?
  • Peut-on outrepasser les droits linux avec les paramètres de montage?
  • Etc…

Si vous répondez sans hésitation à toutes ces questions (et si vous répondez juste!), peut-être n'avez-vous pas besoin de ce tuto.

En ce qui me concerne, après avoir comme tout le monde beaucoup galéré sur le sujet, j'ai essayé de faire le tuto que j'aurais aimé trouvé à mon démarrage sous linux!

Principes généraux des droits d'accès aux fichiers

Dans linux, enfant d'UNIX, tout est fichier:

On distingue plusieurs types de fichiers:

  • les fichiers “normaux” (texte, exécutables, …)
  • les répertoires (qui regroupe d'autres fichiers et répertoires)
  • les liens symboliques (liens qui renvoient à d'autres fichiers)
  • les périphériques (qui transmettent des “caractères” comme le clavier ou des “blocs” de données comme un disque)
  • les “sockets locales” (échanges d'infos entre tâches, par exemple avec le serveur graphique X)
  • les “tubes nommés”.(échanges d'infos entre tâches, par exemple avec le service d'impression)

NB: il existe aussi des “liens en dur” qui, contrairement aux liens symboliques, ne sont pas des fichiers séparés mais seulement des entrées supplémentaires permettant d'accéder au même contenu.

Les fichiers sont regroupés par répertoire, et tous les fichiers et répertoires se raccordent à une même arborescence qui commence à la racine (“/”).

NB: attention à ne pas confondre la racine de l'arborescence (racine = “root” en anglais) avec le superutilisateur “root”: ce sont deux choses différentes.

Chacun de ces fichiers possède:

  • des droits:
    • de lecture,
    • d'écriture
    • d'exécution
    • éventuellement des droits spéciaux (suid, sgid et stiky bit: voir plus loin)
  • pour chacune des 3 catégories d'utilisateurs:
    • son propriétaire,
    • son groupe d'utilisateurs
    • et le reste du monde!

Chaque utilisateur intervenant dans un linux en fonctionnement pour des tâches d'administration ou d'utilisation verra donc ses actions être strictement limités par l'étendu de ses droits sur les fichiers concernés.

A noter qu'il existe aussi maintenant des droits étendues: les ACL, qui feront l'objet d'un autre tuto.

Les "ayants droit": utilisateurs et groupes

Tous les utilisateurs qui interviennent dans un linux en fonctionnement sont identifiés par un compte qui comprend au minumum:

  • un nom (ex: “tyrtamos”) associé à un identificateur numérique unique, l'UID (ex: UID=1000).
  • un mot de passe (ex: “eid47Rik98” mais non, ce n'est pas le mien! ;-) )
  • un groupe par défaut (ex: “users”) et d'autres groupes si utile, chacun associé à un identificateur numérique unique, le GID (ex: GID=1000),
  • en général un “répertoire utilisateur” (ex: /home/tyrtamos) et un shell (ex: “/bin/bash”)

Les utilisateurs

  • les utilisateurs “normaux” (humains en général :-D ): ils ont leur “répertoire utilisateur” dans /home. Sur la suse, ils ont un UID supérieur ou égal à 1000 (le 1er utilisateur déclaré à l'installation a l'UID=1000) et inférieur à 60000 (on peut donc créer 59000 utilisateurs “normaux”!).
  • les utilisateurs “système” qui jouent un rôle dans le fonctionnement et la sécurité du système. Vous pouvez voir les vôtres dans /etc/group. Sur la suse, leur UID est inférieur à 1000, ou supérieurs à 60000 comme “nobody” qui a un UID=65534 (ça dépend de la distribution). Parmi les utilisateurs système, le plus important s'appelle “root” (UID=0): c'est le “superutilisateur”. Il a le droit de tout faire, y compris de détruire linux (involontairement en général)… On travaille sous ce compte (on dit “sous root”) uniquement pour des tâches d'administration du système et uniquement pendant l'exécution de ces tâches. Tant pour des raisons de sécurité que pour éviter de faire soi-même des bétises irrécupérables, on ne travaille JAMAIS “sous root” en dehors de ces périodes d'administration.

Les groupes

  • les groupes d'utilisateurs “normaux”. Un premier groupe a été créé à l'installation: “users” (GID=100), mais on peut en créer d'autres autant qu'on en veut: il sont alors créés avec un GID croissant à partir de 1000.
  • les groupes d'utilisateurs “système” qui ont un GID<1000 ou >60000 comme “audio”, “lp”, “video”, “nobody”, et, bien sûr, le groupe “root” (GID=0) qui a le superutilisateur “root” comme membre. Une grande partie des fichiers et répertoires du système linux ont “root:root” comme propriétaire et comme groupe.

UID et GID

Les UID et GID dépendent de la distribution que vous avez, ainsi que de l'installation et des tâches ultérieures d'administration. Mais, à ma connaissace, l'utilisateur “root” a toujours UID=0 et le groupe “root” a toujours le GID=0.

A noter aussi: ce sont les UID et GID qui se trouvent physiquement dans les fichiers, et non les “noms” d'utilisateurs. Ainsi, si vous téléchargez des fichiers à partir d'une archive (ex: xxx.tar.gz) qui a été construite sur une autre machine linux, vous verrez que dans le listage des fichiers, les propriétaires apparaissent par leur UID s'il n'y a pas d'utilisateur déclaré sur votre linux avec ces UID. Cela peut se produire aussi si vous avez plusieurs linux en multiboot sur votre machine et si vous avez mis une partition commune formatée linux: les mêmes noms d'utilisateurs n'ont pas forcément les mêmes UID:GID dans les différents linux.

Conservation des droits

Enfin, il faut se rappeler que seules les partitions formatées linux (ext3, reiserfs, …) sont capables de “contenir” les propriétaires, groupes et droits de chaque fichier. Ainsi, ni les formatages windows (fat32-vfat, ntfs), ni le formatage des cd (iso9660) n'en sont capables. Et comme linux a besoin de ces droits, ce sont alors les paramètres de montage ainsi que les conditions du montage qui permettront d'affecter des droits à l'ensemble des fichiers et répertoire de la partition!

Les droits d'accès des fichiers

A chaque fichier correspond des “droits d'accès”.

  • “r”=le droit de lire (= examiner son contenu)
  • “w”=le droit d'écrire (= modifier son contenu)
  • “x”=le droit d'exécuter (= exécuter le fichier si c'est un programme, ou rentrer dans un répertoire si c'est un répertoire)

On peut, pour un utilisateur donné, représenter ses droits:

  • soit par une chaine de 3 caractères “r”, “w”, “x” ainsi que “-” pour les droits qu'il n'a pas (ex: “rw-”).
  • soit par un chiffre octal (0 à 7), en prenant r=4, w=2, x=1 et, bien sûr, 0 pour les droits qu'il n'a pas (ex: “rw-” = 4 + 2 + 0 = 6).

Cela donne toutes les possibilités suivantes (toujours pour un utilisateur donné):

  • “rwx” ou 7 (là, il a droit à tout)
  • “-wx” ou 3
  • “r-x” ou 5
  • “rw-” ou 6
  • “–x” ou 1
  • “r–” ou 4
  • “-w-” ou 2
  • “—” ou 0 (là, il n'a droit à rien)

Il y a bien sûr des configurations courantes (ex: “rwx”, “rw-”) et d'autres qui n'ont pas beaucoup de sens, tout en restant techniquement possibles (ex: “-w-”: il peut écrire, mais pas lire?).

Et comme il existe 3 catégories d'utilisateurs (le propriétaire, le groupe d'utilisateurs, le reste de monde), les droits de chaque fichier peuvent être représentés comme un nombre octal de 3 chiffres ou comme une chaine de 9 caractères. Par exemple:

  • 777 ou “rwxrwxrwx”
  • 755 ou “rwxr-xr-x”
  • 644 ou “rw-r–r–”
  • 700 ou “rwx——”
  • etc…

En résumé, par exemple, un fichier non-exécutable appartenant à “alain:users” avec des droits "rw-r--r--" (ou 644), signifie que:

  • alain, propriétaire du fichier a des droits de lecture (“r”) et d'écriture (“w”)
  • les membres du groupe users ont des droits de lecture (“r”) mais pas d'écriture (“-”)
  • les autres utilisateurs (le “reste du monde”) ont des droits de lecture (“r”) mais pas d'écriture (“-”)

NB: attention à l'utilisation des droits représentés en nombre octal: en informatique, un nombre octal est souvent représenté avec un zéro à gauche pour le distinguer d'un nombre décimal (ex: 0777). Dans certains cas, il est nécessaire de ne pas oublier ce zéro (ex: fonction chmod() de php).

Les droits particuliers: suid, sgid, et stiky bit

Au droits “de base” précédents s'ajoutent des droits supplémentaires un peu particuliers:

  • le “suid” (ou “setuid”) qui concerne les programmes:
    • un programme lancé avec ce droit “suid” sera exécuté avec les droits du propriétaire du programme et non les droits de l'utilisateur qui l'a lancé (ex: /usr/bin/passwd ou /usr/bin/crontab).
  • le “sgid” (ou “setgid”) qui concerne les programmes et les répertoires:
    • un programme lancé avec ce droit “sgid” sera exécuté avec les droits du groupe du programme et non les droits du groupe de l'utilisateur qui l'a lancé (ex: /usr/bin/write ou /usr/bin/wall).
    • un fichier créé dans un répertoire ayant le droit sgid aura pour groupe le groupe du répertoire et pas celui de l'utilisateur qui a créé le fichier.
  • le “stiky bit” qui concerne surtout les répertoires:
    • dans un répertoire avec ce droit “stiky bit”, seuls les propriétaires des fichiers pourront les effacer (ex: /tmp ou /var/tmp).
    • appliqué à un fichier, il est demandé au noyau de le conserver le plus possible en mémoire (ram ou swap). A ma connaissance, ce n'est pas utilisé sur linux.

Les droits “suid” et “sgid” sont aussi appelés “droits d'endossement”.

Dans la présentation des droits en texte, ces droits particuliers seront représentés comme suit:

  • pour le suid: un “s” à la place du “x” du propriétaire comme dans “rwsr-xr-x”.
  • pour le sgid: un “s” à la place du “x” du groupe comme dans “rwxr-sr-x”.
  • pour le stiky bit: un “t” à la place du dernier “x” (celui du “reste du monde”) comme dans “drwxrwxrwt”.

NB: s'il n'y avait pas de droit d'exécution “x” avant d'appliquer ces droits, les lettres “s” et “t” seront mises en majuscule (“S” et “T”).

Dans la présentation en nombre octal, ces droits correspondent à un 4ème chiffre octal situé à gauche, avec:

  • suid=4,
  • sgid=2
  • et stiky bit=1

Ce qui donnera, par exemple sur la base d'un “755”=“rwxr-xr-x”:

  • “4755” pour “rwsr-xr-x” avec un suid
  • “2755” pour “rwxr-sr-x” avec un sgid
  • “6755” pour “rwsr-sr-x” avec un suid + un guid“
  • “1755” pour “rwxr-xr-t” avec un stiky bit

Bien que ce ne soit pas techniquement impossible, il est assez rare que l'on ait plusieurs de ces droits particuliers en même temps. On peut cependant utiliser facilement “suid” et “sgid” sur le même fichier exécutable.

Listage des fichiers

Listage des fichiers en console

En console, on obtient la liste des fichiers et répertoires d'un répertoire en faisant simplement:

ls  

Mais si on veut en plus les informations sur les droits de ces fichiers, il faut faire (le “l” est un “L” minuscule):

ls -l  

Par exemple, listage dans la console du répertoire ”/etc/cups“:

Signification des différentes colonnes:

  • Colonne 1: ce sont les droits. Le 1er caractère donne le type de fichier:
    • ”-“ pour un fichier normal (ex: /etc/cups/command.types)
    • “d” pour un répertoire (ex: /etc/cups)
    • “c” pour un périphérique “caractère” (ex: un modem comme /dev/rtc)
    • “b” pour un périphérique “bloc” (ex: un disque comme /dev/hda ou /dev/sda)
    • “l” pour un lien symbolique (ex: /boot/vmlinuz)
    • “s” pour une socket locale (ex:/dev/log)
    • “p” pour un tube nommé (ex: /dev/bootplash ou /dev/xconsole)
  • Colonne 2: (sans intérêt courant: il s'agit d'un comptage de liaisons)
  • Colonne 3: propriétaire
  • Colonne 4: groupe
  • Colonne 5: taille en octets
  • Colonne 6, 7 et 8: date et heure de la dernière modification
  • Colonne 9: nom du fichier

Par defaut, le listage présente les fichiers triés par ordre alphabétique, mais vous pouvez changer cet ordre en ajoutant des options (voir page man de ls). Par contre, les répertoires et les fichiers sont mélangés, contrairement à la pratique des navigateurs graphiques.

S'il y a plus de fichiers qu'il n'y a de ligne dans la console, vous ne pouvez jamais voir les 1ers qui défilent trop vite: pour voir quand même tous les fichiers, vous pouvez faire (exemple avec le répertoire /bin):

ls -l /bin | more  

On peut aussi demander le listage en utilisant des jokers (wildmark en anglais) avec ”?“ pour remplacer un seul caractère, et “*” pour remplacer plusieurs caractères (ou aucun). Par exemple pour lister le contenu des 2 répertoires /bin et /boot:

ls -l /b*  

Et pour lister tous les fichiers et répertoires de /bin qui contiennent “ou” en seconde position (ex: “mount”, “mountpoint” et “touch”):

ls -l /bin/?ou*  

Vous pouvez aussi demander le listage d'un répertoire et de ses sous-répertoires (listage récursif) en ajoutant l'option ”-R“ (que vous combinez avec le ”-l“). Par exemple avec le listage du répertoire /srv:

ls -lR /srv  

Et si vous voulez pouvoir regarder ce listage “à tête reposée” (comme disait Louis XVI :-) ), mettez-le dans un fichier (ce fichier sera créé: mettez-le donc dans un répertoire où vous avez le droit de le faire, par exemple, dans votre home ou dans /tmp):

ls -lR /srv > /home/votrelogin/toto.txt  

NB: méfiez-vous comme de peste de l'option ”-R“ avec des jokers. Cette option ”-R“ permet de traiter toute une arborescence, mais peut avoir des effets inattendus. Par exemple, vous êtes dans un répertoire dont vous voulez lister les fichiers cachés. Intuitivement, vous faites: “ls -R .*”. Le problème, c'est que listerez aussi le répertoire situé au dessus, parce que ”..“ fait partie de ”.*“. Imaginez alors les dégâts que vous auriez fait avec la commande d'effacement “rm”!!!

Listage des fichiers avec konqueror sous KDE

Listage dans konqueror du même répertoire /etc/cups:

NB: Pour obtenir ce résultat détaillé avec konqueror, il faut intervenir dans ses préférences: ce n'est pas le mode d'affichage par défaut. Dans tous les cas, pour des travaux d'administration, demandez l'affichage par liste, et non par icône, et demander en plus l'affichage des droits des fichiers.

Listage des fichiers avec nautilus sous gnome

Listage dans nautilus du même répertoire /etc/cups:

NB: Pour obtenir ce résultat avec nautilus, il faut intervenir dans ses préférences: ce n'est pas le mode d'affichage par défaut.Dans tous les cas, pour des travaux d'administration, demandez l'affichage par liste, et non par icône, et demander en plus l'affichage des droits des fichiers.

Qu'ais-je le droit de faire avec ces droits d'accès?

Droit de lister le contenu d'un répertoire

Pour lister le contenu d'un répertoire, il faut avoir en même temps:

  • le droit d'exécution (“x”) sur ce répertoire ainsi que sur tous ses répertoires “parent” jusqu'à la racine de l'arborescence (”/“).
  • et le droit de lecture (“r”)sur ce répertoire

Au titre de la 1ère condition, il suffit qu'il manque le droit d'exécution sur un seul de ces répertoires parent pour que l'accès au répertoire ne soit pas possible. C'est ce qui se passe dans la suse avec les répertoires des utilisateurs ”/home/utilisateur/Documents“, ainsi que du répertoire ”/root“, qui ont des droits “rwx——”: les autres utilisateurs n'y ont pas accès, et il n'est pas nécessaire pour cela que les fichiers et répertoires situés à l'intérieur de ces répertoires soient aussi protégés de cette façon.

A noter que si vous avez le droit de lister le contenu du répertoire, même les fichiers ne vous appartenant pas et sur lesquels vous n'avez aucun droit seront listés (ex: le fichier /etc/shadow appartenant à root:shadow avec ”-rw-r—–“ et, à l'extrème, un fichier ”———“ seront listés).

A noter aussi que dans les navigateurs “graphiques” de fichiers , les fichiers “cachés” (= dont le nom commencent par ”.“) ne sont pas listés par défaut. Mais ce n'est pas un problème de droit linux: il suffit de demander dans le menu l'affichage des “fichiers cachés”.

Cas particulier rare:

On a le droit de lecture sur le répertoire, mais pas le droit d'exécution sur ce répertoire (mais on a quand même le droit d'exécution sur tous ses répertoires parent):

  • ⇒ Le listage est alors possible en console, mais avec message d'erreur et aucune info ne peut être obtenue sur les fichiers et répertoires en question: seul le nom apparait dans la liste et rien d'autres.

⇒ Par la suite, on ne tiendra pas compte de ce cas particulier rare qui ne peut que compliquer inutilement les explications.

Droit d'accéder à un fichier

Dans le cas général, le droit d'accès à un fichier coïncide avec le droit de listage précédent.

Cependant, si le droit de lecture sur le répertoire est absent, le listage est impossible, mais on peut tout de même accéder au fichier en citant son nom exact et son chemin (et les jokers dans les noms de fichiers ne marchent plus).

Droit d'examiner le contenu d'un fichier

Pour avoir le droit d'examiner le contenu d'un fichier, il faut:

  • pouvoir accéder au fichier
  • et avoir le droit de lecture sur ce fichier (“r”)

Droit de modifier le contenu d'un fichier

Pour avoir le droit de modifier le contenu d'un fichier existant.

  • pouvoir accéder au fichier,
  • et avoir le droit d'écriture sur ce fichier (“w”).

En console, si vous avez le droit d'écriture, mais pas celui de lecture, vous pouvez toujours “injecter” un nouveau contenu dans le fichier, par exemple avec la commande “cat”. Mais n'essayez pas de faire cela avec les éditeurs de texte: ils n'aiment pas ça du tout…

Droit de lancer un fichier exécutable

Pour avoir le droit de lancer l'exécution d'un fichier exécutable, il faut:

  • pouvoir accéder au fichier
  • et avoir le droit d'exécution sur ce fichier (“x”).

Droit de créer, de renommer ou d'effacer un fichier

Pour pouvoir créer, renommer ou effacer un fichier, situé dans un répertoire, il faut:

  • pouvoir accéder au contenu de ce répertoire (=droit de listage)
  • et avoir le droit d'écriture sur ce même répertoire

Ça ne dépend donc pas des droits qu'on a sur le fichier lui-même!!!

C'est facile à comprendre: il s'agit du droit de modifier le contenu d'un répertoire et pas le contenu d'un fichier! Mais cela donne souvent des situations inattendues. Par exemple:

  • Dans un répertoire qui vous appartient (votre home par exemple), rien ne vous empêche de renommer ou même d'effacer un fichier root:root avec un droit “rwx——”: Mais,bien sûr, vous ne pouvez pas voir ce qu'il y a dedans…
  • Dans le répertoire d'un autre utilisateur auquel vous avez accès mais sans droit d'écriture, s'il a un fichier à vous, vous ne pourrez pas l'effacer ni le renommer! Mais vous pouvez en modifier le contenu.

Dans les sites web, gérés à distance par ftp, cela donne aussi certains effets apparemment bizarres:

  • les fichiers et répertoires téléchargés par ftp appartiennent à l'utilisateur déclaré pour la connexion ftp
  • mais les fichiers créés par un script php appartiennent à l'utilisateur système “apache”! Ainsi:
    • pour permettre à ce script php de créer des fichiers et des répertoires dans un répertoire “ftp”, il faut élargir le droit de ce répertoire “ftp” à “777”,
    • lorsque ce script php crée un répertoire et des fichiers dans ce répertoire, on ne peut pas effacer ces fichiers par ftp: seul un autre script php peut le faire!

Affectation des droits à la création des fichiers

Lorsqu'un utilisateur crée un nouveau fichier ou d'un nouveau répertoire:

  • ce fichier ou ce répertoire lui est attribué avec son groupe par défaut
  • avec les droits par défaut définis par la commande shell “umask”.

Attention: umask définit les droits qu'on a pas! C'est donc le complément à 7 des droits qu'on a vu plus haut. En général, la valeur par défaut à l'installation est: umask =0022, ce qui correspond à 755 (7-5=2) ou “rwxr-xr-x” pour les répertoires et 644 ou “rw-r–r–” pour les fichiers.

Connaitre la valeur de umask

Pour connaître la valeur de l'umask de votre linux en nombre octal, il suffit de faire en console:

$ umask 

Résultat:

$ 0022 

Ce qui correspond à un droit de 755 ou “rwxr-xr-x”. Pour avoir la même chose en texte (selon le même format que la commande shell “chmod”)

$ umask -S 

le résultat sera:

$ u=rwx,g=rx,o=rx  

Modifier la valeur de umask

Vous ne devriez pas pouvoir trouver beaucoup de bonnes raisons de changer cette valeur de umask, mais si vous savez ce que vous faites (et que vous aimez vivre dangeureusement), vous faites:

$ umask nouvellevaleur

Si “nouvellevaleur” commence par un chiffre, umask prendra cela pour un nombre octal (ex: 0022), sinon, umask attendra un texte conforme à ce qu'accepterait “chmod” (ex: u=rwx,g=rx,o=rx).

Ce n'est vraiment pas bien expliqué dans les différentes distributions, mais je crois que pour avoir cette modif de umask définitive, il faut intervenir dans certains fichiers comme /etc/profile.

Droits de copier ou de déplacer des fichiers

Droit de copier

Dans une copie, il y a un fichier d'origine placé dans un répertoire d'origine, et une copie conforme dans son contenu, qui doit se retrouver dans un répertoire de destination.

Pour que la copie soit possible, il faut:

  • pour la source:
    • que le fichier d'origine soit accessible
    • et qu'on ait le droit de lecture sur ce fichier.
  • pour la destination:
    • il faut que le répertoire de destination soit accessible
    • et en plus:
      • si le fichier de destination n'existe pas, il faut avoir le droit de créer un nouveau fichier dans le répertoire destination (=droit d'écriture sur ce répertoire)
      • si le fichier de destination existe, il faut avoir le droit d'écriture sur ce fichier pour pouvoir en remplacer son contenu.

Droit de déplacer

Selon les cas, la commande de déplacement en console (=“mv”) peut avoir pour effet de renommer le fichier d'origine ou de le supprimer après la copie (voir page man de “mv”).

Dans les 2 cas, il faut donc avoir, en plus du droit de copie, le droit de renommer ou de supprimer le fichier d'origine dans son répertoire (= droit d'écriture sur le répertoire d'origine)

Transmission des droits par la copie ou le déplacement des fichiers

Surprise: la copie n'est pas, en général, identique à la source!!! Mais rassurez-vous, c'est sur les droits qu'il pourra y avoir des des différences, et pas sur le contenu.

Regardons comment ça marche avec les différents programmes de copie et de déplacement.

Attention: je ne traite ici que des fichiers courants

  • fichiers
  • répertoires
  • liens symboliques

ainsi que des liens en dur, mais pas des fichiers spéciaux de périphériques (/dev/…) ni des sockets locales ni des tubes nommés.

Et je ne parle que des copies courantes et des déplacements courants: voir la page man de “cp” et de “mv” pour voir et utiliser toutes les options disponibles.

Copie et déplacement avec la console

1er cas: copie normale par un utilisateur normal

Vous êtes un utilisateur normal et vous voulez copier, par exemple, le fichier /chemin1/toto dans le répertoire /chemin2/machin. Vous faites (“cp -R” pour copier l'arborecence):

$ cp /chemin1/toto /chemin2/machin  

Quand vous lancez cette commande de copie en tant qu'utilisateur normal, elle s'exécute pour votre compte, c'est à dire qu'elle ne peut que fabriquer un copie vous appartenant (votrelogin:votregroupe)!!!

En résumé, cette copie:

  • affecte la copie à l'utilisateur et à son groupe par défaut,
  • met la date et l'heure de la copie
  • et transmet tous les droits (r, w et x, …), y compris le stiky bit, mais pas les suid et guid.
  • les liens symboliques sont recopiés en tant que liens symboliques, mais continuent à pointer sur les fichiers d'origine, même si ceux-ci faisaient partie de la copie! (attention aux déplacements!)
  • Les liens en dur sont recopiés comme des fichiers normaux avec le contenu des fichiers pointés. Ils sont affectés à l'utilisateur, et les liens avec les anciens fichiers sont rompus (qu'ils fassent ou non partie de la copie)

NB: dans l'affichage des liens symboliques, la console montre les droits du lien et les navigateurs graphiques montrent les droits des fichiers pointés.

Quand c'est “root” qui lance la même copie normale (“cp” ou “cp -R”), c'est la même chose qu'un utilisateur normal, à part bien sûr que tous les fichiers et répertoires copiés deviennent “root:root”.

2ème cas: copie “d'archive” par un utilisateur normal

Vous êtes toujours un utilisateur normal et vous voulez copier, par exemple, fichier /chemin1/toto dans le répertoire /chemin2/machin, mais avec l'option ”-a“. Vous faites donc (l'option ”-R“ n'est pas nécessaire pour copier l'arborescence: ”-a“ le fait déjà):

$ cp -a /chemin1/toto /chemin2/machin  

En résumé, cette copie:

  • affecte la copie à l'utilisateur et à son groupe par défaut,
  • transmet la date et l'heure des fichiers originaux,
  • et transmet tous les droits (r, w et x, …), y compris les suid, guid et stiky bit.
  • les liens symboliques sont recopiés en tant que liens symboliques, mais continuent à pointer sur les fichiers d'origine, même si ceux-ci faisaient partie de la copie! (attention aux déplacements!)
  • pour les liens en dur
    • si les fichiers pointés font partie de la copie, les liens en dur sont recopiés en tant que liens en dur et pointent désormais sur les fichiers recopiés,
    • dans le cas contraire, les liens “en dur” sont recopiés en tant que fichiers normaux avec le contenu, les droits et l'horodatage des anciens fichiers pointés, mais affectés à l'utilisateur et à son groupe par défaut.

NB: dans l'affichage des liens symboliques, la console montre les droits du lien et les navigateurs graphiques montrent les droits des fichiers pointés.

3ème cas: copie d'archive par “root”

C'est seulement quand c'est root qui lance la copie avec “cp -a” que ça devient intéressant, car quasiment tout est transmis sans changement à la copie. Le superutilisateur root fait donc:

# cp -a /chemin1/toto /chemin2/machin  

En résumé, cette copie:

  • conserve les propriétaire:groupe des fichiers d'origine,
  • transmet la date et l'heure des fichiers d'origine,
  • et transmet tous les droits des fichiers d'origine (r, w et x, …), y compris les suid, guid et stiky bit.
  • les liens symboliques sont recopiés en tant que liens symboliques, mais continuent à pointer sur les fichiers d'origine, même si ceux-ci faisaient partie de la copie! (attention aux déplacements!)
  • pour les liens en dur
    • si les fichiers pointés font partie de la copie, les liens en dur sont recopiés en tant que liens en dur et pointent désormais sur les fichiers recopiés,
    • dans le cas contraire, les liens “en dur” sont recopiés en tant que fichiers normaux, avec le contenu, les propriétaire:groupe, les droits et l'horodatage des anciens fichiers pointés.

⇒ Ce n'est donc pas par hasard si le ”-a“ veut dire “archive”: c'est la commande privilégiée pour toutes les sauvegardes à l'identique, y compris les sauvegardes système. Cependant, pour copier et, pire, pour déplacer des répertoires “système”, vous avez bien compris qu'il pouvait y avoir des problèmes avec les liens symboliques et avec les liens en dur!!!

Copie et déplacement avec konqueror sous KDE

La copie, faite par konqueror lancé par un utilisateur normal:

  • affecte la copie à l'utilisateur et à son groupe par défaut
  • respecte la date et l'heure des fichiers d'origine
  • transmet tous les droits (r, w, x,…), y compris les suid et guid, mais pas le sticky bit! (bizarre, bizare..).

Vous noterez que la copie par konqueror ne se comporte pas de la même façon que la console!

Les résultats sont les mêmes pour tous les modes de copie de konqueror: copie-vers, copier-coller, glisser-déposer.

La même copie faite par root donne le même résultat, à part, bien sûr que tous les fichiers er répertoires copiés deviennent “root:root”.

Je n'ai pas trouvé comment simuler le “cp -a” avec konqueror sous root, et c'est bien dommage: cela veut dire que même sous root, konqueror ne transmet jamais dans la copie le propriétaire:groupe des fichiers originaux, ni les droits stiky bit!!!. Attention donc aux opérations d'administration faites avec konqueror!

Copie et déplacement avec nautilus sous gnome

La copie, faite par nautilus lancé par un utilisateur normal:

  • affecte la copie à l'utilisateur et à son groupe par défaut
  • respecte la date et l'heure des fichiers originaux
  • transmet tous les droits (r, w, x), y compris les suid, guid et sticky bit!.

Je m'attendais à ce que la même copie faite par root donne les mêmes résultats. mais, à ma grande surprise, lancé par root, nautilus recopie en respectant tout: le propriétaire:groupe et tout le reste! Donc comme “cp -a”.

Bravo, ça c'est bien!

Droit de modifier les droits

Modification du propriétaire ou du groupe d'un fichier

Seul le superutilisateur “root” peut changer le propriétaire d'un fichier!

  • Cela veut dire que même le propriétaire d'un fichier ne peut l'affecter à quelqu'un d'autre.
  • Cela veut dire aussi qu'un utilisateur ne peut s'approprier un fichier qui ne lui appartient pas, sauf s'il peut de recopier (= le fichier recopié lui appartiendra).

Seul le propriétaire d'un fichier peut changer le groupe de ce fichier, et seulement pour un autre groupe dans lequel il est déjà inscrit.

  • Cas particulier: si on a le droit de copie sur ce fichier, le fait de le recopier dans un répertoire ayant le droit setgid et le groupe voulu l'affecte à ce groupe.
  • Par contre, root peut affecter le fichier à un groupe dans lequel le propriétaire n'est pas membre!

Modification des droits de lecture, d'écriture ou d'exécution

Seul le propriétaire d'un fichier peut modifier les droits r, w et x.

  • donc: un membre du groupe d'utilisateurs du fichier ne peut rien modifier, même s'il a le droit d'écriture, et même sur les droits du “reste du monde”.

Modification des droits spéciaux: suid, sgid et stiky bit

Seul le propriétaire d'un fichier ou d'un répertoire peut modifier les droits suid, sgid et sticky bit.

Comment modifier les droits

Modifier le propriétaire et le groupe

Avec la console

Pour changer le propriétaire et/ou le groupe, on utilise “chown”, et pour changer seulement le groupe, on peut utiliser “chgrp”.

Par exemple:

  • Pour affecter le fichier toto à l'utilisateur albert:
# chown albert toto  
  • pour ne changer que le groupe de toto par le groupe users:
#  chown :users toto

ou

# chgrp users toto  
  • Pour changer les 2 à la fois:
# chown albert:users toto  

Et appliqué à un répertoire, vous pouvez ajouter l'option ”-R“ qui entrainera une modification de tous les fichiers et répertoires de l'arborescence.

Avec konqueror sous KDE

  • on peut facilement changer les propriétaires et groupes (si on a le droit de le faire) avec: clic droit → propriétés → droits d'accès.
  • et avec konqueror sous root: on peut changer ce qu'on veut

Avec nautilus sous gnome

  • idem avec nautilus: clic droit → propriétés → permissions
  • et avec nautilus sous root: on peut changer ce qu'on veut

Modifier les droits de lecture, d'écriture, d'exécution et les droits particuliers

Avec la console

On utilise “chmod”. On peut l'utiliser en notation alphabétique ou numérique.

Notation alphabétique:

chmod [ugo] [+-=] [rwx]  
  • [ugo]: “u”: utilisateur, “g”: groupe, “o”: autres (=“other”). On peut remplacer les 3 ensembles par “a” (=all).
  • [+-=]: ”+“: on ajoute, ”-“: on annule, ”=“: on affecte
  • [rwx]: avec ”+“ ou ”-“, seules les lettres mentionnées comptent. Avec ”=“, toutes les lettres comptent.

Exemples:

On ajoute le droit d'écriture pour le groupe du fichier toto:

chmod g+w toto  

On annule les droits de lecture, d'écriture et d'exécution pour les autres (=le reste du monde) du fichier toto:

chmod o= toto  

On rend exécutable pour tous le fichier toto:

chmod a+x toto  

Notation numérique:

On utilise l'expression des droits en nombres octals comme on l'a vu dans la présentation des droits plus haut.

Exemples:

On veut des droits 644 soit “rw-r–r–” pour le fichier toto:

chmod 644 toto

On veut des droits 755 avec un bit setuid en plus:

chmod 4755 toto

Avec konqueror et, pour root: konqueror en mode superutilisateur,

  • on peut facilement changer les droits (si on a le droit de le faire!) avec: clic droit → propriétés → droits d'accès.

Avec nautilus

Droits des programmes qui s'exécutent

Avec quel droits s'exécute un programme dont on a lancé l'exécution?

Cas général des programmes et des commandes shell (hors droits "suid" et hors script shell)

A part le “init” de départ qui est lancé au boot, tous les programmes sont lancés par un utilisateur ayant un compte sur le linux: utilisateur système (comme “root”) ou utilisateur “normal”

Chaque programme s'exécute sous le compte et avec les droits de l'utilisateur qui l'a lancé! Par exemple, si c'est l'utilisateur normal “albert” (par exemple), tout ce qui sera fait par ce programme le sera sous le compte albert:users avec son niveau de privilège, mais pas plus. C'est donc, dans le cas général, celui qui lance le programme qui compte, et pas le propriétaire du fichier exécutable.

Un programme normal bien écrit ne doit pas pouvoir travailler avec un niveau de privilège supérieur à celui pour le compte de qui il s'exécute!

Exemple, Sous votre login, en ouvrant un éditeur de texte, kate sous KDE ou gedit sous gnome, celui-ci s'exécute sous votre compte (alors que les fichiers exécutables kate et gedit appartiennent à root:root). Si vous voulez ouvrir un fichier, il refusera d'ouvrir un fichier dont vous n'avez pas le droit de lecture, et refusera aussi d'aller dans des répertoires qui vous sont interdits (ex: /root ou les /home/xxx/Documents des autres utilisateurs). Et lorsque vous voudrez sauvegarder un nouveau fichier, il le fera naturellement avec votre login:users comme propriétaire.

Exemple: la commande shell ”/bin/touch“ qui permet de créer un nouveau fichier, appartient à root:root avec “rwxr-xr-x”, donc autorise l'exécution par tous.

  • Sous votre login et dans un répertoire à vous, avec un simple “touch toto” vous allez créer un nouveau fichier “toto” qui vous appartiendra forcément (à vous, et pas à root) parce que c'est vous qui avez lancé le programme! Effacez le “toto”.
  • Si vous lancez maintenant ce même programme “sous root” avec “sudo touch toto”, le nouveau fichier “toto” appartiendra forcément à root:root parce que /bin/touch s'exécutera alors sous le compte de root.

Lorsqu'un programme est lancé au démarrage de linux, il est en général lancé par root. Mais root peut sans problème passer la main à d'autres programmes pour le compte de n'importe quel autre utilisateur!

Exemple: Pour apache, une 1ère partie est lancée sous root, mais celle-ci passe la main rapidement à d'autres parties qui, elles, s'exécuteront sous l'utilisateur système: wwwrun:www. Ce n'est donc pas par hasard si un nouveau fichier créé par un script php aura comme propriétaire wwwrun:www! Ce qui posera un problème spécifique puisque les pages et les répertoires “uploadés” par ftp sur le site web appartiendront au login de la connexion ftp…

Cas des droits "suid" et guid"

Dans ce cadre, que donne le droit “suid” dont on a parlé plus haut? Il fait que le programme s'exécute alors avec les droits du propriétaire de la commande, et non avec les droits de l'utilisateur qui l'a lancée.

Exemple d'un programme “normal”: en ajoutant (provisoirement) ce droit “suid” à /usr/bin/nano (=bon éditeur de texte en console!), vous pouvez, sous votre login, créer un nouveau fichier appartenant à root:users! Et si vous lui ajoutez en plus le droit “guid”, vous allez créer, sous votre login d'utilisateur normal, un nouveau fichier appartenant cette fois à root:root!

Exemple d'une commande shell: en ajoutant (provisoirement) ce droit “suid” à /bin/touch, vous pouvez, sous votre login, créer un nouveau fichier appartenant à root:users! Et si vous ajoutez en plus le droit “guid” à /bin/touch, vous allez créer, sous votre login d'utilisateur normal, un nouveau fichier appartenant cette fois à root:root!

Ce qui fait que ces droits “suid” et “guid” sont à utiliser avec beaucoup de précautions.

Dans les programmes “système”, on peut citer comme exemple justifié la commande /usr/bin/passwd: sans les droits “suid”, un utilisateur normal ne pourrait pas changer son propre mot de passe.

Cas des scripts shell

Essayons maintenant de faire un script shell: on crée “sous root” un fichier texte qu'on appelle “creafic” et dans lequel on place:

#!/bin/sh
touch toto

On le sauvegarde dans /usr/bin par exemple, et on rend le fichier exécutable. Ce script appartient donc à root:root avec “rwxr-xr-x”: tout le monde peut donc le lancer.

Dans une console sous votre login (“albert” par exemple), placez-vous dans un répertoire à vous et lancez-le: un nouveau fichier (vide) appelé “toto” est créé. Il appartient à albert:users avec “rw-r–r–” ce qui est le résultat attendu. Effacez ce fichier “toto”.

Mettez maintenant le droit suid à /usr/bin/creafic, et appelez de nouveau creafic sous votre login et dans un répertoire à vous. On s'attend à ce qu'un nouveau fichier “toto” appartenant à root soit créé: mais ça ne marche pas. Le nouveau fichier est encore créé sous “albert”. Pourquoi? Parce que le script shell ne transmet pas le bit suid car c'est trop dangereux pour la sécurité!

Pour plus d'info: reportez-vous à l'article ici: http://www.lea-linux.org/cached/index/Dev-suid_scripts.html

Solutions de contournement:

- faire “sudo creafic”: l'ensemble du script est alors exécutée sous root, mais il faut donner le mot de passe root à chaque fois (ce qui est très bien!).

- donner l'autorisation dans /etc/sudoers avec possibilité de ne pas avoir de mot de passe à donner (possible, mais dangereux)

- traduire le script shell en programme C qui s'exécutera avec le bit suid: il faudra manipuler sous C les UID réels et effectifs de l'utilisateur pour conserver les droits root dans chaque appel en C de commande shell.

droits_linux.txt · Dernière modification: 2007/12/15 09:58 par tyrtamos

Outils de la page