1 /** @file
2 
3   POSIX Capability related utilities.
4 
5   @section license License
6 
7   Licensed to the Apache Software Foundation (ASF) under one
8   or more contributor license agreements.  See the NOTICE file
9   distributed with this work for additional information
10   regarding copyright ownership.  The ASF licenses this file
11   to you under the Apache License, Version 2.0 (the
12   "License"); you may not use this file except in compliance
13   with the License.  You may obtain a copy of the License at
14 
15       http://www.apache.org/licenses/LICENSE-2.0
16 
17   Unless required by applicable law or agreed to in writing, software
18   distributed under the License is distributed on an "AS IS" BASIS,
19   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20   See the License for the specific language governing permissions and
21   limitations under the License.
22 
23  */
24 #pragma once
25 
26 #include <unistd.h>
27 #include <sys/types.h>
28 
29 #include "tscore/ink_mutex.h"
30 
31 /// Generate a debug message with the current capabilities for the process.
32 extern void DebugCapabilities(const char *tag ///< Debug message tag.
33 );
34 /// Set capabilities to persist across change of user id.
35 /// @return true on success
36 extern bool PreserveCapabilities();
37 /// Initialize and restrict the capabilities of a thread.
38 /// @return true on success
39 extern bool RestrictCapabilities();
40 /** Open a file, elevating privilege only if needed.
41 
42     @internal This is necessary because the CI machines run the regression tests
43     as a normal user, not as root, so attempts to get privilege fail even though
44     the @c open would succeed without elevation. So, try that first and ask for
45     elevation only on an explicit permission failure.
46 */
47 extern int elevating_open(const char *path, unsigned int flags, unsigned int fperms);
48 /// Open a file, elevating privilege only if needed.
49 extern int elevating_open(const char *path, unsigned int flags);
50 /// Open a file, elevating privilege only if needed.
51 extern FILE *elevating_fopen(const char *path, const char *mode);
52 
53 // chmod a file, elevating if necessary
54 extern int elevating_chmod(const char *path, int perm);
55 /// @c stat a file, elevating only if needed.
56 extern int elevating_stat(const char *path, struct stat *buff);
57 
58 /** Control generate of core file on crash.
59     @a flag sets whether core files are enabled on crash.
60     @return true on success
61  */
62 extern bool EnableCoreFile(bool flag ///< New enable state.
63 );
64 
65 void EnableDeathSignal(int signum);
66 
67 enum ImpersonationLevel {
68   IMPERSONATE_EFFECTIVE, // Set the effective credential set.
69   IMPERSONATE_PERMANENT  // Set the real credential (permanently).
70 };
71 
72 void ImpersonateUser(const char *user, ImpersonationLevel level);
73 void ImpersonateUserID(uid_t user, ImpersonationLevel level);
74 
75 class ElevateAccess
76 {
77 public:
78   typedef enum {
79     FILE_PRIVILEGE     = 0x1u, ///< Access filesystem objects with privilege
80     TRACE_PRIVILEGE    = 0x2u, ///< Trace other processes with privilege
81     LOW_PORT_PRIVILEGE = 0x4u, ///< Bind to privilege ports.
82     OWNER_PRIVILEGE    = 0x8u  ///< Bypass permission checks on operations that normally require
83                                ///  filesystem UID & process UID to match
84   } privilege_level;
85 
86   ElevateAccess(unsigned level = FILE_PRIVILEGE);
87   ~ElevateAccess();
88 
89   void elevate(unsigned level);
90   void demote();
91 
92 private:
93   bool elevated = false;
94   uid_t saved_uid;
95   unsigned level;
96 
97   /// Acquire the privileges marked in @a mask for this process.
98   void acquirePrivilege(unsigned priv_mask);
99   /// Restore the privilege set to the state before acquiring them.
100   void releasePrivilege();
101 #if !TS_USE_POSIX_CAP
102   static ink_mutex lock; // only one thread at a time can elevate
103 #else
104   void *cap_state; ///< Original capabilities state to restore.
105 #endif
106 };
107