ड्रॉप प्रक्रिया विशेषाधिकार


12

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

पुनश्च: एक मैक पर यूनिक्स चल रहा है

जवाबों:


5

इस प्रक्रिया को स्वयं सेतु (2) पर कॉल करना होगा। यदि आप पहले से ही नहीं हैं, तो आपको इसे चुरोट (8) के अंदर चलाने की भी जांच करनी चाहिए। जहां तक ​​मुझे पता है, किसी अन्य प्रक्रिया के यूआईडी को बदलने के लिए रूट का कोई रास्ता नहीं है।

यदि आप इसे रूट के रूप में चला रहे हैं, तो यह पोर्ट्स को बाइंड करने के लिए है, मैं इसे उच्च पोर्ट पर एक सामान्य उपयोगकर्ता के रूप में चलाने का सुझाव देता हूं और ओएस एक्स पर आईपीएफडब्ल्यू (8) का उपयोग करते हुए पोर्ट 80/443 / इत्यादि को उच्च पोर्ट पर भेज सकता हूं:

http://support.crashplanpro.com/doku.php/recipe/forward_port_443_to_pro_server_on_mac_osx


मैंने अपने प्रोग्राम में सेतुइद (यूआईडी) डाल दिया जो रूट के रूप में चलता है लेकिन मुझे इसे सामान्य उपयोगकर्ता के रूप में चलाने की आवश्यकता है और कुछ भी नहीं होता है अर्थात यह रूट के रूप में जारी रहता है
सामन्था कैटेनिया

आपको शायद तब से त्रुटियों को पकड़ने की आवश्यकता है (हो सकता है कि आपको यूआईडी के लिए एक EINVAL मिल रहा हो)। इसका असंभावित सेतु आपके मशीन पर टूट गया है जिसे आप यह देखकर सत्यापित कर सकते हैं कि क्या अपाचे _www के रूप में चल रहा है। प्रोग्रामर डॉक्स: developer.apple.com/library/mac/#documentation/Darwin/Reference/…
बहुपद

आप सही हैं, यह सही होने के बावजूद यूआईडी से एक सिंटैक्स त्रुटि देता है। क्या यह सही प्रारूप सेट्यूड (500) है?
सामंथा केतनिया

समस्या पाई गई: मैं सिस्टम के माध्यम से कमांड चलाने की कोशिश कर रहा था (), लेकिन मैं सिर्फ यह कमांड चलाता हूं कि यह काम करे और मेरी समस्या हल करे; मदद के लिए thx
सामंथा

नहीं, यह अच्छी सलाह नहीं है: setuid()अकेले फोन करना बिल्कुल पर्याप्त नहीं है।
निकोलस विल्सन

13

sudo tcpdump -Z अपनी स्वयं की प्रक्रिया के मूल विशेषाधिकारों को छोड़ने के लिए initgroups (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);
            }
...
}

2
सही बात। initgroups, setgid, setuid(पिछले!) ठीक यूनिक्स पर सही प्रतिमान है, और हमेशा पालन किया जाना चाहिए। इसके अलावा, एक जिम्मेदार "ड्रॉपरोट" फ़ंक्शन यह जांचता है कि इसका यूआईडी और जीआईडी ​​वास्तव में सेट किया गया है, भले ही सभी तीन प्राथमिक कार्यों ने सफलता लौटा दी हो।
निकोलस विल्सन

3

आप अन्य उपयोगकर्ताओं के रूप में कमांड चला सकते हैं su:

 su USERNAME -c COMMAND

COMMANDगिराए गए विशेषाधिकारों के साथ चलेगा USER


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


suयदि USERNAME के ​​पास कोई शेल परिभाषित (या /bin/false) नहीं है, जबकि sudo काम करता है तो ऐसा नहीं लगता है ।
ऐफ

