¿Cuál es la forma correcta de autenticar a un usuario sin PAM?

¿Cuál es la forma correcta de autenticar a un usuario sin PAM?

Como mi pregunta relacionada no parece recibir mucho amor, aquí otra: ¿Cuál es la forma correcta de autenticar a un usuario mediante la solicitud de nombre de usuario/contraseña en Linux hoy en día?

En principio, supongo que tendría que obtener el nombre de usuario y la contraseña, leer salt y hash del usuario correspondiente de /etc/shadow. Luego calcularía el hash de la contraseña dada y la sal almacenada y comprobaría si el resultado coincide con el hash almacenado en /etc/shadow.

Normalmente, podría simplemente autenticarme a través de PAM (por ejemplo pam_unix), que ya hace todo esto, pero mi aplicación es un módulo PAM personalizado y no encontré ningún método para llamar a un módulo PAM desde otro. Si esto es posible de alguna manera, con mucho gusto buscaría esta solución.

A partir de ahora, encontré este tutorial realmente anticuado.http://www.tldp.org/HOWTO/Shadow-Password-HOWTO-8.htmldesde 1996 cuando, aparentemente, el soporte oculto aún no estaba integrado en libc. Menciona pw_authy validcomo funciones auxiliares para la autenticación. Intenté implantarlos en mi código y vincularlos con libshadow.alas herramientas de sombra, pero obtengo errores de "referencia externa no resuelta" para pw_authy valid. El código se parece a esto:

if ((pw->pw_passwd && pw->pw_passwd[0] == '@'
     && pw_auth (pw->pw_passwd+1, pw->pw_name, PW_LOGIN, NULL))
    || !valid (passwd, pw)) {
    return (UPAP_AUTHNAK);
}

No he verificado esto más, pero de todos modos esta no es la solución preferida ya que tendría que actualizar mi código cada vez que se actualizan Shadow-Utils.

Preferiría vincularme a una biblioteca (que no sea PAM) que proporcione autenticación contra /etc/shadow. ¿Existe tal cosa y aún no la encontré? ¿O alguna otra solución?

Respuesta1

En mi opinión, el miedo a una actualización de Shadow-Utils es injustificado. Las rutinas descritas en ese CÓMO están disponibles en mis sistemas Ubuntu 12.04 y Mint 17 sin instalar nada especial.

La estructura para leer /etc/shadowinformación en un programa C se puede encontrar en /usr/include/shadow.hy con man 5 shadowlas funciones que necesitaría encontrar, por ejemplo, una entrada de contraseña oculta por nombre como se define en /usr/include/shadow.his getspnamy que también le brindará una página de manual ( man getspnam) que describe eso y todas las funciones relacionadas.

En base a eso, debería poder obtener la entrada de contraseña con hash para cualquier nombre de pila. La contraseña con hash debe tener múltiples tokens '$', eliminar todo lo que sigue e incluir el último '$' de la contraseña con hash y presentarlo como salt a crypt(), la versión glibc (según man 3 crypt) debería poder manejar las sales "extendidas" que indican entradas SHA512 como son más comunes hoy en día.

información relacionada