diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-06-29 00:08:32 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-06-29 00:09:40 +0300 |
commit | 2af5a2255dfcf46c06cb39010768863c5a2837aa (patch) | |
tree | dc354959ed5f909b560b2eb46fa002dc99c67aa7 | |
parent | e696e8668cd2700825c42bf50c8a74a7292dcbf6 (diff) | |
download | smap-2af5a2255dfcf46c06cb39010768863c5a2837aa.tar.gz smap-2af5a2255dfcf46c06cb39010768863c5a2837aa.tar.bz2 |
Implement user-defined variables in configs.
* src/cfg.c (asgn_p, asgn, find_env_var): New functions.
(parse_config_loop): Handle user-defined variable assignments and
expansions.
* modules/mailutils/mailutils.c: Use wordsplit instead of
the MU vartabs.
* doc/ex-meta1.texi: Rewrite.
-rw-r--r-- | doc/ex-meta1.texi | 145 | ||||
-rw-r--r-- | modules/mailutils/mailutils.c | 162 | ||||
-rw-r--r-- | src/cfg.c | 83 |
3 files changed, 239 insertions, 151 deletions
diff --git a/doc/ex-meta1.texi b/doc/ex-meta1.texi index e558008..d74b49c 100644 --- a/doc/ex-meta1.texi +++ b/doc/ex-meta1.texi | |||
@@ -3,13 +3,36 @@ | |||
3 | @c See file smap.texi for copying conditions. | 3 | @c See file smap.texi for copying conditions. |
4 | @c ******************************************************************* | 4 | @c ******************************************************************* |
5 | @cindex MeTA1 | 5 | @cindex MeTA1 |
6 | In this appendix we will show how to use the @samp{mailutils} | 6 | In this appendix we will show how to use the @samp{mysql} |
7 | module (@pxref{mailutils,mailutils module}) to configure local user | 7 | module (@pxref{mysql,mysql module}) to configure local user |
8 | and alias maps for @acronym{MeTA1}. For this purpose, we will assume | 8 | and alias maps for @acronym{MeTA1}. For this purpose, we will assume |
9 | that the actual data is stored in two tables in a @acronym{MySQL} | 9 | that the actual data is stored in two tables in a @acronym{MySQL} |
10 | database. The two maps will be served by two separate databases, each | 10 | database. The two maps will be served by two separate databases, each |
11 | of which uses a separate configuration file. | 11 | of which uses a separate configuration file. |
12 | 12 | ||
13 | To reduce the number of connections to the @acronym{MySQL} server, | ||
14 | the @acronym{MySQL} database will be opened at the module level and | ||
15 | shared between the two smap databases. Thus, the module | ||
16 | initialization in @file{smapd.conf} looks like: | ||
17 | |||
18 | @example | ||
19 | module mysql mysql open config-group=smap | ||
20 | @end example | ||
21 | |||
22 | The @samp{open} parameter instructs the module to open the requested | ||
23 | databases. The @samp{config-group} parameter refers to a group | ||
24 | name in the default @file{/etc/my.cnf} file that contains information | ||
25 | about the @acronym{MySQL} database and credentials for accessing it. | ||
26 | The following is a sample snippet from @file{/etc/my.cnf}: | ||
27 | |||
28 | @example | ||
29 | [smap] | ||
30 | database = Mail | ||
31 | user = smap | ||
32 | password = guessme | ||
33 | socket = /tmp/mysql.sock | ||
34 | @end example | ||
35 | |||
13 | @menu | 36 | @menu |
14 | * userdb-meta1:: Configure local_user_map. | 37 | * userdb-meta1:: Configure local_user_map. |
15 | * aliases-meta1:: Configure aliases. | 38 | * aliases-meta1:: Configure aliases. |
@@ -33,43 +56,25 @@ CREATE TABLE userdb ( | |||
33 | @end group | 56 | @end group |
34 | @end example | 57 | @end example |
35 | 58 | ||
36 | Module configuration file @file{/etc/mailutils.d/meta1-userdb} | 59 | The smap database is defined as follows: |
37 | begins with the following stanza: | ||
38 | 60 | ||
39 | @example | 61 | @example |
40 | @group | 62 | @group |
41 | auth @{ | 63 | database userdb mysql \ |
42 | authentication clear; | 64 | defaultdb |
43 | authentication sql; | 65 | query="SELECT user FROM userdb WHERE user='$key'" |
44 | authorization clear; | 66 | positive-reply=OK |
45 | authorization sql; | ||
46 | @} | ||
47 | @end group | 67 | @end group |
48 | @end example | 68 | @end example |
49 | 69 | ||
50 | This clears any previous settings that the authorization engine might | 70 | The @samp{defaultdb} parameter tells it to use the default SQL |
51 | have read from the main configuration file, and requests that only | 71 | database opened in the module initialization instruction. The |
52 | @samp{sql} method be used for both authentication and authorization. | 72 | @samp{query} parameter supplies the SQL query to run (the |
53 | 73 | @samp{$@{key@}} variable will be expanded to the value of the actual | |
54 | Now, we need to supply a @samp{sql} statement. Mailutils requires | 74 | lookup key, prior to executing the query). Finally, |
55 | that the @code{getpwnam} query return at least six fields, whereas the | 75 | @samp{positive-reply} defines the reply to give if the query returns |
56 | @samp{userdb} table contains only two columns. So we will need to supply | 76 | some tuples. The database only verifies whether the user is present |
57 | defaults for the remaining four: | 77 | or not, so no additional result is supplied in the reply. |
58 | |||
59 | @example | ||
60 | sql @{ | ||
61 | interface mysql; | ||
62 | host sql.host.name | ||
63 | user smap; | ||
64 | passwd guessme; | ||
65 | db mail; | ||
66 | getpwnam "SELECT user as name, 'x' as passwd,10000 as uid, 10000 as gid, " | ||
67 | "'/nonexistent' as dir, '/sbin/nologin' as shell " | ||
68 | "FROM userdb WHERE user='$@{user@}'"; | ||
69 | @}; | ||
70 | @end example | ||
71 | |||
72 | That's all we need to have in @file{/etc/mailutils.d/meta1-userdb}. | ||
73 | 78 | ||
74 | @node aliases-meta1 | 79 | @node aliases-meta1 |
75 | @appendixsec Configure aliases | 80 | @appendixsec Configure aliases |
@@ -87,74 +92,26 @@ CREATE TABLE userdb ( | |||
87 | @end group | 92 | @end group |
88 | @end example | 93 | @end example |
89 | 94 | ||
90 | It will be served by @samp{alias} database, which will read | 95 | It will be served by @samp{alias} database, defined as follows: |
91 | the configuration for Mailutils from the file | ||
92 | @file{/etc/mailutils.d/meta1-alias}. This file is similar to | ||
93 | @file{meta1-userdb}, but uses a different query in its @samp{sql} | ||
94 | section: | ||
95 | 96 | ||
96 | @example | 97 | @example |
97 | auth @{ | 98 | @group |
98 | authentication clear; | 99 | database alias mysql \ |
99 | authentication sql; | 100 | defaultdb \ |
100 | authorization clear; | 101 | query="SELECT alias FROM aliases WHERE user='$key'" \ |
101 | authorization sql; | 102 | positive-reply="OK $alias" |
102 | @} | 103 | @end group |
103 | |||
104 | sql @{ | ||
105 | interface mysql; | ||
106 | host sql.host.name | ||
107 | user smap; | ||
108 | passwd guessme; | ||
109 | db mail; | ||
110 | getpwnam "SELECT alias as name, 'x' as passwd,1 as uid, 1 as gid, " | ||
111 | "'/nonexistent' as dir, '/sbin/nologin' as shell " | ||
112 | "FROM aliases WHERE name='$@{user@}'"; | ||
113 | @} | ||
114 | @end example | ||
115 | |||
116 | @node smapd-meta1 | ||
117 | @appendixsec Smapd configuration | ||
118 | |||
119 | Let's now configure @file{smapd.conf}. Suppose it will run a single | ||
120 | server, which we will call @samp{local}. The server will listen on a | ||
121 | UNIX socket @file{/var/spool/meta1/smap/userdb}. It is important that | ||
122 | @samp{meta1} be able to read from and write to that socket, so we will make | ||
123 | it owned by user @samp{meta1m}: | ||
124 | |||
125 | @example | ||
126 | server local unix:///var/spool/meta1/smap/userdb begin | ||
127 | user meta1m | ||
128 | end | ||
129 | @end example | ||
130 | |||
131 | Next task is to configure the databases. The @samp{userdb} database is | ||
132 | pretty simple: | ||
133 | |||
134 | @example | ||
135 | database userdb mailutils mode=auth \ | ||
136 | config-file=/etc/mailutils.d/meta1-userdb | ||
137 | @end example | 104 | @end example |
138 | 105 | ||
139 | It will return @samp{OK} if the user is found in the database and | 106 | It differs from the @samp{userdb} database only in that it returns |
140 | @samp{NOTFOUND} otherwise, which is exactly what the @acronym{MTA} needs. | 107 | a @dfn{result section} with its positive reply. |
141 | 108 | ||
142 | The @samp{aliasdb} database is a bit different. In case of a | ||
143 | positive reply, it must return the expanded alias value, so we need to | ||
144 | supply a new @samp{positive-reply} template: | ||
145 | 109 | ||
146 | @example | 110 | @node smapd-meta1 |
147 | database aliasdb mailutils mode=auth \ | 111 | @appendixsec Dispatch Rules |
148 | config-file=/usr/local/etc/mailutils.d/meta1-alias \ | ||
149 | positive-reply="OK $@{name@}" | ||
150 | @end example | ||
151 | |||
152 | The @samp{$@{name@}} will be replaced with the value of the first | ||
153 | column in the tuple returned by the @acronym{SQL} database | ||
154 | (@pxref{aliases-meta1, getpwnam}). | ||
155 | 112 | ||
156 | To dispatch queries to these databases, the following rules will | 113 | The following rules dispatch queries based on their map names to |
157 | suffice: | 114 | the two databases: |
158 | 115 | ||
159 | @example | 116 | @example |
160 | dispatch map alias database aliasdb | 117 | dispatch map alias database aliasdb |
diff --git a/modules/mailutils/mailutils.c b/modules/mailutils/mailutils.c index 10018c4..03966c1 100644 --- a/modules/mailutils/mailutils.c +++ b/modules/mailutils/mailutils.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <smap/diag.h> | 25 | #include <smap/diag.h> |
26 | #include <smap/module.h> | 26 | #include <smap/module.h> |
27 | #include <smap/parseopt.h> | 27 | #include <smap/parseopt.h> |
28 | #include <smap/wordsplit.h> | ||
28 | 29 | ||
29 | static char *dfl_positive_reply = "OK"; | 30 | static char *dfl_positive_reply = "OK"; |
30 | static char *dfl_negative_reply = "NOTFOUND"; | 31 | static char *dfl_negative_reply = "NOTFOUND"; |
@@ -66,58 +67,97 @@ _mu_smap_db_free(struct _mu_smap_db *db) | |||
66 | free(db); | 67 | free(db); |
67 | } | 68 | } |
68 | 69 | ||
70 | static void | ||
71 | free_env(char **env) | ||
72 | { | ||
73 | int i; | ||
74 | for (i = 0; env[i]; i++) | ||
75 | free(env[i]); | ||
76 | } | ||
77 | |||
69 | static char * | 78 | static char * |
70 | expand_reply_text(const char *arg, struct _mu_smap_result *res) | 79 | mkvar(const char *name, const char *val) |
71 | { | 80 | { |
72 | int rc; | 81 | char *ptr = malloc(strlen(name) + strlen(val) + 2); |
73 | mu_vartab_t vtab; | 82 | if (ptr) { |
74 | char *reply = NULL; | 83 | strcpy(ptr, name); |
75 | char buf[512]; | 84 | strcat(ptr, "="); |