SETREUID(3P)

πŸ’– SETREUID(3P) πŸ’–

okay bestie, so this one's from the POSIX Programmer's Manual (the SETREUID(3P) page, yes we're doing the fancy POSIX version today πŸ’…), and I'm gonna walk you through it like we're texting at 2am.

🌸 PROLOG 🌸

Real talk before we start, okay? This manual page is part of the POSIX Programmer's Manual. The Linux implementation of this interface may differ β€” so go consult the corresponding Linux manual page for the details on Linux behavior. Also possible: the interface might just straight up not be implemented on Linux. πŸ™ˆ Not every platform is gonna give you this, so vibe check your system first.


✨ NAME ✨

setreuid β€” set real and effective user IDs. it's giving identity crisis, but on purpose. πŸŽ€


πŸ¦‹ SYNOPSIS πŸ¦‹

#include <unistd.h>

int setreuid(uid_t ruid, uid_t euid);

πŸ’œ DESCRIPTION πŸ’œ

So the setreuid() function shall set the real and effective user IDs of the current process to the values you hand it in the ruid and euid arguments. That's it, that's the whole job. πŸ‘‘

But here's the cute loophole: if ruid or euid is -1, then the corresponding effective or real user ID of the current process shall be left unchanged. So -1 basically means "no thoughts, head empty, don't touch that one." 🫢

Now, permissions, because obviously there's a gate. A process with appropriate privileges can set either ID to any value. Main character energy, no restrictions. But an unprivileged process can only set the effective user ID if the euid argument is equal to either the real, effective, or saved user ID of the process. That's the whole guest list. no plus-ones. 😭

Next up, the saved set-user-ID lore: if the real user ID is being set (so ruid is not -1), or the effective user ID is being set to a value not equal to the real user ID, then the saved set-user-ID of the current process shall be set equal to the new effective user ID. It just follows along. lowkey clingy but it's for security.

And one of those "we're not telling you" moments: it is unspecified whether a process without appropriate privileges is permitted to change the real user ID to match the current effective user ID or saved set-user-ID of the process. So don't build your whole personality on that behavior, bestie. πŸ’€


🌈 RETURN VALUE 🌈

Slayed β†’ returns 0. Flopped β†’ returns -1 and errno gets set to indicate the error. That's the whole deal.


πŸ”₯ ERRORS πŸ”₯

The setreuid() function shall fail if:

  • EINVAL β€” The value of the ruid or euid argument is invalid or out-of-range. girl that number does not belong here. 🚫
  • EPERM β€” The current process does not have appropriate privileges, and either an attempt was made to change the effective user ID to a value other than the real user ID or the saved set-user-ID, or an attempt was made to change the real user ID to a value not permitted by the implementation. Basically: no privileges + trying something spicy = denied. πŸ’…
The following sections are informative. (So, like, they're lore, not law. still read them tho πŸ“–)

πŸŽ€ EXAMPLES πŸŽ€

Setting the Effective User ID to the Real User ID

This next example sets the effective user ID of the calling process to the real user ID, so that files created later will be owned by the current user. It also sets the saved set-user-ID to the real user ID β€” which means any future attempt to set the effective user ID back to its previous value will fail. no take-backs, periodt. 🧚

#include <unistd.h>
#include <sys/types.h>
...
setreuid(getuid(), getuid());
...

πŸ’« APPLICATION USAGE πŸ’«

None. literally nothing here. iconic of the standard honestly. πŸ™ˆ


πŸ‘‘ RATIONALE πŸ‘‘

Okay so story time: earlier versions of this standard did not specify whether the saved set-user-ID was affected by setreuid() calls. This version specifies common existing practice that constitutes an important security feature. πŸ›‘οΈ

Here's why it's a big deal: being able to set both the effective user ID and the saved set-user-ID to be the same as the real user ID means that any security weakness in code that's executed after that point cannot result in malicious code being executed with the previous effective user ID. So you drop the privileges and they're actually dropped. no sneaky comeback. ✨

Privileged applications could already do this using just setuid(), but for non-privileged applications the only standard method available is to use this feature of setreuid(). so yeah, this is the one. iykyk. 🫢


⭐ FUTURE DIRECTIONS ⭐

None. the future is, apparently, exactly like the present. πŸ’€


🌸 SEE ALSO 🌸

getegid(), geteuid(), getgid(), getuid(), setegid(), seteuid(), setgid(), setregid(), setuid()

The Base Definitions volume of POSIX.1‐2017, <unistd.h>


Portions of this text are reprinted and reproduced in electronic form from IEEE Std 1003.1-2017, Standard for Information Technology -- Portable Operating System Interface (POSIX), The Open Group Base Specifications Issue 7, 2018 Edition, Copyright (C) 2018 by the Institute of Electrical and Electronics Engineers, Inc and The Open Group.

In the event of any discrepancy between this version and the original IEEE and The Open Group Standard, the original IEEE and The Open Group Standard is the referee document. The original Standard can be obtained online at http://www.opengroup.org/unix/online.html .

Any typographical or formatting errors that appear in this page are most likely to have been introduced during the conversion of the source files to man page format. To report such errors, see https://www.kernel.org/doc/man-pages/reporting_bugs.html .


and that's the whole page, bestie!! πŸ¦‹ this one was brought to you by IEEE/The Open Group, 2017 β€” stay safe, stay privileged (appropriately), and remember: -1 means don't touch it. mwah πŸ’…πŸ’–

πŸ“¦ where this page comes from