unrealircd

- supernets unrealircd source & configuration
git clone git://git.acid.vegas/unrealircd.git
Log | Files | Refs | Archive | README | LICENSE

chgident.c (4532B)

      1 /*
      2  *   IRC - Internet Relay Chat, src/modules/chgident.c
      3  *   (C) 1999-2001 Carsten Munk (Techie/Stskeeps) <stskeeps@tspre.org>
      4  *
      5  *   See file AUTHORS in IRC package for additional names of
      6  *   the programmers. 
      7  *
      8  *   This program is free software; you can redistribute it and/or modify
      9  *   it under the terms of the GNU General Public License as published by
     10  *   the Free Software Foundation; either version 1, or (at your option)
     11  *   any later version.
     12  *
     13  *   This program is distributed in the hope that it will be useful,
     14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  *   GNU General Public License for more details.
     17  *
     18  *   You should have received a copy of the GNU General Public License
     19  *   along with this program; if not, write to the Free Software
     20  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     21  */
     22 
     23 #include "unrealircd.h"
     24 
     25 #define MSG_CHGIDENT 	"CHGIDENT"
     26 
     27 CMD_FUNC(cmd_chgident);
     28 
     29 ModuleHeader MOD_HEADER
     30   = {
     31 	"chgident",	/* Name of module */
     32 	"5.0", /* Version */
     33 	"/chgident", /* Short description of module */
     34 	"UnrealIRCd Team",
     35 	"unrealircd-6",
     36     };
     37 
     38 MOD_INIT()
     39 {
     40 	CommandAdd(modinfo->handle, MSG_CHGIDENT, cmd_chgident, MAXPARA, CMD_USER|CMD_SERVER);
     41 	MARK_AS_OFFICIAL_MODULE(modinfo);
     42 	return MOD_SUCCESS;
     43 }
     44 
     45 MOD_LOAD()
     46 {
     47 	return MOD_SUCCESS;
     48 }
     49 
     50 MOD_UNLOAD()
     51 {
     52 	return MOD_SUCCESS;
     53 }
     54 
     55 /* 
     56  * cmd_chgident - 12/07/1999 (two months after I made SETIDENT) - Stskeeps
     57  * :prefix CHGIDENT <nick> <new identname>
     58  * parv[1] - nickname
     59  * parv[2] - identname
     60  *
     61 */
     62 
     63 CMD_FUNC(cmd_chgident)
     64 {
     65 	Client *target;
     66 	const char *s;
     67 	int legalident = 1;
     68 
     69 	if (!ValidatePermissionsForPath("client:set:ident",client,NULL,NULL,NULL))
     70 	{
     71 		sendnumeric(client, ERR_NOPRIVILEGES);
     72 		return;
     73 	}
     74 
     75 
     76 	if ((parc < 3) || !*parv[2])
     77 	{
     78 		sendnumeric(client, ERR_NEEDMOREPARAMS, "CHGIDENT");
     79 		return;
     80 	}
     81 
     82 	if (strlen(parv[2]) > (USERLEN))
     83 	{
     84 		sendnotice(client, "*** ChgIdent Error: Requested ident too long -- rejected.");
     85 		return;
     86 	}
     87 
     88 	if (!valid_username(parv[2]))
     89 	{
     90 		sendnotice(client, "*** /ChgIdent Error: A ident may contain a-z, A-Z, 0-9, '-' & '.' - Please only use them");
     91 		return;
     92 	}
     93 
     94 	target = find_client(parv[1], NULL);
     95 	if (!MyUser(client) && !target && (target = find_server_by_uid(parv[1])))
     96 	{
     97 		/* CHGIDENT for a UID that is not online.
     98 		 * Let's assume it may not YET be online and forward the message to
     99 		 * the remote server and stop processing ourselves.
    100 		 * That server will then handle pre-registered processing of the
    101 		 * CHGIDENT and later communicate the host when the user actually
    102 		 * comes online in the UID message.
    103 		 */
    104 		sendto_one(target, recv_mtags, ":%s CHGIDENT %s %s", client->id, parv[1], parv[2]);
    105 		return;
    106 	}
    107 
    108 	if (!target || !target->user)
    109 	{
    110 		sendnumeric(client, ERR_NOSUCHNICK, parv[1]);
    111 		return;
    112 	}
    113 	userhost_save_current(target);
    114 
    115 	switch (UHOST_ALLOWED)
    116 	{
    117 		case UHALLOW_NEVER:
    118 			if (MyUser(client))
    119 			{
    120 				sendnumeric(client, ERR_DISABLED, "CHGIDENT",
    121 					"This command is disabled on this server");
    122 				return;
    123 			}
    124 			break;
    125 		case UHALLOW_ALWAYS:
    126 			break;
    127 		case UHALLOW_NOCHANS:
    128 			if (IsUser(target) && MyUser(client) && target->user->joined)
    129 			{
    130 				sendnotice(client, "*** /ChgIdent can not be used while %s is on a channel", target->name);
    131 				return;
    132 			}
    133 			break;
    134 		case UHALLOW_REJOIN:
    135 			/* join sent later when the ident has been changed */
    136 			break;
    137 	}
    138 	if (!IsULine(client))
    139 	{
    140 		const char *issuer = command_issued_by_rpc(recv_mtags);
    141 		if (issuer)
    142 		{
    143 			unreal_log(ULOG_INFO, "chgcmds", "CHGIDENT_COMMAND", client,
    144 				   "CHGIDENT: $issuer changed the username of $target.details to be $new_username",
    145 				   log_data_string("issuer", issuer),
    146 				   log_data_string("change_type", "username"),
    147 				   log_data_client("target", target),
    148 				   log_data_string("new_username", parv[2]));
    149 		} else {
    150 			unreal_log(ULOG_INFO, "chgcmds", "CHGIDENT_COMMAND", client,
    151 				   "CHGIDENT: $client changed the username of $target.details to be $new_username",
    152 				   log_data_string("change_type", "username"),
    153 				   log_data_client("target", target),
    154 				   log_data_string("new_username", parv[2]));
    155 		}
    156 	}
    157 
    158 	/* Send to other servers too, unless the client is still in the registration phase (SASL) */
    159 	if (IsUser(target))
    160 		sendto_server(client, 0, 0, recv_mtags, ":%s CHGIDENT %s %s", client->id, target->id, parv[2]);
    161 
    162 	ircsnprintf(target->user->username, sizeof(target->user->username), "%s", parv[2]);
    163 	userhost_changed(target);
    164 }