Removed unnecessary header files, as all they did was cause
[freeradius.git] / src / modules / rlm_sql / drivers / rlm_sql_mysql / sql_mysql.c
1 /*
2  * sql_mysql.c          SQL Module
3  *
4  * Version:     $Id$
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program; if not, write to the Free Software
18  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * Copyright 2000  The FreeRADIUS server project
21  * Copyright 2000  Mike Machado <mike@innercite.com>
22  * Copyright 2000  Alan DeKok <aland@ox.org>
23  */
24
25 #include <stdio.h>
26 #include <sys/stat.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include <mysql/errmsg.h>
31
32 #include        "radiusd.h"
33
34 #include        <mysql/mysql.h>
35 #include        "rlm_sql.h"
36
37 typedef struct rlm_sql_mysql_sock {
38         MYSQL conn;
39         MYSQL *sock;
40         MYSQL_RES *result;
41         SQL_ROW row;
42 } rlm_sql_mysql_sock;
43
44 /*************************************************************************
45  *
46  *      Function: sql_create_socket
47  *
48  *      Purpose: Establish connection to the db
49  *
50  *************************************************************************/
51 static int sql_init_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
52
53         rlm_sql_mysql_sock *mysql_sock;
54
55         sqlsocket->conn = (rlm_sql_mysql_sock *)rad_malloc(sizeof(rlm_sql_mysql_sock));
56
57         mysql_sock = sqlsocket->conn;
58
59         radlog(L_INFO, "rlm_sql: Starting connect to MySQL server for #%d",
60                         sqlsocket->id);
61
62         mysql_init(&(mysql_sock->conn));
63         if (!(mysql_sock->sock = mysql_real_connect(&(mysql_sock->conn), config->sql_server, config->sql_login, config->sql_password,
64                                                                                                         config->sql_db, 0, NULL, CLIENT_FOUND_ROWS))) {
65                 radlog(L_ERR, "rlm_sql: Couldn't connect socket to MySQL server %s@%s:%s", config->sql_login, config->sql_server, config->sql_db);
66                 radlog(L_ERR, "rlm_sql:  Mysql error '%s'", mysql_error(&mysql_sock->conn));
67                 mysql_sock->sock = NULL;
68                 return -1;
69         }
70
71
72         return 0;
73 }
74
75
76 /*************************************************************************
77  *
78  *      Function: sql_destroy_socket
79  *
80  *      Purpose: Free socket and any private connection data
81  *
82  *************************************************************************/
83 static int sql_destroy_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
84
85         rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
86
87         free(mysql_sock);
88         free(sqlsocket);
89
90         return 0;
91 }
92
93
94 /*************************************************************************
95  *
96  *      Function: sql_query
97  *
98  *      Purpose: Issue a query to the database
99  *
100  *************************************************************************/
101 static int sql_query(SQLSOCK * sqlsocket, SQL_CONFIG *config, char *querystr) {
102
103         rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
104
105         if (config->sqltrace)
106                 radlog(L_DBG,"query:  %s", querystr);
107         if (mysql_sock->sock == NULL) {
108                 radlog(L_ERR, "Socket not connected");
109                 return SQL_DOWN;
110         }
111
112         mysql_query(mysql_sock->sock, querystr);
113         return sql_check_error(mysql_errno(mysql_sock->sock));
114 }
115
116
117 /*************************************************************************
118  *
119  *      Function: sql_select_query
120  *
121  *      Purpose: Issue a select query to the database
122  *
123  *************************************************************************/
124 static int sql_select_query(SQLSOCK *sqlsocket, SQL_CONFIG *config, char *querystr) {
125
126         int ret;
127
128         ret = sql_query(sqlsocket, config, querystr);
129         if(ret)
130                 return ret;
131         ret = sql_store_result(sqlsocket, config);
132         if (ret) {
133                 return ret;
134         }
135
136         /* Why? Per http://www.mysql.com/doc/n/o/node_591.html,
137          * this cannot return an error.  Perhaps just to complain if no
138          * fields are found?
139          */
140         sql_num_fields(sqlsocket, config);
141
142         return ret;
143 }
144
145
146 /*************************************************************************
147  *
148  *      Function: sql_store_result
149  *
150  *      Purpose: database specific store_result function. Returns a result
151  *               set for the query.
152  *
153  *************************************************************************/
154 static int sql_store_result(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
155
156         rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
157
158         if (mysql_sock->sock == NULL) {
159                 radlog(L_ERR, "Socket not connected");
160                 return SQL_DOWN;
161         }
162         if (!(mysql_sock->result = mysql_store_result(mysql_sock->sock))) {
163                 radlog(L_ERR, "MYSQL Error: Cannot get result");
164                 radlog(L_ERR, "MYSQL Error: %s", mysql_error(mysql_sock->sock));
165                 return sql_check_error(mysql_errno(mysql_sock->sock));
166         }
167         return 0;
168 }
169
170
171 /*************************************************************************
172  *
173  *      Function: sql_num_fields
174  *
175  *      Purpose: database specific num_fields function. Returns number
176  *               of columns from query
177  *
178  *************************************************************************/
179 static int sql_num_fields(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
180
181
182         int     num = 0;
183         rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
184
185 #if MYSQL_VERSION_ID >= 32224
186         if (!(num = mysql_field_count(mysql_sock->sock))) {
187 #else
188         if (!(num = mysql_num_fields(mysql_sock->sock))) {
189 #endif
190                 radlog(L_ERR, "MYSQL Error: No Fields");
191                 radlog(L_ERR, "MYSQL error: %s", mysql_error(mysql_sock->sock));
192         }
193         return num;
194 }
195
196
197 /*************************************************************************
198  *
199  *      Function: sql_num_rows
200  *
201  *      Purpose: database specific num_rows. Returns number of rows in
202  *               query
203  *
204  *************************************************************************/
205 static int sql_num_rows(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
206
207         rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
208
209         if(mysql_sock->result)
210                 return mysql_num_rows(mysql_sock->result);
211
212         return 0;
213 }
214
215
216 /*************************************************************************
217  *
218  *      Function: sql_fetch_row
219  *
220  *      Purpose: database specific fetch_row. Returns a SQL_ROW struct
221  *               with all the data for the query in 'sqlsocket->row'. Returns
222  *               0 on success, -1 on failure, SQL_DOWN if database is down.
223  *
224  *************************************************************************/
225 static int sql_fetch_row(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
226
227         rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
228
229         sqlsocket->row = mysql_fetch_row(mysql_sock->result);
230
231         if (sqlsocket->row == NULL) {
232                 return sql_check_error(mysql_errno(mysql_sock->sock));
233         }
234         return 0;
235 }
236
237
238 /*************************************************************************
239  *
240  *      Function: sql_check_error
241  *
242  *      Purpose: check the error to see if the server is down
243  *
244  *************************************************************************/
245 static int sql_check_error(int error) {
246         switch(error) {
247         case CR_SERVER_GONE_ERROR:
248         case CR_SERVER_LOST:
249         case -1:
250                 radlog(L_DBG, "MYSQL check_error: %d, returning SQL_DOWN", error);
251                 return SQL_DOWN;
252                 break;
253         case 0:
254                 return 0;
255                 break;
256         case CR_OUT_OF_MEMORY:
257         case CR_COMMANDS_OUT_OF_SYNC:
258         case CR_UNKNOWN_ERROR:
259         default:
260                 radlog(L_DBG, "MYSQL check_error: %d received", error);
261                 return -1;
262                 break;
263         }
264 }
265
266
267
268 /*************************************************************************
269  *
270  *      Function: sql_free_result
271  *
272  *      Purpose: database specific free_result. Frees memory allocated
273  *               for a result set
274  *
275  *************************************************************************/
276 static int sql_free_result(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
277
278         rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
279
280         if (mysql_sock->result) {
281                 mysql_free_result(mysql_sock->result);
282         }
283
284         return 0;
285 }
286
287
288
289 /*************************************************************************
290  *
291  *      Function: sql_error
292  *
293  *      Purpose: database specific error. Returns error associated with
294  *               connection
295  *
296  *************************************************************************/
297 static char *sql_error(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
298
299         rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
300
301         return mysql_error(mysql_sock->sock);
302 }
303
304
305 /*************************************************************************
306  *
307  *      Function: sql_close
308  *
309  *      Purpose: database specific close. Closes an open database
310  *               connection
311  *
312  *************************************************************************/
313 static int sql_close(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
314
315         rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
316
317         mysql_close(mysql_sock->sock);
318         mysql_sock->sock = NULL;
319
320         return 0;
321 }
322
323
324 /*************************************************************************
325  *
326  *      Function: sql_finish_query
327  *
328  *      Purpose: End the query, such as freeing memory
329  *
330  *************************************************************************/
331 static int sql_finish_query(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
332
333         return 0;
334 }
335
336
337
338 /*************************************************************************
339  *
340  *      Function: sql_finish_select_query
341  *
342  *      Purpose: End the select query, such as freeing memory or result
343  *
344  *************************************************************************/
345 static int sql_finish_select_query(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
346
347         sql_free_result(sqlsocket, config);
348
349         return 0;
350 }
351
352
353 /*************************************************************************
354  *
355  *      Function: sql_affected_rows
356  *
357  *      Purpose: End the select query, such as freeing memory or result
358  *
359  *************************************************************************/
360 static int sql_affected_rows(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
361
362         rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
363
364         return mysql_affected_rows(mysql_sock->sock);
365 }
366
367
368 /* Exported to rlm_sql */
369 rlm_sql_module_t rlm_sql_mysql = {
370         "rlm_sql_mysql",
371         sql_init_socket,
372         sql_destroy_socket,
373         sql_query,
374         sql_select_query,
375         sql_store_result,
376         sql_num_fields,
377         sql_num_rows,
378         sql_fetch_row,
379         sql_free_result,
380         sql_error,
381         sql_close,
382         sql_finish_query,
383         sql_finish_select_query,
384         sql_affected_rows
385 };