gidentity_unix.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2013 Graeme Walker <graeme_walker@users.sourceforge.net>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 //
18 // gidentity_unix.cpp
19 //
20 // Note that gcc requires -D_BSD_SOURCE for seteuid().
21 //
22 
23 #include "gdef.h"
24 #include "gidentity.h"
25 #include "glimits.h"
26 #include "gassert.h"
27 #include <sstream>
28 #include <vector>
29 #include <pwd.h> // getpwnam_r()
30 #include <unistd.h> // sysconf()
31 
33  m_uid(static_cast<uid_t>(-1)) ,
34  m_gid(static_cast<gid_t>(-1)) ,
35  m_h(0)
36 {
37 }
38 
39 G::Identity::Identity( const std::string & name ) :
40  m_uid(static_cast<uid_t>(-1)) ,
41  m_gid(static_cast<gid_t>(-1)) ,
42  m_h(0)
43 {
44  typedef ::passwd Pwd ;
45 
46  size_t buffer_size = 0 ;
47  {
48  long n = ::sysconf( _SC_GETPW_R_SIZE_MAX ) ;
50  {
51  buffer_size = limits::get_pwnam_r_buffer ;
52  }
53  else
54  {
55  G_ASSERT( n > 0 ) ;
56  unsigned long un = static_cast<unsigned long>(n) ;
57  const size_t size_max = (size_t)-1 ;
58  buffer_size = un > size_max ? size_max : static_cast<size_t>(un) ;
59  }
60  }
61 
62  std::vector<char> buffer( buffer_size ) ;
63 
64  Pwd pwd ;
65  Pwd * result_p = NULL ;
66  int rc = ::getpwnam_r( name.c_str() , &pwd , &buffer[0] , buffer_size , &result_p ) ;
67  if( rc != 0 || result_p == NULL )
68  {
69  if( name == "root" ) // in case no /etc/passwd
70  {
71  m_uid = 0 ;
72  m_gid = 0 ;
73  }
74  else
75  {
76  throw NoSuchUser(name) ;
77  }
78  }
79  else
80  {
81  m_uid = result_p->pw_uid ;
82  m_gid = result_p->pw_gid ;
83  }
84 }
85 
87 {
88  G::Identity id ;
89  id.m_uid = ::geteuid() ;
90  id.m_gid = ::getegid() ;
91  return id ;
92 }
93 
95 {
96  G::Identity id ;
97  id.m_uid = ::getuid() ;
98  id.m_gid = ::getgid() ;
99  return id ;
100 }
101 
103 {
104  return G::Identity() ;
105 }
106 
108 {
109  G::Identity id ;
110  id.m_uid = 0 ;
111  id.m_gid = 0 ;
112  return id ;
113 }
114 
115 std::string G::Identity::str() const
116 {
117  std::ostringstream ss ;
118  ss << m_uid << "/" << m_gid ;
119  return ss.str() ;
120 }
121 
123 {
124  return m_uid == 0 ;
125 }
126 
127 bool G::Identity::operator==( const Identity & other ) const
128 {
129  return m_uid == other.m_uid && m_gid == other.m_gid ;
130 }
131 
132 bool G::Identity::operator!=( const Identity & other ) const
133 {
134  return ! operator==( other ) ;
135 }
136 
138 {
139  ::seteuid(m_uid) ;
140 }
141 
142 void G::Identity::setEffectiveUser( bool do_throw )
143 {
144  if( ::seteuid(m_uid) && do_throw ) throw UidError() ;
145 }
146 
147 void G::Identity::setRealUser( bool do_throw )
148 {
149  if( ::setuid(m_uid) && do_throw ) throw UidError() ;
150 }
151 
152 void G::Identity::setEffectiveGroup( bool do_throw )
153 {
154  if( ::setegid(m_gid) && do_throw ) throw GidError() ;
155 }
156 
158 {
159  ::setegid(m_gid) ;
160 }
161 
162 void G::Identity::setRealGroup( bool do_throw )
163 {
164  if( ::setgid(m_gid) && do_throw ) throw GidError() ;
165 }
166 
167 // ===
168 
169 void G::IdentityUser::setRealUserTo( Identity id , bool do_throw )
170 {
171  id.setRealUser( do_throw ) ;
172 }
173 
175 {
176  id.setEffectiveUser( do_throw ) ;
177 }
178 
180 {
181  id.setEffectiveUser( safe ) ;
182 }
183 
184 void G::IdentityUser::setRealGroupTo( Identity id , bool do_throw )
185 {
186  id.setRealGroup( do_throw ) ;
187 }
188 
190 {
191  id.setEffectiveGroup( do_throw ) ;
192 }
193 
195 {
196  id.setEffectiveGroup( safe ) ;
197 }
bool isRoot() const
Returns true if the userid is zero.
An empty structure that is used to indicate a signal-safe, reentrant implementation.
Definition: gsignalsafe.h:35
static Identity root()
Returns the superuser identity.
static Identity real()
Returns the calling process's real identity.
Identity(const std::string &login_name)
Constructor for the named identity.
static Identity invalid()
Returns an invalid identity.
A very low-level interface to getpwnam() and the get/set/e/uid/gid functions.
Definition: gidentity.h:41
static void setRealGroupTo(Identity, bool do_throw=true)
Sets the real group id.
static Identity effective()
Returns the current effective identity.
void setRealUser(bool do_throw=true)
Sets the real userid.
void setRealGroup(bool do_throw=true)
Sets the real group id.
#define G_ASSERT(test)
Definition: gassert.h:30
static void setEffectiveUserTo(Identity, bool do_throw=true)
Sets the effective userid.
void setEffectiveGroup(bool do_throw=true)
Sets the effective group id.
bool operator==(const Identity &) const
Comparison operator.
static void setEffectiveGroupTo(Identity, bool do_throw=true)
Sets the effective group id.
std::string str() const
Returns a string representation.
static void setRealUserTo(Identity, bool do_throw=true)
Sets the real userid.
bool operator!=(const Identity &) const
Comparison operator.
void setEffectiveUser(bool do_throw=true)
Sets the effective userid.