उन फ़ाइलों को ढूंढें जो एक उपयोगकर्ता लिख ​​सकता है, कुशलतापूर्वक न्यूनतम प्रक्रिया निर्माण के साथ


20

मैं जड़ हूँ। मैं जानना चाहूंगा कि क्या एक गैर-रूट उपयोगकर्ता ने कुछ फ़ाइलों तक पहुंच लिखी है - उनमें से हजारों। प्रक्रिया निर्माण से बचते हुए इसे कुशलता से कैसे किया जाए?


कृपया हमें दिखाएं कि आप वास्तव में क्या करते हैं!
एफ। होरी


यह मानते हुए कि आप दौड़ की स्थिति के बारे में परवाह नहीं करते हैं, क्यों न केवल access(2)उचित रूप से सेट किए गए वास्तविक-यूआईडी (जैसे setresuid(2)कि पोर्टेबल समकक्ष) के साथ कॉल करें ? मेरा मतलब है, मैं बैश से ऐसा करने के लिए कड़ी मेहनत कर रहा हूं, लेकिन मुझे यकीन है कि पर्ल / पायथन इसे संभाल सकते हैं।
केविन

1
@ केविन, गोले [ -wआम तौर पर पहुंच (2) या समकक्ष का उपयोग करते हैं। आपको यूआईडी (जैसा कि सु या सुडो करते हैं) के अलावा ग्रिड को भी सेट करना होगा। बैश में उस के लिए बिलिन समर्थन नहीं है लेकिन zsh करता है।
स्टीफन चेज़लस

@ स्टीफनचेज़ेलस - आप chgrpकिसी भी शेल में उपयोग कर सकते हैं ।
15

जवाबों:


2

शायद इस तरह:

#! /bin/bash

writable()
{
    local uid="$1"
    local gids="$2"
    local ids
    local perms

    ids=($( stat -L -c '%u %g %a' -- "$3" ))
    perms="0${ids[2]}"

    if [[ ${ids[0]} -eq $uid ]]; then
        return $(( ( perms & 0200 ) == 0 ))
    elif [[ $gids =~ (^|[[:space:]])"${ids[1]}"($|[[:space:]]) ]]; then
        return $(( ( perms & 020 ) == 0 ))
    else
        return $(( ( perms & 2 ) == 0 ))
    fi
}

user=foo
uid="$( id -u "$user" )"
gids="$( id -G "$user" )"

while IFS= read -r f; do
    writable "$uid" "$gids" "$f" && printf '%s writable\n' "$f"
done

ऊपर प्रत्येक फ़ाइल के लिए एक एकल बाहरी कार्यक्रम चलाता है, अर्थात् stat(1)

नोट: यह मानता है bash(1), और लिनक्स अवतार stat(1)

नोट 2: कृपया इस दृष्टिकोण के अतीत, वर्तमान, भविष्य और संभावित खतरों और सीमाओं के लिए स्टीफन चेज़ेलस की टिप्पणियों को पढ़ें।


यह कह सकता है कि एक फाइल लिखने योग्य है भले ही उपयोगकर्ता को उस निर्देशिका तक पहुंच न हो, जहां वह है।
स्टीफन चेज़लस

फ़ाइल का नाम मानती है जिसमें नईलाइन वर्ण नहीं है और स्टड पर पारित फ़ाइल पथ के साथ शुरू नहीं होता है -। आप इसके बजाय NUL सीमांकित सूची को स्वीकार करने के लिए संशोधित कर सकते हैंread -d ''
स्टीफन चेज़लस

ध्यान दें कि लिनक्स स्टेट जैसी कोई चीज नहीं है । लिनक्स कुछ जीएनयू और गैर-जीएनयू सिस्टम में पाया जाने वाला कर्नेल है। हालांकि, ऐसे कमांड (जैसे util-linux) हैं जो विशेष रूप से लिनक्स के लिए लिखे गए हैं, statआप जिसका उल्लेख नहीं कर रहे हैं, यह एक जीएनयू कमांड है जिसे लिनक्स के लिए ही नहीं, अधिकांश सिस्टम में पोर्ट किया गया है। यह भी ध्यान दें कि statGNU stat( statzsh बिल्डिन) लिखे जाने से बहुत पहले आपके पास लिनक्स पर एक कमांड थी ।
स्टीफन चेज़लस

2
@ स्टीफन चेज़लस: ध्यान दें कि लिनक्स स्टेट जैसी कोई चीज नहीं है। - मुझे विश्वास है कि मैंने "लिनक्स अवतार" लिखा था stat(1)। मैं कह रहा हूँ stat(1)कि एक -c <format>वाक्यविन्यास को स्वीकार करता है , जैसा कि, BSD वाक्यविन्यास के विपरीत कहा जाता है -f <format>। मेरा यह भी मानना ​​है कि यह स्पष्ट था कि मैं इसका जिक्र नहीं कर रहा था stat(2)। मुझे यकीन है कि सामान्य आदेशों के इतिहास के बारे में एक विकी पृष्ठ काफी दिलचस्प होगा।
lcd047

1
@ स्टीफन चेज़लस: यह कह सकता है कि एक फाइल लिखने योग्य है, भले ही उपयोगकर्ता को उस निर्देशिका तक पहुंच न हो, जहां वह है। - सच है, और शायद एक उचित सीमा। उस फ़ाइल के नाम में न्यूलाइन वर्ण नहीं है - यह सच है, और शायद एक उचित सीमा है। और स्टड पर पारित फ़ाइल पथ के साथ शुरू नहीं - - संपादित, धन्यवाद।
lcd047

17

टी एल; डॉ

find / ! -type l -print0 |
  sudo -u "$user" perl -Mfiletest=access -l -0ne 'print if -w'

आपको सिस्टम से पूछना होगा कि क्या उपयोगकर्ता ने अनुमति लिखी है। एकमात्र विश्वसनीय तरीका यह है कि उपयोगकर्ता के प्रभावी यूआईडी, प्रभावी gid और अनुपूरण ग्रिड को स्विच किया जाए और access(W_OK)सिस्टम कॉल (यहां तक ​​कि कुछ सिस्टम / कॉन्फ़िगरेशन पर कुछ सीमाएं) का उपयोग करें।

और ध्यान रखें कि किसी फाइल को लिखने की अनुमति नहीं होना जरूरी नहीं है कि आप उस पथ पर फ़ाइल की सामग्री को संशोधित नहीं कर सकते हैं।

लम्बी कहानी

आइए विचार करें कि एक $ उपयोगकर्ता के लिए लिखने के लिए क्या उपयोग होता है /foo/file.txt(कोई भी नहीं /fooऔर /foo/file.txtसहानुभूति नहीं है) तक पहुंच है ?

उसे जरुरत है:

  1. के लिए खोज का उपयोग /(कोई ज़रूरत नहीं read)
  2. के लिए खोज का उपयोग /foo(कोई ज़रूरत नहीं read)
  3. तक पहुँच लिखो/foo/file.txt

आप पहले से ही देख सकते हैं कि दृष्टिकोण (जैसे @ lcd047 के या @ apaul के ) इस बात का केवल अनुमति जाँच file.txtकाम नहीं करेगा क्योंकि वे कह सकते हैं file.txtलिखने योग्य है, भले ही उपयोगकर्ता के लिए खोज की अनुमति नहीं है /या /foo

और एक दृष्टिकोण जैसे:

sudo -u "$user" find / -writeble

या तो काम नहीं करेगा क्योंकि यह उन निर्देशिकाओं में फ़ाइलों की रिपोर्ट नहीं करेगा, जिन्हें उपयोगकर्ता ने पढ़ा नहीं है (जैसा findकि $userउनकी सामग्री को सूचीबद्ध नहीं किया जा सकता है) भले ही वह उन्हें लिख सकता है।

यदि हम ACLs, केवल-पढ़ने के लिए फ़ाइल सिस्टम, FS झंडे (जैसे अपरिवर्तनीय), अन्य सुरक्षा उपायों (apparmor, SELinux, जो विभिन्न प्रकार के लेखन में भी अंतर कर सकते हैं) के बारे में भूल जाते हैं और केवल पारंपरिक अनुमति और स्वामित्व विशेषताओं पर ध्यान केंद्रित करते हैं, तो दी गई (खोज या लिख) अनुमति, यह पहले से ही काफी जटिल है और इसके साथ व्यक्त करना कठिन है find

आप की जरूरत है:

  • यदि फ़ाइल आपके पास है, तो आपको स्वामी की अनुमति चाहिए (या uid 0 है)
  • यदि फ़ाइल आपके स्वामित्व में नहीं है, लेकिन समूह आपका एक है, तो आपको समूह के लिए उस अनुमति की आवश्यकता है (या आपके पास 0 है)।
  • यदि यह आपके स्वामित्व में नहीं है, और आपके किसी समूह में नहीं है, तो अन्य अनुमतियाँ लागू होती हैं (जब तक कि आपका यूआईडी 0 नहीं है)।

में findवाक्य रचना, यहाँ uid 1 और GIDs 1 और 2 के एक उपयोगकर्ता के साथ एक उदाहरण के रूप में, कि हो सकता है:

find / -type d \
  \( \
    -user 1 \( -perm -u=x -o -prune \) -o \
    \( -group 1 -o -group 2 \) \( -perm -g=x -o -prune \) -o \
    -perm -o=x -o -prune \
  \) -o -type l -o \
    -user 1 \( ! -perm -u=w -o -print \) -o \
    \( -group 1 -o -group 2 \) \( ! -perm -g=w -o -print \) -o \
    ! -perm -o=w -o -print

यह एक निर्देशिका है कि उपयोगकर्ता के लिए और फ़ाइलों के अन्य प्रकार के लिए खोज सही नहीं है prunes (symlinks के रूप में वे प्रासंगिक नहीं हैं), लिखने का उपयोग के लिए जाँच करता है।

यदि आप निर्देशिकाओं के लिए लेखन पहुँच पर विचार करना चाहते हैं:

find / -type d \
  \( \
    -user 1 \( -perm -u=x -o -prune \) -o \
    \( -group 1 -o -group 2 \) \( -perm -g=x -o -prune \) -o \
    -perm -o=x -o -prune \
  \) ! -type d -o -type l -o \
    -user 1 \( ! -perm -u=w -o -print \) -o \
    \( -group 1 -o -group 2 \) \( ! -perm -g=w -o -print \) -o \
    ! -perm -o=w -o -print

या $userउपयोगकर्ता डेटाबेस से प्राप्त एक मनमाना और उसके समूह की सदस्यता के लिए:

groups=$(id -G "$user" | sed 's/ / -o -group /g'); IFS=" "
find / -type d \
  \( \
    -user "$user" \( -perm -u=x -o -prune \) -o \
    \( -group $groups \) \( -perm -g=x -o -prune \) -o \
    -perm -o=x -o -prune \
  \) ! -type d -o -type l -o \
    -user "$user" \( ! -perm -u=w -o -print \) -o \
    \( -group $groups \) \( ! -perm -g=w -o -print \) -o \
    ! -perm -o=w -o -print

(है कि कुल में 3 प्रक्रियाओं है: id, sedऔर find)

यहां सबसे अच्छा होगा कि पेड़ को जड़ के रूप में उतारा जाए और प्रत्येक फाइल के लिए उपयोगकर्ता के रूप में अनुमतियों की जांच की जाए।

 find / ! -type l -exec sudo -u "$user" sh -c '
   for file do
     [ -w "$file" ] && printf "%s\n" "$file"
   done' sh {} +

(यह एक findप्रक्रिया प्लस एक है sudoऔर shहर कुछ हजार फाइलों को प्रोसेस करती है, [और printfआमतौर पर शेल में निर्मित होती है)।

या साथ perl:

find / ! -type l -print0 |
  sudo -u "$user" perl -Mfiletest=access -l -0ne 'print if -w'

(कुल 3 की प्रक्रिया: find, sudoऔर perl)।

या साथ zsh:

files=(/**/*(D^@))
USERNAME=$user
for f ($files) {
  [ -w $f ] && print -r -- $f
}

(कुल में प्रक्रिया, लेकिन मेमोरी में पूरी फ़ाइल सूची संग्रहीत करता है)

वे समाधान access(2)सिस्टम कॉल पर निर्भर करते हैं। एक्सेस सिस्टम को एक्सेस की अनुमति के लिए जांचने के लिए सिस्टम एल्गोरिदम को पुन: प्रस्तुत करने के बजाय, हम सिस्टम को उसी एल्गोरिदम (जो खाता अनुमति, एसीएल, अपरिवर्तनीय झंडे, रीड-ओनली फाइल सिस्टम ...) के साथ जांच करने के लिए कह रहा है। ) इसका उपयोग आप लेखन के लिए फ़ाइल खोलने का प्रयास करेंगे, इसलिए आप एक विश्वसनीय समाधान प्राप्त करने के लिए निकटतम हैं।

यहां दिए गए समाधानों का परीक्षण करने के लिए, उपयोगकर्ता, समूह और अनुमतियों के विभिन्न संयोजनों के साथ, आप कर सकते हैं:

perl -e '
  for $u (1,2) {
    for $g (1,2,3) {
      $d1="u${u}g$g"; mkdir$d1;
      for $m (0..511) {
        $d2=$d1.sprintf"/%03o",$m; mkdir $d2; chown $u, $g, $d2; chmod $m,$d2;
        for $uu (1,2) {
          for $gg (1,2,3) {
            $d3="$d2/u${uu}g$gg"; mkdir $d3;
            for $mm (0..511) {
              $f=$d3.sprintf"/%03o",$mm;
              open F, ">","$f"; close F;
              chown $uu, $gg, $f; chmod $mm, $f
            }
          }
        }
      }
    }
  }'

उपयोगकर्ता 1 और 2 और समूह betweem 1, 2, और 3 के बीच भिन्नता है और अनुमतियों के निचले 9 बिट्स तक खुद को सीमित कर रहा है क्योंकि यह पहले से ही 9458694 फाइलें बनाई गई है। निर्देशिका के लिए और फिर फ़ाइलों के लिए फिर से।

कि सभी संभव संयोजन बनाता है u<x>g<y>/<mode1>/u<z>g<w>/<mode2>। यूआईडी 1 और 2 और 2 यूआईडी वाले उपयोगकर्ता के पास पहुंच के लिए लेखन होगा, u2g1/010/u2g3/777लेकिन u1g2/677/u1g1/777उदाहरण के लिए नहीं ।

अब, वे सभी समाधान उन फ़ाइलों के रास्तों की पहचान करने का प्रयास करते हैं जो उपयोगकर्ता लिखने के लिए खोल सकता है, यह उन रास्तों से अलग है जहाँ उपयोगकर्ता सामग्री को संशोधित करने में सक्षम हो सकता है। उस अधिक सामान्य प्रश्न का उत्तर देने के लिए, कई बातों का ध्यान रखना चाहिए:

  1. $ उपयोगकर्ता के पास लिखने की पहुंच नहीं हो सकती है, /a/b/fileलेकिन यदि वह मालिक है file(और उसके पास खोज एक्सेस है /a/b, और फ़ाइल सिस्टम केवल-पढ़ने के लिए नहीं है, और फ़ाइल में अपरिवर्तनीय ध्वज नहीं है, और उसे सिस्टम में शेल एक्सेस मिल गई है) तब वह fileस्वयं की पहुंच को बदलने और अनुदान की अनुमति देने में सक्षम होगा ।
  2. एक ही बात अगर वह मालिक है, /a/bलेकिन इसके लिए खोज का उपयोग नहीं है।
  3. $ उपयोगकर्ता के पास पहुंच नहीं हो सकती है /a/b/fileक्योंकि उसके पास खोज एक्सेस नहीं है /aया नहीं /a/b, लेकिन उस फ़ाइल में /b/c/fileउदाहरण के लिए एक कठिन लिंक हो सकता है , जिस स्थिति में वह /a/b/fileअपने /b/c/fileपथ के माध्यम से इसे खोलकर सामग्री को संशोधित करने में सक्षम हो सकता है।
  4. बाइंड-माउंट्स के साथ एक ही बात । उसके पास खोज तक पहुँच नहीं हो सकती है /a, लेकिन /a/bइसमें बाइंड-माउंटेड हो सकता है /c, इसलिए वह fileइसके /c/fileदूसरे रास्ते से लिखने के लिए खोल सकता है।
  5. उसके पास लिखने की अनुमति नहीं हो सकती है /a/b/file, लेकिन अगर उसके पास लिखने की पहुंच है, तो वह वहां से /a/bहटा सकता है या नाम बदल fileसकता है और इसे अपने स्वयं के संस्करण के साथ बदल सकता है। वह फ़ाइल की सामग्री को बदल देगा /a/b/fileभले ही वह एक अलग फ़ाइल होगी।
  6. एक ही बात अगर उसे लिखने की सुविधा मिल गई है /a(वह नाम बदल सकता /a/bहै /a/c, एक नई /a/bनिर्देशिका बना सकता है और fileउसमें एक नया भी बना सकता है।

उन मार्गों को खोजने के लिए जो $userसंशोधित करने में सक्षम होंगे। 1 या 2 को संबोधित करने के लिए, हम access(2)अब सिस्टम कॉल पर भरोसा नहीं कर सकते । find -permजैसे ही आप मालिक होते हैं, हम निर्देशिकाओं तक खोज पहुंच को संभालने या फ़ाइलों तक पहुंच लिखने के लिए अपने दृष्टिकोण को समायोजित कर सकते हैं:

groups=$(id -G "$user" | sed 's/ / -o -group /g'); IFS=" "
find / -type d \
  \( \
    -user "$user" -o \
    \( -group $groups \) \( -perm -g=x -o -prune \) -o \
    -perm -o=x -o -prune \
  \) ! -type d -o -type l -o \
    -user "$user" -print -o \
    \( -group $groups \) \( ! -perm -g=w -o -print \) -o \
    ! -perm -o=w -o -print

हम डिवाइस और इनोड नंबरों को रिकॉर्ड करके 3 और 4 को संबोधित कर सकते हैं या सभी फाइल $ उपयोगकर्ता ने उन सभी फ़ाइल रास्तों की अनुमति देने और रिपोर्ट करने की अनुमति दी है जिनके पास देव + इनोड नंबर हैं। इस बार, हम अधिक विश्वसनीय- access(2)आधारित दृष्टिकोण का उपयोग कर सकते हैं :

कुछ इस तरह:

find / ! -type l -print0 |
  sudo -u "$user" perl -Mfiletest=access -0lne 'print 0+-w,$_' |
  perl -l -0ne '
    ($w,$p) = /(.)(.*)/;
    ($dev,$ino) = stat$p or next;
    $writable{"$dev,$ino"} = 1 if $w;
    push @{$p{"$dev,$ino"}}, $p;
    END {
      for $i (keys %writable) {
        for $p (@{$p{$i}}) {
          print $p;
        }
      }
    }'

5 और 6 पहली नज़र tमें अनुमति के बिट द्वारा जटिल हैं । जब निर्देशिकाओं पर लागू किया जाता है, तो यह प्रतिबंधित विलोपन बिट होता है, जो उपयोगकर्ताओं (निर्देशिका के मालिक की तुलना में अन्य) को उन फ़ाइलों को हटाने या उनका नाम बदलने से रोकता है, जो उनके पास नहीं हैं (भले ही उनके पास निर्देशिका तक पहुंच हो)।

उदाहरण के लिए, अगर हम वापस हमारे पिछले उदाहरण पर जाते हैं, आप के लिए लेखन पहुँच है /a, तो आप का नाम बदलने के लिए सक्षम होना चाहिए /a/bकरने के लिए /a/c, और फिर एक को पुन: /a/bऔर निर्देशिका एक नया fileवहाँ में। लेकिन अगर tबिट सेट है /aऔर आप स्वयं नहीं हैं /a, तो आप इसे केवल तभी कर सकते हैं जब आप स्वयं के हों /a/b। देता है कि:

  • यदि आपके पास एक निर्देशिका है, तो 1 के अनुसार, आप अपने आप को लिखने का उपयोग करने के लिए अनुदान दे सकते हैं, और टी बिट लागू नहीं होता है (और आप इसे किसी भी तरह से हटा सकते हैं), इसलिए आप किसी भी फ़ाइल को हटा सकते हैं / नाम बदल सकते हैं या वहां डायर कर सकते हैं, इसलिए किसी भी सामग्री के साथ फिर से लिखने के लिए सभी फ़ाइल पथ आपके हैं।
  • यदि आपके पास यह नहीं है, लेकिन आपके पास लिखित पहुंच है, तो:
    • या तो tबिट सेट नहीं है, और आप ऊपर के समान मामले में हैं (सभी फ़ाइल पथ आपके हैं)।
    • या यह सेट है और फिर आप उन फ़ाइलों को संशोधित नहीं कर सकते हैं जिनके पास आप नहीं हैं या जिनके पास लिखने की पहुंच नहीं है, इसलिए आपके द्वारा संशोधित किए जा सकने वाले फ़ाइल पथों को खोजने के हमारे उद्देश्य के लिए, यह बिल्कुल भी अनुमति नहीं है।

इसलिए हम 1, 2, 5 और 6 सभी को संबोधित कर सकते हैं:

find / -type d \
  \( \
    -user "$user" -prune -exec find {} + -o \
    \( -group $groups \) \( -perm -g=x -o -prune \) -o \
    -perm -o=x -o -prune \
  \) ! -type d -o -type l -o \
    -user "$user" \( -type d -o -print \) -o \
    \( -group $groups \) \( ! -perm -g=w -o \
       -type d ! -perm -1000 -exec find {} + -o -print \) -o \
    ! -perm -o=w -o \
    -type d ! -perm -1000 -exec find {} + -o \
    -print

वह और 3 और 4 के लिए समाधान स्वतंत्र हैं, आप पूरी सूची प्राप्त करने के लिए उनके आउटपुट को मर्ज कर सकते हैं:

{
  find / ! -type l -print0 |
    sudo -u "$user" perl -Mfiletest=access -0lne 'print 0+-w,$_' |
    perl -0lne '
      ($w,$p) = /(.)(.*)/;
      ($dev,$ino) = stat$p or next;
      $writable{"$dev,$ino"} = 1 if $w;
      push @{$p{"$dev,$ino"}}, $p;
      END {
        for $i (keys %writable) {
          for $p (@{$p{$i}}) {
            print $p;
          }
        }
      }'
  find / -type d \
    \( \
      -user "$user" -prune -exec sh -c 'exec find "$@" -print0' sh {} + -o \
      \( -group $groups \) \( -perm -g=x -o -prune \) -o \
      -perm -o=x -o -prune \
    \) ! -type d -o -type l -o \
      -user "$user" \( -type d -o -print0 \) -o \
      \( -group $groups \) \( ! -perm -g=w -o \
         -type d ! -perm -1000 -exec sh -c 'exec find "$@" -print0' sh {} + -o -print0 \) -o \
      ! -perm -o=w -o \
      -type d ! -perm -1000 -exec sh -c 'exec find "$@" -print0' sh {} + -o \
      -print0
} | perl -l -0ne 'print unless $seen{$_}++'

जैसा कि आपने अभी तक सब कुछ पढ़ा है, यह स्पष्ट होना चाहिए, इसका हिस्सा कम से कम केवल अनुमतियों और स्वामित्व से संबंधित है, न कि अन्य सुविधाएँ जो लिखने की पहुँच प्रदान कर सकती हैं या प्रतिबंधित कर सकती हैं (केवल पढ़ने के लिए FS, ACLs, अपरिवर्तनीय ध्वज, अन्य सुरक्षा सुविधाएँ ...)। और जैसा कि हम इसे कई चरणों में संसाधित करते हैं, उस जानकारी में से कुछ गलत हो सकती हैं यदि फ़ाइलें / निर्देशिकाएं बनाई जा रही हैं / हटा दी गई हैं / नाम बदला गया है या उनकी अनुमतियाँ / स्वामित्व संशोधित है, जबकि स्क्रिप्ट चल रही है, जैसे लाखों फ़ाइलों के साथ एक व्यस्त फ़ाइल सर्वर पर। ।

पोर्टेबिलिटी नोट

tसिवाय इसके कि सभी कोड मानक है (POSIX, Unix for bit):

  • -print0GNU एक्सटेंशन अब कुछ अन्य कार्यान्वयनों द्वारा भी समर्थित है। उन findकार्यान्वयनों के साथ जिनमें इसके लिए समर्थन की कमी है, आप -exec printf '%s\0' {} +इसके बजाय उपयोग कर सकते हैं , और इसके -exec sh -c 'exec find "$@" -print0' sh {} +साथ बदल सकते हैं -exec sh -c 'exec find "$@" -exec printf "%s\0" {\} +' sh {} +
  • perlPOSIX- निर्दिष्ट कमांड नहीं है, लेकिन व्यापक रूप से उपलब्ध है। आप के perl-5.6.0लिए या ऊपर की जरूरत है -Mfiletest=access
  • zshPOSIX- निर्दिष्ट कमांड नहीं है। यही कारण है कि zshकोड ऊपर zsh -3 (1995) और इसके बाद के संस्करण के साथ काम करना चाहिए।
  • sudoPOSIX- निर्दिष्ट कमांड नहीं है। कोड किसी भी संस्करण के साथ काम करना चाहिए जब तक कि सिस्टम कॉन्फ़िगरेशन perlदिए गए उपयोगकर्ता के रूप में चलने की अनुमति देता है ।

खोज एक्सेस क्या है ? मैंने इसे पारंपरिक अनुमतियों में कभी नहीं सुना है: पढ़ना, लिखना, निष्पादित करना।
bela83

2
@ bela83, निर्देशिका पर अनुमति निष्पादित करें (आप निर्देशिकाओं को निष्पादित नहीं करते हैं) खोज करने के लिए अनुवाद करता है । यह उस में फ़ाइलों तक पहुँचने की क्षमता है। यदि आपने अनुमति पढ़ी है, तो आप किसी निर्देशिका की सामग्री को सूचीबद्ध कर सकते हैं, लेकिन जब तक आप xनिर्देशिका पर खोज ( बिट) की अनुमति नहीं देते तब तक आप इसमें फ़ाइलों के साथ कुछ नहीं कर सकते । आपके पास खोज अनुमतियाँ भी हो सकती हैं , लेकिन नहीं पढ़ी जा सकती हैं , जिसका अर्थ है कि वहां फ़ाइलें आपके पास छिपी हुई हैं, लेकिन यदि आप उनका नाम जानते हैं, तो आप उन्हें एक्सेस कर सकते हैं। एक विशिष्ट उदाहरण php सत्र फ़ाइल निर्देशिका (कुछ इस तरह / var / lib / php) है।
स्टीफन चेज़लस

2

आप findकमांड के साथ विकल्पों को जोड़ सकते हैं , इसलिए यह निर्दिष्ट मोड और मालिक के साथ फाइलों का पता लगाएगा। उदाहरण के लिए:

$ find / \( -group staff -o -group users \) -and -perm -g+w

उपरोक्त कमांड उन सभी प्रविष्टियों को सूचीबद्ध करेगा जो समूह "स्टाफ" या "उपयोगकर्ता" से संबंधित हैं और उस समूह के लिए अनुमति लिखते हैं।

आपको उन प्रविष्टियों की भी जांच करनी चाहिए जो आपके उपयोगकर्ता के स्वामित्व में हैं, और फाइलें जो विश्व के लिए उपयुक्त हैं, इसलिए:

$ find / \( -user yourusername -or \
             \(  \( -group staff -o -group users \) -and -perm -g+w \
             \) -or \
            -perm -o+w \
         \)

हालाँकि, यह आदेश विस्तारित ACL के साथ प्रविष्टियों से मेल नहीं खाएगा। तो आप suसभी योग्य प्रविष्टियों का पता लगा सकते हैं:

# su - yourusername
$ find / -writable

यह कहेंगे कि एक फ़ाइल के साथ r-xrwxrwx yourusername:anygroupया r-xr-xrwx anyone:staffलेखन योग्य है।
स्टीफन चेज़लस

यह लेखन योग्य फ़ाइलों के रूप में भी रिपोर्ट करेगा जो निर्देशिकाओं yourusernameमें हैं जिनके पास पहुंच नहीं है।
स्टीफन चेज़लस

1

दृष्टिकोण इस बात पर निर्भर करता है कि आप वास्तव में क्या परीक्षण कर रहे हैं।

  1. क्या आप सुनिश्चित करना चाहते हैं कि लेखन पहुंच संभव है?
  2. क्या आप लेखन पहुंच की कमी सुनिश्चित करना चाहते हैं ?

इसका कारण यह है कि 2 पर पहुंचने के बहुत सारे तरीके हैं) और स्टीफन का जवाब इन अच्छी तरह से शामिल है (अपरिवर्तनीय एक को याद रखना है), और याद रखें कि भौतिक साधन भी हैं, जैसे ड्राइव को अनमाउंट करना या इसे केवल पढ़ने के लिए बनाना हार्डवेयर स्तर (फ्लॉपी टैब)। मुझे लगता है कि आपकी हजारों फाइलें अलग-अलग निर्देशिकाओं में हैं और आप एक रिपोर्ट चाहते हैं या आप एक मास्टर सूची के खिलाफ जांच कर रहे हैं। (कठपुतली का एक और दुरुपयोग बस होने की प्रतीक्षा कर रहा है)।

आप संभवतः स्टीफन के पर्ल ट्री-ट्रैवर्सल चाहते हैं और यदि आवश्यक हो (सु भी माता-पिता निर्देशिका पर लापता निष्पादन को पकड़ लेंगे?) के साथ आउटपुट को "जॉइन" करने के लिए। यदि सरोगेसी एक प्रदर्शन समस्या है तो क्या आप उपयोगकर्ताओं की "बड़ी संख्या" के लिए ऐसा कर रहे हैं? या यह एक ऑनलाइन क्वेरी है? यदि यह एक स्थायी चल रही आवश्यकता है, तो तीसरे पक्ष के उत्पाद पर विचार करने का समय हो सकता है।


0

तुम कर सकते हो...

find / ! -type d -exec tee -a {} + </dev/null

... उन सभी फ़ाइलों की सूची के लिए, जिन्हें उपयोगकर्ता नहीं कर सकता प्रपत्र में stderr को लिखा जा सकता है ...

"tee: cannot access %s\n", <pathname>" 

...या इसी के समान।

इस दृष्टिकोण के मुद्दों पर नोट्स के लिए नीचे टिप्पणी देखें, और यह काम क्यों कर सकता है, इसके लिए नीचे की व्याख्या। अधिक पवित्र, हालांकि, आपको संभवतः केवल find नियमित फ़ाइलें पसंद करनी चाहिए :

find / -type f -exec tee -a {} + </dev/null

संक्षेप में, teeत्रुटियों को प्रिंट करेगा जब यह करने का प्रयास करता हैopen() दोनों में से किसी एक झंडे के साथ फाइल ...

O_WRONLY

केवल लिखने के लिए खोलें।

O_RDWR

पढ़ने और लिखने के लिए खुला। यदि यह ध्वज FIFO पर लागू होता है, तो परिणाम अपरिभाषित है।

... और सामना ...

[EACCES]

पथ उपसर्ग के एक घटक पर खोज अनुमति से इनकार किया जाता है, या फ़ाइल मौजूद है और टोलग द्वारा निर्दिष्ट अनुमतियों से इनकार किया जाता है, या फ़ाइल मौजूद नहीं है और लिखने की अनुमति फ़ाइल के मूल निर्देशिका, या O_TRUNC के लिए अस्वीकृत है। निर्दिष्ट और लिखित अनुमति से वंचित है।

... यहाँ निर्दिष्ट है :

teeउपयोगिता मानक आउटपुट में मानक इनपुट नकल करेगा, शून्य या अधिक फ़ाइलों में एक प्रतिलिपि बनाकर। टी यूटिलिटी बफर आउटपुट नहीं देगी।

यदि -aविकल्प निर्दिष्ट नहीं है, तो आउटपुट फाइलें लिखी जाएंगी (देखें फाइल पढ़ें, लिखें और निर्माण करें ...)

... POSIX.1-2008 उपयोग करने के लिए कार्यक्षमता बराबर की आवश्यकता है O_APPEND ...

क्योंकि यह उसी तरह की जाँच test -wकरता है ...

-w पथ नाम

यदि फ़ाइल के लिए मौजूदा निर्देशिका प्रविष्टि के लिए pathname एक मौजूदा निर्देशिका प्रविष्टि को हल करता है तो सही है , जिसके लिए फ़ाइल को लिखने की अनुमति दी जाएगी, जैसा कि फ़ाइल रीड, राइट और निर्माण में परिभाषित किया गया है । यदि पथनाम हल नहीं किया जा सकता है, तो गलत है , या यदि पथनाम फ़ाइल के लिए मौजूदा निर्देशिका प्रविष्टि का समाधान करता है, जिसके लिए फ़ाइल को लिखने की अनुमति नहीं दी जाएगी।

वे दोनों EACCESS की जाँच करते हैं ।


आपको उस दृष्टिकोण के साथ समवर्ती रूप से खुली फ़ाइलों की संख्या की सीमा में चलने की संभावना है (जब तक कि फ़ाइलों की संख्या कम न हो)। उपकरणों और नामित पाइपों के साथ दुष्प्रभावों से सावधान रहें। आपको सॉकेट्स के लिए एक अलग त्रुटि संदेश मिलेगा।
स्टीफन चेजलस

@ स्टीफनचेज़लस - सभी क्यू - मुझे लगता है कि यह भी सच हो सकता है जो teeतब तक लटका रहेगा जब तक कि प्रति रन एक बार स्पष्ट रूप से बाधित न हो। यह सबसे करीबी चीज थी, जिसके बारे में मैं सोच सकता था [ -w... हालांकि - यह प्रभाव इसके करीब होना चाहिए कि यह गारंटी देता है कि उपयोगकर्ता फ़ाइल को OAPPEND कर सकता है। बहुत आसान की तुलना में या तो विकल्प होगा paxसाथ -oऔर / या प्रारूप विकल्पों -tके खिलाफ जाँच के लिए EACCESS- लेकिन हर बार मैं सुझाव paxलोग इसे हिलाना बंद करने लगते हैं। और, वैसे भी, केवल paxमैंने पाया है कि एसटीडी मिलता है एएसटीएस - जिस स्थिति में आप उनका उपयोग कर सकते हैं ls
माइकस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.