/* * $Id: pam_module_authenticating_via_mysql.c,v 1.2 2004/12/07 15:12:38 cinar Exp $ * * cyrus-pam_auth.c: is a PAM module which provides Cyrus IMAP * authentication through MySQL database. The same approach * can be applied to other software/services as well. * * Copyright (c) 2000 Ali Onur Cinar * * Latest version may be downloaded from http://www.zdo.com * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. And also please * DO NOT REMOVE my name, and give me CREDIT when you use * whole or a part of this program in an other program. * * To compile using GNU C Compiler: * $ gcc -Wall -c -O7 -pipe -g cyrus-pam_auth.c * $ gcc -shared -Xlinker -x -lmysqlclient \ * -L/usr/local/lib/mysql -o cyrus-pam_auth.so \ * cyrus-pam_auth.o * $ install -c -m 755 cyrus-pam_auth.so /lib/security * $ /sbin/ldconfig /lib/security * * Post-Process: * Add the following line to your login program's PAM * configuration file (/etc/pam.d/login): * auth required cyrus-pam_auth.so * */ #include #include #include #include #include #define PS_DEBUG #define _PAM_EXTERN_FUNCTIONS #define DB "cyrus" #define USER "dbuser" #define PASS "dbpasswd" #define HOST "localhost" #define SUCCESS 1 #include int authenticate(const char *p, const char *u); int converse (pam_handle_t * pamh, int nargs, struct pam_message **message, struct pam_response **response) { int retval; struct pam_conv *conv; retval = pam_get_item (pamh, PAM_CONV, (const void **) &conv); if (retval == PAM_SUCCESS) { retval = conv->conv (nargs, (const struct pam_message **) message, response, conv->appdata_ptr); } return retval; } static void _pam_log (int err, const char *format,...) { va_list args; va_start (args, format); openlog ("pam-sql", LOG_PID, LOG_AUTH); vsyslog (err, format, args); va_end (args); closelog (); } int askPW (pam_handle_t * pamh) { const char *user; char *p; struct pam_message msg[1], *pmsg[1]; struct pam_response *resp; pmsg[0] = &msg[0]; msg[0].msg_style = PAM_PROMPT_ECHO_OFF; msg[0].msg = "passowrd:"; if (pam_get_user (pamh, &user, NULL) != PAM_SUCCESS) return PAM_USER_UNKNOWN; if (converse (pamh, 1, pmsg, &resp) != PAM_SUCCESS) return PAM_CONV_ERR; if (!resp) return PAM_CONV_ERR; p=resp[0].resp; resp[0].resp=NULL; pam_set_item(pamh, PAM_AUTHTOK, p); free(resp); return authenticate(p, user); } PAM_EXTERN int pam_sm_setcred (pam_handle_t * pamh, int flags, int argc,const char **argv) { // _pam_log (LOG_INFO, "set_cred called "); return PAM_SUCCESS; } PAM_EXTERN int pam_sm_authenticate (pam_handle_t * pamh, int flags, int argc, const char **argv) { // _pam_log (LOG_INFO, "auth called"); return askPW (pamh); } PAM_EXTERN int pam_sm_acct_mgmt (pam_handle_t * pamh, int flags, int argc, const char **argv) { // _pam_log (LOG_INFO, "acct_mgmt called"); return PAM_SUCCESS; } PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) { // _pam_log (LOG_INFO, "session opened"); return PAM_SUCCESS; } PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv) { // _pam_log (LOG_INFO, "session closed."); return PAM_SUCCESS; } int authenticate(const char *p, const char *u) { MYSQL *sock,mysql; MYSQL_RES *res; char qbuf[128]; sprintf(qbuf, "select user_id from users where username='%s' and password='%s'", u,p); mysql_init (&mysql); if (!(sock = mysql_real_connect(&mysql, HOST, USER, PASS, DB, 0, NULL, 0))) { //_pam_log(LOG_INFO,"couldnt connect to mysql"); //perror(""); return PAM_AUTH_ERR; } if (mysql_select_db(sock,DB)) { //_pam_log(LOG_INFO,"couldnt select database"); return PAM_AUTH_ERR; } if (mysql_query(sock,qbuf)) { //_pam_log(LOG_INFO, qbuf); return PAM_AUTH_ERR; } res = mysql_store_result(sock); if (mysql_num_rows(res) != 1) { //_pam_log(LOG_INFO,"login error"); mysql_close(sock); return PAM_AUTH_ERR; } else { //_pam_log(LOG_INFO,"logged in"); mysql_close(sock); return PAM_SUCCESS; } }