E-MailRelay
groot.cpp
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2024 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
29G::Root * G::Root::m_this = nullptr ;
30bool G::Root::m_initialised = false ;
31bool G::Root::m_fixed_group = false ;
32G::Identity G::Root::m_nobody( G::Identity::invalid() ) ;
33G::Identity G::Root::m_startup( G::Identity::invalid() ) ;
34
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
46G::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_( e_saved ) ;
65 }
66}
67
68void G::Root::atExit() noexcept
69{
70 if( m_initialised )
71 Process::beSpecialForExit( SignalSafe() , m_startup ) ;
72}
73
74void G::Root::atExit( SignalSafe safe ) noexcept
75{
76 if( m_initialised )
77 Process::beSpecialForExit( safe , m_startup ) ;
78}
79
80void G::Root::init( const std::string & nobody , bool fixed_group )
81{
82 auto pair = Process::beOrdinaryAtStartup( nobody , !fixed_group ) ;
83 m_nobody = pair.first ;
84 m_startup = pair.second ;
85 m_fixed_group = fixed_group ;
86 m_initialised = true ;
87}
88
90{
91 return m_nobody ;
92}
93
94void G::Root::check()
95{
96 if( G::Test::enabled("root-scope") && m_this != nullptr )
97 G_WARNING( "G::Root::check: root control object exists at outer scope" ) ;
98}
99
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:45
static Identity invalid() noexcept
Returns an invalid identity.
static void beSpecialForExit(SignalSafe, Identity special_id) noexcept
A signal-safe version of beSpecial() that should only be used just before process exit.
static std::pair< Identity, Identity > beOrdinaryAtStartup(const std::string &nobody, bool change_group)
Revokes special privileges (root or suid) at startup, possibly including extra group membership,...
static void beSpecial(Identity special_id, bool change_group=true)
Re-acquires special privileges (either root or suid).
static void beOrdinary(Identity ordinary_id, bool change_group)
Releases special privileges.
static int errno_(const SignalSafe &=G::SignalSafe()) noexcept
Returns the process's current 'errno' value.
A class which acquires the process's special privileges on construction and releases them on destruct...
Definition: groot.h:52
static Identity nobody()
Returns the 'nobody' identity corresponding to the init() user name.
Definition: groot.cpp:89
Root()
Default constructor.
Definition: groot.cpp:35
static void init(const std::string &nobody, bool fixed_group=false)
< Destructor.
Definition: groot.cpp:80
static void atExit() noexcept
Re-acquires special privileges just before process exit.
Definition: groot.cpp:68
An empty structure that is used to indicate a signal-safe, reentrant implementation.
Definition: gsignalsafe.h:37
static bool enabled() noexcept
Returns true if test features are enabled.
Definition: gtest.cpp:79