Example #1
0
int DBUtil::Init(const char* conffile, const char* dbsection, const char* logsection)
{
    SQL_INST* sqlinst = NULL;

    // free previous instance first
    Free();

    // init sql module
    rlm_sql_init();

    // read conf file
    CONF_SECTION *conf;
    conf = conf_read(__FILE__, __LINE__, conffile, NULL);
    if(!conf) {
        radlog(L_CONS|L_ERROR, "[DBUtil::DBUtil] can not read '%s'", conffile);
        rlm_sql_destroy();
        return -1;
    }

    // get db section
    CONF_SECTION* sqlconf = cf_section_sub_find(conf, dbsection);
    if(!sqlconf) {
        radlog(L_CONS|L_ERROR, "[DBUtil::DBUtil] can not find sub section '%s'", dbsection);
        cf_section_free(&conf);
        rlm_sql_destroy();
        return -1;
    }

    // get log section if present
    CONF_SECTION* logconf = NULL;
    if(logsection) {
        logconf = cf_section_sub_find(conf, logsection);
        if(!logconf) {
            radlog(L_CONS|L_WARN, "[DBUtil::DBUtil] can not find sub section '%s', "
                   "no logging parameters would be applied to rlm_sql. This may be "
                   "a problem when using rlm_sql with dynamic loading sql_drivers",
                   logsection);
        }
    }

    // get sql instance
    if(rlm_sql_instantiate(sqlconf, &sqlinst, logconf) != 0) {
        radlog(L_CONS|L_ERROR, "[DBUtil::DBUtil] can not instantiate sql instance");
        cf_section_free(&conf);
        rlm_sql_destroy();
        return -1;
    }

    // free conf section
    cf_section_free(&conf);

    dbHandle_ = sqlinst;

    return 0;
}
/*
 *	Free the configuration.  Called only when the server is exiting.
 */
int free_mainconfig(void)
{
	cached_config_t *cc, *next;

	virtual_servers_free(0);

	/*
	 *	Free all of the cached configurations.
	 */
	for (cc = cs_cache; cc != NULL; cc = next) {
		next = cc->next;
		cf_section_free(&cc->cs);
		free(cc);
	}

	/*
	 *	Clean up the configuration data
	 *	structures.
	 */
	realms_free();
	listen_free(&mainconfig.listen);
	dict_free();

	return 0;
}
static int filter_detach(void *instance)
{
	rlm_protocol_filter_t *inst = instance;

	if (inst->cs) cf_section_free(&(inst->cs));

	free(instance);
	return 0;
}
/*
 *	Read config files.
 *
 *	This function can ONLY be called from the main server process.
 */
int read_mainconfig(int reload)
{
	const char *p = NULL;
	CONF_PAIR *cp;
	CONF_SECTION *cs;
	struct stat statbuf;
	cached_config_t *cc;
	char buffer[1024];

	if (reload != 0) {
		radlog(L_ERR, "Reload is not implemented");
		return -1;
	}

	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

	radlog(L_INFO, "Starting - 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 or parsing %s", buffer);
		return -1;
	}

	/*
	 *	If there was no log destination set on the command line,
	 *	set it now.
	 */
	if (mainconfig.radlog_dest == RADLOG_NULL) {
		if (cf_section_parse(cs, NULL, serverdest_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(syslog_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;
			}

#ifdef HAVE_SYSLOG_H
			/*
			 *	Call openlog only once, when the
			 *	program starts.
			 */
			openlog(progname, LOG_PID, mainconfig.syslog_facility);
#endif

		} else if (mainconfig.radlog_dest == RADLOG_FILES) {
			if (!mainconfig.log_file) {
				fprintf(stderr, "radiusd: Error: Specified \"files\" as a log destination, but no log filename was given!\n");
				cf_section_free(&cs);
				return -1;
			}
		}
	}

#ifdef HAVE_SETUID
	/*
	 *	Switch users as early as possible.
	 */
	if (!switch_users(cs)) exit(1);
#endif

	/*
	 *	Open the log file AFTER switching uid / gid.  If we
	 *	did switch uid/gid, then the code in switch_users()
	 *	took care of setting the file permissions correctly.
	 */
	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));
			cf_section_free(&cs);
			return -1;
		}
	}

	/* 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",
				fr_strerror());
		return -1;
	}

	/*
	 *	This allows us to figure out where, relative to
	 *	radiusd.conf, the other configuration files exist.
	 */
	if (cf_section_parse(cs, NULL, server_config) < 0) {
		return -1;
	}

	if (mainconfig.max_request_time == 0) mainconfig.max_request_time = 100;
	if (mainconfig.reject_delay > 5) mainconfig.reject_delay = 5;
	if (mainconfig.cleanup_delay > 5) mainconfig.cleanup_delay =5;

	/*
	 *	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;

	DEBUG2("%s: #### Loading Realms and Home Servers ####", mainconfig.name);
	if (!realms_init(cs)) {
		return -1;
	}

	DEBUG2("%s: #### Loading Clients ####", mainconfig.name);
	if (!clients_parse_section(cs)) {
		return -1;
	}

	/*
	 *  Register the %{config:section.subsection} xlat function.
	 */
	xlat_register("config", xlat_config, NULL);
	xlat_register("client", xlat_client, NULL);

	/*
	 *	Starting the server, WITHOUT "-x" on the
	 *	command-line: use whatever is in the config
	 *	file.
	 */
	if (debug_flag == 0) {
		debug_flag = mainconfig.debug_level;
	}
	fr_debug_flag = debug_flag;

	/*
	 *  Go update our behaviour, based on the configuration
	 *  changes.
	 */

	/*
	 *	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) {
		return -1;
	}

	if (chroot_dir) {
		if (chdir(radlog_dir) < 0) {
			radlog(L_ERR, "Failed to 'chdir %s' after chroot: %s",
			       radlog_dir, strerror(errno));
			return -1;
		}
	}

	cc = rad_malloc(sizeof(*cc));
	memset(cc, 0, sizeof(*cc));

	cc->cs = cs;
	rad_assert(cs_cache == NULL);
	cs_cache = cc;

	return 0;
}
Example #5
0
/*
 *	Parse a module statement.
 */
