Deleted Added
full compact
tftpd.c (146827) tftpd.c (173852)
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 28 unchanged lines hidden (view full) ---

37 The Regents of the University of California. All rights reserved.\n";
38#endif /* not lint */
39
40#ifndef lint
41#if 0
42static char sccsid[] = "@(#)tftpd.c 8.1 (Berkeley) 6/4/93";
43#endif
44static const char rcsid[] =
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 28 unchanged lines hidden (view full) ---

37 The Regents of the University of California. All rights reserved.\n";
38#endif /* not lint */
39
40#ifndef lint
41#if 0
42static char sccsid[] = "@(#)tftpd.c 8.1 (Berkeley) 6/4/93";
43#endif
44static const char rcsid[] =
45 "$FreeBSD: head/libexec/tftpd/tftpd.c 146827 2005-05-31 17:22:53Z maxim $";
45 "$FreeBSD: head/libexec/tftpd/tftpd.c 173852 2007-11-23 00:05:29Z edwin $";
46#endif /* not lint */
47
48/*
49 * Trivial file transfer protocol server.
50 *
51 * This version includes many modifications by Jim Guyton
52 * <guyton@rand-unix>.
53 */

--- 51 unchanged lines hidden (view full) ---

105static struct dirlist {
106 const char *name;
107 int len;
108} dirs[MAXDIRS+1];
109static int suppress_naks;
110static int logging;
111static int ipchroot;
112static int create_new = 0;
46#endif /* not lint */
47
48/*
49 * Trivial file transfer protocol server.
50 *
51 * This version includes many modifications by Jim Guyton
52 * <guyton@rand-unix>.
53 */

--- 51 unchanged lines hidden (view full) ---

105static struct dirlist {
106 const char *name;
107 int len;
108} dirs[MAXDIRS+1];
109static int suppress_naks;
110static int logging;
111static int ipchroot;
112static int create_new = 0;
113static char *newfile_format = "%Y%m%d";
114static int increase_name = 0;
113static mode_t mask = S_IWGRP|S_IWOTH;
114
115static const char *errtomsg(int);
116static void nak(int);
117static void oack(void);
118
119static void timer(int);
120static void justquit(int);

--- 8 unchanged lines hidden (view full) ---

129 struct sockaddr_storage me;
130 char *chroot_dir = NULL;
131 struct passwd *nobody;
132 const char *chuser = "nobody";
133
134 tzset(); /* syslog in localtime */
135
136 openlog("tftpd", LOG_PID | LOG_NDELAY, LOG_FTP);
115static mode_t mask = S_IWGRP|S_IWOTH;
116
117static const char *errtomsg(int);
118static void nak(int);
119static void oack(void);
120
121static void timer(int);
122static void justquit(int);

--- 8 unchanged lines hidden (view full) ---

