seteuid(2)
π seteuid(2) β the "who am I really today" girlies π
okay bestie, we're in section 2 of the manual (System Calls Manual, that's the syscall girlies) and today's topic is seteuid and setegid. it's giving identity crisis but make it privileged. let's go π¦
β¨ NAME β¨
seteuid, setegid β set effective user or group ID
so like. they change your effective ID. yes there's a real one and an effective one and a saved one. yes it's a whole thing. we'll get there. π
π LIBRARY π
Standard C library (libc, -lc) β the classics, no cap.
πΈ SYNOPSIS πΈ
#include <unistd.h>
int seteuid(uid_t euid);
int setegid(gid_t egid);
look at them. two little functions. so much power. π
π Feature Test Macro Requirements for glibc (see feature_test_macros(7)) π
seteuid(), setegid():
_POSIX_C_SOURCE >= 200112L
|| /* glibc <= 2.19: */ _BSD_SOURCE
ngl if you're on old glibc (2.19 or earlier) you're gonna need _BSD_SOURCE to unlock these. vintage era behavior, we respect the elders π«Ά
π DESCRIPTION π
seteuid() sets the effective user ID of the calling process. that's the one the kernel actually checks when you try to do stuff.
here's the tea for unprivileged processes: they may only set the effective user ID to
- the real user ID,
- the effective user ID, or
- the saved set-user-ID.
that's it. that's the whole shortlist. no wandering off the menu, bestie.
Precisely the same holds for setegid() with "group" instead of "user". literally the exact same deal, just group flavored. π
π₯ RETURN VALUE π₯
On success, zero is returned. cute. clean. slay.
On error, -1 is returned, and errno is set to indicate the error.
Note: there are cases whereseteuid()can fail even when the caller is UID 0; it is a grave security error to omit checking for a failure return fromseteuid(). not me stressing about this but like. CHECK. YOUR. RETURN. VALUE. ππ serious business only.
π ERRORS π
EINVALβ The target user or group ID is not valid in this user namespace.EPERMβ In the case ofseteuid(): the calling process is not privileged (does not have theCAP_SETUIDcapability in its user namespace) andeuiddoes not match the current real user ID, current effective user ID, or current saved set-user-ID.
In the case of setegid(): the calling process is not privileged (does not have the CAP_SETGID capability in its user namespace) and egid does not match the current real group ID, current effective group ID, or current saved set-group-ID.
so basically, no capability + no match = permission denied, bestie. vibe check failed πβ
π VERSIONS π
Setting the effective user (group) ID to the saved set-user-ID (saved set-group-ID) is possible since Linux 1.1.37 (1.1.38). On an arbitrary system one should check _POSIX_SAVED_IDS.
Under glibc 2.0, seteuid(euid) is equivalent to setreuid(-1, euid) and hence may change the saved set-user-ID. Under glibc 2.1 and later, it is equivalent to setresuid(-1, euid, -1) and hence does not change the saved set-user-ID. Analogous remarks hold for setegid(), with the difference that the change in implementation from setregid(-1, egid) to setresgid(-1, egid, -1) occurred in glibc 2.2 or 2.3 (depending on the hardware architecture).
so like. old glibc was out here changing your saved ID as a side quest and modern glibc said "not today". glow up fr. β¨
According to POSIX.1, seteuid() (setegid()) need not permit euid (egid) to be the same value as the current effective user (group) ID, and some implementations do not permit this.
π§ C library/kernel differences π§
On Linux, seteuid() and setegid() are implemented as library functions that call, respectively, setresuid(2) and setresgid(2).
it's a wrapper. a cute little middleman. passing the message along π
β STANDARDS β
POSIX.1-2024. periodt.
π HISTORY π
POSIX.1-2001, 4.3BSD. ancient. iconic. still here.
π¦ SEE ALSO π¦
geteuid(2), setresuid(2), setreuid(2), setuid(2), capabilities(7), credentials(7), user_namespaces(7)
go read them, they're all part of the same lore arc i promise πβ¨
okay that's the whole page bestie!! this one's from Linux man-pages 6.20, dated 2026-02-08, and it's filed under seteuid(2). love that for us. go check your return values, stay hydrated, and never trust a -1 πππ«Ά
π¦ where this page comes from
- arch rolling: man-pages 6.20-1 Β· BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
- nixpkgs unstable: man-pages 6.20
- π the page's license: Linux-man-pages-copyleft
- Copyright 2001, Andries E. Brouwer <aeb@cwi.nl>
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms