summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--extras/m_sqloper.schema.sql23
-rw-r--r--src/modules/extra/m_sqloper.cpp225
2 files changed, 248 insertions, 0 deletions
diff --git a/extras/m_sqloper.schema.sql b/extras/m_sqloper.schema.sql
new file mode 100644
index 000000000..d4da959c2
--- /dev/null
+++ b/extras/m_sqloper.schema.sql
@@ -0,0 +1,23 @@
+-- MySQL dump 9.11
+--
+-- Host: localhost Database: brain
+-- ------------------------------------------------------
+-- Server version 4.0.20
+
+--
+-- Table structure for table `ircd_opers`
+--
+
+CREATE TABLE ircd_opers (
+ id bigint(20) NOT NULL auto_increment,
+ username text,
+ password text,
+ type text,
+ PRIMARY KEY (id)
+) TYPE=MyISAM;
+
+--
+-- Dumping data for table `ircd_opers`
+--
+
+
diff --git a/src/modules/extra/m_sqloper.cpp b/src/modules/extra/m_sqloper.cpp
new file mode 100644
index 000000000..fde524567
--- /dev/null
+++ b/src/modules/extra/m_sqloper.cpp
@@ -0,0 +1,225 @@
+/* +------------------------------------+
+ * | Inspire Internet Relay Chat Daemon |
+ * +------------------------------------+
+ *
+ * Inspire is copyright (C) 2002-2004 ChatSpike-Dev.
+ * E-mail:
+ * <brain@chatspike.net>
+ * <Craig@chatspike.net>
+ *
+ * Written by Craig Edwards, Craig McLure, and others.
+ * This program is free but copyrighted software; see
+ * the file COPYING for details.
+ *
+ * ---------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <string>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <poll.h>
+#include "users.h"
+#include "channels.h"
+#include "modules.h"
+#include "inspircd.h"
+#include "m_sql.h"
+
+/* $ModDesc: Allows storage of oper credentials in an SQL table */
+
+Server *Srv;
+
+class ModuleSQLOper : public Module
+{
+ ConfigReader* Conf;
+ unsigned long dbid;
+ Module* SQLModule;
+
+ public:
+ bool ReadConfig()
+ {
+ dbid = Conf->ReadInteger("sqloper","dbid",0,true); // database id of a database configured in m_sql (see m_sql config)
+ SQLModule = Srv->FindModule("m_sql.so");
+ if (!SQLModule)
+ Srv->Log(DEFAULT,"WARNING: m_sqloper.so could not initialize because m_sql.so is not loaded. Load the module and rehash your server.");
+ return (SQLModule);
+ }
+
+ ModuleSQLOper()
+ {
+ Srv = new Server;
+ Conf = new ConfigReader();
+ ReadConfig();
+ }
+
+ virtual void OnRehash()
+ {
+ delete Conf;
+ Conf = new ConfigReader();
+ ReadConfig();
+ }
+
+ virtual int OnPreCommand(std::string command, char **parameters, int pcnt, userrec *user)
+ {
+ if (command == "OPER")
+ {
+ if (LookupOper(parameters[0],parameters[1],user))
+ return 1;
+ }
+ return 0;
+ }
+
+ bool LookupOper(std::string username, std::string password, userrec* user)
+ {
+ bool found = false;
+
+ // is the sql module loaded? If not, we don't attempt to do anything.
+ if (!SQLModule)
+ return false;
+
+ // sanitize the password (we dont want any mysql insertion exploits!)
+ std::string temp = "";
+ for (int q = 0; q < password.length(); q++)
+ {
+ if (password[q] == '\'')
+ {
+ temp = temp + "\'";
+ }
+ else if (password[q] == '"')
+ {
+ temp = temp + "\\\"";
+ }
+ else temp = temp + password[q];
+ }
+ password = temp;
+ temp = "";
+ for (int v = 0; v < username.length(); v++)
+ {
+ if (username[v] == '\'')
+ {
+ temp = temp + "\'";
+ }
+ if (username[v] == '"')
+ {
+ temp = temp + "\\\"";
+ }
+ else temp = temp + username[v];
+ }
+ username = temp;
+
+ // Create a request containing the SQL query and send it to m_sql.so
+ SQLRequest* query = new SQLRequest(SQL_RESULT,dbid,"SELECT username,password,type FROM ircd_opers WHERE username='"+username+"' AND password=md5('"+password+"')");
+ Request queryrequest((char*)query, this, SQLModule);
+ SQLResult* result = (SQLResult*)queryrequest.Send();
+
+ // Did we get "OK" as a result?
+ if (result->GetType() == SQL_OK)
+ {
+ Srv->Log(DEBUG,"An SQL based oper exists");
+ // if we did, this means we may now request a row... there should be only one row for each user, so,
+ // we don't need to loop to fetch multiple rows.
+ SQLRequest* rowrequest = new SQLRequest(SQL_ROW,dbid,"");
+ Request rowquery((char*)rowrequest, this, SQLModule);
+ SQLResult* rowresult = (SQLResult*)rowquery.Send();
+
+ // did we get a row? If we did, we can now do something with the fields
+ if (rowresult->GetType() == SQL_ROW)
+ {
+ if (rowresult->GetField("username") == username)
+ {
+ found = true;
+ // oper up the user.
+ for (int j =0; j < Conf->Enumerate("type"); j++)
+ {
+ std::string TypeName = Conf->ReadValue("type","name",j);
+ if (TypeName == rowresult->GetField("type"))
+ {
+ /* found this oper's opertype */
+ Srv->MeshSendAll("| "+std::string(user->nick)+" "+TypeName);
+ std::string HostName = Conf->ReadValue("type","host",j);
+ Srv->ChangeHost(user,HostName);
+ strlcpy(user->oper,TypeName.c_str(),NICKMAX);
+ WriteOpers("*** %s (%s@%s) is now an IRC operator of type %s",user->nick,user->ident,user->host,rowresult->GetField("type").c_str());
+ WriteServ(user->fd,"381 %s :You are now an IRC operator of type %s",user->nick,rowresult->GetField("type").c_str());
+ if (!strchr(user->modes,'o'))
+ {
+ strcat(user->modes,"o");
+ WriteServ(user->fd,"MODE %s :+o",user->nick);
+ Srv->MeshSendAll("M "+std::string(user->nick)+" +o");
+ Module* Logger = Srv->FindModule("m_sqllog.so");
+ if (Logger)
+ Logger->OnOper(user);
+ log(DEFAULT,"OPER: %s!%s@%s opered as type: %s",user->nick,user->ident,user->host,rowresult->GetField("type").c_str());
+ }
+ break;
+ }
+ }
+
+ }
+ delete rowresult;
+ }
+ else
+ {
+ // we didn't have a row.
+ found = false;
+ }
+ delete rowrequest;
+ delete result;
+ }
+ else
+ {
+ // the query was bad
+ found = false;
+ }
+ query->SetQueryType(SQL_DONE);
+ query->SetConnID(dbid);
+ Request donerequest((char*)query, this, SQLModule);
+ donerequest.Send();
+ delete query;
+ return found;
+ }
+
+ virtual ~ModuleSQLOper()
+ {
+ delete Conf;
+ delete Srv;
+ }
+
+ virtual Version GetVersion()
+ {
+ return Version(1,0,0,1,VF_VENDOR);
+ }
+
+};
+
+class ModuleSQLOperFactory : public ModuleFactory
+{
+ public:
+ ModuleSQLOperFactory()
+ {
+ }
+
+ ~ModuleSQLOperFactory()
+ {
+ }
+
+ virtual Module * CreateModule()
+ {
+ return new ModuleSQLOper;
+ }
+
+};
+
+
+extern "C" void * init_module( void )
+{
+ return new ModuleSQLOperFactory;
+}
+