]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/inspircd.cpp
Added <options noservices> behaviour for m_chanprotect.so as suggested by Craig
[user/henk/code/inspircd.git] / src / inspircd.cpp
index f226f2af507fc8c3b51685ae91bf69454438d669..310ef4043dcd73be4e1c1e077a7ae609260fbc3c 100644 (file)
@@ -82,8 +82,13 @@ int WHOWAS_MAX = 100;  // default 100 people maximum in the WHOWAS list
 int DieDelay  =  5;
 time_t startup_time = time(NULL);
 int NetBufferSize = 10240; // NetBufferSize used as the buffer size for all read() ops
+extern int MaxWhoResults;
 time_t nb_start = 0;
 
+bool AllowHalfop = true;
+bool AllowProtect = true;
+bool AllowFounder = true;
+
 extern vector<Module*> modules;
 std::vector<std::string> module_names;
 extern vector<ircd_module*> factory;
@@ -299,7 +304,8 @@ void readfile(file_cache &F, const char* fname)
 
 void ReadConfig(void)
 {
-       char dbg[MAXBUF],pauseval[MAXBUF],Value[MAXBUF],timeout[MAXBUF],NB[MAXBUF],flood[MAXBUF];
+       char dbg[MAXBUF],pauseval[MAXBUF],Value[MAXBUF],timeout[MAXBUF],NB[MAXBUF],flood[MAXBUF],MW[MAXBUF];
+       char AH[MAXBUF],AP[MAXBUF],AF[MAXBUF];
        ConnectClass c;
        
        LoadConf(CONFIG_FILE,&config_f);
@@ -319,12 +325,25 @@ void ReadConfig(void)
        ConfValue("die","value",0,DieValue,&config_f);
        ConfValue("options","loglevel",0,dbg,&config_f);
        ConfValue("options","netbuffersize",0,NB,&config_f);
+       ConfValue("options","maxwho",0,MW,&config_f);
+       ConfValue("options","allowhalfop",0,AH,&config_f);
+       ConfValue("options","allowprotect",0,AP,&config_f);
+       ConfValue("options","allowfounder",0,AF,&config_f);
        NetBufferSize = atoi(NB);
+       MaxWhoResults = atoi(MW);
+       AllowHalfop = ((!strcasecmp(AH,"true")) || (!strcasecmp(AH,"1")) || (!strcasecmp(AH,"yes")));
+       AllowProtect = ((!strcasecmp(AP,"true")) || (!strcasecmp(AP,"1")) || (!strcasecmp(AP,"yes")));
+       AllowFounder = ((!strcasecmp(AF,"true")) || (!strcasecmp(AF,"1")) || (!strcasecmp(AF,"yes")));
        if ((!NetBufferSize) || (NetBufferSize > 65535) || (NetBufferSize < 1024))
        {
                log(DEFAULT,"No NetBufferSize specified or size out of range, setting to default of 10240.");
                NetBufferSize = 10240;
        }
+       if ((!MaxWhoResults) || (MaxWhoResults > 65535) || (MaxWhoResults < 1))
+       {
+               log(DEFAULT,"No MaxWhoResults specified or size out of range, setting to default of 128.");
+               MaxWhoResults = 128;
+       }
        if (!strcmp(dbg,"debug"))
                LogLevel = DEBUG;
        if (!strcmp(dbg,"verbose"))
@@ -1114,6 +1133,7 @@ char* chanmodes(chanrec *chan)
        }
        if (strcmp(chan->key,""))
        {
+               strncat(sparam," ",MAXBUF);
                strncat(sparam,chan->key,MAXBUF);
        }
        if (chan->limit)
