web-dev-qa-db-fra.com

Terminal: Répertorie tous les répertoires pour lesquels un utilisateur ou un groupe dispose d'une autorisation d'écriture

J'aimerais répertorier tous les répertoires pour lesquels un utilisateur ou un groupe dispose d'autorisations en écriture.

J'ai trouvé cette question sur ServerFault , mais cela concerne un serveur Windows. Je suis donc optimiste: il y a quelque chose de mieux pour nous dans la communauté Linux. En même temps, je me rends compte que cette question a une connotation récursive qui peut la rendre impossible sans un script long.

Je connais les commandes utiles suivantes:

  • Lister tous les groupes: cut -d : -f 1 /etc/group
  • Répertoriez tous les utilisateurs: cut -d : -f 1 /etc/passwd
  • Récupère le répertoire personnel de l'utilisateur: getent passwd user-name| cut -d: -f 6
  • Ce script qui répertorie chaque utilisateur et ses affectations de groupe
  • Obtenir les autorisations et les informations sur les utilisateurs/groupes sur le contenu du dossier: ls -la

Cependant, lorsque je ne sais pas du tout quel est le but d'un utilisateur, il serait agréable de dresser une liste de TOUS les répertoires pour lesquels il dispose d'une autorisation d'écriture et de commencer à chercher à partir de là. Si rien d'autre c'est un audit super utile ..

Si cela aide à comprendre mon objectif, j’ai hérité (ou au moins je suis assis au baby-sitting?) De deux systèmes après que notre SysAdmin ait changé de poste. J'ai donc essayé de comprendre l'évolution de ces deux systèmes, par exemple quel logiciel est installé et où (..ugh), où résident les différents fichiers de configuration, et maintenant quels groupes et utilisateurs ont été créés - y compris les répertoires auxquels ils sont autorisés à écrire. Habituellement, je peux trouver de telles commandes de terminal utiles ici sur askubuntu, mais ne trouvant pas celle-ci, je pensais aller de l'avant et demander.

Le système exact est Ubuntu 10.04.2, mais nous supportons également Ubuntu 12.04.5, la solution la plus indépendante de la version serait donc préférable. Merci d'avance pour votre aide.


[Mise à jour: premiers résultats pour les deux réponses rapides]

Il est à noter que je suis connecté en tant que root pour ceux-ci, et / était mon répertoire de travail. En outre, ils ont pris un temps comparable à courir.

La commande combinée de @ Rinzwind a obtenu la sortie suivante en environ 5,5 minutes.

root@tatooine:/# Sudo find -type d \( \( -user ftpgisdata -perm /u=w \) -o \( -group ftpgisdata -perm /g=w \) -o -perm /o=w \)
./tmp
./tmp/.ICE-unix
./tmp/.X11-unix
find: `./proc/6594/task/6594/fd/5': No such file or directory
find: `./proc/6594/task/6594/fdinfo/5': No such file or directory
find: `./proc/6594/fd/5': No such file or directory
find: `./proc/6594/fdinfo/5': No such file or directory
./var/tmp
./var/lib/php5
./var/crash
./var/lock
./home/ftpgisdata
./home/ftpgisdata/.ssh
./home/ftpgisdata/.cache
./home/sitename-i-changed.com/wp-content/profile-pics
./dev/shm

La commande révisée de @Oli obtient quelque chose de très similaire, également en 5,5 minutes environ.

root@tatooine:/# Sudo find / -type d -print0 | Sudo -u ftpgisdata xargs -0 sh -c 'for p; do [ -w "$p" ] && echo "$p"; done' -
/tmp
/tmp/.ICE-unix
/tmp/.X11-unix
find: `/proc/15541': No such file or directory
find: `/proc/15542': No such file or directory
find: `/proc/15543': No such file or directory
find: `/proc/15567': No such file or directory
find: `/proc/15568/task/15568/fd/5': No such file or directory
find: `/proc/15568/task/15568/fdinfo/5': No such file or directory
find: `/proc/15568/fd/5': No such file or directory
find: `/proc/15568/fdinfo/5': No such file or directory
/var/tmp
/var/lib/php5
/var/crash
/var/lock
/home/ftpgisdata
/home/ftpgisdata/.ssh
/home/ftpgisdata/.cache
/home/sitename-i-changed.com/wp-content/profile-pics
/dev/shm

