📄 mainconfig.c
字号:
if (pwent == NULL) /* uh oh! */ return(1); if (chown(radlog_dir, pwent->pw_uid, -1) != 0) return(1);#endif return(0);}/* * Switch UID and GID to what is specified in the config file */static int switch_users(void){ int did_setuid = FALSE;#ifdef HAVE_SYS_RESOURCE_H struct rlimit core_limits;#endif#ifdef HAVE_GRP_H /* Set GID. */ if (gid_name != NULL) { struct group *gr; gr = getgrnam(gid_name); if (gr == NULL) { if (errno == ENOMEM) { radlog(L_ERR, "Cannot switch to Group %s: out of memory", gid_name); } else { radlog(L_ERR, "Cannot switch group; %s doesn't exist", gid_name); } return 0; } server_gid = gr->gr_gid; if (setgid(server_gid) < 0) { radlog(L_ERR, "Failed setting Group to %s: %s", gid_name, strerror(errno)); return 0; } } else { server_gid = getgid(); }#endif#ifdef HAVE_PWD_H /* Set UID. */ if (uid_name != NULL) { struct passwd *pw; pw = getpwnam(uid_name); if (pw == NULL) { if (errno == ENOMEM) { radlog(L_ERR, "Cannot switch to User %s: out of memory", uid_name); } else { radlog(L_ERR, "Cannot switch user; %s doesn't exist", uid_name); } return 0; } server_uid = pw->pw_uid;#ifdef HAVE_INITGROUPS if (initgroups(uid_name, server_gid) < 0) { if (errno != EPERM) { radlog(L_ERR, "Failed setting supplementary groups for User %s: %s", uid_name, strerror(errno)); return 0; } }#endif if (setuid(server_uid) < 0) { radlog(L_ERR, "Failed setting User to %s: %s", uid_name, strerror(errno)); return 0; } /* * Now core dumps are disabled on most secure systems. */ did_setuid = TRUE; }#endif#ifdef HAVE_SYS_RESOURCE_H /* Get the current maximum for core files. */ if (getrlimit(RLIMIT_CORE, &core_limits) < 0) { radlog(L_ERR, "Failed to get current core limit: %s", strerror(errno)); return 0; }#endif /* * Core dumps are allowed if we're in debug mode, OR * we've allowed them, OR we did a setuid (which turns * core dumps off). * * Otherwise, disable core dumps for security. * */ if (!(debug_flag || allow_core_dumps || did_setuid)) {#ifdef HAVE_SYS_RESOURCE_H struct rlimit no_core; no_core.rlim_cur = 0; no_core.rlim_max = 0; if (setrlimit(RLIMIT_CORE, &no_core) < 0) { radlog(L_ERR, "Failed disabling core dumps: %s", strerror(errno)); return 0; }#endif /* * Otherwise, re-enable core dumps if we're * running as a daemon, AND core dumps are * allowed, AND we changed UID's. */ } else if ((debug_flag == 0) && allow_core_dumps && did_setuid) { /* * Set the dumpable flag. */#ifdef HAVE_SYS_PRCTL_H#ifdef PR_SET_DUMPABLE if (prctl(PR_SET_DUMPABLE, 1) < 0) { radlog(L_ERR,"Cannot enable core dumps: prctl(PR_SET_DUMPABLE) failed: '%s'", strerror(errno)); }#endif#endif /* * Reset the core dump limits again, just to * double check that they haven't changed. */#ifdef HAVE_SYS_RESOURCE_H if (setrlimit(RLIMIT_CORE, &core_limits) < 0) { radlog(L_ERR, "Cannot update core dump limit: %s", strerror(errno)); return 0; }#endif radlog(L_INFO, "Core dumps are enabled."); } /* * Else we're debugging (so core dumps are enabled) * OR we're not debugging, AND "allow_core_dumps == FALSE", * OR we're not debugging, AND core dumps are allowed, * BUT we didn't call setuid, so we haven't changed the * core dump capabilities inherited from the parent shell. */#if defined(HAVE_PWD_H) && defined(HAVE_GRP_H) /* * We've probably written to the log file already as * root.root, so if we have switched users, we've got to * update the ownership of the file. */ if ((debug_flag == 0) && (mainconfig.radlog_dest == RADLOG_FILES) && (mainconfig.log_file != NULL)) { chown(mainconfig.log_file, server_uid, server_gid); }#endif return 1;}static const FR_NAME_NUMBER str2dest[] = { { "null", RADLOG_NULL }, { "files", RADLOG_FILES }, { "syslog", RADLOG_SYSLOG }, { "stdout", RADLOG_STDOUT }, { "stderr", RADLOG_STDERR }, { NULL, RADLOG_NUM_DEST }};/* * Read config files. * * This function can ONLY be called from the main server process. */int read_mainconfig(int reload){ const char *p = NULL; static int old_debug_level = -1; CONF_PAIR *cp; CONF_SECTION *cs; struct stat statbuf; char buffer[1024]; if (stat(radius_dir, &statbuf) < 0) { radlog(L_ERR, "Errors reading %s: %s", radius_dir, strerror(errno)); return -1; }#ifdef S_IWOTH if ((statbuf.st_mode & S_IWOTH) != 0) { radlog(L_ERR, "Configuration directory %s is globally writable. Refusing to start due to insecure configuration.", radius_dir); return -1; }#endif#ifdef S_IROTH if (0 && (statbuf.st_mode & S_IROTH) != 0) { radlog(L_ERR, "Configuration directory %s is globally readable. Refusing to start due to insecure configuration.", radius_dir); return -1; }#endif if (!reload) { radlog(L_INFO, "Starting - reading configuration files ..."); } else { radlog(L_INFO, "Reloading - reading configuration files..."); } /* Read the configuration file */ snprintf(buffer, sizeof(buffer), "%.200s/%.50s.conf", radius_dir, mainconfig.name); if ((cs = cf_file_read(buffer)) == NULL) { radlog(L_ERR, "Errors reading %s", buffer); return -1; } /* * Don't over-ride a destination set on the command-line. */ if (mainconfig.radlog_dest != RADLOG_NULL) goto read_dict; /* * Debug flag 1 MAY go to files. * Debug flag 2 ALWAYS goes to stdout * * Parse the log{} section before printing anything else. * All messages before this MUST be errors, which log.c * will print to stderr. */ if (debug_flag < 2) { if (cf_section_parse(cs, NULL, serverlog_config) < 0) { fprintf(stderr, "radiusd: Error: Failed to parse log{} section.\n"); cf_section_free(&cs); return -1; } if (!radlog_dest) { fprintf(stderr, "radiusd: Error: No log destination specified.\n"); cf_section_free(&cs); return -1; } mainconfig.radlog_dest = fr_str2int(str2dest, radlog_dest, RADLOG_NUM_DEST); if (mainconfig.radlog_dest == RADLOG_NUM_DEST) { fprintf(stderr, "radiusd: Error: Unknown log_destination %s\n", radlog_dest); cf_section_free(&cs); return -1; } if (mainconfig.radlog_dest == RADLOG_SYSLOG) { /* * Make sure syslog_facility isn't NULL * before using it */ if (!syslog_facility) { fprintf(stderr, "radiusd: Error: Syslog chosen but no facility was specified\n"); cf_section_free(&cs); return -1; } mainconfig.syslog_facility = fr_str2int(str2fac, syslog_facility, -1); if (mainconfig.syslog_facility < 0) { fprintf(stderr, "radiusd: Error: Unknown syslog_facility %s\n", syslog_facility); cf_section_free(&cs); return -1; } } } else if (mainconfig.radlog_dest != RADLOG_NULL) { mainconfig.radlog_dest = RADLOG_STDOUT; mainconfig.radlog_fd = STDOUT_FILENO; } read_dict: /* Initialize the dictionary */ cp = cf_pair_find(cs, "dictionary"); if (cp) p = cf_pair_value(cp); if (!p) p = radius_dir; DEBUG2("including dictionary file %s/%s", p, RADIUS_DICTIONARY); if (dict_init(p, RADIUS_DICTIONARY) != 0) { radlog(L_ERR, "Errors reading dictionary: %s", librad_errstr); return -1; } /* * This allows us to figure out where, relative to * radiusd.conf, the other configuration files exist. */ cf_section_parse(cs, NULL, server_config); /* * Free the old configuration items, and replace them * with the new ones. * * Note that where possible, we do atomic switch-overs, * to ensure that the pointers are always valid. */ cf_section_free(&mainconfig.config); mainconfig.config = cs; clients_parse_section(cs); DEBUG2("%s: #### Loading Realms and Home Servers ####", mainconfig.name); if (!realms_init(cs)) { return -1; } /* * Register the %{config:section.subsection} xlat function. */ xlat_register("config", xlat_config, NULL); xlat_register("client", xlat_client, NULL); /* * Reload: change debug flag if it's changed in the * configuration file. */ if (reload) { if (mainconfig.debug_level != old_debug_level) { debug_flag = mainconfig.debug_level; } } else if (debug_flag == 0) { /* * Starting the server, WITHOUT "-x" on the * command-line: use whatever's in the config * file. */ debug_flag = mainconfig.debug_level; } librad_debug = debug_flag; old_debug_level = mainconfig.debug_level; /* * Go update our behaviour, based on the configuration * changes. */ /* * The first time around, ensure that we can write to the * log directory. */ if (!reload && !debug_flag) { /* * We need root to do mkdir() and chown(), so we * do this before giving up root. */ radlogdir_iswritable(uid_name); } /* * We should really switch users earlier in the process. */ if (!switch_users()) exit(1); /* * Sanity check the configuration for internal * consistency. */ if (mainconfig.reject_delay > mainconfig.cleanup_delay) { mainconfig.reject_delay = mainconfig.cleanup_delay; } if (mainconfig.reject_delay < 0) mainconfig.reject_delay = 0; /* Reload the modules. */ if (setup_modules(reload, mainconfig.config) < 0) { radlog(L_ERR, "Errors initializing modules"); return -1; } return 0;}/* * Free the configuration. Called only when the server is exiting. */int free_mainconfig(void){ /* * Clean up the configuration data * structures. */ cf_section_free(&mainconfig.config); realms_free(); listen_free(&mainconfig.listen); dict_free(); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -