Beispiel #1
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(!IsAnyOper(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);
	}
	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->localClient->privset)
		{
			sendto_one_notice(source_p, ":%s already has privilege set %s.",
					  target_p->name, target_p->localClient->privset->name);
			return 0;
		}
	}

	if(!dodeoper)
	{
		if(!IsAnyOper(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(privilegeset_in_set(privset, "oper:staffer") && !IsOper(target_p))
		{
			dooper = 1;
			if(IsHelper(target_p))
				dodeoper = 1;
		}
		else if(!privilegeset_in_set(privset, "oper:staffer") && IsOper(target_p))
			dooper = dodeoper = 1;
	}

	if(dodeoper)
	{
		const char *modeparv[4];
		modeparv[0] = modeparv[1] = target_p->name;
		modeparv[2] = "-oO";
		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);
	}

	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);

	return 0;
}
Beispiel #2
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);
	}
}
/*
 * m_topic
 *      parv[1] = channel name
 *	parv[2] = new topic, if setting topic
 */
static int
m_topic(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct Channel *chptr = NULL;
	struct membership *msptr;
	char *p = NULL;
	const char *name;
	int operspy = 0;

	if((p = strchr(parv[1], ',')))
		*p = '\0';

	name = parv[1];

	if(IsOperAuspex(source_p) && parv[1][0] == '!')
	{
		name++;
		operspy = 1;

		if(EmptyString(name))
		{
			sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
					me.name, source_p->name, "TOPIC");
			return 0;
		}
	}

	if(MyClient(source_p) && !IsFloodDone(source_p))
		flood_endgrace(source_p);

	if(!IsChannelName(name))
	{
		sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
				   form_str(ERR_NOSUCHCHANNEL), name);
		return 0;
	}

	chptr = find_channel(name);

	if(chptr == NULL)
	{
		sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
				form_str(ERR_NOSUCHCHANNEL), name);
		return 0;
	}

	/* setting topic */
	if(parc > 2)
	{
		char topic_info[USERHOST_REPLYLEN];
		char topic[BUFSIZE];

		msptr = find_channel_membership(chptr, source_p);

		if(msptr == NULL)
		{
			sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
					form_str(ERR_NOTONCHANNEL), name);
			return 0;
		}

		if(MyClient(source_p) && (chptr->mode.mode & MODE_TOPICLIMIT) && !is_chanop(msptr))
		{
			if(IsOverride(source_p))
				sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
						"%s is overriding TOPIC on [%s]",
						get_oper_name(source_p), chptr->chname);
			else
			{
				sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
						get_id(&me, source_p),
						get_id(source_p, source_p), name);
				return 0;
			}
		}

		rb_strlcpy(topic, parv[2], BUFSIZE);
		/* strip_colour(topic); -- draco */

		rb_sprintf(topic_info, "%s!%s@%s",
				source_p->name, source_p->username, source_p->host);
		set_channel_topic(chptr, topic, topic_info, rb_current_time());

		sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
				":%s TOPIC %s :%s",
				use_id(source_p), chptr->chname,
				chptr->topic == NULL ? "" : chptr->topic);
		sendto_channel_local(ALL_MEMBERS,
				chptr, ":%s!%s@%s TOPIC %s :%s",
				source_p->name, source_p->username,
				source_p->host, chptr->chname,
				chptr->topic == NULL ? "" : chptr->topic);
	}
	else if(MyClient(source_p))
	{
		if(operspy)
			report_operspy(source_p, "TOPIC", chptr->chname);
		if(!IsMember(source_p, chptr) && SecretChannel(chptr) &&
				!operspy)
		{
			sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
					form_str(ERR_NOTONCHANNEL), name);
			return 0;
		}
		if(chptr->topic == NULL)
			sendto_one(source_p, form_str(RPL_NOTOPIC),
					me.name, source_p->name, name);
		else
		{
			sendto_one(source_p, form_str(RPL_TOPIC),
					me.name, source_p->name, chptr->chname, chptr->topic);

			sendto_one(source_p, form_str(RPL_TOPICWHOTIME),
					me.name, source_p->name, chptr->chname,
					chptr->topic_info, chptr->topic_time);
		}
	}

	return 0;
}
Beispiel #4
0
/*
** mo_ojoin
**      parv[1] = channel
*/
static int
mo_ojoin(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct Channel *chptr;
	int move_me = 0;

	/* admins only */
	if(!IsOperAdmin(source_p))
	{
		sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "admin");
		return 0;
	}

	if(*parv[1] == '@' || *parv[1] == '%' || *parv[1] == '+' || *parv[1] == '!'
	   || *parv[1] == '~')
	{
		parv[1]++;
		move_me = 1;
	}
	else
	{
		sendto_one_notice(source_p, ":Unrecognised op prefix '%c'", *parv[1]);
		return 0;
	}

	if((chptr = find_channel(parv[1])) == NULL)
	{
		sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
				   form_str(ERR_NOSUCHCHANNEL), parv[1]);
		return 0;
	}

	if(IsMember(source_p, chptr))
	{
		sendto_one_notice(source_p, ":Please part %s before using OJOIN", parv[1]);
		return 0;
	}

	if(move_me == 1)
		parv[1]--;

	/* only sends stuff for #channels remotely */

	if(*parv[1] == '!')
	{
		if(!ConfigChannel.use_admin)
		{
			sendto_one_notice(source_p,
					  ":This server's configuration file does not support admin prefix");
			return 0;
		}

		add_user_to_channel(chptr, source_p, CHFL_ADMIN);
		sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
			      ":%s SJOIN %ld %s + :!%s",
			      me.id, (long) chptr->channelts, chptr->chname, source_p->id);
		sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN %s",
				     source_p->name,
				     source_p->username, source_p->host, chptr->chname);
		sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +a %s",
				     me.name, chptr->chname, source_p->name);

	}
	else if(*parv[1] == '@')
	{
		add_user_to_channel(chptr, source_p, CHFL_CHANOP);
		sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
			      ":%s SJOIN %ld %s + :@%s",
			      me.id, (long) chptr->channelts, chptr->chname, source_p->id);
		send_channel_join(chptr, source_p);
		sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +o %s",
				     me.name, chptr->chname, source_p->name);

	}
	else if(*parv[1] == '%')
	{
		if(!ConfigChannel.use_halfop)
		{
			sendto_one_notice(source_p,
					  ":This server's configuration file does not support halfop prefix");
			return 0;
		}

		add_user_to_channel(chptr, source_p, CHFL_HALFOP);
		sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
			      ":%s SJOIN %ld %s + :%s%s",
			      me.id, (long) chptr->channelts, chptr->chname, "%", source_p->id);
		sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN %s",
				     source_p->name,
				     source_p->username, source_p->host, chptr->chname);
		sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +h %s",
				     me.name, chptr->chname, source_p->name);
	}
	else if(*parv[1] == '+')
	{
		add_user_to_channel(chptr, source_p, CHFL_VOICE);
		sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
			      ":%s SJOIN %ld %s + :+%s",
			      me.id, (long) chptr->channelts, chptr->chname, source_p->id);
		send_channel_join(chptr, source_p);
		sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +v %s",
				     me.name, chptr->chname, source_p->name);
	}
	else if(*parv[1] == '~')
	{
		if(!ConfigChannel.use_founder)
		{
			sendto_one_notice(source_p,
					  ":This server's configuration file does not support founder prefix");
			return 0;
		}

		add_user_to_channel(chptr, source_p, CHFL_FOUNDER);
		sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
			      ":%s SJOIN %ld %s + :~%s",
			      me.id, (long) chptr->channelts, chptr->chname, source_p->id);
		send_channel_join(chptr, source_p);
		sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +u %s",
				     me.name, chptr->chname, source_p->name);
	}
	else
	{
		add_user_to_channel(chptr, source_p, CHFL_PEON);
		sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
			      ":%s JOIN %ld %s +",
			      source_p->id, (long) chptr->channelts, chptr->chname);
		send_channel_join(chptr, source_p);
	}

	/* send the topic... */
	if(chptr->topic != NULL)
	{
		sendto_one(source_p, form_str(RPL_TOPIC), me.name,
			   source_p->name, chptr->chname, chptr->topic);
		sendto_one(source_p, form_str(RPL_TOPICWHOTIME), me.name,
			   source_p->name, chptr->chname, chptr->topic_info, chptr->topic_time);
	}

	source_p->localClient->last_join_time = rb_current_time();
	channel_member_names(chptr, source_p, 1);

	sendto_realops_snomask(SNO_GENERAL, L_ALL,
			       "OJOIN called for %s by %s!%s@%s",
			       parv[1], source_p->name, source_p->username, source_p->host);
	ilog(L_MAIN, "OJOIN called for %s by %s", parv[1], get_oper_name(source_p));


	return 0;
}
Beispiel #5
0
static void cs_cmd_hold(sourceinfo_t *si, int parc, char *parv[])
{
	char *target = parv[0];
	char *action = parv[1];
	mychan_t *mc;

	if (!target || !action)
	{
		command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "HOLD");
		command_fail(si, fault_needmoreparams, _("Usage: HOLD <#channel> <ON|OFF>"));
		return;
	}

	if (*target != '#')
	{
		command_fail(si, fault_badparams, STR_INVALID_PARAMS, "HOLD");
		return;
	}

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

	if (!strcasecmp(action, "ON"))
	{
		if (mc->flags & MC_HOLD)
		{
			command_fail(si, fault_nochange, _("\2%s\2 is already held."), target);
			return;
		}

		mc->flags |= MC_HOLD;

		metadata_add(mc, "private:held:holder", get_oper_name(si));
		metadata_add(mc, "private:held:timestamp", number_to_string(CURRTIME));

		wallops("%s set the HOLD option for the channel \2%s\2.", get_oper_name(si), target);
		logcommand(si, CMDLOG_ADMIN, "HOLD:ON: \2%s\2", mc->name);
		command_success_nodata(si, _("\2%s\2 is now held."), target);
	}
	else if (!strcasecmp(action, "OFF"))
	{
		if (!(mc->flags & MC_HOLD))
		{
			command_fail(si, fault_nochange, _("\2%s\2 is not held."), target);
			return;
		}

		mc->flags &= ~MC_HOLD;

		metadata_delete(mc, "private:held:holder");
		metadata_delete(mc, "private:held:timestamp");

		wallops("%s removed the HOLD option on the channel \2%s\2.", get_oper_name(si), target);
		logcommand(si, CMDLOG_ADMIN, "HOLD:OFF: \2%s\2", mc->name);
		command_success_nodata(si, _("\2%s\2 is no longer held."), target);
	}
	else
	{
		command_fail(si, fault_badparams, STR_INVALID_PARAMS, "HOLD");
		command_fail(si, fault_badparams, _("Usage: HOLD <#channel> <ON|OFF>"));
	}
}
Beispiel #6
0
/*
** m_undline
** added May 28th 2000 by Toby Verrall <*****@*****.**>
** based totally on m_unkline
** added to hybrid-7 7/11/2000 --is
**
**      parv[0] = sender nick
**      parv[1] = dline to remove
*/
static void
mo_undline(struct Client *client_p, struct Client *source_p,
           int parc, char *parv[])
{
  char *addr = NULL, *user = NULL;
  char *target_server = NULL;

  if (!HasOFlag(source_p, OPER_FLAG_UNDLINE))
  {
    sendto_one(source_p, form_str(ERR_NOPRIVS),
               me.name, source_p->name, "undline");
    return;
  }

  if (parc < 2 || EmptyString(parv[1]))
  {
    sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
               me.name, source_p->name, "UNDLINE");
    return;
  }

  if (parse_aline("UNDLINE", source_p, parc, parv, 0, &user,
                  &addr, NULL, &target_server, NULL) < 0)
    return;

  if (target_server != NULL)
  {
    sendto_match_servs(source_p, target_server, CAP_UNDLN,
                       "UNDLINE %s %s", target_server, addr);

    /* Allow ON to apply local unkline as well if it matches */
    if (!match(target_server, me.name))
      return;
  }
  else
    cluster_a_line(source_p, "UNDLINE", CAP_UNDLN, SHARED_UNDLINE,
                   "%s", addr);

  if (remove_tdline_match(addr))
  {
    sendto_one(source_p,
               ":%s NOTICE %s :Un-Dlined [%s] from temporary D-Lines",
               me.name, source_p->name, addr);
    sendto_realops_flags(UMODE_ALL, L_ALL,
                         "%s has removed the temporary D-Line for: [%s]",
                         get_oper_name(source_p), addr);
    ilog(LOG_TYPE_DLINE, "%s removed temporary D-Line for [%s]",
         source_p->name, addr);
    return;
  }

  if (remove_conf_line(DLINE_TYPE, source_p, addr, NULL) > 0)
  {
    sendto_one(source_p, ":%s NOTICE %s :D-Line for [%s] is removed",
               me.name, source_p->name, addr);
    sendto_realops_flags(UMODE_ALL, L_ALL,
                         "%s has removed the D-Line for: [%s]",
                         get_oper_name(source_p), addr);
    ilog(LOG_TYPE_DLINE, "%s removed D-Line for [%s]",
         get_oper_name(source_p), addr);
  }
  else
    sendto_one(source_p, ":%s NOTICE %s :No D-Line for [%s] found",
               me.name, source_p->name, addr);
}
Beispiel #7
0
static void ns_cmd_sendpass(sourceinfo_t *si, int parc, char *parv[])
{
	myuser_t *mu;
	char *name = parv[0];
	char *newpass = NULL;
	char *key;
	metadata_t *md;
	enum specialoperation op = op_none;
	bool ismarked = false;
	char cmdtext[NICKLEN + 20];

	if (!name)
	{
		command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "SENDPASS");
		command_fail(si, fault_needmoreparams, _("Syntax: SENDPASS <account>"));
		return;
	}
	
	if (parc > 1)
	{
		if (!strcasecmp(parv[1], "FORCE"))
			op = op_force;
		else if (!strcasecmp(parv[1], "CLEAR"))
			op = op_clear;
		else
		{
			command_fail(si, fault_badparams, STR_INVALID_PARAMS, "SENDPASS");
			command_fail(si, fault_badparams, _("Syntax: SENDPASS <account> [FORCE|CLEAR]"));
			return;
		}
	}

	if (!(mu = myuser_find_by_nick(name)))
	{
		command_fail(si, fault_nosuch_target, _("\2%s\2 is not registered."), name);
		return;
	}

	if (is_soper(mu) && !has_priv(si, PRIV_ADMIN))
	{
		logcommand(si, CMDLOG_ADMIN, "failed SENDPASS \2%s\2 (is SOPER)", name);
		command_fail(si, fault_badparams, _("\2%s\2 belongs to a services operator; you need %s privilege to send the password."), name, PRIV_ADMIN);
		return;
	}

	if (mu->flags & MU_WAITAUTH)
	{
		command_fail(si, fault_badparams, _("\2%s\2 is not verified."), entity(mu)->name);
		return;
	}

	if ((md = metadata_find(mu, "private:mark:setter")))
	{
		ismarked = true;
		if (op == op_none)
		{
			logcommand(si, CMDLOG_ADMIN, "failed SENDPASS \2%s\2 (marked by \2%s\2)", entity(mu)->name, md->value);
			command_fail(si, fault_badparams, _("This operation cannot be performed on %s, because the account has been marked by %s."), entity(mu)->name, md->value);
			if (has_priv(si, PRIV_MARK))
			{
				snprintf(cmdtext, sizeof cmdtext,
						"SENDPASS %s FORCE", entity(mu)->name);
				command_fail(si, fault_badparams, _("Use %s to override this restriction."), cmdtext);
			}
			return;
		}
		else if (!has_priv(si, PRIV_MARK))
		{
			logcommand(si, CMDLOG_ADMIN, "failed SENDPASS \2%s\2 (marked by \2%s\2)", entity(mu)->name, md->value);
			command_fail(si, fault_noprivs, STR_NO_PRIVILEGE, PRIV_MARK);
			return;
		}
	}

	if (op == op_clear)
	{
		if (metadata_find(mu, "private:setpass:key"))
		{
			metadata_delete(mu, "private:setpass:key");
			logcommand(si, CMDLOG_ADMIN, "SENDPASS:CLEAR: \2%s\2", entity(mu)->name);
			command_success_nodata(si, _("The password change key for \2%s\2 has been cleared."), entity(mu)->name);
		}
		else
			command_fail(si, fault_nochange, _("\2%s\2 did not have a password change key outstanding."), entity(mu)->name);
		return;
	}

	if (MOWGLI_LIST_LENGTH(&mu->logins) > 0)
	{
		command_fail(si, fault_noprivs, _("This operation cannot be performed on %s, because someone is logged in to it."), entity(mu)->name);
		return;
	}

	if (metadata_find(mu, "private:freeze:freezer"))
	{
		command_success_nodata(si, _("%s has been frozen by the %s administration."), entity(mu)->name, me.netname);
		return;
	}

	/* alternative, safer method? */
	if (command_find(si->service->commands, "SETPASS"))
	{
		if (metadata_find(mu, "private:setpass:key"))
		{
			command_fail(si, fault_alreadyexists, _("\2%s\2 already has a password change key outstanding."), entity(mu)->name);
			command_fail(si, fault_alreadyexists, _("Use SENDPASS %s CLEAR to clear it so that a new one can be sent."), entity(mu)->name);
			return;
		}
		key = random_string(12);
		if (sendemail(si->su != NULL ? si->su : si->service->me, mu, EMAIL_SETPASS, mu->email, key))
		{
			metadata_add(mu, "private:setpass:key", crypt_string(key, gen_salt()));
			logcommand(si, CMDLOG_ADMIN, "SENDPASS: \2%s\2 (change key)", name);
			command_success_nodata(si, _("The password change key for \2%s\2 has been sent to \2%s\2."), entity(mu)->name, mu->email);
			if (ismarked)
			{
				wallops("%s sent the password for the \2MARKED\2 account %s.", get_oper_name(si), entity(mu)->name);
				command_success_nodata(si, _("Overriding MARK placed by %s on the account %s."), md->value, entity(mu)->name);
			}
		}
		else
			command_fail(si, fault_emailfail, _("Email send failed."));
		free(key);
		return;
	}

	/* this is not without controversy... :) */
	if (mu->flags & MU_CRYPTPASS)
	{
		command_success_nodata(si, _("The password for the account \2%s\2 is encrypted; a new password will be assigned and sent."), name);
		newpass = random_string(12);
		set_password(mu, newpass);
	}

	if (sendemail(si->su != NULL ? si->su : si->service->me, mu, EMAIL_SENDPASS, mu->email, (newpass == NULL) ? mu->pass : newpass))
	{
		logcommand(si, CMDLOG_ADMIN, "SENDPASS: \2%s\2", name);
		command_success_nodata(si, _("The password for \2%s\2 has been sent to \2%s\2."), entity(mu)->name, mu->email);
		if (ismarked)
		{
			wallops("%s sent the password for the \2MARKED\2 account %s.", get_oper_name(si), entity(mu)->name);
			command_success_nodata(si, _("Overriding MARK placed by %s on the account %s."), md->value, entity(mu)->name);
		}
	}
	else
		command_fail(si, fault_emailfail, _("Email send failed."));

	if (newpass != NULL)
		free(newpass);

	return;
}
Beispiel #8
0
/* parse_resv()
 *
 * inputs	- source_p, NULL supported
 *		- thing to resv
 *		- time_t if tkline
 *		- reason
 * outputs	- none
 * side effects	- parse resv, create if valid
 */
