Skip to content

Commit

Permalink
common/global: refactor global_init to avoid setuser/setgroup modific…
Browse files Browse the repository at this point in the history
…ation

Signed-off-by: liuchang0812 <liuchang0812@gmail.com>
  • Loading branch information
liuchang0812 committed Mar 21, 2017
1 parent b5582dd commit bb72c76
Showing 1 changed file with 84 additions and 83 deletions.
167 changes: 84 additions & 83 deletions src/global/global_init.cc
Expand Up @@ -166,106 +166,107 @@ global_init(std::vector < const char * > *alt_def_args,
if (g_conf->log_flush_on_exit)
g_ceph_context->_log->set_flush_on_exit();

ostringstream priv_ss;

// consider --setuser root a no-op, even if we're not root
if (getuid() != 0) {
if (g_conf->setuser.length()) {
cerr << "ignoring --setuser " << g_conf->setuser << " since I am not root"
<< std::endl;
g_conf->set_val("setuser", "", false);
}
if (g_conf->setgroup.length()) {
cerr << "ignoring --setgroup " << g_conf->setgroup
<< " since I am not root" << std::endl;
g_conf->set_val("setgroup", "", false);
}
}

// drop privileges?
ostringstream priv_ss;
if (g_conf->setgroup.length() ||
g_conf->setuser.length()) {
uid_t uid = 0; // zero means no change; we can only drop privs here.
gid_t gid = 0;
std::string uid_string;
std::string gid_string;
if (g_conf->setuser.length()) {
uid = atoi(g_conf->setuser.c_str());
if (!uid) {
char buf[4096];
struct passwd pa;
struct passwd *p = 0;
getpwnam_r(g_conf->setuser.c_str(), &pa, buf, sizeof(buf), &p);
if (!p) {
cerr << "unable to look up user '" << g_conf->setuser << "'"
<< std::endl;
exit(1);
}
uid = p->pw_uid;
gid = p->pw_gid;
uid_string = g_conf->setuser;
else {
// drop privileges?

if (g_conf->setgroup.length() ||
g_conf->setuser.length()) {
uid_t uid = 0; // zero means no change; we can only drop privs here.
gid_t gid = 0;
std::string uid_string;
std::string gid_string;
if (g_conf->setuser.length()) {
uid = atoi(g_conf->setuser.c_str());
if (!uid) {
char buf[4096];
struct passwd pa;
struct passwd *p = 0;
getpwnam_r(g_conf->setuser.c_str(), &pa, buf, sizeof(buf), &p);
if (!p) {
cerr << "unable to look up user '" << g_conf->setuser << "'"
<< std::endl;
exit(1);
}
uid = p->pw_uid;
gid = p->pw_gid;
uid_string = g_conf->setuser;
}
}
}
if (g_conf->setgroup.length() > 0) {
gid = atoi(g_conf->setgroup.c_str());
if (!gid) {
char buf[4096];
struct group gr;
struct group *g = 0;
getgrnam_r(g_conf->setgroup.c_str(), &gr, buf, sizeof(buf), &g);
if (!g) {
cerr << "unable to look up group '" << g_conf->setgroup << "'"
if (g_conf->setgroup.length() > 0) {
gid = atoi(g_conf->setgroup.c_str());
if (!gid) {
char buf[4096];
struct group gr;
struct group *g = 0;
getgrnam_r(g_conf->setgroup.c_str(), &gr, buf, sizeof(buf), &g);
if (!g) {
cerr << "unable to look up group '" << g_conf->setgroup << "'"
<< ": " << cpp_strerror(errno) << std::endl;
exit(1);
}
gid = g->gr_gid;
gid_string = g_conf->setgroup;
}
}
if ((uid || gid) &&
g_conf->setuser_match_path.length()) {
// induce early expansion of setuser_match_path config option
string match_path = g_conf->setuser_match_path;
g_conf->early_expand_meta(match_path, &cerr);
struct stat st;
int r = ::stat(match_path.c_str(), &st);
if (r < 0) {
cerr << "unable to stat setuser_match_path "
<< g_conf->setuser_match_path
<< ": " << cpp_strerror(errno) << std::endl;
exit(1);
}
gid = g->gr_gid;
gid_string = g_conf->setgroup;
}
}
if ((uid || gid) &&
g_conf->setuser_match_path.length()) {
// induce early expansion of setuser_match_path config option
string match_path = g_conf->setuser_match_path;
g_conf->early_expand_meta(match_path, &cerr);
struct stat st;
int r = ::stat(match_path.c_str(), &st);
if (r < 0) {
cerr << "unable to stat setuser_match_path "
<< g_conf->setuser_match_path
<< ": " << cpp_strerror(errno) << std::endl;
exit(1);
}
if ((uid && uid != st.st_uid) ||
(gid && gid != st.st_gid)) {
cerr << "WARNING: will not setuid/gid: " << match_path
<< " owned by " << st.st_uid << ":" << st.st_gid
<< " and not requested " << uid << ":" << gid
<< std::endl;
uid = 0;
gid = 0;
uid_string.erase();
gid_string.erase();
} else {
priv_ss << "setuser_match_path "
<< match_path << " owned by "
<< st.st_uid << ":" << st.st_gid << ". ";
}
}
if ((uid && uid != st.st_uid) ||
(gid && gid != st.st_gid)) {
cerr << "WARNING: will not setuid/gid: " << match_path
<< " owned by " << st.st_uid << ":" << st.st_gid
<< " and not requested " << uid << ":" << gid
<< std::endl;
uid = 0;
gid = 0;
uid_string.erase();
gid_string.erase();
g_ceph_context->set_uid_gid(uid, gid);
g_ceph_context->set_uid_gid_strings(uid_string, gid_string);
if ((flags & CINIT_FLAG_DEFER_DROP_PRIVILEGES) == 0) {
if (setgid(gid) != 0) {
cerr << "unable to setgid " << gid << ": " << cpp_strerror(errno)
<< std::endl;
exit(1);
}
if (setuid(uid) != 0) {
cerr << "unable to setuid " << uid << ": " << cpp_strerror(errno)
<< std::endl;
exit(1);
}
priv_ss << "set uid:gid to " << uid << ":" << gid << " (" << uid_string << ":" << gid_string << ")";
} else {
priv_ss << "setuser_match_path "
<< match_path << " owned by "
<< st.st_uid << ":" << st.st_gid << ". ";
}
}
g_ceph_context->set_uid_gid(uid, gid);
g_ceph_context->set_uid_gid_strings(uid_string, gid_string);
if ((flags & CINIT_FLAG_DEFER_DROP_PRIVILEGES) == 0) {
if (setgid(gid) != 0) {
cerr << "unable to setgid " << gid << ": " << cpp_strerror(errno)
<< std::endl;
exit(1);
}
if (setuid(uid) != 0) {
cerr << "unable to setuid " << uid << ": " << cpp_strerror(errno)
<< std::endl;
exit(1);
priv_ss << "deferred set uid:gid to " << uid << ":" << gid << " (" << uid_string << ":" << gid_string << ")";
}
priv_ss << "set uid:gid to " << uid << ":" << gid << " (" << uid_string << ":" << gid_string << ")";
} else {
priv_ss << "deferred set uid:gid to " << uid << ":" << gid << " (" << uid_string << ":" << gid_string << ")";
}
}

Expand Down

0 comments on commit bb72c76

Please sign in to comment.