diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-06-30 16:00:28 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-06-30 16:00:28 +0300 |
commit | af7a7d6064d385ea513c8c426e9c70f4adc83601 (patch) | |
tree | 8cca5cedc0be7508e19fdfb0e4eab2e471b71fe4 | |
parent | df105b4f21ae98dad3c6475c86b00911d55635e1 (diff) | |
download | smap-af7a7d6064d385ea513c8c426e9c70f4adc83601.tar.gz smap-af7a7d6064d385ea513c8c426e9c70f4adc83601.tar.bz2 |
Minor changes.
* modules/mysql/mysql.c: Use onerror-reply.
* modules/postgres/postgres.c: Likewise.
* doc/smap.texi: Document expansions, mysql and
postgres modules.
-rw-r--r-- | doc/smap.texi | 392 | ||||
-rw-r--r-- | modules/mysql/mysql.c | 14 | ||||
-rw-r--r-- | modules/postgres/postgres.c | 31 |
3 files changed, 409 insertions, 28 deletions
diff --git a/doc/smap.texi b/doc/smap.texi index 82dc063..a2129dc 100644 --- a/doc/smap.texi +++ b/doc/smap.texi @@ -1250,17 +1250,37 @@ to the end of line are ignored. Empty lines are ignored as well. @cindex configuration statement @cindex statement, configuration Each not empty line constitutes a @dfn{configuration statement}. -The statement is first split into words. A @dfn{word} is any -contiguous sequence of non-whitespace characters. Singly-quoted -and doubly-quoted strings are also considered words. Within a -doubly-quoted string, backslash character introduces an @dfn{escape -sequence}. The following escape sequences are supported: +Before further processing the statement is subject to the following +@dfn{expansions}: + +@table @asis +@cindex variable substitution +@item variable substitution +Variable substitution consists in replacing each sequence +@samp{$@var{name}} or @samp{$@{@var{name}@}} with the value of the +@dfn{variable} @var{name}. Valid variable names begin with a letter +of the Latin alphabet or underscore and consist of alphanumeric +symbols and underscores. Variable names are case-sensitive. +Variables are expanded in unquoted and doubly-quoted arguments. +Variable expansion is suppressed within single-quoted strings (see below). + +@cindex field splitting +@item field splitting +A @dfn{word} is defined as any contiguous sequence of non-whitespace +characters or any sequence of characters enclosed in double or single +quotes. Standalone words and doubly-quoted strings are subject to +variable substitution and escape expansion. + +@cindex escape expansion +@item escape expansion +A backslash character introduces an @dfn{escape sequence}. The +following escape sequences are expanded: @cindex escape sequences @float Table, escape-sequences @caption{Escape sequences} @multitable @columnfractions 0.30 .5 @item Sequence @tab Replaced with @@ -1271,18 +1291,31 @@ sequence}. The following escape sequences are supported: @item \r @tab Carriage return character (@acronym{ASCII} 13) @item \t @tab Horizontal tabulation character (@acronym{ASCII} 9) @item \v @tab Vertical tabulation character (@acronym{ASCII} 11) @end multitable @end float -A @samp{\} followed by any character not listed in the above table is +A @samp{\} followed by any character not listed in the table above is replaced with that character alone. This allows, for example, to include double-quote characters in a doubly-quoted string. - The first word is then treated as a @dfn{keyword}, and the rest of -words as its arguments. +@cindex quote removal +@item quote removal +This stage consists in removing unescaped single and double quotes, +which where not inserted due to variable expansion. +@end table + + If, after expansion, the statement consists of a single word that +begins with a valid variable name immediately followed by an equals +sign, such statement is treated as a @dfn{variable assignment}. The +string to the right of the equals sign is assigned to the variable +named to the left of it. + + Otherwise, if the statement has two or more words, the first word is +treated as a @dfn{keyword}, which identifies a configuration +statement, and the rest of words as its arguments. The following configuration statements are understood. @deffn {Config} inetd-mode bool If @var{bool} is @samp{yes}, enable inet mode (@pxref{inetd-mode}). @end deffn @@ -1442,13 +1475,13 @@ end That is, in the example above, the connections requested on the server @var{main} will be handled by a subprocess with privileges of the user @var{smap}, retaining all the supplementary groups of this user. The following statements are allowed for use in the block statement: @itemize @bullet -@item allgoups +@item allgroups @item backlog @item group @item max-children @item reuseaddr @item single-process @item user @@ -2328,18 +2361,353 @@ dispatch key like *@@* transform key localpart @end example @end deffn @node mysql @section Mysql @cindex mysql module -FIXME + The @command{mysql} module provides interface to MySQL database +management system. It may be used to build smap databases over SQL +ones. + + The SQL database to use may be configured either globally, when +loading the module, or locally, when defining a smap database. If +a database definition lacks SQL configuration statements, then it +attempts to use a globally defined connection. + + Each database is configured with a @dfn{SQL query template}, and +a set of @dfn{smap reply templates} to use. When dispatched a +sockmap query, the database expands the SQL query template using +the actual values of @samp{$@{map@}} (the map name) and +@samp{$@{key@}} (the key value) and sends the expanded query to the | +MySQL server. If the server responds with a non-empty set of tuples, +the @dfn{positive reply template} is expanded and the result is used +as a response. Otherwise, if the query produced an empty set, the +smap database uses the @dfn{negative reply template} to create the +response. + +@menu +* MySQL Configuration:: +* MySQL Query and SMAP Replies:: +@end menu + +@node MySQL Configuration +@subsection MySQL Configuration + +The SQL database is configured using the following options: + +@table @option +@flindex /etc/my.cnf +@kwindex config-file, @command{mysql} +@item config-file=@var{file} + Set the name of the MySQL configuration file to read. By default +@file{/etc/my.cnf} is used. + +@kwindex config-group, @command{mysql} +@item config-group=@var{name} + Set the name of the group in the MySQL configuration file, +from where to read the configuration options. +@end table + + The statements above allow to keep all security-sensitive +information, such as MySQL username and password, in an +external configuration file and thus to relax permission requirements +for @file{smapd.conf}. For a detailed description of the format of +such external configuration file (or @dfn{option file} in @samp{MySQL} +parlance), see +@ifhtml +@uref{http://dev.mysql.com/doc/refman/5.0/en/option-files.html, +MySQL option files}. +@end ifhtml +@ifnothtml +@ref{option-files, Using Option Files,,mysql,MySQL Manual}. +@end ifnothtml + + In case the use of option files is not feasible for some reason, +you may specify MySQL connection and database parameters in +@file{smapd.conf} when loading the @command{mysql} module or defining +a smap database. The following options are used to define MySQL +connection parameters: + +@table @option +@kwindex host, @command{mysql} +@item host=@var{hostname} +Sets the hostname or @acronym{IP} address of the host running the +MySQL server. + +@kwindex port, @command{mysql} +@item port=@var{n} +Sets port number the MySQL server is listening on. Default is 3306. + +@kwindex socket, @command{mysql} +@item socket=@var{file} +Sets the socket name, if the server is listening on a @acronym{UNIX} socket. + +@kwindex ssl-ca, @command{mysql} +@item ssl-ca=@var{file} +Sets the pathname to the certificate authority file, if you +wish to use a secure connection to the server via SSL. +@end table + +Notice, that either @option{host} and, optionally, @option{port} or +@option{socket} must be used. Specifying both is senseless. + + MySQL database and user credentials are defined using the following +options: + +@table @option +@kwindex database, @command{mysql} +@item database=@var{name} +Sets the name of the MySQL database to use. + +@kwindex user, @command{mysql} +@item user=@var{name} +Sets MySQL user name. + +@kwindex password, @command{mysql} +@item password=@var{string} +Sets the password for accessing the MySQL database. +@end table + +When using these options, it is reasonable to tighten the permissions +on @file{smapd.conf} so that no third person could see the MySQL +password. The recommended permissions are @samp{0600}. + +@node MySQL Query and SMAP Replies +@subsection MySQL Query and SMAP Replies + MySQL query is defined using the following option: + +@table @option +@kwindex query, @command{mysql} +@item query=@var{template} + Define MySQL query template. +@end table + +The @var{template} may reference the following variables: + +@float Table, mysql-query-vars +@caption{MySQL query template variables} +@multitable @columnfractions 0.3 0.6 +@headitem Variable @tab Meaning +@kwindex map, @command{mysql} +@item map @tab Name of the map being queried +@kwindex key, @command{mysql} +@item key @tab Lookup key +@end multitable +@end float + + For example: + +@example +@group +database alias mysql \ + query="SELECT alias FROM aliases WHERE email='$key'" +@end group +@end example + + If the database definition lacks the @code{query} option, +it will attempt to use one from the module statement. If the module +statement lacked it as well, an error is reported. + + @dfn{Reply templates} define the responses to be given. They are +given by the following options: + +@table @option +@kwindex positive-reply, @command{mysql} +@item positive-reply=@var{template} +Defines a reply to be sent if the query returned a non-empty set of +tuples. In addition to the variables described above +(@pxref{mysql-query-vars}), the @var{template} may also refer to the +MySQL result columns, by using their names from the @samp{SELECT} part +of the query. For example: + +@example +@group +database alias mysql \ + query="SELECT alias FROM aliases WHERE email='$key'" \ + positive-reply="OK $alias" +@end group +@end example + +The default @code{positive-reply} is @samp{OK}. + +@kwindex negative-reply, @command{mysql} +@item negative-reply=@var{template} +Defines a reply to be sent if the query returned an empty set of +tuples. The @var{template} may refer to the variables described in +@ref{mysql-query-vars}. + +Default value is @samp{NOTFOUND}. + +@kwindex onerror-reply, @command{mysql} +@item onerror-reply=@var{template} +Defines a reply to be sent if an error occurred when executing the +query. The @var{template} may refer to the variables described in +@ref{mysql-query-vars}. + +Default value is @samp{NOTFOUND}. +@end table @node postgres @section Postgres @cindex Postgres module -FIXME + The @command{postgres} module provides interface to PostgreSQL database +management system. It may be used to build smap databases over SQL +ones. + + The module is in many regards similar to @command{mysql} module, +described above. In particular, its overall functionality is exactly +the same as described in @ref{mysql}, except, of course, that it uses +PostgreSQL databases. + +@menu +* Postgres Configuration:: +* Postgres Query and SMAP Replies:: +@end menu + +@node Postgres Configuration +@subsection Postgres Configuration + A Postgres database is configured using a set of options understood +by the Postgres @code{PQconnectdb} function. See +@uref{http://www.postgresql.org/@/docs/@/8.4/@/static/@/libpq-connect.html}, +for a detailed description. The following is a short summary of the +most useful options: + +@table @option +@kwindex host, @command{postgres} option +@item host=@var{name} +Name of host to connect to. If this begins with a slash, +it specifies Unix-domain communication rather than TCP/IP +communication; the value is the name of the directory in which the +socket file is stored. + +@kwindex hostaddr, @command{postgres} option +@item hostaddr=@var{ip} +Numeric IP address of host to connect to. + +@kwindex port, @command{postgres} option +@item port=@var{number} +Port number to connect to at the server host, or socket file name +extension for Unix-domain connections. + +@kwindex dbname, @command{postgres} option +@item dbname=@var{name} +The database name. + +@kwindex user, @command{postgres} option +@item user=@var{name} +PostgreSQL user name to connect as. Defaults to be the same as the +operating system name of the user running the @command{smapd}. + +@kwindex password, @command{postgres} option +@item password=@var{string} +Password to be used if the server demands password authentication. + +@kwindex connect_timeout, @command{postgres} option +@item connect_timeout=@var{number} +Maximum wait for connection, in seconds. Zero or not specified means +wait indefinitely. + +@kwindex options, @command{postgres} option +@item options=@var{string} +Any additional command-line options to send to the server at run-time. +For example, setting this to @samp{-c geqo=off} sets the session's +value of the @samp{geqo} parameter to @samp{off}. For a detailed +discussion of the available options, see Postgres +documentation@footnote{For PostgreSQL version 8.4, see +@uref{http://www.postgresql.org/docs/8.4/static/runtime-config.html, +Chapter 18} in PostgreSQL Manual.}. + +@kwindex sslmode, @command{postgres} option +@item sslmode=@var{mode} +This option determines whether or with what priority an SSL TCP/IP +connection will be negotiated with the server. There are six modes: +@samp{disable}, @samp{allow}, @samp{prefer}, @samp{require}, +@samp{verify-ca} and @samp{verify-full}@footnote{For PostgreSQL +version 8.4, see +@uref{http://www.postgresql.org/docs/8.4/static/libpq-ssl.html, +Section 30.17} in PostgreSQL Manual.}. + +@kwindex sslcert, @command{postgres} option +@item sslcert=@var{file} +This parameter specifies the file name of the client SSL certificate. + +@kwindex sslkey, @command{postgres} option +@item sslkey==@var{file-or-engine-name} +This parameter specifies the location for the secret key used for the +client certificate. + +@kwindex sslrootcert, @command{postgres} option +@item sslrootcert=@var{file} +This parameter specifies the file name of the root SSL certificate. + +@kwindex sslcrl, @command{postgres} option +@item sslcrl=@var{name} +This parameter specifies the file name of the SSL certificate +revocation list (@acronym{CRL}). + +@kwindex krbsrvname, @command{postgres} option +@item krbsrvname=@var{name} +Kerberos service name to use when authenticating with Kerberos 5 or GSSAPI. + +@kwindex service, @command{postgres} option +@item service=@var{name} +Service name to use for additional parameters. +@end table + +@node Postgres Query and SMAP Replies +@subsection Postgres Query and SMAP Replies + Postgres SQL query and the smap replies are configured the same way +as for @command{mysql} module (@pxref{MySQL Query and SMAP Replies}). +The following is a short summary: + +@table @option +@kwindex query, @command{mysql} +@item query=@var{template} + Define the Postgres query template. The @var{template} may +reference the following variables: + +@float Table, postgres-query-vars +@caption{Postgres query template variables} +@multitable @columnfractions 0.3 0.6 +@headitem Variable @tab Meaning +@kwindex map, @command{postgres} +@item map @tab Name of the map being queried +@kwindex key, @command{postgres} +@item key @tab Lookup key +@end multitable +@end float + + If the database definition lacks the @code{query} option, +it will attempt to use one from the module statement. If the module +statement lacked it as well, an error is reported. + +@kwindex positive-reply, @command{mysql} +@item positive-reply=@var{template} +Defines a reply to be sent if the query returned a non-empty set of +tuples. In addition to the variables described above +(@pxref{postgres-query-vars}), the @var{template} may also refer to the +column names from the SQL result set. + +The default @code{positive-reply} is @samp{OK}. + +@kwindex negative-reply, @command{mysql} +@item negative-reply=@var{template} +Defines a reply to be sent if the query returned an empty set of +tuples. The @var{template} may refer to the variables described in +@ref{postgres-query-vars}. + +Default value is @samp{NOTFOUND}. + +@kwindex onerror-reply, @command{mysql} +@item onerror-reply=@var{template} +Defines a reply to be sent if an error occurred when executing the +query. The @var{template} may refer to the variables described in +@ref{postgres-query-vars}. + +Default value is @samp{NOTFOUND}. +@end table @node sed @section Sed @cindex sed module The @samp{sed} module applies sed-like @dfn{s-expressions} to strings to modify them. It is designed mainly for use in transformation rules @@ -2788,13 +3156,13 @@ startup banner. When started, @command{smapc} prints a short list of information useful for beginning users: the program version and warranty conditions and a command to get help, e.g.: @example @group smapc (smap) @value{VERSION} -Copyright (C) 2005, 2006, 2007, 2008 Sergey Poznyakoff +Copyright (C) 2010 Sergey Poznyakoff License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type ? for help summary diff --git a/modules/mysql/mysql.c b/modules/mysql/mysql.c index 315dd8b..60b09f2 100644 --- a/modules/mysql/mysql.c +++ b/modules/mysql/mysql.c @@ -78,12 +78,20 @@ moddb_negative_reply(struct mod_mysql_db *db) { return db->negative_reply ? db->negative_reply : (def_db.negative_reply ? def_db.negative_reply : "NOTFOUND"); } +static const char * +moddb_onerror_reply(struct mod_mysql_db *db) +{ + return db->onerror_reply ? + db->onerror_reply : + (def_db.onerror_reply ? def_db.onerror_reply : "NOTFOUND"); +} + static int opendb(struct mod_mysql_db *db) { if (db->flags & MDB_OPEN) { db->refcnt++; return 0; @@ -569,16 +577,14 @@ mod_query(smap_database_t dbp, return 1; rc = do_query(db, qenv, &res); free_env(qenv); if (rc) { - free_env(env); - return 1; /* FIXME: honor onerror_reply */ - } - if (res) { + rc = send_reply(ostr, moddb_onerror_reply(db), env); + } else if (res) { unsigned nrow = mysql_num_rows(res); unsigned ncol = mysql_num_fields(res); smap_debug(dbgid, 1, ("query returned %u columns in %u rows", ncol, nrow)); diff --git a/modules/postgres/postgres.c b/modules/postgres/postgres.c index 1218564..05f35e8 100644 --- a/modules/postgres/postgres.c +++ b/modules/postgres/postgres.c @@ -71,12 +71,20 @@ modpg_negative_reply(struct modpg_db *db) { return db->negative_reply ? db->negative_reply : (def_db.negative_reply ? def_db.negative_reply : "NOTFOUND"); } +static const char * +modpg_onerror_reply(struct modpg_db *db) +{ + return db->onerror_reply ? + db->onerror_reply : + (def_db.onerror_reply ? def_db.onerror_reply : "NOTFOUND"); +} + static int opendb(struct modpg_db *db) { if (db->flags & MDB_OPEN) { db->refcnt++; return 0; @@ -557,31 +565,30 @@ modpg_query(smap_database_t dbp, struct smap_conninfo const *conninfo) { struct modpg_db *db = (struct modpg_db *)dbp; PGresult *res; int rc; char **env, **qenv; - size_t ntuples; if (create_query_env(map, key, conninfo, &env, &qenv)) return 1; rc = do_query(db, qenv, &res); free_env(qenv); - if (rc) { - free_env(env); - return 1; /* FIXME: honor onerror_reply */ + if (rc) + rc = send_reply(ostr, modpg_onerror_reply(db), env); + else { + size_t ntuples = PQntuples(res); + smap_debug(dbgid, 1, + ("query returned %u columns in %u rows", + PQnfields(res), ntuples)); + if (ntuples) + rc = do_positive_reply(db, ostr, &env, res); + else + rc = send_reply(ostr, modpg_negative_reply(db), env); } - ntuples = PQntuples(res); - smap_debug(dbgid, 1, - ("query returned %u columns in %u rows", - PQnfields(res), ntuples)); - if (ntuples) - rc = do_positive_reply(db, ostr, &env, res); - else - rc = send_reply(ostr, modpg_negative_reply(db), env); free_env(env); return rc; } struct smap_module SMAP_EXPORT(postgres, module) = { SMAP_MODULE_VERSION, |