/*
 *  pam_utmp_auth 1.1
 *  (C) Copyright 2003-2005 Wojtek Kaniewski <wojtekka@toxygen.net>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License Version 2 as
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/*
 *  Prosty moduł pozwalający się zalogować bez hasła, jeśli użytkownik jest
 *  już wpisany do /var/run/utmp z konsoli. Możliwe, że jest niebezpieczny,
 *  dlatego nie gwarantuję niczego. Udostępniony na zasadach licencji GPLv2.
 *
 *  Kompilacja:
 *     gcc pam_utmp_auth.c -o pam_utmp_auth.so -shared
 *     cp pam_utmp_auth.so /lib/security
 *
 *  Instalacja:
 *    dopisać na początku /etc/pam.d/login linię:
 *    "auth    sufficient     /lib/security/pam_utmp_auth.so"
 *
 *  Dostosowanie do PLD i vc: undefine@pld-linux.org
 */
 
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <stdarg.h>
#include <string.h>
#include <utmp.h>
#include <ctype.h>

#define PAM_SM_AUTH
#define PAM_MODULE_NAME "pam_utmp_auth"

#include <security/pam_modules.h>
#include <security/pam_misc.h>

static void _pam_log(int err, const char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);
	openlog(PAM_MODULE_NAME, LOG_PID, LOG_AUTH);
	vsyslog(err, fmt, ap);
	closelog();
	va_end(ap);
}

PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
{
	const char *user, *host, *tty;
	struct utmp *ut;

	if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS)
		return PAM_USER_UNKNOWN;

	if (pam_get_item(pamh, PAM_RHOST, (const void**) &host) != PAM_SUCCESS)
		return PAM_USER_UNKNOWN;

	if (pam_get_item(pamh, PAM_TTY, (const void**) &tty) != PAM_SUCCESS)
		return PAM_USER_UNKNOWN;
  
	if (!user || host || !tty)
		return PAM_AUTHTOK_ERR;

	while ((ut = getutent())) {
		if (ut->ut_type == USER_PROCESS && !strcmp(ut->ut_user, user) && (!strncmp(ut->ut_line, "tty", 3) || !strncmp(ut->ut_line, "vc/", 3)) && isdigit(ut->ut_line[3]))
			return PAM_SUCCESS;
	}
    
	_pam_log(LOG_INFO, "user=%s, rhost=%s, tty=%s", user, host, tty);
	return PAM_AUTHTOK_ERR;
}

PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv)
{
	return PAM_SUCCESS;
}
       
