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 /// \file gidentity.h
19 ///
20 
21 #ifndef G_IDENTITY_H
22 #define G_IDENTITY_H
23 
24 #include "gdef.h"
25 #include "gexception.h"
26 #include "gsignalsafe.h"
27 #include <string>
28 #include <iostream>
29 
30 /// \namespace G
31 namespace G
32 {
33 	class Identity ;
34 	class IdentityUser ;
35 }
36 
37 /// \class G::Identity
38 /// A very low-level interface to getpwnam() and the get/set/e/uid/gid functions.
39 /// \see G::Process, G::Root
40 ///
41 class G::Identity
42 {
43 public:
44 	G_EXCEPTION( NoSuchUser , "no such user" ) ;
45 	G_EXCEPTION( UidError , "cannot set uid" ) ;
46 	G_EXCEPTION( GidError , "cannot set gid" ) ;
47 
48 	explicit Identity( const std::string & login_name ) ;
49 		///< Constructor for the named identity.
50 		///< Throws if NoSuchUser.
51 
52 	static Identity effective() ;
53 		///< Returns the current effective identity.
54 
55 	static Identity real() ;
56 		///< Returns the calling process's real identity.
57 
58 	static Identity root() ;
59 		///< Returns the superuser identity.
60 
61 	static Identity invalid() ;
62 		///< Returns an invalid identity.
63 
64 	bool isRoot() const ;
65 		///< Returns true if the userid is zero.
66 
67 	std::string str() const ;
68 		///< Returns a string representation.
69 
70 	void setRealUser( bool do_throw = true ) ;
71 		///< Sets the real userid.
72 
73 	void setEffectiveUser( bool do_throw = true ) ;
74 		///< Sets the effective userid.
75 
76 	void setEffectiveUser( SignalSafe ) ;
77 		///< Sets the effective userid.
78 		///< A signal-safe, reentrant overload.
79 
80 	void setRealGroup( bool do_throw = true ) ;
81 		///< Sets the real group id.
82 
83 	void setEffectiveGroup( bool do_throw = true ) ;
84 		///< Sets the effective group id.
85 
86 	void setEffectiveGroup( SignalSafe ) ;
87 		///< Sets the effective group id.
88 		///< A signal-safe, reentrant overload.
89 
90 	bool operator==( const Identity & ) const ;
91 		///< Comparison operator.
92 
93 	bool operator!=( const Identity & ) const ;
94 		///< Comparison operator.
95 
96 private:
97 	Identity() ; // no throw
98 
99 private:
100 	uid_t m_uid ;
101 	gid_t m_gid ;
102 	HANDLE m_h ; // windows
103 } ;
104 
105 /// \class G::IdentityUser
106 /// A convenience class which, when used as a private base,
107 /// can improve readability when calling Identity 'set' methods.
108 ///
109 class G::IdentityUser
110 {
111 protected:
112 	static void setRealUserTo( Identity , bool do_throw = true ) ;
113 		///< Sets the real userid.
114 
115 	static void setEffectiveUserTo( Identity , bool do_throw = true ) ;
116 		///< Sets the effective userid.
117 
118 	static void setEffectiveUserTo( SignalSafe , Identity ) ;
119 		///< Sets the effective userid.
120 
121 	static void setRealGroupTo( Identity , bool do_throw = true ) ;
122 		///< Sets the real group id.
123 
124 	static void setEffectiveGroupTo( Identity , bool do_throw = true ) ;
125 		///< Sets the effective group id.
126 
127 	static void setEffectiveGroupTo( SignalSafe , Identity ) ;
128 		///< Sets the effective group id.
129 
130 private:
131 	IdentityUser() ; // not implemented
132 } ;
133 
134 /// \namespace G
135 namespace G
136 {
137 	inline
138 	std::ostream & operator<<( std::ostream & stream , const G::Identity & identity )
139 	{
140 		return stream << identity.str() ;
141 	}
142 }
143 
144 #endif
145 
146