Don't open a new socket without closing a possibly already-open one. RT#5597. diff -uNr krb5/src/appl/gssftp/ftp/ftp.c krb5/src/appl/gssftp/ftp/ftp.c --- krb5/src/appl/gssftp/ftp/ftp.c +++ krb5/src/appl/gssftp/ftp/ftp.c @@ -196,7 +196,7 @@ char * hookup(char* host, int port) { register struct hostent *hp = 0; - int s; + int s, t; socklen_t len; #ifdef IP_TOS #ifdef IPTOS_LOWDELAY @@ -274,8 +274,13 @@ hookup(char* host, int port) } #endif #endif +#ifndef _WIN32 + t = dup(s); +#else + t = s; +#endif cin = FDOPEN_SOCKET(s, "r"); - cout = FDOPEN_SOCKET(s, "w"); + cout = FDOPEN_SOCKET(t, "w"); if (cin == NULL || cout == NULL) { fprintf(stderr, "ftp: fdopen failed.\n"); if (cin) { @@ -1448,6 +1453,8 @@ int a1,a2,a3,a4,p1,p2; if (passivemode) { + if (data != INVALID_SOCKET) + (void) closesocket(data); data = socket(AF_INET, SOCK_STREAM, 0); if (data == INVALID_SOCKET) { PERROR_SOCKET("ftp: socket"); @@ -2366,4 +2371,16 @@ FILE* fdopen_socket(SOCKET s, char* mode return f; } +#else +/* Non-Win32 case takes the address of the variable so that we can "take + * ownership" of the descriptor number. */ +FILE* fdopen_socket(int *s, char* mode) +{ + FILE *fp; + fp = fdopen(*s, mode); + if (fp) { + *s = INVALID_SOCKET; + } + return fp; +} #endif /* _WIN32 */ diff -up krb5-1.3.4/src/appl/gssftp/ftp/ftp_var.h krb5-1.3.4/src/appl/gssftp/ftp/ftp_var.h --- krb5-1.3.4/src/appl/gssftp/ftp/ftp_var.h 2007-08-03 00:53:35.000000000 -0400 +++ krb5-1.3.4/src/appl/gssftp/ftp/ftp_var.h 2007-08-03 00:53:39.000000000 -0400 @@ -48,7 +48,8 @@ FILE* fdopen_socket(SOCKET s, char* mode #define PERROR_SOCKET(str) do { errno = SOCKET_ERRNO; perror(str); } while(0) #else #define FCLOSE_SOCKET(f) fclose(f) -#define FDOPEN_SOCKET(s, mode) fdopen(s, mode) +FILE* fdopen_socket(int *s, char* mode); +#define FDOPEN_SOCKET(s, mode) fdopen_socket(&s, mode) #define SOCKETNO(fd) (fd) #define PERROR_SOCKET(str) perror(str) #endif