static void
parse_resv(struct Client *source_p, char *name, int tkline_time, char *reason)
{
	struct ConfItem *conf = NULL;
	int services = 0;

	if(IsServices(source_p))
		services = 1;

	if(IsChanPrefix(*name))
	{
		struct ResvChannel *resv_p;

		if((conf = create_channel_resv(name, reason, 0)) == NULL)
		{
			if(!services)
				sendto_one(source_p,
					   ":%s NOTICE %s :A RESV has already been placed on channel: %s",
					   me.name, source_p->name, name);
			return;
		}

		resv_p = map_to_conf(conf);

		if(tkline_time != 0)
		{
			if(!services)
			{
				sendto_one(source_p,
					   ":%s NOTICE %s :A %d minute %s RESV has been placed on channel: %s",
					   me.name, source_p->name,
					   tkline_time / 60,
					   (MyClient(source_p) ? "local" : "remote"), name);
				sendto_realops_flags(UMODE_ALL, L_ALL,
						     "%s has placed a %d minute %s RESV on channel: %s [%s]",
						     get_oper_name(source_p),
						     tkline_time / 60,
						     (MyClient(source_p) ? "local" : "remote"),
						     resv_p->name, resv_p->reason);
			}
			ilog(L_TRACE, "%s added temporary %d min. RESV for [%s] [%s]",
			     source_p->name, (int) tkline_time / 60, conf->name, resv_p->reason);
			resv_p->hold = CurrentTime + tkline_time;
			add_temp_line(conf);
		}
		else
		{
			if(!services)
			{
				sendto_one(source_p,
					   ":%s NOTICE %s :A %s RESV has been placed on channel %s",
					   me.name, source_p->name,
					   (MyClient(source_p) ? "local" : "remote"), name);
				sendto_realops_flags(UMODE_ALL, L_ALL,
						     "%s has placed a %s RESV on channel %s : [%s]",
						     get_oper_name(source_p),
						     (MyClient(source_p) ? "local" : "remote"),
						     resv_p->name, resv_p->reason);
			}
			write_conf_line(source_p, conf, NULL /* not used */ , 0 /* not used */ );
		}
	}
	else
	{
		struct MatchItem *resv_p = NULL;

		if(!valid_wild_card_simple(name) && !IsServices(source_p))
		{
			sendto_one(source_p,
				   ":%s NOTICE %s :Please include at least %d non-wildcard characters with the resv",
				   me.name, source_p->name, ConfigFileEntry.min_nonwildcard_simple);
			return;
		}

		if(!IsAdmin(source_p) && !IsServices(source_p) && strpbrk(name, "*?#"))
		{
			sendto_one(source_p, ":%s NOTICE %s :You must be an admin to perform a "
				   "wildcard RESV", me.name, source_p->name);
			return;
		}

		if((conf = create_nick_resv(name, reason, 0)) == NULL)
		{
			if(!services)
				sendto_one(source_p,
					   ":%s NOTICE %s :A RESV has already been placed on nick %s",
					   me.name, source_p->name, name);
			return;
		}

		resv_p = map_to_conf(conf);

		if(tkline_time != 0)
		{
			if(!services)
			{
				sendto_one(source_p,
					   ":%s NOTICE %s :A %d minute %s RESV has been placed on nick %s : [%s]",
					   me.name, source_p->name,
					   tkline_time / 60,
					   (MyClient(source_p) ? "local" : "remote"),
					   conf->name, resv_p->reason);
				sendto_realops_flags(UMODE_ALL, L_ALL,
						     "%s has placed a %d minute %s RESV on nick %s : [%s]",
						     get_oper_name(source_p),
						     tkline_time / 60,
						     (MyClient(source_p) ? "local" : "remote"),
						     conf->name, resv_p->reason);
			}
			ilog(L_TRACE, "%s added temporary %d min. RESV for [%s] [%s]",
			     source_p->name, (int) tkline_time / 60, conf->name, resv_p->reason);
			resv_p->hold = CurrentTime + tkline_time;
			add_temp_line(conf);
		}
		else
		{
			if(!services)
			{
				sendto_one(source_p,
					   ":%s NOTICE %s :A %s RESV has been placed on nick %s : [%s]",
					   me.name, source_p->name,
					   (MyClient(source_p) ? "local" : "remote"),
					   conf->name, resv_p->reason);
				sendto_realops_flags(UMODE_ALL, L_ALL,
						     "%s has placed a %s RESV on nick %s : [%s]",
						     get_oper_name(source_p),
						     (MyClient(source_p) ? "local" : "remote"),
						     conf->name, resv_p->reason);
			}
			write_conf_line(source_p, conf, NULL /* not used */ , 0 /* not used */ );
		}
	}
}
Beispiel #9
0
/*
** m_okick
**      parv[1] = channel
**      parv[2] = client to kick
**      parv[3] = kick comment
*/
static int
mo_okick(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct Client *who;
	struct Client *target_p;
	struct Channel *chptr;
	struct membership *msptr;
	int chasing = 0;
	char *comment;
	char *name;
	char *p = NULL;
	char *user;
	char text[10];
	static char buf[BUFSIZE];

	if(*parv[2] == '\0')
	{
		sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), me.name, source_p->name, "KICK");
		return 0;
	}

	if(MyClient(source_p) && !IsFloodDone(source_p))
		flood_endgrace(source_p);

	comment = (EmptyString(LOCAL_COPY(parv[3]))) ? LOCAL_COPY(parv[2]) : LOCAL_COPY(parv[3]);
	if(strlen(comment) > (size_t) TOPICLEN)
		comment[TOPICLEN] = '\0';

	*buf = '\0';
	if((p = strchr(parv[1], ',')))
		*p = '\0';

	name = LOCAL_COPY(parv[1]);

	chptr = find_channel(name);
	if(!chptr)
	{
		sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL, form_str(ERR_NOSUCHCHANNEL), name);
		return 0;
	}


	if((p = strchr(parv[2], ',')))
		*p = '\0';
	user = LOCAL_COPY(parv[2]);	// strtoken(&p2, parv[2], ","); 
	if(!(who = find_chasing(source_p, user, &chasing)))
	{
		return 0;
	}

	if((target_p = find_client(user)) == NULL)
	{
		sendto_one(source_p, form_str(ERR_NOSUCHNICK), me.name, source_p->name, user);
		return 0;
	}

	if((msptr = find_channel_membership(chptr, target_p)) == NULL)
	{
		sendto_one(source_p, form_str(ERR_USERNOTINCHANNEL),
			   me.name, source_p->name, parv[1], parv[2]);
		return 0;
	}

	sendto_realops_snomask(SNO_GENERAL, L_ALL,
			       "OKICK called for %s %s by %s!%s@%s",
			       chptr->chname, target_p->name,
			       source_p->name, source_p->username, source_p->host);
	ilog(L_MAIN, "OKICK called for %s %s by %s",
	     chptr->chname, target_p->name,
	     get_oper_name(source_p));

	sendto_channel_local(ALL_MEMBERS, chptr, ":%s KICK %s %s :%s",
			     me.name, chptr->chname, who->name, comment);
	sendto_server(&me, chptr, CAP_TS6, NOCAPS,
		      ":%s KICK %s %s :%s", me.id, chptr->chname, who->id, comment);
	remove_user_from_channel(msptr);

	rb_snprintf(text, sizeof(text), "K%s", who->id);

	/* we don't need to track NOREJOIN stuff unless it's our client being kicked */
	if(MyClient(who) && chptr->mode.mode & MODE_NOREJOIN)
		channel_metadata_time_add(chptr, text, rb_current_time(), "KICKNOREJOIN");
	return 0;
}
Beispiel #10
0
static void
ns_cmd_register(struct sourceinfo *si, int parc, char *parv[])
{
	struct myuser *mu;
	struct mynick *mn = NULL;
	mowgli_node_t *n;
	const char *account;
	const char *pass;
	const char *email;
	char lau[BUFSIZE], lao[BUFSIZE];
	hook_user_register_check_t hdata;
	hook_user_req_t req;

	if (si->smu)
	{
		command_fail(si, fault_already_authed, _("You are already logged in as \2%s\2."), entity(si->smu)->name);
		if (si->su != NULL && !mynick_find(si->su->nick) &&
				command_find(si->service->commands, "GROUP"))
			command_fail(si, fault_already_authed, _("Use %s to register %s to your account."), "GROUP", si->su->nick);
		return;
	}

	if (nicksvs.no_nick_ownership || si->su == NULL)
	{
		account = parv[0];
		pass = parv[1];
		email = parv[2];
	}
	else
	{
		account = si->su->nick;
		pass = parv[0];
		email = parv[1];
	}

	if (!account || !pass || !email)
	{
		command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "REGISTER");
		if (nicksvs.no_nick_ownership || si->su == NULL)
			command_fail(si, fault_needmoreparams, _("Syntax: REGISTER <account> <password> <email>"));
		else
			command_fail(si, fault_needmoreparams, _("Syntax: REGISTER <password> <email>"));
		return;
	}

	if (strlen(pass) > PASSLEN)
	{
		command_fail(si, fault_badparams, STR_INVALID_PARAMS, "REGISTER");
		command_fail(si, fault_badparams, _("Registration passwords may not be longer than \2%u\2 characters."), PASSLEN);
		return;
	}

	if (!nicksvs.no_nick_ownership && si->su == NULL && user_find_named(account))
	{
		command_fail(si, fault_noprivs, _("A user matching this account is already on IRC."));
		return;
	}

	if (!nicksvs.no_nick_ownership && IsDigit(*account))
	{
		command_fail(si, fault_badparams, _("For security reasons, you can't register your UID."));
		command_fail(si, fault_badparams, _("Please change to a real nickname, and try again."));
		return;
	}

	if (nicksvs.no_nick_ownership || si->su == NULL)
	{
		if (strchr(account, ' ') || strchr(account, '\n') || strchr(account, '\r') || account[0] == '=' || account[0] == '#' || account[0] == '@' || account[0] == '+' || account[0] == '%' || account[0] == '!' || strchr(account, ','))
		{
			command_fail(si, fault_badparams, _("The account name \2%s\2 is invalid."), account);
			return;
		}
	}

	if (strlen(account) > NICKLEN)
	{
		command_fail(si, fault_badparams, _("The account name \2%s\2 is invalid."), account);
		return;
	}

	if ((si->su != NULL && !strcasecmp(pass, si->su->nick)) || !strcasecmp(pass, account))
	{
		command_fail(si, fault_badparams, _("You cannot use your nickname as a password."));
		if (nicksvs.no_nick_ownership || si->su == NULL)
			command_fail(si, fault_needmoreparams, _("Syntax: REGISTER <account> <password> <email>"));
		else
			command_fail(si, fault_needmoreparams, _("Syntax: REGISTER <password> <email>"));
		return;
	}

	// make sure it isn't registered already
	if (nicksvs.no_nick_ownership ? myuser_find(account) != NULL : mynick_find(account) != NULL)
	{
		command_fail(si, fault_alreadyexists, _("\2%s\2 is already registered."), account);
		return;
	}

	if ((unsigned int)(CURRTIME - ratelimit_firsttime) > config_options.ratelimit_period)
	{
		ratelimit_count = 0;
		ratelimit_firsttime = CURRTIME;
	}

	// Still do flood priv checking because the user may be in the ircop operclass
	if (ratelimit_count > config_options.ratelimit_uses && !has_priv(si, PRIV_FLOOD))
	{
		command_fail(si, fault_toomany, _("The system is currently too busy to process your registration, please try again later."));
		slog(LG_INFO, "NICKSERV:REGISTER:THROTTLED: \2%s\2 by \2%s\2", account, si->su != NULL ? si->su->nick : get_source_name(si));
		return;
	}

	hdata.si = si;
	hdata.account = account;
	hdata.email = email;
	hdata.password = pass;
	hdata.approved = 0;
	hook_call_user_can_register(&hdata);
	if (hdata.approved != 0)
		return;
	if (!nicksvs.no_nick_ownership)
	{
		hook_call_nick_can_register(&hdata);
		if (hdata.approved != 0)
			return;
	}

	if (!validemail(email))
	{
		command_fail(si, fault_badparams, _("\2%s\2 is not a valid e-mail address."), email);
		return;
	}

	if (!email_within_limits(email))
	{
		command_fail(si, fault_toomany, _("\2%s\2 has too many accounts registered."), email);
		return;
	}

	if (si->su && !auth_module_loaded && !crypt_get_default_provider())
		(void) command_success_nodata(si, "%s", _("Warning: Your password will not be encrypted."));

	mu = myuser_add(account, auth_module_loaded ? "*" : pass, email, config_options.defuflags | MU_NOBURSTLOGIN | (auth_module_loaded ? MU_CRYPTPASS : 0));
	mu->registered = CURRTIME;
	mu->lastlogin = CURRTIME;
	if (!nicksvs.no_nick_ownership)
	{
		mn = mynick_add(mu, entity(mu)->name);
		mn->registered = CURRTIME;
		mn->lastseen = CURRTIME;
	}
	if (config_options.ratelimit_uses && config_options.ratelimit_period)
		ratelimit_count++;

	if (auth_module_loaded)
	{
		if (!verify_password(mu, pass))
		{
			command_fail(si, fault_authfail, _("Invalid password for \2%s\2."), entity(mu)->name);
			bad_password(si, mu);
			atheme_object_unref(mu);
			return;
		}
	}

	if (me.auth == AUTH_EMAIL)
	{
		char *key = random_string(12);
		mu->flags |= MU_WAITAUTH;

		metadata_add(mu, "private:verify:register:key", key);
		metadata_add(mu, "private:verify:register:timestamp", number_to_string(time(NULL)));

		if (!sendemail(si->su != NULL ? si->su : si->service->me, mu, EMAIL_REGISTER, mu->email, key))
		{
			command_fail(si, fault_emailfail, _("Sending email failed, sorry! Registration aborted."));
			atheme_object_unref(mu);
			sfree(key);
			return;
		}

		command_success_nodata(si, _("An email containing nickname activation instructions has been sent to \2%s\2."), mu->email);
		command_success_nodata(si, _("If you do not complete registration within one day, your nickname will expire."));

		sfree(key);
	}

	if (si->su != NULL)
	{
		si->su->myuser = mu;
		n = mowgli_node_create();
		mowgli_node_add(si->su, n, &mu->logins);

		if (!(mu->flags & MU_WAITAUTH))
			// only grant ircd registered status if it's verified
			ircd_on_login(si->su, mu, NULL);
	}

	command_add_flood(si, FLOOD_MODERATE);

	if (!nicksvs.no_nick_ownership && si->su != NULL)
		logcommand(si, CMDLOG_REGISTER, "REGISTER: \2%s\2 to \2%s\2", account, email);
	else
		logcommand(si, CMDLOG_REGISTER, "REGISTER: \2%s\2 to \2%s\2 by \2%s\2", account, email, si->su != NULL ? si->su->nick : get_source_name(si));

	if (is_soper(mu))
	{
		wallops("%s registered the nick \2%s\2 and gained services operator privileges.", get_oper_name(si), entity(mu)->name);
		logcommand(si, CMDLOG_ADMIN, "SOPER: \2%s\2 as \2%s\2", get_oper_name(si), entity(mu)->name);
	}

	command_success_nodata(si, _("\2%s\2 is now registered to \2%s\2."), entity(mu)->name, mu->email);
	hook_call_user_register(mu);

	if (si->su != NULL)
	{
		snprintf(lau, BUFSIZE, "%s@%s", si->su->user, si->su->vhost);
		metadata_add(mu, "private:host:vhost", lau);

		snprintf(lao, BUFSIZE, "%s@%s", si->su->user, si->su->host);
		metadata_add(mu, "private:host:actual", lao);
	}

	if (!(mu->flags & MU_WAITAUTH))
	{
		req.si = si;
		req.mu = mu;
		req.mn = mn;
		hook_call_user_verify_register(&req);
	}
}
Beispiel #11
0
static void
cs_cmd_set_mlock(struct sourceinfo *si, int parc, char *parv[])
{
	struct mychan *mc;
	char modebuf[32], *end, c;
	int dir = MTYPE_NUL;
	int newlock_on = 0, newlock_off = 0, newlock_limit = 0, flag = 0;
	unsigned int mask, changed;
	bool mask_ext;
	char newlock_key[KEYLEN + 1];
	char newlock_ext[ignore_mode_list_size][512];
	bool newlock_ext_off[ignore_mode_list_size];
	char newext[512];
	char ext_plus[ignore_mode_list_size + 1];
	char ext_minus[ignore_mode_list_size + 1];
	size_t i;
	char *letters = strtok(parv[1], " ");
	char *arg;
	struct metadata *md;

	if (!(mc = mychan_find(parv[0])))
	{
		command_fail(si, fault_nosuch_target, STR_IS_NOT_REGISTERED, parv[0]);
		return;
	}

	if (!chanacs_source_has_flag(mc, si, CA_SET))
	{
		if (ircd->oper_only_modes == 0 ||
				!has_priv(si, PRIV_CHAN_CMODES) ||
				!has_priv(si, PRIV_CHAN_ADMIN))
		{
			command_fail(si, fault_noprivs, STR_NOT_AUTHORIZED);
			return;
		}
		mask = ~ircd->oper_only_modes;
		mask_ext = true;
	}
	else
	{
		mask = has_priv(si, PRIV_CHAN_CMODES) ? 0 : ircd->oper_only_modes;
		mask_ext = false;

	}

	for (i = 0; i < ignore_mode_list_size; i++)
	{
		newlock_ext[i][0] = '\0';
		newlock_ext_off[i] = false;
	}
	newlock_key[0] = '\0';

	while (letters && *letters)
	{
		if (*letters != '+' && *letters != '-' && dir == MTYPE_NUL)
		{
			letters++;
			continue;
		}

		switch ((c = *letters++))
		{
		  case '+':
			  dir = MTYPE_ADD;
			  break;

		  case '-':
			  dir = MTYPE_DEL;
			  break;

		  case 'k':
			  if (dir == MTYPE_ADD)
			  {
				  arg = strtok(NULL, " ");
				  if (!arg)
				  {
					  command_fail(si, fault_badparams, _("You need to specify a value for mode +%c."), 'k');
					  return;
				  }
				  else if (strlen(arg) > KEYLEN)
				  {
					  command_fail(si, fault_badparams, _("MLOCK key is too long (%zu > %u)."), strlen(arg), KEYLEN);
					  return;
				  }
				  else if (strchr(arg, ',') || arg[0] == ':')
				  {
					  command_fail(si, fault_badparams, _("MLOCK key contains invalid characters."));
					  return;
				  }

				  mowgli_strlcpy(newlock_key, arg, sizeof newlock_key);
				  newlock_off &= ~CMODE_KEY;
			  }
			  else
			  {
				  newlock_key[0] = '\0';
				  newlock_off |= CMODE_KEY;
			  }

			  break;

		  case 'l':
			  if (dir == MTYPE_ADD)
			  {
				  arg = strtok(NULL, " ");
				  if(!arg)
				  {
					  command_fail(si, fault_badparams, _("You need to specify a value for mode +%c."), 'l');
					  return;
				  }

				  if (atol(arg) <= 0)
				  {
					  command_fail(si, fault_badparams, _("You must specify a positive integer for limit."));
					  return;
				  }

				  newlock_limit = atol(arg);
				  newlock_off &= ~CMODE_LIMIT;
			  }
			  else
			  {
				  newlock_limit = 0;
				  newlock_off |= CMODE_LIMIT;
			  }

			  break;

		  default:
			  flag = mode_to_flag(c);

			  if (flag)
			  {
				  if (dir == MTYPE_ADD)
				  {
					  newlock_on |= flag;
					  newlock_off &= ~flag;
				  }
				  else
				  {
					  newlock_off |= flag;
					  newlock_on &= ~flag;
				  }
				  break;
			  }

			  for (i = 0; ignore_mode_list[i].mode != '\0'; i++)
			  {
				  if (c == ignore_mode_list[i].mode)
				  {
					  if (dir == MTYPE_ADD)
					  {
						  arg = strtok(NULL, " ");
						  if(!arg)
						  {
							  command_fail(si, fault_badparams, _("You need to specify a value for mode +%c."), c);
							  return;
						  }
						  if (strlen(arg) > 350)
						  {
							  command_fail(si, fault_badparams, _("Invalid value \2%s\2 for mode +%c."), arg, c);
							  return;
						  }
						  if ((mc->chan == NULL || mc->chan->extmodes[i] == NULL || strcmp(mc->chan->extmodes[i], arg)) && !ignore_mode_list[i].check(arg, mc->chan, mc, si->su, si->smu))
						  {
							  command_fail(si, fault_badparams, _("Invalid value \2%s\2 for mode +%c."), arg, c);
							  return;
						  }
						  mowgli_strlcpy(newlock_ext[i], arg, sizeof newlock_ext[i]);
						  newlock_ext_off[i] = false;
					  }
					  else
					  {
						  newlock_ext[i][0] = '\0';
						  newlock_ext_off[i] = true;
					  }
				  }
			  }
		}
	}

	// note: the following does not treat +lk and extmodes correctly
	changed = ((newlock_on ^ mc->mlock_on) | (newlock_off ^ mc->mlock_off));
	changed &= ~mask;

	/* if they're only allowed to alter oper only modes, require
	 * them to actually change such modes -- jilles */
	if (!changed && mask_ext)
	{
		command_fail(si, fault_noprivs, _("You may only alter \2+%s\2 modes."), flags_to_string(~mask));
		return;
	}

	// save it to mychan, leave the modes in mask unchanged -- jilles
	mc->mlock_on = (newlock_on & ~mask) | (mc->mlock_on & mask);
	mc->mlock_off = (newlock_off & ~mask) | (mc->mlock_off & mask);

	if (!(mask & CMODE_LIMIT))
		mc->mlock_limit = newlock_limit;

	if (!(mask & CMODE_KEY))
	{
		sfree(mc->mlock_key);
		mc->mlock_key = *newlock_key != '\0' ? sstrdup(newlock_key) : NULL;
	}

	ext_plus[0] = '\0';
	ext_minus[0] = '\0';
	if (mask_ext)
	{
		md = metadata_find(mc, "private:mlockext");
		if (md != NULL)
		{
			arg = md->value;
			while (*arg != '\0')
			{
				modebuf[0] = *arg;
				modebuf[1] = '\0';
				mowgli_strlcat(arg[1] == ' ' || arg[1] == '\0' ? ext_minus : ext_plus, modebuf, ignore_mode_list_size + 1);
				arg++;
				while (*arg != ' ' && *arg != '\0')
					arg++;
				while (*arg == ' ')
					arg++;
			}
		}
	}
	else
	{
		newext[0] = '\0';
		for (i = 0; i < ignore_mode_list_size; i++)
		{
			if (newlock_ext[i][0] != '\0' || newlock_ext_off[i])
			{
				if (*newext != '\0')
				{
					modebuf[0] = ' ';
					modebuf[1] = '\0';
					mowgli_strlcat(newext, modebuf, sizeof newext);
				}
				modebuf[0] = ignore_mode_list[i].mode;
				modebuf[1] = '\0';
				mowgli_strlcat(newext, modebuf, sizeof newext);
				mowgli_strlcat(newlock_ext_off[i] ? ext_minus : ext_plus,
						modebuf, ignore_mode_list_size + 1);
				if (!newlock_ext_off[i])
					mowgli_strlcat(newext, newlock_ext[i], sizeof newext);
			}
		}
		if (newext[0] != '\0')
			metadata_add(mc, "private:mlockext", newext);
		else
			metadata_delete(mc, "private:mlockext");
	}

	end = modebuf;
	*end = 0;

	if (mc->mlock_on || mc->mlock_key || mc->mlock_limit || *ext_plus)
		end += snprintf(end, sizeof(modebuf) - (end - modebuf), "+%s%s%s%s", flags_to_string(mc->mlock_on), mc->mlock_key ? "k" : "", mc->mlock_limit ? "l" : "", ext_plus);

	if (mc->mlock_off || *ext_minus)
		end += snprintf(end, sizeof(modebuf) - (end - modebuf), "-%s%s%s%s", flags_to_string(mc->mlock_off), mc->mlock_off & CMODE_KEY ? "k" : "", mc->mlock_off & CMODE_LIMIT ? "l" : "", ext_minus);

	if (*modebuf)
	{
		command_success_nodata(si, _("The MLOCK for \2%s\2 has been set to \2%s\2."), mc->name, modebuf);
		logcommand(si, CMDLOG_SET, "SET:MLOCK: \2%s\2 to \2%s\2", mc->name, modebuf);
		verbose(mc, "\2%s\2 set the mode lock to \2%s\2", get_source_name(si), modebuf);
	}
	else
	{
		command_success_nodata(si, _("The MLOCK for \2%s\2 has been removed."), mc->name);
		logcommand(si, CMDLOG_SET, "SET:MLOCK:NONE: \2%s\2", mc->name);
	}
	if (changed & ircd->oper_only_modes)
		logcommand(si, CMDLOG_SET, "SET:MLOCK: \2%s\2 to \2%s\2 by \2%s\2", mc->name, *modebuf != '\0' ? modebuf : "+", get_oper_name(si));

	check_modes(mc, true);
	if (mc->chan != NULL)
		mlock_sts(mc->chan);

	return;
}
Beispiel #12
0
static void ns_cmd_restrict(sourceinfo_t *si, int parc, char *parv[])
{
	char *target = parv[0];
	char *action = parv[1];
	char *info = parv[2];
	myuser_t *mu;
	myuser_name_t *mun;

	if (!target || !action)
	{
		command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "RESTRICT");
		command_fail(si, fault_needmoreparams, _("Usage: RESTRICT <target> <ON|OFF> [note]"));
		return;
	}

	if (!(mu = myuser_find_ext(target)))
	{
		mun = myuser_name_find(target);
		if (mun != NULL && !strcasecmp(action, "OFF"))
		{
			object_unref(mun);
			wallops("%s unrestricted the name \2%s\2.", get_oper_name(si), target);
			logcommand(si, CMDLOG_ADMIN, "RESTRICT:OFF: \2%s\2", target);
			command_success_nodata(si, _("\2%s\2 is now unrestricted."), target);
			return;
		}
		command_fail(si, fault_nosuch_target, _("\2%s\2 is not registered."), target);
		return;
	}

	if (!strcasecmp(action, "ON"))
	{
		if (!info)
		{
			command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "RESTRICT");
			command_fail(si, fault_needmoreparams, _("Usage: RESTRICT <target> ON <note>"));
			return;
		}

		if (metadata_find(mu, "private:restrict:setter"))
		{
			command_fail(si, fault_badparams, _("\2%s\2 is already restricted."), entity(mu)->name);
			return;
		}

		metadata_add(mu, "private:restrict:setter", get_oper_name(si));
		metadata_add(mu, "private:restrict:reason", info);
		metadata_add(mu, "private:restrict:timestamp", number_to_string(time(NULL)));

		wallops("%s restricted the account \2%s\2.", get_oper_name(si), entity(mu)->name);
		logcommand(si, CMDLOG_ADMIN, "RESTRICT:ON: \2%s\2 (reason: \2%s\2)", entity(mu)->name, info);
		command_success_nodata(si, _("\2%s\2 is now restricted."), entity(mu)->name);
	}
	else if (!strcasecmp(action, "OFF"))
	{
		if (!metadata_find(mu, "private:restrict:setter"))
		{
			command_fail(si, fault_badparams, _("\2%s\2 is not restricted."), entity(mu)->name);
			return;
		}

		metadata_delete(mu, "private:restrict:setter");
		metadata_delete(mu, "private:restrict:reason");
		metadata_delete(mu, "private:restrict:timestamp");

		wallops("%s unrestricted the account \2%s\2.", get_oper_name(si), entity(mu)->name);
		logcommand(si, CMDLOG_ADMIN, "RESTRICT:OFF: \2%s\2", entity(mu)->name);
		command_success_nodata(si, _("\2%s\2 is now unrestricted."), entity(mu)->name);
	}
	else
	{
		command_fail(si, fault_needmoreparams, STR_INVALID_PARAMS, "RESTRICT");
		command_fail(si, fault_needmoreparams, _("Usage: RESTRICT <target> <ON|OFF> [note]"));
	}
}
Beispiel #13
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);
}
Beispiel #14
0
/* FFLAGS <channel> <user> <flags> */
static void cs_cmd_fflags(sourceinfo_t *si, int parc, char *parv[])
{
	const char *channel = parv[0];
	const char *target = parv[1];
	const char *flagstr = parv[2];
	mychan_t *mc;
	myentity_t *mt;
	unsigned int addflags, removeflags;
	chanacs_t *ca;
	hook_channel_acl_req_t req;

	if (parc < 3)
	{
		command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "FFLAGS");
		command_fail(si, fault_needmoreparams, _("Syntax: FFLAGS <channel> <target> <flags>"));
		return;
	}

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

	if (*flagstr == '+' || *flagstr == '-' || *flagstr == '=')
	{
		flags_make_bitmasks(flagstr, &addflags, &removeflags);
		if (addflags == 0 && removeflags == 0)
		{
			command_fail(si, fault_badparams, _("No valid flags given, use /%s%s HELP FLAGS for a list"), ircd->uses_rcommand ? "" : "msg ", chansvs.me->disp);
			return;
		}
	}
	else
	{
		addflags = get_template_flags(mc, flagstr);
		if (addflags == 0)
		{
			/* Hack -- jilles */
			if (*target == '+' || *target == '-' || *target == '=')
				command_fail(si, fault_badparams, _("Usage: FFLAGS %s <target> <flags>"), mc->name);
			else
				command_fail(si, fault_badparams, _("Invalid template name given, use /%s%s TEMPLATE %s for a list"), ircd->uses_rcommand ? "" : "msg ", chansvs.me->disp, mc->name);
			return;
		}
		removeflags = ca_all & ~addflags;
	}

	if (!validhostmask(target))
	{
		if (!(mt = myentity_find_ext(target)))
		{
			command_fail(si, fault_nosuch_target, _("\2%s\2 is not registered."), target);
			return;
		}
		target = mt->name;

		ca = chanacs_open(mc, mt, NULL, true, entity(si->smu));

		/* XXX this should be more like flags.c */
		if (removeflags & CA_FLAGS)
			removeflags |= CA_FOUNDER, addflags &= ~CA_FOUNDER;
		else if (addflags & CA_FOUNDER)
			addflags |= CA_FLAGS, removeflags &= ~CA_FLAGS;
		if (is_founder(mc, mt) && removeflags & CA_FOUNDER && mychan_num_founders(mc) == 1)
		{
			command_fail(si, fault_noprivs, _("You may not remove the last founder."));
			return;
		}

		req.ca = ca;
		req.oldlevel = ca->level;

		if (!chanacs_modify(ca, &addflags, &removeflags, ca_all, si->smu))
		{
			/* this shouldn't happen */
			command_fail(si, fault_noprivs, _("You are not allowed to set \2%s\2 on \2%s\2 in \2%s\2."), bitmask_to_flags2(addflags, removeflags), mt->name, mc->name);
			chanacs_close(ca);
			return;
		}

		req.newlevel = ca->level;

		hook_call_channel_acl_change(&req);
		chanacs_close(ca);
	}
	else
	{
		if (addflags & CA_FOUNDER)
		{
			command_fail(si, fault_badparams, _("You may not set founder status on a hostmask."));
			return;
		}

		ca = chanacs_open(mc, NULL, target, true, entity(si->smu));

		req.ca = ca;
		req.oldlevel = ca->level;

		if (!chanacs_modify(ca, &addflags, &removeflags, ca_all, si->smu))
		{
			/* this shouldn't happen */
			command_fail(si, fault_noprivs, _("You are not allowed to set \2%s\2 on \2%s\2 in \2%s\2."), bitmask_to_flags2(addflags, removeflags), target, mc->name);
			chanacs_close(ca);
			return;
		}

		req.newlevel = ca->level;

		hook_call_channel_acl_change(&req);
		chanacs_close(ca);
	}

	if ((addflags | removeflags) == 0)
	{
		command_fail(si, fault_nochange, _("Channel access to \2%s\2 for \2%s\2 unchanged."), channel, target);
		return;
	}
	flagstr = bitmask_to_flags2(addflags, removeflags);
	wallops("\2%s\2 is forcing flags change \2%s\2 on \2%s\2 in \2%s\2.", get_oper_name(si), flagstr, target, mc->name);
	command_success_nodata(si, _("Flags \2%s\2 were set on \2%s\2 in \2%s\2."), flagstr, target, channel);
	logcommand(si, CMDLOG_ADMIN, "FFLAGS: \2%s\2 \2%s\2 \2%s\2", mc->name, target, flagstr);
	verbose(mc, "\2%s\2 forced flags change \2%s\2 on \2%s\2.", get_source_name(si), flagstr, target);
}
Beispiel #15
0
static void ns_cmd_resetpass(sourceinfo_t *si, int parc, char *parv[])
{
	myuser_t *mu;
	metadata_t *md;
	char *name = parv[0];
	char *newpass;

	if (!name)
	{
		command_fail(si, fault_needmoreparams, STR_INVALID_PARAMS, "RESETPASS");
		command_fail(si, fault_needmoreparams, _("Syntax: RESETPASS <account>"));
		return;
	}

	if (!(mu = myuser_find_by_nick(name)))
	{
		command_fail(si, fault_nosuch_target, _("\2%s\2 is not registered."), name);
		return;
	}

	if (is_soper(mu) && !has_priv(si, PRIV_ADMIN))
	{
		logcommand(si, CMDLOG_ADMIN, "failed RESETPASS \2%s\2 (is SOPER)", name);
		command_fail(si, fault_badparams, _("\2%s\2 belongs to a services operator; you need %s privilege to reset the password."), name, PRIV_ADMIN);
		return;
	}

	if ((md = metadata_find(mu, "private:mark:setter")))
	{
		if (has_priv(si, PRIV_MARK))
		{
			wallops("%s reset the password for the \2MARKED\2 account %s.", get_oper_name(si), entity(mu)->name);
			logcommand(si, CMDLOG_ADMIN, "RESETPASS: \2%s\2 (overriding mark by \2%s\2)", entity(mu)->name, md->value);
			command_success_nodata(si, _("Overriding MARK placed by %s on the account %s."), md->value, entity(mu)->name);
		}
		else
		{
			logcommand(si, CMDLOG_ADMIN, "failed RESETPASS \2%s\2 (marked by \2%s\2)", entity(mu)->name, md->value);
			command_fail(si, fault_badparams, _("This operation cannot be performed on %s, because the account has been marked by %s."), entity(mu)->name, md->value);
			return;
		}
	}
	else
	{
		wallops("%s reset the password for the account %s", get_oper_name(si), entity(mu)->name);
		logcommand(si, CMDLOG_ADMIN, "RESETPASS: \2%s\2", entity(mu)->name);
	}

	newpass = random_string(12);
	metadata_delete(mu, "private:setpass:key");
	metadata_add(mu, "private:sendpass:sender", get_oper_name(si));
	metadata_add(mu, "private:sendpass:timestamp", number_to_string(time(NULL)));
	set_password(mu, newpass);
	free(newpass);

	command_success_nodata(si, _("The password for \2%s\2 has been changed to \2%s\2."), entity(mu)->name, newpass);

	if (mu->flags & MU_NOPASSWORD)
	{
		mu->flags &= ~MU_NOPASSWORD;
		command_success_nodata(si, _("The \2%s\2 flag has been removed for account \2%s\2."), "NOPASSWORD", entity(mu)->name);
	}
}
Beispiel #16
0
/*
** mo_ojoin
**      parv[1] = channel
*/
static int
mo_ojoin(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct Channel *chptr;
	int move_me = 0;

	/* admins only */
	if(!IsOperAdmin(source_p))
	{
		sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "admin");
		return 0;
	}

	if(*parv[1] == '@' || *parv[1] == '+')
	{
		parv[1]++;
		move_me = 1;
	}

	if((chptr = find_channel(parv[1])) == NULL)
	{
		sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
				   form_str(ERR_NOSUCHCHANNEL), parv[1]);
		return 0;
	}

	if(IsMember(source_p, chptr))
	{
		sendto_one_notice(source_p, ":Please part %s before using OJOIN", parv[1]);
		return 0;
	}

	if(move_me == 1)
		parv[1]--;

	sendto_wallops_flags(UMODE_WALLOP, &me,
			     "OJOIN called for %s by %s!%s@%s",
			     parv[1], source_p->name, source_p->username, source_p->host);
	ilog(L_MAIN, "OJOIN called for %s by %s",
	     parv[1], get_oper_name(source_p));
	/* only sends stuff for #channels remotely */
	sendto_server(NULL, chptr, NOCAPS, NOCAPS,
			":%s WALLOPS :OJOIN called for %s by %s!%s@%s",
			me.name, parv[1],
			source_p->name, source_p->username, source_p->host);

	if(*parv[1] == '@')
	{
		add_user_to_channel(chptr, source_p, CHFL_CHANOP);
		sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
			      ":%s SJOIN %ld %s + :@%s",
			      me.id, (long) chptr->channelts, chptr->chname, source_p->id);
		send_channel_join(chptr, source_p);
		sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +o %s",
				     me.name, chptr->chname, source_p->name);

	}
	else if(*parv[1] == '+')
	{
		add_user_to_channel(chptr, source_p, CHFL_VOICE);
		sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
			      ":%s SJOIN %ld %s + :+%s",
			      me.id, (long) chptr->channelts, chptr->chname, source_p->id);
		send_channel_join(chptr, source_p);
		sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +v %s",
				     me.name, chptr->chname, source_p->name);
	}
	else
	{
		add_user_to_channel(chptr, source_p, CHFL_PEON);
		sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
			      ":%s JOIN %ld %s +",
			      source_p->id, (long) chptr->channelts, chptr->chname);
		send_channel_join(chptr, source_p);
	}

	/* send the topic... */
	if(chptr->topic != NULL)
	{
		sendto_one(source_p, form_str(RPL_TOPIC), me.name,
			   source_p->name, chptr->chname, chptr->topic);
		sendto_one(source_p, form_str(RPL_TOPICWHOTIME), me.name,
			   source_p->name, chptr->chname, chptr->topic_info, chptr->topic_time);
	}

	source_p->localClient->last_join_time = rb_current_time();
	channel_member_names(chptr, source_p, 1);

	return 0;
}
Beispiel #17
0
/* parse_resv()
 *
 * inputs	- source_p, NULL supported
 *		- thing to resv
 *		- reason
 * outputs	- none
 * side effects	- parse resv, create if valid
 */
