⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rlm_sql.c

📁 使用最广泛的radius的linux的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
		 */		lt_dlclose(inst->handle);	/* ignore any errors */#endif	}	free(inst);	return 0;}static int rlm_sql_instantiate(CONF_SECTION * conf, void **instance){	SQL_INST *inst;	const char *xlat_name;	inst = rad_malloc(sizeof(SQL_INST));	memset(inst, 0, sizeof(SQL_INST));	inst->config = rad_malloc(sizeof(SQL_CONFIG));	memset(inst->config, 0, sizeof(SQL_CONFIG));	/*	 * If the configuration parameters can't be parsed, then	 * fail.	 */	if (cf_section_parse(conf, inst->config, module_config) < 0) {		rlm_sql_detach(inst);		return -1;	}	xlat_name = cf_section_name2(conf);	if (xlat_name == NULL)		xlat_name = cf_section_name1(conf);	if (xlat_name){		inst->config->xlat_name = strdup(xlat_name);		xlat_register(xlat_name, (RAD_XLAT_FUNC)sql_xlat, inst);	}	if (inst->config->num_sql_socks > MAX_SQL_SOCKS) {		radlog(L_ERR | L_CONS, "rlm_sql (%s): sql_instantiate: number of sqlsockets cannot exceed MAX_SQL_SOCKS, %d",		       inst->config->xlat_name, MAX_SQL_SOCKS);		rlm_sql_detach(inst);		return -1;	}	/*	 *	Sanity check for crazy people.	 */	if (strncmp(inst->config->sql_driver, "rlm_sql_", 8) != 0) {		radlog(L_ERR, "rlm_sql (%s): \"%s\" is NOT an SQL driver!",		       inst->config->xlat_name, inst->config->sql_driver);		rlm_sql_detach(inst);		return -1;	}	inst->handle = lt_dlopenext(inst->config->sql_driver);	if (inst->handle == NULL) {		radlog(L_ERR, "rlm_sql (%s): Could not link driver %s: %s",		       inst->config->xlat_name, inst->config->sql_driver,		       lt_dlerror());		radlog(L_ERR, "rlm_sql (%s): Make sure it (and all its dependent libraries!) are in the search path of your system's ld.",		       inst->config->xlat_name);		rlm_sql_detach(inst);		return -1;	}	inst->module = (rlm_sql_module_t *) lt_dlsym(inst->handle, inst->config->sql_driver);	if (!inst->module) {		radlog(L_ERR, "rlm_sql (%s): Could not link symbol %s: %s",		       inst->config->xlat_name, inst->config->sql_driver,		       lt_dlerror());		rlm_sql_detach(inst);		return -1;	}	radlog(L_INFO, "rlm_sql (%s): Driver %s (module %s) loaded and linked",	       inst->config->xlat_name, inst->config->sql_driver,	       inst->module->name);	radlog(L_INFO, "rlm_sql (%s): Attempting to connect to %s@%s:%s/%s",	       inst->config->xlat_name, inst->config->sql_login,	       inst->config->sql_server, inst->config->sql_port,	       inst->config->sql_db);	if (sql_init_socketpool(inst) < 0) {		rlm_sql_detach(inst);		return -1;	}	paircompare_register(PW_SQL_GROUP, PW_USER_NAME, sql_groupcmp, inst);	if (inst->config->do_clients){		if (generate_sql_clients(inst) == -1){			radlog(L_ERR, "rlm_sql (%s): generate_sql_clients() returned error",inst->config->xlat_name);			rlm_sql_detach(inst);			return -1;		}	}	allowed_chars = inst->config->allowed_chars;	*instance = inst;	return RLM_MODULE_OK;}static int rlm_sql_authorize(void *instance, REQUEST * request){	VALUE_PAIR *check_tmp = NULL;	VALUE_PAIR *reply_tmp = NULL;	VALUE_PAIR *user_profile = NULL;	int     found = 0;	int	dofallthrough = 1;	int	rows;	SQLSOCK *sqlsocket;	SQL_INST *inst = instance;	char    querystr[MAX_QUERY_LEN];	char	sqlusername[MAX_STRING_LEN];	/*	 * the profile username is used as the sqlusername during	 * profile checking so that we don't overwrite the orignal	 * sqlusername string	 */	char   profileusername[MAX_STRING_LEN];	/*	 * Set, escape, and check the user attr here	 */	if (sql_set_user(inst, request, sqlusername, NULL) < 0)		return RLM_MODULE_FAIL;	/*	 * reserve a socket	 */	sqlsocket = sql_get_socket(inst);	if (sqlsocket == NULL) {		/* Remove the username we (maybe) added above */		pairdelete(&request->packet->vps, PW_SQL_USER_NAME);		return RLM_MODULE_FAIL;	}	/*	 *  After this point, ALL 'return's MUST release the SQL socket!	 */	/*	 * Alright, start by getting the specific entry for the user	 */	if (!radius_xlat(querystr, sizeof(querystr), inst->config->authorize_check_query, request, sql_escape_func)) {		radlog(L_ERR, "rlm_sql (%s): Error generating query; rejecting user",		       inst->config->xlat_name);		sql_release_socket(inst, sqlsocket);		/* Remove the username we (maybe) added above */		pairdelete(&request->packet->vps, PW_SQL_USER_NAME);		return RLM_MODULE_FAIL;	}	rows = sql_getvpdata(inst, sqlsocket, &check_tmp, querystr);	if (rows < 0) {		radlog(L_ERR, "rlm_sql (%s): SQL query error; rejecting user",		       inst->config->xlat_name);		sql_release_socket(inst, sqlsocket);		/* Remove the username we (maybe) added above */		pairdelete(&request->packet->vps, PW_SQL_USER_NAME);		pairfree(&check_tmp);		return RLM_MODULE_FAIL;	} else if (rows > 0) {		/*		 *	Only do this if *some* check pairs were returned		 */		if (paircompare(request, request->packet->vps, check_tmp, &request->reply->vps) == 0) {			found = 1;			DEBUG2("rlm_sql (%s): User found in radcheck table", inst->config->xlat_name);			/*			 *	Now get the reply pairs since the paircompare matched			 */			if (!radius_xlat(querystr, sizeof(querystr), inst->config->authorize_reply_query, request, sql_escape_func)) {				radlog(L_ERR, "rlm_sql (%s): Error generating query; rejecting user",				       inst->config->xlat_name);				sql_release_socket(inst, sqlsocket);				/* Remove the username we (maybe) added above */				pairdelete(&request->packet->vps, PW_SQL_USER_NAME);				pairfree(&check_tmp);				return RLM_MODULE_FAIL;			}			if (sql_getvpdata(inst, sqlsocket, &reply_tmp, querystr) < 0) {				radlog(L_ERR, "rlm_sql (%s): SQL query error; rejecting user",				       inst->config->xlat_name);				sql_release_socket(inst, sqlsocket);				/* Remove the username we (maybe) added above */				pairdelete(&request->packet->vps, PW_SQL_USER_NAME);				pairfree(&check_tmp);				pairfree(&reply_tmp);				return RLM_MODULE_FAIL;			}			if (!inst->config->read_groups)				dofallthrough = fallthrough(reply_tmp);			pairxlatmove(request, &request->reply->vps, &reply_tmp);			pairxlatmove(request, &request->config_items, &check_tmp);		}	}	/*	 *	Clear out the pairlists	 */	pairfree(&check_tmp);	pairfree(&reply_tmp);	/*	 *	dofallthrough is set to 1 by default so that if the user information	 *	is not found, we will still process groups.  If the user information,	 *	however, *is* found, Fall-Through must be set in order to process	 *	the groups as well	 */	if (dofallthrough) {		rows = rlm_sql_process_groups(inst, request, sqlsocket, &dofallthrough);		if (rows < 0) {			radlog(L_ERR, "rlm_sql (%s): Error processing groups; rejecting user",			       inst->config->xlat_name);			sql_release_socket(inst, sqlsocket);			/* Remove the username we (maybe) added above */			pairdelete(&request->packet->vps, PW_SQL_USER_NAME);			return RLM_MODULE_FAIL;		} else if (rows > 0) {			found = 1;		}	}	/*	 *	repeat the above process with the default profile or User-Profile	 */	if (dofallthrough) {		int profile_found = 0;		/*	 	* Check for a default_profile or for a User-Profile.		*/		user_profile = pairfind(request->config_items, PW_USER_PROFILE);		if (inst->config->default_profile[0] != 0 || user_profile != NULL){			char *profile = inst->config->default_profile;			if (user_profile != NULL)				profile = user_profile->vp_strvalue;			if (profile && strlen(profile)){				radlog(L_DBG, "rlm_sql (%s): Checking profile %s",				       inst->config->xlat_name, profile);				if (sql_set_user(inst, request, profileusername, profile) < 0) {					radlog(L_ERR, "rlm_sql (%s): Error setting profile; rejecting user",					       inst->config->xlat_name);					sql_release_socket(inst, sqlsocket);					/* Remove the username we (maybe) added above */					pairdelete(&request->packet->vps, PW_SQL_USER_NAME);					return RLM_MODULE_FAIL;				} else {					profile_found = 1;				}			}		}		if (profile_found) {			rows = rlm_sql_process_groups(inst, request, sqlsocket, &dofallthrough);			if (rows < 0) {				radlog(L_ERR, "rlm_sql (%s): Error processing profile groups; rejecting user",				       inst->config->xlat_name);				sql_release_socket(inst, sqlsocket);				/* Remove the username we (maybe) added above */				pairdelete(&request->packet->vps, PW_SQL_USER_NAME);				return RLM_MODULE_FAIL;			} else if (rows > 0) {				found = 1;			}		}	}	/* Remove the username we (maybe) added above */	pairdelete(&request->packet->vps, PW_SQL_USER_NAME);	sql_release_socket(inst, sqlsocket);	if (!found) {		radlog(L_DBG, "rlm_sql (%s): User %s not found",		       inst->config->xlat_name, sqlusername);		return RLM_MODULE_NOTFOUND;	} else {		return RLM_MODULE_OK;	}}/* *	Accounting: save the account data to our sql table */static int rlm_sql_accounting(void *instance, REQUEST * request) {	SQLSOCK *sqlsocket = NULL;	VALUE_PAIR *pair;	SQL_INST *inst = instance;	int	ret = RLM_MODULE_OK;	int     numaffected = 0;	int     acctstatustype = 0;	char    querystr[MAX_QUERY_LEN];	char    logstr[MAX_QUERY_LEN];	char	sqlusername[MAX_STRING_LEN];#ifdef CISCO_ACCOUNTING_HACK	int     acctsessiontime = 0;#endif	memset(querystr, 0, MAX_QUERY_LEN);	/*	 * Find the Acct Status Type	 */	if ((pair = pairfind(request->packet->vps, PW_ACCT_STATUS_TYPE)) != NULL) {		acctstatustype = pair->vp_integer;	} else {		radius_xlat(logstr, sizeof(logstr), "packet has no accounting status type. [user '%{User-Name}', nas '%{NAS-IP-Address}']", request, NULL);		radlog(L_ERR, "rlm_sql (%s) in sql_accounting: %s",		       inst->config->xlat_name, logstr);		return RLM_MODULE_INVALID;	}	switch (acctstatustype) {			/*			 * The Terminal server informed us that it was rebooted			 * STOP all records from this NAS			 */		case PW_STATUS_ACCOUNTING_ON:		case PW_STATUS_ACCOUNTING_OFF:			radlog(L_INFO, "rlm_sql (%s): received Acct On/Off packet", inst->config->xlat_name);			radius_xlat(querystr, sizeof(querystr), inst->config->accounting_onoff_query, request, sql_escape_func);			query_log(request, inst, querystr);			sqlsocket = sql_get_socket(inst);			if (sqlsocket == NULL)				return(RLM_MODULE_FAIL);			if (*querystr) { /* non-empty query */				if (rlm_sql_query(sqlsocket, inst, querystr)) {					radlog(L_ERR, "rlm_sql (%s): Couldn't update SQL accounting for Acct On/Off packet - %s",					       inst->config->xlat_name,					       (inst->module->sql_error)(sqlsocket, inst->config));					ret = RLM_MODULE_FAIL;				}				(inst->module->sql_finish_query)(sqlsocket, inst->config);			}			break;			/*			 * Got an update accounting packet			 */		case PW_STATUS_ALIVE:			/*			 * Set, escape, and check the user attr here			 */			sql_set_user(inst, request, sqlusername, NULL);			radius_xlat(querystr, sizeof(querystr), inst->config->accounting_update_query, request, sql_escape_func);			query_log(request, inst, querystr);			sqlsocket = sql_get_socket(inst);			if (sqlsocket == NULL)				return(RLM_MODULE_FAIL);			if (*querystr) { /* non-empty query */				if (rlm_sql_query(sqlsocket, inst, querystr)) {					radlog(L_ERR, "rlm_sql (%s): Couldn't update SQL accounting ALIVE record - %s",					       inst->config->xlat_name,					       (inst->module->sql_error)(sqlsocket, inst->config));					ret = RLM_MODULE_FAIL;				}				else {					numaffected = (inst->module->sql_affected_rows)(sqlsocket, inst->config);					if (numaffected < 1) {						/*						 * If our update above didn't match anything						 * we assume it's because we haven't seen a						 * matching Start record.  So we have to						 * insert this update rather than do an update						 */						radius_xlat(querystr, sizeof(querystr), inst->config->accounting_update_query_alt, request, sql_escape_func);						query_log(request, inst, querystr);						if (*querystr) { /* non-empty query */							if (rlm_sql_query(sqlsocket, inst, querystr)) {								radlog(L_ERR, "rlm_sql (%s): Couldn't insert SQL accounting ALIVE record - %s",								       inst->config->xlat_name,								       (inst->module->sql_error)(sqlsocket, inst->config));								ret = RLM_MODULE_FAIL;							}							(inst->module->sql_finish_query)(sqlsocket, inst->config);						}					}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -