X-Git-Url: https://jfr.im/git/solanum.git/blobdiff_plain/105a4985b402b3ab294e3bec1fa75bac75430482..ed3ca2ff16a1dc921d90c0a67093de8f47209176:/modules/m_grant.c diff --git a/modules/m_grant.c b/modules/m_grant.c index fe41d1a1..3788fb95 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,154 +30,161 @@ #include "s_serv.h" #include "s_conf.h" #include "s_newconf.h" +#include "privilege.h" -static int mo_grant(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]); -static int me_grant(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]); -static int 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}} -}; +static +void set_mode(struct Client *const target, + const char *const str) +{ + const char *mode[] = + { + target->name, + target->name, + str, + NULL + }; -mapi_clist_av1 grant_clist[] = { &grant_msgtab, NULL }; + user_mode(target, target, 3, mode); +} -DECLARE_MODULE_AV2(grant, NULL, NULL, grant_clist, NULL, NULL, NULL, NULL, NULL); -static int -mo_grant(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) +static +void set_privset(struct Client *const source, + struct Client *const target, + const char *const privset_name) { - struct Client *target_p; - - if(!HasPrivilege(source_p, "oper:grant")) + struct PrivilegeSet *const privset = privilegeset_get(privset_name); + if(!privset) { - sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "grant"); - return 0; + sendto_one_notice(source, ":There is no privilege set named '%s'.", privset_name); + return; } - target_p = find_named_person(parv[1]); - if (target_p == NULL) + if(IsOper(target) && target->user->privset == privset) { - sendto_one_numeric(source_p, ERR_NOSUCHNICK, - form_str(ERR_NOSUCHNICK), parv[1]); - return 0; + sendto_one_notice(source, ":%s already has role of %s.", target->name, privset_name); + return; } - if (MyClient(target_p)) + if(IsOper(target)) { - do_grant(source_p, target_p, parv[2]); + 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->user->privset = privset; + return; } - else + + struct oper_conf oper = { - 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]); + .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; } - return 0; + 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 int me_grant(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) -{ - struct Client *target_p; - target_p = find_person(parv[1]); - if (target_p == NULL) +static +void grant(struct MsgBuf *msgbuf, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) +{ + if(MyClient(source_p) && !HasPrivilege(source_p, "oper:grant")) { - sendto_one_numeric(source_p, ERR_NOSUCHNICK, - form_str(ERR_NOSUCHNICK), parv[1]); - return 0; + sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "grant"); + return; } - if(!find_shared_conf(source_p->username, source_p->host, - source_p->servptr->name, SHARED_GRANT)) + if(parc < 3) { - 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 0; + sendto_one_notice(source_p, ":usage GRANT: "); + return; } - do_grant(source_p, target_p, parv[2]); + struct Client *const target_p = find_person(parv[1]); - return 0; -} - - -static int do_grant(struct Client *source_p, struct Client *target_p, const char *new_privset) -{ - int dooper = 0, dodeoper = 0; - struct PrivilegeSet *privset = 0; - - if (!strcmp(new_privset, "deoper")) + if(!target_p) { - if (!IsOper(target_p)) - { - sendto_one_notice(source_p, ":You can't deoper someone who isn't an oper."); - return 0; - } - 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); + if(IsPerson(source_p)) + sendto_one_numeric(source_p, ERR_NOSUCHNICK, form_str(ERR_NOSUCHNICK), parv[1]); + + return; } - else + + if(!MyClient(source_p) && !find_shared_conf(source_p->username, source_p->host, source_p->servptr->name, SHARED_GRANT)) { - if (!(privset = privilegeset_get(new_privset))) - { - sendto_one_notice(source_p, ":There is no privilege set named '%s'.", new_privset); - return 0; - } - - 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 0; - } + sendto_one_notice(source_p, ":GRANT failed: You have no shared configuration block on this server."); + return; } - if (!dodeoper) + if(MyClient(target_p)) { - 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; - } + if(irccmp(parv[2], "revoke") == 0) + grant_revoke(source_p, target_p); 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); - } + set_privset(source_p, target_p, parv[2]); } - - if (dodeoper) + else if(MyClient(source_p)) { - 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); + 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]); } - if (dooper) - { - struct oper_conf oper; - oper.name = ""; - oper.umodes = 0; - oper.snomask = 0; - oper.privset = privset; + return; +} - oper_up(target_p, &oper); +struct Message msgtab = +{ + "GRANT", 0, 0, 0, 0, + { + mg_ignore, + mg_not_oper, + mg_ignore, + mg_ignore, + { grant, 3 }, + { grant, 3 } } +}; - target_p->localClient->privset = privset; - const char *modeparv[4]; - modeparv[0] = modeparv[1] = target_p->name; - modeparv[2] = "+"; - modeparv[3] = NULL; - user_mode(target_p, target_p, 3, modeparv); +mapi_clist_av1 grant_clist[] = +{ + &msgtab, + NULL +}; - return 0; -} +static const char grant_desc[] = + "Provides the grant facility for giving other users specific privilege sets"; + +DECLARE_MODULE_AV2 +( + grant, + NULL, + NULL, + grant_clist, + NULL, + NULL, + NULL, + NULL, + grant_desc +);