1 /* +------------------------------------+
2 * | Inspire Internet Relay Chat Daemon |
3 * +------------------------------------+
5 * InspIRCd is copyright (C) 2002-2004 ChatSpike-Dev.
7 * <brain@chatspike.net>
8 * <Craig@chatspike.net>
10 * Written by Craig Edwards, Craig McLure, and others.
11 * This program is free but copyrighted software; see
12 * the file COPYING for details.
14 * ---------------------------------------------------
23 #include <sys/types.h>
24 #include <sys/socket.h>
35 #include "configreader.h"
36 #include "helperfuncs.h"
38 #include "commands/cmd_oper.h"
40 /* $ModDesc: Allows storage of oper credentials in an SQL table */
42 /* Required for the FOREACH_MOD alias (OnOper event) */
44 extern ServerConfig* Config;
45 extern std::vector<Module*> modules;
46 extern std::vector<ircd_module*> factory;
48 class ModuleSQLOper : public Module
58 dbid = Conf->ReadInteger("sqloper","dbid",0,true); // database id of a database configured in m_sql (see m_sql config)
59 SQLModule = Srv->FindModule("m_sql.so");
61 Srv->Log(DEFAULT,"WARNING: m_sqloper.so could not initialize because m_sql.so is not loaded. Load the module and rehash your server.");
65 ModuleSQLOper(Server* Me)
69 Conf = new ConfigReader();
73 virtual void OnRehash(const std::string ¶meter)
76 Conf = new ConfigReader();
80 void Implements(char* List)
82 List[I_OnRehash] = List[I_OnPreCommand] = 1;
85 virtual int OnPreCommand(const std::string &command, const char** parameters, int pcnt, userrec *user, bool validated)
87 if ((command == "OPER") && (validated))
89 if (LookupOper(parameters[0],parameters[1],user))
95 bool LookupOper(const std::string &s_username, const std::string &s_password, userrec* user)
99 // is the sql module loaded? If not, we don't attempt to do anything.
103 // sanitize the password (we dont want any mysql insertion exploits!)
104 std::string username = SQLQuery::Sanitise(s_username);
105 std::string password = SQLQuery::Sanitise(s_password);
107 // Create a request containing the SQL query and send it to m_sql.so
108 SQLRequest* query = new SQLRequest(SQL_RESULT,dbid,"SELECT username,password,hostname,type FROM ircd_opers WHERE username='"+username+"' AND password=md5('"+password+"')");
109 Request queryrequest((char*)query, this, SQLModule);
110 SQLResult* result = (SQLResult*)queryrequest.Send();
112 // Did we get "OK" as a result?
113 if (result->GetType() == SQL_OK)
115 Srv->Log(DEBUG,"An SQL based oper exists");
116 // if we did, this means we may now request a row... there should be only one row for each user, so,
117 // we don't need to loop to fetch multiple rows.
118 SQLRequest* rowrequest = new SQLRequest(SQL_ROW,dbid,"");
119 Request rowquery((char*)rowrequest, this, SQLModule);
120 SQLResult* rowresult = (SQLResult*)rowquery.Send();
122 // did we get a row? If we did, we can now do something with the fields
123 if (rowresult->GetType() == SQL_ROW)
125 if (rowresult->GetField("username") == username)
130 for (int j =0; j < Conf->Enumerate("type"); j++)
132 std::string TypeName = Conf->ReadValue("type","name",j);
133 Srv->Log(DEBUG,"Scanning opertype: "+TypeName);
134 std::string pattern = std::string(user->ident) + "@" + std::string(user->host);
136 if((TypeName == rowresult->GetField("type")) && OneOfMatches(pattern.c_str(), rowresult->GetField("hostname").c_str()))
138 /* found this oper's opertype */
139 Srv->Log(DEBUG,"Host and type match: "+TypeName+" "+rowresult->GetField("type"));
140 std::string HostName = Conf->ReadValue("type","host",j);
143 Srv->ChangeHost(user,HostName);
145 strlcpy(user->oper,rowresult->GetField("type").c_str(),NICKMAX-1);
146 WriteOpers("*** %s (%s@%s) is now an IRC operator of type %s",user->nick,user->ident,user->host,rowresult->GetField("type").c_str());
147 WriteServ(user->fd,"381 %s :You are now an IRC operator of type %s",user->nick,rowresult->GetField("type").c_str());
148 if(user->modes[UM_OPERATOR])
150 user->modes[UM_OPERATOR] = 1;
151 WriteServ(user->fd,"MODE %s :+o",user->nick);
152 FOREACH_MOD(I_OnOper,OnOper(user,rowresult->GetField("type")));
154 FOREACH_MOD(I_OnPostOper,OnPostOper(user,rowresult->GetField("type")));
155 log(DEFAULT,"OPER: %s!%s@%s opered as type: %s",user->nick,user->ident,user->host,rowresult->GetField("type").c_str());
167 // we didn't have a row.
179 query->SetQueryType(SQL_DONE);
180 query->SetConnID(dbid);
181 Request donerequest((char*)query, this, SQLModule);
187 virtual ~ModuleSQLOper()
192 virtual Version GetVersion()
194 return Version(1,0,0,1,VF_VENDOR);
199 class ModuleSQLOperFactory : public ModuleFactory
202 ModuleSQLOperFactory()
206 ~ModuleSQLOperFactory()
210 virtual Module * CreateModule(Server* Me)
212 return new ModuleSQLOper(Me);
218 extern "C" void * init_module( void )
220 return new ModuleSQLOperFactory;