Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions db/comdb2.c
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,12 @@ int64_t gbl_num_auth_allowed = 0;
int64_t gbl_num_auth_denied = 0;
int gbl_allow_old_authn = 0;
int gbl_uses_externalauth = 0;
int gbl_vtab_externalauth = 1;
int gbl_vtab_externalauth_strict = 0;
int gbl_uses_simpleauth = 0;
int gbl_uses_externalauth_connect = 0;
int gbl_externalauth_warn = 0;
int gbl_passwords_with_externalauth = 0;
int gbl_identity_cache_max = 500;
int gbl_authorization_cache_max = 2000;
int gbl_authentication_cache_ageout = 900;
Expand Down
3 changes: 3 additions & 0 deletions db/comdb2.h
Original file line number Diff line number Diff line change
Expand Up @@ -1650,9 +1650,12 @@ extern int gbl_allow_old_authn;
extern int gbl_uses_password;
extern int gbl_unauth_tag_access;
extern int gbl_uses_externalauth;
extern int gbl_vtab_externalauth;
extern int gbl_vtab_externalauth_strict;
extern int gbl_uses_simpleauth;
extern int gbl_uses_externalauth_connect;
extern int gbl_externalauth_warn;
extern int gbl_passwords_with_externalauth;
extern int gbl_identity_cache_max;
extern int gbl_authorization_cache_max;
extern int gbl_authentication_cache_ageout;
Expand Down
139 changes: 43 additions & 96 deletions db/db_access.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,21 @@ void get_client_origin(char *out, size_t outlen, struct sqlclntstate *clnt) {
clnt->argv0 ? clnt->argv0 : "?",
clnt->origin ? clnt->origin: "?",
clnt->conninfo.pid);
}
}

static void report_access_denied(const char *action, const char *table, const char *user, int bdberr, errstat_t *err)
{
char msg[1024];
if (bdberr)
snprintf(msg, sizeof(msg), "%s access denied to %s for user %s bdberr=%d", action, table, user, bdberr);
else
snprintf(msg, sizeof(msg), "%s access denied to table %s for user %s", action, table, user);
logmsg(LOGMSG_INFO, "%s\n", msg);
if (err) {
errstat_set_rc(err, SQLITE_ACCESS);
errstat_set_str(err, msg);
}
}

int gbl_fdb_auth_error = 0;

Expand Down Expand Up @@ -126,7 +140,8 @@ int check_user_password(struct sqlclntstate *clnt)
clnt->allow_make_request = 1;
ATOMIC_ADD64(gbl_num_auth_allowed, 1);
}
return rc;
if (rc || !gbl_passwords_with_externalauth)
return rc;
}

