00001
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #include "services.h"
00048 #include "memoserv.h"
00049 #include "queue.h"
00050 #include "macro.h"
00051 #include "nickserv.h"
00052 #include "chanserv.h"
00053 #include "infoserv.h"
00054 #include "email.h"
00055 #include "hash.h"
00056 #include "clone.h"
00057 #include "mass.h"
00058 #include "db.h"
00059 #include "log.h"
00060 #include "hash/md5pw.h"
00061 #define REALLEN 50
00062
00063 struct akill;
00064
00066 typedef struct ghost_struct GhostList;
00067
00068 GhostList *getGhost(char *);
00069 char *urlEncode(const char *);
00070 const char *GetAuthChKey(const char*, const char*pass, time_t,
00071 u_int32_t code_arg);
00072 const char *PrintPass(u_char pI[], char enc);
00073 struct akill* getAkill(char *nick, char *user, char *host);
00074 char* applyAkill(char* nick, char* user, char* host, struct akill* ak);
00075 char* getAkReason(struct akill *ak);
00076 struct akill* getAhurt(char *nick, char *user, char *host);
00077 long getAkillId(struct akill* ak);
00078 void enforce_nickname (char* nick);
00079 int isPasswordAcceptable(const char* password, char* reason);
00080
00081
00082
00084 OperList *firstOper;
00085
00087 static unsigned long top_cnick = 0;
00088
00090 static RegId top_user_idnum(0, 1);
00091
00094 RegId top_regnick_idnum(0, 1001);
00095
00096
00098 struct ghost_struct {
00100 char ghost[NICKLEN];
00101
00103 struct ghost_struct *next;
00104
00106 struct ghost_struct *previous;
00107 };
00108
00110 int totalghosts = 0;
00111
00112
00114 struct opflag_table {
00116 char symbol;
00117
00119 flag_t flag;
00120
00122 char *name;
00123 };
00124
00126 #define OPFLAG(x, y, z) { x, y, z }
00127
00129 struct opflag_table opflags[] =
00130 {
00131
00132 OPFLAG('A', OADMIN, "ADMIN"),
00133 OPFLAG('O', OSERVOP, "SERVOP"),
00134 OPFLAG('o', OOPER, "o"),
00135 OPFLAG('k', ORAKILL, "AKILL"),
00136 OPFLAG('K', OAKILL, "XAKILL"),
00137 OPFLAG('p', OINFOPOST, "INFO-POST"),
00138 OPFLAG('s', OSETOP, "SETOP"),
00139 OPFLAG('S', OSETFLAG, "SETFLAG"),
00140 OPFLAG('N', ONBANDEL, "NBANDEL"),
00141 OPFLAG('C', OCBANDEL, "CBANDEL"),
00142 OPFLAG('I', OIGNORE, "IGNORE"),
00143 OPFLAG('G', OGRP, "GRp"),
00144 OPFLAG('r', ORAW, "RAW"),
00145 OPFLAG('j', OJUPE, "JUPE"),
00146 OPFLAG('L', OLIST, "LIST"),
00147 OPFLAG('!', OPROT, "FLAG-LOCK"),
00148 OPFLAG('c', OCLONE, "CLONE"),
00149 OPFLAG('a', OACC, "OVERRIDE"),
00150 OPFLAG('h', OHELPOP, "HELPOP"),
00151 OPFLAG('H', OAHURT, "AHURT"),
00152 OPFLAG('D', ODMOD, "DIRECTMOD"),
00153 OPFLAG('*', OPFLAG_ADMIN | OPFLAG_DEFAULT | OPFLAG_ROOTSET, "*"),
00154 { (char)0, (int)0, (char *)0 }
00155 };
00156
00157 #undef OPFLAG
00158
00160 enum ns_set_en {
00161 NSS_FLAG,
00162 NSS_PROC
00163 };
00164
00165 struct nss_tab {
00166 const char *keyword;
00167 const char *description;
00168 enum ns_set_en set_type;
00169 flag_t flag;
00170 flag_t opFlagsRequired;
00171
00173 cmd_return (*proc)(nss_tab *, UserList *nick, char *a[], int);
00174 };
00175
00176
00178 char *cnick_prefixes[] =
00179 {
00180 "Visitor-",
00181 "Nobody-",
00182 "Unnamed-",
00183 "Nickless-",
00184 "Nonick-",
00185 "Untitled-"
00186 };
00187
00189 #define NUM_CNICKS (sizeof(cnick_prefixes)/sizeof(char *))
00190
00191 GhostList *firstGhost = NULL;
00192 GhostList *lastGhost = NULL;
00193
00195 interp::service_cmd_t nickserv_commands[] =
00196 {
00197
00198 { "help", ns_help, 0, LOG_NO, CMD_AHURT },
00199 { "identify", ns_identify, 0, LOG_NO, CMD_AHURT },
00200 { "identify-plain", ns_identify, 0, LOG_NO, CMD_AHURT },
00201 { "id-md5", ns_cidentify, 0, LOG_NO, CMD_AHURT },
00202 { "id", ns_identify, 0, LOG_NO, CMD_AHURT },
00203 { "sidentify", ns_identify, 0, LOG_NO, CMD_AHURT },
00204 { "identify-*", ns_cidentify, 0, LOG_NO, CMD_AHURT | CMD_MATCH },
00205 { "register", ns_register, 0, LOG_NO, 0 },
00206 { "info", ns_info, 0, LOG_NO, 0 },
00207 { "ghost", ns_ghost, 0, LOG_NO, 0 },
00208 { "recover", ns_recover, 0, LOG_NO, 0 },
00209 { "release", ns_release, 0, LOG_NO, 0 },
00210 { "set", ns_set, 0, LOG_NO, CMD_REG },
00211 { "vacation", ns_vacation, 0, LOG_NO, 0 },
00212 { "drop", ns_drop, 0, LOG_NO, CMD_REG },
00213 { "addmask", ns_addmask, 0, LOG_NO, CMD_REG },
00214 { "access", ns_access, 0, LOG_NO, 0 },
00215 { "acc", ns_acc, 0, LOG_NO, 0 },
00216 { "logoff", ns_logoff, 0, LOG_NO, 0 },
00217 { "logout", ns_logoff, 0, LOG_NO, 0 },
00218 { "setflag", ns_setflags, OOPER, LOG_NO, 0 },
00219 { "setop", ns_setopflags, OOPER, LOG_NO, 0 },
00220 { "mark", ns_mark, OOPER, LOG_NO, 0 },
00221 { "siteok", ns_bypass, OOPER, LOG_NO, CMD_REG },
00222 { "bypass", ns_bypass, OOPER, LOG_NO, CMD_REG },
00223 { "banish", ns_banish, OOPER, LOG_NO, CMD_REG },
00224 { "getpass", ns_getpass, 0, LOG_NO, CMD_REG },
00225 { "sendpass", ns_getpass, 0, LOG_NO, CMD_REG },
00226 { "setpass", ns_setpass, 0, LOG_DB, 0 },
00227 { "setemail", ns_setemail, 0, LOG_NO, CMD_REG },
00228 { "realgetpass", ns_getrealpass, OOPER, LOG_NO, CMD_REG },
00229 { "delete", ns_delete, OOPER, LOG_DB, CMD_REG },
00230 { "list", ns_list, OOPER, LOG_NO, CMD_REG },
00231 { "save", ns_save, OOPER, LOG_NO, CMD_REG },
00232 { "savememo", ms_save, OOPER, LOG_NO, CMD_REG },
00233 { NULL }
00234 };
00235
00236
00237
00238
00239
00252 void nDesynch(char *nick, char *type)
00253 {
00254 dlogEntry("Desynced user: \"%s\" (%p) removed", nick, nick);
00255
00256 if (nick) {
00257
00258
00259
00260 sSend(":%s GLOBOPS "
00261 " :User %s DESYNCHED during command [%s]", NickServ, nick,
00262 type);
00263 if (!getNickData(nick))
00264 sSend(":%s KILL %s :%s (Desynch, type: [%s])", myname, nick,
00265 myname, type);
00266 }
00267 return;
00268 }
00269
00270
00271
00272
00273
00274
00275
00276
00277 void annoyNickThief(UserList *);
00278 void complainAboutEmail(UserList *);
00279 void killide(char *);
00280 void removeEnforcer(char *);
00281
00283 static void freeUserListRec(UserList *zap)
00284 {
00285 SetDynBuffer(&zap->host, NULL);
00286 #ifdef TRACK_GECOS
00287 SetDynBuffer(&zap->gecos, NULL);
00288 #endif
00289 FREE(zap);
00290 }
00291
00293 static void freeRegNickListRec(RegNickList *zap)
00294 {
00295 if (zap->url != NULL)
00296 FREE(zap->url);
00297 SetDynBuffer(&zap->host, NULL);
00298 #ifdef TRACK_GECOS
00299 SetDynBuffer(&zap->gecos, NULL);
00300 #endif
00301
00302 SetDynBuffer(&zap->markby, NULL);
00303 FREE(zap);
00304 }
00305
00329 void NickSeeUser(UserList *newnick, RegNickList *reg, int caccess,
00330 int verbose)
00331 {
00332
00333
00334
00335
00336 strncpyzt(reg->user, newnick->user, USERLEN);
00337 SetDynBuffer(®->host, newnick->host);
00338
00339 #ifdef TRACK_GECOS
00340 SetDynBuffer(®->gecos, newnick->gecos);
00341 #endif
00342
00343 reg->timestamp = CTime;
00344 reg->flags &= ~NVACATION;
00345
00346 if (verbose)
00347 {
00348 checkMemos(newnick);
00349 complainAboutEmail(newnick);
00350 newsNag(newnick);
00351 }
00352 }
00353
00375 static void SetUserNickHostReal(UserList *newnick, char *nick, char *user,
00376 char *host, char *gecos)
00377 {
00378 char HostTmp[HOSTLEN+1];
00379 #ifdef TRACK_GECOS
00380 char RealTmp[REALLEN+1];
00381 #endif
00382
00383 strncpyzt(newnick->nick, nick, NICKLEN);
00384 strncpyzt(newnick->user, user, USERLEN);
00385
00386 strncpyzt(HostTmp, host, HOSTLEN);
00387 SetDynBuffer(&newnick->host, HostTmp);
00388 #ifdef TRACK_GECOS
00389 strncpyzt(RealTmp, gecos, sizeof(RealTmp));
00390 SetDynBuffer(&newnick->gecos, RealTmp);
00391 #endif
00392
00393 }
00394
00400 char NickGetEnc(RegNickList *rnl)
00401 {
00402 if (rnl)
00403 return ((rnl->flags & NENCRYPT) ? '$' : '@');
00404 return '@';
00405 }
00406
00417 void addNewUser(char **args, int numargs)
00418 {
00419 UserList *newnick = NULL;
00420 struct akill* ak;
00421 char *reason = NULL;
00422 char realtmp[REALLEN+1];
00423 struct akill* ahitem;
00424
00425 if (numargs < 7) {
00426 sSend
00427 (":%s GLOBOP :Error adding nick from uplink server! (args == %d)",
00428 OperServ, numargs);
00429 return;
00430 }
00431
00432 if (getNickData(args[1])) {
00433 sSend
00434 (":%s GLOBOPS :Desync in adding new user \"%s\" (%p) (%s@%s) -- user exists??",
00435 NickServ, args[1], newnick, args[4], args[5]);
00436 logDump(corelog,
00437 "Desync in adding new user \"%s\" (%p) (%s@%s) -- user exists??",
00438 args[1], newnick, args[4], args[5]);
00439 }
00440
00441
00442 if (args[1] && isGhost(args[1])) {
00443 sSend(":%s KILL %s :%s!%s (Nickname currently blocked for NickServ enforcer).", services[1].name, args[1], services[1].host, services[1].name);
00444
00445 addGhost(args[1]);
00446 return;
00447 }
00448
00449 newnick = (UserList *) oalloc(sizeof(UserList));
00450 dlogEntry("Adding new user: \"%s\" (%p) (%s@%s)", args[1], newnick,
00451 args[4], args[5]);
00452 if (args[4][0] == '~')
00453 args[4]++;
00454 args[7]++;
00455
00456 parse_str(args, numargs, 7, realtmp, sizeof(realtmp));
00457 SetUserNickHostReal(newnick, args[1], args[4], args[5], realtmp);
00458
00459 newnick->reg = getRegNickData(args[1]);
00460 newnick->timestamp = (time_t) atol(args[3]);
00461 if ((ak = getAkill(newnick->nick, newnick->user, newnick->host)) &&
00462 (reason = getAkReason(ak))) {
00463
00464 sSend(":%s KILL %s :%s!%s (AKilled: %s)", services[1].name,
00465 newnick->nick, services[1].host, services[1].name, reason);
00466 applyAkill(newnick->nick, newnick->user, newnick->host, ak);
00467 freeUserListRec(newnick);
00468
00469 addGhost(args[1]);
00470 timer(30, delTimedGhost, strdup(args[1]));
00471 return;
00472 }
00473
00474 newnick->idnum.SetNext(top_user_idnum);
00475
00476 if (((CTime - 240) <= (newnick->timestamp)) && (ahitem = getAhurt(newnick->nick, newnick->user, newnick->host))) {
00477 #ifdef IRCD_HURTSET
00478 sSend(":%s HURTSET %s 2 :[#%.6x] Subject to a selective user ban.",
00479 OperServ, newnick->nick, getAkillId(ahitem));
00480 #endif
00481 newnick->oflags |= NISAHURT;
00482 }
00483 if (newnick->reg) {
00484 newnick->reg->flags &= ~(NDOEDIT);
00485
00486 if (newnick->reg->flags & NBANISH) {
00487 sSend(":%s KILL %s :%s!%s (Banished nickname)",
00488 services[1].name, newnick->nick, services[1].host,
00489 services[1].name);
00490 freeUserListRec(newnick);
00491
00492 addGhost(args[1]);
00493 timer(15, delTimedGhost, strdup(args[1]));
00494 return;
00495 }
00496
00497
00498
00499
00500 if ((newnick->reg->flags & NDBISMASK)) {
00501 newnick->oflags |= NOISMASK;
00502 sSend(":%s MODE %s :+m", NickServ, newnick->nick);
00503 }
00504
00505 if (!checkAccess(newnick->user, newnick->host, newnick->reg)) {
00506 newnick->caccess = 1;
00507 annoyNickThief(newnick);
00508 } else {
00509 newnick->caccess = 2;
00510 newnick->reg->timestamp = (time_t) atol(args[3]);
00511
00512 NickSeeUser(newnick, newnick->reg, 2, 1);
00513 }
00514 } else {
00515
00516 do {
00517 newnick->oflags |= NOISMASK;
00518 sSend(":%s MODE %s :+m", NickServ, newnick->nick);
00519 } while (0);
00520
00521 #ifdef WELCOME_NOTE
00522 PutReply(InfoServ, newnick, RPL_IS_GREET_1ARG, WELCOME_NOTE, 0, 0);
00523 #endif
00524 #ifdef DISCLAIMER
00525 PutReply(InfoServ, newnick, RPL_IS_GREET_1ARG, DISCLAIMER, 0, 0);
00526 #endif
00527 #ifdef COPYRIGHT
00528 PutReply(InfoServ, newnick, RPL_IS_COPYRIGHT_1ARG, VERSION_NUM, 0, 0);
00529 #endif
00530 }
00531
00532 if (addClone(newnick->nick, newnick->user, newnick->host))
00533 freeUserListRec(newnick);
00534 else {
00535 addNick(newnick);
00536 }
00537
00538 if (mostusers < totalusers)
00539 mostusers = totalusers;
00540 }
00541
00562 void changeNick(char *from, char *to, char *ts)
00563 {
00564 UserList *changeme, *tmp;
00565 char tmp1[NICKLEN + 2];
00566
00567 changeme = getNickData(from);
00568 if (changeme == NULL) {
00569 nDesynch(from, "NICK");
00570 return;
00571 }
00572
00573 if (changeme->oflags & NCNICK) {
00574 addGhost(changeme->nick);
00575 timer(120, delTimedGhost, strdup(changeme->nick));
00576 changeme->oflags &= ~(NCNICK);
00577 }
00578
00579
00580 tmp = (UserList *) oalloc(sizeof(UserList));
00581 tmp->idnum.SetNext(top_user_idnum);
00582 dlogEntry("Changing nick -> \"%s\" (%p) to \"%s\" (%p)", from, from,
00583 to, tmp);
00584 strcpy(tmp->nick, to);
00585 #ifdef TRACK_GECOS
00586 SetUserNickHostReal(tmp, to, changeme->user, changeme->host, changeme->gecos);
00587 #else
00588 SetUserNickHostReal(tmp, to, changeme->user, changeme->host, NULL);
00589 #endif
00590
00591 tmp->oflags = changeme->oflags;
00592 tmp->floodlevel = changeme->floodlevel;
00593
00594 changeNickOnAllChans(changeme, tmp);
00595 if (ts && *ts) {
00596 if (*ts == ':')
00597 ts++;
00598 tmp->timestamp = (time_t) atol(ts);
00599 } else
00600 tmp->timestamp = CTime;
00601
00602 if (changeme->id.nick) {
00603 RegNickList *tmptarget = getRegNickData(changeme->id.nick);
00604 tmp->id.nick = changeme->id.nick;
00605 tmp->id.idnum = changeme->id.idnum;
00606
00607 if (tmptarget && (tmptarget->timereg < changeme->id.timestamp))
00608 tmp->id.timestamp = tmp->timestamp;
00609 else
00610 clearIdentify(tmp);
00611 changeme->id.nick = NULL;
00612 }
00613
00614
00615 if (changeme->reg && isIdentified(changeme, changeme->reg))
00616 changeme->reg->timestamp = CTime;
00617
00618 addNick(tmp);
00619 delNick(changeme);
00620 if (isAKilled(tmp->nick, tmp->user, tmp->host)) {
00621 sSend(":%s KILL %s :%s!%s (AKilled user)", services[1].name,
00622 tmp->nick, services[1].host, services[1].name);
00623 remUser(to, 1);
00624 addGhost(to);
00625 return;
00626 }
00627
00628
00629 if (isGhost(tmp->nick)) {
00630 sSend(":%s KILL %s :%s!%s (Nickname currently blocked for NickServ enforcer).", services[1].name, tmp->nick, services[1].host, services[1].name);
00631
00632 addGhost(tmp->nick);
00633 remUser(to, 1);
00634 return;
00635 }
00636
00637 tmp->reg = getRegNickData(to);
00638
00639 if (tmp->reg != NULL) {
00640 if (tmp->reg->flags & NBANISH) {
00641 sSend
00642 (":%s 433 %s :Banished nickname - You have 10 seconds to change your nick.",
00643 myname, tmp->nick);
00644 sprintf(tmp1, "%s@@%i", to, 0);
00645 timer(10, killide, strdup(tmp1));
00646 }
00647
00648 if (tmp->id.timestamp && tmp->id.nick
00649 && tmp->id.timestamp > tmp->reg->timereg
00650 && tmp->id.idnum == tmp->reg->regnum
00651 && !strcasecmp(tmp->id.nick, tmp->nick)) {
00652 sSend(":%s NOTICE %s :You have already identified for access.",
00653 NickServ, tmp->nick);
00654 clearIdentify(tmp);
00655 tmp->caccess = 3;
00656 NickSeeUser(tmp, tmp->reg, 3, 1);
00657
00658 if (ts[0] == ':')
00659 ts++;
00660 tmp->reg->timestamp = (time_t) atol(ts);
00661 return;
00662 }
00663
00664 else if (!strcasecmp(tmp->nick, changeme->nick))
00665 tmp->caccess = changeme->caccess;
00666 else if (!checkAccess(tmp->user, tmp->host, tmp->reg)) {
00667 tmp->caccess = 0;
00668 annoyNickThief(tmp);
00669 } else {
00670 tmp->caccess = 2;
00671
00672 NickSeeUser(tmp, tmp->reg, 2, 1);
00673 if (ts[0] == ':')
00674 ts++;
00675 tmp->reg->timestamp = (time_t) atol(ts);
00676 }
00677 }
00678 }
00679
00695 void setMode(char *nick, char *mode)
00696 {
00697 UserList *changeme;
00698 RegNickList *regn;
00699 int i, c = 0;
00700
00701 changeme = getNickData(nick);
00702
00703 dlogEntry("Changing umodes for \"%s\" (%p) to \"%s\" (%p)", changeme,
00704 changeme, mode, mode);
00705
00706 if (changeme == NULL) {
00707 nDesynch(nick, "UMODE");
00708 return;
00709 }
00710
00711 mode++;
00712
00713 for (i = 0; mode[i] != 0; i++) {
00714 switch (tolower(mode[i])) {
00715 case '-':
00716 c = 0;
00717 break;
00718 case '+':
00719 c = 1;
00720 break;
00721 case 'h':
00722 if (c == 1)
00723 changeme->oflags |= NISHELPOP;
00724 else
00725 changeme->oflags &= ~NISHELPOP;
00726 break;
00727 case 'm':
00728 if (c == 1) {
00729 changeme->oflags |= NOISMASK;
00730 if ((regn = getRegNickData(changeme->nick))
00731 && isRecognized(changeme, regn))
00732 regn->flags |= NDBISMASK;
00733 } else {
00734 changeme->oflags &= ~NOISMASK;
00735 if ((regn = getRegNickData(changeme->nick))
00736 && isIdentified(changeme, regn))
00737 regn->flags &= ~NDBISMASK;
00738 }
00739 break;
00740 case 'o':
00741 if (c == 1) {
00742 changeme->oflags |= NISOPER;
00743 changeme->oflags &= ~NISAHURT;
00744 } else
00745 changeme->oflags &= ~NISOPER;
00746 break;
00747 }
00748 }
00749
00750 mode--;
00751 return;
00752 }
00753
00754
00770 void setFlags(char *nick, int flag, char change)
00771 {
00772 UserList *bah;
00773 bah = getNickData(nick);
00774 if (bah == NULL) {
00775 nDesynch(nick, "SETFLAG(internal source)");
00776 return;
00777 }
00778
00779 dlogEntry("Setting flags for \"%s\" (%p) - %i", nick, bah, flag);
00780
00781 if (change == '+')
00782 bah->oflags |= flag;
00783 else
00784 bah->oflags &= ~flag;
00785
00786 }
00787
00798 void setIdentify(UserList * user, RegNickList * nick)
00799 {
00800 if (!user || !nick || !nick->nick)
00801 return;
00802 if (user->id.nick)
00803 FREE(user->id.nick);
00804 user->id.nick = (char *)oalloc(strlen(nick->nick) + 2);
00805 strcpy(user->id.nick, nick->nick);
00806
00807 user->id.timestamp = MAX(user->timestamp, CTime);
00808 user->id.idnum = nick->regnum;
00809 return;
00810 }
00811
00818 void clearIdentify(UserList * user)
00819 {
00820 if (!user)
00821 return;
00822 if (user->id.nick)
00823 FREE(user->id.nick);
00824 user->id.nick = NULL;
00825 user->id.timestamp = 0;
00826 user->id.idnum = RegId(0,0);
00827 return;
00828 }
00829
00841 int isIdentified(UserList * user, RegNickList * nick)
00842 {
00843 if (!(user && nick) || (nick->flags & NVACATION)
00844 || (nick->flags & NFORCEXFER))
00845 return 0;
00846 if (user->reg != nick && user->id.nick && user->id.timestamp) {
00847 if (user->timestamp <= user->id.timestamp &&
00848 nick->timereg < user->id.timestamp &&
00849 nick->regnum == user->id.idnum &&
00850 !strcmp(user->id.nick, nick->nick)) return 1;
00851 return 0;
00852 }
00853 return (user->reg == nick && user->reg && (user->caccess > 2));
00854 }
00855
00856
00869 int isRecognized(UserList * user, RegNickList * nick)
00870 {
00871 if (!(user && nick) || (nick->flags & NVACATION))
00872 return 0;
00873 if (checkAccess(user->user, user->host, nick))
00874 return 1;
00875 if (!(user && nick) || user->reg != nick)
00876 return isIdentified(user, nick);
00877 return (user->reg && user->reg == nick && (user->caccess > 1));
00878 }
00879
00886 int isOper(UserList * nick)
00887 {
00888 if (nick == NULL)
00889 return 0;
00890 else {
00891 if (nick->oflags & NISOPER)
00892 return 1;
00893 else
00894 return 0;
00895 }
00896 }
00897
00911 int opFlagged(UserList * nick, flag_t flag)
00912 {
00913 int need_oper = (flag & OOPER);
00914 int need_user_override = (flag & OACC);
00915 extern int userOverriding(UserList *);
00916
00917 if (nick == NULL)
00918 return 0;
00919 flag &= ~(OOPER);
00920 if (need_user_override && !userOverriding(nick))
00921 return FALSE;
00922 if (nick->reg == NULL || (flag && !isIdentified(nick, nick->reg)))
00923 return 0;
00924 if ((nick->reg->opflags & OROOT))
00925 if (!flag || ((flag & OPFLAG_ROOT) == flag))
00926 return (!need_oper || isOper(nick));
00927 if (!flag || ((nick->reg->opflags & flag) == flag))
00928 return (!need_oper || isOper(nick));
00929 return 0;
00930 }
00931
00945 flag_t getOpFlags(UserList * nick)
00946 {
00947 flag_t flags = 0;
00948 extern int userOverriding(UserList *);
00949
00950 if (nick == NULL)
00951 return 0;
00952 if (isOper(nick))
00953 flags |= OOPER;
00954 if (nick->reg == NULL || (!isIdentified(nick, nick->reg)))
00955 return flags;
00956 if (userOverriding(nick))
00957 flags |= OACC;
00958 if ((nick->reg->opflags & OROOT))
00959 return (flags | (OPFLAG_PLUS));
00960 return (flags | nick->reg->opflags);
00961 }
00962
00963
00965 int issRoot(UserList* nick) {
00966 int ofl;
00967
00968 if (!nick || !isRoot(nick)) {
00969 return 0;
00970 }
00971
00972 ofl = getOpFlags(nick);
00973 return ((ofl & 0x2)) ? 1 : 0;
00974 }
00975
00982 int isRoot(UserList * nick)
00983 {
00984 if (nick == NULL)
00985 return 0;
00986 if (nick->reg == NULL)
00987 return 0;
00988
00989 if (nick->reg->opflags & OROOT && isIdentified(nick, nick->reg))
00990 return isOper(nick);
00991 else
00992 return 0;
00993 }
00994
01002 int isServop(UserList * nick)
01003 {
01004 if (nick == NULL)
01005 return 0;
01006 if (nick->reg == NULL)
01007 return 0;
01008
01009 if ((nick->reg->opflags & OSERVOP || nick->reg->opflags & OROOT)
01010 && isIdentified(nick, nick->reg))
01011 return isOper(nick);
01012 else
01013 return 0;
01014 }
01015
01016 #ifdef ENABLE_GRPOPS
01017
01024 int isGRPop(UserList * nick)
01025 {
01026 if (nick == NULL)
01027 return 0;
01028 if (nick->reg == NULL)
01029 return 0;
01030
01031 if ((nick->reg->opflags & OGRP) && isIdentified(nick, nick->reg))
01032 return isOper(nick);
01033 else
01034 return 0;
01035 }
01036 #endif
01037
01046 int isHelpop(UserList * nick)
01047 {
01048 if (nick == NULL)
01049 return 0;
01050 if (nick->reg == NULL)
01051 return 0;
01052
01053 if ((nick->oflags & NISHELPOP) && isIdentified(nick, nick->reg))
01054 return 1;
01055 else
01056 return 0;
01057 }
01058
01066 int canAkill(UserList * nick)
01067 {
01068 if (nick == NULL)
01069 return 0;
01070 if (nick->reg == NULL)
01071 return 0;
01072
01073 if (nick->reg->opflags & OAKILL && isIdentified(nick, nick->reg))
01074 return isOper(nick);
01075 else
01076 return 0;
01077 }
01078
01079
01094 void remUser(char *nick, int ignoreDesync)
01095 {
01096 UserList *killme;
01097
01098 killme = getNickData(nick);
01099
01100 if (killme == NULL) {
01101 if (!ignoreDesync)
01102 nDesynch(nick, "QUIT");
01103 return;
01104 }
01105
01106 dlogEntry("Removing user \"%s\" (%p)", nick, killme);
01107 remFromAllChans(killme);
01108 delClone(killme->user, killme->host);
01109
01110 if (killme->reg && isIdentified(killme, killme->reg)) {
01111 cleanMemos(killme);
01112 killme->reg->timestamp = CTime;
01113 }
01114
01115 delNick(killme);
01116 }
01117
01118
01128 void addNick(UserList * newnick)
01129 {
01130 HashKeyVal hashEnt;
01131
01132 dlogEntry("Adding nick \"%s\" (%p)", newnick->nick, newnick);
01133
01134 hashEnt = getHashKey(newnick->nick) % NICKHASHSIZE;
01135 dlogEntry("Added nick \"%s\" with hash entry %i",
01136 newnick->nick, hashEnt);
01137 LIST_ENTRY_INIT(newnick, ul_lst);
01138 LIST_INSERT_HEAD(&UserHash[hashEnt], newnick, ul_lst);
01139 totalusers++;
01140 }
01141
01153 void addRegNick(RegNickList * newnick)
01154 {
01155 RegNickList *tmp;
01156 RegNickIdMap *mapPtr, *mapPtrIter, *mapPtrIterNext;
01157 HashKeyVal hashEnt;
01158
01159
01160
01161
01162 if ((tmp = getRegNickData(newnick->nick))) {
01163 logDump(corelog, "addRegNick(%p) : %s already exists",
01164 newnick, newnick->nick);
01165 assert(tmp == NULL);
01166
01167 abort();
01168 freeRegNickListRec(newnick);
01169 return;
01170 }
01171
01172
01173
01174
01175 hashEnt = getHashKey(newnick->nick) % NICKHASHSIZE;
01176 LIST_ENTRY_INIT(newnick, rn_lst);
01177 LIST_INSERT_HEAD(&RegNickHash[hashEnt], newnick, rn_lst);
01178
01179
01180 mapPtr = (RegNickIdMap *)oalloc(sizeof(RegNickIdMap));
01181 mapPtr->nick = newnick;
01182 mapPtr->id = newnick->regnum;
01183
01184 hashEnt = newnick->regnum.getHashKey() % IDHASHSIZE;
01185 LIST_ENTRY_INIT(mapPtr, id_lst);
01186 if (!LIST_FIRST(&RegNickIdHash[hashEnt]))
01187 LIST_INSERT_HEAD(&RegNickIdHash[hashEnt], mapPtr, id_lst);
01188 else {
01189 for(mapPtrIter = LIST_FIRST(&RegNickIdHash[hashEnt]);
01190 mapPtrIter;
01191 mapPtrIter = mapPtrIterNext)
01192 {
01193 mapPtrIterNext = LIST_NEXT(mapPtrIter, id_lst);
01194
01195 if ((mapPtr->id) > (mapPtrIter->id)) {
01196 if (mapPtrIterNext)
01197 continue;
01198 LIST_INSERT_AFTER(mapPtrIter, mapPtr, id_lst);
01199 break;
01200 }
01201 else {
01202 LIST_INSERT_BEFORE(mapPtrIter, mapPtr, id_lst);
01203 break;
01204 }
01205 }
01206
01207 }
01208 }
01209
01210
01221 void delNick(UserList * killme)
01222 {
01223 LIST_REMOVE(killme, ul_lst);
01224 clearIdentify(killme);
01225
01226 freeUserListRec(killme);
01227 flush_ad(killme);
01228 totalusers--;
01229 }
01230
01242 void delRegNick(RegNickList * killme)
01243 {
01244 MemoList *memos;
01245 MemoList *memos_next;
01246 RegNickList *to;
01247 RegNickIdMap *mapPtr;
01248
01249 LIST_REMOVE(killme, rn_lst);
01250
01251 mapPtr = killme->regnum.getIdMap();
01252 if (mapPtr)
01253 {
01254 LIST_REMOVE(mapPtr, id_lst);
01255
01256 FREE(mapPtr);
01257 }
01258
01259 delOpData(killme);
01260 if (killme->memos)
01261 {
01262 memos = LIST_FIRST(&killme->memos->mb_sent);
01263 while (memos != NULL) {
01264 memos_next = LIST_NEXT(memos, ml_sent);
01265 to = memos->realto;
01266 if (to == NULL)
01267 return;
01268 LIST_REMOVE(memos, ml_sent);
01269 delMemo(to->memos, memos);
01270 memos = memos_next;
01271 }
01272 }
01273 freeRegNickListRec(killme);
01274 }
01275
01287 UserList *getNickData(char *nick)
01288 {
01289 HashKeyVal hashEnt;
01290 UserList *tmpnick;
01291
01292 hashEnt = getHashKey(nick) % NICKHASHSIZE;
01293 for (tmpnick = LIST_FIRST(&UserHash[hashEnt]); tmpnick != NULL;
01294 tmpnick = LIST_NEXT(tmpnick, ul_lst)) {
01295 if (!strcasecmp(tmpnick->nick, nick))
01296 return tmpnick;
01297 }
01298
01299 return NULL;
01300 }
01301
01311 RegNickList *getRegNickData(const char *nick)
01312 {
01313 HashKeyVal hashEnt;
01314 RegNickList *tmpnick;
01315 int l;
01316
01317 if (nick == NULL || (l = strlen(nick)) > NICKLEN || l == 0)
01318 return NULL;
01319
01320 hashEnt = getHashKey(nick) % NICKHASHSIZE;
01321 for (tmpnick = LIST_FIRST(&RegNickHash[hashEnt]); tmpnick != NULL;
01322 tmpnick = LIST_NEXT(tmpnick, rn_lst))
01323 if (strcasecmp(tmpnick->nick, nick) == 0)
01324 return tmpnick;
01325
01326 return NULL;
01327 }
01328
01342 int checkAccess(char *user, char *host, RegNickList * nick)
01343 {
01344 nAccessList *tmp;
01345 char theirmask[HOSTLEN + USERLEN + 3];
01346
01347 if (nick == NULL || user == NULL || host == NULL)
01348 return 0;
01349
01350 sprintf(theirmask, "%.*s@%.*s", USERLEN, user, HOSTLEN, host);
01351
01352
01353 for (tmp = LIST_FIRST(&nick->acl); tmp; tmp = LIST_NEXT(tmp, al_lst))
01354 if (!match(tmp->mask, theirmask))
01355 return 1;
01356 return 0;
01357 }
01358
01375 void sendToNickServ(UserList * tmp, char **args, int numargs)
01376 {
01377 char *from = tmp->nick;
01378 interp::parser * cmd;
01379
01380 tmp = getNickData(from);
01381 if (tmp == NULL) {
01382 nDesynch(from, "PRIVMSG");
01383 return;
01384 }
01385
01386 cmd = new interp::parser(NickServ, getOpFlags(tmp),
01387 nickserv_commands, args[0]);
01388 if (!cmd)
01389 return;
01390
01391 switch (cmd->run(tmp, args, numargs)) {
01392 default:
01393 break;
01394 case RET_FAIL:
01395 sSend(":%s NOTICE %s :Unknown command %s.\r\n"
01396 ":%s NOTICE %s :Please try /msg %s HELP",
01397 NickServ, from, args[0], NickServ, from, NickServ);
01398 break;
01399 case RET_OK_DB:
01400 sSend(":%s NOTICE %s :Next database synch(save) in %ld minutes.",
01401 NickServ, tmp->nick, ((nextNsync - CTime) / 60));
01402 break;
01403 }
01404
01405 delete cmd;
01406 }
01407
01408
01409
01410
01411
01412
01421 char *regnick_ugethost(UserList * user, RegNickList * target, int sM)
01422 {
01423 UserList *online;
01424 static char rep[NICKLEN + USERLEN + HOSTLEN + 275];
01425
01426 if (!user || !target || (strlen(target->host) > (sizeof(rep) - 200)))
01427 return "<ERROR>";
01428
01429 if ((online = getNickData(target->nick))) {
01430 if (isRecognized(online, target)) {
01431 if (!(online->oflags & NOISMASK))
01432 return strcpy(rep, target->host);
01433 else if (!(user->oflags & NISOPER)) {
01434 strncpyzt(rep, genHostMask(target->host), sizeof(rep));
01435 return rep;
01436 } else if ((user->oflags & NISOPER)) {
01437 strncpyzt(rep, target->host, sizeof(rep) - 11);
01438 if (sM)
01439 sprintf(rep + strlen(rep), " (\2masked\2)");
01440 return rep;
01441 }
01442 }
01443 }
01444
01445 if (!(target->flags & NDBISMASK))
01446 return strcpy(rep, target->host);
01447 if (!(user->oflags & NISOPER)) {
01448 strncpyzt(rep, genHostMask(target->host), sizeof(rep));
01449 return rep;
01450 } else {
01451 strcpy(rep, target->host);
01452 if (sM)
01453 sprintf(rep + strlen(rep), " (\2masked\2)");
01454 return rep;
01455 }
01456 return ("<ERROR>@<ERROR>");
01457 }
01458
01471 void addAccessMask(char *mask, UserList * nick)
01472 {
01473 if (!isIdentified(nick, nick->reg)) {
01474 sSend(":%s NOTICE %s :You must identify to use ACCESS ADD",
01475 NickServ, nick->nick);
01476 return;
01477 }
01478
01479 if (USERLEN + HOSTLEN + 3 < strlen(mask)) {
01480 sSend(":%s GLOBOPS :%s tried to add a HUGE access mask", NickServ,
01481 nick->nick);
01482 sSend(":%s NOTICE %s :That access mask is WAY too long", NickServ,
01483 nick->nick);
01484 return;
01485 }
01486
01487 if (nick->reg->amasks >= AccessLimit) {
01488 sSend
01489 (":%s NOTICE %s :You have reached the limit of access masks, you cannot add any more",
01490 NickServ, nick->nick);
01491 sSend(":%s GLOBOPS :%s attempts to add too many access items.",
01492 NickServ, nick->nick);
01493 return;
01494 }
01495
01496 if (addAccItem(nick->reg, mask) == 0)
01497 sSend
01498 (":%s NOTICE %s :%s was \002not\002 added to your access list, it is an improper mask or already present.",
01499 NickServ, nick->nick, mask);
01500 else {
01501 sSend(":%s NOTICE %s :%s is added to your access list",
01502 NickServ, nick->nick, mask);
01503 }
01504 }
01505
01518 void delAccessMask(char *mask, UserList * nick)
01519 {
01520 nAccessList *acl;
01521 char deleted[71];
01522
01523 if (!isIdentified(nick, nick->reg)) {
01524 sSend(":%s NOTICE %s :You must identify to use ACCESS DEL",
01525 NickServ, nick->nick);
01526 return;
01527 }
01528
01529 if (LIST_FIRST(&nick->reg->acl) == NULL)
01530 return;
01531
01532 if (*mask == '-') {
01533 for (acl = LIST_FIRST(&nick->reg->acl); acl != NULL;
01534 acl = LIST_NEXT(acl, al_lst))
01535 delAccItem(nick->reg, acl->mask, deleted);
01536
01537 sSend(":%s NOTICE %s :Your access list has been cleared",
01538 NickServ, nick->nick);
01539 nick->reg->amasks = 0;
01540
01541 return;
01542 }
01543
01544 if (delAccItem(nick->reg, mask, deleted)) {
01545 sSend(":%s NOTICE %s :The mask %s has been deleted"
01546 " from your access list", NickServ, nick->nick, deleted);
01547 nick->reg->amasks--;
01548 } else if (strchr(mask, '@') == NULL)
01549 sSend(":%s NOTICE %s :Access list entry #%s was not found",
01550 NickServ, nick->nick, mask);
01551 else
01552 sSend(":%s NOTICE %s :%s was not in your access list",
01553 NickServ, nick->nick, mask);
01554 }
01555
01563 void complainAboutEmail(UserList * nick)
01564 {
01565 if (!nick->reg || (nick->reg->email[0] &&
01566 (strncasecmp(nick->reg->email, "(none)", 6))
01567 || index(nick->reg->email, ' ')))
01568 return;
01569
01570 sSend(":%s NOTICE %s :***** NOTICE *****", NickServ, nick->nick);
01571 sSend(":%s NOTICE %s :You have not specified an e-mail address.",
01572 NickServ, nick->nick);
01573 sSend
01574 (":%s NOTICE %s :Should you forget or lose your NickServ password, the operators will most likely be unable to assist you,",
01575 NickServ, nick->nick);
01576 sSend(":%s NOTICE %s :unless you specify one.", NickServ, nick->nick);
01577 sSend
01578 (":%s NOTICE %s :To set an e-mail address and eliminate this message:",
01579 NickServ, nick->nick);
01580 sSend
01581 (":%s NOTICE %s : type \2/msg nickserv set address YOUREMAIL\2 ",
01582 NickServ, nick->nick);
01583 sSend
01584 (":%s NOTICE %s :Once set, NickServ will NOT divulge your address to other users unless you explicitly tell it to.",
01585 NickServ, nick->nick);
01586 sSend(":%s NOTICE %s :", NickServ, nick->nick);
01587 sSend
01588 (":%s NOTICE %s :To keep no e-mail address but eliminate this message:",
01589 NickServ, nick->nick);
01590 sSend(":%s NOTICE %s : type \2/msg nickserv set address NONE",
01591 NickServ, nick->nick);
01592 sSend(":%s NOTICE %s :", NickServ, nick->nick);
01593 sSend
01594 (":%s NOTICE %s :Type \2/join #help\2 if you have any questions regarding this.",
01595 NickServ, nick->nick);
01596 sSend(":%s NOTICE %s :***** NOTICE *****", NickServ, nick->nick);
01597 sSend
01598 (":%s PRIVMSG %s :You have not yet set an e-mail address or indicated your desire to send none: please see the notice from services (it may be in a status window).",
01599 NickServ, nick->nick);
01600 }
01601
01612 void annoyNickThief(UserList * nick)
01613 {
01614 char buffer[NICKLEN+HOSTLEN+41];
01615
01616 if (nick->reg->flags & NKILL) {
01617 sSend(":%s NOTICE %s :This nick belongs to another user."
01618 " Please change nicks or it will be forcefully changed"
01619 " in %i seconds.", NickServ, nick->nick, nick->reg->idtime);
01620 sSend(":%s NOTICE %s :If this is your nick please try:"
01621 " /msg %s ID password", NickServ, nick->nick, NickServ);
01622
01623
01624 if (nick->reg->idtime > NICKWARNINT) {
01625 if ((nick->reg->idtime - NICKWARNINT) < NICKWARNINT)
01626 sSend(":%s 433 %s %s :Belongs to another user",
01627 myname, nick->nick, nick->nick);
01628 sprintf(buffer, "%s@%s@%i", nick->nick, nick->host,
01629 nick->reg->idtime);
01630 timer(NICKWARNINT, killide, strdup(buffer));
01631 } else {
01632 sSend(":%s 433 %s %s :Belongs to another user",
01633 myname, nick->nick, nick->nick);
01634 sprintf(buffer, "%s@%s@%i", nick->nick, nick->host, 0);
01635 timer(nick->reg->idtime, killide, strdup(buffer));
01636 }
01637 return;
01638 }
01639
01640 sSend(":%s NOTICE %s :This nick belongs to another user."
01641 " Please change nicks", NickServ, nick->nick);
01642 sSend(":%s NOTICE %s :If this is your nick please try:"
01643 " /msg %s ID password", NickServ, nick->nick, NickServ);
01644 return;
01645 }
01646
01647
01648 void guest_cnick(UserList* ul)
01649 {
01650 #ifndef CNICK_UNSUPPORTED
01651 unsigned int j = 0;
01652 extern int dice(int, int);
01653 char forcenick[NICKLEN];
01654 const char* nick;
01655
01657 # define CNICK_FMT ":%s CNICK %s %s %ld"
01658
01659 if (!ul)
01660 return;
01661 nick = ul->nick;
01662
01663 do {
01664 snprintf(forcenick, NICKLEN, "%s%lX%X",
01665 cnick_prefixes[(top_cnick + j) % NUM_CNICKS],
01666 (++top_cnick) / NUM_CNICKS, dice(3, 200) + 1);
01667 } while ((j++ < NUM_CNICKS && getNickData(forcenick))
01668 || (getNickData(forcenick) && ++top_cnick));
01669
01670 sSend(":%s NOTICE %s :Your nickname is now being "
01671 "changed to \2%s\2.", NickServ, nick, forcenick);
01672 sSend(CNICK_FMT, myname, nick, forcenick, CTime);
01673 if (ul)
01674 ul->oflags |= NCNICK;
01675 #endif
01676 }
01677
01678 void enforce_nickname (char* nick)
01679 {
01680 UserList* ul = nick ? getNickData(nick) : 0;
01681
01682 if (ul == 0) {
01683 return;
01684 }
01685
01686 #ifndef CNICK_UNSUPPORTED
01687 guest_cnick(ul);
01688 #else
01689 sSend(":%s KILL %s :%s!%s (Nick protection enforced)",
01690 NickServ, nick, services[1].host, services[1].name);
01691 remUser(nick, 1);
01692 addGhost(nick);
01693 timer(120, delTimedGhost, strdup(nick));
01694 #endif
01695 }
01696
01717 void killide(char *info)
01718 {
01719 char tmp[NICKLEN + HOSTLEN + 10];
01720 UserList *check;
01721 RegNickList *regnick;
01722 char *nick;
01723 char *host;
01724 char *time;
01725
01726 nick = strtok(info, "@");
01727 host = strtok(NULL, "@");
01728 time = strtok(NULL, "\0");
01729
01730 unsigned int left = 0;
01731
01732 if (nick == NULL) {
01733 return;
01734 }
01735
01736
01737
01738
01739
01740 check = getNickData(nick);
01741 regnick = getRegNickData(nick);
01742
01743 if (check == NULL) {
01744 FREE(info);
01745 return;
01746 } else if (isIdentified(check, regnick)) {
01747 FREE(info);
01748 return;
01749 } else if (host != NULL) {
01750 if (strcmp(check->host, host)) {
01751 FREE(info);
01752 return;
01753 }
01754 } else if (time == NULL) {
01755 FREE(info);
01756 return;
01757 }
01758
01759 left = atoi(time);
01760
01761 if (left == 0) {
01762 if (getNickData(nick)) {
01763 enforce_nickname( nick );
01764 }
01765 } else {
01766 if (getNickData(nick)) {
01767 if (left >= NICKWARNINT) {
01768 left -= NICKWARNINT;
01769 } else {
01770
01771
01772 left = NICKWARNINT;
01773 logDump(corelog, "Time left sanity check failed in "
01774 "killide(). Resetting to %i.", NICKWARNINT);
01775 }
01776
01777 if (left >= NICKWARNINT) {
01778 sSend(":%s NOTICE %s :You have %i seconds to "
01779 "change your nick, or %s will be forced "
01780 "to change it for you.", NickServ, nick,
01781 left, NickServ);
01782 if ((left - NICKWARNINT) < NICKWARNINT)
01783 sSend(":%s 433 %s %s :Belongs to "
01784 "another user", myname, nick, nick);
01785 sprintf(tmp, "%s@%s@%i", nick, host, left);
01786 timer(NICKWARNINT, killide, strdup(tmp));
01787 } else {
01788 sprintf(tmp, "%s@%s@%i", nick, host, 0);
01789 timer(left, killide, strdup(tmp));
01790 }
01791 }
01792 FREE(info);
01793 }
01794 }
01795
01810 void addGhost(char *ghost)
01811 {
01812 GhostList *newghost = (GhostList *)0;
01813 char host[HOSTLEN];
01814
01815
01816 if (ghost) {
01817 for(newghost = firstGhost; newghost; newghost = newghost->next)
01818 {
01819 if (!strcasecmp(ghost, newghost->ghost)) {
01820 break;
01821 }
01822 }
01823 }
01824
01825 if (!newghost) {
01826 newghost = (GhostList *) oalloc(sizeof(GhostList));
01827
01828 strncpyzt(newghost->ghost, ghost, NICKLEN);
01829
01830 if (firstGhost == NULL) {
01831 firstGhost = newghost;
01832 newghost->previous = NULL;
01833 } else {
01834 lastGhost->next = newghost;
01835 newghost->previous = lastGhost;
01836 }
01837
01838 lastGhost = newghost;
01839 newghost->next = NULL;
01840
01841 totalusers++;
01842 totalghosts++;
01843 }
01844
01845 snprintf(host, sizeof(host), "nicks.%s", NETWORK);
01846 addUser(ghost, "owned", host, "Nick Enforcement", "i");
01847 }
01848
01858 void delGhost(char *ghost)
01859 {
01860 GhostList *killme;
01861
01862
01863 sSend(":%s QUIT :Ahhh, they finally let me off work!", ghost);
01864
01865 killme = getGhost(ghost);
01866
01867 if (killme == NULL)
01868 return;
01869
01870 if (killme->previous)
01871 killme->previous->next = killme->next;
01872 else
01873 firstGhost = killme->next;
01874 if (killme->next)
01875 killme->next->previous = killme->previous;
01876 else
01877 lastGhost = killme->previous;
01878
01879 FREE(killme);
01880 totalghosts--;
01881 totalusers--;
01882
01883 return;
01884 }
01885
01896 void delTimedGhost(char *ghost)
01897 {
01898 delGhost(ghost);
01899 FREE(ghost);
01900 }
01901
01906 GhostList *getGhost(char *ghost)
01907 {
01908 GhostList *tmp;
01909
01910 for (tmp = firstGhost; tmp; tmp = tmp->next) {
01911 if (strcasecmp(tmp->ghost, ghost) == 0)
01912 return tmp;
01913 }
01914 return NULL;
01915 }
01916
01924 int isGhost(char *ghost)
01925 {
01926 if (getGhost(ghost))
01927 return 1;
01928 else
01929 return 0;
01930 }
01931
01932
01933
01934 RateInfo::RateInfo() :
01935 lastEventTime(0), rateFloodValue(0), numOfEvents(0),
01936 warningsSent(0)
01937 {
01938
01939 }
01940
01941 void RateInfo::Event(int weightOfEvent, time_t tNow)
01942 {
01943
01944
01945 if ((tNow - lastEventTime) >= FLOOD_DET_HALF_PERIOD)
01946 rateFloodValue >>= 1;
01947
01948
01949
01950
01951 if ((tNow - lastEventTime) <= FLOOD_DET_Z_PERIOD)
01952 rateFloodValue += weightOfEvent;
01953 else
01954 rateFloodValue = weightOfEvent;
01955
01956 lastEventTime = tNow;
01957 if (numOfEvents < INT_MAX)
01958 numOfEvents++;
01959 }
01960
01961 void RateInfo::Warn() {
01962 if (warningsSent < UCHAR_MAX)
01963 warningsSent++;
01964 }
01965
01966 int RateInfo::Warned() {
01967 return (int) warningsSent;
01968 }
01969
01970 int RateInfo::GetLev() {
01971 return rateFloodValue;
01972 }
01973
01975 int BadPwNick(UserList *sender, RegNickList *target)
01976 {
01977 if (sender == NULL || target == NULL)
01978 return 0;
01979
01980 if (sender->badpws < UCHAR_MAX)
01981 sender->badpws++;
01982
01983 if (target->badpws < UCHAR_MAX)
01984 target->badpws++;
01985
01986 if ((sender->badpws > NPW_TH_SENDER_1 && target->badpws > NPW_TH_TARGET_1) ||
01987 (sender->badpws > NPW_TH_SENDER_2 && target->badpws > NPW_TH_TARGET_2) ||
01988 (sender->badpws > NPW_TH_SENDER_3 && target->badpws > NPW_TH_TARGET_3))
01989 {
01990 sSend(":%s GLOBOPS :Possible password guess attempt %s!%s@%s (%u) -> %s (%u)",
01991 NickServ, sender->nick, sender->user, sender->host, (u_int)sender->badpws,
01992 target->nick, (u_int)target->badpws
01993 );
01994
01995 if (addFlood(sender, FLOODVAL_BADPW))
01996 return 1;
01997 }
01998
01999 return 0;
02000 }
02001
02003 int GoodPwNick(UserList *sender, RegNickList *target)
02004 {
02005 char timeJunk[80];
02006
02007 if (sender == NULL || target == NULL)
02008 return 0;
02009
02010 if (target->badpws > 0)
02011 {
02012 sSend(":%s NOTICE %s :%d failed password attempt(s) for %s since last access",
02013 NickServ, sender->nick, target->badpws, target->nick);
02014 if (strftime(timeJunk, 80, "%a %Y-%b-%d %T %Z", localtime(&target->timestamp)) > 0) {
02015 sSend(":%s NOTICE %s :%s seen %s from %s@%s.",
02016 NickServ, sender->nick, target->nick, timeJunk, target->user, regnick_ugethost(sender, target));
02017 }
02018
02019 target->badpws = 0;
02020 }
02021
02022 return 0;
02023 }
02024
02051 int addFlood(UserList * tmp, int addtoflood)
02052 {
02053 int fIsIgnored = 0;
02054 long timenow = time(NULL);
02055
02056 if (tmp == NULL)
02057 return 0;
02058
02059 if (isRoot(tmp) == 1) {
02060 return 0;
02061 }
02062
02063 if (tmp->nick && tmp->user && tmp->host)
02064 fIsIgnored = isIgnored(tmp->nick, tmp->user, tmp->host);
02065
02066 tmp->floodlevel.Event(addtoflood, timenow);
02067
02068 if (tmp->floodlevel.Warned() && tmp->floodlevel.GetLev() >= MAXFLOODLEVEL) {
02069 char user[USERLEN], host[HOSTLEN],
02070 theirmask[USERLEN + HOSTLEN + 3];
02071 char tmpstr[NICKLEN + USERLEN + HOSTLEN + 4];
02072 sSend
02073 (":%s KILL %s :%s!%s (Flooding services is not permitted [You are now on services ignore])",
02074 OperServ, tmp->nick, services[0].host, OperServ);
02075 if (!fIsIgnored)
02076 sSend
02077 (":%s GLOBOPS :\002Severe Flooding\002: %s!%s@%s [User killed] (Flood: %i/%i)",
02078 myname, tmp->nick, tmp->user, tmp->host, tmp->floodlevel.GetLev(),
02079 MAXFLOODLEVEL);
02080
02081 strncpyzt(user, tmp->user, USERLEN);
02082 strncpyzt(host, tmp->host, HOSTLEN);
02083
02084 mask(user, host, 0, theirmask);
02085 sprintf(tmpstr, "*!%.*s", USERLEN + HOSTLEN + 4, theirmask);
02086 if (!isIgnored(tmp->nick, tmp->user, tmp->host))
02087 addakill((10 * 3600), tmpstr, OperServ, A_IGNORE,
02088 "Flooding Services");
02089 remUser(tmp->nick, 1);
02090
02091 return 1;
02092 }
02093
02094 else if (tmp->floodlevel.GetLev() >= (.75 * MAXFLOODLEVEL) && !fIsIgnored)
02095 {
02096 sSend(":%s GLOBOPS :\002Flooding\002: %s!%s@%s (Flood: %i/%i)",
02097 myname, tmp->nick, tmp->user, tmp->host, tmp->floodlevel.GetLev(),
02098 MAXFLOODLEVEL);
02099 sSend(":%s NOTICE %s :Flooding is not good for your health or mine, "
02100 "stop now before you are removed from the network and placed "
02101 "on services ignore (Floodlevel %i/%i)", NickServ, tmp->nick,
02102 tmp->floodlevel.GetLev(), MAXFLOODLEVEL);
02103 tmp->floodlevel.Warn();
02104
02105 return 1;
02106 }
02107 return 0;
02108 }
02109
02119
02120 void expireNicks(char *dummy)
02121 {
02122 time_t timestart, timeend;
02123 RegNickList *tmp;
02124 RegNickList *next;
02125 char backup[30];
02126 char cmd[500];
02127 int i = 0, bucket = 0;
02128
02129 mostnicks = 0;
02130 timestart = time(NULL);
02131
02132
02133
02134
02135 strftime(backup, 30, "nickserv.db%d%m%Y", localtime(×tart));
02136 sprintf(cmd, "cp nickserv/nickserv.db nickserv/backups/%s", backup);
02137 system(cmd);
02138
02139
02140
02141
02142 strftime(backup, 30, "memoserv.db%d%m%Y", localtime(×tart));
02143 sprintf(cmd, "cp memoserv/memoserv.db memoserv/backups/%s", backup);
02144 system(cmd);
02145
02146
02147
02148
02149
02150
02151 for (bucket = 0; bucket < NICKHASHSIZE; bucket++) {
02152 tmp = LIST_FIRST(&RegNickHash[bucket]);
02153
02154 while (tmp != NULL) {
02155 next = LIST_NEXT(tmp, rn_lst);
02156
02157 if (getNickData(tmp->nick) != NULL)
02158 tmp->timestamp = CTime;
02159
02160 if (!isIdentified(getNickData(tmp->nick), tmp)) {
02161
02162 if ((tmp->flags & (NHOLD | NBANISH)) != 0) {
02163 ;
02164 } else if (tmp->flags & NVACATION) {
02165 if ((timestart - tmp->timestamp)
02166 >= (3 * NICKDROPTIME)) {
02167 nicklog->log(NULL, NSE_EXPIRE, tmp->nick, 0,
02168 "%ld %ld %ld vacation", timestart,
02169 tmp->timestamp,
02170 timestart - tmp->timestamp);
02171 delRegNick(tmp);
02172 i++;
02173 }
02174 } else if ((timestart - tmp->timestamp) >= NICKDROPTIME) {
02175 nicklog->log(NULL, NSE_EXPIRE, tmp->nick, 0,
02176 "%ld %ld %ld", timestart, tmp->timestamp,
02177 timestart - tmp->timestamp);
02178 delRegNick(tmp);
02179 i++;
02180 }
02181 }
02182
02183 tmp = next;
02184 mostnicks++;
02185 }
02186 }
02187
02188 timeend = time(NULL);
02189 sSend(":%s GLOBOPS :NickServ EXPIRE(%i/%lu) %lu seconds",
02190 NickServ, i, mostnicks, (timeend - timestart));
02191
02192 timer(2 * 3600, (void (*)(char *))expireNicks, NULL);
02193 }
02194
02205 int addAccItem(RegNickList * nick, char *mask)
02206 {
02207 nAccessList *acl;
02208
02209 if (!nick)
02210 return 0;
02211
02212 if (!strcmp(mask, "*@*") || !strcmp(mask, "*@*.*") ||
02213 !match(mask, "..@...com") ||
02214 !match(mask, "..@...edu") ||
02215 !match(mask, "..@...org") ||
02216 !match(mask, "..@...net") ||
02217 !match(mask, "..@...info") ||
02218 !match(mask, "..@...co.uk") ||
02219 !match(mask, "..@...br") ||
02220 index(mask, '!') || !index(mask, '@'))
02221 return 0;
02222
02223 for (acl = LIST_FIRST(&nick->acl); acl != NULL;
02224 acl = LIST_NEXT(acl, al_lst)) if (!strcasecmp(mask, acl->mask))
02225 return 0;
02226
02227 acl = (nAccessList *) oalloc(sizeof(nAccessList));
02228 strncpyzt(acl->mask, mask, 70);
02229
02230 LIST_INSERT_HEAD(&(nick->acl), acl, al_lst);
02231
02232 nick->amasks++;
02233
02234 return 1;
02235 }
02236
02253 int delAccItem(RegNickList * nick, char *mask, char *deletedmask)
02254 {
02255 nAccessList *acl;
02256 int found = 0;
02257 int x = 0;
02258 int idx;
02259
02260 if (nick == NULL)
02261 return 0;
02262
02263 x = atoi(mask);
02264 idx = 1;
02265
02266 for (acl = LIST_FIRST(&nick->acl); acl != NULL;
02267 acl = LIST_NEXT(acl, al_lst)) {
02268 if (!strcasecmp(mask, acl->mask) || (idx++ == x)) {
02269 found = 1;
02270 break;
02271 }
02272 }
02273
02274 if (found == 0)
02275 return 0;
02276
02277 strncpyzt(deletedmask, acl->mask, 70);
02278
02279 LIST_REMOVE(acl, al_lst);
02280
02281 FREE(acl);
02282
02283 return 1;
02284 }
02285
02290 void syncNickData(time_t next)
02291 {
02292 nextNsync = next;
02293 saveNickData();
02294 }
02295
02300 void syncMemoData(time_t next)
02301 {
02302 nextMsync = next;
02303 saveMemoData();
02304 }
02305
02306
02310 NCMD(ms_save)
02311 {
02312 char *from = nick->nick;
02313
02314 if (isRoot(nick) == 0) {
02315 PutReply(MemoServ, nick, ERR_NOACCESS, 0, 0, 0);
02316 return RET_FAIL;
02317 }
02318
02319 #ifdef GLOBOP_ON_SAVE
02320 sSend(":%s GLOBOPS :Saving database. (%s)", MemoServ, from);
02321 #else
02322 sSend(":%s PRIVMSG " LOGCHAN " :Saving database. (%s)", MemoServ,
02323 from);
02324 #endif
02325 saveMemoData();
02326 return RET_OK_DB;
02327 }
02328
02333 void addOpData(RegNickList * nick)
02334 {
02335 OperList *oper;
02336
02337 if (!nick || !nick->opflags)
02338 return;
02339 for (oper = firstOper; oper; oper = oper->next)
02340 if (oper->who == nick)
02341 return;
02342
02343 if (!firstOper || (nick->opflags & OROOT)) {
02344 oper = (OperList *) oalloc(sizeof(OperList));
02345 oper->next = firstOper;
02346 firstOper = oper;
02347 oper->who = nick;
02348 } else {
02349 for (oper = firstOper; oper->next; oper = oper->next);
02350 oper->next = (OperList *) oalloc(sizeof(OperList));
02351 oper->next->who = nick;
02352 oper->next->next = NULL;
02353 }
02354 }
02355
02360 void delOpData(RegNickList * nick)
02361 {
02362 OperList *oper, *nextoper, *tmp;
02363
02364 for (oper = firstOper, tmp = NULL; oper; oper = nextoper) {
02365 nextoper = oper->next;
02366 if (oper->who == nick) {
02367 if (tmp)
02368 tmp->next = nextoper;
02369 else
02370 firstOper = nextoper;
02371 FREE(oper);
02372 continue;
02373 } else
02374 tmp = oper;
02375 }
02376 }
02377
02378
02379
02384 NCMD(ns_help)
02385 {
02386 help(nick->nick, NickServ, args, numargs);
02387 return RET_OK;
02388 }
02389
02396 NCMD(ns_vacation)
02397 {
02398 char *from = nick->nick;
02399 time_t timestart;
02400
02401 timestart = time(NULL);
02402
02403 if (!nick->reg) {
02404 PutError(NickServ, nick, ERR_NEEDREGNICK_1ARG, nick->nick, 0, 0);
02405 return RET_FAIL;
02406 }
02407
02408 if ((timestart - nick->reg->timereg) < NICKDROPTIME) {
02409 sSend
02410 (":%s NOTICE %s :Your nick has not been registered long enough to set vacation mode. The current requirement is %u days",
02411 NickServ, from, (NICKDROPTIME / 3600 / 24));
02412 return RET_FAIL;
02413 }
02414
02415 if (!isIdentified(nick, nick->reg)) {
02416 sSend
02417 (":%s NOTICE %s :You must be identifed with NickServ to use VACATION",
02418 NickServ, from);
02419 return RET_FAIL;
02420 }
02421 nick->reg->flags |= NVACATION;
02422
02423 sSend(":%s NOTICE %s :Your nick is now marked as on vacation.",
02424 NickServ, from);
02425 sSend
02426 (":%s NOTICE %s :Please be aware that this will be automatically removed next time you return to IRC.",
02427 NickServ, from);
02428 sSend
02429 (":%s NOTICE %s :Your nick will automatically expire in %u days if you do not return.",
02430 NickServ, from, (NICKDROPTIME / 3600 / 24 * 2));
02431 return RET_OK_DB;
02432 }
02433
02439 NCMD(ns_identify)
02440 {
02441 RegNickList *tonick = nick->reg;
02442 char *s_nick = NULL, *passwd;
02443 char *from = nick->nick;
02444
02445 if (addFlood(nick, 5))
02446 return RET_KILLED;
02447
02448 if (numargs < 2) {
02449 sSend(":%s NOTICE %s :The IDENTIFY command requires a password",
02450 NickServ, from);
02451 return RET_SYNTAX;
02452 }
02453
02454 if (numargs < 3)
02455 passwd = args[1];
02456 else {
02457 s_nick = args[1];
02458 passwd = args[2];
02459 tonick = getRegNickData(s_nick);
02460 }
02461
02462 if (!tonick) {
02463 PutError(NickServ, nick, ERR_NICKNOTREG_1ARG,
02464 s_nick ? s_nick : nick->nick, 0, 0);
02465 PutHelpInfo(NickServ, nick, "HELP");
02466
02467 return RET_NOTARGET;
02468 }
02469
02470 if ((tonick->flags & NBANISH)) {
02471 PutError(NickServ, nick, ERR_NICKBANISHED_1ARG,
02472 s_nick ? s_nick : nick->nick, 0, 0);
02473
02474 return RET_EFAULT;
02475 }
02476
02477 if (!(tonick->flags & NFORCEXFER)
02478 && Valid_pw(passwd, tonick->password, NickGetEnc(tonick))) {
02479 if (tonick->chpw_key) {
02480 PutReply(NickServ, nick, RPL_CHKEY_DEAD, 0, 0, 0);
02481 tonick->chpw_key = 0;
02482 }
02483
02484 if (nick->reg == tonick)
02485 {
02486 nick->caccess = 3;
02487
02488 assert(!strcasecmp(nick->reg->nick, nick->nick));
02489 strcpy(nick->reg->nick, nick->nick);
02490
02491 PutReply(NickServ, nick, RPL_IDENTIFYOK_NOARG, 0, 0, 0);
02492
02493 if ((tonick && !(tonick->flags & NUSEDPW))) {
02494 tonick->flags |= NUSEDPW;
02495 PutReply(NickServ, nick, RPL_MASKHELP, NickServ, NickServ,
02496 0);
02497 }
02498 } else {
02499 PutReply(NickServ, nick, RPL_IDENTIFYOK_NICKARG, tonick->nick,
02500 0, 0);
02501 clearIdentify(nick);
02502 setIdentify(nick, tonick);
02503 if ((tonick && !(tonick->flags & NUSEDPW))) {
02504 tonick->flags |= NUSEDPW;
02505 PutReply(NickServ, nick, RPL_MASKHELP, NickServ, NickServ,
02506 0);
02507 }
02508 }
02509
02510 #ifdef ENABLE_AHURT
02511
02512
02513
02514 if ((nick->oflags & NISAHURT)) {
02515 if ((tonick && !(tonick->flags & NBYPASS)))
02516 PutError(NickServ, nick, ERR_NOAHURTBYPASS, 0, 0, 0);
02517 else {
02518 PutReply(NickServ, nick, RPL_AHURTBYPASS, 0, 0, 0);
02519 PutReply(NickServ, nick, RPL_BYPASSISLOGGED, 0, 0, 0);
02520 sSend(":%s HEAL %s", NickServ, from);
02521 nick->oflags &= ~(NISAHURT);
02522 nicklog->log(nick, NS_IDENTIFY, tonick->nick, 0, "AHURT");
02523 }
02524 }
02525 #endif
02526
02527
02528
02529
02530
02531 NickSeeUser(nick, tonick, 3, 0);
02532 GoodPwNick(nick, tonick);
02533 tonick->timestamp = CTime;
02534
02535
02536
02537
02538 if (nick->reg == tonick) {
02539 checkMemos(nick);
02540 complainAboutEmail(nick);
02541 newsNag(nick);
02542 }
02543 else if ((nick->oflags & NOISMASK)
02544 && !(tonick->flags & NDBISMASK)) tonick->flags |= NDBISMASK;
02545 return RET_OK;
02546 } else {
02547
02548
02549
02550
02551
02552 if (nick->reg == tonick) {
02553 nick->caccess = 1;
02554 PutError(NickServ, nick, ERR_BADPW, 0, 0, 0);
02555 if (BadPwNick(nick, nick->reg))
02556 return RET_KILLED;
02557 nicklog->logw(nick, NS_IDENTIFY, tonick->nick, LOGF_BADPW);
02558 } else {
02559 PutError(NickServ, nick, ERR_BADPW, 0, 0, 0);
02560 nicklog->logw(nick, NS_IDENTIFY, tonick->nick, LOGF_BADPW);
02561
02562 if (BadPwNick(nick, tonick))
02563 return RET_KILLED;
02564 return RET_BADPW;
02565 }
02566 }
02567 return RET_OK;
02568 }
02569
02570
02571 #ifdef MD5_AUTH
02572
02588 NCMD(ns_cidentify)
02589 {
02590 RegNickList *tonick = nick->reg;
02591 struct auth_data auth_info[1];
02592 char *s_nick = NULL, *passwd;
02593 int valid = 0;
02594
02595 if (addFlood(nick, 5))
02596 return RET_KILLED;
02597
02598
02599
02600
02601 if (!strcasecmp(args[0], "identify-types")) {
02602 PutError(NickServ, nick, RPL_AUTH_TYPES, 0, 0, 0);
02603 return RET_OK;
02604 }
02605
02606
02607
02608
02609 if (!strncasecmp(args[0], "identify-", 9)
02610 && strncasecmp((args[0]) + 9, "md5", 3)) {
02611 PutReply(NickServ, nick, ERR_AUTH_NOTYPE, 0, 0, 0);
02612 return RET_OK;
02613 }
02614
02615
02616
02617
02618 if (numargs >= 2 && !nick->auth_cookie) {
02619 PutError(NickServ, nick, ERR_AUTH_CHAL, 0, 0, 0);
02620 nick->auth_cookie = 0;
02621 return RET_OK;
02622 }
02623
02624
02625
02626
02627 if (nick->auth_cookie && numargs < 2) {
02628 PutError(NickServ, nick, RPL_AUTH_NORESPONSE, 0, 0, 0);
02629 nick->auth_cookie = 0;
02630 }
02631
02638 if (numargs < 2) {
02639
02640
02641
02642 nick->auth_cookie = time(NULL);
02643 if (nick->auth_cookie > 900000000)
02644 nick->auth_cookie -= 900000000;
02645 PutReply(NickServ, nick, RPL_AUTH_SEED,
02646 (unsigned int)nick->auth_cookie,
02647 (unsigned int)nick->idnum.getHashKey(), 0);
02648 return RET_OK;
02649 }
02650
02651
02652
02653
02654
02655
02656 if (numargs < 3)
02657 passwd = args[1];
02658 else {
02659 s_nick = args[1];
02660 passwd = args[2];
02661 tonick = getRegNickData(s_nick);
02662 }
02663
02664
02665
02666
02667
02668 if (!tonick) {
02669 PutError(NickServ, nick, ERR_AUTH_NOTREGISTERED_2ARG, "nickname",
02670 args[1], 0);
02671 PutHelpInfo(NickServ, nick, "HELP IDENTIFY");
02672 return RET_NOTARGET;
02673 }
02674
02675 auth_info->auth_cookie = nick->auth_cookie;
02676 auth_info->auth_user = nick->idnum.getHashKey();
02677 auth_info->format = 1;
02678
02679 valid = Valid_md5key(passwd, auth_info, tonick->nick, tonick->password, NickGetEnc(tonick));
02680
02681 nick->auth_cookie = 0;
02682
02683
02684
02685
02686
02687 if ( valid != 0 ) {
02688 if (tonick->chpw_key) {
02689 PutReply(NickServ, nick, RPL_CHKEY_DEAD, 0, 0, 0);
02690 tonick->chpw_key = 0;
02691 }
02692 if ((tonick && !(tonick->flags & NUSEDPW)))
02693 tonick->flags |= NUSEDPW;
02694
02695
02696
02697
02698 if (nick->reg == tonick) {
02699 nick->caccess = 4;
02700
02701 assert(!strcasecmp(nick->reg->nick, nick->nick));
02702 strcpy(nick->reg->nick, nick->nick);
02703 PutReply(NickServ, nick, RPL_AUTH_OK_0ARG, 0, 0, 0);
02704 GoodPwNick(nick, tonick);
02705 } else {
02706 PutReply(NickServ, nick, RPL_AUTH_OK_1ARG, tonick->nick, 0, 0);
02707 clearIdentify(nick);
02708 setIdentify(nick, tonick);
02709 GoodPwNick(nick, tonick);
02710 }
02711
02712 #ifdef ENABLE_AHURT
02713
02714
02715
02716 if ((nick->oflags & NISAHURT)) {
02717 if ((tonick && !(tonick->flags & NBYPASS)))
02718 PutError(NickServ, nick, ERR_NOAHURTBYPASS, 0, 0, 0);
02719 else {
02720 PutReply(NickServ, nick, RPL_AHURTBYPASS, 0, 0, 0);
02721 PutReply(NickServ, nick, RPL_BYPASSISLOGGED, 0, 0, 0);
02722
02723 sSend(":%s HEAL %s", NickServ, nick->nick);
02724 nick->oflags &= ~(NISAHURT);
02725 nicklog->log(nick, NS_IDENTIFY, tonick->nick, 0, "AHURT");
02726 }
02727 }
02728 #endif
02729
02730
02731
02732
02733 NickSeeUser(nick, tonick, 3, 0);
02734 tonick->timestamp = CTime;
02735
02736
02737
02738
02739 if (nick->reg == tonick) {
02740 checkMemos(nick);
02741 complainAboutEmail(nick);
02742 }
02743 return RET_OK;
02744 } else {
02745
02746
02747
02748 if (nick->reg == tonick) {
02749 PutError(NickServ, nick, ERR_AUTH_BAD_1ARG, tonick->nick, 0,
02750 0);
02751 nicklog->log(nick, NS_IDENTIFY, tonick->nick, LOGF_BADPW,
02752 "MD5");
02753 if (BadPwNick(nick, tonick))
02754 return RET_KILLED;
02755 }
02756 else {
02757 PutError(NickServ, nick, ERR_AUTH_BAD_1ARG, tonick->nick, 0,
02758 0);
02759 nicklog->log(nick, NS_IDENTIFY, tonick->nick, LOGF_BADPW,
02760 "MD5");
02761 if (BadPwNick(nick, tonick))
02762 return RET_KILLED;
02763 return RET_BADPW;
02764 }
02765 }
02766 return RET_OK;
02767 }
02768 #endif
02769
02773 cmd_return ns_set_passwd(nss_tab *setEnt, UserList *nick,
02774 char *args[], int numargs)
02775 {
02776 const char *from = nick->nick;
02777 char pw_reason[IRCBUF];
02778
02779 if (numargs < 2) {
02780 sSend(":%s NOTICE %s :You must specify a parameter", NickServ,
02781 from);
02782 return RET_EFAULT;
02783 }
02784
02785 if (PASSLEN < strlen(args[1])) {
02786 sSend(":%s NOTICE %s :Please specify a password of %d "
02787 "characters or less.", NickServ, from, PASSLEN);
02788 return RET_EFAULT;
02789 }
02790
02791 if (isPasswordAcceptable(args[1], pw_reason) == 0) {
02792 sSend(":%s NOTICE %s :Sorry, %s isn't a password that you can use.",
02793 NickServ, from, args[1]);
02794 sSend(":%s NOTICE %s :%s", NickServ, from, pw_reason);
02795 return RET_EFAULT;
02796 }
02797
02798 pw_enter_password(args[1], nick->reg->password, NickGetEnc(nick->reg));
02799 sSend(":%s NOTICE %s :Your password is now %s, do NOT forget it, we"
02800 " are not responsible for lost passwords", NickServ, from,
02801 args[1]);
02802 return RET_OK_DB;
02803 }
02804
02805
02806
02810 cmd_return ns_set_url(nss_tab *setEnt, UserList *nick,
02811 char *args[], int numargs)
02812 {
02813 const char *from = nick->nick;
02814 int urllen;
02815
02816
02817
02818
02819 if (numargs < 2) {
02820 if (nick->reg->url)
02821 FREE(nick->reg->url);
02822 nick->reg->url = NULL;
02823 sSend(":%s NOTICE %s :Your URL has been cleared",
02824 NickServ, from);
02825 return RET_OK_DB;
02826 }
02827
02828
02829
02830
02831 urllen = strlen(args[1]);
02832 if (urllen > URLLEN - 1) {
02833 sSend(":%s NOTICE %s :URL too long."
02834 " Max is %d characters.", NickServ, from, URLLEN - 1);
02835 return RET_EFAULT;
02836 }
02837
02838
02839
02840
02841 if (nick->reg->url)
02842 FREE(nick->reg->url);
02843 nick->reg->url = strdup(args[1]);
02844 sSend(":%s NOTICE %s :Your URL has been set to: %s",
02845 NickServ, from, nick->reg->url);
02846 return RET_OK_DB;
02847 }
02848
02849
02853 cmd_return ns_set_encrypt(nss_tab *setEnt, UserList *nick,
02854 char *args[], int numargs)
02855 {
02856 const char *from = nick->nick;
02857 int do_enc = 0;
02858
02859 if (numargs < 2) {
02860 sSend(":%s NOTICE %s :Your password is %scurrently encrypted.",
02861 NickServ, from, (nick->reg->flags & NENCRYPT) ? "" : "\2not\2 ");
02862 return RET_OK_DB;
02863 }
02864
02865 if (!str_cmp(args[1], "ON") || !str_cmp(args[1], "ENCRYPT") ||
02866 !str_cmp(args[1], "YES"))
02867 do_enc = 1;
02868 else if (!str_cmp(args[1], "OFF") || !str_cmp(args[1], "UNENCRYPT") ||
02869 !str_cmp(args[1], "NO"))
02870 do_enc = 0;
02871 else {
02872 sSend(":%s NOTICE %s :Invalid setting. Must be ON or OFF.",
02873 NickServ, from);
02874 }
02875
02876 if (numargs < 3) {
02877 sSend(":%s NOTICE %s :Your password must also be specified to "
02878 "change this setting.", NickServ, from);
02879 return RET_OK_DB;
02880 }
02881
02882 if (!Valid_pw(args[2], nick->reg->password, NickGetEnc(nick->reg))) {
02883 PutReply(NickServ, nick, ERR_BADPW, 0, 0, 0);
02884 if (BadPwNick(nick, nick->reg))
02885 return RET_KILLED;
02886
02887 return RET_BADPW;
02888 }
02889 else
02890 GoodPwNick(nick, nick->reg);
02891
02892
02893 if (do_enc) {
02894 sSend(":%s NOTICE %s :You password is now encrypted within services.",
02895 NickServ, from);
02896 nick->reg->flags |= NENCRYPT;
02897 }
02898 else {
02899 sSend(":%s NOTICE %s :You password is no longer encrypted within services.",
02900 NickServ, from);
02901 nick->reg->flags &= ~NENCRYPT;
02902 }
02903
02904 pw_enter_password(args[2], nick->reg->password, NickGetEnc(nick->reg));
02905
02906 return RET_OK_DB;
02907 }
02908
02909
02913 cmd_return ns_set_idtime(nss_tab *setEnt, UserList *nick,
02914 char *args[], int numargs)
02915 {
02916 const char *from = nick->nick;
02917 int delay;
02918
02919 if (numargs < 2) {
02920 sSend(":%s NOTICE %s :Your current ID time is: %i "
02921 "seconds", NickServ, from, nick->reg->idtime);
02922 sSend(":%s NOTICE %s :If you wish to set your ID time,"
02923 " you must specify a delay", NickServ, from);
02924 return RET_OK;
02925 }
02926
02927 if ((delay = atoi(args[1]))) {
02928 if ((delay > ENF_MAXDELAY) || (delay < ENF_MINDELAY)) {
02929 sSend(":%s NOTICE %s :Invalid delay value",
02930 NickServ, from);
02931 sSend(":%s NOTICE %s :Please enter a value in "
02932 "the range of: %i - %i seconds",
02933 NickServ, from, ENF_MINDELAY, ENF_MAXDELAY);
02934 return RET_EFAULT;
02935 }
02936 } else {
02937 sSend(":%s NOTICE %s :Invalid delay value", NickServ, from);
02938 sSend(":%s NOTICE %s :Please enter a value in the "
02939 "range of: %i - %i seconds", NickServ, from,
02940 ENF_MINDELAY, ENF_MAXDELAY);
02941 return RET_EFAULT;
02942 }
02943
02944 nick->reg->idtime = delay;
02945 sSend(":%s NOTICE %s :Your ID time has been set to: %i seconds",
02946 NickServ, from, nick->reg->idtime);
02947
02948 return RET_OK_DB;
02949 }
02950
02951
02952 #ifdef REQ_EMAIL
02953
02954
02955
02956 void ActivateEmail(UserList *nick, char *addy)
02957 {
02958 char buf[IRCBUF * 2];
02959 EmailMessage email;
02960
02961 email.from = "NickName services <nickserv@"NETWORK">";
02962 email.to = addy;
02963 email.subject = "Nickname verification key";
02964 email.body = "Someone, possibly you has specified the e-mail "
02965 "contact address of: ";
02966 email.to += addy;
02967 email.to += "\n";
02968 email.to += "If you do not follow the instructions found in this message, \n";
02969 email.to += "then it will be assumed that the e-mail address specified\n";
02970 email.to += " was not correct.\n";
02971 email.to += "\n";
02972 sprintf(buf, "Your nickname activation key is: %lu\n", nick->reg->email_key);
02973 email.to += buf;
02974 sprintf(buf, "To activate your nickname, switch to the nickname %s and\n", nick->reg->nick);
02975 email.to += buf;
02976 sprintf(buf, "/msg %s ACTIVATE %lu\n", nick->reg->email_key);
02977 email.to += buf;
02978 email.to += "\n";
02979 sprintf(buf, "NOTICE: mail sent by %s@%s using the nickname %s\n", nick->user, nick->host, nick->nick);
02980 email.to += buf;
02981 sprintf(buf, "%s\n", ctime(&CTime));
02982 email.to += buf;
02983 email.to += "\n";
02984 email.send();
02985 email.reset();
02986 }
02987 #endif
02988
02992 cmd_return ns_set_email(nss_tab *setEnt, UserList *nick,
02993 char *args[], int numargs)
02994 {
02995 const char *from = nick->nick;
02996
02997 if (numargs < 2) {
02998 sSend(":%s NOTICE %s :You must specify an e-mail address",
02999 NickServ, from);
03000 return RET_EFAULT;
03001 }
03002
03003 if (!str_cmp(args[1], "on")) {
03004 nick->reg->flags |= NEMAIL;
03005 PutReply(NickServ, nick, RPL_SWITCHNOW_ARG2,
03006 "public e-mail", "ON", 0);
03007 return RET_OK_DB;
03008 } else if (!str_cmp(args[1], "off")) {
03009 nick->reg->flags &= ~(NEMAIL);
03010 PutReply(NickServ, nick, RPL_SWITCHNOW_ARG2,
03011 "public e-mail", "OFF", 0);
03012 return RET_OK_DB;
03013 }
03014
03015 if ((!strchr(args[1], '@')
03016 #ifndef REQ_EMAIL
03017 && strcasecmp(args[1], "none")
03018 #endif
03019 ) || *args[1] == '|' || strchr(args[1], '/') || strchr(args[1], '<')
03020 || strchr(args[1], '>') || strchr(args[1], '\"')) {
03021 sSend(":%s NOTICE %s :Please specify a valid e-mail address"
03022 "in the form of user@host", NickServ, from);
03023 return RET_EFAULT;
03024 }
03025
03026 #ifdef REQ_EMAIL
03027 srandom(time(NULL));
03028
03029 if (emailAbuseCheck(nick, args[1], 0))
03030 return;
03031
03032 nick->reg->email_key = random();
03033 nick->reg->flags |= NDEACC;
03034
03035 sSend(":%s NOTICE %s :Your nick has been temporarily de-activated to verify your new address", NickServ, from);
03036 sSend(":%s NOTICE %s :To re-activate please follow the same procedure as when you registered", NickServ, from);
03037 sSend(":%s NOTICE %s :All your previous data will be saved", NickServ, from);
03038 sSend(":%s NOTICE %s :Registration key sent to %s", NickServ, from, args[1]);
03039
03040 ActivateEmail(nick, args[1]);
03041 #endif
03042
03043 strncpyzt(nick->reg->email, args[1], EMAILLEN);
03044
03045 sSend(":%s NOTICE %s :Your email address has been set to %s",
03046 NickServ, from, args[1]);
03047 if (!strcasecmp(args[1], "none")) {
03048 sSend(":%s NOTICE %s :Please note: should you forget your "
03049 "password and have no e-mail address set, your password "
03050 "cannot be recovered for you.", NickServ, from);
03051 strcpy(nick->reg->email, "(none) ");
03052 }
03053
03054 return RET_OK_DB;
03055 }
03056
03057
03058
03066 NCMD(ns_set)
03067 {
03068 char *from = nick->nick;
03069 int i;
03070
03071
03072 nss_tab ns_set_table[] = {
03073 { "enforce", "nick protection",
03074 NSS_FLAG, NKILL, 0, },
03075 { "kill", "nick protection",
03076 NSS_FLAG, NKILL, 0, },
03077 { "ident", "identification requirement",
03078 NSS_FLAG, NIDENT, 0, },
03079 { "noaddop", "Noaddop option",
03080 NSS_FLAG, NOADDOP, 0, },
03081 { "terse", "Terse option",
03082 NSS_FLAG, NTERSE, 0, },
03083 { "maskadd", "hide mask option",
03084 NSS_FLAG, NDBISMASK, 0, },
03085 { "iphide", "hide mask option",
03086 NSS_FLAG, NDBISMASK, 0, },
03087 { "hideip", "hide mask option",
03088 NSS_FLAG, NDBISMASK, 0, },
03089 { "showemail", "public e-mail",
03090 NSS_FLAG, NEMAIL, 0, },
03091 { "passwd", "password",
03092 NSS_PROC, 0, 0, ns_set_passwd },
03093 { "password", "password",
03094 NSS_PROC, 0, 0, ns_set_passwd },
03095 { "url", "url",
03096 NSS_PROC, 0, 0, ns_set_url },
03097 { "idtime", "identify delay",
03098 NSS_PROC, 0, 0, ns_set_idtime },
03099 { "email", "e-mail address",
03100 NSS_PROC, 0, 0, ns_set_email },
03101 { "address", "e-mail address",
03102 NSS_PROC, 0, 0, ns_set_email },
03103 { "encrypt", "encrypted password",
03104 NSS_PROC, 0, 0, ns_set_encrypt },
03105 { NULL, NULL,
03106 (ns_set_en)0, 0, 0, NULL },
03107 };
03108
03109
03110
03111 if (addFlood(nick, 2))
03112 return RET_KILLED;
03113
03114 if (numargs < 2) {
03115 sSend(":%s NOTICE %s :A variable is required with NickServ SET",
03116 NickServ, from);
03117 sSend(":%s NOTICE %s :See /msg %s HELP SET", NickServ, from,
03118 NickServ);
03119
03120 return RET_SYNTAX;
03121 }
03122
03123 if (!isIdentified(nick, nick->reg)) {
03124 PutError(NickServ, nick, ERR_NOTIDENTIFIED, 0, 0, 0);
03125 return RET_NOPERM;
03126 }
03127
03128
03129 for (i = 0; ns_set_table[i].keyword; i++)
03130 if (!str_cmp(ns_set_table[i].keyword, args[1]) &&
03131 (!ns_set_table[i].opFlagsRequired ||
03132 opFlagged(nick, ns_set_table[i].opFlagsRequired)))
03133 break;
03134
03135 if (!ns_set_table[i].keyword) {
03136 sSend(":%s NOTICE %s :Unknown set command %s, please "
03137 "try /msg %s HELP SET", NickServ, from, args[1], NickServ);
03138 return RET_SYNTAX;
03139 }
03140
03141 if (ns_set_table[i].set_type == NSS_FLAG) {
03142 int flag = ns_set_table[i].flag;
03143
03144 if (numargs < 3) {
03145 PutReply(NickServ, nick, RPL_SWITCHIS_ARG2,
03146 ns_set_table[i].description,
03147 !(nick->reg->flags & (flag)) ? "off" : "on", 0);
03148
03149 return RET_OK;
03150 } else if (!str_cmp(args[2], "on")) {
03151 nick->reg->flags |= flag;
03152 PutReply(NickServ, nick, RPL_SWITCHNOW_ARG2,
03153 ns_set_table[i].description, "ON", 0);
03154 } else if (!str_cmp(args[2], "off")) {
03155 nick->reg->flags &= ~(flag);
03156 PutReply(NickServ, nick, RPL_SWITCHNOW_ARG2,
03157 ns_set_table[i].description, "OFF", 0);
03158 } else {
03159 sSend(":%s NOTICE %s :Unknown variable for SET %s",
03160 NickServ, from, ns_set_table[i].keyword);
03161 sSend(":%s NOTICE %s :Syntax: /msg %s SET %s <on|off>",
03162 NickServ, from, NickServ, ns_set_table[i].keyword);
03163
03164 return RET_SYNTAX;
03165 }
03166
03167 return RET_OK_DB;
03168 }
03169 else if (ns_set_table[i].set_type == NSS_PROC) {
03170 return (* ns_set_table[i].proc)(&ns_set_table[i], nick,
03171 args+1, numargs-1);
03172 }
03173
03174 return RET_OK;
03175 }
03176
03177
03188 NCMD(ns_register)
03189 {
03190 char *from;
03191 char user2[USERLEN];
03192 char host2[HOSTLEN];
03193 char pw_reason[IRCBUF];
03194 char mailTemp[EMAILLEN] = "(none)";
03195 char *p;
03196 int wasvalid = 0;
03197 unsigned int i = 0;
03198 #ifdef REQ_EMAIL
03199 time_t doot = time(NULL);
03200
03201 srandom(time(NULL));
03202 #endif
03203
03204 from = nick->nick;
03205
03206 if (addFlood(nick, 20))
03207 return RET_KILLED;
03208
03209 if (nick->reg != NULL) {
03210 sSend(":%s NOTICE %s :This nickname is already registered.",
03211 NickServ, from);
03212 return RET_EFAULT;
03213 }
03214
03215 for (i = 0; i < NUM_CNICKS; i++)
03216 if (!strncasecmp
03217 (cnick_prefixes[i], nick->nick, strlen(cnick_prefixes[i]))) {
03218 sSend
03219 (":%s NOTICE %s :The nick that you are using is a temporary nickname owned by services: it cannot be registered.",
03220 NickServ, from);
03221 return RET_EFAULT;
03222 }
03223
03224 if (!strncasecmp("Auth-", nick->nick, strlen("Auth-"))) {
03225 sSend
03226 (":%s NOTICE %s :The nick that you are using is a temporary nickname owned by services: it cannot be registered.",
03227 NickServ, from);
03228 return RET_EFAULT;
03229 }
03230
03231 if (numargs < 2) {
03232 sSend(":%s NOTICE %s :You must specify a password to register",
03233 NickServ, from);
03234 return RET_SYNTAX;
03235 }
03236
03237 if (isPasswordAcceptable(args[1], pw_reason) == 0) {
03238 sSend(":%s NOTICE %s :Sorry, %s isn't a password that you can use.",
03239 NickServ, from, args[1]);
03240 sSend(":%s NOTICE %s :%s", NickServ, from, pw_reason);
03241 return RET_EFAULT;
03242 }
03243
03244 if (strlen(args[1]) > 15) {
03245 sSend(":%s NOTICE %s :Please specify a password of "
03246 "%d characters or less", NickServ, from, PASSLEN);
03247 return RET_EFAULT;
03248 }
03249
03250 if (strcasecmp(args[1], from) == 0) {
03251 sSend(":%s NOTICE %s :Your password cannot be your nickname.",
03252 NickServ, from);
03253 return RET_EFAULT;
03254 }
03255
03256 if (strchr(args[1], '@')
03257 || (args[1] == strchr(args[1], '<') && (p = strrchr(args[1], '>'))
03258 && !*(p + 1))) {
03259 if (strchr(args[1], '@'))
03260 sSend
03261 (":%s NOTICE %s :Your registration password cannot contain the @ symbol.",
03262 NickServ, from);
03263 if (args[1] == strchr(args[1], '<') && strchr(args[1], '>')) {
03264 sSend
03265 (":%s NOTICE %s :Your registration password should not be surrounded with <>.",
03266 NickServ, from);
03267 sSend
03268 (":%s NOTICE %s :The '<' and '>' symbols surrounding a word in services' helpfiles is an indicator that 'password' is a field that you should specify a value for.",
03269 NickServ, from);
03270 }
03271 sSend(":%s NOTICE %s :\2/msg %s HELP REGISTER\2 for assistance",
03272 NickServ, from, NickServ);
03273 return RET_EFAULT;
03274 }
03275
03276 if (strlen(args[1]) < 5)
03277 {
03278 sSend(":%s NOTICE %s :Your password cannot be %s. A password should be impossible to guess and must have a length of 5 or more characters (letters, numbers, and symbols).",
03279 NickServ, from, args[1]);
03280 return RET_EFAULT;
03281 }
03282
03283 if (strcasecmp(args[1], "password") == 0 || strcasecmp(args[1], "<password>") == 0
03284 || strcasecmp(args[1], "1234") == 0 || strcasecmp(args[1], "fz345") == 0
03285 || strcasecmp(args[1], "word") == 0)
03286 {
03287 sSend(":%s NOTICE %s :Your password cannot be %s.", NickServ, from,
03288 args[1]);
03289 return RET_EFAULT;
03290 }
03291
03292 if (numargs < 3) {
03293 #ifndef REQ_EMAIL
03294 sSend
03295 (":%s NOTICE %s :To register you must also either specify your e-mail address or NONE.",
03296 NickServ, from);
03297 sSend
03298 (":%s NOTICE %s :E-mail addresses provided are treated as private material and are used ONLY to assist with lost passwords.",
03299 NickServ, from);
03300 sSend
03301 (":%s NOTICE %s :Specifying an e-mail address of NONE indicates that, should you lose your password, operators will be unable to retrieve the password for you.",
03302 NickServ, from);
03303 sSend
03304 (":%s NOTICE %s :examples: /msg nickserv register \2MYSECRETCODE\2 \2me@myemail.com\2",
03305 NickServ, from);
03306 sSend
03307 (":%s NOTICE %s : /msg nickserv register \2MYSECRETCODE\2 \2NONE\2",
03308 NickServ, from);
03309 #else
03310 sSend(":%s NOTICE %s :You must specify an e-mail address and a "
03311 "password to register.", NickServ, from);
03312 #endif
03313 return RET_SYNTAX;
03314 }
03315
03316 #ifdef REQ_EMAIL
03317 if (numargs > 2)
03318 #else
03319 if (numargs > 2 && strcasecmp(args[2], "none"))
03320 #endif
03321 if (!strchr(args[2], '@') || !strchr(args[2], '.'))
03322 {
03323 sSend
03324 (":%s NOTICE %s :specified a e-mail address is invalid. "
03325 "Must be of the form user@host", NickServ, from);
03326 #ifdef EMAIL_OK_IF_SPECIFIED
03327 return;
03328 #endif
03329 }
03330 else {
03331 wasvalid = 1;
03332 strncpyzt(mailTemp, args[2], EMAILLEN);
03333 } else if (numargs > 2 && !strcasecmp(args[2], "none"))
03334 strcpy(mailTemp, "(none) ");
03335 else
03336 strcpy(mailTemp, "(none)");
03337
03338 if (wasvalid == 0)
03339 sSend
03340 (":%s NOTICE %s :To enable us to recover your password in the event that it is lost, you must specify your e-mail address by using /msg NickServ set address <email address>",
03341 NickServ, from);
03342
03343 #ifdef REQ_EMAIL
03344 if (emailAbuseCheck(nick, args[1], 1))
03345 return;
03346 #endif
03347
03348 strncpyzt(user2, nick->user, USERLEN);
03349 strncpyzt(host2, nick->host, HOSTLEN);
03350
03351 nick->reg = (RegNickList *) oalloc(sizeof(RegNickList));
03352
03353 strncpyzt(nick->reg->nick, nick->nick, NICKLEN);
03354 strncpyzt(nick->reg->user, nick->user, USERLEN);
03355 SetDynBuffer(&nick->reg->host, nick->host);
03356 strncpyzt(nick->reg->email, mailTemp, EMAILLEN);
03357 #ifdef TRACK_GECOS
03358 SetDynBuffer(&nick->reg->gecos, nick->gecos);
03359 #endif
03360
03361 nick->reg->timestamp = CTime;
03362 nick->reg->timereg = CTime;
03363 #ifdef REQ_EMAIL
03364 nick->reg->email_key = random();
03365 #endif
03366 nick->caccess = 3;
03367 nick->reg->flags |= NENCRYPT;
03368 pw_enter_password(args[1], nick->reg->password, NickGetEnc(nick->reg));
03369
03370 nicklog->log(nick, NS_REGISTER, nick->nick);
03371 ADD_MEMO_BOX(nick->reg);
03372 mostnicks++;
03373
03374 nick->reg->amasks = 0;
03375 nick->reg->url = NULL;
03376 nick->reg->chans = 0;
03377 nick->reg->idtime = DEF_NDELAY;
03378 nick->reg->regnum.SetNext(top_regnick_idnum);
03379
03380 addRegNick(nick->reg);
03381 #ifdef REQ_EMAIL
03382 ActivateEmail(nick, args[1]);
03383 #endif
03384
03385 if (nick->oflags & NOISMASK)
03386 nick->reg->flags |= NDBISMASK;
03387 #if defined(AHURT_BYPASS_BY_DEFAULT)
03388 if (!
03389 (isAHurt(tmp->nick, tmp->user, tmp->host)
03390 || isAKilled(tmp->nick, tmp->user,
03391 tmp->host))) nick->reg->flags |= NBYPASS;
03392 else {
03393 sSend
03394 (":%s NOTICE %s :Warning: you will not be able to use this registration to bypass select bans without further assistance.",
03395 NickServ, nick->nick);
03396 sSend
03397 (":%s NOTICE %s :This is true for all nicks registered from a domain while selective users from it are being banned for security reasons.",
03398 NickServ, nick->nick);
03399 }
03400 #endif
03401
03402 sSend
03403 (":%s NOTICE %s :Your nickname has been registered with the password %s",
03404 NickServ, from, args[1]);
03405
03406 if (nick->oflags & NOISMASK)
03407 nick->reg->flags |= NDBISMASK;
03408 return RET_OK_DB;
03409 }
03410
03411
03437 void SendNickInfo(UserList *nick, RegNickList *rnl, int terseOption)
03438 {
03439 char *from = nick->nick;
03440 struct tm *time;
03441 char temp[80];
03442 unsigned int j;
03443 UserList *online = NULL;
03444 struct {
03445 const char *optname;
03446 const char *optline;
03447 flag_t bit;
03448 int verbatim, oper_only;
03449 } regnick_flag_tab[] = {
03450 { "Enforce", "nick protection", NKILL, 0 },
03451 { "Held", "This nickname will not expire.", NHOLD, 1 },
03452 { "Vacation", "This nickname has vacation set and has an "
03453 "extended expiration period.", NVACATION, 1 },
03454 { "Nosendpass", NULL, NOSENDPASS, 0, 1},
03455 { NULL }
03456 };
03457
03458 sSend(":%s NOTICE %s :Information for %s:", NickServ, from, rnl->nick);
03459
03460 if ((online = getNickData(rnl->nick))) {
03461 if (isIdentified(online, rnl)) {
03462 PutReply(NickServ, nick, RPL_INFONLINE_ID, rnl->nick, online->caccess, 0);
03463 } else if (isRecognized(online, rnl)) {
03464 PutReply(NickServ, nick, RPL_INFONLINE_NOID, rnl->nick, online->caccess, 0);
03465
03466
03467
03468 }
03469 }
03470
03471 if (rnl->flags & NBANISH) {
03472 PutReply(NickServ, nick, RPL_NS_BANISH, rnl->nick, 0, 0);
03473 PutReply(NickServ, nick, RPL_NS_ENDINFO, rnl->nick, 0, 0);
03474 return;
03475 }
03476
03477 #ifdef REQ_EMAIL
03478 if (!(rnl->flags & NACTIVE)) {
03479 sSend(":%s NOTICE %s :%s is not activated.",
03480 NickServ, from, rnl->nick);
03481 if (!isOper(nick))
03482 return;
03483 }
03484 #endif
03485 #ifdef TRACK_GECOS
03486 if (rnl->gecos)
03487 sSend(":%s NOTICE %s :%s[%s@%s] (%s)", NickServ, from,
03488 rnl->nick, rnl->user, regnick_ugethost(nick, rnl),
03489 rnl->gecos);
03490 else
03491 #endif
03492 sSend(":%s NOTICE %s :%s[%s@%s]", NickServ, from,
03493 rnl->nick, rnl->user, regnick_ugethost(nick, rnl));
03494
03495 if (rnl->url)
03496 sSend(":%s NOTICE %s :Url : %s", NickServ, from,
03497 rnl->url);
03498
03499
03500 if (((rnl->flags & NEMAIL) || isIdentified(nick, rnl))
03501 && rnl->email[0])
03502 sSend(":%s NOTICE %s :Email : %s", NickServ, from,
03503 rnl->email);
03504 do
03505 {
03506 char optBuf[IRCBUF];
03507
03508 time = localtime(&rnl->timestamp);
03509 if ( strftime(temp, 80, "%a %Y-%b-%d %T %Z", time) > 0 )
03510 sSend(":%s NOTICE %s :Last seen time : %s", NickServ, from, temp);
03511
03512 time = localtime(&rnl->timereg);
03513
03514 if ( strftime(temp, 80, "%a %Y-%b-%d %T %Z", time) > 0 )
03515 sSend(":%s NOTICE %s :Registered at : %s", NickServ, from, temp);
03516
03517 time = localtime(&CTime);
03518
03519 if ( strftime(temp, 80, "%a %Y-%b-%d %T %Z", time) > 0 )
03520 sSend(":%s NOTICE %s :Current time : %s", NickServ, from, temp);
03521
03522 memset(optBuf, 0, sizeof(optBuf));
03523
03524 for(j = 0; regnick_flag_tab[j].optname; j++)
03525 {
03526 if (regnick_flag_tab[j].oper_only && !isOper(nick))
03527 continue;
03528
03529 if (terseOption || !regnick_flag_tab[j].optline) {
03530 if ((rnl->flags & regnick_flag_tab[j].bit) &&
03531 (strlen(optBuf) < (IRCBUF - strlen(regnick_flag_tab[j].optname) - 25)))
03532 {
03533 if (*optBuf)
03534 strcat(optBuf, ", ");
03535 strcat(optBuf, regnick_flag_tab[j].optname);
03536 }
03537 continue;
03538 }
03539
03540 if (rnl->flags & regnick_flag_tab[j].bit)
03541 {
03542 if (!regnick_flag_tab[j].verbatim)
03543 sSend(":%s NOTICE %s :This user has enabled \2%s\2.", NickServ,
03544 from, regnick_flag_tab[j].optline);
03545 else
03546 sSend(":%s NOTICE %s :%s", NickServ,
03547 from, regnick_flag_tab[j].optline);
03548 }
03549 }
03550
03551 if (terseOption) {
03552 if (rnl->memos) {
03553
03554
03555
03556 if (rnl->memos->flags & MNOMEMO)
03557 sprintf(optBuf + strlen(optBuf), "%sNoMemo",
03558 *optBuf ? ", " : "");
03559 }
03560 }
03561
03562 if (rnl->memos) {
03563 if (!terseOption && (rnl->memos->flags & MNOMEMO))
03564 sSend(":%s NOTICE %s :%s has chosen not to receive memos",
03565 NickServ, from, rnl->nick);
03566 if (rnl->memos->flags & MFORWARDED)
03567 sSend(":%s NOTICE %s :Memos forwarded to: %s",
03568 NickServ, from, rnl->memos->forward->nick);
03569 }
03570
03571 if (*optBuf)
03572 sSend(":%s NOTICE %s :Nick options : %s", NickServ, from,
03573 optBuf);
03574 #ifdef ENABLE_GRPOPS
03575 if (((rnl->opflags & OGRP) && !(rnl->opflags & OROOT)))
03576 sSend(":%s NOTICE %s :User is a GRP-op.",
03577 NickServ, from);
03578 else if (!isOper(nick) && (rnl->opflags & OROOT))
03579 sSend(":%s NOTICE %s :User is a SRA and GRP-op.",
03580 NickServ, from);
03581 #else
03582 else if (!isOper(nick) && (rnl->opflags & OROOT))
03583 sSend(":%s NOTICE %s :User is a Services root admin, GRP-op.",
03584 NickServ, from);
03585 #endif
03586 else
03587 if (online && !isOper(nick) && (isHelpop(online) || isOper(online)))
03588 sSend(":%s NOTICE %s :User can mail lost passwords.", NickServ, from);
03589 } while(0);
03590
03591 if (isOper(nick) == 1) {
03592 if (!terseOption)
03593 {
03594 sSend(":%s NOTICE %s :+++ IRCop Data +++", NickServ, from);
03595 if (rnl->opflags & OROOT)
03596 sSend(":%s NOTICE %s :+ This user is a Warlock/Sorceress (Services Root)",
03597 NickServ, from);
03598 else if (rnl->opflags & OPFLAG_ROOTSET)
03599 sSend(":%s NOTICE %s :+ This user is a Wizard/Witch (Services Operator)",
03600 NickServ, from);
03601 }
03602 else
03603 {
03604 if (rnl->opflags & OROOT)
03605 sSend(":%s NOTICE %s :+ Services root admin.",
03606 NickServ, from);
03607 else if (rnl->opflags & OPFLAG_ROOTSET)
03608 sSend(":%s NOTICE %s :+ Services operator.",
03609 NickServ, from);
03610 }
03611
03612 {
03613 char buf[EMAILLEN+15];
03614
03615 *buf = '\0';
03616
03617 if (((rnl->flags & NEMAIL) == 0) && (rnl->email[0])
03618 && !isIdentified(nick, rnl))
03619 snprintf(buf, sizeof(buf), ", Prv Email: %s", rnl->email);
03620 sSend(":%s NOTICE %s :+ Masks: %i, Bypass: %s%s", NickServ, from,
03621 rnl->amasks, (rnl->flags & NBYPASS) ? "Yes" : "No", buf);
03622 }
03623
03624
03625 if (online) {
03626 sSend(":%s NOTICE %s :+ %s flood level: %i/100", NickServ,
03627 from, rnl->nick, online->floodlevel.GetLev());
03628 }
03629 if ((rnl->flags & NMARK)) {
03630 sSend(":%s NOTICE %s :+ %s MARKED%s%s", NickServ,
03631 from, rnl->nick, rnl->markby ? " by " : "",
03632 rnl->markby ? rnl->markby : "");
03633 }
03634 }
03635
03636 if (isHelpop(nick) == 1 && isOper(nick) == 0) {
03637 if (((rnl->flags & NEMAIL) == 0) && (rnl->email[0]))
03638 sSend(":%s NOTICE %s :+ Email address: Hidden (not displayed)",
03639 NickServ, from);
03640 }
03641 sSend(":%s NOTICE %s :End of info on %s", NickServ, from,
03642 rnl->nick);
03643 }
03644
03646 NCMD(ns_info)
03647 {
03648 char *from = nick->nick;
03649 unsigned int i;
03650 int terseOption, k;
03651 RegNickList *regnick;
03652
03653 if (addFlood(nick, 5))
03654 return RET_KILLED;
03655
03656 terseOption = (nick->reg && (nick->reg->flags & NTERSE));
03657
03658 for(k = 1; k < numargs; k++)
03659 {
03660 if (args[k][0] != '-')
03661 break;
03662 if (strcmp(args[k], "-short") == 0 || strcmp(args[k], "-terse") == 0)
03663 terseOption = 1;
03664 else if (strcmp(args[k], "-long") == 0 || strcmp(args[k], "-verbose") == 0)
03665 terseOption = 0;
03666 }
03667
03668 if (k < numargs)
03669 regnick = getRegNickData(args[k]);
03670 else
03671 regnick = nick->reg;
03672
03673 #if defined(NICKSERV_INFO_TZ_ARG)
03674 if (regnick && numargs > 2 && args[2])
03675 tzapply(args[2]);
03676 #endif
03677
03678 if (numargs > 1)
03679 for (i = 0; i < NUM_CNICKS; i++)
03680 if (!strncasecmp
03681 (cnick_prefixes[i], args[k], strlen(cnick_prefixes[i]))) {
03682 sSend
03683 (":%s NOTICE %s :That is a services temporary user nickname.",
03684 NickServ, from);
03685 return RET_OK;
03686 }
03687
03688 if (regnick == NULL) {
03689 sSend(":%s NOTICE %s :%s is not registered", NickServ, from,
03690 numargs > 1 ? args[k] : from);
03691 return RET_FAIL;
03692 }
03693
03694 SendNickInfo(nick, regnick, terseOption);
03695
03696 #if defined(NICKSERV_INFO_TZ_ARG)
03697 if (numargs > 2 && args[2])
03698 tzapply(DEF_TIMEZONE);
03699 #endif
03700 return RET_OK;
03701 }
03702
03706 NCMD(ns_drop)
03707 {
03708 char *from = nick->nick;
03709
03710 if (addFlood(nick, 3))
03711 return RET_KILLED;
03712
03713 if (!nick->reg) {
03714 sSend(":%s NOTICE %s :Your present nickname is not registered.",
03715 NickServ, nick->nick);
03716 return RET_EFAULT;
03717 }
03718
03719 if ((nick->reg->flags & NBANISH)) {
03720 sSend
03721 (":%s NOTICE %s :Sorry, but that nickname is currently banished.",
03722 NickServ, from);
03723 return RET_FAIL;
03724 }
03725
03726 if (numargs > 1) {
03727 if (!Valid_pw(args[1], nick->reg->password, NickGetEnc(nick->reg))) {
03728 sSend(":%s NOTICE %s :Incorrect password.", NickServ,
03729 nick->nick);
03730 BadPwNick(nick, nick->reg);
03731 return RET_BADPW;
03732 }
03733 else
03734 GoodPwNick(nick, nick->reg);
03735 }
03736
03737 if (!isIdentified(nick, nick->reg)) {
03738 sSend(":%s NOTICE %s :You must identify to drop your nick",
03739 NickServ, nick->nick);
03740 return RET_NOPERM;
03741 }
03742
03743 mostnicks--;
03744 sSend(":%s NOTICE %s :Your nick %s has been dropped.",
03745 NickServ, from, from);
03746 nicklog->log(nick, NS_DROP, nick->nick);
03747 delRegNick(nick->reg);
03748 nick->reg = NULL;
03749 return RET_OK_DB;
03750 }
03751
03757 NCMD(ns_addmask)
03758 {
03759
03760 if (addFlood(nick, 2))
03761 return RET_KILLED;
03762
03763 if (!isIdentified(nick, nick->reg)) {
03764 sSend(":%s NOTICE %s :You must identify to use ADDMASK", NickServ,
03765 nick->nick);
03766 return RET_NOPERM;
03767 }
03768
03769 if (numargs < 2) {
03770 char *user, *host, theirmask[USERLEN + HOSTLEN + 3];
03771
03772 user = host = NULL;
03773
03774 SetDynBuffer(&user, nick->user);
03775 SetDynBuffer(&host, nick->host);
03776 mask(user, host, 0, theirmask);
03777 addAccessMask(theirmask, nick);
03778 SetDynBuffer(&user, NULL);
03779 SetDynBuffer(&host, NULL);
03780
03781 return RET_OK_DB;
03782 } else if (numargs < 4) {
03783 if (!strcasecmp(args[1], "S")) {
03784 addAccessMask(args[2], nick);
03785 return RET_OK_DB;
03786 }
03787 }
03788
03789 sSend(":%s NOTICE %s :Incorrect use of ADDMASK", NickServ, nick->nick);
03790 return RET_SYNTAX;
03791 }
03792
03807 NCMD(ns_access)
03808 {
03809 char *from = nick->nick;
03810 nAccessList *acl;
03811 int idx;
03812
03813 if (addFlood(nick, 2))
03814 return RET_KILLED;
03815
03816 if (numargs < 2) {
03817 sSend(":%s NOTICE %s :Your access is %i",
03818 NickServ, nick->nick, nick->caccess);
03819 return RET_OK;
03820 }
03821
03822 if (strcasecmp(args[1], "list") == 0) {
03823 if (numargs < 3) {
03824 if (!nick->reg) {
03825 sSend(":%s NOTICE %s :Your nickname is not registered.",
03826 NickServ, from);
03827 return RET_FAIL;
03828 }
03829 if (!isIdentified(nick, nick->reg)) {
03830 sSend(":%s NOTICE %s :You must identify "
03831 "to get the access list", NickServ, from);
03832 return RET_NOPERM;
03833 }
03834
03835 if (LIST_FIRST(&nick->reg->acl) == NULL) {
03836 sSend(":%s NOTICE %s :Access list for %s"
03837 " is empty", NickServ, nick->nick, nick->nick);
03838 return RET_OK;
03839 }
03840
03841 sSend(":%s NOTICE %s :Access list for %s:",
03842 NickServ, nick->nick, nick->nick);
03843
03844 idx = 1;
03845 for (acl = LIST_FIRST(&nick->reg->acl); acl != NULL;
03846 acl = LIST_NEXT(acl, al_lst)) {
03847 sSend(":%s NOTICE %s :%2i: %s",
03848 NickServ, nick->nick, idx++, acl->mask);
03849 }
03850 sSend(":%s NOTICE %s :End of list for %s",
03851 NickServ, nick->nick, nick->nick);
03852 } else {
03853 RegNickList *tmpnick;
03854
03855 tmpnick = getRegNickData(args[2]);
03856
03857 if (tmpnick == NULL) {
03858 sSend(":%s NOTICE %s :%s is not registered",
03859 NickServ, from, args[2]);
03860 return RET_NOTARGET;
03861 }
03862
03863 if (!isOper(nick) && !isIdentified(nick, tmpnick)) {
03864 sSend(":%s NOTICE %s :Access denied to list for %s",
03865 NickServ, nick->nick, args[2]);
03866 return RET_NOPERM;
03867 }
03868
03869 if (LIST_FIRST(&tmpnick->acl) == NULL) {
03870 sSend(":%s NOTICE %s :Access list for %s"
03871 " is empty", NickServ, nick->nick, tmpnick->nick);
03872 return RET_OK;
03873 }
03874
03875 sSend(":%s NOTICE %s :Access list for %s:",
03876 NickServ, nick->nick, args[2]);
03877
03878 idx = 1;
03879 for (acl = LIST_FIRST(&tmpnick->acl); acl != NULL;
03880 acl = LIST_NEXT(acl, al_lst))
03881 sSend(":%s NOTICE %s :%2i: %s",
03882 NickServ, nick->nick, idx++, acl->mask);
03883
03884 sSend(":%s NOTICE %s :End of list for %s",
03885 NickServ, nick->nick, args[2]);
03886 }
03887 } else if (strcasecmp(args[1], "add") == 0) {
03888 if (!nick->reg) {
03889 sSend(":%s NOTICE %s :Your nickname is not registered.",
03890 NickServ, from);
03891 return RET_FAIL;
03892 }
03893 if (numargs < 3) {
03894 sSend(":%s NOTICE %s :You must specify a mask to add",
03895 NickServ, nick->nick);
03896 return RET_SYNTAX;
03897 }
03898
03899 addAccessMask(args[2], nick);
03900 return RET_OK_DB;
03901 } else if (strncasecmp(args[1], "del", 3) == 0) {
03902
03903 if (numargs < 3) {
03904 sSend(":%s NOTICE %s :You must specify a mask to delete",
03905 NickServ, nick->nick);
03906 return RET_SYNTAX;
03907 }
03908
03909 if (!nick->reg) {
03910 sSend(":%s NOTICE %s :Your nickname is not registered.",
03911 NickServ, from);
03912 return RET_FAIL;
03913 }
03914
03915 delAccessMask(args[2], nick);
03916 return RET_OK_DB;
03917 } else {
03918 UserList *info;
03919
03920 info = getNickData(args[1]);
03921
03922 if (info == NULL) {
03923 sSend(":%s NOTICE %s :%s is not online, access is \0020\002",
03924 NickServ, nick->nick, args[1]);
03925 return RET_OK;
03926 } else {
03927 if (!isOper(nick) && nick != info)
03928 sSend
03929 (":%s NOTICE %s :Current access level for \002%s\002!%s@%s is \002%i\002",
03930 NickServ, nick->nick, info->nick, info->user, genHostMask(info->host),
03931 info->caccess);
03932 else
03933 sSend
03934 (":%s NOTICE %s :Current access level for \002%s\002!%s@%s is \002%i\002",
03935 NickServ, nick->nick, info->nick, info->user, info->host,
03936 info->caccess);
03937 return RET_OK;
03938 }
03939 }
03940 return RET_OK;
03941 }
03942
03948 NCMD(ns_acc)
03949 {
03950 char *from = nick->nick;
03951 RegNickList *tmpnick;
03952
03953 if (addFlood(nick, 2))
03954 return RET_KILLED;
03955
03956 if (numargs < 2) {
03957 tmpnick = getRegNickData(from);
03958 } else {
03959 if (numargs < 3)
03960 tmpnick = getRegNickData(args[1]);
03961 else
03962 tmpnick = getRegNickData(args[2]);
03963 }
03964
03965 {
03966 UserList *info;
03967 char *ustr;
03968 char *nstr;
03969
03970 if (numargs >= 2)
03971 info = getNickData(args[1]);
03972 else
03973 info = nick;
03974 ustr = (numargs > 1) ? args[1] : from;
03975 nstr = (numargs > 2) ? args[2] : (numargs > 1) ? args[1] : from;
03976
03977 if (!tmpnick) {
03978 if ((numargs > 2))
03979 sSend(":%s NOTICE %s :%s -> %s ACC 0 (not registered)",
03980 NickServ, nick->nick, ustr, nstr);
03981 else
03982 sSend(":%s NOTICE %s :%s ACC 0 (not registered)",
03983 NickServ, nick->nick, ustr);
03984 return RET_OK;
03985 } else if (info == NULL) {
03986 if ((numargs > 2))
03987 sSend(":%s NOTICE %s :%s -> %s ACC 0 (offline)",
03988 NickServ, nick->nick, args[1], nstr);
03989 else
03990 sSend(":%s NOTICE %s :%s ACC 0 (offline)",
03991 NickServ, nick->nick,
03992 (numargs > 1) ? args[1] : from);
03993 return RET_OK;
03994 } else {
03995 if ((numargs > 2)) {
03996 int cacc = 1;
03997
03998 if (isRecognized(info, tmpnick))
03999 cacc = 2;
04000 if (isIdentified(info, tmpnick))
04001 cacc = 3;
04002 if ((info->reg == tmpnick) && (info->caccess > 3))
04003 cacc = info->caccess;
04004
04005 sSend(":%s NOTICE %s :%s -> %s ACC %i",
04006 NickServ, nick->nick, ustr, nstr, cacc);
04007 } else
04008 sSend(":%s NOTICE %s :%s ACC %i",
04009 NickServ, nick->nick, info->nick, info->caccess);
04010 }
04011 }
04012 return RET_OK;
04013 }
04014
04015
04035 NCMD(ns_ghost)
04036 {
04037 RegNickList *tmp;
04038 UserList *taruser;
04039 char *from = nick->nick;
04040
04041 if (addFlood(nick, 3))
04042 return RET_KILLED;
04043
04044 if (numargs < 2) {
04045 sSend
04046 (":%s NOTICE %s :you must specify an argument after the GHOST command",
04047 NickServ, nick->nick);
04048 return RET_SYNTAX;
04049 }
04050
04051 #ifndef ALLOW_GHOST_YOURSELF
04052 if (!strcasecmp(nick->nick, args[1])) {
04053 sSend(":%s NOTICE %s :You cannot ghost yourself", NickServ, from);
04054 return RET_EFAULT;
04055 }
04056 #endif
04057
04058 if (getGhost(args[1])) {
04059 tmp = getRegNickData(args[1]);
04060 if (tmp == NULL) {
04061 sSend(":%s NOTICE %s :%s is not registered", NickServ, from,
04062 args[1]);
04063 return RET_EFAULT;
04064 }
04065
04066 if (Valid_pw(args[2], tmp->password, NickGetEnc(tmp)) ||
04067 ( !(tmp->flags & NIDENT) &&
04068 checkAccess(tmp->user, tmp->host, nick->reg) )
04069 )
04070 {
04071 sSend(":%s NOTICE %s :%s has been ghosted", NickServ,
04072 nick->nick, args[1]);
04073 if (isGhost(args[1])) {
04074 delGhost(args[1]);
04075 }
04076 }
04077 return RET_OK;
04078 }
04079
04080
04081 tmp = getRegNickData(args[1]);
04082 taruser = getNickData(args[1]);
04083
04084 if (tmp != NULL)
04085 if (checkAccess(nick->user, nick->host, tmp)
04086 || Valid_pw(args[2], tmp->password, NickGetEnc(tmp))) {
04087 taruser = getNickData(args[1]);
04088
04089 if (!taruser && (getGhost(args[1]) == NULL)) {
04090 sSend(":%s NOTICE %s :%s is not online.", NickServ,
04091 nick->nick, args[1]);
04092 }
04093
04094 if (!taruser)
04095 sSend(":%s KILL %s :%s!%s (Ghosted. By: %s (%s@%s)", NickServ,
04096 args[1], services[1].host, NickServ, nick->nick, nick->user, nick->host);
04097 else {
04098 if (strcmp(nick->host, taruser->host))
04099 sSend(":%s KILL %s :%s!%s (Ghosted. By: %s (%s@%s))",
04100 NickServ, args[1], services[1].host, NickServ,
04101 nick->nick, nick->user,
04102 (nick->oflags & NOISMASK) ? genHostMask(nick->
04103 host) :
04104 nick->host);
04105 else
04106 sSend(":%s KILL %s :%s!%s (Ghosted. By: %s)", NickServ,
04107 args[1], services[1].host, NickServ, nick->nick);
04108
04109 }
04110
04111 sSend(":%s NOTICE %s :Removing ghost, '%s'", NickServ,
04112 nick->nick, args[1]);
04113 remUser(args[1], 1);
04114 if (isGhost(args[1])) {
04115 delGhost(args[1]);
04116 }
04117 return RET_OK;
04118 } else if ((tmp == NULL)) {
04119 sSend(":%s NOTICE %s :%s is not registered.", NickServ,
04120 nick->nick, args[1]);
04121 return RET_EFAULT;
04122 } else {
04123 PutReply(NickServ, nick, ERR_NOACCESS, 0, 0, 0);
04124 return RET_NOPERM;
04125 }
04126 return RET_FAIL;
04127 }
04128
04129
04145 NCMD(ns_recover)
04146 {
04147 RegNickList *tmp;
04148 UserList *taruser;
04149 char *from = nick->nick;
04150
04151 if (addFlood(nick, 3))
04152 return RET_KILLED;
04153
04154 if (numargs < 2) {
04155 sSend
04156 (":%s NOTICE %s :you must specify an argument after the RECOVER command",
04157 NickServ, nick->nick);
04158 return RET_SYNTAX;
04159 }
04160
04161
04162 if (!strcasecmp(nick->nick, args[1])) {
04163 sSend(":%s NOTICE %s :You are already using the nickname.", NickServ, from);
04164 return RET_EFAULT;
04165 }
04166
04167 tmp = getRegNickData(args[1]);
04168 if (tmp == 0) {
04169 PutReply(NickServ, nick, ERR_NICKNOTREG_1ARG, args[1], 0, 0);
04170 return RET_EFAULT;
04171 }
04172
04173
04174 if (numargs >= 3)
04175 {
04176 struct auth_data auth_info[] = {{
04177 nick->auth_cookie,
04178 nick->idnum.getHashKey(),
04179 2
04180 }};
04181
04182 if (isMD5Key(args[2]))
04183 {
04184 if (!Valid_md5key(args[2], auth_info, tmp->nick, tmp->password, NickGetEnc(tmp)))
04185 {
04186 sSend(":%s NOTICE %s :Invalid MD5 key.", NickServ, nick->nick);
04187 nick->auth_cookie = 0;
04188 if (BadPwNick(nick, tmp))
04189 return RET_KILLED;
04190
04191 return RET_BADPW;
04192 }
04193 nick->auth_cookie = 0;
04194 }
04195 else if (!Valid_pw(args[2], tmp->password, NickGetEnc(tmp))) {
04196 PutReply(NickServ, nick, ERR_BADPW_NICK_1ARG, args[1], 0, 0);
04197 if (BadPwNick(nick, tmp))
04198 return RET_KILLED;
04199
04200 return RET_BADPW;
04201 }
04202 }
04203
04204 #ifndef ALLOW_PASSLESS_RECOVER
04205 if (numargs < 3) {
04206 #else
04207 if ((numargs < 3) && !isFullyRecognized(nick, tmp))
04208 #endif
04209 sSend(":%s NOTICE %s :Permission denied: you will need to specify a password.", NickServ, nick->nick);
04210 PutHelpInfo(NickServ, nick, "HELP RECOVER");
04211 return RET_NOPERM;
04212 }
04213
04214
04215 if (isGhost(args[1])) {
04216 sSend(":%s NOTICE %s :%s is currently held by a %s enforcer.", NickServ,
04217 nick->nick, args[1], NickServ);
04218 PutHelpInfo(NickServ, nick, "HELP RELEASE");
04219 return RET_EFAULT;
04220 }
04221
04222
04223 if (getGhost(args[1])) {
04224 return RET_OK;
04225 }
04226
04227 taruser = getNickData(args[1]);
04228
04229 if (taruser == 0) {
04230 sSend(":%s NOTICE %s :%s is not currently in use.", NickServ,
04231 nick->nick, args[1]);
04232 return RET_NOTARGET;
04233 }
04234
04235 enforce_nickname (taruser->nick);
04236 sSend(":%s NOTICE %s :Recovering nickname, '%s'", NickServ,
04237 nick->nick, args[1]);
04238 return RET_OK;
04239 }
04240
04241
04247 NCMD(ns_release)
04248 {
04249
04250 char *from = nick->nick;
04251 RegNickList *tmp;
04252
04253 if (addFlood(nick, 1))
04254 return RET_KILLED;
04255
04256 if (numargs < 2) {
04257 sSend
04258 (":%s NOTICE %s :You must specify a registered nick and its password after the RELEASE command",
04259 NickServ, from);
04260 return RET_NOTARGET;
04261 }
04262 if (numargs < 3) {
04263 sSend
04264 (":%s NOTICE %s :You must specify the nick's password after the specifed nick",
04265 NickServ, from);
04266 return RET_SYNTAX;
04267 }
04268
04269 if (isGhost(args[1])) {
04270 tmp = getRegNickData(args[1]);
04271
04272
04273 if (tmp == NULL) {
04274 sSend(":%s NOTICE %s :The nick %s is not registered.",
04275 NickServ, from, args[1]);
04276 return RET_NOTARGET;
04277 }
04278
04279 if ((numargs >= 3) && !Valid_pw(args[2], tmp->password, NickGetEnc(tmp))) {
04280 PutReply(NickServ, nick, ERR_BADPW, 0, 0, 0);
04281 if (BadPwNick(nick, tmp))
04282 return RET_KILLED;
04283
04284 return RET_BADPW;
04285 }
04286 else if ((numargs < 3)
04287 && !checkAccess(nick->user, nick->host, tmp)) {
04288 PutReply(NickServ, nick, ERR_NOACCESS, 0, 0, 0);
04289 return RET_NOPERM;
04290 }
04291 else
04292 GoodPwNick(nick, tmp);
04293
04294 if ((tmp != NULL)) {
04295 if (isGhost(args[1])) {
04296 delGhost(args[1]);
04297 }
04298 sSend(":%s NOTICE %s :The nick %s has been released",
04299 NickServ, from, args[1]);
04300 }
04301 return RET_OK;
04302 }
04303
04304 sSend(":%s NOTICE %s :Services are not currently holding that nick.",
04305 NickServ, from);
04306 return RET_NOTARGET;
04307 }
04308
04309
04310
04311
04312
04313
04314
04328
04329 NCMD(ns_setopflags)
04330 {
04331 char *from = nick->nick;
04332 char modebuf[IRCBUF] = "";
04333 char totbuf[IRCBUF] = "";
04334 RegNickList *regnick;
04335 int mode = 1;
04336 flag_t setflags, thisflag;
04337 u_int i, j, x;
04338
04339 if (isOper(nick) && (numargs < 2)) {
04340 sSend(":%s NOTICE %s :\2Your flag status\2:", OperServ, from);
04341 for (i = 0; opflags[i].symbol; i++) {
04342 if (opflags[i].symbol == 'A' || opflags[i].symbol == '*')
04343 continue;
04344 j = opFlagged(nick, opflags[i].flag);
04345 sSend(":%s NOTICE %s :%c (%-15s) : %s", OperServ, from,
04346 opflags[i].symbol, opflags[i].name, j ? "YES" : "NO ");
04347 }
04348 if (addFlood(nick, 15))
04349 return RET_KILLED;
04350 return RET_OK;
04351 }
04352
04353 if (addFlood(nick, 1))
04354 return RET_KILLED;
04355 if (!opFlagged(nick, OOPER)) {
04356 sSend
04357 (":%s NOTICE %s :You must be an IRC Operator to use this command.",
04358 OperServ, from);
04359 return RET_NOPERM;
04360 }
04361
04362 if (numargs < 2) {
04363 sSend(":%s NOTICE %s :You must specify a nick.", OperServ, from);
04364 return RET_SYNTAX;
04365 } else if (!strcasecmp(args[1], "list")) {
04366 OperList *oper;
04367
04368 for (oper = firstOper; oper; oper = oper->next)
04369 if (oper->who) {
04370 for (x = 0, j = 0; opflags[j].symbol; j++)
04371 if ((oper->who->opflags & opflags[j].flag)) {
04372 if (opflags[j].symbol == '*')
04373 continue;
04374 if (!x)
04375 modebuf[x++] = '+';
04376 modebuf[x++] = opflags[j].symbol;
04377 }
04378 modebuf[x++] = '\0';
04379 if (!(oper->who->opflags & OROOT))
04380 sSend(":%s NOTICE %s :%-17s (\37%-20s\37)", OperServ,
04381 from, oper->who->nick, modebuf);
04382 else
04383 sSend
04384 (":%s NOTICE %s :%-17s (\2Root \2)",
04385 OperServ, from, oper->who->nick);
04386 }
04387 return RET_OK;
04388 } else if (!strcasecmp(args[1], "add")) {
04389 if (opFlagged(nick, OSETOP | OOPER) == 0) {
04390 PutReply(OperServ, nick, ERR_NOACCESS, 0, 0, 0);
04391 return RET_NOPERM;
04392 }
04393 if (numargs < 3) {
04394 sSend(":%s NOTICE %s :Add opflags to what nick?", OperServ,
04395 from);
04396 return RET_NOPERM;
04397 }
04398 if (!(regnick = getRegNickData(args[2]))) {
04399 sSend(":%s NOTICE %s :The nick %s is not registered.",
04400 OperServ, from, args[2]);
04401 return RET_EFAULT;
04402 }
04403 if (regnick->opflags) {
04404 sSend(":%s NOTICE %s :%s already has opflags.", NickServ, from,
04405 args[2]);
04406 return RET_FAIL;
04407 }
04408 regnick->opflags |= OPFLAG_DEFAULT;
04409 addOpData(regnick);
04410 return RET_OK_DB;
04411 } else if (!strcasecmp(args[1], "del")) {
04412 if (opFlagged(nick, OSETOP | OOPER) == 0) {
04413 PutReply(OperServ, nick, ERR_NOACCESS, 0, 0, 0);
04414 return RET_NOPERM;
04415 }
04416 if (numargs < 3) {
04417 sSend(":%s NOTICE %s :Del opflags from what nick?", OperServ,
04418 from);
04419 return RET_SYNTAX;
04420 }
04421 if (!(regnick = getRegNickData(args[2]))) {
04422 sSend(":%s NOTICE %s :The nick %s is not registered.",
04423 OperServ, from, args[2]);
04424 return RET_EFAULT;
04425 }
04426 if (!regnick->opflags) {
04427 sSend(":%s NOTICE %s :%s has no opflags.", OperServ, from,
04428 args[2]);
04429 return RET_EFAULT;
04430 }
04431 if ((regnick->opflags & (OROOT | OREMROOT))
04432 || ((regnick->opflags & (OPFLAG_ROOTSET))
04433 && !opFlagged(nick, OOPER | OROOT))) {
04434 sSend
04435 (":%s NOTICE %s :%s holds one or more flags that you cannot remove.",
04436 NickServ, from, args[2]);
04437 return RET_EFAULT;
04438 }
04439 regnick->opflags = 0;
04440 delOpData(regnick);
04441 return RET_OK_DB;
04442 }
04443
04444 if (!(regnick = getRegNickData(args[1]))) {
04445 sSend(":%s NOTICE %s :%s is not registered", OperServ, from,
04446 args[1]);
04447 return RET_EFAULT;
04448 }
04449
04450 if (numargs < 3) {
04451 for (x = 0, j = 0; opflags[j].symbol; j++)
04452 if ((regnick->opflags & opflags[j].flag)) {
04453 if (opflags[j].symbol == '*')
04454 continue;
04455 if (!x)
04456 modebuf[x++] = '+';
04457 modebuf[x++] = opflags[j].symbol;
04458 }
04459 modebuf[x++] = '\0';
04460 sSend(":%s NOTICE %s :Current opflags of user %s are %s.",
04461 OperServ, from, args[1], modebuf);
04462 return RET_OK;
04463 }
04464
04465 if (!opFlagged(nick, OSETOP | OOPER)) {
04466 PutReply(OperServ, nick, ERR_NOACCESS, 0, 0, 0);
04467 return RET_NOPERM;
04468 }
04469
04470 if (!opFlagged(nick, OOPER | OROOT)
04471 && (regnick->opflags & (OROOT | OPROT))) {
04472 sSend(":%s NOTICE %s :You cannot alter the opflags of %s.",
04473 OperServ, from, args[1]);
04474 return RET_NOPERM;
04475 }
04476
04477 setflags = regnick->opflags;
04478
04479 for (i = 0; args[2] && args[2][i]; i++) {
04480 switch (args[2][i]) {
04481 case '+':
04482 mode = 1;
04483 break;
04484 case '-':
04485 mode = 0;
04486 break;
04487 default:
04488 for (j = 0; opflags[j].symbol; j++)
04489 if (opflags[j].symbol == args[2][i]) {
04490 thisflag = opflags[j].flag;
04491
04492 if (mode) {
04493 if (thisflag & OADMIN)
04494 thisflag |= OPFLAG_ADMIN;
04495 if (thisflag & OOPER)
04496 thisflag |= OPFLAG_DEFAULT;
04497 thisflag &= ~OADMIN;
04498 if (mode && (thisflag & OSERVOP))
04499 sSend
04500 (":%s NOTICE %s :Note: the servop opflag is deprecate.",
04501 OperServ, from);
04502 }
04503
04504
04505 if (!isRoot(nick)
04506 && (OPFLAG_ROOTSET & opflags[j].flag)) {
04507 sSend
04508 (":%s NOTICE %s :Setting the flag '%c' requires root access.",
04509 OperServ, from,
04510 opflags[j].symbol ? opflags[j].symbol : ' ');
04511 continue;
04512 }
04513 if (opflags[j].flag & (OROOT | OREMROOT)) {
04514 sSend
04515 (":%s NOTICE %s :SETOP cannot change this flag.",
04516 OperServ, from);
04517 continue;
04518 }
04519 if (mode)
04520 regnick->opflags |= thisflag;
04521 else
04522 regnick->opflags &= ~thisflag;
04523 }
04524 break;
04525 }
04526 }
04527 for (x = 0, j = 0; opflags[j].symbol; j++)
04528 if (!(setflags & opflags[j].flag) &&
04529 (regnick->opflags & opflags[j].flag)) {
04530 if (opflags[j].symbol == '*')
04531 continue;
04532 if (!x)
04533 modebuf[x++] = '+';
04534 modebuf[x++] = opflags[j].symbol;
04535 }
04536 for (mode = 0, j = 0; opflags[j].symbol; j++)
04537 if ((setflags & opflags[j].flag) &&
04538 !(regnick->opflags & opflags[j].flag)) {
04539 if (opflags[j].symbol == '*')
04540 continue;
04541 if (!mode) {
04542 modebuf[x++] = '-';
04543 mode++;
04544 }
04545 modebuf[x++] = opflags[j].symbol;
04546 }
04547 modebuf[x++] = '\0';
04548 for (x = 0, j = 0; opflags[j].symbol; j++)
04549 if ((regnick->opflags & opflags[j].flag)) {
04550 if (opflags[j].symbol == '*')
04551 continue;
04552 if (!x)
04553 totbuf[x++] = '+';
04554 totbuf[x++] = opflags[j].symbol;
04555 }
04556 totbuf[x++] = '\0';
04557 if (*modebuf && nick->reg && nick->reg != regnick)
04558 sSend(":%s GLOBOPS :%s set opflags %s on user %s.", OperServ, from,
04559 modebuf, regnick->nick);
04560 operlog->log(nick, NS_SETOP, regnick->nick, 0, "%s (%s)", modebuf,
04561 totbuf);
04562 sSend(":%s NOTICE %s :Opflags for user \2%s\2 are now \2%s\2.",
04563 OperServ, from, regnick->nick, totbuf);
04564 if (regnick->opflags && !setflags)
04565 addOpData(regnick);
04566 else if (setflags && !regnick->opflags)
04567 delOpData(regnick);
04568 return RET_OK_DB;
04569 }
04570
04571
04572
04573
04586 NCMD(ns_mark)
04587 {
04588 char *from = nick->nick;
04589 RegNickList *target;
04590
04591 if (isServop(nick) == 0) {
04592 PutReply(NickServ, nick, ERR_NOACCESS, 0, 0, 0);
04593 return RET_NOPERM;
04594 }
04595
04596 if (numargs < 2) {
04597 sSend(":%s NOTICE %s :Must supply at least one argument",
04598 NickServ, from);
04599 return RET_SYNTAX;
04600 }
04601
04602 target = getRegNickData(args[1]);
04603 if (target == NULL) {
04604 sSend(":%s NOTICE %s :Nick not found", NickServ, from);
04605 return RET_EFAULT;
04606 }
04607 if (numargs < 3) {
04608 if (!target->markby)
04609 sSend(":%s NOTICE %s :%s is \2%s\2.", NickServ, from, args[1],
04610 target->flags & NMARK ? "Marked" : "Not Marked");
04611 else if (target->flags & NMARK)
04612 sSend(":%s NOTICE %s :%s was \2%s\2 by %s.", NickServ, from,
04613 args[1], target->flags & NMARK ? "Marked" : "Not Marked",
04614 target->markby);
04615 return RET_OK;
04616 }
04617 if (!strcasecmp(args[2], "on") || !strcasecmp(args[2], "yes")) {
04618 if (target->flags & NMARK) {
04619 sSend(":%s NOTICE %s :%s is already marked%s%s.", NickServ,
04620 from, args[1], target->markby ? " by " : "",
04621 target->markby ? target->markby : "");
04622 return RET_OK;
04623 }
04624 sSend(":%s NOTICE %s :%s is now \2Marked\2.", NickServ, from,
04625 args[1]);
04626 target->flags |= NMARK;
04627 if (target->markby)
04628 FREE(target->markby);
04629 target->markby = strdup(nick->nick);
04630 nicklog->log(nick, NS_MARK, target->nick, LOGF_ON);
04631 return RET_OK_DB;
04632 } else if (!strcasecmp(args[2], "off") || !strcasecmp(args[2], "no")) {
04633 sSend(":%s NOTICE %s :%s is now \2Unmarked\2.", NickServ, from,
04634 args[1]);
04635 target->flags &= ~NMARK;
04636 if (target->markby)
04637 FREE(target->markby);
04638 target->markby = NULL;
04639 nicklog->log(nick, NS_MARK, target->nick, LOGF_OFF);
04640 return RET_OK_DB;
04641 } else {
04642 sSend(":%s NOTICE %s :Unrecognized usage.", NickServ, from);
04643 sSend(":%s NOTICE %s :MARK <nick> <on|off>", NickServ, from);
04644 return RET_OK;
04645 }
04646 return RET_FAIL;
04647 }
04648
04649
04650
04651
04657 NCMD(ns_setflags)
04658 {
04659 char *from = nick->nick;
04660 RegNickList *regnick;
04661 int mode = 1;
04662 u_int i;
04663
04664 if (addFlood(nick, 1))
04665 return RET_KILLED;
04666
04667 if (opFlagged(nick, OOPER | OSETFLAG) == 0 && isRoot(nick) == 0) {
04668 PutReply(NickServ, nick, ERR_NOACCESS, 0, 0, 0);
04669 return RET_NOPERM;
04670 }
04671
04672 else if (numargs < 3) {
04673 sSend(":%s NOTICE %s :You must specify at least 2"
04674 " parameters after setflags", NickServ, from);
04675 return RET_SYNTAX;
04676 }
04677
04678 regnick = getRegNickData(args[1]);
04679 if (regnick == NULL) {
04680 sSend(":%s NOTICE %s :%s is not registered",
04681 NickServ, from, args[1]);
04682 return RET_EFAULT;
04683 }
04684 if (isRoot(nick) == 0 && (regnick->opflags & OROOT)) {
04685 sSend
04686 (":%s NOTICE %s :Permission denied -- in altering flags of %s.",
04687 NickServ, from, args[1]);
04688 return RET_NOPERM;
04689 }
04690
04691 sSend(":%s NOTICE %s :Flags for %s are now %s",
04692 NickServ, from, args[1], args[2]);
04693 sSend(":%s GLOBOPS :%s set mode %s on %s",
04694 myname, from, args[2], args[1]);
04695 operlog->log(nick, NS_SETFLAG, args[1], 0, "%s", args[2]);
04696
04697 for (i = 0; i < strlen(args[2]); i++) {
04698 switch (args[2][i]) {
04699 case '+':
04700 mode = 1;
04701 break;
04702 case '-':
04703 mode = 0;
04704 break;
04705 case 'k':
04706 if (mode)
04707 regnick->flags |= NKILL;
04708 else
04709 regnick->flags &= ~NKILL;
04710 break;
04711 case 'v':
04712 if (mode)
04713 regnick->flags |= NVACATION;
04714 else
04715 regnick->flags &= ~NVACATION;
04716 break;
04717 case 'f':
04718 if (mode && !(regnick->opflags & OROOT))
04719 regnick->flags |= NFORCEXFER;
04720 else
04721 regnick->flags &= ~NFORCEXFER;
04722 break;
04723 case 'e':
04724 if (mode)
04725 regnick->flags |= NEMAIL;
04726 else
04727 regnick->flags &= ~NEMAIL;
04728 case 'h':
04729 if (isRoot(nick) == 0)
04730 sSend(":%s NOTICE %s :You cannot set the 'h' flag",
04731 NickServ, from);
04732 else if (mode)
04733 regnick->flags |= NHOLD;
04734 else
04735 regnick->flags &= ~NHOLD;
04736 break;
04737 case 'b':
04738 if (mode)
04739 regnick->flags |= NBANISH;
04740 else
04741 regnick->flags &= ~NBANISH;
04742 break;
04743 case 'g':
04744 if (isRoot(nick) == 0)
04745 sSend(":%s NOTICE %s :You cannot set the 'g' flag",
04746 NickServ, from);
04747 else if (mode)
04748 regnick->opflags |= OGRP;
04749 else
04750 regnick->opflags &= ~OGRP;
04751 break;
04752 case 's':
04753 if (isRoot(nick) == 0)
04754 sSend(":%s NOTICE %s :You cannot set the 's' flag",
04755 NickServ, from);
04756 else if (mode)
04757 regnick->opflags |= OSERVOP;
04758 else
04759 regnick->opflags &= ~OSERVOP;
04760 break;
04761 case 'B':
04762 if (opFlagged(nick, OAKILL) == 0)
04763 sSend(":%s NOTICE %s :You cannot set the 'o' flag",
04764 NickServ, from);
04765 else if (mode)
04766 regnick->flags |= NBYPASS;
04767 else
04768 regnick->flags &= ~NBYPASS;
04769 break;
04770 default:
04771 sSend(":%s NOTICE %s :Unknown mode flag: %c", NickServ, from,
04772 args[2][i]);
04773 break;
04774 }
04775 }
04776 return RET_OK_DB;
04777 }
04778
04784 NCMD(ns_banish)
04785 {
04786
04787 char *from = nick->nick;
04788 char buf[IRCBUF];
04789 RegNickList *bannick;
04790
04791 if (addFlood(nick, 1))
04792 return RET_KILLED;
04793
04794 if (opFlagged(nick, OOPER | ONBANDEL) == 0) {
04795 PutReply(NickServ, nick, ERR_NOACCESS, 0, 0, 0);
04796 return RET_NOPERM;
04797 }
04798
04799 if (numargs < 2) {
04800 sSend
04801 (":%s NOTICE %s :You must specify an argument after the banish command",
04802 NickServ, from);
04803 return RET_SYNTAX;
04804 }
04805
04806 bannick = getRegNickData(args[1]);
04807
04808 if (bannick == NULL) {
04809 bannick = (RegNickList *) oalloc(sizeof(RegNickList));
04810 strncpyzt(bannick->nick, args[1], NICKLEN);
04811 bannick->regnum.SetNext(top_regnick_idnum);
04812
04813 addRegNick(bannick);
04814 } else if (isRoot(nick) == 0 && (bannick->opflags & OROOT)) {
04815 sSend(":%s NOTICE %s :Permission denied.", NickServ, from);
04816 return RET_NOPERM;
04817 }
04818
04819 strncpyzt(bannick->nick, args[1], NICKLEN);
04820
04821 strcpy(bannick->user, "banished");
04822
04823 snprintf(buf, HOSTLEN, "nicks.%s", NETWORK);
04824 SetDynBuffer(&bannick->host, buf);
04825
04826 snprintf(bannick->email, EMAILLEN, "nickserv@%s", NETWORK);
04827
04828 snprintf(buf, URLLEN, "http://www.%s", NETWORK);
04829 SetDynBuffer(&bannick->url, buf);
04830
04831 memset(bannick->password, 0, PASSLEN);
04832 bannick->amasks = 0;
04833 bannick->timereg = 0;
04834 bannick->timestamp = 0;
04835 bannick->flags = 0;
04836 bannick->flags |= NBANISH|NENCRYPT;
04837
04838
04839
04840
04841 while (LIST_FIRST(&bannick->acl))
04842 LIST_REMOVE(LIST_FIRST(&bannick->acl), al_lst);
04843
04844 sSend(":%s GNOTICE :%s Banished nick %s", myname, from, args[1]);
04845 operlog->log(nick, NS_BANISH, args[1]);
04846 return RET_OK_DB;
04847 }
04848
04849 #ifdef REQ_EMAIL
04850 NCMD(ns_getkey)
04851 {
04852 char *from = nick->nick;
04853 RegNickList *regnick;
04854
04855 if(addFlood(nick,5))
04856 return;
04857
04858 if (numargs<2) {
04859 sSend(":%s NOTICE %s :You must specify a nick to getkey", NickServ, from);
04860 return;
04861 }
04862
04863 if (!isRoot(nick)) {
04864 sSend(":%s NOTICE %s :Access denied", NickServ, from);
04865 return;
04866 }
04867
04868 regnick=getRegNickData(args[1]);
04869
04870 if(!regnick || !(regnick->flags & NREG))
04871 sSend(":%s NOTICE %s :Nick %s is not registered", NickServ, from, args[1]);
04872 else {
04873 sSend(":%s NOTICE %s :The activation code for %s is %lu", NickServ, from, regnick->nick, regnick->email_key);
04874 sSend(":%s GNOTICE :%s used getkey on %s", myname, from, args[1]);
04875 }
04876 return;
04877 }
04878 #endif
04879
04884 NCMD(ns_getrealpass)
04885 {
04886 char *from = nick->nick;
04887 RegNickList *targetNick;
04888
04889 if (addFlood(nick, 5))
04890 return RET_KILLED;
04891
04892 if (numargs < 2) {
04893 sSend(":%s NOTICE %s :You must specify a nick to getrealpass",
04894 NickServ, from);
04895 return RET_SYNTAX;
04896 }
04897 #ifdef ENABLE_GRPOPS
04898 if (isRoot(nick) == 0 && isGRPop(nick) == 0)
04899 #else
04900 if (isRoot(nick) == 0)
04901 #endif
04902 {
04903 PutReply(NickServ, nick, ERR_NOACCESS, 0, 0, 0);
04904 return RET_NOPERM;
04905 }
04906
04907 sSend(":%s NOTICE %s :Warning -- this command is deprecated.",
04908 NickServ, from);
04909
04910 targetNick = getRegNickData(args[1]);
04911
04912 if (targetNick == NULL)
04913 sSend(":%s NOTICE %s :Nick %s is not registered", NickServ, from,
04914 args[1]);
04915 else if (targetNick->flags & NMARK) {
04916 if (targetNick->markby)
04917 sSend
04918 (":%s NOTICE %s :\2Important Note:\2 %s has been marked by %s -- you need to contact the setter before retrieving the password for the nick in question.",
04919 NickServ, from, targetNick->nick, targetNick->markby);
04920 else
04921 sSend(":%s NOTICE %s :\2Important Note:\2 %s has been marked.",
04922 NickServ, from, targetNick->nick);
04923 return RET_OK;
04924 }
04925 else if (!opFlagged(nick, OROOT | OVERRIDE)
04926 && (targetNick->flags & NOSENDPASS)) {
04927 sSend
04928 (":%s NOTICE %s :Nick %s has enabled the \2NOPWSEND\2 option.",
04929 NickServ, from, args[1]);
04930 return RET_EFAULT;
04931 }
04932 else if ((!isRoot(nick) && (targetNick->opflags & OROOT))
04933 || (!isServop(nick) && (targetNick->opflags & OSERVOP))) {
04934 sSend
04935 (":%s NOTICE %s :Permission denied -- a GRPop may not GRP a user with root or servop privileges.",
04936 NickServ, from);
04937 sSend(":%s GLOBOPS :%s!%s@%s tries to getrealpass \2%s\2.",
04938 NickServ, from, nick->user, nick->host, args[1]);
04939 operlog->log(nick, NS_GETREALPASS, args[1], RET_FAIL);
04940 return RET_NOPERM;
04941 } else {
04942 if (!(targetNick->flags & NENCRYPT))
04943 sSend(":%s NOTICE %s :The password for %s is %s", NickServ, from,
04944 targetNick->nick, targetNick->password);
04945 else {
04946 u_char *p;
04947
04948 sSend(":%s NOTICE %s :The password for %s is encrypted: %s", NickServ, from,
04949 targetNick->nick, md5_printable(targetNick->password));
04950 p = toBase64(targetNick->password, 16);
04951 if (p != NULL) {
04952 sSend(":%s NOTICE %s :In Base64 format that is: $%s", NickServ, from,
04953 p);
04954 FREE(p);
04955 }
04956 }
04957 sSend(":%s GLOBOPS :%s used getrealpass on %s", myname, from,
04958 args[1]);
04959 operlog->log(nick, NS_GETREALPASS, args[1], 0);
04960 }
04961 return RET_OK;
04962 }
04963
04971 NCMD(ns_getpass)
04972 {
04973 char buf[MAXBUF];
04974 char *from = nick->nick;
04975 RegNickList *targetNick;
04976 EmailMessage *email;
04977 const char *pwAuthKey;
04978 time_t doot = time(NULL);
04979 int key_new, key_resend, key_transfer, i, nick_arg = 1;
04980
04981 key_new = key_resend = key_transfer = 0;
04982 srand48(time(NULL));
04983
04984 if (addFlood(nick, 5))
04985 return RET_KILLED;
04986
04987 if ((isOper(nick) == 0) && (isHelpop(nick) == 0)) {
04988 PutReply(NickServ, nick, ERR_NOACCESS, 0, 0, 0);
04989 return RET_NOPERM;
04990 }
04991
04992 if (numargs < 2) {
04993 sSend(":%s NOTICE %s :You must specify a nick to getpass",
04994 NickServ, from);
04995 return RET_SYNTAX;
04996 }
04997
04998 if (numargs >= 3) {
04999 for(i = 2; i < numargs; i++)
05000 {
05001 if (*args[i] == '-')
05002 {
05003 if (!strcmp(args[i], "-new") && isOper(nick))
05004 key_new = 1;
05005 else if (!strcmp(args[i], "-resend"))
05006 key_resend = 1;
05007 else if (opFlagged(nick, OGRP) && !strcmp(args[i], "-transfer"))
05008 key_transfer = 1;
05009 else if (args[i][1] == '-') {
05010 break;
05011 }
05012 else
05013 continue;
05014 }
05015 else {
05016 break;
05017 }
05018 }
05019 }
05020
05021 targetNick = getRegNickData(args[nick_arg]);
05022
05023 if (targetNick == NULL) {
05024 sSend(":%s NOTICE %s :Nick %s is not registered", NickServ, from,
05025 args[nick_arg]);
05026 return RET_EFAULT;
05027 }
05028 if (!key_transfer && (strncmp(targetNick->email, "(none)", 6) == 0
05029 || targetNick->email[0] == 0)) {
05030 sSend(":%s NOTICE %s :Nick %s has not specified an e-mail address",
05031 NickServ, from, args[nick_arg]);
05032 return RET_EFAULT;
05033 }
05034 else if (!opFlagged(nick, OVERRIDE) && !key_transfer
05035 && (targetNick->flags & NOSENDPASS)) {
05036 sSend
05037 (":%s NOTICE %s :Warning: nick %s has enabled the \2NOPWSEND\2 option.",
05038 NickServ, from, args[nick_arg]);
05039 return RET_EFAULT;
05040 } else if (targetNick->chpw_key && !key_new && !key_resend) {
05041 sSend(":%s NOTICE %s :That nickname has already had a change "
05042 "key sent out. Please specify -new or -resend.",
05043 NickServ, from);
05044 } else if ((key_transfer || (targetNick->flags & NFORCEXFER)) && (!(targetNick->opflags & OROOT))) {
05045 if (!targetNick->chpw_key || !(targetNick->flags & NFORCEXFER))
05046 {
05047 targetNick->chpw_key = (u_int32_t)(lrand48());
05048 if (!targetNick->chpw_key)
05049 targetNick->chpw_key = 1;
05050 }
05051
05052 pwAuthKey = GetAuthChKey("-forced-transfer-",
05053 PrintPass(targetNick->password, NickGetEnc(targetNick)),
05054 targetNick->timereg,
05055 targetNick->chpw_key);
05056
05057 if (key_transfer)
05058 sSend(":%s GLOBOPS :%s used sendpass (transfer) on %s",
05059 ChanServ, from, args[nick_arg]);
05060 else
05061 sSend(":%s GLOBOPS :%s used sendpass (getkey) on %s",
05062 ChanServ, from, args[nick_arg]);
05063 sSend(":%s NOTICE %s :Transfer key for %s is %s",
05064 ChanServ, from, args[nick_arg], pwAuthKey);
05065 targetNick->flags |= NFORCEXFER;
05066 operlog->log(nick, NSS_GETPASS_XFER, args[nick_arg]);
05067 } else if ((targetNick->flags & NFORCEXFER) && targetNick->chpw_key && !opFlagged(nick, OGRP | OOPER | OVERRIDE)) {
05068 sSend(":%s NOTICE %s :This nick's pw key is marked for ``nick transfer''",
05069 NickServ, from);
05070 } else {
05071 email = new EmailMessage;
05072
05073 if (!email) {
05074 sSend(":%s WALLOPS :Fatal error: ns_sendpass: out of memory",
05075 NickServ);
05076 sSend(":%s NOTICE %s :Fatal error: ns_sendpass: out of memory",
05077 NickServ, from);
05078 abort();
05079 return RET_EFAULT;
05080 }
05081
05082 if (key_new || !key_resend || !targetNick->chpw_key) {
05083 targetNick->chpw_key = (u_int32_t)(lrand48());
05084 if (!targetNick->chpw_key)
05085 targetNick->chpw_key = 1;
05086 }
05087
05088 pwAuthKey = GetAuthChKey(targetNick->email,
05089 PrintPass(targetNick->password, NickGetEnc(targetNick)),
05090 targetNick->timereg,
05091 targetNick->chpw_key);
05092
05093 sSend(":%s GNOTICE :%s used sendpass%s on %s", myname, from,
05094 key_resend ? " (resend)" : "", args[nick_arg]);
05095 if (isOper(nick) == 0)
05096 sSend
05097 (":%s NOTICE %s :The \2password change key\2 has been sent to the email address: (hidden)",
05098 NickServ, from);
05099 else
05100 sSend
05101 (":%s NOTICE %s :The \2password change key\2 has been sent to the email address: %s",
05102 NickServ, from, targetNick->email);
05103 sprintf(buf, "%s Password Recovery <%s@%s>", NickServ, NickServ,
05104 NETWORK);
05105 email->from = buf;
05106 email->to = targetNick->email;
05107 email->subject = "Password recovery";
05108
05109 sprintf(buf, "\nThe password change key for %s is %s\n", targetNick->nick,
05110 pwAuthKey);
05111 email->body = buf;
05112
05113 email->body += "This key can be used to set a new password "
05114 "for your nickname.\n";
05115 email->body += "\n";
05116 sprintf(buf, "On IRC, use: /NickServ SETPASS %s %s <password>\n",
05117 targetNick->nick, pwAuthKey);
05118 email->body += buf;
05119 email->body += "Or navigate to: "
05120 "http://astral.sorcery.net/~sortest/setpass.php?u_nick=";
05121 email->body += urlEncode(targetNick->nick);
05122 email->body += "&u_ck=";
05123 email->body += urlEncode(pwAuthKey);
05124 email->body += "\nTo choose your new password.\n\n";
05125
05126 sprintf(buf, "This key was recovered by %s at %s\n",
05127 nick->nick, ctime(&(doot)));
05128 email->body += buf;
05129
05130 email->send();
05131 email->reset();
05132 delete email;
05133
05134 operlog->log(nick, NS_GETPASS, args[nick_arg]);
05135 }
05136 return RET_OK_DB;
05137 }
05138
05143 NCMD(ns_delete)
05144 {
05145 char *from = nick->nick;
05146 RegNickList *targetNick;
05147
05148 if (opFlagged(nick, OOPER | ONBANDEL) == 0) {
05149 PutReply(NickServ, nick, ERR_NOACCESS, 0, 0, 0);
05150 return RET_NOPERM;
05151 }
05152
05153 if (numargs < 2) {
05154 sSend(":%s NOTICE %s :You must specify a nick", NickServ, from);
05155 return RET_SYNTAX;
05156 }
05157
05158 targetNick = getRegNickData(args[1]);
05159 if (targetNick == NULL) {
05160 sSend(":%s NOTICE %s :Nickname %s is not registered",
05161 NickServ, from, args[1]);
05162 return RET_EFAULT;
05163 }
05164
05165 if (isRoot(nick) == 0 && (targetNick->opflags & OROOT)) {
05166 sSend(":%s NOTICE %s :Permission denied.", NickServ, from);
05167 return RET_NOPERM;
05168 }
05169
05170 delRegNick(targetNick);
05171 sSend(":%s NOTICE %s :This nick has been deleted by %s."
05172 " To enable you to use this nick, you will need to "
05173 "change nicknames and then change back",
05174 NickServ, args[1], from);
05175
05176 sSend(":%s NOTICE %s :Deleted nick %s", NickServ, from, args[1]);
05177 sSend(":%s GLOBOPS :%s deleted nick %s", myname, from, args[1]);
05178
05179 return RET_OK_DB;
05180 }
05181
05183
05184 NCMD(ns_save)
05185 {
05186 char *from = nick->nick;
05187
05188 if (isRoot(nick) == 0) {
05189 PutReply(NickServ, nick, ERR_NOACCESS, 0, 0, 0);
05190 return RET_NOPERM;
05191 }
05192 #ifdef GLOBOP_ON_SAVE
05193 sSend(":%s GLOBOPS :Saving database. (%s)", NickServ, from);
05194 #else
05195 sSend(":%s PRIVMSG " LOGCHAN " :Saving database. (%s)", NickServ,
05196 from);
05197 #endif
05198 saveNickData();
05199 return RET_OK_DB;
05200 }
05201
05206 NCMD(ns_list)
05207 {
05208 char *from = nick->nick;
05209 RegNickList *reg;
05210 MaskData *umask;
05211 int i = 0, x = 0, bucket = 0;
05212
05213 if (opFlagged(nick, OLIST) == 0) {
05214 PutReply(NickServ, nick, ERR_NOACCESS, 0, 0, 0);
05215 return RET_NOPERM;
05216 }
05217
05218 if (numargs != 2) {
05219 sSend(":%s NOTICE %s :You must specify ONE address to search by",
05220 NickServ, from);
05221 return RET_SYNTAX;
05222 }
05223
05224 umask = make_mask();
05225
05226 if (split_userhost(args[1], umask) < 0) {
05227 free_mask(umask);
05228
05229 sSend(":%s NOTICE %s :Unable to read mask.", NickServ, from);
05230 return RET_SYNTAX;
05231 }
05232
05233 if (!strcmp(umask->nick, "*") && !strcmp(umask->user, "*")
05234 && !strcmp(umask->host, "*")) {
05235 sSend(":%s NOTICE %s :Invalid mask *!*@*.", NickServ, from);
05236 free_mask(umask);
05237 return RET_EFAULT;
05238 }
05239
05240 for (bucket = 0; bucket < NICKHASHSIZE; bucket++) {
05241 reg = LIST_FIRST(&RegNickHash[bucket]);
05242
05243 while (reg != NULL) {
05244 if (!match(umask->nick, reg->nick)
05245 && !match(umask->user, reg->user)
05246 && !match(umask->host, reg->host)) {
05247 i++;
05248 if (i <= 200)
05249 sSend(":%s NOTICE %s :%4i: %s!%s@%s",
05250 NickServ, from, i, reg->nick,
05251 reg->user, reg->host);
05252 }
05253
05254 reg = LIST_NEXT(reg, rn_lst);
05255 x++;
05256 }
05257 }
05258 if (i > 200)
05259 sSend(":%s NOTICE %s :[Results truncated to 200 items]",
05260 NickServ, from);
05261 sSend(":%s NOTICE %s :%i/%i matched conditions (%s!%s@%s)",
05262 NickServ, from, i, x, umask->nick, umask->user, umask->host);
05263 sSend(":%s GLOBOPS :%s is listing %s!%s@%s (%d/%d matches)",
05264 NickServ, from, umask->nick, umask->user, umask->host, i, x);
05265 free_mask(umask);
05266
05267 return RET_OK;
05268 }
05269
05275 NCMD(ns_bypass)
05276 {
05277 RegNickList *targetnick;
05278 char *from;
05279 HashKeyVal hashEnt;
05280
05281 if (!nick || !(from = nick->nick))
05282 return RET_FAIL;
05283
05284 if (!opFlagged(nick, OAKILL) && !opFlagged(nick, OAHURT)) {
05285 sSend
05286 (":%s NOTICE %s :You do not have the necessary flags to use this"
05287 " command", NickServ, from);
05288 return RET_NOPERM;
05289 }
05290
05291 if (numargs < 2) {
05292 sSend(":%s NOTICE %s :Syntax: /msg %s BYPASS <nick> [<on|off>]",
05293 NickServ, from, NickServ);
05294 return RET_SYNTAX;
05295 }
05296
05297 if (isServop(nick) && !strcasecmp("allon", args[1])) {
05298 char mask[IRCBUF + 2] = "";
05299
05300 if ((numargs <= 2) && !opFlagged(nick, OROOT | OVERRIDE) ) {
05301 sSend(":%s NOTICE %s :Syntax error, mask required.",
05302 OperServ, from);
05303 sSend(":%s NOTICE %s :Must use /os override "
05304 "to set bypass for all nicks in db.",
05305 OperServ, from);
05306 return RET_NOPERM;
05307 }
05308
05309 if (numargs > 2)
05310 {
05311 if (!match(args[2], "...!..@...com")
05312 || !match(args[2], "...!..@...net")
05313 || !match(args[2], "...!..@...edu")
05314 || !match(args[2], "...!..@...org")
05315 || !match(args[2], "...!..@...my")
05316 || !match(args[2], "...!..@...uk"))
05317 {
05318 sSend(":%s NOTICE %s :That %s is too broad.", OperServ,
05319 from, "bypass mask");
05320 sSend(":%s GLOBOPS :%s attempts to set %s for %s", OperServ,
05321 from, "bypass_allon", args[2]);
05322 return RET_NOPERM;
05323 }
05324 nicklog->log(nick, NS_BYPASS, args[2], LOGF_ON | LOGF_PATTERN);
05325 }
05326 else {
05327 nicklog->log(nick, NS_BYPASS, "*!*@*", LOGF_ON | LOGF_PATTERN);
05328 }
05329
05330 for (hashEnt = 0; hashEnt < NICKHASHSIZE; hashEnt++) {
05331 for (targetnick = LIST_FIRST(&RegNickHash[hashEnt]);
05332 targetnick; targetnick = LIST_NEXT(targetnick, rn_lst)) {
05333 if (numargs >= 3) {
05334 snprintf(mask, IRCBUF, "%s!%s@%s", targetnick->nick,
05335 targetnick->user, targetnick->host);
05336 if ((numargs > 2)
05337 && match(args[2], mask))
05338 continue;
05339 }
05340 targetnick->flags |= NBYPASS;
05341 sSend(":%s NOTICE %s :%s", NickServ, from,
05342 targetnick->nick);
05343 }
05344 }
05345 sSend(":%s NOTICE %s :End of list", NickServ, from);
05346 return RET_OK_DB;
05347 }
05348
05349 if (isRoot(nick) && !strcasecmp("alloff", args[1])) {
05350 char mask[IRCBUF + 2] = "";
05351
05352 if ((numargs <= 2) && !opFlagged(nick, OROOT | OVERRIDE) ) {
05353 sSend(":%s NOTICE %s :Syntax error, mask required.",
05354 OperServ, from);
05355 sSend(":%s NOTICE %s :Must use /os override "
05356 "to clear bypass for all nicks in db.",
05357 OperServ, from);
05358 return RET_NOPERM;
05359 }
05360
05361 if (numargs > 2)
05362 {
05363 if (!match(args[2], "...!..@...com")
05364 || !match(args[2], "...!..@...net")
05365 || !match(args[2], "...!..@...edu")
05366 || !match(args[2], "...!..@...org")
05367 || !match(args[2], "...!..@...my")
05368 || !match(args[2], "...!..@...uk"))
05369 {
05370 sSend(":%s NOTICE %s :That %s is too broad.", OperServ,
05371 from, "bypass mask");
05372 sSend(":%s GLOBOPS :%s attempts to set %s for %s", OperServ,
05373 from, "bypass_alloff", args[2]);
05374 return RET_NOPERM;
05375 }
05376 nicklog->log(nick, NS_BYPASS, args[2], LOGF_OFF | LOGF_PATTERN);
05377 }
05378 else {
05379 nicklog->log(nick, NS_BYPASS, "*!*@*", LOGF_OFF | LOGF_PATTERN);
05380 }
05381
05382 for (hashEnt = 0; hashEnt < NICKHASHSIZE; hashEnt++) {
05383 for (targetnick = LIST_FIRST(&RegNickHash[hashEnt]);
05384 targetnick; targetnick = LIST_NEXT(targetnick, rn_lst)) {
05385 if (numargs >= 3) {
05386 snprintf(mask, IRCBUF, "%s!%s@%s", targetnick->nick,
05387 targetnick->user, targetnick->host);
05388 if (match(args[2], mask))
05389 continue;
05390 }
05391 targetnick->flags &= ~NBYPASS;
05392 sSend(":%s NOTICE %s :%s", NickServ, from,
05393 targetnick->nick);
05394 }
05395 }
05396 sSend(":%s NOTICE %s :End of list", NickServ, from);
05397 return RET_OK_DB;
05398 }
05399
05400
05401 if (!strcasecmp("list", args[1])) {
05402 char mask[IRCBUF + 2] = "";
05403
05404 nicklog->log(nick, NS_BYPASS, args[2], LOGF_SCAN | LOGF_PATTERN,
05405 "LIST");
05406
05407 for (hashEnt = 0; hashEnt < NICKHASHSIZE; hashEnt++) {
05408 for (targetnick = LIST_FIRST(&RegNickHash[hashEnt]);
05409 targetnick; targetnick = LIST_NEXT(targetnick, rn_lst)) {
05410 if (numargs >= 3) {
05411 snprintf(mask, IRCBUF, "%s!%s@%s", targetnick->nick,
05412 targetnick->user, targetnick->host);
05413 if (match(args[2], mask))
05414 continue;
05415 }
05416 if (!(targetnick->flags & NBYPASS))
05417 continue;
05418 sSend(":%s NOTICE %s :%s", NickServ, from,
05419 targetnick->nick);
05420 }
05421 }
05422 sSend(":%s NOTICE %s :End of list", NickServ, from);
05423 return RET_OK;
05424 }
05425
05426 if (!(targetnick = getRegNickData(args[1]))) {
05427 sSend(":%s NOTICE %s :%s is not registered.",
05428 NickServ, from, args[1]);
05429 return RET_EFAULT;
05430 }
05431
05432 if (numargs < 3)
05433 sSend(":%s NOTICE %s :%s can%s bypass selective bans (autohurts).",
05434 NickServ, from, args[1],
05435 targetnick->flags & NBYPASS ? "" : "not");
05436 else {
05437 if (!strcasecmp(args[2], "on") || !strcasecmp(args[2], "yes")) {
05438 sSend
05439 (":%s NOTICE %s :%s is now a nick that can be used to bypass selective bans.",
05440 NickServ, from, args[1]);
05441 targetnick->flags |= NBYPASS;
05442 return RET_OK_DB;
05443 }
05444 else if (!strcasecmp(args[2], "off")
05445 || !strcasecmp(args[2], "no")) {
05446 sSend
05447 (":%s NOTICE %s :%s is no longer a nick that can be used to bypass selective bans.",
05448 NickServ, from, args[1]);
05449 targetnick->flags &= ~NBYPASS;
05450 return RET_OK_DB;
05451 } else {
05452 sSend
05453 (":%s NOTICE %s :Turn %s's selective ban bypass ability on or off?",
05454 NickServ, from, args[1]);
05455 return RET_OK;
05456 }
05457 }
05458 return RET_OK;
05459 }
05460
05466 NCMD(ns_logoff)
05467 {
05468 char *from = nick->nick;
05469
05470 clearIdentify(nick);
05471 if (nick->caccess > 2)
05472 nick->caccess = 2;
05473 sSend(":%s NOTICE %s :You are no longer identified with %s.", NickServ,
05474 from, NickServ);
05475 return RET_OK;
05476 }
05477
05478 #ifdef REQ_EMAIL
05479
05487 NCMD(ns_activate)
05488 {
05489 char *from = nick->nick;
05490
05491
05492 if (addFlood(nick, 5))
05493 return;
05494
05495 if(numargs < 2)
05496 {
05497 sSend(":%s NOTICE %s :A validation password is required with %s ACTIVATE", NickServ, from, NickServ);
05498 return;
05499 }
05500
05501 if(!nick->reg || (nick->reg->flags & NBANISH)) {
05502 sSend(":%s NOTICE %s :Your nick is not registered", NickServ, from);
05503 return;
05504 }
05505
05506 if(atoi(args[1]) != nick->reg->email_key) {
05507 sSend(":%s NOTICE %s :Incorrect activation key.", NickServ, from);
05508 return;
05509 }
05510
05511 if(strlen(args[2]) > PASSLEN) {
05512 sSend(":%s NOTICE %s :The password you specified is too long to use, please make it 15 characters or less.", NickServ, from);
05513 return;
05514 }
05515
05516 if ((nick->reg->flags & NACTIVE) &&
05517 !(nick->reg->flags & NDEACC))
05518 {
05519 sSend(":%s NOTICE %s :This nickname is already active.",
05520 NickServ, from);
05521 return;
05522 }
05523
05524 doot = time(NULL);
05525
05526 if (!(nick->reg->flags & NACTIVE))
05527 {
05528 nick->reg->flags |= NACTIVE;
05529 sSend(":%s NOTICE %s :Your nick %s is now activated.", NickServ, from, from);
05530 #ifdef
05531 sSend(":%s NOTICE %s :Your MemoServ memo box has been configured",
05532 NickServ, from);
05533 #endif
05534 }
05535 else
05536 {
05537 nick->reg->flags |= NACTIVE;
05538 nick->reg->flags &= ~NDEACC;
05539 sSend(":%s NOTICE %s :Your nick has been re-activated", NickServ, from);
05540 }
05541 }
05542 #endif
05543
05544
05545 #ifdef REQ_EMAIL
05546
05552 int emailAbuseCheck(UserList *nick, const char *email, int newNick)
05553 {
05554 if (newNick && !addNReg(email)) {
05555 sSend(":%s NOTICE %s :You have too many nicks registered.", NickServ, from);
05556 #ifdef REGLIMITYELL
05557 sSend(":%s GLOBOPS :%s is trying to register too many nicks.", NickServ, from);
05558 #endif
05559 return 1;
05560 }
05561 }
05562
05566 int addNReg(char *email)
05567 {
05568 nRegList *tmp;
05569 for(tmp = firstReg;tmp;tmp=tmp->next) {
05570 if(!strcasecmp(email, tmp->email)) {
05571 tmp->regs++;
05572 if(tmp->regs > NickLimit) {
05573 tmp->regs--;
05574 return 0;
05575 }
05576
05577 }
05578 }
05579
05580 tmp = malloc(sizeof(nRegList));
05581 strcpy(tmp->email, email);
05582 tmp->regs = 1;
05583
05584 if(!firstReg) {
05585 firstReg = tmp;
05586 tmp->previous = NULL;
05587 }
05588 else {
05589 lastReg->next = tmp;
05590 tmp->previous = lastReg;
05591 }
05592
05593 lastReg = tmp;
05594 tmp->next = NULL;
05595 return 1;
05596 }
05597
05598 void delNReg(char *email) {
05599 nRegList *tmp;
05600
05601 for(tmp=firstReg;tmp;tmp=tmp->next) {
05602 if(!strcasecmp(email, tmp->email)) {
05603 tmp->regs--;
05604 if(!tmp->regs) {
05605 if(tmp->previous)
05606 tmp->previous->next = tmp->next;
05607 else
05608 firstReg = tmp->next;
05609 if(tmp->next)
05610 tmp->next->previous = tmp->previous;
05611 else
05612 lastReg = tmp->previous;
05613 sfree(tmp);
05614 }
05615 }
05616 }
05617 }
05618 #endif
05619
05626 NCMD(ns_setpass)
05627 {
05628 const char *from = nick->nick;
05629 const char *pwAuthChKey = NULL;
05630 RegNickList *rnl;
05631
05632 if (numargs < 4)
05633 {
05634 sSend(":%s NOTICE %s :Syntax: SETPASS <nick> <code> <new password>",
05635 NickServ, from);
05636 return RET_SYNTAX;
05637 }
05638
05639 if ((rnl = getRegNickData(args[1])) == NULL)
05640 {
05641 sSend(":%s NOTICE %s :That nickname is not registered.",
05642 NickServ, from);
05643 return RET_NOTARGET;
05644 }
05645
05646 if (rnl->chpw_key) {
05647 const char *rnE = rnl->email;
05648 const char *rnP = PrintPass(rnl->password, NickGetEnc(rnl));
05649
05650 if (rnl->flags & NFORCEXFER)
05651 rnE = "-forced-transfer-";
05652 pwAuthChKey = GetAuthChKey(rnE, rnP,
05653 rnl->timereg, rnl->chpw_key);
05654 }
05655
05656 if (rnl->chpw_key == 0 || strcmp(pwAuthChKey, args[2]))
05657 {
05658 sSend(":%s NOTICE %s :Access Denied.",
05659 NickServ, from);
05660 return RET_FAIL;
05661 }
05662
05663 if (strlen(args[3]) > PASSLEN)
05664 {
05665 sSend(":%s NOTICE %s :Specified password is too long, please "
05666 "choose a password of %d characters or less.",
05667 NickServ, from, PASSLEN);
05668 return RET_EFAULT;
05669 }
05670
05671
05672 if (strcasecmp(args[1], args[3]) == 0 || strcasecmp(args[3], "password") == 0
05673 || strlen(args[3]) < 3)
05674 {
05675 sSend(":%s NOTICE %s :You cannot use \2%s\2 as your nickname password.",
05676 NickServ, from, args[3]);
05677 return RET_EFAULT;
05678 }
05679
05680 sSend(":%s NOTICE %s :Ok.", NickServ, from);
05681
05682 pw_enter_password(args[3], rnl->password, NickGetEnc(rnl));
05683 rnl->chpw_key = 0;
05684 rnl->flags &= ~NFORCEXFER;
05685
05686 sSend(":%s NOTICE %s :Password for %s is now %s, do NOT forget it, we"
05687 " are not responsible for lost passwords.",
05688 NickServ, from, rnl->nick, args[3]);
05689
05690 return RET_OK_DB;
05691 }
05692
05699 NCMD(ns_setemail)
05700 {
05701 char *from = nick->nick;
05702 RegNickList *regnick;
05703
05704 if (isOper(nick) == 0) {
05705 sSend(":%s NOTICE %s :Unknown command %s.\r\n"
05706 ":%s NOTICE %s :Please try /msg %s HELP",
05707 NickServ, from, args[0], NickServ, from, NickServ);
05708 return RET_NOPERM;
05709 }
05710
05711 if (opFlagged(nick, OOPER | OGRP) == 0) {
05712 sSend(":%s NOTICE %s :Access denied.",
05713 NickServ, from);
05714 return RET_NOPERM;
05715 }
05716
05717 if (numargs < 3)
05718 {
05719 sSend(":%s NOTICE %s :Syntax: SETEMAIL <nick> <email>",
05720 NickServ, from);
05721 return RET_SYNTAX;
05722 }
05723
05724 regnick = getRegNickData(args[1]);
05725
05726 if (!regnick) {
05727 PutError(NickServ, nick, ERR_NICKNOTREG_1ARG, args[1], 0, 0);
05728 PutHelpInfo(NickServ, nick, "HELP");
05729
05730 return RET_NOTARGET;
05731 }
05732
05733 if ((regnick->opflags & OROOT) && (opFlagged(nick, OROOT) == 0)) {
05734 sSend(":%s NOTICE %s :Access denied.",
05735 NickServ, from);
05736 return RET_NOPERM;
05737 }
05738
05739 if (strchr(args[2], '@') == NULL || strchr(args[2], '.') == NULL ||
05740 strlen(args[2]) > EMAILLEN)
05741 {
05742 sSend(":%s NOTICE %s :Invalid e-mail address.", NickServ, from);
05743 return RET_SYNTAX;
05744 }
05745
05746 sSend(":%s GLOBOPS :%s sets email for nick %s from \"%s\" to \"%s\"", NickServ, from, args[1],
05747 regnick->email, args[2]);
05748 operlog->log(nick, NS_SETEMAIL, regnick->nick, 0, "%s -> %s", regnick->email,
05749 args[2]);
05750 strncpyzt(regnick->email, args[2], EMAILLEN);
05751 return RET_FAIL;
05752 }
05753
05754