Terminal: Listet alle Verzeichnisse auf, für die ein Benutzer oder eine Gruppe Schreibberechtigung hat

7

Ich möchte alle Verzeichnisse auflisten, für die ein Benutzer oder eine Gruppe Schreibberechtigungen hat.

Ich habe diese Frage in ServerFault gefunden , sie bezieht sich jedoch auf einen Windows Server. Daher bin ich optimistisch, dass es in der Linux-Community etwas Besseres für uns gibt. Gleichzeitig ist mir klar, dass diese Frage eine rekursive Wendung aufweist, die sie ohne ein lang laufendes Skript möglicherweise unmöglich macht.

Mir sind die folgenden nützlichen Befehle bekannt:

  • Listen Sie alle Gruppen auf: cut -d : -f 1 /etc/group
  • Alle Benutzer auflisten: cut -d : -f 1 /etc/passwd
  • Holen Sie sich das Home-Verzeichnis eines Benutzers: getent passwd user-name| cut -d: -f 6
  • Dieses Skript listet jeden Benutzer und seine Gruppenzuweisungen auf
  • Abrufen von Berechtigungen und Benutzer- / Gruppendetails zum Ordnerinhalt: ls -la

Wenn ich jedoch keine Ahnung habe, was der Zweck eines Benutzers ist, wäre es schön, eine Liste ALLER Verzeichnisse aufzurufen, für die er eine Schreibberechtigung hat, und sich von dort aus umzuschauen. Wenn nichts anderes, ist es ein sehr nützliches Audit.

Wenn es hilft, meinen Zweck zu verstehen, habe ich einige Systeme geerbt (oder bin ich zumindest Babysitter?), Nachdem unser SysAdmin eine neue Position eingenommen hat. Daher habe ich versucht, die Entwicklung dieser beiden Systeme zu verstehen, z. B. welche Software installiert ist und wo (..ugh), wo verschiedene Konfigurationsdateien gespeichert sind und welche verschiedenen Gruppen und Benutzer jetzt erstellt wurden - einschließlich die Verzeichnisse, in die sie schreiben dürfen. Normalerweise kann ich solche nützlichen Terminalbefehle hier auf askubuntu finden, aber wenn ich diesen nicht finde, dachte ich, ich würde weitermachen und fragen.

Das genaue System ist Ubuntu 10.04.2, aber wir unterstützen auch Ubuntu 12.04.5, daher ist die versionunabhängigste Lösung die beste. Vielen Dank im Voraus für jede Hilfe.


[Update: Erste Ergebnisse für die beiden schnellen Antworten]

Es ist erwähnenswert, dass ich als Root für diese angemeldet war und /mein Arbeitsverzeichnis war. Außerdem brauchten sie eine vergleichbare Zeit zum Laufen.

@ Rinzwinds kombinierter Befehl erhielt die folgende Ausgabe in ungefähr 5,5 Minuten.

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

@ Olis überarbeiteter Befehl bekommt etwas sehr Ähnliches, auch in ca. 5,5 Minuten ..

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

Die Antwort von @PeterCordes lieferte ähnliche Ergebnisse in etwa 5,5 Minuten.

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
Elrobis
quelle

Antworten:

7

Es ist schwierig herauszufinden, was ein Benutzer tun kann, wenn Sie nicht dieser Benutzer sind. Sie können verschiedene Dinge testen (ist Eigentümer, dieselbe Gruppe usw.), aber ACL kann zutreffen, es gibt möglicherweise keine Berechtigungen im Mount, wer weiß. Es ist schwer.

Wenn Sie sich in diesen Benutzer verwandeln können , können Sie test -w <path>sehen, ob er schreiben kann. Dies ist nicht so schnell wie das Betrachten der Inode, aber es ist mit möglich sudo.

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

Wir können das dann auf das Backend von wirbeln find. Anstatt nur zu verwenden -exec, um immer und immer wieder zum oli-Benutzer zu wechseln (siehe frühere Revisionen), leiten wir alles in eine xargs-Instanz weiter, die als oli ausgeführt wird. Das geht viel schneller.

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

Eine etwas optimierte (aber visuell schwächere) Version davon beinhaltet das Minimieren der Menge an Unterschalen, die die Xargs ausführen, indem ein Strom von Pfaden in eine geringe Anzahl von Bash-Unterschalen geleitet wird. Dies ist zweifellos schneller für große Suchvorgänge.

