summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdam <Adam@drink-coca-cola.info>2010-05-17 23:48:18 -0400
committerAdam <Adam@anope.org>2010-06-18 21:03:43 -0400
commitcab6fcc82d2d184339bfe5ed0eba22482a404ad8 (patch)
tree29df26a375cbaa29d0c6023ad3478b28a826c307 /src
parent17ab4104005cc5098d9152e6c90d54977222dd06 (diff)
Added a founder access level used to determin who is a channel founder. This is completely independant of the owner levels
Diffstat (limited to 'src')
-rw-r--r--src/channels.c2
-rw-r--r--src/chanserv.c153
-rw-r--r--src/core/bs_info.c2
-rw-r--r--src/core/cs_access.c28
-rw-r--r--src/core/cs_akick.c2
-rw-r--r--src/core/cs_drop.c4
-rw-r--r--src/core/cs_modes.c4
-rw-r--r--src/core/cs_set.c6
-rw-r--r--src/core/cs_xop.c6
-rw-r--r--src/modules.c1
10 files changed, 42 insertions, 166 deletions
diff --git a/src/channels.c b/src/channels.c
index 4cdfb2c42..5a439726f 100644
--- a/src/channels.c
+++ b/src/channels.c
@@ -1465,7 +1465,7 @@ void chan_set_correct_modes(User * user, Channel * c, int give_modes)
/* If this channel has secureops or the user matches autodeop or the channel is syncing and this is the first user and they are not ulined, check to remove modes */
if ((ci->HasFlag(CI_SECUREOPS) || check_access(user, ci, CA_AUTODEOP) || (c->HasFlag(CH_SYNCING) && c->users.size() == 1)) && !user->server->IsULined())
{
- if (owner && c->HasUserStatus(user, CMODE_OWNER) && !IsFounder(user, ci))
+ if (owner && c->HasUserStatus(user, CMODE_OWNER) && !check_access(user, ci, CA_FOUNDER))
c->RemoveMode(NULL, CMODE_OWNER, user->nick);
if (admin && c->HasUserStatus(user, CMODE_PROTECT) && !check_access(user, ci, CA_AUTOPROTECT) && !check_access(user, ci, CA_PROTECTME))
diff --git a/src/chanserv.c b/src/chanserv.c
index 17dd65a7b..36e82f6b9 100644
--- a/src/chanserv.c
+++ b/src/chanserv.c
@@ -59,6 +59,7 @@ static int def_levels[][2] = {
{ CA_AUTOOWNER, ACCESS_QOP },
{ CA_OWNER, ACCESS_FOUNDER },
{ CA_OWNERME, ACCESS_QOP },
+ { CA_FOUNDER, ACCESS_QOP },
{ -1 }
};
@@ -103,6 +104,7 @@ LevelInfo levelinfo[] = {
{ CA_AUTOOWNER, "AUTOOWNER", CHAN_LEVEL_AUTOOWNER },
{ CA_OWNER, "OWNER", CHAN_LEVEL_OWNER },
{ CA_OWNERME, "OWNERME", CHAN_LEVEL_OWNERME },
+ { CA_FOUNDER, "FOUNDER", CHAN_LEVEL_FOUNDER },
{ -1 }
};
int levelinfo_maxwidth = 0;
@@ -466,111 +468,6 @@ int check_valid_op(User * user, Channel * chan, int servermode)
/*************************************************************************/
-/* Check whether a user should be opped on a channel, and if so, do it.
- * Return 1 if the user was opped, 0 otherwise. (Updates the channel's
- * last used time if the user was opped.) */
-
-int check_should_op(User * user, char *chan)
-{
- ChannelInfo *ci = cs_findchan(chan);
-
- if (!ci || (ci->HasFlag(CI_FORBIDDEN)) || *chan == '+')
- return 0;
-
- if ((ci->HasFlag(CI_SECURE)) && !user->IsIdentified())
- return 0;
-
- if (check_access(user, ci, CA_AUTOOP))
- {
- ci->c->SetMode(NULL, CMODE_OP, user->nick);
- return 1;
- }
-
- return 0;
-}
-
-/*************************************************************************/
-
-/* Check whether a user should be voiced on a channel, and if so, do it.
- * Return 1 if the user was voiced, 0 otherwise. */
-
-int check_should_voice(User * user, char *chan)
-{
- ChannelInfo *ci = cs_findchan(chan);
-
- if (!ci || (ci->HasFlag(CI_FORBIDDEN)) || *chan == '+')
- return 0;
-
- if ((ci->HasFlag(CI_SECURE)) && !user->IsIdentified())
- return 0;
-
- if (check_access(user, ci, CA_AUTOVOICE))
- {
- ci->c->SetMode(NULL, CMODE_VOICE, user->nick);
- return 1;
- }
-
- return 0;
-}
-
-/*************************************************************************/
-
-int check_should_halfop(User * user, char *chan)
-{
- ChannelInfo *ci = cs_findchan(chan);
-
- if (!ci || (ci->HasFlag(CI_FORBIDDEN)) || *chan == '+')
- return 0;
-
- if (check_access(user, ci, CA_AUTOHALFOP))
- {
- ci->c->SetMode(NULL, CMODE_HALFOP, user->nick);
- return 1;
- }
-
- return 0;
-}
-
-/*************************************************************************/
-
-int check_should_owner(User * user, char *chan)
-{
- ChannelInfo *ci = cs_findchan(chan);
-
- if (!ci || !ci->c || ci->HasFlag(CI_FORBIDDEN) || *chan == '+')
- return 0;
-
- if ((ci->HasFlag(CI_SECUREFOUNDER) && IsRealFounder(user, ci))
- || (!ci->HasFlag(CI_SECUREFOUNDER) && IsFounder(user, ci))) {
- ci->c->SetMode(NULL, CMODE_OP, user->nick);
- ci->c->SetMode(NULL, CMODE_OWNER, user->nick);
- return 1;
- }
-
- return 0;
-}
-
-/*************************************************************************/
-
-int check_should_protect(User * user, char *chan)
-{
- ChannelInfo *ci = cs_findchan(chan);
-
- if (!ci || !ci->c || ci->HasFlag(CI_FORBIDDEN) || *chan == '+')
- return 0;
-
- if (check_access(user, ci, CA_AUTOPROTECT))
- {
- ci->c->SetMode(NULL, CMODE_OWNER, user->nick);
- ci->c->SetMode(NULL, CMODE_PROTECT, user->nick);
- return 1;
- }
-
- return 0;
-}
-
-/*************************************************************************/
-
/* Record the current channel topic in the ChannelInfo structure. */
void record_topic(const char *chan)
@@ -846,15 +743,20 @@ int check_access(User * user, ChannelInfo * ci, int what)
if (level > 0)
ci->last_used = time(NULL);
+ /* Superadmin always wins. Always. */
+ if (user->isSuperAdmin)
+ return (what == CA_AUTODEOP || what == CA_NOJOIN ? 0 : 1);
+ /* If the access of the level we are checking is disabled, they *always* get denied */
if (limit == ACCESS_INVALID)
return 0;
- if (limit > ACCESS_FOUNDER)
- return 1;
- if (limit == ACCESS_FOUNDER)
- return (what == CA_AUTODEOP || what == CA_NOJOIN ? !IsRealFounder(user, ci) : IsRealFounder(user, ci));
+ /* If the level of the user is >= the level for "founder" of this channel and "founder" isn't disabled, they can do anything */
+ if (ci->levels[CA_FOUNDER] != ACCESS_INVALID && level >= ci->levels[CA_FOUNDER])
+ return (what == CA_AUTODEOP || what == CA_NOJOIN ? 0 : 1);
+
/* Hacks to make flags work */
if (what == CA_AUTODEOP && (ci->HasFlag(CI_SECUREOPS)) && level == 0)
return 1;
+
if (what == CA_AUTODEOP || what == CA_NOJOIN)
return level <= ci->levels[what];
else
@@ -886,43 +788,12 @@ void reset_levels(ChannelInfo * ci)
/*************************************************************************/
-/** Is the user a channel founder? (owner)
- * @param user The user
- * @param ci The channel
- * @return true or false
- */
-bool IsFounder(User *user, ChannelInfo *ci)
-{
- ChanAccess *access = NULL;
-
- if (!user || !ci)
- return false;
-
- if (IsRealFounder(user, ci))
- return true;
-
- if (user->Account())
- access = ci->GetAccess(user->Account());
- else
- {
- NickAlias *na = findnick(user->nick);
- if (na)
- access = ci->GetAccess(na->nc);
- }
-
- /* If they're QOP+ and theyre identified or theyre recognized and the channel isn't secure */
- if (access && access->level >= ACCESS_QOP && (user->Account() || (user->IsRecognized() && !(ci->HasFlag(CI_SECURE)))))
- return true;
-
- return false;
-}
-
/** Is the user the real founder?
* @param user The user
* @param ci The channel
* @return true or false
*/
-bool IsRealFounder(User *user, ChannelInfo *ci)
+bool IsFounder(User *user, ChannelInfo *ci)
{
if (!user || !ci)
return false;
diff --git a/src/core/bs_info.c b/src/core/bs_info.c
index 3f873aafd..f7d6fb46d 100644
--- a/src/core/bs_info.c
+++ b/src/core/bs_info.c
@@ -78,7 +78,7 @@ class CommandBSInfo : public Command
}
else if ((ci = cs_findchan(query)))
{
- if (!IsFounder(u, ci) && !u->Account()->HasPriv("botserv/administration"))
+ if (!check_access(u, ci, CA_FOUNDER) && !u->Account()->HasPriv("botserv/administration"))
{
notice_lang(Config.s_BotServ, u, ACCESS_DENIED);
return MOD_CONT;
diff --git a/src/core/cs_access.c b/src/core/cs_access.c
index f49fca990..6ef238b71 100644
--- a/src/core/cs_access.c
+++ b/src/core/cs_access.c
@@ -416,7 +416,7 @@ class CommandCSAccess : public Command
return MOD_CONT;
}
- if (!IsFounder(u, ci) && !u->Account()->HasPriv("chanserv/access/modify"))
+ if (!check_access(u, ci, CA_FOUNDER) && !u->Account()->HasPriv("chanserv/access/modify"))
{
notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
return MOD_CONT;
@@ -474,7 +474,7 @@ class CommandCSLevels : public Command
this->OnSyntaxError(u, cmd);
else if (ci->HasFlag(CI_XOP))
notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_XOP);
- else if (!IsFounder(u, ci) && !u->Account()->HasPriv("chanserv/access/modify"))
+ else if (!check_access(u, ci, CA_FOUNDER) && !u->Account()->HasPriv("chanserv/access/modify"))
notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
else if (cmd == "SET") {
level = strtol(s, &error, 10);
@@ -514,16 +514,20 @@ class CommandCSLevels : public Command
notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_UNKNOWN, what, Config.s_ChanServ);
} else if (cmd == "DIS" || cmd == "DISABLE") {
- for (i = 0; levelinfo[i].what >= 0; i++) {
- if (stricmp(levelinfo[i].name, what) == 0) {
- ci->levels[levelinfo[i].what] = ACCESS_INVALID;
- FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, i, levelinfo[i].what));
-
- Alog() << Config.s_ChanServ << ": " << u->GetMask() << " disabled level " << levelinfo[i].name
- << " on channel " << ci->name;
- notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_DISABLED,
- levelinfo[i].name, chan);
- return MOD_CONT;
+ /* Don't allow disabling of the founder level. It would be hard to change it back if you dont have access to use this command */
+ if (stricmp(what, "FOUNDER"))
+ {
+ for (i = 0; levelinfo[i].what >= 0; i++) {
+ if (stricmp(levelinfo[i].name, what) == 0) {
+ ci->levels[levelinfo[i].what] = ACCESS_INVALID;
+ FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, i, levelinfo[i].what));
+
+ Alog() << Config.s_ChanServ << ": " << u->GetMask() << " disabled level " << levelinfo[i].name
+ << " on channel " << ci->name;
+ notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_DISABLED,
+ levelinfo[i].name, chan);
+ return MOD_CONT;
+ }
}
}
diff --git a/src/core/cs_akick.c b/src/core/cs_akick.c
index 42b79c362..3d56e4846 100644
--- a/src/core/cs_akick.c
+++ b/src/core/cs_akick.c
@@ -224,7 +224,7 @@ class CommandCSAKick : public Command
{
User *u2 = it->second;
- if (IsFounder(u2, ci) || (get_access(u2, ci) >= get_access(u, ci)))
+ if (check_access(u2, ci, CA_FOUNDER) || (get_access(u2, ci) >= get_access(u, ci)))
{
if (match_usermask(mask.c_str(), u2))
{
diff --git a/src/core/cs_drop.c b/src/core/cs_drop.c
index f7c7a8571..baae58026 100644
--- a/src/core/cs_drop.c
+++ b/src/core/cs_drop.c
@@ -48,7 +48,7 @@ class CommandCSDrop : public Command
return MOD_CONT;
}
- if ((ci->HasFlag(CI_SECUREFOUNDER) ? !IsRealFounder(u, ci) : !IsFounder(u, ci)) && !u->Account()->HasCommand("chanserv/drop"))
+ if ((ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER)) && !u->Account()->HasCommand("chanserv/drop"))
{
notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
return MOD_CONT;
@@ -78,7 +78,7 @@ class CommandCSDrop : public Command
* drop the channel before issuing the wallops.
*/
if (Config.WallDrop) {
- if ((level < ACCESS_FOUNDER) || (!IsRealFounder(u, ci) && ci->HasFlag(CI_SECUREFOUNDER)))
+ if ((level < ACCESS_FOUNDER) || (!IsFounder(u, ci) && ci->HasFlag(CI_SECUREFOUNDER)))
ircdproto->SendGlobops(ChanServ, "\2%s\2 used DROP on channel \2%s\2", u->nick.c_str(), chan);
}
diff --git a/src/core/cs_modes.c b/src/core/cs_modes.c
index 3480ca1b6..312bc55dc 100644
--- a/src/core/cs_modes.c
+++ b/src/core/cs_modes.c
@@ -381,7 +381,7 @@ class CSModes : public Module
this->AddCommand(ChanServ, new CommandCSDeVoice());
if (Me && Me->IsSynced())
- OnUplinkSync();
+ OnUplinkSync(NULL);
Implementation i[] = {
I_OnUplinkSync, I_OnServerDisconnect, I_OnChanServHelp
@@ -389,7 +389,7 @@ class CSModes : public Module
ModuleManager::Attach(i, this, 3);
}
- void OnUplinkSync()
+ void OnUplinkSync(Server *)
{
if (ModeManager::FindChannelModeByName(CMODE_OWNER))
{
diff --git a/src/core/cs_set.c b/src/core/cs_set.c
index 75850f453..07171bdc1 100644
--- a/src/core/cs_set.c
+++ b/src/core/cs_set.c
@@ -645,14 +645,14 @@ class CommandCSSet : public Command
notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
else if (cmd == "FOUNDER")
{
- if (!is_servadmin && (ci->HasFlag(CI_SECUREFOUNDER) ? !IsRealFounder(u, ci) : !IsFounder(u, ci)))
+ if (!is_servadmin && (ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER)))
notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
else
DoSetFounder(u, ci, param);
}
else if (cmd == "SUCCESSOR")
{
- if (!is_servadmin && (ci->HasFlag(CI_SECUREFOUNDER) ? !IsRealFounder(u, ci) : !IsFounder(u, ci)))
+ if (!is_servadmin && (ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER)))
notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
else
DoSetSuccessor(u, ci, param);
@@ -681,7 +681,7 @@ class CommandCSSet : public Command
DoSetSecureOps(u, ci, param);
else if (cmd == "SECUREFOUNDER")
{
- if (!is_servadmin && (ci->HasFlag(CI_SECUREFOUNDER) ? !IsRealFounder(u, ci) : !IsFounder(u, ci)))
+ if (!is_servadmin && (ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER)))
notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
else
DoSetSecureFounder(u, ci, param);
diff --git a/src/core/cs_xop.c b/src/core/cs_xop.c
index eb4a76c47..c25bf02e2 100644
--- a/src/core/cs_xop.c
+++ b/src/core/cs_xop.c
@@ -421,7 +421,7 @@ class XOPBase : public Command
return MOD_CONT;
}
- if (!IsFounder(u, ci) && !u->Account()->HasPriv("chanserv/access/modify"))
+ if (!check_access(u, ci, CA_FOUNDER) && !u->Account()->HasPriv("chanserv/access/modify"))
{
notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
return MOD_CONT;
@@ -612,7 +612,7 @@ class CSXOP : public Module
this->AddCommand(ChanServ, new CommandCSVOP());
if (Me && Me->IsSynced())
- OnUplinkSync();
+ OnUplinkSync(NULL);
Implementation i[] = {
I_OnUplinkSync, I_OnServerDisconnect, I_OnChanServHelp
@@ -620,7 +620,7 @@ class CSXOP : public Module
ModuleManager::Attach(i, this, 3);
}
- void OnUplinkSync()
+ void OnUplinkSync(Server *)
{
if (ModeManager::FindChannelModeByName(CMODE_OWNER))
this->AddCommand(ChanServ, new CommandCSQOP());
diff --git a/src/modules.c b/src/modules.c
index 822d04ea2..0044bcc56 100644
--- a/src/modules.c
+++ b/src/modules.c
@@ -166,6 +166,7 @@ int Module::AddCommand(BotInfo *bi, Command *c)
if (!bi || !c)
return MOD_ERR_PARAMS;
+ c->module = this;
c->service = bi;
std::pair<std::map<ci::string, Command *>::iterator, bool> it = bi->Commands.insert(std::make_pair(c->name, c));