SD_BUS_CREDS_GET_PID(3)
πΈ NAME πΈ
Okay so this is the sd_bus_creds_get_pid(3) manual page, bestie, and the whole function squad below is here to retrieve fields from a credentials object. No cap, every single one is part of the team:
sd_bus_creds_get_pidsd_bus_creds_get_pidfd_dupsd_bus_creds_get_ppidsd_bus_creds_get_tidsd_bus_creds_get_uidsd_bus_creds_get_euidsd_bus_creds_get_suidsd_bus_creds_get_fsuidsd_bus_creds_get_gidsd_bus_creds_get_egidsd_bus_creds_get_sgidsd_bus_creds_get_fsgidsd_bus_creds_get_supplementary_gidssd_bus_creds_get_commsd_bus_creds_get_tid_commsd_bus_creds_get_exesd_bus_creds_get_cmdlinesd_bus_creds_get_cgroupsd_bus_creds_get_unitsd_bus_creds_get_slicesd_bus_creds_get_user_unitsd_bus_creds_get_user_slicesd_bus_creds_get_sessionsd_bus_creds_get_owner_uidsd_bus_creds_has_effective_capsd_bus_creds_has_permitted_capsd_bus_creds_has_inheritable_capsd_bus_creds_has_bounding_capsd_bus_creds_get_selinux_contextsd_bus_creds_get_audit_session_idsd_bus_creds_get_audit_login_uidsd_bus_creds_get_ttysd_bus_creds_get_unique_namesd_bus_creds_get_well_known_namessd_bus_creds_get_description
β¨ SYNOPSIS β¨
First the include, because she is required:
#include <systemd/sd-bus.h>
Then the signatures, exactly as they are:
int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid);
int sd_bus_creds_get_pidfd_dup(sd_bus_creds *c, int *ret_fd);
int sd_bus_creds_get_ppid(sd_bus_creds *c, pid_t *ppid);
int sd_bus_creds_get_tid(sd_bus_creds *c, pid_t *tid);
int sd_bus_creds_get_uid(sd_bus_creds *c, uid_t *uid);
int sd_bus_creds_get_euid(sd_bus_creds *c, uid_t *uid);
int sd_bus_creds_get_suid(sd_bus_creds *c, uid_t *uid);
int sd_bus_creds_get_fsuid(sd_bus_creds *c, uid_t *uid);
int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid);
int sd_bus_creds_get_egid(sd_bus_creds *c, gid_t *gid);
int sd_bus_creds_get_sgid(sd_bus_creds *c, gid_t *gid);
int sd_bus_creds_get_fsgid(sd_bus_creds *c, gid_t *gid);
int sd_bus_creds_get_supplementary_gids(sd_bus_creds *c,
const gid_t **gids);
int sd_bus_creds_get_comm(sd_bus_creds *c, const char **comm);
int sd_bus_creds_get_tid_comm(sd_bus_creds *c, const char **comm);
int sd_bus_creds_get_exe(sd_bus_creds *c, const char **exe);
int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline);
int sd_bus_creds_get_cgroup(sd_bus_creds *c, const char **cgroup);
int sd_bus_creds_get_unit(sd_bus_creds *c, const char **unit);
int sd_bus_creds_get_slice(sd_bus_creds *c, const char **slice);
int sd_bus_creds_get_user_unit(sd_bus_creds *c, const char **unit);
int sd_bus_creds_get_user_slice(sd_bus_creds *c, const char **slice);
int sd_bus_creds_get_session(sd_bus_creds *c, const char **slice);
int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid);
int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability);
int sd_bus_creds_has_permitted_cap(sd_bus_creds *c, int capability);
int sd_bus_creds_has_inheritable_cap(sd_bus_creds *c, int capability);
int sd_bus_creds_has_bounding_cap(sd_bus_creds *c, int capability);
int sd_bus_creds_get_selinux_context(sd_bus_creds *c,
const char **context);
int sd_bus_creds_get_audit_session_id(sd_bus_creds *c,
uint32_t *sessionid);
int sd_bus_creds_get_audit_login_uid(sd_bus_creds *c, uid_t *loginuid);
int sd_bus_creds_get_tty(sd_bus_creds *c, const char **tty);
int sd_bus_creds_get_unique_name(sd_bus_creds *c, const char **name);
int sd_bus_creds_get_well_known_names(sd_bus_creds *c, char ***name);
int sd_bus_creds_get_description(sd_bus_creds *c, const char **name);
π DESCRIPTION π
Okay bestie, these functions pull credential information out of an sd_bus_creds object. Credential objects can be created in a few different ways, and each way changes what the object is describing:
- with
sd_bus_creds_new_from_pid(3), where it describes the credentials of the process identified by the specified PID - with
sd_bus_get_name_creds(3), where it describes the credentials of a bus peer identified by the specified bus name - with
sd_bus_get_owner_creds(3), where it describes the credentials of the creator of a bus - with
sd_bus_message_get_creds(3), where it describes the credentials of the sender of the message
Not every credential field is part of every sd_bus_creds object, periodt. Use sd_bus_creds_get_mask(3) to determine the mask of fields that are actually available.
sd_bus_creds_get_pid() retrieves the PID (process identifier). Similarly, sd_bus_creds_get_ppid() retrieves the parent PID. Little note: PID 1 has no parent process, so in that case -ENXIO is returned.
sd_bus_creds_get_pidfd_dup() retrieves the PID file descriptor (pidfd), see pidfd_open(2) for details. The file descriptor is duplicated, so the caller has to close it β yes, that means you, bestie.
sd_bus_creds_get_tid() retrieves the TID (thread identifier).
sd_bus_creds_get_uid() retrieves the numeric UID (user identifier). Similarly, sd_bus_creds_get_euid() returns the effective UID, sd_bus_creds_get_suid() the saved UID, and sd_bus_creds_get_fsuid() the file system UID.
sd_bus_creds_get_gid() retrieves the numeric GID (group identifier). Similarly, sd_bus_creds_get_egid() returns the effective GID, sd_bus_creds_get_sgid() the saved GID, and sd_bus_creds_get_fsgid() the file system GID.
sd_bus_creds_get_supplementary_gids() retrieves the supplementary GIDs list.
sd_bus_creds_get_comm() retrieves the comm field β that's the truncated name of the executable, as stored in /proc/pid/comm.
sd_bus_creds_get_tid_comm() retrieves the comm field of the thread, as stored in /proc/pid/task/tid/comm.
sd_bus_creds_get_exe() retrieves the path to the program executable, as stored in the /proc/pid/exe link, but with the " (deleted)" suffix removed. Note that kernel threads do not have an executable path, in which case -ENXIO is returned. Also, this property should not be used for more than explanatory information β in particular, it should not be used for security-relevant decisions. Why? Because the executable might have been replaced or removed by the time the value can be processed. Moreover, the kernel exports this information in an ambiguous way, i.e. a deleted executable cannot be safely distinguished from one whose name suffix is " (deleted)". Big yikes, but that's the deal.
sd_bus_creds_get_cmdline() retrieves an array of command line arguments, as stored in /proc/pid/cmdline. Note that kernel threads do not have a command line, in which case -ENXIO is returned.
sd_bus_creds_get_cgroup() retrieves the control group path. See Control Groups v2[1].
sd_bus_creds_get_unit() retrieves the systemd unit name, in the system instance of systemd, that the process is a part of. See systemd.unit(5). For processes that are not part of a unit, it returns -ENXIO.
sd_bus_creds_get_user_unit() retrieves the systemd unit name, in the user instance of systemd, that the process is a part of. See systemd.unit(5). For processes that are not part of a user unit, it returns -ENXIO.
sd_bus_creds_get_slice() retrieves the systemd slice β a unit in the system instance of systemd β that the process is a part of. See systemd.slice(5). Similarly, sd_bus_creds_get_user_slice() retrieves the systemd slice of the process, in the user instance of systemd.
sd_bus_creds_get_session() retrieves the identifier of the login session that the process is a part of. Please note the login session may be limited to a stub process or two. User processes may instead be started from their systemd user manager, e.g. GUI applications started using DBus activation, as well as service processes which are shared between multiple logins of the same user. For processes that are not part of a session, it returns -ENXIO.
sd_bus_creds_get_owner_uid() retrieves the numeric UID (user identifier) of the user who owns the user unit or login session that the process is a part of. See systemd-logind.service(8). For processes that are not part of a user unit or session, it returns -ENXIO.
sd_bus_creds_has_effective_cap() checks whether the capability specified by capability was set in the effective capabilities mask. A positive return value means it was set, zero means it was not set, and a negative return value indicates an error. See capabilities(7) and the AmbientCapabilities= and CapabilityBoundingSet= settings in systemd.exec(5).
sd_bus_creds_has_permitted_cap() is similar to sd_bus_creds_has_effective_cap(), but it checks the permitted capabilities mask.
sd_bus_creds_has_inheritable_cap() is similar to sd_bus_creds_has_effective_cap(), but it checks the inheritable capabilities mask.
sd_bus_creds_has_bounding_cap() is similar to sd_bus_creds_has_effective_cap(), but it checks the bounding capabilities mask.
sd_bus_creds_get_selinux_context() retrieves the SELinux security context (label) of the process.
sd_bus_creds_get_audit_session_id() retrieves the audit session identifier of the process. It returns -ENXIO for processes that are not part of an audit session.
sd_bus_creds_get_audit_login_uid() retrieves the audit user login identifier β the identifier of the user who is "responsible" for the session. It returns -ENXIO for processes that are not part of an audit session.
sd_bus_creds_get_tty() retrieves the controlling TTY, without the prefixing "/dev/". It returns -ENXIO for processes that have no controlling TTY.
sd_bus_creds_get_unique_name() retrieves the D-Bus unique name. See The D-Bus specification[2].
sd_bus_creds_get_well_known_names() retrieves the set of D-Bus well-known names. See The D-Bus specification[2].
sd_bus_creds_get_description() retrieves a descriptive name of the bus connection of the peer. This name is useful to discern multiple bus connections by the same peer, and may be altered by the peer with the sd_bus_set_description(3) call.
All functions that take a const char** parameter will store the answer there as an address of a NUL-terminated string. It will be valid as long as c remains valid, and it should not be freed or modified by the caller.
All functions that take a char*** parameter will store the answer there as an address of an array of strings. Each individual string is NUL-terminated, and the array is NULL-terminated as a whole. It will be valid as long as c remains valid, and it should not be freed or modified by the caller.
On success, these calls return 0 or a positive integer. On failure, these calls return a negative errno-style error code. That's it, that's the vibe check π
πΈ Errors
ngl this is the part you actually screenshot and keep. Returned errors may indicate the following problems:
-ENODATAβ the given field is not available in the credentials objectc. it's giving "asked for something that isn't there" π«-ENXIOβ the given field is not specified for the described process or peer. Okay so this one shows up in a bunch of places, so let me just list them for you, bestie:- it'll come back from
sd_bus_creds_get_unit(),sd_bus_creds_get_slice(),sd_bus_creds_get_user_unit(),sd_bus_creds_get_user_slice(), andsd_bus_creds_get_session()if the process is not part of a systemd system unit, systemd user unit, systemd slice, or logind session - it'll come back from
sd_bus_creds_get_owner_uid()if the process is not part of a systemd user unit or logind session - it'll also come back from
sd_bus_creds_get_exe()andsd_bus_creds_get_cmdline()for kernel threads (since these are not started from an executable binary, nor have a command line β they literally never had an exe, icon behavior tbh π) - and from
sd_bus_creds_get_audit_session_id()andsd_bus_creds_get_audit_login_uid()when the process is not part of an audit session - and from
sd_bus_creds_get_tty()if the process has no controlling TTY
- it'll come back from
-EINVALβ you handed it aNULLpointer parameter. specified pointer parameter isNULL, that's the whole crime π-ENOMEMβ memory allocation failed. she ran out of room π
β¨ NOTES β¨
Functions described here are available as a shared library, which can be compiled against and linked to with the libsystemd pkg-config(1) file. yup, that's the one you link against, go off π
All functions listed here are thread-agnostic and only a single thread may operate on a given object at any given time. Different threads may access the same object at different times. Multiple independent objects may be used from different threads in parallel. so like β one object, one thread at a time, that's the rule. but different objects? go parallel, it's not a competition π β¨
The code described here uses getenv(3), which is declared to be not multi-thread-safe. This means that the code calling the functions described here must not call setenv(3) from a parallel thread. It is recommended to only do calls to setenv() from an early phase of the program when no other threads have been started.
β οΈ lowkey important: do your setenv() early, before any other threads exist. no cap, this is the "not multi-thread-safe" part doing its thing π
π¦ HISTORY π¦
okay so here's the lore drop, bestie, and I am not cutting any of it:
sd_bus_creds_get_pid(), sd_bus_creds_get_tid(), sd_bus_creds_get_gid(), sd_bus_creds_get_comm(), sd_bus_creds_get_tid_comm(), sd_bus_creds_get_exe(), sd_bus_creds_get_cmdline(), sd_bus_creds_get_cgroup(), sd_bus_creds_get_unit(), sd_bus_creds_get_user_unit(), sd_bus_creds_get_slice(), sd_bus_creds_get_session(), sd_bus_creds_get_owner_uid(), sd_bus_creds_has_effective_cap(), sd_bus_creds_has_permitted_cap(), sd_bus_creds_has_inheritable_cap(), sd_bus_creds_has_bounding_cap(), sd_bus_creds_get_selinux_context(), sd_bus_creds_get_audit_session_id(), sd_bus_creds_get_audit_login_uid(), sd_bus_creds_get_unique_name(), sd_bus_creds_get_well_known_names(), sd_bus_creds_get_ppid(), sd_bus_creds_get_uid(), sd_bus_creds_get_euid(), sd_bus_creds_get_suid(), sd_bus_creds_get_fsuid(), sd_bus_creds_get_egid(), sd_bus_creds_get_sgid(), sd_bus_creds_get_fsgid(), sd_bus_creds_get_supplementary_gids(), sd_bus_creds_get_tty(), sd_bus_creds_get_description(), and sd_bus_creds_get_user_slice() were added in version 221.
sd_bus_creds_get_pidfd_dup() was added in version 256. the new kid, main character energy π₯
π§ SEE ALSO π§
systemd(1), sd-bus(3), sd_bus_creds_new_from_pid(3), fork(2), execve(2), credentials(7), free(3), proc(5), systemd.journal-fields(7)
like, read these too, iykyk π«Ά
π NOTES <small>(yes there's a second NOTES section, no I'm not making the rules π)</small>
- Control Groups v2
https://docs.kernel.org/admin-guide/cgroup-v2.html - The D-Bus specification
https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-bus
aaaand that's the whole page, bestie!! πβ¨ this one's straight outta systemd 261.3 and it's the SD_BUS_CREDS_GET_PID(3) page β go forth and read your credentials, you're gonna slay ππ
π¦ where this page comes from
- ubuntu stonking: libsystemd-dev 261.3-0ubuntu3 Β· LGPL-2.1-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms