নূন্যতম প্রক্রিয়া তৈরির সাথে দক্ষতার সাথে ব্যবহারকারী লিখতে পারেন এমন ফাইলগুলি সন্ধান করুন


20

আমি মূল। আমি জানতে চাইছি যে কোনও রুটবিহীন ব্যবহারকারীর কিছু ফাইল - এর মধ্যে কয়েক হাজারের লেখার অ্যাক্সেস রয়েছে। প্রক্রিয়া সৃষ্টি এড়ানো চলাকালীন কীভাবে এটি কার্যকরভাবে করবেন?


আপনি আসলে কি দয়া করে আমাদের দেখান!
এফ। হাউরি


ধরে নিচ্ছি যে আপনি জাতি অবস্থার বিষয়ে যত্নবান নন, কেন কেবলমাত্র access(2)একটি যথাযথ সেট রিয়েল-ইউআইডি (যেমন মাধ্যমে setresuid(2)বা বহনযোগ্য সমতুল্য) দিয়ে কল করবেন না? আমার অর্থ, বাশ থেকে আমি এটি করতে কঠোর চাপ দিয়েছি, তবে আমি নিশ্চিত পার্ল / পাইথন এটি পরিচালনা করতে পারে।
কেভিন

1
@ কেভিন, শেলগুলি [ -wসাধারণত অ্যাক্সেস (2) বা সমমানের ব্যবহার করে। আপনাকে ইউআইডি ছাড়াও গিডগুলি সেট করতে হবে (সু বা সুডো হিসাবে)। বাশ এর জন্য অন্তর্নির্মিত সমর্থন করে না তবে zsh করে।
স্টাফেন চেজেলাস 21

@ স্টাফেনচেজেলাস - আপনি যে chgrpকোনও শেল ব্যবহার করতে পারেন ।
মাইকজার্ভ

উত্তর:


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আপনি উল্লেখ করছেন না এটি একটি জিএনইউ কমান্ড যা কেবলমাত্র লিনাক্স নয়, বেশিরভাগ সিস্টেমে পোর্ট করা হয়েছে। আরও লক্ষ করুন যে statজিএনইউ statলেখার অনেক আগে আপনার লিনাক্সে কমান্ড ছিল ( statzsh বিল্টিন)।
স্টাফেন চেজেলাস

2
@ স্টাফেন চেজেলাস: নোট করুন যে লিনাক্স স্ট্যাটাসের মতো কোনও জিনিস নেই। - আমি বিশ্বাস করি যে আমি "লিনাক্স অবতার" লিখেছি stat(1)। আমি stat(1)এমন একটিকে উল্লেখ করছি যা -c <format>বিএসডি সিনট্যাক্সের বিপরীতে সিনট্যাক্স গ্রহণ করে -f <format>। আমি এটিও বিশ্বাস করি এটি বেশ পরিষ্কার ছিল যে আমি উল্লেখ করছি না stat(2)। আমি নিশ্চিত যে সাধারণ কমান্ডগুলির ইতিহাস সম্পর্কে একটি উইকি পৃষ্ঠা যদিও আকর্ষণীয় হবে।
lcd047

1
@ স্টাফেন শেজেলাস: এটি বলতে পারে যে কোনও ফাইল যেখানে এটির ডিরেক্টরিতে অ্যাক্সেস না থাকা সত্ত্বেও কোনও ফাইল লিখনযোগ্য। - সত্য, এবং সম্ভবত একটি যুক্তিসঙ্গত সীমাবদ্ধতা। এটি ধরে নিয়েছে যে ফাইলের নামগুলিতে নতুন লাইন অক্ষর নেই - সত্য এবং সম্ভবত যুক্তিসঙ্গত সীমাবদ্ধতা। এবং স্টিডিনে পাস করা ফাইল পাথগুলি শুরু হয় না - - সম্পাদিত, আপনাকে ধন্যবাদ।
lcd047

17

টি এল; ডিআর

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

ব্যবহারকারীর লেখার অনুমতি আছে কিনা তা আপনাকে সিস্টেমটি জিজ্ঞাসা করতে হবে। একমাত্র নির্ভরযোগ্য উপায় হ'ল কার্যকর ইউড, কার্যকর গিড এবং পরিপূরক গিডগুলি ব্যবহারকারীর তুলনায় স্যুইচ করা এবং access(W_OK)সিস্টেম কল ব্যবহার করা (এমনকি এতে কিছু সিস্টেম / কনফিগারেশনের কিছু সীমাবদ্ধতা রয়েছে)।

এবং মনে রাখবেন যে কোনও ফাইলে লেখার অনুমতি না থাকা নিশ্চিতভাবে গ্যারান্টি দেয় না যে আপনি সেই পথে ফাইলের সামগ্রীটি পরিবর্তন করতে পারবেন না।

দীর্ঘ গল্প

আসুন বিবেচনা করা যাক কোনও $ ব্যবহারকারীর লেখার অ্যাক্সেসের জন্য উদাহরণটির জন্য কী লাগে /foo/file.txt(ধরে নেই /fooএবং /foo/file.txtএর কোনও চিহ্ন নেই )?

তার দরকার:

  1. অ্যাক্সেস অনুসন্ধান/ (প্রয়োজন নেই read)
  2. অ্যাক্সেস অনুসন্ধান/foo (প্রয়োজন নেই read)
  3. প্রবেশাধিকার লিখুন/foo/file.txt

আপনি ইতিমধ্যে দেখতে পেলেন যে পদ্ধতিগুলি ( @ lcd047's বা @ apaul এর ) যা কেবলমাত্র অনুমতি ব্যবহার করে file.txtনা তা কাজ করে না কারণ তারা বলতে পারে যে file.txtলিখিতযোগ্য এমনকি যদি ব্যবহারকারীটির কাছে অনুসন্ধানের অনুমতি না থাকে /বা না থাকে /foo

এবং মত একটি পদ্ধতির:

sudo -u "$user" find / -writeble

হয় কাজ করবে না কারণ এটি যে ডিরেক্টরিগুলিতে ফাইল পড়তে পারে না সেগুলি ফাইলগুলিতে প্রতিবেদন করবে না (যদিও তাদের সামগ্রী লিখিত থাকতে পারে না findচলমান $user) এমনকি যদি সে তাদের কাছে লিখতে পারে।

যদি আমরা এসিএল, কেবল পঠনযোগ্য ফাইল সিস্টেম, এফএস পতাকা (অপরিবর্তনীয়), অন্যান্য সুরক্ষা ব্যবস্থা (অ্যাপারমোর, সেলইনাক্স, যা বিভিন্ন ধরণের লেখার মধ্যে পার্থক্য করতে পারে) এবং কেবলমাত্র চিরাচরিত অনুমতি এবং মালিকানার বৈশিষ্ট্যগুলিতে ফোকাস করে, প্রদত্ত (অনুসন্ধান বা লেখার) অনুমতি, এটি ইতিমধ্যে বেশ জটিল এবং এর সাথে প্রকাশ করা শক্ত find

তোমার দরকার:

  • যদি ফাইলটি আপনার মালিকানাধীন থাকে তবে আপনার মালিকের জন্য সেই অনুমতি প্রয়োজন (বা আপনার ইউড 0 আছে)
  • যদি ফাইলটি আপনার মালিকানাধীন না থাকে তবে গোষ্ঠীটি আপনার একটির হয়ে থাকে তবে আপনার গোষ্ঠীর (বা uid 0 আছে) অনুমতি প্রয়োজন।
  • যদি এটি আপনার মালিকানাধীন না হয় এবং আপনার কোনও গ্রুপে না থাকে তবে অন্যান্য অনুমতিগুলি প্রয়োগ হয় (যদি না আপনার ইউইড 0 হয়)।

ইন findসিনট্যাক্স, এখানে ইউআইডি 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

এক যে আলুবোখারা ডিরেক্টরি যে ব্যবহারকারীর জন্য এবং অন্যান্য (যেমন তারা প্রাসঙ্গিক নও বাদ 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
}

(মোট 0 টি প্রক্রিয়া, তবে পুরো ফাইল তালিকাকে মেমরিতে সংরক্ষণ করে)

এই সমাধানগুলি 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 এবং গ্রুপ বেটউইম 1, 2 এবং 3 এর মধ্যে ব্যবহারকারীকে পৃথক করা এবং ইতিমধ্যে 9458694 ফাইল তৈরি হওয়া হিসাবে নিজেকে নীচের 9 বিটের মধ্যে সীমাবদ্ধ করা উচিত। এটি ডিরেক্টরিগুলির জন্য এবং তারপরে আবার ফাইলগুলির জন্য।

এটি এর সম্ভাব্য সমস্ত সমন্বয় তৈরি করে u<x>g<y>/<mode1>/u<z>g<w>/<mode2>। Uid 1 এবং 1 এবং 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 ঠিকানাটি চিহ্নিত করতে পারি dev ব্যবহারকারীর কাছে সেই সমস্ত ডিভাইস + ইনোড নম্বর রয়েছে এমন সমস্ত ফাইল পাথের লিখন এবং প্রতিবেদন করার অনুমতি রয়েছে। এবার, আমরা আরও নির্ভরযোগ্য 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{$_}++'

আপনি যদি এতদূর পর্যন্ত সমস্ত কিছু পড়ে থাকেন তবে এটি স্পষ্ট হওয়া উচিত, এর অংশটি কমপক্ষে কেবল অনুমতি এবং মালিকানা নিয়ে কাজ করে, অন্য বৈশিষ্ট্যগুলি যা লেখার অ্যাক্সেসকে মঞ্জুর বা সীমাবদ্ধ করতে পারে না (কেবলমাত্র পঠনযোগ্য এফএস, এসিএলস, পরিবর্তনীয় পতাকা, অন্যান্য সুরক্ষা বৈশিষ্ট্য) ...)। এবং আমরা যখন এটি বেশ কয়েকটি পর্যায়ে প্রক্রিয়া করি, তখন ফাইলগুলি / ডিরেক্টরিগুলি তৈরি করা / মুছে ফেলা / পুনরায় নামকরণ করা হয় বা সেই স্ক্রিপ্টটি চলাকালীন তাদের অনুমতি / মালিকানা পরিবর্তিত হয়, যেমন কয়েক মিলিয়ন ফাইল সহ ব্যস্ত ফাইল সার্ভারে ।

বহনযোগ্যতা নোট

এই সমস্ত কোড মানক (POSIX, tবিটের জন্য ইউনিক্স ) ব্যতীত:

  • -print0GNU এক্সটেনশন এখন অন্যান্য কয়েকটি বাস্তবায়ন দ্বারা সমর্থিত। সঙ্গে findবাস্তবায়নের এটি জন্য সমর্থন অভাব, আপনি ব্যবহার করতে পারেন -exec printf '%s\0' {} +পরিবর্তে, এবং প্রতিস্থাপন -exec sh -c 'exec find "$@" -print0' sh {} +সঙ্গে -exec sh -c 'exec find "$@" -exec printf "%s\0" {\} +' sh {} +
  • perlকোনও পসিক্স-নির্দিষ্ট কমান্ড নয় তবে এটি ব্যাপকভাবে উপলব্ধ। আপনার প্রয়োজন perl-5.6.0বা উপরে প্রয়োজন -Mfiletest=access
  • zshকোনও পসিক্স-নির্দিষ্ট কমান্ড নয়। zshউপরের এই কোডটি zsh-3 (1995) এবং তারপরের উপরে কাজ করা উচিত।
  • sudoকোনও পসিক্স-নির্দিষ্ট কমান্ড নয়। যতক্ষণ না সিস্টেম কনফিগারেশন perlপ্রদত্ত ব্যবহারকারীর হিসাবে চলতে দেয় ততক্ষণ কোডটি কোনও সংস্করণের সাথে কাজ করা উচিত ।

একটি অনুসন্ধান অ্যাক্সেস কি? আমি এটি সনাতন অনুমতিতে কখনও শুনিনি: পড়ুন, লিখুন, কার্যকর করুন।
বেলা 83

2
@ বেলা 83, কোনও ডিরেক্টরিতে অনুমতি কার্যকর করুন (আপনি ডিরেক্টরিগুলি চালাবেন না) অনুসন্ধানে অনুবাদ করে । এটি এতে ফাইল অ্যাক্সেস করার ক্ষমতা। আপনি যদি পড়ার অনুমতি পেয়ে থাকেন তবে আপনি ডিরেক্টরিটির সামগ্রী তালিকাভুক্ত করতে পারেন, তবে xডিরেক্টরিতে অনুসন্ধান ( বিট) অনুমতি না থাকলে আপনি এতে থাকা ফাইলগুলি দিয়ে কিছুই করতে পারবেন না । আপনার কাছে অনুসন্ধানের অনুমতি থাকতে পারে তবে পড়তে পারেন না , অর্থাত সেখানে থাকা ফাইলগুলি আপনার কাছে লুকিয়ে রয়েছে তবে আপনি যদি তাদের নামটি জানেন তবে আপনি সেগুলি অ্যাক্সেস করতে পারবেন। একটি সাধারণ উদাহরণ হ'ল পিএইচপি সেশন ফাইল ডিরেক্টরি (/ 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 \
         \)

তবে এই কমান্ডটি প্রসারিত এসিএলের সাথে প্রবেশের সাথে মেলে না। সুতরাং আপনি suসমস্ত লিখনযোগ্য এন্ট্রিগুলি খুঁজে পেতে পারেন:

# su - yourusername
$ find / -writable

এটি বলবে যে ফাইল সহ r-xrwxrwx yourusername:anygroupবা r-xr-xrwx anyone:staffলিখনযোগ্য able
স্টাফেন চেজেলাস

এটি ডিরেক্টরিতে লেখা লিখিত ফাইলগুলির yourusernameঅ্যাক্সেস নেই বলেও প্রতিবেদন করবে ।
স্টাফেন চেজেলাস

1

আপনি যা যা পরীক্ষা করছেন তার উপর দৃষ্টিভঙ্গি নির্ভর করে।

  1. আপনি কি নিশ্চিত করতে চান যে লেখার অ্যাক্সেস সম্ভব?
  2. আপনি কি লেখার অ্যাক্সেসের অভাব নিশ্চিত করতে চান ?

এটি এ কারণেই ২ এ পৌঁছানোর অনেকগুলি উপায় রয়েছে) এবং স্টাফেনের উত্তরগুলি এইগুলি ভালভাবে আবরণ করে (অপরিবর্তনীয় এক এটি মনে রাখা যায়), এবং মনে রাখবেন যে শারীরিক উপায়গুলিও রয়েছে যেমন ড্রাইভটি আনমাউন্ট করা বা এটি কেবলমাত্র পড়ার জন্য তৈরি করা হার্ডওয়্যার স্তর (ফ্লপি ট্যাব)। আমি অনুমান করছি যে আপনার হাজার হাজার ফাইলগুলি ভিন্ন ভিন্ন ডিরেক্টরিতে রয়েছে এবং আপনি একটি প্রতিবেদন চান বা আপনি একটি মাস্টার তালিকার বিপরীতে যাচ্ছেন। (পুতুলের আর একটি অপব্যবহার সবেমাত্র ঘটতে অপেক্ষা করছে)।