@@ -1290,6 +1310,7 @@ chanrec* add_channel(userrec *user, const char* cn, const char* key, bool overri
 
        if (!FindChan(cname))
        {
+               int MOD_RESULT = 0;
                FOREACH_RESULT(OnUserPreJoin(user,NULL,cname));
                if (MOD_RESULT) {
                        return NULL;
@@ -1327,6 +1348,7 @@ chanrec* add_channel(userrec *user, const char* cn, const char* key, bool overri
                        // and bans (used by servers)
                        if (!override)
                        {
+                               int MOD_RESULT = 0;
                                FOREACH_RESULT(OnUserPreJoin(user,Ptr,cname));
                                if (MOD_RESULT) {
                                        return NULL;
@@ -1443,7 +1465,14 @@ chanrec* add_channel(userrec *user, const char* cn, const char* key, bool overri
                        {
                                // use the stamdard J token with no privilages.
                                char buffer[MAXBUF];
-                               snprintf(buffer,MAXBUF,"J %s %s",user->nick,Ptr->name);
+                               if (created == 2)
+                               {
+                                       snprintf(buffer,MAXBUF,"J %s @%s",user->nick,Ptr->name);
+                               }
+                               else
+                               {
+                                       snprintf(buffer,MAXBUF,"J %s %s",user->nick,Ptr->name);
+                               }
                                NetSendToAll(buffer);
                        }
 
@@ -1573,18 +1602,28 @@ void kick_channel(userrec *src,userrec *user, chanrec *Ptr, char* reason)
                WriteServ(src->fd,"441 %s %s %s :They are not on that channel",src->nick, user->nick, Ptr->name);
                return;
        }
-       if (((cstatus(src,Ptr) < STATUS_HOP) || (cstatus(src,Ptr) < cstatus(user,Ptr))) && (!is_uline(src->server)))
+
+       int MOD_RESULT = 0;
+       FOREACH_RESULT(OnAccessCheck(src,user,Ptr,AC_KICK));
+       
+       if (MOD_RESULT == ACR_DENY)
+               return;
+
+       if (MOD_RESULT == ACR_DEFAULT)
        {
-               if (cstatus(src,Ptr) == STATUS_HOP)
-               {
-                       WriteServ(src->fd,"482 %s %s :You must be a channel operator",src->nick, Ptr->name);
-               }
-               else
+               if (((cstatus(src,Ptr) < STATUS_HOP) || (cstatus(src,Ptr) < cstatus(user,Ptr))) && (!is_uline(src->server)))
                {
-                       WriteServ(src->fd,"482 %s %s :You must be at least a half-operator to change modes on this channel",src->nick, Ptr->name);
+                       if (cstatus(src,Ptr) == STATUS_HOP)
+                       {
+                               WriteServ(src->fd,"482 %s %s :You must be a channel operator",src->nick, Ptr->name);
+                       }
+                       else
+                       {
+                               WriteServ(src->fd,"482 %s %s :You must be at least a half-operator to change modes on this channel",src->nick, Ptr->name);
+                       }
+                       
+                       return;
                }
-               
-               return;
        }
        
        for (int i =0; i != MAXCHANS; i++)
@@ -1840,6 +1879,56 @@ void kill_link(userrec *user,const char* r)
        }
 }
 
+void kill_link_silent(userrec *user,const char* r)
+{
+       user_hash::iterator iter = clientlist.find(user->nick);
+       
+       char reason[MAXBUF];
+       
+       strncpy(reason,r,MAXBUF);
+
+       if (strlen(reason)>MAXQUIT)
+       {
+               reason[MAXQUIT-1] = '\0';
+       }
+
+       log(DEBUG,"kill_link: %s '%s'",user->nick,reason);
+       Write(user->fd,"ERROR :Closing link (%s@%s) [%s]",user->ident,user->host,reason);
+       log(DEBUG,"closing fd %d",user->fd);
+
+       /* bugfix, cant close() a nonblocking socket (sux!) */
+       if (user->registered == 7) {
+               FOREACH_MOD OnUserQuit(user);
+               WriteCommonExcept(user,"QUIT :%s",reason);
+
+               // Q token must go to ALL servers!!!
+               char buffer[MAXBUF];
+               snprintf(buffer,MAXBUF,"Q %s :%s",user->nick,reason);
+               NetSendToAll(buffer);
+       }
+
+       /* push the socket on a stack of sockets due to be closed at the next opportunity
+        * 'Client exited' is an exception to this as it means the client side has already
+        * closed the socket, we don't need to do it.
+        */
+       fd_reap.push_back(user->fd);
+       
+       bool do_purge = false;
+       
+       if (iter != clientlist.end())
+       {
+               log(DEBUG,"deleting user hash value %d",iter->second);
+               if ((iter->second) && (user->registered == 7)) {
+                       delete iter->second;
+               }
+               clientlist.erase(iter);
+       }
+
+       if (user->registered == 7) {
+               purge_empty_chans();
+       }
+}
+
 
 
 // looks up a users password for their connection class (<ALLOW>/<DENY> tags)
@@ -2046,7 +2135,7 @@ void AddClient(int socket, char* host, int port, bool iscached, char* ip)
        clientlist[tempnick] = new userrec();
 
        NonBlocking(socket);
-       log(DEBUG,"AddClient: %d %s %d",socket,host,port);
+       log(DEBUG,"AddClient: %d %s %d %s",socket,host,port,ip);
 
        clientlist[tempnick]->fd = socket;
        strncpy(clientlist[tempnick]->nick, tn2,NICKMAX);
@@ -2240,7 +2329,7 @@ void ConnectUser(userrec *user)
        {
                char reason[MAXBUF];
                snprintf(reason,MAXBUF,"G-Lined: %s",r);
-               kill_link(user,reason);
+               kill_link_silent(user,reason);
                return;
        }
 
@@ -2249,7 +2338,7 @@ void ConnectUser(userrec *user)
        {
                char reason[MAXBUF];
                snprintf(reason,MAXBUF,"K-Lined: %s",r);
-               kill_link(user,reason);
+               kill_link_silent(user,reason);
                return;
        }
 
@@ -2265,7 +2354,7 @@ void ConnectUser(userrec *user)
        WriteOpers("*** Client connecting on port %d: %s!%s@%s",user->port,user->nick,user->ident,user->host);
        
        char buffer[MAXBUF];
-       snprintf(buffer,MAXBUF,"N %d %s %s %s %s +%s %s :%s",user->age,user->nick,user->host,user->dhost,user->ident,user->modes,ServerName,user->fullname);
+       snprintf(buffer,MAXBUF,"N %d %s %s %s %s +%s %s %s :%s",user->age,user->nick,user->host,user->dhost,user->ident,user->modes,user->ip,ServerName,user->fullname);
        NetSendToAll(buffer);
 }
 
@@ -2525,7 +2614,7 @@ void process_command(userrec *user, char* cmd)
        for (int i = 0; i <= MODCOUNT; i++)
        {
                std::string oldtmp = tmp;
-               modules[i]->OnServerRaw(tmp,true);
+               modules[i]->OnServerRaw(tmp,true,user);
                if (oldtmp != tmp)
                {
                        log(DEBUG,"A Module changed the input string!");
@@ -2662,6 +2751,13 @@ void process_command(userrec *user, char* cmd)
                                                cmd_found = 1;
                                                return;
                                        }
+                                       if ((cmdlist[i].flags_needed) && (!user->HasPermission(command)))
+                                       {
+                                               log(DEBUG,"process_command: permission denied: %s %s",user->nick,command);
+                                               WriteServ(user->fd,"481 %s :Permission Denied- Oper type %s does not have access to command %s",user->nick,user->oper,command);
+                                               cmd_found = 1;
+                                               return;
+                                       }
                                        /* if the command isnt USER, PASS, or NICK, and nick is empty,
                                         * deny command! */
                                        if ((strncmp(command,"USER",4)) && (strncmp(command,"NICK",4)) && (strncmp(command,"PASS",4)))
@@ -2846,7 +2942,7 @@ void DoSync(serverrec* serv, char* tcp_host)
        // send users and channels
        for (user_hash::iterator u = clientlist.begin(); u != clientlist.end(); u++)
        {
-               snprintf(data,MAXBUF,"N %d %s %s %s %s +%s %s :%s",u->second->age,u->second->nick,u->second->host,u->second->dhost,u->second->ident,u->second->modes,u->second->server,u->second->fullname);
+               snprintf(data,MAXBUF,"N %d %s %s %s %s +%s %s %s :%s",u->second->age,u->second->nick,u->second->host,u->second->dhost,u->second->ident,u->second->modes,u->second->ip,u->second->server,u->second->fullname);
                serv->SendPacket(data,tcp_host);
                if (strcmp(chlist(u->second),""))
                {
@@ -2872,6 +2968,8 @@ void DoSync(serverrec* serv, char* tcp_host)
                        serv->SendPacket(data,tcp_host);
                }
        }
+       // sync global zlines, glines, etc
+       sync_xlines(serv,tcp_host);
        snprintf(data,MAXBUF,"F %d",time(NULL));
        serv->SendPacket(data,tcp_host);
        log(DEBUG,"Sent sync");
@@ -3493,7 +3591,7 @@ int InspIRCd(void)
                                }
                                else
                                {
-                                       AddClient(incomingSockfd, resolved, ports[count], iscached, target);
+                                       AddClient(incomingSockfd, resolved, ports[count], iscached, inet_ntoa (client.sin_addr));
                                        log(DEBUG,"InspIRCd: adding client on port %d fd=%d",ports[count],incomingSockfd);
                                }
                                goto label;