]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/users.cpp
Fix for bug #541: /taxonomy reporting metadata for incorrect user. Can someone please...
[user/henk/code/inspircd.git] / src / users.cpp
index c4c9fe9d160508a1de047f1244aa648622577371..a86c6f824aafdee5af99035e45f6c472bd02b1dd 100644 (file)
@@ -210,9 +210,9 @@ User::User(InspIRCd* Instance, const std::string &uid) : ServerInstance(Instance
        memset(snomasks,0,sizeof(snomasks));
 
        if (uid.empty())
-               uuid.assign(Instance->GetUID(), 0, UUID_LENGTH);
+               uuid.assign(Instance->GetUID(), 0, UUID_LENGTH - 1);
        else
-               uuid.assign(uid, 0, UUID_LENGTH);
+               uuid.assign(uid, 0, UUID_LENGTH - 1);
 
        ServerInstance->Logs->Log("USERS", DEBUG,"New UUID for user: %s (%s)", uuid.c_str(), uid.empty() ? "allocated new" : "used remote");
 
@@ -721,7 +721,7 @@ void User::Oper(const std::string &opertype, const std::string &opername)
                this->WriteServ("MODE %s :+o", this->nick.c_str());
                FOREACH_MOD(I_OnOper, OnOper(this, opertype));
                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, NICKMAX - 1);
+               this->oper.assign(opertype, 0, 512);
                ServerInstance->Users->all_opers.push_back(this);
 
                opertype_t::iterator iter_opertype = ServerInstance->Config->opertypes.find(this->oper.c_str());
@@ -886,7 +886,7 @@ void User::CheckClass()
        this->MaxChans = a->GetMaxChans();
 }
 
-void User::CheckLines()
+bool User::CheckLines()
 {
        const char* check[] = { "G" , "K", NULL };
 
@@ -899,10 +899,12 @@ void User::CheckLines()
                        if (r)
                        {
                                r->Apply(this);
-                               return;
+                               return true;
                        }
                }
        }
+
+       return false;
 }
 
 void User::FullConnect()
@@ -927,7 +929,8 @@ void User::FullConnect()
                return;
        }
 
-       CheckLines();
+       if (this->CheckLines())
+               return;
 
        this->WriteServ("NOTICE Auth :Welcome to \002%s\002!",ServerInstance->Config->Network);
        this->WriteNumeric(001, "%s :Welcome to the %s IRC Network %s!%s@%s",this->nick.c_str(), ServerInstance->Config->Network, this->nick.c_str(), this->ident.c_str(), this->host.c_str());
@@ -947,9 +950,11 @@ void User::FullConnect()
 
        /* Trigger LUSERS output, give modules a chance too */
        int MOD_RESULT = 0;
-       FOREACH_RESULT(I_OnPreCommand, OnPreCommand("LUSERS", std::vector<std::string>(), this, true, "LUSERS"));
+       std::string command("LUSERS");
+       std::vector<std::string> parameters;
+       FOREACH_RESULT(I_OnPreCommand, OnPreCommand(command, parameters, this, true, "LUSERS"));
        if (!MOD_RESULT)
