E-MailRelay

groot.cpp
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2021 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 groot.cpp
19///
20
21#include "gdef.h"
22#include "groot.h"
23#include "gcleanup.h"
24#include "gtest.h"
25#include "gassert.h"
26#include "gprocess.h"
27#include "glog.h"
28
29 G::Root * G::Root::m_this = nullptr ;
30 bool G::Root::m_initialised = false ;
31 bool G::Root::m_fixed_group = false ;
32 G::Identity G::Root::m_nobody( G::Identity::invalid() ) ; // noexcept
33 G::Identity G::Root::m_startup( G::Identity::invalid() ) ; // noexcept
34
35 G::Root::Root() :
36 m_change_group(!m_fixed_group)
37{
38 check() ;
39 if( m_this == nullptr && m_initialised )
40 {
41 Process::beSpecial( m_startup , m_change_group ) ;
42 m_this = this ;
43 }
44}
45
46 G::Root::Root( bool change_group ) :
47 m_change_group(m_fixed_group?false:change_group)
48{
49 check() ;
50 if( m_this == nullptr && m_initialised )
51 {
52 Process::beSpecial( m_startup , m_change_group ) ;
53 m_this = this ;
54 }
55}
56
57G::Root::~Root() // NOLINT bugprone-exception-escape
58{
59 if( m_this == this && m_initialised )
60 {
61 m_this = nullptr ;
62 int e_saved = Process::errno_() ;
63 Process::beOrdinary( m_nobody , m_change_group ) ; // can throw - std::terminate is correct
64 Process::errno_( SignalSafe() , e_saved ) ;
65 }
66}
67
68 void G::Root::atExit() noexcept
69{
70 if( m_initialised )
71 Process::beSpecialForExit( SignalSafe() , m_startup ) ;
72}
73
74 void G::Root::atExit( SignalSafe safe ) noexcept
75{
76 if( m_initialised )
77 Process::beSpecialForExit( safe , m_startup ) ;
78}
79
80 void G::Root::init( const std::string & nobody , bool fixed_group )
81{
82 m_nobody = Identity( nobody ) ;
83 m_startup = Process::beOrdinaryAtStartup( m_nobody , !fixed_group ) ;
84 m_fixed_group = fixed_group ;
85 m_initialised = true ;
86}
87
88 G::Identity G::Root::nobody()
89{
90 return m_nobody ;
91}
92
93 void G::Root::check()
94{
95 if( G::Test::enabled("root-scope") && m_this != nullptr )
96 G_WARNING( "G::Root::check: root control object exists at outer scope" ) ;
97}
98
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:43
G::Identity::invalid
static Identity invalid() noexcept
Returns an invalid identity.
Definition: gidentity_unix.cpp:159
G::Process::beSpecialForExit
static void beSpecialForExit(SignalSafe, Identity special_id) noexcept
A signal-safe version of beSpecial() that should only be used just before process exit.
Definition: gprocess_unix.cpp:140
G::Process::beSpecial
static void beSpecial(Identity special_id, bool change_group=true)
Re-acquires special privileges (either root or suid).
Definition: gprocess_unix.cpp:135
G::Process::beOrdinary
static void beOrdinary(Identity ordinary_id, bool change_group)
Releases special privileges.
Definition: gprocess_unix.cpp:160
G::Process::errno_
static int errno_(const SignalSafe &=G::SignalSafe()) noexcept
Returns the process's current 'errno' value.
Definition: gprocess_unix.cpp:115
G::Process::beOrdinaryAtStartup
static Identity beOrdinaryAtStartup(Identity ordinary_id, bool change_group)
Revokes special privileges (root or suid), possibly including extra group membership.
Definition: gprocess_unix.cpp:145
G::Root
A class which acquires the process's special privileges on construction and releases them on destruct...
Definition: groot.h:52
G::Root::nobody
static Identity nobody()
Returns the 'nobody' identity corresponding to the init() user name.
Definition: groot.cpp:88
G::Root::Root
Root()
Default constructor.
Definition: groot.cpp:35
G::Root::init
static void init(const std::string &nobody, bool fixed_group=false)
< Desctructor.
Definition: groot.cpp:80
G::Root::atExit
static void atExit() noexcept
Re-acquires special privileges just before process exit.
Definition: groot.cpp:68
G::SignalSafe
An empty structure that is used to indicate a signal-safe, reentrant implementation.
Definition: gsignalsafe.h:37
G::Test::enabled
static bool enabled() noexcept
Returns true if test features are enabled.
Definition: gtest.cpp:79
gassert.h
gcleanup.h
glog.h
gprocess.h
groot.h
gtest.h