From: Sage Weil Date: Fri, 24 Apr 2015 21:57:46 +0000 (-0700) Subject: global: add --setuser and --setgroup options X-Git-Tag: v9.1.0~294^2~25 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=4dfe0a8a4b958aab154ee14729c8444fbcb4b798;p=ceph.git global: add --setuser and --setgroup options These are done after reading config files/environment and before log files are opened. Allow a name or id to be specified. In the case of --setuser, also switch to that user's gid, unless --setgroup is also specified. Signed-off-by: Sage Weil --- diff --git a/doc/man/8/ceph-mds.rst b/doc/man/8/ceph-mds.rst index d2ae92292256..af1f3c7cb52a 100644 --- a/doc/man/8/ceph-mds.rst +++ b/doc/man/8/ceph-mds.rst @@ -47,6 +47,17 @@ Options Debug mode: like ``-f``, but also send all log output to stderr. +.. option:: --setuser userorgid + + Set uid after starting. If a username is specified, the user + record is looked up to get a uid and a gid, and the gid is also set + as well, unless --setgroup is also specified. + +.. option:: --setgroup grouporgid + + Set gid after starting. If a group name is specified the group + record is looked up to get a gid. + .. option:: -c ceph.conf, --conf=ceph.conf Use *ceph.conf* configuration file instead of the default diff --git a/doc/man/8/ceph-mon.rst b/doc/man/8/ceph-mon.rst index 287c668349bb..7a2cd032c481 100644 --- a/doc/man/8/ceph-mon.rst +++ b/doc/man/8/ceph-mon.rst @@ -36,6 +36,17 @@ Options Debug mode: like ``-f``, but also send all log output to stderr. +.. option:: --setuser userorgid + + Set uid after starting. If a username is specified, the user + record is looked up to get a uid and a gid, and the gid is also set + as well, unless --setgroup is also specified. + +.. option:: --setgroup grouporgid + + Set gid after starting. If a group name is specified the group + record is looked up to get a gid. + .. option:: -c ceph.conf, --conf=ceph.conf Use *ceph.conf* configuration file instead of the default diff --git a/doc/man/8/ceph-osd.rst b/doc/man/8/ceph-osd.rst index 9a1e6afdd88d..e8b2805b14e7 100644 --- a/doc/man/8/ceph-osd.rst +++ b/doc/man/8/ceph-osd.rst @@ -38,6 +38,17 @@ Options Debug mode: like ``-f``, but also send all log output to stderr. +.. option:: --setuser userorgid + + Set uid after starting. If a username is specified, the user + record is looked up to get a uid and a gid, and the gid is also set + as well, unless --setgroup is also specified. + +.. option:: --setgroup grouporgid + + Set gid after starting. If a group name is specified the group + record is looked up to get a gid. + .. option:: --osd-data osddata Use object store at *osddata*. diff --git a/src/common/ceph_argparse.cc b/src/common/ceph_argparse.cc index 858882baf0ef..1a60f2e1a835 100644 --- a/src/common/ceph_argparse.cc +++ b/src/common/ceph_argparse.cc @@ -521,6 +521,8 @@ static void generic_usage(bool is_server) --id/-i ID set ID portion of my name\n\ --name/-n TYPE.ID set name\n\ --cluster NAME set cluster name (default: ceph)\n\ + --setuser USER set uid to user or uid (and gid to user's gid)\n\ + --setgroup GROUP set gid to group or gid\n\ --version show version and quit\n\ " << std::endl; diff --git a/src/common/config_opts.h b/src/common/config_opts.h index 15c8ed57592a..5e26ac1fb9ba 100644 --- a/src/common/config_opts.h +++ b/src/common/config_opts.h @@ -29,6 +29,8 @@ OPTION(admin_socket, OPT_STR, "$run_dir/$cluster-$name.asok") // default changed 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(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 06a7c2eaff58..23be38c5f4f2 100644 --- a/src/global/global_init.cc +++ b/src/global/global_init.cc @@ -29,6 +29,9 @@ #include "include/compat.h" #include "include/color.h" +#include +#include + #include #include #ifdef WITH_LTTNG @@ -130,13 +133,64 @@ void global_init(std::vector < const char * > *alt_def_args, if (g_conf->log_flush_on_exit) g_ceph_context->_log->set_flush_on_exit(); + // 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; + 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; + } + } + 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 << "'" + << std::endl; + exit(1); + } + gid = g->gr_gid; + } + } + if (setgid(gid) != 0) { + int r = errno; + cerr << "unable to setgid " << gid << ": " << cpp_strerror(r) + << std::endl; + exit(1); + } + if (setuid(uid) != 0) { + int r = errno; + cerr << "unable to setuid " << uid << ": " << cpp_strerror(r) + << std::endl; + exit(1); + } + dout(0) << "set uid:gid to " << uid << ":" << gid << dendl; + } + if (g_conf->run_dir.length() && code_env == CODE_ENVIRONMENT_DAEMON && !(flags & CINIT_FLAG_NO_DAEMON_ACTIONS)) { int r = ::mkdir(g_conf->run_dir.c_str(), 0755); if (r < 0 && errno != EEXIST) { r = -errno; - derr << "warning: unable to create " << g_conf->run_dir << ": " << cpp_strerror(r) << dendl; + cerr << "warning: unable to create " << g_conf->run_dir << ": " << cpp_strerror(r) << std::endl; } } diff --git a/src/test/cli/radosgw-admin/help.t b/src/test/cli/radosgw-admin/help.t index 33aee1d5eb33..fec8737541e4 100644 --- a/src/test/cli/radosgw-admin/help.t +++ b/src/test/cli/radosgw-admin/help.t @@ -135,6 +135,8 @@ --id/-i ID set ID portion of my name --name/-n TYPE.ID set name --cluster NAME set cluster name (default: ceph) + --setuser USER set uid to user or uid (and gid to user's gid) + --setgroup GROUP set gid to group or gid --version show version and quit [1]