Chcę znaleźć pliki, których dany użytkownik nie będzie w stanie odczytać.
Załóżmy, że nazwa użytkownika to „użytkownik123” i należą do grupy o nazwie „użytkownik123”. Chcę znaleźć pliki, które, jeśli są własnością użytkownika123, mają włączoną funkcję u + r; w przeciwnym razie, jeśli plik należy do grupy user123, powinien mieć włączony g + r; w przeciwnym razie może mieć włączone o + r.
Ponieważ GNU find ma opcję „-readable”, mógłbym to zrobić:
sudo -u user123 find /start ! -readable -ls
Jednak proces musi być uruchamiany przez użytkownika, który nie ma dostępu do sudo. Dlatego próbowałem tego: (nie sprawdza o + r, ale w tym momencie nie jest to ważne)
find /start \( -user user123 ! -perm -u=r \) -o \( -group user123 ! -perm -g=r \) -ls
ale wyświetla ten plik:
272118 4 -rw------- 1 user123 user123 3243 Jul 3 19:50 /start/blah/blah/file.txt
Ten plik jest jedynym plikiem /start
należącym do użytkownika123 przy g=r
wyłączonym. To tak, jakby find interpretuje -u=r
jako -g=r
.
Postanowiłem spróbować odwrócić logikę i zamiast tego przetestować not ( truth )
:
find /etc/puppet ! \( \( -user puppet -perm -u=r \) -o \( -group puppet -perm -g=r \) -o \( -perm -o=r \) \) -ls
To działa!
Dlaczego oryginał find
zawiódł? Czy to błąd find
(mało prawdopodobne), czy logika jest zła?
Aktualizacja: pomyliłem logikę. Jak wskazano poniżej, ponieważ! (A || B || C) == (! A &&! B &&! C) są to dwa równoważne stwierdzenia:
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
Moim celem nie było dwukrotne testowanie użytkownika / grupy. To, czego naprawdę potrzebuję, to bardziej skomplikowana struktura „jeśli to wtedy”, która prawdopodobnie byłaby możliwa tylko wtedy, gdyby istniał operator -xor. Mógłbym zbudować xor z i / lub / nie, ale byłoby to bardziej złożone niż dwa powyższe rozwiązania.
puppet
ma dostęp do pliku za pomocą--wxrwxrwx puppet puppet
.Odpowiedzi:
Logika jest zła. Uważasz, że ten plik nie powinien być wymieniony, ponieważ jest własnością
user123
i mar
ustawiony bit użytkownika . Jest on jednak wymieniony, ponieważ spełnia drugie kryterium (jest własnością grupyuser123
i mar
ustawiony bit grupy ).Druga wersja działa z powodu jednego z praw de Morgana : negowanie logicznej ORing grupy instrukcji jest logicznie równoważne z ANDingiem negacji poszczególnych instrukcji. Innymi słowy:
Więc praca
find
szuka pliku, któryuser123
i czytelny dla tego użytkownika) ORAZuser123
i jest czytelny dla tej grupy) ORAZpodczas gdy pierwszy
find
szuka pliku, któryuser123
i nie może być odczytany przez tego użytkownika LUBuser123
i nie można jej odczytać przez wspomnianą grupę LUB (jeśli ją ukończyłeś)Tak więc plik pasujący do DOWOLNEGO z powyższych 3 kryteriów (i niekoniecznie wszystkich) byłby wymieniony tak, jak widziałeś.
Edytować
Nawiasem mówiąc (po obejrzeniu twojego profilu) jestem wielkim fanem twojej książki O'Reilly :)
źródło
( !A && !B && !C )
ale przeniosłem się!
do wnętrza każdej części, co nie jest ważne. Dzięki!Jest o wiele więcej rzeczy, które należy wziąć pod uwagę, aby sprawdzić, czy użytkownik ma dostęp do pliku za pośrednictwem danej ścieżki:
Poza tym, że faktycznie przełączam wszystkie identyfikatory użytkownika na identyfikatory użytkownika i sprawdzasz, bardzo trudno jest wdrożyć tę samą logikę, co system.
Z zsh możesz zrobić (jako root):
Lub z
perl
:W obu przypadkach należy opuścić drzewo katalogów jako,
root
ale przetestować dostęp do pliku jako odpowiedni użytkownik.Działa
find -readable
taksome-user
, jak nie jest, ponieważ nie będzie w stanie przejść obok katalogów, do których użytkownik nie ma dostępu lub nie ma uprawnień do odczytu (ale prawdopodobnie dostępu).Nawet jeśli rozważasz tylko uprawnienia i własność samego pliku (a nie list ACL lub komponentów ścieżki ...), potrzebujesz przynajmniej (tutaj składni GNU):
Chodzi o to, że jeśli plik jest własnością użytkownika, wszystkie inne uprawnienia są nieistotne. Jeśli nie, to jeśli plik należy do grupy którejkolwiek z grup użytkowników, wówczas uprawnienie „inne” nie ma znaczenia.
źródło
access()
to, że używa tego samego kodu jądra coopen()
.sudo -u user123 find /start -readable
Jest to zatem najlepsze rozwiązanie, jeślisudo
jest opcją.sudo -u user123 find -readable
, nie zgłosi plików w katalogach, do których nie możesz wejść, lub w katalogach, których nie możesz odczytać (więc będą fałszywe negatywy i fałszywe pozytywy). Dlatego sugeruję używaniezsh
do opuszczania drzewa katalogów jako root i doaccess()
([ -r ... ]
) jako rzeczywistego użytkownika (ustawienie$USERNAME
wzsh
zmianach wszystkich identyfikatorów UID i GIDsudo
).