@PeterCordes answer a également renvoyé des résultats similaires en 5,5 minutes environ.

root@tatooine:~# username_to_check=ftpgisdata base_dir=/   # for example
root@tatooine:~# Sudo -u "$username_to_check" find "$base_dir" -type d -writable  2>/dev/null ## GNU find, not POSIX
/tmp
/tmp/.ICE-unix
/tmp/.X11-unix
/proc/7159/task/7159/fd
/proc/7159/fd
/proc/7159/map_files
/var/tmp
/var/lib/php5
/var/crash
/var/lock
/home/ftpgisdata
/home/ftpgisdata/.ssh
/home/ftpgisdata/.cache
/home/sitename-i-changed.com/wp-content/profile-pics
/dev/shm
7
elrobis

Il est difficile de déterminer ce qu'un utilisateur peut faire si vous n'êtes pas cet utilisateur. Vous pouvez tester différentes choses (propriétaire, même groupe, etc.), mais la liste de contrôle d'accès peut s'appliquer, il se peut qu'il n'y ait aucune autorisation dans le montage, qui sait. C'est dur.

Si vous pouvez transformer cet utilisateur, vous pouvez test -w <path> pour voir s’il peut écrire. Ce n'est pas aussi rapide que de regarder simplement l'inode mais c'est possible avec Sudo.

Sudo -u oli test -w <path> && echo "HOORAY"

Nous pouvons ensuite le placer sur le back-end de find. Au lieu d'utiliser simplement -exec pour passer à l'utilisateur oli encore et encore (voir les révisions précédentes), nous dirigons tout vers une instance xargs exécutée en tant que oli. C'est beaucoup plus rapide.

Sudo find / -type d -print0 | Sudo -u oli xargs -0 -I{} sh -c 'test -w "$0" && echo "$0"' {}

Une version quelque peu optimisée (mais visuellement plus flatteuse) de cette opération implique de minimiser le nombre de sous-traitements effectués par les xargs en canalisant un flux de chemins dans un nombre réduit de sous-réservoirs bash. C'est sans doute plus rapide pour les grosses recherches.

Sudo find / -type d -print0 | Sudo -u oli xargs -0 sh -c 'for p; do [ -w "$p" ] && echo "$p"; done' -
7
Oli

Dans le chat, nous sommes arrivés aux instructions suivantes pour l'utilisateur et le groupe:

Sudo find / -type d -user rinzwind -perm /u=w
Sudo find / -type d -group rinzwind -perm /g=w
Sudo find / -type d -perm /o=w

Ou combinez les trois en un:

Sudo find -type d \( \( -user rinzwind -perm /u=w \) -o \( -group rinzwind -perm /g=w \) -o -perm /o=w \)

Sans le/it recherche le répertoire courant.

A pris moins de 2 secondes sur 67 Go de données sur mon système;)

4
Rinzwind

Réponse en construction, veuillez patienter

se tester

On peut tester les autorisations d’écriture pour lui-même avec le code suivant:

[ -w /home/$USER ] && echo yes # using home directory as example

En utilisant l'indicateur -d pour le test, nous pouvons tester si quelque chose est un répertoire.

Sachant tout cela et find que nous pouvons faire

find /home/ -print0 2> /dev/null | while IFS=""  read -r -d "" file ; do [ -d "$file"  ] &&  [ -w "$file" ]  && echo "$file" is writeable ; done

Note latérale: Évidemment, si vous obtenez des erreurs d'autorisation avec find, vous ne pouvez pas lire ce fichier, il n'y a donc aucune raison de les afficher, d'où la redirection vers dev null. Évidemment, cela ne fonctionnera pas si nous voulons trouver des autorisations pour des utilisateurs autres que nous-mêmes, et notez que/home est juste un exemple ici. Des dossiers tels que /var ont des dossiers partagés entre plusieurs utilisateurs.

