Skip to content
This repository has been archived by the owner on Mar 12, 2019. It is now read-only.

Commit

Permalink
Merge pull request #111 from PierreF/backend-error
Browse files Browse the repository at this point in the history
Handle backend downtime in a safer way
  • Loading branch information
jpmens committed Nov 30, 2015
2 parents 4d4f738 + fb4c9c1 commit f3a31df
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 11 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -320,8 +320,10 @@ The following `auth_opt_` options are supported by the `http` back-end:
| http_aclcheck_uri | | Y | URI for check acl |
| http_with_tls | false | N | Use TLS on connect |

If the configured URLs return an HTTP status code == `200`, the authentication /
authorization succeeds, else it fails.
If the configured URLs return an HTTP status code == `2xx`, the authentication /
authorization succeeds. If the status code == `4xx` authentication /
authorization fails. For status code == `5xx` or server unreachable, if no
other backend succeeded, then an error is returned and client is disconnected.

| URI-Param | username | password | clientid | topic | acc |
| ----------------- | -------- | -------- | -------- | :---: | :-: |
Expand Down
15 changes: 14 additions & 1 deletion auth-plug.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ int mosquitto_auth_acl_check(void *userdata, const char *clientid, const char *u
struct userdata *ud = (struct userdata *)userdata;
struct backend_p **bep;
char *backend_name = NULL;
int match = 0, authorized = FALSE;
int match = 0, authorized = FALSE, has_error = FALSE;
int granted = MOSQ_DENY_ACL;

if (!username || !*username) { // anonymous users
Expand Down Expand Up @@ -504,6 +504,10 @@ int mosquitto_auth_acl_check(void *userdata, const char *clientid, const char *u
username, topic, access, b->name);
granted = MOSQ_ERR_SUCCESS;
goto outout;
} else if (match == BACKEND_ERROR) {
_log(LOG_DEBUG, "aclcheck(%s, %s, %d) HAS_ERROR=Y by %s",
username, topic, access, b->name);
has_error = TRUE;
}
}

Expand All @@ -521,6 +525,10 @@ int mosquitto_auth_acl_check(void *userdata, const char *clientid, const char *u
username, topic, access, b->name);
authorized = TRUE;
break;
} else if (match == BACKEND_ERROR) {
_log(LOG_DEBUG, "aclcheck(%s, %s, %d) HAS_ERROR=Y by %s",
username, topic, access, b->name);
has_error = TRUE;
}
}

Expand All @@ -529,6 +537,11 @@ int mosquitto_auth_acl_check(void *userdata, const char *clientid, const char *u
username, topic, access, authorized, backend_name);

granted = (authorized) ? MOSQ_ERR_SUCCESS : MOSQ_DENY_ACL;
if (granted == MOSQ_DENY_ACL && has_error) {
_log(LOG_DEBUG, "aclcheck(%s, %s, %d) AUTHORIZED=N HAS_ERROR=Y => ERR_UNKNOWN",
username, topic, access);
granted = MOSQ_ERR_UNKNOWN;
}

outout: /* goto fail goto fail */

Expand Down
3 changes: 3 additions & 0 deletions backends.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
#ifndef FALSE
# define FALSE (0)
#endif
#ifndef BACKEND_ERROR
# define BACKEND_ERROR (2)
#endif

#ifndef __BACKENDS_H
# define __BACKENDS_H
Expand Down
3 changes: 3 additions & 0 deletions be-http.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,11 +197,14 @@ static int http_post(void *handle, char *uri, const char *clientid, const char *
re = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &respCode);
if (re == CURLE_OK && respCode >= 200 && respCode < 300) {
ok = TRUE;
} else if (re == CURLE_OK && respCode >= 500) {
ok = BACKEND_ERROR;
} else {
//_log(LOG_NOTICE, "http auth fail re=%d respCode=%d", re, respCode);
}
} else {
_log(LOG_DEBUG, "http req fail url=%s re=%s", url, curl_easy_strerror(re));
ok = BACKEND_ERROR;
}

