+// MySQL stuff
+#undef _GNU_SOURCE // HACK to silence compiler warning on redefinition in my_global.h
+#include <my_global.h>
+#include <mysql.h>
+
+
+
+
+
+/**
+ * Attempt to login by searching a MySQL database
+ * @param user - Username
+ * @param pass - Password
+ * @param db_host - Host running the DataBase
+ * @param db_user - User to search the database as
+ * @param db_pass - Password for the database user
+ * @param db_name - Name of the database to use
+ * @param db_table - Table to search in
+ * @returns Privelage level of the user or USER_UNAUTH for failure to authenticate
+ */
+UserType Login_MySQL(const char * user, const char * pass,
+ const char * db_host, const char * db_user, const char * db_pass, const char * db_name, const char * db_table)
+{
+ MYSQL * con = mysql_init(NULL);
+ if (con == NULL)
+ {
+ Log(LOGERR, "mysql_init failed - %s", mysql_error(con));
+ return USER_UNAUTH;
+ }
+
+ if (mysql_real_connect(con, db_host, db_user, db_pass, NULL, 0, NULL, 0) == NULL)
+ {
+ Log(LOGERR, "mysql_real_connect failed - %s", mysql_error(con));
+ mysql_close(con);
+ return USER_UNAUTH;
+ }
+
+ char buffer[BUFSIZ];
+
+ // Select the database
+ sprintf(buffer, "USE %s;", db_name);
+ if (mysql_query(con, buffer))
+ {
+ Log(LOGERR, "mysql_query failed - %s", mysql_error(con));
+ mysql_close(con);
+ return USER_UNAUTH;
+ }
+
+ // Search for the user
+ sprintf(buffer, "SELECT password FROM %s WHERE user_name = \"%s\";", db_table, user);
+ if (mysql_query(con, buffer))
+ {
+ Log(LOGERR, "mysql_query failed - %s", mysql_error(con));
+ mysql_close(con);
+ return USER_UNAUTH;
+ }
+
+ // Process the result
+ MYSQL_RES * result = mysql_store_result(con);
+ if (result == NULL)
+ {
+ Log(LOGERR, "mysql_store_result failed - %s", mysql_error(con));
+ mysql_close(con);
+ return USER_UNAUTH;
+ }
+
+ int num_fields = mysql_num_fields(result);
+ if (num_fields != 1)
+ {
+ Log(LOGERR, "The database may be corrupt; %d fields found, expected %d", num_fields, 1);
+ mysql_close(con);
+ return USER_UNAUTH;
+ }
+
+ UserType user_type = USER_UNAUTH;
+ MYSQL_ROW row;
+
+ // Get first row
+ if ((row = mysql_fetch_row(result)))
+ {
+ if (strcmp(crypt(pass, row[0]), row[0]) == 0)
+ {
+ user_type = USER_NORMAL;
+ }
+
+ // There should only be one row. Through a hissy fit if we see any more.
+ if ((row = mysql_fetch_row(result)))
+ {
+ Log(LOGERR, "Too many rows found.");
+ user_type = USER_UNAUTH;
+ }
+ }
+ else
+ {
+ Log(LOGERR, "No user matching %s", user);
+ }
+
+ //TODO: Handle administrator users somehow better than this
+ // UserCake stores the permission level in a seperate table to the username/password, which is annoying
+ if (user_type != USER_UNAUTH && strcmp(user, "admin") == 0)
+ {
+ user_type = USER_ADMIN;
+ }
+ mysql_free_result(result);
+ mysql_close(con);
+ return user_type;
+}
+