Test pour les autres

On pourrait utiliser stat pour chaque fichier que find trouve et le filtrer avec awk

 find /var -type d -exec stat --format '%g %n'  {} \; 2> /dev/null | awk '$1=='1000'{print}' 

Ici, je filtre pour ID numérique de mon propre utilisateur, 1000, mais il pourrait s'agir de l'identifiant de n'importe quel utilisateur. Bien sûr, on peut jouer avec les options, utiliser le nom du groupe plutôt que les identifiants numériques. C'est quelque chose qui est très flexible et adaptable à la fin dont vous avez besoin

Petits ajustements

J'ai donc remarqué que vous avez mentionné être connecté en tant que root. Voici un résultat de ma commande, où je stat les fichiers et imprimer leur groupe et nom de fichier, puis filtrer en utilisant AWK par nom de groupe approprié.

$ find /proc -type d -exec stat --format '%G %n'  {} \; 2> /dev/null  | awk '$1=="syslog"{print}'
syslog /proc/560
syslog /proc/560/task
syslog /proc/560/task/560
syslog /proc/560/task/560/net
syslog /proc/560/task/560/attr
syslog /proc/560/task/562
syslog /proc/560/task/562/net
syslog /proc/560/task/562/attr
syslog /proc/560/task/563
syslog /proc/560/task/563/net
syslog /proc/560/task/563/attr
syslog /proc/560/task/564
syslog /proc/560/task/564/net
syslog /proc/560/task/564/attr
syslog /proc/560/net
syslog /proc/560/attr
^C
2

Si vous avez GNU find, vous pouvez utiliser le test -writable (notez l'orthographe, ce n'est pas writeable). Cela utilise l'appel système access(2) au lieu d'essayer de comprendre les choses en regardant les autorisations, afin que cela fonctionne correctement avec les ACL. (Mais pourrait casser sur NFS avec les mappages ID).

Il trouvera également des répertoires accessibles en écriture à l'utilisateur grâce à son appartenance à un groupe secondaire. (Par exemple, un répertoire de /usr/local inscriptible par les utilisateurs du groupe admin ou quelque chose comme chown root:users /data/share && chmod 2775 /data/share, dans lequel certains comptes sont membres du groupe users.)

username_to_check=peter base_dir=/   # for example
Sudo -u "$username_to_check" find "$base_dir" -type d -writable  2>/dev/null ## GNU find, not POSIX

Il y aura des erreurs lorsque find rencontrera des répertoires dans lesquels l'utilisateur ne peut pas descendre, nous redirigeons donc les erreurs vers /dev/null.

Ceci ne trouvera pas tous les répertoires accessibles en écriture mais situés dans des répertoires sans autorisation d'exécution, car find étant exécuté en tant que l'utilisateur ne peut pas parcourir les répertoires supérieurs. Toutefois, si un processus qu'ils possèdent est démarré dans un tel répertoire, ils pourront y écrire avec des chemins relatifs. (ou ils récupèrent un descripteur de fichier ouvert dans un tel répertoire, ils peuvent utiliser openat(2)). pwd ne fonctionnera pas s’ils n’ont pas le droit d’exécution sur l’un des composants de répertoire du chemin complet, ce n’est donc pas une installation courante.

Il manque également des répertoires inscriptibles se trouvant dans des répertoires exécutables mais non lisibles . Pour contourner ces limitations, exécutez probablement find -type d en tant que root et utilisez find -writable en tant qu'utilisateur pour vérifier les chemins résultants. Cela pourrait être plus efficace qu'une boucle Shell utilisant [ -w "$f" ].

POSIX find(1) a beaucoup moins d'options que GNU find. Si votre script doit être portable vers POSIX, il est probablement plus facile de canaliser vers quelque chose qui vérifie les autorisations, comme un shell avec [ -w "$f" ] (voir l'autre réponse suggérant ceci.)

2
Peter Cordes