--- autologin-1.0.0.orig/src/autologin.c 2010-04-02 13:33:10 +0400 +++ autologin-1.0.0/src/autologin.c 2010-04-02 13:41:02 +0400 @@ -19,6 +19,9 @@ #include #include #include +#include +#include +#include static int PAM_conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { /* We use PAM to authenticate for pam_console only, we don't need @@ -37,6 +40,33 @@ { kill(child, SIGTERM); } + +static int +is_a_console(int fd) { + char arg; + + arg = 0; + return (ioctl(fd, KDGKBTYPE, &arg) == 0 + && ((arg == KB_101) || (arg == KB_84))); +} + +static int +open_a_console(const char *fnam) { + int fd; + + fd = open(fnam, O_RDWR); + if (fd < 0) + fd = open(fnam, O_WRONLY); + if (fd < 0) + fd = open(fnam, O_RDONLY); + if (fd < 0) + return -1; + if (!is_a_console(fd)) { + close(fd); + return -1; + } + return fd; +} #endif char runthis[1024]; @@ -56,7 +86,9 @@ int outfd; #ifdef HAVE_PAM pam_handle_t *pamh; - int status; + int status, fd; + struct vt_stat vtstat; + char console[6]; #endif runthis[0]=0; runthis[1023]=0; @@ -159,10 +191,29 @@ /* Take console ownership and satisfy PAM */ #ifdef HAVE_PAM + fd = open_a_console("/proc/self/fd/0"); + if (fd < 0) + fd = open_a_console("/dev/tty"); + if (fd < 0) + fd = open_a_console("/dev/tty0"); + if (fd < 0) + fd = open_a_console("/dev/vc/0"); + if (fd < 0) + fd = open_a_console("/dev/console"); + if (fd < 0) { + free(dir); free(shell); + puts("autologin ERROR: Couldn't get a file descriptor referring to the console"); + return 1; + } + if (ioctl(fd, VT_GETSTATE, &vtstat)) { + puts("autologin ERROR: Can't get VT_GETSTATE of the console"); + return 1; + } + sprintf(console, "%s%d", "tty", vtstat.v_active); pam_start("autologin", user, &PAM_conversation, &pamh); pam_acct_mgmt(pamh, PAM_SILENT); pam_set_item(pamh, PAM_USER, user); - pam_set_item(pamh, PAM_TTY, "tty0"); + pam_set_item(pamh, PAM_TTY, console); pam_set_item(pamh, PAM_RHOST, NULL); pam_set_item(pamh, PAM_RUSER, user); pam_open_session(pamh, PAM_SILENT);