static void
parse_resv (struct Client *source_p, char *name, char *reason, int cluster)
{
  struct ConfItem *conf;

  if (IsChanPrefix (*name))
    {
      struct ResvChannel *resv_p;

      if ((conf = create_channel_resv (name, reason, 0)) == NULL)
	{
	  if (!cluster)
	    sendto_one (source_p,
			":%s NOTICE %s :A RESV has already been placed on channel: %s",
			me.name, source_p->name, name);
	  return;
	}

      resv_p = (struct ResvChannel *) map_to_conf (conf);

      if (!cluster)
	sendto_one (source_p,
		    ":%s NOTICE %s :A %s RESV has been placed on channel: %s",
		    me.name, source_p->name,
		    (MyClient (source_p) ? "local" : "remote"), name);
      sendto_realops_flags (UMODE_ALL, L_ALL,
			    "%s has placed a %s RESV on channel: %s [%s]",
			    get_oper_name (source_p),
			    (MyClient (source_p) ? "local" : "remote"),
			    resv_p->name, resv_p->reason);
      write_conf_line (source_p, conf, NULL /* not used */ ,
		       0 /* not used */ );
    }
  else if (clean_resv_nick (name))
    {
      struct MatchItem *resv_p;

      if ((strchr (name, '*') || strchr (name, '?')) && !IsAdmin (source_p))
	{
	  if (!cluster)
	    sendto_one (source_p,
			":%s NOTICE %s :You must be an admin to perform a wildcard RESV",
			me.name, source_p->name);
	  return;
	}

      if ((conf = create_nick_resv (name, reason, 0)) == NULL)
	{
	  if (!cluster)
	    sendto_one (source_p,
			":%s NOTICE %s :A RESV has already been placed on nick: %s",
			me.name, source_p->name, name);
	  return;
	}

      resv_p = (struct MatchItem *) map_to_conf (conf);

      if (!cluster)
	sendto_one (source_p,
		    ":%s NOTICE %s :A %s RESV has been placed on nick: %s [%s]",
		    me.name, source_p->name,
		    (MyClient (source_p) ? "local" : "remote"),
		    conf->name, resv_p->reason);
      sendto_realops_flags (UMODE_ALL, L_ALL,
			    "%s has placed a %s RESV on nick: %s [%s]",
			    get_oper_name (source_p),
			    (MyClient (source_p) ? "local" : "remote"),
			    conf->name, resv_p->reason);
      write_conf_line (source_p, conf, NULL /* not used */ ,
		       0 /* not used */ );
    }
  else if (!cluster)
    sendto_one (source_p,
		":%s NOTICE %s :You have specified an invalid resv: [%s]",
		me.name, source_p->name, name);
}
Beispiel #18
0
static void
remove_resv(struct Client *source_p, const char *name)
{
	struct ConfItem *conf = NULL;
	int services = 0;

	if(IsServices(source_p))
		services = 1;

	if(IsChanPrefix(*name))
	{
		struct ResvChannel *resv_p;

		if(resv_channel_list.head == NULL || !(resv_p = hash_find_resv(name)))
		{
			if(!services)
				sendto_one(source_p,
					   ":%s NOTICE %s :A RESV does not exist for channel: %s",
					   me.name, source_p->name, name);
			return;
		}

		if(resv_p->conf)
		{
			if(!services)
				sendto_one(source_p,
					   ":%s NOTICE %s :The RESV for channel: %s is in ircd.conf and must be removed by hand.",
					   me.name, source_p->name, name);
			return;
		}

		delete_channel_resv(resv_p);
		remove_conf_line(CRESV_TYPE, source_p, name, NULL);

		if(!services)
		{
			sendto_one(source_p,
				   ":%s NOTICE %s :The RESV has been removed on channel: %s",
				   me.name, source_p->name, name);
			sendto_realops_flags(UMODE_ALL, L_ALL,
					     "%s has removed the RESV for channel: %s",
					     get_oper_name(source_p), name);
		}
	}
	else
	{
		struct MatchItem *resv_p = NULL;

		if((conf = find_exact_name_conf(NRESV_TYPE, name, NULL, NULL, NULL)) == NULL)
		{
			if(!services)
				sendto_one(source_p,
					   ":%s NOTICE %s :A RESV does not exist for nick: %s",
					   me.name, source_p->name, name);
			return;
		}

		resv_p = map_to_conf(conf);

		if(resv_p->action)
		{
			if(!services)
				sendto_one(source_p,
					   ":%s NOTICE %s :The RESV for nick: %s is in ircd.conf and must be removed by hand.",
					   me.name, source_p->name, name);
			return;
		}

		delete_conf_item(conf);
		remove_conf_line(NRESV_TYPE, source_p, name, NULL);

		if(!services)
		{
			sendto_one(source_p, ":%s NOTICE %s :The RESV has been removed on nick: %s",
				   me.name, source_p->name, name);
			sendto_realops_flags(UMODE_ALL, L_ALL,
					     "%s has removed the RESV for nick: %s",
					     get_oper_name(source_p), name);
		}
	}
}
Beispiel #19
0
static void
remove_resv (struct Client *source_p, char *name, int cluster)
{
  struct ConfItem *conf;

  if (IsChanPrefix (*name))
    {
      struct ResvChannel *resv_p;

      if (resv_channel_list.head == NULL || !(resv_p = hash_find_resv (name)))
	{
	  if (!cluster)
	    sendto_one (source_p,
			":%s NOTICE %s :A RESV does not exist for channel: %s",
			me.name, source_p->name, name);
	  return;
	}
      else if (resv_p->conf)
	{
	  if (!cluster)
	    sendto_one (source_p,
			":%s NOTICE %s :The RESV for channel: %s is in ircd.conf and must be removed by hand.",
			me.name, source_p->name, name);
	  return;
	}
      else
	{
	  delete_channel_resv (resv_p);
	  (void) remove_conf_line (CRESV_TYPE, source_p, name, NULL);

	  if (!cluster)
	    sendto_one (source_p,
			":%s NOTICE %s :The RESV has been removed on channel: %s",
			me.name, source_p->name, name);
	  sendto_realops_flags (UMODE_ALL, L_ALL,
				"%s has removed the RESV for channel: %s",
				get_oper_name (source_p), name);
	}
    }
  else if (clean_resv_nick (name))
    {
      struct MatchItem *resv_p;
      conf = find_matching_name_conf (NRESV_TYPE, name, NULL, NULL, 0);

      if (conf == NULL)
	{
	  if (!cluster)
	    sendto_one (source_p,
			":%s NOTICE %s :A RESV does not exist for nick: %s",
			me.name, source_p->name, name);
	  return;
	}
      resv_p = (struct MatchItem *) map_to_conf (conf);
      if (resv_p->action)
	{
	  if (!cluster)
	    sendto_one (source_p,
			":%s NOTICE %s :The RESV for nick: %s is in ircd.conf and must be removed by hand.",
			me.name, source_p->name, name);
	  return;
	}
      else
	{
	  delete_conf_item (conf);
	  (void) remove_conf_line (NRESV_TYPE, source_p, name, NULL);

	  if (!cluster)
	    sendto_one (source_p,
			":%s NOTICE %s :The RESV has been removed on nick: %s",
			me.name, source_p->name, name);
	  sendto_realops_flags (UMODE_ALL, L_ALL,
				"%s has removed the RESV for nick: %s",
				get_oper_name (source_p), name);
	}
    }
}
Beispiel #20
0
/*
 * mo_omode - MODE command handler
 * parv[1] - channel
 */
