2009-06-17 9 views
11

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

क्या ऐसा करने के लिए कोई सिस्टम कॉल है? मैं इसे हार्डकोड नहीं करना चाहता/या/etc/passwd से पार्स नहीं करना चाहता हूं।

इसके अलावा, मैं का उपयोग करने से प्रोग्राम के रूप में नहीं बल्कि ऐसा करने के लिए करना चाहते हैं:

आईडी -u USERNAME

किसी भी मदद होगी बहुत सराहना

+0

क्या पार्स/etc/पासवर्ड के साथ गलत क्या है? – eduffy

+1

मुझे यह कहना चाहिए था, "मैं बल्कि पार्स/etc/passwd नहीं करना चाहूंगा", क्योंकि मुझे संदेह था कि वहां एक आसान तरीका था, और उत्तर के लिए धन्यवाद, मुझे यह मिला है। – Evan

+10

पार्सिंग/etc/passwd के साथ एक चीज़ गलत है कि उपयोगकर्ता नाम वहां संग्रहीत नहीं किए जा सकते हैं - वे किसी निर्देशिका सर्वर (एलडीएपी, आदि) पर कहीं बाहर हो सकते हैं। एक और बात गलत है कि यह आपके लिए पहले से ही किया गया है, getpwnam() et al द्वारा। –

उत्तर

3

आप सिस्टम कॉल के getpw * परिवार का उपयोग करना चाहते हैं, आमतौर पर pwd.h में। यह अनिवार्य रूप से/etc/passwd में जानकारी के लिए एक सी-स्तरीय इंटरफ़ेस है।

1

getpwnam और struct passwd को देखो।

3
#include <sys/types.h> 
#include <pwd.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <stdio.h> 

int main() 
{ 
    char *username = ... 

    struct passwd *pwd = calloc(1, sizeof(struct passwd)); 
    if(pwd == NULL) 
    { 
     fprintf(stderr, "Failed to allocate struct passwd for getpwnam_r.\n"); 
     exit(1); 
    } 
    size_t buffer_len = sysconf(_SC_GETPW_R_SIZE_MAX) * sizeof(char); 
    char *buffer = malloc(buffer_len); 
    if(buffer == NULL) 
    { 
     fprintf(stderr, "Failed to allocate buffer for getpwnam_r.\n"); 
     exit(2); 
    } 
    getpwnam_r(username, pwd, buffer, buffer_len, &pwd); 
    if(pwd == NULL) 
    { 
     fprintf(stderr, "getpwnam_r failed to find requested entry.\n"); 
     exit(3); 
    } 
    printf("uid: %d\n", pwd->pw_uid); 
    printf("gid: %d\n", pwd->pw_gid); 

    free(pwd); 
    free(buffer); 

    return 0; 
} 
+0

आपने कभी भी 'pwd' या' buffer' 'को मुक्त नहीं किया है - लेकिन फिर भी आप – Siler

+0

@Siler पर ढेर पर' pwd' या 'buffer' आवंटित करने के लिए भी परेशान क्यों हैं, मैंने फ्री को जोड़ा। मैं मानता हूं कि यह स्टैक पर किया जा सकता है (केवल चेतावनी यह सुनिश्चित करना है कि sysconf (_SC_GETPW_R_SIZE_MAX) बहुत बड़ा नहीं है (यह किसी यथार्थवादी सिस्टम पर होने की संभावना नहीं है) हालांकि, मैं इसके लिए इसे फिर से लिखने वाला नहीं हूं –

+0

यह बहुत अच्छा है जब आप उपयोगकर्ता नाम_ जानते हैं, लेकिन 'getuid()' के लिए प्रतिस्थापन नहीं है। –

0

आप नीचे दिए गए कोड स्निपेट का उपयोग कर सकते हैं:

#include <pwd.h> 
#include <grp.h> 

gid_t Sandbox::getGroupIdByName(const char *name) 
{ 
    struct group *grp = getgrnam(name); /* don't free, see getgrnam() for details */ 
    if(grp == NULL) { 
     throw runtime_error(string("Failed to get groupId from groupname : ") + name); 
    } 
    return grp->gr_gid; 
} 

uid_t Sandbox::getUserIdByName(const char *name) 
{ 
    struct passwd *pwd = getpwnam(name); /* don't free, see getpwnam() for details */ 
    if(pwd == NULL) { 
     throw runtime_error(string("Failed to get userId from username : ") + name); 
    } 
    return pwd->pw_uid; 
} 

रेफरी: getpwnam()getgrnam()

संबंधित मुद्दे