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

📄 rlm_sql.c

📁 RADIUS 服务器介绍 RADIUS服务器支持标准的RADIUS协议
💻 C
📖 第 1 页 / 共 3 页
字号:
		if (row[0] == NULL){			DEBUG("rlm_sql (%s): row[0] returned NULL",			      inst->config->xlat_name);			(inst->module->sql_finish_select_query)(sqlsocket, inst->config);			sql_release_socket(inst, sqlsocket);			return 1;		}		if (strcmp(row[0],check->strvalue) == 0){			DEBUG("rlm_sql (%s): - sql_groupcmp finished: User belongs in group %s",			      inst->config->xlat_name,			      (char *)check->strvalue);			(inst->module->sql_finish_select_query)(sqlsocket, inst->config);			sql_release_socket(inst, sqlsocket);			return 0;		}	}	(inst->module->sql_finish_select_query)(sqlsocket, inst->config);	sql_release_socket(inst,sqlsocket);	DEBUG("rlm_sql (%s): - sql_groupcmp finished: User does not belong in group %s",	      inst->config->xlat_name, (char *)check->strvalue);	return 1;}static int rlm_sql_instantiate(CONF_SECTION * conf, void **instance){	SQL_INST *inst;	lt_dlhandle handle;	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) {		free(inst->config);		free(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, 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);		free(inst->config);		free(inst);		return -1;	}	handle = lt_dlopenext(inst->config->sql_driver);	if (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);		return -1;	}	inst->module = (rlm_sql_module_t *) lt_dlsym(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());		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) {		free(inst->config);		free(inst);		return -1;	}	paircompare_register(PW_SQL_GROUP, PW_USER_NAME, sql_groupcmp, inst);	*instance = inst;	return RLM_MODULE_OK;}static int rlm_sql_destroy(void){	return 0;}static int rlm_sql_detach(void *instance){	SQL_INST *inst = instance;	sql_poolfree(inst);	if (inst->config->xlat_name)		xlat_unregister(inst->config->xlat_name,sql_xlat);	paircompare_unregister(PW_SQL_GROUP, sql_groupcmp);	free(inst->config);	free(inst);	return 0;}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;	SQLSOCK *sqlsocket;	SQL_INST *inst = instance;	char    querystr[MAX_QUERY_LEN];	/* sqlusername holds the sql escaped username. The original	 * username is at most MAX_STRING_LEN chars long and	 * *sql_escape_string doubles its length in the worst case.	 * Throw in an extra 10 to account for trailing NULs and to have	 * a safety margin. */	char   sqlusername[2 * MAX_STRING_LEN + 10];	/*	 *	They MUST have a user name to do SQL authorization.	 */	if ((request->username == NULL) ||	    (request->username->length == 0)) {		radlog(L_ERR, "rlm_sql (%s): zero length username not permitted\n", inst->config->xlat_name);		return RLM_MODULE_INVALID;	}	/*	 *  After this point, ALL 'return's MUST release the SQL socket!	 */	/*	 * Set, escape, and check the user attr here	 */	if (sql_set_user(inst, request, sqlusername, NULL) < 0)		return RLM_MODULE_FAIL;	radius_xlat(querystr, sizeof(querystr), inst->config->authorize_check_query, request, sql_escape_func);	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);	}	found = sql_getvpdata(inst, sqlsocket, &check_tmp, querystr, PW_VP_USERDATA);	/*	 *      Find the entry for the user.	 */	if (found > 0) {		radius_xlat(querystr, sizeof(querystr), inst->config->authorize_group_check_query, request, sql_escape_func);		sql_getvpdata(inst, sqlsocket, &check_tmp, querystr, PW_VP_GROUPDATA);		radius_xlat(querystr, sizeof(querystr), inst->config->authorize_reply_query, request, sql_escape_func);		sql_getvpdata(inst, sqlsocket, &reply_tmp, querystr, PW_VP_USERDATA);		radius_xlat(querystr, sizeof(querystr), inst->config->authorize_group_reply_query, request, sql_escape_func);		sql_getvpdata(inst, sqlsocket, &reply_tmp, querystr, PW_VP_GROUPDATA);	} else if (found < 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);		return RLM_MODULE_FAIL;	} else {		radlog(L_DBG, "rlm_sql (%s): User %s not found in radcheck",		       inst->config->xlat_name, sqlusername);                /*		 * We didn't find the user in radcheck, so we try looking		 * for radgroupcheck entry		 */                radius_xlat(querystr, sizeof(querystr), inst->config->authorize_group_check_query, request, sql_escape_func);                found = sql_getvpdata(inst, sqlsocket, &check_tmp, querystr, PW_VP_GROUPDATA);                radius_xlat(querystr, sizeof(querystr), inst->config->authorize_group_reply_query, request, sql_escape_func);                sql_getvpdata(inst, sqlsocket, &reply_tmp, querystr, PW_VP_GROUPDATA);        }	if (!found)		radlog(L_DBG, "rlm_sql (%s): User %s not found in radgroupcheck",		       inst->config->xlat_name, sqlusername);	if (found || (!found && inst->config->query_on_not_found)){		/*	 	* 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->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, sqlusername, profile) < 0) {					return RLM_MODULE_FAIL;				}				radius_xlat(querystr, sizeof(querystr), inst->config->authorize_group_check_query,									request, sql_escape_func);				found = sql_getvpdata(inst, sqlsocket, &check_tmp, querystr, PW_VP_GROUPDATA);				radius_xlat(querystr, sizeof(querystr), inst->config->authorize_group_reply_query,									request, sql_escape_func);				sql_getvpdata(inst, sqlsocket, &reply_tmp, querystr, PW_VP_GROUPDATA);			}		}	}	if (!found) {		radlog(L_DBG, "rlm_sql (%s): User not found",		       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_NOTFOUND;	}	/*	 * Uncomment these lines for debugging	 * Recompile, and run 'radiusd -X'	 */	/*	DEBUG2("rlm_sql:  check items");	vp_listdebug(check_tmp);	DEBUG2("rlm_sql:  reply items");	vp_listdebug(reply_tmp); 	*/	if (paircmp(request, request->packet->vps, check_tmp, &reply_tmp) != 0) {		radlog(L_INFO, "rlm_sql (%s): No matching entry in the database for request from user [%s]",		       inst->config->xlat_name, sqlusername);		/* Remove the username we (maybe) added above */		pairdelete(&request->packet->vps, PW_SQL_USER_NAME);		sql_release_socket(inst, sqlsocket);		pairfree(&reply_tmp);		pairfree(&check_tmp);		return RLM_MODULE_NOTFOUND;	}	pairmove(&request->reply->vps, &reply_tmp);	pairmove(&request->config_items, &check_tmp);	pairfree(&reply_tmp);	pairfree(&check_tmp);	/* Remove the username we (maybe) added above */	pairdelete(&request->packet->vps, PW_SQL_USER_NAME);	sql_release_socket(inst, sqlsocket);	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[2 * MAX_STRING_LEN + 10];#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->lvalue;	} else {		radius_xlat(logstr, sizeof(logstr), "rlm_sql: packet has no account status type.  [user '%{User-Name}', nas '%{NAS-IP-Address}']", request, sql_escape_func);		radlog(L_ERR, 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,					       (char *)(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);

⌨️ 快捷键说明

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