/** * noop.C: OperServ NOOP command. * * Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team * Rights to this code are as documented in COPYING. * * * Portions of this file were derived from sources bearing the following license: * Copyright © 2005-2006 William Pitcock, et al. * Rights to this code are as documented in doc/pod/license.pod. * * $Id: noop.C,v 1.9 2007/09/22 14:27:28 pippijn Exp $ */ #include "atheme.h" #include "servers.h" #include static char const rcsid[] = "$Id: noop.C,v 1.9 2007/09/22 14:27:28 pippijn Exp $"; REGISTER_MODULE ("operserv/noop", true, "The Ermyth Team "); typedef struct noop_ noop_t; struct noop_ { char *target; char *added_by; char *reason; }; list_t noop_hostmask_list; list_t noop_server_list; static void os_cmd_noop (sourceinfo_t *si, int parc, char *parv[]); command_t const os_noop = { "NOOP", N_("Restricts IRCop access."), PRIV_NOOP, 4, os_cmd_noop }; E cmdvec os_cmdtree; E helpvec os_helptree; static void check_user (user_t *u) { node_t *n; char hostbuf[BUFSIZE]; snprintf (hostbuf, BUFSIZE, "%s!%s@%s", u->nick, u->user, u->host); LIST_FOREACH (n, noop_hostmask_list.head) { noop_t *np = static_cast < noop_t * >(n->data); if (!match (np->target, hostbuf)) { phandler->skill (opersvs.nick, u->nick, "Operator access denied to hostmask: %s [%s] <%s@%s>", np->target, np->reason, np->added_by, opersvs.nick); user_delete (u); return; } } LIST_FOREACH (n, noop_server_list.head) { noop_t *np = static_cast < noop_t * >(n->data); if (!match (np->target, u->server->name)) { phandler->skill (opersvs.nick, u->nick, "Operator access denied to server: %s [%s] <%s@%s>", np->target, np->reason, np->added_by, opersvs.nick); user_delete (u); return; } } } static noop_t * noop_find (char *target, list_t *list) { node_t *n; LIST_FOREACH (n, list->head) { noop_t *np = static_cast < noop_t * >(n->data); if (!match (np->target, target)) return np; } return NULL; } /* NOOP [reason] */ static void os_cmd_noop (sourceinfo_t *si, int parc, char *parv[]) { node_t *n; noop_t *np; char *action = parv[0]; char *type = parv[1]; char *mask = parv[2]; char *reason = parv[3]; if (!action || !type) { command_fail (si, fault::needmoreparams, STR_INSUFFICIENT_PARAMS, "NOOP"); command_fail (si, fault::needmoreparams, _("Syntax: NOOP [reason]")); return; } if (!strcasecmp (action, "ADD")) { if (!strcasecmp (type, "HOSTMASK")) { if (!mask) { command_fail (si, fault::needmoreparams, STR_INSUFFICIENT_PARAMS, "NOOP"); command_fail (si, fault::needmoreparams, _("Syntax: NOOP [reason]")); return; } if ((np = noop_find (mask, &noop_hostmask_list))) { command_fail (si, fault::nochange, _("There is already a NOOP entry covering this target.")); return; } np = new noop_t; np->target = sstrdup (mask); np->added_by = sstrdup (get_oper_name (si)); if (reason) np->reason = sstrdup (reason); else np->reason = sstrdup ("Abusive operator."); n = node_create (); node_add (np, n, &noop_hostmask_list); logcommand (si, CMDLOG_ADMIN, "NOOP ADD HOSTMASK %s %s", np->target, np->reason); command_success_nodata (si, _("Added \2%s\2 to the hostmask NOOP list."), mask); return; } else if (!strcasecmp (type, "SERVER")) { if (!mask) { command_fail (si, fault::needmoreparams, STR_INSUFFICIENT_PARAMS, "NOOP"); command_fail (si, fault::needmoreparams, _("Syntax: NOOP [reason]")); return; } if ((np = noop_find (mask, &noop_server_list))) { command_fail (si, fault::nochange, _("There is already a NOOP entry covering this target.")); return; } np = new noop_t; np->target = sstrdup (mask); np->added_by = sstrdup (get_oper_name (si)); if (reason) np->reason = sstrdup (reason); else np->reason = sstrdup ("Abusive operator."); n = node_create (); node_add (np, n, &noop_server_list); logcommand (si, CMDLOG_ADMIN, "NOOP ADD SERVER %s %s", np->target, np->reason); command_success_nodata (si, _("Added \2%s\2 to the server NOOP list."), mask); return; } else { command_fail (si, fault::needmoreparams, STR_INSUFFICIENT_PARAMS, "NOOP"); command_fail (si, fault::needmoreparams, _("Syntax: NOOP ADD [reason]")); } } else if (!strcasecmp (action, "DEL")) { if (!strcasecmp (type, "HOSTMASK")) { if (!mask) { command_fail (si, fault::needmoreparams, STR_INSUFFICIENT_PARAMS, "NOOP"); command_fail (si, fault::needmoreparams, _("Syntax: NOOP [reason]")); return; } if (!(np = noop_find (mask, &noop_hostmask_list))) { command_fail (si, fault::nosuch_target, _("There is no NOOP hostmask entry for this target.")); return; } logcommand (si, CMDLOG_ADMIN, "NOOP DEL HOSTMASK %s", np->target); command_success_nodata (si, _("Removed \2%s\2 from the hostmask NOOP list."), np->target); n = node_find (np, &noop_hostmask_list); sfree (np->target); sfree (np->added_by); sfree (np->reason); node_del (n, &noop_hostmask_list); node_free (n); delete np; return; } else if (!strcasecmp (type, "SERVER")) { if (!(np = noop_find (mask, &noop_server_list))) { command_fail (si, fault::nosuch_target, _("There is no NOOP server entry for this target.")); return; } logcommand (si, CMDLOG_ADMIN, "NOOP DEL SERVER %s", np->target); command_success_nodata (si, _("Removed \2%s\2 from the server NOOP list."), np->target); n = node_find (np, &noop_server_list); sfree (np->target); sfree (np->added_by); sfree (np->reason); node_del (n, &noop_server_list); node_free (n); delete np; return; } else { command_fail (si, fault::needmoreparams, STR_INSUFFICIENT_PARAMS, "NOOP"); command_fail (si, fault::needmoreparams, _("Syntax: NOOP DEL ")); } } else if (!strcasecmp (action, "LIST")) { if (!strcasecmp (type, "HOSTMASK")) { unsigned int i = 1; logcommand (si, CMDLOG_GET, "NOOP LIST HOSTMASK"); command_success_nodata (si, _("Hostmask NOOP list (%d entries):"), noop_hostmask_list.count); command_success_nodata (si, " "); command_success_nodata (si, _("Entry Hostmask Adder Reason")); command_success_nodata (si, "----- ------------------------------- --------------------- --------------------------"); LIST_FOREACH (n, noop_hostmask_list.head) { np = static_cast < noop_t * >(n->data); command_success_nodata (si, "%-5d %-31s %-21s %s", i, np->target, np->added_by, np->reason); i++; } command_success_nodata (si, "----- ------------------------------- --------------------- --------------------------"); command_success_nodata (si, _("End of Hostmask NOOP list.")); } else if (!strcasecmp (type, "SERVER")) { unsigned int i = 1; logcommand (si, CMDLOG_GET, "NOOP LIST SERVER"); command_success_nodata (si, _("Server NOOP list (%d entries):"), noop_server_list.count); command_success_nodata (si, " "); command_success_nodata (si, _("Entry Hostmask Adder Reason")); command_success_nodata (si, "----- ------------------------------- --------------------- --------------------------"); LIST_FOREACH (n, noop_server_list.head) { np = static_cast < noop_t * >(n->data); command_success_nodata (si, "%-5d %-31s %-21s %s", i, np->target, np->added_by, np->reason); i++; } command_success_nodata (si, "----- ------------------------------- --------------------- --------------------------"); command_success_nodata (si, _("End of Server NOOP list.")); } else { command_fail (si, fault::needmoreparams, STR_INSUFFICIENT_PARAMS, "NOOP"); command_fail (si, fault::needmoreparams, _("Syntax: NOOP LIST ")); } } } bool _modinit (module *m) { os_cmdtree << os_noop; help_addentry (os_helptree, "NOOP", "help/operserv/noop", NULL); user_t::callback.oper.attach (check_user); return true; } void _moddeinit () { os_cmdtree >> os_noop; help_delentry (os_helptree, "NOOP"); user_t::callback.oper.detach (check_user); }