1
0
mirror of https://github.com/unrealircd/unrealircd.git synced 2026-06-30 03:16:38 +02:00

Make SVSLOGIN a broadcast, so all servers have the same svid information

for the user. Otherwise with post-connect SASL authentication you will
have different login information on server X compared to server Y
(the server with the user on it was always correct, though).

Also, add a function called user_account_login() which is used by both
SVSMODE/SVS2MODE and SVSLOGIN to send ACCOUNT messages to the channel.
This too was missing for SVSLOGIN (post-authentication SASL).

For this fix to be 100% effective, you need 100% UnrealIRCd 5.
This commit is contained in:
Bram Matthys
2019-11-18 15:35:41 +01:00
parent 54513307ec
commit ab42e12002
4 changed files with 39 additions and 24 deletions
+1
View File
@@ -958,3 +958,4 @@ extern void sendnotice_multiline(Client *client, MultiLine *m);
extern void unreal_del_quotes(char *i);
extern char *unreal_add_quotes(char *str);
extern int unreal_add_quotes_r(char *i, char *o, size_t len);
extern void user_account_login(MessageTag *recv_mtags, Client *client);
+24 -16
View File
@@ -73,34 +73,42 @@ long CAP_SASL = 0L;
*/
CMD_FUNC(cmd_svslogin)
{
Client *target;
if (!SASL_SERVER || MyUser(client) || (parc < 3) || !parv[3])
return;
if (!strcasecmp(parv[1], me.name) || !strncmp(parv[1], me.id, 3))
/* We actually ignore parv[1] since this is a broadcast message.
* It is a broadcast message because we want ALL servers to know
* that the user is now logged in under account xyz.
*/
target = find_client(parv[2], NULL);
if (!target)
return; /* client not found */
if (IsServer(target))
return;
if (target->user == NULL)
make_user(target);
strlcpy(target->user->svid, parv[3], sizeof(target->user->svid));
if (MyConnect(target))
{
Client *target;
target = find_client(parv[2], NULL);
if (!target || !MyConnect(target))
return;
if (target->user == NULL)
make_user(target);
strlcpy(target->user->svid, parv[3], sizeof(target->user->svid));
/* Notify user */
sendnumeric(target, RPL_LOGGEDIN,
BadPtr(target->name) ? "*" : target->name,
BadPtr(target->user->username) ? "*" : target->user->username,
BadPtr(target->user->realhost) ? "*" : target->user->realhost,
target->user->svid, target->user->svid);
return;
}
/* not for us; propagate. */
user_account_login(recv_mtags, target);
/* Propagate to the rest of the network */
sendto_server(client, 0, 0, NULL, ":%s SVSLOGIN %s %s %s",
client->name, parv[1], parv[2], parv[3]);
client->name, parv[1], parv[2], parv[3]);
}
/*
+1 -8
View File
@@ -406,15 +406,8 @@ void do_svsmode(Client *client, MessageTag *recv_mtags, int parc, char *parv[],
case 'd':
if (parv[3])
{
MessageTag *mtags = NULL;
strlcpy(target->user->svid, parv[3], sizeof(target->user->svid));
new_message(target, recv_mtags, &mtags);
sendto_local_common_channels(target, target,
ClientCapabilityBit("account-notify"), mtags,
":%s ACCOUNT %s",
target->name,
!isdigit(*target->user->svid) ? target->user->svid : "*");
free_message_tags(mtags);
user_account_login(recv_mtags, target);
}
else
{
+13
View File
@@ -693,3 +693,16 @@ void make_cloakedhost(Client *client, char *curr, char *buf, size_t buflen)
strlcpy(buf, mask, buflen);
}
/** Called after a user is logged in (or out) of a services account */
void user_account_login(MessageTag *recv_mtags, Client *client)
{
MessageTag *mtags = NULL;
new_message(client, recv_mtags, &mtags);
sendto_local_common_channels(client, client,
ClientCapabilityBit("account-notify"), mtags,
":%s ACCOUNT %s",
client->name,
!isdigit(*client->user->svid) ? client->user->svid : "*");
free_message_tags(mtags);
}