Jeff Carneal <jeff@apex.net>
[freeradius.git] / src / modules / rlm_sql / sql_module.c
1 /***************************************************************************
2 *  sql_mysql.c                        rlm_sql - FreeRADIUS SQL Module      *
3 *                                                                          *
4 *      MySQL routines for rlm_sql                                          *
5 *                                                                          *
6 *                                     Mike Machado <mike@innercite.com>    *
7 ***************************************************************************/
8 #include <stdio.h>
9 #include <sys/stat.h>
10 #include <stdlib.h>
11 #include <string.h>
12
13 #include        "radiusd.h"
14 #include        "rlm_sql.h"
15
16
17 /*************************************************************************
18  *
19  *      Function: sql_create_socket
20  *
21  *      Purpose: Establish connection to the db
22  *
23  *************************************************************************/
24 SQLSOCK *sql_create_socket(SQL_INST *inst) {
25         SQLSOCK *socket;
26
27         if ((socket = malloc(sizeof(SQLSOCK))) == NULL) {
28                 radlog(L_CONS|L_ERR, "sql_create_socket: no memory");
29                 exit(1);
30         }
31
32         mysql_init(&(socket->conn));
33         if (!(socket->sock = mysql_real_connect(&(socket->conn), inst->config->sql_server, inst->config->sql_login, inst->config->sql_password, inst->config->sql_db, 0, NULL, CLIENT_FOUND_ROWS))) {
34                 radlog(L_ERR, "rlm_sql: Couldn't connect socket to MySQL server %s@%s:%s", inst->config->sql_login, inst->config->sql_server, inst->config->sql_db);
35                 radlog(L_ERR, "rlm_sql:  Mysql error '%s'", mysql_error(&socket->conn));
36                 socket->sock = NULL;
37                 return NULL;
38         }
39         return socket;
40 }
41
42 /*************************************************************************
43  *
44  *      Function: sql_query
45  *
46  *      Purpose: Issue a query to the database
47  *
48  *************************************************************************/
49 int sql_query(SQL_INST *inst, SQLSOCK *socket, char *querystr) {
50
51         if (inst->config->sqltrace)
52                 DEBUG(querystr);
53          if (socket->sock == NULL) {
54                 radlog(L_ERR, "Socket not connected");
55                 return 0;
56         }
57         return mysql_query(socket->sock, querystr);
58 }
59
60
61 /*************************************************************************
62  *
63  *      Function: sql_select_query
64  *
65  *      Purpose: Issue a select query to the database
66  *
67  *************************************************************************/
68 int sql_select_query(SQL_INST *inst, SQLSOCK *socket, char *querystr) {
69
70         if (inst->config->sqltrace)
71                 DEBUG(querystr);
72         if (socket->sock == NULL) {
73                 radlog(L_ERR, "Socket not connected");
74                 return 0;
75         }
76         mysql_query(socket->sock, querystr);
77         if (sql_store_result(socket) && sql_num_fields(socket)) 
78                 return 1;
79         else
80                 return 0;
81 }
82
83
84 /*************************************************************************
85  *
86  *      Function: sql_store_result
87  *
88  *      Purpose: database specific store_result function. Returns a result
89  *               set for the query.
90  *
91  *************************************************************************/
92 int sql_store_result(SQLSOCK *socket) {
93
94         if (socket->sock == NULL) {
95                 radlog(L_ERR, "Socket not connected");
96                 return 0;
97         }
98         if (!(socket->result = mysql_store_result(socket->sock))) {
99                 radlog(L_ERR,"MYSQL Error: Cannot get result");
100                 radlog(L_ERR,"MYSQL Error: %s",mysql_error(socket->sock));
101                 return 0;
102         }
103         return 1;
104
105 }
106
107
108 /*************************************************************************
109  *
110  *      Function: sql_num_fields
111  *
112  *      Purpose: database specific num_fields function. Returns number
113  *               of columns from query
114  *
115  *************************************************************************/
116 int sql_num_fields(SQLSOCK *socket) {
117
118         int     num = 0;
119 #if MYSQL_VERSION_ID >= 32224
120         if (!(num = mysql_field_count(socket->sock))) {
121 #else
122         if (!(num = mysql_num_fields(socket->sock))) {
123 #endif
124                 radlog(L_ERR,"MYSQL Error: Cannot get result");
125                 radlog(L_ERR,"MYSQL error: %s",mysql_error(socket->sock));
126         }
127         return num;
128 }
129
130
131 /*************************************************************************
132  *
133  *      Function: sql_num_rows
134  *
135  *      Purpose: database specific num_rows. Returns number of rows in
136  *               query
137  *
138  *************************************************************************/
139 int sql_num_rows(SQLSOCK *socket) {
140
141         return mysql_num_rows(socket->result);
142 }
143
144
145 /*************************************************************************
146  *
147  *      Function: sql_fetch_row
148  *
149  *      Purpose: database specific fetch_row. Returns a SQL_ROW struct
150  *               with all the data for the query
151  *
152  *************************************************************************/
153 SQL_ROW sql_fetch_row(SQLSOCK *socket) {
154
155         return mysql_fetch_row(socket->result);
156 }
157
158
159
160 /*************************************************************************
161  *
162  *      Function: sql_free_result
163  *
164  *      Purpose: database specific free_result. Frees memory allocated
165  *               for a result set
166  *
167  *************************************************************************/
168 void sql_free_result(SQLSOCK *socket) {
169
170         mysql_free_result(socket->result);
171 }
172
173
174
175 /*************************************************************************
176  *
177  *      Function: sql_error
178  *
179  *      Purpose: database specific error. Returns error associated with
180  *               connection
181  *
182  *************************************************************************/
183 char *sql_error(SQLSOCK *socket) {
184
185         return mysql_error(socket->sock);
186 }
187
188
189 /*************************************************************************
190  *
191  *      Function: sql_close
192  *
193  *      Purpose: database specific close. Closes an open database
194  *               connection
195  *
196  *************************************************************************/
197 void sql_close(SQLSOCK *socket) {
198
199         mysql_close(socket->sock);
200         socket->sock = NULL;
201 }
202
203
204 /*************************************************************************
205  *
206  *      Function: sql_finish_query
207  *
208  *      Purpose: End the query, such as freeing memory
209  *
210  *************************************************************************/
211 void sql_finish_query(SQLSOCK *socket) {
212
213 }
214
215
216
217 /*************************************************************************
218  *
219  *      Function: sql_finish_select_query
220  *
221  *      Purpose: End the select query, such as freeing memory or result
222  *
223  *************************************************************************/
224 void sql_finish_select_query(SQLSOCK *socket) {
225
226         sql_free_result(socket);
227 }
228
229
230 /*************************************************************************
231  *
232  *      Function: sql_affected_rows
233  *
234  *      Purpose: End the select query, such as freeing memory or result
235  *
236  *************************************************************************/
237 int sql_affected_rows(SQLSOCK *socket) {
238
239         return mysql_affected_rows(socket->sock);
240 }
241
242
243 /*************************************************************************
244  *
245  *      Function: sql_escape_string
246  *
247  *      Purpose: Esacpe "'" and any other wierd charactors
248  *
249  *************************************************************************/
250 int sql_escape_string(char *to, char *from, int length) {
251
252         mysql_escape_string(to, from, length);
253         return 1;
254 }