2009-06-17 26 views
11

Estoy tratando de usar setuid() y setgid() para establecer los respectivos identificadores de un programa para reducir los privilegios hacia abajo desde la raíz, sino para usarlos Necesito saber el UID y GID del usuario Quiero cambiar a .¿Obtiene el UID y el GID mediante programación mediante un nombre de usuario en Unix?

¿Hay una llamada al sistema para hacer esto? No quiero codificarlo ni analizarlo desde/etc/passwd.

También me gustaría hacer esto mediante programación en lugar de utilizar:

Identificación -u USUARIO

Cualquier ayuda sería muy apreciada

+0

¿Qué pasa con el análisis/etc/password? – eduffy

+1

Debería haber dicho: "Preferiría no analizar/etc/passwd", ya que sospechaba que había una manera más fácil, y gracias a las respuestas, lo encontré. – Evan

+10

Una cosa incorrecta con el análisis/etc/passwd es que los nombres de usuario pueden no almacenarse allí; pueden estar en algún servidor de directorio (LDAP, etc.). Otra cosa incorrecta es que ya está hecho para ti, por getpwnam() et al. –

Respuesta

3

que desea utilizar el getpw * familia de las llamadas al sistema, generalmente en pwd.h. Básicamente es una interfaz de nivel C para la información en/etc/passwd.

1

Mira getpwnam y estructura 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

Nunca libre de '' pwd' o buffer' - pero ¿por qué te molestas para asignar '' pwd' o buffer' en el montón de todos modos – Siler

+0

@Siler, añadí los libera. Estoy de acuerdo en que se puede hacer en la pila (la única advertencia es asegurarse sysconf (_SC_GETPW_R_SIZE_MAX) no es demasiado grande (que es poco probable que sea en cualquier sistema realista). Sin embargo, no voy a volver a escribir para ese –

+0

Esto es genial _cuando conoces el nombre de usuario_, pero no es un reemplazo para 'getuid()'. –

0

Se pueden utilizar los siguientes fragmentos de código:

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

Ref: getpwnam()getgrnam()

Cuestiones relacionadas