static int
mo_omode(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct Channel *chptr = NULL;
	struct membership *msptr;
	char params[512];
	int i;
	int wasonchannel;

	/* admins only */
	if(!IsOperAdmin(source_p))
	{
		sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "admin");
		return 0;
	}

	/* Now, try to find the channel in question */
	if(!IsChanPrefix(parv[1][0]) || !check_channel_name(parv[1]))
	{
		sendto_one_numeric(source_p, ERR_BADCHANNAME,
				form_str(ERR_BADCHANNAME), parv[1]);
		return 0;
	}

	chptr = find_channel(parv[1]);

	if(chptr == NULL)
	{
		sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
				form_str(ERR_NOSUCHCHANNEL), parv[1]);
		return 0;
	}

	/* Now know the channel exists */
	msptr = find_channel_membership(chptr, source_p);
	wasonchannel = msptr != NULL;

	if (is_any_op(msptr))
	{
		sendto_one_notice(source_p, ":Use a normal MODE you idiot");
		return 0;
	}

	params[0] = '\0';
	for (i = 2; i < parc; i++)
	{
		if (i != 2)
			rb_strlcat(params, " ", sizeof params);
		rb_strlcat(params, parv[i], sizeof params);
	}

	sendto_wallops_flags(UMODE_WALLOP, &me, 
			     "OMODE called for [%s] [%s] by %s!%s@%s",
			     parv[1], params, source_p->name, source_p->username, source_p->host);
	ilog(L_MAIN, "OMODE called for [%s] [%s] by %s",
	     parv[1], params, get_oper_name(source_p));

	if(*chptr->chname != '&')
		sendto_server(NULL, NULL, NOCAPS, NOCAPS, 
			      ":%s WALLOPS :OMODE called for [%s] [%s] by %s!%s@%s",
			      me.name, parv[1], params, source_p->name, source_p->username,
			      source_p->host);

