]> andersk Git - openssh.git/blob - servconf.c
- (djm) Add pointer to http://www.imasy.or.jp/~gotoh/connect.c to
[openssh.git] / servconf.c
1 /*
2  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
3  *                    All rights reserved
4  *
5  * As far as I am concerned, the code I have written for this software
6  * can be used freely for any purpose.  Any derived versions of this
7  * software must be clearly marked as such, and if the derived work is
8  * incompatible with the protocol description in the RFC file, it must be
9  * called by a name other than "ssh" or "Secure Shell".
10  */
11
12 #include "includes.h"
13 RCSID("$OpenBSD: servconf.c,v 1.53 2000/10/14 12:12:09 markus Exp $");
14
15 #include "ssh.h"
16 #include "servconf.h"
17 #include "xmalloc.h"
18 #include "compat.h"
19
20 /* add listen address */
21 void add_listen_addr(ServerOptions *options, char *addr);
22
23 /* Initializes the server options to their default values. */
24
25 void
26 initialize_server_options(ServerOptions *options)
27 {
28         memset(options, 0, sizeof(*options));
29         options->num_ports = 0;
30         options->ports_from_cmdline = 0;
31         options->listen_addrs = NULL;
32         options->host_key_file = NULL;
33         options->host_dsa_key_file = NULL;
34         options->pid_file = NULL;
35         options->server_key_bits = -1;
36         options->login_grace_time = -1;
37         options->key_regeneration_time = -1;
38         options->permit_root_login = -1;
39         options->ignore_rhosts = -1;
40         options->ignore_user_known_hosts = -1;
41         options->print_motd = -1;
42         options->check_mail = -1;
43         options->x11_forwarding = -1;
44         options->x11_display_offset = -1;
45         options->xauth_location = NULL;
46         options->strict_modes = -1;
47         options->keepalives = -1;
48         options->log_facility = (SyslogFacility) - 1;
49         options->log_level = (LogLevel) - 1;
50         options->rhosts_authentication = -1;
51         options->rhosts_rsa_authentication = -1;
52         options->rsa_authentication = -1;
53         options->dsa_authentication = -1;
54 #ifdef KRB4
55         options->kerberos_authentication = -1;
56         options->kerberos_or_local_passwd = -1;
57         options->kerberos_ticket_cleanup = -1;
58 #endif
59 #ifdef AFS
60         options->kerberos_tgt_passing = -1;
61         options->afs_token_passing = -1;
62 #endif
63         options->password_authentication = -1;
64         options->kbd_interactive_authentication = -1;
65 #ifdef SKEY
66         options->skey_authentication = -1;
67 #endif
68         options->permit_empty_passwd = -1;
69         options->use_login = -1;
70         options->allow_tcp_forwarding = -1;
71         options->num_allow_users = 0;
72         options->num_deny_users = 0;
73         options->num_allow_groups = 0;
74         options->num_deny_groups = 0;
75         options->ciphers = NULL;
76         options->protocol = SSH_PROTO_UNKNOWN;
77         options->gateway_ports = -1;
78         options->num_subsystems = 0;
79         options->max_startups_begin = -1;
80         options->max_startups_rate = -1;
81         options->max_startups = -1;
82 }
83
84 void
85 fill_default_server_options(ServerOptions *options)
86 {
87         if (options->num_ports == 0)
88                 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
89         if (options->listen_addrs == NULL)
90                 add_listen_addr(options, NULL);
91         if (options->host_key_file == NULL)
92                 options->host_key_file = HOST_KEY_FILE;
93         if (options->host_dsa_key_file == NULL)
94                 options->host_dsa_key_file = HOST_DSA_KEY_FILE;
95         if (options->pid_file == NULL)
96                 options->pid_file = SSH_DAEMON_PID_FILE;
97         if (options->server_key_bits == -1)
98                 options->server_key_bits = 768;
99         if (options->login_grace_time == -1)
100                 options->login_grace_time = 600;
101         if (options->key_regeneration_time == -1)
102                 options->key_regeneration_time = 3600;
103         if (options->permit_root_login == -1)
104                 options->permit_root_login = 1;                 /* yes */
105         if (options->ignore_rhosts == -1)
106                 options->ignore_rhosts = 1;
107         if (options->ignore_user_known_hosts == -1)
108                 options->ignore_user_known_hosts = 0;
109         if (options->check_mail == -1)
110                 options->check_mail = 0;
111         if (options->print_motd == -1)
112                 options->print_motd = 1;
113         if (options->x11_forwarding == -1)
114                 options->x11_forwarding = 0;
115         if (options->x11_display_offset == -1)
116                 options->x11_display_offset = 10;
117 #ifdef XAUTH_PATH
118         if (options->xauth_location == NULL)
119                 options->xauth_location = XAUTH_PATH;
120 #endif /* XAUTH_PATH */
121         if (options->strict_modes == -1)
122                 options->strict_modes = 1;
123         if (options->keepalives == -1)
124                 options->keepalives = 1;
125         if (options->log_facility == (SyslogFacility) (-1))
126                 options->log_facility = SYSLOG_FACILITY_AUTH;
127         if (options->log_level == (LogLevel) (-1))
128                 options->log_level = SYSLOG_LEVEL_INFO;
129         if (options->rhosts_authentication == -1)
130                 options->rhosts_authentication = 0;
131         if (options->rhosts_rsa_authentication == -1)
132                 options->rhosts_rsa_authentication = 0;
133         if (options->rsa_authentication == -1)
134                 options->rsa_authentication = 1;
135         if (options->dsa_authentication == -1)
136                 options->dsa_authentication = 1;
137 #ifdef KRB4
138         if (options->kerberos_authentication == -1)
139                 options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
140         if (options->kerberos_or_local_passwd == -1)
141                 options->kerberos_or_local_passwd = 1;
142         if (options->kerberos_ticket_cleanup == -1)
143                 options->kerberos_ticket_cleanup = 1;
144 #endif /* KRB4 */
145 #ifdef AFS
146         if (options->kerberos_tgt_passing == -1)
147                 options->kerberos_tgt_passing = 0;
148         if (options->afs_token_passing == -1)
149                 options->afs_token_passing = k_hasafs();
150 #endif /* AFS */
151         if (options->password_authentication == -1)
152                 options->password_authentication = 1;
153         if (options->kbd_interactive_authentication == -1)
154                 options->kbd_interactive_authentication = 0;
155 #ifdef SKEY
156         if (options->skey_authentication == -1)
157                 options->skey_authentication = 1;
158 #endif
159         if (options->permit_empty_passwd == -1)
160                 options->permit_empty_passwd = 0;
161         if (options->use_login == -1)
162                 options->use_login = 0;
163         if (options->allow_tcp_forwarding == -1)
164                 options->allow_tcp_forwarding = 1;
165         if (options->protocol == SSH_PROTO_UNKNOWN)
166                 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
167         if (options->gateway_ports == -1)
168                 options->gateway_ports = 0;
169         if (options->max_startups == -1)
170                 options->max_startups = 10;
171         if (options->max_startups_rate == -1)
172                 options->max_startups_rate = 100;               /* 100% */
173         if (options->max_startups_begin == -1)
174                 options->max_startups_begin = options->max_startups;
175 }
176
177 /* Keyword tokens. */
178 typedef enum {
179         sBadOption,             /* == unknown option */
180         sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
181         sPermitRootLogin, sLogFacility, sLogLevel,
182         sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
183 #ifdef KRB4
184         sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
185 #endif
186 #ifdef AFS
187         sKerberosTgtPassing, sAFSTokenPassing,
188 #endif
189 #ifdef SKEY
190         sSkeyAuthentication,
191 #endif
192         sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
193         sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset,
194         sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail,
195         sUseLogin, sAllowTcpForwarding,
196         sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
197         sIgnoreUserKnownHosts, sHostDSAKeyFile, sCiphers, sProtocol, sPidFile,
198         sGatewayPorts, sDSAAuthentication, sXAuthLocation, sSubsystem, sMaxStartups
199 } ServerOpCodes;
200
201 /* Textual representation of the tokens. */
202 static struct {
203         const char *name;
204         ServerOpCodes opcode;
205 } keywords[] = {
206         { "port", sPort },
207         { "hostkey", sHostKeyFile },
208         { "hostdsakey", sHostDSAKeyFile },
209         { "pidfile", sPidFile },
210         { "serverkeybits", sServerKeyBits },
211         { "logingracetime", sLoginGraceTime },
212         { "keyregenerationinterval", sKeyRegenerationTime },
213         { "permitrootlogin", sPermitRootLogin },
214         { "syslogfacility", sLogFacility },
215         { "loglevel", sLogLevel },
216         { "rhostsauthentication", sRhostsAuthentication },
217         { "rhostsrsaauthentication", sRhostsRSAAuthentication },
218         { "rsaauthentication", sRSAAuthentication },
219         { "dsaauthentication", sDSAAuthentication },
220 #ifdef KRB4
221         { "kerberosauthentication", sKerberosAuthentication },
222         { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
223         { "kerberosticketcleanup", sKerberosTicketCleanup },
224 #endif
225 #ifdef AFS
226         { "kerberostgtpassing", sKerberosTgtPassing },
227         { "afstokenpassing", sAFSTokenPassing },
228 #endif
229         { "passwordauthentication", sPasswordAuthentication },
230         { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
231 #ifdef SKEY
232         { "skeyauthentication", sSkeyAuthentication },
233 #endif
234         { "checkmail", sCheckMail },
235         { "listenaddress", sListenAddress },
236         { "printmotd", sPrintMotd },
237         { "ignorerhosts", sIgnoreRhosts },
238         { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
239         { "x11forwarding", sX11Forwarding },
240         { "x11displayoffset", sX11DisplayOffset },
241         { "xauthlocation", sXAuthLocation },
242         { "strictmodes", sStrictModes },
243         { "permitemptypasswords", sEmptyPasswd },
244         { "uselogin", sUseLogin },
245         { "randomseed", sRandomSeedFile },
246         { "keepalive", sKeepAlives },
247         { "allowtcpforwarding", sAllowTcpForwarding },
248         { "allowusers", sAllowUsers },
249         { "denyusers", sDenyUsers },
250         { "allowgroups", sAllowGroups },
251         { "denygroups", sDenyGroups },
252         { "ciphers", sCiphers },
253         { "protocol", sProtocol },
254         { "gatewayports", sGatewayPorts },
255         { "subsystem", sSubsystem },
256         { "maxstartups", sMaxStartups },
257         { NULL, 0 }
258 };
259
260 /*
261  * Returns the number of the token pointed to by cp of length len. Never
262  * returns if the token is not known.
263  */
264
265 static ServerOpCodes
266 parse_token(const char *cp, const char *filename,
267             int linenum)
268 {
269         unsigned int i;
270
271         for (i = 0; keywords[i].name; i++)
272                 if (strcasecmp(cp, keywords[i].name) == 0)
273                         return keywords[i].opcode;
274
275         fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
276                 filename, linenum, cp);
277         return sBadOption;
278 }
279
280 /*
281  * add listen address
282  */
283 void
284 add_listen_addr(ServerOptions *options, char *addr)
285 {
286         extern int IPv4or6;
287         struct addrinfo hints, *ai, *aitop;
288         char strport[NI_MAXSERV];
289         int gaierr;
290         int i;
291
292         if (options->num_ports == 0)
293                 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
294         for (i = 0; i < options->num_ports; i++) {
295                 memset(&hints, 0, sizeof(hints));
296                 hints.ai_family = IPv4or6;
297                 hints.ai_socktype = SOCK_STREAM;
298                 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
299                 snprintf(strport, sizeof strport, "%d", options->ports[i]);
300                 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
301                         fatal("bad addr or host: %s (%s)\n",
302                             addr ? addr : "<NULL>",
303                             gai_strerror(gaierr));
304                 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
305                         ;
306                 ai->ai_next = options->listen_addrs;
307                 options->listen_addrs = aitop;
308         }
309 }
310
311 /* Reads the server configuration file. */
312
313 void
314 read_server_config(ServerOptions *options, const char *filename)
315 {
316         FILE *f;
317         char line[1024];
318         char *cp, **charptr, *arg;
319         int linenum, *intptr, value;
320         int bad_options = 0;
321         ServerOpCodes opcode;
322         int i;
323
324         f = fopen(filename, "r");
325         if (!f) {
326                 perror(filename);
327                 exit(1);
328         }
329         linenum = 0;
330         while (fgets(line, sizeof(line), f)) {
331                 linenum++;
332                 cp = line;
333                 arg = strdelim(&cp);
334                 /* Ignore leading whitespace */
335                 if (*arg == '\0')
336                         arg = strdelim(&cp);
337                 if (!*arg || *arg == '#')
338                         continue;
339                 opcode = parse_token(arg, filename, linenum);
340                 switch (opcode) {
341                 case sBadOption:
342                         bad_options++;
343                         continue;
344                 case sPort:
345                         /* ignore ports from configfile if cmdline specifies ports */
346                         if (options->ports_from_cmdline)
347                                 continue;
348                         if (options->listen_addrs != NULL)
349                                 fatal("%s line %d: ports must be specified before "
350                                     "ListenAdress.\n", filename, linenum);
351                         if (options->num_ports >= MAX_PORTS)
352                                 fatal("%s line %d: too many ports.\n",
353                                     filename, linenum);
354                         arg = strdelim(&cp);
355                         if (!arg || *arg == '\0')
356                                 fatal("%s line %d: missing port number.\n",
357                                     filename, linenum);
358                         options->ports[options->num_ports++] = atoi(arg);
359                         break;
360
361                 case sServerKeyBits:
362                         intptr = &options->server_key_bits;
363 parse_int:
364                         arg = strdelim(&cp);
365                         if (!arg || *arg == '\0') {
366                                 fprintf(stderr, "%s line %d: missing integer value.\n",
367                                         filename, linenum);
368                                 exit(1);
369                         }
370                         value = atoi(arg);
371                         if (*intptr == -1)
372                                 *intptr = value;
373                         break;
374
375                 case sLoginGraceTime:
376                         intptr = &options->login_grace_time;
377                         goto parse_int;
378
379                 case sKeyRegenerationTime:
380                         intptr = &options->key_regeneration_time;
381                         goto parse_int;
382
383                 case sListenAddress:
384                         arg = strdelim(&cp);
385                         if (!arg || *arg == '\0')
386                                 fatal("%s line %d: missing inet addr.\n",
387                                     filename, linenum);
388                         add_listen_addr(options, arg);
389                         break;
390
391                 case sHostKeyFile:
392                 case sHostDSAKeyFile:
393                         charptr = (opcode == sHostKeyFile ) ?
394                             &options->host_key_file : &options->host_dsa_key_file;
395 parse_filename:
396                         arg = strdelim(&cp);
397                         if (!arg || *arg == '\0') {
398                                 fprintf(stderr, "%s line %d: missing file name.\n",
399                                     filename, linenum);
400                                 exit(1);
401                         }
402                         if (*charptr == NULL)
403                                 *charptr = tilde_expand_filename(arg, getuid());
404                         break;
405
406                 case sPidFile:
407                         charptr = &options->pid_file;
408                         goto parse_filename;
409
410                 case sRandomSeedFile:
411                         fprintf(stderr, "%s line %d: \"randomseed\" option is obsolete.\n",
412                                 filename, linenum);
413                         arg = strdelim(&cp);
414                         break;
415
416                 case sPermitRootLogin:
417                         intptr = &options->permit_root_login;
418                         arg = strdelim(&cp);
419                         if (!arg || *arg == '\0') {
420                                 fprintf(stderr, "%s line %d: missing yes/without-password/no argument.\n",
421                                         filename, linenum);
422                                 exit(1);
423                         }
424                         if (strcmp(arg, "without-password") == 0)
425                                 value = 2;
426                         else if (strcmp(arg, "yes") == 0)
427                                 value = 1;
428                         else if (strcmp(arg, "no") == 0)
429                                 value = 0;
430                         else {
431                                 fprintf(stderr, "%s line %d: Bad yes/without-password/no argument: %s\n",
432                                         filename, linenum, arg);
433                                 exit(1);
434                         }
435                         if (*intptr == -1)
436                                 *intptr = value;
437                         break;
438
439                 case sIgnoreRhosts:
440                         intptr = &options->ignore_rhosts;
441 parse_flag:
442                         arg = strdelim(&cp);
443                         if (!arg || *arg == '\0') {
444                                 fprintf(stderr, "%s line %d: missing yes/no argument.\n",
445                                         filename, linenum);
446                                 exit(1);
447                         }
448                         if (strcmp(arg, "yes") == 0)
449                                 value = 1;
450                         else if (strcmp(arg, "no") == 0)
451                                 value = 0;
452                         else {
453                                 fprintf(stderr, "%s line %d: Bad yes/no argument: %s\n",
454                                         filename, linenum, arg);
455                                 exit(1);
456                         }
457                         if (*intptr == -1)
458                                 *intptr = value;
459                         break;
460
461                 case sIgnoreUserKnownHosts:
462                         intptr = &options->ignore_user_known_hosts;
463                         goto parse_flag;
464
465                 case sRhostsAuthentication:
466                         intptr = &options->rhosts_authentication;
467                         goto parse_flag;
468
469                 case sRhostsRSAAuthentication:
470                         intptr = &options->rhosts_rsa_authentication;
471                         goto parse_flag;
472
473                 case sRSAAuthentication:
474                         intptr = &options->rsa_authentication;
475                         goto parse_flag;
476
477                 case sDSAAuthentication:
478                         intptr = &options->dsa_authentication;
479                         goto parse_flag;
480
481 #ifdef KRB4
482                 case sKerberosAuthentication:
483                         intptr = &options->kerberos_authentication;
484                         goto parse_flag;
485
486                 case sKerberosOrLocalPasswd:
487                         intptr = &options->kerberos_or_local_passwd;
488                         goto parse_flag;
489
490                 case sKerberosTicketCleanup:
491                         intptr = &options->kerberos_ticket_cleanup;
492                         goto parse_flag;
493 #endif
494
495 #ifdef AFS
496                 case sKerberosTgtPassing:
497                         intptr = &options->kerberos_tgt_passing;
498                         goto parse_flag;
499
500                 case sAFSTokenPassing:
501                         intptr = &options->afs_token_passing;
502                         goto parse_flag;
503 #endif
504
505                 case sPasswordAuthentication:
506                         intptr = &options->password_authentication;
507                         goto parse_flag;
508
509                 case sKbdInteractiveAuthentication:
510                         intptr = &options->kbd_interactive_authentication;
511                         goto parse_flag;
512
513                 case sCheckMail:
514                         intptr = &options->check_mail;
515                         goto parse_flag;
516
517 #ifdef SKEY
518                 case sSkeyAuthentication:
519                         intptr = &options->skey_authentication;
520                         goto parse_flag;
521 #endif
522
523                 case sPrintMotd:
524                         intptr = &options->print_motd;
525                         goto parse_flag;
526
527                 case sX11Forwarding:
528                         intptr = &options->x11_forwarding;
529                         goto parse_flag;
530
531                 case sX11DisplayOffset:
532                         intptr = &options->x11_display_offset;
533                         goto parse_int;
534
535                 case sXAuthLocation:
536                         charptr = &options->xauth_location;
537                         goto parse_filename;
538                         
539                 case sStrictModes:
540                         intptr = &options->strict_modes;
541                         goto parse_flag;
542
543                 case sKeepAlives:
544                         intptr = &options->keepalives;
545                         goto parse_flag;
546
547                 case sEmptyPasswd:
548                         intptr = &options->permit_empty_passwd;
549                         goto parse_flag;
550
551                 case sUseLogin:
552                         intptr = &options->use_login;
553                         goto parse_flag;
554
555                 case sGatewayPorts:
556                         intptr = &options->gateway_ports;
557                         goto parse_flag;
558
559                 case sLogFacility:
560                         intptr = (int *) &options->log_facility;
561                         arg = strdelim(&cp);
562                         value = log_facility_number(arg);
563                         if (value == (SyslogFacility) - 1)
564                                 fatal("%.200s line %d: unsupported log facility '%s'\n",
565                                     filename, linenum, arg ? arg : "<NONE>");
566                         if (*intptr == -1)
567                                 *intptr = (SyslogFacility) value;
568                         break;
569
570                 case sLogLevel:
571                         intptr = (int *) &options->log_level;
572                         arg = strdelim(&cp);
573                         value = log_level_number(arg);
574                         if (value == (LogLevel) - 1)
575                                 fatal("%.200s line %d: unsupported log level '%s'\n",
576                                     filename, linenum, arg ? arg : "<NONE>");
577                         if (*intptr == -1)
578                                 *intptr = (LogLevel) value;
579                         break;
580
581                 case sAllowTcpForwarding:
582                         intptr = &options->allow_tcp_forwarding;
583                         goto parse_flag;
584
585                 case sAllowUsers:
586                         while ((arg = strdelim(&cp)) && *arg != '\0') {
587                                 if (options->num_allow_users >= MAX_ALLOW_USERS)
588                                         fatal("%s line %d: too many allow users.\n",
589                                             filename, linenum);
590                                 options->allow_users[options->num_allow_users++] = xstrdup(arg);
591                         }
592                         break;
593
594                 case sDenyUsers:
595                         while ((arg = strdelim(&cp)) && *arg != '\0') {
596                                 if (options->num_deny_users >= MAX_DENY_USERS)
597                                         fatal( "%s line %d: too many deny users.\n",
598                                             filename, linenum);
599                                 options->deny_users[options->num_deny_users++] = xstrdup(arg);
600                         }
601                         break;
602
603                 case sAllowGroups:
604                         while ((arg = strdelim(&cp)) && *arg != '\0') {
605                                 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
606                                         fatal("%s line %d: too many allow groups.\n",
607                                             filename, linenum);
608                                 options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
609                         }
610                         break;
611
612                 case sDenyGroups:
613                         while ((arg = strdelim(&cp)) && *arg != '\0') {
614                                 if (options->num_deny_groups >= MAX_DENY_GROUPS)
615                                         fatal("%s line %d: too many deny groups.\n",
616                                             filename, linenum);
617                                 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
618                         }
619                         break;
620
621                 case sCiphers:
622                         arg = strdelim(&cp);
623                         if (!arg || *arg == '\0')
624                                 fatal("%s line %d: Missing argument.", filename, linenum);
625                         if (!ciphers_valid(arg))
626                                 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
627                                     filename, linenum, arg ? arg : "<NONE>");
628                         if (options->ciphers == NULL)
629                                 options->ciphers = xstrdup(arg);
630                         break;
631
632                 case sProtocol:
633                         intptr = &options->protocol;
634                         arg = strdelim(&cp);
635                         if (!arg || *arg == '\0')
636                                 fatal("%s line %d: Missing argument.", filename, linenum);
637                         value = proto_spec(arg);
638                         if (value == SSH_PROTO_UNKNOWN)
639                                 fatal("%s line %d: Bad protocol spec '%s'.",
640                                       filename, linenum, arg ? arg : "<NONE>");
641                         if (*intptr == SSH_PROTO_UNKNOWN)
642                                 *intptr = value;
643                         break;
644
645                 case sSubsystem:
646                         if(options->num_subsystems >= MAX_SUBSYSTEMS) {
647                                 fatal("%s line %d: too many subsystems defined.",
648                                       filename, linenum);
649                         }
650                         arg = strdelim(&cp);
651                         if (!arg || *arg == '\0')
652                                 fatal("%s line %d: Missing subsystem name.",
653                                       filename, linenum);
654                         for (i = 0; i < options->num_subsystems; i++)
655                                 if(strcmp(arg, options->subsystem_name[i]) == 0)
656                                         fatal("%s line %d: Subsystem '%s' already defined.",
657                                               filename, linenum, arg);
658                         options->subsystem_name[options->num_subsystems] = xstrdup(arg);
659                         arg = strdelim(&cp);
660                         if (!arg || *arg == '\0')
661                                 fatal("%s line %d: Missing subsystem command.",
662                                       filename, linenum);
663                         options->subsystem_command[options->num_subsystems] = xstrdup(arg);
664                         options->num_subsystems++;
665                         break;
666
667                 case sMaxStartups:
668                         arg = strdelim(&cp);
669                         if (!arg || *arg == '\0')
670                                 fatal("%s line %d: Missing MaxStartups spec.",
671                                       filename, linenum);
672                         if (sscanf(arg, "%d:%d:%d",
673                             &options->max_startups_begin,
674                             &options->max_startups_rate,
675                             &options->max_startups) == 3) {
676                                 if (options->max_startups_begin >
677                                     options->max_startups ||
678                                     options->max_startups_rate > 100 ||
679                                     options->max_startups_rate < 1)
680                                 fatal("%s line %d: Illegal MaxStartups spec.",
681                                       filename, linenum);
682                                 break;
683                         }
684                         intptr = &options->max_startups;
685                         goto parse_int;
686
687                 default:
688                         fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n",
689                                 filename, linenum, arg, opcode);
690                         exit(1);
691                 }
692                 if ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
693                         fprintf(stderr, 
694                                 "%s line %d: garbage at end of line; \"%.200s\".\n",
695                                 filename, linenum, arg);
696                         exit(1);
697                 }
698         }
699         fclose(f);
700         if (bad_options > 0) {
701                 fprintf(stderr, "%s: terminating, %d bad configuration options\n",
702                         filename, bad_options);
703                 exit(1);
704         }
705 }
This page took 0.09672 seconds and 5 git commands to generate.