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