1 /*
2 * ProFTPD - FTP server daemon
3 * Copyright (c) 1997, 1998 Public Flood Software
4 * Copyright (c) 1999, 2000 MacGyver aka Habeeb J. Dihu <macgyver@tos.net>
5 * Copyright (c) 2001-2020 The ProFTPD Project team
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
20 *
21 * As a special exemption, Public Flood Software/MacGyver aka Habeeb J. Dihu
22 * and other respective copyright holders give permission to link this program
23 * with OpenSSL, and distribute the resulting executable, without including
24 * the source code for OpenSSL in the source distribution.
25 */
26
27 /* House initialization and main program loop */
28
29 #include "conf.h"
30
31 #ifdef HAVE_GETOPT_H
32 # include <getopt.h>
33 #endif
34
35 #ifdef HAVE_LIBUTIL_H
36 # include <libutil.h>
37 #endif /* HAVE_LIBUTIL_H */
38
39 #ifdef HAVE_UNAME
40 # include <sys/utsname.h>
41 #endif
42
43 #include "privs.h"
44
45 #ifdef PR_USE_OPENSSL
46 # include <openssl/opensslv.h>
47 #endif /* PR_USE_OPENSSL */
48
49 int (*cmd_auth_chk)(cmd_rec *);
50 void (*cmd_handler)(server_rec *, conn_t *);
51
52 /* From modules/module_glue.c */
53 extern module *static_modules[];
54
55 extern int have_dead_child;
56 extern xaset_t *server_list;
57
58 unsigned long max_connects = 0UL;
59 unsigned int max_connect_interval = 1;
60
61 session_t session;
62
63 /* Is this process the master standalone daemon process? */
64 unsigned char is_master = TRUE;
65
66 pid_t mpid = 0; /* Master pid */
67
68 uid_t daemon_uid;
69 gid_t daemon_gid;
70 array_header *daemon_gids;
71
72 static time_t shut = 0, deny = 0, disc = 0;
73 static char shutmsg[81] = {'\0'};
74
75 /* The default command buffer size SHOULD be large enough to handle the
76 * maximum path length, plus 4 bytes for the FTP command, plus 1 for the
77 * whitespace separating command from path, and 2 for the terminating CRLF.
78 */
79 #define PR_DEFAULT_CMD_BUFSZ (PR_TUNABLE_PATH_MAX + 7)
80
81 /* From response.c */
82 extern pr_response_t *resp_list, *resp_err_list;
83
84 int nodaemon = 0;
85
86 static int no_forking = FALSE;
87 static int quiet = 0;
88 static int shutting_down = 0;
89 static int syntax_check = 0;
90
91 /* Command handling */
92 static void cmd_loop(server_rec *s, conn_t *conn);
93
94 static cmd_rec *make_ftp_cmd(pool *p, char *buf, size_t buflen, int flags);
95
96 static const char *config_filename = PR_CONFIG_FILE_PATH;
97
98 /* Add child semaphore fds into the rfd for selecting */
semaphore_fds(fd_set * rfd,int maxfd)99 static int semaphore_fds(fd_set *rfd, int maxfd) {
100 if (child_count()) {
101 pr_child_t *ch;
102
103 for (ch = child_get(NULL); ch; ch = child_get(ch)) {
104 pr_signals_handle();
105
106 if (ch->ch_pipefd != -1) {
107 FD_SET(ch->ch_pipefd, rfd);
108 if (ch->ch_pipefd > maxfd) {
109 maxfd = ch->ch_pipefd;
110 }
111 }
112 }
113 }
114
115 return maxfd;
116 }
117
set_auth_check(int (* chk)(cmd_rec *))118 void set_auth_check(int (*chk)(cmd_rec*)) {
119 cmd_auth_chk = chk;
120 }
121
pr_cmd_set_handler(void (* handler)(server_rec *,conn_t *))122 void pr_cmd_set_handler(void (*handler)(server_rec *, conn_t *)) {
123 if (handler == NULL) {
124 cmd_handler = cmd_loop;
125
126 } else {
127 cmd_handler = handler;
128 }
129 }
130
session_exit(int pri,void * lv,int exitval,void * dummy)131 void session_exit(int pri, void *lv, int exitval, void *dummy) {
132 char *msg = (char *) lv;
133
134 pr_log_pri(pri, "%s", msg);
135
136 if (ServerType == SERVER_STANDALONE &&
137 is_master) {
138 pr_log_pri(PR_LOG_NOTICE, "ProFTPD " PROFTPD_VERSION_TEXT
139 " standalone mode SHUTDOWN");
140
141 PRIVS_ROOT
142 pr_delete_scoreboard();
143 if (!nodaemon)
144 pr_pidfile_remove();
145 PRIVS_RELINQUISH
146 }
147
148 pr_session_end(0);
149 }
150
shutdown_end_session(void * d1,void * d2,void * d3,void * d4)151 void shutdown_end_session(void *d1, void *d2, void *d3, void *d4) {
152 pool *p = permanent_pool;
153
154 if (check_shutmsg(p, PR_SHUTMSG_PATH, &shut, &deny, &disc, shutmsg,
155 sizeof(shutmsg)) == 1) {
156 const char *user;
157 time_t now;
158 const char *msg, *serveraddress;
159 config_rec *c = NULL;
160 unsigned char *authenticated = get_param_ptr(main_server->conf,
161 "authenticated", FALSE);
162
163 serveraddress = (session.c && session.c->local_addr) ?
164 pr_netaddr_get_ipstr(session.c->local_addr) :
165 main_server->ServerAddress;
166
167 c = find_config(main_server->conf, CONF_PARAM, "MasqueradeAddress", FALSE);
168 if (c != NULL) {
169 pr_netaddr_t *masq_addr = NULL;
170
171 if (c->argv[0] != NULL) {
172 masq_addr = c->argv[0];
173 }
174
175 if (masq_addr != NULL) {
176 serveraddress = pr_netaddr_get_ipstr(masq_addr);
177 }
178 }
179
180 time(&now);
181 if (authenticated && *authenticated == TRUE) {
182 user = pr_table_get(session.notes, "mod_auth.orig-user", NULL);
183
184 } else {
185 user = "NONE";
186 }
187
188 msg = sreplace(p, shutmsg,
189 "%s", pstrdup(p, pr_strtime3(p, shut, FALSE)),
190 "%r", pstrdup(p, pr_strtime3(p, deny, FALSE)),
191 "%d", pstrdup(p, pr_strtime3(p, disc, FALSE)),
192 "%C", (session.cwd[0] ? session.cwd : "(none)"),
193 "%L", serveraddress,
194 "%R", (session.c && session.c->remote_name ?
195 session.c->remote_name : "(unknown)"),
196 "%T", pstrdup(p, pr_strtime3(p, now, FALSE)),
197 "%U", user,
198 "%V", main_server->ServerName,
199 NULL );
200
201 pr_response_send_async(R_421, _("FTP server shutting down - %s"), msg);
202
203 pr_log_pri(PR_LOG_NOTICE, "%s", msg);
204 pr_session_disconnect(NULL, PR_SESS_DISCONNECT_SERVER_SHUTDOWN, NULL);
205 }
206
207 if (signal(SIGUSR1, pr_signals_handle_disconnect) == SIG_ERR) {
208 pr_log_pri(PR_LOG_NOTICE,
209 "unable to install SIGUSR1 (signal %d) handler: %s", SIGUSR1,
210 strerror(errno));
211 }
212 }
213
get_command_class(const char * name)214 static int get_command_class(const char *name) {
215 int idx = -1;
216 unsigned int hash = 0;
217 cmdtable *c;
218
219 c = pr_stash_get_symbol2(PR_SYM_CMD, name, NULL, &idx, &hash);
220 while (c && c->cmd_type != CMD) {
221 pr_signals_handle();
222 c = pr_stash_get_symbol2(PR_SYM_CMD, name, c, &idx, &hash);
223 }
224
225 /* By default, every command has a class of CL_ALL. This insures that
226 * any configured ExtendedLogs that default to "all" will log the command.
227 */
228 return (c ? c->cmd_class : CL_ALL);
229 }
230
_dispatch(cmd_rec * cmd,int cmd_type,int validate,char * match)231 static int _dispatch(cmd_rec *cmd, int cmd_type, int validate, char *match) {
232 const char *cmdargstr = NULL;
233 cmdtable *c;
234 modret_t *mr;
235 int success = 0, xerrno = 0;
236 int send_error = 0;
237 static int match_index_cache = -1;
238 static unsigned int match_hash_cache = 0;
239 static char *last_match = NULL;
240 int *index_cache = NULL;
241 unsigned int *hash_cache = NULL;
242
243 send_error = (cmd_type == PRE_CMD || cmd_type == CMD ||
244 cmd_type == POST_CMD_ERR);
245
246 if (!match) {
247 match = cmd->argv[0];
248 index_cache = &cmd->stash_index;
249 hash_cache = &cmd->stash_hash;
250
251 } else {
252 if (last_match != match) {
253 match_index_cache = -1;
254 last_match = match;
255 }
256
257 index_cache = &match_index_cache;
258 hash_cache = &match_hash_cache;
259 }
260
261 c = pr_stash_get_symbol2(PR_SYM_CMD, match, NULL, index_cache, hash_cache);
262
263 while (c && !success) {
264 size_t cmdargstrlen = 0;
265
266 pr_signals_handle();
267
268 session.curr_cmd = cmd->argv[0];
269 session.curr_cmd_id = cmd->cmd_id;
270 session.curr_cmd_rec = cmd;
271 session.curr_phase = cmd_type;
272
273 if (c->cmd_type == cmd_type) {
274 if (c->group) {
275 cmd->group = pstrdup(cmd->pool, c->group);
276 }
277
278 if (c->requires_auth &&
279 cmd_auth_chk &&
280 !cmd_auth_chk(cmd)) {
281 pr_trace_msg("command", 8,
282 "command '%s' failed 'requires_auth' check for mod_%s.c",
283 (char *) cmd->argv[0], c->m->name);
284 errno = EACCES;
285 return -1;
286 }
287
288 if (cmd->tmp_pool == NULL) {
289 cmd->tmp_pool = make_sub_pool(cmd->pool);
290 pr_pool_tag(cmd->tmp_pool, "cmd_rec tmp pool");
291 }
292
293 cmdargstr = pr_cmd_get_displayable_str(cmd, &cmdargstrlen);
294
295 if (cmd_type == CMD) {
296
297 /* The client has successfully authenticated... */
298 if (session.user) {
299 char *args = NULL;
300
301 /* Be defensive, and check whether cmdargstrlen has a value.
302 * If it's zero, assume we need to use strchr(3), rather than
303 * memchr(2); see Bug#3714.
304 */
305 if (cmdargstrlen > 0) {
306 args = memchr(cmdargstr, ' ', cmdargstrlen);
307
308 } else {
309 args = strchr(cmdargstr, ' ');
310 }
311
312 pr_scoreboard_entry_update(session.pid,
313 PR_SCORE_CMD, "%s", cmd->argv[0], NULL, NULL);
314 pr_scoreboard_entry_update(session.pid,
315 PR_SCORE_CMD_ARG, "%s", args ? (args + 1) : "", NULL, NULL);
316
317 pr_proctitle_set("%s - %s: %s", session.user, session.proc_prefix,
318 cmdargstr);
319
320 /* ...else the client has not yet authenticated */
321 } else {
322 pr_proctitle_set("%s:%d: %s", session.c->remote_addr ?
323 pr_netaddr_get_ipstr(session.c->remote_addr) : "?",
324 session.c->remote_port ? session.c->remote_port : 0, cmdargstr);
325 }
326 }
327
328 /* Skip logging the internal CONNECT/DISCONNECT commands. */
329 if (!(cmd->cmd_class & CL_CONNECT) &&
330 !(cmd->cmd_class & CL_DISCONNECT)) {
331
332 pr_log_debug(DEBUG4, "dispatching %s command '%s' to mod_%s",
333 (cmd_type == PRE_CMD ? "PRE_CMD" :
334 cmd_type == CMD ? "CMD" :
335 cmd_type == POST_CMD ? "POST_CMD" :
336 cmd_type == POST_CMD_ERR ? "POST_CMD_ERR" :
337 cmd_type == LOG_CMD ? "LOG_CMD" :
338 cmd_type == LOG_CMD_ERR ? "LOG_CMD_ERR" :
339 "(unknown)"),
340 cmdargstr, c->m->name);
341
342 pr_trace_msg("command", 7, "dispatching %s command '%s' to mod_%s.c",
343 (cmd_type == PRE_CMD ? "PRE_CMD" :
344 cmd_type == CMD ? "CMD" :
345 cmd_type == POST_CMD ? "POST_CMD" :
346 cmd_type == POST_CMD_ERR ? "POST_CMD_ERR" :
347 cmd_type == LOG_CMD ? "LOG_CMD" :
348 cmd_type == LOG_CMD_ERR ? "LOG_CMD_ERR" :
349 "(unknown)"),
350 cmdargstr, c->m->name);
351 }
352
353 cmd->cmd_class |= c->cmd_class;
354
355 /* KLUDGE: disable umask() for not G_WRITE operations. Config/
356 * Directory walking code will be completely redesigned in 1.3,
357 * this is only necessary for performance reasons in 1.1/1.2
358 */
359
360 if (!c->group || strcmp(c->group, G_WRITE) != 0)
361 kludge_disable_umask();
362 mr = pr_module_call(c->m, c->handler, cmd);
363 kludge_enable_umask();
364
365 if (MODRET_ISHANDLED(mr)) {
366 success = 1;
367
368 } else if (MODRET_ISERROR(mr)) {
369 xerrno = errno;
370 success = -1;
371
372 if (cmd_type == POST_CMD ||
373 cmd_type == LOG_CMD ||
374 cmd_type == LOG_CMD_ERR) {
375 if (MODRET_ERRMSG(mr)) {
376 pr_log_pri(PR_LOG_NOTICE, "%s", MODRET_ERRMSG(mr));
377 }
378
379 /* Even though we normally want to return a negative value
380 * for success (indicating lack of success), for
381 * LOG_CMD/LOG_CMD_ERR handlers, we always want to handle
382 * errors as a success value of zero (meaning "keep looking").
383 *
384 * This will allow the cmd_rec to continue to be dispatched to
385 * the other interested handlers (Bug#3633).
386 */
387 if (cmd_type == LOG_CMD ||
388 cmd_type == LOG_CMD_ERR) {
389 success = 0;
390 }
391
392 } else if (send_error) {
393 if (MODRET_ERRNUM(mr) &&
394 MODRET_ERRMSG(mr)) {
395 pr_response_add_err(MODRET_ERRNUM(mr), "%s", MODRET_ERRMSG(mr));
396
397 } else if (MODRET_ERRMSG(mr)) {
398 pr_response_send_raw("%s", MODRET_ERRMSG(mr));
399 }
400 }
401
402 errno = xerrno;
403 }
404
405 if (session.user &&
406 !(session.sf_flags & SF_XFER) &&
407 cmd_type == CMD) {
408 pr_session_set_idle();
409 }
410
411 destroy_pool(cmd->tmp_pool);
412 cmd->tmp_pool = NULL;
413 }
414
415 if (!success) {
416 c = pr_stash_get_symbol2(PR_SYM_CMD, match, c, index_cache, hash_cache);
417 }
418 }
419
420 /* Note: validate is only TRUE for the CMD phase, for specific handlers
421 * (as opposed to any C_ANY handlers).
422 */
423
424 if (!c &&
425 !success &&
426 validate) {
427 char *method;
428
429 /* Prettify the command method, if need be. */
430 if (strchr(cmd->argv[0], '_') == NULL) {
431 method = cmd->argv[0];
432
433 } else {
434 register unsigned int i;
435
436 method = pstrdup(cmd->pool, cmd->argv[0]);
437 for (i = 0; method[i]; i++) {
438 if (method[i] == '_')
439 method[i] = ' ';
440 }
441 }
442
443 pr_event_generate("core.unhandled-command", cmd);
444
445 pr_response_add_err(R_500, _("%s not understood"), method);
446 success = -1;
447 }
448
449 return success;
450 }
451
452 /* Returns the appropriate maximum buffer size to use for FTP commands
453 * from the client.
454 */
get_max_cmd_sz(void)455 static size_t get_max_cmd_sz(void) {
456 size_t res;
457 size_t *bufsz = NULL;
458
459 bufsz = get_param_ptr(main_server->conf, "CommandBufferSize", FALSE);
460 if (bufsz == NULL) {
461 res = PR_DEFAULT_CMD_BUFSZ;
462
463 } else {
464 pr_log_debug(DEBUG1, "setting CommandBufferSize to %lu",
465 (unsigned long) *bufsz);
466 res = *bufsz;
467 }
468
469 return res;
470 }
471
pr_cmd_read(cmd_rec ** res)472 int pr_cmd_read(cmd_rec **res) {
473 static long cmd_bufsz = -1;
474 static char *cmd_buf = NULL;
475 int cmd_buflen;
476 unsigned int too_large_count = 0;
477 char *ptr;
478
479 if (res == NULL) {
480 errno = EINVAL;
481 return -1;
482 }
483
484 if (cmd_bufsz == -1) {
485 cmd_bufsz = get_max_cmd_sz();
486 }
487
488 if (cmd_buf == NULL) {
489 cmd_buf = pcalloc(session.pool, cmd_bufsz + 1);
490 }
491
492 while (TRUE) {
493 pr_signals_handle();
494
495 memset(cmd_buf, '\0', cmd_bufsz);
496
497 cmd_buflen = pr_netio_telnet_gets2(cmd_buf, cmd_bufsz, session.c->instrm,
498 session.c->outstrm);
499 if (cmd_buflen < 0) {
500 if (errno == E2BIG) {
501 /* The client sent a too-long command which was ignored; give
502 * them a few more chances, with minor delays?
503 */
504 too_large_count++;
505 pr_timer_usleep(250 * 1000);
506
507 if (too_large_count > 3) {
508 return -1;
509 }
510
511 continue;
512 }
513
514 if (session.c->instrm->strm_errno == 0) {
515 pr_trace_msg("command", 6,
516 "client sent EOF, closing control connection");
517 }
518
519 return -1;
520 }
521
522 break;
523 }
524
525 /* If the read length is less than the cmd_bufsz, then there is no need to
526 * truncate the buffer by inserting a NUL.
527 */
528 if (cmd_buflen > cmd_bufsz) {
529 pr_log_debug(DEBUG0, "truncating incoming command length (%d bytes) to "
530 "CommandBufferSize %lu; use the CommandBufferSize directive to increase "
531 "the allowed command length", cmd_buflen, (unsigned long) cmd_bufsz);
532 cmd_buf[cmd_bufsz-1] = '\0';
533 }
534
535 if (cmd_buflen > 0 &&
536 (cmd_buf[cmd_buflen-1] == '\n' || cmd_buf[cmd_buflen-1] == '\r')) {
537 cmd_buf[cmd_buflen-1] = '\0';
538 cmd_buflen--;
539
540 if (cmd_buflen > 0 &&
541 (cmd_buf[cmd_buflen-1] == '\n' || cmd_buf[cmd_buflen-1] =='\r')) {
542 cmd_buf[cmd_buflen-1] = '\0';
543 cmd_buflen--;
544 }
545 }
546
547 ptr = cmd_buf;
548 if (*ptr == '\r') {
549 ptr++;
550 }
551
552 if (*ptr) {
553 int flags = 0;
554 cmd_rec *cmd;
555
556 /* If this is a SITE command, preserve embedded whitespace in the
557 * command parameters, in order to handle file names that have multiple
558 * spaces in the names. Arguably this should be handled in the SITE
559 * command handlers themselves, via cmd->arg. This small hack
560 * reduces the burden on SITE module developers, however.
561 */
562 if (strncasecmp(ptr, C_SITE, 4) == 0) {
563 flags |= PR_STR_FL_PRESERVE_WHITESPACE;
564 }
565
566 cmd = make_ftp_cmd(session.pool, ptr, cmd_buflen, flags);
567 if (cmd != NULL) {
568 *res = cmd;
569
570 if (pr_cmd_is_http(cmd) == TRUE) {
571 cmd->is_ftp = FALSE;
572 cmd->protocol = "HTTP";
573
574 } else if (pr_cmd_is_ssh2(cmd) == TRUE) {
575 cmd->is_ftp = FALSE;
576 cmd->protocol = "SSH2";
577
578 } else if (pr_cmd_is_smtp(cmd) == TRUE) {
579 cmd->is_ftp = FALSE;
580 cmd->protocol = "SMTP";
581
582 } else {
583 /* Assume that the client is sending valid FTP commands. */
584 cmd->is_ftp = TRUE;
585 cmd->protocol = "FTP";
586 }
587 }
588 }
589
590 return 0;
591 }
592
set_cmd_start_ms(cmd_rec * cmd)593 static int set_cmd_start_ms(cmd_rec *cmd) {
594 void *v;
595 uint64_t start_ms;
596
597 if (cmd->notes == NULL) {
598 return 0;
599 }
600
601 v = (void *) pr_table_get(cmd->notes, "start_ms", NULL);
602 if (v != NULL) {
603 return 0;
604 }
605
606 if (pr_gettimeofday_millis(&start_ms) < 0) {
607 return -1;
608 }
609
610 v = palloc(cmd->pool, sizeof(uint64_t));
611 memcpy(v, &start_ms, sizeof(uint64_t));
612
613 return pr_table_add(cmd->notes, "start_ms", v, sizeof(uint64_t));
614 }
615
pr_cmd_dispatch_phase(cmd_rec * cmd,int phase,int flags)616 int pr_cmd_dispatch_phase(cmd_rec *cmd, int phase, int flags) {
617 char *cp = NULL;
618 int success = 0, xerrno = 0;
619 pool *resp_pool = NULL;
620
621 if (cmd == NULL) {
622 errno = EINVAL;
623 return -1;
624 }
625
626 cmd->server = main_server;
627
628 if (flags & PR_CMD_DISPATCH_FL_CLEAR_RESPONSE) {
629 /* Skip logging the internal CONNECT/DISCONNECT commands. */
630 if (!(cmd->cmd_class & CL_CONNECT) &&
631 !(cmd->cmd_class & CL_DISCONNECT)) {
632 pr_trace_msg("response", 9,
633 "clearing response lists before dispatching command '%s'",
634 (char *) cmd->argv[0]);
635 }
636 pr_response_clear(&resp_list);
637 pr_response_clear(&resp_err_list);
638 }
639
640 /* Get any previous pool that may be being used by the Response API.
641 *
642 * In most cases, this will be NULL. However, if proftpd is in the
643 * midst of a data transfer when a command comes in on the control
644 * connection, then the pool in use will be that of the data transfer
645 * instigating command. We want to stash that pool, so that after this
646 * command is dispatched, we can return the pool of the old command.
647 * Otherwise, Bad Things (segfaults) happen.
648 */
649 resp_pool = pr_response_get_pool();
650
651 /* Set the pool used by the Response API for this command. */
652 pr_response_set_pool(cmd->pool);
653
654 for (cp = cmd->argv[0]; *cp; cp++) {
655 *cp = toupper(*cp);
656 }
657
658 if (cmd->cmd_class == 0) {
659 cmd->cmd_class = get_command_class(cmd->argv[0]);
660 }
661
662 if (cmd->cmd_id == 0) {
663 cmd->cmd_id = pr_cmd_get_id(cmd->argv[0]);
664 }
665
666 set_cmd_start_ms(cmd);
667
668 if (phase == 0) {
669 /* First, dispatch to wildcard PRE_CMD handlers. */
670 success = _dispatch(cmd, PRE_CMD, FALSE, C_ANY);
671
672 if (!success) /* run other pre_cmd */
673 success = _dispatch(cmd, PRE_CMD, FALSE, NULL);
674
675 if (success < 0) {
676 /* Dispatch to POST_CMD_ERR handlers as well. */
677
678 _dispatch(cmd, POST_CMD_ERR, FALSE, C_ANY);
679 _dispatch(cmd, POST_CMD_ERR, FALSE, NULL);
680
681 _dispatch(cmd, LOG_CMD_ERR, FALSE, C_ANY);
682 _dispatch(cmd, LOG_CMD_ERR, FALSE, NULL);
683
684 xerrno = errno;
685 pr_trace_msg("response", 9, "flushing error response list for '%s'",
686 (char *) cmd->argv[0]);
687 pr_response_flush(&resp_err_list);
688
689 /* Restore any previous pool to the Response API. */
690 pr_response_set_pool(resp_pool);
691
692 errno = xerrno;
693 return success;
694 }
695
696 success = _dispatch(cmd, CMD, FALSE, C_ANY);
697 if (!success)
698 success = _dispatch(cmd, CMD, TRUE, NULL);
699
700 if (success == 1) {
701 success = _dispatch(cmd, POST_CMD, FALSE, C_ANY);
702 if (!success)
703 success = _dispatch(cmd, POST_CMD, FALSE, NULL);
704
705 _dispatch(cmd, LOG_CMD, FALSE, C_ANY);
706 _dispatch(cmd, LOG_CMD, FALSE, NULL);
707
708 xerrno = errno;
709 pr_trace_msg("response", 9, "flushing response list for '%s'",
710 (char *) cmd->argv[0]);
711 pr_response_flush(&resp_list);
712
713 errno = xerrno;
714
715 } else if (success < 0) {
716 /* Allow for non-logging command handlers to be run if CMD fails. */
717
718 success = _dispatch(cmd, POST_CMD_ERR, FALSE, C_ANY);
719 if (!success)
720 success = _dispatch(cmd, POST_CMD_ERR, FALSE, NULL);
721
722 _dispatch(cmd, LOG_CMD_ERR, FALSE, C_ANY);
723 _dispatch(cmd, LOG_CMD_ERR, FALSE, NULL);
724
725 xerrno = errno;
726 pr_trace_msg("response", 9, "flushing error response list for '%s'",
727 (char *) cmd->argv[0]);
728 pr_response_flush(&resp_err_list);
729
730 errno = xerrno;
731 }
732
733 } else {
734 switch (phase) {
735 case PRE_CMD:
736 case POST_CMD:
737 case POST_CMD_ERR:
738 success = _dispatch(cmd, phase, FALSE, C_ANY);
739 if (!success) {
740 success = _dispatch(cmd, phase, FALSE, NULL);
741 xerrno = errno;
742 }
743 break;
744
745 case CMD:
746 success = _dispatch(cmd, phase, FALSE, C_ANY);
747 if (!success)
748 success = _dispatch(cmd, phase, TRUE, NULL);
749 break;
750
751 case LOG_CMD:
752 case LOG_CMD_ERR:
753 (void) _dispatch(cmd, phase, FALSE, C_ANY);
754 (void) _dispatch(cmd, phase, FALSE, NULL);
755 break;
756
757 default:
758 /* Restore any previous pool to the Response API. */
759 pr_response_set_pool(resp_pool);
760
761 errno = EINVAL;
762 return -1;
763 }
764
765 if (flags & PR_CMD_DISPATCH_FL_SEND_RESPONSE) {
766 xerrno = errno;
767
768 if (success == 1) {
769 pr_trace_msg("response", 9, "flushing response list for '%s'",
770 (char *) cmd->argv[0]);
771 pr_response_flush(&resp_list);
772
773 } else if (success < 0) {
774 pr_trace_msg("response", 9, "flushing error response list for '%s'",
775 (char *) cmd->argv[0]);
776 pr_response_flush(&resp_err_list);
777 }
778
779 errno = xerrno;
780 }
781 }
782
783 /* Restore any previous pool to the Response API. */
784 pr_response_set_pool(resp_pool);
785
786 errno = xerrno;
787 return success;
788 }
789
pr_cmd_dispatch(cmd_rec * cmd)790 int pr_cmd_dispatch(cmd_rec *cmd) {
791 return pr_cmd_dispatch_phase(cmd, 0,
792 PR_CMD_DISPATCH_FL_SEND_RESPONSE|PR_CMD_DISPATCH_FL_CLEAR_RESPONSE);
793 }
794
make_ftp_cmd(pool * p,char * buf,size_t buflen,int flags)795 static cmd_rec *make_ftp_cmd(pool *p, char *buf, size_t buflen, int flags) {
796 register unsigned int i, j;
797 char *arg, *ptr, *wrd;
798 size_t arg_len;
799 cmd_rec *cmd;
800 pool *subpool;
801 array_header *tarr;
802 int have_crnul = FALSE, str_flags = PR_STR_FL_PRESERVE_COMMENTS|flags;
803
804 /* Be pedantic (and RFC-compliant) by not allowing leading whitespace
805 * in an issued FTP command. Will this cause troubles with many clients?
806 */
807 if (PR_ISSPACE(buf[0])) {
808 pr_trace_msg("ctrl", 5,
809 "command '%s' has illegal leading whitespace, rejecting", buf);
810 errno = EINVAL;
811 return NULL;
812 }
813
814 ptr = buf;
815 wrd = pr_str_get_word(&ptr, str_flags);
816 if (wrd == NULL) {
817 /* Nothing there...bail out. */
818 pr_trace_msg("ctrl", 5, "command '%s' is empty, ignoring", buf);
819 errno = ENOENT;
820 return NULL;
821 }
822
823 subpool = make_sub_pool(p);
824 pr_pool_tag(subpool, "make_ftp_cmd pool");
825 cmd = pcalloc(subpool, sizeof(cmd_rec));
826 cmd->pool = subpool;
827 cmd->tmp_pool = NULL;
828 cmd->stash_index = -1;
829 cmd->stash_hash = 0;
830
831 tarr = make_array(cmd->pool, 2, sizeof(char *));
832
833 *((char **) push_array(tarr)) = pstrdup(cmd->pool, wrd);
834 cmd->argc++;
835
836 /* Make a copy of the command argument; we need to scan through it,
837 * looking for any CR+NUL sequences, per RFC 2460, Section 3.1.
838 *
839 * Note for future readers that this scanning may cause problems for
840 * commands such as ADAT, ENC, and MIC. Per RFC 2228, the arguments for
841 * these commands are base64-encoded Telnet strings, thus there is no
842 * chance of them containing CRNUL sequences. Any modules which implement
843 * the translating of those arguments, e.g. mod_gss, will need to ensure
844 * it does the proper handling of CRNUL sequences itself.
845 */
846 arg_len = buflen - strlen(wrd);
847 arg = pcalloc(cmd->pool, arg_len + 1);
848
849 for (i = 0, j = 0; i < arg_len; i++) {
850 pr_signals_handle();
851 if (i > 1 &&
852 ptr[i] == '\0' &&
853 ptr[i-1] == '\r') {
854
855 /* Strip out the NUL by simply not copying it into the new buffer. */
856 have_crnul = TRUE;
857 } else {
858 arg[j++] = ptr[i];
859 }
860 }
861
862 cmd->arg = arg;
863
864 if (have_crnul) {
865 char *dup_arg;
866
867 /* Now make a copy of the stripped argument; this is what we need to
868 * tokenize into words, for further command dispatching/processing.
869 */
870 dup_arg = pstrdup(cmd->pool, arg);
871 ptr = dup_arg;
872 }
873
874 while ((wrd = pr_str_get_word(&ptr, str_flags)) != NULL) {
875 pr_signals_handle();
876 *((char **) push_array(tarr)) = pstrdup(cmd->pool, wrd);
877 cmd->argc++;
878 }
879
880 *((char **) push_array(tarr)) = NULL;
881 cmd->argv = tarr->elts;
882 pr_pool_tag(cmd->pool, cmd->argv[0]);
883
884 /* This table will not contain that many entries, so a low number
885 * of chains should suffice.
886 */
887 cmd->notes = pr_table_nalloc(cmd->pool, 0, 8);
888
889 return cmd;
890 }
891
cmd_loop(server_rec * server,conn_t * c)892 static void cmd_loop(server_rec *server, conn_t *c) {
893
894 while (TRUE) {
895 int res = 0;
896 cmd_rec *cmd = NULL;
897
898 pr_signals_handle();
899
900 res = pr_cmd_read(&cmd);
901 if (res < 0) {
902 if (PR_NETIO_ERRNO(session.c->instrm) == EINTR) {
903 /* Simple interrupted syscall */
904 continue;
905 }
906
907 #ifndef PR_DEVEL_NO_DAEMON
908 /* Otherwise, EOF */
909 pr_session_disconnect(NULL, PR_SESS_DISCONNECT_CLIENT_EOF, NULL);
910 #else
911 return;
912 #endif /* PR_DEVEL_NO_DAEMON */
913 }
914
915 /* Data received, reset idle timer */
916 if (pr_data_get_timeout(PR_DATA_TIMEOUT_IDLE) > 0) {
917 pr_timer_reset(PR_TIMER_IDLE, ANY_MODULE);
918 }
919
920 if (cmd != NULL) {
921 /* Detect known commands for other protocols; if found, drop the
922 * connection, lest we be used as part of an attack on a different
923 * protocol server (Bug#4143).
924 */
925 if (cmd->is_ftp == FALSE) {
926 pr_log_pri(PR_LOG_WARNING,
927 "client sent %s command '%s', disconnecting", cmd->protocol,
928 (char *) cmd->argv[0]);
929 pr_event_generate("core.bad-protocol", cmd);
930 pr_session_disconnect(NULL, PR_SESS_DISCONNECT_BAD_PROTOCOL,
931 cmd->protocol);
932 }
933
934 pr_cmd_dispatch(cmd);
935 destroy_pool(cmd->pool);
936 session.curr_cmd = NULL;
937 session.curr_cmd_id = 0;
938 session.curr_cmd_rec = NULL;
939
940 } else {
941 pr_event_generate("core.invalid-command", NULL);
942 pr_response_send(R_500, _("Invalid command: try being more creative"));
943 }
944
945 /* Release any working memory allocated in inet */
946 pr_inet_clear();
947 }
948 }
949
restart_daemon(void * d1,void * d2,void * d3,void * d4)950 void restart_daemon(void *d1, void *d2, void *d3, void *d4) {
951 if (is_master && mpid) {
952 int maxfd;
953 fd_set childfds;
954 struct timeval restart_start, restart_finish;
955 long restart_elapsed = 0;
956
957 pr_log_pri(PR_LOG_NOTICE, "received SIGHUP -- master server reparsing "
958 "configuration file");
959
960 gettimeofday(&restart_start, NULL);
961
962 /* Make sure none of our children haven't completed start up */
963 FD_ZERO(&childfds);
964 maxfd = -1;
965
966 maxfd = semaphore_fds(&childfds, maxfd);
967 if (maxfd > -1) {
968 pr_log_pri(PR_LOG_NOTICE, "waiting for child processes to complete "
969 "initialization");
970
971 while (maxfd != -1) {
972 int i;
973
974 i = select(maxfd + 1, &childfds, NULL, NULL, NULL);
975
976 if (i > 0) {
977 pr_child_t *ch;
978
979 for (ch = child_get(NULL); ch; ch = child_get(ch)) {
980 if (ch->ch_pipefd != -1 &&
981 FD_ISSET(ch->ch_pipefd, &childfds)) {
982 (void) close(ch->ch_pipefd);
983 ch->ch_pipefd = -1;
984 }
985 }
986 }
987
988 FD_ZERO(&childfds);
989 maxfd = -1;
990 maxfd = semaphore_fds(&childfds, maxfd);
991 }
992 }
993
994 free_bindings();
995
996 /* Run through the list of registered restart callbacks. */
997 pr_event_generate("core.restart", NULL);
998
999 init_log();
1000 init_netaddr();
1001 init_class();
1002 init_config();
1003 init_dirtree();
1004
1005 #ifdef PR_USE_NLS
1006 encode_free();
1007 #endif /* PR_USE_NLS */
1008
1009 pr_netaddr_clear_cache();
1010
1011 pr_parser_prepare(NULL, NULL);
1012
1013 pr_event_generate("core.preparse", NULL);
1014
1015 PRIVS_ROOT
1016 if (pr_parser_parse_file(NULL, config_filename, NULL, 0) < 0) {
1017 int xerrno = errno;
1018
1019 PRIVS_RELINQUISH
1020
1021 /* Note: EPERM is used to indicate the presence of unrecognized
1022 * configuration directives in the parsed file(s).
1023 */
1024 if (xerrno != EPERM) {
1025 pr_log_pri(PR_LOG_WARNING,
1026 "fatal: unable to read configuration file '%s': %s", config_filename,
1027 strerror(xerrno));
1028 }
1029
1030 pr_session_end(0);
1031 }
1032 PRIVS_RELINQUISH
1033
1034 if (pr_parser_cleanup() < 0) {
1035 pr_log_pri(PR_LOG_WARNING,
1036 "fatal: error processing configuration file '%s': "
1037 "unclosed configuration section", config_filename);
1038 pr_session_end(0);
1039 }
1040
1041 #ifdef PR_USE_NLS
1042 encode_init();
1043 #endif /* PR_USE_NLS */
1044
1045 /* After configuration is complete, make sure that passwd, group
1046 * aren't held open (unnecessary fds for master daemon)
1047 */
1048 endpwent();
1049 endgrent();
1050
1051 if (fixup_servers(server_list) < 0) {
1052 pr_log_pri(PR_LOG_WARNING,
1053 "fatal: error processing configuration file '%s'", config_filename);
1054 pr_session_end(0);
1055 }
1056
1057 pr_event_generate("core.postparse", NULL);
1058
1059 /* Recreate the listen connection. Can an inetd-spawned server accept
1060 * and process HUP?
1061 */
1062 init_bindings();
1063
1064 gettimeofday(&restart_finish, NULL);
1065
1066 restart_elapsed = ((restart_finish.tv_sec - restart_start.tv_sec) * 1000L) +
1067 ((restart_finish.tv_usec - restart_start.tv_usec) / 1000L);
1068 pr_trace_msg("config", 12, "restart took %ld millisecs", restart_elapsed);
1069
1070 } else {
1071
1072 /* Child process -- cannot restart, log error */
1073 pr_log_pri(PR_LOG_ERR, "received SIGHUP, cannot restart child process");
1074 }
1075 }
1076
set_server_privs(void)1077 static void set_server_privs(void) {
1078 uid_t server_uid, current_euid = geteuid();
1079 gid_t server_gid, current_egid = getegid();
1080 unsigned char switch_server_id = FALSE;
1081
1082 uid_t *uid = get_param_ptr(main_server->conf, "UserID", FALSE);
1083 gid_t *gid = get_param_ptr(main_server->conf, "GroupID", FALSE);
1084
1085 if (uid) {
1086 server_uid = *uid;
1087 switch_server_id = TRUE;
1088
1089 } else
1090 server_uid = current_euid;
1091
1092 if (gid) {
1093 server_gid = *gid;
1094 switch_server_id = TRUE;
1095
1096 } else
1097 server_gid = current_egid;
1098
1099 if (switch_server_id) {
1100 PRIVS_ROOT
1101
1102 /* Note: will it be necessary to double check this switch, as is done
1103 * in elsewhere in this file?
1104 */
1105 PRIVS_SETUP(server_uid, server_gid);
1106 }
1107 }
1108
fork_server(int fd,conn_t * l,unsigned char no_fork)1109 static void fork_server(int fd, conn_t *l, unsigned char no_fork) {
1110 conn_t *conn = NULL;
1111 int i, rev;
1112 int semfds[2] = { -1, -1 };
1113 int xerrno = 0;
1114
1115 #ifndef PR_DEVEL_NO_FORK
1116 pid_t pid;
1117 sigset_t sig_set;
1118
1119 if (no_fork == FALSE) {
1120
1121 /* A race condition exists on heavily loaded servers where the parent
1122 * catches SIGHUP and attempts to close/re-open the main listening
1123 * socket(s), however the children haven't finished closing them
1124 * (EADDRINUSE). We use a semaphore pipe here to flag the parent once
1125 * the child has closed all former listening sockets.
1126 */
1127
1128 if (pipe(semfds) == -1) {
1129 pr_log_pri(PR_LOG_ALERT, "pipe(2) failed: %s", strerror(errno));
1130 (void) close(fd);
1131 return;
1132 }
1133
1134 /* Need to make sure the child (writer) end of the pipe isn't
1135 * < 2 (stdio/stdout/stderr) as this will cause problems later.
1136 */
1137 semfds[1] = pr_fs_get_usable_fd(semfds[1]);
1138
1139 /* Make sure we set the close-on-exec flag for the parent's read side
1140 * of the pipe.
1141 */
1142 (void) fcntl(semfds[0], F_SETFD, FD_CLOEXEC);
1143
1144 /* We block SIGCHLD to prevent a race condition if the child
1145 * dies before we can record it's pid. Also block SIGTERM to
1146 * prevent sig_terminate() from examining the child list
1147 */
1148
1149 sigemptyset(&sig_set);
1150 sigaddset(&sig_set, SIGTERM);
1151 sigaddset(&sig_set, SIGCHLD);
1152 sigaddset(&sig_set, SIGUSR1);
1153 sigaddset(&sig_set, SIGUSR2);
1154
1155 if (sigprocmask(SIG_BLOCK, &sig_set, NULL) < 0) {
1156 pr_log_pri(PR_LOG_NOTICE,
1157 "unable to block signal set: %s", strerror(errno));
1158 }
1159
1160 pid = fork();
1161 xerrno = errno;
1162
1163 switch (pid) {
1164
1165 case 0: /* child */
1166 /* No longer the master process. */
1167 is_master = FALSE;
1168 if (sigprocmask(SIG_UNBLOCK, &sig_set, NULL) < 0) {
1169 pr_log_pri(PR_LOG_NOTICE,
1170 "unable to unblock signal set: %s", strerror(errno));
1171 }
1172
1173 /* No longer need the read side of the semaphore pipe. */
1174 (void) close(semfds[0]);
1175 break;
1176
1177 case -1:
1178 if (sigprocmask(SIG_UNBLOCK, &sig_set, NULL) < 0) {
1179 pr_log_pri(PR_LOG_NOTICE,
1180 "unable to unblock signal set: %s", strerror(errno));
1181 }
1182
1183 pr_log_pri(PR_LOG_ALERT, "unable to fork(): %s", strerror(xerrno));
1184
1185 /* The parent doesn't need the socket open. */
1186 (void) close(fd);
1187 (void) close(semfds[0]);
1188 (void) close(semfds[1]);
1189
1190 return;
1191
1192 default: /* parent */
1193 /* The parent doesn't need the socket open */
1194 (void) close(fd);
1195
1196 child_add(pid, semfds[0]);
1197 (void) close(semfds[1]);
1198
1199 /* Unblock the signals now as sig_child() will catch
1200 * an "immediate" death and remove the pid from the children list
1201 */
1202 if (sigprocmask(SIG_UNBLOCK, &sig_set, NULL) < 0) {
1203 pr_log_pri(PR_LOG_NOTICE,
1204 "unable to unblock signal set: %s", strerror(errno));
1205 }
1206
1207 return;
1208 }
1209 }
1210
1211 session.pid = getpid();
1212
1213 /* No longer need any listening fds. */
1214 pr_ipbind_close_listeners();
1215
1216 /* There would appear to be no useful purpose behind setting the process
1217 * group of the newly forked child. In daemon/inetd mode, we should have no
1218 * controlling tty and either have the process group of the parent or of
1219 * inetd. In non-daemon mode (-n), doing this may cause SIGTTOU to be
1220 * raised on output to the terminal (stderr logging).
1221 *
1222 * #ifdef HAVE_SETPGID
1223 * setpgid(0,getpid());
1224 * #else
1225 * # ifdef SETPGRP_VOID
1226 * setpgrp();
1227 * # else
1228 * setpgrp(0,getpid());
1229 * # endif
1230 * #endif
1231 *
1232 */
1233
1234 /* Reseed pseudo-randoms */
1235 pr_random_init();
1236
1237 #endif /* PR_DEVEL_NO_FORK */
1238
1239 /* Child is running here */
1240 if (signal(SIGUSR1, pr_signals_handle_disconnect) == SIG_ERR) {
1241 pr_log_pri(PR_LOG_NOTICE,
1242 "unable to install SIGUSR1 (signal %d) handler: %s", SIGUSR1,
1243 strerror(errno));
1244 }
1245
1246 if (signal(SIGUSR2, pr_signals_handle_event) == SIG_ERR) {
1247 pr_log_pri(PR_LOG_NOTICE,
1248 "unable to install SIGUSR2 (signal %d) handler: %s", SIGUSR2,
1249 strerror(errno));
1250 }
1251
1252 if (signal(SIGCHLD, SIG_DFL) == SIG_ERR) {
1253 pr_log_pri(PR_LOG_NOTICE,
1254 "unable to install SIGCHLD (signal %d) handler: %s", SIGCHLD,
1255 strerror(errno));
1256 }
1257
1258 if (signal(SIGHUP, SIG_IGN) == SIG_ERR) {
1259 pr_log_pri(PR_LOG_NOTICE,
1260 "unable to install SIGHUP (signal %d) handler: %s", SIGHUP,
1261 strerror(errno));
1262 }
1263
1264 /* From this point on, syslog stays open. We close it first so that the
1265 * logger will pick up our new PID.
1266 *
1267 * We have to delay calling log_opensyslog() until after pr_inet_openrw()
1268 * is called, otherwise the potential exists for the syslog FD to
1269 * be overwritten and the user to see logging information.
1270 *
1271 * This isn't that big of a deal because the logging functions will
1272 * just open it dynamically if they need to.
1273 */
1274 log_closesyslog();
1275
1276 /* Specifically DO NOT perform reverse DNS at this point, to alleviate
1277 * the race condition mentioned above. Instead we do it after closing
1278 * all former listening sockets.
1279 */
1280 conn = pr_inet_openrw(permanent_pool, l, NULL, PR_NETIO_STRM_CTRL, fd,
1281 STDIN_FILENO, STDOUT_FILENO, FALSE);
1282
1283 /* Capture errno here, if necessary. */
1284 if (conn == NULL) {
1285 xerrno = errno;
1286 }
1287
1288 /* Now do the permanent syslog open
1289 */
1290 pr_signals_block();
1291 PRIVS_ROOT
1292
1293 log_opensyslog(NULL);
1294
1295 PRIVS_RELINQUISH
1296 pr_signals_unblock();
1297
1298 if (conn == NULL) {
1299 /* There are some errors, e.g. ENOTCONN ("Transport endpoint is not
1300 * connected") which can easily happen, as during scans/TCP
1301 * probes/healthchecks, commonly done by load balancers, firewalls, and
1302 * other clients. By the time proftpd reaches the point of looking up
1303 * the peer data for that connection, the client has disconnected.
1304 *
1305 * These are normal errors, and thus should not be logged as fatal
1306 * conditions.
1307 */
1308 if (xerrno == ENOTCONN ||
1309 xerrno == ECONNABORTED ||
1310 xerrno == ECONNRESET) {
1311 pr_log_pri(PR_LOG_DEBUG, "unable to open incoming connection: %s",
1312 strerror(xerrno));
1313
1314 } else {
1315 pr_log_pri(PR_LOG_ERR, "fatal: unable to open incoming connection: %s",
1316 strerror(xerrno));
1317 }
1318
1319 exit(1);
1320 }
1321
1322 pr_gettimeofday_millis(&session.connect_time_ms);
1323 pr_event_generate("core.connect", conn);
1324
1325 /* Find the server for this connection. */
1326 main_server = pr_ipbind_get_server(conn->local_addr, conn->local_port);
1327
1328 /* Make sure we allocate a session pool, even if this connection will
1329 * dropped soon.
1330 */
1331 session.pool = make_sub_pool(permanent_pool);
1332 pr_pool_tag(session.pool, "Session Pool");
1333
1334 session.c = conn;
1335 session.data_port = conn->remote_port - 1;
1336 session.sf_flags = 0;
1337 session.sp_flags = 0;
1338 session.proc_prefix = "(connecting)";
1339
1340 /* If no server is configured to handle the addr the user is connected to,
1341 * drop them.
1342 */
1343 if (main_server == NULL) {
1344 pr_log_debug(DEBUG2, "No server configuration found for IP address %s",
1345 pr_netaddr_get_ipstr(conn->local_addr));
1346 pr_log_debug(DEBUG2, "Use the DefaultServer directive to designate "
1347 "a default server configuration to handle requests like this");
1348
1349 pr_response_send(R_500,
1350 _("Sorry, no server available to handle request on %s"),
1351 pr_netaddr_get_dnsstr(conn->local_addr));
1352 exit(0);
1353 }
1354
1355 pr_inet_set_proto_opts(permanent_pool, conn, 0, 1, IPTOS_LOWDELAY, 0);
1356
1357 /* Close the write side of the semaphore pipe to tell the parent
1358 * we are all grown up and have finished housekeeping (closing
1359 * former listen sockets).
1360 */
1361 close(semfds[1]);
1362
1363 /* Now perform reverse DNS lookups. */
1364 if (ServerUseReverseDNS) {
1365 rev = pr_netaddr_set_reverse_dns(ServerUseReverseDNS);
1366
1367 if (conn->remote_addr)
1368 conn->remote_name = pr_netaddr_get_dnsstr(conn->remote_addr);
1369
1370 pr_netaddr_set_reverse_dns(rev);
1371 }
1372
1373 pr_netaddr_set_sess_addrs();
1374
1375 /* Check and see if we are shutting down. */
1376 if (shutting_down) {
1377 time_t now;
1378
1379 time(&now);
1380 if (!deny || deny <= now) {
1381 pool *tmp_pool;
1382 config_rec *c = NULL;
1383 const char *reason = NULL, *serveraddress;
1384
1385 serveraddress = (session.c && session.c->local_addr) ?
1386 pr_netaddr_get_ipstr(session.c->local_addr) :
1387 main_server->ServerAddress;
1388
1389 c = find_config(main_server->conf, CONF_PARAM, "MasqueradeAddress",
1390 FALSE);
1391 if (c != NULL) {
1392 pr_netaddr_t *masq_addr = NULL;
1393
1394 if (c->argv[0] != NULL) {
1395 masq_addr = c->argv[0];
1396 }
1397
1398 if (masq_addr != NULL) {
1399 serveraddress = pr_netaddr_get_ipstr(masq_addr);
1400 }
1401 }
1402
1403 tmp_pool = make_sub_pool(permanent_pool);
1404 pr_pool_tag(tmp_pool, "shutmsg check pool");
1405
1406 reason = sreplace(tmp_pool, shutmsg,
1407 "%s", pstrdup(tmp_pool, pr_strtime3(tmp_pool, shut, FALSE)),
1408 "%r", pstrdup(tmp_pool, pr_strtime3(tmp_pool, deny, FALSE)),
1409 "%d", pstrdup(tmp_pool, pr_strtime3(tmp_pool, disc, FALSE)),
1410 "%C", (session.cwd[0] ? session.cwd : "(none)"),
1411 "%L", serveraddress,
1412 "%R", (session.c && session.c->remote_name ?
1413 session.c->remote_name : "(unknown)"),
1414 "%T", pstrdup(tmp_pool, pr_strtime3(tmp_pool, now, FALSE)),
1415 "%U", "NONE",
1416 "%V", main_server->ServerName,
1417 NULL );
1418
1419 pr_log_auth(PR_LOG_NOTICE, "connection refused (%s) from %s [%s]",
1420 reason, session.c->remote_name,
1421 pr_netaddr_get_ipstr(session.c->remote_addr));
1422 pr_response_send(R_500,
1423 _("FTP server shut down (%s) -- please try again later"), reason);
1424
1425 destroy_pool(tmp_pool);
1426 exit(0);
1427 }
1428 }
1429
1430 if (main_server->listen) {
1431 if (main_server->listen->listen_fd == conn->rfd ||
1432 main_server->listen->listen_fd == conn->wfd) {
1433 main_server->listen->listen_fd = -1;
1434 }
1435
1436 main_server->listen = NULL;
1437 }
1438
1439 /* Set the ID/privs for the User/Group in this server */
1440 set_server_privs();
1441
1442 /* Find the class for this session. */
1443 session.conn_class = pr_class_match_addr(session.c->remote_addr);
1444 if (session.conn_class != NULL) {
1445 pr_log_debug(DEBUG2, "session requested from client in '%s' class",
1446 session.conn_class->cls_name);
1447
1448 } else {
1449 pr_log_debug(DEBUG5, "session requested from client in unknown class");
1450 }
1451
1452 /* Check config tree for <Limit LOGIN> directives. Do not perform
1453 * this check until after the class of the session has been determined,
1454 * in order to properly handle any AllowClass/DenyClass directives
1455 * within the <Limit> section.
1456 */
1457 if (!login_check_limits(main_server->conf, TRUE, FALSE, &i)) {
1458 pr_log_pri(PR_LOG_NOTICE, "Connection from %s [%s] denied",
1459 session.c->remote_name,
1460 pr_netaddr_get_ipstr(session.c->remote_addr));
1461
1462 /* XXX Send DisplayConnect here? No chroot to worry about; modules have
1463 * NOT been initialized, so generating an event would not work as
1464 * expected.
1465 */
1466
1467 pr_session_disconnect(NULL, PR_SESS_DISCONNECT_CONFIG_ACL,
1468 "Blocked by <Limit LOGIN>");
1469 }
1470
1471 /* Create a table for modules to use. */
1472 session.notes = pr_table_alloc(session.pool, 0);
1473 if (session.notes == NULL) {
1474 pr_log_debug(DEBUG3, "error creating session.notes table: %s",
1475 strerror(errno));
1476 }
1477
1478 /* Prepare the Timers API. */
1479 timers_init();
1480
1481 /* Inform all the modules that we are now a child */
1482 pr_log_debug(DEBUG7, "performing module session initializations");
1483 if (modules_session_init() < 0) {
1484 pr_session_disconnect(NULL, PR_SESS_DISCONNECT_SESSION_INIT_FAILED, NULL);
1485 }
1486
1487 pr_log_debug(DEBUG4, "connected - local : %s:%d",
1488 pr_netaddr_get_ipstr(session.c->local_addr), session.c->local_port);
1489 pr_log_debug(DEBUG4, "connected - remote : %s:%d",
1490 pr_netaddr_get_ipstr(session.c->remote_addr), session.c->remote_port);
1491
1492 pr_proctitle_set("connected: %s (%s:%d)",
1493 session.c->remote_name ? session.c->remote_name : "?",
1494 session.c->remote_addr ? pr_netaddr_get_ipstr(session.c->remote_addr) : "?",
1495 session.c->remote_port ? session.c->remote_port : 0);
1496
1497 pr_log_pri(PR_LOG_INFO, "%s session opened.",
1498 pr_session_get_protocol(PR_SESS_PROTO_FL_LOGOUT));
1499
1500 /* Make sure we can receive OOB data */
1501 pr_inet_set_async(session.pool, session.c);
1502
1503 pr_session_send_banner(main_server,
1504 PR_DISPLAY_FL_NO_EOM|PR_DISPLAY_FL_SEND_NOW);
1505
1506 cmd_handler(main_server, conn);
1507
1508 #ifdef PR_DEVEL_NO_DAEMON
1509 /* Cleanup */
1510 pr_session_end(PR_SESS_END_FL_NOEXIT);
1511 main_server = NULL;
1512 free_pools();
1513 pr_proctitle_free();
1514 #endif /* PR_DEVEL_NO_DAEMON */
1515 }
1516
disc_children(void)1517 static void disc_children(void) {
1518
1519 if (disc && disc <= time(NULL) && child_count()) {
1520 sigset_t sig_set;
1521
1522 sigemptyset(&sig_set);
1523 sigaddset(&sig_set, SIGTERM);
1524 sigaddset(&sig_set, SIGCHLD);
1525 sigaddset(&sig_set, SIGUSR1);
1526 sigaddset(&sig_set, SIGUSR2);
1527
1528 if (sigprocmask(SIG_BLOCK, &sig_set, NULL) < 0) {
1529 pr_log_pri(PR_LOG_NOTICE,
1530 "unable to block signal set: %s", strerror(errno));
1531 }
1532
1533 PRIVS_ROOT
1534 child_signal(SIGUSR1);
1535 PRIVS_RELINQUISH
1536
1537 if (sigprocmask(SIG_UNBLOCK, &sig_set, NULL) < 0) {
1538 pr_log_pri(PR_LOG_NOTICE,
1539 "unable to unblock signal set: %s", strerror(errno));
1540 }
1541 }
1542 }
1543
daemon_loop(void)1544 static void daemon_loop(void) {
1545 fd_set listenfds;
1546 conn_t *listen_conn;
1547 int i, err_count = 0, fd, xerrno = 0;
1548 unsigned long nconnects = 0UL;
1549 time_t last_error;
1550 struct timeval tv;
1551 static int running = 0;
1552
1553 pr_proctitle_set("(accepting connections)");
1554
1555 time(&last_error);
1556
1557 while (TRUE) {
1558 int maxfd;
1559
1560 run_schedule();
1561
1562 FD_ZERO(&listenfds);
1563 maxfd = pr_ipbind_listen(&listenfds);
1564
1565 /* Monitor children pipes */
1566 maxfd = semaphore_fds(&listenfds, maxfd);
1567
1568 /* Check for ftp shutdown message file */
1569 switch (check_shutmsg(permanent_pool, PR_SHUTMSG_PATH, &shut, &deny,
1570 &disc, shutmsg, sizeof(shutmsg))) {
1571 case 1:
1572 if (!shutting_down) {
1573 disc_children();
1574 }
1575 shutting_down = TRUE;
1576 break;
1577
1578 default:
1579 shutting_down = FALSE;
1580 deny = disc = (time_t) 0;
1581 break;
1582 }
1583
1584 if (shutting_down) {
1585 tv.tv_sec = 5L;
1586 tv.tv_usec = 0L;
1587
1588 } else {
1589
1590 tv.tv_sec = PR_TUNABLE_SELECT_TIMEOUT;
1591 tv.tv_usec = 0L;
1592 }
1593
1594 /* If running (a flag signaling whether proftpd is just starting up)
1595 * AND shutting_down (a flag signalling the present of /etc/shutmsg) are
1596 * true, then log an error stating this -- but don't stop the server.
1597 */
1598 if (shutting_down && !running) {
1599
1600 /* Check the value of the deny time_t struct w/ the current time.
1601 * If the deny time has passed, log that all incoming connections
1602 * will be refused. If not, note the date at which they will be
1603 * refused in the future.
1604 */
1605 time_t now = time(NULL);
1606
1607 if (difftime(deny, now) < 0.0) {
1608 pr_log_pri(PR_LOG_WARNING, PR_SHUTMSG_PATH
1609 " present: all incoming connections will be refused");
1610
1611 } else {
1612 #if defined(HAVE_CTIME_R)
1613 char deny_ts[32];
1614
1615 memset(deny_ts, '\0', sizeof(deny_ts));
1616 (void) ctime_r(&deny, deny_ts);
1617 #else
1618 char *deny_ts = NULL;
1619 deny_ts = ctime(&deny);
1620 #endif /* HAVE_CTIME_R */
1621
1622 pr_log_pri(PR_LOG_NOTICE,
1623 PR_SHUTMSG_PATH " present: incoming connections "
1624 "will be denied starting %s", CHOP(deny_ts));
1625 }
1626 }
1627
1628 running = 1;
1629 xerrno = errno = 0;
1630
1631 PR_DEVEL_CLOCK(i = select(maxfd + 1, &listenfds, NULL, NULL, &tv));
1632 if (i < 0) {
1633 xerrno = errno;
1634 }
1635
1636 if (i == -1 &&
1637 xerrno == EINTR) {
1638 errno = xerrno;
1639 pr_signals_handle();
1640
1641 /* We handled our signal; clear errno. */
1642 xerrno = errno = 0;
1643 continue;
1644 }
1645
1646 if (have_dead_child) {
1647 sigset_t sig_set;
1648
1649 sigemptyset(&sig_set);
1650 sigaddset(&sig_set, SIGCHLD);
1651 sigaddset(&sig_set, SIGTERM);
1652 pr_alarms_block();
1653 if (sigprocmask(SIG_BLOCK, &sig_set, NULL) < 0) {
1654 pr_log_pri(PR_LOG_NOTICE,
1655 "unable to block signal set: %s", strerror(errno));
1656 }
1657
1658 have_dead_child = FALSE;
1659 child_update();
1660
1661 if (sigprocmask(SIG_UNBLOCK, &sig_set, NULL) < 0) {
1662 pr_log_pri(PR_LOG_NOTICE,
1663 "unable to unblock signal set: %s", strerror(errno));
1664 }
1665
1666 pr_alarms_unblock();
1667 }
1668
1669 if (i == -1) {
1670 time_t this_error;
1671
1672 time(&this_error);
1673
1674 if ((this_error - last_error) <= 5 && err_count++ > 10) {
1675 pr_log_pri(PR_LOG_ERR, "fatal: select(2) failing repeatedly, shutting "
1676 "down");
1677 exit(1);
1678
1679 } else if ((this_error - last_error) > 5) {
1680 last_error = this_error;
1681 err_count = 0;
1682 }
1683
1684 pr_log_pri(PR_LOG_WARNING, "select(2) failed in daemon_loop(): %s",
1685 strerror(xerrno));
1686 }
1687
1688 if (i == 0) {
1689 continue;
1690 }
1691
1692 /* Reset the connection counter. Take into account this current
1693 * connection, which does not (yet) have an entry in the child list.
1694 */
1695 nconnects = 1UL;
1696
1697 /* See if child semaphore pipes have signaled */
1698 if (child_count()) {
1699 pr_child_t *ch;
1700 time_t now = time(NULL);
1701
1702 for (ch = child_get(NULL); ch; ch = child_get(ch)) {
1703 if (ch->ch_pipefd != -1 &&
1704 FD_ISSET(ch->ch_pipefd, &listenfds)) {
1705 (void) close(ch->ch_pipefd);
1706 ch->ch_pipefd = -1;
1707 }
1708
1709 /* While we're looking, tally up the number of children forked in
1710 * the past interval.
1711 */
1712 if (ch->ch_when >= (time_t) (now - (long) max_connect_interval)) {
1713 nconnects++;
1714 }
1715 }
1716 }
1717
1718 pr_signals_handle();
1719
1720 if (i < 0) {
1721 continue;
1722 }
1723
1724 /* Accept the connection. */
1725 listen_conn = pr_ipbind_accept_conn(&listenfds, &fd);
1726
1727 /* Fork off servers to handle each connection our job is to get back to
1728 * answering connections ASAP, so leave the work of determining which
1729 * server the connection is for to our child.
1730 */
1731
1732 if (listen_conn != NULL) {
1733
1734 /* Check for exceeded MaxInstances. */
1735 if (ServerMaxInstances > 0 &&
1736 child_count() >= ServerMaxInstances) {
1737 pr_event_generate("core.max-instances", NULL);
1738
1739 pr_log_pri(PR_LOG_WARNING,
1740 "MaxInstances (%lu) reached, new connection denied",
1741 ServerMaxInstances);
1742 close(fd);
1743
1744 /* Check for exceeded MaxConnectionRate. */
1745 } else if (max_connects && (nconnects > max_connects)) {
1746 pr_event_generate("core.max-connection-rate", NULL);
1747
1748 pr_log_pri(PR_LOG_WARNING,
1749 "MaxConnectionRate (%lu/%u secs) reached, new connection denied",
1750 max_connects, max_connect_interval);
1751 close(fd);
1752
1753 /* Fork off a child to handle the connection. */
1754 } else {
1755 PR_DEVEL_CLOCK(fork_server(fd, listen_conn, no_forking));
1756 }
1757 }
1758 #ifdef PR_DEVEL_NO_DAEMON
1759 /* Do not continue the while() loop here if not daemonizing. */
1760 break;
1761 #endif /* PR_DEVEL_NO_DAEMON */
1762 }
1763 }
1764
daemonize(void)1765 static void daemonize(void) {
1766 #ifndef HAVE_SETSID
1767 int ttyfd;
1768 #endif
1769
1770 /* Fork off and have parent exit.
1771 */
1772 switch (fork()) {
1773 case -1:
1774 perror("fork(2) error");
1775 exit(1);
1776
1777 case 0:
1778 break;
1779
1780 default:
1781 exit(0);
1782 }
1783
1784 #ifdef HAVE_SETSID
1785 /* setsid() is the preferred way to disassociate from the
1786 * controlling terminal
1787 */
1788 setsid();
1789 #else
1790 /* Open /dev/tty to access our controlling tty (if any) */
1791 if ((ttyfd = open("/dev/tty", O_RDWR)) != -1) {
1792 if (ioctl(ttyfd, TIOCNOTTY, NULL) == -1) {
1793 perror("ioctl");
1794 exit(1);
1795 }
1796
1797 close(ttyfd);
1798 }
1799 #endif /* HAVE_SETSID */
1800
1801 /* Close the three big boys */
1802 close(fileno(stdin));
1803 close(fileno(stdout));
1804 close(fileno(stderr));
1805
1806 /* Portable way to prevent re-acquiring a tty in the future */
1807
1808 #ifdef HAVE_SETPGID
1809 setpgid(0, getpid());
1810 #else
1811 # ifdef SETPGRP_VOID
1812 setpgrp();
1813 # else
1814 setpgrp(0, getpid());
1815 # endif
1816 #endif
1817
1818 /* Reset the cached "master PID" value to that of the daemon process;
1819 * there are places in the code which check this value to see if they
1820 * are the daemon process, e.g. at shutdown.
1821 */
1822 mpid = getpid();
1823
1824 pr_fsio_chdir("/", 0);
1825 }
1826
inetd_main(void)1827 static void inetd_main(void) {
1828 int res = 0;
1829
1830 /* Make sure the scoreboard file exists. */
1831 PRIVS_ROOT
1832 res = pr_open_scoreboard(O_RDWR);
1833 if (res < 0) {
1834 PRIVS_RELINQUISH
1835
1836 switch (res) {
1837 case PR_SCORE_ERR_BAD_MAGIC:
1838 pr_log_pri(PR_LOG_ERR, "error opening scoreboard: bad/corrupted file");
1839 return;
1840
1841 case PR_SCORE_ERR_OLDER_VERSION:
1842 case PR_SCORE_ERR_NEWER_VERSION:
1843 pr_log_pri(PR_LOG_ERR, "error opening scoreboard: wrong version, "
1844 "writing new scoreboard");
1845
1846 /* Delete the scoreboard, then open it again. */
1847 PRIVS_ROOT
1848 pr_delete_scoreboard();
1849 if (pr_open_scoreboard(O_RDWR) < 0) {
1850 int xerrno = errno;
1851
1852 PRIVS_RELINQUISH
1853 pr_log_pri(PR_LOG_ERR, "error opening scoreboard: %s",
1854 strerror(xerrno));
1855 return;
1856 }
1857 break;
1858
1859 default:
1860 pr_log_pri(PR_LOG_ERR, "error opening scoreboard: %s",
1861 strerror(errno));
1862 return;
1863 }
1864 }
1865 PRIVS_RELINQUISH
1866 pr_close_scoreboard(FALSE);
1867
1868 pr_event_generate("core.startup", NULL);
1869
1870 init_bindings();
1871
1872 /* Check our shutdown status */
1873 if (check_shutmsg(permanent_pool, PR_SHUTMSG_PATH, &shut, &deny, &disc,
1874 shutmsg, sizeof(shutmsg)) == 1) {
1875 shutting_down = TRUE;
1876 }
1877
1878 /* Finally, call right into fork_server() to start servicing the
1879 * connection immediately.
1880 */
1881 fork_server(STDIN_FILENO, main_server->listen, TRUE);
1882 }
1883
standalone_main(void)1884 static void standalone_main(void) {
1885 int res = 0;
1886
1887 if (nodaemon) {
1888 log_stderr(quiet ? FALSE : TRUE);
1889 close(fileno(stdin));
1890 close(fileno(stdout));
1891
1892 } else {
1893 log_stderr(FALSE);
1894 daemonize();
1895 }
1896
1897 PRIVS_ROOT
1898 pr_delete_scoreboard();
1899 res = pr_open_scoreboard(O_RDWR);
1900 if (res < 0) {
1901 PRIVS_RELINQUISH
1902
1903 switch (res) {
1904 case PR_SCORE_ERR_BAD_MAGIC:
1905 pr_log_pri(PR_LOG_ERR,
1906 "error opening scoreboard: bad/corrupted file");
1907 return;
1908
1909 case PR_SCORE_ERR_OLDER_VERSION:
1910 pr_log_pri(PR_LOG_ERR,
1911 "error opening scoreboard: bad version (too old)");
1912 return;
1913
1914 case PR_SCORE_ERR_NEWER_VERSION:
1915 pr_log_pri(PR_LOG_ERR,
1916 "error opening scoreboard: bad version (too new)");
1917 return;
1918
1919 default:
1920 pr_log_pri(PR_LOG_ERR, "error opening scoreboard: %s", strerror(errno));
1921 return;
1922 }
1923 }
1924 PRIVS_RELINQUISH
1925 pr_close_scoreboard(TRUE);
1926
1927 pr_event_generate("core.startup", NULL);
1928
1929 init_bindings();
1930
1931 pr_log_pri(PR_LOG_NOTICE, "ProFTPD %s (built %s) standalone mode STARTUP",
1932 PROFTPD_VERSION_TEXT " " PR_STATUS, BUILD_STAMP);
1933
1934 if (pr_pidfile_write() < 0) {
1935 fprintf(stderr, "error opening PidFile '%s': %s\n", pr_pidfile_get(),
1936 strerror(errno));
1937 exit(1);
1938 }
1939
1940 daemon_loop();
1941 }
1942
1943 extern char *optarg;
1944 extern int optind, opterr, optopt;
1945
1946 #ifdef HAVE_GETOPT_LONG
1947 static struct option opts[] = {
1948 { "nocollision", 0, NULL, 'N' },
1949 { "nodaemon", 0, NULL, 'n' },
1950 { "quiet", 0, NULL, 'q' },
1951 { "debug", 1, NULL, 'd' },
1952 { "define", 1, NULL, 'D' },
1953 { "config", 1, NULL, 'c' },
1954 { "persistent", 1, NULL, 'p' },
1955 { "list", 0, NULL, 'l' },
1956 { "version", 0, NULL, 'v' },
1957 { "settings", 0, NULL, 'V' },
1958 { "version-status", 0, NULL, 1 },
1959 { "configtest", 0, NULL, 't' },
1960 { "help", 0, NULL, 'h' },
1961 { "ipv4", 0, NULL, '4' },
1962 { "ipv6", 0, NULL, '6' },
1963 { NULL, 0, NULL, 0 }
1964 };
1965 #endif /* HAVE_GETOPT_LONG */
1966
show_settings(void)1967 static void show_settings(void) {
1968 #ifdef HAVE_UNAME
1969 int res;
1970 struct utsname uts;
1971 #endif /* !HAVE_UNAME */
1972
1973 printf("%s", "Compile-time Settings:\n");
1974 printf("%s", " Version: " PROFTPD_VERSION_TEXT " " PR_STATUS "\n");
1975
1976 #ifdef HAVE_UNAME
1977 /* We use uname(2) to get the 'machine', which will tell us whether
1978 * we're a 32- or 64-bit machine.
1979 */
1980 res = uname(&uts);
1981 if (res < 0) {
1982 printf("%s", " Platform: " PR_PLATFORM " [unavailable]\n");
1983
1984 } else {
1985 printf(" Platform: " PR_PLATFORM " [%s %s %s]\n", uts.sysname,
1986 uts.release, uts.machine);
1987 }
1988 #else
1989 printf("%s", " Platform: " PR_PLATFORM " [unknown]\n");
1990 #endif /* !HAVE_UNAME */
1991
1992 printf("%s", " Built: " BUILD_STAMP "\n");
1993 printf("%s", " Built With:\n configure " PR_BUILD_OPTS "\n\n");
1994
1995 printf("%s", " CFLAGS: " PR_BUILD_CFLAGS "\n");
1996 printf("%s", " LDFLAGS: " PR_BUILD_LDFLAGS "\n");
1997 printf("%s", " LIBS: " PR_BUILD_LIBS "\n");
1998
1999 /* Files/paths */
2000 printf("%s", "\n Files:\n");
2001 printf("%s", " Configuration File:\n");
2002 printf("%s", " " PR_CONFIG_FILE_PATH "\n");
2003 printf("%s", " Pid File:\n");
2004 printf("%s", " " PR_PID_FILE_PATH "\n");
2005 printf("%s", " Scoreboard File:\n");
2006 printf("%s", " " PR_RUN_DIR "/proftpd.scoreboard\n");
2007 #ifdef PR_USE_DSO
2008 printf("%s", " Header Directory:\n");
2009 printf("%s", " " PR_INCLUDE_DIR "/proftpd\n");
2010 printf("%s", " Shared Module Directory:\n");
2011 printf("%s", " " PR_LIBEXEC_DIR "\n");
2012 #endif /* PR_USE_DSO */
2013
2014 /* Informational */
2015 printf("%s", "\n Info:\n");
2016 #if SIZEOF_UID_T == SIZEOF_INT
2017 printf(" + Max supported UID: %u\n", UINT_MAX);
2018 #elif SIZEOF_UID_T == SIZEOF_LONG
2019 printf(" + Max supported UID: %lu\n", ULONG_MAX);
2020 #elif SIZEOF_UID_T == SIZEOF_LONG_LONG
2021 printf(" + Max supported UID: %llu\n", ULLONG_MAX);
2022 #endif
2023
2024 #if SIZEOF_GID_T == SIZEOF_INT
2025 printf(" + Max supported GID: %u\n", UINT_MAX);
2026 #elif SIZEOF_GID_T == SIZEOF_LONG
2027 printf(" + Max supported GID: %lu\n", ULONG_MAX);
2028 #elif SIZEOF_GID_T == SIZEOF_LONG_LONG
2029 printf(" + Max supported GID: %llu\n", ULLONG_MAX);
2030 #endif
2031
2032 /* Feature settings */
2033 printf("%s", "\n Features:\n");
2034 #ifdef PR_USE_AUTO_SHADOW
2035 printf("%s", " + Autoshadow support\n");
2036 #else
2037 printf("%s", " - Autoshadow support\n");
2038 #endif /* PR_USE_AUTO_SHADOW */
2039
2040 #ifdef PR_USE_CTRLS
2041 printf("%s", " + Controls support\n");
2042 #else
2043 printf("%s", " - Controls support\n");
2044 #endif /* PR_USE_CTRLS */
2045
2046 #if defined(PR_USE_CURSES) && defined(HAVE_LIBCURSES)
2047 printf("%s", " + curses support\n");
2048 #else
2049 printf("%s", " - curses support\n");
2050 #endif /* PR_USE_CURSES && HAVE_LIBCURSES */
2051
2052 #ifdef PR_USE_DEVEL
2053 printf("%s", " + Developer support\n");
2054 #else
2055 printf("%s", " - Developer support\n");
2056 #endif /* PR_USE_DEVEL */
2057
2058 #ifdef PR_USE_DSO
2059 printf("%s", " + DSO support\n");
2060 #else
2061 printf("%s", " - DSO support\n");
2062 #endif /* PR_USE_DSO */
2063
2064 #ifdef PR_USE_IPV6
2065 printf("%s", " + IPv6 support\n");
2066 #else
2067 printf("%s", " - IPv6 support\n");
2068 #endif /* PR_USE_IPV6 */
2069
2070 #ifdef PR_USE_LARGEFILES
2071 printf("%s", " + Largefile support\n");
2072 #else
2073 printf("%s", " - Largefile support\n");
2074 #endif /* PR_USE_LARGEFILES */
2075
2076 #ifdef PR_USE_LASTLOG
2077 printf("%s", " + Lastlog support\n");
2078 #else
2079 printf("%s", " - Lastlog support\n");
2080 #endif /* PR_USE_LASTLOG */
2081
2082 #ifdef PR_USE_MEMCACHE
2083 printf("%s", " + Memcache support\n");
2084 #else
2085 printf("%s", " - Memcache support\n");
2086 #endif /* PR_USE_MEMCACHE */
2087
2088 #if defined(PR_USE_NCURSESW) && defined(HAVE_LIBNCURSESW)
2089 printf("%s", " + ncursesw support\n");
2090 #elif defined(PR_USE_NCURSES) && defined(HAVE_LIBNCURSES)
2091 printf("%s", " + ncurses support\n");
2092 #else
2093 printf("%s", " - ncurses support\n");
2094 #endif
2095
2096 #ifdef PR_USE_NLS
2097 printf("%s", " + NLS support\n");
2098 #else
2099 printf("%s", " - NLS support\n");
2100 #endif /* PR_USE_NLS */
2101
2102 #ifdef PR_USE_OPENSSL
2103 # ifdef PR_USE_OPENSSL_FIPS
2104 printf(" + OpenSSL support (%s, FIPS enabled)\n", OPENSSL_VERSION_TEXT);
2105 # else
2106 # ifdef LIBRESSL_VERSION_NUMBER
2107 printf(" + OpenSSL support (%s, LibreSSL)\n", OPENSSL_VERSION_TEXT);
2108 # else
2109 printf(" + OpenSSL support (%s)\n", OPENSSL_VERSION_TEXT);
2110 # endif /* Have LibreSSL */
2111 # endif /* PR_USE_OPENSSL_FIPS */
2112 #else
2113 printf("%s", " - OpenSSL support\n");
2114 #endif /* PR_USE_OPENSSL */
2115
2116 #ifdef PR_USE_PCRE
2117 printf("%s", " + PCRE support\n");
2118 #else
2119 printf("%s", " - PCRE support\n");
2120 #endif /* PR_USE_PCRE */
2121
2122 #ifdef PR_USE_FACL
2123 printf("%s", " + POSIX ACL support\n");
2124 #else
2125 printf("%s", " - POSIX ACL support\n");
2126 #endif /* PR_USE_FACL */
2127
2128 #ifdef PR_USE_REDIS
2129 printf("%s", " + Redis support\n");
2130 #else
2131 printf("%s", " - Redis support\n");
2132 #endif /* PR_USE_REDIS */
2133
2134 #ifdef PR_USE_SENDFILE
2135 printf("%s", " + Sendfile support\n");
2136 #else
2137 printf("%s", " - Sendfile support\n");
2138 #endif /* PR_USE_SENDFILE */
2139
2140 #ifdef PR_USE_SHADOW
2141 printf("%s", " + Shadow file support\n");
2142 #else
2143 printf("%s", " - Shadow file support\n");
2144 #endif /* PR_USE_SHADOW */
2145
2146 #ifdef PR_USE_SODIUM
2147 printf("%s", " + Sodium support\n");
2148 #else
2149 printf("%s", " - Sodium support\n");
2150 #endif /* PR_USE_SODIUM */
2151
2152 #ifdef PR_USE_TRACE
2153 printf("%s", " + Trace support\n");
2154 #else
2155 printf("%s", " - Trace support\n");
2156 #endif /* PR_USE_TRACE */
2157
2158 #ifdef PR_USE_XATTR
2159 printf("%s", " + xattr support\n");
2160 #else
2161 printf("%s", " - xattr support\n");
2162 #endif /* PR_USE_XATTR */
2163
2164 /* Tunable settings */
2165 printf("%s", "\n Tunable Options:\n");
2166 printf(" PR_TUNABLE_BUFFER_SIZE = %u\n", PR_TUNABLE_BUFFER_SIZE);
2167 printf(" PR_TUNABLE_DEFAULT_RCVBUFSZ = %u\n", PR_TUNABLE_DEFAULT_RCVBUFSZ);
2168 printf(" PR_TUNABLE_DEFAULT_SNDBUFSZ = %u\n", PR_TUNABLE_DEFAULT_SNDBUFSZ);
2169 printf(" PR_TUNABLE_ENV_MAX = %u\n", PR_TUNABLE_ENV_MAX);
2170 printf(" PR_TUNABLE_GLOBBING_MAX_MATCHES = %lu\n", PR_TUNABLE_GLOBBING_MAX_MATCHES);
2171 printf(" PR_TUNABLE_GLOBBING_MAX_RECURSION = %u\n", PR_TUNABLE_GLOBBING_MAX_RECURSION);
2172 printf(" PR_TUNABLE_HASH_TABLE_SIZE = %u\n", PR_TUNABLE_HASH_TABLE_SIZE);
2173 printf(" PR_TUNABLE_LOGIN_MAX = %u\n", PR_TUNABLE_LOGIN_MAX);
2174 printf(" PR_TUNABLE_NEW_POOL_SIZE = %u\n", PR_TUNABLE_NEW_POOL_SIZE);
2175 printf(" PR_TUNABLE_PATH_MAX = %u\n", PR_TUNABLE_PATH_MAX);
2176 printf(" PR_TUNABLE_SCOREBOARD_BUFFER_SIZE = %u\n",
2177 PR_TUNABLE_SCOREBOARD_BUFFER_SIZE);
2178 printf(" PR_TUNABLE_SCOREBOARD_SCRUB_TIMER = %u\n",
2179 PR_TUNABLE_SCOREBOARD_SCRUB_TIMER);
2180 printf(" PR_TUNABLE_SELECT_TIMEOUT = %u\n", PR_TUNABLE_SELECT_TIMEOUT);
2181 printf(" PR_TUNABLE_TIMEOUTIDENT = %u\n", PR_TUNABLE_TIMEOUTIDENT);
2182 printf(" PR_TUNABLE_TIMEOUTIDLE = %u\n", PR_TUNABLE_TIMEOUTIDLE);
2183 printf(" PR_TUNABLE_TIMEOUTLINGER = %u\n", PR_TUNABLE_TIMEOUTLINGER);
2184 printf(" PR_TUNABLE_TIMEOUTLOGIN = %u\n", PR_TUNABLE_TIMEOUTLOGIN);
2185 printf(" PR_TUNABLE_TIMEOUTNOXFER = %u\n", PR_TUNABLE_TIMEOUTNOXFER);
2186 printf(" PR_TUNABLE_TIMEOUTSTALLED = %u\n", PR_TUNABLE_TIMEOUTSTALLED);
2187 printf(" PR_TUNABLE_XFER_SCOREBOARD_UPDATES = %u\n\n",
2188 PR_TUNABLE_XFER_SCOREBOARD_UPDATES);
2189 }
2190
2191 static struct option_help {
2192 const char *long_opt, *short_opt, *desc;
2193
2194 } opts_help[] = {
2195 { "--help", "-h",
2196 "Display proftpd usage"},
2197
2198 { "--nocollision", "-N",
2199 "Disable address/port collision checking" },
2200
2201 { "--nodaemon", "-n",
2202 "Disable background daemon mode (and send all output to stderr)" },
2203
2204 { "--quiet", "-q",
2205 "Don't send output to stderr when running with -n or --nodaemon" },
2206
2207 { "--debug", "-d [level]",
2208 "Set debugging level (0-10, 10 = most debugging)" },
2209
2210 { "--define", "-D [definition]",
2211 "Set arbitrary IfDefine definition" },
2212
2213 { "--config", "-c [config-file]",
2214 "Specify alternate configuration file" },
2215
2216 { "--persistent", "-p [0|1]",
2217 "Enable/disable default persistent passwd support" },
2218
2219 { "--list", "-l",
2220 "List all compiled-in modules" },
2221
2222 { "--serveraddr", "-S",
2223 "Specify IP address for server config" },
2224
2225 { "--configtest", "-t",
2226 "Test the syntax of the specified config" },
2227
2228 { "--settings", "-V",
2229 "Print compile-time settings and exit" },
2230
2231 { "--version", "-v",
2232 "Print version number and exit" },
2233
2234 { "--version-status", "-vv",
2235 "Print extended version information and exit" },
2236
2237 { "--nofork", "-X",
2238 "Non-forking debug mode; exits after one session" },
2239
2240 { "--ipv4", "-4",
2241 "Support IPv4 connections only" },
2242
2243 { "--ipv6", "-6",
2244 "Support IPv6 connections" },
2245
2246 { NULL, NULL, NULL }
2247 };
2248
show_usage(int exit_code)2249 static void show_usage(int exit_code) {
2250 struct option_help *h;
2251
2252 printf("%s", "usage: proftpd [options]\n");
2253 for (h = opts_help; h->long_opt; h++) {
2254 #ifdef HAVE_GETOPT_LONG
2255 printf(" %s, %s\n ", h->short_opt, h->long_opt);
2256 #else /* HAVE_GETOPT_LONG */
2257 printf(" %s\n", h->short_opt);
2258 #endif /* HAVE_GETOPT_LONG */
2259 printf(" %s\n", h->desc);
2260 }
2261
2262 exit(exit_code);
2263 }
2264
main(int argc,char * argv[],char ** envp)2265 int main(int argc, char *argv[], char **envp) {
2266 int optc, show_version = 0;
2267 const char *cmdopts = "D:NVc:d:hlnp:qS:tvX46";
2268 mode_t *main_umask = NULL;
2269 socklen_t peerlen;
2270 struct sockaddr peer;
2271
2272 #ifdef HAVE_SET_AUTH_PARAMETERS
2273 (void) set_auth_parameters(argc, argv);
2274 #endif
2275
2276 #ifdef HAVE_TZSET
2277 /* Preserve timezone information in jailed environments.
2278 */
2279 tzset();
2280 #endif
2281
2282 memset(&session, 0, sizeof(session));
2283
2284 pr_fs_close_extra_fds();
2285 pr_proctitle_init(argc, argv, envp);
2286
2287 /* Seed rand */
2288 pr_random_init();
2289
2290 /* getpeername() fails if the fd isn't a socket */
2291 peerlen = sizeof(peer);
2292 memset(&peer, 0, peerlen);
2293 if (getpeername(fileno(stdin), &peer, &peerlen) != -1)
2294 log_stderr(FALSE);
2295
2296 /* Open the syslog */
2297 log_opensyslog(NULL);
2298
2299 /* Initialize the memory subsystem here */
2300 init_pools();
2301
2302 /* Command line options supported:
2303 *
2304 * -D parameter set run-time configuration parameter
2305 * --define parameter
2306 * -V
2307 * --settings report compile-time settings
2308 * -c path set the configuration path
2309 * --config path
2310 * -d n set the debug level
2311 * --debug n
2312 * -q quiet mode; don't log to stderr when not daemonized
2313 * --quiet
2314 * -N disable address/port collision checks
2315 * --nocollision
2316 * -n standalone server does not daemonize, all logging
2317 * --nodaemon redirected to stderr
2318 * -S specify the IP address for the 'server config',
2319 * --serveraddr rather than using DNS on the hostname
2320 * -t syntax check of the configuration file
2321 * --configtest
2322 * -v report version number
2323 * --version
2324 * -X
2325 * --nofork debug/non-fork mode
2326 * -4 support IPv4 connections only
2327 * --ipv4
2328 * -6 support IPv6 connections
2329 * --ipv6
2330 */
2331
2332 opterr = 0;
2333 while ((optc =
2334 #ifdef HAVE_GETOPT_LONG
2335 getopt_long(argc, argv, cmdopts, opts, NULL)
2336 #else /* HAVE_GETOPT_LONG */
2337 getopt(argc, argv, cmdopts)
2338 #endif /* HAVE_GETOPT_LONG */
2339 ) != -1) {
2340 switch (optc) {
2341
2342 case 'D':
2343 if (!optarg) {
2344 pr_log_pri(PR_LOG_WARNING, "fatal: -D requires definition parameter");
2345 exit(1);
2346 }
2347
2348 pr_define_add(optarg, TRUE);
2349 break;
2350
2351 case 'V':
2352 show_settings();
2353 exit(0);
2354 break;
2355
2356 case 'N':
2357 AddressCollisionCheck = FALSE;
2358 break;
2359
2360 case 'n':
2361 nodaemon++;
2362 #ifdef PR_USE_DEVEL
2363 pr_pool_debug_set_flags(PR_POOL_DEBUG_FL_OOM_DUMP_POOLS);
2364 #endif
2365 break;
2366
2367 case 'q':
2368 quiet++;
2369 break;
2370
2371 case 'd':
2372 if (!optarg) {
2373 pr_log_pri(PR_LOG_WARNING, "fatal: -d requires debug level parameter");
2374 exit(1);
2375 }
2376 pr_log_setdebuglevel(atoi(optarg));
2377
2378 /* If the admin uses -d on the command-line, they explicitly WANT
2379 * debug logging, thus make sure the default SyslogLevel is set to
2380 * DEBUG (rather than NOTICE); see Bug#3983.
2381 */
2382 pr_log_setdefaultlevel(PR_LOG_DEBUG);
2383 break;
2384
2385 case 'c':
2386 if (!optarg) {
2387 pr_log_pri(PR_LOG_WARNING,
2388 "fatal: -c requires configuration path parameter");
2389 exit(1);
2390 }
2391
2392 /* Note: we delay sanity-checking the given path until after the FSIO
2393 * layer has been initialized.
2394 */
2395 config_filename = strdup(optarg);
2396 break;
2397
2398 case 'l':
2399 modules_list2(NULL, PR_MODULES_LIST_FL_SHOW_STATIC);
2400 exit(0);
2401 break;
2402
2403 case 'S':
2404 if (!optarg) {
2405 pr_log_pri(PR_LOG_WARNING, "fatal: -S requires IP address parameter");
2406 exit(1);
2407 }
2408
2409 if (pr_netaddr_set_localaddr_str(optarg) < 0) {
2410 pr_log_pri(PR_LOG_WARNING,
2411 "fatal: unable to use '%s' as server address: %s", optarg,
2412 strerror(errno));
2413 exit(1);
2414 }
2415 break;
2416
2417 case 't':
2418 syntax_check = 1;
2419 printf("%s", "Checking syntax of configuration file\n");
2420 fflush(stdout);
2421 break;
2422
2423 /* Note: This is now unused, and should be deprecated in the next release.
2424 * See Bug#3952 for details.
2425 */
2426 case 'p': {
2427 if (!optarg ||
2428 (atoi(optarg) != 1 && atoi(optarg) != 0)) {
2429 pr_log_pri(PR_LOG_WARNING,
2430 "fatal: -p requires Boolean (0|1) parameter");
2431 exit(1);
2432 }
2433
2434 break;
2435 }
2436
2437 case 'v':
2438 show_version++;
2439 break;
2440
2441 case 'X':
2442 no_forking = TRUE;
2443 break;
2444
2445 case 1:
2446 show_version = 2;
2447 break;
2448
2449 case 'h':
2450 show_usage(0);
2451 break;
2452
2453 case '4':
2454 pr_netaddr_disable_ipv6();
2455 break;
2456
2457 case '6':
2458 pr_netaddr_enable_ipv6();
2459 break;
2460
2461 case '?':
2462 pr_log_pri(PR_LOG_WARNING, "unknown option: %c", (char) optopt);
2463 show_usage(1);
2464 break;
2465 }
2466 }
2467
2468 /* If we have any leftover parameters, it's an error. */
2469 if (argv[optind]) {
2470 pr_log_pri(PR_LOG_WARNING, "fatal: unknown parameter: '%s'", argv[optind]);
2471 exit(1);
2472 }
2473
2474 if (show_version &&
2475 show_version == 1) {
2476 printf("%s", "ProFTPD Version " PROFTPD_VERSION_TEXT "\n");
2477 exit(0);
2478 }
2479
2480 mpid = getpid();
2481
2482 /* Initialize sub-systems */
2483 init_signals();
2484 init_pools();
2485 init_privs();
2486 init_log();
2487 init_regexp();
2488 init_inet();
2489 init_netio();
2490 init_netaddr();
2491 init_fs();
2492 init_class();
2493 free_bindings();
2494 init_config();
2495 init_dirtree();
2496 init_stash();
2497 init_json();
2498
2499 #ifdef PR_USE_CTRLS
2500 init_ctrls();
2501 #endif /* PR_USE_CTRLS */
2502
2503 var_init();
2504 modules_init();
2505
2506 #ifdef PR_USE_NLS
2507 # ifdef HAVE_LOCALE_H
2508 /* Initialize the locale based on environment variables. */
2509 if (setlocale(LC_ALL, "") == NULL) {
2510 const char *env_lang;
2511
2512 env_lang = pr_env_get(permanent_pool, "LANG");
2513 pr_log_pri(PR_LOG_WARNING, "warning: unknown/unsupported LANG environment "
2514 "variable '%s', ignoring", env_lang);
2515
2516 setlocale(LC_ALL, "C");
2517
2518 } else {
2519 /* Make sure that LC_NUMERIC is always set to "C", so as not to interfere
2520 * with formatting of strings (like printing out floats in SQL query
2521 * strings).
2522 */
2523 setlocale(LC_NUMERIC, "C");
2524 }
2525 # endif /* !HAVE_LOCALE_H */
2526
2527 encode_init();
2528 #endif /* PR_USE_NLS */
2529
2530 /* Now, once the modules have had a chance to initialize themselves
2531 * but before the configuration stream is actually parsed, check
2532 * that the given configuration path is valid.
2533 */
2534 if (pr_fs_valid_path(config_filename) < 0) {
2535 pr_log_pri(PR_LOG_WARNING, "fatal: -c requires an absolute path");
2536 exit(1);
2537 }
2538
2539 pr_parser_prepare(NULL, NULL);
2540
2541 pr_event_generate("core.preparse", NULL);
2542
2543 if (pr_parser_parse_file(NULL, config_filename, NULL, 0) < 0) {
2544 /* Note: EPERM is used to indicate the presence of unrecognized
2545 * configuration directives in the parsed file(s).
2546 */
2547 if (errno != EPERM) {
2548 pr_log_pri(PR_LOG_WARNING,
2549 "fatal: unable to read configuration file '%s': %s", config_filename,
2550 strerror(errno));
2551 }
2552
2553 exit(1);
2554 }
2555
2556 if (pr_parser_cleanup() < 0) {
2557 pr_log_pri(PR_LOG_WARNING,
2558 "fatal: error processing configuration file '%s': "
2559 "unclosed configuration section", config_filename);
2560 exit(1);
2561 }
2562
2563 if (fixup_servers(server_list) < 0) {
2564 pr_log_pri(PR_LOG_WARNING,
2565 "fatal: error processing configuration file '%s'", config_filename);
2566 exit(1);
2567 }
2568
2569 pr_event_generate("core.postparse", NULL);
2570
2571 if (show_version == 2) {
2572 printf("ProFTPD Version: %s", PROFTPD_VERSION_TEXT " " PR_STATUS "\n");
2573 printf(" Scoreboard Version: %08x\n", PR_SCOREBOARD_VERSION);
2574 printf(" Built: %s\n\n", BUILD_STAMP);
2575
2576 modules_list2(NULL, PR_MODULES_LIST_FL_SHOW_VERSION);
2577 exit(0);
2578 }
2579
2580 /* We're only doing a syntax check of the configuration file. */
2581 if (syntax_check) {
2582 printf("%s", "Syntax check complete.\n");
2583 pr_session_end(PR_SESS_END_FL_SYNTAX_CHECK);
2584 }
2585
2586 /* Security */
2587 {
2588 uid_t *uid = (uid_t *) get_param_ptr(main_server->conf, "UserID", FALSE);
2589 gid_t *gid = (gid_t *) get_param_ptr(main_server->conf, "GroupID", FALSE);
2590
2591 daemon_uid = (uid != NULL ? *uid : PR_ROOT_UID);
2592 daemon_gid = (gid != NULL ? *gid : PR_ROOT_GID);
2593 }
2594
2595 if (daemon_uid != PR_ROOT_UID) {
2596 pr_log_debug(DEBUG9, "ignoring supplemental groups for non-root UID %lu",
2597 (unsigned long) daemon_uid);
2598 }
2599
2600 /* After configuration is complete, make sure that passwd, group
2601 * aren't held open (unnecessary fds for master daemon)
2602 */
2603 endpwent();
2604 endgrent();
2605
2606 main_umask = get_param_ptr(main_server->conf, "Umask", FALSE);
2607 if (main_umask == NULL) {
2608 umask((mode_t) 0022);
2609
2610 } else {
2611 umask(*main_umask);
2612 }
2613
2614 /* Give up root and save our uid/gid for later use (if supported)
2615 * If we aren't currently root, PRIVS_SETUP will get rid of setuid
2616 * granted root and prevent further uid switching from being attempted.
2617 */
2618
2619 PRIVS_SETUP(daemon_uid, daemon_gid)
2620
2621 #ifndef PR_DEVEL_COREDUMP
2622 /* Test to make sure that our uid/gid is correct. Try to do this in
2623 * a portable fashion *gah!*
2624 */
2625
2626 if (geteuid() != daemon_uid) {
2627 pr_log_pri(PR_LOG_ERR, "unable to set UID to %s, current UID: %s",
2628 pr_uid2str(permanent_pool, daemon_uid),
2629 pr_uid2str(permanent_pool, geteuid()));
2630 exit(1);
2631 }
2632
2633 if (getegid() != daemon_gid) {
2634 pr_log_pri(PR_LOG_ERR, "unable to set GID to %s, current GID: %s",
2635 pr_gid2str(permanent_pool, daemon_gid),
2636 pr_gid2str(permanent_pool, getegid()));
2637 exit(1);
2638 }
2639 #endif /* PR_DEVEL_COREDUMP */
2640
2641 switch (ServerType) {
2642 case SERVER_STANDALONE:
2643 standalone_main();
2644 break;
2645
2646 case SERVER_INETD:
2647 /* Reset the variable containing the pid of the master/daemon process;
2648 * it should only be non-zero in the case of standalone daemons.
2649 */
2650 mpid = 0;
2651 inetd_main();
2652 break;
2653 }
2654
2655 #ifdef PR_DEVEL_NO_DAEMON
2656 PRIVS_ROOT
2657 chdir(PR_RUN_DIR);
2658 #endif /* PR_DEVEL_NO_DAEMON */
2659
2660 return 0;
2661 }
2662