1 /* +------------------------------------+
2 * | Inspire Internet Relay Chat Daemon |
3 * +------------------------------------+
5 * Inspire 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 * ---------------------------------------------------
21 #include <sys/types.h>
22 #include <sys/socket.h>
33 #include "helperfuncs.h"
36 /* $ModDesc: Allows storage of oper credentials in an SQL table */
40 class ModuleSQLOper : public Module
49 dbid = Conf->ReadInteger("sqloper","dbid",0,true); // database id of a database configured in m_sql (see m_sql config)
50 SQLModule = Srv->FindModule("m_sql.so");
52 Srv->Log(DEFAULT,"WARNING: m_sqloper.so could not initialize because m_sql.so is not loaded. Load the module and rehash your server.");
59 Conf = new ConfigReader();
63 virtual void OnRehash()
66 Conf = new ConfigReader();
70 virtual int OnPreCommand(std::string command, char **parameters, int pcnt, userrec *user)
72 if (command == "OPER")
74 if (LookupOper(parameters[0],parameters[1],user))
80 bool LookupOper(std::string username, std::string password, userrec* user)
84 // is the sql module loaded? If not, we don't attempt to do anything.
88 // sanitize the password (we dont want any mysql insertion exploits!)
89 std::string temp = "";
90 for (int q = 0; q < password.length(); q++)
92 if (password[q] == '\'')
96 else if (password[q] == '"')
100 else temp = temp + password[q];
104 for (int v = 0; v < username.length(); v++)
106 if (username[v] == '\'')
110 if (username[v] == '"')
112 temp = temp + "\\\"";
114 else temp = temp + username[v];
118 // Create a request containing the SQL query and send it to m_sql.so
119 SQLRequest* query = new SQLRequest(SQL_RESULT,dbid,"SELECT username,password,hostname,type FROM ircd_opers WHERE username='"+username+"' AND password=md5('"+password+"')");
120 Request queryrequest((char*)query, this, SQLModule);
121 SQLResult* result = (SQLResult*)queryrequest.Send();
123 // Did we get "OK" as a result?
124 if (result->GetType() == SQL_OK)
126 Srv->Log(DEBUG,"An SQL based oper exists");
127 // if we did, this means we may now request a row... there should be only one row for each user, so,
128 // we don't need to loop to fetch multiple rows.
129 SQLRequest* rowrequest = new SQLRequest(SQL_ROW,dbid,"");
130 Request rowquery((char*)rowrequest, this, SQLModule);
131 SQLResult* rowresult = (SQLResult*)rowquery.Send();
133 // did we get a row? If we did, we can now do something with the fields
134 if (rowresult->GetType() == SQL_ROW)
136 if (rowresult->GetField("username") == username)
140 for (int j =0; j < Conf->Enumerate("type"); j++)
142 std::string TypeName = Conf->ReadValue("type","name",j);
143 std::string pattern = std::string(user->ident) + "@" + std::string(user->host);
144 if ((TypeName == rowresult->GetField("type")) && (Srv->MatchText(pattern,rowresult->GetField("hostname"))));
146 /* found this oper's opertype */
147 Srv->MeshSendAll("| "+std::string(user->nick)+" "+TypeName);
148 std::string HostName = Conf->ReadValue("type","host",j);
149 Srv->ChangeHost(user,HostName);
150 strlcpy(user->oper,TypeName.c_str(),NICKMAX);
151 WriteOpers("*** %s (%s@%s) is now an IRC operator of type %s",user->nick,user->ident,user->host,rowresult->GetField("type").c_str());
152 WriteServ(user->fd,"381 %s :You are now an IRC operator of type %s",user->nick,rowresult->GetField("type").c_str());
153 if (!strchr(user->modes,'o'))
155 strcat(user->modes,"o");
156 WriteServ(user->fd,"MODE %s :+o",user->nick);
157 Srv->MeshSendAll("M "+std::string(user->nick)+" +o");
158 Module* Logger = Srv->FindModule("m_sqllog.so");
160 Logger->OnOper(user);
162 log(DEFAULT,"OPER: %s!%s@%s opered as type: %s",user->nick,user->ident,user->host,rowresult->GetField("type").c_str());
173 // we didn't have a row.
184 query->SetQueryType(SQL_DONE);
185 query->SetConnID(dbid);
186 Request donerequest((char*)query, this, SQLModule);
192 virtual ~ModuleSQLOper()
198 virtual Version GetVersion()
200 return Version(1,0,0,1,VF_VENDOR);
205 class ModuleSQLOperFactory : public ModuleFactory
208 ModuleSQLOperFactory()
212 ~ModuleSQLOperFactory()
216 virtual Module * CreateModule()
218 return new ModuleSQLOper;
224 extern "C" void * init_module( void )
226 return new ModuleSQLOperFactory;