📄 sql.c
字号:
*************************************************************************/int sql_release_socket(SQL_INST * inst, SQLSOCK * sqlsocket){#ifdef HAVE_PTHREAD_H pthread_mutex_unlock(&sqlsocket->mutex);#endif radlog(L_DBG, "rlm_sql (%s): Released sql socket id: %d", inst->config->xlat_name, sqlsocket->id); return 0;}/************************************************************************* * * Function: sql_userparse * * Purpose: Read entries from the database and fill VALUE_PAIR structures * *************************************************************************/int sql_userparse(VALUE_PAIR ** first_pair, SQL_ROW row, int querymode){ DICT_ATTR *attr; VALUE_PAIR *pair, *check; char *ptr; char buf[128]; char value[256]; LRAD_TOKEN xlat, pairmode = T_EOL; if ((attr = dict_attrbyname(row[2])) == (DICT_ATTR *) NULL) { radlog(L_ERR | L_CONS, "rlm_sql: unknown attribute %s", row[2]); return (-1); } if (row[4] != NULL && strlen(row[4]) > 0) { ptr = row[4]; pairmode = gettoken(&ptr, buf, sizeof(buf)); } else { /* * 'op' fields of NULL are a plague, and a bane on the * existence of mankind. */ radlog(L_ERR, "rlm_sql: The 'op' field for attribute '%s = %s' is NULL, or non-existent.", row[2], row[3]); radlog(L_ERR, "rlm_sql: You MUST FIX THIS if you want the configuration to behave as you expect."); } if (pairmode <= T_EOL) pairmode = T_OP_CMP_EQ; /* * If attribute is already there, skip it because we checked usercheck first * and we want user settings to over ride group settings */ if (pairmode != T_OP_ADD && (check = pairfind(*first_pair, attr->attr)) != NULL &&#ifdef ASCEND_BINARY attr->type != PW_TYPE_ABINARY &&#endif querymode == PW_VP_GROUPDATA) return 0; /* * If we have a new-style quoted string, where the * *entire* string is quoted, do xlat's. */ if (((row[3][0] == '\'') || (row[3][0] == '`') || (row[3][0] == '"')) && (row[3][0] == row[3][strlen(row[3])-1])) { ptr = row[3]; xlat = gettoken(&ptr, value, sizeof(value)); switch (xlat) { /* * Make the full pair now. */ default: pair = pairmake(row[2], row[3], pairmode); break; case T_SINGLE_QUOTED_STRING: case T_DOUBLE_QUOTED_STRING: pair = pairmake(row[2], value, pairmode); break; /* * Mark the pair to be allocated later. */ case T_BACK_QUOTED_STRING: pair = pairmake(row[2], NULL, pairmode); if (pair) { pair->flags.do_xlat = 1; strNcpy(pair->strvalue, value, sizeof(pair->strvalue)); pair->length = 0; } } } else { /* * String starts and ends differently. Take it literally * */ pair = pairmake(row[2], row[3], pairmode); } pairadd(first_pair, pair); return 0;}/************************************************************************* * * Function: rlm_sql_fetch_row * * Purpose: call the module's sql_fetch_row and implement re-connect * *************************************************************************/int rlm_sql_fetch_row(SQLSOCK *sqlsocket, SQL_INST *inst){ int ret; if (sqlsocket->conn) { ret = (inst->module->sql_fetch_row)(sqlsocket, inst->config); } else { ret = SQL_DOWN; } if (ret == SQL_DOWN) { /* close the socket that failed, but only if it was open */ if (sqlsocket->conn) { (inst->module->sql_close)(sqlsocket, inst->config); } /* reconnect the socket */ if (connect_single_socket(sqlsocket, inst) < 0) { radlog(L_ERR, "rlm_sql (%s): reconnect failed, database down?", inst->config->xlat_name); return -1; } /* retry the query on the newly connected socket */ ret = (inst->module->sql_fetch_row)(sqlsocket, inst->config); if (ret) { radlog(L_ERR, "rlm_sql (%s): failed after re-connect", inst->config->xlat_name); return -1; } } return ret;}/************************************************************************* * * Function: rlm_sql_query * * Purpose: call the module's sql_query and implement re-connect * *************************************************************************/int rlm_sql_query(SQLSOCK *sqlsocket, SQL_INST *inst, char *query){ int ret; /* * If there's no query, return an error. */ if (!query || !*query) { return -1; } ret = (inst->module->sql_query)(sqlsocket, inst->config, query); if (ret == SQL_DOWN) { /* close the socket that failed */ (inst->module->sql_close)(sqlsocket, inst->config); /* reconnect the socket */ if (connect_single_socket(sqlsocket, inst) < 0) { radlog(L_ERR, "rlm_sql (%s): reconnect failed, database down?", inst->config->xlat_name); return -1; } /* retry the query on the newly connected socket */ ret = (inst->module->sql_query)(sqlsocket, inst->config, query); if (ret) { radlog(L_ERR, "rlm_sql (%s): failed after re-connect", inst->config->xlat_name); return -1; } } return ret;}/************************************************************************* * * Function: rlm_sql_select_query * * Purpose: call the module's sql_select_query and implement re-connect * *************************************************************************/int rlm_sql_select_query(SQLSOCK *sqlsocket, SQL_INST *inst, char *query){ int ret; /* * If there's no query, return an error. */ if (!query || !*query) { return -1; } ret = (inst->module->sql_select_query)(sqlsocket, inst->config, query); if (ret == SQL_DOWN) { /* close the socket that failed */ (inst->module->sql_close)(sqlsocket, inst->config); /* reconnect the socket */ if (connect_single_socket(sqlsocket, inst) < 0) { radlog(L_ERR, "rlm_sql (%s): reconnect failed, database down?", inst->config->xlat_name); return -1; } /* retry the query on the newly connected socket */ ret = (inst->module->sql_select_query)(sqlsocket, inst->config, query); if (ret) { radlog(L_ERR, "rlm_sql (%s): failed after re-connect", inst->config->xlat_name); return -1; } } return ret;}/************************************************************************* * * Function: sql_getvpdata * * Purpose: Get any group check or reply pairs * *************************************************************************/int sql_getvpdata(SQL_INST * inst, SQLSOCK * sqlsocket, VALUE_PAIR **pair, char *query, int mode){ SQL_ROW row; int rows = 0; /* * If there's no query, return an error. */ if (!query || !*query) { return -1; } if (rlm_sql_select_query(sqlsocket, inst, query)) { radlog(L_ERR, "rlm_sql_getvpdata: database query error"); return -1; } while (rlm_sql_fetch_row(sqlsocket, inst)==0) { row = sqlsocket->row; if (!row) break; if (sql_userparse(pair, row, mode) != 0) { radlog(L_ERR | L_CONS, "rlm_sql (%s): Error getting data from database", inst->config->xlat_name); (inst->module->sql_finish_select_query)(sqlsocket, inst->config); return -1; } rows++; } (inst->module->sql_finish_select_query)(sqlsocket, inst->config); return rows;}void query_log(REQUEST *request, SQL_INST *inst, char *querystr){ FILE *sqlfile = NULL; if (inst->config->sqltrace) { char buffer[8192]; if (!radius_xlat(buffer, sizeof(buffer), inst->config->tracefile, request, NULL)) { radlog(L_ERR, "rlm_sql (%s): xlat failed.", inst->config->xlat_name); return; } if ((sqlfile = fopen(buffer, "a")) == (FILE *) NULL) { radlog(L_ERR, "rlm_sql (%s): Couldn't open file %s", inst->config->xlat_name, buffer); } else { int fd = fileno(sqlfile); rad_lockfd(fd, MAX_QUERY_LEN); fputs(querystr, sqlfile); fputs(";\n", sqlfile); fclose(sqlfile); /* and release the lock */ } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -