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

📄 rlm_sql.c

📁 使用最广泛的radius的linux的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
			break;		}		/*		 *	Allowed character.		 */		*out = *in;		out++;		in++;		outlen--;		len++;	}	*out = '\0';	return len;}/* *	Set the SQL user name. * *	We don't call the escape function here. The resulting string *	will be escaped later in the queries xlat so we don't need to *	escape it twice. (it will make things wrong if we have an *	escape candidate character in the username) */int sql_set_user(SQL_INST *inst, REQUEST *request, char *sqlusername, const char *username){	VALUE_PAIR *vp=NULL;	char tmpuser[MAX_STRING_LEN];	tmpuser[0] = '\0';	sqlusername[0]= '\0';	/* Remove any user attr we added previously */	pairdelete(&request->packet->vps, PW_SQL_USER_NAME);	if (username != NULL) {		strlcpy(tmpuser, username, sizeof(tmpuser));	} else if (strlen(inst->config->query_user)) {		radius_xlat(tmpuser, sizeof(tmpuser), inst->config->query_user, request, NULL);	} else {		return 0;	}	strlcpy(sqlusername, tmpuser, MAX_STRING_LEN);	DEBUG2("rlm_sql (%s): sql_set_user escaped user --> '%s'",		       inst->config->xlat_name, sqlusername);	vp = pairmake("SQL-User-Name", sqlusername, 0);	if (vp == NULL) {		radlog(L_ERR, "%s", librad_errstr);		return -1;	}	pairadd(&request->packet->vps, vp);	return 0;}static void sql_grouplist_free (SQL_GROUPLIST **group_list){	SQL_GROUPLIST *last;	while(*group_list) {		last = *group_list;		*group_list = (*group_list)->next;		free(last);	}}static int sql_get_grouplist (SQL_INST *inst, SQLSOCK *sqlsocket, REQUEST *request, SQL_GROUPLIST **group_list){	char    querystr[MAX_QUERY_LEN];	int     num_groups = 0;	SQL_ROW row;	SQL_GROUPLIST   *group_list_tmp;	/* NOTE: sql_set_user should have been run before calling this function */	group_list_tmp = *group_list = NULL;	if (!inst->config->groupmemb_query ||	    (inst->config->groupmemb_query[0] == 0))		return 0;	if (!radius_xlat(querystr, sizeof(querystr), inst->config->groupmemb_query, request, sql_escape_func)) {		radlog(L_ERR, "rlm_sql (%s): xlat failed.",			inst->config->xlat_name);		return -1;	}	if (rlm_sql_select_query(sqlsocket, inst, querystr) < 0) {		radlog(L_ERR, "rlm_sql (%s): database query error, %s: %s",		       inst->config->xlat_name,querystr,		       (inst->module->sql_error)(sqlsocket,inst->config));		return -1;	}	while (rlm_sql_fetch_row(sqlsocket, inst) == 0) {		row = sqlsocket->row;		if (row == NULL)			break;		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_grouplist_free(group_list);			return -1;		}		if (*group_list == NULL) {			*group_list = rad_malloc(sizeof(SQL_GROUPLIST));			group_list_tmp = *group_list;		} else {			group_list_tmp->next = rad_malloc(sizeof(SQL_GROUPLIST));			group_list_tmp = group_list_tmp->next;		}		group_list_tmp->next = NULL;		strlcpy(group_list_tmp->groupname, row[0], MAX_STRING_LEN);	}	(inst->module->sql_finish_select_query)(sqlsocket, inst->config);	return num_groups;}/* * sql groupcmp function. That way we can do group comparisons (in the users file for example) * with the group memberships reciding in sql * The group membership query should only return one element which is the username. The returned * username will then be checked with the passed check string. */static int sql_groupcmp(void *instance, REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check,			VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs){	SQLSOCK *sqlsocket;	SQL_INST *inst = instance;	char sqlusername[MAX_STRING_LEN];	SQL_GROUPLIST *group_list, *group_list_tmp;	check_pairs = check_pairs;	reply_pairs = reply_pairs;	request = request;	DEBUG("rlm_sql (%s): - sql_groupcmp", inst->config->xlat_name);	if (!check || !check->vp_strvalue || !check->length){		DEBUG("rlm_sql (%s): sql_groupcmp: Illegal group name",		      inst->config->xlat_name);		return 1;	}	if (req == NULL){		DEBUG("rlm_sql (%s): sql_groupcmp: NULL request",		      inst->config->xlat_name);		return 1;	}	/*	 * Set, escape, and check the user attr here	 */	if (sql_set_user(inst, req, sqlusername, NULL) < 0)		return 1;	/*	 *	Get a socket for this lookup	 */	sqlsocket = sql_get_socket(inst);	if (sqlsocket == NULL) {		/* Remove the username we (maybe) added above */		pairdelete(&req->packet->vps, PW_SQL_USER_NAME);		return 1;	}	/*	 *	Get the list of groups this user is a member of	 */	if (sql_get_grouplist(inst, sqlsocket, req, &group_list) < 0) {		radlog(L_ERR, "rlm_sql (%s): Error getting group membership",		       inst->config->xlat_name);		/* Remove the username we (maybe) added above */		pairdelete(&req->packet->vps, PW_SQL_USER_NAME);		sql_release_socket(inst, sqlsocket);		return 1;	}	for (group_list_tmp = group_list; group_list_tmp != NULL; group_list_tmp = group_list_tmp->next) {		if (strcmp(group_list_tmp->groupname, check->vp_strvalue) == 0){			DEBUG("rlm_sql (%s): - sql_groupcmp finished: User is a member of group %s",			      inst->config->xlat_name,			      (char *)check->vp_strvalue);			/* Free the grouplist */			sql_grouplist_free(&group_list);			/* Remove the username we (maybe) added above */			pairdelete(&req->packet->vps, PW_SQL_USER_NAME);			sql_release_socket(inst, sqlsocket);			return 0;		}	}	/* Free the grouplist */	sql_grouplist_free(&group_list);	/* Remove the username we (maybe) added above */	pairdelete(&req->packet->vps, PW_SQL_USER_NAME);	sql_release_socket(inst,sqlsocket);	DEBUG("rlm_sql (%s): - sql_groupcmp finished: User is NOT a member of group %s",	      inst->config->xlat_name, (char *)check->vp_strvalue);	return 1;}static int rlm_sql_process_groups(SQL_INST *inst, REQUEST *request, SQLSOCK *sqlsocket, int *dofallthrough){	VALUE_PAIR *check_tmp = NULL;	VALUE_PAIR *reply_tmp = NULL;	SQL_GROUPLIST *group_list, *group_list_tmp;	VALUE_PAIR *sql_group = NULL;	char    querystr[MAX_QUERY_LEN];	int found = 0;	int rows;	/*	 *	Get the list of groups this user is a member of	 */	if (sql_get_grouplist(inst, sqlsocket, request, &group_list) < 0) {		radlog(L_ERR, "rlm_sql (%s): Error retrieving group list",		       inst->config->xlat_name);		return -1;	}	for (group_list_tmp = group_list; group_list_tmp != NULL && *dofallthrough != 0; group_list_tmp = group_list_tmp->next) {		/*		 *	Add the Sql-Group attribute to the request list so we know		 *	which group we're retrieving attributes for		 */		sql_group = pairmake("Sql-Group", group_list_tmp->groupname, T_OP_EQ);		if (!sql_group) {			radlog(L_ERR, "rlm_sql (%s): Error creating Sql-Group attribute",			       inst->config->xlat_name);			return -1;		}		pairadd(&request->packet->vps, sql_group);		if (!radius_xlat(querystr, sizeof(querystr), inst->config->authorize_group_check_query, request, sql_escape_func)) {			radlog(L_ERR, "rlm_sql (%s): Error generating query; rejecting user",			       inst->config->xlat_name);			/* Remove the grouup we added above */			pairdelete(&request->packet->vps, PW_SQL_GROUP);			return -1;		}		rows = sql_getvpdata(inst, sqlsocket, &check_tmp, querystr);		if (rows < 0) {			radlog(L_ERR, "rlm_sql (%s): Error retrieving check pairs for group %s",			       inst->config->xlat_name, group_list_tmp->groupname);			/* Remove the grouup we added above */			pairdelete(&request->packet->vps, PW_SQL_GROUP);			pairfree(&check_tmp);			return -1;		} 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 group %s",					inst->config->xlat_name, group_list_tmp->groupname);				/*				 *	Now get the reply pairs since the paircompare matched				 */				if (!radius_xlat(querystr, sizeof(querystr), inst->config->authorize_group_reply_query, request, sql_escape_func)) {					radlog(L_ERR, "rlm_sql (%s): Error generating query; rejecting user",					       inst->config->xlat_name);					/* Remove the grouup we added above */					pairdelete(&request->packet->vps, PW_SQL_GROUP);					pairfree(&check_tmp);					return -1;				}				if (sql_getvpdata(inst, sqlsocket, &reply_tmp, querystr) < 0) {					radlog(L_ERR, "rlm_sql (%s): Error retrieving reply pairs for group %s",					       inst->config->xlat_name, group_list_tmp->groupname);					/* Remove the grouup we added above */					pairdelete(&request->packet->vps, PW_SQL_GROUP);					pairfree(&check_tmp);					pairfree(&reply_tmp);					return -1;				}				*dofallthrough = fallthrough(reply_tmp);				pairxlatmove(request, &request->reply->vps, &reply_tmp);				pairxlatmove(request, &request->config_items, &check_tmp);			}		} else {			/*			 *	rows == 0.  This is like having the username on a line			 * 	in the user's file with no check vp's.  As such, we treat			 *	it as found and add the reply attributes, so that we			 *	match expected behavior			 */			found = 1;			DEBUG2("rlm_sql (%s): User found in group %s",				inst->config->xlat_name, group_list_tmp->groupname);			/*			 *	Now get the reply pairs since the paircompare matched			 */			if (!radius_xlat(querystr, sizeof(querystr), inst->config->authorize_group_reply_query, request, sql_escape_func)) {				radlog(L_ERR, "rlm_sql (%s): Error generating query; rejecting user",				       inst->config->xlat_name);				/* Remove the grouup we added above */				pairdelete(&request->packet->vps, PW_SQL_GROUP);				pairfree(&check_tmp);				return -1;			}			if (sql_getvpdata(inst, sqlsocket, &reply_tmp, querystr) < 0) {				radlog(L_ERR, "rlm_sql (%s): Error retrieving reply pairs for group %s",				       inst->config->xlat_name, group_list_tmp->groupname);				/* Remove the grouup we added above */				pairdelete(&request->packet->vps, PW_SQL_GROUP);				pairfree(&check_tmp);				pairfree(&reply_tmp);				return -1;			}			*dofallthrough = fallthrough(reply_tmp);			pairxlatmove(request, &request->reply->vps, &reply_tmp);			pairxlatmove(request, &request->config_items, &check_tmp);		}		/*		 * Delete the Sql-Group we added above		 * And clear out the pairlists		 */		pairdelete(&request->packet->vps, PW_SQL_GROUP);		pairfree(&check_tmp);		pairfree(&reply_tmp);	}	sql_grouplist_free(&group_list);	return found;}static int rlm_sql_detach(void *instance){	SQL_INST *inst = instance;	paircompare_unregister(PW_SQL_GROUP, sql_groupcmp);	if (inst->config) {		int i;		if (inst->sqlpool) {			sql_poolfree(inst);		}		if (inst->config->xlat_name) {			xlat_unregister(inst->config->xlat_name,(RAD_XLAT_FUNC)sql_xlat);			free(inst->config->xlat_name);		}		/*		 *	Free up dynamically allocated string pointers.		 */		for (i = 0; module_config[i].name != NULL; i++) {			char **p;			if (module_config[i].type != PW_TYPE_STRING_PTR) {				continue;			}			/*			 *	Treat 'config' as an opaque array of bytes,			 *	and take the offset into it.  There's a			 *      (char*) pointer at that offset, and we want			 *	to point to it.			 */			p = (char **) (((char *)inst->config) + module_config[i].offset);			if (!*p) { /* nothing allocated */				continue;			}			free(*p);			*p = NULL;		}		allowed_chars = NULL;		free(inst->config);		inst->config = NULL;	}	if (inst->handle) {#if 0		/*		 *	FIXME: Call the modules 'destroy' function?

⌨️ 快捷键说明

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