ฉันมีกระบวนการที่เริ่มต้นโดย damon ที่เรียกใช้ในฐานะ root ตอนนี้ฉันต้องการ "ลดระดับ" สิทธิ์ของกระบวนการนี้ให้กับผู้ใช้ทั่วไปของคุณ เป็นไปได้ไหม ถ้าใช่เป็นอย่างไร
PS: การเรียกใช้ unix บนเครื่อง mac
ฉันมีกระบวนการที่เริ่มต้นโดย damon ที่เรียกใช้ในฐานะ root ตอนนี้ฉันต้องการ "ลดระดับ" สิทธิ์ของกระบวนการนี้ให้กับผู้ใช้ทั่วไปของคุณ เป็นไปได้ไหม ถ้าใช่เป็นอย่างไร
PS: การเรียกใช้ unix บนเครื่อง mac
คำตอบ:
กระบวนการต้องเรียก setuid (2) คุณควรตรวจสอบการใช้ภายใน chroot (8) หากยังไม่ได้ดำเนินการ เท่าที่ฉันรู้ไม่มีทางรูทที่จะเปลี่ยน uid ของกระบวนการอื่นได้
หากเหตุผลที่คุณใช้เป็นรูทคือการผูกพอร์ตผมขอแนะนำให้ใช้มันเป็นผู้ใช้ปกติบนพอร์ตที่สูงกว่าและใช้ ipfw (8) บน OS X เพื่อส่งต่อพอร์ต 80/443 / etc ไปยังพอร์ตที่สูงกว่า:
http://support.crashplanpro.com/doku.php/recipe/forward_port_443_to_pro_server_on_mac_osx
setuid()
คนเดียวไม่เพียงพอ
sudo tcpdump -Z
ใช้กลุ่มเริ่มต้น (3), setgid (2) และ setuid (2) เพื่อปล่อยสิทธิ์รูทของกระบวนการของตัวเอง
# code taken from:
# http://www.opensource.apple.com/source/tcpdump/tcpdump-32/tcpdump/tcpdump.c
/* Drop root privileges and chroot if necessary */
static void
droproot(const char *username, const char *chroot_dir)
{
...
if (initgroups(pw->pw_name, pw->pw_gid) != 0 ||
setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) {
fprintf(stderr, "tcpdump: Couldn't change to '%.32s' uid=%lu gid=%lu: %s\n",
username,
(unsigned long)pw->pw_uid,
(unsigned long)pw->pw_gid,
pcap_strerror(errno));
exit(1);
}
...
}
initgroups
, setgid
, setuid
(ที่ผ่านมา) เป็นอย่างแม่นยำกระบวนทัศน์ทางด้านขวาบนยูนิกซ์และควรได้รับการปฏิบัติตาม นอกจากนี้ฟังก์ชั่น "droproot" ที่รับผิดชอบจะตรวจสอบว่ามีการตั้งค่า uid และ gid จริง ๆ แม้ว่าฟังก์ชันหลักทั้งสามจะกลับมาประสบความสำเร็จ
คุณสามารถเรียกใช้คำสั่งในฐานะผู้ใช้รายอื่นโดยใช้su
:
su USERNAME -c COMMAND
จะทำงานที่มีสิทธิ์ที่จะปรับตัวลดลงCOMMAND
USER
โปรดทราบว่าโดยค่าเริ่มต้นsu
จะใช้ตัวแปลเชลล์ของผู้ใช้เป้าหมายเพื่อรันคำสั่ง ในทางตรงกันข้ามพฤติกรรมเริ่มต้นของsudo
คือการปฏิบัติต่อCOMMAND
เป็นโปรแกรมแบบสแตนด์อโลนที่เรียกใช้สภาพแวดล้อมปัจจุบัน แน่นอนพฤติกรรมเริ่มต้นเหล่านี้สามารถเปลี่ยนแปลงได้ด้วยสวิตช์และตัวแปรสภาพแวดล้อมต่างๆ
su
จะไม่ทำงานหาก USERNAME ไม่มีการกำหนดเชลล์ (หรือ/bin/false
) ในขณะที่ sudo ทำงาน
su
จะแสดงให้เห็นว่า อย่างไรก็ตามหนึ่งสามารถแทนที่ที่ใช้-s
สวิตช์ โปรดทราบว่าจุดประสงค์su
คือเพื่อเลียนแบบพฤติกรรมของผู้ใช้ที่กำหนดซึ่งโดยปกติจะได้รับอิทธิพลจากเปลือกของเขา / เธอ ในทางตรงกันข้ามsudo
จะ (โดยค่าเริ่มต้น) ละเว้นการตั้งค่าเปลือกของผู้ใช้เป้าหมาย
ในการลบสิทธิ์คุณต้องมีผู้ใช้ที่ไม่ใช่รูทเพื่อเลื่อนไป จากนั้นเป็นเรื่องของการสลับไปใช้ผู้ใช้นั้น:
#define UNPRIV_UID 48
#define UNPRIV_GID 48
if (getuid() == 0) { // we are root
// setting UID/GID requires root privileges, so if you don't set
// the GID first, you won't be able to do it at all.
if (setgid(UNPRIV_GID)!=0) die("Failed to set nonroot GID");
if (setuid(UNPRIV_UID)!=0) die("Failed to set nonroot UID");
}
ASSERT(getuid() != 0);
โปรดทราบว่าสิ่งนี้จะกระทำภายในโปรแกรมเองแทนที่จะเป็นสคริปต์ตัวตัดคำ หลายโปรแกรมต้องการสิทธิ์รูทสำหรับวัตถุประสงค์เฉพาะ (เช่นผูกเข้ากับพอร์ตที่มีหมายเลขต่ำ) แต่ไม่ต้องการรูทหลังจากนั้น ดังนั้นโปรแกรมเหล่านี้จะเริ่มต้นเป็นรูท แต่จากนั้นให้ลบสิทธิ์เมื่อไม่ต้องการใช้อีกต่อไป
หากคุณไม่ต้องการสิทธิ์รูทเลยเพียงแค่เรียกใช้ในฐานะรูท เช่น:
# Change this:
myprog -C /my/config/file
# To this:
sudo -u someuser myprog -C /my/config/file
# Or this
su someuser -c "myprog -C /my/config/file"
setuid
ฟังก์ชั่นเพียงชุดที่มีประสิทธิภาพ UID ไม่ได้โพสต์จริง คุณควรใช้setreuid
หากคุณไม่ต้องการให้กระบวนการได้รับสิทธิ์คืน (และรหัสด้านบนไม่ได้จัดการกับสิทธิ์พิเศษของกลุ่มเพิ่มเติมเหมาะสำหรับการเปิดใช้รหัสที่เชื่อถือได้ส่วนใหญ่เท่านั้น)
setuid()
ตั้งค่า userids จริงและบันทึกไว้; seteuid()
คุณอาจจะคิดของ ระบบบางระบบไม่มีsetreuid()
ดังนั้นจึงไม่สามารถใช้งานได้ทุกที่ ความหมายที่แท้จริงของsetuid()
กำลัง compliced แต่ถ้าคุณมี EUID 0, setuid()
คุณจะสามารถที่จะลดสิทธิพิเศษในการใช้รหัสแบบดั้งเดิมทั้งหมดที่มี การละเลยที่ใหญ่ที่สุดในคำตอบนี้ก็คือว่าinitgroups
หรือsetgroups
จะต้องเรียกว่าเช่นเดียวกับsetgid
และsetuid
และที่ยืนยันอย่างละเอียดมากขึ้นควรจะทำในตอนท้าย
หากคุณกำลังดำเนินการปฏิบัติการที่แตกต่างกันเช่นคุณกำลังเรียกexecve
หรืออื่น ๆ ของexec
ฟังก์ชั่นของครอบครัวอาจจะทางอ้อมผ่านฟังก์ชั่นเช่นsystem
หรือpopen
และกระบวนการเด็กควรทำงานโดยไม่มีสิทธิ์ตั้งแต่เริ่มต้นวิธีที่ง่ายที่สุดคือการรับ su
เปลือกที่เกี่ยวข้องและการโทร ต่อไปนี้เป็นภาพรวมของโค้ดที่ดูเหมือนใน Perl โดยแสดงข้อความที่ต้องการสำหรับ:
$shell_command = quotemeta($path_to_executable) . " --option";
$shell_command =~ s/'/'\\''/; # protect single quotes for the use as argument to su
$su_command = sprintf("su -c '%s' %s", $shell_command, quotemeta($user_name));
open(PIPE, "$su_command |") or die;
หากกระบวนการลูกต้องเริ่มจากรูท แต่ปล่อยสิทธิพิเศษในภายหลังดูรหัสในคำตอบนี้ซึ่งแสดงวิธีการดาวน์เกรดสิทธิ์ในกระบวนการ