22725fe333e709debdbc77ecf82a612b836a8368
[tac_plus.git] / db_pgsql.c
1 #if defined(DB_PGSQL) && defined(DB)
2
3 /*
4 Writen by Devrim SERAL(devrim@tef.gazi.edu.tr)
5 For PostgreSQL Authentication And Accounting
6                 28-01-2001
7 This program protected with GPL License. 
8 */
9
10 #include "tac_plus.h"
11 #include <stdio.h>
12 #include "libpq-fe.h" 
13 #define SQLCMDL 1024
14 #define PWLEN   13
15 #define AUTHSQL "SELECT %s FROM %s WHERE %s='%s'"
16 #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())"  
17
18 PGconn     *conn;
19 PGresult   *res;
20
21 int pgsql_db_verify(user, users_passwd, db_user, db_password,
22         db_hostname,db_name, db_table, dbfield_name, dbfield_passwd)
23
24
25 char *user, *users_passwd;      /* Username and gived password   */
26 char *db_user;                  /* db's parameters               */
27 char *db_password;
28 char *db_hostname;
29 char *db_name;
30 char *db_table;
31 char *dbfield_name;
32 char *dbfield_passwd;
33
34 {
35
36 char *real_passwd;
37 char *pgsqlcmd;
38 int sql_len;
39 int nrow;
40
41 if (debug & DEBUG_AUTHEN_FLAG)
42         report(LOG_DEBUG, "PGSQL: verify %s", user);
43         
44 /* Connect database server */
45
46 conn=PQsetdbLogin(db_hostname,NULL,NULL,NULL,db_name,db_user,db_password);
47
48 if ( PQstatus(conn) == CONNECTION_BAD ) 
49 {
50     if (debug & DEBUG_AUTHEN_FLAG)
51         report(LOG_DEBUG, "PGSQL: Connection to database %s failed", db_name);
52         return(0);
53 }
54
55 /* Check select string length */
56
57 sql_len=strlen(dbfield_passwd)+strlen(dbfield_name)+strlen(db_table)+strlen(user)+strlen(AUTHSQL);
58
59 if ( sql_len> SQLCMDL )
60 {
61     if (debug & DEBUG_AUTHEN_FLAG)
62         report(LOG_DEBUG, "PGSQL: Sql cmd exceed alowed limits");
63         return(0);
64 }
65
66 /* Prepare select string */
67
68 pgsqlcmd=(char *) malloc(sql_len);
69
70 if(pgsqlcmd==NULL) 
71
72     if (debug & DEBUG_AUTHEN_FLAG)
73         report(LOG_ERR, "pgsql_db_verify: pgsqlcmd malloc error");
74         return(0);
75 }
76
77 sprintf(pgsqlcmd,AUTHSQL,dbfield_passwd,db_table,dbfield_name,user);
78
79 /*  Query database */
80 res=PQexec(conn,pgsqlcmd);
81
82 if (!res || PQresultStatus(res) != PGRES_TUPLES_OK)
83 {
84    if (debug & DEBUG_AUTHEN_FLAG) {
85         report(LOG_DEBUG, "PGSQL: cannot query database ");
86         report(LOG_DEBUG, "PGSQL: Error message->%s", PQerrorMessage(conn) );
87    }
88         free(pgsqlcmd);
89         exit_nicely(conn,res);
90         return(0);
91 }
92
93 free(pgsqlcmd);
94
95 if( nrow=PQntuples(res)!=1) 
96 {  
97     if (debug & DEBUG_AUTHEN_FLAG)
98         report(LOG_DEBUG, "PGSQL: Have we got more than one password!!");
99         exit_nicely(conn,res);
100         return(0);
101 }  
102   
103 if ( PQgetisnull(res,0,PQfnumber(res,dbfield_passwd)) ) 
104 {
105     if (debug & DEBUG_AUTHEN_FLAG)
106         report(LOG_DEBUG, "PGSQL: DB passwd entry is NULL");
107         exit_nicely(conn,res);
108         return(0);
109 }
110
111   /* Allocate memory for real_passwd */
112         real_passwd=(char *) malloc(PWLEN+1);
113         strncpy(real_passwd,PQgetvalue(res,0,PQfnumber(res,dbfield_passwd)),PWLEN);
114         real_passwd[PWLEN]='\0';
115  
116 exit_nicely(conn,res);
117   
118 if (debug & DEBUG_AUTHEN_FLAG)
119         report(LOG_DEBUG, "PGSQL: verify password '%s' to DES encrypted string '%s'", users_passwd, real_passwd);
120  
121         /* Try to verify the password */
122         if (!des_verify(users_passwd, real_passwd)) 
123         {
124         return (0);
125         }
126
127     return (1); /* Return 1 if verified, 0 otherwise. */
128 }
129
130 /*      PGSQL ACCOUNTING function       */ 
131
132 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)
133
134 char *db_user;                  /* db's parameters              */
135 char *db_password;
136 char *db_hostname;
137 char *db_name;
138 char *db_table;
139 char *s_name, *c_name,*a_username,*elapsed_time,*bytes_in,*bytes_out;
140
141 {
142
143 char *pgsqlcmd;
144 int sql_len;
145
146   if (debug & DEBUG_ACCT_FLAG)
147         report(LOG_DEBUG, "PGSQL: Accounting for %s begin", a_username);
148         
149 /* Connect database server */
150
151 conn=PQsetdbLogin(db_hostname,NULL,NULL,NULL,db_name,db_user,db_password);
152
153 if ( PQstatus(conn) == CONNECTION_BAD ) 
154 {
155    if (debug & DEBUG_ACCT_FLAG) {
156         report(LOG_DEBUG, "PGSQL: Connection to database %s failed", db_name);
157         report(LOG_DEBUG, "PGSQL: Error message->%s", PQerrorMessage(conn) );
158    }
159         return(0);
160 }
161
162 /* Check select string length */
163
164 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); 
165
166 if ( sql_len> SQLCMDL )
167 {
168    if (debug & DEBUG_ACCT_FLAG) 
169         report(LOG_DEBUG, "PGSQL: Sql cmd exceed alowed limits");
170         return(0);
171 }
172
173 /* Prepare select string */
174
175 pgsqlcmd=(char *) malloc(sql_len);
176
177 if(pgsqlcmd==NULL) 
178 {
179 if (debug & DEBUG_ACCT_FLAG) 
180         report(LOG_ERR, "pgsql_db_verify: pgsqlcmd malloc error");
181         return(0);
182 }
183
184 sprintf(pgsqlcmd,ACCTSQL,db_table,a_username,s_name,c_name,elapsed_time,bytes_in,bytes_out);
185  
186 /*  Query database */
187 res=PQexec(conn,pgsqlcmd);
188
189 if (!res || PQresultStatus(res) != PGRES_COMMAND_OK )
190 {
191  if (debug & DEBUG_ACCT_FLAG) { 
192         report(LOG_DEBUG, "PGSQL: cannot establish database query");
193         report(LOG_DEBUG, "PGSQL: Error message->%s", PQerrorMessage(conn) );
194 }
195         free(pgsqlcmd);
196         exit_nicely(conn,res);
197         return(0);
198 }
199
200 free(pgsqlcmd);
201     
202 /* Flush all result and close connection */
203 exit_nicely(conn,res);
204
205     if (debug & DEBUG_ACCT_FLAG)
206         report(LOG_DEBUG, "PGSQL: Accounting for %s finished", a_username);
207   
208     return (1); /* Return 1 if verified, 0 otherwise. */
209 }
210
211 int
212 exit_nicely(PGconn *cn,PGresult *r)
213 {
214     PQclear(r);
215     PQfinish(cn);
216 }
217
218 #endif