Commit 18590880 18590880814ffb1941ba9a67b49a246323e36d37 by Sergey Poznyakoff

Implement normal UNIX-style configuration files:

* mailbox/cfg_lexer.c: New file.
* mailbox/cfg_parser.c: New file.
* mailbox/cfg_parser.h: New file.
* mailbox/Makefile.am: Add cfg_ sources and socket_stream.c.

* include/mailutils/cfg.h: New file.
* include/mailutils/Makefile.am (pkginclude_HEADERS): Add cfg.h.
* include/mailutils/argp.h: Include cfg.h.
(mu_create_argcv): Remove prototype.
* include/mailutils/mu_auth.h (struct mu_auth_module): New member
`cfg'.
(MU_AUTH_REGISTER_ALL_MODULES): Call mu_auth_init first.

* mailbox/mu_argp.c: Rewrite. Implement normal configuration
(resource) file support. Overloaded command line options begin to
phase out.
* mailbox/mu_auth.c, auth/gsasl.c, auth/pam.c, auth/radius.c,
auth/sql.c, auth/tls.c, auth/virtual.c, libsieve/argp.c,
mailbox/system.c: Implement configuration statements.

* imap4d/imap4d.c: Begin switching to the new configuration scheme.
1 parent 1f6c71fc
...@@ -41,8 +41,7 @@ char *mu_gsasl_cram_md5_pwd = SITE_CRAM_MD5_PWD; ...@@ -41,8 +41,7 @@ char *mu_gsasl_cram_md5_pwd = SITE_CRAM_MD5_PWD;
41 #define ARG_CRAM_PASSWD 1 41 #define ARG_CRAM_PASSWD 1
42 42
43 static struct argp_option _gsasl_argp_options[] = { 43 static struct argp_option _gsasl_argp_options[] = {
44 {NULL, 0, NULL, 0, N_("GSASL options"), 0}, 44 {"cram-passwd", ARG_CRAM_PASSWD, N_("FILE"), OPTION_HIDDEN,
45 {"cram-passwd", ARG_CRAM_PASSWD, N_("FILE"), 0,
46 N_("Specify password file for CRAM-MD5 authentication"), 0}, 45 N_("Specify password file for CRAM-MD5 authentication"), 0},
47 { NULL, 0, NULL, 0, NULL, 0 } 46 { NULL, 0, NULL, 0, NULL, 0 }
48 }; 47 };
...@@ -77,7 +76,7 @@ static struct argp_child _gsasl_argp_child = { ...@@ -77,7 +76,7 @@ static struct argp_child _gsasl_argp_child = {
77 void 76 void
78 mu_gsasl_init_argp () 77 mu_gsasl_init_argp ()
79 { 78 {
80 if (mu_register_capa ("gsasl", &_gsasl_argp_child)) 79 if (mu_register_capa ("gsasl", &_gsasl_argp_child, NULL))
81 { 80 {
82 mu_error (_("INTERNAL ERROR: cannot register argp capability gsasl")); 81 mu_error (_("INTERNAL ERROR: cannot register argp capability gsasl"));
83 abort (); 82 abort ();
......
...@@ -150,7 +150,7 @@ mu_pam_argp_parser (int key, char *arg, struct argp_state *state) ...@@ -150,7 +150,7 @@ mu_pam_argp_parser (int key, char *arg, struct argp_state *state)
150 } 150 }
151 151
152 static struct argp_option mu_pam_argp_option[] = { 152 static struct argp_option mu_pam_argp_option[] = {
153 { "pam-service", ARG_PAM_SERVICE, N_("STRING"), 0, 153 { "pam-service", ARG_PAM_SERVICE, N_("STRING"), OPTION_HIDDEN,
154 N_("Use STRING as PAM service name"), 0}, 154 N_("Use STRING as PAM service name"), 0},
155 { NULL, 0, NULL, 0, NULL, 0 } 155 { NULL, 0, NULL, 0, NULL, 0 }
156 }; 156 };
...@@ -179,8 +179,10 @@ struct mu_auth_module mu_auth_pam_module = { ...@@ -179,8 +179,10 @@ struct mu_auth_module mu_auth_pam_module = {
179 "pam", 179 "pam",
180 #ifdef USE_LIBPAM 180 #ifdef USE_LIBPAM
181 &mu_pam_argp, 181 &mu_pam_argp,
182 NULL,
182 #else 183 #else
183 NULL, 184 NULL,
185 NULL,
184 #endif 186 #endif
185 mu_authenticate_pam, 187 mu_authenticate_pam,
186 NULL, 188 NULL,
......
...@@ -51,13 +51,13 @@ ...@@ -51,13 +51,13 @@
51 #define ARG_RADIUS_DIR 259 51 #define ARG_RADIUS_DIR 259
52 52
53 static struct argp_option mu_radius_argp_option[] = { 53 static struct argp_option mu_radius_argp_option[] = {
54 { "radius-auth-request", ARG_AUTH_REQUEST, N_("REQUEST"), 0, 54 { "radius-auth-request", ARG_AUTH_REQUEST, N_("REQUEST"), OPTION_HIDDEN,
55 N_("Radius request to authenitcate the user"), 0 }, 55 N_("Radius request to authenitcate the user"), 0 },
56 { "radius-getpwnam-request", ARG_GETPWNAM_REQUEST, N_("REQUEST"), 0, 56 { "radius-getpwnam-request", ARG_GETPWNAM_REQUEST, N_("REQUEST"), OPTION_HIDDEN,
57 N_("Radius request to retrieve a passwd entry based on username"), 0 }, 57 N_("Radius request to retrieve a passwd entry based on username"), 0 },
58 { "radius-getpwuid-request", ARG_GETPWUID_REQUEST, N_("REQUEST"), 0, 58 { "radius-getpwuid-request", ARG_GETPWUID_REQUEST, N_("REQUEST"), OPTION_HIDDEN,
59 N_("Radius request to retrieve a passwd entry based on UID"), 0 }, 59 N_("Radius request to retrieve a passwd entry based on UID"), 0 },
60 { "radius-directory", ARG_RADIUS_DIR, N_("DIR"), 0, 60 { "radius-directory", ARG_RADIUS_DIR, N_("DIR"), OPTION_HIDDEN,
61 N_("Set path to the radius configuration directory"), 0 }, 61 N_("Set path to the radius configuration directory"), 0 },
62 { NULL } 62 { NULL }
63 }; 63 };
...@@ -598,8 +598,10 @@ struct mu_auth_module mu_auth_radius_module = { ...@@ -598,8 +598,10 @@ struct mu_auth_module mu_auth_radius_module = {
598 "radius", 598 "radius",
599 #ifdef ENABLE_RADIUS 599 #ifdef ENABLE_RADIUS
600 &mu_radius_argp, 600 &mu_radius_argp,
601 NULL,
601 #else 602 #else
602 NULL, 603 NULL,
604 NULL,
603 #endif 605 #endif
604 mu_radius_authenticate, 606 mu_radius_authenticate,
605 NULL, 607 NULL,
......
...@@ -175,6 +175,22 @@ mu_sql_expand_query (const char *query, const char *ustr) ...@@ -175,6 +175,22 @@ mu_sql_expand_query (const char *query, const char *ustr)
175 return res; 175 return res;
176 } 176 }
177 177
178 static int
179 set_sql_password_type (const char *arg)
180 {
181 if (strcmp (arg, "plain") == 0)
182 mu_sql_password_type = password_plaintext;
183 else if (strcmp (arg, "hash") == 0)
184 mu_sql_password_type = password_hash;
185 else if (strcmp (arg, "scrambled") == 0)
186 mu_sql_password_type = password_scrambled;
187 else
188 return 1;
189 return 0;
190 }
191
192
193 /* Command-line configuration */
178 # define ARG_SQL_INTERFACE 256 194 # define ARG_SQL_INTERFACE 256
179 # define ARG_SQL_GETPWNAM 257 195 # define ARG_SQL_GETPWNAM 257
180 # define ARG_SQL_GETPWUID 258 196 # define ARG_SQL_GETPWUID 258
...@@ -188,27 +204,27 @@ mu_sql_expand_query (const char *query, const char *ustr) ...@@ -188,27 +204,27 @@ mu_sql_expand_query (const char *query, const char *ustr)
188 # define ARG_SQL_FIELD_MAP 266 204 # define ARG_SQL_FIELD_MAP 266
189 205
190 static struct argp_option mu_sql_argp_option[] = { 206 static struct argp_option mu_sql_argp_option[] = {
191 {"sql-interface", ARG_SQL_INTERFACE, N_("NAME"), 0, 207 {"sql-interface", ARG_SQL_INTERFACE, N_("NAME"), OPTION_HIDDEN,
192 N_("Type of SQL interface to use"), 0}, 208 N_("Type of SQL interface to use"), },
193 {"sql-getpwnam", ARG_SQL_GETPWNAM, N_("QUERY"), 0, 209 {"sql-getpwnam", ARG_SQL_GETPWNAM, N_("QUERY"), OPTION_HIDDEN,
194 N_("SQL query to retrieve a passwd entry based on username"), 0}, 210 N_("SQL query to retrieve a passwd entry based on username"), 0},
195 {"sql-getpwuid", ARG_SQL_GETPWUID, N_("QUERY"), 0, 211 {"sql-getpwuid", ARG_SQL_GETPWUID, N_("QUERY"), OPTION_HIDDEN,
196 N_("SQL query to retrieve a passwd entry based on UID"), 0}, 212 N_("SQL query to retrieve a passwd entry based on UID"), 0},
197 {"sql-getpass", ARG_SQL_GETPASS, N_("QUERY"), 0, 213 {"sql-getpass", ARG_SQL_GETPASS, N_("QUERY"), OPTION_HIDDEN,
198 N_("SQL query to retrieve a password from the database"), 0}, 214 N_("SQL query to retrieve a password from the database"), 0},
199 {"sql-host", ARG_SQL_HOST, N_("HOSTNAME"), 0, 215 {"sql-host", ARG_SQL_HOST, N_("HOSTNAME"), OPTION_HIDDEN,
200 N_("Name or IP of MySQL server to connect to"), 0}, 216 N_("Name or IP of MySQL server to connect to"), 0},
201 {"sql-user", ARG_SQL_USER, N_("NAME"), 0, 217 {"sql-user", ARG_SQL_USER, N_("NAME"), OPTION_HIDDEN,
202 N_("SQL user name"), 0}, 218 N_("SQL user name"), 0},
203 {"sql-passwd", ARG_SQL_PASSWD, N_("STRING"), 0, 219 {"sql-passwd", ARG_SQL_PASSWD, N_("STRING"), OPTION_HIDDEN,
204 N_("SQL connection password"), 0}, 220 N_("SQL connection password"), 0},
205 {"sql-db", ARG_SQL_DB, N_("STRING"), 0, 221 {"sql-db", ARG_SQL_DB, N_("STRING"), OPTION_HIDDEN,
206 N_("Name of the database to connect to"), 0}, 222 N_("Name of the database to connect to"), 0},
207 {"sql-port", ARG_SQL_PORT, N_("NUMBER"), 0, 223 {"sql-port", ARG_SQL_PORT, N_("NUMBER"), OPTION_HIDDEN,
208 N_("Port to use"), 0}, 224 N_("Port to use"), 0},
209 {"sql-password-type", ARG_SQL_MU_PASSWORD_TYPE, N_("STRING"), 0, 225 {"sql-password-type", ARG_SQL_MU_PASSWORD_TYPE, N_("STRING"), OPTION_HIDDEN,
210 N_("Type of password returned by --sql-getpass query. STRING is one of: plain, hash, scrambled"), 0}, 226 N_("Type of password returned by --sql-getpass query. STRING is one of: plain, hash, scrambled"), 0},
211 {"sql-field-map", ARG_SQL_FIELD_MAP, N_("MAP"), 0, 227 {"sql-field-map", ARG_SQL_FIELD_MAP, N_("MAP"), OPTION_HIDDEN,
212 N_("Declare a name translation map for SQL fields in results of sql-getpwnam and " 228 N_("Declare a name translation map for SQL fields in results of sql-getpwnam and "
213 "sql-getpwuid queries"), 0}, 229 "sql-getpwuid queries"), 0},
214 { NULL, 0, NULL, 0, NULL, 0 } 230 { NULL, 0, NULL, 0, NULL, 0 }
...@@ -260,13 +276,7 @@ mu_sql_argp_parser (int key, char *arg, struct argp_state *state) ...@@ -260,13 +276,7 @@ mu_sql_argp_parser (int key, char *arg, struct argp_state *state)
260 break; 276 break;
261 277
262 case ARG_SQL_MU_PASSWORD_TYPE: 278 case ARG_SQL_MU_PASSWORD_TYPE:
263 if (strcmp (arg, "plain") == 0) 279 if (set_sql_password_type (arg))
264 mu_sql_password_type = password_plaintext;
265 else if (strcmp (arg, "hash") == 0)
266 mu_sql_password_type = password_hash;
267 else if (strcmp (arg, "scrambled") == 0)
268 mu_sql_password_type = password_scrambled;
269 else
270 argp_error (state, _("Unknown password type `%s'"), arg); 280 argp_error (state, _("Unknown password type `%s'"), arg);
271 break; 281 break;
272 282
...@@ -283,11 +293,59 @@ mu_sql_argp_parser (int key, char *arg, struct argp_state *state) ...@@ -283,11 +293,59 @@ mu_sql_argp_parser (int key, char *arg, struct argp_state *state)
283 return 0; 293 return 0;
284 } 294 }
285 295
286 struct argp mu_sql_argp = { 296 static struct argp mu_sql_argp = {
287 mu_sql_argp_option, 297 mu_sql_argp_option,
288 mu_sql_argp_parser, 298 mu_sql_argp_parser,
289 }; 299 };
290 300
301
302 /* Resource file configuration */
303 static int
304 cb_iface (mu_cfg_locus_t *locus, void *data, char *arg)
305 {
306 sql_interface = mu_sql_interface_index (arg);
307 if (sql_interface == 0)
308 mu_error (_("%s:%d: Unknown SQL interface `%s'"),
309 locus->file, locus->line, arg);
310 return 0;
311 }
312
313 static int
314 cb_password_type (mu_cfg_locus_t *locus, void *data, char *arg)
315 {
316 if (set_sql_password_type (arg))
317 mu_error (_("%s:%d: Unknown password type `%s'"),
318 locus->file, locus->line, arg);
319 return 0;
320 }
321
322 static int
323 cb_field_map (mu_cfg_locus_t *locus, void *data, char *arg)
324 {
325 int err;
326 int rc = mutil_parse_field_map (arg, &sql_field_map, &err);
327 if (rc)
328 mu_error (_("%s:%d: Error near element %d: %s"),
329 locus->file, locus->line, err, mu_strerror (rc));
330 return 0;
331 }
332
333 static struct mu_cfg_param mu_sql_param[] = {
334 { "interface", mu_cfg_callback, NULL, cb_iface },
335 { "getwpnam", mu_cfg_string, &mu_sql_getpwnam_query },
336 { "getpwuid", mu_cfg_string, &mu_sql_getpwuid_query },
337 { "getpass", mu_cfg_string, &mu_sql_getpass_query },
338 { "host", mu_cfg_string, &mu_sql_host },
339 { "user", mu_cfg_string, &mu_sql_user },
340 { "passwd", mu_cfg_string, &mu_sql_passwd },
341 { "db", mu_cfg_string, &mu_sql_db },
342 { "port", mu_cfg_int, &mu_sql_port },
343 { "password-type", mu_cfg_callback, NULL, cb_password_type },
344 { "field-map", mu_cfg_callback, NULL, cb_field_map },
345 { NULL }
346 };
347
348
291 static int 349 static int
292 decode_tuple_v1_0 (mu_sql_connection_t conn, int n, 350 decode_tuple_v1_0 (mu_sql_connection_t conn, int n,
293 struct mu_auth_data **return_data) 351 struct mu_auth_data **return_data)
...@@ -787,8 +845,10 @@ struct mu_auth_module mu_auth_sql_module = { ...@@ -787,8 +845,10 @@ struct mu_auth_module mu_auth_sql_module = {
787 "sql", 845 "sql",
788 #ifdef USE_SQL 846 #ifdef USE_SQL
789 &mu_sql_argp, 847 &mu_sql_argp,
848 mu_sql_param,
790 #else 849 #else
791 NULL, 850 NULL,
851 NULL,
792 #endif 852 #endif
793 mu_sql_authenticate, 853 mu_sql_authenticate,
794 NULL, 854 NULL,
......
...@@ -55,12 +55,11 @@ static char *ssl_cafile = NULL; ...@@ -55,12 +55,11 @@ static char *ssl_cafile = NULL;
55 #define ARG_SSL_CAFILE 4 55 #define ARG_SSL_CAFILE 4
56 56
57 static struct argp_option _tls_argp_options[] = { 57 static struct argp_option _tls_argp_options[] = {
58 {NULL, 0, NULL, 0, N_("Encryption options"), 0}, 58 {"ssl-cert", ARG_SSL_CERT, N_("FILE"), OPTION_HIDDEN,
59 {"ssl-cert", ARG_SSL_CERT, N_("FILE"), 0,
60 N_("Specify SSL certificate file"), 0}, 59 N_("Specify SSL certificate file"), 0},
61 {"ssl-key", ARG_SSL_KEY, N_("FILE"), 0, 60 {"ssl-key", ARG_SSL_KEY, N_("FILE"), OPTION_HIDDEN,
62 N_("Specify SSL certificate key"), 0}, 61 N_("Specify SSL certificate key"), },
63 {"ssl-cafile", ARG_SSL_CAFILE, N_("FILE"), 0, 62 {"ssl-cafile", ARG_SSL_CAFILE, N_("FILE"), OPTION_HIDDEN,
64 N_("Specify trusted CAs file"), 0}, 63 N_("Specify trusted CAs file"), 0},
65 {NULL, 0, NULL, 0, NULL, 0} 64 {NULL, 0, NULL, 0, NULL, 0}
66 }; 65 };
...@@ -117,7 +116,7 @@ static struct argp_child _tls_argp_child = { ...@@ -117,7 +116,7 @@ static struct argp_child _tls_argp_child = {
117 void 116 void
118 mu_tls_init_argp () 117 mu_tls_init_argp ()
119 { 118 {
120 if (mu_register_capa ("tls", &_tls_argp_child)) 119 if (mu_register_capa ("tls", &_tls_argp_child, NULL))
121 { 120 {
122 mu_error (_("INTERNAL ERROR: cannot register argp capability tls")); 121 mu_error (_("INTERNAL ERROR: cannot register argp capability tls"));
123 abort (); 122 abort ();
...@@ -145,7 +144,7 @@ static struct argp_child _tls_argp_client_child = { ...@@ -145,7 +144,7 @@ static struct argp_child _tls_argp_client_child = {
145 void 144 void
146 mu_tls_init_client_argp () 145 mu_tls_init_client_argp ()
147 { 146 {
148 if (mu_register_capa ("tls", &_tls_argp_client_child)) 147 if (mu_register_capa ("tls", &_tls_argp_client_child, NULL))
149 { 148 {
150 mu_error (_("INTERNAL ERROR: cannot register argp capability tls")); 149 mu_error (_("INTERNAL ERROR: cannot register argp capability tls"));
151 abort (); 150 abort ();
......
...@@ -191,7 +191,7 @@ mu_virt_argp_parser (int key, char *arg, struct argp_state *state) ...@@ -191,7 +191,7 @@ mu_virt_argp_parser (int key, char *arg, struct argp_state *state)
191 } 191 }
192 192
193 static struct argp_option mu_virt_argp_option[] = { 193 static struct argp_option mu_virt_argp_option[] = {
194 { "virtual-passwd-dir", ARG_PWDDIR, N_("DIR"), 0, 194 { "virtual-passwd-dir", ARG_PWDDIR, N_("DIR"), OPTION_HIDDEN,
195 N_("Search for virtual passwd file in DIR"), 0}, 195 N_("Search for virtual passwd file in DIR"), 0},
196 { NULL, 0, NULL, 0, NULL, 0 } 196 { NULL, 0, NULL, 0, NULL, 0 }
197 }; 197 };
...@@ -216,8 +216,10 @@ struct mu_auth_module mu_auth_virtual_module = { ...@@ -216,8 +216,10 @@ struct mu_auth_module mu_auth_virtual_module = {
216 "virtdomain", 216 "virtdomain",
217 #ifdef ENABLE_VIRTUAL_DOMAINS 217 #ifdef ENABLE_VIRTUAL_DOMAINS
218 &mu_virt_argp, 218 &mu_virt_argp,
219 NULL,
219 #else 220 #else
220 NULL, 221 NULL,
222 NULL,
221 #endif 223 #endif
222 mu_auth_nosupport, 224 mu_auth_nosupport,
223 NULL, 225 NULL,
......
...@@ -41,7 +41,8 @@ int login_disabled; /* Disable LOGIN command */ ...@@ -41,7 +41,8 @@ int login_disabled; /* Disable LOGIN command */
41 int tls_required; /* Require STARTTLS */ 41 int tls_required; /* Require STARTTLS */
42 int create_home_dir; /* Create home directory if it does not 42 int create_home_dir; /* Create home directory if it does not
43 exist */ 43 exist */
44 int home_dir_mode; 44 int home_dir_mode = S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
45
45 46
46 /* Number of child processes. */ 47 /* Number of child processes. */
47 size_t children; 48 size_t children;
...@@ -54,21 +55,23 @@ static char doc[] = N_("GNU imap4d -- the IMAP4D daemon"); ...@@ -54,21 +55,23 @@ static char doc[] = N_("GNU imap4d -- the IMAP4D daemon");
54 #define ARG_CREATE_HOME_DIR 3 55 #define ARG_CREATE_HOME_DIR 3
55 56
56 static struct argp_option options[] = { 57 static struct argp_option options[] = {
57 {"other-namespace", 'O', N_("PATHLIST"), 0, 58 {"other-namespace", 'O', N_("PATHLIST"), OPTION_HIDDEN,
58 N_("Set the `other' namespace"), 0}, 59 N_("Set the `other' namespace"), 0},
59 {"shared-namespace", 'S', N_("PATHLIST"), 0, 60 {"shared-namespace", 'S', N_("PATHLIST"), OPTION_HIDDEN,
60 N_("Set the `shared' namespace"), 0}, 61 N_("Set the `shared' namespace"), 0},
61 {"login-disabled", ARG_LOGIN_DISABLED, NULL, 0, 62 {"login-disabled", ARG_LOGIN_DISABLED, NULL, OPTION_HIDDEN,
62 N_("Disable LOGIN command")}, 63 N_("Disable LOGIN command")},
63 {"create-home-dir", ARG_CREATE_HOME_DIR, N_("MODE"), OPTION_ARG_OPTIONAL, 64 {"create-home-dir", ARG_CREATE_HOME_DIR, N_("MODE"),
65 OPTION_ARG_OPTIONAL|OPTION_HIDDEN,
64 N_("Create home directory, if it does not exist")}, 66 N_("Create home directory, if it does not exist")},
65 #ifdef WITH_TLS 67 #ifdef WITH_TLS
66 {"tls-required", ARG_TLS_REQUIRED, NULL, 0, 68 {"tls-required", ARG_TLS_REQUIRED, NULL, OPTION_HIDDEN,
67 N_("Always require STARTTLS before entering authentication phase")}, 69 N_("Always require STARTTLS before entering authentication phase")},
68 #endif 70 #endif
69 {NULL, 0, NULL, 0, NULL, 0} 71 {NULL, 0, NULL, 0, NULL, 0}
70 }; 72 };
71 73
74
72 static error_t imap4d_parse_opt (int key, char *arg, 75 static error_t imap4d_parse_opt (int key, char *arg,
73 struct argp_state *state); 76 struct argp_state *state);
74 77
...@@ -120,7 +123,6 @@ imap4d_parse_opt (int key, char *arg, struct argp_state *state) ...@@ -120,7 +123,6 @@ imap4d_parse_opt (int key, char *arg, struct argp_state *state)
120 123
121 case ARG_LOGIN_DISABLED: 124 case ARG_LOGIN_DISABLED:
122 login_disabled = 1; 125 login_disabled = 1;
123 imap4d_capability_add (IMAP_CAPA_LOGINDISABLED);
124 break; 126 break;
125 127
126 case ARG_CREATE_HOME_DIR: 128 case ARG_CREATE_HOME_DIR:
...@@ -132,14 +134,11 @@ imap4d_parse_opt (int key, char *arg, struct argp_state *state) ...@@ -132,14 +134,11 @@ imap4d_parse_opt (int key, char *arg, struct argp_state *state)
132 if (p || (home_dir_mode & 0777)) 134 if (p || (home_dir_mode & 0777))
133 argp_error (state, _("Invalid mode specification: %s"), arg); 135 argp_error (state, _("Invalid mode specification: %s"), arg);
134 } 136 }
135 else
136 home_dir_mode = S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
137 break; 137 break;
138 138
139 #ifdef WITH_TLS 139 #ifdef WITH_TLS
140 case ARG_TLS_REQUIRED: 140 case ARG_TLS_REQUIRED:
141 tls_required = 1; 141 tls_required = 1;
142 imap4d_capability_add (IMAP_CAPA_XTLSREQUIRED);
143 break; 142 break;
144 #endif 143 #endif
145 144
...@@ -149,6 +148,41 @@ imap4d_parse_opt (int key, char *arg, struct argp_state *state) ...@@ -149,6 +148,41 @@ imap4d_parse_opt (int key, char *arg, struct argp_state *state)
149 return 0; 148 return 0;
150 } 149 }
151 150
151 static int
152 cb_other (mu_cfg_locus_t *locus, void *data, char *arg)
153 {
154 set_namespace (NS_OTHER, arg);
155 return 0;
156 }
157
158 static int
159 cb_shared (mu_cfg_locus_t *locus, void *data, char *arg)
160 {
161 set_namespace (NS_SHARED, arg);
162 return 0;
163 }
164
165 static int
166 cb_mode (mu_cfg_locus_t *locus, void *data, char *arg)
167 {
168 char *p;
169 home_dir_mode = strtoul (arg, &p, 8);
170 if (p || (home_dir_mode & 0777))
171 mu_error (_("%s:%d: Invalid mode specification: %s"),
172 locus->file, locus->line, arg);
173 return 0;
174 }
175
176 static struct mu_cfg_param imap4d_cfg_param[] = {
177 { "other-namespace", mu_cfg_callback, NULL, cb_other },
178 { "shared-namespace", mu_cfg_callback, NULL, cb_shared },
179 { "login-disabled", mu_cfg_int, &login_disabled },
180 { "create-home-dir", mu_cfg_bool, &create_home_dir },
181 { "home-dir-mode", mu_cfg_callback, NULL, cb_mode },
182 { "tls-required", mu_cfg_int, &tls_required },
183 { NULL }
184 };
185
152 int 186 int
153 main (int argc, char **argv) 187 main (int argc, char **argv)
154 { 188 {
...@@ -170,8 +204,16 @@ main (int argc, char **argv) ...@@ -170,8 +204,16 @@ main (int argc, char **argv)
170 #ifdef WITH_GSASL 204 #ifdef WITH_GSASL
171 mu_gsasl_init_argp (); 205 mu_gsasl_init_argp ();
172 #endif 206 #endif
207 mu_config_register_plain_section (NULL, NULL, imap4d_cfg_param);
173 mu_argp_parse (&argp, &argc, &argv, 0, imap4d_capa, NULL, &daemon_param); 208 mu_argp_parse (&argp, &argc, &argv, 0, imap4d_capa, NULL, &daemon_param);
174 209
210 if (login_disabled)
211 imap4d_capability_add (IMAP_CAPA_LOGINDISABLED);
212 #ifdef WITH_TLS
213 if (tls_required)
214 imap4d_capability_add (IMAP_CAPA_XTLSREQUIRED);
215 #endif
216
175 auth_gssapi_init (); 217 auth_gssapi_init ();
176 auth_gsasl_init (); 218 auth_gsasl_init ();
177 219
......
...@@ -36,6 +36,7 @@ pkginclude_HEADERS = \ ...@@ -36,6 +36,7 @@ pkginclude_HEADERS = \
36 attribute.h \ 36 attribute.h \
37 auth.h \ 37 auth.h \
38 body.h \ 38 body.h \
39 cfg.h \
39 compat.h \ 40 compat.h \
40 daemon.h \ 41 daemon.h \
41 debug.h \ 42 debug.h \
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
21 #define _MAILUTILS_ARGP_H 21 #define _MAILUTILS_ARGP_H
22 22
23 #include <mailutils/types.h> 23 #include <mailutils/types.h>
24 #include <mailutils/cfg.h>
24 #include <argp.h> 25 #include <argp.h>
25 #include <errno.h> /* May declare program_invocation_name */ 26 #include <errno.h> /* May declare program_invocation_name */
26 27
...@@ -49,15 +50,13 @@ extern "C" { ...@@ -49,15 +50,13 @@ extern "C" {
49 50
50 extern void mu_argp_init (const char *vers, const char *bugaddr); 51 extern void mu_argp_init (const char *vers, const char *bugaddr);
51 52
52 extern void mu_create_argcv (const char *capa[],
53 int argc, char **argv,
54 int *p_argc, char ***p_argv);
55 extern error_t mu_argp_parse (const struct argp * argp, 53 extern error_t mu_argp_parse (const struct argp * argp,
56 int *p_argc, char ***p_argv, 54 int *p_argc, char ***p_argv,
57 unsigned flags, 55 unsigned flags,
58 const char *capa[], 56 const char *capa[],
59 int *arg_index, void *input); 57 int *arg_index, void *input);
60 extern int mu_register_capa (const char *name, struct argp_child *child); 58 extern int mu_register_capa (const char *name, struct argp_child *child,
59 struct mu_cfg_param *param);
61 60
62 extern void mu_print_options (void); 61 extern void mu_print_options (void);
63 extern const char *mu_check_option (char *name); 62 extern const char *mu_check_option (char *name);
......
1 /* cfg.h -- general-purpose configuration file parser
2 Copyright (C) 2007 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License as
6 published by the Free Software Foundation; either version 3, or (at
7 your option) any later version.
8
9 This program is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #ifndef _MAILUTILS_CFG_H
19 #define _MAILUTILS_CFG_H
20
21 #include <sys/socket.h>
22 #include <netinet/in.h>
23 #include <arpa/inet.h>
24
25 typedef enum mu_cfg_node_type mu_cfg_node_type_t;
26 typedef struct mu_cfg_node mu_cfg_node_t;
27 typedef struct mu_cfg_locus mu_cfg_locus_t;
28
29 typedef int (*mu_cfg_lexer_t) (void *ptr);
30 typedef void (*mu_cfg_perror_t) (void *ptr, const mu_cfg_locus_t *loc,
31 const char *fmt, ...);
32 typedef void *(*mu_cfg_alloc_t) (size_t size);
33 typedef void (*mu_cfg_free_t) (void *ptr);
34
35 enum mu_cfg_node_type
36 {
37 mu_cfg_node_undefined,
38 mu_cfg_node_tag,
39 mu_cfg_node_param
40 };
41
42 struct mu_cfg_locus
43 {
44 char *file;
45 size_t line;
46 };
47
48 struct mu_cfg_node
49 {
50 mu_cfg_node_t *next;
51 mu_cfg_locus_t locus;
52 enum mu_cfg_node_type type;
53 char *tag_name;
54 char *tag_label;
55 mu_cfg_node_t *node;
56 };
57
58 int mu_cfg_parse (mu_cfg_node_t **ptree,
59 void *data,
60 mu_cfg_lexer_t lexer,
61 mu_cfg_perror_t perror,
62 mu_cfg_alloc_t alloc,
63 mu_cfg_free_t free);
64
65 extern mu_cfg_locus_t mu_cfg_locus;
66 extern int mu_cfg_tie_in;
67 extern mu_cfg_perror_t mu_cfg_perror;
68
69 #define MU_CFG_ITER_OK 0
70 #define MU_CFG_ITER_SKIP 1
71 #define MU_CFG_ITER_STOP 2
72
73 typedef int (*mu_cfg_iter_func_t) (const mu_cfg_node_t *node, void *data);
74
75 void mu_cfg_destroy_tree (mu_cfg_node_t **tree);
76
77 int mu_cfg_preorder (mu_cfg_node_t *node,
78 mu_cfg_iter_func_t fun, mu_cfg_iter_func_t endfun,
79 void *data);
80 int mu_cfg_postorder (mu_cfg_node_t *node,
81 mu_cfg_iter_func_t fun, mu_cfg_iter_func_t endfun,
82 void *data);
83
84 int mu_cfg_find_node (mu_cfg_node_t *tree, const char *path,
85 mu_cfg_node_t **pval);
86 int mu_cfg_find_node_label (mu_cfg_node_t *tree, const char *path,
87 const char **pval);
88
89 /* Table-driven parsing */
90 enum mu_cfg_param_data_type
91 {
92 mu_cfg_string,
93 mu_cfg_short,
94 mu_cfg_ushort,
95 mu_cfg_int,
96 mu_cfg_uint,
97 mu_cfg_long,
98 mu_cfg_ulong,
99 mu_cfg_size,
100 mu_cfg_off,
101 mu_cfg_bool,
102 mu_cfg_ipv4,
103 mu_cfg_cidr,
104 mu_cfg_host,
105 mu_cfg_callback
106 };
107
108 typedef int (*mu_cfg_callback_t) (mu_cfg_locus_t *, void *, char *);
109
110 struct mu_cfg_param
111 {
112 const char *ident;
113 enum mu_cfg_param_data_type type;
114 void *data;
115 mu_cfg_callback_t callback;
116 };
117
118 enum mu_cfg_section_stage
119 {
120 mu_cfg_section_start,
121 mu_cfg_section_end
122 };
123
124 typedef int (*mu_cfg_section_fp) (enum mu_cfg_section_stage stage,
125 const mu_cfg_node_t *node,
126 void *section_data, void *call_data);
127
128 struct mu_cfg_section
129 {
130 const char *ident;
131 mu_cfg_section_fp parser;
132 void *data;
133 struct mu_cfg_section *subsec;
134 struct mu_cfg_param *param;
135 };
136
137 typedef struct mu_cfg_cidr mu_cfg_cidr_t;
138
139 struct mu_cfg_cidr
140 {
141 struct in_addr addr;
142 unsigned long mask;
143 };
144
145 int mu_cfg_scan_tree (mu_cfg_node_t *node,
146 struct mu_cfg_section *sections,
147 void *data, mu_cfg_perror_t perror,
148 mu_cfg_alloc_t palloc, mu_cfg_free_t pfree);
149
150 int mu_cfg_find_section (struct mu_cfg_section *root_sec,
151 const char *path, struct mu_cfg_section **retval);
152
153 int mu_config_register_section (const char *parent_path,
154 const char *ident,
155 mu_cfg_section_fp parser,
156 void *data,
157 struct mu_cfg_param *param);
158 int mu_config_register_plain_section (const char *parent_path,
159 const char *ident,
160 struct mu_cfg_param *params);
161
162 #endif
...@@ -116,7 +116,7 @@ sieve_argp_parser (int key, char *arg, struct argp_state *state) ...@@ -116,7 +116,7 @@ sieve_argp_parser (int key, char *arg, struct argp_state *state)
116 void 116 void
117 mu_sieve_argp_init () 117 mu_sieve_argp_init ()
118 { 118 {
119 if (mu_register_capa ("sieve", &sieve_argp_child)) 119 if (mu_register_capa ("sieve", &sieve_argp_child, NULL))
120 { 120 {
121 mu_error ("INTERNAL ERROR: cannot register argp capability sieve"); 121 mu_error ("INTERNAL ERROR: cannot register argp capability sieve");
122 abort (); 122 abort ();
......
...@@ -32,7 +32,7 @@ AM_CPPFLAGS = \ ...@@ -32,7 +32,7 @@ AM_CPPFLAGS = \
32 -DSITE_VIRTUAL_PWDDIR=\"@SITE_VIRTUAL_PWDDIR@\"\ 32 -DSITE_VIRTUAL_PWDDIR=\"@SITE_VIRTUAL_PWDDIR@\"\
33 -DLOCALEDIR=\"$(localedir)\" 33 -DLOCALEDIR=\"$(localedir)\"
34 34
35 EXTRA_DIST = @MU_EXTRA_DIST@ errors muerrno.cin parsedate.y fgetpwent.c 35 EXTRA_DIST = @MU_EXTRA_DIST@ errors muerrno.cin parsedate.y fgetpwent.c cfg_parser.y cfg_parser.h
36 36
37 libmailutils_la_SOURCES = \ 37 libmailutils_la_SOURCES = \
38 address.c \ 38 address.c \
...@@ -46,6 +46,8 @@ body.c \ ...@@ -46,6 +46,8 @@ body.c \
46 daemon.c \ 46 daemon.c \
47 date.c \ 47 date.c \
48 debug.c \ 48 debug.c \
49 cfg_lexer.c \
50 cfg_parser.c \
49 envelope.c \ 51 envelope.c \
50 file_stream.c \ 52 file_stream.c \
51 filter.c \ 53 filter.c \
...@@ -83,6 +85,7 @@ parsedate.c \ ...@@ -83,6 +85,7 @@ parsedate.c \
83 property.c \ 85 property.c \
84 registrar.c \ 86 registrar.c \
85 rfc2047.c \ 87 rfc2047.c \
88 socket_stream.c \
86 stream.c \ 89 stream.c \
87 system.c \ 90 system.c \
88 tcp.c \ 91 tcp.c \
...@@ -98,6 +101,12 @@ parsedate.c: $(srcdir)/parsedate.y ...@@ -98,6 +101,12 @@ parsedate.c: $(srcdir)/parsedate.y
98 y.tab.c parsedate.c y.output parsedate.y.output \ 101 y.tab.c parsedate.c y.output parsedate.y.output \
99 -- -yy pd_yy 102 -- -yy pd_yy
100 103
104 cfg_parser.c: $(srcdir)/cfg_parser.y
105 $(YLWRAP) "$(YACC) $(AM_YFLAGS) -d" $< \
106 y.tab.c cfg_parser.c y.tab.h cfg_parser.h \
107 y.output cfg_parser.y.output \
108 -- -yy mu_cfg_yy
109
101 muerrno.c: errors muerrno.cin 110 muerrno.c: errors muerrno.cin
102 $(AWK) -f $(top_srcdir)/scripts/generr.awk $^ > $@ 111 $(AWK) -f $(top_srcdir)/scripts/generr.awk $^ > $@
103 112
......
1 /* cfg_lexer.c -- default lexer for Mailutils configuration files
2 Copyright (C) 2007 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License as
6 published by the Free Software Foundation; either version 3, or (at
7 your option) any later version.
8
9 This program is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <fcntl.h>
23 #include <errno.h>
24 #include <unistd.h>
25 #include <ctype.h>
26 #include <mailutils/argcv.h>
27 #include <mailutils/nls.h>
28 #include <mailutils/cfg.h>
29 #include <mailutils/errno.h>
30 #include <mailutils/error.h>
31 #include <mailutils/mutil.h>
32
33 #define obstack_chunk_alloc malloc
34 #define obstack_chunk_free free
35 #include "obstack.h"
36 #include "cfg_parser.h"
37
38 struct lexer_data
39 {
40 char *buffer;
41 char *curp;
42 struct obstack stk;
43 };
44
45 static void
46 skipws (struct lexer_data *p)
47 {
48 while (*p->curp && isspace (*p->curp))
49 {
50 if (*p->curp == '\n')
51 mu_cfg_locus.line++;
52 p->curp++;
53 }
54 }
55
56 static void
57 skipline (struct lexer_data *p)
58 {
59 while (*p->curp && *p->curp != '\n')
60 p->curp++;
61 }
62
63 static int
64 isword (int c)
65 {
66 if (mu_cfg_tie_in)
67 return c && c != ';';
68
69 return isalnum (c) || c == '_' || c == '-';
70 }
71
72 static char *
73 copy_alpha (struct lexer_data *p)
74 {
75 do
76 {
77 if (*p->curp == '\n')
78 mu_cfg_locus.line++;
79 obstack_1grow (&p->stk, *p->curp);
80 p->curp++;
81 } while (*p->curp && isword(*p->curp));
82 obstack_1grow (&p->stk, 0);
83 return obstack_finish (&p->stk);
84 }
85
86 static char *
87 copy_string(struct lexer_data *p)
88 {
89 int quote = *p->curp++;
90
91 while (*p->curp)
92 {
93 if (*p->curp == '\\')
94 {
95 char c;
96 if (*++p->curp == 0)
97 {
98 obstack_1grow (&p->stk, '\\');
99 break;
100 }
101 c = mu_argcv_unquote_char (*p->curp);
102 if (c == *p->curp)
103 {
104 obstack_1grow (&p->stk, '\\');
105 obstack_1grow (&p->stk, *p->curp);
106 }
107 else
108 obstack_1grow (&p->stk, c);
109 p->curp++;
110 }
111 else if (*p->curp == quote)
112 {
113 p->curp++;
114 break;
115 }
116 else
117 {
118 obstack_1grow (&p->stk, *p->curp);
119 p->curp++;
120 }
121 }
122 obstack_1grow (&p->stk, 0);
123 return obstack_finish (&p->stk);
124 }
125
126 int
127 default_lexer (void *dp)
128 {
129 struct lexer_data *p = dp;
130 char *save_start;
131 char *tag, *label;
132
133 again:
134 skipws (p);
135
136 if (*p->curp == '#')
137 {
138 skipline (p);
139 goto again;
140 }
141
142 if (*p->curp == '/' && p->curp[1] == '*')
143 {
144 int keep_line = mu_cfg_locus.line;
145
146 p->curp += 2;
147 do
148 {
149 while (*p->curp != '*')
150 {
151 if (*p->curp == 0)
152 {
153 mu_cfg_perror (p,
154 &mu_cfg_locus,
155 _("unexpected EOF in comment started at line %d"),
156 keep_line);
157 return 0;
158 }
159 else if (*p->curp == '\n')
160 mu_cfg_locus.line++;
161 ++p->curp;
162 }
163 } while (*++p->curp != '/');
164 ++p->curp;
165 goto again;
166 }
167
168 if (*p->curp == 0)
169 return 0;
170
171 if (*p->curp == '\"')
172 {
173 mu_cfg_yylval.string = copy_string (p);
174 return MU_CFG_STRING_TOKEN;
175 }
176
177 if (mu_cfg_tie_in)
178 {
179 mu_cfg_yylval.string = copy_alpha (p);
180 return MU_CFG_STRING_TOKEN;
181 }
182
183 if (*p->curp == '}')
184 {
185 p->curp++;
186 memset (&mu_cfg_yylval.node, 0, sizeof mu_cfg_yylval.node);
187 mu_cfg_yylval.node.locus = mu_cfg_locus;
188 return MU_CFG_END_TOKEN;
189 }
190
191 if (*p->curp == ';')
192 {
193 p->curp++;
194 return MU_CFG_EOL_TOKEN;
195 }
196
197 tag = copy_alpha (p);
198 skipws (p);
199 if (*p->curp == '"')
200 {
201 mu_cfg_yylval.string = tag;
202 return MU_CFG_STRING_TOKEN;
203 }
204
205 save_start = p->curp;
206 if (*p->curp != '{')
207 {
208 label = copy_alpha(p);
209 skipws(p);
210 }
211 else
212 label = NULL;
213 if (*p->curp == '{')
214 {
215 p->curp++;
216 mu_cfg_yylval.node.tag_name = tag;
217 mu_cfg_yylval.node.locus = mu_cfg_locus;
218 mu_cfg_yylval.node.tag_label = label;
219 return MU_CFG_START_TOKEN;
220 }
221 else
222 {
223 p->curp = save_start;
224 mu_cfg_yylval.string = tag;
225 }
226 return MU_CFG_STRING_TOKEN;
227 }
228
229 static struct mu_cfg_section *root_section;
230
231 int
232 mu_config_register_section (const char *parent_path,
233 const char *ident,
234 mu_cfg_section_fp parser,
235 void *data,
236 struct mu_cfg_param *param)
237 {
238 struct mu_cfg_section *parent;
239 size_t size = 0;
240
241 if (!root_section)
242 {
243 root_section = calloc (1, sizeof (root_section[0]));
244 if (!root_section)
245 return MU_ERR_NOENT;
246 }
247
248 if (parent_path)
249 {
250 if (mu_cfg_find_section (root_section, parent_path, &parent))
251 return MU_ERR_NOENT;
252 }
253 else
254 parent = root_section;
255
256 if (ident)
257 {
258 struct mu_cfg_section *s;
259
260 if (parent->subsec)
261 for (s = parent->subsec; s->ident; s++)
262 size++;
263
264 s = realloc (parent->subsec, (size + 2) * sizeof parent->subsec[0]);
265 if (!s)
266 return ENOMEM;
267 parent->subsec = s;
268 s = parent->subsec + size;
269 s[1].ident = NULL;
270
271 s->ident = strdup (ident);
272 s->parser = parser;
273 s->data = data;
274 s->subsec = NULL;
275 s->param = param;
276 }
277 else
278 {
279 size_t orig_size = 0;
280 struct mu_cfg_param *p;
281 if (parent->param)
282 for (p = parent->param; p->ident; p++)
283 orig_size++;
284 size = 0;
285 for (p = param; p->ident; p++)
286 size++;
287 parent->param = realloc (parent->param,
288 (size + orig_size + 1)
289 * sizeof (parent->param[0]));
290 memcpy (parent->param + orig_size, param,
291 size * sizeof (parent->param[0]));
292 if (!parent->parser)
293 parent->parser = parser;
294 if (!parent->data)
295 parent->data = data;
296 }
297 return 0;
298 }
299
300 int
301 mu_config_register_plain_section (const char *parent_path, const char *ident,
302 struct mu_cfg_param *params)
303 {
304 return mu_config_register_section (parent_path, ident, NULL, NULL, params);
305 }
306
307 static int
308 _mu_parse_config (char *file, char *progname)
309 {
310 struct lexer_data data;
311 struct stat st;
312 int fd;
313 extern int mu_cfg_yydebug;
314 int rc;
315 mu_cfg_node_t *parse_tree;
316
317 mu_cfg_locus.file = file;
318 mu_cfg_locus.line = 1;
319
320 if (stat (mu_cfg_locus.file, &st))
321 {
322 mu_error (_("can't stat `%s'"), mu_cfg_locus.file);
323 return -1;
324 }
325 fd = open (mu_cfg_locus.file, O_RDONLY);
326 if (fd == -1)
327 {
328 if (errno != ENOENT)
329 mu_error (_("can't open config file `%s'"),
330 mu_cfg_locus.file);
331 return -1;
332 }
333 data.buffer = malloc (st.st_size+1);
334
335 read (fd, data.buffer, st.st_size);
336 data.buffer[st.st_size] = 0;
337 close (fd);
338 data.curp = data.buffer;
339
340 mu_cfg_yydebug = strncmp (data.curp, "#debug", 6) == 0;
341
342 obstack_init (&data.stk);
343
344 /* Parse configuration */
345 rc = mu_cfg_parse (&parse_tree,
346 &data,
347 default_lexer,
348 NULL,
349 NULL,
350 NULL);
351
352 if (rc == 0)
353 {
354 rc = mu_cfg_scan_tree (parse_tree, root_section,
355 progname, NULL, NULL, NULL);
356 }
357
358 mu_cfg_destroy_tree (&parse_tree);
359 obstack_free (&data.stk, NULL);
360 free (data.buffer);
361
362 return rc;
363 }
364
365 int
366 mu_parse_config (char *file, char *progname)
367 {
368 int rc;
369 char *full_name = mu_tilde_expansion (file, "/", NULL);
370 if (full_name)
371 {
372 if (access (full_name, R_OK) == 0)
373 {
374 rc = _mu_parse_config (full_name, progname);
375 free (full_name);
376 }
377 else
378 rc = ENOENT;
379 }
380 else
381 rc = ENOMEM;
382 return rc;
383 }
1 /* A Bison parser, made by GNU Bison 2.3. */
2
3 /* Skeleton interface for Bison's Yacc-like parsers in C
4
5 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
6 Free Software Foundation, Inc.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
22
23 /* As a special exception, you may create a larger work that contains
24 part or all of the Bison parser skeleton and distribute that work
25 under terms of your choice, so long as that work isn't itself a
26 parser generator using the skeleton or a modified version thereof
27 as a parser skeleton. Alternatively, if you modify or redistribute
28 the parser skeleton itself, you may (at your option) remove this
29 special exception, which will cause the skeleton and the resulting
30 Bison output files to be licensed under the GNU General Public
31 License without this special exception.
32
33 This special exception was added by the Free Software Foundation in
34 version 2.2 of Bison. */
35
36 /* Tokens. */
37 #ifndef YYTOKENTYPE
38 # define YYTOKENTYPE
39 /* Put the tokens into the symbol table, so that GDB and other debuggers
40 know about them. */
41 enum mu_cfg_yytokentype {
42 MU_CFG_EOL_TOKEN = 258,
43 MU_CFG_START_TOKEN = 259,
44 MU_CFG_END_TOKEN = 260,
45 MU_CFG_STRING_TOKEN = 261
46 };
47 #endif
48 /* Tokens. */
49 #define MU_CFG_EOL_TOKEN 258
50 #define MU_CFG_START_TOKEN 259
51 #define MU_CFG_END_TOKEN 260
52 #define MU_CFG_STRING_TOKEN 261
53
54
55
56
57 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
58 typedef union YYSTYPE
59 #line 115 "cfg_parser.y"
60 {
61 mu_cfg_node_t node;
62 mu_cfg_node_t *pnode;
63 struct
64 {
65 mu_cfg_node_t *head, *tail;
66 } nodelist;
67 char *string;
68 }
69 /* Line 1489 of yacc.c. */
70 #line 71 "cfg_parser.h"
71 YYSTYPE;
72 # define mu_cfg_yystype YYSTYPE /* obsolescent; will be withdrawn */
73 # define YYSTYPE_IS_DECLARED 1
74 # define YYSTYPE_IS_TRIVIAL 1
75 #endif
76
77 extern YYSTYPE mu_cfg_yylval;
78
...@@ -241,8 +241,10 @@ mu_authenticate (struct mu_auth_data *auth_data, char *pass) ...@@ -241,8 +241,10 @@ mu_authenticate (struct mu_auth_data *auth_data, char *pass)
241 return mu_auth_runlist (mu_authenticate_list, NULL, auth_data, pass); 241 return mu_auth_runlist (mu_authenticate_list, NULL, auth_data, pass);
242 } 242 }
243 243
244 /* Modules & configuration */ 244
245 245 /* ************************************************************************* */
246 /* Traditional configuration */
247 /* ************************************************************************* */
246 248
247 #define ARG_AUTHORIZATION 1 249 #define ARG_AUTHORIZATION 1
248 #define ARG_AUTHENTICATION 2 250 #define ARG_AUTHENTICATION 2
...@@ -252,22 +254,22 @@ static error_t mu_auth_argp_parser (int key, char *arg, ...@@ -252,22 +254,22 @@ static error_t mu_auth_argp_parser (int key, char *arg,
252 254
253 /* Options used by programs that use extended authentication mechanisms. */ 255 /* Options used by programs that use extended authentication mechanisms. */
254 static struct argp_option mu_auth_argp_option[] = { 256 static struct argp_option mu_auth_argp_option[] = {
255 { "authentication", ARG_AUTHENTICATION, N_("MODLIST"), 0, 257 { "authentication", ARG_AUTHENTICATION, N_("MODLIST"), OPTION_HIDDEN,
256 N_("Set the list of modules to be used for authentication"), 0 }, 258 N_("Set the list of modules to be used for authentication"), 0 },
257 { "authorization", ARG_AUTHORIZATION, N_("MODLIST"), 0, 259 { "authorization", ARG_AUTHORIZATION, N_("MODLIST"), OPTION_HIDDEN,
258 N_("Set list of modules to be used for authorization"), 0 }, 260 N_("Set list of modules to be used for authorization"), 0 },
259 { NULL, 0, NULL, 0, NULL, 0 } 261 { NULL, 0, NULL, 0, NULL, 0 }
260 }; 262 };
261 263
262 struct argp mu_auth_argp = { 264 static struct argp mu_auth_argp = {
263 mu_auth_argp_option, 265 mu_auth_argp_option,
264 mu_auth_argp_parser, 266 mu_auth_argp_parser,
265 }; 267 };
266 268
267 struct argp_child mu_auth_argp_child = { 269 static struct argp_child mu_auth_argp_child = {
268 &mu_auth_argp, 270 &mu_auth_argp,
269 0, 271 0,
270 "Authentication options", 272 NULL,
271 0 273 0
272 }; 274 };
273 275
...@@ -295,6 +297,43 @@ mu_auth_argp_parser (int key, char *arg, struct argp_state *state) ...@@ -295,6 +297,43 @@ mu_auth_argp_parser (int key, char *arg, struct argp_state *state)
295 return 0; 297 return 0;
296 } 298 }
297 299
300
301 /* ************************************************************************* */
302 /* Resource-style configuration */
303 /* ************************************************************************* */
304 static int
305 cb_authentication (mu_cfg_locus_t *locus, void *data, char *arg)
306 {
307 mu_authentication_add_module_list (arg);/*FIXME: error reporting*/
308 return 0;
309 }
310
311 static int
312 cb_authorization (mu_cfg_locus_t *locus, void *data, char *arg)
313 {
314 mu_authorization_add_module_list (arg);
315 return 0;
316 }
317
318 static struct mu_cfg_param mu_auth_param[] = {
319 { "authentication", mu_cfg_callback, NULL, cb_authentication },
320 { "authorization", mu_cfg_callback, NULL, cb_authorization },
321 { NULL }
322 };
323
324
325 void
326 mu_auth_init ()
327 {
328 if (mu_register_capa ("auth", &mu_auth_argp_child, mu_auth_param))
329 {
330 mu_error (_("INTERNAL ERROR: cannot register argp capability auth (please report)"));
331 abort ();
332 }
333 }
334
335
336 /* ************************************************************************* */
298 337
299 struct _module_handler { 338 struct _module_handler {
300 struct auth_stack_entry authenticate; 339 struct auth_stack_entry authenticate;
...@@ -342,7 +381,10 @@ mu_auth_register_module (struct mu_auth_module *mod) ...@@ -342,7 +381,10 @@ mu_auth_register_module (struct mu_auth_module *mod)
342 cp++; 381 cp++;
343 cp->argp = NULL; 382 cp->argp = NULL;
344 } 383 }
345 384
385 if (mod->cfg)
386 mu_config_register_plain_section (NULL, mod->name, mod->cfg);
387
346 if (!module_handler_list && mu_list_create (&module_handler_list)) 388 if (!module_handler_list && mu_list_create (&module_handler_list))
347 abort (); 389 abort ();
348 390
......
...@@ -138,6 +138,7 @@ mu_authenticate_system (struct mu_auth_data **return_data MU_ARG_UNUSED, ...@@ -138,6 +138,7 @@ mu_authenticate_system (struct mu_auth_data **return_data MU_ARG_UNUSED,
138 struct mu_auth_module mu_auth_system_module = { 138 struct mu_auth_module mu_auth_system_module = {
139 "system", 139 "system",
140 NULL, 140 NULL,
141 NULL,
141 mu_authenticate_system, 142 mu_authenticate_system,
142 NULL, 143 NULL,
143 mu_auth_system_by_name, 144 mu_auth_system_by_name,
...@@ -150,6 +151,7 @@ struct mu_auth_module mu_auth_system_module = { ...@@ -150,6 +151,7 @@ struct mu_auth_module mu_auth_system_module = {
150 struct mu_auth_module mu_auth_generic_module = { 151 struct mu_auth_module mu_auth_generic_module = {
151 "generic", 152 "generic",
152 NULL, 153 NULL,
154 NULL,
153 mu_authenticate_generic, 155 mu_authenticate_generic,
154 NULL, 156 NULL,
155 mu_auth_nosupport, 157 mu_auth_nosupport,
......