diff --git a/appl/ftp/acconfig.h b/appl/ftp/acconfig.h index 55b8dec30..9e5ebc6ec 100644 --- a/appl/ftp/acconfig.h +++ b/appl/ftp/acconfig.h @@ -3,11 +3,14 @@ @BOTTOM@ +#undef HAVE___PROGNAME +#undef HAVE_UT_HOST +#undef BROKEN_GETCWD + #ifdef __STDC__ -#define RCSID(msg) static const char *rcsid[] = { (char *)rcsid, "@(#)" msg } +#define RCSID(msg) static const char *rcsid[] = { (char *)rcsid, "\0100(#)" msg } #else #define RCSID(msg) static char *rcsid[] = { (char *)rcsid, msg } #endif #define WTMP_PATH "/var/adm/wtmp" - diff --git a/appl/ftp/common/Makefile.in b/appl/ftp/common/Makefile.in index 5d4e268fd..508a62ca6 100644 --- a/appl/ftp/common/Makefile.in +++ b/appl/ftp/common/Makefile.in @@ -28,13 +28,13 @@ all: libcommon.a libcommon.a: $(libcommon_OBJS) ar cr libcommon.a $(libcommon_OBJS) - ranlib libcommon.a + $(RANLIB) libcommon.a install: clean cleandir: - rm -f *~ *.o ftp core \#* + rm -f *~ *.o libcommon.a core \#* distclean: rm -f Makefile diff --git a/appl/ftp/common/common.h b/appl/ftp/common/common.h index 191471508..280e61b02 100644 --- a/appl/ftp/common/common.h +++ b/appl/ftp/common/common.h @@ -1,5 +1,5 @@ -#ifndef __MISSING_H__ -#define __MISSING_H__ +#ifndef __COMMON_H__ +#define __COMMON_H__ #ifdef HAVE_CONFIG_H #include @@ -13,4 +13,4 @@ #include "base64.h" -#endif /* __MISSING_H__ */ +#endif /* __COMMON_H__ */ diff --git a/appl/ftp/common/getusershell.c b/appl/ftp/common/getusershell.c new file mode 100644 index 000000000..ff696a03d --- /dev/null +++ b/appl/ftp/common/getusershell.c @@ -0,0 +1,149 @@ +/* $NetBSD: getusershell.c,v 1.5 1995/02/27 04:13:27 cgd Exp $ */ + +/* + * Copyright (c) 1985, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +RCSID("$Id$"); + +#ifndef HAVE_GETUSERSHELL + +#include +#include +#include +#include +#include + +#ifndef __P +#define __P(X) X +#endif + +#ifndef _PATH_SHELLS +#define _PATH_SHELLS "/etc/shells" +#endif + +/* + * Local shells should NOT be added here. They should be added in + * /etc/shells. + */ + +static char *okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL }; +static char **curshell, **shells, *strings; +static char **initshells __P((void)); + +/* + * Get a list of shells from _PATH_SHELLS, if it exists. + */ +char * +getusershell() +{ + char *ret; + + if (curshell == NULL) + curshell = initshells(); + ret = *curshell; + if (ret != NULL) + curshell++; + return (ret); +} + +void +endusershell() +{ + + if (shells != NULL) + free(shells); + shells = NULL; + if (strings != NULL) + free(strings); + strings = NULL; + curshell = NULL; +} + +void +setusershell() +{ + + curshell = initshells(); +} + +static char ** +initshells() +{ + register char **sp, *cp; + register FILE *fp; + struct stat statb; + + if (shells != NULL) + free(shells); + shells = NULL; + if (strings != NULL) + free(strings); + strings = NULL; + if ((fp = fopen(_PATH_SHELLS, "r")) == NULL) + return (okshells); + if (fstat(fileno(fp), &statb) == -1) { + (void)fclose(fp); + return (okshells); + } + if ((strings = malloc((u_int)statb.st_size)) == NULL) { + (void)fclose(fp); + return (okshells); + } + shells = calloc((unsigned)statb.st_size / 3, sizeof (char *)); + if (shells == NULL) { + (void)fclose(fp); + free(strings); + strings = NULL; + return (okshells); + } + sp = shells; + cp = strings; + while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) { + while (*cp != '#' && *cp != '/' && *cp != '\0') + cp++; + if (*cp == '#' || *cp == '\0') + continue; + *sp++ = cp; + while (!isspace(*cp) && *cp != '#' && *cp != '\0') + cp++; + *cp++ = '\0'; + } + *sp = NULL; + (void)fclose(fp); + return (shells); +} +#endif /* HAVE_GETUSERSHELL */ diff --git a/appl/ftp/common/vsyslog.h b/appl/ftp/common/vsyslog.h index 83fb89ee9..fb0a10502 100644 --- a/appl/ftp/common/vsyslog.h +++ b/appl/ftp/common/vsyslog.h @@ -1,8 +1,6 @@ #ifndef __VSYSLOG_H__ #define __VSYSLOG_H__ -#ifndef HAVE_VSYSLOG -void vsyslog(int pri, const char *fmt, ...); -#endif +void vsyslog(int pri, const char *fmt, va_list ap); #endif /* __VSYSLOG_H__ */ diff --git a/appl/ftp/configure.in b/appl/ftp/configure.in index 0dff23ea5..2c3175931 100644 --- a/appl/ftp/configure.in +++ b/appl/ftp/configure.in @@ -15,6 +15,8 @@ AC_PROG_CC AC_PROG_RANLIB AC_PROG_CPP +AC_C_CROSS + AC_SUBST(CFLAGS)dnl AC_SUBST(LDFLAGS)dnl @@ -22,9 +24,73 @@ AC_CHECK_HEADERS(sys/select.h paths.h) AC_CHECK_LIB(socket, socket) AC_CHECK_LIB(nsl, gethostbyname) +LDFLAGS="$LDFLAGS -L/usr/athena/lib" +AC_CHECK_LIB(des, des_encrypt) AC_CHECK_LIB(krb, krb_mk_req) +AC_CHECK_LIB(kafs, k_afsklog) -AC_REPLACE_FUNCS(errx hstrerror inet_aton krb_get_err_text memmove snprintf vsyslog verrx vwarn vwarnx warn warnx) +AC_MSG_CHECKING([for ut_host in utmp]) +AC_CACHE_VAL(ac_cv_struct_ut_host, [ +AC_TRY_COMPILE([ +#include +#include +],[ +char *p; +struct utmp ut; +p = ut.ut_host; +],ac_cv_struct_ut_host=yes,ac_cv_struct_ut_host=no) +]) +AC_MSG_RESULT($ac_cv_struct_ut_host) +if test "$ac_cv_struct_ut_host" = "yes"; then + AC_DEFINE(HAVE_UT_HOST, 1) +fi + + +AC_CHECK_FUNCS(getcwd setproctitle getdtablesize) + +if test "$ac_cv_func_getcwd" = yes; then +AC_MSG_CHECKING(for broken getcwd) +AC_CACHE_VAL(ac_cv_func_getcwd_broken, [ +ac_cv_func_getcwd_broken=no + +AC_TRY_RUN([ +#include +char *getcwd(char*, int); + +void *popen(char *cmd, char *mode) +{ + errno = ENOTTY; + return 0; +} + +int main() +{ + char *ret; + ret = getcwd(0, 1024); + if(ret == 0 && errno == ENOTTY) + return 0; + return 1; +} +], ac_cv_func_getcwd_broken=yes,:,:) +]) +AC_MSG_RESULT($ac_cv_func_getcwd_broken) +if test "$ac_cv_func_getcwd_broken" = yes; then + AC_DEFINE(BROKEN_GETCWD, 1) +fi +fi + + +AC_REPLACE_FUNCS(errx hstrerror inet_aton getusershell krb_get_err_text memmove snprintf vsyslog verrx vwarn vwarnx warn warnx) + + +AC_MSG_CHECKING([for __progname]) +AC_CACHE_VAL(ac_cv_var___progname, [ +AC_TRY_LINK([extern char *__progname;], [return strlen(__progname);], ac_cv_var___progname=yes, ac_cv_var___progname=no) +]) +AC_MSG_RESULT($ac_cv_var___progname) +if test "$ac_cv_var___progname" = "yes"; then + AC_DEFINE(HAVE___PROGNAME, 1) +fi AC_OUTPUT(Makefile common/Makefile ftp/Makefile ftpd/Makefile) \ No newline at end of file diff --git a/appl/ftp/ftp/Makefile.in b/appl/ftp/ftp/Makefile.in index f37135f71..6c4c8996d 100644 --- a/appl/ftp/ftp/Makefile.in +++ b/appl/ftp/ftp/Makefile.in @@ -34,7 +34,7 @@ ftp: $(ftp_OBJS) ../common/libcommon.a $(CC) -o ftp $(ftp_OBJS) ../common/libcommon.a -L$(ATHENA)/lib -lkrb -ldes $(LIBS) clean cleandir: - rm -f *~ *.o core ftpd ftpcmd.c \#* + rm -f *~ *.o core ftp \#* distclean: rm -f Makefile diff --git a/appl/ftp/ftp/cmds.c b/appl/ftp/ftp/cmds.c index d3384f693..cf76c5a79 100644 --- a/appl/ftp/ftp/cmds.c +++ b/appl/ftp/ftp/cmds.c @@ -803,6 +803,7 @@ status(int argc, char **argv) } pswitch(0); } + sec_status(); printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n", modename, typename, formname, structname); printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n", @@ -1003,7 +1004,7 @@ lcd(int argc, char **argv) code = -1; return; } - if (getwd(buf) != NULL) + if (getcwd(buf, sizeof(buf)) != NULL) printf("Local directory now %s\n", buf); else warnx("getwd: %s", buf); diff --git a/appl/ftp/ftp/ftp.c b/appl/ftp/ftp/ftp.c index b738ca474..8af0b5d60 100644 --- a/appl/ftp/ftp/ftp.c +++ b/appl/ftp/ftp/ftp.c @@ -165,6 +165,12 @@ login(char *host) int n, aflag = 0; user = pass = acct = 0; + + if(do_klogin(host)) + printf("\n*** Using plaintext user and password ***\n\n"); + else + printf("Kerberos login successful.\n\n"); + if (ruserpass(host, &user, &pass, &acct) < 0) { code = -1; return (0); @@ -189,10 +195,6 @@ login(char *host) else user = tmp; } - if(strcmp(user, "ftp") && strcmp(user, "anonymous")){ - if(do_klogin(host) < 0) - fprintf(stderr, "Resorting to plaintext user and password.\n"); - } strcpy(username, user); n = command("USER %s", user); if (n == CONTINUE) { @@ -284,6 +286,7 @@ int getreply(int expecteof) { char *p; + char *lead_string; int c; struct sigaction sa, osa; char buf[1024]; @@ -326,16 +329,19 @@ getreply(int expecteof) if(code == 631){ krb4_read_mic(buf); sscanf(buf, "%d", &code); - fprintf(stdout, "S:"); + lead_string = "S:"; } else if(code == 632){ krb4_read_enc(buf); sscanf(buf, "%d", &code); - fprintf(stdout, "P:"); + lead_string = "P:"; }else if(code == 633){ - fprintf(stdout, "Confidentiality is meaningless:\n"); + printf("Received confidential reply!\n"); }else if(auth_complete) - fprintf(stdout, "!!"); /* clear text */ - fprintf(stdout, "%s\n", buf); + lead_string = "!!"; + else + lead_string = ""; + if(verbose > 0 || (verbose > -1 && code > 499)) + fprintf(stdout, "%s%s\n", lead_string, buf); if(buf[3] == ' '){ strcpy(reply_string, buf); if (code < 200) @@ -1095,7 +1101,7 @@ initconn(void) goto bad; } - bzero((char*)&data_addr, sizeof(data_addr)); + memset(&data_addr, 0, sizeof(data_addr)); data_addr.sin_family = AF_INET; a = (char *)&data_addr.sin_addr.s_addr; a[0] = a0 & 0xff; diff --git a/appl/ftp/ftp/kauth.c b/appl/ftp/ftp/kauth.c index adfc69b40..e1fd8bc7d 100644 --- a/appl/ftp/ftp/kauth.c +++ b/appl/ftp/ftp/kauth.c @@ -58,7 +58,7 @@ void kauth(int argc, char **argv) sprintf(buf, "Password for %s:", name); des_read_password(&key, buf, 0); - des_set_key(&key, schedule); + des_key_sched(&key, schedule); des_pcbc_encrypt((des_cblock*)tkt.dat, (des_cblock*)tkt.dat, tkt.length, schedule, &key, DES_DECRYPT); diff --git a/appl/ftp/ftp/krb4.c b/appl/ftp/ftp/krb4.c index fe5b398d8..73da334e0 100644 --- a/appl/ftp/ftp/krb4.c +++ b/appl/ftp/ftp/krb4.c @@ -22,6 +22,54 @@ static int command_prot; static int auth_pbsz; static int data_prot; + +static struct { + int level; + char *name; +} level_names[] = { + { prot_clear, "clear" }, + { prot_safe, "safe" }, + { prot_confidential, "confidential" }, + { prot_private, "private" } +}; + +static char *level_to_name(int level) +{ + int i; + for(i = 0; i < sizeof(level_names) / sizeof(level_names[0]); i++) + if(level_names[i].level == level) + return level_names[i].name; + return "unknown"; +} + +static int name_to_level(char *name) +{ + int i; + for(i = 0; i < sizeof(level_names) / sizeof(level_names[0]); i++) + if(!strncasecmp(level_names[i].name, name, strlen(name))) + return level_names[i].level; + return -1; +} + +void sec_status(void) +{ + if(auth_complete){ + printf("Using KERBEROS_V4 for authentication.\n"); + + command_prot = prot_private; /* this variable is not used */ + + printf("Using %s command channel.\n", + level_to_name(command_prot)); + + printf("Using %s data channel.\n", + level_to_name(data_prot)); + if(auth_pbsz > 0) + printf("Protection buffer size: %d.\n", auth_pbsz); + }else{ + printf("Not using any security mechanism.\n"); + } +} + void sec_prot(int argc, char **argv) { int s; @@ -38,15 +86,14 @@ void sec_prot(int argc, char **argv) code = -1; return; } - if(!strcmp(argv[1], "clear")) - level = prot_clear; + level = name_to_level(argv[1]); - if(!strcmp(argv[1], "safe")) - level = prot_safe; + if(level == prot_confidential){ + printf("Confidential protection is not defined for Kerberos.\n"); + code = -1; + return; + } - if(!strcmp(argv[1], "private")) - level = prot_private; - if(level == -1){ fprintf(stderr, "ehu?\n"); code = -1; @@ -232,7 +279,7 @@ int sec_fflush(FILE *F) { if(data_prot){ - if(index){ + if(p_index){ sec_write(fileno(F), p_buf, p_index); p_index = 0; } @@ -299,6 +346,10 @@ do_klogin(char *host) int checksum; int tmp; + int old_verbose = verbose; + + verbose = 0; + printf("Trying KERBEROS_V4...\n"); ret = command("AUTH KERBEROS_V4"); if(ret != CONTINUE){ if(code == 504){ @@ -308,6 +359,7 @@ do_klogin(char *host) }else if(ret == ERROR) fprintf(stderr, "The server doesn't understand the FTP " "security extentions.\n"); + verbose = old_verbose; return -1; } @@ -317,6 +369,7 @@ do_klogin(char *host) ret = do_auth("rcmd", host, checksum); if(ret){ fprintf(stderr, "%s\n", krb_get_err_text(ret)); + verbose = old_verbose; return ret; } @@ -326,18 +379,21 @@ do_klogin(char *host) if(ret != COMPLETE){ fprintf(stderr, "Server didn't accept auth data."); + verbose = old_verbose; return -1; } p = strstr(reply_string, "ADAT="); if(!p){ fprintf(stderr, "Remote host didn't send adat reply."); + verbose = old_verbose; return -1; } p+=5; len = base64_decode(p, adat); if(len < 0){ fprintf(stderr, "Failed to decode base64 from server."); + verbose = old_verbose; return -1; } ret = krb_rd_safe(adat, len, &key, @@ -345,15 +401,18 @@ do_klogin(char *host) if(ret){ fprintf(stderr, "Error reading reply from server: %s.", krb_get_err_text(ret)); + verbose = old_verbose; return -1; } memmove(&tmp, msg_data.app_data, 4); tmp = ntohl(tmp); if(tmp - checksum != 1){ fprintf(stderr, "Bad checksum returned from server."); + verbose = old_verbose; return -1; } auth_complete = 1; + verbose = old_verbose; return 0; } diff --git a/appl/ftp/ftp/krb4.h b/appl/ftp/ftp/krb4.h index a49fb6b2f..bd6fcfb2b 100644 --- a/appl/ftp/ftp/krb4.h +++ b/appl/ftp/ftp/krb4.h @@ -3,6 +3,8 @@ extern int auth_complete; +void sec_status(void); + void sec_prot(int, char**); void kauth(int, char **); diff --git a/appl/ftp/ftpd/Makefile.in b/appl/ftp/ftpd/Makefile.in index 3ba061622..6ee7135e0 100644 --- a/appl/ftp/ftpd/Makefile.in +++ b/appl/ftp/ftpd/Makefile.in @@ -17,7 +17,10 @@ prefix = @prefix@ exec_prefix = $(prefix) libdir = $(exec_prefix)/lib -ATHENA = /usr/athena +ATHENA = /usr/athena + +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ ftpd_OBJS = ftpd.o ftpcmd.o logwtmp.o popen.o auth.o krb4.o kauth.o @@ -30,7 +33,7 @@ install: ftpd: $(ftpd_OBJS) ../common/libcommon.a - $(CC) -o ftpd $(ftpd_OBJS) ../common/libcommon.a -L$(ATHENA)/lib -lkafs -lkrb -ldes + $(CC) -o ftpd $(ftpd_OBJS) ../common/libcommon.a $(LDFLAGS) $(LIBS) ftpcmd.c: ftpcmd.y $(YACC) $(YFLAGS) $< diff --git a/appl/ftp/ftpd/ftpcmd.y b/appl/ftp/ftpd/ftpcmd.y index 8c4dc9767..924fe9c7e 100644 --- a/appl/ftp/ftpd/ftpcmd.y +++ b/appl/ftp/ftpd/ftpcmd.y @@ -50,6 +50,8 @@ static char rcsid[] = "$NetBSD: ftpcmd.y,v 1.6 1995/06/03 22:46:45 mycroft Exp $ #endif #endif /* not lint */ +#include + #include #include #include @@ -81,6 +83,25 @@ static int cmd_bytesz; char cbuf[512]; char *fromname; +struct tab { + char *name; + short token; + short state; + short implemented; /* 1 if command is implemented */ + char *help; +}; + +extern struct tab cmdtab[]; +extern struct tab sitetab[]; + +static char *copy __P((char *)); +static void help __P((struct tab *, char *)); +static struct tab * + lookup __P((struct tab *, char *)); +static void sizecmd __P((char *)); +static void toolong __P((int)); +static int yylex __P((void)); + %} %union { @@ -800,14 +821,6 @@ extern jmp_buf errcatch; #define SITECMD 7 /* SITE command */ #define NSTR 8 /* Number followed by a string */ -struct tab { - char *name; - short token; - short state; - short implemented; /* 1 if command is implemented */ - char *help; -}; - struct tab cmdtab[] = { /* In order defined in RFC 765 */ { "USER", USER, STR1, 1, " username" }, { "PASS", PASS, ZSTR1, 1, " password" }, @@ -881,14 +894,6 @@ struct tab sitetab[] = { { NULL, 0, 0, 0, 0 } }; -static char *copy __P((char *)); -static void help __P((struct tab *, char *)); -static struct tab * - lookup __P((struct tab *, char *)); -static void sizecmd __P((char *)); -static void toolong __P((int)); -static int yylex __P((void)); - static struct tab * lookup(struct tab *p, char *cmd) { @@ -916,7 +921,7 @@ getline(char *s, int n) strncpy(s, ftp_command, n); if (debug) syslog(LOG_DEBUG, "command: %s", s); -#if 0 +#ifdef XXX fprintf(stderr, "%s\n", s); #endif return s; @@ -972,7 +977,7 @@ getline(char *s, int n) syslog(LOG_DEBUG, "command: %.*s", len, s); } } -#if 0 +#ifdef XXX fprintf(stderr, "%s\n", s); #endif return (s); diff --git a/appl/ftp/ftpd/ftpd.c b/appl/ftp/ftpd/ftpd.c index f9dfcc90c..1906c2376 100644 --- a/appl/ftp/ftpd/ftpd.c +++ b/appl/ftp/ftpd/ftpd.c @@ -147,19 +147,16 @@ int notickets = 1; char *krbtkfile_env = NULL; #endif -char *getusershell(void); -int endusershell(void); -int setusershell(void); - #ifdef sun extern char *optarg; extern int optind, opterr; int fclose(FILE*); char* crypt(char*, char*); -char* getwd(char*); #endif +char *getusershell(void); + /* * Timeout intervals for retrying connections * to hosts that don't accept PORT cmds. This @@ -171,9 +168,9 @@ char* getwd(char*); int swaitmax = SWAITMAX; int swaitint = SWAITINT; -#ifdef HASSETPROCTITLE +#ifdef HAVE_SETPROCTITLE char proctitle[BUFSIZ]; /* initial part of title */ -#endif /* HASSETPROCTITLE */ +#endif /* HAVE_SETPROCTITLE */ #define LOGCMD(cmd, file) \ if (logging > 1) \ @@ -224,7 +221,7 @@ curdir(void) #define LINE_MAX 1024 #endif -static void conn_wait(void) +static void conn_wait(int port) { int s, t; struct sockaddr_in sa; @@ -233,7 +230,7 @@ static void conn_wait(void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); memset(&sa, 0, sizeof(sa)); - sa.sin_port = htons(21); + sa.sin_port = port; /* in network byteorder */ sa.sin_addr.s_addr = INADDR_ANY; bind(s, (struct sockaddr*)&sa, sizeof(sa)); listen(s, 5); @@ -258,52 +255,49 @@ main(int argc, char **argv, char **envp) char *cp, line[LINE_MAX]; FILE *fd; + int not_inetd = 0; + int port; + struct servent *sp; + char tkfile[1024]; -#if 0 - conn_wait(); -#endif + /* detach from and tickets and tokens */ sprintf(tkfile, "/tmp/ftp_%d", getpid()); - setenv("KRBTKFILE", tkfile); + krb_set_tkt_string(tkfile); if(k_hasafs()) k_setpag(); - /* - * LOG_NDELAY sets up the logging connection immediately, - * necessary for anonymous ftp's that chroot and can't do it later. - */ - openlog("ftpd", LOG_PID | LOG_NDELAY, LOG_FTP); - addrlen = sizeof(his_addr); - if (getpeername(0, (struct sockaddr *)&his_addr, &addrlen) < 0) { - syslog(LOG_ERR, "getpeername (%s): %m",argv[0]); - exit(1); - } - addrlen = sizeof(ctrl_addr); - if (getsockname(0, (struct sockaddr *)&ctrl_addr, &addrlen) < 0) { - syslog(LOG_ERR, "getsockname (%s): %m",argv[0]); - exit(1); - } -#ifdef IP_TOS - tos = IPTOS_LOWDELAY; - if (setsockopt(0, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0) - syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); -#endif - data_source.sin_port = htons(ntohs(ctrl_addr.sin_port) - 1); - debug = 0; - /* set this here so klogin can use it... */ - (void)sprintf(ttyline, "ftp%d", getpid()); + sp = getservbyname("ftp", "tcp"); + if(sp) + port = sp->s_port; + else + port = htons(21); - while ((ch = getopt(argc, argv, "dlt:T:u:v")) != EOF) { + while ((ch = getopt(argc, argv, "dilp:t:T:u:v")) != EOF) { switch (ch) { case 'd': debug = 1; break; + case 'i': + not_inetd = 1; + break; case 'l': logging++; /* > 1 == extra logging */ break; + case 'p': + sp = getservbyname(optarg, "tcp"); + if(sp) + port = sp->s_port; + else + if(isdigit(optarg[0])) + port = htons(atoi(optarg)); + else + warnx("bad value for -p"); + break; + case 't': timeout = atoi(optarg); if (maxtimeout < timeout) @@ -337,6 +331,38 @@ main(int argc, char **argv, char **envp) break; } } + + if(not_inetd) + conn_wait(port); + + + /* + * LOG_NDELAY sets up the logging connection immediately, + * necessary for anonymous ftp's that chroot and can't do it later. + */ + openlog("ftpd", LOG_PID | LOG_NDELAY, LOG_FTP); + addrlen = sizeof(his_addr); + if (getpeername(0, (struct sockaddr *)&his_addr, &addrlen) < 0) { + syslog(LOG_ERR, "getpeername (%s): %m",argv[0]); + exit(1); + } + addrlen = sizeof(ctrl_addr); + if (getsockname(0, (struct sockaddr *)&ctrl_addr, &addrlen) < 0) { + syslog(LOG_ERR, "getsockname (%s): %m",argv[0]); + exit(1); + } +#ifdef IP_TOS + tos = IPTOS_LOWDELAY; + if (setsockopt(0, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0) + syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); +#endif + data_source.sin_port = htons(ntohs(ctrl_addr.sin_port) - 1); + debug = 0; + + /* set this here so klogin can use it... */ + (void)sprintf(ttyline, "ftp%d", getpid()); + + /* (void) freopen(_PATH_DEVNULL, "w", stderr); */ (void) signal(SIGPIPE, lostconn); (void) signal(SIGCHLD, SIG_IGN); @@ -625,23 +651,23 @@ int do_login(int code, char *passwd) } if (guest) { reply(code, "Guest login ok, access restrictions apply."); -#ifdef HASSETPROCTITLE +#ifdef HAVE_SETPROCTITLE snprintf(proctitle, sizeof(proctitle), "%s: anonymous/%.*s", remotehost, sizeof(proctitle) - sizeof(remotehost) - sizeof(": anonymous/"), passwd); setproctitle(proctitle); -#endif /* HASSETPROCTITLE */ +#endif /* HAVE_SETPROCTITLE */ if (logging) syslog(LOG_INFO, "ANONYMOUS FTP LOGIN FROM %s, %s", remotehost, passwd); } else { reply(code, "User %s logged in.", pw->pw_name); -#ifdef HASSETPROCTITLE +#ifdef HAVE_SETPROCTITLE snprintf(proctitle, sizeof(proctitle), "%s: %s", remotehost, pw->pw_name); setproctitle(proctitle); -#endif /* HASSETPROCTITLE */ +#endif /* HAVE_SETPROCTITLE */ if (logging) syslog(LOG_INFO, "FTP LOGIN FROM %s as %s", remotehost, pw->pw_name); @@ -1378,12 +1404,21 @@ removedir(char *name) void pwd(void) { - char path[MAXPATHLEN + 1]; + char path[MAXPATHLEN + 1]; + char *ret; - if (getwd(path) == (char *)NULL) - reply(550, "%s.", path); - else - reply(257, "\"%s\" is current directory.", path); + /* SunOS has a broken getcwd that does popen(pwd) (!!!), this + * failes miserably when running chroot + */ +#if defined(HAVE_GETCWD) && !defined(BROKEN_GETCWD) + ret = getcwd(path, sizeof(path)); +#else + ret = getwd(path); +#endif + if (ret == NULL) + reply(550, "%s.", strerror(errno)); + else + reply(257, "\"%s\" is current directory.", path); } char * @@ -1421,10 +1456,10 @@ dolog(struct sockaddr_in *sin) else (void) strncpy(remotehost, inet_ntoa(sin->sin_addr), sizeof(remotehost)); -#ifdef HASSETPROCTITLE +#ifdef HAVE_SETPROCTITLE snprintf(proctitle, sizeof(proctitle), "%s: connected", remotehost); setproctitle(proctitle); -#endif /* HASSETPROCTITLE */ +#endif /* HAVE_SETPROCTITLE */ if (logging) syslog(LOG_INFO, "connection from %s", remotehost); @@ -1664,10 +1699,9 @@ send_file_list(char *whichf) while ((dir = readdir(dirp)) != NULL) { char nbuf[MAXPATHLEN]; - if (dir->d_name[0] == '.' && dir->d_namlen == 1) + if (!strcmp(dir->d_name, ".")) continue; - if (dir->d_name[0] == '.' && dir->d_name[1] == '.' && - dir->d_namlen == 2) + if (!strcmp(dir->d_name, "..")) continue; sprintf(nbuf, "%s/%s", dirname, dir->d_name); diff --git a/appl/ftp/ftpd/kauth.c b/appl/ftp/ftpd/kauth.c index 6e07d6f28..b1e148a47 100644 --- a/appl/ftp/ftpd/kauth.c +++ b/appl/ftp/ftpd/kauth.c @@ -4,6 +4,7 @@ #include +#include #include #include @@ -25,7 +26,7 @@ static char name[ANAME_SZ], inst[INST_SZ], realm[REALM_SZ]; static int save_tkt(char *user, char *instance, char *realm, void *arg, - key_proc_t key_proc, KTEXT *cipp) + int (*key_proc)(char*, char*, char*, void*, des_cblock*), KTEXT *cipp) { local_time = time(0); memmove(&cip, *cipp, sizeof(cip)); diff --git a/appl/ftp/ftpd/krb4.c b/appl/ftp/ftpd/krb4.c index a49d97ae7..c001c1744 100644 --- a/appl/ftp/ftpd/krb4.c +++ b/appl/ftp/ftpd/krb4.c @@ -2,6 +2,7 @@ #include #endif +#include #include #include diff --git a/appl/ftp/ftpd/logwtmp.c b/appl/ftp/ftpd/logwtmp.c index b0a35d5bc..21b492f71 100644 --- a/appl/ftp/ftpd/logwtmp.c +++ b/appl/ftp/ftpd/logwtmp.c @@ -75,7 +75,9 @@ logwtmp(char *line, char *name, char *host) if (fstat(fd, &buf) == 0) { (void)strncpy(ut.ut_line, line, sizeof(ut.ut_line)); (void)strncpy(ut.ut_name, name, sizeof(ut.ut_name)); +#ifdef HAVE_UT_HOST (void)strncpy(ut.ut_host, host, sizeof(ut.ut_host)); +#endif (void)time(&ut.ut_time); if (write(fd, (char *)&ut, sizeof(struct utmp)) != sizeof(struct utmp)) diff --git a/appl/ftp/ftpd/popen.c b/appl/ftp/ftpd/popen.c index d9302774c..84dd1741c 100644 --- a/appl/ftp/ftpd/popen.c +++ b/appl/ftp/ftpd/popen.c @@ -50,6 +50,7 @@ static char rcsid[] = "$NetBSD: popen.c,v 1.5 1995/04/11 02:45:00 cgd Exp $"; #endif #include +#include #include #include @@ -60,6 +61,8 @@ static char rcsid[] = "$NetBSD: popen.c,v 1.5 1995/04/11 02:45:00 cgd Exp $"; #include #include +#include + #include "extern.h" /* @@ -82,11 +85,30 @@ ftpd_popen(char *program, char *type) return (NULL); if (!pids) { - if ((fds = getdtablesize()) <= 0) - return (NULL); - if ((pids = (int *)malloc((u_int)(fds * sizeof(int)))) == NULL) - return (NULL); - memset(pids, 0, fds * sizeof(int)); + + /* This is really ugly. One would have hoped that + * getdtablesize would be dead and buried, and that + * getrlimit would be available everywhere. However, in + * AIX getrlimit is available, but there is no + * RLIMIT_NOFILE to be found. So we have to use + * getdtablesize if it is available. + * + * (and besides this function is ugly and should be + * rewritten, in modern unices there is no such thing as a + * maximum filedescriptor) + */ + +#ifdef HAVE_GETDTABLESIZE + fds = getdtablesize(); +#else + struct rlimit r; + if(getrlimit(RLIMIT_NOFILE, &r) < 0) + return NULL; + fds = r.rlim_cur; +#endif + pids = (int*)calloc(fds, sizeof(int)); + if(!pids) + return NULL; } if (pipe(pdes) < 0) return (NULL); @@ -113,7 +135,7 @@ ftpd_popen(char *program, char *type) gargv[gargc] = NULL; iop = NULL; - switch(pid = vfork()) { + switch(pid = fork()) { case -1: /* error */ (void)close(pdes[0]); (void)close(pdes[1]);