if ((!remsql_warned || gbl_fdb_auth_error) && (!gbl_uses_password && !gbl_uses_externalauth) &&
Expand Down Expand Up @@ -265,11 +280,7 @@ int access_control_check_sql_write(struct BtCursor *pCur,
if ((authdata = get_authdata(clnt)) != NULL)
clnt->authdata = authdata;
char client_info[1024];
snprintf(client_info, sizeof(client_info),
"%s:origin:%s:pid:%d",
clnt->argv0 ? clnt->argv0 : "?",
clnt->origin ? clnt->origin: "?",
clnt->conninfo.pid);
get_client_origin(client_info, sizeof(client_info), clnt);
if (!clnt->authdata && clnt->secure && !gbl_allow_anon_id_for_spmux) {
return reject_anon_id(clnt);
}
Expand All @@ -278,31 +289,20 @@ int access_control_check_sql_write(struct BtCursor *pCur,
clnt->argv0 ? clnt->argv0 : "???", clnt->conninfo.pid, clnt->conninfo.node);
} else if (externalComdb2AuthenticateUserWrite(clnt->authdata, table_name, client_info)) {
ATOMIC_ADD64(gbl_num_auth_denied, 1);
char msg[1024];
snprintf(msg, sizeof(msg), "Write access denied to table %s for user %s",
table_name, clnt->externalAuthUser ? clnt->externalAuthUser : "");
logmsg(LOGMSG_INFO, "%s\n", msg);
errstat_set_rc(&thd->clnt->osql.xerr, SQLITE_ACCESS);
errstat_set_str(&thd->clnt->osql.xerr, msg);
report_access_denied("Write", table_name, clnt->externalAuthUser ? clnt->externalAuthUser : "", 0,
&thd->clnt->osql.xerr);
return SQLITE_ABORT;
}
} else {
/* Check read access if its not user schema. */
}
if ((gbl_passwords_with_externalauth && !clnt->admin) || !gbl_uses_externalauth) {
/* Check write access via password ACLs. */
/* Check it only if engine is open already. */
if (gbl_uses_password && !clnt->current_user.bypass_auth && (thd->clnt->in_sqlite_init == 0)) {
rc = bdb_check_user_tbl_access(
pCur->db->dbenv->bdb_env, thd->clnt->current_user.name,
pCur->db->tablename, ACCESS_WRITE, &bdberr);
rc = bdb_check_user_tbl_access(pCur->db->dbenv->bdb_env, thd->clnt->current_user.name, pCur->db->tablename,
ACCESS_WRITE, &bdberr);
if (rc != 0) {
ATOMIC_ADD64(gbl_num_auth_denied, 1);
char msg[1024];
snprintf(msg, sizeof(msg),
"Write access denied to %s for user %s bdberr=%d",
table_name, thd->clnt->current_user.name, bdberr);
logmsg(LOGMSG_INFO, "%s\n", msg);
errstat_set_rc(&thd->clnt->osql.xerr, SQLITE_ACCESS);
errstat_set_str(&thd->clnt->osql.xerr, msg);

report_access_denied("Write", table_name, thd->clnt->current_user.name, bdberr, &thd->clnt->osql.xerr);
return SQLITE_ABORT;
}
}
Expand Down Expand Up @@ -352,42 +352,26 @@ int access_control_check_sql_read(struct BtCursor *pCur, struct sql_thread *thd,
if ((authdata = get_authdata(clnt)) != NULL)
clnt->authdata = authdata;
char client_info[1024];
snprintf(client_info, sizeof(client_info),
"%s:origin:%s:pid:%d",
clnt->argv0 ? clnt->argv0 : "?",
clnt->origin ? clnt->origin: "?",
clnt->conninfo.pid);
get_client_origin(client_info, sizeof(client_info), clnt);
if (!clnt->authdata && clnt->secure && !gbl_allow_anon_id_for_spmux)
return reject_anon_id(clnt);
if (gbl_externalauth_warn && !clnt->authdata) {
logmsg(LOGMSG_INFO, "Client %s pid:%d mach:%d is missing authentication data\n",
clnt->argv0 ? clnt->argv0 : "???", clnt->conninfo.pid, clnt->conninfo.node);
} else if (externalComdb2AuthenticateUserRead(clnt->authdata, table_name, client_info)) {
ATOMIC_ADD64(gbl_num_auth_denied, 1);
char msg[1024];
snprintf(msg, sizeof(msg), "Read access denied to table %s for user %s",
table_name, clnt->externalAuthUser ? clnt->externalAuthUser : "");
logmsg(LOGMSG_INFO, "%s\n", msg);
errstat_set_rc(&thd->clnt->osql.xerr, SQLITE_ACCESS);
errstat_set_str(&thd->clnt->osql.xerr, msg);
report_access_denied("Read", table_name, clnt->externalAuthUser ? clnt->externalAuthUser : "", 0,
&thd->clnt->osql.xerr);
return SQLITE_ABORT;
}
} else {
if (gbl_uses_password && !clnt->current_user.bypass_auth && pCur && pCur->db &&
thd->clnt->in_sqlite_init == 0) {
rc = bdb_check_user_tbl_access(
pCur->db->dbenv->bdb_env, thd->clnt->current_user.name,
pCur->db->tablename, ACCESS_READ, &bdberr);
}
if ((gbl_passwords_with_externalauth && !clnt->admin) || !gbl_uses_externalauth) {
if (gbl_uses_password && !clnt->current_user.bypass_auth && table_name && thd->clnt->in_sqlite_init == 0) {
rc = bdb_check_user_tbl_access(thedb->bdb_env, thd->clnt->current_user.name, (char *)table_name,
ACCESS_READ, &bdberr);
if (rc != 0) {
ATOMIC_ADD64(gbl_num_auth_denied, 1);
char msg[1024];
snprintf(msg, sizeof(msg),
"Read access denied to %s for user %s bdberr=%d",
table_name, thd->clnt->current_user.name, bdberr);
logmsg(LOGMSG_INFO, "%s\n", msg);
errstat_set_rc(&thd->clnt->osql.xerr, SQLITE_ACCESS);
errstat_set_str(&thd->clnt->osql.xerr, msg);

report_access_denied("Read", table_name, thd->clnt->current_user.name, bdberr, &thd->clnt->osql.xerr);
return SQLITE_ABORT;
}
}
Expand Down Expand Up @@ -455,12 +439,11 @@ int comdb2_check_vtab_access(sqlite3 *db, sqlite3_module *module)
{
HashElem *current;

if (!gbl_uses_password) {
if (!gbl_uses_password && !(gbl_uses_externalauth && gbl_vtab_externalauth)) {
return 0;
}

struct sql_thread *thd = pthread_getspecific(query_info_key);
struct sqlclntstate *clnt = thd->clnt;

for (current = sqliteHashFirst(&db->aModule); current;
current = sqliteHashNext(current)) {
Expand All @@ -469,56 +452,20 @@ int comdb2_check_vtab_access(sqlite3 *db, sqlite3_module *module)
continue;
}

int bdberr;
int rc;

if ((module->access_flag == 0) ||
(module->access_flag & CDB2_ALLOW_ALL)) {
return SQLITE_OK;
}

if (gbl_uses_externalauth && (thd->clnt->in_sqlite_init == 0) &&
externalComdb2AuthenticateUserRead && !clnt->admin /* not admin connection */
&& !clnt->current_user.bypass_auth /* not analyze */) {
clnt->authdata = get_authdata(clnt);
char client_info[1024];
snprintf(client_info, sizeof(client_info),
"%s:origin:%s:pid:%d",
clnt->argv0 ? clnt->argv0 : "?",
clnt->origin ? clnt->origin: "?",
clnt->conninfo.pid);
if (!clnt->authdata && clnt->secure && !gbl_allow_anon_id_for_spmux)
return reject_anon_id(clnt);
if (gbl_externalauth_warn && !clnt->authdata) {
logmsg(LOGMSG_INFO, "Client %s pid:%d mach:%d is missing authentication data\n",
clnt->argv0 ? clnt->argv0 : "???", clnt->conninfo.pid, clnt->conninfo.node);
} else if (externalComdb2AuthenticateUserRead(clnt->authdata, mod->zName, client_info)) {
ATOMIC_ADD64(gbl_num_auth_denied, 1);
char msg[1024];
snprintf(msg, sizeof(msg), "Read access denied to table %s for user %s",
mod->zName, clnt->externalAuthUser ? clnt->externalAuthUser : "");
logmsg(LOGMSG_INFO, "%s\n", msg);
errstat_set_rc(&thd->clnt->osql.xerr, SQLITE_ACCESS);
errstat_set_str(&thd->clnt->osql.xerr, msg);
return SQLITE_ABORT;
}
return SQLITE_OK;
} else {
rc = bdb_check_user_tbl_access(
thedb->bdb_env, thd->clnt->current_user.name,
(char *)mod->zName, ACCESS_READ, &bdberr);
if (rc != 0) {
char msg[1024];
snprintf(msg, sizeof(msg),
"Read access denied to %s for user %s bdberr=%d",
mod->zName, thd->clnt->current_user.name, bdberr);
logmsg(LOGMSG_INFO, "%s\n", msg);
errstat_set_rc(&thd->clnt->osql.xerr, SQLITE_ACCESS);
errstat_set_str(&thd->clnt->osql.xerr, msg);
return SQLITE_AUTH;
}
if (gbl_uses_externalauth && gbl_vtab_externalauth && !gbl_vtab_externalauth_strict &&
!(module->access_flag & CDB2_STRICT)) {
return SQLITE_OK;
}

int rc = access_control_check_sql_read(NULL, thd, (char *)mod->zName);
if (rc != SQLITE_OK)
return SQLITE_AUTH;
return SQLITE_OK;
}
assert(0);
return 0;
Expand Down
8 changes: 8 additions & 0 deletions db/db_tunables.h
Original file line number Diff line number Diff line change
Expand Up @@ -2387,13 +2387,21 @@ REGISTER_TUNABLE("allow_old_authn", "Reuse old successful authentication for the
REGISTER_TUNABLE("externalauth", NULL, TUNABLE_BOOLEAN, &gbl_uses_externalauth, NOARG | READEARLY,
NULL, NULL, NULL, NULL);

REGISTER_TUNABLE("vtab_externalauth", "Use IAM for vtab access control (Default: on)", TUNABLE_BOOLEAN,
&gbl_vtab_externalauth, 0, NULL, NULL, NULL, NULL);

REGISTER_TUNABLE("vtab_externalauth_strict", "Enforce access control on all CDB2_ALLOW_USER vtabs (Default: off)",
TUNABLE_BOOLEAN, &gbl_vtab_externalauth_strict, 0, NULL, NULL, NULL, NULL);

REGISTER_TUNABLE("externalauth_connect", "Check for externalauth only once on connect", TUNABLE_BOOLEAN,
&gbl_uses_externalauth_connect, NOARG | READEARLY, NULL, NULL, NULL, NULL);

REGISTER_TUNABLE("externalauth_warn", "Warn instead of returning error in case of missing authdata",
TUNABLE_BOOLEAN, &gbl_externalauth_warn, NOARG | READEARLY,
NULL, NULL, NULL, NULL);

REGISTER_TUNABLE("passwords_with_externalauth", "Check password auth in addition to externalauth (Default: off)",
TUNABLE_BOOLEAN, &gbl_passwords_with_externalauth, NOARG | READEARLY, NULL, NULL, NULL, NULL);

REGISTER_TUNABLE("view_feature", "Enables support for VIEWs (Default: ON)",
TUNABLE_BOOLEAN, &gbl_view_feature, 0, NULL, NULL, NULL, NULL);
Expand Down
2 changes: 1 addition & 1 deletion lua/sp.c
Original file line number Diff line number Diff line change
Expand Up @@ -7246,7 +7246,7 @@ static int exec_procedure_int(struct sqlthdstate *thd,
// Use () to differentiate between tablename and spname
snprintf(spfunc, sizeof(spfunc), "%s()", spname);

if (access_control_check_sql_read(NULL, sqlthd, spfunc)) {
if (gbl_uses_externalauth && access_control_check_sql_read(NULL, sqlthd, spfunc)) {
(*err) = strdup("Read access denied for the stored procedure");
return SQLITE_ACCESS;
}
Expand Down
9 changes: 3 additions & 6 deletions plugins/simpleauth/simplecheck.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,8 @@ static void simpleAuthInit(void)
int rc = run_internal_sql_clnt(
&clnt, "create table if not exists comdb2_simple_auth(cluster cstring(20) default '*', user cstring(20) "
"default '*', bpkg cstring(50) default '*', verb cstring(20) default '*', resourcetype cstring(20) "
"default '*', resourcename cstring(50) default '*')");
if (rc)
exit(1);
rc = run_internal_sql_clnt(&clnt, "create unique index if not exists comdb2_simple_auth_ix on "
"comdb2_simple_auth(cluster, user, bpkg, verb, resourcetype, resourcename)");
"default '*', resourcename cstring(50) default '*', "
"unique(cluster, user, bpkg, verb, resourcetype, resourcename))");
if (rc)
exit(1);

Expand Down Expand Up @@ -180,7 +177,7 @@ int simpleAuthCheck(const char *principal, const char *verb_in, const char *reso
strcat(sql, "' ");
}
strcat(sql, ") and (bpkg='*' ");
if (user) {
if (bpkg) {
strcat(sql, "or bpkg = '");
strcat(sql, bpkg);
strcat(sql, "' ");
Expand Down
2 changes: 1 addition & 1 deletion sqlite/ext/comdb2/activeosqls.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ static void free_osqls(void *p, int n)
}

sqlite3_module systblActiveOsqlsModule = {
.access_flag = CDB2_ALLOW_USER,
.access_flag = CDB2_ALLOW_USER | CDB2_STRICT,
};

int systblActiveOsqlsInit(sqlite3 *db)
Expand Down
2 changes: 1 addition & 1 deletion sqlite/ext/comdb2/connections.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#include "types.h"

sqlite3_module systblConnectionsModule = {
.access_flag = CDB2_ALLOW_USER,
.access_flag = CDB2_ALLOW_USER | CDB2_STRICT,
};

int get_connections(void **data, int *num_points) {
Expand Down
2 changes: 1 addition & 1 deletion sqlite/ext/comdb2/files.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,4 +270,4 @@ const sqlite3_module systblFilesModule = {
0, /* xRelease */
0, /* xRollbackTo */
0, /* xShadowName */
.access_flag = CDB2_ALLOW_USER};
.access_flag = CDB2_ALLOW_USER | CDB2_STRICT};
2 changes: 1 addition & 1 deletion sqlite/ext/comdb2/logicalops.c
Original file line number Diff line number Diff line change
Expand Up @@ -1285,7 +1285,7 @@ sqlite3_module systblLogicalOpsModule = {
0, /* xRelease */
0, /* xRollbackTo */
0, /* xShadowName */
.access_flag = CDB2_ALLOW_USER,
.access_flag = CDB2_ALLOW_USER | CDB2_STRICT,
};


2 changes: 1 addition & 1 deletion sqlite/ext/comdb2/sample_queries.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ extern hash_t *gbl_sample_queries_hash;
extern pthread_mutex_t gbl_fingerprint_hash_mu;

sqlite3_module systblSampleQueriesModule = {
.access_flag = CDB2_ALLOW_USER,
.access_flag = CDB2_ALLOW_USER | CDB2_STRICT,
};

typedef struct systable_sample_queries {
Expand Down
2 changes: 1 addition & 1 deletion sqlite/ext/comdb2/sqlpoolqueue.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ static void free_sqlpoolqueue(void *p, int n)
}

sqlite3_module systblSqlpoolQueueModule = {
.access_flag = CDB2_ALLOW_USER,
.access_flag = CDB2_ALLOW_USER | CDB2_STRICT,
};

int systblSqlpoolQueueInit(sqlite3 *db) {
Expand Down
2 changes: 1 addition & 1 deletion sqlite/ext/comdb2/stringrefs.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ static void free_stringrefs(void *p, int n)
}

sqlite3_module systblStringRefsModule = {
.access_flag = CDB2_ALLOW_USER,
.access_flag = CDB2_ALLOW_USER | CDB2_STRICT,
};

int systblStringRefsInit(sqlite3 *db) {
Expand Down
2 changes: 1 addition & 1 deletion sqlite/ext/comdb2/tranlog.c
Original file line number Diff line number Diff line change
Expand Up @@ -951,7 +951,7 @@ sqlite3_module systblTransactionLogsModule = {
0, /* xRelease */
0, /* xRollbackTo */
0, /* xShadowName */
.access_flag = CDB2_ALLOW_USER
.access_flag = CDB2_ALLOW_USER | CDB2_STRICT
};


1 change: 1 addition & 0 deletions sqlite/src/sqlite3.h
Original file line number Diff line number Diff line change
Expand Up @@ -6540,6 +6540,7 @@ enum {
CDB2_ALLOW_USER = 1<<1, /* Limit access only to permitted users */
CDB2_HIDDEN = 1<<2, /* Remove it from system table list
(comdb2_systables) */
CDB2_STRICT = 1<<3, /* Always enforce access check */
};
#endif /* defined(SQLITE_BUILDING_FOR_COMDB2) */

Expand Down
2 changes: 1 addition & 1 deletion tests/simpleauth.test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ else
include $(TESTSROOTDIR)/testcase.mk
endif
ifeq ($(TEST_TIMEOUT),)
export TEST_TIMEOUT=5m
export TEST_TIMEOUT=1m
endif
Loading
Loading