]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Working privs implementation, and example usage in NOTICE for mass messaging.
authorw00t <w00t@e03df62e-2008-0410-955e-edbf42e46eb7>
Sat, 18 Oct 2008 16:52:48 +0000 (16:52 +0000)
committerw00t <w00t@e03df62e-2008-0410-955e-edbf42e46eb7>
Sat, 18 Oct 2008 16:52:48 +0000 (16:52 +0000)
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@10662 e03df62e-2008-0410-955e-edbf42e46eb7

conf/opers.conf.example
include/configreader.h
include/users.h
src/commands/cmd_notice.cpp
src/configreader.cpp
src/inspircd.cpp
src/users.cpp

index c8bdc0a64656b2e48b2600bd6096f0f84fa41680..d1e317aad34c6593dc07f50633360e05160f46ad 100644 (file)
@@ -17,6 +17,9 @@
      # commands: oper commands that users of this class can run.
      commands="DIE RESTART REHASH LOADMODULE UNLOADMODULE RELOAD" 
 
+     # privs: special priviledges that users with this class may utilise.
+#     privs="users/mass-message"
+
      # usermodes: Oper-only usermodes that opers with this class can use.
      usermodes="*" 
 
index 41a0fc9b1e81ba208ccbfe61ed7ecfe5a611b46d..89116c5c5fa888c3545b73a63e293d51f6efe763 100644 (file)
@@ -232,13 +232,19 @@ struct operclass_data : public Extensible
 {
        /** Command list for the class
         */
-       char* commandlist;
+       char *commandlist;
+
        /** Channel mode list for the class
         */
-       char* cmodelist;
+       char *cmodelist;
+
        /** User mode list for the class
         */
-       char* umodelist;
+       char *umodelist;
+
+       /** Priviledges given by this class
+        */
+       char *privs;
 };
 
 /** A Set of oper classes
index 2f87300889da260233561e2843cbe308097934ea..d8a9b3e64176df256eebdd4c2109addc4a870eb5 100644 (file)
@@ -794,8 +794,9 @@ class CoreExport User : public EventHandler
         * 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 HasPrivPermission(const std::string &privstr, bool noisy = true);
 
        /** 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
index 37f11eeb9d74d2139053b499d145dc4aa6d07748..537f8ac784725b90233051b05d95a971a8a7713f 100644 (file)
@@ -30,8 +30,11 @@ CmdResult CommandNotice::Handle (const std::vector<std::string>& parameters, Use
        
        if (ServerInstance->Parser->LoopCall(user, this, parameters, 0))
                return CMD_SUCCESS;
-       if ((parameters[0][0] == '$') && (IS_OPER(user) || ServerInstance->ULine(user->server)))
+       if (parameters[0][0] == '$')
        {
+               if (!user->HasPrivPermission("users/mass-message"))
+                       return CMD_SUCCESS;
+
                int MOD_RESULT = 0;
                std::string temp = parameters[1];
                FOREACH_RESULT(I_OnUserPreNotice,OnUserPreNotice(user, (void*)parameters[0].c_str(), TYPE_SERVER, temp, 0, exempt_list));
index 1185078615224f9a959c60eb76ea6297afabb3e1..18914613749422bc7a2aec65f6dd4fb113e57299 100644 (file)
@@ -913,9 +913,9 @@ void ServerConfig::Read(bool bail, const std::string &useruid)
                                InitTypes, DoType, DoneClassesAndTypes},
 
                {"class",
-                               {"name",        "commands",     "usermodes",    "chanmodes",    NULL},
-                               {"",            "",             "",             "",             NULL},
-                               {DT_NOSPACES,   DT_CHARPTR,     DT_CHARPTR,     DT_CHARPTR},
+                               {"name",        "commands",     "usermodes",    "chanmodes",    "privs",        NULL},
+                               {"",            "",                             "",                             "",                     "",                     NULL},
+                               {DT_NOSPACES,   DT_CHARPTR,     DT_CHARPTR,     DT_CHARPTR, DT_CHARPTR},
                                InitClasses, DoClass, DoneClassesAndTypes},
        
                {NULL,
@@ -2224,6 +2224,8 @@ bool InitClasses(ServerConfig* conf, const char*)
                                delete[] n->second.cmodelist;
                        if (n->second.umodelist)
                                delete[] n->second.umodelist;
+                       if (n->second.privs)
+                               delete[] n->second.privs;
                }
        }
 
@@ -2252,6 +2254,7 @@ bool DoClass(ServerConfig* conf, const char* tag, char**, ValueList &values, int
        const char* CommandList = values[1].GetString();
        const char* UModeList = values[2].GetString();
        const char* CModeList = values[3].GetString();
+       const char *PrivsList = values[4].GetString();
 
        for (const char* c = UModeList; *c; ++c)
        {
@@ -2271,6 +2274,7 @@ bool DoClass(ServerConfig* conf, const char* tag, char**, ValueList &values, int
        conf->operclass[ClassName].commandlist = strnewdup(CommandList);
        conf->operclass[ClassName].umodelist = strnewdup(UModeList);
        conf->operclass[ClassName].cmodelist = strnewdup(CModeList);
+       conf->operclass[ClassName].privs = strnewdup(PrivsList);
        return true;
 }
 
index 3a2392ee67f7b9a0051adb50fef6acdb33ff1a00..463f9d82fdcbc130a85131d0005c4aa61c79b84f 100644 (file)
@@ -656,8 +656,6 @@ InspIRCd::InspIRCd(int argc, char** argv)
        /* set up fake client again this time with the correct uid */
        this->FakeClient = new User(this, "#INVALID");
        this->FakeClient->SetFd(FD_MAGIC_NUMBER);
