/* * Parses a G-Line entry from a storage journal line. * Returns 0 on invalid input, 1 otherwise. */ static int gs_read(char *s) { char type; time_t duration = 0; char *user; char *host; char *reason = ""; struct userBan *ban; struct userBan *existing; type = *s++; /* bad type */ if (type != '+' && type != '-') return 0; /* malformed */ if (*s++ != ' ') return 0; if (type == '+') { duration = strtol(s, &s, 0); if (duration) { /* already expired */ if (NOW >= duration) return 1; duration -= NOW; } /* malformed */ if (*s++ != ' ') return 0; } /* usermask */ user = s; while (*s && *s != ' ') s++; /* malformed */ if (*s != ' ') return 0; /* mark end of user mask */ *s++ = 0; /* hostmask */ host = s; while (*s && *s != ' ') s++; if (type == '+') { /* malformed */ if (*s != ' ') return 0; /* mark end of host mask */ *s++ = 0; /* reason is the only thing left */ reason = s; } ban = make_hostbased_ban(user, host); if (!ban) return 0; ban->flags |= UBAN_GLINE; if (type == '+') { if (duration) { ban->flags |= UBAN_TEMPORARY; ban->timeset = NOW; ban->duration = duration; } if (*reason) DupString(ban->reason, reason); add_hostbased_userban(ban); } else { existing = find_userban_exact(ban, UBAN_GLINE|UBAN_CONF); userban_free(ban); /* add may have been skipped due to being expired, so not an error */ if (!existing) return 1; remove_userban(existing); userban_free(existing); } return 1; }
/* * m_gline * Add a local user@host ban. * * parv[0] = sender * parv[1] = duration (optional) * parv[2] = nick or user@host mask * parv[3] = reason (optional) */ int m_gline(aClient *cptr, aClient *sptr, int parc, char *parv[]) { char rbuf[512]; char *target; char *user; char *host; char *reason = "<no reason>"; int tgminutes = DEFAULT_GLINE_TIME; int tgseconds; long lval; struct userBan *ban; struct userBan *existing; if (!IsPrivileged(sptr)) { sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]); return 0; } if (parc < 2) { sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "gline"); return 0; } lval = strtol(parv[1], &target, 10); if (*target != 0) { target = parv[1]; if (parc > 2) reason = parv[2]; } else { /* valid expiration time */ tgminutes = lval; if (parc < 3) { sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "Gline"); return 0; } target = parv[2]; if (parc > 3) reason = parv[3]; } /* negative times, or times greater than a year, are permanent */ if (tgminutes < 0 || tgminutes > (365 * 24 * 60)) tgminutes = 0; tgseconds = tgminutes * 60; if ((host = strchr(target, '@'))) { *host++ = 0; user = target; } else { user = "******"; host = target; } if (!match(user, "akjhfkahfasfjd") && !match(host, "ldksjfl.kss...kdjfd.jfklsjf")) { sendto_one(sptr, ":%s NOTICE %s :gline: %s@%s mask is too wide", me.name, parv[0], user, host); return 0; } /* * XXX: nick target support to be re-added */ if (!(ban = make_hostbased_ban(user, host))) { sendto_one(sptr, ":%s NOTICE %s :gline: invalid ban mask %s@%s", me.name, parv[0], user, host); return 0; } ban->flags |= UBAN_GLINE; /* only looks for duplicate glines, not akills */ if ((existing = find_userban_exact(ban, UBAN_GLINE))) { if (!IsServer(sptr)) sendto_one(sptr, ":%s NOTICE %s :gline: %s@%s is already %s: %s", me.name, parv[0], user, host, NETWORK_GLINE_NAME, existing->reason ? existing->reason : "<no reason>"); userban_free(ban); return 0; } if (MyClient(sptr) && user_match_ban(sptr, ban)) { sendto_one(sptr, ":%s NOTICE %s :gline: %s@%s matches you, rejected", me.name, parv[0], user, host); userban_free(ban); return 0; } if (!IsServer(sptr)) ircsnprintf(rbuf, sizeof(rbuf), "%s (%s)", reason, smalldate(0)); else ircsnprintf(rbuf, sizeof(rbuf), "%s", reason); ban->reason = MyMalloc(strlen(rbuf) + 1); strcpy(ban->reason, rbuf); if (tgseconds) { ban->flags |= UBAN_TEMPORARY; ban->timeset = NOW; ban->duration = tgseconds; } add_hostbased_userban(ban); if (!tgminutes || tgminutes >= GLINE_MIN_STORE_TIME) glinestore_add(ban); userban_sweep(ban); host = get_userban_host(ban, rbuf, sizeof(rbuf)); sendto_serv_butone(MyConnect(sptr) ? NULL : cptr, ":%s GLINE %l %s@%s :%s", sptr->name, tgseconds, user, host, reason); if (tgminutes) sendto_realops("%s added temporary %d min. "NETWORK_GLINE_NAME" for" " [%s@%s] [%s]", parv[0], tgminutes, user, host, reason); else sendto_realops("%s added "NETWORK_GLINE_NAME" for [%s@%s] [%s]", parv[0], user, host, reason); return 0; }
/* * m_kline * Add a local user@host ban. * * parv[0] = sender * parv[1] = duration (optional) * parv[2] = nick or user@host mask * parv[3] = reason (optional) */ int m_kline(aClient *cptr, aClient *sptr, int parc, char *parv[]) { char rbuf[512]; char hostbuf[HOSTIPLEN+3+1]; char *target; char *user; char *host; char *reason = "<no reason>"; int tkminutes = DEFAULT_KLINE_TIME; int tkseconds; long lval; struct userBan *ban; struct userBan *existing; aClient *acptr; if (!OPCanKline(sptr)) { sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]); return 0; } if (parc < 2) { sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "KLINE"); return 0; } lval = strtol(parv[1], &target, 10); if (*target != 0) { target = parv[1]; if (parc > 2 && !BadPtr(parv[2])) reason = parv[2]; } else { /* valid expiration time */ tkminutes = lval; if (parc < 3) { sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "KLINE"); return 0; } target = parv[2]; if (parc > 3 && !BadPtr(parv[3])) reason = parv[3]; } /* negative times, or times greater than a year, are permanent */ if (tkminutes < 0 || tkminutes > (365 * 24 * 60)) tkminutes = 0; tkseconds = tkminutes * 60; if ((host = strchr(target, '@'))) { *host++ = 0; user = target; } else if (strchr(target, '*')) { user = "******"; host = target; } else { if (!(acptr = find_chasing(sptr, target, NULL))) return 0; if (!acptr->user) return 0; user = acptr->user->username; if (acptr->ip_family == AF_INET) { ircsprintf(hostbuf, "%s/24", acptr->hostip); host = hostbuf; } else host = acptr->hostip; } if (!match(user, "akjhfkahfasfjd") && !match(host, "ldksjfl.kss...kdjfd.jfklsjf")) { sendto_one(sptr, ":%s NOTICE %s :KLINE: %s@%s mask is too wide", me.name, parv[0], user, host); return 0; } if (strchr(host, ' ') || !(ban = make_hostbased_ban(user, host))) { sendto_one(sptr, ":%s NOTICE %s :KLINE: invalid ban mask %s@%s", me.name, parv[0], user, host); return 0; } ban->flags |= UBAN_LOCAL; /* only looks for duplicate klines, not akills */ if ((existing = find_userban_exact(ban, UBAN_LOCAL))) { sendto_one(sptr, ":%s NOTICE %s :KLINE: %s@%s is already %s: %s", me.name, parv[0], user, host, LOCAL_BANNED_NAME, existing->reason ? existing->reason : "<no reason>"); userban_free(ban); return 0; } if (user_match_ban(sptr, ban)) { sendto_one(sptr, ":%s NOTICE %s :KLINE: %s@%s matches you, rejected", me.name, parv[0], user, host); userban_free(ban); return 0; } ircsnprintf(rbuf, sizeof(rbuf), "%s (%s)", reason, smalldate(0)); ban->reason = MyMalloc(strlen(rbuf) + 1); strcpy(ban->reason, rbuf); if (tkseconds) { ban->flags |= UBAN_TEMPORARY; ban->timeset = NOW; ban->duration = tkseconds; } add_hostbased_userban(ban); if (!tkminutes || tkminutes >= KLINE_MIN_STORE_TIME) klinestore_add(ban); userban_sweep(ban); host = get_userban_host(ban, rbuf, sizeof(rbuf)); if (tkminutes) sendto_realops("%s added temporary %d min. "LOCAL_BAN_NAME" for" " [%s@%s] [%s]", parv[0], tkminutes, user, host, reason); else sendto_realops("%s added "LOCAL_BAN_NAME" for [%s@%s] [%s]", parv[0], user, host, reason); return 0; }