#if 0
	set_channel_mode(client_p, source_p->servptr, chptr, msptr, 
			 parc - 2, parv + 2);
#else
        if (parc == 4 && !strcmp(parv[2], "+y") && !irccmp(parv[3], source_p->name))
        {
                /* Ownering themselves */
                if (!wasonchannel)
                {
                        sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL,
                                        form_str(ERR_USERNOTINCHANNEL), parv[3], chptr->chname);
                        return 0;
                }
                sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +y %s",
                                me.name, parv[1], source_p->name);
                sendto_server(NULL, chptr, CAP_TS6, NOCAPS,
                                ":%s TMODE %ld %s +y %s",
                                me.id, (long) chptr->channelts, parv[1],
                                source_p->id);
                msptr->flags |= CHFL_OWNER;
        }
        else if (parc == 4 && !strcmp(parv[2], "+a") && !irccmp(parv[3], source_p->name))
	{
		/* Admining themselves */
		if (!wasonchannel)
		{
			sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL,
					   form_str(ERR_USERNOTINCHANNEL), parv[3], chptr->chname);
			return 0;
		}
		sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +a %s",
				me.name, parv[1], source_p->name);
		sendto_server(NULL, chptr, CAP_TS6, NOCAPS,
				":%s TMODE %ld %s +a %s",
				me.id, (long) chptr->channelts, parv[1],
				source_p->id);
		msptr->flags |= CHFL_ADMIN;
	}
	else if (parc == 4 && !strcmp(parv[2], "+o") && !irccmp(parv[3], source_p->name))
	{
		/* Opping themselves */
		if (!wasonchannel)
		{
			sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL,
					   form_str(ERR_USERNOTINCHANNEL), parv[3], chptr->chname);
			return 0;
		}
		sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +o %s",
				me.name, parv[1], source_p->name);
		sendto_server(NULL, chptr, CAP_TS6, NOCAPS,
				":%s TMODE %ld %s +o %s",
				me.id, (long) chptr->channelts, parv[1],
				source_p->id);
		msptr->flags |= CHFL_CHANOP;
	}
	else if (parc == 4 && !strcmp(parv[2], "+h") && !irccmp(parv[3], source_p->name))
	{
		/* Halfopping themselves */
		if (!wasonchannel)
		{
			sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL,
					   form_str(ERR_USERNOTINCHANNEL), parv[3], chptr->chname);
			return 0;
		}
		sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +h %s",
				me.name, parv[1], source_p->name);
		sendto_server(NULL, chptr, CAP_TS6, NOCAPS,
				":%s TMODE %ld %s +h %s",
				me.id, (long) chptr->channelts, parv[1],
				source_p->id);
		msptr->flags |= CHFL_HALFOP;
	}
        else if (ConfigChannel.use_owner)
        {
                /* I hope this is correct.
                 * -- Kabaka */

                /* Hack it so set_channel_mode() will accept */
                if (wasonchannel)
                        msptr->flags |= CHFL_OWNER;
                else
                {
                        add_user_to_channel(chptr, source_p, CHFL_CHANOP);
                        msptr = find_channel_membership(chptr, source_p);
                }
                set_channel_mode(client_p, source_p, chptr, msptr,
                                parc - 2, parv + 2);
                if (wasonchannel)
                        msptr->flags &= ~CHFL_OWNER;
                else
                        remove_user_from_channel(msptr);
        }
	else if (ConfigChannel.use_admin)
	{
		/* Hack it so set_channel_mode() will accept */
		if (wasonchannel)
			msptr->flags |= CHFL_ADMIN;
		else
		{
			add_user_to_channel(chptr, source_p, CHFL_CHANOP);
			msptr = find_channel_membership(chptr, source_p);
		}
		set_channel_mode(client_p, source_p, chptr, msptr, 
				parc - 2, parv + 2);
		/* We know they were not opped before and they can't have opped
		 * themselves as set_channel_mode() does not allow that
		 * -- jilles */
		if (wasonchannel)
			msptr->flags &= ~CHFL_ADMIN;
		else
			remove_user_from_channel(msptr);
	}
	else
	{
		/* CHFL_ADMIN is only useful if admin is enabled
		 * so hack it with op if it is not. */
		if (wasonchannel)
			msptr->flags |= CHFL_CHANOP;
		else
		{
			add_user_to_channel(chptr, source_p, CHFL_CHANOP);
			msptr = find_channel_membership(chptr, source_p);
		}
		set_channel_mode(client_p, source_p, chptr, msptr, 
				parc - 2, parv + 2);
		/* We know they were not opped before and they can't have opped
		 * themselves as set_channel_mode() does not allow that 
		 * -- jilles */
		if (wasonchannel)
			msptr->flags &= ~CHFL_CHANOP;
		else
			remove_user_from_channel(msptr);
	}
