Massively cleaned up #include's, so they're in a consistent
[freeradius.git] / src / modules / rlm_sql / drivers / rlm_sql_mysql / sql_mysql.c
index 8922520..8da0503 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
- * Copyright 2000  The FreeRADIUS server project
+ * Copyright 2000,2006  The FreeRADIUS server project
  * Copyright 2000  Mike Machado <mike@innercite.com>
  * Copyright 2000  Alan DeKok <aland@ox.org>
  */
 
-#include <stdio.h>
+#include <freeradius-devel/ident.h>
+RCSID("$Id$")
+
+#include <freeradius-devel/radiusd.h>
+
 #include <sys/stat.h>
-#include <stdlib.h>
-#include <string.h>
 
-#include <mysql/errmsg.h>
+#include "config.h"
 
-#include       "radiusd.h"
+#ifdef HAVE_MYSQL_MYSQL_H
+#include <mysql/mysql_version.h>
+#include <mysql/errmsg.h>
+#include <mysql/mysql.h>
+#else
+#ifdef HAVE_MYSQL_H
+#include <mysql_version.h>
+#include <errmsg.h>
+#include <mysql.h>
+#endif
+#endif
 
-#include       <mysql/mysql.h>
 #include       "rlm_sql.h"
 
 typedef struct rlm_sql_mysql_sock {
@@ -48,22 +59,34 @@ typedef struct rlm_sql_mysql_sock {
  *     Purpose: Establish connection to the db
  *
  *************************************************************************/
-static int sql_init_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
-
+static int sql_init_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config)
+{
        rlm_sql_mysql_sock *mysql_sock;
 
-       sqlsocket->conn = (rlm_sql_mysql_sock *)rad_malloc(sizeof(rlm_sql_mysql_sock));
-
+       if (!sqlsocket->conn) {
+               sqlsocket->conn = (rlm_sql_mysql_sock *)rad_malloc(sizeof(rlm_sql_mysql_sock));
+               if (!sqlsocket->conn) {
+                       return -1;
+               }
+       }
        mysql_sock = sqlsocket->conn;
+       memset(mysql_sock, 0, sizeof(*mysql_sock));
 
-       radlog(L_INFO, "rlm_sql: Starting connect to MySQL server for #%d",
+       radlog(L_INFO, "rlm_sql_mysql: Starting connect to MySQL server for #%d",
                        sqlsocket->id);
 
        mysql_init(&(mysql_sock->conn));
-       if (!(mysql_sock->sock = mysql_real_connect(&(mysql_sock->conn), config->sql_server, config->sql_login, config->sql_password,
-                                                                                                       config->sql_db, 0, NULL, CLIENT_FOUND_ROWS))) {
-               radlog(L_ERR, "rlm_sql: Couldn't connect socket to MySQL server %s@%s:%s", config->sql_login, config->sql_server, config->sql_db);
-               radlog(L_ERR, "rlm_sql:  Mysql error '%s'", mysql_error(&mysql_sock->conn));
+       mysql_options(&(mysql_sock->conn), MYSQL_READ_DEFAULT_GROUP, "freeradius");
+       if (!(mysql_sock->sock = mysql_real_connect(&(mysql_sock->conn),
+                                                   config->sql_server,
+                                                   config->sql_login,
+                                                   config->sql_password,
+                                                   config->sql_db,
+                                                   atoi(config->sql_port),
+                                                   NULL,
+                                                   CLIENT_FOUND_ROWS))) {
+               radlog(L_ERR, "rlm_sql_mysql: Couldn't connect socket to MySQL server %s@%s:%s", config->sql_login, config->sql_server, config->sql_db);
+               radlog(L_ERR, "rlm_sql_mysql: Mysql error '%s'", mysql_error(&mysql_sock->conn));
                mysql_sock->sock = NULL;
                return -1;
        }
@@ -80,12 +103,10 @@ static int sql_init_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
  *     Purpose: Free socket and any private connection data
  *
  *************************************************************************/
-static int sql_destroy_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
-
-       rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
-
-       free(mysql_sock);
-       free(sqlsocket);
+static int sql_destroy_socket(SQLSOCK *sqlsocket, UNUSED SQL_CONFIG *config)
+{
+       free(sqlsocket->conn);
+       sqlsocket->conn = NULL;
 
        return 0;
 }
@@ -93,53 +114,54 @@ static int sql_destroy_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
 
 /*************************************************************************
  *
- *     Function: sql_query
+ *     Function: sql_check_error
  *
- *     Purpose: Issue a query to the database
+ *     Purpose: check the error to see if the server is down
  *
  *************************************************************************/
-static int sql_query(SQLSOCK * sqlsocket, SQL_CONFIG *config, char *querystr) {
-
-       rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
-
-       if (config->sqltrace)
-               radlog(L_DBG,"query:  %s", querystr);
-       if (mysql_sock->sock == NULL) {
-               radlog(L_ERR, "Socket not connected");
+static int sql_check_error(int error)
+{
+       switch(error) {
+       case CR_SERVER_GONE_ERROR:
+       case CR_SERVER_LOST:
+       case -1:
+               radlog(L_DBG, "rlm_sql_mysql: MYSQL check_error: %d, returning SQL_DOWN", error);
                return SQL_DOWN;
+               break;
+       case 0:
+               return 0;
+               break;
+       case CR_OUT_OF_MEMORY:
+       case CR_COMMANDS_OUT_OF_SYNC:
+       case CR_UNKNOWN_ERROR:
+       default:
+               radlog(L_DBG, "rlm_sql_mysql: MYSQL check_error: %d received", error);
+               return -1;
+               break;
        }
-
-       mysql_query(mysql_sock->sock, querystr);
-       return sql_check_error(mysql_errno(mysql_sock->sock));
 }
 
 
 /*************************************************************************
  *
- *     Function: sql_select_query
+ *     Function: sql_query
  *
- *     Purpose: Issue a select query to the database
+ *     Purpose: Issue a query to the database
  *
  *************************************************************************/
-static int sql_select_query(SQLSOCK *sqlsocket, SQL_CONFIG *config, char *querystr) {
-
-       int ret;
+static int sql_query(SQLSOCK * sqlsocket, SQL_CONFIG *config, char *querystr)
+{
+       rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
 
-       ret = sql_query(sqlsocket, config, querystr);
-       if(ret)
-               return ret;
-       ret = sql_store_result(sqlsocket, config);
-       if (ret) {
-               return ret;
+       if (config->sqltrace)
+               radlog(L_DBG,"rlm_sql_mysql: query:  %s", querystr);
+       if (mysql_sock->sock == NULL) {
+               radlog(L_ERR, "rlm_sql_mysql: Socket not connected");
+               return SQL_DOWN;
        }
 
-       /* Why? Per http://www.mysql.com/doc/n/o/node_591.html,
-        * this cannot return an error.  Perhaps just to complain if no
-        * fields are found?
-        */
-       sql_num_fields(sqlsocket, config);
-
-       return ret;
+       mysql_query(mysql_sock->sock, querystr);
+       return sql_check_error(mysql_errno(mysql_sock->sock));
 }
 
 
@@ -151,17 +173,18 @@ static int sql_select_query(SQLSOCK *sqlsocket, SQL_CONFIG *config, char *querys
  *               set for the query.
  *
  *************************************************************************/
-static int sql_store_result(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
-
+static int sql_store_result(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config)
+{
        rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
 
        if (mysql_sock->sock == NULL) {
-               radlog(L_ERR, "Socket not connected");
+               radlog(L_ERR, "rlm_sql_mysql: Socket not connected");
                return SQL_DOWN;
        }
        if (!(mysql_sock->result = mysql_store_result(mysql_sock->sock))) {
-               radlog(L_ERR, "MYSQL Error: Cannot get result");
-               radlog(L_ERR, "MYSQL Error: %s", mysql_error(mysql_sock->sock));
+               radlog(L_ERR, "rlm_sql_mysql: MYSQL Error: Cannot get result");
+               radlog(L_ERR, "rlm_sql_mysql: MYSQL Error: %s",
+                      mysql_error(mysql_sock->sock));
                return sql_check_error(mysql_errno(mysql_sock->sock));
        }
        return 0;
@@ -176,9 +199,8 @@ static int sql_store_result(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
  *               of columns from query
  *
  *************************************************************************/
-static int sql_num_fields(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
-
-
+static int sql_num_fields(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config)
+{
        int     num = 0;
        rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
 
@@ -187,8 +209,9 @@ static int sql_num_fields(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
 #else
        if (!(num = mysql_num_fields(mysql_sock->sock))) {
 #endif
-               radlog(L_ERR, "MYSQL Error: No Fields");
-               radlog(L_ERR, "MYSQL error: %s", mysql_error(mysql_sock->sock));
+               radlog(L_ERR, "rlm_sql_mysql: MYSQL Error: No Fields");
+               radlog(L_ERR, "rlm_sql_mysql: MYSQL error: %s",
+                      mysql_error(mysql_sock->sock));
        }
        return num;
 }
@@ -196,17 +219,47 @@ static int sql_num_fields(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
 
 /*************************************************************************
  *
+ *     Function: sql_select_query
+ *
+ *     Purpose: Issue a select query to the database
+ *
+ *************************************************************************/
+static int sql_select_query(SQLSOCK *sqlsocket, SQL_CONFIG *config,
+                           char *querystr)
+{
+       int ret;
+
+       ret = sql_query(sqlsocket, config, querystr);
+       if(ret)
+               return ret;
+       ret = sql_store_result(sqlsocket, config);
+       if (ret) {
+               return ret;
+       }
+
+       /* Why? Per http://www.mysql.com/doc/n/o/node_591.html,
+        * this cannot return an error.  Perhaps just to complain if no
+        * fields are found?
+        */
+       sql_num_fields(sqlsocket, config);
+
+       return ret;
+}
+
+
+/*************************************************************************
+ *
  *     Function: sql_num_rows
  *
  *     Purpose: database specific num_rows. Returns number of rows in
  *               query
  *
  *************************************************************************/
-static int sql_num_rows(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
-
+static int sql_num_rows(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config)
+{
        rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
 
-       if(mysql_sock->result)
+       if (mysql_sock->result)
                return mysql_num_rows(mysql_sock->result);
 
        return 0;
@@ -222,10 +275,17 @@ static int sql_num_rows(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
  *              0 on success, -1 on failure, SQL_DOWN if database is down.
  *
  *************************************************************************/
-static int sql_fetch_row(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
-
+static int sql_fetch_row(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config)
+{
        rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
 
+       /*
+        *  Check pointer before de-referencing it.
+        */
+       if (!mysql_sock->result) {
+               return SQL_DOWN;
+       }
+
        sqlsocket->row = mysql_fetch_row(mysql_sock->result);
 
        if (sqlsocket->row == NULL) {
@@ -237,48 +297,19 @@ static int sql_fetch_row(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
 
 /*************************************************************************
  *
- *     Function: sql_check_error
- *
- *     Purpose: check the error to see if the server is down
- *
- *************************************************************************/
-static int sql_check_error(int error) {
-       switch(error) {
-       case CR_SERVER_GONE_ERROR:
-       case CR_SERVER_LOST:
-       case -1:
-               radlog(L_DBG, "MYSQL check_error: %d, returning SQL_DOWN", error);
-               return SQL_DOWN;
-               break;
-       case 0:
-               return 0;
-               break;
-       case CR_OUT_OF_MEMORY:
-       case CR_COMMANDS_OUT_OF_SYNC:
-       case CR_UNKNOWN_ERROR:
-       default:
-               radlog(L_DBG, "MYSQL check_error: %d received", error);
-               return -1;
-               break;
-       }
-}
-
-
-
-/*************************************************************************
- *
  *     Function: sql_free_result
  *
  *     Purpose: database specific free_result. Frees memory allocated
  *               for a result set
  *
  *************************************************************************/
-static int sql_free_result(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
-
+static int sql_free_result(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config)
+{
        rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
 
        if (mysql_sock->result) {
                mysql_free_result(mysql_sock->result);
+               mysql_sock->result = NULL;
        }
 
        return 0;
@@ -294,10 +325,13 @@ static int sql_free_result(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
  *               connection
  *
  *************************************************************************/
-static char *sql_error(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
-
+static char *sql_error(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config)
+{
        rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
 
+       if (mysql_sock == NULL || mysql_sock->sock == NULL) {
+               return "rlm_sql_mysql: no connection to db";
+       }
        return mysql_error(mysql_sock->sock);
 }
 
@@ -310,12 +344,14 @@ static char *sql_error(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
  *               connection
  *
  *************************************************************************/
-static int sql_close(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
-
+static int sql_close(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config)
+{
        rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
 
-       mysql_close(mysql_sock->sock);
-       mysql_sock->sock = NULL;
+       if (mysql_sock && mysql_sock->sock){
+               mysql_close(mysql_sock->sock);
+               mysql_sock->sock = NULL;
+       }
 
        return 0;
 }
@@ -328,8 +364,8 @@ static int sql_close(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
  *     Purpose: End the query, such as freeing memory
  *
  *************************************************************************/
-static int sql_finish_query(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
-
+static int sql_finish_query(UNUSED SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config)
+{
        return 0;
 }
 
@@ -342,8 +378,8 @@ static int sql_finish_query(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
  *     Purpose: End the select query, such as freeing memory or result
  *
  *************************************************************************/
-static int sql_finish_select_query(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
-
+static int sql_finish_select_query(SQLSOCK * sqlsocket, SQL_CONFIG *config)
+{
        sql_free_result(sqlsocket, config);
 
        return 0;
@@ -357,8 +393,8 @@ static int sql_finish_select_query(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
  *     Purpose: End the select query, such as freeing memory or result
  *
  *************************************************************************/
-static int sql_affected_rows(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
-
+static int sql_affected_rows(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config)
+{
        rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
 
        return mysql_affected_rows(mysql_sock->sock);