1
@ यदि उपयोगकर्ता को इंटरेक्टिव कमांड चलाने की अनुमति नहीं है, तो डिफ़ॉल्ट व्यवहार suउसे प्रतिबिंबित करेगा। हालांकि, कोई हमेशा -sस्विच का उपयोग करके ओवरराइड कर सकता है । ध्यान दें कि इसका उद्देश्य suकिसी दिए गए उपयोगकर्ता के व्यवहार की नकल करना है - जो आमतौर पर उसके खोल से प्रभावित होता है। इसके विपरीत, sudo(डिफ़ॉल्ट रूप से) लक्ष्य उपयोगकर्ता की शेल सेटिंग को अनदेखा करेगा।
रोज़ज़ेट्रिएवेज़ेज़

नहीं, कृपया विशेषाधिकारों को छोड़ने के लिए शेल का उपयोग करके चीजों को न चलाएं। एक हमलावर के नियंत्रण में बहुत दूर निकल जाता है, विभिन्न कॉन्फिग फाइलों में पढ़ना जिन्हें आप छूना नहीं चाहते हैं।
निकोलस विल्सन

2

विशेषाधिकार छोड़ने के लिए, आपको ड्रॉप करने के लिए एक गैर-रूट उपयोगकर्ता की आवश्यकता होती है। फिर यह उस उपयोगकर्ता के लिए स्विच करने की बात है:

#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"

1
ध्यान दें कि यह प्रक्रिया को विशेषाधिकारों को पुनर्प्राप्त करने की अनुमति देता है यदि यह चाहता है! setuidसमारोह केवल सेट प्रभावी यूआईडी, नहीं असली यूआईडी। setreuidयदि आप प्रक्रिया को विशेषाधिकार प्राप्त करने में सक्षम नहीं होना चाहते हैं तो आपको इसका उपयोग करना चाहिए । (और उपरोक्त कोड पूरक समूह विशेषाधिकारों के साथ सौदा नहीं करता है। यह केवल ज्यादातर विश्वसनीय कोड लॉन्च करने के लिए उपयुक्त है।)
डेविड श्वार्ट्ज

@ दाविद श्वार्ट्ज कोड का उपयोग किए गए तंत्र को दिखाने के लिए जानबूझकर सरल किया गया था।
टायलरल

यदि आप सुरक्षा के लिए महत्वपूर्ण कोड को आसान बनाने के लिए जा रहे हैं, तो आप बनाने के लिए यह राशि बहुत स्पष्ट यह आप क्या कर रहे हैं है। और आपको "जब यह नहीं है तो यह सिर्फ" की बात है।
डेविड श्वार्ट्ज

2
@ setuid()डेविड वास्तव में, वास्तविक और सहेजे गए उपयोगकर्ता सेट करता है; आप के बारे में सोच हो सकती है seteuid()। सभी प्रणालियों में नहीं है setreuid(), इसलिए इसका हर जगह उपयोग नहीं किया जा सकता है। सटीक शब्दार्थ setuid()जटिल हैं, लेकिन यदि आपके पास यूरोप 0 है, तो आप सभी पारंपरिक उपयोगकर्ता आईडी विशेषाधिकारों को छोड़ सकेंगे setuid()। इस जवाब में सबसे बड़ी चूक थी जिसने है initgroupsया setgroupsके रूप में भी बुलाया जाना चाहिए setgidऔर setuid, और कहा कि अधिक गहन दावे अंत में किया जाना चाहिए।
निकोलस विल्सन

0

यदि आप एक अलग निष्पादन योग्य कार्य कर रहे हैं, यानी आप कॉल कर रहे हैं execveया execफ़ंक्शन का एक और कार्य, शायद अप्रत्यक्ष रूप से किसी फ़ंक्शन के माध्यम से systemया जैसे popen, और बच्चे की प्रक्रिया शुरू से विशेषाधिकारों के बिना चलनी चाहिए, तो सबसे आसान तरीका एक प्राप्त करना है खोल शामिल है, और कॉल करें su। यहां बताया गया है कि पर्ल में कोड कैसा दिख सकता है, इसके लिए आवश्यक उद्धरण दिखाते हुए:

$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;

यदि बाल प्रक्रिया को मूल के रूप में शुरू करने की आवश्यकता है, लेकिन बाद में विशेषाधिकारों को छोड़ दें, तो इस उत्तर में कोड देखें , जो दिखाता है कि किसी प्रक्रिया में विशेषाधिकारों को कैसे अपग्रेड किया जाए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.