SETCRED(2)                FreeBSD System Calls Manual               SETCRED(2)

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.

     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.

     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:

     sc_uid                The ID to set the effective user to, if flag
                           SETCREDF_UID is specified.
     sc_ruid               The ID to set the real user to, if flag
                           SETCREDF_RUID is specified.
     sc_svuid              The ID to set the saved user to, if flag
                           SETCREDF_SVUID is specified.
     sc_gid                The ID to set the effective group to, if flag
                           SETCREDF_GID is specified.
     sc_rgid               The ID to set the real group to, if flag
                           SETCREDF_RGID is specified.
     sc_svgid              The ID to set the saved group to, if flag
                           SETCREDF_SVGID is specified.
     sc_supp_groups_nb     The size of array sc_supp_groups, if flag
                           SETCREDF_SUPP_GROUPS is 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 flag SETCREDF_SUPP_GROUPS is specified.
     sc_label              A pointer to a valid MAC label structure, e.g.,
                           built with the mac_from_text(3) function, if flag
                           SETCREDF_MAC_LABEL is specified.

     For forward compatibility and security reasons, it is recommended that
     users always initialize objects of type struct setcred with the provided
     initializer: SETCRED_INITIALIZER.

     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.

ERRORS

     The setcred() system call will fail if:

     [EINVAL]           Unrecognized flags were passed in flags, or the size
                        parameter does not match the size of struct setcred,
                        or the field sc_supp_group_nb has a value strictly
                        greater than {NGROUPS_MAX} (if flag
                        SETCREDF_SUPP_GROUPS was supplied), or the MAC label
                        pointed to by field sc_label is invalid (if flag
                        SETCREDF_MAC_LABEL was supplied).

     [EFAULT]           The wcred pointer, or pointers in fields
                        sc_supp_groups (if flag SETCREDF_SUPP_GROUPS was
                        supplied) or sc_label (if flag SETCREDF_MAC_LABEL was
                        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.

     [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 and
                        SETCREDF_MAC_LABEL has 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:

     o   All requested changes are performed atomically.
     o   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, while
         setcred() called with flag SETCREDF_UID does not.

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.

     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().

AUTHORS

     The setcred() system call and this manual page were written by Olivier
     Certner <olce.freebsd@certner.fr>.

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.

FreeBSD 15.1-STABLE-HBSD        August 29, 2025                     SETCRED(2)