Trova file che un utente non può leggere?


12

Voglio trovare file che un determinato utente non sarà in grado di leggere.

Supponiamo che il nome utente sia "user123" e siano in un gruppo chiamato "user123". Voglio trovare file che, se sono di proprietà di user123, hanno u + r attivo; in caso contrario, se il file è il gruppo user123 dovrebbe avere g + r acceso; in mancanza di ciò può avere o + r acceso.

Dato che GNU find ha "-readable", potrei farlo:

sudo -u user123 find /start ! -readable -ls

Tuttavia, il processo deve essere eseguito da un utente che non ha accesso sudo. Quindi ho provato questo: (non controlla o + r ma non è importante a questo punto)

find /start \( -user user123 ! -perm -u=r  \) -o \( -group user123 ! -perm -g=r  \) -ls

ma elenca questo file:

272118    4 -rw-------   1 user123   user123       3243 Jul  3 19:50 /start/blah/blah/file.txt

Questo file è l'unico sotto /startquello di proprietà dell'utente123 con g=roff. È come se find stia interpretando l' -u=ras -g=r.

Ho deciso di provare a invertire la logica e invece testare not ( truth )invece:

find /etc/puppet ! \( \( -user puppet -perm -u=r  \) -o \( -group puppet -perm -g=r \) -o \( -perm -o=r \) \)  -ls

Che funzioni!

Perché l'originale findnon è riuscito? È un bug in find(improbabile) o la logica è sbagliata?

Aggiornamento: ho avuto la logica sbagliata. Come indicato di seguito, da allora! (A || B || C) == (! A &&! B &&! C) queste sono le due affermazioni equivalenti:

find /start ! \( \( -user user123 -perm -u=r \) -o \( -group user123 -perm -g=r \) -o \( ! \( -user user123 -o -group user123 \) -perm -o=r \) \) -ls
find /start ! \( -user user123 -perm -u=r \) ! \( -group user123 -perm -g=r \) ! \( ! \( -user user123 -o -group user123 \) -perm -o=r \) -ls

Il mio obiettivo non era di testare due volte utente / gruppo. Ciò di cui ho davvero bisogno è una struttura if-then-else più complicata, che probabilmente sarebbe possibile solo se esistesse un operatore -xor. Potrei costruire un xor da e / o / no ma sarebbe più complesso delle due soluzioni sopra.


1
Anche la seconda logica è sbagliata, perché direbbe che puppetha accesso a un file con --wxrwxrwx puppet puppet.
Stéphane Chazelas,

Risposte:


7

La logica è sbagliata Stai pensando che questo file non avrebbe dovuto essere elencato perché è di proprietà user123e ha il rbit impostato dall'utente . Tuttavia, è elencato perché corrisponde al secondo criterio (è di proprietà del gruppo user123e ha il rbit del gruppo non impostato).

La tua seconda versione funziona a causa di una delle leggi di de Morgan : negare il ORing logico di un gruppo di affermazioni equivale logicamente a ANDing la negazione delle singole affermazioni. In altre parole:

 ! ( A || B || C ) == ( !A && !B && !C )

Quindi il lavoro findè alla ricerca di un file che

  • Non è (di proprietà dell'utente user123e leggibile da detto utente) AND
  • Non è (di proprietà di un gruppo user123e leggibile da detto gruppo) AND
  • Non è leggibile dal mondo.

mentre il primo findè alla ricerca di un file che

  • È di proprietà dell'utente user123e non è leggibile da detto utente OPPURE
  • È di proprietà di un gruppo user123e non è leggibile da detto gruppo OPPURE (se l'hai completato)
  • Non è leggibile dal mondo

Quindi un file che corrisponde a QUALSIASI dei 3 criteri di cui sopra (e non necessariamente tutti) verrà elencato come hai visto.

modificare

Per inciso (dopo aver visto il tuo profilo), sono un grande fan del tuo libro O'Reilly :)


Grazie per l'analisi Sì, è stata un'errata applicazione della legge di Morgan. Stavo cercando di fare ( !A && !B && !C )ma ho spostato !l'interno di ogni parte, il che non è valido. Grazie!
TomOnTime,

PS Sono contento che tu sia un fan del mio libro! Sono curioso di
sapere in

@TomOnTime English, ovviamente. Cerco di leggere qualsiasi libro nella sua lingua originale se posso aiutarlo.
Joseph R.,

8

Ci sono molte altre cose da prendere in considerazione per verificare se un utente ha accesso a un file tramite un determinato percorso:

  • Il proprietario del file
  • il gruppo del file
  • gli ACL nel file
  • uid, gid e gid supplementari dell'utente
  • cerca l'accesso a qualsiasi componente del percorso che porta a quel file.
  • se il file è un collegamento simbolico
  • le autorizzazioni si applicano in modo diverso per gli utenti di id 0.
  • forse più funzionalità di sicurezza come SELinux ...

A corto di passare effettivamente tutti gli uid e i gid a quelli dell'utente e verificare, è molto difficile implementare la stessa logica di ciò che fa il sistema.

Con zsh, potresti fare (come root):

readable() (
  USERNAME=$u
  [ -r "$REPLY" ]
)
u=some-user
print -rl -- **/*(DoN^+readable)

O con perl:

find . -print0 | sudo -u some-user perl -Mfiletest=access -l -0ne '
  print unless -r'

Cioè in entrambi i casi, discendi l'albero delle directory come rootma verifica l'accesso ai file come l'utente corrispondente.

L'esecuzione find -readablecome some-usernon avverrà nei casi in cui non sarà in grado di superare le directory per le quali l'utente non ha accesso o nessun permesso di lettura (ma possibilmente l'accesso).

Anche quando si considera solo l'autorizzazione e la proprietà del file stesso (e non di ACL o componenti di percorso ...), è necessario almeno (qui sintassi GNU):

u=some-user; g=$(id -G "$u" | sed 's/ / -o -group /g'); IFS=" "
find . ! \( -user "$u" -perm -u=r -o \
          ! -user "$u" \( -group $g \) -perm -g=r -o \
          ! -user "$u" ! \( -group $g \) -perm -o=r \)

L'idea è che se il file è di proprietà dell'utente, tutte le altre autorizzazioni sono irrilevanti. In caso contrario, se il file appartiene al gruppo di uno dei gruppi dell'utente, l'autorizzazione "altro" è irrilevante.


1
Un buon punto su ACL e altri fattori. L'unica valutazione corretta al 100% è access()poiché utilizza lo stesso codice kernel di open(). Quindi sudo -u user123 find /start -readableè la soluzione migliore se sudoè un'opzione.
TomOnTime,

1
@TomOnTime. Bene no, se lo usi sudo -u user123 find -readable, non riporterà i file nelle directory che non puoi inserire o nelle directory che non puoi leggere (quindi ci saranno falsi negativi e falsi positivi). Ecco perché suggerisco di usare zshper discendere l'albero delle directory come root e do access()( [ -r ... ]) come l'utente reale (impostando $USERNAMEin zshcambi tutti gli uid e le gid come sudofarebbero).
Stéphane Chazelas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.