2010-10-01 14 views
8

Versión corta: quiero una forma de ejecutar somefunction("username") y hacer que devuelva la identificación de usuario asociada con username. Por ejemplo, somefunction("root") devolvería 0.¿Cómo puedo obtener la identificación de usuario asociada con un inicio de sesión en Linux?

Estoy escribiendo un programa de servidor que podría utilizar puertos de bajo número, por lo que debe comenzar como root. Obviamente, no quiero que se ejecute como root, por lo que el plan es permitir que los usuarios especifiquen con qué usuario se ejecutará el programa. El problema es que setuid() requiere una identificación de usuario y no sé cómo buscar una identificación de usuario desde un nombre de usuario. Miré en unistd.h y parece que solo tiene funciones para encontrar información sobre el usuario actual.

Sé que podría simplemente abrir /etc/passwd, pero prefiero no cuando haya una función para esto.

+2

La respuesta que dio un pez; he aquí cómo pescar: 'man -k -s 3 password' y' man man' en caso de que no sepas lo que significa el primer comando. – msw

Respuesta

15

Quiere getpwnam.

Aquí está un ejemplo completo que acabo de escribir:

#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

Parece exactamente lo que necesitaba. ¡Muchas gracias! –

+0

'void main' es incorrecto; debería ser 'int main'. Y debe verificar el valor de 'argc' antes de acceder a' argv [1] '. –

+0

@KeithThompson: es corto para propósitos de ejemplo. La verificación de límites y el manejo de errores fuera de la función name_to_uid está fuera del alcance de la respuesta. –

5

Un enfoque más sencillo será:

#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; 
} 
Cuestiones relacionadas