सी

2012-02-15 3 views
6

में सेटयूड प्रोग्राम चलाने के लिए सही तरीका है मेरे पास अनुमति 4750 के साथ एक प्रक्रिया है। मेरे उपयोगकर्ता सिस्टम में दो उपयोगकर्ता मौजूद हैं। रूट उपयोगकर्ता और ऐप उपयोगकर्ता। प्रक्रिया को एक प्रक्रिया प्रबंधक की अनुमतियां मिलती हैं जो "एपज़" उपयोगकर्ता के रूप में चलती है।सी

मैं दो बुनियादी दिनचर्या है:

int main() { 
undo_root(); 
do some stuff; 
do_root(); 
bind(port 80); //needs root perm 
undo_root(); 
while(1) { 

    accept commads() 
    if (commands needs root user access) 
    { 
     do_root(); 
     execute(); 
     undo_root(); 

    } 

} 

आप मैं रूट के रूप में कुछ आदेश पर अमल करना चाहते हैं देख सकते हैं:

void do_root (void) 
{ 
     int status; 
     status = seteuid (euid); 
     if (status < 0) { 
     exit (status); 
     }  
} 

/* undo root permissions */ 
void undo_root (void) 
{ 
int status; 
     status = seteuid (ruid); 
     if (status < 0) { 
       exit (status); 
     } 
     status = setuid(ruid); 
     if (status < 0) { 
       exit (status); 
     } 
} 

मेरे प्रवाह निम्नलिखित है। मैं अनुमतियों को अस्थायी रूप से छोड़ने की कोशिश कर रहा हूं और यदि कार्यों को रूट पहुंच की आवश्यकता है, तो मैं do_root और undo_root कॉल के बीच कमांड को लपेटता हूं।

हालांकि ऐसा लगता है कि मेरा प्रोग्राम काम नहीं कर रहा है।

ऐसा करने का कैननिक तरीका क्या है?

+0

सेट्यूयूड विफल होने पर बाहर निकलने के बजाय, कॉलर() पर कॉल करें और आपका कार्यक्रम आपको बताएगा कि यह क्यों विफल रहा है। –

+4

एक बार जब आप रूट अनुमतियां छोड़ देते हैं, तो आप उन्हें वापस नहीं ले सकते !! – Petesh

+0

तकनीकी रूप से, यह उस प्रोग्राम को धारण करने वाली फ़ाइल है जिसमें 4750 अनुमति है, प्रक्रिया नहीं। आप सीधे यह नहीं कहते कि अनुमतियां रूट हैं: समूह: 4750' - क्या यह एक सुरक्षित अनुमान है? –

उत्तर

5

ओल्ड-स्कूल तरीका दोनों do_root और undo_root में है ruid और euid स्वैप करने के लिए setreuid() का उपयोग करने के लिए:

setreuid(geteuid(), getuid()); 

यह पूरी तरह से स्वीकार्य है, तो कार्यक्रम काफी छोटा एक पूर्ण सुरक्षा लेखापरीक्षा करने के लिए है ।

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

+0

आपका क्या मतलब है? बस अपने कोड को दोनों कार्यों में कॉपी और पेस्ट करें? – cateof

+0

हां। __________ – Joshua

2

setuid आदमी पेज निम्नलिखित कहते हैं:

... एक सेट उपयोगकर्ता के आईडी-रूट कार्यक्रम अस्थायी रूप से, जड़ विशेषाधिकार छोड़ गैर-रूट उपयोगकर्ता की पहचान मान, और उसके बाद करने के इच्छुक रूट विशेषाधिकारों हासिल बाद में उपयोग नहीं कर सकते setuid()

मतलब है कि आप setuid() उपयोग नहीं कर सकते। आपको seteuid() और संभवतः setreuid() का उपयोग करना होगा। अधिक जानकारी के लिए Setuid Program Example देखें।

+0

मेरा प्रोग्राम बिल्कुल इस जीएनयू पेज पर आधारित है। Do_setuid के बजाय, मैंने शुरुआत में do_root किया था। – cateof

+0

@cateof: मुझे लगता है कि आपने पोस्ट किए गए कोड में 'setuid' फ़ंक्शन का उपयोग किया है। यह एक तरह का टिकट है। –

5

हाओ चेन, डेविड वाग्नेर और ड्रू डीन द्वारा एक पेपर 'Setuid Demystified' है। यह यूएसएनईक्स 2002 में प्रस्तुत किया गया था। यह वर्णन करता है कि कैसे setuid() और संक्रमण बहुत विस्तार से काम करते हैं (2002 के अनुसार सही)। यह पढ़ने योग्य है (कई बार - मुझे इसके दोबारा पढ़ने पर एक या दो साल का अतिदेय होना चाहिए)।

मूल रूप से, Petesh के रूप में, एक टिप्पणी में बताया गया है जब EUID 0 के साथ एक प्रक्रिया nuid != 0 साथ setuid(nuid) करता है, वहाँ root (EUID 0) विशेषाधिकार वापस करने के लिए कोई रास्ता नहीं है। और, वास्तव में, यह महत्वपूर्ण है कि ऐसा है। अन्यथा, जब आप लॉगिन करते हैं, तो root प्रक्रिया जो आपको लॉग इन करती है, वह आपको अपने विशेषाधिकारों तक सीमित नहीं कर सकती - आप root पर वापस आ सकेंगे। सहेजा गया यूआईडी चीजों को जटिल करता है, लेकिन मुझे विश्वास नहीं है कि यह ईयूआईडी 0 के 0 -पर एक-तरफा जाल को प्रभावित करता है।