void fr_suid_down(void) { if (!uid_name) return; if (setuid(server_uid) < 0) { fprintf(stderr, "%s: Failed switching to uid %s: %s\n", progname, uid_name, fr_syserror(errno)); fr_exit_now(1); } fr_set_dumpable(allow_core_dumps); }
void fr_suid_down(void) { if (!uid_name) return; if (setuid(server_uid) < 0) { fprintf(stderr, "%s: Failed switching to uid %s: %s\n", progname, uid_name, strerror(errno)); _exit(1); } fr_set_dumpable(); }
void fr_suid_down_permanent(void) { if (!doing_setuid) return; if (setresuid(server_uid, server_uid, server_uid) < 0) { radlog(L_ERR, "Failed in permanent switch to uid %s: %s", uid_name, strerror(errno)); _exit(1); } if (geteuid() != server_uid) { radlog(L_ERR, "Switched to unknown uid"); _exit(1); } fr_set_dumpable(); }
void fr_suid_down_permanent(void) { if (!doing_setuid) return; if (setresuid(server_uid, server_uid, server_uid) < 0) { ERROR("Failed in permanent switch to uid %s: %s", uid_name, fr_syserror(errno)); fr_exit_now(1); } if (geteuid() != server_uid) { ERROR("Switched to unknown uid"); fr_exit_now(1); } fr_set_dumpable(allow_core_dumps); }
void fr_suid_down(void) { if (!doing_setuid) return; if (setresuid(-1, server_uid, geteuid()) < 0) { fprintf(stderr, "%s: Failed switching to uid %s: %s\n", progname, uid_name, strerror(errno)); _exit(1); } if (geteuid() != server_uid) { fprintf(stderr, "%s: Failed switching uid: UID is incorrect\n", progname); _exit(1); } fr_set_dumpable(); }
/* * Do chroot, if requested. * * Switch UID and GID to what is specified in the config file */ static int switch_users(CONF_SECTION *cs) { #ifdef HAVE_SYS_RESOURCE_H /* * Get the current maximum for core files. Do this * before anything else so as to ensure it's properly * initialized. */ if (getrlimit(RLIMIT_CORE, &core_limits) < 0) { radlog(L_ERR, "Failed to get current core limit: %s", strerror(errno)); return 0; } #endif /* * Don't do chroot/setuid/setgid if we're in debugging * as non-root. */ if (debug_flag && (getuid() != 0)) return 1; if (cf_section_parse(cs, NULL, bootstrap_config) < 0) { fprintf(stderr, "radiusd: Error: Failed to parse user/group information.\n"); return 0; } #ifdef HAVE_GRP_H /* Set GID. */ if (gid_name) { struct group *gr; gr = getgrnam(gid_name); if (gr == NULL) { fprintf(stderr, "%s: Cannot get ID for group %s: %s\n", progname, gid_name, strerror(errno)); return 0; } server_gid = gr->gr_gid; } else { server_gid = getgid(); } #endif #ifdef HAVE_PWD_H /* Set UID. */ if (uid_name) { struct passwd *pw; pw = getpwnam(uid_name); if (pw == NULL) { fprintf(stderr, "%s: Cannot get passwd entry for user %s: %s\n", progname, uid_name, strerror(errno)); return 0; } if (getuid() == pw->pw_uid) { uid_name = NULL; } else { server_uid = pw->pw_uid; #ifdef HAVE_INITGROUPS if (initgroups(uid_name, server_gid) < 0) { fprintf(stderr, "%s: Cannot initialize supplementary group list for user %s: %s\n", progname, uid_name, strerror(errno)); return 0; } #endif } } else { server_uid = getuid(); } #endif if (chroot_dir) { if (chroot(chroot_dir) < 0) { fprintf(stderr, "%s: Failed to perform chroot %s: %s", progname, chroot_dir, strerror(errno)); return 0; } /* * Note that we leave chdir alone. It may be * OUTSIDE of the root. This allows us to read * the configuration from "-d ./etc/raddb", with * the chroot as "./chroot/" for example. After * the server has been loaded, it does a "cd * ${logdir}" below, so that core files (if any) * go to a logging directory. * * This also allows the configuration of the * server to be outside of the chroot. If the * server is statically linked, then the only * things needed inside of the chroot are the * logging directories. */ } #ifdef HAVE_GRP_H /* Set GID. */ if (gid_name && (setgid(server_gid) < 0)) { fprintf(stderr, "%s: Failed setting group to %s: %s", progname, gid_name, strerror(errno)); return 0; } #endif #ifdef HAVE_SETUID /* * Just before losing root permissions, ensure that the * log files have the correct owner && group. * * We have to do this because the log file MAY have been * specified on the command-line. */ if (uid_name || gid_name) { if ((mainconfig.radlog_dest == RADLOG_FILES) && (mainconfig.radlog_fd < 0)) { mainconfig.radlog_fd = open(mainconfig.log_file, O_WRONLY | O_APPEND | O_CREAT, 0640); if (mainconfig.radlog_fd < 0) { fprintf(stderr, "radiusd: Failed to open log file %s: %s\n", mainconfig.log_file, strerror(errno)); return 0; } if (chown(mainconfig.log_file, server_uid, server_gid) < 0) { fprintf(stderr, "%s: Cannot change ownership of log file %s: %s\n", progname, mainconfig.log_file, strerror(errno)); return 0; } } } if (uid_name) { doing_setuid = TRUE; fr_suid_down(); } #endif /* * This also clears the dumpable flag if core dumps * aren't allowed. */ fr_set_dumpable(); if (allow_core_dumps) { radlog(L_INFO, "Core dumps are enabled."); } return 1; }
void fr_suid_down_permanent(void) { fr_set_dumpable(); }
void fr_suid_down(void) { fr_set_dumpable(); }
void fr_suid_down_permanent(void) { fr_set_dumpable(allow_core_dumps); }
void fr_suid_down(void) { fr_set_dumpable(allow_core_dumps); }
/* * Do chroot, if requested. * * Switch UID and GID to what is specified in the config file */ static int switch_users(CONF_SECTION *cs) { bool do_suid = false; bool do_sgid = false; /* * Get the current maximum for core files. Do this * before anything else so as to ensure it's properly * initialized. */ if (fr_set_dumpable_init() < 0) { fr_perror("%s", main_config.name); return 0; } /* * Don't do chroot/setuid/setgid if we're in debugging * as non-root. */ if (rad_debug_lvl && (getuid() != 0)) return 1; if (cf_section_parse(cs, NULL, bootstrap_config) < 0) { fprintf(stderr, "%s: Error: Failed to parse user/group information.\n", main_config.name); return 0; } #ifdef HAVE_GRP_H /* * Get the correct GID for the server. */ server_gid = getgid(); if (gid_name) { struct group *gr; gr = getgrnam(gid_name); if (!gr) { fprintf(stderr, "%s: Cannot get ID for group %s: %s\n", main_config.name, gid_name, fr_syserror(errno)); return 0; } if (server_gid != gr->gr_gid) { server_gid = gr->gr_gid; do_sgid = true; } } #endif /* * Get the correct UID for the server. */ server_uid = getuid(); if (uid_name) { struct passwd *user; if (rad_getpwnam(cs, &user, uid_name) < 0) { fprintf(stderr, "%s: Cannot get passwd entry for user %s: %s\n", main_config.name, uid_name, fr_strerror()); return 0; } /* * We're not the correct user. Go set that. */ if (server_uid != user->pw_uid) { server_uid = user->pw_uid; do_suid = true; #ifdef HAVE_INITGROUPS if (initgroups(uid_name, server_gid) < 0) { fprintf(stderr, "%s: Cannot initialize supplementary group list for user %s: %s\n", main_config.name, uid_name, fr_syserror(errno)); talloc_free(user); return 0; } #endif } talloc_free(user); } /* * Do chroot BEFORE changing UIDs. */ if (chroot_dir) { if (chroot(chroot_dir) < 0) { fprintf(stderr, "%s: Failed to perform chroot %s: %s", main_config.name, chroot_dir, fr_syserror(errno)); return 0; } /* * Note that we leave chdir alone. It may be * OUTSIDE of the root. This allows us to read * the configuration from "-d ./etc/raddb", with * the chroot as "./chroot/" for example. After * the server has been loaded, it does a "cd * ${logdir}" below, so that core files (if any) * go to a logging directory. * * This also allows the configuration of the * server to be outside of the chroot. If the * server is statically linked, then the only * things needed inside of the chroot are the * logging directories. */ } #ifdef HAVE_GRP_H /* * Set the GID. Don't bother checking it. */ if (do_sgid) { if (setgid(server_gid) < 0){ fprintf(stderr, "%s: Failed setting group to %s: %s", main_config.name, gid_name, fr_syserror(errno)); return 0; } } #endif /* * The directories for PID files and logs must exist. We * need to create them if we're told to write files to * those directories. * * Because this creation is new in 3.0.9, it's a soft * fail. * */ if (main_config.write_pid) { char *my_dir; my_dir = talloc_strdup(NULL, run_dir); if (rad_mkdir(my_dir, 0750, server_uid, server_gid) < 0) { DEBUG("Failed to create run_dir %s: %s", my_dir, strerror(errno)); } talloc_free(my_dir); } if (default_log.dst == L_DST_FILES) { char *my_dir; my_dir = talloc_strdup(NULL, radlog_dir); if (rad_mkdir(my_dir, 0750, server_uid, server_gid) < 0) { DEBUG("Failed to create logdir %s: %s", my_dir, strerror(errno)); } talloc_free(my_dir); } /* * If we don't already have a log file open, open one * now. We may not have been logging anything yet. The * server normally starts up fairly quietly. */ if ((default_log.dst == L_DST_FILES) && (default_log.fd < 0)) { default_log.fd = open(main_config.log_file, O_WRONLY | O_APPEND | O_CREAT, 0640); if (default_log.fd < 0) { fprintf(stderr, "%s: Failed to open log file %s: %s\n", main_config.name, main_config.log_file, fr_syserror(errno)); return 0; } } /* * If we need to change UID, ensure that the log files * have the correct owner && group. * * We have to do this because some log files MAY already * have been written as root. We need to change them to * have the correct ownership before proceeding. */ if ((do_suid || do_sgid) && (default_log.dst == L_DST_FILES)) { if (fchown(default_log.fd, server_uid, server_gid) < 0) { fprintf(stderr, "%s: Cannot change ownership of log file %s: %s\n", main_config.name, main_config.log_file, fr_syserror(errno)); return 0; } } /* * Once we're done with all of the privileged work, * permanently change the UID. */ if (do_suid) { rad_suid_set_down_uid(server_uid); rad_suid_down(); } /* * This also clears the dumpable flag if core dumps * aren't allowed. */ if (fr_set_dumpable(allow_core_dumps) < 0) { ERROR("%s", fr_strerror()); } if (allow_core_dumps) { INFO("Core dumps are enabled"); } return 1; }
/** Reset dumpable state to previously configured value * * Needed after suid up/down * * @return 0 on success, else -1 on failure. */ int fr_reset_dumpable(void) { return fr_set_dumpable(dump_core); }