-       this->FakeClient->HasPrivPermission("users/override/topic");
-       exit(0);
 
        // Get XLine to do it's thing.
        this->XLines->CheckELines();
index 3b69c1a258e4186709c13247188e98b131b53251..2b6e00e0e4ec79746dbce34ea2b672311d977767 100644 (file)
@@ -216,7 +216,7 @@ User::User(InspIRCd* Instance, const std::string &uid) : ServerInstance(Instance
        Visibility = NULL;
        ip = NULL;
        MyClass = NULL;
-       AllowedOperCommands = NULL;
+       AllowedPrivs = AllowedOperCommands = NULL;
        chans.clear();
        invites.clear();
 
@@ -242,12 +242,19 @@ User::~User()
                this->MyClass->RefCount--;
                ServerInstance->Logs->Log("USERS", DEBUG, "User destructor -- connect refcount now: %lu", this->MyClass->RefCount);
        }
+
        if (this->AllowedOperCommands)
        {
                delete AllowedOperCommands;
                AllowedOperCommands = NULL;
        }
 
+       if (this->AllowedPrivs)
+       {
+               delete AllowedPrivs;
+               AllowedPrivs = NULL;
+       }
+
        this->InvalidateCache();
        this->DecrementModes();
 
@@ -505,10 +512,46 @@ bool User::HasPermission(const std::string &command)
 }
 
 
-bool User::HasPrivPermission(const std::string &privstr)
+bool User::HasPrivPermission(const std::string &privstr, bool noisy)
 {
-       ServerInstance->Logs->Log("CRAP", DEBUG, "Checking if I have " + privstr);
-       return true;
+       ServerInstance->Logs->Log("PRIVS", DEBUG, "Checking if I have " + privstr);
+       if (!IS_LOCAL(this))
+       {
+               ServerInstance->Logs->Log("PRIVS", DEBUG, "Remote (yes)");
+               return true;
+       }
+
+       if (!IS_OPER(this))
+       {
+               if (noisy)
+                       this->WriteServ("NOTICE %s :You are not an oper", this->nick.c_str());
+               ServerInstance->Logs->Log("PRIVS", DEBUG, "Not oper (no)");
+               return false;
+       }
+
+       if (!AllowedPrivs)
+       {
+               if (noisy)
+                       this->WriteServ("NOTICE %s :Privset empty(!?)", this->nick.c_str());
+               ServerInstance->Logs->Log("PRIVS", DEBUG, "No privs(?) (no)");
+               return false;
+       }
+
+       if (AllowedPrivs->find(privstr) != AllowedPrivs->end())
+       {
+               ServerInstance->Logs->Log("PRIVS", DEBUG, "I do have it.");             
+               return true;
+       }
+       else if (AllowedPrivs->find("*") != AllowedPrivs->end())
+       {
+               ServerInstance->Logs->Log("PRIVS", DEBUG, "I allow all.");
+               return true;
+       }
+
+       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());
+       ServerInstance->Logs->Log("PRIVS", DEBUG, "I don't have it...");
+       return false;
 }
 
 bool User::AddBuffer(const std::string &a)
@@ -717,28 +760,40 @@ void User::Oper(const std::string &opertype, const std::string &opername)
        opertype_t::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.
 
-               std::string myclass, mycmd;
+               std::string myclass, mycmd, mypriv;
                irc::spacesepstream Classes(iter_opertype->second);
                while (Classes.GetToken(myclass))
                {
                        operclass_t::iterator iter_operclass = ServerInstance->Config->operclass.find(myclass.c_str());
                        if (iter_operclass != ServerInstance->Config->operclass.end())
                        {
+                               /* Process commands */
                                irc::spacesepstream CommandList(iter_operclass->second.commandlist);
                                while (CommandList.GetToken(mycmd))
                                {
                                        this->AllowedOperCommands->insert(mycmd);
                                }
+
+                               irc::spacesepstream PrivList(iter_operclass->second.privs);
+                               while (PrivList.GetToken(mypriv))
+                               {
+                                       this->AllowedPrivs->insert(mypriv);
+                               }
+
                                for (unsigned char* c = (unsigned char*)iter_operclass->second.umodelist; *c; ++c)
                                {
                                        if (*c == '*')
@@ -750,6 +805,7 @@ void User::Oper(const std::string &opertype, const std::string &opername)
                                                this->AllowedUserModes[*c - 'A'] = true;
                                        }
                                }
+
                                for (unsigned char* c = (unsigned char*)iter_operclass->second.cmodelist; *c; ++c)
                                {
                                        if (*c == '*')
@@ -804,6 +860,12 @@ void User::UnOper()
                        AllowedOperCommands = NULL;
                }
 
+               if (AllowedPrivs)
+               {
+                       delete AllowedPrivs;
+                       AllowedPrivs = NULL;
+               }
+
                AllowedUserModes.reset();
                AllowedChanModes.reset();
        }