diff --git a/modules/m_grant.c b/modules/m_grant.c index 13ee6aa4..1f0b0502 100644 --- a/modules/m_grant.c +++ b/modules/m_grant.c @@ -1,6 +1,23 @@ /* * Copyright (C) 2006 Jilles Tjoelker * Copyright (C) 2006 Stephen Bennett + * Copyright (C) 2016 Jason Volk + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice is present in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #include "stdinc.h" @@ -13,153 +30,156 @@ #include "s_serv.h" #include "s_conf.h" #include "s_newconf.h" +#include "privilege.h" -static const char grant_desc[] = - "Provides the grant facility for giving other users specific privilege sets"; -static void mo_grant(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]); -static void me_grant(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]); - -static void do_grant(struct Client *source_p, struct Client *target_p, const char *new_privset); - -struct Message grant_msgtab = { - "GRANT", 0, 0, 0, 0, - { mg_ignore, mg_not_oper, mg_ignore, mg_ignore, {me_grant, 3}, {mo_grant, 3}} -}; - -mapi_clist_av1 grant_clist[] = { &grant_msgtab, NULL }; - -DECLARE_MODULE_AV2(grant, NULL, NULL, grant_clist, NULL, NULL, NULL, NULL, grant_desc); - -static void -mo_grant(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) +static +void set_mode(struct Client *const target, + const char *const str) { - struct Client *target_p; + const char *mode[] = + { + target->name, + target->name, + str, + NULL + }; + user_mode(target, target, 3, mode); +} + + +static +void set_privset(struct Client *const source, + struct Client *const target, + const char *const privset_name) +{ + struct PrivilegeSet *const privset = privilegeset_get(privset_name); + if(!privset) + { + sendto_one_notice(source, ":There is no privilege set named '%s'.", privset_name); + return; + } + + if(IsOper(target) && target->localClient->privset == privset) + { + sendto_one_notice(source, ":%s already has role of %s.", target->name, privset_name); + return; + } + + if(IsOper(target)) + { + sendto_one_notice(target, ":%s has changed your role to %s.", source->name, privset_name); + sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "%s has changed %s's role to %s.", get_oper_name(source), target->name, privset_name); + target->localClient->privset = privset; + return; + } + + struct oper_conf oper = + { + .name = (char *)privset->name, + .privset = privset, + }; + + oper_up(target, &oper); + set_mode(target, "+o"); + sendto_one_notice(target, ":%s has granted you the role of %s.", source->name, privset_name); + sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "%s has granted %s the role of %s.", get_oper_name(source), target->name, privset_name); +} + + +static +void grant_revoke(struct Client *const source, + struct Client *const target) +{ + if(!IsOper(target)) + { + sendto_one_notice(source, ":You can't deoper someone who isn't an oper."); + return; + } + + set_mode(target, "-o"); + sendto_one_notice(target, ":%s has deopered you.", source->name); + sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "%s has deopered %s.", get_oper_name(source), target->name); +} + + +static +void grant(struct MsgBuf *msgbuf, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) +{ if(!HasPrivilege(source_p, "oper:grant")) { sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "grant"); return; } - target_p = find_named_person(parv[1]); - if (target_p == NULL) + if(parc < 3) { - sendto_one_numeric(source_p, ERR_NOSUCHNICK, - form_str(ERR_NOSUCHNICK), parv[1]); + sendto_one_notice(source_p, ":usage GRANT: "); return; } - if (MyClient(target_p)) + struct Client *const target_p = find_person(parv[1]); + + if(!target_p) { - do_grant(source_p, target_p, parv[2]); + if(IsPerson(source_p)) + sendto_one_numeric(source_p, ERR_NOSUCHNICK, form_str(ERR_NOSUCHNICK), parv[1]); + + return; } - else + + if(!find_shared_conf(source_p->username, source_p->host, source_p->servptr->name, SHARED_GRANT)) + { + sendto_one_notice(source_p, ":GRANT failed: You have no shared configuration block on this server."); + return; + } + + if(MyClient(target_p)) + { + if(irccmp(parv[2], "revoke") == 0) + grant_revoke(source_p, target_p); + else + set_privset(source_p, target_p, parv[2]); + } + else if(MyClient(source_p)) { sendto_one(target_p, ":%s ENCAP %s GRANT %s %s", - get_id(source_p, target_p), target_p->servptr->name, - get_id(target_p, target_p), parv[2]); + get_id(source_p, target_p), + target_p->servptr->name, + get_id(target_p, target_p), + parv[2]); } + + return; } -static void -me_grant(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) +struct Message msgtab = { - struct Client *target_p; - - target_p = find_person(parv[1]); - if (target_p == NULL) + "GRANT", 0, 0, 0, 0, { - sendto_one_numeric(source_p, ERR_NOSUCHNICK, - form_str(ERR_NOSUCHNICK), parv[1]); - return; + mg_ignore, + mg_not_oper, + mg_ignore, + mg_ignore, + { grant, 3 }, + { grant, 3 } } +}; - if(!find_shared_conf(source_p->username, source_p->host, - source_p->servptr->name, SHARED_GRANT)) - { - sendto_one(source_p, ":%s NOTICE %s :You don't have an appropriate shared" - "block to grant privilege on this server.", me.name, source_p->name); - return; - } - - do_grant(source_p, target_p, parv[2]); -} - - -static void -do_grant(struct Client *source_p, struct Client *target_p, const char *new_privset) +mapi_clist_av1 clist[] = { - int dooper = 0, dodeoper = 0; - struct PrivilegeSet *privset = 0; - const char *modeparv[4]; + &msgtab, + NULL +}; - if (!strcmp(new_privset, "deoper")) - { - if (!IsOper(target_p)) - { - sendto_one_notice(source_p, ":You can't deoper someone who isn't an oper."); - return; - } - new_privset = "default"; - dodeoper = 1; - - sendto_one_notice(target_p, ":%s is deopering you.", source_p->name); - sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "%s is deopering %s.", get_oper_name(source_p), target_p->name); - } - else - { - if (!(privset = privilegeset_get(new_privset))) - { - sendto_one_notice(source_p, ":There is no privilege set named '%s'.", new_privset); - return; - } - - if (privset == target_p->localClient->privset) - { - sendto_one_notice(source_p, ":%s already has privilege set %s.", target_p->name, target_p->localClient->privset->name); - return; - } - } - - if (!dodeoper) - { - if (!IsOper(target_p)) - { - sendto_one_notice(target_p, ":%s is opering you with privilege set %s", source_p->name, privset->name); - sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "%s is opering %s with privilege set %s", get_oper_name(source_p), target_p->name, privset->name); - dooper = 1; - } - else - { - sendto_one_notice(target_p, ":%s is changing your privilege set to %s", source_p->name, privset->name); - sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "%s is changing the privilege set of %s to %s", get_oper_name(source_p), target_p->name, privset->name); - } - } - - if (dodeoper) - { - const char *modeparv[4]; - modeparv[0] = modeparv[1] = target_p->name; - modeparv[2] = "-o"; - modeparv[3] = NULL; - user_mode(target_p, target_p, 3, modeparv); - } - - if (dooper) - { - struct oper_conf oper; - oper.name = ""; - oper.umodes = 0; - oper.snomask = 0; - oper.privset = privset; - - oper_up(target_p, &oper); - } - - target_p->localClient->privset = privset; - modeparv[0] = modeparv[1] = target_p->name; - modeparv[2] = "+"; - modeparv[3] = NULL; - user_mode(target_p, target_p, 3, modeparv); -} +DECLARE_MODULE_AV1 +( + grant, + NULL, + NULL, + clist, + NULL, + NULL, + "$Revision$" +);