#endif
	return 0;
}
Beispiel #21
0
/*
 * mo_rehash - REHASH message handler
 *
 */
static void
mo_rehash(struct Client *client_p, struct Client *source_p,
          int parc, char *parv[])
{
  int found = 0;

  if (!IsOperRehash(source_p))
  {
    sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
               me.name, source_p->name);
    return;
  }

  if (parc > 1)
  {
    if (irccmp(parv[1], "DNS") == 0)
    {
      sendto_one(source_p, form_str(RPL_REHASHING), me.name, parv[0], "DNS");
      sendto_realops_flags(UMODE_ALL, L_ALL, "%s is rehashing DNS",
                           get_oper_name(source_p));
      restart_resolver();   /* re-read /etc/resolv.conf AGAIN?
                               and close/re-open res socket */
      found = 1;
    }
    else if (irccmp(parv[1], "MOTD") == 0)
    {
      sendto_realops_flags(UMODE_ALL, L_ALL,
                           "%s is forcing re-reading of MOTD file",
                           get_oper_name(source_p));
      read_message_file(&ConfigFileEntry.motd);
      found = 1;
    }
    else if (irccmp(parv[1], "OMOTD") == 0)
    {
      sendto_realops_flags(UMODE_ALL, L_ALL,
                           "%s is forcing re-reading of OPER MOTD file",
                           get_oper_name(source_p));
      read_message_file(&ConfigFileEntry.opermotd);
      found = 1;
    }

    if (found)
    {
      ilog(L_NOTICE, "REHASH %s From %s",
           parv[1], get_client_name(source_p, HIDE_IP));
      return;
    }
    else
    {
      sendto_one(source_p, ":%s NOTICE %s :rehash one of :DNS MOTD OMOTD",
                 me.name, source_p->name);
      return;
    }
  }
  else
  {
    sendto_one(source_p, form_str(RPL_REHASHING),
               me.name, source_p->name, ConfigFileEntry.configfile);
    sendto_realops_flags(UMODE_ALL, L_ALL,
                         "%s is rehashing server config file",
                         get_oper_name(source_p));
    ilog(L_NOTICE, "REHASH From %s[%s]",
         get_oper_name(source_p), source_p->localClient->sockhost);
    rehash(0);
  }
}