SETCRED(2)
π SETCRED(2) β bestie, we're doing the setcred system call manual page β¨
okay so this is SETCRED(2), the page for setcred β and no cap, it's kind of the main character of credential syscalls. buckle up π
π¦ NAME
setcred β set current process credentials atomically
πΈ LIBRARY
Standard C Library (libc, -lc)
β¨ SYNOPSIS
#include <sys/ucred.h>
int
setcred(u_int flags, const struct setcred *wcred, size_t size);
π DESCRIPTION
The setcred() system call can set any combination of user-accessible credentials of the current process in an atomic manner. like, all at once, no messy in-between states. it's giving glow-up in one shot π
This system call is normally permitted only for processes having the ID of the super-user (0) as their effective user ID, or not at all if the sysctl(8) variable security.bsd.suser_enabled is zero or some active MAC policy specifically denies these processes. π€
Some MAC policies, such as mac_do(4), may also allow unprivileged users to call it successfully, possibly depending on the exact credentials transition requested β once again unless any active MAC policy specifically denies that. (so like, permission is a whole vibe check π)
The flags argument serves to indicate which process credentials should be changed by the call. Allowed flags are:
SETCREDF_UIDβ set the effective user ID.SETCREDF_RUIDβ set the real user ID.SETCREDF_SVUIDβ set the saved user ID.SETCREDF_GIDβ set the effective group ID.SETCREDF_RGIDβ set the real group ID.SETCREDF_SVGIDβ set the saved group ID.SETCREDF_SUPP_GROUPSβ set the supplementary group list.SETCREDF_MAC_LABELβ set the MAC label.
The struct setcred structure is currently defined as:
struct setcred {
uid_t sc_uid; /* effective user id */
uid_t sc_ruid; /* real user id */
uid_t sc_svuid; /* saved user id */
gid_t sc_gid; /* effective group id */
gid_t sc_rgid; /* real group id */
gid_t sc_svgid; /* saved group id */
u_int sc_pad; /* padding, unused */
u_int sc_supp_groups_nb; /* supplementary groups number */
gid_t *sc_supp_groups; /* supplementary groups */
struct mac *sc_label; /* MAC label */
};
Its fields are β ok take notes bestie, there are ten π:
sc_uidβ the ID to set the effective user to, if flagSETCREDF_UIDis specified.sc_ruidβ the ID to set the real user to, if flagSETCREDF_RUIDis specified.sc_svuidβ the ID to set the saved user to, if flagSETCREDF_SVUIDis specified.sc_gidβ the ID to set the effective group to, if flagSETCREDF_GIDis specified.sc_rgidβ the ID to set the real group to, if flagSETCREDF_RGIDis specified.sc_svgidβ the ID to set the saved group to, if flagSETCREDF_SVGIDis specified.sc_supp_groups_nbβ the size of arraysc_supp_groups, if flagSETCREDF_SUPP_GROUPSis specified. It must be less than or equal to{NGROUPS_MAX}. πsc_supp_groupsβ an array of IDs to set the supplementary groups to, if flagSETCREDF_SUPP_GROUPSis specified.sc_labelβ a pointer to a valid MAC label structure, e.g., built with themac_from_text(3)function, if flagSETCREDF_MAC_LABELis specified.
For forward compatibility and security reasons, it is recommended that users always initialize objects of typestruct setcredwith the provided initializer:SETCRED_INITIALIZER. do it. it's iconic and it protects you π«Ά
The size argument must be the size of the passed wcred structure.
π RETURN VALUES
Upon successful completion, the value 0 is returned; otherwise the value -1 is returned and the global variable errno is set to indicate the error.
like, 0 = slay, -1 = check errno, bestie π
π₯ ERRORS
The setcred() system call will fail if:
[EINVAL]β unrecognized flags were passed inflags, or thesizeparameter does not match the size ofstruct setcred, or the fieldsc_supp_group_nbhas a value strictly greater than{NGROUPS_MAX}(if flagSETCREDF_SUPP_GROUPSwas supplied), or the MAC label pointed to by fieldsc_labelis invalid (if flagSETCREDF_MAC_LABELwas supplied). π©[EFAULT]β thewcredpointer, or pointers in fieldssc_supp_groups(if flagSETCREDF_SUPP_GROUPSwas supplied) orsc_label(if flagSETCREDF_MAC_LABELwas supplied) point to invalid locations.[EPERM]β the user is not the super-user and/or the requested credentials transition is not allowed by the system or MAC modules. rude but valid π[EOPNOTSUPP]β some of the requested credentials have a type that the system does not support. This currently can occur only if the kernel has been compiled without MAC andSETCREDF_MAC_LABELhas been passed.
π SEE ALSO
issetugid(2), setregid(2), setreuid(2), setuid(2), mac_text(3), mac(4), mac_do(4), maclabel(7)
π STANDARDS
The setcred() system call is specific to FreeBSD. π
A call to setcred() usually changes process credentials that are listed by POSIX/SUS standards. The changed values then produce the effects with respect to the rest of the system that are described in these standards, as if these changes had resulted from calling standard or traditional credentials-setting functions. Currently, all flags but SETCREDF_MAC_LABEL lead to modifying standard credentials.
The only differences in using setcred() to change standard credentials instead of standard or traditional functions are:
- All requested changes are performed atomically.
- Only the super-user or an unprivileged user authorized by some MAC module can successfully call
setcred(), even if the standard system calls would have authorized any unprivileged user to effect the same changes. For example,seteuid()allows any unprivileged user to change the effective user ID to either the real or saved ones, whilesetcred()called with flagSETCREDF_UIDdoes not. (so like, way more exclusive, iykyk β¨)
π§ HISTORY
The setcred() system call appeared in FreeBSD 14.3.
Traditionally in UNIX, all credential changes beyond shuffles of effective, real and saved IDs have been done by setuid binaries that successively call multiple credentials-setting system calls and in a specific order. For example, to change all user IDs to that of some unprivileged user, setuid() must be called last so that all other credentials-changing calls can be performed successfully beforehand, as they require super-user privileges.
This piecewise approach causes such a process to transiently hold high privilege credentials that are neither the original nor necessarily the desired final ones. Besides opening a transition window where possible vulnerabilities could have catastrophic consequences, it makes it impossible for the kernel to enforce that only certain transitions of credentials are allowed. π¬ big yikes energy fr fr
The necessity of an atomic, global approach to changing credentials clearly appeared while working on extending mac_do(4) to allow rules to authorize only specific changes of primary or supplementary groups, which prompted the addition of setcred(). and that's the origin story π¦
π AUTHORS
The setcred() system call and this manual page were written by Olivier Certner <olce.freebsd@certner.fr>. thank you olivier, icon behavior π
β SECURITY CONSIDERATIONS
The same considerations as those of standard or traditional credentials-setting system calls apply to setcred(), except for the lack of atomicity of successive such calls.
In particular, please consult section SECURITY CONSIDERATIONS of the setuid(2) manual page about the absence of effect of changing standard credentials on already open files. π no cap, go read it.
okay that's the whole page bestie, you ate that π β¨
shoutout to the Debian package for this page, dated August 29, 2025 β footer says SETCRED(2) and we're done here. bye! ππ«Ά
π¦ where this page comes from
- freebsd 15.1: base 15.1
- π the page's license: BSD-2-Clause
- Copyright Β© 2024 The FreeBSD Foundation
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms