static void req_send_memos(User * u, char *vHost) { int i; int z = 2; if (checkDefCon(DEFCON_NO_NEW_MEMOS)) return; if (HSRequestMemoOper == 1) { for (i = 0; i < servopers.count; i++) { my_memo_lang(u, (((NickCore *) servopers.list[i])->display), z, u->na->nick, LNG_REQUEST_MEMO, vHost); } for (i = 0; i < servadmins.count; i++) { my_memo_lang(u, (((NickCore *) servadmins.list[i])->display), z, u->na->nick, LNG_REQUEST_MEMO, vHost); } for (i = 0; i < RootNumber; i++) { my_memo_lang(u, ServicesRoots[i], z, u->na->nick, LNG_REQUEST_MEMO, vHost); } } if (HSRequestMemoSetters == 1) { for (i = 0; i < HostNumber; i++) { my_memo_lang(u, HostSetters[i], z, u->na->nick, LNG_REQUEST_MEMO, vHost); } } }
/** * The /ms sendall command. * @param u The user who issued the command * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. **/ int do_sendall(User * u) { int i, z = 1; NickCore *nc; char *text = strtok(NULL, ""); if (readonly) { notice_lang(s_MemoServ, u, MEMO_SEND_DISABLED); return MOD_CONT; } else if (checkDefCon(DEFCON_NO_NEW_MEMOS)) { notice_lang(s_MemoServ, u, OPER_DEFCON_DENIED); return MOD_CONT; } else if (!text) { syntax_error(s_MemoServ, u, "SENDALL", MEMO_SEND_SYNTAX); return MOD_CONT; } for (i = 0; i < 1024; i++) { for (nc = nclists[i]; nc; nc = nc->next) { if (stricmp(u->nick, nc->display) != 0) memo_send(u, nc->display, text, z); } /* /nc */ } /* /i */ notice_lang(s_MemoServ, u, MEMO_MASS_SENT); return MOD_CONT; }
int add_session(char *nick, char *host, char *hostip) { Session *session, **list; Exception *exception; int sessionlimit = 0; session = findsession(host); if (session) { exception = find_hostip_exception(host, hostip); if (checkDefCon(DEFCON_REDUCE_SESSION)) { sessionlimit = exception ? exception->limit : DefConSessionLimit; } else { sessionlimit = exception ? exception->limit : DefSessionLimit; } if (sessionlimit != 0 && session->count >= sessionlimit) { if (SessionLimitExceeded) notice(s_OperServ, nick, SessionLimitExceeded, host); if (SessionLimitDetailsLoc) notice(s_OperServ, nick, "%s", SessionLimitDetailsLoc); /* We don't use kill_user() because a user stucture has not yet * been created. Simply kill the user. -TheShadow */ kill_user(s_OperServ, nick, "Session limit exceeded"); session->hits++; if (MaxSessionKill && session->hits >= MaxSessionKill) { char akillmask[BUFSIZE]; snprintf(akillmask, sizeof(akillmask), "*@%s", host); add_akill(NULL, akillmask, s_OperServ, time(NULL) + SessionAutoKillExpiry, "Session limit exceeded"); anope_cmd_global(s_OperServ, "Added a temporary AKILL for \2%s\2 due to excessive connections", akillmask); } return 0; } else { session->count++; return 1; } } nsessions++; session = scalloc(sizeof(Session), 1); session->host = sstrdup(host); list = &sessionlist[HASH(session->host)]; session->next = *list; if (*list) (*list)->prev = session; *list = session; session->count = 1; return 1; }
int check_akill(char *nick, const char *username, const char *host, const char *vhost, const char *ip) { int i; Akill *ak; /** * If DefCon is set to NO new users - kill the user ;). **/ if (checkDefCon(DEFCON_NO_NEW_CLIENTS)) { kill_user(s_OperServ, nick, DefConAkillReason); return 1; } if (akills.count == 0) return 0; for (i = 0; i < akills.count; i++) { ak = akills.list[i]; if (!ak) continue; if (match_wild_nocase(ak->user, username) && match_wild_nocase(ak->host, host)) { xanadu_cmd_akill(ak->user, ak->host, ak->by, ak->seton, ak->expires, ak->reason); return 1; } if (ircd->vhost) { if (vhost) { if (match_wild_nocase(ak->user, username) && match_wild_nocase(ak->host, vhost)) { xanadu_cmd_akill(ak->user, ak->host, ak->by, ak->seton, ak->expires, ak->reason); return 1; } } } if (ircd->nickip) { if (ip) { if (match_wild_nocase(ak->user, username) && match_wild_nocase(ak->host, ip)) { xanadu_cmd_akill(ak->user, ak->host, ak->by, ak->seton, ak->expires, ak->reason); return 1; } } } } return 0; }
void rsend_notify(User * u, Memo * m, const char *chan) { NickAlias *na; NickCore *nc; char text[256]; const char *fmt; /* Only send receipt if memos are allowed */ if ((!readonly) && (!checkDefCon(DEFCON_NO_NEW_MEMOS))) { /* Get nick alias for sender */ na = findnick(m->sender); if (!na) { return; } /* Get nick core for sender */ nc = na->nc; if (!nc) { return; } /* Text of the memo varies if the recepient was a nick or channel */ if (chan) { fmt = getstring(na, MEMO_RSEND_CHAN_MEMO_TEXT); snprintf(text, sizeof(text), fmt, chan); } else { fmt = getstring(na, MEMO_RSEND_NICK_MEMO_TEXT); snprintf(text, sizeof(text), "%s", fmt); } /* Send notification */ memo_send(u, m->sender, text, 2); /* Notify recepient of the memo that a notification has been sent to the sender */ notice_lang(s_MemoServ, u, MEMO_RSEND_USER_NOTIFICATION, nc->display); } /* Remove receipt flag from the original memo */ m->flags &= ~MF_RECEIPT; return; }
/** * Run DefCon level specific Functions. **/ void runDefCon(void) { char *newmodes; if (checkDefCon(DEFCON_FORCE_CHAN_MODES)) { if (DefConChanModes && !DefConModesSet) { if (DefConChanModes[0] == '+' || DefConChanModes[0] == '-') { alog("DEFCON: setting %s on all chan's", DefConChanModes); do_mass_mode(DefConChanModes); DefConModesSet = 1; } } } else { if (DefConChanModes && (DefConModesSet != 0)) { if (DefConChanModes[0] == '+' || DefConChanModes[0] == '-') { DefConModesSet = 0; if ((newmodes = defconReverseModes(DefConChanModes))) { alog("DEFCON: setting %s on all chan's", newmodes); do_mass_mode(newmodes); free(newmodes); } } } } }
/** * Adds a new user to anopes internal userlist. * * If the SVID passed is 2, the user will not be marked registered or requested to ID. * This is an addition to accomodate IRCds where we cannot determine this based on the NICK * or UID command. Some IRCd's keep +r on when changing nicks and do not use SVID (ex. InspIRCd 1.2). * Instead we get a METADATA command containing the accountname the user was last identified to. * Since this is received after the user is introduced to us we should not yet mark the user * as identified or ask him to identify. We will mark him as recognized for the time being and let * him keep his +r if he has it. * It is the responsibility of the protocol module to make sure that this is either invalidated, * or changed to identified. ~ Viper **/ User *do_nick(const char *source, char *nick, char *username, char *host, char *server, char *realname, time_t ts, uint32 svid, uint32 ip, char *vhost, char *uid) { User *user = NULL; char *tmp = NULL; NickAlias *old_na; /* Old nick rec */ int nc_changed = 1; /* Did nick core change? */ int status = 0; /* Status to apply */ char mask[USERMAX + HOSTMAX + 2]; char *logrealname; char *oldnick; if (!*source) { char ipbuf[16]; struct in_addr addr; if (ircd->nickvhost) { if (vhost) { if (!strcmp(vhost, "*")) { vhost = NULL; if (debug) alog("debug: new user�with no vhost in NICK command: %s", nick); } } } /* This is a new user; create a User structure for it. */ if (debug) alog("debug: new user: %s", nick); if (ircd->nickip) { addr.s_addr = htonl(ip); ntoa(addr, ipbuf, sizeof(ipbuf)); } if (LogUsers) { /** * Ugly swap routine for Flop's bug :) **/ if (realname) { tmp = strchr(realname, '%'); while (tmp) { *tmp = '-'; tmp = strchr(realname, '%'); } } logrealname = normalizeBuffer(realname); /** * End of ugly swap **/ if (ircd->nickvhost) { if (ircd->nickip) { alog("LOGUSERS: %s (%s@%s => %s) (%s) [%s] connected to the network (%s).", nick, username, host, (vhost ? vhost : "none"), logrealname, ipbuf, server); } else { alog("LOGUSERS: %s (%s@%s => %s) (%s) connected to the network (%s).", nick, username, host, (vhost ? vhost : "none"), logrealname, server); } } else { if (ircd->nickip) { alog("LOGUSERS: %s (%s@%s) (%s) [%s] connected to the network (%s).", nick, username, host, logrealname, ipbuf, server); } else { alog("LOGUSERS: %s (%s@%s) (%s) connected to the network (%s).", nick, username, host, logrealname, server); } } Anope_Free(logrealname); } /* We used to ignore the ~ which a lot of ircd's use to indicate no * identd response. That caused channel bans to break, so now we * just take what the server gives us. People are still encouraged * to read the RFCs and stop doing anything to usernames depending * on the result of an identd lookup. */ /* First check for AKILLs. */ /* DONT just return null if its an akill match anymore - yes its more efficent to, however, now that ircd's are * starting to use things like E/F lines, we cant be 100% sure the client will be removed from the network :/ * as such, create a user_struct, and if the client is removed, we'll delete it again when the QUIT notice * comes in from the ircd. **/ if (check_akill(nick, username, host, vhost, ipbuf)) { /* return NULL; */ } /** * DefCon AKILL system, if we want to akill all connecting user's here's where to do it * then force check_akill again on them... **/ /* don't akill on netmerges -Certus */ /* don't akill clients introduced by ulines. -Viper */ if (is_sync(findserver(servlist, server)) && checkDefCon(DEFCON_AKILL_NEW_CLIENTS) && !is_ulined(server)) { strncpy(mask, "*@", 3); strncat(mask, host, HOSTMAX); alog("DEFCON: adding akill for %s", mask); add_akill(NULL, mask, s_OperServ, time(NULL) + dotime(DefConAKILL), DefConAkillReason ? DefConAkillReason : "DEFCON AKILL"); if (check_akill(nick, username, host, vhost, ipbuf)) { /* return NULL; */ } } /* SGLINE */ if (ircd->sgline) { if (check_sgline(nick, realname)) return NULL; } /* SQLINE */ if (ircd->sqline) { if (check_sqline(nick, 0)) return NULL; } /* SZLINE */ if (ircd->szline && ircd->nickip) { if (check_szline(nick, ipbuf)) return NULL; } /* Now check for session limits */ if (LimitSessions && !is_ulined(server) && !add_session(nick, host, ipbuf)) return NULL; /* Allocate User structure and fill it in. */ user = new_user(nick); user->username = sstrdup(username); user->host = sstrdup(host); user->server = findserver(servlist, server); user->realname = sstrdup(realname); user->timestamp = ts; user->my_signon = time(NULL); user->chost = vhost ? sstrdup(vhost) : sstrdup(host); user->vhost = vhost ? sstrdup(vhost) : sstrdup(host); if (uid) { user->uid = sstrdup(uid); /* p10/ts6 stuff */ } else { user->uid = NULL; } user->vident = sstrdup(username); /* We now store the user's ip in the user_ struct, * because we will use it in serveral places -- DrStein */ if (ircd->nickip) { user->hostip = sstrdup(ipbuf); } else { user->hostip = NULL; } if (svid == 0) { display_news(user, NEWS_LOGON); display_news(user, NEWS_RANDOM); } if (svid == 2 && user->na) { /* We do not yet know if the user should be identified or not. * mark him as recognized for now. * It s up to the protocol module to make sure this either becomes ID'd or * is invalidated. ~ Viper */ if (debug) alog("debug: Marking %s as recognized..", user->nick); user->svid = 1; user->na->status |= NS_RECOGNIZED; nc_changed = 0; } else if (svid == ts && user->na) { /* Timestamp and svid match, and nick is registered; automagically identify the nick */ user->svid = svid; user->na->status |= NS_IDENTIFIED; check_memos(user); nc_changed = 0; /* Start nick tracking if available */ if (NSNickTracking) nsStartNickTracking(user); } else if (svid != 1) { /* Resets the svid because it doesn't match */ user->svid = 1; anope_cmd_svid_umode(user->nick, user->timestamp); } else { user->svid = 1; } send_event(EVENT_NEWNICK, 1, nick); } else { /* An old user changing nicks. */ if (UseTS6 && ircd->ts6) user = find_byuid(source); if (!user) user = finduser(source); if (!user) { alog("user: NICK from nonexistent nick %s", source); return NULL; } user->isSuperAdmin = 0; /* Dont let people nick change and stay SuperAdmins */ if (debug) alog("debug: %s changes nick to %s", source, nick); if (LogUsers) { logrealname = normalizeBuffer(user->realname); if (ircd->vhost) { alog("LOGUSERS: %s (%s@%s => %s) (%s) changed nick to %s (%s).", user->nick, user->username, user->host, (user->vhost ? user->vhost : "(none)"), logrealname, nick, user->server->name); } else { alog("LOGUSERS: %s (%s@%s) (%s) changed nick to %s (%s).", user->nick, user->username, user->host, logrealname, nick, user->server->name); } if (logrealname) { free(logrealname); } } user->timestamp = ts; if (stricmp(nick, user->nick) == 0) { /* No need to redo things */ change_user_nick(user, nick); nc_changed = 0; } else { /* Update this only if nicks aren't the same */ user->my_signon = time(NULL); old_na = user->na; if (old_na) { if (nick_recognized(user)) user->na->last_seen = time(NULL); status = old_na->status & NS_TRANSGROUP; cancel_user(user); } oldnick = sstrdup(user->nick); change_user_nick(user, nick); if ((old_na ? old_na->nc : NULL) == (user->na ? user->na->nc : NULL)) nc_changed = 0; if (!nc_changed && (user->na)) user->na->status |= status; else { anope_cmd_nc_change(user); } send_event(EVENT_CHANGE_NICK, 2, nick, oldnick); free(oldnick); } if (ircd->sqline) { if (!is_oper(user) && check_sqline(user->nick, 1)) return NULL; } } /* if (!*source) */ /* Check for nick tracking to bypass identification */ if (NSNickTracking && nsCheckNickTracking(user)) { user->na->status |= NS_IDENTIFIED; nc_changed = 0; } if (nc_changed || !nick_recognized(user)) { if (validate_user(user)) check_memos(user); } else { if (nick_identified(user)) { char tsbuf[16]; user->na->last_seen = time(NULL); if (user->na->last_usermask) free(user->na->last_usermask); user->na->last_usermask = smalloc(strlen(common_get_vident(user)) + strlen(common_get_vhost(user)) + 2); sprintf(user->na->last_usermask, "%s@%s", common_get_vident(user), common_get_vhost(user)); snprintf(tsbuf, sizeof(tsbuf), "%lu", (unsigned long int) user->timestamp); anope_cmd_svid_umode2(user, tsbuf); alog("%s: %s!%s@%s automatically identified for nick %s", s_NickServ, user->nick, user->username, user->host, user->nick); } } /* Bahamut sets -r on every nick changes, so we must test it even if nc_changed == 0 */ if (ircd->check_nick_id) { if (nick_identified(user)) { char tsbuf[16]; snprintf(tsbuf, sizeof(tsbuf), "%lu", (unsigned long int) user->timestamp); anope_cmd_svid_umode3(user, tsbuf); } } return user; }
int do_addnick(User * u) { NickAlias *na, *target; NickCore *nc; char *nick = strtok(NULL, " "); char *pass = strtok(NULL, " "); int i; char tsbuf[16]; char modes[512]; int len; if (NSEmailReg && (findrequestnick(u->nick))) { notice_lang(s_NickServ, u, NS_REQUESTED); return MOD_CONT; } if (readonly) { notice_lang(s_NickServ, u, NS_ADDNICK_DISABLED); return MOD_CONT; } if (checkDefCon(DEFCON_NO_NEW_NICKS)) { notice_lang(s_NickServ, u, OPER_DEFCON_DENIED); return MOD_CONT; } if (RestrictOperNicks) { for (i = 0; i < RootNumber; i++) { if (stristr(u->nick, ServicesRoots[i]) && !is_oper(u)) { notice_lang(s_NickServ, u, NICK_CANNOT_BE_REGISTERED, u->nick); return MOD_CONT; } } for (i = 0; i < servadmins.count && (nc = servadmins.list[i]); i++) { if (stristr(u->nick, nc->display) && !is_oper(u)) { notice_lang(s_NickServ, u, NICK_CANNOT_BE_REGISTERED, u->nick); return MOD_CONT; } } for (i = 0; i < servopers.count && (nc = servopers.list[i]); i++) { if (stristr(u->nick, nc->display) && !is_oper(u)) { notice_lang(s_NickServ, u, NICK_CANNOT_BE_REGISTERED, u->nick); return MOD_CONT; } } } if (!nick || !pass) { syntax_error(s_NickServ, u, "ADDNICK", NS_ADDNICK_SYNTAX); } else if (!(target = findnick(nick))) { notice_lang(s_NickServ, u, NICK_X_NOT_REGISTERED, nick); } else if (time(NULL) < u->lastnickreg + NSRegDelay) { notice_lang(s_NickServ, u, NS_ADDNICK_PLEASE_WAIT, NSRegDelay); } else if (u->na && (u->na->status & NS_VERBOTEN)) { alog("%s: %s@%s tried to use ADDNICK from forbidden nick %s.", s_NickServ, u->username, u->host, u->nick); notice_lang(s_NickServ, u, NICK_X_FORBIDDEN, u->nick); } else if (u->na && (u->na->nc->flags & NI_SUSPENDED)) { alog("%s: %s!%s@%s tried to use ADDNICK from suspended nick %s.", s_NickServ, u->nick, u->username, u->host, target->nick); notice_lang(s_NickServ, u, NICK_X_SUSPENDED, u->nick); } else if (u->na && NSNoGroupChange) { notice_lang(s_NickServ, u, NS_ADDNICK_CHANGE_DISABLED, s_NickServ); } else if (u->na && !nick_identified(u)) { notice_lang(s_NickServ, u, NICK_IDENTIFY_REQUIRED, s_NickServ); } else if (target && (target->nc->flags & NI_SUSPENDED)) { alog("%s: %s!%s@%s tried to use GROUP from SUSPENDED nick %s", s_NickServ, u->nick, u->username, u->host, target->nick); notice_lang(s_NickServ, u, NICK_X_SUSPENDED, target->nick); } else if (target->status & NS_VERBOTEN) { notice_lang(s_NickServ, u, NICK_X_FORBIDDEN, nick); } else if (u->na && target->nc == u->na->nc) { notice_lang(s_NickServ, u, NS_ADDNICK_SAME, target->nick); } else if (NSMaxAliases && (target->nc->aliases.count >= NSMaxAliases) && !nick_is_services_admin(target->nc)) { notice_lang(s_NickServ, u, NS_ADDNICK_TOO_MANY, target->nick, s_NickServ, s_NickServ); } else if (enc_check_password(pass, target->nc->pass) != 1) { alog("%s: Failed ADDNICK for %s!%s@%s (invalid password).", s_NickServ, u->nick, u->username, u->host); notice_lang(s_NickServ, u, PASSWORD_INCORRECT); bad_password(u); } else { /* If the nick is already registered, drop it. * If not, check that it is valid. */ if (u->na) { delnick(u->na); } else { int prefixlen = strlen(NSGuestNickPrefix); int nicklen = strlen(u->nick); if (nicklen <= prefixlen + 7 && nicklen >= prefixlen + 1 && stristr(u->nick, NSGuestNickPrefix) == u->nick && strspn(u->nick + prefixlen, "1234567890") == nicklen - prefixlen) { notice_lang(s_NickServ, u, NICK_CANNOT_BE_REGISTERED, u->nick); return MOD_CONT; } } na = makealias(u->nick, target->nc); if (na) { na->last_usermask = scalloc(strlen(common_get_vident(u)) + strlen(common_get_vhost(u)) + 2, 1); sprintf(na->last_usermask, "%s@%s", common_get_vident(u), common_get_vhost(u)); na->last_realname = sstrdup(u->realname); na->time_registered = na->last_seen = time(NULL); na->status = (int16) (NS_IDENTIFIED | NS_RECOGNIZED); if (!(na->nc->flags & NI_SERVICES_ROOT)) { for (i = 0; i < RootNumber; i++) { if (!stricmp(ServicesRoots[i], u->nick)) { na->nc->flags |= NI_SERVICES_ROOT; break; } } } u->na = na; na->u = u; #ifdef USE_RDB /* Is this really needed? Since this is a new alias it will get * its unique id on the next update, since it was previously * deleted by delnick. Must observe... */ if (rdb_open()) { rdb_save_ns_alias(na); rdb_close(); } #endif send_event(EVENT_GROUP, 1, u->nick); alog("%s: %s!%s@%s makes %s join group of %s (%s) (e-mail: %s)", s_NickServ, u->nick, u->username, u->host, u->nick, target->nick, target->nc->display, (target->nc->email ? target->nc->email : "none")); notice_lang(s_NickServ, u, NS_ADDNICK_SUCCESS, target->nick); u->lastnickreg = time(NULL); snprintf(tsbuf, sizeof(tsbuf), "%lu", (unsigned long int) u->timestamp); if (ircd->modeonreg) { len = strlen(ircd->modeonreg); strncpy(modes,ircd->modeonreg,512); if(ircd->rootmodeonid && is_services_root(u)) { strncat(modes,ircd->rootmodeonid,512-len); } else if(ircd->adminmodeonid && is_services_admin(u)) { strncat(modes,ircd->adminmodeonid,512-len); } else if(ircd->opermodeonid && is_services_oper(u)) { strncat(modes,ircd->opermodeonid,512-len); } if (ircd->tsonmode) { common_svsmode(u, modes, tsbuf); } else { common_svsmode(u, modes, NULL); } } check_memos(u); } else { alog("%s: makealias(%s) failed", s_NickServ, u->nick); notice_lang(s_NickServ, u, NS_ADDNICK_FAILED); } } return MOD_CONT; }
/** * The /cs register command. * @param u The user who issued the command * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. **/ int do_register(User * u) { char *chan = strtok(NULL, " "); char *pass = strtok(NULL, " "); char *desc = strtok(NULL, ""); NickCore *nc; Channel *c; ChannelInfo *ci; struct u_chaninfolist *uc; int is_servadmin = is_services_admin(u); char founderpass[PASSMAX + 1]; char tmp_pass[PASSMAX]; if (readonly) { notice_lang(s_ChanServ, u, CHAN_REGISTER_DISABLED); return MOD_CONT; } if (checkDefCon(DEFCON_NO_NEW_CHANNELS)) { notice_lang(s_ChanServ, u, OPER_DEFCON_DENIED); return MOD_CONT; } if (!desc) { syntax_error(s_ChanServ, u, "REGISTER", CHAN_REGISTER_SYNTAX); } else if (*chan == '&') { notice_lang(s_ChanServ, u, CHAN_REGISTER_NOT_LOCAL); } else if (*chan != '#') { notice_lang(s_ChanServ, u, CHAN_SYMBOL_REQUIRED); } else if (!xanadu_valid_chan(chan)) { notice_lang(s_ChanServ, u, CHAN_X_INVALID, chan); } else if (!u->na || !(nc = u->na->nc)) { notice_lang(s_ChanServ, u, CHAN_MUST_REGISTER_NICK, s_NickServ); } else if (!nick_recognized(u)) { notice_lang(s_ChanServ, u, CHAN_MUST_IDENTIFY_NICK, s_NickServ, s_NickServ); } else if (!(c = findchan(chan))) { notice_lang(s_ChanServ, u, CHAN_REGISTER_NONE_CHANNEL, chan); } else if ((ci = cs_findchan(chan)) != NULL) { if (ci->flags & CI_VERBOTEN) { alog("%s: Attempt to register FORBIDden channel %s by %s!%s@%s", s_ChanServ, ci->name, u->nick, u->username, u->host); notice_lang(s_ChanServ, u, CHAN_MAY_NOT_BE_REGISTERED, chan); } else { notice_lang(s_ChanServ, u, CHAN_ALREADY_REGISTERED, chan); } } else if (!stricmp(chan, "#")) { notice_lang(s_ChanServ, u, CHAN_MAY_NOT_BE_REGISTERED, chan); } else if (!chan_has_user_status(c, u, CUS_OP)) { notice_lang(s_ChanServ, u, CHAN_MUST_BE_CHANOP); } else if (!is_servadmin && nc->channelmax > 0 && nc->channelcount >= nc->channelmax) { notice_lang(s_ChanServ, u, nc->channelcount > nc-> channelmax ? CHAN_EXCEEDED_CHANNEL_LIMIT : CHAN_REACHED_CHANNEL_LIMIT, nc->channelmax); } else if (stricmp(u->nick, pass) == 0 || (StrictPasswords && strlen(pass) < 5)) { notice_lang(s_ChanServ, u, MORE_OBSCURE_PASSWORD); } else if (!(ci = makechan(chan))) { alog("%s: makechan() failed for REGISTER %s", s_ChanServ, chan); notice_lang(s_ChanServ, u, CHAN_REGISTRATION_FAILED); } else if (strscpy(founderpass, pass, PASSMAX + 1), enc_encrypt_in_place(founderpass, PASSMAX) < 0) { alog("%s: Couldn't encrypt password for %s (REGISTER)", s_ChanServ, chan); notice_lang(s_ChanServ, u, CHAN_REGISTRATION_FAILED); delchan(ci); } else { c->ci = ci; ci->c = c; ci->bantype = CSDefBantype; ci->flags = CSDefFlags; ci->mlock_on = ircd->defmlock; ci->memos.memomax = MSMaxMemos; ci->last_used = ci->time_registered; ci->founder = nc; if (strlen(pass) > PASSMAX) notice_lang(s_ChanServ, u, PASSWORD_TRUNCATED, PASSMAX); memset(pass, 0, strlen(pass)); memcpy(ci->founderpass, founderpass, PASSMAX); ci->desc = sstrdup(desc); if (c->topic) { ci->last_topic = sstrdup(c->topic); strscpy(ci->last_topic_setter, c->topic_setter, NICKMAX); ci->last_topic_time = c->topic_time; } else { /* Set this to something, otherwise it will maliform the topic */ strscpy(ci->last_topic_setter, s_ChanServ, NICKMAX); } ci->bi = NULL; ci->botflags = BSDefFlags; ci->founder->channelcount++; alog("%s: Channel '%s' registered by %s!%s@%s", s_ChanServ, chan, u->nick, u->username, u->host); notice_lang(s_ChanServ, u, CHAN_REGISTERED, chan, u->nick); if(enc_decrypt(ci->founderpass,tmp_pass,PASSMAX) == 1) { notice_lang(s_ChanServ, u, CHAN_PASSWORD_IS, ci->founderpass); } uc = scalloc(sizeof(*uc), 1); uc->next = u->founder_chans; uc->prev = NULL; if (u->founder_chans) u->founder_chans->prev = uc; u->founder_chans = uc; uc->chan = ci; /* Implement new mode lock */ check_modes(c); /* On most ircds you do not receive the admin/owner mode till its registered */ if (ircd->admin) { xanadu_cmd_mode(s_ChanServ, chan, "%s %s", ircd->adminset, u->nick); } if (ircd->owner && ircd->ownerset) { xanadu_cmd_mode(s_ChanServ, chan, "%s %s", ircd->ownerset, u->nick); } send_event(EVENT_CHAN_REGISTERED, 1, chan); } return MOD_CONT; }
/** * Split from do_send, this way we can easily send a memo from any point. * * @param u User Struct * @param name Target of the memo * @param text Memo Text * @param z type see info * @param source Nickname of the alias the memo originates from. * 0 - reply to user * 1 - silent * 2 - silent with no delay timer * 3 - reply to user and request read receipt * @return void */ void memo_send_from(User * u, char *name, char *text, int z, char *source) { int ischan; int isforbid; Memo *m; MemoInfo *mi; time_t now = time(NULL); int is_servoper = is_services_oper(u); if (readonly) { notice_lang(s_MemoServ, u, MEMO_SEND_DISABLED); } else if (checkDefCon(DEFCON_NO_NEW_MEMOS)) { notice_lang(s_MemoServ, u, OPER_DEFCON_DENIED); return; } else if (!text) { if (z == 0) syntax_error(s_MemoServ, u, "SEND", MEMO_SEND_SYNTAX); if (z == 3) syntax_error(s_MemoServ, u, "RSEND", MEMO_RSEND_SYNTAX); } else if (!nick_recognized(u)) { if (z == 0 || z == 3) notice_lang(s_MemoServ, u, NICK_IDENTIFY_REQUIRED, s_NickServ); } else if (!(mi = getmemoinfo(name, &ischan, &isforbid))) { if (z == 0 || z == 3) { if (isforbid) { notice_lang(s_MemoServ, u, ischan ? CHAN_X_FORBIDDEN : NICK_X_FORBIDDEN, name); } else { notice_lang(s_MemoServ, u, ischan ? CHAN_X_NOT_REGISTERED : NICK_X_NOT_REGISTERED, name); } } } else if (z != 2 && MSSendDelay > 0 && u && u->lastmemosend + MSSendDelay > now && !is_servoper) { u->lastmemosend = now; if (z == 0) notice_lang(s_MemoServ, u, MEMO_SEND_PLEASE_WAIT, MSSendDelay); if (z == 3) notice_lang(s_MemoServ, u, MEMO_RSEND_PLEASE_WAIT, MSSendDelay); } else if (mi->memomax == 0 && !is_servoper) { if (z == 0 || z == 3) notice_lang(s_MemoServ, u, MEMO_X_GETS_NO_MEMOS, name); } else if (mi->memocount >= 32767 || (mi->memomax > 0 && mi->memocount >= mi->memomax && !is_servoper)) { if (z == 0 || z == 3) notice_lang(s_MemoServ, u, MEMO_X_HAS_TOO_MANY_MEMOS, name); } else { u->lastmemosend = now; mi->memocount++; mi->memos = srealloc(mi->memos, sizeof(Memo) * mi->memocount); m = &mi->memos[mi->memocount - 1]; strscpy(m->sender, source, NICKMAX); m->moduleData = NULL; if (mi->memocount > 1) { m->number = m[-1].number + 1; if (m->number < 1) { int i; for (i = 0; i < mi->memocount; i++) { mi->memos[i].number = i + 1; } } } else { m->number = 1; } m->time = time(NULL); m->text = sstrdup(text); m->flags = MF_UNREAD; #ifdef USE_MYSQL m->id = 0; #endif /* Set notify sent flag - DrStein */ if (z == 2) { m->flags |= MF_NOTIFYS; } /* Set receipt request flag */ if (z == 3) m->flags |= MF_RECEIPT; if (z == 0 || z == 3) notice_lang(s_MemoServ, u, MEMO_SENT, name); if (!ischan) { NickAlias *na; NickCore *nc = (findnick(name))->nc; if (MSNotifyAll) { if ((nc->flags & NI_MEMO_RECEIVE) && get_ignore(name) == NULL) { int i; for (i = 0; i < nc->aliases.count; i++) { na = nc->aliases.list[i]; if (na->u && nick_identified(na->u)) notice_lang(s_MemoServ, na->u, MEMO_NEW_MEMO_ARRIVED, source, s_MemoServ, m->number); } } else { if ((u = finduser(name)) && nick_identified(u) && (nc->flags & NI_MEMO_RECEIVE)) notice_lang(s_MemoServ, u, MEMO_NEW_MEMO_ARRIVED, source, s_MemoServ, m->number); } /* if (flags & MEMO_RECEIVE) */ } /* if (MSNotifyAll) */ /* let's get out the mail if set in the nickcore - certus */ if (nc->flags & NI_MEMO_MAIL) new_memo_mail(nc, m); } else { struct c_userlist *cu, *next; Channel *c; if (MSNotifyAll && (c = findchan(name))) { for (cu = c->users; cu; cu = next) { next = cu->next; if (check_access(cu->user, c->ci, CA_MEMO)) { if (cu->user->na && (cu->user->na->nc->flags & NI_MEMO_RECEIVE) && get_ignore(cu->user->nick) == NULL) { notice_lang(s_MemoServ, cu->user, MEMO_NEW_X_MEMO_ARRIVED, c->ci->name, s_MemoServ, c->ci->name, m->number); } } } } /* MSNotifyAll */ } /* if (!ischan) */ } /* if command is valid */ }