move check_user/set_user from mysqld.cc to mysys
This commit is contained in:
parent
706fb790bc
commit
c8e49f2f57
@ -602,8 +602,12 @@ extern void *my_memmem(const void *haystack, size_t haystacklen,
|
|||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
extern int my_access(const char *path, int amode);
|
extern int my_access(const char *path, int amode);
|
||||||
|
#define my_check_user(A,B) (NULL)
|
||||||
|
#define my_set_user(A,B,C) (0)
|
||||||
#else
|
#else
|
||||||
#define my_access access
|
#define my_access access
|
||||||
|
struct passwd *my_check_user(const char *user, myf MyFlags);
|
||||||
|
int my_set_user(const char *user, struct passwd *user_info, myf MyFlags);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern int check_if_legal_filename(const char *path);
|
extern int check_if_legal_filename(const char *path);
|
||||||
|
@ -34,7 +34,7 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c default.c
|
|||||||
rijndael.c sha1.c string.c thr_alarm.c thr_lock.c thr_mutex.c
|
rijndael.c sha1.c string.c thr_alarm.c thr_lock.c thr_mutex.c
|
||||||
thr_rwlock.c tree.c typelib.c base64.c my_memmem.c my_getpagesize.c
|
thr_rwlock.c tree.c typelib.c base64.c my_memmem.c my_getpagesize.c
|
||||||
lf_alloc-pin.c lf_dynarray.c lf_hash.c
|
lf_alloc-pin.c lf_dynarray.c lf_hash.c
|
||||||
safemalloc.c my_new.cc
|
safemalloc.c my_new.cc
|
||||||
my_atomic.c my_getncpus.c my_safehash.c my_chmod.c my_rnd.c
|
my_atomic.c my_getncpus.c my_safehash.c my_chmod.c my_rnd.c
|
||||||
my_uuid.c wqueue.c waiting_threads.c ma_dyncol.c
|
my_uuid.c wqueue.c waiting_threads.c ma_dyncol.c
|
||||||
my_rdtsc.c my_context.c file_logger.c)
|
my_rdtsc.c my_context.c file_logger.c)
|
||||||
@ -44,7 +44,7 @@ IF (WIN32)
|
|||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF(UNIX)
|
IF(UNIX)
|
||||||
SET (MYSYS_SOURCES ${MYSYS_SOURCES} my_addr_resolve.c)
|
SET (MYSYS_SOURCES ${MYSYS_SOURCES} my_addr_resolve.c my_setuser.c)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF(HAVE_ALARM)
|
IF(HAVE_ALARM)
|
||||||
|
81
mysys/my_setuser.c
Normal file
81
mysys/my_setuser.c
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
#include <my_global.h>
|
||||||
|
#include <m_string.h>
|
||||||
|
#include <my_sys.h>
|
||||||
|
#include <my_pthread.h>
|
||||||
|
#ifdef HAVE_PWD_H
|
||||||
|
#include <pwd.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_GRP_H
|
||||||
|
#include <grp.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct passwd *my_check_user(const char *user, myf MyFlags)
|
||||||
|
{
|
||||||
|
struct passwd *user_info;
|
||||||
|
uid_t user_id= geteuid();
|
||||||
|
DBUG_ENTER("my_check_user");
|
||||||
|
|
||||||
|
// Don't bother if we aren't superuser
|
||||||
|
if (user_id)
|
||||||
|
{
|
||||||
|
if (user)
|
||||||
|
{
|
||||||
|
/* Don't give a warning, if real user is same as given with --user */
|
||||||
|
user_info= getpwnam(user);
|
||||||
|
if (!user_info || user_id != user_info->pw_uid)
|
||||||
|
{
|
||||||
|
my_errno= EPERM;
|
||||||
|
if (MyFlags & MY_WME)
|
||||||
|
my_printf_error(my_errno, "One can only use the --user switch if "
|
||||||
|
"running as root", MYF(ME_JUST_WARNING|ME_NOREFRESH));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DBUG_RETURN(NULL);
|
||||||
|
}
|
||||||
|
if (!user)
|
||||||
|
{
|
||||||
|
if (MyFlags & MY_FAE)
|
||||||
|
{
|
||||||
|
my_errno= EINVAL;
|
||||||
|
my_printf_error(my_errno, "Please consult the Knowledge Base to find "
|
||||||
|
"out how to run mysqld as root!", MYF(ME_NOREFRESH));
|
||||||
|
}
|
||||||
|
DBUG_RETURN(NULL);
|
||||||
|
}
|
||||||
|
if (!strcmp(user,"root"))
|
||||||
|
DBUG_RETURN(NULL);
|
||||||
|
|
||||||
|
if (!(user_info= getpwnam(user)))
|
||||||
|
{
|
||||||
|
// Allow a numeric uid to be used
|
||||||
|
int err= 0;
|
||||||
|
user_id= my_strtoll10(user, NULL, &err);
|
||||||
|
if (err || !(user_info= getpwuid(user_id)))
|
||||||
|
{
|
||||||
|
my_errno= EINVAL;
|
||||||
|
my_printf_error(my_errno, "Can't change to run as user '%s'. Please "
|
||||||
|
"check that the user exists!", MYF(ME_NOREFRESH), user);
|
||||||
|
DBUG_RETURN(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DBUG_ASSERT(user_info);
|
||||||
|
DBUG_RETURN(user_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
int my_set_user(const char *user, struct passwd *user_info, myf MyFlags)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("my_set_user");
|
||||||
|
|
||||||
|
DBUG_ASSERT(user_info != 0);
|
||||||
|
#ifdef HAVE_INITGROUPS
|
||||||
|
initgroups(user, user_info->pw_gid);
|
||||||
|
#endif
|
||||||
|
if (setgid(user_info->pw_gid) == -1 || setuid(user_info->pw_uid) == -1)
|
||||||
|
{
|
||||||
|
my_errno= errno;
|
||||||
|
if (MyFlags & MY_WME)
|
||||||
|
my_error(my_errno, MYF(ME_NOREFRESH));
|
||||||
|
DBUG_RETURN(my_errno);
|
||||||
|
}
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
@ -121,10 +121,7 @@ extern "C" { // Because of SCO 3.2V4.2
|
|||||||
#include <sysent.h>
|
#include <sysent.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_PWD_H
|
#ifdef HAVE_PWD_H
|
||||||
#include <pwd.h> // For getpwent
|
#include <pwd.h> // For struct passwd
|
||||||
#endif
|
|
||||||
#ifdef HAVE_GRP_H
|
|
||||||
#include <grp.h>
|
|
||||||
#endif
|
#endif
|
||||||
#include <my_net.h>
|
#include <my_net.h>
|
||||||
|
|
||||||
@ -455,9 +452,7 @@ ulong opt_binlog_rows_event_max_size;
|
|||||||
my_bool opt_master_verify_checksum= 0;
|
my_bool opt_master_verify_checksum= 0;
|
||||||
my_bool opt_slave_sql_verify_checksum= 1;
|
my_bool opt_slave_sql_verify_checksum= 1;
|
||||||
const char *binlog_format_names[]= {"MIXED", "STATEMENT", "ROW", NullS};
|
const char *binlog_format_names[]= {"MIXED", "STATEMENT", "ROW", NullS};
|
||||||
#ifdef HAVE_INITGROUPS
|
|
||||||
volatile sig_atomic_t calling_initgroups= 0; /**< Used in SIGSEGV handler. */
|
volatile sig_atomic_t calling_initgroups= 0; /**< Used in SIGSEGV handler. */
|
||||||
#endif
|
|
||||||
uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options;
|
uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options;
|
||||||
uint mysqld_extra_port;
|
uint mysqld_extra_port;
|
||||||
uint mysqld_port_timeout;
|
uint mysqld_port_timeout;
|
||||||
@ -2001,59 +1996,18 @@ static void set_ports()
|
|||||||
|
|
||||||
static struct passwd *check_user(const char *user)
|
static struct passwd *check_user(const char *user)
|
||||||
{
|
{
|
||||||
#if !defined(__WIN__)
|
myf flags= 0;
|
||||||
struct passwd *tmp_user_info;
|
if (global_system_variables.log_warnings)
|
||||||
uid_t user_id= geteuid();
|
flags|= MY_WME;
|
||||||
|
if (!opt_bootstrap && !opt_help)
|
||||||
|
flags|= MY_FAE;
|
||||||
|
|
||||||
// Don't bother if we aren't superuser
|
struct passwd *tmp_user_info= my_check_user(user, MYF(flags));
|
||||||
if (user_id)
|
|
||||||
{
|
|
||||||
if (user)
|
|
||||||
{
|
|
||||||
/* Don't give a warning, if real user is same as given with --user */
|
|
||||||
/* purecov: begin tested */
|
|
||||||
tmp_user_info= getpwnam(user);
|
|
||||||
if ((!tmp_user_info || user_id != tmp_user_info->pw_uid) &&
|
|
||||||
global_system_variables.log_warnings)
|
|
||||||
sql_print_warning(
|
|
||||||
"One can only use the --user switch if running as root\n");
|
|
||||||
/* purecov: end */
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (!user)
|
|
||||||
{
|
|
||||||
if (!opt_bootstrap && !opt_help)
|
|
||||||
{
|
|
||||||
sql_print_error("Fatal error: Please consult the Knowledge Base "
|
|
||||||
"to find out how to run mysqld as root!\n");
|
|
||||||
unireg_abort(1);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
/* purecov: begin tested */
|
|
||||||
if (!strcmp(user,"root"))
|
|
||||||
return NULL; // Avoid problem with dynamic libraries
|
|
||||||
|
|
||||||
if (!(tmp_user_info= getpwnam(user)))
|
if (!tmp_user_info && my_errno==EINVAL && (flags & MY_FAE))
|
||||||
{
|
unireg_abort(1);
|
||||||
// Allow a numeric uid to be used
|
|
||||||
const char *pos;
|
|
||||||
for (pos= user; my_isdigit(mysqld_charset,*pos); pos++) ;
|
|
||||||
if (*pos) // Not numeric id
|
|
||||||
goto err;
|
|
||||||
if (!(tmp_user_info= getpwuid(atoi(user))))
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return tmp_user_info;
|
return tmp_user_info;
|
||||||
/* purecov: end */
|
|
||||||
|
|
||||||
err:
|
|
||||||
sql_print_error("Fatal error: Can't change to run as user '%s' ; Please check that the user exists!\n",user);
|
|
||||||
unireg_abort(1);
|
|
||||||
#endif
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void allow_coredumps()
|
static inline void allow_coredumps()
|
||||||
@ -2070,10 +2024,6 @@ static inline void allow_coredumps()
|
|||||||
|
|
||||||
static void set_user(const char *user, struct passwd *user_info_arg)
|
static void set_user(const char *user, struct passwd *user_info_arg)
|
||||||
{
|
{
|
||||||
/* purecov: begin tested */
|
|
||||||
#if !defined(__WIN__)
|
|
||||||
DBUG_ASSERT(user_info_arg != 0);
|
|
||||||
#ifdef HAVE_INITGROUPS
|
|
||||||
/*
|
/*
|
||||||
We can get a SIGSEGV when calling initgroups() on some systems when NSS
|
We can get a SIGSEGV when calling initgroups() on some systems when NSS
|
||||||
is configured to use LDAP and the server is statically linked. We set
|
is configured to use LDAP and the server is statically linked. We set
|
||||||
@ -2081,22 +2031,11 @@ static void set_user(const char *user, struct passwd *user_info_arg)
|
|||||||
output a specific message to help the user resolve this problem.
|
output a specific message to help the user resolve this problem.
|
||||||
*/
|
*/
|
||||||
calling_initgroups= 1;
|
calling_initgroups= 1;
|
||||||
initgroups((char*) user, user_info_arg->pw_gid);
|
int res= my_set_user(user, user_info_arg, MYF(MY_WME));
|
||||||
calling_initgroups= 0;
|
calling_initgroups= 0;
|
||||||
#endif
|
if (res)
|
||||||
if (setgid(user_info_arg->pw_gid) == -1)
|
|
||||||
{
|
|
||||||
sql_perror("setgid");
|
|
||||||
unireg_abort(1);
|
unireg_abort(1);
|
||||||
}
|
|
||||||
if (setuid(user_info_arg->pw_uid) == -1)
|
|
||||||
{
|
|
||||||
sql_perror("setuid");
|
|
||||||
unireg_abort(1);
|
|
||||||
}
|
|
||||||
allow_coredumps();
|
allow_coredumps();
|
||||||
#endif
|
|
||||||
/* purecov: end */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user