diff options
author | Vladislav Vaintroub <wlad@mariadb.com> | 2020-05-01 18:06:50 +0200 |
---|---|---|
committer | Vladislav Vaintroub <wlad@mariadb.com> | 2020-05-18 18:08:28 +0200 |
commit | d9b81210fdd00d07c2b440284d40c72ec3dfa5cb (patch) | |
tree | e01bdbd87b397df86ba944170397e0386039a337 /sql/mysql_install_db.cc | |
parent | a42a0979c5100bd68b19ed85add880312c446177 (diff) | |
download | mariadb-git-d9b81210fdd00d07c2b440284d40c72ec3dfa5cb.tar.gz |
MDEV-22175 windows installer - create SeLockMemoryPrivilege for Service account
Diffstat (limited to 'sql/mysql_install_db.cc')
-rw-r--r-- | sql/mysql_install_db.cc | 107 |
1 files changed, 98 insertions, 9 deletions
diff --git a/sql/mysql_install_db.cc b/sql/mysql_install_db.cc index 41a53c57744..c18ce6acff3 100644 --- a/sql/mysql_install_db.cc +++ b/sql/mysql_install_db.cc @@ -26,6 +26,7 @@ #include <shellapi.h> #include <accctrl.h> #include <aclapi.h> +#include <ntsecapi.h> struct IUnknown; #include <shlwapi.h> @@ -58,6 +59,7 @@ static my_bool opt_allow_remote_root_access; static my_bool opt_skip_networking; static my_bool opt_verbose_bootstrap; static my_bool verbose_errors; +static my_bool opt_large_pages; #define DEFAULT_INNODB_PAGE_SIZE 16*1024 @@ -73,14 +75,14 @@ static struct my_option my_long_options[]= &opt_password, &opt_password, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"port", 'P', "mysql port", &opt_port, &opt_port, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"socket", 'W', + {"socket", 'W', "named pipe name (if missing, it will be set the same as service)", &opt_socket, &opt_socket, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"default-user", 'D', "Create default user", &opt_default_user, &opt_default_user, 0 , GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0}, - {"allow-remote-root-access", 'R', + {"allow-remote-root-access", 'R', "Allows remote access from network for user root", - &opt_allow_remote_root_access, &opt_allow_remote_root_access, 0 , GET_BOOL, + &opt_allow_remote_root_access, &opt_allow_remote_root_access, 0 , GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"skip-networking", 'N', "Do not use TCP connections, use pipe instead", &opt_skip_networking, &opt_skip_networking, 0 , GET_BOOL, OPT_ARG, 0, 0, 0, 0, @@ -91,6 +93,9 @@ static struct my_option my_long_options[]= &opt_silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"verbose-bootstrap", 'o', "Include mysqld bootstrap output",&opt_verbose_bootstrap, &opt_verbose_bootstrap, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"large-pages",'l', "Use large pages", &opt_large_pages, + &opt_large_pages, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -135,7 +140,7 @@ ATTRIBUTE_NORETURN static void die(const char *fmt, ...) } -static void verbose(const char *fmt, ...) +static void verbose( const char *fmt, ...) { va_list args; @@ -318,7 +323,7 @@ static int create_myini() if (!opt_socket) opt_socket= opt_service; } - enable_named_pipe= (my_bool) + enable_named_pipe= (my_bool) ((opt_socket && opt_socket[0]) || opt_skip_networking); if (enable_named_pipe) @@ -338,6 +343,10 @@ static int create_myini() { fprintf(myini, "innodb-page-size=%d\n", opt_innodb_page_size); } + if (opt_large_pages) + { + fprintf(myini, "large-pages=ON\n"); + } /* Write out client settings. */ fprintf(myini, "[client]\n"); @@ -375,6 +384,76 @@ static const char allow_remote_root_access_cmd[]= "DROP TABLE tmp_user;\n"; static const char end_of_script[]="-- end."; +/* +Add or remove privilege for a user +@param[in] account_name - user name, Windows style, e.g "NT SERVICE\mariadb", or ".\joe" +@param[in] privilege name - standard Windows privilege name, e.g "SeLockMemoryPrivilege" +@param[in] add - when true, add privilege, otherwise remove it + +In special case where privilege name is NULL, and add is false +all privileges for the user are removed. +*/ +static int handle_user_privileges(const char *account_name, const wchar_t *privilege_name, bool add) +{ + LSA_OBJECT_ATTRIBUTES attr{}; + LSA_HANDLE lsa_handle; + auto status= LsaOpenPolicy( + 0, &attr, POLICY_LOOKUP_NAMES | POLICY_CREATE_ACCOUNT, &lsa_handle); + if (status) + { + verbose("LsaOpenPolicy returned %lu", LsaNtStatusToWinError(status)); + return 1; + } + BYTE sidbuf[SECURITY_MAX_SID_SIZE]; + PSID sid= (PSID) sidbuf; + SID_NAME_USE name_use; + char domain_name[256]; + DWORD cbSid= sizeof(sidbuf); + DWORD cbDomain= sizeof(domain_name); + BOOL ok= LookupAccountNameA(0, account_name, sid, &cbSid, domain_name, + &cbDomain, &name_use); + if (!ok) + { + verbose("LsaOpenPolicy returned %lu", LsaNtStatusToWinError(status)); + return 1; + } + + if (privilege_name) + { + LSA_UNICODE_STRING priv{}; + priv.Buffer= (PWSTR) privilege_name; + priv.Length= (USHORT) wcslen(privilege_name) * sizeof(wchar_t); + priv.MaximumLength= priv.Length; + if (add) + { + status= LsaAddAccountRights(lsa_handle, sid, &priv, 1); + if (status) + { + verbose("LsaAddAccountRights returned %lu/%lu", status, + LsaNtStatusToWinError(status)); + return 1; + } + } + else + { + status= LsaRemoveAccountRights(lsa_handle, sid, FALSE, &priv, 1); + if (status) + { + verbose("LsaRemoveRights returned %lu/%lu", + LsaNtStatusToWinError(status)); + return 1; + } + } + } + else + { + DBUG_ASSERT(!add); + status= LsaRemoveAccountRights(lsa_handle, sid, TRUE, 0, 0); + } + LsaClose(lsa_handle); + return 0; +} + /* Register service. Assume my.ini is in datadir */ static int register_service(const char *user, const char *passwd) @@ -636,18 +715,23 @@ static int create_db_instance() goto end; service_created = true; } + if (opt_large_pages) + { + handle_user_privileges(service_user.c_str(), L"SeLockMemoryPrivilege", true); + } /* Set data directory permissions for both current user and default_os_user (the one who runs services). */ set_directory_permissions(opt_datadir, NULL); if (!service_user.empty()) + { set_directory_permissions(opt_datadir, service_user.c_str()); - + set_directory_permissions("mysql",service_user.c_str()); + } /* Do mysqld --bootstrap. */ init_bootstrap_command_line(cmdline, sizeof(cmdline)); - if(opt_verbose_bootstrap) printf("Executing %s\n", cmdline); @@ -732,8 +816,6 @@ static int create_db_instance() if (ret) goto end; - - end: if (!ret) return ret; @@ -758,6 +840,13 @@ end: } CloseServiceHandle(sc_manager); } + + /*Remove all service user privileges for the user.*/ + if(strncmp(service_user.c_str(), "NT SERVICE\\", + sizeof("NT SERVICE\\")-1) + { + handle_user_privileges(service_user.c_str(), 0, false); + } } return ret; } |