* src/oftpd.c (reopen_syslog_hack): Removed.
authorWerner Koch <wk@gnupg.org>
Wed, 13 Aug 2003 11:58:11 +0000 (11:58 +0000)
committerWerner Koch <wk@gnupg.org>
Wed, 13 Aug 2003 11:58:11 +0000 (11:58 +0000)
(init_syslog_hack): Removed.  That was a whole stupid thing by me
as I didn'd realized that we are running chroot and so the
/dev/log socket could not be reopened by libc.
(main): Print a warning if there is no /dev directory below the
chroot.

* src/file_list.c (file_nlst,file_list): Don't list "/dev".
* src/ftp_session.c (change_dir, do_retr)
(do_size, do_mdtm): Likewise.

ChangeLog
NEWS
configure.in
src/file_list.c
src/ftp_listener.c
src/ftp_session.c
src/oftpd.c
src/oftpd.h
src/telnet_session.c

index 3faf0c3..43e2324 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2003-08-13  Werner Koch  <wk@gnupg.org>
+
+       
+       * src/oftpd.c (reopen_syslog_hack): Removed.
+       (init_syslog_hack): Removed.  That was a whole stupid thing by me
+       as I didn'd realized that we are running chroot and so the
+       /dev/log socket could not be reopened by libc.
+       (main): Print a warning if there is no /dev directory below the
+       chroot.
+
+       * src/file_list.c (file_nlst,file_list): Don't list "/dev".
+       * src/ftp_session.c (change_dir, do_retr)
+       (do_size, do_mdtm): Likewise.
+
+2003-08-12  Werner Koch  <wk@gnupg.org>
+
+       * src/oftpd.c (reopen_syslog_hack): Simply comparing the fd is not
+       enough due to race conditions.  So always check whether the syslog
+       fd is still bound to a unix domain socket.
+
 2003-08-09  Werner Koch  <wk@gnupg.org>
 
        * src/oftpd.c (main): Give LOG_FACILITY file scope.
 2003-08-09  Werner Koch  <wk@gnupg.org>
 
        * src/oftpd.c (main): Give LOG_FACILITY file scope.
diff --git a/NEWS b/NEWS
index 7a82c0c..1c4784b 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,11 @@
+2003-08-13 <wk@gnupg.org>
+
+  Print a warning if the /dev direcory does no exists below the
+  chroot.  It is required so that a syslogd restart won't harm.
+  Ignore the /dev directory in the ftp session.
+
+  Fixed some minor problems.
+
 2000-12-13
 
   IPv6 code is maintained by Mauro Tortonesi <mauro@ferrara.linux.it>.
 2000-12-13
 
   IPv6 code is maintained by Mauro Tortonesi <mauro@ferrara.linux.it>.
index 7e4fc92..389f602 100644 (file)
@@ -1,6 +1,6 @@
 dnl Process this file with autoconf to produce a configure script.
 AC_INIT(src/file_list.c)
 dnl Process this file with autoconf to produce a configure script.
 AC_INIT(src/file_list.c)
-AM_INIT_AUTOMAKE(oftpd, 0.3.6)
+AM_INIT_AUTOMAKE(oftpd, 0.3.6-wk1)
 AM_CONFIG_HEADER(src/config.h)
 
 dnl Checks for programs.
 AM_CONFIG_HEADER(src/config.h)
 
 dnl Checks for programs.
index a66ad17..01bcc2e 100644 (file)
@@ -106,6 +106,9 @@ int file_nlst(int out, const char *cur_dir, const char *filespec)
        return 0;
     }
     strcat(pattern, filespec);
        return 0;
     }
     strcat(pattern, filespec);
+    if ( !strncmp (pattern, "/dev", 4)
+         && (!pattern[4] || pattern[4] == '/'))
+      return 1; /* ignore /dev */
 
     /* do a glob() */
     memset(&glob_buf, 0, sizeof(glob_buf));
 
     /* do a glob() */
     memset(&glob_buf, 0, sizeof(glob_buf));
