upas/smtp: handle temporary authentication failures
under heavy load, factotum can return a "too much activity" error, which upas/smtpd and upas/smtp should consider a temporary error instead of a permanent one.
This commit is contained in:
parent
4ff5a4febb
commit
56e71d5260
4 changed files with 32 additions and 10 deletions
|
@ -108,3 +108,12 @@ returnable(char *path)
|
||||||
{
|
{
|
||||||
return strcmp(path, "/dev/null") != 0;
|
return strcmp(path, "/dev/null") != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
temperror(void)
|
||||||
|
{
|
||||||
|
char err[ERRMAX];
|
||||||
|
|
||||||
|
rerrstr(err, sizeof(err));
|
||||||
|
return strstr(err, "too much activity") != nil || strstr(err, "temporary problem") != nil;
|
||||||
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ int shellchars(char*);
|
||||||
String *escapespecial(String*);
|
String *escapespecial(String*);
|
||||||
String *unescapespecial(String*);
|
String *unescapespecial(String*);
|
||||||
int returnable(char*);
|
int returnable(char*);
|
||||||
|
int temperror(void);
|
||||||
|
|
||||||
/* folder.c */
|
/* folder.c */
|
||||||
Biobuf *openfolder(char*, long);
|
Biobuf *openfolder(char*, long);
|
||||||
|
|
|
@ -30,8 +30,8 @@ void quit(char*);
|
||||||
char* rcptto(char*);
|
char* rcptto(char*);
|
||||||
char *rewritezone(char *);
|
char *rewritezone(char *);
|
||||||
|
|
||||||
#define Retry "Retry, Temporary Failure"
|
char Retry[] = "Retry, Temporary Failure";
|
||||||
#define Giveup "Permanent Failure"
|
char Giveup[] = "Permanent Failure";
|
||||||
|
|
||||||
String *reply; /* last reply */
|
String *reply; /* last reply */
|
||||||
String *toline;
|
String *toline;
|
||||||
|
@ -468,8 +468,12 @@ smtpcram(DS *ds)
|
||||||
n = auth_respond(ch, l, usr, sizeof usr, rbuf, sizeof rbuf, auth_getkey,
|
n = auth_respond(ch, l, usr, sizeof usr, rbuf, sizeof rbuf, auth_getkey,
|
||||||
"proto=cram role=client server=%q user=%q",
|
"proto=cram role=client server=%q user=%q",
|
||||||
ds->host, user);
|
ds->host, user);
|
||||||
if(n == -1)
|
if(n == -1){
|
||||||
return "cannot find SMTP password";
|
if(temperror())
|
||||||
|
return Retry;
|
||||||
|
syslog(0, "smtp.fail", "failed to get challenge response: %r");
|
||||||
|
return Giveup;
|
||||||
|
}
|
||||||
if(usr[0] == 0)
|
if(usr[0] == 0)
|
||||||
return "cannot find user name";
|
return "cannot find user name";
|
||||||
for(i = 0; i < n; i++)
|
for(i = 0; i < n; i++)
|
||||||
|
@ -498,6 +502,8 @@ doauth(char *methods)
|
||||||
"proto=pass service=smtp server=%q user=%q",
|
"proto=pass service=smtp server=%q user=%q",
|
||||||
ds.host, user);
|
ds.host, user);
|
||||||
if (p == nil) {
|
if (p == nil) {
|
||||||
|
if(temperror())
|
||||||
|
return Retry;
|
||||||
syslog(0, "smtp.fail", "failed to get userpasswd: %r");
|
syslog(0, "smtp.fail", "failed to get userpasswd: %r");
|
||||||
return Giveup;
|
return Giveup;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1685,9 +1685,7 @@ auth(String *mech, String *resp)
|
||||||
memset(s_to_c(s_resp1_64), 'X', s_len(s_resp1_64));
|
memset(s_to_c(s_resp1_64), 'X', s_len(s_resp1_64));
|
||||||
user = s_to_c(s_resp1) + strlen(s_to_c(s_resp1)) + 1;
|
user = s_to_c(s_resp1) + strlen(s_to_c(s_resp1)) + 1;
|
||||||
pass = user + strlen(user) + 1;
|
pass = user + strlen(user) + 1;
|
||||||
// ai = auth_userpasswd(user, pass);
|
authenticated = passauth(user, pass) != -1;
|
||||||
// authenticated = ai != nil;
|
|
||||||
authenticated = passauth(user, pass) != -1;
|
|
||||||
memset(pass, 'X', strlen(pass));
|
memset(pass, 'X', strlen(pass));
|
||||||
goto windup;
|
goto windup;
|
||||||
}
|
}
|
||||||
|
@ -1727,8 +1725,13 @@ windup:
|
||||||
reply("235 2.0.0 Authentication successful\r\n");
|
reply("235 2.0.0 Authentication successful\r\n");
|
||||||
} else {
|
} else {
|
||||||
rejectcount++;
|
rejectcount++;
|
||||||
reply("535 5.7.1 Authentication failed\r\n");
|
if(temperror()){
|
||||||
syslog(0, "smtpd", "authentication failed: %r");
|
syslog(0, "smtpd", "temporary authentication failure: %r");
|
||||||
|
reply("454 4.7.0 Temporary authentication failure\r\n");
|
||||||
|
} else {
|
||||||
|
syslog(0, "smtpd", "authentication failed: %r");
|
||||||
|
reply("535 5.7.1 Authentication failed\r\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
goto bomb_out;
|
goto bomb_out;
|
||||||
}
|
}
|
||||||
|
@ -1738,7 +1741,10 @@ windup:
|
||||||
chs = auth_challenge("proto=cram role=server");
|
chs = auth_challenge("proto=cram role=server");
|
||||||
if (chs == nil) {
|
if (chs == nil) {
|
||||||
rejectcount++;
|
rejectcount++;
|
||||||
reply("501 5.7.5 Couldn't get CRAM-MD5 challenge\r\n");
|
if(temperror())
|
||||||
|
reply("454 4.7.0 Temporary authentication failure\r\n");
|
||||||
|
else
|
||||||
|
reply("501 5.7.5 Couldn't get CRAM-MD5 challenge\r\n");
|
||||||
goto bomb_out;
|
goto bomb_out;
|
||||||
}
|
}
|
||||||
reply("334 %.*[\r\n", chs->nchal, chs->chal);
|
reply("334 %.*[\r\n", chs->nchal, chs->chal);
|
||||||
|
|
Loading…
Reference in a new issue