summaryrefslogtreecommitdiffstats
path: root/database
diff options
context:
space:
mode:
Diffstat (limited to 'database')
-rw-r--r--database/eurephiadb_driver.h4
-rw-r--r--database/sqlite/edb-sqlite.c96
-rw-r--r--database/sqlite/sql-schema.sql8
3 files changed, 75 insertions, 33 deletions
diff --git a/database/eurephiadb_driver.h b/database/eurephiadb_driver.h
index 00c2ba4..e59f2ba 100644
--- a/database/eurephiadb_driver.h
+++ b/database/eurephiadb_driver.h
@@ -86,8 +86,8 @@ int (*eDBstore_session_value) (eurephiaCTX *ctx, eurephiaSESSION *skey, int mode
const char *key, const char *val);
/* API version 2 functions */
-int (*eDBadminAuth) (eurephiaCTX *ctx, const char *uname, const char *pwd);
-int (*eDBadminValidateSession) (eurephiaCTX *ctx, const char *sesskey);
+int (*eDBadminAuth) (eurephiaCTX *ctx, const char *req_acc, const char *uname, const char *pwd);
+int (*eDBadminValidateSession) (eurephiaCTX *ctx, const char *sesskey, const char *req_acc);
int (*eDBadminRegisterLogin) (eurephiaCTX *ctx, eurephiaSESSION *session);
int (*eDBadminLogout) (eurephiaCTX *ctx, eurephiaSESSION *session);
diff --git a/database/sqlite/edb-sqlite.c b/database/sqlite/edb-sqlite.c
index 4227234..220d9f7 100644
--- a/database/sqlite/edb-sqlite.c
+++ b/database/sqlite/edb-sqlite.c
@@ -931,16 +931,23 @@ eurephiaVALUES *eDBget_blacklisted_ip(eurephiaCTX *ctx) {
*/
// Authenticate admin user against user database
-int eDBadminAuth(eurephiaCTX *ctx, const char *uname, const char *pwd) {
+int eDBadminAuth(eurephiaCTX *ctx, const char *req_access, const char *uname, const char *pwd) {
dbresult *res = NULL;
char *crpwd = NULL;
char *activated = NULL, *deactivated = NULL, *blid = NULL;
- int uid = -1, admacc = 0, pwok = 0;
+ int uid = -1, pwok = 0;
+ char interface, *access = NULL;
assert(ctx != NULL);
- if( (ctx->context_type != ECTX_ADMIN_CONSOLE)
- && (ctx->context_type != ECTX_ADMIN_WEB) ) {
+ switch( ctx->context_type ) {
+ case ECTX_ADMIN_CONSOLE:
+ interface = 'C';
+ break;
+ case ECTX_ADMIN_WEB:
+ interface = 'W';
+ break;
+ default:
eurephia_log(ctx, LOG_ERROR, 0, "Wrong eurephia context type (0x%04x)", ctx->context_type);
return 0;
}
@@ -957,7 +964,7 @@ int eDBadminAuth(eurephiaCTX *ctx, const char *uname, const char *pwd) {
assert(crpwd != NULL);
res = sqlite_query(ctx,
"SELECT activated, deactivated, bl.blid, "
- " (password = '%q') AS pwok, acc_admin, uid"
+ " (password = '%q') AS pwok, uid "
" FROM openvpn_users ou"
" LEFT JOIN openvpn_blacklist bl USING (username)"
" WHERE ou.username = '%q'",
@@ -965,7 +972,7 @@ int eDBadminAuth(eurephiaCTX *ctx, const char *uname, const char *pwd) {
memset(crpwd, 0, strlen_nullsafe(crpwd));
free_nullsafe(crpwd);
- if( !res ) {
+ if( res == NULL ) {
eurephia_log(ctx, LOG_FATAL, 0, "Could not authenticate user against the database");
return 0;
}
@@ -975,8 +982,8 @@ int eDBadminAuth(eurephiaCTX *ctx, const char *uname, const char *pwd) {
deactivated = sqlite_get_value(res, 0, 1);
blid = sqlite_get_value(res, 0, 2);
pwok = atoi_nullsafe(sqlite_get_value(res, 0, 3));
- admacc = atoi_nullsafe(sqlite_get_value(res, 0, 4));
- uid = atoi_nullsafe(sqlite_get_value(res, 0, 5));
+ uid = atoi_nullsafe(sqlite_get_value(res, 0, 4));
+ sqlite_free_results(res);
if( blid != NULL ) {
eurephia_log(ctx, LOG_WARNING, 0,
@@ -997,57 +1004,83 @@ int eDBadminAuth(eurephiaCTX *ctx, const char *uname, const char *pwd) {
return 0;
}
- if( admacc != 1 ) {
- eurephia_log(ctx, LOG_WARNING, 0, "Your user account is lacking privileges");
+ if( pwok != 1 ) {
+ eurephia_log(ctx, LOG_WARNING, 0, "Authentication failed,");
sqlite_free_results(res);
return 0;
}
- if( pwok != 1 ) {
- eurephia_log(ctx, LOG_WARNING, 0, "Authentication failed,");
- sqlite_free_results(res);
+ // Check if access level is granted
+ // (SQLite do not handle advanced joins so well, so we need to
+ // do this check with an extra query)
+ res = sqlite_query(ctx,
+ "SELECT (count(*) = 1) AS access "
+ " FROM eurephia_adminaccess"
+ " WHERE uid = '%i' AND interface = '%c' AND access = '%q'",
+ uid, interface, req_access);
+ if( res == NULL ) {
+ eurephia_log(ctx, LOG_FATAL, 0, "Could not check access level");
+ return 0;
+ }
+ access = atoi_nullsafe(sqlite_get_value(res, 0, 0));
+ sqlite_free_results(res);
+
+ if( access == 0 ) {
+ eurephia_log(ctx, LOG_WARNING, 0, "Your account is lacking privileges for this operation");
return 0;
}
} else {
- eurephia_log(ctx, LOG_WARNING, 0, "Authentication failed. Too many records found.");
+ eurephia_log(ctx, LOG_WARNING, 0, "Authentication failed. No unique records found.");
sqlite_free_results(res);
return 0;
}
- sqlite_free_results(res);
// If we reach this place, authentication was successful. Return users uid
return uid;
}
-int eDBadminValidateSession(eurephiaCTX *ctx, char *sesskey) {
+int eDBadminValidateSession(eurephiaCTX *ctx, const char *sesskey, const char *req_access) {
dbresult *res = NULL;
- int valid = 0;
+ int valid = 0, access = 0, expire_time = 0;
+ char interface;
assert( (ctx != NULL) && (sesskey != NULL) );
- if( (ctx->context_type != ECTX_ADMIN_CONSOLE)
- && (ctx->context_type != ECTX_ADMIN_WEB) ) {
+ switch( ctx->context_type ) {
+ case ECTX_ADMIN_CONSOLE:
+ interface = 'C';
+ break;
+ case ECTX_ADMIN_WEB:
+ interface = 'W';
+ break;
+ default:
eurephia_log(ctx, LOG_ERROR, 0, "Wrong eurephia context type (0x%04x)", ctx->context_type);
return 0;
}
- // Check if the session is still valid.
+ // Check if the session is still valid (not expired) and that this session are allowed to access
+ // the requested access level.
+ expire_time = (60 * atoi_nullsafe(defaultValue(eGet_value(ctx->dbc->config, "eurephiadmin_autologout"),
+ "10")
+ )
+ );
res = sqlite_query(ctx,
- "SELECT (strftime('%%s',CURRENT_TIMESTAMP)-strftime('%%s',last_action)) > %i"
+ "SELECT (strftime('%%s',CURRENT_TIMESTAMP)-strftime('%%s',last_action)) > %i AS exp,"
+ " (access IS NOT NULL) AS access"
" FROM eurephia_adminlog"
+ " LEFT JOIN eurephia_adminaccess USING(uid,interface)"
" WHERE status IN (1,2)"
- " AND sessionkey = '%q'",
- (60 * atoi_nullsafe(defaultValue(eGet_value(ctx->dbc->config,
- "eurephiadmin_autologout"),
- "10")
- )),
- sesskey);
+ " AND sessionkey = '%q'"
+ " AND access = '%q'",
+ expire_time, sesskey, req_access);
+
if( (res == NULL) || (sqlite_get_numtuples(res) != 1) ) {
eurephia_log(ctx, LOG_FATAL, 0, "Could not validate session");
return 0;
}
- valid = (atoi_nullsafe(sqlite_get_value(res, 0, 0)) == 0);
+ valid = (atoi_nullsafe(sqlite_get_value(res, 0, 0)) == 0);
+ access = (atoi_nullsafe(sqlite_get_value(res, 0, 1)) == 1);
sqlite_free_results(res);
// If still valid, update last_action
@@ -1060,6 +1093,10 @@ int eDBadminValidateSession(eurephiaCTX *ctx, char *sesskey) {
eurephia_log(ctx, LOG_ERROR, 0, "Could not register session activity");
}
sqlite_free_results(res);
+
+ if( !access ) {
+ eurephia_log(ctx, LOG_WARNING, 0, "Your user account is lacking privileges");
+ }
} else {
// If not valid, register session as auto-logged out
res = sqlite_query(ctx,
@@ -1081,8 +1118,7 @@ int eDBadminValidateSession(eurephiaCTX *ctx, char *sesskey) {
}
sqlite_free_results(res);
}
-
- return valid;
+ return (valid && access);
}
int eDBadminRegisterLogin(eurephiaCTX *ctx, eurephiaSESSION *session) {
diff --git a/database/sqlite/sql-schema.sql b/database/sqlite/sql-schema.sql
index 7fb6769..7f0d1af 100644
--- a/database/sqlite/sql-schema.sql
+++ b/database/sqlite/sql-schema.sql
@@ -15,7 +15,6 @@ CREATE TABLE openvpn_users (
activated timestamp ,
deactivated timestamp ,
last_accessed timestamp ,
- acc_admin boolean ,
uid integer PRIMARY KEY AUTOINCREMENT
);
CREATE UNIQUE INDEX openvpn_users_uname ON openvpn_users(username);
@@ -128,3 +127,10 @@ CREATE TABLE eurephia_adminlog (
CREATE INDEX eurephia_adminlog_uid ON eurephia_adminlog(uid);
CREATE INDEX eurephia_adminlog_sesskey ON eurephia_adminlog(sessionkey);
+CREATE TABLE eurephia_adminaccess (
+ uid integer NOT NULL,
+ interface char NOT NULL, -- C-onsole, W-eb
+ access varchar(64) NOT NULL
+);
+CREATE INDEX eurephia_adminacc_uid ON eurephia_adminaccess (uid);
+CREATE INDEX eurephia_adminacc_uid_intf ON eurephia_adminaccess (uid,interface);