From 28fdac32e7b22a9eda43a610610abd9b5b242269 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 6 Aug 2015 11:57:48 -0400 Subject: [PATCH] global: implement setuser_match_path Allow the --setuser and --setgroup to be conditional on the specified user/group matching the ownership of a given path. This allows the ceph daemons to switch to user ceph for newly deployed instances or stay as root depending on the ownership of the data directory. Signed-off-by: Sage Weil Reviewed-by: Boris Ranto --- src/common/config_opts.h | 1 + src/global/global_init.cc | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/common/config_opts.h b/src/common/config_opts.h index 5e26ac1fb9b..0abf9b418f5 100644 --- a/src/common/config_opts.h +++ b/src/common/config_opts.h @@ -31,6 +31,7 @@ OPTION(crushtool, OPT_STR, "crushtool") // crushtool utility path OPTION(daemonize, OPT_BOOL, false) // default changed by common_preinit() OPTION(setuser, OPT_STR, "") // uid or user name OPTION(setgroup, OPT_STR, "") // gid or group name +OPTION(setuser_match_path, OPT_STR, "") // make setuser/group conditional on this patch matching ownership OPTION(pid_file, OPT_STR, "") // default changed by common_preinit() OPTION(chdir, OPT_STR, "/") OPTION(max_open_files, OPT_LONGLONG, 0) diff --git a/src/global/global_init.cc b/src/global/global_init.cc index 23be38c5f4f..a073613fa67 100644 --- a/src/global/global_init.cc +++ b/src/global/global_init.cc @@ -169,6 +169,32 @@ void global_init(std::vector < const char * > *alt_def_args, gid = g->gr_gid; } } + if ((uid || gid) && + g_conf->setuser_match_path.length()) { + struct stat st; + int r = ::stat(g_conf->setuser_match_path.c_str(), &st); + if (r < 0) { + r = -errno; + cerr << "unable to stat setuser_match_path " + << g_conf->setuser_match_path + << ": " << cpp_strerror(r) << std::endl; + exit(1); + } + if ((uid && uid != st.st_uid) || + (gid && gid != st.st_gid)) { + cerr << "WARNING: will not setuid/gid: " << g_conf->setuser_match_path + << " owned by " << st.st_uid << ":" << st.st_gid + << " and not requested " << uid << ":" << gid + << std::endl; + uid = 0; + gid = 0; + } else { + dout(10) << "setuser_match_path " + << g_conf->setuser_match_path << " owned by " + << st.st_uid << ":" << st.st_gid << ", doing setuid/gid" + << dendl; + } + } if (setgid(gid) != 0) { int r = errno; cerr << "unable to setgid " << gid << ": " << cpp_strerror(r)