2010-10-01 9 views
8

Krótka wersja: chcę, aby uruchomić program somefunction("username") i zwrócić mu identyfikator użytkownika powiązany z username. Na przykład somefunction("root") zwróci 0.Jak mogę uzyskać identyfikator użytkownika powiązany z loginem w systemie Linux?

Piszę program serwera, który może potencjalnie używać portów o niskim numerze, więc musi zaczynać się jako root. Oczywiście nie chcę, aby działał jako root, więc plan polega na umożliwieniu użytkownikom określenia, który użytkownik powinien uruchomić program. Problem polega na tym, że setuid() wymaga identyfikatora użytkownika i nie wiem, jak wyszukać identyfikator użytkownika z nazwy logowania. Spojrzałem w unistd.h i wydaje się, że ma tylko funkcje do wyszukiwania informacji o bieżącym użytkowniku.

Wiem, że mogę po prostu otworzyć /etc/passwd, ale wolałbym, gdy nie ma być funkcja do tego.

+2

Odpowiedź dał ci rybę; oto jak łowić ryby: 'man -k -s 3 password' oraz' man man' w przypadku, gdy nie wiesz, co oznacza pierwsze polecenie. – msw

Odpowiedz

15

Chcesz getpwnam.

Oto pełna przykład Właśnie napisał:

#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

Wygląda dokładnie tak, jak potrzebowałem. Wielkie dzięki! –

+0

'void main' jest źle; powinno to być 'int main'. Powinieneś sprawdzić wartość 'argc' przed uzyskaniem dostępu do' argv [1] '. –

+0

@KeithThompson: Jest krótki dla celów przykładowych. Sprawdzanie granic i obsługa błędów poza funkcją name_to_uid jest poza zakresem odpowiedzi. –

5

Prostsze podejście będzie:

#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; 
} 
Powiązane problemy