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

View file

@ -1,23 +1,6 @@
/* /*
* Copyright (C) 2006 Jilles Tjoelker * Copyright (C) 2006 Jilles Tjoelker
* Copyright (C) 2006 Stephen Bennett <spb@gentoo.org> * 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" #include "stdinc.h"
@ -30,161 +13,170 @@
#include "s_serv.h" #include "s_serv.h"
#include "s_conf.h" #include "s_conf.h"
#include "s_newconf.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 static int do_grant(struct Client *source_p, struct Client *target_p, const char *new_privset);
void set_mode(struct Client *const target,
const char *const str) 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[] = struct Client *target_p;
{
target->name,
target->name,
str,
NULL
};
user_mode(target, target, 3, mode); if(!HasPrivilege(source_p, "oper:grant"))
}
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"))
{ {
sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "grant"); sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "grant");
return; 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; return;
} }
struct Client *const target_p = find_person(parv[1]); if (MyClient(target_p))
if(!target_p)
{ {
if(IsPerson(source_p)) do_grant(source_p, target_p, parv[2]);
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))
{
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", sendto_one(target_p, ":%s ENCAP %s GRANT %s %s",
get_id(source_p, target_p), get_id(source_p, target_p), target_p->servptr->name,
target_p->servptr->name, get_id(target_p, target_p), parv[2]);
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, sendto_one_numeric(source_p, ERR_NOSUCHNICK,
mg_not_oper, form_str(ERR_NOSUCHNICK), parv[1]);
mg_ignore, return;
mg_ignore,
{ grant, 3 },
{ grant, 3 }
} }
};
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, int dooper = 0, dodeoper = 0;
NULL struct PrivilegeSet *privset = 0;
};
static const char grant_desc[] = if (!strcasecmp(new_privset, "deoper"))
"Provides the grant facility for giving other users specific privilege sets"; {
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 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);
grant, }
NULL, else
NULL, {
grant_clist, if (!(privset = privilegeset_get(new_privset)))
NULL, {
NULL, sendto_one_notice(source_p, ":There is no privilege set named '%s'.", new_privset);
NULL, return 0;
NULL, }
grant_desc
); 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;
}