টি এল; ডিআর
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
এর কোনও চিহ্ন নেই )?
তার দরকার:
- অ্যাক্সেস অনুসন্ধান
/
(প্রয়োজন নেই read
)
- অ্যাক্সেস অনুসন্ধান
/foo
(প্রয়োজন নেই read
)
- প্রবেশাধিকার লিখুন
/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
উদাহরণ হিসাবে নয়।
এখন, এই সমস্ত সমাধানগুলি ফাইলের জন্য যেগুলি ফাইল লেখার জন্য খুলতে পারে সেগুলি চিহ্নিত করার চেষ্টা করে, এটি ব্যবহারকারী যে সামগ্রীগুলি পরিবর্তন করতে সক্ষম হতে পারে তার থেকে পৃথক। এই আরও সাধারণ প্রশ্নের উত্তর দিতে, বেশ কয়েকটি বিষয় বিবেচনায় নেওয়া উচিত:
- $ ব্যবহারকারীর লিখিত অ্যাক্সেস নাও থাকতে পারে
/a/b/file
তবে তার মালিকানাধীন রয়েছে file
(এবং এতে সন্ধান অ্যাক্সেস রয়েছে /a/b
এবং ফাইল সিস্টেমটি কেবল পঠনযোগ্য নয় এবং ফাইলটিতে স্থায়ী পতাকা নেই এবং সে সিস্টেমে শেল অ্যাক্সেস পেয়েছে), তারপরে তিনি অনুমতিগুলির অনুমতি পরিবর্তন করতে file
এবং নিজেকে অ্যাক্সেস দিতে সক্ষম হবেন ।
- একই জিনিস যদি তার মালিকানা থাকে
/a/b
তবে সেটিতে অনুসন্ধানের অ্যাক্সেস নেই।
- $ ব্যবহারকারীর অ্যাক্সেস নাও থাকতে পারে
/a/b/file
কারণ তার কাছে অনুসন্ধানের অ্যাক্সেস নেই /a
বা নেই /a/b
তবে /b/c/file
উদাহরণস্বরূপ সেই ফাইলটির একটি শক্ত লিঙ্ক থাকতে পারে, সেক্ষেত্রে সে তার সামগ্রীর /a/b/file
মাধ্যমে এটির সামগ্রীটি খোলার মাধ্যমে সংশোধন করতে সক্ষম হতে পারে /b/c/file
।
- বাঁধাই-মাউন্টগুলির সাথে একই জিনিস । তিনি সার্চ অ্যাক্সেস নাও থাকতে পারে
/a
, কিন্তু /a/b
হতে পারে বেঁধে-র উপরে মাউন্ট মধ্যে /c
, তাই সে খোলা যায়নি file
তার মাধ্যমে লেখার জন্য /c/file
অন্যান্য পথ।
- তার কাছে লিখনের অনুমতি নাও থাকতে পারে
/a/b/file
তবে তার যদি লেখার অ্যাক্সেস থাকে তবে /a/b
সে file
সেখানে মুছে ফেলতে বা নাম পরিবর্তন করতে এবং নিজের সংস্করণ দিয়ে এটিকে প্রতিস্থাপন করতে পারে। তিনি ফাইলের বিষয়বস্তু পরিবর্তন করতে চাইলে /a/b/file
এমনকি এটি অন্য কোনও ফাইল হতে পারে।
- একই জিনিস তিনি লেখার অ্যাক্সেস পেয়েছে যদি
/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
বিটের জন্য ইউনিক্স ) ব্যতীত:
-print0
GNU এক্সটেনশন এখন অন্যান্য কয়েকটি বাস্তবায়ন দ্বারা সমর্থিত। সঙ্গে 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
প্রদত্ত ব্যবহারকারীর হিসাবে চলতে দেয় ততক্ষণ কোডটি কোনও সংস্করণের সাথে কাজ করা উচিত ।