@@ -131,8 +134,11 @@ int file_nlst(int out, const char *cur_dir, const char *filespec)
     /* print our results */
     for (i=0; i<glob_buf.gl_pathc; i++) {
         file_name = glob_buf.gl_pathv[i];
     /* print our results */
     for (i=0; i<glob_buf.gl_pathc; i++) {
         file_name = glob_buf.gl_pathv[i];
+        if ( !strncmp (file_name, "/dev", 4)
+             && (!file_name[4] || file_name[4] == '/'))
+          continue; /* ignore /dev */
        if (memcmp(file_name, pattern, dir_len) == 0) {
        if (memcmp(file_name, pattern, dir_len) == 0) {
-           file_name += dir_len;
+          file_name += dir_len;
        }
        fdprintf(out, "%s\r\n", file_name);
     }
        }
        fdprintf(out, "%s\r\n", file_name);
     }
@@ -194,6 +200,10 @@ int file_list(int out, const char *cur_dir, const char *filespec)
        return 0;
     }
     strcat(pattern, filespec);
        return 0;
     }
     strcat(pattern, filespec);
+    if ( !strncmp (pattern, "/dev", 4)
+         && (!pattern[4] || pattern[4] == '/'))
+      return 1; /* ignore /dev */
+
 
     /* do a glob() */
     memset(&glob_buf, 0, sizeof(glob_buf));
 
     /* do a glob() */
     memset(&glob_buf, 0, sizeof(glob_buf));
