Exemple #1
0
static void os_cmd_modunload(sourceinfo_t *si, int parc, char *parv[])
{
	char *module;
	int i;
	module_t *m;

	if (parc < 1)
	{
		command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "MODUNLOAD");
		command_fail(si, fault_needmoreparams, _("Syntax: MODUNLOAD <module...>"));
		return;
	}
	i = 0;
	while (i < parc)
	{
		module = parv[i++];
		m = module_find_published(module);

		if (!m)
		{
			command_fail(si, fault_nosuch_target, _("\2%s\2 is not loaded; it cannot be unloaded."), module);
			continue;
		}

		if (m->can_unload != MODULE_UNLOAD_CAPABILITY_OK)
		{
			slog(LG_INFO, "\2%s\2 tried to unload a permanent module",
				get_oper_name(si));
			command_fail(si, fault_noprivs, _("\2%s\2 is a permanent module; it cannot be unloaded."), module);
			continue;
		}

		if (!strcmp(m->name, "operserv/main") || !strcmp(m->name, "operserv/modload") || !strcmp(m->name, "operserv/modunload"))
		{
			command_fail(si, fault_noprivs, _("Refusing to unload \2%s\2."),
					module);
			continue;
		}

		logcommand(si, CMDLOG_ADMIN, "MODUNLOAD: \2%s\2", module);

		module_unload(m, MODULE_UNLOAD_INTENT_PERM);

		command_success_nodata(si, _("Module \2%s\2 unloaded."), module);
	}
}
Exemple #2
0
static void os_cmd_modinspect(sourceinfo_t *si, int parc, char *parv[])
{
	char *mname = parv[0];
	module_t *m;

	if (!mname)
	{
		command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "MODINSPECT");
		command_fail(si, fault_needmoreparams, _("Syntax: MODINSPECT <module>"));
		return;
	}

	logcommand(si, CMDLOG_GET, "MODINSPECT %s", mname);

	m = module_find_published(mname);

	if (!m)
	{
		command_fail(si, fault_nosuch_target, _("\2%s\2 is not loaded."), mname);
		return;
	}

	/* Is there a header? */
	if (!m->header)
	{
		command_fail(si, fault_unimplemented, _("\2%s\2 cannot be inspected."), mname);
		return;
	}

	command_success_nodata(si, _("Information on \2%s\2:"), mname);
	command_success_nodata(si, _("Name       : %s"), m->header->name);
	command_success_nodata(si, _("Address    : %p"), m->address);
	command_success_nodata(si, _("Entry point: %p"), m->header->modinit);
	command_success_nodata(si, _("Exit point : %p"), m->header->deinit);
	command_success_nodata(si, _("Version    : %s"), m->header->version);
	command_success_nodata(si, _("Vendor     : %s"), m->header->vendor);

	if (m->header->norestart)
		command_success_nodata(si, _("Permanent     : Yes"));
	else
		command_success_nodata(si, _("Permanent     : No"));

	command_success_nodata(si, _("*** \2End of Info\2 ***"));
}
Exemple #3
0
static bool evaluate_condition(sourceinfo_t *si, const char *s)
{
	char word[80];
	char *p, *q;

	while (*s == ' ' || *s == '\t')
		s++;
	if (*s == '!')
		return !evaluate_condition(si, s + 1);
	mowgli_strlcpy(word, s, sizeof word);
	p = strchr(word, ' ');
	if (p != NULL)
	{
		*p++ = '\0';
		while (*p == ' ' || *p == '\t')
			p++;
	}
	if (!strcmp(word, "halfops"))
		return ircd->uses_halfops;
	else if (!strcmp(word, "owner"))
		return ircd->uses_owner;
	else if (!strcmp(word, "protect"))
		return ircd->uses_protect;
	else if (!strcmp(word, "anyprivs"))
		return has_any_privs(si);
	else if (!strcmp(word, "priv"))
	{
		if (p != NULL && (q = strchr(p, ' ')) != NULL)
			*q = '\0';
		return has_priv(si, p);
	}
	else if (!strcmp(word, "module"))
	{
		if (p != NULL && (q = strchr(p, ' ')) != NULL)
			*q = '\0';
		return module_find_published(p) != NULL;
	}
	else if (!strcmp(word, "auth"))
		return me.auth != AUTH_NONE;
	else
		return false;
}
Exemple #4
0
static void os_cmd_modinspect(sourceinfo_t *si, int parc, char *parv[])
{
	char *mname = parv[0];
	module_t *m;

	if (!mname)
	{
		command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "MODINSPECT");
		command_fail(si, fault_needmoreparams, _("Syntax: MODINSPECT <module>"));
		return;
	}

	logcommand(si, CMDLOG_GET, "MODINSPECT: \2%s\2", mname);

	m = module_find_published(mname);

	if (!m)
	{
		command_fail(si, fault_nosuch_target, _("\2%s\2 is not loaded."), mname);
		return;
	}

	/* Is there a header? */
	if (!m->header)
	{
		command_fail(si, fault_unimplemented, _("\2%s\2 cannot be inspected."), mname);
		return;
	}

	command_success_nodata(si, _("Information on \2%s\2:"), mname);
	command_success_nodata(si, _("Name       : %s"), m->name);
	command_success_nodata(si, _("Address    : %p"), m->address);
	command_success_nodata(si, _("Entry point: %p"), m->header->modinit);
	command_success_nodata(si, _("Exit point : %p"), m->header->deinit);
	command_success_nodata(si, _("SDK Serial : %s"), m->header->serial);
	command_success_nodata(si, _("Version    : %s"), m->header->version);
	command_success_nodata(si, _("Vendor     : %s"), m->header->vendor);
	command_success_nodata(si, _("Can unload : %s"), m->can_unload == MODULE_UNLOAD_CAPABILITY_OK ? "Yes" :
					( m->can_unload == MODULE_UNLOAD_CAPABILITY_NEVER ? "No" : "Reload only"));
	command_success_nodata(si, _("*** \2End of Info\2 ***"));
}
Exemple #5
0
static void os_cmd_modload(sourceinfo_t *si, int parc, char *parv[])
{
	char *module;
	module_t *m;
	int i;

	if (parc < 1)
	{
		command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "MODLOAD");
		command_fail(si, fault_needmoreparams, _("Syntax: MODLOAD <module...>"));
		return;
	}
	i = 0;
	while (i < parc)
	{
		module = parv[i++];
		if (module_find_published(module))
		{
			command_fail(si, fault_nochange, _("\2%s\2 is already loaded."), module);
			continue;
		}

		logcommand(si, CMDLOG_ADMIN, "MODLOAD: \2%s\2", module);
		m = module_load(module);

		if (m != NULL)
			command_success_nodata(si, _("Module \2%s\2 loaded."), module);
		else
			command_fail(si, fault_nosuch_target, _("Module \2%s\2 failed to load."), module);
	}

	if (conf_need_rehash)
	{
		logcommand(si, CMDLOG_ADMIN, "REHASH (MODLOAD)");
		wallops("Rehashing \2%s\2 to complete module load by request of \2%s\2.", config_file, get_oper_name(si));
		if (!conf_rehash())
			command_fail(si, fault_nosuch_target, _("REHASH of \2%s\2 failed. Please correct any errors in the file and try again."), config_file);
	}
}
Exemple #6
0
static void cs_cmd_set_guard(sourceinfo_t *si, int parc, char *parv[])
{
	mychan_t *mc;

	if (!(mc = mychan_find(parv[0])))
	{
		command_fail(si, fault_nosuch_target, _("Channel \2%s\2 is not registered."), parv[0]);
		return;
	}

	if (!parv[1])
	{
		command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "SET GUARD");
		return;
	}

	if (!chanacs_source_has_flag(mc, si, CA_SET))
	{
		command_fail(si, fault_noprivs, _("You are not authorized to perform this command."));
		return;
	}

	if (!strcasecmp("ON", parv[1]))
	{
		if (MC_GUARD & mc->flags)
		{
			command_fail(si, fault_nochange, _("The \2%s\2 flag is already set for channel \2%s\2."), "GUARD", mc->name);
			return;
		}
		if (metadata_find(mc, "private:botserv:bot-assigned") &&
				module_find_published("botserv/main"))
		{
			command_fail(si, fault_noprivs, _("Channel \2%s\2 already has a BotServ bot assigned to it.  You need to unassign it first."), mc->name);
			return;
		}

		logcommand(si, CMDLOG_SET, "SET:GUARD:ON: \2%s\2", mc->name);

		mc->flags |= MC_GUARD;

		if (!(mc->flags & MC_INHABIT))
			join(mc->name, chansvs.nick);

		command_success_nodata(si, _("The \2%s\2 flag has been set for channel \2%s\2."), "GUARD", mc->name);
		return;
	}
	else if (!strcasecmp("OFF", parv[1]))
	{
		if (!(MC_GUARD & mc->flags))
		{
			command_fail(si, fault_nochange, _("The \2%s\2 flag is not set for channel \2%s\2."), "GUARD", mc->name);
			return;
		}

		logcommand(si, CMDLOG_SET, "SET:GUARD:OFF: \2%s\2", mc->name);

		mc->flags &= ~MC_GUARD;

		if (mc->chan != NULL && !(mc->flags & MC_INHABIT) && !(mc->chan->flags & CHAN_LOG))
			part(mc->name, chansvs.nick);

		command_success_nodata(si, _("The \2%s\2 flag has been removed for channel \2%s\2."), "GUARD", mc->name);
		return;
	}
	else
	{
		command_fail(si, fault_badparams, STR_INVALID_PARAMS, "GUARD");
		return;
	}
}
Exemple #7
0
static void ns_cmd_fungroup(sourceinfo_t *si, int parc, char *parv[])
{
	mynick_t *mn, *mn2 = NULL;
	myuser_t *mu;
	hook_user_req_t hdata;

	if (parc < 1)
	{
		command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "FUNGROUP");
		command_fail(si, fault_needmoreparams, _("Syntax: FUNGROUP <nickname> [newaccountname]"));
		return;
	}

	mn = mynick_find(parv[0]);
	if (mn == NULL)
	{
		command_fail(si, fault_nosuch_target, _("Nick \2%s\2 is not registered."), parv[0]);
		return;
	}
	mu = mn->owner;
	if (!irccasecmp(mn->nick, entity(mu)->name))
	{
		if (MOWGLI_LIST_LENGTH(&mu->nicks) <= 1 ||
			       !module_find_published("nickserv/set_accountname"))
		{
			command_fail(si, fault_noprivs, _("Nick \2%s\2 is an account name; you may not remove it."), mn->nick);
			return;
		}
		if (is_conf_soper(mu))
		{
			command_fail(si, fault_noprivs, _("You may not modify \2%s\2's account name because their operclass is defined in the configuration file."),
					entity(mu)->name);
			return;
		}
		if (parc < 2)
		{
			command_fail(si, fault_needmoreparams, _("Please specify a new account name for \2%s\2."), entity(mu)->name);
			command_fail(si, fault_needmoreparams, _("Syntax: FUNGROUP <nickname> <newaccountname>"));
			return;
		}
		mn2 = mynick_find(parv[1]);
		if (mn2 == NULL)
		{
			command_fail(si, fault_nosuch_target, _("Nick \2%s\2 is not registered."), parv[1]);
			return;
		}
		if (mn2 == mn)
		{
			command_fail(si, fault_noprivs, _("The new account name must be different from the nick to be ungrouped."));
			return;
		}
		if (mn2->owner != mu)
		{
			command_fail(si, fault_noprivs, _("Nick \2%s\2 is not registered to \2%s\2."), mn2->nick, entity(mu)->name);
			return;
		}
	}
	else if (parc > 1)
	{
		command_fail(si, fault_badparams, _("Nick \2%s\2 is not an account name so no new account name is needed."), mn->nick);
		return;
	}

	if (mn2 != NULL)
	{
		logcommand(si, CMDLOG_ADMIN | LG_REGISTER, "FUNGROUP: \2%s\2 from \2%s\2 (new account name: \2%s\2)", mn->nick, entity(mu)->name, mn2->nick);
		wallops("%s dropped the nick \2%s\2 from %s, changing account name to \2%s\2",
				get_oper_name(si), mn->nick, entity(mu)->name,
				mn2->nick);
		myuser_rename(mu, mn2->nick);
	}
	else
	{
		logcommand(si, CMDLOG_ADMIN | LG_REGISTER, "FUNGROUP: \2%s\2 from \2%s\2", mn->nick, entity(mu)->name);
		wallops("%s dropped the nick \2%s\2 from %s",
				get_oper_name(si), mn->nick, entity(mu)->name);
	}
	hdata.si = si;
	hdata.mu = mu;
	hdata.mn = mn;
	hook_call_nick_ungroup(&hdata);
	holdnick_sts(si->service->me, 0, mn->nick, NULL);
	if (mn2 != NULL)
		command_success_nodata(si, _("Nick \2%s\2 has been removed from account \2%s\2, name changed to \2%s\2."), mn->nick, entity(mu)->name, mn2->nick);
	else
		command_success_nodata(si, _("Nick \2%s\2 has been removed from account \2%s\2."), mn->nick, entity(mu)->name);
	object_unref(mn);
}
Exemple #8
0
/*
 * Implementation functions: load or unload a perl script.
 */