curl_easy_cleanup(curl);
Expand Down
14 changes: 8 additions & 6 deletions be-mysql.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,16 +248,16 @@ int be_mysql_superuser(void *handle, const char *username)
if (mysql_ping(conf->mysql)) {
fprintf(stderr, "%s\n", mysql_error(conf->mysql));
if (!auto_connect(conf)) {
return (FALSE);
return (BACKEND_ERROR);
}
}

if ((u = escape(conf, username, &ulen)) == NULL)
return (FALSE);
return (BACKEND_ERROR);

if ((query = malloc(strlen(conf->superquery) + ulen + 128)) == NULL) {
free(u);
return (FALSE);
return (BACKEND_ERROR);
}
sprintf(query, conf->superquery, u);
free(u);
Expand All @@ -266,6 +266,7 @@ int be_mysql_superuser(void *handle, const char *username)

if (mysql_query(conf->mysql, query)) {
fprintf(stderr, "%s\n", mysql_error(conf->mysql));
issuper = BACKEND_ERROR;
goto out;
}

Expand Down Expand Up @@ -323,16 +324,16 @@ int be_mysql_aclcheck(void *handle, const char *clientid, const char *username,
if (mysql_ping(conf->mysql)) {
fprintf(stderr, "%s\n", mysql_error(conf->mysql));
if (!auto_connect(conf)) {
return (FALSE);
return (BACKEND_ERROR);
}
}

if ((u = escape(conf, username, &ulen)) == NULL)
return (FALSE);
return (BACKEND_ERROR);

if ((query = malloc(strlen(conf->aclquery) + ulen + 128)) == NULL) {
free(u);
return (FALSE);
return (BACKEND_ERROR);
}
sprintf(query, conf->aclquery, u, acc);
free(u);
Expand All @@ -341,6 +342,7 @@ int be_mysql_aclcheck(void *handle, const char *clientid, const char *username,

if (mysql_query(conf->mysql, query)) {
_log(LOG_NOTICE, "%s", mysql_error(conf->mysql));
match = BACKEND_ERROR;
goto out;
}

Expand Down
2 changes: 2 additions & 0 deletions be-postgres.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ int be_pg_superuser(void *handle, const char *username)
if ( PQresultStatus(res) != PGRES_TUPLES_OK )
{
fprintf(stderr, "%s\n", PQresultErrorMessage(res));
issuper = BACKEND_ERROR;
goto out;
}

Expand Down Expand Up @@ -266,6 +267,7 @@ int be_pg_aclcheck(void *handle, const char *clientid, const char *username, con
if ( PQresultStatus(res) != PGRES_TUPLES_OK )
{
fprintf(stderr, "%s\n", PQresultErrorMessage(res));
match = BACKEND_ERROR;
goto out;
}

Expand Down
3 changes: 2 additions & 1 deletion be-redis.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <string.h>
#include "log.h"
#include "hash.h"
#include "backends.h"
#include <hiredis/hiredis.h>

struct redis_backend {
Expand Down Expand Up @@ -181,7 +182,7 @@ int be_redis_aclcheck(void *handle, const char *clientid, const char *username,
r = redisCommand(conf->redis, query, username, acc);
if (r == NULL || conf->redis->err != REDIS_OK) {
be_redis_reconnect(conf);
return 0;
return BACKEND_ERROR;
}

free(query);
Expand Down
2 changes: 1 addition & 1 deletion cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ void acl_cache(const char *clientid, const char *username, const char *topic, in

HASH_FIND_STR(ud->aclcache, hex, a);
if (a) {
granted = a->granted;
a->granted = granted;

if (time(NULL) > (a->seconds + cacheseconds)) {
_log(LOG_DEBUG, " Expired [%s] for (%s,%s,%d)", hex, clientid, username, access);
Expand Down

0 comments on commit f3a31df

Please sign in to comment.