Patch from Thiago Rondon <maluco@mileniumnet.com.br>
[freeradius.git] / src / modules / rlm_sql / sql_module.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        "radiusd.h"
31 #include        "rlm_sql.h"
32
33
34 /*************************************************************************
35  *
36  *      Function: sql_create_socket
37  *
38  *      Purpose: Establish connection to the db
39  *
40  *************************************************************************/
41 SQLSOCK *
42 sql_create_socket(SQL_INST * inst)
43 {
44
45         SQLSOCK *sqlsocket;
46
47         sqlsocket = rad_malloc(sizeof(SQLSOCK));
48
49         mysql_init(&(sqlsocket->conn));
50         if (!
51                         (sqlsocket->sock =
52                          mysql_real_connect(&(sqlsocket->conn), inst->config->sql_server,
53                                                                                                         inst->config->sql_login, inst->config->sql_password,
54                                                                                                         inst->config->sql_db, 0, NULL, CLIENT_FOUND_ROWS))) {
55                 radlog(L_ERR, "rlm_sql: Couldn't connect socket to MySQL server %s@%s:%s",
56                                          inst->config->sql_login, inst->config->sql_server,
57                                          inst->config->sql_db);
58                 radlog(L_ERR, "rlm_sql:  Mysql error '%s'",
59                                          mysql_error(&sqlsocket->conn));
60                 sqlsocket->sock = NULL;
61                 return NULL;
62         }
63
64         return sqlsocket;
65 }
66
67 /*************************************************************************
68  *
69  *      Function: sql_query
70  *
71  *      Purpose: Issue a query to the database
72  *
73  *************************************************************************/
74 int
75 sql_query(SQL_INST * inst, SQLSOCK * sqlsocket, char *querystr)
76 {
77
78         if (inst->config->sqltrace)
79                 DEBUG("query:  %s", querystr);
80         if (sqlsocket->sock == NULL) {
81                 radlog(L_ERR, "Socket not connected");
82                 return 0;
83         }
84         return mysql_query(sqlsocket->sock, querystr);
85 }
86
87
88 /*************************************************************************
89  *
90  *      Function: sql_select_query
91  *
92  *      Purpose: Issue a select query to the database
93  *
94  *************************************************************************/
95 int
96 sql_select_query(SQL_INST * inst, SQLSOCK * sqlsocket, char *querystr)
97 {
98
99         if (inst->config->sqltrace)
100                 DEBUG(querystr);
101         if (sqlsocket->sock == NULL) {
102                 radlog(L_ERR, "Socket not connected");
103                 return -1;
104         }
105         mysql_query(sqlsocket->sock, querystr);
106         if (sql_store_result(sqlsocket) && sql_num_fields(sqlsocket))
107                 return 0;
108         else
109                 return -1;
110 }
111
112
113 /*************************************************************************
114  *
115  *      Function: sql_store_result
116  *
117  *      Purpose: database specific store_result function. Returns a result
118  *               set for the query.
119  *
120  *************************************************************************/
121 int
122 sql_store_result(SQLSOCK * sqlsocket)
123 {
124
125         if (sqlsocket->sock == NULL) {
126                 radlog(L_ERR, "Socket not connected");
127                 return 0;
128         }
129         if (!(sqlsocket->result = mysql_store_result(sqlsocket->sock))) {
130                 radlog(L_ERR, "MYSQL Error: Cannot get result");
131                 radlog(L_ERR, "MYSQL Error: %s", mysql_error(sqlsocket->sock));
132                 return 0;
133         }
134         return 1;
135
136 }
137
138
139 /*************************************************************************
140  *
141  *      Function: sql_num_fields
142  *
143  *      Purpose: database specific num_fields function. Returns number
144  *               of columns from query
145  *
146  *************************************************************************/
147 int
148 sql_num_fields(SQLSOCK * sqlsocket)
149 {
150
151         int     num = 0;
152
153 #if MYSQL_VERSION_ID >= 32224
154         if (!(num = mysql_field_count(sqlsocket->sock))) {
155 #else
156         if (!(num = mysql_num_fields(sqlsocket->sock))) {
157 #endif
158                 radlog(L_ERR, "MYSQL Error: Cannot get result");
159                 radlog(L_ERR, "MYSQL error: %s", mysql_error(sqlsocket->sock));
160         }
161         return num;
162 }
163
164
165 /*************************************************************************
166  *
167  *      Function: sql_num_rows
168  *
169  *      Purpose: database specific num_rows. Returns number of rows in
170  *               query
171  *
172  *************************************************************************/
173 int
174 sql_num_rows(SQLSOCK * sqlsocket)
175 {
176
177         return mysql_num_rows(sqlsocket->result);
178 }
179
180
181 /*************************************************************************
182  *
183  *      Function: sql_fetch_row
184  *
185  *      Purpose: database specific fetch_row. Returns a SQL_ROW struct
186  *               with all the data for the query
187  *
188  *************************************************************************/
189 SQL_ROW
190 sql_fetch_row(SQLSOCK * sqlsocket)
191 {
192
193         return mysql_fetch_row(sqlsocket->result);
194 }
195
196
197
198 /*************************************************************************
199  *
200  *      Function: sql_free_result
201  *
202  *      Purpose: database specific free_result. Frees memory allocated
203  *               for a result set
204  *
205  *************************************************************************/
206 void
207 sql_free_result(SQLSOCK * sqlsocket)
208 {
209
210         if (sqlsocket->result) {
211                 mysql_free_result(sqlsocket->result);
212         }
213 }
214
215
216
217 /*************************************************************************
218  *
219  *      Function: sql_error
220  *
221  *      Purpose: database specific error. Returns error associated with
222  *               connection
223  *
224  *************************************************************************/
225 char   *
226 sql_error(SQLSOCK * sqlsocket)
227 {
228
229         return mysql_error(sqlsocket->sock);
230 }
231
232
233 /*************************************************************************
234  *
235  *      Function: sql_close
236  *
237  *      Purpose: database specific close. Closes an open database
238  *               connection
239  *
240  *************************************************************************/
241 void
242 sql_close(SQLSOCK * sqlsocket)
243 {
244
245         mysql_close(sqlsocket->sock);
246         sqlsocket->sock = NULL;
247 }
248
249
250 /*************************************************************************
251  *
252  *      Function: sql_finish_query
253  *
254  *      Purpose: End the query, such as freeing memory
255  *
256  *************************************************************************/
257 void
258 sql_finish_query(SQLSOCK * sqlsocket)
259 {
260
261 }
262
263
264
265 /*************************************************************************
266  *
267  *      Function: sql_finish_select_query
268  *
269  *      Purpose: End the select query, such as freeing memory or result
270  *
271  *************************************************************************/
272 void
273 sql_finish_select_query(SQLSOCK * sqlsocket)
274 {
275
276         sql_free_result(sqlsocket);
277 }
278
279
280 /*************************************************************************
281  *
282  *      Function: sql_affected_rows
283  *
284  *      Purpose: End the select query, such as freeing memory or result
285  *
286  *************************************************************************/
287 int
288 sql_affected_rows(SQLSOCK * sqlsocket)
289 {
290
291         return mysql_affected_rows(sqlsocket->sock);
292 }
293
294
295 /*************************************************************************
296  *
297  *      Function: sql_escape_string
298  *
299  *      Purpose: Esacpe "'" and any other wierd charactors
300  *
301  *************************************************************************/
302 int
303 sql_escape_string(char *to, char *from, int length)
304 {
305
306         mysql_escape_string(to, from, length);
307         return 1;
308 }