/[inetutils]/inetutils/ftpd/ftpd.c
ViewVC logotype

Diff of /inetutils/ftpd/ftpd.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.53 by ams, Sat Jan 22 14:53:23 2005 UTC revision 1.54 by gray, Tue Oct 11 11:16:13 2005 UTC
# Line 440  main(int argc, char *argv[], char **envp Line 440  main(int argc, char *argv[], char **envp
440    /* LOG_NDELAY sets up the logging connection immediately,    /* LOG_NDELAY sets up the logging connection immediately,
441       necessary for anonymous ftp's that chroot and can't do it later.  */       necessary for anonymous ftp's that chroot and can't do it later.  */
442    openlog ("ftpd", LOG_PID | LOG_NDELAY, LOG_FTP);    openlog ("ftpd", LOG_PID | LOG_NDELAY, LOG_FTP);
443    (void) freopen (PATH_DEVNULL, "w", stderr);    freopen (PATH_DEVNULL, "w", stderr);
444    
445    /* If not running via inetd, we detach and dup(fd, 0), dup(fd, 1) the    /* If not running via inetd, we detach and dup(fd, 0), dup(fd, 1) the
446       fd = accept(). tcpd is check if compile with the support  */       fd = accept(). tcpd is check if compile with the support  */
# Line 460  main(int argc, char *argv[], char **envp Line 460  main(int argc, char *argv[], char **envp
460          }          }
461      }      }
462    
463    (void) signal (SIGHUP, sigquit);    signal (SIGHUP, sigquit);
464    (void) signal (SIGINT, sigquit);    signal (SIGINT, sigquit);
465    (void) signal (SIGQUIT, sigquit);    signal (SIGQUIT, sigquit);
466    (void) signal (SIGTERM, sigquit);    signal (SIGTERM, sigquit);
467    (void) signal (SIGPIPE, lostconn);    signal (SIGPIPE, lostconn);
468    (void) signal (SIGCHLD, SIG_IGN);    signal (SIGCHLD, SIG_IGN);
469    if (signal (SIGURG, myoob) == SIG_ERR)    if (signal (SIGURG, myoob) == SIG_ERR)
470      syslog (LOG_ERR, "signal: %m");      syslog (LOG_ERR, "signal: %m");
471    
# Line 526  main(int argc, char *argv[], char **envp Line 526  main(int argc, char *argv[], char **envp
526    
527    /* Display a Welcome message if exists,    /* Display a Welcome message if exists,
528       N.B. reply(220,) must follow.  */       N.B. reply(220,) must follow.  */
529    (void) display_file (PATH_FTPWELCOME, 220);    display_file (PATH_FTPWELCOME, 220);
530    
531    hostname = localhost ();    hostname = localhost ();
532    if (! hostname)    if (! hostname)
# Line 541  main(int argc, char *argv[], char **envp Line 541  main(int argc, char *argv[], char **envp
541    
542    /* Set the jump, if we have an error parsing,    /* Set the jump, if we have an error parsing,
543       come here and start fresh.  */       come here and start fresh.  */
544    (void) setjmp (errcatch);    setjmp (errcatch);
545    
546    /* Roll.  */    /* Roll.  */
547    for (;;)    for (;;)
548      (void) yyparse ();      yyparse ();
549    /* NOTREACHED */    /* NOTREACHED */
550  }  }
551    
# Line 574  curdir (void) Line 574  curdir (void)
574    return (cred.guest ? path+1 : path);    return (cred.guest ? path+1 : path);
575  }  }
576    
577  static void  static RETSIGTYPE
578  sigquit (int signo)  sigquit (int signo)
579  {  {
580    syslog (LOG_ERR, "got signal %s", strsignal (signo));    syslog (LOG_ERR, "got signal %s", strsignal (signo));
# Line 582  sigquit (int signo) Line 582  sigquit (int signo)
582  }  }
583    
584    
585  static void  static RETSIGTYPE
586  lostconn (int signo)  lostconn (int signo ARG_UNUSED)
587  {  {
588    (void)signo;    signo;
589    if (debug)    if (debug)
590      syslog (LOG_DEBUG, "lost connection");      syslog (LOG_DEBUG, "lost connection");
591    dologout (-1);    dologout (-1);
# Line 624  complete_login (struct credentials *pcre Line 624  complete_login (struct credentials *pcre
624      }      }
625    
626  #ifdef HAVE_INITGROUPS  #ifdef HAVE_INITGROUPS
627    (void) initgroups (pcred->name, pcred->gid);    initgroups (pcred->name, pcred->gid);
628  #endif  #endif
629    
630    /* open wtmp before chroot */    /* open wtmp before chroot */
631    (void)snprintf (ttyline, sizeof (ttyline), "ftp%d", getpid ());    snprintf (ttyline, sizeof (ttyline), "ftp%d", getpid ());
632    logwtmp_keep_open (ttyline, pcred->name, pcred->remotehost);    logwtmp_keep_open (ttyline, pcred->name, pcred->remotehost);
633    
634    if (pcred->guest)    if (pcred->guest)
# Line 671  complete_login (struct credentials *pcre Line 671  complete_login (struct credentials *pcre
671    
672    /* Display a login message, if it exists.    /* Display a login message, if it exists.
673      N.B. reply(230,) must follow the message.  */      N.B. reply(230,) must follow the message.  */
674    (void) display_file (PATH_FTPLOGINMESG, 230);    display_file (PATH_FTPLOGINMESG, 230);
675    
676    if (pcred->guest)    if (pcred->guest)
677      {      {
# Line 697  complete_login (struct credentials *pcre Line 697  complete_login (struct credentials *pcre
697          syslog (LOG_INFO, "FTP LOGIN FROM %s as %s",          syslog (LOG_INFO, "FTP LOGIN FROM %s as %s",
698                  pcred->remotehost, pcred->name);                  pcred->remotehost, pcred->name);
699      }      }
700    (void) umask(defumask);    umask(defumask);
701    return;    return;
702  bad:  bad:
703    /* Forget all about it... */    /* Forget all about it... */
# Line 777  end_login (struct credentials *pcred) Line 777  end_login (struct credentials *pcred)
777  {  {
778    char *remotehost = pcred->remotehost;    char *remotehost = pcred->remotehost;
779    int atype = pcred->auth_type;    int atype = pcred->auth_type;
780    (void) seteuid ((uid_t)0);    seteuid ((uid_t)0);
781    if (pcred->logged_in)    if (pcred->logged_in)
782      logwtmp_keep_open (ttyline, "", "");      logwtmp_keep_open (ttyline, "", "");
783    
# Line 920  retrieve (const char *cmd, const char *n Line 920  retrieve (const char *cmd, const char *n
920    if (dout == NULL)    if (dout == NULL)
921      goto done;      goto done;
922    send_data (fin, dout, buffer_size);    send_data (fin, dout, buffer_size);
923    (void) fclose (dout);    fclose (dout);
924    data = -1;    data = -1;
925    pdata = -1;    pdata = -1;
926  done:  done:
# Line 999  store (const char *name, const char *mod Line 999  store (const char *name, const char *mod
999        else        else
1000          reply (226, "Transfer complete.");          reply (226, "Transfer complete.");
1001      }      }
1002    (void) fclose (din);    fclose (din);
1003    data = -1;    data = -1;
1004    pdata = -1;    pdata = -1;
1005   done:   done:
# Line 1014  getdatasock (const char *mode) Line 1014  getdatasock (const char *mode)
1014    
1015    if (data >= 0)    if (data >= 0)
1016      return fdopen (data, mode);      return fdopen (data, mode);
1017    (void) seteuid ((uid_t)0);    seteuid ((uid_t)0);
1018    s = socket (AF_INET, SOCK_STREAM, 0);    s = socket (AF_INET, SOCK_STREAM, 0);
1019    if (s < 0)    if (s < 0)
1020      goto bad;      goto bad;
# Line 1039  getdatasock (const char *mode) Line 1039  getdatasock (const char *mode)
1039          goto bad;          goto bad;
1040        sleep (tries);        sleep (tries);
1041      }      }
1042    (void) seteuid ((uid_t)cred.uid);    seteuid ((uid_t)cred.uid);
1043    
1044  #if defined (IP_TOS) && defined (IPTOS_THROUGHPUT) && defined (IPPROTO_IP)  #if defined (IP_TOS) && defined (IPTOS_THROUGHPUT) && defined (IPPROTO_IP)
1045    {    {
# Line 1053  getdatasock (const char *mode) Line 1053  getdatasock (const char *mode)
1053   bad:   bad:
1054    /* Return the real value of errno (close may change it) */    /* Return the real value of errno (close may change it) */
1055    t = errno;    t = errno;
1056    (void) seteuid ((uid_t)cred.uid);    seteuid ((uid_t)cred.uid);
1057    (void) close(s);    close(s);
1058    errno = t;    errno = t;
1059    return NULL;    return NULL;
1060  }  }
# Line 1069  dataconn (const char *name, off_t size, Line 1069  dataconn (const char *name, off_t size,
1069    file_size = size;    file_size = size;
1070    byte_count = 0;    byte_count = 0;
1071    if (size != (off_t) -1)    if (size != (off_t) -1)
1072      (void) snprintf(sizebuf, sizeof(sizebuf), " (%s bytes)",      snprintf(sizebuf, sizeof(sizebuf), " (%s bytes)",
1073                      off_to_str (size));                      off_to_str (size));
1074    else    else
1075      *sizebuf = '\0';      *sizebuf = '\0';
# Line 1078  dataconn (const char *name, off_t size, Line 1078  dataconn (const char *name, off_t size,
1078        struct sockaddr_in from;        struct sockaddr_in from;
1079        int s, fromlen = sizeof (from);        int s, fromlen = sizeof (from);
1080    
1081        (void) signal (SIGALRM, toolong);        signal (SIGALRM, toolong);
1082        (void) alarm ((unsigned) timeout);        alarm ((unsigned) timeout);
1083        s = accept (pdata, (struct sockaddr *)&from, &fromlen);        s = accept (pdata, (struct sockaddr *)&from, &fromlen);
1084        (void) alarm (0);        alarm (0);
1085        if (s < 0)        if (s < 0)
1086          {          {
1087            reply(425, "Can't open data connection.");            reply(425, "Can't open data connection.");
1088            (void) close (pdata);            close (pdata);
1089            pdata = -1;            pdata = -1;
1090            return NULL;            return NULL;
1091          }          }
1092        (void) close (pdata);        close (pdata);
1093        pdata = s;        pdata = s;
1094  #if defined (IP_TOS) && defined (IPTOS_THROUGHPUT) && defined (IPPROTO_IP)  #if defined (IP_TOS) && defined (IPTOS_THROUGHPUT) && defined (IPPROTO_IP)
1095        /* Optimize throughput.  */        /* Optimize throughput.  */
1096        {        {
1097          int tos = IPTOS_THROUGHPUT;          int tos = IPTOS_THROUGHPUT;
1098          (void) setsockopt (s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof (int));          setsockopt (s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof (int));
1099        }        }
1100  #endif  #endif
1101  #ifdef SO_KEEPALIVE  #ifdef SO_KEEPALIVE
1102        /* Set keepalives on the socket to detect dropped conns.  */        /* Set keepalives on the socket to detect dropped conns.  */
1103        {        {
1104          int keepalive = 1;          int keepalive = 1;
1105          (void) setsockopt (s, SOL_SOCKET, SO_KEEPALIVE,          setsockopt (s, SOL_SOCKET, SO_KEEPALIVE,
1106                             (char *)&keepalive, sizeof (int));                             (char *)&keepalive, sizeof (int));
1107        }        }
1108  #endif  #endif
# Line 1139  dataconn (const char *name, off_t size, Line 1139  dataconn (const char *name, off_t size,
1139            continue;            continue;
1140          }          }
1141        perror_reply (425, "Can't build data connection");        perror_reply (425, "Can't build data connection");
1142        (void) fclose (file);        fclose (file);
1143        data = -1;        data = -1;
1144        return NULL;        return NULL;
1145      }      }
# Line 1196  send_data (FILE *instr, FILE *outstr, of Line 1196  send_data (FILE *instr, FILE *outstr, of
1196                  {                  {
1197                    if (ferror (outstr))                    if (ferror (outstr))
1198                      break;                      break;
1199                    (void) putc ('\r', outstr);                    putc ('\r', outstr);
1200                  }                  }
1201                (void) putc (buf[len], outstr);                putc (buf[len], outstr);
1202                len++;                len++;
1203              }              }
1204            fflush (outstr);            fflush (outstr);
# Line 1217  send_data (FILE *instr, FILE *outstr, of Line 1217  send_data (FILE *instr, FILE *outstr, of
1217              {              {
1218                if (ferror (outstr))                if (ferror (outstr))
1219                  goto data_err;                  goto data_err;
1220                (void) putc ('\r', outstr);                putc ('\r', outstr);
1221              }              }
1222            (void) putc (c, outstr);            putc (c, outstr);
1223          }          }
1224        fflush (outstr);        fflush (outstr);
1225        transflag = 0;        transflag = 0;
# Line 1263  send_data (FILE *instr, FILE *outstr, of Line 1263  send_data (FILE *instr, FILE *outstr, of
1263               write(netfd, buf, cnt) == cnt)               write(netfd, buf, cnt) == cnt)
1264          byte_count += cnt;          byte_count += cnt;
1265        transflag = 0;        transflag = 0;
1266        (void)free (buf);        free (buf);
1267        if (cnt != 0)        if (cnt != 0)
1268          {          {
1269            if (cnt < 0)            if (cnt < 0)
# Line 1338  receive_data (FILE *instr, FILE *outstr) Line 1338  receive_data (FILE *instr, FILE *outstr)
1338                c = getc (instr);                c = getc (instr);
1339                if (c != '\n')                if (c != '\n')
1340                  {                  {
1341                    (void) putc ('\r', outstr);                    putc ('\r', outstr);
1342                    if (c == '\0' || c == EOF)                    if (c == '\0' || c == EOF)
1343                      goto contin2;                      goto contin2;
1344                  }                  }
1345              }              }
1346            (void) putc (c, outstr);            putc (c, outstr);
1347          contin2:        ;          contin2:        ;
1348          }          }
1349        fflush(outstr);        fflush(outstr);
# Line 1356  receive_data (FILE *instr, FILE *outstr) Line 1356  receive_data (FILE *instr, FILE *outstr)
1356          {          {
1357            lreply (226, "WARNING! %d bare linefeeds received in ASCII mode",            lreply (226, "WARNING! %d bare linefeeds received in ASCII mode",
1358                    bare_lfs);                    bare_lfs);
1359            (void)printf ("   File may not have transferred correctly.\r\n");            printf ("   File may not have transferred correctly.\r\n");
1360          }          }
1361        return (0);        return (0);
1362      default:      default:
# Line 1383  statfilecmd (const char *filename) Line 1383  statfilecmd (const char *filename)
1383    int c;    int c;
1384    char line[LINE_MAX];    char line[LINE_MAX];
1385    
1386    (void)snprintf (line, sizeof(line), "/bin/ls -lgA %s", filename);    snprintf (line, sizeof(line), "/bin/ls -lgA %s", filename);
1387    fin = ftpd_popen (line, "r");    fin = ftpd_popen (line, "r");
1388    lreply (211, "status of %s:", filename);    lreply (211, "status of %s:", filename);
1389    while ((c = getc (fin)) != EOF)    while ((c = getc (fin)) != EOF)
# Line 1393  statfilecmd (const char *filename) Line 1393  statfilecmd (const char *filename)
1393            if (ferror (stdout))            if (ferror (stdout))
1394              {              {
1395                perror_reply (421, "control connection");                perror_reply (421, "control connection");
1396                (void) ftpd_pclose (fin);                ftpd_pclose (fin);
1397                dologout (1);                dologout (1);
1398                                  /* NOTREACHED */                                  /* NOTREACHED */
1399              }              }
1400            if (ferror (fin))            if (ferror (fin))
1401              {              {
1402                perror_reply (551, filename);                perror_reply (551, filename);
1403                (void) ftpd_pclose (fin);                ftpd_pclose (fin);
1404                return;                return;
1405              }              }
1406            (void) putc ('\r', stdout);            putc ('\r', stdout);
1407          }          }
1408        (void) putc (c, stdout);        putc (c, stdout);
1409      }      }
1410    (void) ftpd_pclose (fin);    ftpd_pclose (fin);
1411    reply (211, "End of Status");    reply (211, "End of Status");
1412  }  }
1413    
# Line 1494  reply (int n, const char *fmt, ...) Line 1494  reply (int n, const char *fmt, ...)
1494  #else  #else
1495    va_start (ap);    va_start (ap);
1496  #endif  #endif
1497    (void)printf ("%d ", n);    printf ("%d ", n);
1498    (void)vprintf (fmt, ap);    vprintf (fmt, ap);
1499    (void)printf ("\r\n");    printf ("\r\n");
1500    (void)fflush (stdout);    fflush (stdout);
1501    if (debug)    if (debug)
1502      {      {
1503        syslog (LOG_DEBUG, "<--- %d ", n);        syslog (LOG_DEBUG, "<--- %d ", n);
# Line 1514  lreply (int n, const char *fmt, ...) Line 1514  lreply (int n, const char *fmt, ...)
1514  #else  #else
1515    va_start (ap);    va_start (ap);
1516  #endif  #endif
1517    (void)printf ("%d- ", n);    printf ("%d- ", n);
1518    (void)vprintf (fmt, ap);    vprintf (fmt, ap);
1519    (void)printf ("\r\n");    printf ("\r\n");
1520    (void)fflush (stdout);    fflush (stdout);
1521    if (debug)    if (debug)
1522      {      {
1523        syslog (LOG_DEBUG, "<--- %d- ", n);        syslog (LOG_DEBUG, "<--- %d- ", n);
# Line 1687  dologout (int status) Line 1687  dologout (int status)
1687    
1688    if (cred.logged_in)    if (cred.logged_in)
1689      {      {
1690        (void) seteuid ((uid_t)0);        seteuid ((uid_t)0);
1691        logwtmp_keep_open (ttyline, "", "");        logwtmp_keep_open (ttyline, "", "");
1692      }      }
1693    /* beware of flushing buffers after a SIGPIPE */    /* beware of flushing buffers after a SIGPIPE */
1694    _exit (status);    _exit (status);
1695  }  }
1696    
1697  static void  static RETSIGTYPE
1698  myoob (int signo)  myoob (int signo ARG_UNUSED)
1699  {  {
1700    char *cp;    char *cp;
1701    
   (void)signo;  
1702    /* only process if transfer occurring */    /* only process if transfer occurring */
1703    if (!transflag)    if (!transflag)
1704      return;      return;
# Line 1746  passive (void) Line 1745  passive (void)
1745      }      }
1746    pasv_addr = ctrl_addr;    pasv_addr = ctrl_addr;
1747    pasv_addr.sin_port = 0;    pasv_addr.sin_port = 0;
1748    (void) seteuid ((uid_t)0);    seteuid ((uid_t)0);
1749    if (bind (pdata, (struct sockaddr *)&pasv_addr, sizeof (pasv_addr)) < 0)    if (bind (pdata, (struct sockaddr *)&pasv_addr, sizeof (pasv_addr)) < 0)
1750      {      {
1751        (void) seteuid ((uid_t)cred.uid);        seteuid ((uid_t)cred.uid);
1752        goto pasv_error;        goto pasv_error;
1753      }      }
1754    (void) seteuid ((uid_t)cred.uid);    seteuid ((uid_t)cred.uid);
1755    len = sizeof(pasv_addr);    len = sizeof(pasv_addr);
1756    if (getsockname (pdata, (struct sockaddr *) &pasv_addr, &len) < 0)    if (getsockname (pdata, (struct sockaddr *) &pasv_addr, &len) < 0)
1757      goto pasv_error;      goto pasv_error;
# Line 1768  passive (void) Line 1767  passive (void)
1767    return;    return;
1768    
1769   pasv_error:   pasv_error:
1770    (void) close (pdata);    close (pdata);
1771    pdata = -1;    pdata = -1;
1772    perror_reply (425, "Can't open passive connection");    perror_reply (425, "Can't open passive connection");
1773    return;    return;
# Line 1807  gunique (const char *local) Line 1806  gunique (const char *local)
1806        *cp++ = '.';        *cp++ = '.';
1807        for (count = 1; count < 100; count++)        for (count = 1; count < 100; count++)
1808          {          {
1809            (void)sprintf (cp, "%d", count);            sprintf (cp, "%d", count);
1810            if (stat (string, &st) < 0)            if (stat (string, &st) < 0)
1811              return string;              return string;
1812          }          }
# Line 1901  send_file_list (const char *whichf) Line 1900  send_file_list (const char *whichf)
1900            perror_reply (550, whichf);            perror_reply (550, whichf);
1901            if (dout != NULL)            if (dout != NULL)
1902              {              {
1903                (void) fclose (dout);                fclose (dout);
1904                transflag = 0;                transflag = 0;
1905                data = -1;                data = -1;
1906                pdata = -1;                pdata = -1;
# Line 1963  send_file_list (const char *whichf) Line 1962  send_file_list (const char *whichf)
1962                byte_count += strlen (nbuf) + 1;                byte_count += strlen (nbuf) + 1;
1963              }              }
1964          }          }
1965        (void) closedir (dirp);        closedir (dirp);
1966      }      }
1967    
1968    if (dout == NULL)    if (dout == NULL)
# Line 1975  send_file_list (const char *whichf) Line 1974  send_file_list (const char *whichf)
1974    
1975    transflag = 0;    transflag = 0;
1976    if (dout != NULL)    if (dout != NULL)
1977      (void) fclose (dout);      fclose (dout);
1978    data = -1;    data = -1;
1979    pdata = -1;    pdata = -1;
1980   out:   out:

Legend:
Removed from v.1.53  
changed lines
  Added in v.1.54

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26