summaryrefslogtreecommitdiffstats
path: root/src/modules/rlm_sql/rlm_sql.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/rlm_sql/rlm_sql.h')
-rw-r--r--src/modules/rlm_sql/rlm_sql.h258
1 files changed, 258 insertions, 0 deletions
diff --git a/src/modules/rlm_sql/rlm_sql.h b/src/modules/rlm_sql/rlm_sql.h
new file mode 100644
index 0000000..5af8db4
--- /dev/null
+++ b/src/modules/rlm_sql/rlm_sql.h
@@ -0,0 +1,258 @@
+/*
+ * This program is is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * $Id$
+ * @file rlm_sql.h
+ * @brief Prototypes and functions for the SQL module
+ *
+ * @copyright 2012-2014 Arran Cudbard-Bell <a.cudbardb@freeradius.org>
+ * @copyright 2000,2006 The FreeRADIUS server project
+ * @copyright 2000 Mike Machado <mike@innercite.com>
+ * @copyright 2000 Alan DeKok <aland@ox.org>
+ */
+#ifndef _RLM_SQL_H
+#define _RLM_SQL_H
+
+RCSIDH(rlm_sql_h, "$Id$")
+
+#include <freeradius-devel/radiusd.h>
+#include <freeradius-devel/connection.h>
+#include <freeradius-devel/modpriv.h>
+#include <freeradius-devel/exfile.h>
+
+#define MOD_PREFIX "rlm_sql"
+
+#define PW_ITEM_CHECK 0
+#define PW_ITEM_REPLY 1
+
+
+/* SQL Errors */
+typedef enum {
+ RLM_SQL_QUERY_INVALID = -3, //!< Query syntax error.
+ RLM_SQL_ERROR = -2, //!< General connection/server error.
+ RLM_SQL_OK = 0, //!< Success.
+ RLM_SQL_RECONNECT = 1, //!< Stale connection, should reconnect.
+ RLM_SQL_ALT_QUERY, //!< Key constraint violation, use an alternative query.
+ RLM_SQL_NO_MORE_ROWS, //!< No more rows available
+} sql_rcode_t;
+
+typedef enum {
+ FALL_THROUGH_NO = 0,
+ FALL_THROUGH_YES,
+ FALL_THROUGH_DEFAULT,
+} sql_fall_through_t;
+
+
+typedef char **rlm_sql_row_t;
+
+typedef struct sql_log_entry {
+ log_type_t type; //!< Type of log entry L_ERR, L_WARN, L_INFO, L_DBG etc..
+ char const *msg; //!< Log message.
+} sql_log_entry_t;
+
+/*
+ * Sections where we dynamically resolve the config entry to use,
+ * by xlating reference.
+ */
+typedef struct sql_acct_section {
+ CONF_SECTION *cs; //!< The CONF_SECTION representing the group
+ //!< of queries to process.
+
+ char const *reference; //!< Reference string, expanded to point to
+ //!< a group of queries.
+ bool reference_cp;
+
+ char const *logfile;
+
+ char const *query; /* for xlat parsing */
+} sql_acct_section_t;
+
+typedef struct sql_config {
+ char const *sql_driver_name; //!< SQL driver module name e.g. rlm_sql_sqlite.
+ char const *sql_server; //!< Server to connect to.
+ uint32_t sql_port; //!< Port to connect to.
+ char const *sql_login; //!< Login credentials to use.
+ char const *sql_password; //!< Login password to use.
+ char const *sql_db; //!< Database to run queries against.
+
+ char const *query_user; //!< xlat expansion used to specify the user
+ //!< to use as the subject of queries.
+
+ char const *default_profile; //!< Default profile to use if no other
+ //!< profiles were configured.
+
+ char const *client_query; //!< Query used to get FreeRADIUS client
+ //!< definitions.
+
+ char const *authorize_check_query; //!< Query used get check VPs for a user.
+ char const *authorize_reply_query; //!< Query used get reply VPs for a user.
+ char const *authorize_group_check_query; //!< Query used get check VPs for a group.
+ char const *authorize_group_reply_query; //!< Query used get reply VPs for a group.
+ char const *simul_count_query; //!< Query used get number of active sessions
+ //!< for a user (basic simultaneous use check).
+ char const *simul_verify_query; //!< Query to get active sessions for a user
+ //!< the result is fed to session_zap.
+ char const *groupmemb_query; //!< Query to determine group membership.
+
+ bool do_clients; //!< Read clients from SQL database.
+ bool read_groups; //!< Read user groups by default.
+ //!< If false, Fall-Through = yes is required
+ //!< in the previous reply list to process
+ //!< groups.
+ bool read_profiles; //!< Read user profiles by default.
+ //!< If false, Fall-Through = yes is required
+ //!< in the previous reply list to process
+ //!< profiles.
+ char const *logfile; //!< Keep a log of all SQL queries executed
+ //!< Useful for batch insertion with the
+ //!< NULL drivers.
+
+ bool delete_stale_sessions; //!< Whether we should use session_zap to create
+ //!< a fake stop packet, to terminate any
+ //!< stale sessions.
+
+ char const *allowed_chars; //!< Chars which done need escaping..
+ bool driver_specific_escape; //!< Use the driver specific SQL escape method
+ uint32_t query_timeout; //!< How long to allow queries to run for.
+
+ char const *connect_query; //!< Query executed after establishing
+ //!< new connection.
+ struct timeval connect_timeout_tv; //!< Connection timeout timeval.
+ uint32_t connect_timeout_ms; //!< Connection timeout ms.
+ uint32_t connect_timeout_s; //!< Connection timeout in seconds.
+
+ void *driver; //!< Where drivers should write a
+ //!< pointer to their configurations.
+
+ /*
+ * @todo The rest of the queries should also be moved into
+ * their own sections.
+ */
+
+ /*
+ * Section configurations
+ */
+ sql_acct_section_t postauth;
+ sql_acct_section_t accounting;
+} rlm_sql_config_t;
+
+typedef struct sql_inst rlm_sql_t;
+
+typedef struct rlm_sql_handle {
+ void *conn; //!< Database specific connection handle.
+ rlm_sql_row_t row; //!< Row data from the last query.
+ rlm_sql_t *inst; //!< The rlm_sql instance this connection belongs to.
+ TALLOC_CTX *log_ctx; //!< Talloc pool used to avoid mallocing memory on
+ //!< when log strings need to be copied.
+} rlm_sql_handle_t;
+
+extern const FR_NAME_NUMBER sql_rcode_table[];
+/*
+ * Capabilities flags for drivers
+ */
+#define RLM_SQL_RCODE_FLAGS_ALT_QUERY 1 //!< Can distinguish between other errors and those
+ //!< resulting from a unique key violation.
+
+/** Retrieve errors from the last query operation
+ *
+ * @note Buffers allocated in the context provided will be automatically freed. The driver
+ * should not free these buffers explicitly.
+ * @note If the driver uses its own buffers to aggregate messages, they should be cleared
+ * on sql_query_finish, and after each call to sql_error, to prevent the same messages
+ * being printed multiple times.
+ *
+ * @param[in,out] ctx to allocate any buffers required. If static buffers are provided by the
+ * driver they need not be strduped, just write the pointer to those buffers to the .msg
+ * field of a sql_log_entry_t element.
+ * @param[out] out a pre-allocated array of log entries to fill. Need not be NULL terminated.
+ * @param[in] outlen Number of log entries available for populating. Do not write to index
+ * out[outlen] or higher.
+ * @param[in] handle to retrieve errors from.
+ * @param[in] config of the SQL instance.
+ * @return
+ * 0 - If no error messages are available.
+ * >0 - Number of log entries
+ */
+typedef size_t (*sql_error_t)(TALLOC_CTX *ctx, sql_log_entry_t out[], size_t outlen, rlm_sql_handle_t *handle,
+ rlm_sql_config_t *config);
+
+typedef struct rlm_sql_module_t {
+ char const *name;
+ int flags;
+
+ sql_rcode_t (*mod_instantiate)(CONF_SECTION *conf, rlm_sql_config_t *config);
+ sql_rcode_t (*sql_socket_init)(rlm_sql_handle_t *handle, rlm_sql_config_t *config);
+
+ sql_rcode_t (*sql_query)(rlm_sql_handle_t *handle, rlm_sql_config_t *config, char const *query);
+ sql_rcode_t (*sql_select_query)(rlm_sql_handle_t *handle, rlm_sql_config_t *config, char const *query);
+ sql_rcode_t (*sql_store_result)(rlm_sql_handle_t *handle, rlm_sql_config_t *config);
+
+ int (*sql_num_fields)(rlm_sql_handle_t *handle, rlm_sql_config_t *config);
+ int (*sql_num_rows)(rlm_sql_handle_t *handle, rlm_sql_config_t *config);
+ int (*sql_affected_rows)(rlm_sql_handle_t *handle, rlm_sql_config_t *config);
+
+ sql_rcode_t (*sql_fetch_row)(rlm_sql_handle_t *handle, rlm_sql_config_t *config);
+ sql_rcode_t (*sql_free_result)(rlm_sql_handle_t *handle, rlm_sql_config_t *config);
+
+ sql_error_t sql_error; //!< Get any errors from the previous query.
+
+ sql_rcode_t (*sql_finish_query)(rlm_sql_handle_t *handle, rlm_sql_config_t *config);
+ sql_rcode_t (*sql_finish_select_query)(rlm_sql_handle_t *handle, rlm_sql_config_t *config);
+
+ xlat_escape_t sql_escape_func;
+} rlm_sql_module_t;
+
+struct sql_inst {
+ rlm_sql_config_t myconfig; /* HACK */
+ fr_connection_pool_t *pool;
+ rlm_sql_config_t *config;
+ CONF_SECTION *cs;
+
+ DICT_ATTR const *sql_user; //!< Cached pointer to SQL-User-Name
+ //!< dictionary attribute.
+ exfile_t *ef;
+
+ void *handle;
+ rlm_sql_module_t *module;
+
+ int (*sql_set_user)(rlm_sql_t *inst, REQUEST *request, char const *username);
+ size_t (*sql_escape_func)(REQUEST *, char *out, size_t outlen, char const *in, void *arg);
+ sql_rcode_t (*sql_query)(rlm_sql_t *inst, REQUEST *request, rlm_sql_handle_t **handle, char const *query);
+ sql_rcode_t (*sql_select_query)(rlm_sql_t *inst, REQUEST *request, rlm_sql_handle_t **handle, char const *query);
+ sql_rcode_t (*sql_fetch_row)(rlm_sql_t *inst, REQUEST *request, rlm_sql_handle_t **handle);
+
+ char const *name; //!< Module instance name.
+ DICT_ATTR const *group_da;
+};
+
+typedef struct sql_grouplist {
+ char *name;
+ struct sql_grouplist *next;
+} rlm_sql_grouplist_t;
+
+int sql_fr_pair_list_afrom_str(TALLOC_CTX *ctx, REQUEST *request, VALUE_PAIR **first_pair, rlm_sql_row_t row);
+int sql_read_realms(rlm_sql_handle_t *handle);
+int sql_getvpdata(TALLOC_CTX *ctx, rlm_sql_t *inst, REQUEST *request, rlm_sql_handle_t **handle, VALUE_PAIR **pair, char const *query);
+int sql_read_clients(rlm_sql_handle_t *handle);
+int sql_dict_init(rlm_sql_handle_t *handle);
+void CC_HINT(nonnull (1, 2, 4)) rlm_sql_query_log(rlm_sql_t *inst, REQUEST *request, sql_acct_section_t *section, char const *query);
+sql_rcode_t CC_HINT(nonnull (1, 3, 4)) rlm_sql_select_query(rlm_sql_t *inst, REQUEST *request, rlm_sql_handle_t **handle, char const *query);
+sql_rcode_t CC_HINT(nonnull (1, 3, 4)) rlm_sql_query(rlm_sql_t *inst, REQUEST *request, rlm_sql_handle_t **handle, char const *query);
+int rlm_sql_fetch_row(rlm_sql_t *inst, REQUEST *request, rlm_sql_handle_t **handle);
+void rlm_sql_print_error(rlm_sql_t *inst, REQUEST *request, rlm_sql_handle_t *handle, bool force_debug);
+int sql_set_user(rlm_sql_t *inst, REQUEST *request, char const *username);
+#endif