Esempio n. 1
0
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);
}
Esempio n. 2
0
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();
}
Esempio n. 3
0
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();
}
Esempio n. 4
0
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);
}
Esempio n. 5
0
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();
}
Esempio n. 6
0
/*
 *  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;
}
Esempio n. 7
0
void fr_suid_down_permanent(void)
{
	fr_set_dumpable();
}
Esempio n. 8
0
void fr_suid_down(void)
{
	fr_set_dumpable();
}
Esempio n. 9
0
void fr_suid_down_permanent(void)
{
	fr_set_dumpable(allow_core_dumps);
}
Esempio n. 10
0
void fr_suid_down(void)
{
	fr_set_dumpable(allow_core_dumps);
}
Esempio n. 11
0
/*
 *  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;
}
Esempio n. 12
0
/** 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);
}