+Use realusername where needed instead of username
+
Use realusername when looking for Operator blocks, Kill blocks, and G-lines.
-diff -r 0d42b86bc341 ircd/s_conf.c
---- a/ircd/s_conf.c Tue Feb 10 13:31:34 2009 +0100
-+++ b/ircd/s_conf.c Tue Feb 10 14:35:31 2009 +0100
-@@ -646,8 +646,8 @@
+Use realusername when matching usernames in WHO (provided the target user is +h, and the source user is an oper).
+
+Use realusername when checking the user@IP in nick collisions to determine which one to kill.
+
+Copy realusername from username where username itself is copied - do not copy from cli_username()
+as that is the one provided by the client (may contain bad chars?) and does not have the ~ prefix.
+
+TODO:
+
+Check realusername in bans/silences too? Currently it only matches the visible username.
+
+WHOWAS does not save the realusername, only the realhost.
+
+diff -r 4677b599b0cc ircd/gline.c
+--- a/ircd/gline.c
++++ b/ircd/gline.c
+@@ -259,7 +259,7 @@
+ match(gline->gl_nick, cli_name(acptr)) !=0)
+ continue;
+
+- if (cli_user(acptr)->username &&
++ if (cli_user(acptr)->realusername &&
+ match(gline->gl_user, (cli_user(acptr))->realusername) != 0)
+ continue;
+
+@@ -415,8 +415,8 @@
+ continue;
+
+ ircd_snprintf(0, namebuf, sizeof(namebuf), "%s@%s",
+- cli_user(acptr)->username, cli_user(acptr)->host);
+- ircd_snprintf(0, ipbuf, sizeof(ipbuf), "%s@%s", cli_user(acptr)->username,
++ cli_user(acptr)->realusername, cli_user(acptr)->host); /* TODO: should be realhost? ircu bug? */
++ ircd_snprintf(0, ipbuf, sizeof(ipbuf), "%s@%s", cli_user(acptr)->realusername,
+ ircd_ntoa(&cli_ip(acptr)));
+
+ if (!match(mask, namebuf)
+@@ -1342,7 +1342,7 @@
+ if (match(gline->gl_nick, nick) != 0)
+ continue;
+
+- if (match(gline->gl_user, (cli_user(cptr))->username) != 0)
++ if (match(gline->gl_user, (cli_user(cptr))->realusername) != 0)
+ continue;
+
+ if (GlineIsIpMask(gline)) {
+diff -r 4677b599b0cc ircd/m_nick.c
+--- a/ircd/m_nick.c
++++ b/ircd/m_nick.c
+@@ -421,7 +421,7 @@
+ */
+ base64toip(parv[parc - 3], &ip);
+ differ = (0 != memcmp(&cli_ip(acptr), &ip, sizeof(cli_ip(acptr)))) ||
+- (0 != ircd_strcmp(cli_user(acptr)->username, parv[4]));
++ (0 != ircd_strcmp(cli_user(acptr)->realusername, parv[4]));
+ sendto_opmask_butone(0, SNO_OLDSNO, "Nick collision on %C (%C %Tu <- "
+ "%C %Tu (%s user@host))", acptr, cli_from(acptr),
+ cli_lastnick(acptr), cptr, lastnick,
+@@ -435,7 +435,7 @@
+ * compare IP address and username
+ */
+ differ = (0 != memcmp(&cli_ip(acptr), &cli_ip(sptr), sizeof(cli_ip(acptr)))) ||
+- (0 != ircd_strcmp(cli_user(acptr)->username, cli_user(sptr)->username));
++ (0 != ircd_strcmp(cli_user(acptr)->realusername, cli_user(sptr)->realusername));
+ sendto_opmask_butone(0, SNO_OLDSNO, "Nick change collision from %C to "
+ "%C (%C %Tu <- %C %Tu)", sptr, acptr, cli_from(acptr),
+ cli_lastnick(acptr), cptr, lastnick);
+diff -r 4677b599b0cc ircd/m_who.c
+--- a/ircd/m_who.c
++++ b/ircd/m_who.c
+@@ -389,6 +389,10 @@
+ || matchexec(cli_name(acptr), mymask, minlen))
+ && ((!(matchsel & WHO_FIELD_UID))
+ || matchexec(cli_user(acptr)->username, mymask, minlen))
++ && ((!(matchsel & WHO_FIELD_UID))
++ || !IsSetHost(acptr)
++ || !IsAnOper(sptr)
++ || matchexec(cli_user(acptr)->realusername, mymask, minlen))
+ && ((!(matchsel & WHO_FIELD_SER))
+ || (!(HasFlag(cli_user(acptr)->server, FLAG_MAP))))
+ && ((!(matchsel & WHO_FIELD_HOS))
+@@ -428,6 +432,10 @@
+ || matchexec(cli_name(acptr), mymask, minlen))
+ && ((!(matchsel & WHO_FIELD_UID))
+ || matchexec(cli_user(acptr)->username, mymask, minlen))
++ && ((!(matchsel & WHO_FIELD_UID))
++ || !IsSetHost(acptr)
++ || !IsAnOper(sptr)
++ || matchexec(cli_user(acptr)->realusername, mymask, minlen))
+ && ((!(matchsel & WHO_FIELD_SER))
+ || (!(HasFlag(cli_user(acptr)->server, FLAG_MAP))))
+ && ((!(matchsel & WHO_FIELD_HOS))
+diff -r 4677b599b0cc ircd/s_auth.c
+--- a/ircd/s_auth.c
++++ b/ircd/s_auth.c
+@@ -232,6 +232,7 @@
+ char last;
+ char *reason;
+
++ /* TODO: */
+ if (FlagHas(&auth->flags, AR_IAUTH_USERNAME))
+ {
+ ircd_strncpy(cli_user(sptr)->username, cli_username(sptr), USERLEN);
+@@ -264,6 +265,7 @@
+ || ((user->username[0] == '~') && (user->username[1] == '\0')))
+ return exit_client(sptr, sptr, &me, "USER: Bogus userid.");
+
++ /* TODO: */
+ /* Have to set up "realusername" before doing the gline check below */
+ ircd_strncpy(user->realusername, user->username, USERLEN);
+
+@@ -1063,7 +1065,9 @@
+ FlagClr(&auth->flags, AR_NEEDS_USER);
+ cptr = auth->client;
+ ircd_strncpy(cli_info(cptr), userinfo, REALLEN);
++ /* TODO: */
+ ircd_strncpy(cli_user(cptr)->username, username, USERLEN);
++ ircd_strncpy(cli_user(cptr)->realusername, username, USERLEN);
+ ircd_strncpy(cli_user(cptr)->host, cli_sockhost(cptr), HOSTLEN);
+ if (IAuthHas(iauth, IAUTH_UNDERNET))
+ sendto_iauth(cptr, "U %s %s %s :%s", username, hostname, servername, userinfo);
+@@ -1723,8 +1727,11 @@
+ {
+ assert(cli_auth(cli) != NULL);
+ FlagClr(&cli_auth(cli)->flags, AR_AUTH_PENDING);
+- if (!EmptyString(params[0]))
++ /* TODO: */
++ if (!EmptyString(params[0])) {
+ ircd_strncpy(cli_user(cli)->username, params[0], USERLEN);
++ ircd_strncpy(cli_user(cli)->realusername, params[0], USERLEN);
++ }
+ return 1;
+ }
+
+diff -r 4677b599b0cc ircd/s_conf.c
+--- a/ircd/s_conf.c
++++ b/ircd/s_conf.c
+@@ -647,8 +647,8 @@
0 != ircd_strcmp(tmp->name, name))
continue;
if (tmp->username
continue;
if (tmp->addrbits < 0)
{
-@@ -1060,7 +1060,7 @@
+@@ -1061,7 +1061,7 @@
return 0;
host = cli_sockhost(cptr);
realname = cli_info(cptr);
assert(strlen(host) <= HOSTLEN);
+diff -r 4677b599b0cc ircd/s_misc.c
+--- a/ircd/s_misc.c
++++ b/ircd/s_misc.c
+@@ -399,7 +399,7 @@
+ if (IsUser(victim))
+ log_write(LS_USER, L_TRACE, 0, "%Tu %i %s@%s %s %s %s%s %s :%s",
+ cli_firsttime(victim), on_for,
+- cli_user(victim)->username, cli_sockhost(victim),
++ cli_user(victim)->realusername, cli_sockhost(victim),
+ ircd_ntoa(&cli_ip(victim)),
+ IsAccount(victim) ? cli_username(victim) : "0",
+ NumNick(victim), /* two %s's */