summaryrefslogtreecommitdiff
path: root/mysys
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2016-12-20 15:17:59 +0100
committerSergei Golubchik <serg@mariadb.org>2016-12-22 12:25:10 +0100
commitc8e49f2f57b7e8c9dcf3cdb108dc15e6b63b4dc4 (patch)
treee47843125de2ee27dcd99a55a1b99fc0cf9c9f03 /mysys
parent706fb790bcf9105a73f34002fe28c75032267c4b (diff)
downloadmariadb-git-c8e49f2f57b7e8c9dcf3cdb108dc15e6b63b4dc4.tar.gz
move check_user/set_user from mysqld.cc to mysys
Diffstat (limited to 'mysys')
-rw-r--r--mysys/CMakeLists.txt4
-rw-r--r--mysys/my_setuser.c81
2 files changed, 83 insertions, 2 deletions
diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt
index 06a811f0994..cb86850c2de 100644
--- a/mysys/CMakeLists.txt
+++ b/mysys/CMakeLists.txt
@@ -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
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
- 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_uuid.c wqueue.c waiting_threads.c ma_dyncol.c
my_rdtsc.c my_context.c file_logger.c)
@@ -44,7 +44,7 @@ IF (WIN32)
ENDIF()
IF(UNIX)
- SET (MYSYS_SOURCES ${MYSYS_SOURCES} my_addr_resolve.c)
+ SET (MYSYS_SOURCES ${MYSYS_SOURCES} my_addr_resolve.c my_setuser.c)
ENDIF()
IF(HAVE_ALARM)
diff --git a/mysys/my_setuser.c b/mysys/my_setuser.c
new file mode 100644
index 00000000000..1f3e7770d4c
--- /dev/null
+++ b/mysys/my_setuser.c
@@ -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);
+}