sudo find / -type d -print0 | sudo -u oli xargs -0 sh -c 'for p; do [ -w "$p" ] && echo "$p"; done' -
Oli
quelle
Ich habe zuerst @ Rinzwinds Ansatz ausprobiert, weil dieser etwas beängstigend war, aber seltsamerweise erzielen sie etwas andere Ergebnisse ..!
Elrobis
4

Im Chat kamen wir zu folgenden Anweisungen für Benutzer und Gruppe:

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

Oder kombinieren Sie alle drei zu einem:

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

Ohne das / sucht es das aktuelle Verzeichnis.

Bei 67 GB Daten auf meinem System dauerte es weniger als 2 Sekunden;)

Rinzwind
quelle
Hmm .. vielleicht mache ich etwas falsch? Aber wenn ich genau dies für den Zielbenutzer ausführe ftpgisdata, erhalte ich keine Ergebnisse. Es fällt einfach in die nächste Zeile im Terminal:find -type d -user ftpgisdata -perm /u=w,g=w
Elrobis
sudo mkdir cheese; sudo chmod o+w cheeseist ein Verzeichnis, in das jeder schreiben kann, das jedoch in keinem dieser Verzeichnisse angezeigt wird.
Oli
@elrobis Ändere sie so, dass sie beginnen find /. Derzeit wird nur das aktuelle Arbeitsverzeichnis durchsucht.
Oli
Ahh ok. ..so folgt daraus, dass wenn ich cd /, dass es von der Wurzel vorwärts suchen und einen bestimmten Benutzer oder eine bestimmte Gruppe berücksichtigen wird? Es läuft gerade und sieht vielversprechend aus - es dauert definitiv etwas länger als 2 Sekunden!
Elrobis
Und Sie müssen dies wahrscheinlich ausführen sudo, um Berechtigungsfehler zu vermeiden.
Muru
2

Antwort im Aufbau, bitte haben Sie etwas Geduld

Für sich selbst testen

Mit dem folgenden Code kann man Schreibberechtigungen für sich selbst testen:

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

Mit dem -dFlag zum Testen können wir testen, ob etwas ein Verzeichnis ist.

Das alles zu wissen und findwir können es tun

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

Randnotiz: Wenn Sie mit find Berechtigungsfehler erhalten, können Sie diese Datei natürlich nicht lesen. Daher gibt es keinen Grund, diese Fehler auszugeben. Daher wird auf dev null umgeleitet. Dies funktioniert natürlich nicht, wenn wir Berechtigungen für andere Benutzer als sich selbst herausfinden möchten, und beachten Sie, dass / home hier nur ein Beispiel ist. Ordner wie /varOrdner, die von mehreren Benutzern gemeinsam genutzt werden

Testen für andere

Man könnte für statjede Datei die findFunde verwenden und sie mit awk herausfiltern

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

Hier filtere ich nach der numerischen ID meines eigenen Benutzers, 1000, aber es könnte die ID eines beliebigen Benutzers sein. Natürlich kann man mit Optionen spielen, Gruppennamen anstelle von numerischen IDs verwenden. Es ist etwas, das sehr biegsam und an den gewünschten Zweck anpassbar ist

Kleine Anpassungen

Ich habe also festgestellt, dass Sie erwähnen, dass Sie als root angemeldet sind. Hier ist eine Ausgabe meines Befehls, in der ich Dateien statisiere und deren Gruppen- und Dateinamen drucke und dann mit AWK nach dem entsprechenden Gruppennamen herausfiltere.

$ 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
Sergiy Kolodyazhnyy
quelle
Zwar bin ich als Route angemeldet, aber im Grunde möchte ich lernen, "Hey, in welche Verzeichnisse kann X-Benutzer schreiben?" Ich habe gerade Ihren Ansatz für Benutzer mit id = 1001 ausprobiert, dh $1=='1001'es wurden keine Treffer zurückgegeben. Gedanken?
Elrobis
1
@elrobis Ja, ich habe die Seite verfolgt - mir ist klar, dass Sie die Schreibberechtigungen für ein Verzeichnis pro Benutzer überprüfen wollten. Ein Benutzer kann Teil einer Gruppe sein, sodass er in ein Verzeichnis schreiben kann. Die Verzeichnisgruppe ist beispielsweise foobar, aber der Benutzer, der zu dieser Gruppe gehört, hat möglicherweise einen Benutzernamen scooby. Dies ist anscheinend ein komplexeres Problem. . Ich werde mehr daran arbeiten, muss wahrscheinlich Funktionen zum Überprüfen des Benutzers und zum Überprüfen des Gruppenschreibzugriffs auf eine Datei schreiben
Sergiy Kolodyazhnyy
2

