]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
global: add --setuser and --setgroup options
authorSage Weil <sage@redhat.com>
Fri, 24 Apr 2015 21:57:46 +0000 (14:57 -0700)
committerSage Weil <sage@redhat.com>
Thu, 27 Aug 2015 00:34:15 +0000 (20:34 -0400)
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 <sage@redhat.com>
doc/man/8/ceph-mds.rst
doc/man/8/ceph-mon.rst
doc/man/8/ceph-osd.rst
src/common/ceph_argparse.cc
src/common/config_opts.h
src/global/global_init.cc
src/test/cli/radosgw-admin/help.t

index d2ae92292256b3ca729f857f260e9705a380d72e..af1f3c7cb52a71adbc7819570aaccd8096bd08ad 100644 (file)
@@ -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
index 287c668349bb9b9721889551b2f2dc7b78705f33..7a2cd032c481482782e3a22a1a74c3e8909d87e3 100644 (file)
@@ -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
index 9a1e6afdd88d059a88ba8cd96ded932149db54b9..e8b2805b14e7fede76274f97736d7f6c2a28b063 100644 (file)
@@ -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*.
index 858882baf0efded1de65551a5203d1e523cf495b..1a60f2e1a8351052252d1ba8e8d1f0760f181e41 100644 (file)
@@ -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;
 
index 15c8ed57592a88fd150ed439722db87e71f60b6c..5e26ac1fb9ba444d68d58bcdfd43d7f808f3e35a 100644 (file)
@@ -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)
index 06a7c2eaff58842a6a90500c67a56f312376de74..23be38c5f4f24664ffd106a252b1fdc1f2626b79 100644 (file)
@@ -29,6 +29,9 @@
 #include "include/compat.h"
 #include "include/color.h"
 
+#include <pwd.h>
+#include <grp.h>
+
 #include <errno.h>
 #include <deque>
 #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;
     }
   }
 
index 33aee1d5eb332ffa70e72407c29a208c23081bd3..fec8737541e4b024627114a111feea9df0229ab8 100644 (file)
     --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]