Commit 462ee7c4 authored by unknown's avatar unknown

A fix (bug #2631: mlockall called after dropping root permissions).

parent b871ea38
...@@ -414,6 +414,7 @@ char mysql_real_data_home[FN_REFLEN], ...@@ -414,6 +414,7 @@ char mysql_real_data_home[FN_REFLEN],
max_sort_char,*mysqld_user,*mysqld_chroot, *opt_init_file; max_sort_char,*mysqld_user,*mysqld_chroot, *opt_init_file;
char *language_ptr= language; char *language_ptr= language;
char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home; char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home;
struct passwd *user_info;
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
bool mysql_embedded=0; bool mysql_embedded=0;
#else #else
...@@ -1028,27 +1029,26 @@ static void set_ports() ...@@ -1028,27 +1029,26 @@ static void set_ports()
} }
} }
/* Change to run as another user if started with --user */
static void set_user(const char *user) static struct passwd *check_user(const char *user)
{ {
#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__) #if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
struct passwd *ent; struct passwd *user_info;
uid_t user_id= geteuid(); uid_t user_id= geteuid();
// don't bother if we aren't superuser // Don't bother if we aren't superuser
if (user_id) if (user_id)
{ {
if (user) if (user)
{ {
/* Don't give a warning, if real user is same as given with --user */ // Don't give a warning, if real user is same as given with --user
struct passwd *user_info= getpwnam(user); user_info= getpwnam(user);
if ((!user_info || user_id != user_info->pw_uid) && if ((!user_info || user_id != user_info->pw_uid) &&
global_system_variables.log_warnings) global_system_variables.log_warnings)
fprintf(stderr, fprintf(stderr,
"Warning: One can only use the --user switch if running as root\n"); "Warning: One can only use the --user switch if running as root\n");
} }
return; return NULL;
} }
if (!user) if (!user)
{ {
...@@ -1057,45 +1057,77 @@ static void set_user(const char *user) ...@@ -1057,45 +1057,77 @@ static void set_user(const char *user)
fprintf(stderr,"Fatal error: Please read \"Security\" section of the manual to find out how to run mysqld as root!\n"); fprintf(stderr,"Fatal error: Please read \"Security\" section of the manual to find out how to run mysqld as root!\n");
unireg_abort(1); unireg_abort(1);
} }
return; return NULL;
} }
if (!strcmp(user,"root")) if (!strcmp(user,"root"))
return; // Avoid problem with dynamic libraries return NULL; // Avoid problem with dynamic libraries
if (!(user_info= getpwnam(user)))
uid_t uid;
if (!(ent = getpwnam(user)))
{ {
// allow a numeric uid to be used // Allow a numeric uid to be used
const char *pos; const char *pos;
for (pos=user; isdigit(*pos); pos++) ; for (pos= user; isdigit(*pos); pos++);
if (*pos) // Not numeric id if (*pos) // Not numeric id
{ goto err;
fprintf(stderr,"Fatal error: Can't change to run as user '%s' ; Please check that the user exists!\n",user); if (!(user_info= getpwuid(atoi(user))))
unireg_abort(1); goto err;
} else
uid=atoi(user); // Use numberic uid return user_info;
} }
else else
{ {
return user_info;
}
err:
fprintf(stderr,
"Fatal error: Can't change to run as user '%s'. Please check that the user exists!\n",
user);
unireg_abort(1);
return NULL;
#else
return NULL;
#endif
}
static void set_user(const char *user, struct passwd *user_info)
{
#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
DBUG_ASSERT(user_info);
#ifdef HAVE_INITGROUPS #ifdef HAVE_INITGROUPS
initgroups((char*) user,ent->pw_gid); initgroups((char*) user, user_info->pw_gid);
#endif #endif
if (setgid(ent->pw_gid) == -1) if (setgid(user_info->pw_gid) == -1)
{ {
sql_perror("setgid"); sql_perror("setgid");
unireg_abort(1); unireg_abort(1);
} }
uid=ent->pw_uid; if (setuid(user_info->pw_uid) == -1)
{
sql_perror("setuid");
unireg_abort(1);
} }
#endif
}
if (setuid(uid) == -1) static void set_effective_user(struct passwd *user_info)
{
#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
DBUG_ASSERT(user_info);
if (setegid(user_info->pw_gid) == -1)
{ {
sql_perror("setuid"); sql_perror("setegid");
unireg_abort(1);
}
if (seteuid(user_info->pw_uid) == -1)
{
sql_perror("seteuid");
unireg_abort(1); unireg_abort(1);
} }
#endif #endif
} }
/* Change root user if started with --chroot */ /* Change root user if started with --chroot */
static void set_root(const char *path) static void set_root(const char *path)
...@@ -1171,7 +1203,18 @@ static void server_init(void) ...@@ -1171,7 +1203,18 @@ static void server_init(void)
unireg_abort(1); unireg_abort(1);
} }
} }
set_user(mysqld_user); // Works also with mysqld_user==NULL
if ((user_info= check_user(mysqld_user)))
{
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
if (locked_in_memory && !getuid())
set_effective_user(user_info);
else
set_user(mysqld_user, user_info);
#else
set_user(mysqld_user, user_info);
#endif
}
#ifdef __NT__ #ifdef __NT__
/* create named pipe */ /* create named pipe */
...@@ -2466,8 +2509,13 @@ You should consider changing lower_case_table_names to 1 or 2", ...@@ -2466,8 +2509,13 @@ You should consider changing lower_case_table_names to 1 or 2",
} }
ha_key_cache(); ha_key_cache();
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) #if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
if (locked_in_memory && !geteuid()) if (locked_in_memory && !getuid())
{ {
if (seteuid(0) == -1)
{ // this should never happen
sql_perror("seteuid");
unireg_abort(1);
}
if (mlockall(MCL_CURRENT)) if (mlockall(MCL_CURRENT))
{ {
if (global_system_variables.log_warnings) if (global_system_variables.log_warnings)
...@@ -2475,6 +2523,8 @@ You should consider changing lower_case_table_names to 1 or 2", ...@@ -2475,6 +2523,8 @@ You should consider changing lower_case_table_names to 1 or 2",
} }
else else
locked_in_memory=1; locked_in_memory=1;
if (user_info)
set_user(mysqld_user, user_info);
} }
#else #else
locked_in_memory=0; locked_in_memory=0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment