]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Move all local-only fields to LocalUser
authordanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>
Wed, 21 Oct 2009 23:45:32 +0000 (23:45 +0000)
committerdanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>
Wed, 21 Oct 2009 23:45:32 +0000 (23:45 +0000)
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11944 e03df62e-2008-0410-955e-edbf42e46eb7

17 files changed:
include/users.h
src/channels.cpp
src/command_parse.cpp
src/commands/cmd_invite.cpp
src/commands/cmd_nick.cpp
src/commands/cmd_oper.cpp
src/commands/cmd_pass.cpp
src/commands/cmd_pong.cpp
src/modules/extra/m_ldapauth.cpp
src/modules/m_cgiirc.cpp
src/modules/m_cloaking.cpp
src/modules/m_override.cpp
src/modules/m_sqlauth.cpp
src/modules/m_testnet.cpp
src/modules/m_uninvite.cpp
src/usermanager.cpp
src/users.cpp

index 0be98f3bf45c2464a6e2b2c3a84272b9fd5bab73..51600e3af8f1eb1aae86d5a35cb4a285f96bfe7c 100644 (file)
@@ -235,12 +235,6 @@ class User;
 class CoreExport User : public StreamSocket
 {
  private:
-       /** A list of channels the user has a pending invite to.
-        * Upon INVITE channels are added, and upon JOIN, the
-        * channels are removed from this list.
-        */
-       InvitedList invites;
-
        /** Cached nick!ident@dhost value using the displayed hostname
         */
        std::string cached_fullhost;
@@ -266,30 +260,13 @@ class CoreExport User : public StreamSocket
         * mode characters this user is making use of.
         */
        void DecrementModes();
-
-       std::set<std::string> *AllowedOperCommands;
-       std::set<std::string> *AllowedPrivs;
-
-       /** Allowed user modes from oper classes. */
-       std::bitset<64> AllowedUserModes;
-
-       /** Allowed channel modes from oper classes. */
-       std::bitset<64> AllowedChanModes;
-
  public:
-       /** Contains a pointer to the connect class a user is on from - this will be NULL for remote connections.
-        */
-       reference<ConnectClass> MyClass;
 
        /** Hostname of connection.
         * This should be valid as per RFC1035.
         */
        std::string host;
 
-       /** Time the connection was last pinged
-        */
-       time_t lastping;
-
        /** Time that the object was instantiated (used for TS calculation etc)
        */
        time_t age;
@@ -304,20 +281,12 @@ class CoreExport User : public StreamSocket
         */
        time_t idle_lastmsg;
 
-       /** Used by PING checking code
-        */
-       time_t nping;
-
        /** Client address that the user is connected from.
         * Do not modify this value directly, use SetClientIP() to change it
         * Port is not valid for remote users.
         */
        irc::sockets::sockaddrs client_sa;
 
-       /** Stored reverse lookup from res_forward. Should not be used after resolution.
-        */
-       std::string stored_host;
-
        /** The users nickname.
         * An invalid nickname indicates an unregistered connection prior to the NICK command.
         * Use InspIRCd::IsNick() to validate nicknames.
@@ -360,7 +329,7 @@ class CoreExport User : public StreamSocket
         */
        std::bitset<64> snomasks;
 
-       /** Channels this user is on, and the permissions they have there
+       /** Channels this user is on
         */
        UserChanList chans;
 
@@ -380,22 +349,11 @@ class CoreExport User : public StreamSocket
 
        /** 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 'yay' or 'nay' to any commands they issue.
-        * The value of this is the value of a valid 'type name=' tag.
+        * 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;
 
-       /** Password specified by the user when they registered.
-        * This is stored even if the <connect> block doesnt need a password, so that
-        * modules may check it.
-        */
-       std::string password;
-
-       /** This value contains how far into the penalty threshold the user is. Once its over
-        * the penalty threshold then commands are held and processed on-timer.
-        */
-       int Penalty;
-
        /** 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
         * the connection state.
@@ -423,6 +381,10 @@ class CoreExport User : public StreamSocket
         */
        unsigned int exempt:1;
 
+       /** has the user responded to their previous ping?
+        */
+       unsigned int lastping:1;
+
        /** Get client IP string from sockaddr, using static internal buffer
         * @return The IP string
         */
@@ -517,32 +479,13 @@ class CoreExport User : public StreamSocket
         */
        void SetMode(unsigned char m, bool value);
 
-       /** Returns true if a user is invited to a channel.
-        * @param channel A channel name to look up
-        * @return True if the user is invited to the given channel
-        */
-       virtual bool IsInvited(const irc::string &channel);
-
-       /** Adds a channel to a users invite list (invites them to a channel)
-        * @param channel A channel name to add
-        * @param timeout When the invite should expire (0 == never)
-        */
-       virtual void InviteTo(const irc::string &channel, time_t timeout);
-
-       /** Removes a channel from a users invite list.
-        * This member function is called on successfully joining an invite only channel
-        * to which the user has previously been invited, to clear the invitation.
-        * @param channel The channel to remove the invite to
-        */
-       virtual void RemoveInvite(const irc::string &channel);
-
        /** Returns true or false for if a user can execute a privilaged oper command.
         * This is done by looking up their oper type from User::oper, then referencing
         * this to their oper classes and checking the commands they can execute.
         * @param command A command (should be all CAPS)
         * @return True if this user can execute the command
         */
-       bool HasPermission(const std::string &command);
+       virtual bool HasPermission(const std::string &command);
 
        /** Returns true if a user has a given permission.
         * This is used to check whether or not users may perform certain actions which admins may not wish to give to
@@ -552,7 +495,7 @@ class CoreExport User : public StreamSocket
         * @param noisy If set to true, the user is notified that they do not have the specified permission where applicable. If false, no notification is sent.
         * @return True if this user has the permission in question.
         */
-       bool HasPrivPermission(const std::string &privstr, bool noisy = false);
+       virtual bool HasPrivPermission(const std::string &privstr, bool noisy = false);
 
        /** Returns true or false if a user can set a privileged user or channel mode.
         * This is done by looking up their oper type from User::oper, then referencing
@@ -561,12 +504,7 @@ class CoreExport User : public StreamSocket
         * @param type ModeType (MODETYPE_CHANNEL or MODETYPE_USER).
         * @return True if the user can set or unset this mode.
         */
-       bool HasModePermission(unsigned char mode, ModeType type);
-
-       /** Returns the list of channels this user has been invited to but has not yet joined.
-        * @return A list of channels the user is invited to
-        */
-       InvitedList* GetInviteList();
+       virtual bool HasModePermission(unsigned char mode, ModeType type);
 
        /** Creates a wildcard host.
         * Takes a buffer to use and fills the given buffer with the host in the format *!*@hostname
@@ -596,10 +534,6 @@ class CoreExport User : public StreamSocket
         */
        void Oper(const std::string &opertype, const std::string &opername);
 
-       /** Call this method to find the matching <connect> for a user, and to check them against it.
-        */
-       void CheckClass();
-
        /** Change this users hash key to a new string.
         * You should not call this function directly. It is used by the core
         * to update the users hash entry on a nickchange.
@@ -786,10 +720,10 @@ class CoreExport User : public StreamSocket
         */
        void PurgeEmptyChannels();
 
-       /** Get the connect class which this user belongs to.
-        * @return A pointer to this user's connect class
+       /** Get the connect class which this user belongs to. NULL for remote users.
+        * @return A pointer to this user's connect class.
         */
-       ConnectClass *GetClass();
+       virtual ConnectClass* GetClass();
 
        /** Show the message of the day to this user
         */
@@ -799,10 +733,6 @@ class CoreExport User : public StreamSocket
         */
        void ShowRULES();
 
-       /** Increases a user's command penalty by a set amount.
-        */
-       void IncreasePenalty(int increase);
-
        virtual void OnDataReady();
        virtual void OnError(BufferedSocketError error);
        /** Default destructor
@@ -821,6 +751,21 @@ class CoreExport User : public StreamSocket
 
 class CoreExport LocalUser : public User
 {
+       /** A list of channels the user has a pending invite to.
+        * Upon INVITE channels are added, and upon JOIN, the
+        * channels are removed from this list.
+        */
+       InvitedList invites;
+
+       std::set<std::string> *AllowedOperCommands;
+       std::set<std::string> *AllowedPrivs;
+
+       /** Allowed user modes from oper classes. */
+       std::bitset<64> AllowedUserModes;
+
+       /** Allowed channel modes from oper classes. */
+       std::bitset<64> AllowedChanModes;
+
  public:
        LocalUser();
        CullResult cull();
@@ -841,6 +786,22 @@ class CoreExport LocalUser : public User
         */
        int cmds_out;
 
+       /** Password specified by the user when they registered (if any).
+        * This is stored even if the <connect> block doesnt need a password, so that
+        * modules may check it.
+        */
+       std::string password;
+
+       /** Contains a pointer to the connect class a user is on from
+        */
+       reference<ConnectClass> MyClass;
+
+       ConnectClass* GetClass();
+
+       /** Call this method to find the matching <connect> for a user, and to check them against it.
+        */
+       void CheckClass();
+
        /** Server address and port that this user is connected to.
         */
        irc::sockets::sockaddrs server_sa;
@@ -850,6 +811,19 @@ class CoreExport LocalUser : public User
         */
        int GetServerPort();
 
+       /** Used by PING checking code
+        */
+       time_t nping;
+
+       /** This value contains how far into the penalty threshold the user is. Once its over
+        * the penalty threshold then commands are held and processed on-timer.
+        */
+       int Penalty;
+
+       /** Stored reverse lookup from res_forward. Should not be used after resolution.
+        */
+       std::string stored_host;
+
        /** Starts a DNS lookup of the user's IP.
         * This will cause two UserResolver classes to be instantiated.
         * When complete, these objects set User::dns_done to true.
@@ -865,7 +839,7 @@ class CoreExport LocalUser : public User
         * @param explicit_name Set this string to tie the user to a specific class name. Otherwise, the class is fitted by checking <connect> tags from the configuration file.
         * @return A reference to this user's current connect class.
         */
-       ConnectClass *SetClass(const std::string &explicit_name = "");
+       void SetClass(const std::string &explicit_name = "");
 
        void OnDataReady();
        void SendText(const std::string& line);
@@ -878,6 +852,60 @@ class CoreExport LocalUser : public User
         * @param data The data to add to the write buffer
         */
        void AddWriteBuf(const std::string &data);
+
+       /** Returns the list of channels this user has been invited to but has not yet joined.
+        * @return A list of channels the user is invited to
+        */
+       InvitedList* GetInviteList();
+
+       /** Returns true if a user is invited to a channel.
+        * @param channel A channel name to look up
+        * @return True if the user is invited to the given channel
+        */
+       bool IsInvited(const irc::string &channel);
+
+       /** Adds a channel to a users invite list (invites them to a channel)
+        * @param channel A channel name to add
+        * @param timeout When the invite should expire (0 == never)
+        */
+       void InviteTo(const irc::string &channel, time_t timeout);
+
+       /** Removes a channel from a users invite list.
+        * This member function is called on successfully joining an invite only channel
+        * to which the user has previously been invited, to clear the invitation.
+        * @param channel The channel to remove the invite to
+        */
+       void RemoveInvite(const irc::string &channel);
+
+       /** Returns true or false for if a user can execute a privilaged oper command.
+        * This is done by looking up their oper type from User::oper, then referencing
+        * this to their oper classes and checking the commands they can execute.
+        * @param command A command (should be all CAPS)
+        * @return True if this user can execute the command
+        */
+       bool HasPermission(const std::string &command);
+
+       /** Returns true if a user has a given permission.
+        * This is used to check whether or not users may perform certain actions which admins may not wish to give to
+        * all operators, yet are not commands. An example might be oper override, mass messaging (/notice $*), etc.
+        *
+        * @param privstr The priv to chec, e.g. "users/override/topic". These are loaded free-form from the config file.
+        * @param noisy If set to true, the user is notified that they do not have the specified permission where applicable. If false, no notification is sent.
+        * @return True if this user has the permission in question.
+        */
+       bool HasPrivPermission(const std::string &privstr, bool noisy = false);
+
+       /** Returns true or false if a user can set a privileged user or channel mode.
+        * This is done by looking up their oper type from User::oper, then referencing
+        * this to their oper classes, and checking the modes they can set.
+        * @param mode The mode the check
+        * @param type ModeType (MODETYPE_CHANNEL or MODETYPE_USER).
+        * @return True if the user can set or unset this mode.
+        */
+       bool HasModePermission(unsigned char mode, ModeType type);
+
+       void OperInternal();
+       void UnOperInternal();
 };
 
 class CoreExport RemoteUser : public User