static int parse_module(policy_lex_file_t *lexer, policy_item_t **tail)
{
    int component;
    policy_lex_t token;
    policy_module_t *this;
    char *p;
    const char *section_name;
    char filename[1024];
    char buffer[2048];
    CONF_SECTION *cs, *subcs;
    modcallable *mc;

    /*
     *	And the filename
     */
    token = policy_lex_file(lexer, 0, filename, sizeof(filename));
    if (token != POLICY_LEX_DOUBLE_QUOTED_STRING) {
        fprintf(stderr, "%s[%d]: Expected filename, got \"%s\"\n",
                lexer->filename, lexer->lineno,
                fr_int2str(rlm_policy_tokens, token, "?"));
        return 0;
    }

    /*
     *	See if we're including all of the files in a subdirectory.
     */
    strlcpy(buffer, lexer->filename, sizeof(buffer));
    p = strrchr(buffer, '/');
    if (p) {
        strlcpy(p + 1, filename, sizeof(buffer) - 1 - (p - buffer));
    } else {
        snprintf(buffer, sizeof(buffer), "%s/%s",
                 radius_dir, filename);
    }

    /*
     *	Include section calling a module.
     */
    debug_tokens("including module section from file %s\n", buffer);
    cs = cf_file_read(buffer);
    if (!cs) {
        return 0;	/* it prints out error messages */
    }

    /*
     *	The outer section is called "main", and can be ignored.
     *	It should be a section, so there should be a subsection.
     */
    subcs = cf_subsection_find_next(cs, NULL, NULL);
    if (!subcs) {
        fprintf(stderr, "%s[%d]: Expected section containing modules\n",
                lexer->filename, lexer->lineno);
        cf_section_free(&cs);
        return 0;
    }

    section_name = cf_section_name1(subcs);
    rad_assert(section_name != NULL);
    component = fr_str2int(policy_component_names, section_name,
                           RLM_COMPONENT_COUNT);
    if (component == RLM_COMPONENT_COUNT) {
        fprintf(stderr, "%s[%d]: Invalid section name \"%s\"\n",
                lexer->filename, lexer->lineno, section_name);
        cf_section_free(&cs);
        return 0;
    }

    /*
     *	Compile the module entry.
     */
    mc = compile_modgroup(NULL, component, subcs);
    if (!mc) {
        cf_section_free(&cs);
        return 0;	/* more often results in calling exit... */
    }

    this = rad_malloc(sizeof(*this));
    memset(this, 0, sizeof(*this));

    this->item.type = POLICY_TYPE_MODULE;
    this->item.lineno = lexer->lineno;
    this->component = component;
    this->cs = cs;
    this->mc = mc;

    *tail = (policy_item_t *) this;

    return 1;
}
Example #6
0
/*
 *	The "free" functions are here, for no particular reason.
 */
void rlm_policy_free_item(policy_item_t *item)
{
	while (item) {
		policy_item_t *next = item->next;

		switch (item->type) {
		default:
		case POLICY_TYPE_BAD:
			break;

		case POLICY_TYPE_ASSIGNMENT:
			{
				policy_assignment_t *this;

				this = (policy_assignment_t *) item;
				if (this->lhs) free(this->lhs);
				if (this->rhs) free(this->rhs);
			}
			break;

		case POLICY_TYPE_CONDITIONAL:
			{
				policy_condition_t *this;

				this = (policy_condition_t *) item;
				if (this->lhs) free(this->lhs);
				if (this->rhs) free(this->rhs);

				if (this->child) {
					rlm_policy_free_item(this->child);
					this->child = NULL;
				}
			}
			break;

		case POLICY_TYPE_IF:
			{
				policy_if_t *this;

				this = (policy_if_t *) item;
				if (this->condition) {
					rlm_policy_free_item(this->condition);
					this->condition = NULL;
				}
				if (this->if_true) {
					rlm_policy_free_item(this->if_true);
					this->if_true = NULL;
				}
				if (this->if_false) {
					rlm_policy_free_item(this->if_false);
					this->if_false = NULL;
				}
			}
			break;

		case POLICY_TYPE_ATTRIBUTE_LIST:
			{
				policy_attributes_t *this;

				this = (policy_attributes_t *) item;
				rlm_policy_free_item(this->attributes);
			}
			break;

		case POLICY_TYPE_NAMED_POLICY:
			{
				policy_named_t *this;

				this = (policy_named_t *) item;
				rad_assert(this->name != NULL);
				free(this->name);
				rlm_policy_free_item(this->policy);
			}
			break;

		case POLICY_TYPE_CALL:
			{
				policy_call_t *this;

				this = (policy_call_t *) item;
				if (this->name) free(this->name);
			}
			break;

		case POLICY_TYPE_RETURN:
			break;	/* do nothing */

		case POLICY_TYPE_MODULE:
			{
				policy_module_t *this;

				this = (policy_module_t *) item;
				if (this->cs) cf_section_free(&this->cs);
				if (this->mc) modcallable_free(&this->mc);
			}
			break;
		} /* switch over type */
		item->next = NULL; /* for debugging & sanity checks */
		item->type = POLICY_TYPE_BAD;
		free(item);

		item = next;
	}
}