Merge pull request #283 from edk0/grant

m_grant improvements
This commit is contained in:
Aaron Jones 2019-09-14 23:39:40 +00:00 committed by GitHub
commit 2f2a26fe9d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 168 additions and 167 deletions

9
help/opers/grant Normal file
View file

@ -0,0 +1,9 @@
GRANT <target> deoper
Removes oper status from <target>.
GRANT <target> <privset>
Opers <target> with the privset <privset>.
- Requires Oper Priv: grant

View file

@ -3,22 +3,22 @@ Help topics available to opers:
ACCEPT ADMIN AWAY CAPAB
CHALLENGE CHANTRACE CLOSE CMODE
CONNECT CREDITS DIE DLINE
ERROR ETRACE EXTBAN HELP
INDEX INFO INVITE ISON
JOIN KICK KILL KLINE
KNOCK LINKS LIST LOCOPS
LUSERS MAP MASKTRACE MODLIST
MODLOAD MODRELOAD MODRESTART MODUNLOAD
MONITOR MOTD NAMES NICK
NOTICE OPER OPERSPY OPERWALL
PART PASS PING PONG
POST PRIVMSG PRIVS QUIT
REHASH RESTART RESV SCAN
SERVER SET SJOIN SNOMASK
SQUIT STATS SVINFO TESTGECOS
TESTLINE TESTMASK TIME TOPIC
TRACE UHELP UMODE UNDLINE
UNKLINE UNREJECT UNRESV UNXLINE
USER USERHOST USERS VERSION
WALLOPS WHO WHOIS WHOWAS
XLINE
ERROR ETRACE EXTBAN GRANT
HELP INDEX INFO INVITE
ISON JOIN KICK KILL
KLINE KNOCK LINKS LIST
LOCOPS LUSERS MAP MASKTRACE
MODLIST MODLOAD MODRELOAD MODRESTART
MODUNLOAD MONITOR MOTD NAMES
NICK NOTICE OPER OPERSPY
OPERWALL PART PASS PING
PONG POST PRIVMSG PRIVS
QUIT REHASH RESTART RESV
SCAN SERVER SET SJOIN
SNOMASK SQUIT STATS SVINFO
TESTGECOS TESTLINE TESTMASK TIME
TOPIC TRACE UHELP UMODE
UNDLINE UNKLINE UNREJECT UNRESV
UNXLINE USER USERHOST USERS
VERSION WALLOPS WHO WHOIS
WHOWAS XLINE

View file

@ -1,23 +1,6 @@
/*
* Copyright (C) 2006 Jilles Tjoelker
* Copyright (C) 2006 Stephen Bennett <spb@gentoo.org>
* Copyright (C) 2016 Jason Volk <jason@zemos.net>
*
* 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"
@ -30,161 +13,170 @@
#include "s_serv.h"
#include "s_conf.h"
#include "s_newconf.h"
#include "privilege.h"
#include "msgbuf.h"
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 set_mode(struct Client *const target,
const char *const str)
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}}
};
mapi_clist_av1 grant_clist[] = { &grant_msgtab, NULL };
static const char grant_desc[] = "Allows operators to set or remove operator privileges on other users";
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[])
{
const char *mode[] =
{
target->name,
target->name,
str,
NULL
};
struct Client *target_p;
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->user->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->user->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(MyClient(source_p) && !HasPrivilege(source_p, "oper:grant"))
if(!HasPrivilege(source_p, "oper:grant"))
{
sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "grant");
return;
}
if(parc < 3)
target_p = find_named_person(parv[1]);
if (target_p == NULL)
{
sendto_one_notice(source_p, ":usage GRANT: <target nickname> <privilegese name | 'revoke'>");
sendto_one_numeric(source_p, ERR_NOSUCHNICK,
form_str(ERR_NOSUCHNICK), parv[1]);
return;
}
struct Client *const target_p = find_person(parv[1]);
if(!target_p)
if (MyClient(target_p))
{
if(IsPerson(source_p))
sendto_one_numeric(source_p, ERR_NOSUCHNICK, form_str(ERR_NOSUCHNICK), parv[1]);
return;
do_grant(source_p, target_p, parv[2]);
}
if(!MyClient(source_p) && !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))
else
{
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;
}
struct Message msgtab =
static void
me_grant(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
"GRANT", 0, 0, 0, 0,
struct Client *target_p;
target_p = find_person(parv[1]);
if (target_p == NULL)
{
mg_ignore,
mg_not_oper,
mg_ignore,
mg_ignore,
{ grant, 3 },
{ grant, 3 }
sendto_one_numeric(source_p, ERR_NOSUCHNICK,
form_str(ERR_NOSUCHNICK), parv[1]);
return;
}
};
mapi_clist_av1 grant_clist[] =
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 int do_grant(struct Client *source_p, struct Client *target_p, const char *new_privset)
{
&msgtab,
NULL
};
int dooper = 0, dodeoper = 0;
struct PrivilegeSet *privset = 0;
static const char grant_desc[] =
"Provides the grant facility for giving other users specific privilege sets";
if (!strcasecmp(new_privset, "deoper"))
{
if (!IsOper(target_p))
{
sendto_one_notice(source_p, ":You can't deoper someone who isn't an oper.");
return 0;
}
dodeoper = 1;
DECLARE_MODULE_AV2
(
grant,
NULL,
NULL,
grant_clist,
NULL,
NULL,
NULL,
NULL,
grant_desc
);
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 0;
}
if (privset == target_p->user->privset)
{
sendto_one_notice(source_p, ":%s already has privilege set %s.", target_p->name, target_p->user->privset->name);
return 0;
}
}
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 (!IsOper(target_p))
{
dooper = 1;
}
}
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 = "<grant>";
oper.umodes = 0;
oper.snomask = 0;
oper.privset = privset;
oper_up(target_p, &oper);
}
else if (privset != NULL)
{
privilegeset_ref(privset);
}
if (target_p->user->privset != NULL)
privilegeset_unref(target_p->user->privset);
target_p->user->privset = privset;
if (privset != NULL)
sendto_server(NULL, NULL, CAP_TS6, NOCAPS, ":%s OPER %s %s",
use_id(target_p), target_p->user->opername, privset->name);
const char *modeparv[4];
modeparv[0] = modeparv[1] = target_p->name;
modeparv[2] = "+";
modeparv[3] = NULL;
user_mode(target_p, target_p, 3, modeparv);
return 0;
}