আপনি সম্ভবত স্টাফেনের পার্ল ট্রি-ট্র্যাভারসাল চান এবং প্রয়োজনে একটি তালিকা সহ আউটপুটটিতে "যোগ" দিতে চান (অভিভাবক ডিরেক্টরিতেও অনুপস্থিত নিখরচায় ধরা পড়বে?)। যদি সারোগেসি কোনও পারফরম্যান্স সমস্যা হয় আপনি কি "বড় সংখ্যক" ব্যবহারকারীর জন্য এটি করছেন? নাকি এটি একটি অনলাইন কোয়েরি? এটি যদি স্থায়ী চলমান প্রয়োজনীয়তা হয় তবে এটি তৃতীয় পক্ষের পণ্য বিবেচনা করার সময় হতে পারে।


0

আপনি করতে পারেন...

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

... সমস্ত ফাইলের তালিকার জন্য যা ব্যবহারকারী ফর্মটিতে স্ট্ডারকে লিখিতভাবে লিখতে পারে না ...

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

...অথবা সাদৃশ্যপূর্ণ.

এই পদ্ধতির কী থাকতে পারে সেই বিষয়ে নোটের জন্য নীচের মন্তব্যগুলি এবং এটি কেন কাজ করতে পারে তার নীচের ব্যাখ্যা দেখুন। আরও বিচক্ষণতার সাথে, আপনার সম্ভবত কেবল find নিয়মিত ফাইলগুলি হওয়া উচিত :

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

