diff options
author | unknown <ram@gw.mysql.r18.ru> | 2004-09-03 19:26:11 +0500 |
---|---|---|
committer | unknown <ram@gw.mysql.r18.ru> | 2004-09-03 19:26:11 +0500 |
commit | 462ee7c4175436938785c06c77394247b83d0d87 (patch) | |
tree | 29011b87c2b9ccb50302baa5657c18a78e3095fb /sql/mysqld.cc | |
parent | b871ea386c706a63bb53876d143d06e4109b4169 (diff) | |
download | mariadb-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.cc | 122 |
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; |