Skip to content

Commit

Permalink
MDEV-26339 Account specifics to be handled before proxying
Browse files Browse the repository at this point in the history
  • Loading branch information
vuvova committed Jan 17, 2022
1 parent 5e04c08 commit da76d25
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 55 deletions.
29 changes: 29 additions & 0 deletions mysql-test/suite/plugins/r/pam.result
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,35 @@ test_pam@localhost pam_test@% test
#
Now, the magic number!
PIN: 9212
#
# MDEV-26339 Account specifics to be handled before proxying
#
alter user pam_test account lock;
alter user pam_test require subject 'foobar';
alter user pam_test password expire;
Now, the magic number!
PIN: 9212
select user(), current_user(), database();
user() current_user() database()
test_pam@localhost pam_test@% test
alter user pam_test account unlock;
alter user pam_test require none;
alter user pam_test identified by '';
show create user pam_test;
CREATE USER for pam_test@%
CREATE USER `pam_test`@`%`
alter user test_pam account lock;
Now, the magic number!
PIN: 9212
alter user test_pam account unlock;
alter user test_pam require subject 'foobar';
Now, the magic number!
PIN: 9212
alter user test_pam require none;
alter user test_pam password expire;
Now, the magic number!
PIN: 9212
select user(), current_user(), database();
drop user test_pam;
drop user pam_test;
create user PAM_TEST identified via pam using 'mariadb_mtr';
Expand Down
30 changes: 30 additions & 0 deletions mysql-test/suite/plugins/t/pam.test
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,36 @@ EOF
--error 1
--exec $MYSQL_TEST -u test_pam -pbadpassword --plugin-dir=$plugindir < $MYSQLTEST_VARDIR/tmp/pam_good2.txt

--echo #
--echo # MDEV-26339 Account specifics to be handled before proxying
--echo #

# one can connect if the proxy account is locked
alter user pam_test account lock;
alter user pam_test require subject 'foobar';
alter user pam_test password expire;
--error 0
--exec $MYSQL_TEST -u test_pam -pgoodpassword --plugin-dir=$plugindir < $MYSQLTEST_VARDIR/tmp/pam_good2.txt
alter user pam_test account unlock;
alter user pam_test require none;
alter user pam_test identified by '';
show create user pam_test;

#one cannot connect if the proxied account is locked
alter user test_pam account lock;
--error 1
--exec $MYSQL_TEST -u test_pam -pgoodpassword --plugin-dir=$plugindir < $MYSQLTEST_VARDIR/tmp/pam_good2.txt
alter user test_pam account unlock;

alter user test_pam require subject 'foobar';
--error 1
--exec $MYSQL_TEST -u test_pam -pgoodpassword --plugin-dir=$plugindir < $MYSQLTEST_VARDIR/tmp/pam_good2.txt
alter user test_pam require none;

alter user test_pam password expire;
--error 1
--exec $MYSQL_TEST -u test_pam -pgoodpassword --plugin-dir=$plugindir < $MYSQLTEST_VARDIR/tmp/pam_good2.txt

drop user test_pam;
drop user pam_test;
create user PAM_TEST identified via pam using 'mariadb_mtr';
Expand Down
114 changes: 59 additions & 55 deletions sql/sql_acl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13932,61 +13932,6 @@ bool acl_authenticate(THD *thd, uint com_change_user_pkt_len)

