Hello community,

here is the log from the commit of package tftp for openSUSE:Factory
checked in at Fri Jun 24 09:56:51 CEST 2011.



--------
--- tftp/tftp.changes   2010-12-11 01:00:45.000000000 +0100
+++ /mounts/work_src_done/STABLE/tftp/tftp.changes      2011-06-24 
09:14:08.000000000 +0200
@@ -1,0 +2,19 @@
+Fri Jun 24 07:09:50 UTC 2011 - [email protected]
+
+- unbreak tftp by changing to user to run as in tftpd itself,
+  not via xinetd (bnc#682340)
+
+-------------------------------------------------------------------
+Thu Jun 23 12:17:37 UTC 2011 - [email protected]
+
+- update to version-5.1
+  - Add -P option to write a PID file.  Patch by Ferenc Wagner.
+  - Bounce the syslog socket in standalone mode, in case the
+    syslog daemon has been restarted.  Patch by Ferenc Wagner.
+  - Build fixes.
+  - Fix handling of block number wraparound after a successful
+    options negotiation.
+  - Fix a buffer overflow in option parsing.
+- fixes bnc#699714, CVE-2011-2199
+
+-------------------------------------------------------------------

calling whatdependson for head-i586


Old:
----
  tftp-hpa-5.0.tar.bz2

New:
----
  tftp-hpa-5.1.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ tftp.spec ++++++
--- /var/tmp/diff_new_pack.LhGDcW/_old  2011-06-24 09:54:44.000000000 +0200
+++ /var/tmp/diff_new_pack.LhGDcW/_new  2011-06-24 09:54:44.000000000 +0200
@@ -1,7 +1,7 @@
 #
-# spec file for package tftp (Version 5.0)
+# spec file for package tftp
 #
-# Copyright (c) 2010 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2011 SUSE LINUX Products GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,13 +18,13 @@
 
 
 Name:           tftp
-Version:        5.0
+Version:        5.1
 Release:        1
 License:        BSD3c
 Summary:        Trivial File Transfer Protocol (TFTP)
 Url:            http://www.kernel.org/pub/software/network/tftp/
 Group:          Productivity/Networking/Ftp/Clients
-Source:         tftp-hpa-%{version}.tar.bz2
+Source:         
http://www.kernel.org/pub/software/network/tftp/tftp-hpa-%{version}.tar.bz2
 Source1:        tftp.xinetd
 Patch0:         tftp-hpa-0.43_include_sys_params.patch
 Patch1:         tftp-hpa-0.46_colon_check.patch
@@ -68,7 +68,7 @@
 
 %install
 %makeinstall INSTALLROOT=%{buildroot} MANDIR="%{_mandir}"
-install -D -m 0644 %{S:1} %{buildroot}%{_sysconfdir}/xinetd.d/tftp
+install -D -m 0644 %{SOURCE1} %{buildroot}%{_sysconfdir}/xinetd.d/tftp
 install -d -m 0750 %{buildroot}/srv/tftpboot
 
 %pre

++++++ tftp-hpa-0.48-tzfix.patch ++++++
--- /var/tmp/diff_new_pack.LhGDcW/_old  2011-06-24 09:54:44.000000000 +0200
+++ /var/tmp/diff_new_pack.LhGDcW/_new  2011-06-24 09:54:44.000000000 +0200
@@ -1,9 +1,9 @@
-Index: tftp-hpa-git-0.48/tftpd/tftpd.c
+Index: tftp-hpa-5.1/tftpd/tftpd.c
 ===================================================================
---- tftp-hpa-git-0.48.orig/tftpd/tftpd.c
-+++ tftp-hpa-git-0.48/tftpd/tftpd.c
-@@ -350,6 +350,14 @@ int main(int argc, char **argv)
- #endif
+--- tftp-hpa-5.1.orig/tftpd/tftpd.c
++++ tftp-hpa-5.1/tftpd/tftpd.c
+@@ -384,6 +384,14 @@ int main(int argc, char **argv)
+     const char *pidfile = NULL;
      u_short tp_opcode;
  
 +    time_t my_time = 0;

++++++ tftp-hpa-5.0.tar.bz2 -> tftp-hpa-5.1.tar.bz2 ++++++
++++ 20789 lines of diff (skipped)
++++    retrying with extended exclude list
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/tftp-hpa-5.0/CHANGES new/tftp-hpa-5.1/CHANGES
--- old/tftp-hpa-5.0/CHANGES    2009-02-16 23:51:22.000000000 +0100
+++ new/tftp-hpa-5.1/CHANGES    2011-06-23 01:32:56.000000000 +0200
@@ -1,3 +1,17 @@
+Changes in 5.1:
+       Add -P option to write a PID file.  Patch by Ferenc Wagner.
+
+       Bounce the syslog socket in standalone mode, in case the
+       syslog daemon has been restarted.  Patch by Ferenc Wagner.
+
+       Build fixes.
+
+       Fix handling of block number wraparound after a successful
+       options negotiation.
+
+       Fix a buffer overflow in option parsing.
+
+
 Changes in 5.0:
        Try to on platforms with getaddrinfo() without AI_ADDRCONFIG or
        AI_CANONNAME.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/tftp-hpa-5.0/MCONFIG.in new/tftp-hpa-5.1/MCONFIG.in
--- old/tftp-hpa-5.0/MCONFIG.in 2009-02-16 23:51:22.000000000 +0100
+++ new/tftp-hpa-5.1/MCONFIG.in 2011-06-23 01:32:56.000000000 +0200
@@ -32,7 +32,7 @@
 SBINDIR = @sbindir@
 
 # Data root directory
-DATAROOTDIR = @datarootdir@
+datarootdir = @datarootdir@
 
 # Binary suffixes
 O = @OBJEXT@
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/tftp-hpa-5.0/aconfig.h.in new/tftp-hpa-5.1/aconfig.h.in
--- old/tftp-hpa-5.0/aconfig.h.in       2009-02-16 23:51:36.000000000 +0100
+++ new/tftp-hpa-5.1/aconfig.h.in       2011-06-23 01:33:28.000000000 +0200
@@ -21,6 +21,9 @@
 /* Define to 1 if you have the `ftruncate' function. */
 #undef HAVE_FTRUNCATE
 
+/* Define if fcntl.h defines F_SETLK */
+#undef HAVE_F_SETLK_DEFINITION
+
 /* Define if getaddrinfo function was found */
 #undef HAVE_GETADDRINFO
 
@@ -54,6 +57,12 @@
 /* Define to 1 if you have the `wrap' library (-lwrap). */
 #undef HAVE_LIBWRAP
 
+/* Define if sys/file.h defines LOCK_EX */
+#undef HAVE_LOCK_EX_DEFINITION
+
+/* Define if sys/file.h defines LOCK_SH */
+#undef HAVE_LOCK_SH_DEFINITION
+
 /* Define to 1 if the system has the type `long long'. */
 #undef HAVE_LONG_LONG
 
@@ -141,6 +150,9 @@
 /* Define to 1 if you have the <sysexits.h> header file. */
 #undef HAVE_SYSEXITS_H
 
+/* Define to 1 if you have the <sys/file.h> header file. */
+#undef HAVE_SYS_FILE_H
+
 /* Define to 1 if you have the <sys/filio.h> header file. */
 #undef HAVE_SYS_FILIO_H
 
@@ -204,6 +216,9 @@
 /* Define to the one symbol short name of this package. */
 #undef PACKAGE_TARNAME
 
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
 /* Define to the version of this package. */
 #undef PACKAGE_VERSION
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/tftp-hpa-5.0/autogen.sh new/tftp-hpa-5.1/autogen.sh
--- old/tftp-hpa-5.0/autogen.sh 2009-02-16 23:51:22.000000000 +0100
+++ new/tftp-hpa-5.1/autogen.sh 2011-06-23 01:32:56.000000000 +0200
@@ -1,3 +1,2 @@
 #!/bin/sh
-autoheader
-autoconf
+make autoconf
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/tftp-hpa-5.0/configure.in new/tftp-hpa-5.1/configure.in
--- old/tftp-hpa-5.0/configure.in       2009-02-16 23:51:22.000000000 +0100
+++ new/tftp-hpa-5.1/configure.in       2011-06-23 01:32:56.000000000 +0200
@@ -46,6 +46,7 @@
 AC_CHECK_HEADERS(sysexits.h)
 AC_CHECK_HEADERS(time.h)
 AC_CHECK_HEADERS(unistd.h)
+AC_CHECK_HEADERS(sys/file.h)
 AC_CHECK_HEADERS(sys/filio.h)
 AC_CHECK_HEADERS(sys/stat.h)
 AC_CHECK_HEADERS(sys/time.h)
@@ -140,6 +141,11 @@
 PA_HEADER_DEFINES(fcntl.h, int, O_BINARY)
 PA_HEADER_DEFINES(fcntl.h, int, O_TEXT)
 
+PA_HEADER_DEFINES(fcntl.h, int, F_SETLK)
+
+PA_HEADER_DEFINES(sys/file.h, int, LOCK_SH)
+PA_HEADER_DEFINES(sys/file.h, int, LOCK_EX)
+
 AH_TEMPLATE([HAVE_SIGSETJMP],
 [Define if we have sigsetjmp, siglongjmp and sigjmp_buf.])
 PA_SIGSETJMP([AC_DEFINE(HAVE_SIGSETJMP)])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/tftp-hpa-5.0/tftp.spec new/tftp-hpa-5.1/tftp.spec
--- old/tftp-hpa-5.0/tftp.spec  2009-02-16 23:51:36.000000000 +0100
+++ new/tftp-hpa-5.1/tftp.spec  2011-06-23 01:33:28.000000000 +0200
@@ -1,11 +1,11 @@
 Summary: The client for the Trivial File Transfer Protocol (TFTP).
 Name: tftp
-Version: 5.0
+Version: 5.1
 Release: 1
 License: BSD
 Group: Applications/Internet
 Source0: 
http://www.kernel.org/pub/software/network/tftp/tftp-hpa-%{version}.tar.gz
-BuildPreReq: tcp_wrappers
+BuildRequires: tcp_wrappers-devel
 BuildRoot: %{_tmppath}/%{name}-root
 
 %description
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/tftp-hpa-5.0/tftp.spec.in new/tftp-hpa-5.1/tftp.spec.in
--- old/tftp-hpa-5.0/tftp.spec.in       2009-02-16 23:51:22.000000000 +0100
+++ new/tftp-hpa-5.1/tftp.spec.in       2011-06-23 01:32:56.000000000 +0200
@@ -5,7 +5,7 @@
 License: BSD
 Group: Applications/Internet
 Source0: 
http://www.kernel.org/pub/software/network/tftp/tftp-hpa-%{version}.tar.gz
-BuildPreReq: tcp_wrappers
+BuildRequires: tcp_wrappers-devel
 BuildRoot: %{_tmppath}/%{name}-root
 
 %description
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/tftp-hpa-5.0/tftpd/recvfrom.c new/tftp-hpa-5.1/tftpd/recvfrom.c
--- old/tftp-hpa-5.0/tftpd/recvfrom.c   2009-02-16 23:51:22.000000000 +0100
+++ new/tftp-hpa-5.1/tftpd/recvfrom.c   2011-06-23 01:32:56.000000000 +0200
@@ -245,7 +245,8 @@
 
 int
 myrecvfrom(int s, void *buf, int len, unsigned int flags,
-           struct sockaddr *from, int *fromlen, union sock_addr *myaddr)
+           struct sockaddr *from, socklen_t * fromlen,
+           union sock_addr *myaddr)
 {
     /* There is no way we can get the local address, fudge it */
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/tftp-hpa-5.0/tftpd/remap.c new/tftp-hpa-5.1/tftpd/remap.c
--- old/tftp-hpa-5.0/tftpd/remap.c      2009-02-16 23:51:22.000000000 +0100
+++ new/tftp-hpa-5.1/tftpd/remap.c      2011-06-23 01:32:56.000000000 +0200
@@ -30,14 +30,13 @@
 #define RULE_EXIT      0x04    /* Exit after matching this rule */
 #define RULE_RESTART   0x08    /* Restart at the top after matching this rule 
*/
 #define RULE_ABORT     0x10    /* Terminate processing with an error */
-#define RULE_GETONLY   0x20    /* Applicable to GET only */
-#define RULE_PUTONLY   0x40    /* Applicable to PUT only */
-#define RULE_INVERSE   0x80    /* Execute if regex *doesn't* match */
+#define RULE_INVERSE   0x20    /* Execute if regex *doesn't* match */
 
 struct rule {
     struct rule *next;
     int nrule;
     int rule_flags;
+    char rule_mode;
     regex_t rx;
     const char *pattern;
 };
@@ -221,15 +220,13 @@
         case 'i':
             rxflags |= REG_ICASE;
             break;
-        case 'G':
-            r->rule_flags |= RULE_GETONLY;
-            break;
-        case 'P':
-            r->rule_flags |= RULE_PUTONLY;
-            break;
         case '~':
             r->rule_flags |= RULE_INVERSE;
             break;
+       case 'G':
+       case 'P':
+            r->rule_mode = *p;
+            break;
         default:
             syslog(LOG_ERR,
                    "Remap command \"%s\" on line %d contains invalid char 
\"%c\"",
@@ -329,7 +326,7 @@
 
 /* Execute a rule set on a string; returns a malloc'd new string. */
 char *rewrite_string(const char *input, const struct rule *rules,
-                     int is_put, match_pattern_callback macrosub,
+                     char mode, match_pattern_callback macrosub,
                      const char **errmsg)
 {
     char *current = tfstrdup(input);
@@ -348,10 +345,8 @@
     }
 
     for (ruleptr = rules; ruleptr; ruleptr = ruleptr->next) {
-        if (((ruleptr->rule_flags & RULE_GETONLY) && is_put) ||
-            ((ruleptr->rule_flags & RULE_PUTONLY) && !is_put)) {
+       if (ruleptr->rule_mode && ruleptr->rule_mode != mode)
             continue;           /* Rule not applicable, try next */
-        }
 
         if (!deadman--) {
             syslog(LOG_WARNING,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/tftp-hpa-5.0/tftpd/remap.h new/tftp-hpa-5.1/tftpd/remap.h
--- old/tftp-hpa-5.0/tftpd/remap.h      2009-02-16 23:51:22.000000000 +0100
+++ new/tftp-hpa-5.1/tftpd/remap.h      2011-06-23 01:32:56.000000000 +0200
@@ -35,7 +35,7 @@
 void freerules(struct rule *);
 
 /* Execute a rule set on a string; returns a malloc'd new string. */
-char *rewrite_string(const char *, const struct rule *, int,
+char *rewrite_string(const char *, const struct rule *, char,
                      match_pattern_callback, const char **);
 
 #endif                          /* WITH_REGEX */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/tftp-hpa-5.0/tftpd/tftpd.8.in new/tftp-hpa-5.1/tftpd/tftpd.8.in
--- old/tftp-hpa-5.0/tftpd/tftpd.8.in   2009-02-16 23:51:22.000000000 +0100
+++ new/tftp-hpa-5.1/tftpd/tftpd.8.in   2011-06-23 01:32:56.000000000 +0200
@@ -3,7 +3,7 @@
 .\" Copyright (c) 1990, 1993, 1994
 .\"     The Regents of the University of California.  All rights reserved.
 .\"
-.\" Copyright 2001-2008 H. Peter Anvin - All Rights Reserved
+.\" Copyright 2001-2009 H. Peter Anvin - All Rights Reserved
 .\"
 .\" Redistribution and use in source and binary forms, with or without
 .\" modification, are permitted provided that the following conditions
@@ -30,10 +30,10 @@
 .\" SUCH DAMAGE.
 .\"
 .\"----------------------------------------------------------------------- */
-.TH TFTPD 8 "30 July 2008" "tftp-hpa @@VERSION@@" "System Manager's Manual"
+.TH TFTPD 8 "14 September 2009" "tftp-hpa @@VERSION@@" "System Manager's 
Manual"
 .SH NAME
 .B tftpd
-\- IPv4 Trivial File Transfer Protocol server
+\- Trivial File Transfer Protocol server
 .SH SYNOPSIS
 .B in.tftpd
 .RI [ options... ]
@@ -133,6 +133,11 @@
 .B \-\-user
 option.
 .TP
+\fB\-\-pidfile\fP \fIpidfile\fP, \fB\-P\fP \fIpidfile\fP
+When run in standalone mode, write the process ID of the listening
+server into \fIpidfile\fP.  On normal termination (SIGTERM or SIGINT)
+the pid file is automatically removed.
+.TP
 \fB\-\-timeout\fP \fItimeout\fP, \fB\-t\fP \fItimeout\fP
 When run from
 .B inetd
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/tftp-hpa-5.0/tftpd/tftpd.c new/tftp-hpa-5.1/tftpd/tftpd.c
--- old/tftp-hpa-5.0/tftpd/tftpd.c      2009-02-16 23:51:22.000000000 +0100
+++ new/tftp-hpa-5.1/tftpd/tftpd.c      2011-06-23 01:32:56.000000000 +0200
@@ -1,5 +1,7 @@
 /*
  * Copyright (c) 1983 Regents of the University of California.
+ * Copyright (c) 1999-2009 H. Peter Anvin
+ * Copyright (c) 2011 Intel Corporation; author: H. Peter Anvin
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -113,18 +115,18 @@
 int tftp(struct tftphdr *, int);
 static void nak(int, const char *);
 static void timer(int);
-static void do_opt(char *, char *, char **);
+static void do_opt(const char *, const char *, char **);
 
-static int set_blksize(char *, char **);
-static int set_blksize2(char *, char **);
-static int set_tsize(char *, char **);
-static int set_timeout(char *, char **);
-static int set_utimeout(char *, char **);
-static int set_rollover(char *, char **);
+static int set_blksize(uintmax_t *);
+static int set_blksize2(uintmax_t *);
+static int set_tsize(uintmax_t *);
+static int set_timeout(uintmax_t *);
+static int set_utimeout(uintmax_t *);
+static int set_rollover(uintmax_t *);
 
 struct options {
     const char *o_opt;
-    int (*o_fnc) (char *, char **);
+    int (*o_fnc)(uintmax_t *);
 } options[] = {
     {"blksize",  set_blksize},
     {"blksize2", set_blksize2},
@@ -143,6 +145,13 @@
     caught_sighup = 1;
 }
 
+/* Handle exit requests by SIGTERM and SIGINT */
+static volatile sig_atomic_t exit_signal = 0;
+static void handle_exit(int sig)
+{
+    exit_signal = sig;
+}
+
 /* Handle timeout signal or timeout event */
 void timer(int sig)
 {
@@ -171,6 +180,26 @@
 }
 #endif
 
+/*
+ * Rules for locking files; return 0 on success, -1 on failure
+ */
+static int lock_file(int fd, int lock_write)
+{
+#if defined(HAVE_FCNTL) && defined(HAVE_F_SETLK_DEFINITION)
+  struct flock fl;
+
+  fl.l_type   = lock_write ? F_WRLCK : F_RDLCK;
+  fl.l_whence = SEEK_SET;
+  fl.l_start  = 0;
+  fl.l_len    = 0;             /* Whole file */
+  return fcntl(fd, F_SETLK, &fl);
+#elif defined(HAVE_LOCK_SH_DEFINITION)
+  return flock(fd, lock_write ? LOCK_EX|LOCK_NB : LOCK_SH|LOCK_NB);
+#else
+  return 0;                    /* Hope & pray... */
+#endif
+}
+
 static void set_socket_nonblock(int fd, int flag)
 {
     int err;
@@ -317,9 +346,10 @@
     { "retransmit",  1, NULL, 'T' },
     { "port-range",  1, NULL, 'R' },
     { "map-file",    1, NULL, 'm' },
+    { "pidfile",     1, NULL, 'P' },
     { NULL, 0, NULL, 0 }
 };
-static const char short_options[] = "46cspvVlLa:B:u:U:r:t:T:R:m:";
+static const char short_options[] = "46cspvVlLa:B:u:U:r:t:T:R:m:P:";
 
 int main(int argc, char **argv)
 {
@@ -351,6 +381,7 @@
 #ifdef WITH_REGEX
     char *rewrite_file = NULL;
 #endif
+    const char *pidfile = NULL;
     u_short tp_opcode;
 
     /* basename() is way too much of a pain from a portability standpoint */
@@ -363,7 +394,7 @@
     srand(time(NULL) ^ getpid());
 
     while ((c = getopt_long(argc, argv, short_options, long_options, NULL))
-          != -1)
+           != -1)
         switch (c) {
         case '4':
             ai_fam = AF_INET;
@@ -466,14 +497,17 @@
         case 'v':
             verbosity++;
             break;
-       case OPT_VERBOSITY:
-           verbosity = atoi(optarg);
-           break;
+        case OPT_VERBOSITY:
+            verbosity = atoi(optarg);
+            break;
         case 'V':
             /* Print configuration to stdout and exit */
             printf("%s\n", TFTPD_CONFIG_STR);
             exit(0);
             break;
+        case 'P':
+            pidfile = optarg;
+            break;
         default:
             syslog(LOG_ERR, "Unknown option: '%c'", optopt);
             break;
@@ -506,16 +540,19 @@
         exit(EX_NOUSER);
     }
 
-    if (spec_umask || !unixperms)
-        umask(my_umask);
-
 #ifdef WITH_REGEX
     if (rewrite_file)
         rewrite_rules = read_remap_rules(rewrite_file);
 #endif
 
+    if (pidfile && !standalone) {
+        syslog(LOG_WARNING, "not in standalone mode, ignoring pid file");
+        pidfile = NULL;
+    }
+
     /* If we're running standalone, set up the input port */
     if (standalone) {
+        FILE *pf;
 #ifdef HAVE_IPV6
         if (ai_fam != AF_INET6) {
 #endif
@@ -695,12 +732,26 @@
         }
 #endif
         /* Daemonize this process */
-        /* Note: when running in secure mode (-s), we must not chroot, since
+        /* Note: when running in secure mode (-s), we must not chdir, since
            we are already in the proper directory. */
         if (!nodaemon && daemon(secure, 0) < 0) {
             syslog(LOG_ERR, "cannot daemonize: %m");
             exit(EX_OSERR);
         }
+        set_signal(SIGTERM, handle_exit, 0);
+        set_signal(SIGINT,  handle_exit, 0);
+        if (pidfile) {
+            pf = fopen (pidfile, "w");
+            if (!pf) {
+                syslog(LOG_ERR, "cannot open pid file '%s' for writing: %m", 
pidfile);
+                pidfile = NULL;
+            } else {
+                if (fprintf(pf, "%d\n", getpid()) < 0)
+                    syslog(LOG_ERR, "error writing pid file '%s': %m", 
pidfile);
+                if (fclose(pf))
+                    syslog(LOG_ERR, "error closing pid file '%s': %m", 
pidfile);
+            }
+        }
         if (fd6 > fd4)
             fdmax = fd6;
         else
@@ -733,11 +784,23 @@
        lose packets as a result. */
     set_signal(SIGHUP, handle_sighup, 0);
 
+    if (spec_umask || !unixperms)
+        umask(my_umask);
+
     while (1) {
         fd_set readset;
         struct timeval tv_waittime;
         int rv;
 
+        if (exit_signal) { /* happens in standalone mode only */
+            if (pidfile && unlink(pidfile)) {
+                syslog(LOG_WARNING, "error removing pid file '%s': %m", 
pidfile);
+                exit(EX_OSERR);
+            } else {
+                exit(0);
+            }
+       }
+
         if (caught_sighup) {
             caught_sighup = 0;
             if (standalone) {
@@ -869,6 +932,15 @@
     /* Ignore SIGHUP */
     set_signal(SIGHUP, SIG_IGN, 0);
 
+    /* Make sure the log socket is still connected.  This has to be
+       done before the chroot, while /dev/log is still accessible.
+       When not running standalone, there is little chance that the
+       syslog daemon gets restarted by the time we get here. */
+    if (secure && standalone) {
+        closelog();
+        openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
+    }
+
 #ifdef HAVE_TCPWRAPPERS
     /* Verify if this was a legal request for us.  This has to be
        done before the chroot, while /etc is still accessible. */
@@ -972,18 +1044,19 @@
 }
 
 static char *rewrite_access(char *, int, const char **);
-static int validate_access(char *, int, struct formats *, const char **);
-static void tftp_sendfile(struct formats *, struct tftphdr *, int);
-static void tftp_recvfile(struct formats *, struct tftphdr *, int);
+static int validate_access(char *, int, const struct formats *, const char **);
+static void tftp_sendfile(const struct formats *, struct tftphdr *, int);
+static void tftp_recvfile(const struct formats *, struct tftphdr *, int);
 
 struct formats {
     const char *f_mode;
     char *(*f_rewrite) (char *, int, const char **);
-    int (*f_validate) (char *, int, struct formats *, const char **);
-    void (*f_send) (struct formats *, struct tftphdr *, int);
-    void (*f_recv) (struct formats *, struct tftphdr *, int);
+    int (*f_validate) (char *, int, const struct formats *, const char **);
+    void (*f_send) (const struct formats *, struct tftphdr *, int);
+    void (*f_recv) (const struct formats *, struct tftphdr *, int);
     int f_convert;
-} formats[] = {
+};
+static const struct formats formats[] = {
     {
     "netascii", rewrite_access, validate_access, tftp_sendfile,
             tftp_recvfile, 1}, {
@@ -999,7 +1072,7 @@
 {
     char *cp, *end;
     int argn, ecode;
-    struct formats *pf = NULL;
+    const struct formats *pf = NULL;
     char *origfilename;
     char *filename, *mode = NULL;
     const char *errmsgptr;
@@ -1103,48 +1176,38 @@
 /*
  * Set a non-standard block size (c.f. RFC2348)
  */
-static int set_blksize(char *val, char **ret)
+static int set_blksize(uintmax_t *vp)
 {
-    static char b_ret[6];
-    unsigned int sz;
-    char *vend;
-
-    sz = (unsigned int)strtoul(val, &vend, 10);
+    uintmax_t sz = *vp;
 
-    if (blksize_set || *vend)
+    if (blksize_set)
         return 0;
 
     if (sz < 8)
-        return (0);
+        return 0;
     else if (sz > max_blksize)
         sz = max_blksize;
 
-    segsize = sz;
-    sprintf(*ret = b_ret, "%u", sz);
-
+    *vp = segsize = sz;
     blksize_set = 1;
-
-    return (1);
+    return 1;
 }
 
 /*
  * Set a power-of-two block size (nonstandard)
  */
-static int set_blksize2(char *val, char **ret)
+static int set_blksize2(uintmax_t *vp)
 {
-    static char b_ret[6];
-    unsigned int sz;
-    char *vend;
-
-    sz = (unsigned int)strtoul(val, &vend, 10);
+    uintmax_t sz = *vp;
 
-    if (blksize_set || *vend)
+    if (blksize_set)
         return 0;
 
     if (sz < 8)
         return (0);
     else if (sz > max_blksize)
         sz = max_blksize;
+    else
 
     /* Convert to a power of two */
     if (sz & (sz - 1)) {
@@ -1155,29 +1218,23 @@
         sz = sz1;
     }
 
-    segsize = sz;
-    sprintf(*ret = b_ret, "%u", sz);
-
+    *vp = segsize = sz;
     blksize_set = 1;
-
-    return (1);
+    return 1;
 }
 
 /*
  * Set the block number rollover value
  */
-static int set_rollover(char *val, char **ret)
+static int set_rollover(uintmax_t *vp)
 {
-  uintmax_t ro;
-  char *vend;
+    uintmax_t ro = *vp;
+    
+    if (ro > 65535)
+       return 0;
 
-  ro = strtoumax(val, &vend, 10);
-  if (ro > 65535 || *vend)
-    return 0;
-
-  rollover_val = (uint16_t)ro;
-  *ret = val;
-  return 1;
+    rollover_val = (uint16_t)ro;
+    return 1;
 }
 
 /*
@@ -1185,22 +1242,18 @@
  * For netascii mode, we don't know the size ahead of time;
  * so reject the option.
  */
-static int set_tsize(char *val, char **ret)
+static int set_tsize(uintmax_t *vp)
 {
-    static char b_ret[sizeof(uintmax_t) * CHAR_BIT / 3 + 2];
-    uintmax_t sz;
-    char *vend;
+    uintmax_t sz = *vp;
 
-    sz = strtoumax(val, &vend, 10);
-
-    if (!tsize_ok || *vend)
+    if (!tsize_ok)
         return 0;
 
     if (sz == 0)
-        sz = (uintmax_t) tsize;
+        sz = tsize;
 
-    sprintf(*ret = b_ret, "%" PRIuMAX, sz);
-    return (1);
+    *vp = sz;
+    return 1;
 }
 
 /*
@@ -1208,74 +1261,86 @@
  * to be the (default) retransmission timeout, but being an
  * integer in seconds it seems a bit limited.
  */
-static int set_timeout(char *val, char **ret)
+static int set_timeout(uintmax_t *vp)
 {
-    static char b_ret[4];
-    unsigned long to;
-    char *vend;
+    uintmax_t to = *vp;
 
-    to = strtoul(val, &vend, 10);
-
-    if (to < 1 || to > 255 || *vend)
+    if (to < 1 || to > 255)
         return 0;
 
     rexmtval = timeout = to * 1000000UL;
     maxtimeout = rexmtval * TIMEOUT_LIMIT;
 
-    sprintf(*ret = b_ret, "%lu", to);
-    return (1);
+    return 1;
 }
 
 /* Similar, but in microseconds.  We allow down to 10 ms. */
-static int set_utimeout(char *val, char **ret)
+static int set_utimeout(uintmax_t *vp)
 {
-    static char b_ret[4];
-    unsigned long to;
-    char *vend;
+    uintmax_t to = *vp;
 
-    to = strtoul(val, &vend, 10);
-
-    if (to < 10000UL || to > 255000000UL || *vend)
+    if (to < 10000UL || to > 255000000UL)
         return 0;
 
     rexmtval = timeout = to;
     maxtimeout = rexmtval * TIMEOUT_LIMIT;
 
-    sprintf(*ret = b_ret, "%lu", to);
-    return (1);
+    return 1;
 }
 
 /*
- * Parse RFC2347 style options
+ * Conservative calculation for the size of a buffer which can hold an
+ * arbitrary integer
+ */
+#define OPTBUFSIZE     (sizeof(uintmax_t) * CHAR_BIT / 3 + 3)
+
+/*
+ * Parse RFC2347 style options; we limit the arguments to positive
+ * integers which matches all our current options.
  */
-static void do_opt(char *opt, char *val, char **ap)
+static void do_opt(const char *opt, const char *val, char **ap)
 {
     struct options *po;
-    char *ret;
+    char retbuf[OPTBUFSIZE];
+    char *p = *ap;
+    size_t optlen, retlen;
+    char *vend;
+    uintmax_t v;
 
     /* Global option-parsing variables initialization */
     blksize_set = 0;
 
-    if (!*opt)
+    if (!*opt || !*val)
         return;
 
+    errno = 0;
+    v = strtoumax(val, &vend, 10);
+    if (*vend || errno == ERANGE)
+       return;
+
     for (po = options; po->o_opt; po++)
         if (!strcasecmp(po->o_opt, opt)) {
-            if (po->o_fnc(val, &ret)) {
-                if (*ap + strlen(opt) + strlen(ret) + 2 >=
-                    ackbuf + sizeof(ackbuf)) {
+            if (po->o_fnc(&v)) {
+               optlen = strlen(opt);
+               retlen = sprintf(retbuf, "%"PRIuMAX, v);
+
+                if (p + optlen + retlen + 2 >= ackbuf + sizeof(ackbuf)) {
                     nak(EOPTNEG, "Insufficient space for options");
                     exit(0);
                 }
-                *ap = strrchr(strcpy(strrchr(strcpy(*ap, opt), '\0') + 1,
-                                     ret), '\0') + 1;
+               
+               memcpy(p, opt, optlen+1);
+               p += optlen+1;
+               memcpy(p, retbuf, retlen+1);
+               p += retlen+1;
             } else {
                 nak(EOPTNEG, "Unsupported option(s) requested");
                 exit(0);
             }
             break;
         }
-    return;
+
+    *ap = p;
 }
 
 #ifdef WITH_REGEX
@@ -1337,7 +1402,8 @@
 {
     if (rewrite_rules) {
         char *newname =
-            rewrite_string(filename, rewrite_rules, mode != RRQ,
+            rewrite_string(filename, rewrite_rules,
+                          mode != RRQ ? 'P' : 'G',
                            rewrite_macros, msg);
         filename = newname;
     }
@@ -1366,7 +1432,7 @@
  * given as we have no login directory.
  */
 static int validate_access(char *filename, int mode,
-                          struct formats *pf, const char **errmsg)
+                          const struct formats *pf, const char **errmsg)
 {
     struct stat stbuf;
     int i, len;
@@ -1410,11 +1476,13 @@
      * We use different a different permissions scheme if `cancreate' is
      * set.
      */
-    wmode = O_WRONLY |
-        (cancreate ? O_CREAT : 0) |
-        (unixperms ? O_TRUNC : 0) | (pf->f_convert ? O_TEXT : O_BINARY);
+    wmode = O_WRONLY | (cancreate ? O_CREAT : 0) | (pf->f_convert ? O_TEXT : 
O_BINARY);
     rmode = O_RDONLY | (pf->f_convert ? O_TEXT : O_BINARY);
 
+#ifndef HAVE_FTRUNCATE
+    wmode |= O_TRUNC;          /* This really sucks on a dupe */
+#endif
+
     fd = open(filename, mode == RRQ ? rmode : wmode, 0666);
     if (fd < 0) {
         switch (errno) {
@@ -1433,6 +1501,10 @@
     if (fstat(fd, &stbuf) < 0)
         exit(EX_OSERR);         /* This shouldn't happen */
 
+    /* A duplicate RRQ or (worse!) WRQ packet could really cause havoc... */
+    if (lock_file(fd, mode != RRQ))
+       exit(0);
+
     if (mode == RRQ) {
         if (!unixperms && (stbuf.st_mode & (S_IREAD >> 6)) == 0) {
             *errmsg = "File must have global read permissions";
@@ -1447,15 +1519,15 @@
                 *errmsg = "File must have global write permissions";
                 return (EACCESS);
             }
+        }
 
-            /* We didn't get to truncate the file at open() time */
 #ifdef HAVE_FTRUNCATE
-            if (ftruncate(fd, (off_t) 0)) {
-                *errmsg = "Cannot reset file size";
-                return (EACCESS);
-            }
+       /* We didn't get to truncate the file at open() time */
+       if (ftruncate(fd, (off_t) 0)) {
+         *errmsg = "Cannot reset file size";
+         return (EACCESS);
+       }
 #endif
-        }
         tsize = 0;
         tsize_ok = 1;
     }
@@ -1474,7 +1546,7 @@
 /*
  * Send the requested file.
  */
-static void tftp_sendfile(struct formats *pf, struct tftphdr *oap, int oacklen)
+static void tftp_sendfile(const struct formats *pf, struct tftphdr *oap, int 
oacklen)
 {
     struct tftphdr *dp;
     struct tftphdr *ap;         /* ack packet */
@@ -1572,7 +1644,7 @@
 /*
  * Receive a file.
  */
-static void tftp_recvfile(struct formats *pf, struct tftphdr *oap, int oacklen)
+static void tftp_recvfile(const struct formats *pf, struct tftphdr *oap, int 
oacklen)
 {
     struct tftphdr *dp;
     int n, size;
@@ -1595,6 +1667,10 @@
             ap->th_opcode = htons((u_short) ACK);
             ap->th_block = htons((u_short) block);
             acksize = 4;
+            /* If we're sending a regular ACK, that means we have successfully
+             * sent the OACK. Clear oap so that we won't try to send another
+             * OACK when the block number wraps back to 0. */
+            oap = NULL;
         }
         if (!++block)
          block = rollover_val;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/tftp-hpa-5.0/version new/tftp-hpa-5.1/version
--- old/tftp-hpa-5.0/version    2009-02-16 23:51:22.000000000 +0100
+++ new/tftp-hpa-5.1/version    2011-06-23 01:32:56.000000000 +0200
@@ -1 +1 @@
-5.0
+5.1

++++++ tftp.xinetd ++++++
--- /var/tmp/diff_new_pack.LhGDcW/_old  2011-06-24 09:54:44.000000000 +0200
+++ /var/tmp/diff_new_pack.LhGDcW/_new  2011-06-24 09:54:44.000000000 +0200
@@ -11,9 +11,9 @@
        protocol                = udp
        wait                    = yes
        flags                   = IPv6 IPv4
-       user                    = tftp
+       user                    = root
        server                  = /usr/sbin/in.tftpd
-       server_args             = -s /srv/tftpboot
+       server_args             = -u tftp -s /srv/tftpboot
 #      per_source              = 11
 #      cps                     = 100 2
        disable                 = yes


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++



Remember to have fun...

-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to