libi2ncommon: (tomj) implemented drop_root_priviledges using new User/Group classes
authorThomas Jarosch <thomas.jarosch@intra2net.com>
Mon, 7 Apr 2008 16:49:34 +0000 (16:49 +0000)
committerThomas Jarosch <thomas.jarosch@intra2net.com>
Mon, 7 Apr 2008 16:49:34 +0000 (16:49 +0000)
src/Makefile.am
src/daemonfunc.cpp
src/daemonfunc.hpp [moved from src/daemonfunc.hxx with 71% similarity]
src/filefunc.hxx
src/userfunc.cpp
src/userfunc.hpp [moved from src/userfunc.hxx with 100% similarity]
test/test_filefunc.cpp
test/test_pidfile.cpp

index 6c8882a..ced5609 100644 (file)
@@ -4,9 +4,9 @@ INCLUDES = -I$(top_srcdir)/src @LIBGETTEXT_CFLAGS@ @LIBICONV_CFLAGS@ $(all_inclu
 
 # the library search path.
 lib_LTLIBRARIES = libi2ncommon.la
-include_HEADERS = containerfunc.hpp daemonfunc.hxx filefunc.hxx \
+include_HEADERS = containerfunc.hpp daemonfunc.hpp filefunc.hxx \
        insocketstream.hxx ip_type.hxx ipfunc.hxx logread.hxx oftmpstream.hxx pidfile.hpp \
-       pipestream.hxx stringfunc.hxx timefunc.hxx userfunc.hxx
+       pipestream.hxx stringfunc.hxx timefunc.hxx userfunc.hpp
 libi2ncommon_la_SOURCES = containerfunc.cpp daemonfunc.cpp filefunc.cpp \
        ipfunc.cpp logread.cpp oftmpstream.cpp pidfile.cpp stringfunc.cpp timefunc.cpp \
        userfunc.cpp
index 979920e..680ef96 100644 (file)
@@ -27,41 +27,55 @@ using namespace std;
  */
 void daemonize()
 {
-    int pid=fork();
-
-    if (pid < 0)
-    {
-        throw runtime_error("fork() failed");
-    }
-    if (pid > 0)
-    {
-        // parent process
-        exit (0);
-    }
-    // pid==0 -> child process: continue
+   int pid=fork();
+
+   if (pid < 0)
+   {
+      throw runtime_error("fork() failed");
+   }
+   if (pid > 0)
+   {
+      // parent process
+      exit (0);
+   }
+   // pid==0 -> child process: continue
 }
 
 /**
  * Drop root privileges
  * @param username User to become. Don't change user if empty
  * @param group Group to become. Don't change group if empty
+ * @param get_group_from_user Get group GID from user information if group is empty.
+ * @return true if all is fine, false otherwise
  */
-void drop_root_privileges(const std::string &username,
-                                                 const std::string &group)
+bool drop_root_privileges(const std::string &username,
+                          const std::string &group, bool get_group_from_user)
 {
-/*
-    if (!group.empty()) {
-        if (setgid(daemon::lookup_gid(group))) {
-            throw runtime_error("Can't change to group " + group);
-        }
-    }
-
-    if (!username.empty()) {
-        if (setuid(daemon::lookup_uid(username))) {
-            throw runtime_error("Can't change to user " + username);
-        }
-    }
-*/
+   if (!group.empty())
+   {
+      Group my_group(group);
+      if (!my_group.is_valid())
+         return false;
+
+      if (setgid((my_group.Gid)))
+         return false;
+   }
+
+   if (!username.empty())
+   {
+      User my_user(username);
+      if (!my_user.is_valid())
+         return false;
+
+      if (get_group_from_user && group.empty())
+      {
+         if (setgid((my_user.Gid)))
+            return false;
+      }
+
+      if (setuid(my_user.Uid))
+         return false;
+   }
 }
 
 /**
@@ -79,48 +93,48 @@ void drop_root_privileges(const std::string &username,
  */
 bool pid_of(const std::string& name, std::vector< pid_t >& result)
 {
-    std::vector< std::string > entries;
-    std::vector< pid_t > fuzz1_result;
-    std::vector< pid_t > fuzz2_result;
-    result.clear();
-    if (!get_dir("/proc", entries)) return false;
-    for(std::vector< std::string >::const_iterator it= entries.begin();
-        it != entries.end();
-        ++it)
-    {
-        pid_t pid;
-        if (! string_to<pid_t>(*it, pid)) continue;
-        std::string base_path= std::string("/proc/") + *it;
-        std::string exe_path= base_path + "/exe";
-        I2n::Stat stat(exe_path, false);
-        if (not stat or not stat.is_link()) continue;
-        std::string real_exe= read_link(exe_path);
-        if (real_exe == name)
-        {
-            result.push_back( pid );
-            continue;
-        }
-
-        std::string proc_stat= read_file( base_path + "/stat");
-        if (proc_stat.empty()) continue; // process vanished
-
-        //TODO some more fuzz tests here?! (cmdline, stat(us))
-
-        if (basename(real_exe) == name)
-        {
-            fuzz2_result.push_back(pid);
-            continue;
-        }
-    }
-    if (result.empty())
-    {
-        result.swap(fuzz1_result);
-    }
-    if (result.empty())
-    {
-        result.swap(fuzz2_result);
-    }
-    return true;
+   std::vector< std::string > entries;
+   std::vector< pid_t > fuzz1_result;
+   std::vector< pid_t > fuzz2_result;
+   result.clear();
+   if (!get_dir("/proc", entries)) return false;
+   for (std::vector< std::string >::const_iterator it= entries.begin();
+         it != entries.end();
+         ++it)
+   {
+      pid_t pid;
+      if (! string_to<pid_t>(*it, pid)) continue;
+      std::string base_path= std::string("/proc/") + *it;
+      std::string exe_path= base_path + "/exe";
+      I2n::Stat stat(exe_path, false);
+      if (not stat or not stat.is_link()) continue;
+      std::string real_exe= read_link(exe_path);
+      if (real_exe == name)
+      {
+         result.push_back( pid );
+         continue;
+      }
+
+      std::string proc_stat= read_file( base_path + "/stat");
+      if (proc_stat.empty()) continue; // process vanished
+
+      //TODO some more fuzz tests here?! (cmdline, stat(us))
+
+      if (basename(real_exe) == name)
+      {
+         fuzz2_result.push_back(pid);
+         continue;
+      }
+   }
+   if (result.empty())
+   {
+      result.swap(fuzz1_result);
+   }
+   if (result.empty())
+   {
+      result.swap(fuzz2_result);
+   }
+   return true;
 } // eo pidOf(const std::string&,std::vector< pid_t >&)
 
 }
