📄 sql.c
字号:
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){ VALUE_PAIR *pair, *check; char *ptr, *value; char buf[MAX_STRING_LEN]; char do_xlat = 0; LRAD_TOKEN token, operator = T_EOL; /* * Verify the 'Attribute' field */ if (row[2] == NULL || row[2][0] == '\0') { radlog(L_ERR, "rlm_sql: The 'Attribute' field is empty or NULL, skipping the entire row."); return -1; } /* * Verify the 'op' field */ if (row[4] != NULL && row[4][0] != '\0') { ptr = row[4]; operator = gettoken(&ptr, buf, sizeof(buf)); } if (operator <= T_EOL) { /* * Complain about empty or invalid 'op' field */ operator = T_OP_CMP_EQ; 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."); } /* * The 'Value' field may be empty or NULL */ value = row[3]; /* * If we have a new-style quoted string, where the * *entire* string is quoted, do xlat's. */ if (row[3] != NULL && ((row[3][0] == '\'') || (row[3][0] == '`') || (row[3][0] == '"')) && (row[3][0] == row[3][strlen(row[3])-1])) { token = gettoken(&value, buf, sizeof(buf)); switch (token) { /* * Take the unquoted string. */ case T_SINGLE_QUOTED_STRING: case T_DOUBLE_QUOTED_STRING: value = buf; break; /* * Mark the pair to be allocated later. */ case T_BACK_QUOTED_STRING: value = NULL; do_xlat = 1; break; /* * Keep the original string. */ default: value = row[3]; break; } } /* * Create the pair */ pair = pairmake(row[2], value, operator); if (pair == NULL) { radlog(L_ERR, "rlm_sql: Failed to create the pair: %s", librad_errstr); return -1; } if (do_xlat) { pair->flags.do_xlat = 1; strNcpy(pair->strvalue, buf, sizeof(pair->strvalue)); pair->length = 0; } /* * If attribute is already there, skip it because we * checked usercheck first and we want user settings to * override group settings */ if (operator != T_OP_ADD && (check = pairfind(*first_pair, pair->attribute)) != NULL &&#ifdef ASCEND_BINARY pair->type != PW_TYPE_ABINARY &&#endif querymode == PW_VP_GROUPDATA) { pairbasicfree(pair); return 0; } /* * Add the pair into the packet */ 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 + -