Flow-IPC 1.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
28namespace ipc::util
29{
30
31// Types.
32
33/**
34 * A process's credentials (PID, UID, GID as of this writing).
35 *
36 * @see Opt_peer_process_credentials, a sub-class.
37 */
39{
40public:
41 // Constructors/destructor.
42
43 /// Default ctor: each value is initialized to zero or equivalent.
45
46 /**
47 * Ctor that sets the values explicitly.
48 * @param process_id_init
49 * See process_id().
50 * @param user_id_init
51 * See user_id().
52 * @param group_id_init
53 * See group_id().
54 */
55 explicit Process_credentials(process_id_t process_id_init, user_id_t user_id_init, group_id_t group_id_init);
56
57 /**
58 * Boring copy ctor.
59 * @param src
60 * Source object.
61 */
63
64 /// Methods.
65
66 /**
67 * Boring copy assignment.
68 * @param src
69 * Source object.
70 * @return `*this`.
71 */
73
74 /**
75 * The process ID (PID).
76 * @return See above.
77 */
79
80 /**
81 * The user ID (UID).
82 * @return See above.
83 */
84 user_id_t user_id() const;
85
86 /**
87 * The group user ID (GID).
88 * @return See above.
89 */
90 group_id_t group_id() const;
91
92 /**
93 * Obtains, from the OS, information as to the binary name via which process process_id() was started, per its
94 * command line, namely `argv[0]`. In simplified terms this is the executable of `*this` process; however
95 * there are important properties to consider about this information:
96 * - The process must be currently executing. If it is not, a no-such-file error is emitted.
97 * - The executable name is as-it-appeared on the command line; e.g., it might be a relative and/or
98 * un-normalized and/or a symlink. It is only the normalized, absolute path if that is how it was invoked.
99 * - It is possible (not common but not non-existent either) for a process to change its own command line
100 * upon execution; in this case there's almost no limit to what string might result.
101 * Note! Even an empty returned string is possible; and this is not emitted as an error.
102 *
103 * Because of these facts we feel it is, informally, best to use this information for one of these use cases:
104 * - logging;
105 * - verification against an expected value, especially when safety-checking against an expected policy
106 * (e.g., against session::App::m_exec_path) -- namely that, say, the given process was (1) an instance
107 * of a specific application and (2) was invoked via its normalized, absolute path.
108 *
109 * For these cases it should be reasonable to use.
110 *
111 * ### Implementation/rationale for it ###
112 * (Normally we omit impl details in public doc headers, but in this case the utility is low-level, and it may
113 * benefit you to know it.)
114 *
115 * This builds in Linux only; it reads /proc/(pid)/cmdline (if it exists) and obtains the first NUL-terminated
116 * entry there. This is `argv[0]`. `argv` space may be overwritten by the process, so it could be something
117 * other than the original invocation. Ignoring that, it'll be whatever the command line included; could be
118 * absolute or not, normalized or not, the symlink or not... and so on. The tool `ps` uses the same technique.
119 *
120 * One technique was considered: read Linux's /proc/(pid)/exe symlink which points to the absolute, normalized
121 * executable path actually invoked. That would have been perfect; however it appears to require
122 * admin privileges on our part, and we do not want to require this. On balance, since the original use case
123 * prompting this feature (session::App::m_exec_path verification) is acceptably served by the less-demanding
124 * /proc/.../cmdline method, we chose that.
125 *
126 * @param err_code
127 * See `flow::Error_code` docs for error reporting semantics. #Error_code generated:
128 * some system error code; but most likely no-such-file error of some kind, indicating the process
129 * is not executing (any longer?).
130 * @return The first entry -- the executable -- according to the process's command line (see above),
131 * if no #Error_code is emitted. If one *is* emitted, without an exception (`err_code` not null),
132 * empty string. Caution: If error is *not* emitted, returned value *might* still be empty,
133 * if the process overrode its own command line (see above).
134 */
135 std::string process_invoked_as(Error_code* err_code = 0) const;
136
137 /**
138 * Obtains the calling process's process_id(). This value will never change.
139 * @return See above.
140 */
142
143 /**
144 * Obtains the calling process's effective user_id(). This value can be changed via OS calls.
145 * @return See above.
146 */
147 static user_id_t own_user_id();
148
149 /**
150 * Obtains the calling process's effective group_id(). This value can be changed via OS calls.
151 * @return See above.
152 */
153 static group_id_t own_group_id();
154
155 /**
156 * Constructs and returns Process_credentials containing values pertaining to the calling process at this
157 * time. Note that certain values therein may become incorrect over time (see own_user_id(), own_group_id()).
158 *
159 * @return `Process_credentials(own_process_id(), own_user_id(), own_group_id())`.
160 */
162
163private:
164 // Data.
165
166 /// The raw data. By using Linux `ucred` directly, we can reuse this as base for Opt_peer_process_credentials.
167 ::ucred m_val;
168}; // class Process_credentials
169
170// Free functions: in *_fwd.hpp.
171
172} // 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 or 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)
Methods.
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).
std::string process_invoked_as(Error_code *err_code=0) const
Obtains, from the OS, information as to the binary name via which process process_id() was started,...
group_id_t group_id() const
The group user ID (GID).
Flow-IPC module containing miscellaneous general-use facilities that ubiquitously used by ~all Flow-I...
::pid_t process_id_t
Syntactic-sugary type for POSIX process ID (integer).
Definition: util_fwd.hpp:137
::gid_t group_id_t
Syntactic-sugary type for POSIX group ID (integer).
Definition: util_fwd.hpp:143
::uid_t user_id_t
Syntactic-sugary type for POSIX user ID (integer).
Definition: util_fwd.hpp:140
flow::Error_code Error_code
Short-hand for flow::Error_code which is very common.
Definition: common.hpp:297