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