@@ -233,6 +243,9 @@ int file_list(int out, const char *cur_dir, const char *filespec)
     total_blocks = 0;
     for (i=0; i<glob_buf.gl_pathc; i++) {
         file_name = glob_buf.gl_pathv[i];
     total_blocks = 0;
     for (i=0; i<glob_buf.gl_pathc; i++) {
         file_name = glob_buf.gl_pathv[i];
+        if ( !strncmp (file_name, "/dev", 4)
+             && (!file_name[4] || file_name[4] == '/'))
+          continue;
        if (memcmp(file_name, pattern, dir_len) == 0) {
            file_name += dir_len;
        }
        if (memcmp(file_name, pattern, dir_len) == 0) {
            file_name += dir_len;
        }
index a3a6fa7..2227a76 100644 (file)
@@ -178,7 +178,6 @@ int ftp_listener_init(ftp_listener_t *f,
 
     /* okay, finally do some socket manipulation */
     fd = socket(AF_INET, SOCK_STREAM, 0);
 
     /* okay, finally do some socket manipulation */
     fd = socket(AF_INET, SOCK_STREAM, 0);
-    reopen_syslog_hack (fd);
     if (fd == -1) {
         error_init(err, errno, "error creating socket; %s", strerror(errno));
         return 0;
     if (fd == -1) {
         error_init(err, errno, "error creating socket; %s", strerror(errno));
         return 0;
@@ -358,7 +357,6 @@ static void *connection_acceptor(ftp_listener_t *f)
          /* otherwise accept our pending connection (if any) */
          addr_len = sizeof(sockaddr_storage_t);
          fd = accept(f->fd, (struct sockaddr *)&client_addr, &addr_len);
          /* otherwise accept our pending connection (if any) */
          addr_len = sizeof(sockaddr_storage_t);
          fd = accept(f->fd, (struct sockaddr *)&client_addr, &addr_len);
-         reopen_syslog_hack (fd);
          if (fd >= 0) {
 
              tcp_nodelay = 1;
          if (fd >= 0) {
 
              tcp_nodelay = 1;
index 94b533f..e54a7b3 100644 (file)
@@ -569,9 +569,11 @@ static void change_dir(ftp_session_t *f, const char *new_dir)
        }
     }
 
        }
     }
 
-    /* see if this is a directory we can change into */
+    /* see if this is a directory we can change into.  We don't allow
+       /dev as usual. */
     dir_okay = 0;
     dir_okay = 0;
-    if (stat(target, &stat_buf) == 0) {
+    if (!(!strncmp (target, "/dev", 4) && (!target[4] || target[4] == '/'))
+        && stat(target, &stat_buf) == 0) {
 #ifndef STAT_MACROS_BROKEN
         if (!S_ISDIR(stat_buf.st_mode)) {
 #else
 #ifndef STAT_MACROS_BROKEN
         if (!S_ISDIR(stat_buf.st_mode)) {
 #else
@@ -726,7 +728,6 @@ static int set_pasv(ftp_session_t *f, sockaddr_storage_t *bind_addr)
     daemon_assert(bind_addr != NULL);
 
     socket_fd = socket(SSFAM(bind_addr), SOCK_STREAM, 0);
     daemon_assert(bind_addr != NULL);
 
     socket_fd = socket(SSFAM(bind_addr), SOCK_STREAM, 0);
-    reopen_syslog_hack (socket_fd);
     if (socket_fd == -1) {
         reply(f, 500, "Error creating server socket; %s.", strerror(errno));
        return -1;
     if (socket_fd == -1) {
         reply(f, 500, "Error creating server socket; %s.", strerror(errno));
        return -1;
@@ -1097,10 +1098,14 @@ static void do_retr(ftp_session_t *f, const ftp_command_t *cmd)
     /* create an absolute name for our file */
     file_name = cmd->arg[0].string;
     get_absolute_fname(full_path, sizeof(full_path), f->dir, file_name);
     /* create an absolute name for our file */
     file_name = cmd->arg[0].string;
     get_absolute_fname(full_path, sizeof(full_path), f->dir, file_name);
-
     /* open file */
     /* open file */
-    file_fd = open(full_path, O_RDONLY);
-    reopen_syslog_hack (file_fd);
+    if (!strncmp (full_path, "/dev", 4)
+        && (!full_path[4] || full_path[4] == '/')) {
+      file_fd = -1;
+      errno = ENOENT;
+    }
+    else
+      file_fd = open(full_path, O_RDONLY);
     if (file_fd == -1) {
         reply(f, 550, "Error opening file; %s.", strerror(errno));
        goto exit_retr;
     if (file_fd == -1) {
         reply(f, 550, "Error opening file; %s.", strerror(errno));
        goto exit_retr;
@@ -1291,7 +1296,6 @@ static int open_connection(ftp_session_t *f)
 
     if (f->data_channel == DATA_PORT) {
         socket_fd = socket(SSFAM(&f->data_port), SOCK_STREAM, 0);
 
     if (f->data_channel == DATA_PORT) {
         socket_fd = socket(SSFAM(&f->data_port), SOCK_STREAM, 0);
-        reopen_syslog_hack (socket_fd);
        if (socket_fd == -1) {
            reply(f, 425, "Error creating socket; %s.", strerror(errno));
            return -1;
        if (socket_fd == -1) {
            reply(f, 425, "Error creating socket; %s.", strerror(errno));
            return -1;
@@ -1308,7 +1312,6 @@ static int open_connection(ftp_session_t *f)
 
         addr_len = sizeof(struct sockaddr_in);
         socket_fd = accept(f->server_fd, (struct sockaddr *)&addr, &addr_len);
 
         addr_len = sizeof(struct sockaddr_in);
         socket_fd = accept(f->server_fd, (struct sockaddr *)&addr, &addr_len);
-        reopen_syslog_hack (socket_fd);
        if (socket_fd == -1) {
            reply(f, 425, "Error accepting connection; %s.", strerror(errno));
            return -1;
        if (socket_fd == -1) {
            reply(f, 425, "Error accepting connection; %s.", strerror(errno));
            return -1;
@@ -1639,9 +1642,13 @@ static void do_size(ftp_session_t *f, const ftp_command_t *cmd)
         /* create an absolute name for our file */
         file_name = cmd->arg[0].string;
         get_absolute_fname(full_path, sizeof(full_path), f->dir, file_name);
         /* create an absolute name for our file */
         file_name = cmd->arg[0].string;
         get_absolute_fname(full_path, sizeof(full_path), f->dir, file_name);
-
         /* get the file information */
         /* get the file information */
-        if (stat(full_path, &stat_buf) != 0) {
+        if (!strncmp (full_path, "/dev", 4)
+            && (!full_path[4] || full_path[4] == '/')) {
+            errno = ENOENT;
+            reply(f, 550, "Error getting file status; %s.", strerror(errno));
+        }
+        else if (stat(full_path, &stat_buf) != 0) {
             reply(f, 550, "Error getting file status; %s.", strerror(errno));
         } else {
             /* output the size */
             reply(f, 550, "Error getting file status; %s.", strerror(errno));
         } else {
             /* output the size */
@@ -1687,7 +1694,12 @@ static void do_mdtm(ftp_session_t *f, const ftp_command_t *cmd)
     get_absolute_fname(full_path, sizeof(full_path), f->dir, file_name);
 
     /* get the file information */
     get_absolute_fname(full_path, sizeof(full_path), f->dir, file_name);
 
     /* get the file information */
-    if (stat(full_path, &stat_buf) != 0) {
+    if (!strncmp (full_path, "/dev", 4)
+        && (!full_path[4] || full_path[4] == '/')) {
+        errno = ENOENT;
+        reply(f, 550, "Error getting file status; %s.", strerror(errno));
+    }
+    else if (stat(full_path, &stat_buf) != 0) {
         reply(f, 550, "Error getting file status; %s.", strerror(errno));
     } else {
         gmtime_r(&stat_buf.st_mtime, &mtime);
         reply(f, 550, "Error getting file status; %s.", strerror(errno));
     } else {
         gmtime_r(&stat_buf.st_mtime, &mtime);
@@ -1733,7 +1745,6 @@ static void send_readme(const ftp_session_t *f, int code)
 
     /* open our file */
     fd = open(file_name, O_RDONLY);
 
     /* open our file */
     fd = open(file_name, O_RDONLY);
-    reopen_syslog_hack (fd);
     if (fd == -1) {
         goto exit_send_readme;
     }
     if (fd == -1) {
         goto exit_send_readme;
     }
index 16d5a23..9beb16e 100644 (file)
 
 /* put our executable name here where everybody can see it */
 static const char *exe_name = "oftpd";
 
 /* put our executable name here where everybody can see it */
 static const char *exe_name = "oftpd";
-static int log_facility;
 
 int pasv_port_low = 1024;
 int pasv_port_high = MAX_PORT;
 
 
 int pasv_port_low = 1024;
 int pasv_port_high = MAX_PORT;
 
-/* This is used by the reopen_syslog_hack. */
 static int my_syslog_fd = -1;
 
 static void daemonize();
 static void print_usage(const char *error);
 static int my_syslog_fd = -1;
 
 static void daemonize();
 static void print_usage(const char *error);
-static void init_syslog_hack (void);
 
 int main(int argc, char *argv[])
 {
 
 int main(int argc, char *argv[])
 {
@@ -58,6 +55,8 @@ int main(int argc, char *argv[])
 
     int detach;
 
 
     int detach;
 
+    int log_facility;
+
     sigset_t term_signal;
     int sig;
 
     sigset_t term_signal;
     int sig;
 
@@ -238,7 +237,6 @@ int main(int argc, char *argv[])
     /* log the start time */
     openlog(NULL, LOG_NDELAY, log_facility);
     syslog(LOG_INFO,"Starting, version %s, as PID %d", VERSION, getpid());
     /* log the start time */
     openlog(NULL, LOG_NDELAY, log_facility);
     syslog(LOG_INFO,"Starting, version %s, as PID %d", VERSION, getpid());
-    init_syslog_hack ();
 
     /* change to root directory */
     if (chroot(dir_ptr) != 0) {
 
     /* change to root directory */
     if (chroot(dir_ptr) != 0) {
@@ -251,6 +249,25 @@ int main(int argc, char *argv[])
         exit(1);
     }
 
         exit(1);
     }
 
+    /* Check that a /dev directory exists, so that syslog works
+       properly even after a syslogd restart. */
+    {
+      struct stat stat_buf;
+
+      if (stat( "/dev", &stat_buf)) {
+        syslog (LOG_ERR, "required `%s/dev' directory is missing: %s\n",
+                dir_ptr, strerror (errno));
+      }
+#ifndef STATS_MACRO_BROKEN
+      if (!S_ISDIR(stat_buf.st_mode)) {
+#else
+      if (S_ISDIR(stat_buf.st_mode)) {
+#endif
+          syslog (LOG_ERR, "`%s/dev' is not a directory\n", dir_ptr);
+      }
+    }
+
+
     /* create our main listener */
     if (!ftp_listener_init(&ftp_listener, 
                            address,
     /* create our main listener */
     if (!ftp_listener_init(&ftp_listener, 
                            address,
@@ -381,61 +398,3 @@ static void daemonize()
     }
 }
 
     }
 }
 
-
-/* Figure out the syslog fd and store it away. */
-static void init_syslog_hack ()
-{
-    struct sockaddr_un addr;
-    socklen_t len;
-    int fd;
-
-    my_syslog_fd = -1;
-    /* We know that stdin, stdout and stderr are connected to
-     * /dev/null, so we can start with 3.  FIXME: We should use a
-     * POSIX thing to figure out the highest possible fd. */
-    for (fd=3; fd < 1024; fd++) {
-        len = sizeof addr;
-        if (!getsockname (fd, (struct sockaddr*)&addr, &len)) {
-            if (addr.sun_family == PF_LOCAL) {
-                /* Found a unix domain socket.  This is what we were
-                 * looking for. */
-                my_syslog_fd = fd;
-                syslog(LOG_INFO,"Found my syslog file descriptor (%d).", fd);
-                return;
-            }
-        }
-    }
-}
-
-
-void reopen_syslog_hack (int fd)
-{
-    if (fd < 0)
-        return;
-    if (my_syslog_fd == -1)
-        return; /* not initialized, so we can't use the hack. */
-    if (fd == my_syslog_fd) {
-        ; /* We lost the fd in the meantime, otherwise the next
-           * file descriptor should not get this fd. */
-    }
-    else {
-      struct sockaddr_un addr;
-      socklen_t len = sizeof addr;
-
-      if (!getsockname (my_syslog_fd, (struct sockaddr*)&addr, &len)) 
-        if (addr.sun_family == PF_LOCAL) 
-          return;   /* Okay, this is still a unix domain socket, so
-                       everything seems to be fine. */
-    }
-
-    my_syslog_fd = -1;
-    /* fixme: If we would employ a syslog() wrapper and use a lock
-     * there we could easily avoid to lose messages.  But OTOH, this
-     * is just a glibc fix, so we will live with that.  Anyway, we can
-     * detect a lost syslog file descriptor only after an open or
-     * socket call - so it does not matter at all. */
-    openlog(NULL, LOG_NDELAY, log_facility);
-    syslog(LOG_INFO,"Redone the openlog call to fix a glibc bug."
-                    "Some messages might have been lost.");
-    init_syslog_hack ();
-}
index 9987482..0e4dc3c 100644 (file)
@@ -29,9 +29,5 @@
 #define README_FILE_NAME "README"
 
 
 #define README_FILE_NAME "README"
 
 
-/*-- oftpd.c --*/
-void reopen_syslog_hack (int fd);
-
-
 #endif /* OFTPD_H */
 
 #endif /* OFTPD_H */
 
index b196272..5221b0d 100644 (file)
@@ -534,7 +534,6 @@ int main()
 
     signal(SIGPIPE, SIG_IGN);
     while ((newfd = accept(fd, &newaddr, &newaddrlen)) >= 0) {
 
     signal(SIGPIPE, SIG_IGN);
     while ((newfd = accept(fd, &newaddr, &newaddrlen)) >= 0) {
-        reopen_syslog_hack (newfd);
         telnet_session_init(&t, newfd, newfd);
         telnet_session_print(&t, "Password:");
         telnet_session_readln(&t, buf, sizeof(buf));
         telnet_session_init(&t, newfd, newfd);
         telnet_session_print(&t, "Password:");
         telnet_session_readln(&t, buf, sizeof(buf));