用于mysql验证的Pam模块

用于mysql验证的Pam模块,mysql,c,linux,pam,Mysql,C,Linux,Pam,我已经编写了pam模块来使用数据库对用户进行身份验证。所以我有一个数据库,我编译了这个将pam_sql.So添加到/lib/security并将它添加到pam.d中的公共auth中 account sufficient pam_param.so auth optional pam_param.so 但它根本不起作用。。。当我使用sudo登录时,我可以使用我帐户的凭据登录,但当我尝试使用存储在我数据库中的凭据时,它只会说:登录不正确。我不知道是我的代码出了问

我已经编写了pam模块来使用数据库对用户进行身份验证。所以我有一个数据库,我编译了这个将pam_sql.So添加到/lib/security并将它添加到pam.d中的公共auth中

account    sufficient     pam_param.so 
auth       optional     pam_param.so 
但它根本不起作用。。。当我使用sudo登录时,我可以使用我帐户的凭据登录,但当我尝试使用存储在我数据库中的凭据时,它只会说:登录不正确。我不知道是我的代码出了问题,还是我无法将它正确地连接到pam.d。我的pam代码如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <stdarg.h>
#include <alloca.h>
#include <string.h>

#include <mysql/mysql.h>

#define PAM_SM_AUTH

#define PAM_MODULE_NAME  "pam_mysql"

/* #define DEBUG */

#include <security/pam_modules.h> 
#include <security/pam_misc.h>
    /*Max length for most MySQL fields is 16 */

 char host[256]="localhost";
char db[17]="mysql";
char userdb[17]="root";
char password[17]="root";
char table[17]="user";
char usercolumn[17]="User";
char passwdcolumn[17]="Password";
int converse (pam_handle_t * pamh,
      int nargs,
      struct pam_message **message,
      struct pam_response **response);

int _set_auth_tok (pam_handle_t * pamh,
       int flags, int argc,
       const char **argv);

int db_connect (MYSQL * auth_sql_server)
{
int retvalue = PAM_AUTH_ERR;
MYSQL *mysql_auth = NULL;


mysql_init (auth_sql_server);
mysql_auth = mysql_real_connect (auth_sql_server,
                 host,
                 userdb,
                 password,
                db, 0, NULL, 0);

if (mysql_auth != NULL) {
    if (!mysql_select_db (auth_sql_server, db)) {
        retvalue = PAM_SUCCESS;
    }
}

return retvalue;
} 

 int checkpassword(MYSQL * auth_sql_server, const char *user, const char *passwd)
    {
    char query[256];
      char *pass,*passcrypt;
    pass=NULL;
    MYSQL_RES *result;
    MYSQL_ROW sql_row;
   int retvalue = PAM_AUTH_ERR;
    sprintf(query,"select %s from %s where %s='%s'",passwd,table,usercolumn,user);
    mysql_query(auth_sql_server,query);
    result=mysql_store_result(auth_sql_server);
if(!result)
{
    return PAM_AUTH_ERR;
}
if(mysql_num_rows(result)>=1)
{
sql_row=mysql_fetch_row(result);
pass=(char*)malloc(strlen(sql_row[0])*sizeof(char)+1);
if(!pass)
return PAM_AUTH_ERR;
strcpy(pass,sql_row[0]);
}
if (!strcmp (pass, passwd)) {
            retvalue = PAM_SUCCESS;
        } 
        free(pass);
        return retvalue;
    }
PAM_EXTERN int pam_sm_authenticate(pam_handle_t * pamh,int flags,int argc,const char    **argv)
{
int retval,i;
const char *user;
MYSQL serv;
char *passw;

retval=pam_get_user(pamh,&user,NULL);
if(retval!=PAM_SUCCESS)
return PAM_USER_UNKNOWN;
retval=pam_get_item(pamh,PAM_AUTHTOK,(const void**) &passw);
if(passw==NULL)
return PAM_AUTHINFO_UNAVAIL;
if((retval = db_connect (&serv))!=PAM_SUCCESS)
{
return retval;
}
if((retval==checkpassword(&serv,user,passw))!=PAM_SUCCESS)
{
return retval;
}

return retval;
}

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

  /*
  * Account management
  */

pam_sm_acct_mgmt ( pam_handle_t *pamh, int flags, int argc,
        const char *argv[] )
{
return PAM_SUCCESS;
}

/*
* Password management
*/

PAM_EXTERN int
pam_sm_chauthtok ( pam_handle_t *pamh, int flags, int argc,
        const char *argv[] )
{
return (PAM_SERVICE_ERR);
}



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;                  /* propagate error status */
   }

#ifdef PAM_MODULE_ENTRY
PAM_MODULE_ENTRY("pam_PTEIDCC");
#endif

我很乐意得到任何帮助。谢谢。

包括有关linux版本、linux发行版的详细信息。使用pam_调试时您看到了什么结果?在google中搜索pam调试。查看系统日志,LinuxPAM将日志记录到其中,如果使用systemd,则使用journalctl-xn。