00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "inspircd.h"
00017 #include <stdarg.h>
00018 #include "socketengine.h"
00019 #include "xline.h"
00020 #include "bancache.h"
00021 #include "commands/cmd_whowas.h"
00022
00023
00024 unsigned long uniq_id = 1;
00025
00026 static unsigned long* already_sent = NULL;
00027
00028
00029 void InitializeAlreadySent(SocketEngine* SE)
00030 {
00031 already_sent = new unsigned long[SE->GetMaxFds()];
00032 memset(already_sent, 0, SE->GetMaxFds() * sizeof(unsigned long));
00033 }
00034
00035
00036 std::string User::ProcessNoticeMasks(const char *sm)
00037 {
00038 bool adding = true, oldadding = false;
00039 const char *c = sm;
00040 std::string output;
00041
00042 while (c && *c)
00043 {
00044 switch (*c)
00045 {
00046 case '+':
00047 adding = true;
00048 break;
00049 case '-':
00050 adding = false;
00051 break;
00052 case '*':
00053 for (unsigned char d = 'A'; d <= 'z'; d++)
00054 {
00055 if (ServerInstance->SNO->IsEnabled(d))
00056 {
00057 if ((!IsNoticeMaskSet(d) && adding) || (IsNoticeMaskSet(d) && !adding))
00058 {
00059 if ((oldadding != adding) || (!output.length()))
00060 output += (adding ? '+' : '-');
00061
00062 this->SetNoticeMask(d, adding);
00063
00064 output += d;
00065 }
00066 }
00067 oldadding = adding;
00068 }
00069 break;
00070 default:
00071 if ((*c >= 'A') && (*c <= 'z') && (ServerInstance->SNO->IsEnabled(*c)))
00072 {
00073 if ((!IsNoticeMaskSet(*c) && adding) || (IsNoticeMaskSet(*c) && !adding))
00074 {
00075 if ((oldadding != adding) || (!output.length()))
00076 output += (adding ? '+' : '-');
00077
00078 this->SetNoticeMask(*c, adding);
00079
00080 output += *c;
00081 }
00082 }
00083 else
00084 this->WriteNumeric(ERR_UNKNOWNSNOMASK, "%s %c :is unknown snomask char to me", this->nick.c_str(), *c);
00085
00086 oldadding = adding;
00087 break;
00088 }
00089
00090 *c++;
00091 }
00092
00093 return output;
00094 }
00095
00096 void User::StartDNSLookup()
00097 {
00098 try
00099 {
00100 bool cached = false;
00101 const char* sip = this->GetIPString(false);
00102
00103
00104 if (!strncmp(sip, "0::ffff:", 8))
00105 res_reverse = new UserResolver(this->ServerInstance, this, sip + 8, DNS_QUERY_PTR4, cached);
00106 else
00107 res_reverse = new UserResolver(this->ServerInstance, this, sip, this->GetProtocolFamily() == AF_INET ? DNS_QUERY_PTR4 : DNS_QUERY_PTR6, cached);
00108
00109 this->ServerInstance->AddResolver(res_reverse, cached);
00110 }
00111 catch (CoreException& e)
00112 {
00113 ServerInstance->Logs->Log("USERS", DEBUG,"Error in resolver: %s",e.GetReason());
00114 }
00115 }
00116
00117 bool User::IsNoticeMaskSet(unsigned char sm)
00118 {
00119 if (!isalpha(sm))
00120 return false;
00121 return (snomasks[sm-65]);
00122 }
00123
00124 void User::SetNoticeMask(unsigned char sm, bool value)
00125 {
00126 if (!isalpha(sm))
00127 return;
00128 snomasks[sm-65] = value;
00129 }
00130
00131 const char* User::FormatNoticeMasks()
00132 {
00133 static char data[MAXBUF];
00134 int offset = 0;
00135
00136 for (int n = 0; n < 64; n++)
00137 {
00138 if (snomasks[n])
00139 data[offset++] = n+65;
00140 }
00141
00142 data[offset] = 0;
00143 return data;
00144 }
00145
00146 bool User::IsModeSet(unsigned char m)
00147 {
00148 if (!isalpha(m))
00149 return false;
00150 return (modes[m-65]);
00151 }
00152
00153 void User::SetMode(unsigned char m, bool value)
00154 {
00155 if (!isalpha(m))
00156 return;
00157 modes[m-65] = value;
00158 }
00159
00160 const char* User::FormatModes()
00161 {
00162 static char data[MAXBUF];
00163 int offset = 0;
00164 for (int n = 0; n < 64; n++)
00165 {
00166 if (modes[n])
00167 data[offset++] = n+65;
00168 }
00169 data[offset] = 0;
00170 return data;
00171 }
00172
00173 void User::DecrementModes()
00174 {
00175 ServerInstance->Logs->Log("USERS", DEBUG, "DecrementModes()");
00176 for (unsigned char n = 'A'; n <= 'z'; n++)
00177 {
00178 if (modes[n-65])
00179 {
00180 ServerInstance->Logs->Log("USERS", DEBUG,"DecrementModes() found mode %c", n);
00181 ModeHandler* mh = ServerInstance->Modes->FindMode(n, MODETYPE_USER);
00182 if (mh)
00183 {
00184 ServerInstance->Logs->Log("USERS", DEBUG,"Found handler %c and call ChangeCount", n);
00185 mh->ChangeCount(-1);
00186 }
00187 }
00188 }
00189 }
00190
00191 User::User(InspIRCd* Instance, const std::string &uid) : ServerInstance(Instance)
00192 {
00193 server = (char*)Instance->FindServerNamePtr(Instance->Config->ServerName);
00194 reset_due = ServerInstance->Time();
00195 age = ServerInstance->Time();
00196 Penalty = 0;
00197 lines_in = lastping = signon = idle_lastmsg = nping = registered = 0;
00198 bytes_in = bytes_out = cmds_in = cmds_out = 0;
00199 quietquit = OverPenalty = ExemptFromPenalty = quitting = exempt = haspassed = dns_done = false;
00200 fd = -1;
00201 recvq.clear();
00202 sendq.clear();
00203 res_forward = res_reverse = NULL;
00204 Visibility = NULL;
00205 ip = NULL;
00206 MyClass = NULL;
00207 io = NULL;
00208 AllowedUserModes = NULL;
00209 AllowedChanModes = NULL;
00210 AllowedOperCommands = NULL;
00211 chans.clear();
00212 invites.clear();
00213
00214 if (uid.empty())
00215 uuid.assign(Instance->GetUID(), 0, UUID_LENGTH - 1);
00216 else
00217 uuid.assign(uid, 0, UUID_LENGTH - 1);
00218
00219 ServerInstance->Logs->Log("USERS", DEBUG,"New UUID for user: %s (%s)", uuid.c_str(), uid.empty() ? "allocated new" : "used remote");
00220
00221 user_hash::iterator finduuid = Instance->Users->uuidlist->find(uuid);
00222 if (finduuid == Instance->Users->uuidlist->end())
00223 (*Instance->Users->uuidlist)[uuid] = this;
00224 else
00225 throw CoreException("Duplicate UUID "+std::string(uuid)+" in User constructor");
00226 }
00227
00228 User::~User()
00229 {
00230
00231 if (this->MyClass)
00232 {
00233 this->MyClass->RefCount--;
00234 ServerInstance->Logs->Log("USERS", DEBUG, "User destructor -- connect refcount now: %lu", this->MyClass->RefCount);
00235 }
00236 if (this->AllowedOperCommands)
00237 {
00238 delete AllowedOperCommands;
00239 AllowedOperCommands = NULL;
00240 }
00241
00242 if (this->AllowedUserModes)
00243 {
00244 delete[] AllowedUserModes;
00245 AllowedUserModes = NULL;
00246 }
00247
00248 if (this->AllowedChanModes)
00249 {
00250 delete[] AllowedChanModes;
00251 AllowedChanModes = NULL;
00252 }
00253
00254 this->InvalidateCache();
00255 this->DecrementModes();
00256
00257 if (ip)
00258 {
00259 ServerInstance->Users->RemoveCloneCounts(this);
00260
00261 if (this->GetProtocolFamily() == AF_INET)
00262 {
00263 delete (sockaddr_in*)ip;
00264 }
00265 #ifdef SUPPORT_IP6LINKS
00266 else
00267 {
00268 delete (sockaddr_in6*)ip;
00269 }
00270 #endif
00271 }
00272
00273 ServerInstance->Users->uuidlist->erase(uuid);
00274 }
00275
00276 const std::string& User::MakeHost()
00277 {
00278 if (!this->cached_makehost.empty())
00279 return this->cached_makehost;
00280
00281 char nhost[MAXBUF];
00282
00283 char* t = nhost;
00284 for(const char* n = ident.c_str(); *n; n++)
00285 *t++ = *n;
00286 *t++ = '@';
00287 for(const char* n = host.c_str(); *n; n++)
00288 *t++ = *n;
00289 *t = 0;
00290
00291 this->cached_makehost.assign(nhost);
00292
00293 return this->cached_makehost;
00294 }
00295
00296 const std::string& User::MakeHostIP()
00297 {
00298 if (!this->cached_hostip.empty())
00299 return this->cached_hostip;
00300
00301 char ihost[MAXBUF];
00302
00303 char* t = ihost;
00304 for(const char* n = ident.c_str(); *n; n++)
00305 *t++ = *n;
00306 *t++ = '@';
00307 for(const char* n = this->GetIPString(); *n; n++)
00308 *t++ = *n;
00309 *t = 0;
00310
00311 this->cached_hostip = ihost;
00312
00313 return this->cached_hostip;
00314 }
00315
00316 void User::CloseSocket()
00317 {
00318 if (this->fd > -1)
00319 {
00320 ServerInstance->SE->Shutdown(this, 2);
00321 ServerInstance->SE->Close(this);
00322 }
00323 }
00324
00325 const std::string& User::GetFullHost()
00326 {
00327 if (!this->cached_fullhost.empty())
00328 return this->cached_fullhost;
00329
00330 char result[MAXBUF];
00331 char* t = result;
00332 for(const char* n = nick.c_str(); *n; n++)
00333 *t++ = *n;
00334 *t++ = '!';
00335 for(const char* n = ident.c_str(); *n; n++)
00336 *t++ = *n;
00337 *t++ = '@';
00338 for(const char* n = dhost.c_str(); *n; n++)
00339 *t++ = *n;
00340 *t = 0;
00341
00342 this->cached_fullhost = result;
00343
00344 return this->cached_fullhost;
00345 }
00346
00347 char* User::MakeWildHost()
00348 {
00349 static char nresult[MAXBUF];
00350 char* t = nresult;
00351 *t++ = '*'; *t++ = '!';
00352 *t++ = '*'; *t++ = '@';
00353 for(const char* n = dhost.c_str(); *n; n++)
00354 *t++ = *n;
00355 *t = 0;
00356 return nresult;
00357 }
00358
00359 int User::ReadData(void* buffer, size_t size)
00360 {
00361 if (IS_LOCAL(this))
00362 {
00363 #ifndef WIN32
00364 return read(this->fd, buffer, size);
00365 #else
00366 return recv(this->fd, (char*)buffer, size, 0);
00367 #endif
00368 }
00369 else
00370 return 0;
00371 }
00372
00373
00374 const std::string& User::GetFullRealHost()
00375 {
00376 if (!this->cached_fullrealhost.empty())
00377 return this->cached_fullrealhost;
00378
00379 char fresult[MAXBUF];
00380 char* t = fresult;
00381 for(const char* n = nick.c_str(); *n; n++)
00382 *t++ = *n;
00383 *t++ = '!';
00384 for(const char* n = ident.c_str(); *n; n++)
00385 *t++ = *n;
00386 *t++ = '@';
00387 for(const char* n = host.c_str(); *n; n++)
00388 *t++ = *n;
00389 *t = 0;
00390
00391 this->cached_fullrealhost = fresult;
00392
00393 return this->cached_fullrealhost;
00394 }
00395
00396 bool User::IsInvited(const irc::string &channel)
00397 {
00398 time_t now = time(NULL);
00399 InvitedList::iterator safei;
00400 for (InvitedList::iterator i = invites.begin(); i != invites.end(); ++i)
00401 {
00402 if (channel == i->first)
00403 {
00404 if (i->second != 0 && now > i->second)
00405 {
00406
00407 safei = i;
00408 --i;
00409 invites.erase(safei);
00410 continue;
00411 }
00412 return true;
00413 }
00414 }
00415 return false;
00416 }
00417
00418 InvitedList* User::GetInviteList()
00419 {
00420 time_t now = time(NULL);
00421
00422 InvitedList::iterator safei;
00423 for (InvitedList::iterator i = invites.begin(); i != invites.end(); ++i)
00424 {
00425 if (i->second != 0 && now > i->second)
00426 {
00427
00428 safei = i;
00429 --i;
00430 invites.erase(safei);
00431 }
00432 }
00433 return &invites;
00434 }
00435
00436 void User::InviteTo(const irc::string &channel, time_t invtimeout)
00437 {
00438 time_t now = time(NULL);
00439 if (invtimeout != 0 && now > invtimeout) return;
00440 for (InvitedList::iterator i = invites.begin(); i != invites.end(); ++i)
00441 {
00442 if (channel == i->first)
00443 {
00444 if (i->second != 0 && invtimeout > i->second)
00445 {
00446 i->second = invtimeout;
00447 }
00448
00449 return;
00450 }
00451 }
00452 invites.push_back(std::make_pair(channel, invtimeout));
00453 }
00454
00455 void User::RemoveInvite(const irc::string &channel)
00456 {
00457 for (InvitedList::iterator i = invites.begin(); i != invites.end(); i++)
00458 {
00459 if (channel == i->first)
00460 {
00461 invites.erase(i);
00462 return;
00463 }
00464 }
00465 }
00466
00467 bool User::HasModePermission(unsigned char mode, ModeType type)
00468 {
00469 if (!IS_LOCAL(this))
00470 return true;
00471
00472 if (!IS_OPER(this))
00473 return false;
00474
00475 if (!AllowedUserModes || !AllowedChanModes)
00476 return false;
00477
00478 return ((type == MODETYPE_USER ? AllowedUserModes : AllowedChanModes))[(mode - 'A')];
00479
00480 }
00481
00482 bool User::HasPermission(const std::string &command)
00483 {
00484
00485
00486
00487
00488
00489
00490
00491 if (!IS_LOCAL(this))
00492 return true;
00493
00494
00495 if (!IS_OPER(this))
00496 {
00497 return false;
00498 }
00499
00500 if (!AllowedOperCommands)
00501 return false;
00502
00503 if (AllowedOperCommands->find(command) != AllowedOperCommands->end())
00504 return true;
00505 else if (AllowedOperCommands->find("*") != AllowedOperCommands->end())
00506 return true;
00507
00508 return false;
00509 }
00510
00511 bool User::AddBuffer(const std::string &a)
00512 {
00513 std::string::size_type start = 0;
00514 std::string::size_type i = a.find('\r');
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530 if (i == std::string::npos)
00531 {
00532
00533 recvq.append(a);
00534 }
00535 else
00536 {
00537
00538 while (i != std::string::npos)
00539 {
00540
00541 recvq.append(a, start, (i - start));
00542
00543
00544 start = i + 1;
00545 i = a.find('\r', start);
00546 }
00547
00548 if (start != a.length())
00549 {
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561 recvq.append(a, start, (a.length() - start));
00562 }
00563 }
00564
00565 if (this->MyClass && (recvq.length() > this->MyClass->GetRecvqMax()))
00566 {
00567 ServerInstance->Users->QuitUser(this, "RecvQ exceeded");
00568 ServerInstance->SNO->WriteToSnoMask('A', "User %s RecvQ of %lu exceeds connect class maximum of %lu",this->nick.c_str(),(unsigned long int)recvq.length(),this->MyClass->GetRecvqMax());
00569 return false;
00570 }
00571
00572 return true;
00573 }
00574
00575 bool User::BufferIsReady()
00576 {
00577 return (recvq.find('\n') != std::string::npos);
00578 }
00579
00580 void User::ClearBuffer()
00581 {
00582 recvq.clear();
00583 }
00584
00585 std::string User::GetBuffer()
00586 {
00587 try
00588 {
00589 if (recvq.empty())
00590 return "";
00591
00592
00593
00594
00595
00596 std::string::iterator t = recvq.begin();
00597 while (t != recvq.end() && (*t == '\r' || *t == '\n'))
00598 {
00599 recvq.erase(t);
00600 t = recvq.begin();
00601 }
00602
00603 for (std::string::iterator x = recvq.begin(); x != recvq.end(); x++)
00604 {
00605
00606
00607
00608 if (*x == '\n')
00609 {
00610 std::string ret = std::string(recvq.begin(), x);
00611 recvq.erase(recvq.begin(), x + 1);
00612 return ret;
00613 }
00614 }
00615 return "";
00616 }
00617
00618 catch (...)
00619 {
00620 ServerInstance->Logs->Log("USERS", DEBUG,"Exception in User::GetBuffer()");
00621 return "";
00622 }
00623 }
00624
00625 void User::AddWriteBuf(const std::string &data)
00626 {
00627 if (this->quitting)
00628 return;
00629
00630 if (this->MyClass && (sendq.length() + data.length() > this->MyClass->GetSendqMax()))
00631 {
00632
00633
00634
00635
00636
00637 ServerInstance->Users->QuitUser(this, "SendQ exceeded");
00638 ServerInstance->SNO->WriteToSnoMask('A', "User %s SendQ of %lu exceeds connect class maximum of %lu",this->nick.c_str(),(unsigned long int)sendq.length() + data.length(),this->MyClass->GetSendqMax());
00639 return;
00640 }
00641
00642 if (data.length() > MAXBUF - 2)
00643 sendq.append(data.substr(0,MAXBUF - 4)).append("\r\n");
00644 else
00645 sendq.append(data);
00646 }
00647
00648
00649 void User::FlushWriteBuf()
00650 {
00651 if (this->fd == FD_MAGIC_NUMBER)
00652 {
00653 sendq.clear();
00654 return;
00655 }
00656
00657 if ((sendq.length()) && (this->fd != FD_MAGIC_NUMBER))
00658 {
00659 int old_sendq_length = sendq.length();
00660 int n_sent = ServerInstance->SE->Send(this, this->sendq.data(), this->sendq.length(), 0);
00661
00662 if (n_sent == -1)
00663 {
00664 if (errno == EAGAIN)
00665 {
00666
00667
00668
00669 ServerInstance->SE->WantWrite(this);
00670 }
00671 else
00672 {
00673
00674 ServerInstance->Users->QuitUser(this, errno ? strerror(errno) : "Write error");
00675 return;
00676 }
00677 }
00678 else
00679 {
00680
00681 if (n_sent)
00682 this->sendq = this->sendq.substr(n_sent);
00683
00684 this->bytes_out += n_sent;
00685 this->cmds_out++;
00686 if (n_sent != old_sendq_length)
00687 this->ServerInstance->SE->WantWrite(this);
00688 }
00689 }
00690
00691
00692 if (this->sendq.empty())
00693 {
00694 FOREACH_MOD(I_OnBufferFlushed,OnBufferFlushed(this));
00695 }
00696 }
00697
00698 void User::Oper(const std::string &opertype, const std::string &opername)
00699 {
00700 char* mycmd;
00701 char* savept;
00702 char* savept2;
00703
00704 if (this->IsModeSet('o'))
00705 this->UnOper();
00706
00707 this->modes[UM_OPERATOR] = 1;
00708 this->WriteServ("MODE %s :+o", this->nick.c_str());
00709 FOREACH_MOD(I_OnOper, OnOper(this, opertype));
00710
00711 ServerInstance->SNO->WriteToSnoMask('o',"%s (%s@%s) is now an IRC operator of type %s (using oper '%s')", this->nick.c_str(), this->ident.c_str(), this->host.c_str(), irc::Spacify(opertype.c_str()), opername.c_str());
00712 this->WriteNumeric(381, "%s :You are now %s %s", this->nick.c_str(), strchr("aeiouAEIOU", *opertype.c_str()) ? "an" : "a", irc::Spacify(opertype.c_str()));
00713
00714 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());
00715 this->oper.assign(opertype, 0, 512);
00716 ServerInstance->Users->all_opers.push_back(this);
00717
00718 opertype_t::iterator iter_opertype = ServerInstance->Config->opertypes.find(this->oper.c_str());
00719 if (iter_opertype != ServerInstance->Config->opertypes.end())
00720 {
00721
00722 if (AllowedOperCommands)
00723 AllowedOperCommands->clear();
00724 else
00725 AllowedOperCommands = new std::map<std::string, bool>;
00726
00727 if (!AllowedChanModes)
00728 AllowedChanModes = new bool[64];
00729
00730 if (!AllowedUserModes)
00731 AllowedUserModes = new bool[64];
00732
00733 memset(AllowedUserModes, 0, 64);
00734 memset(AllowedChanModes, 0, 64);
00735
00736 char* Classes = strdup(iter_opertype->second);
00737 char* myclass = strtok_r(Classes," ",&savept);
00738 while (myclass)
00739 {
00740 operclass_t::iterator iter_operclass = ServerInstance->Config->operclass.find(myclass);
00741 if (iter_operclass != ServerInstance->Config->operclass.end())
00742 {
00743 char* CommandList = strdup(iter_operclass->second.commandlist);
00744 mycmd = strtok_r(CommandList," ",&savept2);
00745 while (mycmd)
00746 {
00747 this->AllowedOperCommands->insert(std::make_pair(mycmd, true));
00748 mycmd = strtok_r(NULL," ",&savept2);
00749 }
00750 free(CommandList);
00751 this->AllowedUserModes['o' - 'A'] = true;
00752 for (unsigned char* c = (unsigned char*)iter_operclass->second.umodelist; *c; ++c)
00753 {
00754 if (*c == '*')
00755 {
00756 memset(this->AllowedUserModes, (int)(true), 64);
00757 }
00758 else
00759 {
00760 this->AllowedUserModes[*c - 'A'] = true;
00761 }
00762 }
00763 for (unsigned char* c = (unsigned char*)iter_operclass->second.cmodelist; *c; ++c)
00764 {
00765 if (*c == '*')
00766 {
00767 memset(this->AllowedChanModes, (int)(true), 64);
00768 }
00769 else
00770 {
00771 this->AllowedChanModes[*c - 'A'] = true;
00772 }
00773 }
00774 }
00775 myclass = strtok_r(NULL," ",&savept);
00776 }
00777 free(Classes);
00778 }
00779
00780 FOREACH_MOD(I_OnPostOper,OnPostOper(this, opertype, opername));
00781 }
00782
00783 void User::UnOper()
00784 {
00785 if (IS_OPER(this))
00786 {
00787
00788
00789
00790
00791
00792 this->oper.clear();
00793
00794
00795 std::string moderemove("-");
00796
00797 for (unsigned char letter = 'A'; letter <= 'z'; letter++)
00798 {
00799 ModeHandler* mh = ServerInstance->Modes->FindMode(letter, MODETYPE_USER);
00800 if (mh && mh->NeedsOper())
00801 moderemove += letter;
00802 }
00803
00804 std::vector<std::string> parameters;
00805 parameters.push_back(this->nick);
00806 parameters.push_back(moderemove);
00807
00808 ServerInstance->Parser->CallHandler("MODE", parameters, this);
00809
00810
00811 ServerInstance->Users->all_opers.remove(this);
00812
00813 if (AllowedOperCommands)
00814 {
00815 delete AllowedOperCommands;
00816 AllowedOperCommands = NULL;
00817 }
00818 if (AllowedUserModes)
00819 {
00820 delete[] AllowedUserModes;
00821 AllowedUserModes = NULL;
00822 }
00823 if (AllowedChanModes)
00824 {
00825 delete[] AllowedChanModes;
00826 AllowedChanModes = NULL;
00827 }
00828
00829 }
00830 }
00831
00832
00833 void User::AddToWhoWas()
00834 {
00835 Command* whowas_command = ServerInstance->Parser->GetHandler("WHOWAS");
00836 if (whowas_command)
00837 {
00838 std::deque<classbase*> params;
00839 params.push_back(this);
00840 whowas_command->HandleInternal(WHOWAS_ADD, params);
00841 }
00842 }
00843
00844
00845
00846
00847 void User::CheckClass()
00848 {
00849 ConnectClass* a = this->MyClass;
00850
00851 if ((!a) || (a->GetType() == CC_DENY))
00852 {
00853 ServerInstance->Users->QuitUser(this, "Unauthorised connection");
00854 return;
00855 }
00856 else if ((a->GetMaxLocal()) && (ServerInstance->Users->LocalCloneCount(this) > a->GetMaxLocal()))
00857 {
00858 ServerInstance->Users->QuitUser(this, "No more connections allowed from your host via this connect class (local)");
00859 ServerInstance->SNO->WriteToSnoMask('A', "WARNING: maximum LOCAL connections (%ld) exceeded for IP %s", a->GetMaxLocal(), this->GetIPString());
00860 return;
00861 }
00862 else if ((a->GetMaxGlobal()) && (ServerInstance->Users->GlobalCloneCount(this) > a->GetMaxGlobal()))
00863 {
00864 ServerInstance->Users->QuitUser(this, "No more connections allowed from your host via this connect class (global)");
00865 ServerInstance->SNO->WriteToSnoMask('A', "WARNING: maximum GLOBAL connections (%ld) exceeded for IP %s", a->GetMaxGlobal(), this->GetIPString());
00866 return;
00867 }
00868
00869 this->nping = ServerInstance->Time() + a->GetPingTime() + ServerInstance->Config->dns_timeout;
00870 }
00871
00872 bool User::CheckLines()
00873 {
00874 const char* check[] = { "G" , "K", NULL };
00875
00876 if (!this->exempt)
00877 {
00878 for (int n = 0; check[n]; ++n)
00879 {
00880 XLine *r = ServerInstance->XLines->MatchesLine(check[n], this);
00881
00882 if (r)
00883 {
00884 r->Apply(this);
00885 return true;
00886 }
00887 }
00888 }
00889
00890 return false;
00891 }
00892
00893 void User::FullConnect()
00894 {
00895 ServerInstance->stats->statsConnects++;
00896 this->idle_lastmsg = ServerInstance->Time();
00897
00898
00899
00900
00901
00902
00903
00904 this->SetClass();
00905
00906
00907
00908
00909 if (this->MyClass && !this->MyClass->GetPass().empty() && !this->haspassed)
00910 {
00911 ServerInstance->Users->QuitUser(this, "Invalid password");
00912 return;
00913 }
00914
00915 if (this->CheckLines())
00916 return;
00917
00918 this->WriteServ("NOTICE Auth :Welcome to \002%s\002!",ServerInstance->Config->Network);
00919 this->WriteNumeric(RPL_WELCOME, "%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());
00920 this->WriteNumeric(RPL_YOURHOSTIS, "%s :Your host is %s, running version InspIRCd-1.2",this->nick.c_str(),ServerInstance->Config->ServerName);
00921 this->WriteNumeric(RPL_SERVERCREATED, "%s :This server was created %s %s", this->nick.c_str(), __TIME__, __DATE__);
00922 this->WriteNumeric(RPL_SERVERVERSION, "%s %s InspIRCd-1.2 %s %s %s", this->nick.c_str(), ServerInstance->Config->ServerName, ServerInstance->Modes->UserModeList().c_str(), ServerInstance->Modes->ChannelModeList().c_str(), ServerInstance->Modes->ParaModeList().c_str());
00923
00924 ServerInstance->Config->Send005(this);
00925 this->WriteNumeric(RPL_YOURUUID, "%s %s :your unique ID", this->nick.c_str(), this->uuid.c_str());
00926
00927
00928 this->ShowMOTD();
00929
00930
00931 if (ServerInstance->Users->unregistered_count)
00932 ServerInstance->Users->unregistered_count--;
00933
00934
00935 int MOD_RESULT = 0;
00936 std::string command("LUSERS");
00937 std::vector<std::string> parameters;
00938 FOREACH_RESULT(I_OnPreCommand, OnPreCommand(command, parameters, this, true, "LUSERS"));
00939 if (!MOD_RESULT)
00940 ServerInstance->CallCommandHandler(command, parameters, this);
00941
00942
00943
00944
00945
00946 FOREACH_MOD(I_OnUserConnect,OnUserConnect(this));
00947
00948 this->registered = REG_ALL;
00949
00950 ServerInstance->PI->Introduce(this);
00951
00952 FOREACH_MOD(I_OnPostConnect,OnPostConnect(this));
00953
00954 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());
00955 ServerInstance->Logs->Log("BANCACHE", DEBUG, "BanCache: Adding NEGATIVE hit for %s", this->GetIPString());
00956 ServerInstance->BanCache->AddHit(this->GetIPString(), "", "");
00957 }
00958
00963 User* User::UpdateNickHash(const char* New)
00964 {
00965
00966 user_hash::iterator oldnick = ServerInstance->Users->clientlist->find(this->nick);
00967
00968 if (!irc::string(this->nick.c_str()).compare(New))
00969 return oldnick->second;
00970
00971 if (oldnick == ServerInstance->Users->clientlist->end())
00972 return NULL;
00973
00974 User* olduser = oldnick->second;
00975 (*(ServerInstance->Users->clientlist))[New] = olduser;
00976 ServerInstance->Users->clientlist->erase(oldnick);
00977 return olduser;
00978 }
00979
00980 void User::InvalidateCache()
00981 {
00982
00983 cached_fullhost.clear();
00984 cached_hostip.clear();
00985 cached_makehost.clear();
00986 cached_fullrealhost.clear();
00987 }
00988
00989 bool User::ForceNickChange(const char* newnick)
00990 {
00991 int MOD_RESULT = 0;
00992
00993 this->InvalidateCache();
00994
00995 FOREACH_RESULT(I_OnUserPreNick,OnUserPreNick(this, newnick));
00996
00997 if (MOD_RESULT)
00998 {
00999 ServerInstance->stats->statsCollisions++;
01000 return false;
01001 }
01002
01003 std::deque<classbase*> dummy;
01004 Command* nickhandler = ServerInstance->Parser->GetHandler("NICK");
01005 if (nickhandler)
01006 {
01007 std::vector<std::string> parameters;
01008 nickhandler->HandleInternal(1, dummy);
01009