เหตุใดไฟล์ที่มีสิทธิ์ 400 รายการที่รูทเครื่องสามารถอ่านได้ แต่อ่านอย่างเดียวโดยผู้ใช้


10

หากฉันสร้างไฟล์ในฐานะผู้ใช้ที่ไม่มีสิทธิ์และเปลี่ยนโหมดการอนุญาต400เป็นผู้ใช้นั้นจะเห็นว่าเป็นแบบอ่านอย่างเดียวอย่างถูกต้อง:

$ touch somefile
$ chmod 400 somefile
$ [ -w somefile ] && echo rw || echo ro
ro

ทั้งหมดเป็นอย่างดี.

แต่แล้วรากก็มาพร้อม:

# [ -w somefile ] && echo rw || echo ro
rw

ห่า? แน่นอนว่ารูทสามารถเขียนไปยังไฟล์แบบอ่านอย่างเดียวได้ แต่ไม่ควรทำให้เป็นนิสัย: แนวปฏิบัติที่ดีที่สุดมีแนวโน้มที่จะกำหนดว่าฉันควรจะสามารถทดสอบบิตการอนุญาตการเขียนได้และถ้าไม่ใช่ก็เป็นไปได้ ทางนั้นด้วยเหตุผล

ผมคิดว่าผมต้องการที่จะเข้าใจทั้งสองเหตุผลนี้เกิดขึ้นและวิธีการที่ฉันจะได้รับเท็จรหัสการส่งคืนเมื่อการทดสอบไฟล์ที่ไม่ได้มีการเขียนชุดบิตหรือไม่?


btw ฉันใช้ทั้ง RHEL6 ( 4.1.2(1)-release) และ RHEL7 ( 4.2.46(2)-release)
รวย

16
"แนวปฏิบัติที่ดีที่สุดมีแนวโน้มที่จะบงการว่าฉันควรจะสามารถทดสอบบิตการอนุญาตให้เขียนได้และหากไม่เป็นเช่นนั้น - จริง ๆ แล้ววิธีปฏิบัติที่ดีที่สุดคือ "อย่าเรียกใช้เนื้อหาในฐานะที่เป็นราก หากคุณใช้งานเป็น root คุณได้ตัดสินใจเลี่ยงการตรวจสอบสิทธิ์แล้ว อีกครั้งด้วยตนเองการดำเนินการตรวจสอบได้รับอนุญาตจากผู้ที่อยู่ใน userspace เป็นสูตรสำหรับภัยพิบัติ
เควิน

@ Kevin ดีสำหรับคุณถ้าคุณสามารถเรียกใช้สิ่งที่ไม่มีสิทธิ์ นี่คือการจัดการ/etc/dhcp/dhcpd.confซึ่งเป็นของรูต dhcpdฉันใช้ผู้ขายที่จัดมาให้ ภัยพิบัติทั้งหมดใช่มั้ย ไฟล์จะถูกตรวจสอบใน RCS ฉันอัตโนมัติใช้rcsdiff, ciและcoเพราะเรามีผู้ประกอบการที่จะต้องดำเนินการ ... การตรวจสอบสิทธิ์บิต ( -wตามรายละเอียดโดยtest(1)) จะเป็นความล้มเหลวในบรรทัดแรกโดยทำงานบนพื้นฐานที่ci -uปล่อยให้ไฟล์อ่านได้อย่างเดียว ฉันอร่อยที่และตรงไปและการตรวจสอบrcsdiff -q ไม่$?ร้ายกาจdhcpd? dhcpdมันจะเป็นเจ้าของโดย
รวย