-               ServerInstance->CallCommandHandler("LUSERS", std::vector<std::string>(), this);
+               ServerInstance->CallCommandHandler(command, parameters, this);
 
        /*
         * We don't set REG_ALL until triggering OnUserConnect, so some module events don't spew out stuff
@@ -959,6 +964,8 @@ void User::FullConnect()
 
        this->registered = REG_ALL;
 
+       ServerInstance->PI->Introduce(this);
+
        FOREACH_MOD(I_OnPostConnect,OnPostConnect(this));
 
        ServerInstance->SNO->WriteToSnoMask('c',"Client connecting on port %d: %s!%s@%s [%s] [%s]", this->GetPort(), this->nick.c_str(), this->ident.c_str(), this->host.c_str(), this->GetIPString(), this->fullname.c_str());
@@ -1094,13 +1101,116 @@ int User::GetProtocolFamily()
        return sin->sin_family;
 }
 
-/*
- * XXX the duplication here is horrid..
- * do we really need two methods doing essentially the same thing?
- */
+const char* User::GetCIDRMask(int range)
+{
+       static char buf[40];
+
+       if (this->ip == NULL)
+               return "";
+
+       if (range < 0)
+               throw "Negative range, sorry, no.";
+
+       /*
+        * Original code written by Oliver Lupton (Om).
+        * Integrated by me. Thanks. :) -- w00t
+        */
+       switch (this->GetProtocolFamily())
+       {
+#ifdef SUPPORT_IP6LINKS
+               case AF_INET6:
+               {
+                       struct in6_addr v6;
+        
+                       if(range > 128)
+                       {
+                               printf("Error, range given (%d) larger than address length (128)\n", range);
+                               return 0;
+                       }
+        
+                       if(inet_pton(AF_INET6, this->GetIPString(), &v6))
+                       {
+                               /* unsigned char s6_addr[16]; */
+                               int i;
+                               int bytestoblank;
+                               int extrabits;
+                               char buffer[64];
+
+                               if(range > 0)
+                               {
+                                       /* (128 - range) bits must be blanked, so ((128 - range) / 8) of the bytes, working backwards, must be blanked. */
+                                       bytestoblank = (128 - range) / 8;
+        
+                                       /* ((128 - range) % 8) bits of the next byte must also be blanked. */
+                                       extrabits = (128 - range) % 8;
+                                       v6.s6_addr[15 - bytestoblank] = (v6.s6_addr[15 - bytestoblank] >> extrabits) << extrabits;
+
+                                       for(i = 0; i < bytestoblank; i++)
+                                       {
+                                               v6.s6_addr[15 - i] = 0;
+                                       }
+                               }
+                               else
+                               {
+                                       for(i = 0; i < 15; i++)
+                                       {
+                                               v6.s6_addr[i] = 0;
+                                       }
+                               }
+
+                               sprintf(buf, "%s/%d\n", inet_ntop(AF_INET6, &v6, buffer, 64), range);
+                               return buf;
+                       }
+                       else
+                       {
+                               throw "CIDR mask for v6 failed";
+                       }
+
+               }
+               break;
+#endif
+               case AF_INET:
+               {
+                       struct in_addr v4;
+
+                       if (range > 32)
+                               throw "more than 32 bits on an ipv4 connection, can't do that..";
+
+                       if(inet_pton(AF_INET, this->GetIPString(), &v4))
+                       {
+                               char buffer[16];
+                               uint32_t temp;
+
+                               /* (32 - range) is the number of bits we are *ignoring*. We shift this left and then right to wipe off these bits. */
+
+                               if(range > 0)
+                               {
+                                       temp = ntohl(v4.s_addr);
+                                       temp = (temp >> (32 - range)) << (32 - range);
+                                       v4.s_addr = htonl(temp);
+                               }
+                               else
+                               {
+                                       v4.s_addr = 0;
+                               }
+
+                               sprintf(buf, "%s/%d\n", inet_ntop(AF_INET, &v4, buffer, 16), range);
+                               return buf;
+                       }
+                       else
+                       {
+                               throw "CIDR mask for v4 failed";
+                       }
+               }
+               break;
+       }
+
+       return ""; // unused, but oh well
+}
+
 const char* User::GetIPString(bool translate4in6)
 {
-       static char buf[1024];
+       static char buf[40];
 
        if (this->ip == NULL)
                return "";
@@ -1521,7 +1631,7 @@ bool User::ChangeName(const char* gecos)
                        return false;
                FOREACH_MOD(I_OnChangeName,OnChangeName(this,gecos));
        }
-       this->fullname.assign(gecos, 0, MAXGECOS+1);
+       this->fullname.assign(gecos, 0, ServerInstance->Config->Limits.MaxGecos);
 
        return true;
 }
@@ -1573,7 +1683,7 @@ bool User::ChangeIdent(const char* newident)
        if (this->ServerInstance->Config->CycleHosts)
                this->WriteCommonExcept("%s","QUIT :Changing ident");
 
-       this->ident.assign(newident, 0, IDENTMAX + 1);
+       this->ident.assign(newident, 0, ServerInstance->Config->Limits.IdentMax + 1);
 
        this->InvalidateCache();