pion  5.0.6
src/admin_rights.cpp
00001 // ---------------------------------------------------------------------
00002 // pion:  a Boost C++ framework for building lightweight HTTP interfaces
00003 // ---------------------------------------------------------------------
00004 // Copyright (C) 2007-2014 Splunk Inc.  (https://github.com/splunk/pion)
00005 //
00006 // Distributed under the Boost Software License, Version 1.0.
00007 // See http://www.boost.org/LICENSE_1_0.txt
00008 //
00009 
00010 #include <pion/admin_rights.hpp>
00011 
00012 #ifndef _MSC_VER
00013     #include <sys/types.h>
00014     #include <unistd.h>
00015     #include <sys/types.h>
00016     #include <boost/regex.hpp>
00017     #include <boost/tokenizer.hpp>
00018     #include <boost/lexical_cast.hpp>
00019     #include <fstream>
00020 #endif
00021 
00022 
00023 namespace pion {    // begin namespace pion
00024 
00025 
00026 // static members of admin_rights
00027 
00028 const boost::int16_t    admin_rights::ADMIN_USER_ID = 0;
00029 boost::mutex            admin_rights::m_mutex;
00030 
00031 
00032 // admin_rights member functions
00033 
00034 #ifdef _MSC_VER
00035 
00036 admin_rights::admin_rights(bool use_log)
00037     : m_logger(PION_GET_LOGGER("pion.admin_rights")),
00038     m_lock(m_mutex), m_user_id(-1), m_has_rights(false), m_use_log(use_log)
00039 {}
00040 
00041 void admin_rights::release(void)
00042 {}
00043 
00044 long admin_rights::run_as_user(const std::string& user_name)
00045 {
00046     return -1;
00047 }
00048 
00049 long admin_rights::run_as_group(const std::string& group_name)
00050 {
00051     return -1;
00052 }
00053 
00054 long admin_rights::find_system_id(const std::string& name,
00055     const std::string& file)
00056 {
00057     return -1;
00058 }
00059 
00060 #else   // NOT #ifdef _MSC_VER
00061 
00062 admin_rights::admin_rights(bool use_log)
00063     : m_logger(PION_GET_LOGGER("pion.admin_rights")),
00064     m_lock(m_mutex), m_user_id(-1), m_has_rights(false), m_use_log(use_log)
00065 {
00066     m_user_id = geteuid();
00067     if ( seteuid(ADMIN_USER_ID) != 0 ) {
00068         if (m_use_log)
00069             PION_LOG_ERROR(m_logger, "Unable to upgrade to administrative rights");
00070         m_lock.unlock();
00071         return;
00072     } else {
00073         m_has_rights = true;
00074         if (m_use_log)
00075             PION_LOG_DEBUG(m_logger, "Upgraded to administrative rights");
00076     }
00077 }
00078 
00079 void admin_rights::release(void)
00080 {
00081     if (m_has_rights) {
00082         if ( seteuid(m_user_id) == 0 ) {
00083             if (m_use_log)
00084                 PION_LOG_DEBUG(m_logger, "Released administrative rights");
00085         } else {
00086             if (m_use_log)
00087                 PION_LOG_ERROR(m_logger, "Unable to release administrative rights");
00088         }
00089         m_has_rights = false;
00090         m_lock.unlock();
00091     }
00092 }
00093 
00094 long admin_rights::run_as_user(const std::string& user_name)
00095 {
00096     long user_id = find_system_id(user_name, "/etc/passwd");
00097     if (user_id != -1) {
00098         if ( seteuid(user_id) != 0 )
00099             user_id = -1;
00100     } else {
00101         user_id = geteuid();
00102     }
00103     return user_id;
00104 }
00105 
00106 long admin_rights::run_as_group(const std::string& group_name)
00107 {
00108     long group_id = find_system_id(group_name, "/etc/group");
00109     if (group_id != -1) {
00110         if ( setegid(group_id) != 0 )
00111             group_id = -1;
00112     } else {
00113         group_id = getegid();
00114     }
00115     return group_id;
00116 }
00117 
00118 long admin_rights::find_system_id(const std::string& name,
00119     const std::string& file)
00120 {
00121     // check if name is the system id
00122     const boost::regex just_numbers("\\d+");
00123     if (boost::regex_match(name, just_numbers)) {
00124         return boost::lexical_cast<boost::int32_t>(name);
00125     }
00126 
00127     // open system file
00128     std::ifstream system_file(file.c_str());
00129     if (! system_file.is_open()) {
00130         return -1;
00131     }
00132 
00133     // find id in system file
00134     typedef boost::tokenizer<boost::char_separator<char> > Tok;
00135     boost::char_separator<char> sep(":");
00136     std::string line;
00137     boost::int32_t system_id = -1;
00138 
00139     while (std::getline(system_file, line, '\n')) {
00140         Tok tokens(line, sep);
00141         Tok::const_iterator token_it = tokens.begin();
00142         if (token_it != tokens.end() && *token_it == name) {
00143             // found line matching name
00144             if (++token_it != tokens.end() && ++token_it != tokens.end()
00145                 && boost::regex_match(*token_it, just_numbers))
00146             {
00147                 // found id as third parameter
00148                 system_id = boost::lexical_cast<boost::int32_t>(*token_it);
00149             }
00150             break;
00151         }
00152     }
00153 
00154     return system_id;
00155 }
00156 
00157 #endif  // #ifdef _MSC_VER
00158     
00159 }   // end namespace pion
00160