/* * Opens up a MySQL connection and returns the connection handle. */ MYSQL *db_conn(const char *host, const char *db, bool ssl) { MYSQL *ret; MYSQL *mysql; if (MULTI_TENANT) { char tenant[TENANT_MAX + 1]; char db[sizeof(tenant) + 3] = "rm_"; get_tenant(env_vars.host, tenant); strncat(db, tenant, TENANT_MAX); free(db_name); db_name = strdup(db); } mysql = mysql_init(NULL); if (ssl) mysql_ssl_set(mysql, NULL, NULL, NULL, NULL, "DHE-RSA-AES256-SHA:AES128-SHA"); ret = mysql_real_connect(mysql, host, DB_USER, DB_PASS, db, DB_PORT_NUM, DB_SOCKET_NAME, DB_FLAGS); if (!ret) { d_fprintf(error_log, "Failed to connect to database. Error: " "%s\n", mysql_error(mysql)); mysql = NULL; } return mysql; }
/* * This takes a sql query and returns the result set. * It also takes __func__ to get the name of the calling function. It also * logs the query into the sql log. * * This function should not be called directly and should instead be used via * the sql_query() macro. * * This function will either return a result set or NULL. Note that some * queries don't return result sets by design. */ MYSQL_RES *__sql_query(MYSQL *conn, const char *func, const char *fmt, ...) { va_list args; char sql[SQL_MAX]; int len; va_start(args, fmt); len = vsnprintf(sql, sizeof(sql), fmt, args); va_end(args); if (DEBUG_LEVEL) { char tenant[TENANT_MAX + 1]; char ts_buf[32]; time_t secs = time(NULL); struct tm *tm = localtime(&secs); get_tenant(env_vars.host, tenant); strftime(ts_buf, sizeof(ts_buf), "%F %T %z", tm); fprintf(sql_log, "[%s] %d %s %s: %s\n", ts_buf, getpid(), tenant, func, sql); fflush(sql_log); } mysql_real_query(conn, sql, len); return mysql_store_result(conn); }
/* * Create a new user session. This is done upon each successful login. */ void create_session(unsigned long long sid) { char session_id[SID_LEN + 1]; char restrict_ip[2] = "0\0"; char pkbuf[256]; char timestamp[21]; char ssid[21]; char tenant[TENANT_MAX + 1]; char *username; int primary_key_size; MYSQL_RES *res; TCTDB *tdb; TCMAP *cols; GHashTable *db_row = NULL; username = make_mysql_safe_string(get_var(qvars, "username")); res = sql_query("SELECT uid, name, capabilities FROM passwd WHERE " "username = '******'", username); db_row = get_dbrow(res); get_tenant(env_vars.host, tenant); generate_hash(session_id, SHA256); if (strcmp(get_var(qvars, "restrict_ip"), "true") == 0) { d_fprintf(debug_log, "Restricting session to origin ip " "address\n"); restrict_ip[0] = '1'; } tdb = tctdbnew(); tctdbopen(tdb, SESSION_DB, TDBOWRITER | TDBOCREAT); primary_key_size = sprintf(pkbuf, "%ld", (long)tctdbgenuid(tdb)); snprintf(timestamp, sizeof(timestamp), "%ld", (long)time(NULL)); snprintf(ssid, sizeof(ssid), "%llu", sid); cols = tcmapnew3("tenant", tenant, "sid", ssid, "uid", get_var(db_row, "uid"), "username", get_var(qvars, "username"), "name", get_var(db_row, "name"), "login_at", timestamp, "last_seen", timestamp, "origin_ip", env_vars.remote_addr, "client_id", env_vars.http_user_agent, "session_id", session_id, "csrf_token", "\0", "restrict_ip", restrict_ip, "capabilities", get_var(db_row, "capabilities"), NULL); tctdbput(tdb, pkbuf, primary_key_size, cols); tcmapdel(cols); tctdbclose(tdb); tctdbdel(tdb); fcgx_p("Set-Cookie: session_id=%s; path=/; httponly\r\n", session_id); mysql_free_result(res); free_vars(db_row); free(username); }