if (initialized) // if not --skip-grant-tables
{
#ifndef NO_EMBEDDED_ACCESS_CHECKS
bool is_proxy_user= FALSE;
const char *auth_user = acl_user->user.str;
ACL_PROXY_USER *proxy_user;
/* check if the user is allowed to proxy as another user */
proxy_user= acl_find_proxy_user(auth_user, sctx->host, sctx->ip,
mpvio.auth_info.authenticated_as,
&is_proxy_user);
if (is_proxy_user)
{
ACL_USER *acl_proxy_user;

/* we need to find the proxy user, but there was none */
if (!proxy_user)
{
Host_errors errors;
errors.m_proxy_user= 1;
inc_host_errors(mpvio.auth_info.thd->security_ctx->ip, &errors);
if (!thd->is_error())
login_failed_error(thd);
DBUG_RETURN(1);
}

my_snprintf(sctx->proxy_user, sizeof(sctx->proxy_user) - 1,
"'%s'@'%s'", auth_user,
safe_str(acl_user->host.hostname));

/* we're proxying : find the proxy user definition */
mysql_mutex_lock(&acl_cache->lock);
acl_proxy_user= find_user_exact(safe_str(proxy_user->get_proxied_host()),
mpvio.auth_info.authenticated_as);
if (!acl_proxy_user)
{
mysql_mutex_unlock(&acl_cache->lock);

Host_errors errors;
errors.m_proxy_user_acl= 1;
inc_host_errors(mpvio.auth_info.thd->security_ctx->ip, &errors);
if (!thd->is_error())
login_failed_error(thd);
DBUG_RETURN(1);
}
acl_user= acl_proxy_user->copy(thd->mem_root);
mysql_mutex_unlock(&acl_cache->lock);
}
#endif

sctx->master_access= acl_user->access;
strmake_buf(sctx->priv_user, acl_user->user.str);

if (acl_user->host.hostname)
strmake_buf(sctx->priv_host, acl_user->host.hostname);
else
*sctx->priv_host= 0;

/*
OK. Let's check the SSL. Historically it was checked after the password,
as an additional layer, not instead of the password
Expand Down Expand Up @@ -14023,6 +13968,65 @@ bool acl_authenticate(THD *thd, uint com_change_user_pkt_len)

sctx->password_expired= password_expired;

#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (!password_expired)
{
bool is_proxy_user= FALSE;
const char *auth_user = acl_user->user.str;
ACL_PROXY_USER *proxy_user;
/* check if the user is allowed to proxy as another user */
proxy_user= acl_find_proxy_user(auth_user, sctx->host, sctx->ip,
mpvio.auth_info.authenticated_as,
&is_proxy_user);
if (is_proxy_user)
{
ACL_USER *acl_proxy_user;

/* we need to find the proxy user, but there was none */
if (!proxy_user)
{
Host_errors errors;
errors.m_proxy_user= 1;
inc_host_errors(mpvio.auth_info.thd->security_ctx->ip, &errors);
if (!thd->is_error())
login_failed_error(thd);
DBUG_RETURN(1);
}

my_snprintf(sctx->proxy_user, sizeof(sctx->proxy_user) - 1,
"'%s'@'%s'", auth_user,
safe_str(acl_user->host.hostname));

/* we're proxying : find the proxy user definition */
mysql_mutex_lock(&acl_cache->lock);
acl_proxy_user= find_user_exact(safe_str(proxy_user->get_proxied_host()),
mpvio.auth_info.authenticated_as);
if (!acl_proxy_user)
{
mysql_mutex_unlock(&acl_cache->lock);

Host_errors errors;
errors.m_proxy_user_acl= 1;
inc_host_errors(mpvio.auth_info.thd->security_ctx->ip, &errors);
if (!thd->is_error())
login_failed_error(thd);
DBUG_RETURN(1);
}
acl_user= acl_proxy_user->copy(thd->mem_root);
mysql_mutex_unlock(&acl_cache->lock);
}
}
#endif

sctx->master_access= acl_user->access;
strmake_buf(sctx->priv_user, acl_user->user.str);

if (acl_user->host.hostname)
strmake_buf(sctx->priv_host, acl_user->host.hostname);
else
*sctx->priv_host= 0;


/*
Don't allow the user to connect if he has done too many queries.
As we are testing max_user_connections == 0 here, it means that we
Expand Down

0 comments on commit da76d25

Please sign in to comment.