131 struct sockaddr_storage me;
132 char *chroot_dir = NULL;
133 struct passwd *nobody;
134 const char *chuser = "nobody";
135
136 tzset(); /* syslog in localtime */
137
138 openlog("tftpd", LOG_PID | LOG_NDELAY, LOG_FTP);
137 while ((ch = getopt(argc, argv, "cClns:u:U:w")) != -1) {
139 while ((ch = getopt(argc, argv, "cCF:lns:u:U:wW")) != -1) {
138 switch (ch) {
139 case 'c':
140 ipchroot = 1;
141 break;
142 case 'C':
143 ipchroot = 2;
144 break;
140 switch (ch) {
141 case 'c':
142 ipchroot = 1;
143 break;
144 case 'C':
145 ipchroot = 2;
146 break;
147 case 'F':
148 newfile_format = optarg;
149 break;
145 case 'l':
146 logging = 1;
147 break;
148 case 'n':
149 suppress_naks = 1;
150 break;
151 case 's':
152 chroot_dir = optarg;
153 break;
154 case 'u':
155 chuser = optarg;
156 break;
157 case 'U':
158 mask = strtol(optarg, NULL, 0);
159 break;
160 case 'w':
161 create_new = 1;
162 break;
150 case 'l':
151 logging = 1;
152 break;
153 case 'n':
154 suppress_naks = 1;
155 break;
156 case 's':
157 chroot_dir = optarg;
158 break;
159 case 'u':
160 chuser = optarg;
161 break;
162 case 'U':
163 mask = strtol(optarg, NULL, 0);
164 break;
165 case 'w':
166 create_new = 1;
167 break;
168 case 'W':
169 create_new = 1;
170 increase_name = 1;
171 break;
163 default:
164 syslog(LOG_WARNING, "ignoring unknown option -%c", ch);
165 }
166 }
167 if (optind < argc) {
168 struct dirlist *dirp;
169
170 /* Get list of directory prefixes. Skip relative pathnames. */

--- 337 unchanged lines hidden (view full) ---

508 (*pf->f_send)(pf);
509 exit(0);
510}
511
512
513FILE *file;
514
515/*
172 default:
173 syslog(LOG_WARNING, "ignoring unknown option -%c", ch);
174 }
175 }
176 if (optind < argc) {
177 struct dirlist *dirp;
178
179 /* Get list of directory prefixes. Skip relative pathnames. */

--- 337 unchanged lines hidden (view full) ---

517 (*pf->f_send)(pf);
518 exit(0);
519}
520
521
522FILE *file;
523
524/*
525 * Find the next value for YYYYMMDD.nn when the file to be written should
526 * be unique. Due to the limitations of nn, we will fail if nn reaches 100.
527 * Besides, that is four updates per hour on a file, which is kind of
528 * execessive anyway.
529 */
530static int
531find_next_name(char *filename, int *fd)
532{
533 int i;
534 time_t tval;
535 size_t len;
536 struct tm lt;
537 char yyyymmdd[MAXPATHLEN];
538 char newname[MAXPATHLEN];
539 struct stat sb;
540 int ret;
541
542 /* Create the YYYYMMDD part of the filename */
543 time(&tval);
544 lt = *localtime(&tval);
545 len = strftime(yyyymmdd, sizeof(yyyymmdd), newfile_format, &lt);
546 if (len == 0) {
547 syslog(LOG_WARNING,
548 "Filename suffix too long (%d characters maximum)",
549 MAXPATHLEN);
550 return (EACCESS);
551 }
552
553 /* Make sure the new filename is not too long */
554 if (strlen(filename) > MAXPATHLEN - len - 5) {
555 syslog(LOG_WARNING,
556 "Filename too long (%d characters, %d maximum)",
557 strlen(filename), MAXPATHLEN - len - 5);
558 return (EACCESS);
559 }
560
561 /* Find the first file which doesn't exist */
562 for (i = 0; i < 100; i++) {
563 sprintf(newname, "%s.%s.%02d", filename, yyyymmdd, i);
564 *fd = open(newname,
565 O_WRONLY | O_CREAT | O_EXCL,
566 S_IRUSR | S_IWUSR | S_IRGRP |
567 S_IWGRP | S_IROTH | S_IWOTH);
568 if (*fd > 0)
569 return 0;
570 }
571
572 return (EEXIST);
573}
574
575/*
516 * Validate file access. Since we
517 * have no uid or gid, for now require
518 * file to exist and be publicly
519 * readable/writable.
520 * If we were invoked with arguments
521 * from inetd then the file must also be
522 * in one of the given directory prefixes.
523 * Note also, full path name must be
524 * given as we have no login directory.
525 */
526int
527validate_access(char **filep, int mode)
528{
529 struct stat stbuf;
530 int fd;
576 * Validate file access. Since we
577 * have no uid or gid, for now require
578 * file to exist and be publicly
579 * readable/writable.
580 * If we were invoked with arguments
581 * from inetd then the file must also be
582 * in one of the given directory prefixes.
583 * Note also, full path name must be
584 * given as we have no login directory.
585 */
586int
587validate_access(char **filep, int mode)
588{
589 struct stat stbuf;
590 int fd;
591 int error;
531 struct dirlist *dirp;
532 static char pathname[MAXPATHLEN];
533 char *filename = *filep;
534
535 /*
536 * Prevent tricksters from getting around the directory restrictions
537 */
538 if (strstr(filename, "/../"))

--- 66 unchanged lines hidden (view full) ---

605 else
606 /* XXX Allows writes of all sizes. */
607 options[OPT_TSIZE].o_reply =
608 atoi(options[OPT_TSIZE].o_request);
609 }
610 if (mode == RRQ)
611 fd = open(filename, O_RDONLY);
612 else {
592 struct dirlist *dirp;
593 static char pathname[MAXPATHLEN];
594 char *filename = *filep;
595
596 /*
597 * Prevent tricksters from getting around the directory restrictions
598 */
599 if (strstr(filename, "/../"))

--- 66 unchanged lines hidden (view full) ---

666 else
667 /* XXX Allows writes of all sizes. */
668 options[OPT_TSIZE].o_reply =
669 atoi(options[OPT_TSIZE].o_request);
670 }
671 if (mode == RRQ)
672 fd = open(filename, O_RDONLY);
673 else {
613 if (create_new)
614 fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0666);
615 else
616 fd = open(filename, O_WRONLY|O_TRUNC);
674 if (create_new) {
675 if (increase_name) {
676 error = find_next_name(filename, &fd);
677 if (error > 0)
678 return (error + 100);
679 } else
680 fd = open(filename,
681 O_WRONLY | O_TRUNC | O_CREAT,
682 S_IRUSR | S_IWUSR | S_IRGRP |
683 S_IWGRP | S_IROTH | S_IWOTH );
684 } else
685 fd = open(filename, O_WRONLY | O_TRUNC);
617 }
618 if (fd < 0)
619 return (errno + 100);
620 file = fdopen(fd, (mode == RRQ)? "r":"w");
621 if (file == NULL) {
622 close(fd);
623 return (errno + 100);
624 }

--- 305 unchanged lines hidden ---
686 }
687 if (fd < 0)
688 return (errno + 100);
689 file = fdopen(fd, (mode == RRQ)? "r":"w");
690 if (file == NULL) {
691 close(fd);
692 return (errno + 100);
693 }

--- 305 unchanged lines hidden ---