Wenn Sie GNU gefunden haben, können Sie den -writableTest verwenden (beachten Sie die Schreibweise, es ist nicht writeable). Dadurch wird der access(2)Systemaufruf verwendet, anstatt nur zu versuchen, die Berechtigungen zu überprüfen. Daher funktioniert er mit ACLs ordnungsgemäß. (Kann aber bei NFS mit ID-Zuordnungen beschädigt werden).

Es werden auch Verzeichnisse gefunden, die vom Benutzer beschreibbar sind, da er Mitglied einer sekundären Gruppe ist. (z. B. ein Verzeichnis, das /usr/localvon Benutzern in der adminGruppe geschrieben werden kann, oder ähnliches chown root:users /data/share && chmod 2775 /data/share, in dem einige Konten Mitglieder der usersGruppe sind.)

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

Es findtreten Fehler auf, wenn auf Verzeichnisse gestoßen wird, in die der Benutzer nicht absteigen kann. Daher leiten wir Fehler an weiter /dev/null.

Dies wird nicht alle Verzeichnisse finden, die beschreibbar aber in Verzeichnissen ohne Genehmigung auszuführen, weil , findwenn der Benutzer nicht ausgeführt , die höheren Verzeichnisse durchqueren können. Wenn jedoch ein eigener Prozess in einem solchen Verzeichnis gestartet wird, können sie mit relativen Pfaden darauf schreiben. (oder sie erhalten einen offenen Dateideskriptor für ein solches Verzeichnis, den sie verwenden können openat(2)). pwdfunktioniert nicht, wenn sie keine Exec-Berechtigung für eine der Verzeichniskomponenten des vollständigen Pfads haben, daher ist dies kein allgemeines Setup.

Dabei fehlen auch beschreibbare Verzeichnisse, die sich in ausführbaren, aber nicht lesbaren Verzeichnissen befinden . Um diese Einschränkungen zu umgehen, führen Sie sie wahrscheinlich find -type dals root aus und find -writableüberprüfen Sie die resultierenden Pfade als Benutzer. Das ist möglicherweise effizienter als eine Shell-Schleife [ -w "$f" ].

POSIXfind(1) bietet weit weniger Optionen als GNU. Wenn Ihr Skript auf POSIX portierbar sein muss, ist es wahrscheinlich am einfachsten, es in etwas anderes zu leiten, das Berechtigungen überprüft, z. B. eine Shell mit [ -w "$f" ](siehe die andere Antwort, die dies vorschlägt.)

Peter Cordes
quelle
Das Problem beim Ausführen der Suche als Nicht-Root besteht darin, dass Sie nicht den gesamten Baum auswerten. Erstellen Sie beispielsweise Folgendes: sudo mkdir -p cheese/deep; sudo chmod o+w cheese/deep; sudo chmod o-r cheeseJeder kann schreiben, cheese/deep aber den Inhalt des übergeordneten cheeseVerzeichnisses nicht lesen und daher findnicht sehen cheese/deep. Ihr Fund wird nur fehlerhaft sein (und den Fehler unterdrücken). Es tut uns leid.
Oli
@Oli: Oh richtig, ich habe das xohne rFall übersehen . Vielen Dank. Ich denke, wir könnten eine findBefehlszeile mit einer Shell-Schleife erstellen, die über die sekundären Gruppen des Benutzers iteriert, wenn wir nicht einfach die Root-Find-Ausgabe in einen anderen Prozess access(2)leiten möchten, der als Benutzer prüft. Dieser 2. Prozess könnte sein find -writable.
Peter Cordes
Peter danke für deinen Beitrag und die hilfreiche Beschreibung. Ich habe Ihre Lösung ausgeführt und meinen Beitrag aktualisiert, um das Ergebnis für denselben Benutzer aufzunehmen, gegen den ich getestet habe.
Elrobis
1
Auch ein netter Ansatz, aber dies stellte sich als ziemlich schwierig heraus und Sie würden fast einen Fehlerbericht einreichen, um dieses D zu verbessern. Die Frage ist gültig, wenn Sie sich mit der Sicherung eines Systems befassen. Und es ist einfach zu verdammt schwierig.
Rinzwind