Fixes.
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@395 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
		| @@ -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" | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| #ifndef __MISSING_H__ | ||||
| #define __MISSING_H__ | ||||
| #ifndef __COMMON_H__ | ||||
| #define __COMMON_H__ | ||||
|  | ||||
| #ifdef HAVE_CONFIG_H | ||||
| #include <config.h> | ||||
| @@ -13,4 +13,4 @@ | ||||
|  | ||||
| #include "base64.h" | ||||
|  | ||||
| #endif /* __MISSING_H__ */ | ||||
| #endif /* __COMMON_H__ */ | ||||
|   | ||||
							
								
								
									
										149
									
								
								appl/ftp/common/getusershell.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								appl/ftp/common/getusershell.c
									
									
									
									
									
										Normal file
									
								
							| @@ -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 <config.h> | ||||
| #endif | ||||
|  | ||||
| RCSID("$Id$"); | ||||
|  | ||||
| #ifndef HAVE_GETUSERSHELL | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <paths.h> | ||||
| #include <sys/stat.h> | ||||
| #include <sys/param.h> | ||||
|  | ||||
| #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 */ | ||||
| @@ -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__ */ | ||||
|   | ||||
| @@ -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 <time.h> | ||||
| #include <utmp.h> | ||||
| ],[ | ||||
| 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 <errno.h> | ||||
| 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) | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -3,6 +3,8 @@ | ||||
|  | ||||
| extern int auth_complete; | ||||
|  | ||||
| void sec_status(void); | ||||
|  | ||||
| void sec_prot(int, char**); | ||||
|  | ||||
| void kauth(int, char **); | ||||
|   | ||||
| @@ -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) $< | ||||
|   | ||||
| @@ -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 <sys/types.h> | ||||
|  | ||||
| #include <sys/param.h> | ||||
| #include <sys/socket.h> | ||||
| #include <sys/stat.h> | ||||
| @@ -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,	"<sp> username" }, | ||||
| 	{ "PASS", PASS, ZSTR1, 1,	"<sp> 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); | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -4,6 +4,7 @@ | ||||
|  | ||||
|  | ||||
| #include <sys/time.h> | ||||
| #include <sys/types.h> | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| @@ -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)); | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
| #include <config.h> | ||||
| #endif | ||||
|  | ||||
| #include <sys/types.h> | ||||
| #include <sys/param.h> | ||||
| #include <netinet/in.h> | ||||
|  | ||||
|   | ||||
| @@ -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)) | ||||
|   | ||||
| @@ -50,6 +50,7 @@ static char rcsid[] = "$NetBSD: popen.c,v 1.5 1995/04/11 02:45:00 cgd Exp $"; | ||||
| #endif | ||||
|  | ||||
| #include <sys/types.h> | ||||
| #include <sys/time.h> | ||||
| #include <sys/wait.h> | ||||
|  | ||||
| #include <errno.h> | ||||
| @@ -60,6 +61,8 @@ static char rcsid[] = "$NetBSD: popen.c,v 1.5 1995/04/11 02:45:00 cgd Exp $"; | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
|  | ||||
| #include <sys/resource.h> | ||||
|  | ||||
| #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]); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Unknown User d91-jda
					Unknown User d91-jda