日期:2014-05-16 浏览次数:20991 次
#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);
}