AR_NEEDS_USER, /**< user must send USER command */
AR_NEEDS_NICK, /**< user must send NICK command */
AR_LAST_SCAN = AR_NEEDS_NICK, /**< maximum flag to scan through */
+ AR_ZOMBIE_RECOVER, /**< nick of user is already taken by a zombie - try to recover */
AR_IAUTH_PENDING, /**< iauth request sent, waiting for response */
AR_IAUTH_HURRY, /**< we told iauth to hurry up */
AR_IAUTH_USERNAME, /**< iauth sent a username (preferred or forced) */
unsigned int cookie; /**< cookie the user must PONG */
unsigned short port; /**< client's remote port number */
unsigned int numeric; /**< unregistered client numeric */
+ struct Client* recover_client; /**< zombie client to be recovered later */
char loc_user[ACCOUNTLEN];
char loc_pass[PASSWDLEN];
};
MSG("NOTICE AUTH :*** Checking login\r\n"),
MSG("NOTICE AUTH :*** Login rejected\r\n"),
MSG("NOTICE AUTH :*** Login accepted\r\n"),
+ MSG("NOTICE AUTH :*** Nickname in Use by Zombie - try to recover\r\n"),
#undef MSG
};
REPORT_INVAL_DNS,
REPORT_DO_LOC,
REPORT_FAIL_LOC,
- REPORT_DONE_LOC
+ REPORT_DONE_LOC,
+ REPORT_ZOMBIE_RECOVER
} ReportType;
/** Sends response \a r (from #ReportType) to client \a c. */
if (IsUserPort(auth->client))
{
+ if(FlagHas(&auth->flags, AR_ZOMBIE_RECOVER)) {
+ /* check if able to recover connection */
+ if(!IsAccount(auth->client) || ircd_strcmp(cli_user(auth->client)->account, cli_user(auth->recover_client)->account)) {
+ send_reply(auth->client, ERR_RECOVERDENIED, cli_name(auth->recover_client), "auth missmatch");
+
+ /* reset nickname */
+ FlagSet(&auth->flags, AR_NEEDS_NICK);
+ send_reply(auth->client, ERR_NICKNAMEINUSE, cli_name(auth->recover_client));
+ hRemClient(auth->client);
+ (cli_name(auth->client))[0] = '\0';
+ return 0;
+ }
+ }
memset(cli_passwd(auth->client), 0, sizeof(cli_passwd(auth->client)));
res = auth_set_username(auth);
if (res == 0)
res = register_user(auth->client, auth->client);
+ if (res == 0 && FlagHas(&auth->flags, AR_ZOMBIE_RECOVER)) {
+ unzombie_client(&me, &me, auth->client, auth->recover_client);
+ auth->client = auth->recover_client;
+ }
}
else
res = 0;
return check_auth_finished(auth);
}
+/** Set Zombie Client that should be recovered later
+ */
+int auth_set_recover_client(struct AuthRequest *auth, struct Client *zombie)
+{
+ assert(auth != NULL);
+ FlagSet(&auth->flags, AR_ZOMBIE_RECOVER);
+ auth->recover_client = zombie;
+
+ sendheader(auth->client, REPORT_ZOMBIE_RECOVER);
+}
+
/** Handle authorization-related aspects of initial nickname selection.
* This is called after verifying that the nickname is available.
* @param[in] auth Authorization request for client.
{
assert(auth != NULL);
FlagClr(&auth->flags, AR_NEEDS_NICK);
+
/*
* If the client hasn't gotten a cookie-ping yet,
* choose a cookie and send it. -record!jegelhof@cloud9.net