2 * sql_module.c - MySQL routines for FreeRADIUS SQL module
4 * Mike Machado <mike@innercite.com>
16 /*************************************************************************
18 * Function: sql_connect
20 * Purpose: Connect to the sql server
22 *************************************************************************/
23 int sql_connect(void) {
28 /* Connect to the database server */
29 mysql_init(&MyAuthConn);
30 if (!(sql->AuthSock->conn = mysql_real_connect(&MyAuthConn, sql->config.sql_server, sql->config.sql_login, sql->config.sql_password, sql->config.sql_db, 0, NULL, 0))) {
31 log(L_ERR, "Init: Couldn't connect authentication socket to MySQL server on %s as %s", sql->config.sql_server, sql->config.sql_login);
32 sql->AuthSock->conn = NULL;
34 mysql_init(&MyAcctConn);
35 if (!(sql->AcctSock->conn = mysql_real_connect(&MyAcctConn, sql->config.sql_server, sql->config.sql_login, sql->config.sql_password, sql->config.sql_db, 0, NULL, 0))) {
36 log(L_ERR, "Init: Couldn't connect accounting socket to MySQL server on %s as %s", sql->config.sql_server, sql->config.sql_login);
37 sql->AcctSock->conn = NULL;
45 /*************************************************************************
47 * Function: sql_checksocket
49 * Purpose: Make sure our database connection is up
51 *************************************************************************/
52 int sql_checksocket(const char *facility) {
54 if ((strncmp(facility, "Auth", 4) == 0)) {
55 if (sql->AuthSock->conn == NULL) {
58 if (sql->config.sql_keepopen)
59 log(L_ERR, "%s: Keepopen set but had to reconnect to MySQL", facility);
60 /* Connect to the database server */
61 mysql_init(&MyAuthConn);
62 if (!(sql->AuthSock->conn = mysql_real_connect(&MyAuthConn, sql->config.sql_server, sql->config.sql_login, sql->config.sql_password, sql->config.sql_db, 0, NULL, 0))) {
63 log(L_ERR, "Auth: Couldn't connect authentication socket to MySQL server on %s as %s", sql->config.sql_server, sql->config.sql_login);
64 sql->AuthSock->conn = NULL;
70 if (sql->AcctSock->conn == NULL) {
72 if (sql->config.sql_keepopen)
73 log(L_ERR, "%s: Keepopen set but had to reconnect to MySQL", facility);
74 /* Connect to the database server */
75 mysql_init(&MyAcctConn);
76 if (!(sql->AcctSock->conn = mysql_real_connect(&MyAcctConn, sql->config.sql_server, sql->config.sql_login, sql->config.sql_password, sql->config.sql_db, 0, NULL, 0))) {
77 log(L_ERR, "Acct: Couldn't connect accounting socket to MySQL server on %s as %s", sql->config.sql_server, sql->config.sql_login);
78 sql->AcctSock->conn = NULL;
90 /*************************************************************************
94 * Purpose: Issue a query to the database
96 *************************************************************************/
97 int sql_query(SQLSOCK *socket, char *querystr) {
99 if (sql->config.sqltrace)
101 return mysql_query(socket->conn, querystr);
106 /*************************************************************************
108 * Function: sql_select_query
110 * Purpose: Issue a select query to the database
112 *************************************************************************/
113 int sql_select_query(SQLSOCK *socket, char *querystr) {
115 if (sql->config.sqltrace)
117 mysql_query(socket->conn, querystr);
118 if (sql_store_result(socket) && sql_num_fields(socket))
126 /*************************************************************************
128 * Function: sql_store_result
130 * Purpose: database specific store_result function. Returns a result
133 *************************************************************************/
134 int sql_store_result(SQLSOCK *socket) {
136 if (!(socket->result = mysql_store_result(socket->conn))) {
137 log(L_ERR,"MYSQL Error: Cannot get result");
138 log(L_ERR,"MYSQL error: %s",mysql_error(socket->conn));
147 /*************************************************************************
149 * Function: sql_num_fields
151 * Purpose: database specific num_fields function. Returns number
152 * of columns from query
154 *************************************************************************/
155 int sql_num_fields(SQLSOCK *socket) {
158 if (!(num = mysql_num_fields(socket->conn))) {
159 log(L_ERR,"MYSQL Error: Cannot get result");
160 log(L_ERR,"MYSQL error: %s",mysql_error(socket->conn));
167 /*************************************************************************
169 * Function: sql_num_rows
171 * Purpose: database specific num_rows. Returns number of rows in
174 *************************************************************************/
175 int sql_num_rows(SQLSOCK *socket) {
177 return mysql_num_rows(socket->result);
182 /*************************************************************************
184 * Function: sql_fetch_row
186 * Purpose: database specific fetch_row. Returns a SQL_RES struct
187 * with all the data for the query
189 *************************************************************************/
190 SQL_ROW sql_fetch_row(SQLSOCK *socket) {
192 return mysql_fetch_row(socket->result);
198 /*************************************************************************
200 * Function: sql_free_result
202 * Purpose: database specific free_result. Frees memory allocated
205 *************************************************************************/
206 void sql_free_result(SQLSOCK *socket) {
208 mysql_free_result(socket->result);
214 /*************************************************************************
216 * Function: sql_error
218 * Purpose: database specific error. Returns error associated with
221 *************************************************************************/
222 char *sql_error(SQLSOCK *socket) {
224 return (mysql_error(socket->conn));
229 /*************************************************************************
231 * Function: sql_close
233 * Purpose: database specific close. Closes an open database
236 *************************************************************************/
237 void sql_close(SQLSOCK *socket) {
239 mysql_close(socket->conn);
244 /*************************************************************************
246 * Function: sql_finish_query
248 * Purpose: End the query, such as freeing memory
250 *************************************************************************/
251 void sql_finish_query(SQLSOCK *socket) {
257 /*************************************************************************
259 * Function: sql_finish_select_query
261 * Purpose: End the select query, such as freeing memory or result
263 *************************************************************************/
264 void sql_finish_select_query(SQLSOCK *socket) {
266 sql_free_result(socket);
270 /*************************************************************************
272 * Function: sql_affected_rows
274 * Purpose: End the select quh as freeing memory or result
276 *************************************************************************/
277 int sql_affected_rows(SQLSOCK *socket) {
280 rows = mysql_affected_rows(socket->conn);
285 /*************************************************************************
287 * Function: sql_escape_string
289 * Purpose: strdup() with the added feature of escaping binary
290 * data in the string to safely fit into an SQL query
292 *************************************************************************/
293 char *sql_escape_string(const char *from) {
298 if((to=malloc((strlen(from)*2) + 1)) == NULL)
300 mysql_escape_string(to,from,strlen(from));