E-MailRelay

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

gidentity_unix.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2018 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/glibc previously required -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
32 G::Identity::Identity() :
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( G::SignalSafe ) :
40 m_uid(static_cast<uid_t>(-1)) ,
41 m_gid(static_cast<gid_t>(-1)) ,
42 m_h(0)
43 {
44 }
45
46 G::Identity::Identity( const std::string & name ) :
47 m_uid(static_cast<uid_t>(-1)) ,
48 m_gid(static_cast<gid_t>(-1)) ,
49 m_h(0)
50 {
51 size_t buffer_size = 0 ;
52 {
53 long n = ::sysconf( _SC_GETPW_R_SIZE_MAX ) ;
54 if( n < limits::get_pwnam_r_buffer )
55 {
56 buffer_size = limits::get_pwnam_r_buffer ;
57 }
58 else
59 {
60 G_ASSERT( n > 0 ) ;
61 unsigned long un = static_cast<unsigned long>(n) ;
62 const size_t size_max = (size_t)-1 ;
63 buffer_size = un > size_max ? size_max : static_cast<size_t>(un) ;
64 }
65 }
66
67 std::vector<char> buffer( buffer_size ) ;
68
69 ::passwd pwd ;
70 ::passwd * result_p = nullptr ;
71 int rc = ::getpwnam_r( name.c_str() , &pwd , &buffer[0] , buffer_size , &result_p ) ;
72 if( rc != 0 || result_p == nullptr )
73 {
74 if( name == "root" ) // in case no /etc/passwd
75 {
76 m_uid = 0 ;
77 m_gid = 0 ;
78 }
79 else
80 {
81 throw NoSuchUser(name) ;
82 }
83 }
84 else
85 {
86 m_uid = result_p->pw_uid ;
87 m_gid = result_p->pw_gid ;
88 }
89 }
90
91 G::Identity G::Identity::effective()
92 {
93 G::Identity id ;
94 id.m_uid = ::geteuid() ;
95 id.m_gid = ::getegid() ;
96 return id ;
97 }
98
99 G::Identity G::Identity::real()
100 {
101 G::Identity id ;
102 id.m_uid = ::getuid() ;
103 id.m_gid = ::getgid() ;
104 return id ;
105 }
106
107 G::Identity G::Identity::invalid()
108 {
109 return G::Identity() ;
110 }
111
112 G::Identity G::Identity::invalid( SignalSafe safe )
113 {
114 return G::Identity(safe) ;
115 }
116
117 G::Identity G::Identity::root()
118 {
119 G::Identity id ;
120 id.m_uid = 0 ;
121 id.m_gid = 0 ;
122 return id ;
123 }
124
125 std::string G::Identity::str() const
126 {
127 std::ostringstream ss ;
128 ss << m_uid << "/" << m_gid ;
129 return ss.str() ;
130 }
131
132 bool G::Identity::isRoot() const
133 {
134 return m_uid == 0 ;
135 }
136
137 bool G::Identity::operator==( const Identity & other ) const
138 {
139 return m_uid == other.m_uid && m_gid == other.m_gid ;
140 }
141
142 bool G::Identity::operator!=( const Identity & other ) const
143 {
144 return ! operator==( other ) ;
145 }
146
147 void G::Identity::setEffectiveUser( SignalSafe )
148 {
149 int rc = ::seteuid(m_uid) ; G_IGNORE_VARIABLE(rc) ;
150 }
151
152 void G::Identity::setEffectiveUser( bool do_throw )
153 {
154 if( ::seteuid(m_uid) && do_throw ) throw UidError() ;
155 }
156
157 void G::Identity::setRealUser( bool do_throw )
158 {
159 if( ::setuid(m_uid) && do_throw ) throw UidError() ;
160 }
161
162 void G::Identity::setEffectiveGroup( bool do_throw )
163 {
164 if( ::setegid(m_gid) && do_throw ) throw GidError() ;
165 }
166
167 void G::Identity::setEffectiveGroup( SignalSafe )
168 {
169 int rc = ::setegid(m_gid) ; G_IGNORE_VARIABLE(rc) ;
170 }
171
172 void G::Identity::setRealGroup( bool do_throw )
173 {
174 if( ::setgid(m_gid) && do_throw ) throw GidError() ;
175 }
176
177 // ===
178
179 void G::IdentityUser::setRealUserTo( Identity id , bool do_throw )
180 {
181 id.setRealUser( do_throw ) ;
182 }
183
184 void G::IdentityUser::setEffectiveUserTo( Identity id , bool do_throw )
185 {
186 id.setEffectiveUser( do_throw ) ;
187 }
188
189 void G::IdentityUser::setEffectiveUserTo( SignalSafe safe , Identity id )
190 {
191 id.setEffectiveUser( safe ) ;
192 }
193
194 void G::IdentityUser::setRealGroupTo( Identity id , bool do_throw )
195 {
196 id.setRealGroup( do_throw ) ;
197 }
198
199 void G::IdentityUser::setEffectiveGroupTo( Identity id , bool do_throw )
200 {
201 id.setEffectiveGroup( do_throw ) ;
202 }
203
204 void G::IdentityUser::setEffectiveGroupTo( SignalSafe safe , Identity id )
205 {
206 id.setEffectiveGroup( safe ) ;
207 }
208 /// \file gidentity_unix.cpp
G::Identity::isRoot
bool isRoot() const
Returns true if the userid is zero.
Definition: gidentity_unix.cpp:132
G::SignalSafe
An empty structure that is used to indicate a signal-safe, reentrant implementation.
Definition: gsignalsafe.h:36
G::Identity::root
static Identity root()
Returns the superuser identity.
Definition: gidentity_unix.cpp:117
G::Identity::real
static Identity real()
Returns the calling process's real identity.
Definition: gidentity_unix.cpp:99
G::Identity::Identity
Identity(const std::string &login_name)
Constructor for the named identity.
Definition: gidentity_unix.cpp:46
G::Identity::invalid
static Identity invalid()
Returns an invalid identity.
Definition: gidentity_unix.cpp:107
gidentity.h
G::Identity
A combination of user-id and group-id, with a very low-level interface to the get/set/e/uid/gid funct...
Definition: gidentity.h:42
G::IdentityUser::setRealGroupTo
static void setRealGroupTo(Identity, bool do_throw=true)
Sets the real group id.
Definition: gidentity_unix.cpp:194
G::Identity::effective
static Identity effective()
Returns the current effective identity.
Definition: gidentity_unix.cpp:91
G::Identity::setRealUser
void setRealUser(bool do_throw=true)
Sets the real userid.
Definition: gidentity_unix.cpp:157
G::Identity::setRealGroup
void setRealGroup(bool do_throw=true)
Sets the real group id.
Definition: gidentity_unix.cpp:172
glimits.h
gassert.h
G::IdentityUser::setEffectiveUserTo
static void setEffectiveUserTo(Identity, bool do_throw=true)
Sets the effective userid.
Definition: gidentity_unix.cpp:184
G::Identity::setEffectiveGroup
void setEffectiveGroup(bool do_throw=true)
Sets the effective group id.
Definition: gidentity_unix.cpp:162
G::Identity::operator==
bool operator==(const Identity &) const
Comparison operator.
Definition: gidentity_unix.cpp:137
G::IdentityUser::setEffectiveGroupTo
static void setEffectiveGroupTo(Identity, bool do_throw=true)
Sets the effective group id.
Definition: gidentity_unix.cpp:199
G::Identity::str
std::string str() const
Returns a string representation.
Definition: gidentity_unix.cpp:125
G::IdentityUser::setRealUserTo
static void setRealUserTo(Identity, bool do_throw=true)
Sets the real userid.
Definition: gidentity_unix.cpp:179
G::Identity::operator!=
bool operator!=(const Identity &) const
Comparison operator.
Definition: gidentity_unix.cpp:142
G::Identity::setEffectiveUser
void setEffectiveUser(bool do_throw=true)
Sets the effective userid.
Definition: gidentity_unix.cpp:152