mirror of
https://github.com/inspircd/inspircd.git
synced 2025-03-09 18:49:03 -04:00
Change User::oper to an OperInfo reference
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11945 e03df62e-2008-0410-955e-edbf42e46eb7
This commit is contained in:
parent
ff3eef491a
commit
a30abe26fc
@ -61,8 +61,6 @@ struct CoreExport ConfigTag : public refcountbase
|
||||
*/
|
||||
typedef std::multimap<std::string, reference<ConfigTag> > ConfigDataHash;
|
||||
|
||||
typedef std::map<std::string, reference<ConfigTag> > TagIndex;
|
||||
|
||||
/** Defines the server's length limits on various length-limited
|
||||
* items such as topics, nicknames, channel names etc.
|
||||
*/
|
||||
@ -112,6 +110,30 @@ class ServerLimits
|
||||
}
|
||||
};
|
||||
|
||||
class CoreExport OperInfo : public refcountbase
|
||||
{
|
||||
public:
|
||||
/** <oper> block used for this oper-up. May be NULL. */
|
||||
reference<ConfigTag> oper_block;
|
||||
/** <type> block used for this oper-up. Valid for local users, may be NULL on remote */
|
||||
reference<ConfigTag> type_block;
|
||||
/** <class> blocks referenced from the <type> block. These define individual permissions */
|
||||
std::vector<reference<ConfigTag> > class_blocks;
|
||||
/** Name of the oper type; i.e. the one shown in WHOIS */
|
||||
std::string name;
|
||||
|
||||
/** Get a configuration item, searching in the oper, type, and class blocks (in that order) */
|
||||
std::string getConfig(const std::string& key);
|
||||
|
||||
inline const char* NameStr()
|
||||
{
|
||||
return irc::Spacify(name.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::map<std::string, reference<ConfigTag> > TagIndex;
|
||||
typedef std::map<std::string, reference<OperInfo> > OperIndex;
|
||||
|
||||
/** This class holds the bulk of the runtime configuration for the ircd.
|
||||
* It allows for reading new config values, accessing configuration files,
|
||||
* and storage of the configuration data needed to run the ircd, such as
|
||||
@ -495,13 +517,10 @@ class CoreExport ServerConfig
|
||||
*/
|
||||
bool FullHostInTopic;
|
||||
|
||||
/** All oper type definitions from the config file
|
||||
/** Oper block and type index.
|
||||
* For anonymous oper blocks (type only), prefix with a space.
|
||||
*/
|
||||
TagIndex opertypes;
|
||||
|
||||
/** All oper class definitions from the config file
|
||||
*/
|
||||
TagIndex operclass;
|
||||
OperIndex oper_blocks;
|
||||
|
||||
/** Saved argv from startup
|
||||
*/
|
||||
|
@ -60,6 +60,7 @@ enum RegistrationState {
|
||||
class Channel;
|
||||
class UserResolver;
|
||||
struct ConfigTag;
|
||||
class OperInfo;
|
||||
|
||||
/** Holds information relevent to <connect allow> and <connect deny> tags in the config file.
|
||||
*/
|
||||
@ -348,11 +349,8 @@ class CoreExport User : public StreamSocket
|
||||
time_t awaytime;
|
||||
|
||||
/** The oper type they logged in as, if they are an oper.
|
||||
* This is used to check permissions in operclasses, so that
|
||||
* we can say 'yea' or 'nay' to any commands they issue.
|
||||
* The value of this was the value of a valid 'type name=' tag
|
||||
*/
|
||||
std::string oper;
|
||||
reference<OperInfo> oper;
|
||||
|
||||
/** Used by User to indicate the registration status of the connection
|
||||
* It is a bitfield of the REG_NICK, REG_USER and REG_ALL bits to indicate
|
||||
@ -530,9 +528,8 @@ class CoreExport User : public StreamSocket
|
||||
|
||||
/** Oper up the user using the given opertype.
|
||||
* This will also give the +o usermode.
|
||||
* @param opertype The oper type to oper as
|
||||
*/
|
||||
void Oper(const std::string &opertype, const std::string &opername);
|
||||
void Oper(OperInfo* info);
|
||||
|
||||
/** Change this users hash key to a new string.
|
||||
* You should not call this function directly. It is used by the core
|
||||
@ -949,7 +946,7 @@ inline FakeUser* IS_SERVER(User* u)
|
||||
return u->GetFd() == FD_FAKEUSER_NUMBER ? static_cast<FakeUser*>(u) : NULL;
|
||||
}
|
||||
/** Is an oper */
|
||||
#define IS_OPER(x) (!x->oper.empty())
|
||||
#define IS_OPER(x) (x->oper)
|
||||
/** Is away */
|
||||
#define IS_AWAY(x) (!x->awaymsg.empty())
|
||||
|
||||
|
@ -340,7 +340,8 @@ bool CommandParser::ProcessCommand(User *user, std::string &cmd)
|
||||
}
|
||||
if (!user->HasPermission(command))
|
||||
{
|
||||
user->WriteNumeric(ERR_NOPRIVILEGES, "%s :Permission Denied - Oper type %s does not have access to command %s",user->nick.c_str(),irc::Spacify(user->oper.c_str()),command.c_str());
|
||||
user->WriteNumeric(ERR_NOPRIVILEGES, "%s :Permission Denied - Oper type %s does not have access to command %s",
|
||||
user->nick.c_str(), user->oper->NameStr(), command.c_str());
|
||||
return do_more;
|
||||
}
|
||||
}
|
||||
|
@ -54,8 +54,6 @@ CmdResult CommandOper::HandleLocal(const std::vector<std::string>& parameters, L
|
||||
{
|
||||
char TheHost[MAXBUF];
|
||||
char TheIP[MAXBUF];
|
||||
std::string type;
|
||||
bool found = false;
|
||||
bool match_login = false;
|
||||
bool match_pass = false;
|
||||
bool match_hosts = false;
|
||||
@ -63,89 +61,51 @@ CmdResult CommandOper::HandleLocal(const std::vector<std::string>& parameters, L
|
||||
snprintf(TheHost,MAXBUF,"%s@%s",user->ident.c_str(),user->host.c_str());
|
||||
snprintf(TheIP, MAXBUF,"%s@%s",user->ident.c_str(),user->GetIPString());
|
||||
|
||||
for (int i = 0;; i++)
|
||||
OperIndex::iterator i = ServerInstance->Config->oper_blocks.find(parameters[0]);
|
||||
if (i != ServerInstance->Config->oper_blocks.end())
|
||||
{
|
||||
ConfigTag* tag = ServerInstance->Config->ConfValue("oper", i);
|
||||
if (!tag)
|
||||
break;
|
||||
if (tag->getString("name") != parameters[0])
|
||||
continue;
|
||||
OperInfo* ifo = i->second;
|
||||
ConfigTag* tag = ifo->oper_block;
|
||||
match_login = true;
|
||||
match_pass = !ServerInstance->PassCompare(user, tag->getString("password"), parameters[1], tag->getString("hash"));
|
||||
match_hosts = OneOfMatches(TheHost,TheIP,tag->getString("host"));
|
||||
|
||||
if (match_pass && match_hosts)
|
||||
{
|
||||
type = tag->getString("type");
|
||||
ConfigTag* typeTag = ServerInstance->Config->opertypes[type];
|
||||
|
||||
if (typeTag)
|
||||
/* found this oper's opertype */
|
||||
std::string host = ifo->getConfig("host");
|
||||
if (!host.empty())
|
||||
user->ChangeDisplayedHost(host.c_str());
|
||||
std::string opClass = ifo->getConfig("class");
|
||||
if (!opClass.empty())
|
||||
{
|
||||
/* found this oper's opertype */
|
||||
if (!ServerInstance->IsNick(type.c_str(), ServerInstance->Config->Limits.NickMax))
|
||||
{
|
||||
user->WriteNumeric(491, "%s :Invalid oper type (oper types must follow the same syntax as nicknames)",user->nick.c_str());
|
||||
ServerInstance->SNO->WriteToSnoMask('o',"CONFIGURATION ERROR! Oper type '%s' contains invalid characters",type.c_str());
|
||||
ServerInstance->Logs->Log("OPER",DEFAULT,"OPER: Failed oper attempt by %s!%s@%s: credentials valid, but oper type erroneous.", user->nick.c_str(), user->ident.c_str(), user->host.c_str());
|
||||
return CMD_FAILURE;
|
||||
}
|
||||
std::string host = typeTag->getString("host");
|
||||
if (!host.empty())
|
||||
user->ChangeDisplayedHost(host.c_str());
|
||||
std::string opClass = typeTag->getString("class");
|
||||
if (!opClass.empty())
|
||||
{
|
||||
user->SetClass(opClass);
|
||||
user->CheckClass();
|
||||
}
|
||||
found = true;
|
||||
user->SetClass(opClass);
|
||||
user->CheckClass();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (found)
|
||||
{
|
||||
/* correct oper credentials */
|
||||
user->Oper(type, parameters[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
char broadcast[MAXBUF];
|
||||
|
||||
if (type.empty())
|
||||
{
|
||||
std::string fields;
|
||||
if (!match_login)
|
||||
fields.append("login ");
|
||||
if (!match_pass)
|
||||
fields.append("password ");
|
||||
if (!match_hosts)
|
||||
fields.append("hosts");
|
||||
|
||||
// tell them they suck, and lag them up to help prevent brute-force attacks
|
||||
user->WriteNumeric(491, "%s :Invalid oper credentials",user->nick.c_str());
|
||||
user->Penalty += 10;
|
||||
|
||||
snprintf(broadcast, MAXBUF, "WARNING! Failed oper attempt by %s!%s@%s using login '%s': The following fields do not match: %s", user->nick.c_str(), user->ident.c_str(), user->host.c_str(), parameters[0].c_str(), fields.c_str());
|
||||
ServerInstance->SNO->WriteToSnoMask('o',std::string(broadcast));
|
||||
ServerInstance->PI->SendSNONotice("o", std::string("OPER: ") + broadcast);
|
||||
|
||||
ServerInstance->Logs->Log("OPER",DEFAULT,"OPER: Failed oper attempt by %s!%s@%s using login '%s': The following fields did not match: %s", user->nick.c_str(), user->ident.c_str(), user->host.c_str(), parameters[0].c_str(), fields.c_str());
|
||||
return CMD_FAILURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
user->WriteNumeric(491, "%s :Your oper block does not have a valid opertype associated with it",user->nick.c_str());
|
||||
|
||||
snprintf(broadcast, MAXBUF, "CONFIGURATION ERROR! Oper block '%s': missing OperType %s",parameters[0].c_str(),type.c_str());
|
||||
|
||||
ServerInstance->SNO->WriteToSnoMask('o', std::string(broadcast));
|
||||
|
||||
ServerInstance->Logs->Log("OPER",DEFAULT,"OPER: Failed oper attempt by %s!%s@%s using login '%s': credentials valid, but oper type nonexistent.", user->nick.c_str(), user->ident.c_str(), user->host.c_str(), parameters[0].c_str());
|
||||
return CMD_FAILURE;
|
||||
user->Oper(ifo);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
}
|
||||
return CMD_SUCCESS;
|
||||
char broadcast[MAXBUF];
|
||||
|
||||
std::string fields;
|
||||
if (!match_login)
|
||||
fields.append("login ");
|
||||
if (!match_pass)
|
||||
fields.append("password ");
|
||||
if (!match_hosts)
|
||||
fields.append("hosts");
|
||||
|
||||
// tell them they suck, and lag them up to help prevent brute-force attacks
|
||||
user->WriteNumeric(491, "%s :Invalid oper credentials",user->nick.c_str());
|
||||
user->Penalty += 10;
|
||||
|
||||
snprintf(broadcast, MAXBUF, "WARNING! Failed oper attempt by %s!%s@%s using login '%s': The following fields do not match: %s", user->nick.c_str(), user->ident.c_str(), user->host.c_str(), parameters[0].c_str(), fields.c_str());
|
||||
ServerInstance->SNO->WriteToSnoMask('o',std::string(broadcast));
|
||||
ServerInstance->PI->SendSNONotice("o", std::string("OPER: ") + broadcast);
|
||||
|
||||
ServerInstance->Logs->Log("OPER",DEFAULT,"OPER: Failed oper attempt by %s!%s@%s using login '%s': The following fields did not match: %s", user->nick.c_str(), user->ident.c_str(), user->host.c_str(), parameters[0].c_str(), fields.c_str());
|
||||
return CMD_FAILURE;
|
||||
}
|
||||
|
||||
COMMAND_INIT(CommandOper)
|
||||
|
@ -589,8 +589,10 @@ static void ReadXLine(ServerConfig* conf, const std::string& tag, const std::str
|
||||
}
|
||||
}
|
||||
|
||||
typedef std::map<std::string, ConfigTag*> LocalIndex;
|
||||
void ServerConfig::CrossCheckOperClassType()
|
||||
{
|
||||
LocalIndex operclass;
|
||||
for (int i = 0;; ++i)
|
||||
{
|
||||
ConfigTag* tag = ConfValue("class", i);
|
||||
@ -610,16 +612,49 @@ void ServerConfig::CrossCheckOperClassType()
|
||||
std::string name = tag->getString("name");
|
||||
if (name.empty())
|
||||
throw CoreException("<type:name> is missing from tag at " + tag->getTagLocation());
|
||||
opertypes[name] = tag;
|
||||
|
||||
if (!ServerInstance->IsNick(name.c_str(), Limits.NickMax))
|
||||
throw CoreException("<type:name> is invalid (value '" + name + "')");
|
||||
|
||||
OperInfo* ifo = new OperInfo;
|
||||
oper_blocks[" " + name] = ifo;
|
||||
ifo->type_block = tag;
|
||||
|
||||
std::string classname;
|
||||
irc::spacesepstream str(tag->getString("classes"));
|
||||
while (str.GetToken(classname))
|
||||
{
|
||||
if (operclass.find(classname) == operclass.end())
|
||||
LocalIndex::iterator cls = operclass.find(classname);
|
||||
if (cls == operclass.end())
|
||||
throw CoreException("Oper type " + name + " has missing class " + classname);
|
||||
ifo->class_blocks.push_back(cls->second);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0;; ++i)
|
||||
{
|
||||
ConfigTag* tag = ConfValue("oper", i);
|
||||
if (!tag)
|
||||
break;
|
||||
|
||||
std::string name = tag->getString("name");
|
||||
if (name.empty())
|
||||
throw CoreException("<oper:name> missing from tag at " + tag->getTagLocation());
|
||||
|
||||
std::string type = tag->getString("type");
|
||||
OperIndex::iterator tblk = oper_blocks.find(" " + type);
|
||||
if (tblk == oper_blocks.end())
|
||||
throw CoreException("Oper block " + name + " has missing type " + type);
|
||||
if (oper_blocks.find(name) != oper_blocks.end())
|
||||
throw CoreException("Duplicate oper block with name " + name);
|
||||
|
||||
OperInfo* ifo = new OperInfo;
|
||||
ifo->name = type;
|
||||
ifo->oper_block = tag;
|
||||
ifo->type_block = tblk->second->type_block;
|
||||
ifo->class_blocks.assign(tblk->second->class_blocks.begin(), tblk->second->class_blocks.end());
|
||||
oper_blocks[name] = ifo;
|
||||
}
|
||||
}
|
||||
|
||||
void ServerConfig::CrossCheckConnectBlocks(ServerConfig* current)
|
||||
@ -1255,6 +1290,16 @@ std::string ConfigTag::getTagLocation()
|
||||
return src_name + ":" + ConvToStr(src_line);
|
||||
}
|
||||
|
||||
std::string OperInfo::getConfig(const std::string& key)
|
||||
{
|
||||
std::string rv;
|
||||
if (type_block)
|
||||
type_block->readString(key, rv);
|
||||
if (oper_block)
|
||||
oper_block->readString(key, rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/** Read the contents of a file located by `fname' into a file_cache pointed at by `F'.
|
||||
*/
|
||||
bool ServerConfig::ReadFile(file_cache &F, const std::string& fname)
|
||||
|
@ -336,7 +336,7 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, bool
|
||||
if (IS_OPER(user))
|
||||
{
|
||||
user->WriteNumeric(ERR_NOPRIVILEGES, "%s :Permission Denied - Oper type %s does not have access to set %s mode %c",
|
||||
user->nick.c_str(), irc::Spacify(user->oper.c_str()), type == MODETYPE_CHANNEL ? "channel" : "user", modechar);
|
||||
user->nick.c_str(), user->oper->NameStr(), type == MODETYPE_CHANNEL ? "channel" : "user", modechar);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -25,7 +25,7 @@ ModeUserOperator::ModeUserOperator() : ModeHandler(NULL, "oper", 'o', PARAM_NONE
|
||||
ModeAction ModeUserOperator::OnModeChange(User* source, User* dest, Channel*, std::string&, bool adding)
|
||||
{
|
||||
/* Only opers can execute this class at all */
|
||||
if (!ServerInstance->ULine(source->nick.c_str()) && !ServerInstance->ULine(source->server) && source->oper.empty())
|
||||
if (!ServerInstance->ULine(source->nick.c_str()) && !ServerInstance->ULine(source->server) && !IS_OPER(source))
|
||||
return MODEACTION_DENY;
|
||||
|
||||
/* Not even opers can GIVE the +o mode, only take it away */
|
||||
|
@ -98,7 +98,7 @@ class CommandCheck : public Command
|
||||
if (IS_OPER(targuser))
|
||||
{
|
||||
/* user is an oper of type ____ */
|
||||
user->SendText(checkstr + " opertype " + irc::Spacify(targuser->oper.c_str()));
|
||||
user->SendText(checkstr + " opertype " + targuser->oper->NameStr());
|
||||
}
|
||||
|
||||
LocalUser* loctarg = IS_LOCAL(targuser);
|
||||
|
@ -167,7 +167,7 @@ class ModuleHttpStats : public Module
|
||||
if (IS_AWAY(u))
|
||||
data << "<away>" << Sanitize(u->awaymsg) << "</away><awaytime>" << u->awaytime << "</awaytime>";
|
||||
if (IS_OPER(u))
|
||||
data << "<opertype>" << Sanitize(u->oper) << "</opertype>";
|
||||
data << "<opertype>" << Sanitize(u->oper->NameStr()) << "</opertype>";
|
||||
data << "<modes>" << u->FormatModes() << "</modes><ident>" << Sanitize(u->ident) << "</ident>";
|
||||
LocalUser* lu = IS_LOCAL(u);
|
||||
if (lu)
|
||||
|
@ -71,7 +71,7 @@ class ModuleOperChans : public Module
|
||||
{
|
||||
if (mask[0] == 'O' && mask[1] == ':')
|
||||
{
|
||||
if (IS_OPER(user) && InspIRCd::Match(user->oper, mask.substr(2)))
|
||||
if (IS_OPER(user) && InspIRCd::Match(user->oper->name, mask.substr(2)))
|
||||
return MOD_RES_DENY;
|
||||
}
|
||||
return MOD_RES_PASSTHRU;
|
||||
|
@ -92,7 +92,7 @@ class ModuleOperjoin : public Module
|
||||
if (ServerInstance->IsChannel(it->c_str(), ServerInstance->Config->Limits.ChanMax))
|
||||
Channel::JoinUser(user, it->c_str(), override, "", false, ServerInstance->Time());
|
||||
|
||||
std::map<std::string, std::vector<std::string> >::iterator i = operTypeChans.find(user->oper);
|
||||
std::map<std::string, std::vector<std::string> >::iterator i = operTypeChans.find(user->oper->name);
|
||||
|
||||
if (i != operTypeChans.end())
|
||||
{
|
||||
|
@ -42,16 +42,8 @@ class ModuleOperLevels : public Module
|
||||
// oper killing an oper?
|
||||
if (IS_OPER(dest) && IS_OPER(source))
|
||||
{
|
||||
TagIndex::iterator dest_type = ServerInstance->Config->opertypes.find(dest->oper);
|
||||
TagIndex::iterator src_type = ServerInstance->Config->opertypes.find(source->oper);
|
||||
|
||||
if (dest_type == ServerInstance->Config->opertypes.end())
|
||||
return MOD_RES_PASSTHRU;
|
||||
if (src_type == ServerInstance->Config->opertypes.end())
|
||||
return MOD_RES_PASSTHRU;
|
||||
|
||||
long dest_level = dest_type->second->getInt("level");
|
||||
long source_level = src_type->second->getInt("level");
|
||||
long dest_level = atol(dest->oper->getConfig("level").c_str());
|
||||
long source_level = atol(source->oper->getConfig("level").c_str());
|
||||
if (dest_level > source_level)
|
||||
{
|
||||
if (IS_LOCAL(source)) ServerInstance->SNO->WriteGlobalSno('a', "Oper %s (level %ld) attempted to /kill a higher oper: %s (level %ld): Reason: %s",source->nick.c_str(),source_level,dest->nick.c_str(),dest_level,reason.c_str());
|
||||
|
@ -40,13 +40,10 @@ class ModuleModesOnOper : public Module
|
||||
|
||||
virtual void OnPostOper(User* user, const std::string &opertype, const std::string &opername)
|
||||
{
|
||||
TagIndex::iterator typetag = ServerInstance->Config->opertypes.find(opertype);
|
||||
if (typetag == ServerInstance->Config->opertypes.end())
|
||||
return;
|
||||
// whenever a user opers, go through the oper types, find their <type:modes>,
|
||||
// and if they have one apply their modes. The mode string can contain +modes
|
||||
// to add modes to the user or -modes to take modes from the user.
|
||||
std::string ThisOpersModes = typetag->second->getString("modes");
|
||||
std::string ThisOpersModes = user->oper->getConfig("modes");
|
||||
if (!ThisOpersModes.empty())
|
||||
{
|
||||
ApplyModes(user, ThisOpersModes);
|
||||
|
@ -61,7 +61,7 @@ class ModuleOverride : public Module
|
||||
bool CanOverride(User* source, const char* token)
|
||||
{
|
||||
// checks to see if the oper's type has <type:override>
|
||||
override_t::iterator j = overrides.find(source->oper);
|
||||
override_t::iterator j = overrides.find(source->oper->name);
|
||||
|
||||
if (j != overrides.end())
|
||||
{
|
||||
|
@ -259,7 +259,7 @@ void TreeSocket::SendUsers(TreeServer* Current)
|
||||
this->WriteLine(data);
|
||||
if (IS_OPER(u->second))
|
||||
{
|
||||
snprintf(data,MAXBUF,":%s OPERTYPE %s", u->second->uuid.c_str(), u->second->oper.c_str());
|
||||
snprintf(data,MAXBUF,":%s OPERTYPE %s", u->second->uuid.c_str(), u->second->oper->name.c_str());
|
||||
this->WriteLine(data);
|
||||
}
|
||||
if (IS_AWAY(u->second))
|
||||
|
@ -35,7 +35,14 @@ bool TreeSocket::OperType(const std::string &prefix, parameterlist ¶ms)
|
||||
if (!IS_OPER(u))
|
||||
ServerInstance->Users->all_opers.push_back(u);
|
||||
u->modes[UM_OPERATOR] = 1;
|
||||
u->oper.assign(opertype, 0, 512);
|
||||
OperIndex::iterator iter = ServerInstance->Config->oper_blocks.find(" " + opertype);
|
||||
if (iter != ServerInstance->Config->oper_blocks.end())
|
||||
u->oper = iter->second;
|
||||
else
|
||||
{
|
||||
u->oper = new OperInfo;
|
||||
u->oper->name = opertype;
|
||||
}
|
||||
Utils->DoOneToAllButSender(u->uuid, "OPERTYPE", params, u->server);
|
||||
|
||||
TreeServer* remoteserver = Utils->FindServer(u->server);
|
||||
|
@ -275,26 +275,21 @@ public:
|
||||
|
||||
bool OperUser(User* user, const std::string &pattern, const std::string &type)
|
||||
{
|
||||
ConfigReader Conf;
|
||||
OperIndex::iterator iter = ServerInstance->Config->oper_blocks.find(" " + type);
|
||||
if (iter == ServerInstance->Config->oper_blocks.end())
|
||||
return false;
|
||||
OperInfo* ifo = iter->second;
|
||||
|
||||
for (int j = 0; j < Conf.Enumerate("type"); j++)
|
||||
std::string hostname(user->ident);
|
||||
|
||||
hostname.append("@").append(user->host);
|
||||
|
||||
if (OneOfMatches(hostname.c_str(), user->GetIPString(), pattern.c_str()))
|
||||
{
|
||||
std::string tname = Conf.ReadValue("type","name",j);
|
||||
std::string hostname(user->ident);
|
||||
/* Opertype and host match, looks like this is it. */
|
||||
|
||||
hostname.append("@").append(user->host);
|
||||
|
||||
if ((tname == type) && OneOfMatches(hostname.c_str(), user->GetIPString(), pattern.c_str()))
|
||||
{
|
||||
/* Opertype and host match, looks like this is it. */
|
||||
std::string operhost = Conf.ReadValue("type", "host", j);
|
||||
|
||||
if (operhost.size())
|
||||
user->ChangeDisplayedHost(operhost.c_str());
|
||||
|
||||
user->Oper(type, tname);
|
||||
return true;
|
||||
}
|
||||
user->Oper(ifo);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -106,32 +106,7 @@ class ModuleSWhois : public Module
|
||||
return;
|
||||
ConfigReader Conf;
|
||||
|
||||
std::string swhois;
|
||||
|
||||
for (int i = 0; i < Conf.Enumerate("oper"); i++)
|
||||
{
|
||||
std::string name = Conf.ReadValue("oper", "name", i);
|
||||
|
||||
if (name == params[0])
|
||||
{
|
||||
swhois = Conf.ReadValue("oper", "swhois", i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!swhois.length())
|
||||
{
|
||||
for (int i = 0; i < Conf.Enumerate("type"); i++)
|
||||
{
|
||||
std::string type = Conf.ReadValue("type", "name", i);
|
||||
|
||||
if (type == user->oper)
|
||||
{
|
||||
swhois = Conf.ReadValue("type", "swhois", i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::string swhois = user->oper->getConfig("swhois");
|
||||
|
||||
if (!swhois.length())
|
||||
return;
|
||||
|
134
src/users.cpp
134
src/users.cpp
@ -499,7 +499,7 @@ bool LocalUser::HasPrivPermission(const std::string &privstr, bool noisy)
|
||||
}
|
||||
|
||||
if (noisy)
|
||||
this->WriteServ("NOTICE %s :Oper type %s does not have access to priv %s", this->nick.c_str(), this->oper.c_str(), privstr.c_str());
|
||||
this->WriteServ("NOTICE %s :Oper type %s does not have access to priv %s", this->nick.c_str(), oper->NameStr(), privstr.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -637,97 +637,87 @@ CullResult LocalUser::cull()
|
||||
return User::cull();
|
||||
}
|
||||
|
||||
void User::Oper(const std::string &opertype, const std::string &opername)
|
||||
void User::Oper(OperInfo* info)
|
||||
{
|
||||
if (this->IsModeSet('o'))
|
||||
this->UnOper();
|
||||
|
||||
this->modes[UM_OPERATOR] = 1;
|
||||
this->oper = info;
|
||||
this->WriteServ("MODE %s :+o", this->nick.c_str());
|
||||
FOREACH_MOD(I_OnOper, OnOper(this, opertype));
|
||||
FOREACH_MOD(I_OnOper, OnOper(this, info->name));
|
||||
|
||||
ServerInstance->SNO->WriteToSnoMask('o',"%s (%s@%s) is now an IRC operator of type %s (using oper '%s')", this->nick.c_str(), this->ident.c_str(), this->host.c_str(), irc::Spacify(opertype.c_str()), opername.c_str());
|
||||
this->WriteNumeric(381, "%s :You are now %s %s", this->nick.c_str(), strchr("aeiouAEIOU", *opertype.c_str()) ? "an" : "a", irc::Spacify(opertype.c_str()));
|
||||
std::string opername;
|
||||
if (info->oper_block)
|
||||
opername = info->oper_block->getString("name");
|
||||
|
||||
ServerInstance->Logs->Log("OPER", DEFAULT, "%s!%s@%s opered as type: %s", this->nick.c_str(), this->ident.c_str(), this->host.c_str(), opertype.c_str());
|
||||
this->oper.assign(opertype, 0, 512);
|
||||
ServerInstance->SNO->WriteToSnoMask('o',"%s (%s@%s) is now an IRC operator of type %s (using oper '%s')",
|
||||
nick.c_str(), ident.c_str(), host.c_str(), info->NameStr(), opername.c_str());
|
||||
this->WriteNumeric(381, "%s :You are now %s %s", nick.c_str(), strchr("aeiouAEIOU", info->name[0]) ? "an" : "a", info->NameStr());
|
||||
|
||||
ServerInstance->Logs->Log("OPER", DEFAULT, "%s!%s@%s opered as type: %s", this->nick.c_str(), this->ident.c_str(), this->host.c_str(), info->NameStr());
|
||||
ServerInstance->Users->all_opers.push_back(this);
|
||||
|
||||
if (IS_LOCAL(this))
|
||||
IS_LOCAL(this)->OperInternal();
|
||||
|
||||
FOREACH_MOD(I_OnPostOper,OnPostOper(this, opertype, opername));
|
||||
FOREACH_MOD(I_OnPostOper,OnPostOper(this, info->name, opername));
|
||||
}
|
||||
|
||||
void LocalUser::OperInternal()
|
||||
{
|
||||
/*
|
||||
* This might look like it's in the wrong place.
|
||||
* It is *not*!
|
||||
*
|
||||
* For multi-network servers, we may not have the opertypes of the remote server, but we still want to mark the user as an oper of that type.
|
||||
* -- w00t
|
||||
*/
|
||||
TagIndex::iterator iter_opertype = ServerInstance->Config->opertypes.find(this->oper.c_str());
|
||||
if (iter_opertype != ServerInstance->Config->opertypes.end())
|
||||
if (AllowedOperCommands)
|
||||
AllowedOperCommands->clear();
|
||||
else
|
||||
AllowedOperCommands = new std::set<std::string>;
|
||||
|
||||
if (AllowedPrivs)
|
||||
AllowedPrivs->clear();
|
||||
else
|
||||
AllowedPrivs = new std::set<std::string>;
|
||||
|
||||
AllowedUserModes.reset();
|
||||
AllowedChanModes.reset();
|
||||
this->AllowedUserModes['o' - 'A'] = true; // Call me paranoid if you want.
|
||||
|
||||
for(std::vector<reference<ConfigTag> >::iterator iter = oper->class_blocks.begin(); iter != oper->class_blocks.end(); ++iter)
|
||||
{
|
||||
if (AllowedOperCommands)
|
||||
AllowedOperCommands->clear();
|
||||
else
|
||||
AllowedOperCommands = new std::set<std::string>;
|
||||
|
||||
if (AllowedPrivs)
|
||||
AllowedPrivs->clear();
|
||||
else
|
||||
AllowedPrivs = new std::set<std::string>;
|
||||
|
||||
AllowedUserModes.reset();
|
||||
AllowedChanModes.reset();
|
||||
this->AllowedUserModes['o' - 'A'] = true; // Call me paranoid if you want.
|
||||
|
||||
std::string myclass, mycmd, mypriv;
|
||||
irc::spacesepstream Classes(iter_opertype->second->getString("classes"));
|
||||
while (Classes.GetToken(myclass))
|
||||
ConfigTag* tag = *iter;
|
||||
std::string mycmd, mypriv;
|
||||
/* Process commands */
|
||||
irc::spacesepstream CommandList(tag->getString("commands"));
|
||||
while (CommandList.GetToken(mycmd))
|
||||
{
|
||||
TagIndex::iterator iter_operclass = ServerInstance->Config->operclass.find(myclass.c_str());
|
||||
if (iter_operclass != ServerInstance->Config->operclass.end())
|
||||
this->AllowedOperCommands->insert(mycmd);
|
||||
}
|
||||
|
||||
irc::spacesepstream PrivList(tag->getString("privs"));
|
||||
while (PrivList.GetToken(mypriv))
|
||||
{
|
||||
this->AllowedPrivs->insert(mypriv);
|
||||
}
|
||||
|
||||
for (unsigned char* c = (unsigned char*)tag->getString("usermodes").c_str(); *c; ++c)
|
||||
{
|
||||
if (*c == '*')
|
||||
{
|
||||
/* Process commands */
|
||||
irc::spacesepstream CommandList(iter_operclass->second->getString("commands"));
|
||||
while (CommandList.GetToken(mycmd))
|
||||
{
|
||||
this->AllowedOperCommands->insert(mycmd);
|
||||
}
|
||||
this->AllowedUserModes.set();
|
||||
}
|
||||
else
|
||||
{
|
||||
this->AllowedUserModes[*c - 'A'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
irc::spacesepstream PrivList(iter_operclass->second->getString("privs"));
|
||||
while (PrivList.GetToken(mypriv))
|
||||
{
|
||||
this->AllowedPrivs->insert(mypriv);
|
||||
}
|
||||
|
||||
for (unsigned char* c = (unsigned char*)iter_operclass->second->getString("usermodes").c_str(); *c; ++c)
|
||||
{
|
||||
if (*c == '*')
|
||||
{
|
||||
this->AllowedUserModes.set();
|
||||
}
|
||||
else
|
||||
{
|
||||
this->AllowedUserModes[*c - 'A'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned char* c = (unsigned char*)iter_operclass->second->getString("chanmodes").c_str(); *c; ++c)
|
||||
{
|
||||
if (*c == '*')
|
||||
{
|
||||
this->AllowedChanModes.set();
|
||||
}
|
||||
else
|
||||
{
|
||||
this->AllowedChanModes[*c - 'A'] = true;
|
||||
}
|
||||
}
|
||||
for (unsigned char* c = (unsigned char*)tag->getString("chanmodes").c_str(); *c; ++c)
|
||||
{
|
||||
if (*c == '*')
|
||||
{
|
||||
this->AllowedChanModes.set();
|
||||
}
|
||||
else
|
||||
{
|
||||
this->AllowedChanModes[*c - 'A'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -743,7 +733,7 @@ void User::UnOper()
|
||||
* note, order is important - this must come before modes as -o attempts
|
||||
* to call UnOper. -- w00t
|
||||
*/
|
||||
this->oper.clear();
|
||||
oper = NULL;
|
||||
|
||||
|
||||
/* Remove all oper only modes from the user when the deoper - Bug #466*/
|
||||
|
@ -53,7 +53,7 @@ void InspIRCd::DoWhois(User* user, User* dest,unsigned long signon, unsigned lon
|
||||
if (this->Config->GenericOper)
|
||||
this->SendWhoisLine(user, dest, 313, "%s %s :is an IRC operator",user->nick.c_str(), dest->nick.c_str());
|
||||
else
|
||||
this->SendWhoisLine(user, dest, 313, "%s %s :is %s %s on %s",user->nick.c_str(), dest->nick.c_str(), (strchr("AEIOUaeiou",dest->oper[0]) ? "an" : "a"),irc::Spacify(dest->oper.c_str()), this->Config->Network.c_str());
|
||||
this->SendWhoisLine(user, dest, 313, "%s %s :is %s %s on %s",user->nick.c_str(), dest->nick.c_str(), (strchr("AEIOUaeiou",dest->oper->name[0]) ? "an" : "a"),dest->oper->NameStr(), this->Config->Network.c_str());
|
||||
}
|
||||
|
||||
if (user == dest || user->HasPrivPermission("users/auspex"))
|
||||
|
Loading…
x
Reference in New Issue
Block a user