summaryrefslogtreecommitdiff
path: root/sql/mysqld.cc
diff options
context:
space:
mode:
authorunknown <ram@gw.mysql.r18.ru>2004-09-03 19:26:11 +0500
committerunknown <ram@gw.mysql.r18.ru>2004-09-03 19:26:11 +0500
commit462ee7c4175436938785c06c77394247b83d0d87 (patch)
tree29011b87c2b9ccb50302baa5657c18a78e3095fb /sql/mysqld.cc
parentb871ea386c706a63bb53876d143d06e4109b4169 (diff)
downloadmariadb-git-462ee7c4175436938785c06c77394247b83d0d87.tar.gz
A fix (bug #2631: mlockall called after dropping root permissions).
Diffstat (limited to 'sql/mysqld.cc')
-rw-r--r--sql/mysqld.cc122
1 files changed, 86 insertions, 36 deletions
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 670e6a5a63e..06599cf0ea7 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -414,6 +414,7 @@ char mysql_real_data_home[FN_REFLEN],
max_sort_char,*mysqld_user,*mysqld_chroot, *opt_init_file;
char *language_ptr= language;
char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home;
+struct passwd *user_info;
#ifndef EMBEDDED_LIBRARY
bool mysql_embedded=0;
#else
@@ -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__)
- struct passwd *ent;
+#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
+ struct passwd *user_info;
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)
{
- /* Don't give a warning, if real user is same as given with --user */
- struct passwd *user_info= getpwnam(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) &&
- global_system_variables.log_warnings)
- fprintf(stderr,
- "Warning: One can only use the --user switch if running as root\n");
+ global_system_variables.log_warnings)
+ fprintf(stderr,
+ "Warning: One can only use the --user switch if running as root\n");
}
- return;
+ return NULL;
}
if (!user)
{
@@ -1057,38 +1057,52 @@ 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");
unireg_abort(1);
}
- return;
+ return NULL;
}
if (!strcmp(user,"root"))
- return; // Avoid problem with dynamic libraries
-
- uid_t uid;
- if (!(ent = getpwnam(user)))
+ return NULL; // Avoid problem with dynamic libraries
+ if (!(user_info= getpwnam(user)))
{
- // allow a numeric uid to be used
+ // Allow a numeric uid to be used
const char *pos;
- for (pos=user; isdigit(*pos); pos++) ;
- if (*pos) // Not numeric id
- {
- fprintf(stderr,"Fatal error: Can't change to run as user '%s' ; Please check that the user exists!\n",user);
- unireg_abort(1);
- }
- uid=atoi(user); // Use numberic uid
+ for (pos= user; isdigit(*pos); pos++);
+ if (*pos) // Not numeric id
+ goto err;
+ if (!(user_info= getpwuid(atoi(user))))
+ goto err;
+ else
+ return user_info;
}
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
- initgroups((char*) user,ent->pw_gid);
+ initgroups((char*) user, user_info->pw_gid);
#endif
- if (setgid(ent->pw_gid) == -1)
- {
- sql_perror("setgid");
- unireg_abort(1);
- }
- uid=ent->pw_uid;
+ if (setgid(user_info->pw_gid) == -1)
+ {
+ sql_perror("setgid");
+ unireg_abort(1);
}
-
- if (setuid(uid) == -1)
+ if (setuid(user_info->pw_uid) == -1)
{
sql_perror("setuid");
unireg_abort(1);
@@ -1096,6 +1110,24 @@ static void set_user(const char *user)
#endif
}
+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("setegid");
+ unireg_abort(1);
+ }
+ if (seteuid(user_info->pw_uid) == -1)
+ {
+ sql_perror("seteuid");
+ unireg_abort(1);
+ }
+#endif
+}
+
+
/* Change root user if started with --chroot */
static void set_root(const char *path)
@@ -1171,7 +1203,18 @@ static void server_init(void)
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__
/* create named pipe */
@@ -2466,8 +2509,13 @@ You should consider changing lower_case_table_names to 1 or 2",
}
ha_key_cache();
#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 (global_system_variables.log_warnings)
@@ -2475,6 +2523,8 @@ You should consider changing lower_case_table_names to 1 or 2",
}
else
locked_in_memory=1;
+ if (user_info)
+ set_user(mysqld_user, user_info);
}
#else
locked_in_memory=0;