1
มันเป็นความหายนะที่อาจเกิดขึ้นเพราะตอนนี้คุณมีการตรวจสอบการอนุญาตใช้งานที่แตกต่างกันสองแบบ: หนึ่งรายการในเคอร์เนลและอีกหนึ่งรายการใน userspace ยิ่งไปกว่านั้นการใช้งานเหล่านั้นไม่ได้มีวัตถุประสงค์เพื่อสร้างผลลัพธ์ที่เหมือนกันดังนั้นคุณจึงไม่สามารถฝืนทดสอบกับพวกเขาได้ ดังนั้นตอนนี้คุณมีสองเส้นทางในการเข้าถึงซึ่งจะต้องถูกล็อคและปลอดภัยจากกัน
เควิน

@ เควินแน่นอนว่าพวกเขาไม่ได้ผลลัพธ์ที่เหมือนกันและไม่ได้มีเจตนาที่จะ (แม้จะมีความละเอียดของรายละเอียดใน manpages) แต่ฉันต้องการตรวจสอบบิตสิทธิ์การเขียน ; และ manpages สำหรับbashและtestทำให้ฉันเชื่อว่านั่นคือสิ่งที่[ -wมีไว้สำหรับ
รวย

คำตอบ:


26

test -wอาคา[ -wไม่ได้ตรวจสอบโหมดไฟล์ มันตรวจสอบว่ามันเขียนได้ สำหรับรูทนั้น

$ help test | grep '\-w'
  -w FILE        True if the file is writable by you.

วิธีที่ฉันจะทดสอบจะทำการเปรียบเทียบในระดับบิตกับผลลัพธ์ของstat(1)(" %a สิทธิ์การเข้าถึงในฐานแปด")

(( 0$(stat -c %a somefile) & 0200 )) && echo rw || echo ro

หมายเหตุ subshell $(...)ต้องการ0นำหน้าเพื่อให้การส่งออกของถูกตีความว่าเป็นฐานแปดโดยstat(( ... ))


ขอบคุณที่กระชับ (( ... & ... ))การใช้งานที่ดีของ มีการพิมพ์ผิดหนึ่งรายการ :-)
Rich

ทำอย่างนั้น 3 ... ไม่ifจำเป็นต้องใช้เอาต์พุตของสิทธิ์แบบฐานแปด%aไม่ใช่%dและ(( ... ))ต้องการคำนำหน้า0เพื่อแปลเอาต์พุตstatเป็นแบบฐานแปด
Rich

@ แพทริคหลอกฉันman statว่า "% d หมายเลขอุปกรณ์เป็นทศนิยม" แต่สิ่งที่เราต้องการคือ "สิทธิ์การเข้าถึง" ไม่ใช่หรือ? ประเด็นของคุณเกี่ยวกับการต้องการคำนำหน้า 0 นั้นทำได้ดีมาก แต่ฉันคิดว่าเราต้องหลบมันไว้ที่นั่น :)
sourcejedi

2
stat -c 0%a...
sourcejedi

@sourcejedi ack คุณพูดถูก ด้วยเหตุผลบางอย่างฉันคิดว่า% d เป็นสิทธิ์การเข้าถึงระดับทศนิยม คืนค่าการแก้ไข ขอบคุณ :-)
Patrick

30

ผมคิดว่าคุณต้องมีความเข้าใจผิดในสิ่งที่-wทำ มันไม่ได้ตรวจสอบเพื่อดูว่าไฟล์มี "สิทธิ์เขียน" มันจะตรวจสอบเพื่อดูว่าไฟล์นั้นเขียนได้โดยผู้ใช้ที่เรียกใช้

โดยเฉพาะอย่างยิ่งมันโทรaccess(2)หรือคล้ายกัน

เช่นถ้าสคริปต์มีif [ -w /etc/shadow ]แล้วถ้าคุณเรียกใช้straceสคริปต์คุณอาจเห็นบรรทัดคล้ายกับ

faccessat(AT_FDCWD, "/etc/shadow", W_OK)

เนื่องจากrootสามารถเขียนไปยังไฟล์ได้ดังนั้นจึงส่งคืน 0

เช่นในฐานะผู้ใช้ปกติ:

faccessat(AT_FDCWD, "/etc/shadow", W_OK) = -1 EACCES (Permission denied)

