ircd: implement support for remote module load/unload/etc commands
This commit is contained in:
parent
cc7ae51cdc
commit
15feac531c
4 changed files with 188 additions and 63 deletions
|
@ -673,6 +673,7 @@ shared {
|
|||
* undline - allow removing dlines
|
||||
* grant - allow granting operator status
|
||||
* die - allow remote DIE/RESTART
|
||||
* module - allow remote module commands
|
||||
* none - disallow everything
|
||||
*/
|
||||
|
||||
|
|
|
@ -82,22 +82,23 @@ struct remote_conf
|
|||
};
|
||||
|
||||
/* flags used in shared/cluster */
|
||||
#define SHARED_TKLINE 0x0001
|
||||
#define SHARED_PKLINE 0x0002
|
||||
#define SHARED_UNKLINE 0x0004
|
||||
#define SHARED_LOCOPS 0x0008
|
||||
#define SHARED_TXLINE 0x0010
|
||||
#define SHARED_PXLINE 0x0020
|
||||
#define SHARED_UNXLINE 0x0040
|
||||
#define SHARED_TRESV 0x0080
|
||||
#define SHARED_PRESV 0x0100
|
||||
#define SHARED_UNRESV 0x0200
|
||||
#define SHARED_REHASH 0x0400
|
||||
#define SHARED_TDLINE 0x0800
|
||||
#define SHARED_PDLINE 0x1000
|
||||
#define SHARED_UNDLINE 0x2000
|
||||
#define SHARED_GRANT 0x4000
|
||||
#define SHARED_DIE 0x8000
|
||||
#define SHARED_TKLINE 0x00001
|
||||
#define SHARED_PKLINE 0x00002
|
||||
#define SHARED_UNKLINE 0x00004
|
||||
#define SHARED_LOCOPS 0x00008
|
||||
#define SHARED_TXLINE 0x00010
|
||||
#define SHARED_PXLINE 0x00020
|
||||
#define SHARED_UNXLINE 0x00040
|
||||
#define SHARED_TRESV 0x00080
|
||||
#define SHARED_PRESV 0x00100
|
||||
#define SHARED_UNRESV 0x00200
|
||||
#define SHARED_REHASH 0x00400
|
||||
#define SHARED_TDLINE 0x00800
|
||||
#define SHARED_PDLINE 0x01000
|
||||
#define SHARED_UNDLINE 0x02000
|
||||
#define SHARED_GRANT 0x04000
|
||||
#define SHARED_DIE 0x08000
|
||||
#define SHARED_MODULE 0x10000
|
||||
|
||||
#define SHARED_ALL (SHARED_TKLINE | SHARED_PKLINE | SHARED_UNKLINE |\
|
||||
SHARED_PXLINE | SHARED_TXLINE | SHARED_UNXLINE |\
|
||||
|
|
216
ircd/modules.c
216
ircd/modules.c
|
@ -25,8 +25,6 @@
|
|||
*/
|
||||
|
||||
#include "stdinc.h"
|
||||
|
||||
|
||||
#include "modules.h"
|
||||
#include "logger.h"
|
||||
#include "ircd.h"
|
||||
|
@ -38,7 +36,7 @@
|
|||
#include "parse.h"
|
||||
#include "ircd_defs.h"
|
||||
#include "match.h"
|
||||
|
||||
#include "s_serv.h"
|
||||
|
||||
#include <ltdl.h>
|
||||
|
||||
|
@ -73,29 +71,41 @@ static int mo_modreload(struct Client *, struct Client *, int, const char **);
|
|||
static int mo_modunload(struct Client *, struct Client *, int, const char **);
|
||||
static int mo_modrestart(struct Client *, struct Client *, int, const char **);
|
||||
|
||||
static int me_modload(struct Client *, struct Client *, int, const char **);
|
||||
static int me_modlist(struct Client *, struct Client *, int, const char **);
|
||||
static int me_modreload(struct Client *, struct Client *, int, const char **);
|
||||
static int me_modunload(struct Client *, struct Client *, int, const char **);
|
||||
static int me_modrestart(struct Client *, struct Client *, int, const char **);
|
||||
|
||||
static int do_modload(struct Client *, const char *);
|
||||
static int do_modunload(struct Client *, const char *);
|
||||
static int do_modreload(struct Client *, const char *);
|
||||
static int do_modlist(struct Client *, const char *);
|
||||
static int do_modrestart(struct Client *);
|
||||
|
||||
struct Message modload_msgtab = {
|
||||
"MODLOAD", 0, 0, 0, MFLG_SLOW,
|
||||
{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_modload, 2}}
|
||||
{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, {me_modload, 2}, {mo_modload, 2}}
|
||||
};
|
||||
|
||||
struct Message modunload_msgtab = {
|
||||
"MODUNLOAD", 0, 0, 0, MFLG_SLOW,
|
||||
{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_modunload, 2}}
|
||||
{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, {me_modunload, 2}, {mo_modunload, 2}}
|
||||
};
|
||||
|
||||
struct Message modreload_msgtab = {
|
||||
"MODRELOAD", 0, 0, 0, MFLG_SLOW,
|
||||
{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_modreload, 2}}
|
||||
{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, {me_modreload, 2}, {mo_modreload, 2}}
|
||||
};
|
||||
|
||||
struct Message modlist_msgtab = {
|
||||
"MODLIST", 0, 0, 0, MFLG_SLOW,
|
||||
{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_modlist, 0}}
|
||||
{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, {me_modlist, 0}, {mo_modlist, 0}}
|
||||
};
|
||||
|
||||
struct Message modrestart_msgtab = {
|
||||
"MODRESTART", 0, 0, 0, MFLG_SLOW,
|
||||
{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_modrestart, 0}}
|
||||
{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, {me_modrestart, 0}, {mo_modrestart, 0}}
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -318,8 +328,6 @@ load_one_module(const char *path, int coremodule)
|
|||
static int
|
||||
mo_modload(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
|
||||
{
|
||||
char *m_bn;
|
||||
|
||||
if(!IsOperAdmin(source_p))
|
||||
{
|
||||
sendto_one(source_p, form_str(ERR_NOPRIVS),
|
||||
|
@ -327,7 +335,34 @@ mo_modload(struct Client *client_p, struct Client *source_p, int parc, const cha
|
|||
return 0;
|
||||
}
|
||||
|
||||
m_bn = rb_basename(parv[1]);
|
||||
if(parc > 2)
|
||||
{
|
||||
sendto_match_servs(source_p, parv[2], CAP_ENCAP, NOCAPS,
|
||||
"ENCAP %s MODLOAD %s", parv[2], parv[1]);
|
||||
if (match(parv[2], me.name) == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return do_modload(source_p, parv[1]);
|
||||
}
|
||||
|
||||
static int
|
||||
me_modload(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
|
||||
{
|
||||
if(!find_shared_conf(source_p->username, source_p->host, source_p->servptr->name, SHARED_MODULE))
|
||||
{
|
||||
sendto_one_notice(source_p, ":*** You do not have an appropriate shared block "
|
||||
"to load modules on this server.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return do_modload(source_p, parv[1]);
|
||||
}
|
||||
|
||||
static int
|
||||
do_modload(struct Client *source_p, const char *module)
|
||||
{
|
||||
char *m_bn = rb_basename(module);
|
||||
|
||||
if(findmodule_byname(m_bn) != -1)
|
||||
{
|
||||
|
@ -336,7 +371,7 @@ mo_modload(struct Client *client_p, struct Client *source_p, int parc, const cha
|
|||
return 0;
|
||||
}
|
||||
|
||||
load_one_module(parv[1], 0);
|
||||
load_one_module(module, 0);
|
||||
|
||||
rb_free(m_bn);
|
||||
|
||||
|
@ -348,9 +383,6 @@ mo_modload(struct Client *client_p, struct Client *source_p, int parc, const cha
|
|||
static int
|
||||
mo_modunload(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
|
||||
{
|
||||
char *m_bn;
|
||||
int modindex;
|
||||
|
||||
if(!IsOperAdmin(source_p))
|
||||
{
|
||||
sendto_one(source_p, form_str(ERR_NOPRIVS),
|
||||
|
@ -358,7 +390,35 @@ mo_modunload(struct Client *client_p, struct Client *source_p, int parc, const c
|
|||
return 0;
|
||||
}
|
||||
|
||||
m_bn = rb_basename(parv[1]);
|
||||
if(parc > 2)
|
||||
{
|
||||
sendto_match_servs(source_p, parv[2], CAP_ENCAP, NOCAPS,
|
||||
"ENCAP %s MODUNLOAD %s", parv[2], parv[1]);
|
||||
if (match(parv[2], me.name) == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return do_modunload(source_p, parv[1]);
|
||||
}
|
||||
|
||||
static int
|
||||
me_modunload(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
|
||||
{
|
||||
if(!find_shared_conf(source_p->username, source_p->host, source_p->servptr->name, SHARED_MODULE))
|
||||
{
|
||||
sendto_one_notice(source_p, ":*** You do not have an appropriate shared block "
|
||||
"to load modules on this server.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return do_modunload(source_p, parv[1]);
|
||||
}
|
||||
|
||||
static int
|
||||
do_modunload(struct Client *source_p, const char *module)
|
||||
{
|
||||
int modindex;
|
||||
char *m_bn = rb_basename(module);
|
||||
|
||||
if((modindex = findmodule_byname(m_bn)) == -1)
|
||||
{
|
||||
|
@ -387,10 +447,6 @@ mo_modunload(struct Client *client_p, struct Client *source_p, int parc, const c
|
|||
static int
|
||||
mo_modreload(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
|
||||
{
|
||||
char *m_bn;
|
||||
int modindex;
|
||||
int check_core;
|
||||
|
||||
if(!IsOperAdmin(source_p))
|
||||
{
|
||||
sendto_one(source_p, form_str(ERR_NOPRIVS),
|
||||
|
@ -398,7 +454,36 @@ mo_modreload(struct Client *client_p, struct Client *source_p, int parc, const c
|
|||
return 0;
|
||||
}
|
||||
|
||||
m_bn = rb_basename(parv[1]);
|
||||
if(parc > 2)
|
||||
{
|
||||
sendto_match_servs(source_p, parv[2], CAP_ENCAP, NOCAPS,
|
||||
"ENCAP %s MODRELOAD %s", parv[2], parv[1]);
|
||||
if (match(parv[2], me.name) == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return do_modreload(source_p, parv[1]);
|
||||
}
|
||||
|
||||
static int
|
||||
me_modreload(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
|
||||
{
|
||||
if(!find_shared_conf(source_p->username, source_p->host, source_p->servptr->name, SHARED_MODULE))
|
||||
{
|
||||
sendto_one_notice(source_p, ":*** You do not have an appropriate shared block "
|
||||
"to load modules on this server.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return do_modreload(source_p, parv[1]);
|
||||
}
|
||||
|
||||
static int
|
||||
do_modreload(struct Client *source_p, const char *module)
|
||||
{
|
||||
int modindex;
|
||||
int check_core;
|
||||
char *m_bn = rb_basename(module);
|
||||
|
||||
if((modindex = findmodule_byname(m_bn)) == -1)
|
||||
{
|
||||
|
@ -418,7 +503,7 @@ mo_modreload(struct Client *client_p, struct Client *source_p, int parc, const c
|
|||
|
||||
if((load_one_module(m_bn, check_core) == -1) && check_core)
|
||||
{
|
||||
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
||||
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
|
||||
"Error reloading core module: %s: terminating ircd", m_bn);
|
||||
ilog(L_MAIN, "Error loading core module %s: terminating ircd", m_bn);
|
||||
exit(0);
|
||||
|
@ -432,8 +517,6 @@ mo_modreload(struct Client *client_p, struct Client *source_p, int parc, const c
|
|||
static int
|
||||
mo_modlist(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(!IsOperAdmin(source_p))
|
||||
{
|
||||
sendto_one(source_p, form_str(ERR_NOPRIVS),
|
||||
|
@ -441,11 +524,40 @@ mo_modlist(struct Client *client_p, struct Client *source_p, int parc, const cha
|
|||
return 0;
|
||||
}
|
||||
|
||||
if(parc > 2)
|
||||
{
|
||||
sendto_match_servs(source_p, parv[2], CAP_ENCAP, NOCAPS,
|
||||
"ENCAP %s MODLIST %s", parv[2], parv[1]);
|
||||
if (match(parv[2], me.name) == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return do_modlist(source_p, parc > 1 ? parv[1] : 0);
|
||||
}
|
||||
|
||||
static int
|
||||
me_modlist(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
|
||||
{
|
||||
if(!find_shared_conf(source_p->username, source_p->host, source_p->servptr->name, SHARED_MODULE))
|
||||
{
|
||||
sendto_one_notice(source_p, ":*** You do not have an appropriate shared block "
|
||||
"to load modules on this server.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return do_modlist(source_p, parv[1]);
|
||||
}
|
||||
|
||||
static int
|
||||
do_modlist(struct Client *source_p, const char *pattern)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_mods; i++)
|
||||
{
|
||||
if(parc > 1)
|
||||
if(pattern)
|
||||
{
|
||||
if(match(parv[1], modlist[i]->name))
|
||||
if(match(pattern, modlist[i]->name))
|
||||
{
|
||||
sendto_one(source_p, form_str(RPL_MODLIST),
|
||||
me.name, source_p->name,
|
||||
|
@ -458,8 +570,7 @@ mo_modlist(struct Client *client_p, struct Client *source_p, int parc, const cha
|
|||
{
|
||||
sendto_one(source_p, form_str(RPL_MODLIST),
|
||||
me.name, source_p->name, modlist[i]->name,
|
||||
(unsigned long)(uintptr_t)modlist[i]->address,
|
||||
modlist[i]->version,
|
||||
(unsigned long)(uintptr_t)modlist[i]->address, modlist[i]->version,
|
||||
modlist[i]->core ? "(core)" : "");
|
||||
}
|
||||
}
|
||||
|
@ -472,8 +583,6 @@ mo_modlist(struct Client *client_p, struct Client *source_p, int parc, const cha
|
|||
static int
|
||||
mo_modrestart(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
|
||||
{
|
||||
int modnum;
|
||||
|
||||
if(!IsOperAdmin(source_p))
|
||||
{
|
||||
sendto_one(source_p, form_str(ERR_NOPRIVS),
|
||||
|
@ -481,6 +590,35 @@ mo_modrestart(struct Client *client_p, struct Client *source_p, int parc, const
|
|||
return 0;
|
||||
}
|
||||
|
||||
if(parc > 1)
|
||||
{
|
||||
sendto_match_servs(source_p, parv[1], CAP_ENCAP, NOCAPS,
|
||||
"ENCAP %s MODRESTART", parv[1]);
|
||||
if (match(parv[1], me.name) == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return do_modrestart(source_p);
|
||||
}
|
||||
|
||||
static int
|
||||
me_modrestart(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
|
||||
{
|
||||
if(!find_shared_conf(source_p->username, source_p->host, source_p->servptr->name, SHARED_MODULE))
|
||||
{
|
||||
sendto_one_notice(source_p, ":*** You do not have an appropriate shared block "
|
||||
"to load modules on this server.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return do_modrestart(source_p);
|
||||
}
|
||||
|
||||
static int
|
||||
do_modrestart(struct Client *source_p)
|
||||
{
|
||||
int modnum;
|
||||
|
||||
sendto_one_notice(source_p, ":Reloading all modules");
|
||||
|
||||
modnum = num_mods;
|
||||
|
@ -491,7 +629,7 @@ mo_modrestart(struct Client *client_p, struct Client *source_p, int parc, const
|
|||
load_core_modules(0);
|
||||
rehash(0);
|
||||
|
||||
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
||||
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
|
||||
"Module Restart: %d modules unloaded, %d modules loaded",
|
||||
modnum, num_mods);
|
||||
ilog(L_MAIN, "Module Restart: %d modules unloaded, %d modules loaded", modnum, num_mods);
|
||||
|
@ -499,22 +637,6 @@ mo_modrestart(struct Client *client_p, struct Client *source_p, int parc, const
|
|||
}
|
||||
|
||||
|
||||
|
||||
#ifndef RTLD_NOW
|
||||
#define RTLD_NOW RTLD_LAZY /* openbsd deficiency */
|
||||
#endif
|
||||
|
||||
#ifndef RTLD_LOCAL
|
||||
#define RTLD_LOCAL 0
|
||||
#endif
|
||||
|
||||
#ifdef CHARYBDIS_PROFILE
|
||||
# ifndef RTLD_PROFILE
|
||||
# warning libdl may not support profiling, sucks. :(
|
||||
# define RTLD_PROFILE 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static void increase_modlist(void);
|
||||
|
||||
#define MODS_INCREMENT 10
|
||||
|
|
|
@ -391,6 +391,7 @@ static struct mode_table shared_table[] =
|
|||
{ "rehash", SHARED_REHASH },
|
||||
{ "grant", SHARED_GRANT },
|
||||
{ "die", SHARED_DIE },
|
||||
{ "module", SHARED_MODULE },
|
||||
{ "all", SHARED_ALL },
|
||||
{ "none", 0 },
|
||||
{NULL, 0}
|
||||
|
|
Loading…
Reference in a new issue