* This file is part of the oGRAC project.
* Copyright (c) 2024 Huawei Technologies Co.,Ltd.
*
* oGRAC is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* -------------------------------------------------------------------------
*
* ogsql_audit.c
*
*
* IDENTIFICATION
* src/ogsql/ogsql_audit.c
*
* -------------------------------------------------------------------------
*/
#include "ogsql_audit.h"
#include "srv_instance.h"
#include "ogsql_func.h"
#include "cm_util.h"
#include "ast.h"
#ifndef WIN32
#include <syslog.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct st_syslog_map {
const char *name;
int32_t id;
} syslog_map_t;
#ifdef WIN32
#define LOG_AUTH 0
#define LOG_AUTHPRIV 0
#define LOG_CRON 0
#define LOG_DAEMON 0
#define LOG_FTP 0
#define LOG_KERN 0
#define LOG_LOCAL0 0
#define LOG_LOCAL1 0
#define LOG_LOCAL2 0
#define LOG_LOCAL3 0
#define LOG_LOCAL4 0
#define LOG_LOCAL5 0
#define LOG_LOCAL6 0
#define LOG_LOCAL7 0
#define LOG_LPR 0
#define LOG_MAIL 0
#define LOG_NEWS 0
#define LOG_SYSLOG 0
#define LOG_USER 0
#define LOG_UUCP 0
#define LOG_EMERG 0
#define LOG_ALERT 0
#define LOG_CRIT 0
#define LOG_ERR 0
#define LOG_WARNING 0
#define LOG_NOTICE 0
#define LOG_INFO 0
#define LOG_DEBUG 0
#define OPEN_SYSLOG(ident, option, facility)
#define WRITE_SYSLOG(priority, format, ...)
#define CLOSE_SYSLOG()
#else
#define OPEN_SYSLOG(ident, option, facility) openlog(ident, option, facility)
#define WRITE_SYSLOG(priority, format, ...) syslog(priority, format, ##__VA_ARGS__)
#define CLOSE_SYSLOG() closelog()
#endif
static syslog_map_t g_syslog_facilitys[] = {
{ "AUTH", LOG_AUTH },
{ "AUTHPRIV", LOG_AUTHPRIV },
{ "CRON", LOG_CRON },
{ "DAEMON", LOG_DAEMON },
{ "FTP", LOG_FTP },
{ "KERN", LOG_KERN },
{ "LOCAL0", LOG_LOCAL0 },
{ "LOCAL1", LOG_LOCAL1 },
{ "LOCAL2", LOG_LOCAL2 },
{ "LOCAL3", LOG_LOCAL3 },
{ "LOCAL4", LOG_LOCAL4 },
{ "LOCAL5", LOG_LOCAL5 },
{ "LOCAL6", LOG_LOCAL6 },
{ "LOCAL7", LOG_LOCAL7 },
{ "LPR", LOG_LPR },
{ "MAIL", LOG_MAIL },
{ "NEWS", LOG_NEWS },
{ "SYSLOG", LOG_SYSLOG },
{ "USER", LOG_USER },
{ "UUCP", LOG_UUCP }
};
static syslog_map_t g_syslog_prioritys[] = {
{ "EMERG", LOG_EMERG },
{ "ALERT", LOG_ALERT },
{ "CRIT", LOG_CRIT },
{ "ERR", LOG_ERR },
{ "WARNING", LOG_WARNING },
{ "NOTICE", LOG_NOTICE },
{ "INFO", LOG_INFO },
{ "DEBUG", LOG_DEBUG }
};
#define SYSLOG_FACILITY_CNT (sizeof(g_syslog_facilitys) / sizeof(syslog_map_t))
#define SYSLOG_PRIORITY_CNT (sizeof(g_syslog_prioritys) / sizeof(syslog_map_t))
status_t sql_parse_audit_trail_mode(const char *str_trail_mode, uint8_t *mode)
{
if (cm_str_equal_ins(str_trail_mode, "FILE")) {
*mode = AUDIT_TRAIL_FILE;
} else if (cm_str_equal_ins(str_trail_mode, "ALL")) {
*mode = AUDIT_TRAIL_ALL;
} else if (cm_str_equal_ins(str_trail_mode, "DB")) {
*mode = AUDIT_TRAIL_DB;
} else if (cm_str_equal_ins(str_trail_mode, "SYSLOG")) {
*mode = AUDIT_TRAIL_SYSLOG;
} else if (cm_str_equal_ins(str_trail_mode, "NONE")) {
*mode = AUDIT_TRAIL_NONE;
} else {
OG_THROW_ERROR(ERR_SQL_SYNTAX_ERROR, "Only ALL/FILE/DB/SYSLOG/NONE for AUDIT_TRAIL_MODE parameter");
return OG_ERROR;
}
return OG_SUCCESS;
}
status_t sql_parse_audit_syslog(char *str_audit_syslog, audit_log_param_t *audit_log_param)
{
text_t syslog_audit;
text_t syslog_facility;
text_t syslog_priority;
uint32 i;
syslog_audit.str = str_audit_syslog;
syslog_audit.len = (uint32_t)strlen(str_audit_syslog);
cm_split_text(&syslog_audit, '.', '\0', &syslog_facility, &syslog_priority);
for (i = 0; i < SYSLOG_FACILITY_CNT; i++) {
if (cm_compare_text_str_ins(&syslog_facility, g_syslog_facilitys[i].name) == 0) {
audit_log_param->syslog_facility = g_syslog_facilitys[i].id;
break;
}
}
if (i == SYSLOG_FACILITY_CNT) {
OG_THROW_ERROR(ERR_SQL_SYNTAX_ERROR, "invalid facility value for AUDIT_SYSLOG_LEVEL parameter");
return OG_ERROR;
}
for (i = 0; i < SYSLOG_PRIORITY_CNT; i++) {
if (cm_compare_text_str_ins(&syslog_priority, g_syslog_prioritys[i].name) == 0) {
audit_log_param->syslog_level = g_syslog_prioritys[i].id;
break;
}
}
if (i == SYSLOG_PRIORITY_CNT) {
OG_THROW_ERROR(ERR_SQL_SYNTAX_ERROR, "invalid priority value for AUDIT_SYSLOG_LEVEL parameter");
return OG_ERROR;
}
return OG_SUCCESS;
}
void sql_auditlog_init(const audit_log_param_t *audit_log_param)
{
if (audit_log_param->audit_trail_mode & AUDIT_TRAIL_SYSLOG) {
OPEN_SYSLOG("oGRACd", LOG_CONS | LOG_PID, audit_log_param->syslog_facility);
}
}
void sql_auditlog_deinit(const audit_log_param_t *audit_log_param)
{
if (audit_log_param->audit_trail_mode & AUDIT_TRAIL_SYSLOG) {
CLOSE_SYSLOG();
}
}
void sql_auditlog_reinit(const audit_log_param_t *old_audit_log_param, const audit_log_param_t *audit_log_param)
{
if (!(audit_log_param->audit_trail_mode & AUDIT_TRAIL_SYSLOG)) {
if (old_audit_log_param->audit_trail_mode & AUDIT_TRAIL_SYSLOG) {
CLOSE_SYSLOG();
}
return;
}
if (old_audit_log_param->audit_trail_mode & AUDIT_TRAIL_SYSLOG) {
if (old_audit_log_param->syslog_facility == audit_log_param->syslog_facility) {
return;
} else {
CLOSE_SYSLOG();
}
}
OPEN_SYSLOG("oGRACd", LOG_CONS | LOG_PID, audit_log_param->syslog_facility);
return;
}
static inline void sql_get_dml_text(session_t *session, text_t *sql, vmc_t *vmc)
{
sql_stmt_t *stmt = session->current_stmt;
uint32 cmd = (uint32)session->agent->recv_pack.head->cmd;
if (cmd != CS_CMD_EXECUTE && cmd != CS_CMD_FETCH) {
return;
}
#if ((defined DB_DEBUG_VERSION) || (defined OG_OGRACD_PARAM_LOG))
if (stmt != NULL && stmt->lang_type == LANG_PL && stmt->context != NULL) {
pl_entity_t *entity = stmt->pl_context;
pl_line_ctrl_t *line = (pl_line_ctrl_t *)entity->anonymous->body;
if (line->type == LINE_PROC) {
pl_line_normal_t *proc_line = (pl_line_normal_t *)line;
if (proc_line->proc->type == EXPR_NODE_USER_PROC) {
sql->str = proc_line->proc->word.func.name.str;
sql->len = proc_line->proc->word.func.name.len;
return;
}
}
}
#endif
if (stmt == NULL || stmt->lang_type != LANG_DML ||
stmt->context == NULL) {
return;
}
if (vmc_alloc(vmc, stmt->context->ctrl.text_size + 1, (void **)&sql->str) != OG_SUCCESS) {
sql->len = 0;
return;
}
sql->len = stmt->context->ctrl.text_size + 1;
if (ogx_read_text(sql_pool, &stmt->context->ctrl, sql, OG_FALSE) != OG_SUCCESS) {
sql->len = 0;
return;
}
}
static void sql_get_text(session_t *session, text_t *sql, vmc_t *vmc)
{
if (session->sql_audit.packet_sql.len > 0) {
*sql = session->sql_audit.packet_sql;
} else if (session->pipe != NULL) {
sql_get_dml_text(session, sql, vmc);
}
}
static void write_audit_syslog(const char *format, ...)
{
char audit_msg[OG_T2S_LARGER_BUFFER_SIZE];
va_list var_list;
va_start(var_list, format);
if (vsnprintf_s(audit_msg, OG_T2S_LARGER_BUFFER_SIZE, OG_T2S_LARGER_BUFFER_SIZE - 1, format, var_list) < 0) {
va_end(var_list);
return;
}
va_end(var_list);
WRITE_SYSLOG(cm_log_param_instance()->audit_param.syslog_level, "%s", audit_msg);
}
static void sql_get_params(sql_stmt_t *stmt, char *buf, uint32 buf_len, write_audit_log_func audit_func)
{
uint32 i;
uint32 count;
sql_param_t *param;
variant_t value;
text_buf_t buffer;
int32 type = OG_TYPE_UNKNOWN;
CM_INIT_TEXTBUF(&buffer, buf_len, buf);
count = stmt->context->params->count;
audit_func("SESSIONID=[%u], PARAMS-SIZE:[%u], PARAMS-COUNT:[%u]", stmt->session->knl_session.id,
stmt->param_info.paramset_size, count);
for (i = 0; i < count; i++) {
char *data = NULL;
uint32 length = 0;
param = &stmt->param_info.params[i];
var_copy(¶m->value, &value);
type = value.type;
if (value.is_null) {
audit_func("SESSIONID=[%u],PARAM-VALUE:id=[%u],direct=[%d],type=[%d],len=[%d],value=[NULL]",
stmt->session->knl_session.id, i, param->direction, type, -1);
continue;
}
switch (type) {
case OG_TYPE_UINT32:
case OG_TYPE_INTEGER:
case OG_TYPE_BIGINT:
case OG_TYPE_REAL:
case OG_TYPE_NUMBER:
case OG_TYPE_NUMBER2:
case OG_TYPE_DECIMAL:
case OG_TYPE_DATE:
case OG_TYPE_TIMESTAMP:
case OG_TYPE_BOOLEAN:
case OG_TYPE_TIMESTAMP_TZ_FAKE:
case OG_TYPE_TIMESTAMP_TZ:
case OG_TYPE_TIMESTAMP_LTZ:
if (var_as_string(SESSION_NLS(stmt), &value, &buffer) != OG_SUCCESS) {
continue;
}
data = value.v_text.str;
length = value.v_text.len;
break;
case OG_TYPE_BINARY:
case OG_TYPE_VARBINARY:
case OG_TYPE_RAW:
if (var_as_string(SESSION_NLS(stmt), &value, &buffer) != OG_SUCCESS) {
continue;
}
data = value.v_text.str;
length = value.v_text.len;
break;
case OG_TYPE_CLOB:
case OG_TYPE_BLOB:
case OG_TYPE_IMAGE:
data = "LOB";
length = sql_get_lob_var_length(&value);
break;
case OG_TYPE_CHAR:
case OG_TYPE_VARCHAR:
case OG_TYPE_STRING:
data = value.v_text.str;
length = value.v_text.len;
break;
default:
audit_func("SESSIONID=[%u],PARAM-VALUE:id=[%u],direct=[%d],type=[%d],len=[-2],value=[NULL]",
stmt->session->knl_session.id, i, param->direction, type);
continue;
}
if (!OG_IS_LOB_TYPE(type) && length > 0) {
data[length] = '\0';
}
audit_func("SESSIONID=[%u],PARAM-VALUE:id=[%u],direct=[%d],type=[%d],len=[%u],value=[%s]",
stmt->session->knl_session.id, i, param->direction, type, length, (length == 0) ? "" : data);
}
audit_func("\n");
}
static void sql_ignore_passwd_log_core(session_t *session, text_t *sql_text)
{
bool32 matched = OG_FALSE;
int32 match_type;
cm_text_try_map_key2type(&session->sql_audit.sql, &match_type, &matched);
if (!matched) {
return;
}
text_t l_text;
text_t r_text;
text_t sub_text;
char *pattern_str = g_key_pattern[match_type].type_desc;
uint32 pattern_len = (uint32)strlen(pattern_str);
cm_str2text("begin", &sub_text);
if (cm_text_split(&session->sql_audit.sql, &sub_text, &l_text, &r_text)) {
sql_text->len = l_text.len + pattern_len;
sql_text->str = (char *)cm_push(session->stack, (uint32)(sql_text->len + 1));
if (sql_text->str == NULL) {
return;
}
(void)cm_text2str(&l_text, sql_text->str, sql_text->len);
MEMS_RETVOID_IFERR(strncpy_s(sql_text->str + l_text.len, pattern_len + 1, pattern_str, pattern_len));
} else {
sql_text->len = pattern_len;
sql_text->str = (char *)cm_push(session->stack, (uint32)(sql_text->len + 1));
if (sql_text->str == NULL) {
return;
}
MEMS_RETVOID_IFERR(strncpy_s(sql_text->str, sql_text->len + 1, pattern_str, pattern_len));
}
}
void sql_ignore_passwd_log(void *session, text_t *sql_text)
{
session_t *sess = (session_t *)session;
if (sess->sql_audit.need_ignore_pwd && sql_text->len != 0) {
if (sess->sql_audit.need_copy_sql) {
sql_ignore_passwd_log_core(sess, sql_text);
} else {
sql_text->str = (char *)cm_push(sess->stack, (uint32)(sql_text->len + 1));
if (sql_text->str == NULL) {
return;
}
MEMS_RETVOID_IFERR(
strncpy_s(sql_text->str, sql_text->len + 1, sess->sql_audit.sql.str, sess->sql_audit.sql.len));
cm_text_star_to_one(sql_text);
}
}
}
static status_t db_write_sysaudit(knl_session_t *session, audit_t *audit_key, text_t *sql_text)
{
uint32 max_size;
row_assist_t row_ass;
table_t *table = NULL;
char *buffer = NULL;
status_t status;
errno_t ret;
CM_SAVE_STACK(session->stack);
knl_cursor_t *cursor = knl_push_cursor(session);
uint32 buffer_len = sql_text->len + 1;
if (sql_text->len > OG_MAX_VARCHAR_LEN) {
buffer_len = OG_MAX_VARCHAR_LEN;
}
cursor->row = (row_head_t *)cursor->buf;
buffer = (char *)cm_push(session->stack, buffer_len);
ret = memset_sp(buffer, buffer_len, 0, buffer_len);
if (ret != EOK) {
CM_RESTORE_STACK(session->stack);
OG_THROW_ERROR(ERR_SYSTEM_CALL, ret);
return OG_ERROR;
}
if (sql_text->len != 0) {
(void)cm_text2str(sql_text, buffer, buffer_len);
}
max_size = session->kernel->attr.max_row_size;
knl_open_sys_cursor(session, cursor, CURSOR_ACTION_INSERT, SYS_AUDIT_ID, OG_INVALID_ID32);
table = (table_t *)cursor->table;
row_init(&row_ass, (char *)cursor->row, max_size, table->desc.column_count);
(void)row_put_str(&row_ass, audit_key->ctime);
(void)row_put_int32(&row_ass, audit_key->sessionid);
(void)row_put_int32(&row_ass, audit_key->stmtid);
(void)row_put_str(&row_ass, audit_key->username);
(void)row_put_str(&row_ass, audit_key->hostname);
(void)row_put_str(&row_ass, audit_key->action);
(void)row_put_int32(&row_ass, audit_key->returncode);
(void)row_put_str(&row_ass, buffer);
status = knl_internal_insert(session, cursor);
CM_RESTORE_STACK(session->stack);
return status;
}
static void sql_record_para_audit_log(void *session, char *log_msg, uint8 audit_trail_mode)
{
session_t *sess = (session_t *)session;
write_audit_log_func audit_func = NULL;
if ((cm_log_param_instance()->audit_param.audit_level & (uint32)SQL_AUDIT_PARAM) == 0) {
return;
}
audit_func = (audit_trail_mode == AUDIT_TRAIL_SYSLOG ? write_audit_syslog : cm_write_audit_log);
if (sess->current_stmt != NULL && sess->pipe != NULL &&
strcmp(sess->sql_audit.action, SQL_AUDIT_ACTION_DISCONNECT) != 0) {
uint32 cmd = (uint32)sess->agent->recv_pack.head->cmd;
if ((cmd == CS_CMD_EXECUTE || cmd == CS_CMD_PREP_AND_EXEC) &&
(sess->current_stmt->context != NULL && sess->current_stmt->context->params != NULL &&
sess->current_stmt->context->params->count != 0) &&
(sess->current_stmt->param_info.params != NULL && sess->current_stmt->params_ready == OG_TRUE)) {
sql_get_params(sess->current_stmt, log_msg, OG_T2S_LARGER_BUFFER_SIZE - 1, audit_func);
}
}
}
static void sql_audit_init_assist(audit_assist_t *audit_ass, session_t *session, status_t status)
{
int iret_snprintf;
int tz_hour;
int tz_min;
const char *err_msg = NULL;
audit_ass->sql_text = session->sql_audit.sql;
sql_ignore_passwd_log(session, &audit_ass->sql_text);
audit_ass->action = session->sql_audit.action;
MEMS_RETVOID_IFERR(strcpy_s(audit_ass->db_user, OG_NAME_BUFFER_SIZE, session->db_user));
MEMS_RETVOID_IFERR(strcpy_s(audit_ass->os_host, OG_HOST_NAME_BUFFER_SIZE, session->os_host));
audit_ass->tz = g_timer()->tz;
tz_hour = TIMEZONE_GET_HOUR(audit_ass->tz);
tz_min = TIMEZONE_GET_MINUTE(audit_ass->tz);
if (tz_hour >= 0) {
iret_snprintf =
snprintf_s(audit_ass->date, OG_MAX_TIME_STRLEN, OG_MAX_TIME_STRLEN - 1, "UTC+%02d:%02d ", tz_hour, tz_min);
} else {
iret_snprintf =
snprintf_s(audit_ass->date, OG_MAX_TIME_STRLEN, OG_MAX_TIME_STRLEN - 1, "UTC%02d:%02d ", tz_hour, tz_min);
}
if (iret_snprintf == -1) {
OG_THROW_ERROR(ERR_SYSTEM_CALL, iret_snprintf);
return;
}
(void)cm_date2str(g_timer()->now, "yyyy-mm-dd hh24:mi:ss.ff3", audit_ass->date + iret_snprintf,
OG_MAX_TIME_STRLEN - iret_snprintf);
audit_ass->sid = (int32)session->knl_session.id;
audit_ass->session_id.str = audit_ass->session_buf;
cm_int2text(audit_ass->sid, &audit_ass->session_id);
audit_ass->session_id.str[audit_ass->session_id.len] = '\0';
audit_ass->stmt_id.len = 0;
audit_ass->stmt_id.str = audit_ass->stmt_buf;
if (session->current_stmt != NULL) {
audit_ass->stmtid = (int32)session->current_stmt->id;
cm_int2text(audit_ass->stmtid, &audit_ass->stmt_id);
}
audit_ass->stmt_id.str[audit_ass->stmt_id.len] = '\0';
audit_ass->return_code.str = audit_ass->return_code_buf;
audit_ass->code = 0;
if (status != OG_SUCCESS) {
cm_get_error(&audit_ass->code, &err_msg, NULL);
}
PRTS_RETVOID_IFERR(
snprintf_s(audit_ass->return_code_buf, OG_MAX_NUMBER_LEN, OG_MAX_NUMBER_LEN - 1, "OG-%05d", audit_ass->code));
audit_ass->return_code.len = (uint32)strlen(audit_ass->return_code_buf);
audit_ass->return_code.str[audit_ass->return_code.len] = '\0';
}
static void sql_audit_write_systab(audit_assist_t *audit_ass, knl_session_t *knl_session)
{
audit_t audit_key;
status_t stat;
audit_key.action = audit_ass->action;
audit_key.ctime = audit_ass->date;
audit_key.hostname = audit_ass->os_host;
audit_key.sessionid = audit_ass->sid;
audit_key.stmtid = audit_ass->stmtid;
audit_key.username = audit_ass->db_user;
audit_key.returncode = audit_ass->code;
if (knl_begin_auton_rm(knl_session) != OG_SUCCESS) {
return;
}
stat = db_write_sysaudit(knl_session, &audit_key, &audit_ass->sql_text);
if (stat == OG_ERROR) {
if (g_instance->audit_log_warning == OG_FALSE) {
OG_LOG_ALARM(WARN_AUDITLOG, "'instance-name':'%s'}", g_instance->kernel.instance_name);
g_instance->audit_log_warning = OG_TRUE;
}
knl_end_auton_rm(knl_session, OG_ERROR);
OG_LOG_RUN_WAR("write audit log table error");
return;
}
if (g_instance->audit_log_warning == OG_TRUE) {
OG_LOG_ALARM_RECOVER(WARN_AUDITLOG, "'instance-name':'%s'}", g_instance->kernel.instance_name);
g_instance->audit_log_warning = OG_FALSE;
}
knl_end_auton_rm(knl_session, OG_SUCCESS);
}
static void sql_audit_create_message(audit_assist_t *audit_ass, char *log_msg, uint32 *log_msg_len)
{
int iret_snprintf;
iret_snprintf = snprintf_s(log_msg, OG_T2S_LARGER_BUFFER_SIZE, OG_T2S_LARGER_BUFFER_SIZE - 1,
"SESSIONID:[%u] \"%s\" STMTID:[%u] \"%s\" USER:[%u] \"%s\" "
"HOST:[%u] \"%s\" ACTION:[%u] \"%s\" RETURNCODE:[%u] \"%s\" "
"SQLTEXT:[%u] \"",
audit_ass->session_id.len, audit_ass->session_id.str,
audit_ass->stmt_id.len, audit_ass->stmt_id.str,
(uint32)strlen(audit_ass->db_user), audit_ass->db_user,
(uint32)strlen(audit_ass->os_host), audit_ass->os_host,
(uint32)strlen(audit_ass->action), audit_ass->action,
audit_ass->return_code.len, audit_ass->return_code.str,
audit_ass->sql_text.len);
PRTS_RETVOID_IFERR(iret_snprintf);
if (iret_snprintf > OG_T2S_LARGER_BUFFER_SIZE - 1) {
*log_msg_len = OG_T2S_LARGER_BUFFER_SIZE - 1;
log_msg[OG_T2S_LARGER_BUFFER_SIZE - 1] = '\0';
return;
}
*log_msg_len = (uint32)iret_snprintf + audit_ass->sql_text.len + 1;
if (*log_msg_len > OG_T2S_LARGER_BUFFER_SIZE - 1) {
*log_msg_len = OG_T2S_LARGER_BUFFER_SIZE - 1;
}
if (*log_msg_len > (uint32)iret_snprintf + 1) {
MEMS_RETVOID_IFERR(memcpy_s(log_msg + iret_snprintf, *log_msg_len - (uint32)iret_snprintf,
audit_ass->sql_text.str,
MIN(*log_msg_len - (uint32)iret_snprintf, audit_ass->sql_text.len)));
}
log_msg[*log_msg_len - 1] = '\"';
log_msg[*log_msg_len] = '\0';
}
void sql_audit_log(void *sess, status_t status, bool8 ignore_sql, bool8 is_log_param)
{
char *log_msg = cm_get_t2s_addr();
uint32 log_msg_len;
audit_assist_t audit_ass;
session_t *session = (session_t *)sess;
vmc_t vmc;
if (cm_log_param_instance()->audit_param.audit_trail_mode == AUDIT_TRAIL_NONE && is_log_param == OG_FALSE) {
return;
}
vmc_init(&session->vmp, &vmc);
session->sql_audit.sql.len = 0;
if (!ignore_sql) {
sql_get_text(session, &session->sql_audit.sql, &vmc);
}
sql_audit_init_assist(&audit_ass, session, status);
if (cm_log_param_instance()->audit_param.audit_trail_mode & AUDIT_TRAIL_FILE) {
sql_audit_create_message(&audit_ass, log_msg, &log_msg_len);
OG_LOG_AUDIT("%s\nLENGTH: \"%u\"\n%s\n", audit_ass.date, log_msg_len, log_msg);
sql_record_para_audit_log(sess, log_msg, AUDIT_TRAIL_FILE);
}
if (knl_get_db_status(&session->knl_session) == DB_STATUS_OPEN &&
knl_get_db_open_status(&session->knl_session) == DB_OPEN_STATUS_NORMAL &&
(cm_log_param_instance()->audit_param.audit_trail_mode & AUDIT_TRAIL_DB)) {
sql_audit_write_systab(&audit_ass, &session->knl_session);
}
if (cm_log_param_instance()->audit_param.audit_trail_mode & AUDIT_TRAIL_SYSLOG) {
sql_audit_create_message(&audit_ass, log_msg, &log_msg_len);
WRITE_SYSLOG(cm_log_param_instance()->audit_param.syslog_level, "LENGTH: \"%u\" %s\n", log_msg_len, log_msg);
sql_record_para_audit_log(sess, log_msg, AUDIT_TRAIL_SYSLOG);
}
vmc_free(&vmc);
}
void sql_record_audit_log(void *sess, status_t status, bool8 ignore_sql)
{
if ((cm_log_param_instance()->audit_param.audit_level & ((session_t *)sess)->sql_audit.audit_type) == 0) {
return;
}
sql_audit_log(sess, status, ignore_sql, OG_FALSE);
}
static void sql_audit_init_assist_ddos(audit_assist_t *audit_ass, const char *ip_str)
{
int iret_snprintf;
int tz_hour;
int tz_min;
const char *msg = NULL;
audit_ass->sql_text = g_null_text;
audit_ass->action = SQL_AUDIT_ACTION_INVALID_ADDRESS_DISCONNECT;
audit_ass->db_user[0] = '\0';
MEMS_RETVOID_IFERR(strcpy_s(audit_ass->os_host, OG_HOST_NAME_BUFFER_SIZE, ip_str));
audit_ass->tz = g_timer()->tz;
tz_hour = TIMEZONE_GET_HOUR(audit_ass->tz);
tz_min = TIMEZONE_GET_MINUTE(audit_ass->tz);
if (tz_hour >= 0) {
iret_snprintf =
snprintf_s(audit_ass->date, OG_MAX_TIME_STRLEN, OG_MAX_TIME_STRLEN - 1, "UTC+%02d:%02d ", tz_hour, tz_min);
} else {
iret_snprintf =
snprintf_s(audit_ass->date, OG_MAX_TIME_STRLEN, OG_MAX_TIME_STRLEN - 1, "UTC%02d:%02d ", tz_hour, tz_min);
}
if (iret_snprintf == -1) {
OG_THROW_ERROR(ERR_SYSTEM_CALL, iret_snprintf);
return;
}
(void)cm_date2str(g_timer()->now, "yyyy-mm-dd hh24:mi:ss.ff3", audit_ass->date + iret_snprintf,
OG_MAX_TIME_STRLEN - iret_snprintf);
audit_ass->sid = 0;
audit_ass->session_id = g_null_text;
audit_ass->stmtid = 0;
audit_ass->stmt_id = g_null_text;
cm_get_error(&audit_ass->code, &msg, NULL);
audit_ass->return_code.str = audit_ass->return_code_buf;
PRTS_RETVOID_IFERR(
snprintf_s(audit_ass->return_code_buf, OG_MAX_NUMBER_LEN, OG_MAX_NUMBER_LEN - 1, "OG-%05d", audit_ass->code));
audit_ass->return_code.len = (uint32)strlen(audit_ass->return_code_buf);
audit_ass->return_code.str[audit_ass->return_code.len] = '\0';
}
void sql_audit_log_ddos(const char *ip_str)
{
audit_assist_t audit_ass;
char *log_msg = cm_get_t2s_addr();
uint32 log_msg_len;
if (cm_log_param_instance()->audit_param.audit_level == 0) {
return;
}
sql_audit_init_assist_ddos(&audit_ass, ip_str);
if (cm_log_param_instance()->audit_param.audit_trail_mode == AUDIT_TRAIL_FILE ||
cm_log_param_instance()->audit_param.audit_trail_mode == AUDIT_TRAIL_ALL) {
sql_audit_create_message(&audit_ass, log_msg, &log_msg_len);
OG_LOG_AUDIT("%s\nLENGTH: \"%u\"\n%s\n", audit_ass.date, log_msg_len, log_msg);
}
}
#ifdef __cplusplus
}
#endif