static module_t *do_script_load(const char *filename)
{
	/* Remember, this must now be re-entrant. The use of the static
	 * perl_error buffer is still OK, as it's only used immediately after
	 * setting, without control passing from this function.
	 */
	perl_script_module_t *m = mowgli_heap_alloc(perl_script_module_heap);
	mowgli_strlcpy(m->filename, filename, sizeof(m->filename));

	snprintf(perl_error, sizeof(perl_error),  "Unknown error attempting to load perl script %s",
			filename);

	dSP;
	ENTER;

	SAVETMPS;
	PUSHMARK(SP);

	XPUSHs(newRV_noinc((SV*)get_cv("Atheme::Init::load_script", 0)));
	XPUSHs(sv_2mortal(newSVpv(filename, 0)));
	PUTBACK;

	int perl_return_count = call_pv("Atheme::Init::call_wrapper", G_EVAL | G_SCALAR);

	SPAGAIN;

	if (SvTRUE(ERRSV))
	{
		mowgli_strlcpy(perl_error, SvPV_nolen(ERRSV), sizeof(perl_error));
		goto fail;
	}
	if (1 != perl_return_count)
	{
		snprintf(perl_error, sizeof(perl_error), "Script load didn't return a package name");
		goto fail;
	}

	/* load_script should have returned the package name that was just
	 * loaded...
	 */
	const char *packagename = POPp;
	char info_varname[BUFSIZE];
	snprintf(info_varname, BUFSIZE, "%s::Info", packagename);

	/* ... so use that name to grab the script information hash...
	 */
	HV *info_hash = get_hv(info_varname, 0);
	if (!info_hash)
	{
		snprintf(perl_error, sizeof(perl_error), "Couldn't get package info hash %s", info_varname);
		goto fail;
	}

	/* ..., extract the canonical name...
	 */
	SV **name_var = hv_fetch(info_hash, "name", 4, 0);
	if (!name_var)
	{
		snprintf(perl_error, sizeof(perl_error), "Couldn't find canonical name in package info hash");
		goto fail;
	}

	mowgli_strlcpy(m->mod.name, SvPV_nolen(*name_var), sizeof(m->mod.name));

	/* ... and dependency list.
	 */
	SV **deplist_var = hv_fetch(info_hash, "depends", 7, 0);
	/* Not declaring this is legal... */
	if (deplist_var)
	{
		/* ... but having it as anything but an arrayref isn't. */
		if (!SvROK(*deplist_var) || SvTYPE(SvRV(*deplist_var)) != SVt_PVAV)
		{
			snprintf(perl_error, sizeof(perl_error), "$Info::depends must be an array reference");
			goto fail;
		}

		AV *deplist = (AV*)SvRV(*deplist_var);
		I32 len = av_len(deplist);
		/* av_len returns max index, not number of items */
		for (I32 i = 0; i <= len; ++i)
		{
			SV **item = av_fetch(deplist, i, 0);
			if (!item)
				continue;
			const char *dep_name = SvPV_nolen(*item);
			if (!module_request(dep_name))
			{
				snprintf(perl_error, sizeof(perl_error), "Dependent module %s failed to load",
						dep_name);
				goto fail;
			}
			module_t *dep_mod = module_find_published(dep_name);
			mowgli_node_add(dep_mod, mowgli_node_create(), &m->mod.deplist);
			mowgli_node_add(m, mowgli_node_create(), &dep_mod->dephost);
		}
	}

	FREETMPS;
	LEAVE;
	invalidate_object_references();

	/* Now that everything's loaded, do the module housekeeping stuff. */
	m->mod.unload_handler = perl_script_module_unload_handler;
	/* Can't do much better than the address of the module_t here */
	m->mod.address = m;
	m->mod.can_unload = MODULE_UNLOAD_CAPABILITY_OK;
	return (module_t*)m;

fail:
	slog(LG_ERROR, "Failed to load Perl script %s: %s", filename, perl_error);

	if (info_hash)
		SvREFCNT_dec((SV*)info_hash);

	do_script_unload(filename);

	mowgli_heap_free(perl_script_module_heap, m);
	POPs;

	FREETMPS;
	LEAVE;

	invalidate_object_references();

	return NULL;
}