X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=ircd%2Fm_gline.c;h=549ae140db667df9ebac742cc6efb0ec0ec25635;hb=79f4396535284e060d4a4ada4a4cc897cd5f69d3;hp=1fa28dd79064d7d556bb2173ccccce4f548df94e;hpb=6b73b99f7c5af48c83c30334c20fd07029628a1e;p=ircu2.10.12-pk.git diff --git a/ircd/m_gline.c b/ircd/m_gline.c index 1fa28dd..549ae14 100644 --- a/ircd/m_gline.c +++ b/ircd/m_gline.c @@ -1,4 +1,4 @@ -/* +\/* * IRC - Internet Relay Chat, ircd/m_gline.c * Copyright (C) 1990 Jarkko Oikarinen and * University of Oulu, Computing Center @@ -102,6 +102,19 @@ #include #include +#define PASTWATCH 157680000 /* number of seconds in 5 years */ + +/* + * If the expiration value, interpreted as an absolute timestamp, is + * more recent than 5 years in the past, we interpret it as an + * absolute timestamp; otherwise, we assume it's relative and convert + * it to an absolute timestamp. Either way, the output of this macro + * is an absolute timestamp--not guaranteed to be a *valid* timestamp, + * but you can't have everything in a macro ;) + */ +#define abs_expire(exp) \ + ((exp) >= CurrentTime - PASTWATCH ? (exp) : (exp) + CurrentTime) + /* * ms_gline - server message handler * @@ -118,7 +131,7 @@ ms_gline(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) struct Gline *agline = 0; unsigned int flags = 0; enum GlineAction action = GLINE_MODIFY; - time_t expire_off = 0, lastmod = 0, lifetime = 0; + time_t expire = 0, lastmod = 0, lifetime = 0; char *mask = parv[2], *target = parv[1], *reason = "No reason", *tmp = 0; if (parc < 3) @@ -170,13 +183,13 @@ ms_gline(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) if ((action == GLINE_LOCAL_ACTIVATE || action == GLINE_LOCAL_DEACTIVATE) && !IsMe(acptr)) { Debug((DEBUG_DEBUG, "I am forwarding a local change to a global gline " - "to a remote server; target %s, mask %s, operforce %s, action %s", + "to a remote server; target %s, mask %s, operforce %s, action %c", target, mask, flags & GLINE_OPERFORCE ? "YES" : "NO", - action == GLINE_LOCAL_ACTIVATE ? ">" : "<")); + action == GLINE_LOCAL_ACTIVATE ? '>' : '<')); sendcmdto_one(sptr, CMD_GLINE, acptr, "%C %s%c%s", acptr, flags & GLINE_OPERFORCE ? "!" : "", - action == GLINE_LOCAL_ACTIVATE ? ">" : "<", mask); + action == GLINE_LOCAL_ACTIVATE ? '>' : '<', mask); return 0; /* all done */ } @@ -203,7 +216,8 @@ ms_gline(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) if (parc < 5) /* check parameter count... */ return need_more_params(sptr, "GLINE"); - expire_off = atoi(parv[3]); /* get expiration... */ + expire = atoi(parv[3]); /* get expiration... */ + expire = abs_expire(expire); /* convert to absolute... */ reason = parv[parc - 1]; /* and reason */ if (IsMe(acptr)) { @@ -214,9 +228,9 @@ ms_gline(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) Debug((DEBUG_DEBUG, "I am creating a local G-line here; target %s, " "mask %s, operforce %s, action %s, expire %Tu, reason: %s", target, mask, flags & GLINE_OPERFORCE ? "YES" : "NO", - action == GLINE_ACTIVATE ? "+" : "-", expire_off, reason)); + action == GLINE_ACTIVATE ? "+" : "-", expire, reason)); - return gline_add(cptr, sptr, mask, reason, expire_off, lastmod, + return gline_add(cptr, sptr, mask, reason, expire, lastmod, lifetime, flags | GLINE_ACTIVE); } } else if (IsMe(acptr)) { /* destroying a local G-line */ @@ -241,16 +255,16 @@ ms_gline(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) assert(!IsMe(acptr)); Debug((DEBUG_DEBUG, "I am forwarding a local G-line to a remote server; " - "target %s, mask %s, operforce %s, action %s, expire %Tu, " + "target %s, mask %s, operforce %s, action %c, expire %Tu, " "lastmod %Tu, reason: %s", target, mask, flags & GLINE_OPERFORCE ? "YES" : "NO", - action == GLINE_ACTIVATE ? "+" : "-", expire_off, CurrentTime, + action == GLINE_ACTIVATE ? '+' : '-', expire, CurrentTime, reason)); sendcmdto_one(sptr, CMD_GLINE, acptr, "%C %s%c%s %Tu %Tu :%s", acptr, flags & GLINE_OPERFORCE ? "!" : "", - action == GLINE_ACTIVATE ? '+' : '-', mask, expire_off, - CurrentTime, reason); + action == GLINE_ACTIVATE ? '+' : '-', mask, + expire - CurrentTime, CurrentTime, reason); return 0; /* all done */ } @@ -265,6 +279,7 @@ ms_gline(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) case GLINE_LOCAL_DEACTIVATE: /* locally deactivating a G-line */ if (!agline) /* no G-line to locally activate or deactivate? */ return send_reply(sptr, ERR_NOSUCHGLINE, mask); + lastmod = agline->gl_lastmod; break; /* no additional parameters to manipulate */ case GLINE_ACTIVATE: /* activating a G-line */ @@ -278,10 +293,8 @@ ms_gline(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) case GLINE_MODIFY: /* modifying a G-line */ /* convert expire and lastmod, look for lifetime and reason */ if (parc > 4) { /* protect against fall-through from 4-param form */ - if (parc < 5) - return need_more_params(sptr, "GLINE"); - - expire_off = atoi(parv[3]); /* convert expiration and lastmod */ + expire = atoi(parv[3]); /* convert expiration and lastmod */ + expire = abs_expire(expire); lastmod = atoi(parv[4]); flags |= GLINE_EXPIRE; /* we have an expiration time update */ @@ -295,7 +308,7 @@ ms_gline(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) if (!agline || /* gline creation, has to be the reason */ /* trial-convert as lifetime, and if it doesn't fully convert, * it must be the reason */ - ((lifetime = strtoul(parv[5], &tmp, 10)) && !*tmp)) { + (!(lifetime = strtoul(parv[5], &tmp, 10)) && !*tmp)) { lifetime = 0; reason = parv[5]; @@ -318,7 +331,7 @@ ms_gline(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) (action == GLINE_DEACTIVATE ? "-" : (action == GLINE_LOCAL_ACTIVATE ? ">" : (action == GLINE_LOCAL_DEACTIVATE ? "<" : "(MODIFY)"))), - expire_off, lastmod, lifetime, reason, + expire, lastmod, lifetime, reason, agline ? "EXISTS" : "does not exist", flags & GLINE_EXPIRE ? "expire" : "", flags & GLINE_LIFETIME ? "lifetime" : "", @@ -328,14 +341,26 @@ ms_gline(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) * Let's actually do the action! */ if (agline) - return gline_modify(cptr, sptr, agline, action, reason, expire_off, + return gline_modify(cptr, sptr, agline, action, reason, expire, lastmod, lifetime, flags); assert(action != GLINE_LOCAL_ACTIVATE); assert(action != GLINE_LOCAL_DEACTIVATE); assert(action != GLINE_MODIFY); - return gline_add(cptr, sptr, mask, reason, expire_off, lastmod, lifetime, + if (!expire) { /* Cannot *add* a G-line we don't have, but try hard */ + Debug((DEBUG_DEBUG, "Propagating G-line %s for G-line we don't have", + action == GLINE_ACTIVATE ? "activation" : "deactivation")); + + /* propagate the G-line, even though we don't have it */ + sendcmdto_serv_butone(sptr, CMD_GLINE, cptr, "* %c%s %Tu", + action == GLINE_ACTIVATE ? '+' : '-', + mask, lastmod); + + return 0; + } + + return gline_add(cptr, sptr, mask, reason, expire, lastmod, lifetime, flags | ((action == GLINE_ACTIVATE) ? GLINE_ACTIVE : 0)); } @@ -354,8 +379,8 @@ mo_gline(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) struct Gline *agline = 0; unsigned int flags = 0; enum GlineAction action = GLINE_MODIFY; - time_t expire_off = 0; - char *mask = parv[1], *target = 0, *reason = 0; + time_t expire = 0; + char *mask = parv[1], *target = 0, *reason = 0, *end; if (parc < 2) return gline_list(sptr, 0); @@ -398,12 +423,14 @@ mo_gline(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) return need_more_params(sptr, "GLINE"); target = parv[2]; /* get the target... */ - expire_off = atoi(parv[3]); /* and the expiration */ + expire = strtol(parv[3], &end, 10) + CurrentTime; /* and the expiration */ + if (*end != '\0') + return send_reply(sptr, SND_EXPLICIT | ERR_BADEXPIRE, "%s :Bad expire time", parv[3]); flags |= GLINE_EXPIRE; /* remember that we got an expire time */ if (parc > 4) { /* also got a reason... */ - reason = parv[4]; + reason = parv[parc - 1]; flags |= GLINE_REASON; } @@ -418,8 +445,11 @@ mo_gline(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) case GLINE_LOCAL_ACTIVATE: /* locally activate a G-line */ case GLINE_LOCAL_DEACTIVATE: /* locally deactivate a G-line */ - if (parc > 2) /* if target is available, pick it */ + if (parc > 2) { /* if target is available, pick it */ target = parv[2]; + if (target[0] == '*' && target[1] == '\0') + return send_reply(sptr, ERR_NOSUCHSERVER, target); + } break; case GLINE_ACTIVATE: /* activating/adding a G-line */ @@ -429,8 +459,10 @@ mo_gline(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) if (parc > 3) { /* get expiration and target */ - expire_off = atoi(parv[parc - 2]); reason = parv[parc - 1]; + expire = strtol(parv[parc - 2], &end, 10) + CurrentTime; + if (*end != '\0') + return send_reply(sptr, SND_EXPLICIT | ERR_BADEXPIRE, "%s :Bad expire time", parv[parc - 2]); flags |= GLINE_EXPIRE | GLINE_REASON; /* remember that we got 'em */ @@ -470,13 +502,13 @@ mo_gline(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) return send_reply(sptr, ERR_NOPRIVILEGES); Debug((DEBUG_DEBUG, "I am forwarding a local change to a global gline " - "to a remote server; target %s, mask %s, operforce %s, action %s", + "to a remote server; target %s, mask %s, operforce %s, action %c", cli_name(acptr), mask, flags & GLINE_OPERFORCE ? "YES" : "NO", - action == GLINE_LOCAL_ACTIVATE ? ">" : "<")); + action == GLINE_LOCAL_ACTIVATE ? '>' : '<')); sendcmdto_one(sptr, CMD_GLINE, acptr, "%C %s%c%s", acptr, - flags & GLINE_OPERFORCE ? "!" : "", - action == GLINE_LOCAL_ACTIVATE ? ">" : "<", mask); + flags & GLINE_OPERFORCE ? "!" : "", + action == GLINE_LOCAL_ACTIVATE ? '>' : '<', mask); return 0; /* all done */ } @@ -514,15 +546,15 @@ mo_gline(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) return send_reply(sptr, ERR_NOPRIVILEGES); Debug((DEBUG_DEBUG, "I am forwarding a local G-line to a remote " - "server; target %s, mask %s, operforce %s, action %s, " + "server; target %s, mask %s, operforce %s, action %c, " "expire %Tu, reason %s", target, mask, flags & GLINE_OPERFORCE ? "YES" : "NO", - action == GLINE_ACTIVATE ? "+" : "-", expire_off, reason)); + action == GLINE_ACTIVATE ? '+' : '-', expire, reason)); sendcmdto_one(sptr, CMD_GLINE, acptr, "%C %s%c%s %Tu %Tu :%s", acptr, flags & GLINE_OPERFORCE ? "!" : "", - action == GLINE_ACTIVATE ? "+" : "-", mask, expire_off, - CurrentTime, reason); + action == GLINE_ACTIVATE ? '+' : '-', mask, + expire - CurrentTime, CurrentTime, reason); return 0; /* all done */ } @@ -540,9 +572,9 @@ mo_gline(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) Debug((DEBUG_DEBUG, "I am creating a local G-line here; target %s, " "mask %s, operforce %s, action %s, expire %Tu, reason: %s", target, mask, flags & GLINE_OPERFORCE ? "YES" : "NO", - action == GLINE_ACTIVATE ? "+" : "-", expire_off, reason)); + action == GLINE_ACTIVATE ? "+" : "-", expire, reason)); - return gline_add(cptr, sptr, mask, reason, expire_off, 0, 0, + return gline_add(cptr, sptr, mask, reason, expire, 0, 0, flags | GLINE_ACTIVE); } else { /* OK, it's a deactivation/destruction */ if (!agline) /* G-line doesn't exist, so let's complain... */ @@ -558,10 +590,12 @@ mo_gline(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) } } - /* can't modify a G-line that doesn't exist... */ + /* can't modify a G-line that doesn't exist... + * (and if we are creating a new one, we need a reason and expiration) + */ if (!agline && (action == GLINE_MODIFY || action == GLINE_LOCAL_ACTIVATE || - action == GLINE_LOCAL_DEACTIVATE)) + action == GLINE_LOCAL_DEACTIVATE || !reason || !expire)) return send_reply(sptr, ERR_NOSUCHGLINE, mask); /* check for G-line permissions... */ @@ -584,12 +618,12 @@ mo_gline(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) (action == GLINE_DEACTIVATE ? "-" : (action == GLINE_LOCAL_ACTIVATE ? ">" : (action == GLINE_LOCAL_DEACTIVATE ? "<" : "(MODIFY)"))), - expire_off, reason, agline ? "EXISTS" : "does not exist", + expire, reason, agline ? "EXISTS" : "does not exist", flags & GLINE_EXPIRE ? "expire" : "", flags & GLINE_REASON ? "reason" : "")); if (agline) /* modifying an existing G-line */ - return gline_modify(cptr, sptr, agline, action, reason, expire_off, + return gline_modify(cptr, sptr, agline, action, reason, expire, CurrentTime, 0, flags); assert(action != GLINE_LOCAL_ACTIVATE); @@ -597,7 +631,7 @@ mo_gline(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) assert(action != GLINE_MODIFY); /* create a new G-line */ - return gline_add(cptr, sptr, mask, reason, expire_off, CurrentTime, 0, + return gline_add(cptr, sptr, mask, reason, expire, CurrentTime, 0, flags | ((action == GLINE_ACTIVATE) ? GLINE_ACTIVE : 0)); }