From 253d6d211feac73ae22b820047c034b65530d2ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Tue, 15 Aug 2017 14:15:59 +0300 Subject: [PATCH] MXS-1354: Allow creation of basic users The type of the user being created is defined at creation time. This allows the creation of basic users. Although the users can be created internally, they cannot yet be created via maxadmin or the REST API. --- include/maxscale/users.h | 10 +++++- server/core/adminusers.cc | 12 ++++--- server/core/test/testusers.cc | 4 +-- server/core/users.cc | 35 +++++++++---------- .../CDCPlainAuth/cdc_plain_auth.c | 4 +-- 5 files changed, 37 insertions(+), 28 deletions(-) diff --git a/include/maxscale/users.h b/include/maxscale/users.h index 8bdf7a7ef..f213f8373 100644 --- a/include/maxscale/users.h +++ b/include/maxscale/users.h @@ -25,6 +25,13 @@ MXS_BEGIN_DECLS +/** User account types */ +enum account_type +{ + ACCOUNT_BASIC, /**< Allows read-only access */ + ACCOUNT_ADMIN /**< Allows complete access */ +}; + /** * An opaque users object */ @@ -52,10 +59,11 @@ void users_free(USERS* users); * @param users The users table * @param user The user name * @param password The password for the user + * @param type The type of account to create * * @return True if user was added */ -bool users_add(USERS *users, const char *user, const char *password); +bool users_add(USERS *users, const char *user, const char *password, enum account_type type); /** * Delete a user from the user table. diff --git a/server/core/adminusers.cc b/server/core/adminusers.cc index 4bc2e653a..c74d13d40 100644 --- a/server/core/adminusers.cc +++ b/server/core/adminusers.cc @@ -62,7 +62,7 @@ static const char *admin_add_user(USERS** pusers, const char* fname, const char* uname, const char* password) { FILE *fp; - char path[PATH_MAX], *home; + char path[PATH_MAX]; if (access(get_datadir(), F_OK) != 0) { @@ -83,20 +83,22 @@ static const char *admin_add_user(USERS** pusers, const char* fname, } if ((fp = fopen(path, "w")) == NULL) { - MXS_ERROR("Unable to create password file %s.", path); + MXS_ERROR("Unable to create password file %s: %d, %s", path, + errno, mxs_strerror(errno)); return ADMIN_ERR_PWDFILEOPEN; } fclose(fp); } - if (!users_add(*pusers, uname, password ? password : "")) + if (!users_add(*pusers, uname, password ? password : "", ACCOUNT_ADMIN)) { return ADMIN_ERR_DUPLICATE; } if ((fp = fopen(path, "a")) == NULL) { - MXS_ERROR("Unable to append to password file %s.", path); + MXS_ERROR("Unable to append to password file %s: %d, %s", path, + errno, mxs_strerror(errno)); return ADMIN_ERR_FILEAPPEND; } if (password) @@ -401,7 +403,7 @@ loadUsers(const char *fname) password = ""; } - if (users_add(rval, uname, password)) + if (users_add(rval, uname, password, ACCOUNT_ADMIN)) { added_users++; } diff --git a/server/core/test/testusers.cc b/server/core/test/testusers.cc index f99e89c39..3453e0e71 100644 --- a/server/core/test/testusers.cc +++ b/server/core/test/testusers.cc @@ -48,7 +48,7 @@ static int test1() mxs_log_flush_sync(); ss_info_dassert(NULL != users, "Allocating user table should not return NULL."); ss_dfprintf(stderr, "\t..done\nAdd a user"); - rv = users_add(users, "username", "authorisation"); + rv = users_add(users, "username", "authorisation", ACCOUNT_ADMIN); mxs_log_flush_sync(); ss_info_dassert(rv, "Should add one user"); rv = users_auth(users, "username", "authorisation"); @@ -59,7 +59,7 @@ static int test1() ss_info_dassert(rv, "Fetch valid user must not return NULL"); ss_dfprintf(stderr, "\t..done\nAdd another user"); - rv = users_add(users, "username2", "authorisation2"); + rv = users_add(users, "username2", "authorisation2", ACCOUNT_ADMIN); mxs_log_flush_sync(); ss_info_dassert(rv, "Should add one user"); ss_dfprintf(stderr, "\t..done\nDelete a user."); diff --git a/server/core/users.cc b/server/core/users.cc index e6656d958..d6af61db3 100644 --- a/server/core/users.cc +++ b/server/core/users.cc @@ -24,22 +24,21 @@ namespace { -enum permission_type -{ - PERM_BASIC, - PERM_ADMIN -}; - struct UserInfo { - UserInfo(std::string pw = "", permission_type perm = PERM_ADMIN): // TODO: Change default to PERM_BASIC + UserInfo(): + permissions(ACCOUNT_BASIC) + { + } + + UserInfo(std::string pw, account_type perm): password(pw), permissions(perm) { } - std::string password; - permission_type permissions; + std::string password; + account_type permissions; }; @@ -59,10 +58,10 @@ public: { } - bool add(std::string user, std::string password) + bool add(std::string user, std::string password, account_type perm) { mxs::SpinLockGuard guard(m_lock); - return m_data.insert(std::make_pair(user, UserInfo(password))).second; + return m_data.insert(std::make_pair(user, UserInfo(password, perm))).second; } bool remove(std::string user) @@ -98,7 +97,7 @@ public: return rval; } - bool check_permissions(std::string user, permission_type perm) const + bool check_permissions(std::string user, account_type perm) const { mxs::SpinLockGuard guard(m_lock); UserMap::const_iterator it = m_data.find(user); @@ -112,7 +111,7 @@ public: return rval; } - bool set_permissions(std::string user, permission_type perm) + bool set_permissions(std::string user, account_type perm) { mxs::SpinLockGuard guard(m_lock); UserMap::iterator it = m_data.find(user); @@ -182,10 +181,10 @@ void users_free(USERS *users) delete u; } -bool users_add(USERS *users, const char *user, const char *password) +bool users_add(USERS *users, const char *user, const char *password, enum account_type type) { Users* u = reinterpret_cast(users); - return u->add(user, password); + return u->add(user, password, type); } bool users_delete(USERS *users, const char *user) @@ -217,19 +216,19 @@ bool users_auth(USERS* users, const char* user, const char* password) bool users_is_admin(USERS* users, const char* user) { Users* u = reinterpret_cast(users); - return u->check_permissions(user, PERM_ADMIN); + return u->check_permissions(user, ACCOUNT_ADMIN); } bool users_promote(USERS* users, const char* user) { Users* u = reinterpret_cast(users); - return u->set_permissions(user, PERM_ADMIN); + return u->set_permissions(user, ACCOUNT_ADMIN); } bool users_demote(USERS* users, const char* user) { Users* u = reinterpret_cast(users); - return u->set_permissions(user, PERM_BASIC); + return u->set_permissions(user, ACCOUNT_BASIC); } void users_diagnostic(DCB* dcb, USERS* users) diff --git a/server/modules/authenticator/CDCPlainAuth/cdc_plain_auth.c b/server/modules/authenticator/CDCPlainAuth/cdc_plain_auth.c index c1ad0bdde..286ef10ca 100644 --- a/server/modules/authenticator/CDCPlainAuth/cdc_plain_auth.c +++ b/server/modules/authenticator/CDCPlainAuth/cdc_plain_auth.c @@ -460,7 +460,7 @@ cdc_set_service_user(SERV_LISTENER *listener) } /* add service user */ - (void)users_add(listener->users, service->credentials.name, newpasswd); + (void)users_add(listener->users, service->credentials.name, newpasswd, ACCOUNT_ADMIN); MXS_FREE(newpasswd); MXS_FREE(dpwd); @@ -510,7 +510,7 @@ cdc_read_users(USERS *users, char *usersfile) } /* add user */ - users_add(users, avro_user, user_passwd); + users_add(users, avro_user, user_passwd, ACCOUNT_ADMIN); loaded++; }