diff --git a/include/h.h b/include/h.h index ff86647f5..d0d837376 100644 --- a/include/h.h +++ b/include/h.h @@ -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); diff --git a/src/modules/sasl.c b/src/modules/sasl.c index b5e46b8de..d12d734a1 100644 --- a/src/modules/sasl.c +++ b/src/modules/sasl.c @@ -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]); } /* diff --git a/src/modules/svsmode.c b/src/modules/svsmode.c index 5ddb89046..4772abcf9 100644 --- a/src/modules/svsmode.c +++ b/src/modules/svsmode.c @@ -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 { diff --git a/src/user.c b/src/user.c index b16a92903..cb1799e9d 100644 --- a/src/user.c +++ b/src/user.c @@ -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); +}