core: add support for temporary privilege drop and elevation

Added "user" and "group" options to general section of configuration file.
NFD will attempt to set the effective group and user id to these values
after initializing all management modules.

Added privilege helper to drop and temporarily elevate privileges on demand.

Updated README.md with instructions to configure NFD to drop privileges.

Added handler for general confguration file section.

refs: #1370

Change-Id: Id27140ad2dc2ca14751058691511132a35649d58
diff --git a/daemon/main.cpp b/daemon/main.cpp
index ebea105..fdf14b5 100644
--- a/daemon/main.cpp
+++ b/daemon/main.cpp
@@ -28,6 +28,7 @@
 #include "version.hpp"
 #include "core/logger.hpp"
 #include "core/global-io.hpp"
+#include "core/privilege-helper.hpp"
 #include "fw/forwarder.hpp"
 #include "mgmt/internal-face.hpp"
 #include "mgmt/fib-manager.hpp"
@@ -35,6 +36,7 @@
 #include "mgmt/strategy-choice-manager.hpp"
 #include "mgmt/status-server.hpp"
 #include "core/config-file.hpp"
+#include "mgmt/general-config-section.hpp"
 
 namespace nfd {
 
@@ -60,6 +62,8 @@
     m_forwarder = make_shared<Forwarder>();
 
     initializeManagement(configFile);
+
+    PrivilegeHelper::drop();
   }
 
 
@@ -118,6 +122,8 @@
                                                boost::ref(*m_forwarder));
 
     ConfigFile config((IgnoreRibAndLogSections()));
+
+    general::setConfigFile(config);
     m_internalFace->getValidator().setConfigFile(config);
 
     m_forwarder->addFace(m_internalFace);
@@ -289,6 +295,16 @@
     NFD_LOG_FATAL(e.what());
     return 2;
   }
+  catch (const PrivilegeHelper::Error& e) {
+    // PrivilegeHelper::Errors do not inherit from std::exception
+    // and represent seteuid/gid failures
+
+    NFD_LOG_FATAL(e.what());
+    return 3;
+  }
+
+
+
 
   boost::asio::signal_set signalSet(getGlobalIoService());
   signalSet.add(SIGINT);
@@ -302,9 +318,13 @@
   try {
     getGlobalIoService().run();
   }
-  catch (std::exception& e) {
+  catch (const std::exception& e) {
     NFD_LOG_FATAL(e.what());
-    return 3;
+    return 4;
+  }
+  catch (const PrivilegeHelper::Error& e) {
+    NFD_LOG_FATAL(e.what());
+    return 5;
   }
 
   return 0;