/* Writen by Devrim SERAL(devrim@tef.gazi.edu.tr) For PostgreSQL Authentication And Accounting 28-01-2001 This program protected with GPL License. */ #include "tac_plus.h" #if defined(DB_PGSQL) && defined(DB) #include #include #include #include #include "db_pgsql.h" #include "main.h" #include "report.h" #include "utils.h" #include "pwlib.h" static void exit_nicely TAC_ARGS((PGconn *cn, PGresult *r)); #define SQLCMDL 1024 #define PWLEN 13 #define AUTHSQL "SELECT %s FROM %s WHERE %s='%s'" #define ACCTSQL "INSERT INTO %s (usern,s_name,c_name,elapsed_time,bytes_in,bytes_out,fin_t) VALUES ('%s','%s','%s',%s,%s,%s,NOW())" static PGconn *conn; static PGresult *res; int pgsql_db_verify TAC_ARGS((const char *user, const char *users_passwd, const char *db_user, const char *db_password, const char *db_hostname, const char *db_name, const char *db_table, const char *dbfield_name, const char *dbfield_passwd)); int pgsql_db_verify(user, users_passwd, db_user, db_password, db_hostname, db_name, db_table, dbfield_name, dbfield_passwd) const char *user; /* username ... */ const char *users_passwd; /* ... and given password */ const char *db_user; /* db's parameters */ const char *db_password; const char *db_hostname; const char *db_name; const char *db_table; const char *dbfield_name; const char *dbfield_passwd; { char *real_passwd; char *pgsqlcmd; int sql_len; int nrow; if (debug & DEBUG_AUTHEN_FLAG) report(LOG_DEBUG, "PGSQL: verify %s", user); /* Connect database server */ conn=PQsetdbLogin(db_hostname,NULL,NULL,NULL,db_name,db_user,db_password); if ( PQstatus(conn) == CONNECTION_BAD ) { if (debug & DEBUG_AUTHEN_FLAG) report(LOG_DEBUG, "PGSQL: Connection to database %s failed", db_name); return(0); } /* Check select string length */ sql_len=strlen(dbfield_passwd)+strlen(dbfield_name)+strlen(db_table)+strlen(user)+strlen(AUTHSQL); if ( sql_len> SQLCMDL ) { if (debug & DEBUG_AUTHEN_FLAG) report(LOG_DEBUG, "PGSQL: Sql cmd exceed alowed limits"); return(0); } /* Prepare select string */ pgsqlcmd=(char *) tac_malloc(sql_len); sprintf(pgsqlcmd,AUTHSQL,dbfield_passwd,db_table,dbfield_name,user); /* Query database */ res=PQexec(conn,pgsqlcmd); if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) { if (debug & DEBUG_AUTHEN_FLAG) { report(LOG_DEBUG, "PGSQL: cannot query database "); report(LOG_DEBUG, "PGSQL: Error message->%s", PQerrorMessage(conn) ); } free(pgsqlcmd); exit_nicely(conn,res); return(0); } free(pgsqlcmd); if ( (nrow=PQntuples(res)) !=1 ) { if (debug & DEBUG_AUTHEN_FLAG) report(LOG_DEBUG, "PGSQL: Have we got more than one password!!"); exit_nicely(conn,res); return(0); } if ( PQgetisnull(res,0,PQfnumber(res,dbfield_passwd)) ) { if (debug & DEBUG_AUTHEN_FLAG) report(LOG_DEBUG, "PGSQL: DB passwd entry is NULL"); exit_nicely(conn,res); return(0); } /* Allocate memory for real_passwd */ real_passwd=(char *) tac_malloc(PWLEN+1); strncpy(real_passwd,PQgetvalue(res,0,PQfnumber(res,dbfield_passwd)),PWLEN); real_passwd[PWLEN]='\0'; exit_nicely(conn,res); if (debug & DEBUG_AUTHEN_FLAG) report(LOG_DEBUG, "PGSQL: verify password '%s' to DES encrypted string '%s'", users_passwd, real_passwd); /* Try to verify the password */ if (!des_verify(users_passwd, real_passwd)) return (0); return (1); /* Return 1 if verified, 0 otherwise. */ } /* PGSQL ACCOUNTING function */ int pgsql_db_acct TAC_ARGS((const char *db_user, const char *db_password, const char *db_hostname, const char *db_name, const char *db_table, const char *s_name, const char *c_name, const char *a_username, const char *elapsed_time, const char *bytes_in, const char *bytes_out)); int pgsql_db_acct(db_user,db_password,db_hostname,db_name,db_table,s_name,c_name,a_username,elapsed_time,bytes_in,bytes_out) const char *db_user; /* db's parameters */ const char *db_password; const char *db_hostname; const char *db_name; const char *db_table; const char *s_name; const char *c_name; const char *a_username; const char *elapsed_time; const char *bytes_in; const char *bytes_out; { char *pgsqlcmd; int sql_len; if (debug & DEBUG_ACCT_FLAG) report(LOG_DEBUG, "PGSQL: Accounting for %s begin", a_username); /* Connect database server */ conn=PQsetdbLogin(db_hostname,NULL,NULL,NULL,db_name,db_user,db_password); if ( PQstatus(conn) == CONNECTION_BAD ) { if (debug & DEBUG_ACCT_FLAG) { report(LOG_DEBUG, "PGSQL: Connection to database %s failed", db_name); report(LOG_DEBUG, "PGSQL: Error message->%s", PQerrorMessage(conn) ); } return(0); } /* Check select string length */ sql_len=strlen(db_table)+strlen(a_username)+strlen(s_name)+strlen(c_name)+strlen(elapsed_time)+strlen(bytes_in)+strlen(bytes_out)+strlen(ACCTSQL); if ( sql_len> SQLCMDL ) { if (debug & DEBUG_ACCT_FLAG) report(LOG_DEBUG, "PGSQL: Sql cmd exceed alowed limits"); return(0); } /* Prepare select string */ pgsqlcmd=(char *) tac_malloc(sql_len); sprintf(pgsqlcmd,ACCTSQL,db_table,a_username,s_name,c_name,elapsed_time,bytes_in,bytes_out); /* Query database */ res=PQexec(conn,pgsqlcmd); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK ) { if (debug & DEBUG_ACCT_FLAG) { report(LOG_DEBUG, "PGSQL: cannot establish database query"); report(LOG_DEBUG, "PGSQL: Error message->%s", PQerrorMessage(conn) ); } free(pgsqlcmd); exit_nicely(conn,res); return(0); } free(pgsqlcmd); /* Flush all result and close connection */ exit_nicely(conn,res); if (debug & DEBUG_ACCT_FLAG) report(LOG_DEBUG, "PGSQL: Accounting for %s finished", a_username); return (1); /* Return 1 if verified, 0 otherwise. */ } static void exit_nicely TAC_ARGS((PGconn *cn, PGresult *r)); static void exit_nicely(cn, r) PGconn *cn; PGresult *r; { PQclear(r); PQfinish(cn); } #else /* defined(DB_PGSQL) && defined(DB) */ TAC_SOURCEFILE_EMPTY #endif /* defined(DB_PGSQL) && defined(DB) */