সংক্ষেপে, এটি দুটি পতাকাগুলির একটির সাথে কোনও ফাইলের teeচেষ্টা করার সময় ত্রুটিগুলি মুদ্রণ করবে open()...

O_WRONLY

কেবল লেখার জন্য উন্মুক্ত।

O_RDWR

পড়া এবং লেখার জন্য উন্মুক্ত। যদি এই পতাকাটি কোনও ফিফোর জন্য প্রয়োগ করা হয় তবে ফলাফলটি অনির্ধারিত।

... এবং মুখোমুখি ...

[EACCES]

পথের উপসর্গের কোনও অংশে অনুসন্ধানের অনুমতি অস্বীকার করা হয়েছে, বা ফাইলটি উপস্থিত রয়েছে এবং অফলাগ দ্বারা নির্দিষ্ট করা অনুমতিগুলি অস্বীকার করা হয়েছে, অথবা ফাইলটি উপস্থিত নেই এবং লেখার অনুমতি ফাইলটিকে প্যারেন্ট ডিরেক্টরি তৈরি করার জন্য অস্বীকার করা হয়েছে, বা O_TRUNC নির্দিষ্ট এবং লেখার অনুমতি অস্বীকার করা হয়।

... এখানে নির্দিষ্ট হিসাবে :

