in src/native/unix/native/jsvc-unix.c [368:415]
static int linuxset_user_group(const char *user, int uid, int gid)
{
int caps_set = 0;
if (user == NULL)
return 0;
/* set capabilities enough for binding port 80 setuid/getuid */
if (getuid() == 0) {
if (set_caps(CAPS_UID) != 0) {
log_debug("set_caps(CAPS_UID) failed for user '%s'", user);
if (set_caps(CAPS_UID_MIN) != 0) {
if (getuid() != uid) {
log_error("set_caps(CAPS_UID_MIN) failed for user '%s'", user);
return -1;
}
log_debug("set_caps(CAPS_UID_MIN) failed for user '%s'", user);
}
}
/* make sure they are kept after setuid */
if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) {
log_error("prctl failed in for user '%s'", user);
return -1;
}
caps_set = 1;
}
/* set setuid/getuid */
if (set_user_group(user, uid, gid) != 0) {
log_error("set_user_group failed for user '%s'", user);
return -1;
}
if (caps_set) {
/* set capability to binding port 80 read conf */
if (set_caps(CAPS_NO_UID) != 0) {
log_debug("set_caps(CAPS_NO_UID) failed for user '%s'", user);
if (set_caps(CAPS_NO_UID_MIN) != 0) {
if (getuid() != uid) {
log_error("set_caps(CAPS_NO_UID_MIN) failed for user '%s'", user);
return -1;
}
log_debug("set_caps(CAPS_NO_UID_MIN) failed for user '%s'", user);
}
}
}
return 0;
}