사용자가 읽을 수없는 파일을 찾으십니까?


12

특정 사용자가 읽을 수없는 파일을 찾고 싶습니다.

사용자 이름이 "user123"이고 "user123"이라는 그룹에 있다고 가정하십시오. user123이 소유 한 경우 u + r이 설정된 파일을 찾고 싶습니다. 파일이 user123 그룹 인 경우 g + r이 켜져 있어야합니다. o + r을 켤 수 없습니다.

GNU find는 "읽을 수있는"것을 가지고 있기 때문에 다음과 같이 할 수 있습니다 :

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

그러나 프로세스는 sudo 액세스 권한이없는 사용자가 실행해야합니다. 따라서 II는 이것을 시도했습니다 : (o + r을 확인하지는 않지만 지금은 중요하지 않습니다)

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

그러나이 파일을 나열합니다 :

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

이 파일은 /startuser123이 소유 한 유일한 파일 g=r입니다. 마치 find가 -u=ras를 해석하는 것과 같습니다 -g=r.

나는 논리를 뒤집으려고 시도하고 대신 테스트 not ( truth )했습니다.

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

작동합니다!

원본이 find실패한 이유는 무엇 입니까? 버그 find일까요 (아마도) 또는 논리가 잘못 되었습니까?

업데이트 : 나는 논리가 잘못되었습니다. 이후 지적했듯이! (A || B || C) == (! A &&! B &&! C) 이들은 두 개의 동등한 문장입니다.

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

내 목표는 사용자 / 그룹을 두 번 테스트 할 필요가 없었습니다. 내가 정말로 필요한 것은 더 복잡한 if-then-else 구조이며, 아마도 -xor 연산자가있는 경우에만 가능합니다. 나는 xor를 만들거나하지 않을 수 있지만 위의 두 솔루션보다 더 복잡 할 것입니다.


1
두 번째 논리조차도 puppet로 파일에 액세스 할 수 있기 때문에 잘못 되었습니다 --wxrwxrwx puppet puppet.
Stéphane Chazelas

답변:


7

논리가 잘못되었습니다. 이 파일은 소유하고 user123있고 사용자 r비트가 설정 되어 있기 때문에이 파일이 나열되어서는 안된다고 생각합니다 . 그러나 두 번째 기준 (그룹이 소유 user123하고 그룹의 r비트가 설정되지 않음) 과 일치하기 때문에 나열됩니다 .

두 번째 버전은 de Morgan의 법칙 중 하나로 작동합니다 . 진술 그룹의 논리적 OR을 부정하는 것은 개별 진술을 부정하는 것과 논리적으로 동일합니다. 다시 말해:

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

그래서 작업 find은 파일을 찾고 있습니다

  • (사용자가 소유하고 해당 사용자 user123가 읽을 수있는)
  • (그룹이 소유하고 해당 그룹이 user123읽을 수있는)
  • 세계가 읽을 수 없습니다.

첫 번째 find파일을 찾는 동안

  • 사용자가 소유하고 있으며 해당 사용자 user123가 읽을 수 없거나
  • 그룹이 소유하고 있으며 해당 그룹이 user123읽을 수 없거나 OR (완료 한 경우)
  • 세계가 읽을 수 없습니다

따라서 위에서 본 3 가지 기준 중 하나와 일치하는 파일 (모두는 아님)이 나열됩니다.

편집하다

덧붙여서 (프로필을 본 후) 나는 O'Reilly 책의 큰 팬입니다. :)


분석해 주셔서 감사합니다. 그렇습니다. 그것은 모건의 법을 잘못 적용한 것입니다. 나는 노력하고 ( !A && !B && !C )있었지만 !각 부분의 내부 로 옮겼습니다 . 감사!
TomOnTime

추신 : 나는 당신이 내 책의 팬이되어 기쁘다! 어떤 언어로 읽었는지 궁금합니다.
TomOnTime

물론 @TomOnTime 영어. 도움이 될 수 있다면 원래 언어로 된 책을 읽으려고합니다.
Joseph R.

8

주어진 경로를 통해 사용자가 파일에 액세스 할 수 있는지 확인하기 위해 고려해야 할 사항이 훨씬 더 많습니다.

  • 파일의 소유자
  • 파일의 그룹
  • 파일의 ACL
  • 사용자의 UID, GID 및 보조 GID
  • 해당 파일로 연결되는 모든 경로 구성 요소에 대한 검색 액세스
  • 파일이 심볼릭 링크인지 여부
  • ID 0의 사용자에게는 권한이 다르게 적용됩니다.
  • SELinux와 같은 더 많은 보안 기능 ...

실제로 모든 uid 및 gid를 사용자의 것으로 변경하고 확인하지 않으면 시스템과 동일한 논리를 구현하기가 매우 어렵습니다.

zsh를 사용하면 (루트로) 다음을 수행 할 수 있습니다.

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

또는과 perl:

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

즉, 두 경우 모두 디렉토리 트리를 내림차순으로 설정 root하지만 해당 사용자로 파일 액세스를 테스트하십시오.

실행 find -readable등의 some-user경우되지 않습니다 것은 사용자가 접근 또는 읽기 권한 (그러나 가능 액세스)를 갖지 않는 디렉토리를지나 갈 수 없을 것 같은.

ACL 또는 경로 구성 요소가 아닌 파일 자체의 권한과 소유권 만 고려할 때도 최소한 여기 (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 \)

사용자가 파일을 소유 한 경우 다른 모든 권한은 관련이 없습니다. 그렇지 않은 경우 파일이 사용자 그룹 중 하나에 의해 그룹 소유인 경우 "기타"권한은 관련이 없습니다.


1
ACL 및 기타 요인에 대한 좋은 지적. 100 % 정확한 평가는와 access()동일한 커널 코드를 사용하기 때문 open()입니다. 따라서 옵션 인 sudo -u user123 find /start -readable경우 최상의 솔루션 sudo입니다.
TomOnTime

1
@TomOnTime. 글쎄,를 사용 sudo -u user123 find -readable하면 입력 할 수없는 디렉토리 또는 읽을 수없는 디렉토리에 파일을보고하지 않습니다 (따라서 오 탐지 및 오 탐지가 있습니다). 그렇기 때문에 zsh디렉토리 트리를 루트로 내림차순 으로 사용하고 실제 사용자로 access()( [ -r ... ])를 수행하는 것이 좋습니다 ( 모든 uid 및 gid $USERNAMEzsh변경하는 것처럼 설정 sudo).
Stéphane Chazelas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.