เช่นเดียวกับราก

faccessat(AT_FDCWD, "/etc/shadow", W_OK) = 0

สิ่งนี้แม้จะมีข้อเท็จจริงว่า/etc/shadowได้รับอนุญาต000บนเครื่องของฉัน

---------- 1 root root 4599 Jan 29 20:08 /etc/shadow

ตอนนี้สิ่งที่คุณต้องการทำให้น่าสนใจและไม่ใช่เรื่องง่าย

หากคุณต้องการตรวจสอบการอนุญาตอย่างง่ายจากนั้นตรวจสอบlsผลลัพธ์หรือการโทรstatหรือสิ่งที่คล้ายกัน แต่ตระหนักว่า ACL สามารถใช้สิทธิ์เหล่านี้ได้มากเกินไป เพียงเพราะไฟล์ได้รับอนุญาต 400 ไม่ได้หยุดเขียนไม่ได้ ...


ไม่ "ความเข้าใจผิด" จะอ่าน manpages ที่ไม่ถูกต้องสำหรับ-w: test(1)ชัดแจ้ง: "มีไฟล์อยู่และได้รับอนุญาตให้เขียน " ไม่ใช่ " ไฟล์อาจถูกเขียนโดยผู้ใช้ปัจจุบัน " ไม่เกี่ยวกับการแทนที่สิทธิ์หรือ ACL bash(1)is Cagey: "True ถ้าไฟล์มีอยู่และเขียนได้ " ksh(1)ทำให้คำใบ้ที่ละเอียดไปยัง shenanigans: "-w file // True หากไฟล์นั้นมีอยู่และสามารถเขียนได้โดยกระบวนการปัจจุบัน " zsh(1)defers to test(1), zshmisc(1)ถูกใช้คำว่าksh(1), และบอกzshexpn(1)รายละเอียดบางอย่างที่อิงตามการอนุญาตที่น่าสนใจ csh(1)สั้น ๆ อย่างสนุกสนาน: "การเข้าถึงเพื่อเขียน"

btw: ฉันยอมรับคำตอบของแพทริค 1. เพราะคุณไม่ได้ตอบคำถามนำไปสู่อย่างเพียงพอ: ฉันจะรับรหัสส่งคืนเท็จได้อย่างไรเมื่อทดสอบไฟล์ที่ไม่มีชุดบิตการเขียน? และ 2. เนื่องจากข้อสันนิษฐานที่นำไปสู่การต่อว่าต่อขานฉันจึงเข้าใจผิดเกี่ยวกับ manpages
รวย

3
@ ริชวิธีที่ฉันอ่านสิ่งนี้ฉันคิดว่าความคิดเห็นของคุณกำลังเจอกัน ฉันไม่ได้บอกว่าสิ่งที่คุณเขียนนั้นผิด แต่อาจจะดีกว่าถ้าแสดงออกด้วยความสุภาพมากกว่านี้
David Z

3
"ฉันคิดว่าคุณเข้าใจผิด ... " ไม่ใช่คำพูดที่น่ารังเกียจ การตอบสนองของคุณอย่างไรก็ตาม 100% คำสาปแช่ง
บาร์บีคิว

@ Rich ในขณะที่ manpages อาจไม่ชัดสตีเฟ่นแจ้งว่าคุณอาจมี "เข้าใจผิดว่า -w ทำอะไร " และไม่ใช่สิ่งที่manpagesพูดซึ่งในอดีตดูเหมือนจะเป็นกรณีดังนั้นคำถาม
Sebi

1

ผู้ใช้รูทสามารถทำตามที่ต้องการได้การอนุญาตไฟล์ "ปกติ" ไม่ จำกัด มันจะไม่เรียกใช้ไฟล์ธรรมดาโดยตรงหากไม่มีสิทธิ์ eXecute ใด ๆ เพียงแค่ทำประกันเล็กน้อยกับการฝึกซ้อมตามเป้าหมายเท้า

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.