]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Added m_sqloper, allows storage of opers within a mysql database
authorbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>
Mon, 25 Apr 2005 17:06:24 +0000 (17:06 +0000)
committerbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>
Mon, 25 Apr 2005 17:06:24 +0000 (17:06 +0000)
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@1187 e03df62e-2008-0410-955e-edbf42e46eb7

extras/m_sqloper.schema.sql [new file with mode: 0644]
src/modules/extra/m_sqloper.cpp [new file with mode: 0644]

diff --git a/extras/m_sqloper.schema.sql b/extras/m_sqloper.schema.sql
new file mode 100644 (file)
index 0000000..d4da959
--- /dev/null
@@ -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 (file)
index 0000000..fde5245
--- /dev/null
@@ -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;
+}
+