X-Git-Url: http://git.pk910.de/?p=ircu2.10.12-pk.git;a=blobdiff_plain;f=ircd%2Fgline.c;h=9c3d2970e24df6a078e4c976cb94c64a2b7d8d36;hp=f294d99f456f07694a4c5fd5e22324339c299ebd;hb=72b0c799c590095ad78de705f36e9553bd41fa67;hpb=0a448eb4337cd92f8eeb21d9560506eb384ad69d diff --git a/ircd/gline.c b/ircd/gline.c index f294d99..9c3d297 100644 --- a/ircd/gline.c +++ b/ircd/gline.c @@ -24,6 +24,7 @@ #include "config.h" #include "gline.h" +#include "channel.h" #include "client.h" #include "ircd.h" #include "ircd_alloc.h" @@ -86,11 +87,11 @@ struct Gline* BadChanGlineList = 0; /* Figure out the next pointer in list... */ \ if ((((next) = (gl)->gl_next) || 1) && \ /* Then see if it's expired */ \ - (gl)->gl_lifetime <= CurrentTime) \ + (gl)->gl_lifetime <= TStime()) \ /* Record has expired, so free the G-line */ \ gline_free((gl)); \ /* See if we need to expire the G-line */ \ - else if ((((gl)->gl_expire > CurrentTime) || \ + else if ((((gl)->gl_expire > TStime()) || \ (((gl)->gl_flags &= ~GLINE_ACTIVE) && 0) || \ ((gl)->gl_state = GLOCAL_GLOBAL)) && 0) \ ; /* empty statement */ \ @@ -341,7 +342,7 @@ gline_propagate(struct Client *cptr, struct Client *sptr, struct Gline *gline) GlineIsRemActive(gline) ? '+' : '-', gline->gl_user, gline->gl_host ? "@" : "", gline->gl_host ? gline->gl_host : "", - gline->gl_expire - CurrentTime, gline->gl_lastmod, + gline->gl_expire - TStime(), gline->gl_lastmod, gline->gl_lifetime, gline->gl_reason); return 0; @@ -349,26 +350,35 @@ gline_propagate(struct Client *cptr, struct Client *sptr, struct Gline *gline) /** Count number of users who match \a mask. * @param[in] mask user\@host or user\@ip mask to check. + * @param[in] flags Bitmask possibly containing the value GLINE_LOCAL, to limit searches to this server. * @return Count of matching users. */ static int -count_users(char *mask) +count_users(char *mask, int flags) { + struct irc_in_addr ipmask; struct Client *acptr; int count = 0; + int ipmask_valid; char namebuf[USERLEN + HOSTLEN + 2]; char ipbuf[USERLEN + SOCKIPLEN + 2]; + unsigned char ipmask_len; + ipmask_valid = ipmask_parse(mask, &ipmask, &ipmask_len); for (acptr = GlobalClientList; acptr; acptr = cli_next(acptr)) { if (!IsUser(acptr)) continue; + if ((flags & GLINE_LOCAL) && !MyConnect(acptr)) + continue; ircd_snprintf(0, namebuf, sizeof(namebuf), "%s@%s", - cli_user(acptr)->username, cli_user(acptr)->host); + cli_user(acptr)->username, cli_user(acptr)->realhost); ircd_snprintf(0, ipbuf, sizeof(ipbuf), "%s@%s", cli_user(acptr)->username, ircd_ntoa(&cli_ip(acptr))); - if (!match(mask, namebuf) || !match(mask, ipbuf)) + if (!match(mask, namebuf) + || !match(mask, ipbuf) + || (ipmask_valid && ipmask_check(&cli_ip(acptr), &ipmask, ipmask_len))) count++; } @@ -429,6 +439,8 @@ gline_add(struct Client *cptr, struct Client *sptr, char *userhost, assert(0 != userhost); assert(0 != reason); + assert(((flags & (GLINE_GLOBAL | GLINE_LOCAL)) == GLINE_GLOBAL) || + ((flags & (GLINE_GLOBAL | GLINE_LOCAL)) == GLINE_LOCAL)); Debug((DEBUG_DEBUG, "gline_add(\"%s\", \"%s\", \"%s\", \"%s\", %Tu, %Tu " "%Tu, 0x%04x)", cli_name(cptr), cli_name(sptr), userhost, reason, @@ -437,13 +449,21 @@ gline_add(struct Client *cptr, struct Client *sptr, char *userhost, if (*userhost == '#' || *userhost == '&') { if ((flags & GLINE_LOCAL) && !HasPriv(sptr, PRIV_LOCAL_BADCHAN)) return send_reply(sptr, ERR_NOPRIVILEGES); + /* Allow maximum channel name length, plus margin for wildcards. */ + if (strlen(userhost+1) >= CHANNELLEN + 6) + return send_reply(sptr, ERR_LONGMASK); flags |= GLINE_BADCHAN; user = userhost; host = NULL; } else if (*userhost == '$') { switch (userhost[1]) { - case 'R': flags |= GLINE_REALNAME; break; + case 'R': + /* Allow REALLEN for the real name, plus margin for wildcards. */ + if (strlen(userhost+2) >= REALLEN + 6) + return send_reply(sptr, ERR_LONGMASK); + flags |= GLINE_REALNAME; + break; default: /* uh, what to do here? */ /* The answer, my dear Watson, is we throw a protocol_violation() @@ -477,7 +497,7 @@ gline_add(struct Client *cptr, struct Client *sptr, char *userhost, break; } - if ((tmp = count_users(uhmask)) >= + if ((tmp = count_users(uhmask, flags)) >= feature_int(FEAT_GLINEMAXUSERCOUNT) && !(flags & GLINE_OPERFORCE)) return send_reply(sptr, ERR_TOOMANYUSERS, tmp); } @@ -488,10 +508,13 @@ gline_add(struct Client *cptr, struct Client *sptr, char *userhost, * expiration time for greater than GLINE_MAX_EXPIRE. */ if (!(flags & GLINE_FORCE) && - (expire <= CurrentTime || expire > CurrentTime + GLINE_MAX_EXPIRE)) { + (expire <= TStime() || expire > TStime() + GLINE_MAX_EXPIRE)) { if (!IsServer(sptr) && MyConnect(sptr)) send_reply(sptr, ERR_BADEXPIRE, expire); return 0; + } else if (expire <= TStime()) { + /* This expired G-line was forced to be added, so mark it inactive. */ + flags &= ~GLINE_ACTIVE; } if (!lifetime) /* no lifetime set, use expiration time */ @@ -501,16 +524,17 @@ gline_add(struct Client *cptr, struct Client *sptr, char *userhost, /* Inform ops... */ sendto_opmask_butone(0, ircd_strncmp(reason, "AUTO", 4) ? SNO_GLINE : - SNO_AUTO, "%s adding %s %s for %s%s%s, expiring at " + SNO_AUTO, "%s adding %s%s %s for %s%s%s, expiring at " "%Tu: %s", (feature_bool(FEAT_HIS_SNOTICES) || IsServer(sptr)) ? cli_name(sptr) : cli_name((cli_user(sptr))->server), + (flags & GLINE_ACTIVE) ? "" : "deactivated ", (flags & GLINE_LOCAL) ? "local" : "global", (flags & GLINE_BADCHAN) ? "BADCHAN" : "GLINE", user, (flags & (GLINE_BADCHAN|GLINE_REALNAME)) ? "" : "@", (flags & (GLINE_BADCHAN|GLINE_REALNAME)) ? "" : host, - expire + TSoffset, reason); + expire, reason); /* and log it */ log_write(LS_GLINE, L_INFO, LOG_NOSNOTICE, @@ -519,7 +543,7 @@ gline_add(struct Client *cptr, struct Client *sptr, char *userhost, flags & GLINE_BADCHAN ? "BADCHAN" : "GLINE", user, flags & (GLINE_BADCHAN|GLINE_REALNAME) ? "" : "@", flags & (GLINE_BADCHAN|GLINE_REALNAME) ? "" : host, - expire + TSoffset, reason); + expire, reason); /* make the gline */ agline = make_gline(user, host, reason, expire, lastmod, lifetime, flags); @@ -577,14 +601,14 @@ gline_activate(struct Client *cptr, struct Client *sptr, struct Gline *gline, GlineIsBadChan(gline) ? "BADCHAN" : "GLINE", gline->gl_user, gline->gl_host ? "@" : "", gline->gl_host ? gline->gl_host : "", - gline->gl_expire + TSoffset, gline->gl_reason); - + gline->gl_expire, gline->gl_reason); + log_write(LS_GLINE, L_INFO, LOG_NOSNOTICE, "%#C activating global %s for %s%s%s, expiring at %Tu: %s", sptr, GlineIsBadChan(gline) ? "BADCHAN" : "GLINE", gline->gl_user, gline->gl_host ? "@" : "", gline->gl_host ? gline->gl_host : "", - gline->gl_expire + TSoffset, gline->gl_reason); + gline->gl_expire, gline->gl_reason); if (!(flags & GLINE_LOCAL)) /* don't propagate local changes */ gline_propagate(cptr, sptr, gline); @@ -645,14 +669,14 @@ gline_deactivate(struct Client *cptr, struct Client *sptr, struct Gline *gline, msg, GlineIsBadChan(gline) ? "BADCHAN" : "GLINE", gline->gl_user, gline->gl_host ? "@" : "", gline->gl_host ? gline->gl_host : "", - gline->gl_expire + TSoffset, gline->gl_reason); + gline->gl_expire, gline->gl_reason); log_write(LS_GLINE, L_INFO, LOG_NOSNOTICE, "%#C %s %s for %s%s%s, expiring at %Tu: %s", sptr, msg, GlineIsBadChan(gline) ? "BADCHAN" : "GLINE", gline->gl_user, gline->gl_host ? "@" : "", gline->gl_host ? gline->gl_host : "", - gline->gl_expire + TSoffset, gline->gl_reason); + gline->gl_expire, gline->gl_reason); if (!(flags & GLINE_LOCAL)) /* don't propagate local changes */ gline_propagate(cptr, sptr, gline); @@ -682,7 +706,7 @@ gline_modify(struct Client *cptr, struct Client *sptr, struct Gline *gline, time_t lastmod, time_t lifetime, unsigned int flags) { char buf[BUFSIZE], *op = ""; - int pos = 0; + int pos = 0, non_auto = 0; assert(gline); assert(!GlineIsLocal(gline)); @@ -712,7 +736,7 @@ gline_modify(struct Client *cptr, struct Client *sptr, struct Gline *gline, /* first, check out the expiration time... */ if ((flags & GLINE_EXPIRE) && expire) { if (!(flags & GLINE_FORCE) && - (expire <= CurrentTime || expire > CurrentTime + GLINE_MAX_EXPIRE)) { + (expire <= TStime() || expire > TStime() + GLINE_MAX_EXPIRE)) { if (!IsServer(sptr) && MyConnect(sptr)) /* bad expiration time */ send_reply(sptr, ERR_BADEXPIRE, expire); return 0; @@ -753,7 +777,7 @@ gline_modify(struct Client *cptr, struct Client *sptr, struct Gline *gline, (action == GLINE_LOCAL_DEACTIVATE && (gline->gl_state == GLOCAL_DEACTIVATED)) || /* can't activate an expired G-line */ - IRCD_MAX(gline->gl_expire, expire) <= CurrentTime) + IRCD_MAX(gline->gl_expire, expire) <= TStime()) action = GLINE_MODIFY; /* no activity state modifications */ Debug((DEBUG_DEBUG, "About to perform changes; flags 0x%04x, action %s", @@ -826,6 +850,7 @@ gline_modify(struct Client *cptr, struct Client *sptr, struct Gline *gline, /* Now, handle reason changes... */ if (flags & GLINE_REASON) { + non_auto = non_auto || ircd_strncmp(gline->gl_reason, "AUTO", 4); MyFree(gline->gl_reason); /* release old reason */ DupString(gline->gl_reason, reason); /* store new reason */ if (pos < BUFSIZE) @@ -835,7 +860,9 @@ gline_modify(struct Client *cptr, struct Client *sptr, struct Gline *gline, } /* All right, inform ops... */ - sendto_opmask_butone(0, SNO_GLINE, "%s modifying global %s for %s%s%s:%s", + non_auto = non_auto || ircd_strncmp(gline->gl_reason, "AUTO", 4); + sendto_opmask_butone(0, non_auto ? SNO_GLINE : SNO_AUTO, + "%s modifying global %s for %s%s%s:%s", (feature_bool(FEAT_HIS_SNOTICES) || IsServer(sptr)) ? cli_name(sptr) : cli_name((cli_user(sptr))->server), GlineIsBadChan(gline) ? "BADCHAN" : "GLINE", @@ -858,7 +885,7 @@ gline_modify(struct Client *cptr, struct Client *sptr, struct Gline *gline, flags & GLINE_OPERFORCE ? "!" : "", op, gline->gl_user, gline->gl_host ? "@" : "", gline->gl_host ? gline->gl_host : "", - gline->gl_expire - CurrentTime, gline->gl_lastmod, + gline->gl_expire - TStime(), gline->gl_lastmod, gline->gl_lifetime, gline->gl_reason); /* OK, let's do the G-line... */ @@ -918,8 +945,7 @@ gline_find(char *userhost, unsigned int flags) if (flags & (GLINE_BADCHAN | GLINE_ANY)) { gliter(BadChanGlineList, gline, sgline) { - if ((flags & GLINE_GLOBAL && gline->gl_flags & GLINE_LOCAL) || - (flags & GLINE_LOCAL && gline->gl_flags & GLINE_GLOBAL) || + if ((flags & (GlineIsLocal(gline) ? GLINE_GLOBAL : GLINE_LOCAL)) || (flags & GLINE_LASTMOD && !gline->gl_lastmod)) continue; else if ((flags & GLINE_EXACT ? ircd_strcmp(gline->gl_user, userhost) : @@ -936,8 +962,7 @@ gline_find(char *userhost, unsigned int flags) canon_userhost(t_uh, &user, &host, "*"); gliter(GlobalGlineList, gline, sgline) { - if ((flags & GLINE_GLOBAL && gline->gl_flags & GLINE_LOCAL) || - (flags & GLINE_LOCAL && gline->gl_flags & GLINE_GLOBAL) || + if ((flags & (GlineIsLocal(gline) ? GLINE_GLOBAL : GLINE_LOCAL)) || (flags & GLINE_LASTMOD && !gline->gl_lastmod)) continue; else if (flags & GLINE_EXACT) { @@ -1036,7 +1061,7 @@ gline_burst(struct Client *cptr) GlineIsRemActive(gline) ? '+' : '-', gline->gl_user, gline->gl_host ? "@" : "", gline->gl_host ? gline->gl_host : "", - gline->gl_expire - CurrentTime, gline->gl_lastmod, + gline->gl_expire - TStime(), gline->gl_lastmod, gline->gl_lifetime, gline->gl_reason); } @@ -1044,7 +1069,7 @@ gline_burst(struct Client *cptr) if (!GlineIsLocal(gline) && gline->gl_lastmod) sendcmdto_one(&me, CMD_GLINE, cptr, "* %c%s %Tu %Tu %Tu :%s", GlineIsRemActive(gline) ? '+' : '-', gline->gl_user, - gline->gl_expire - CurrentTime, gline->gl_lastmod, + gline->gl_expire - TStime(), gline->gl_lastmod, gline->gl_lifetime, gline->gl_reason); } } @@ -1064,7 +1089,7 @@ gline_resend(struct Client *cptr, struct Gline *gline) GlineIsRemActive(gline) ? '+' : '-', gline->gl_user, gline->gl_host ? "@" : "", gline->gl_host ? gline->gl_host : "", - gline->gl_expire - CurrentTime, gline->gl_lastmod, + gline->gl_expire - TStime(), gline->gl_lastmod, gline->gl_lifetime, gline->gl_reason); return 0; @@ -1091,8 +1116,8 @@ gline_list(struct Client *sptr, char *userhost) send_reply(sptr, RPL_GLIST, gline->gl_user, gline->gl_host ? "@" : "", gline->gl_host ? gline->gl_host : "", - gline->gl_expire + TSoffset, gline->gl_lastmod, - gline->gl_lifetime + TSoffset, + gline->gl_expire, gline->gl_lastmod, + gline->gl_lifetime, GlineIsLocal(gline) ? cli_name(&me) : "*", gline->gl_state == GLOCAL_ACTIVATED ? ">" : (gline->gl_state == GLOCAL_DEACTIVATED ? "<" : ""), @@ -1102,8 +1127,8 @@ gline_list(struct Client *sptr, char *userhost) send_reply(sptr, RPL_GLIST, gline->gl_user, gline->gl_host ? "@" : "", gline->gl_host ? gline->gl_host : "", - gline->gl_expire + TSoffset, gline->gl_lastmod, - gline->gl_lifetime + TSoffset, + gline->gl_expire, gline->gl_lastmod, + gline->gl_lifetime, GlineIsLocal(gline) ? cli_name(&me) : "*", gline->gl_state == GLOCAL_ACTIVATED ? ">" : (gline->gl_state == GLOCAL_DEACTIVATED ? "<" : ""), @@ -1112,8 +1137,8 @@ gline_list(struct Client *sptr, char *userhost) gliter(BadChanGlineList, gline, sgline) { send_reply(sptr, RPL_GLIST, gline->gl_user, "", "", - gline->gl_expire + TSoffset, gline->gl_lastmod, - gline->gl_lifetime + TSoffset, + gline->gl_expire, gline->gl_lastmod, + gline->gl_lifetime, GlineIsLocal(gline) ? cli_name(&me) : "*", gline->gl_state == GLOCAL_ACTIVATED ? ">" : (gline->gl_state == GLOCAL_DEACTIVATED ? "<" : ""), @@ -1141,8 +1166,8 @@ gline_stats(struct Client *sptr, const struct StatDesc *sd, send_reply(sptr, RPL_STATSGLINE, 'G', gline->gl_user, gline->gl_host ? "@" : "", gline->gl_host ? gline->gl_host : "", - gline->gl_expire + TSoffset, gline->gl_lastmod, - gline->gl_lifetime + TSoffset, + gline->gl_expire, gline->gl_lastmod, + gline->gl_lifetime, gline->gl_state == GLOCAL_ACTIVATED ? ">" : (gline->gl_state == GLOCAL_DEACTIVATED ? "<" : ""), GlineIsRemActive(gline) ? '+' : '-',