similarity index 71%
rename from src/daemonfunc.hxx
rename to src/daemonfunc.hpp
index 14deeb1..e8698b7 100644 (file)
@@ -15,12 +15,12 @@ namespace I2n
 {
 namespace daemon
 {
-    void daemonize();
+void daemonize();
 
-    void drop_root_privileges(const std::string &username,
-                                              const std::string &group);
+bool drop_root_privileges(const std::string &username,
+                          const std::string &group, bool get_group_from_user=false);
 
-    bool pid_of(const std::string& name, std::vector< pid_t >& result);
+bool pid_of(const std::string& name, std::vector< pid_t >& result);
 }
 }
 
index b2216af..9de7873 100644 (file)
@@ -7,7 +7,7 @@
 #ifndef __FILEFUNC_HXX
 #define __FILEFUNC_HXX
 
-#include "userfunc.hxx"
+#include "userfunc.hpp"
 
 namespace I2n
 {
index 2930ecd..c11ec20 100644 (file)
@@ -11,7 +11,7 @@
  *
  */
 
-#include "userfunc.hxx"
+#include "userfunc.hpp"
 
 #include <algorithm>
 #include <fstream>
similarity index 100%
rename from src/userfunc.hxx
rename to src/userfunc.hpp
index e315df3..e011060 100644 (file)
@@ -22,7 +22,7 @@
 #include <cppunit/extensions/HelperMacros.h>
 
 #include <filefunc.hxx>
-#include <daemonfunc.hxx>
+#include <daemonfunc.hpp>
 
 #ifdef NOISEDEBUG
 #define DOUT(msg) std::cout << msg << std::endl
index 477072d..815ae85 100644 (file)
@@ -52,7 +52,7 @@ public:
       PidFile pidfile(Filename);
       bool rtn_write = pidfile.write();
 
-      CPPUNIT_ASSERT_EQUAL(rtn_write, true);
+      CPPUNIT_ASSERT_EQUAL(true, rtn_write);
    }
 
    void AutoRemoval()
@@ -64,8 +64,8 @@ public:
       }
       bool exists = I2n::file_exists(Filename);
 
-      CPPUNIT_ASSERT_EQUAL(rtn_write, true);
-      CPPUNIT_ASSERT_EQUAL(exists, false);
+      CPPUNIT_ASSERT_EQUAL(true, rtn_write);
+      CPPUNIT_ASSERT_EQUAL(false, exists);
    }
 
    void NoAutoRemoval()
@@ -78,8 +78,8 @@ public:
       bool exists = I2n::file_exists(Filename);
       I2n::unlink(Filename);
 
-      CPPUNIT_ASSERT_EQUAL(rtn_write, true);
-      CPPUNIT_ASSERT_EQUAL(exists, true);
+      CPPUNIT_ASSERT_EQUAL(true, rtn_write);
+      CPPUNIT_ASSERT_EQUAL(true, exists);
    }
 
    void NotRunning()
@@ -87,7 +87,7 @@ public:
       PidFile pidfile(Filename);
       bool rtn_check = pidfile.check_already_running();
 
-      CPPUNIT_ASSERT_EQUAL(rtn_check, false);
+      CPPUNIT_ASSERT_EQUAL(false, rtn_check);
    }
 
    void IsAlreadyRunning()
@@ -96,13 +96,15 @@ public:
       bool rtn_file1_check = pidfile1.check_already_running();
       bool rtn_file1_write = pidfile1.write();
 
-      CPPUNIT_ASSERT_EQUAL(rtn_file1_check, false);
-      CPPUNIT_ASSERT_EQUAL(rtn_file1_write, true);
+      CPPUNIT_ASSERT_EQUAL(false, rtn_file1_check);
+      CPPUNIT_ASSERT_EQUAL(true, rtn_file1_write);
 
       PidFile pidfile2(Filename);
-      bool rtn_file2_check = pidfile2.check_already_running();
+      pid_t my_pid = 0;
+      bool rtn_file2_check = pidfile2.check_already_running(&my_pid);
 
-      CPPUNIT_ASSERT_EQUAL(rtn_file2_check, true);
+      CPPUNIT_ASSERT_EQUAL(true, rtn_file2_check);
+      CPPUNIT_ASSERT_EQUAL(getpid(), my_pid);
    }
 
 private: