2010-10-01 24 views
8

Phiên bản ngắn: Tôi muốn có một cách để chạy somefunction("username") và yêu cầu trả lại ID người dùng được liên kết với username. Ví dụ: somefunction("root") sẽ trả về 0.Tôi làm cách nào để có được id người dùng được liên kết với thông tin đăng nhập trên Linux?

Tôi đang viết chương trình máy chủ có khả năng sử dụng các cổng được đánh số thấp, vì vậy nó phải bắt đầu bằng root. Rõ ràng, tôi không muốn nó chạy như root, vì vậy kế hoạch là để cho phép người dùng xác định người dùng chương trình nên chạy như thế nào. Vấn đề là setuid() yêu cầu ID người dùng và tôi không biết cách tra cứu ID người dùng từ tên đăng nhập. Tôi đã xem unistd.h và dường như chỉ có các chức năng để tìm thông tin về người dùng hiện tại.

Tôi biết tôi chỉ có thể mở /etc/passwd, nhưng tôi không muốn khi có ràng buộc là một chức năng cho việc này.

+2

Câu trả lời cho bạn một con cá; đây là cách để cá: 'man -k -s 3 password' và' man man' trong trường hợp bạn không biết lệnh đầu tiên có nghĩa là gì. – msw

Trả lời

15

Bạn muốn getpwnam.

Dưới đây là một ví dụ hoàn chỉnh tôi chỉ viết:

#define _POSIX_SOURCE 
#include <sys/types.h> 
#include <stdio.h> 
#include <pwd.h> 
#include <unistd.h> 

uid_t name_to_uid(char const *name) 
{ 
    if (!name) 
    return -1; 
    long const buflen = sysconf(_SC_GETPW_R_SIZE_MAX); 
    if (buflen == -1) 
    return -1; 
    // requires c99 
    char buf[buflen]; 
    struct passwd pwbuf, *pwbufp; 
    if (0 != getpwnam_r(name, &pwbuf, buf, buflen, &pwbufp) 
     || !pwbufp) 
    return -1; 
    return pwbufp->pw_uid; 
} 

void main(int argc, char **argv) 
{ 
    printf("%i\n", name_to_uid(argv[1])); 
} 
+0

Hình như chính xác những gì tôi cần. Cảm ơn rất nhiều! –

+0

'void main' là sai; nó phải là 'int main'. Và bạn nên kiểm tra giá trị của 'argc' trước khi truy cập' argv [1] '. –

+0

@KeithThompson: Đó là viết tắt của các mục đích ví dụ. Ràng buộc kiểm tra và xử lý lỗi bên ngoài hàm name_to_uid nằm ngoài phạm vi của câu trả lời. –

5

Một cách tiếp cận đơn giản sẽ là:

#include <pwd.h> 

#define INVALID_UID -1 
uid_t getuid_byName(const char *name) 
{ 
    if(name) { 
     struct passwd *pwd = getpwnam(name); /* don't free, see getpwnam() for details */ 
     if(pwd) return pwd->pw_uid; 
    } 
    return INVALID_UID; 
} 
Các vấn đề liên quan