Flow-IPC 3.0.0
Flow-IPC project: Full implementation reference.
process_credentials.hpp
Go to the documentation of this file.
1/* Flow-IPC: Core
2 * Copyright 2023 Akamai Technologies, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the
5 * "License"); you may not use this file except in
6 * compliance with the License. You may obtain a copy
7 * of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in
12 * writing, software distributed under the License is
13 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
14 * CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing
16 * permissions and limitations under the License. */
17
18/// @file
19#pragma once
20
21#ifndef _GNU_SOURCE
22# define _GNU_SOURCE // Needed at least to get access to `struct ::ucred` (Linux).
23#endif
24
25#include "ipc/util/util_fwd.hpp"
27#include <flow/common.hpp>
28#include <string>
29#include <sys/socket.h>
30
31#ifndef FLOW_OS_LINUX
32static_assert(false,
33 "Not tested outside Linux; look into it when porting this module. Might be fine in POSIXy OS at least.");
34#endif
35
36namespace ipc::util
37{
38
39// Types.
40
41/**
42 * A process's credentials (PID, UID, GID as of this writing).
43 *
44 * @see Opt_peer_process_credentials, a sub-class.
45 */
47{
48public:
49 // Constructors/destructor.
50
51 /// Default ctor: each value is initialized to zero/OS-appropriate equivalent.
53
54 /**
55 * Ctor that sets the values explicitly.
56 * @param process_id_init
57 * See process_id().
58 * @param user_id_init
59 * See user_id().
60 * @param group_id_init
61 * See group_id().
62 */
63 explicit Process_credentials(process_id_t process_id_init, user_id_t user_id_init, group_id_t group_id_init);
64
65 /**
66 * Boring copy ctor.
67 * @param src
68 * Source object.
69 */
71
72 // Methods.
73
74 /**
75 * Boring copy assignment.
76 * @param src
77 * Source object.
78 * @return `*this`.
79 */
81
82 /**
83 * The process ID (PID).
84 * @return See above.
85 */
87
88 /**
89 * The user ID (UID).
90 * @return See above.
91 */
92 user_id_t user_id() const;
93
94 /**
95 * The group ID (GID).
96 * @return See above.
97 */
98 group_id_t group_id() const;
99
100 /**
101 * Obtains, from the OS, information as to the binary name via which process process_id() was started, per its
102 * command line, namely `argv[0]`. In simplified terms this is the executable of `*this` process; however
103 * there are important properties to consider about this information:
104 * - The process must be currently executing. If it is not, a no-such-file error is emitted.
105 * - The executable name is as-it-appeared on the command line; e.g., it might be a relative and/or
106 * un-normalized path and/or a symlink. It is only the normalized, absolute path, if that is how it was invoked.
107 * - It is possible (not common but not non-existent either) for a process to change its own command line
108 * upon execution; in this case there's almost no limit to what string might result.
109 * Note! Even an empty returned string is possible; and this is not emitted as an error.
110 *
111 * Because of these facts we feel it is, informally, best to use this information for one of these use cases:
112 * - logging;
113 * - verification against an expected value, especially when safety-checking against an expected policy
114 * (e.g., against session::App::m_exec_path) -- namely that, say, the given process was (1) an instance
115 * of a specific application and (2) was invoked via its normalized, absolute path.
116 *
117 * For these cases it should be reasonable to use.
118 *
119 * ### Implementation/rationale for it ###
120 * (Normally we omit impl details in public doc headers, but in this case the utility is low-level, and it may
121 * benefit you to know it.)
122 *
123 * This builds in Linux only; it reads `/proc/(pid)/cmdline` (if it exists) and obtains the first NUL-terminated
124 * entry there. This is `argv[0]`. `argv` space may be overwritten by the process, so it could be something
125 * other than the original invocation. Ignoring that, it'll be whatever the command line included; could be
126 * absolute or not, normalized or not, the symlink or not... and so on. The tool `ps` uses the same technique.
127 *
128 * One technique was considered: read Linux's `/proc/(pid)/exe` symlink which points to the absolute, normalized
129 * executable path actually invoked. That would have been perfect; however reading it requires ptrace-level access
130 * to the target process (in practice: same user, or admin privileges on our part), and we do not want to require
131 * this. On balance, since the original use case prompting this feature (session::App::m_exec_path verification)
132 * is acceptably served by the less-demanding `/proc/.../cmdline` method, we chose that.
133 *
134 * @param err_code
135 * See `flow::Error_code` docs for error reporting semantics. #Error_code generated:
136 * some system error code; but most likely no-such-file error of some kind, indicating the process
137 * is not executing (any longer?).
138 * @return The first entry -- the executable -- according to the process's command line (see above),
139 * if no #Error_code is emitted. If one *is* emitted, without an exception (`err_code` not null),
140 * empty string. Caution: If error is *not* emitted, returned value *might* still be empty,
141 * if the process overrode its own command line (see above).
142 */
143 std::string process_invoked_as(Error_code* err_code = nullptr) const;
144
145 /**
146 * Obtains the calling process's process_id(). This value will never change.
147 * @return See above.
148 */
150
151 /**
152 * Obtains the calling process's effective user_id(). This value can be changed via OS calls.
153 * @return See above.
154 */
155 static user_id_t own_user_id();
156
157 /**
158 * Obtains the calling process's effective group_id(). This value can be changed via OS calls.
159 * @return See above.
160 */
161 static group_id_t own_group_id();
162
163 /**
164 * Constructs and returns Process_credentials containing values pertaining to the calling process at this
165 * time. Note that certain values therein may become incorrect over time (see own_user_id(), own_group_id()).
166 *
167 * @return `Process_credentials(own_process_id(), own_user_id(), own_group_id())`.
168 */
170
171private:
172 // Data.
173
174 /// The raw data. By using Linux `ucred` directly, we can reuse this as base for Opt_peer_process_credentials.
175 ::ucred m_val;
176}; // class Process_credentials
177
178// Free functions: in *_fwd.hpp.
179
180// Constants.
181
182/// A (default-cted) Process_credentials. May be useful for functions returning `const Process_credentials&`.
184
185} // namespace ipc::util
A process's credentials (PID, UID, GID as of this writing).
process_id_t process_id() const
The process ID (PID).
static process_id_t own_process_id()
Obtains the calling process's process_id().
Process_credentials()
Default ctor: each value is initialized to zero/OS-appropriate equivalent.
Process_credentials(const Process_credentials &src)
Boring copy ctor.
static Process_credentials own_process_credentials()
Constructs and returns Process_credentials containing values pertaining to the calling process at thi...
::ucred m_val
The raw data. By using Linux ucred directly, we can reuse this as base for Opt_peer_process_credentia...
Process_credentials & operator=(const Process_credentials &src)
Boring copy assignment.
std::string process_invoked_as(Error_code *err_code=nullptr) const
Obtains, from the OS, information as to the binary name via which process process_id() was started,...
static user_id_t own_user_id()
Obtains the calling process's effective user_id().
static group_id_t own_group_id()
Obtains the calling process's effective group_id().
user_id_t user_id() const
The user ID (UID).
group_id_t group_id() const
The group ID (GID).
Flow-IPC module containing miscellaneous general-use facilities that are ubiquitously used by ~all Fl...
Definition: util.cpp:31
::pid_t process_id_t
Syntactic-sugary type for POSIX process ID (integer).
Definition: util_fwd.hpp:140
::gid_t group_id_t
Syntactic-sugary type for POSIX group ID (integer).
Definition: util_fwd.hpp:146
::uid_t user_id_t
Syntactic-sugary type for POSIX user ID (integer).
Definition: util_fwd.hpp:143
const Process_credentials NULL_PROCESS_CREDENTIALS
A (default-cted) Process_credentials. May be useful for functions returning const Process_credentials...
flow::Error_code Error_code
Short-hand for flow::Error_code which is very common.
Definition: common.hpp:313