teeউপযোগ মানক আউটপুটে স্ট্যান্ডার্ড ইনপুট কপি হইবে, শূন্য বা একাধিক ফাইল একটি অনুলিপি করা। টি ইউটিলিটি আউটপুট বাফার করবে না।

যদি -aঅপশন উল্লেখিত হয় না, আউটপুট ফাইল লিখিত হইবে (দেখুন ফাইল পঠন, লিখন ও সৃষ্টি ) ...

... POSIX.1-2008 ব্যবহার করে কার্যকারিতা সমতুল্য প্রয়োজন O_APPEND ...

কারণ এটি একইভাবে চেক করতে test -wহয় ...

-w পথনাম

সত্য, যদি পাঠের নামটি কোনও ফাইলের জন্য কোনও ডিরেক্টরি ডিরেক্টরি প্রবেশের সাথে সমাধান করে যার জন্য ফাইলটি পড়ার, লেখার, এবং তৈরির সংজ্ঞায়িত হিসাবে ফাইলটিতে লেখার অনুমতি দেওয়া হবে । মিথ্যা যদি পথের নামটি সমাধান করা যায় না, বা যদি পথের নামটি কোনও ফাইলের জন্য কোনও ডিরেক্টরিতে প্রবেশের জন্য সমাধান হয় তবে যার জন্য ফাইলটিতে লেখার অনুমতি দেওয়া হবে না।

