pion  5.0.6
admin_rights.cpp
1 // ---------------------------------------------------------------------
2 // pion: a Boost C++ framework for building lightweight HTTP interfaces
3 // ---------------------------------------------------------------------
4 // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion)
5 //
6 // Distributed under the Boost Software License, Version 1.0.
7 // See http://www.boost.org/LICENSE_1_0.txt
8 //
9 
10 #include <pion/admin_rights.hpp>
11 
12 #ifndef _MSC_VER
13  #include <sys/types.h>
14  #include <unistd.h>
15  #include <sys/types.h>
16  #include <boost/regex.hpp>
17  #include <boost/tokenizer.hpp>
18  #include <boost/lexical_cast.hpp>
19  #include <fstream>
20 #endif
21 
22 
23 namespace pion { // begin namespace pion
24 
25 
26 // static members of admin_rights
27 
28 const boost::int16_t admin_rights::ADMIN_USER_ID = 0;
29 boost::mutex admin_rights::m_mutex;
30 
31 
32 // admin_rights member functions
33 
34 #ifdef _MSC_VER
35 
36 admin_rights::admin_rights(bool use_log)
37  : m_logger(PION_GET_LOGGER("pion.admin_rights")),
38  m_lock(m_mutex), m_user_id(-1), m_has_rights(false), m_use_log(use_log)
39 {}
40 
41 void admin_rights::release(void)
42 {}
43 
44 long admin_rights::run_as_user(const std::string& user_name)
45 {
46  return -1;
47 }
48 
49 long admin_rights::run_as_group(const std::string& group_name)
50 {
51  return -1;
52 }
53 
54 long admin_rights::find_system_id(const std::string& name,
55  const std::string& file)
56 {
57  return -1;
58 }
59 
60 #else // NOT #ifdef _MSC_VER
61 
63  : m_logger(PION_GET_LOGGER("pion.admin_rights")),
64  m_lock(m_mutex), m_user_id(-1), m_has_rights(false), m_use_log(use_log)
65 {
66  m_user_id = geteuid();
67  if ( seteuid(ADMIN_USER_ID) != 0 ) {
68  if (m_use_log)
69  PION_LOG_ERROR(m_logger, "Unable to upgrade to administrative rights");
70  m_lock.unlock();
71  return;
72  } else {
73  m_has_rights = true;
74  if (m_use_log)
75  PION_LOG_DEBUG(m_logger, "Upgraded to administrative rights");
76  }
77 }
78 
80 {
81  if (m_has_rights) {
82  if ( seteuid(m_user_id) == 0 ) {
83  if (m_use_log)
84  PION_LOG_DEBUG(m_logger, "Released administrative rights");
85  } else {
86  if (m_use_log)
87  PION_LOG_ERROR(m_logger, "Unable to release administrative rights");
88  }
89  m_has_rights = false;
90  m_lock.unlock();
91  }
92 }
93 
94 long admin_rights::run_as_user(const std::string& user_name)
95 {
96  long user_id = find_system_id(user_name, "/etc/passwd");
97  if (user_id != -1) {
98  if ( seteuid(user_id) != 0 )
99  user_id = -1;
100  } else {
101  user_id = geteuid();
102  }
103  return user_id;
104 }
105 
106 long admin_rights::run_as_group(const std::string& group_name)
107 {
108  long group_id = find_system_id(group_name, "/etc/group");
109  if (group_id != -1) {
110  if ( setegid(group_id) != 0 )
111  group_id = -1;
112  } else {
113  group_id = getegid();
114  }
115  return group_id;
116 }
117 
118 long admin_rights::find_system_id(const std::string& name,
119  const std::string& file)
120 {
121  // check if name is the system id
122  const boost::regex just_numbers("\\d+");
123  if (boost::regex_match(name, just_numbers)) {
124  return boost::lexical_cast<boost::int32_t>(name);
125  }
126 
127  // open system file
128  std::ifstream system_file(file.c_str());
129  if (! system_file.is_open()) {
130  return -1;
131  }
132 
133  // find id in system file
134  typedef boost::tokenizer<boost::char_separator<char> > Tok;
135  boost::char_separator<char> sep(":");
136  std::string line;
137  boost::int32_t system_id = -1;
138 
139  while (std::getline(system_file, line, '\n')) {
140  Tok tokens(line, sep);
141  Tok::const_iterator token_it = tokens.begin();
142  if (token_it != tokens.end() && *token_it == name) {
143  // found line matching name
144  if (++token_it != tokens.end() && ++token_it != tokens.end()
145  && boost::regex_match(*token_it, just_numbers))
146  {
147  // found id as third parameter
148  system_id = boost::lexical_cast<boost::int32_t>(*token_it);
149  }
150  break;
151  }
152  }
153 
154  return system_id;
155 }
156 
157 #endif // #ifdef _MSC_VER
158 
159 } // end namespace pion
160 
void release(void)
releases administrative rights
static long run_as_group(const std::string &group_name)
calculates the group id based upon the group configuration parameter
admin_rights(bool use_log=true)
static long run_as_user(const std::string &user_name)
calculates the user id based upon the user configuration parameter