日期:2014-05-16 浏览次数:20751 次
#include <sys/types.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <strings.h> #include <signal.h> #include <pwd.h> #include <errno.h> #include <security/pam_appl.h> extern int pam_tty_conv(int num_msg, struct pam_message **msg,struct pam_response **response, void *appdata_ptr); /* Disable keyboard interrupts (Ctrl-C, Ctrl-Z, Ctrl-\) */ static void disable_kbd_signals(void) {(void) signal(SIGINT, SIG_IGN); (void) signal(SIGTSTP, SIG_IGN); (void) signal(SIGQUIT, SIG_IGN); } /* Terminate current user session, i.e., logout */ static void logout() { pid_t pgroup = getpgrp(); (void) signal(SIGTERM, SIG_IGN); (void) fprintf(stderr, "Sorry, your session can't be restored.\n"); (void) fprintf(stderr, "Press return to terminate this session.\n"); (void) getchar(); (void) kill(-pgroup, SIGTERM); (void) sleep(2); (void) kill(-pgroup, SIGKILL); exit(-1); } int main(int argc, char *argv) { struct pam_conv conv = { pam_tty_conv, NULL }; pam_handle_t *pamh; struct passwd *pw; int err; disable_kbd_signals(); if ((pw = getpwuid(getuid())) == NULL) { (void) fprintf(stderr, "plock: Can't get username: %s\n", strerror(errno)); exit(1); } /* Initialize PAM framework */ err = pam_start("plock", pw->pw_name, &conv, &pamh); if (err != PAM_SUCCESS) { (void) fprintf(stderr, "plock: pam_start failed: %s\n", pam_strerror(pamh, err)); exit(1); } /* Authenticate user in order to unlock screen */ do { (void) fprintf(stderr, "Terminal locked for %s. ", pw->pw_name); err = pam_authenticate(pamh, 0); if (err == PAM_USER_UNKNOWN) logout(); else if (err != PAM_SUCCESS) { (void) fprintf(stderr, "Invalid password.\n"); } } while (err != PAM_SUCCESS); /* Make sure account and password are still valid */ switch (err = pam_acct_mgmt(pamh, 0)) { case PAM_USER_UNKNOWN: case PAM_ACCT_EXPIRED: /* User not allowed in anymore */ logout(); break; case PAM_NEW_AUTHTOK_REQD: /* The user's password has expired. Get a new one */ do { err = pam_chauthtok(pamh, 0); } while (err == PAM_AUTHTOK_ERR); if (err != PAM_SUCCESS) logout(); break; } if (pam_setcred(pamh, PAM_REFRESH_CRED)!= PAM_SUCCESS) { logout(); } (void) pam_end(pamh, 0); exit(0); }