তারা উভয়ই EACCESS পরীক্ষা করে ।


আপনি সম্ভবত এই পদ্ধতির সাথে একযোগে খোলার ফাইলের একটি সীমাতে চলে যেতে পারেন (যদি না ফাইলের সংখ্যা কম থাকে)। ডিভাইস এবং নামযুক্ত পাইপগুলির সাথে পার্শ্ব প্রতিক্রিয়া থেকে সাবধান থাকুন। আপনি সকেটের জন্য একটি পৃথক ত্রুটি বার্তা পাবেন।
স্টাফেন চেজেলাস 21

@ স্টাফেনচাজেলাস - সমস্ত মঙ্গল - আমি মনে করি এটি সত্যও হতে পারে যা teeপ্রতি রান একবারে স্পষ্টভাবে বাধা না দিলে স্তব্ধ হয়ে যাবে। এটি আমার নিকটতম জিনিস যা আমি ভাবতে পারি [ -w... যদিও - এর প্রভাবগুলি এমনভাবে হওয়া উচিত যা এটি ব্যবহারকারীকে ফাইলটি অপপেন্ড করতে পারে তার গ্যারান্টি দেয়। অনেক সহজ তুলনায় পারেন বিকল্প হবে paxসঙ্গে -oএবং / অথবা ফর্ম্যাট বিকল্পগুলি -tবিরুদ্ধে চেক করার জন্য EACCESS- কিন্তু প্রত্যেক সময় আমি আপনাকে পরামর্শ দিচ্ছি paxমানুষ এটা বন্ধ অসহায়তা বলে মনে হচ্ছে। এবং যাইহোক, কেবলমাত্র paxআমি খুঁজে পেয়েছি যে সেখানে এসটি রয়েছে এটিএসটির সাথে মিলিত হয়েছে - সেক্ষেত্রে আপনি সম্ভবত তাদের ব্যবহার করতে পারেন ls
মাইকজার্ভ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.