index d7f8f372e47b1645742027286aa4b5bee4d2bcf4..d0d8e52c5bc8daaeb1ec102027cb62e51695c888 100644 (file)
@@ -218,24 +218,20 @@ Channel* Channel::JoinUser(User *user, const char* cn, bool override, const char
         */
        if (IS_LOCAL(user) && !override)
        {
-               // Checking MyClass exists because we *may* get here with NULL, not 100% sure.
-               if (user->MyClass && user->MyClass->maxchans)
+               if (user->HasPrivPermission("channels/high-join-limit"))
                {
-                       if (user->HasPrivPermission("channels/high-join-limit"))
+                       if (user->chans.size() >= ServerInstance->Config->OperMaxChans)
                        {
-                               if (user->chans.size() >= ServerInstance->Config->OperMaxChans)
-                               {
-                                       user->WriteNumeric(ERR_TOOMANYCHANNELS, "%s %s :You are on too many channels",user->nick.c_str(), cn);
-                                       return NULL;
-                               }
+                               user->WriteNumeric(ERR_TOOMANYCHANNELS, "%s %s :You are on too many channels",user->nick.c_str(), cn);
+                               return NULL;
                        }
-                       else
+               }
+               else
+               {
+                       if (user->chans.size() >= user->GetClass()->maxchans)
                        {
-                               if (user->chans.size() >= user->MyClass->maxchans)
-                               {
-                                       user->WriteNumeric(ERR_TOOMANYCHANNELS, "%s %s :You are on too many channels",user->nick.c_str(), cn);
-                                       return NULL;
-                               }
+                               user->WriteNumeric(ERR_TOOMANYCHANNELS, "%s %s :You are on too many channels",user->nick.c_str(), cn);
+                               return NULL;
                        }
                }
        }
@@ -291,7 +287,7 @@ Channel* Channel::JoinUser(User *user, const char* cn, bool override, const char
                        else if (MOD_RESULT == MOD_RES_PASSTHRU)
                        {
                                std::string ckey = Ptr->GetModeParameter('k');
-                               bool invited = user->IsInvited(Ptr->name.c_str());
+                               bool invited = IS_LOCAL(user)->IsInvited(Ptr->name.c_str());
                                bool can_bypass = ServerInstance->Config->InvBypassModes && invited;
 
                                if (!ckey.empty())
@@ -338,7 +334,7 @@ Channel* Channel::JoinUser(User *user, const char* cn, bool override, const char
                                 */
                                if (invited)
                                {
-                                       user->RemoveInvite(Ptr->name.c_str());
+                                       IS_LOCAL(user)->RemoveInvite(Ptr->name.c_str());
                                }
                        }
                }
index 6dd4e663e04726411b63c904d201faab6d5b785f..9fc8f85bb449999643d1d90b1f7d5e6cbbad44c4 100644 (file)
@@ -249,11 +249,10 @@ bool CommandParser::ProcessCommand(User *user, std::string &cmd)
 
        /* Modify the user's penalty regardless of whether or not the command exists */
        bool do_more = true;
-       if (!user->HasPrivPermission("users/flood/no-throttle"))
+       if (IS_LOCAL(user) && !user->HasPrivPermission("users/flood/no-throttle"))
        {
                // If it *doesn't* exist, give it a slightly heftier penalty than normal to deter flooding us crap
-               user->IncreasePenalty(cm != cmdlist.end() ? cm->second->Penalty : 2);
-               do_more = (user->GetClass()->GetPenaltyThreshold() && ((unsigned long)user->Penalty < user->GetClass()->GetPenaltyThreshold()));
+               IS_LOCAL(user)->Penalty += cm != cmdlist.end() ? cm->second->Penalty : 2;
        }
 
 
@@ -328,8 +327,9 @@ bool CommandParser::ProcessCommand(User *user, std::string &cmd)
                return true;
 
        /* activity resets the ping pending timer */
-       if (user->MyClass)
-               user->nping = ServerInstance->Time() + user->MyClass->GetPingTime();
+       LocalUser* luser = IS_LOCAL(user);
+       if (luser)
+               luser->nping = ServerInstance->Time() + luser->MyClass->GetPingTime();
 
        if (cm->second->flags_needed)
        {
index 9da6096a41600f9f40df89377758cca013ab5de8..84c522754930765a15699c6c108968b72dbe89df 100644 (file)
@@ -90,7 +90,8 @@ CmdResult CommandInvite::Handle (const std::vector<std::string>& parameters, Use
                        }
                }
 
-               u->InviteTo(c->name.c_str(), timeout);
+               if (IS_LOCAL(u))
+                       IS_LOCAL(u)->InviteTo(c->name.c_str(), timeout);
                u->WriteFrom(user,"INVITE %s :%s",u->nick.c_str(),c->name.c_str());
                user->WriteNumeric(RPL_INVITING, "%s %s %s",user->nick.c_str(),u->nick.c_str(),c->name.c_str());
                switch (ServerInstance->Config->AnnounceInvites)
@@ -113,11 +114,11 @@ CmdResult CommandInvite::Handle (const std::vector<std::string>& parameters, Use
                }
                FOREACH_MOD(I_OnUserInvite,OnUserInvite(user,u,c,timeout));
        }
-       else
+       else if (IS_LOCAL(user))
        {
                // pinched from ircu - invite with not enough parameters shows channels
                // youve been invited to but haven't joined yet.
-               InvitedList* il = user->GetInviteList();
+               InvitedList* il = IS_LOCAL(user)->GetInviteList();
                for (InvitedList::iterator i = il->begin(); i != il->end(); i++)
                {
                        user->WriteNumeric(RPL_INVITELIST, "%s :%s",user->nick.c_str(),i->first.c_str());
index ee8c4625cfff2b804a17d726b081d348370f5d26..489551dd198a74c261aeb3cf0a4224111fa5201f 100644 (file)
@@ -202,7 +202,8 @@ CmdResult CommandNick::Handle (const std::vector<std::string>& parameters, User
 
        if (user->registered == REG_ALL)
        {
-               user->IncreasePenalty(10);
+               if (IS_LOCAL(user))
+                       IS_LOCAL(user)->Penalty += 10;
                FOREACH_MOD(I_OnUserPostNick,OnUserPostNick(user, oldnick));
        }
 
index dc15a5415ee85344570840ecab2935bd3ae4ec45..428e7b1095609508f559cac25584b516c9c8c4ed 100644 (file)
@@ -124,7 +124,7 @@ CmdResult CommandOper::HandleLocal(const std::vector<std::string>& parameters, L
 
                        // 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->IncreasePenalty(10);
+                       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));
index 21b5b275990dd7cde97c2df55cb509ca4d62b9f6..0bf1b46a48f3e97d64e7287303a467794031afe7 100644 (file)
  * the same way, however, they can be fully unloaded, where these
  * may not.
  */
-class CommandPass : public Command
+class CommandPass : public SplitCommand
 {
  public:
        /** Constructor for pass.
         */
-       CommandPass ( Module* parent) : Command(parent,"PASS",1,1) { works_before_reg = true; Penalty = 0; syntax = "<password>"; }
+       CommandPass (Module* parent) : SplitCommand(parent,"PASS",1,1) { works_before_reg = true; Penalty = 0; syntax = "<password>"; }
        /** Handle command.
         * @param parameters The parameters to the comamnd
         * @param pcnt The number of parameters passed to teh command
         * @param user The user issuing the command
         * @return A value from CmdResult to indicate command success or failure.
         */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+       CmdResult HandleLocal(const std::vector<std::string>& parameters, LocalUser *user);
 };
 
 
-CmdResult CommandPass::Handle (const std::vector<std::string>& parameters, User *user)
+CmdResult CommandPass::HandleLocal(const std::vector<std::string>& parameters, LocalUser *user)
 {
        // Check to make sure they haven't registered -- Fix by FCS
        if (user->registered == REG_ALL)
index 225be147a5d7672ed949bd7988cac9216fc36d80..9bff00ed2ed8683ff8e46d23f39de72b494c1209 100644 (file)
@@ -36,7 +36,8 @@ class CommandPong : public Command
 CmdResult CommandPong::Handle (const std::vector<std::string>&, User *user)
 {
        // set the user as alive so they survive to next ping
-       user->lastping = 1;
+       if (IS_LOCAL(user))
+               IS_LOCAL(user)->lastping = 1;
        return CMD_SUCCESS;
 }
 
index 26e9683673a5686f590908702b3178cec4c0e463..af676de44d27bede5fcbc6dd60c567c902d1c52b 100644 (file)
@@ -127,17 +127,16 @@ public:
                return MOD_RES_PASSTHRU;
        }
 
-       bool CheckCredentials(User* user)
+       bool CheckCredentials(LocalUser* user)
        {
                if (conn == NULL)
                        if (!Connect())
                                return false;
 
                int res;
-               char* authpass = strdup(password.c_str());
                // bind anonymously if no bind DN and authentication are given in the config
                struct berval cred;
-               cred.bv_val = authpass;
+               cred.bv_val = const_cast<char*>(password.c_str());
                cred.bv_len = password.length();
 
                if ((res = ldap_sasl_bind_s(conn, username.c_str(), LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL)) != LDAP_SUCCESS)
@@ -155,13 +154,11 @@ public:
                        {
                                if (verbose)
                                        ServerInstance->SNO->WriteToSnoMask('c', "Forbidden connection from %s!%s@%s (LDAP bind failed: %s)", user->nick.c_str(), user->ident.c_str(), user->host.c_str(), ldap_err2string(res));
-                               free(authpass);
                                ldap_unbind_ext(conn, NULL, NULL);
                                conn = NULL;
                                return false;
                        }
                }
-               free(authpass);
 
                LDAPMessage *msg, *entry;
                std::string what = (attribute + "=" + (useusername ? user->ident : user->nick));
index 745dc13d2225b8878cc8ef4c04d99889f99840d3..5f8cfeca7414871d135cd6caf13c0d5ebb0666af 100644 (file)
@@ -277,7 +277,7 @@ public:
                }
        }
 
-       bool CheckPass(User* user)
+       bool CheckPass(LocalUser* user)
        {
                if(IsValidHost(user->password))
                {
@@ -324,7 +324,7 @@ public:
                return false;
        }
 
-       bool CheckIdent(User* user)
+       bool CheckIdent(LocalUser* user)
        {
                const char* ident;
                int len = user->ident.length();
index 0ad790de933a645996d302d1cda65d7c49e8ed9d..c0ebbc99bfdbe0f92d2a4985b97f811e9c7a2a51 100644 (file)
@@ -57,7 +57,7 @@ class CloakUser : public ModeHandler
                }
 
                /* don't allow this user to spam modechanges */
-               dest->IncreasePenalty(5);
+               IS_LOCAL(dest)->Penalty += 5;
 
                if (adding)
                {
index e37282525df5054ca2639f9b7f51b27cc6fd7670..8a3fcdd62faa6509fa411edf8df949abcacee717 100644 (file)
@@ -135,7 +135,7 @@ class ModuleOverride : public Module
                                if ((chan->modes[CM_INVITEONLY]) && (CanOverride(user,"INVITE")))
                                {
                                        irc::string x(chan->name.c_str());
-                                       if (!user->IsInvited(x))
+                                       if (!IS_LOCAL(user)->IsInvited(x))
                                        {
                                                if (RequireKey && keygiven != "override")
                                                {
index a4c237e4e3a932c9ae72f18b9d9729bae8cfc216..3a446148036a9c8ea30b63c3e9dfee22cc869d08 100644 (file)
@@ -85,7 +85,7 @@ public:
                return MOD_RES_PASSTHRU;
        }
 
-       bool CheckCredentials(User* user)
+       bool CheckCredentials(LocalUser* user)
        {
                std::string thisquery = freeformquery;
                std::string safepass = user->password;
index 6a0cfa303311667f05ad21390ea424b9e3a05ec8..7f825a72878c4af729859da317c19bdd266c1708 100644 (file)
@@ -32,9 +32,9 @@ class CommandTest : public Command
                        for(unsigned int i=0; i < count; i++)
                                user->Write(line);
                }
-               else if (parameters[0] == "freeze")
+               else if (parameters[0] == "freeze" && IS_LOCAL(user))
                {
-                       user->Penalty += 100;
+                       IS_LOCAL(user)->Penalty += 100;
                }
                else if (parameters[0] == "shutdown")
                {
index 1215dd0df73ed5235a2781e44a08dc0523645d4d..fff51817e80ea99101c299650fae2b67ae536de3 100644 (file)
@@ -56,28 +56,29 @@ class CommandUninvite : public Command
 
                irc::string xname(c->name.c_str());
 
-               if (!u->IsInvited(xname))
+               if (IS_LOCAL(u))
                {
-                       user->WriteNumeric(505, "%s %s %s :Is not invited to channel %s", user->nick.c_str(), u->nick.c_str(), c->name.c_str(), c->name.c_str());
-                       return CMD_FAILURE;
-               }
-               if (!c->HasUser(user))
-               {
-                       user->WriteNumeric(492, "%s %s :You're not on that channel!",user->nick.c_str(), c->name.c_str());
-                       return CMD_FAILURE;
+                       // TODO send messages & such out to remote servers
+                       LocalUser* lu = IS_LOCAL(u);
+                       if (!lu->IsInvited(xname))
+                       {
+                               user->WriteNumeric(505, "%s %s %s :Is not invited to channel %s", user->nick.c_str(), u->nick.c_str(), c->name.c_str(), c->name.c_str());
+                               return CMD_FAILURE;
+                       }
+                       user->WriteNumeric(494, "%s %s %s :Uninvited", user->nick.c_str(), c->name.c_str(), u->nick.c_str());
+                       lu->RemoveInvite(xname);
+                       lu->WriteNumeric(493, "%s :You were uninvited from %s by %s", u->nick.c_str(), c->name.c_str(), user->nick.c_str());
+                       c->WriteChannelWithServ(ServerInstance->Config->ServerName, "NOTICE %s :*** %s uninvited %s.",
+                               c->name.c_str(), user->nick.c_str(), u->nick.c_str());
                }
 
-               u->RemoveInvite(xname);
-               user->WriteNumeric(494, "%s %s %s :Uninvited", user->nick.c_str(), c->name.c_str(), u->nick.c_str());
-               u->WriteNumeric(493, "%s :You were uninvited from %s by %s", u->nick.c_str(), c->name.c_str(), user->nick.c_str());
-               c->WriteChannelWithServ(ServerInstance->Config->ServerName.c_str(), "NOTICE %s :*** %s uninvited %s.", c->name.c_str(), user->nick.c_str(), u->nick.c_str());
-
                return CMD_SUCCESS;
        }
 
        RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
        {
-               return ROUTE_BROADCAST;
+               User* u = ServerInstance->FindNick(parameters[0]);
+               return u ? ROUTE_UNICAST(u->server) : ROUTE_LOCALONLY;
        }
 };
 
@@ -98,7 +99,7 @@ class ModuleUninvite : public Module
 
        virtual Version GetVersion()
        {
-               return Version("Provides the UNINVITE command which lets users un-invite other users from channels (!)", VF_VENDOR | VF_COMMON);
+               return Version("Provides the UNINVITE command which lets users un-invite other users from channels", VF_VENDOR | VF_COMMON);
        }
 };
 
index 6889ddba369c757197800c114780665518e606c4..2d824c6b2ff188417a971ec57f54fd57ecebe26c 100644 (file)
@@ -81,13 +81,7 @@ void UserManager::AddUser(int socket, ClientListenSocket* via, irc::sockets::soc
         * First class check. We do this again in FullConnect after DNS is done, and NICK/USER is recieved.
         * See my note down there for why this is required. DO NOT REMOVE. :) -- w00t
         */
-       ConnectClass* i = New->SetClass();
-
-       if (!i)
-       {
-               this->QuitUser(New, "Access denied by configuration");
-               return;
-       }
+       New->SetClass();
 
        /*
         * Check connect class settings and initialise settings into User.
index dfb386871be45b24da09bf4b5fc4c4c2fb41146c..bcf50a1fff23e5ed9fc7026d8934f584fa50f4a7 100644 (file)
@@ -225,11 +225,9 @@ User::User(const std::string &uid)
 {
        server = ServerInstance->Config->ServerName;
        age = ServerInstance->Time();
-       Penalty = 0;
-       lastping = signon = idle_lastmsg = nping = registered = 0;
+       signon = idle_lastmsg = registered = 0;
        quietquit = quitting = exempt = dns_done = false;
        fd = -1;
-       AllowedPrivs = AllowedOperCommands = NULL;
        uuid = uid;
        client_sa.sa.sa_family = AF_UNSPEC;
 
@@ -244,8 +242,11 @@ User::User(const std::string &uid)
 
 LocalUser::LocalUser() : User(ServerInstance->GetUID())
 {
+       AllowedPrivs = AllowedOperCommands = NULL;
        bytes_in = bytes_out = cmds_in = cmds_out = 0;
        server_sa.sa.sa_family = AF_UNSPEC;
+       Penalty = 0;
+       lastping = nping = 0;
 }
 
 User::~User()
@@ -350,7 +351,7 @@ const std::string User::GetFullRealHost()
        return this->cached_fullrealhost;
 }
 
-bool User::IsInvited(const irc::string &channel)
+bool LocalUser::IsInvited(const irc::string &channel)
 {
        time_t now = ServerInstance->Time();
        InvitedList::iterator safei;
@@ -372,7 +373,7 @@ bool User::IsInvited(const irc::string &channel)
        return false;
 }
 
-InvitedList* User::GetInviteList()
+InvitedList* LocalUser::GetInviteList()
 {
        time_t now = ServerInstance->Time();
        /* Weed out expired invites here. */
@@ -390,7 +391,7 @@ InvitedList* User::GetInviteList()
        return &invites;
 }
 
-void User::InviteTo(const irc::string &channel, time_t invtimeout)
+void LocalUser::InviteTo(const irc::string &channel, time_t invtimeout)
 {
        time_t now = ServerInstance->Time();
        if (invtimeout != 0 && now > invtimeout) return; /* Don't add invites that are expired from the get-go. */
@@ -409,7 +410,7 @@ void User::InviteTo(const irc::string &channel, time_t invtimeout)
        invites.push_back(std::make_pair(channel, invtimeout));
 }
 
-void User::RemoveInvite(const irc::string &channel)
+void LocalUser::RemoveInvite(const irc::string &channel)
 {
        for (InvitedList::iterator i = invites.begin(); i != invites.end(); i++)
        {
@@ -421,11 +422,13 @@ void User::RemoveInvite(const irc::string &channel)
        }
 }
 
-bool User::HasModePermission(unsigned char mode, ModeType type)
+bool User::HasModePermission(unsigned char, ModeType)
 {
-       if (!IS_LOCAL(this))
-               return true;
+       return true;
+}
 
+bool LocalUser::HasModePermission(unsigned char mode, ModeType type)
+{
        if (!IS_OPER(this))
                return false;
 
@@ -434,19 +437,20 @@ bool User::HasModePermission(unsigned char mode, ModeType type)
        return ((type == MODETYPE_USER ? AllowedUserModes : AllowedChanModes))[(mode - 'A')];
 
 }
-
-bool User::HasPermission(const std::string &command)
+/*
+ * users on remote servers can completely bypass all permissions based checks.
+ * This prevents desyncs when one server has different type/class tags to another.
+ * That having been said, this does open things up to the possibility of source changes
+ * allowing remote kills, etc - but if they have access to the src, they most likely have
+ * access to the conf - so it's an end to a means either way.
+ */
+bool User::HasPermission(const std::string&)
 {
-       /*
-        * users on remote servers can completely bypass all permissions based checks.
-        * This prevents desyncs when one server has different type/class tags to another.
-        * That having been said, this does open things up to the possibility of source changes
-        * allowing remote kills, etc - but if they have access to the src, they most likely have
-        * access to the conf - so it's an end to a means either way.
-        */
-       if (!IS_LOCAL(this))
-               return true;
+       return true;
+}
 
+bool LocalUser::HasPermission(const std::string &command)
+{
        // are they even an oper at all?
        if (!IS_OPER(this))
        {
@@ -464,15 +468,13 @@ bool User::HasPermission(const std::string &command)
        return false;
 }
 
-
 bool User::HasPrivPermission(const std::string &privstr, bool noisy)
 {
-       if (!IS_LOCAL(this))
-       {
-               ServerInstance->Logs->Log("PRIVS", DEBUG, "Remote (yes)");
-               return true;
-       }
+       return true;
+}
 
+bool LocalUser::HasPrivPermission(const std::string &privstr, bool noisy)
+{
        if (!IS_OPER(this))
        {
                if (noisy)
@@ -510,14 +512,14 @@ void LocalUser::OnDataReady()
        if (quitting)
                return;
 
-       if (MyClass && recvq.length() > MyClass->GetRecvqMax() && !HasPrivPermission("users/flood/increased-buffers"))
+       if (recvq.length() > MyClass->GetRecvqMax() && !HasPrivPermission("users/flood/increased-buffers"))
        {
                ServerInstance->Users->QuitUser(this, "RecvQ exceeded");
                ServerInstance->SNO->WriteToSnoMask('a', "User %s RecvQ of %lu exceeds connect class maximum of %lu",
                        nick.c_str(), (unsigned long)recvq.length(), MyClass->GetRecvqMax());
        }
        unsigned long sendqmax = ULONG_MAX;
-       if (MyClass && !HasPrivPermission("users/flood/increased-buffers"))
+       if (!HasPrivPermission("users/flood/increased-buffers"))
                sendqmax = MyClass->GetSendqSoftMax();
        int penaltymax = MyClass->GetPenaltyThreshold();
        if (penaltymax == 0 || HasPrivPermission("users/flood/no-fakelag"))
@@ -566,7 +568,7 @@ eol_found:
 
 void LocalUser::AddWriteBuf(const std::string &data)
 {
-       if (!quitting && MyClass && getSendQSize() + data.length() > MyClass->GetSendqHardMax() && !HasPrivPermission("users/flood/increased-buffers"))
+       if (!quitting && getSendQSize() + data.length() > MyClass->GetSendqHardMax() && !HasPrivPermission("users/flood/increased-buffers"))
        {
                /*
                 * Quit the user FIRST, because otherwise we could recurse
@@ -602,18 +604,6 @@ CullResult User::cull()
        if (IS_LOCAL(this) && fd != INT_MAX)
                Close();
 
-       if (this->AllowedOperCommands)
-       {
-               delete AllowedOperCommands;
-               AllowedOperCommands = NULL;
-       }
-
-       if (this->AllowedPrivs)
-       {
-               delete AllowedPrivs;
-               AllowedPrivs = NULL;
-       }
-
        this->InvalidateCache();
        this->DecrementModes();
 
@@ -630,6 +620,18 @@ CullResult LocalUser::cull()
        else
                ServerInstance->Logs->Log("USERS", DEBUG, "Failed to remove user from vector");
 
+       if (this->AllowedOperCommands)
+       {
+               delete AllowedOperCommands;
+               AllowedOperCommands = NULL;
+       }
+
+       if (this->AllowedPrivs)
+       {
+               delete AllowedPrivs;
+               AllowedPrivs = NULL;
+       }
+
        if (client_sa.sa.sa_family != AF_UNSPEC)
                ServerInstance->Users->RemoveCloneCounts(this);
        return User::cull();
@@ -651,6 +653,14 @@ void User::Oper(const std::string &opertype, const std::string &opername)
        this->oper.assign(opertype, 0, 512);
        ServerInstance->Users->all_opers.push_back(this);
 
+       if (IS_LOCAL(this))
+               IS_LOCAL(this)->OperInternal();
+
+       FOREACH_MOD(I_OnPostOper,OnPostOper(this, opertype, opername));
+}
+
+void LocalUser::OperInternal()
+{
        /*
         * This might look like it's in the wrong place.
         * It is *not*!
@@ -721,60 +731,64 @@ void User::Oper(const std::string &opertype, const std::string &opername)
                        }
                }
        }
-
-       FOREACH_MOD(I_OnPostOper,OnPostOper(this, opertype, opername));
 }
 
 void User::UnOper()
 {
-       if (IS_OPER(this))
-       {
-               /*
-                * unset their oper type (what IS_OPER checks).
-                * note, order is important - this must come before modes as -o attempts
-                * to call UnOper. -- w00t
-                */
-               this->oper.clear();
+       if (!IS_OPER(this))
+               return;
 
+       /*
+        * unset their oper type (what IS_OPER checks).
+        * note, order is important - this must come before modes as -o attempts
+        * to call UnOper. -- w00t
+        */
+       this->oper.clear();
 
-               /* Remove all oper only modes from the user when the deoper - Bug #466*/
-               std::string moderemove("-");
 
-               for (unsigned char letter = 'A'; letter <= 'z'; letter++)
-               {
-                       ModeHandler* mh = ServerInstance->Modes->FindMode(letter, MODETYPE_USER);
-                       if (mh && mh->NeedsOper())
-                               moderemove += letter;
-               }
+       /* Remove all oper only modes from the user when the deoper - Bug #466*/
+       std::string moderemove("-");
 
+       for (unsigned char letter = 'A'; letter <= 'z'; letter++)
+       {
+               ModeHandler* mh = ServerInstance->Modes->FindMode(letter, MODETYPE_USER);
+               if (mh && mh->NeedsOper())
+                       moderemove += letter;
+       }
 
-               std::vector<std::string> parameters;
-               parameters.push_back(this->nick);
-               parameters.push_back(moderemove);
 
-               ServerInstance->Parser->CallHandler("MODE", parameters, this);
+       std::vector<std::string> parameters;
+       parameters.push_back(this->nick);
+       parameters.push_back(moderemove);
 
-               /* remove the user from the oper list. Will remove multiple entries as a safeguard against bug #404 */
-               ServerInstance->Users->all_opers.remove(this);
+       ServerInstance->Parser->CallHandler("MODE", parameters, this);
 
-               if (AllowedOperCommands)
-               {
-                       delete AllowedOperCommands;
-                       AllowedOperCommands = NULL;
-               }
+       /* remove the user from the oper list. Will remove multiple entries as a safeguard against bug #404 */
+       ServerInstance->Users->all_opers.remove(this);
 
-               if (AllowedPrivs)
-               {
-                       delete AllowedPrivs;
-                       AllowedPrivs = NULL;
-               }
+       if (IS_LOCAL(this))
+               IS_LOCAL(this)->UnOperInternal();
+       this->modes[UM_OPERATOR] = 0;
+}
 
-               AllowedUserModes.reset();
-               AllowedChanModes.reset();
-               this->modes[UM_OPERATOR] = 0;
+void LocalUser::UnOperInternal()
+{
+       if (AllowedOperCommands)
+       {
+               delete AllowedOperCommands;
+               AllowedOperCommands = NULL;
+       }
+
+       if (AllowedPrivs)
+       {
+               delete AllowedPrivs;
+               AllowedPrivs = NULL;
        }
+       AllowedUserModes.reset();
+       AllowedChanModes.reset();
 }
 
+
 /* adds or updates an entry in the whowas list */
 void User::AddToWhoWas()
 {
@@ -790,11 +804,15 @@ void User::AddToWhoWas()
 /*
  * Check class restrictions
  */
-void User::CheckClass()
+void LocalUser::CheckClass()
 {
        ConnectClass* a = this->MyClass;
 
-       if ((!a) || (a->type == CC_DENY))
+       if (!a)
+       {
+               ServerInstance->Users->QuitUser(this, "Access denied by configuration");
+       }
+       else if (a->type == CC_DENY)
        {
                ServerInstance->Users->QuitUser(this, "Unauthorised connection");
                return;
@@ -852,7 +870,7 @@ void LocalUser::FullConnect()
        /* Check the password, if one is required by the user's connect class.
         * This CANNOT be in CheckClass(), because that is called prior to PASS as well!
         */
-       if (MyClass && !MyClass->pass.empty())
+       if (!MyClass->pass.empty())
        {
                if (ServerInstance->PassCompare(this, MyClass->pass.c_str(), password.c_str(), MyClass->hash.c_str()))
                {
@@ -1641,7 +1659,7 @@ void User::SplitChanList(User* dest, const std::string &cl)
  * then their ip will be taken as 'priority' anyway, so for example,
  * <connect allow="127.0.0.1"> will match joe!bloggs@localhost
  */
-ConnectClass* LocalUser::SetClass(const std::string &explicit_name)
+void LocalUser::SetClass(const std::string &explicit_name)
 {
        ConnectClass *found = NULL;
 
@@ -1719,8 +1737,6 @@ ConnectClass* LocalUser::SetClass(const std::string &explicit_name)
        {
                MyClass = found;
        }
-
-       return this->MyClass;
 }
 
 /* looks up a users password for their connection class (<ALLOW>/<DENY> tags)
@@ -1728,9 +1744,14 @@ ConnectClass* LocalUser::SetClass(const std::string &explicit_name)
  * then their ip will be taken as 'priority' anyway, so for example,
  * <connect allow="127.0.0.1"> will match joe!bloggs@localhost
  */
+ConnectClass* LocalUser::GetClass()
+{
+       return MyClass;
+}
+
 ConnectClass* User::GetClass()
 {
-       return this->MyClass;
+       return NULL;
 }
 
 void User::PurgeEmptyChannels()
@@ -1776,11 +1797,6 @@ void User::ShowRULES()
        this->WriteNumeric(RPL_RULESEND, "%s :End of RULES command.",this->nick.c_str());
 }
 
-void User::IncreasePenalty(int increase)
-{
-       this->Penalty += increase;
-}
-
 void FakeUser::SetFakeServer(std::string name)
 {
        this->nick = name;