Index: common-src/stream.c =================================================================== RCS file: /cvsroot/amanda/amanda/common-src/stream.c,v retrieving revision 1.10.2.8 diff -u -r1.10.2.8 stream.c --- common-src/stream.c 2001/06/18 22:23:19 1.10.2.8 +++ common-src/stream.c 2001/07/30 19:13:19 @@ -143,9 +143,10 @@ return server_socket; } -int stream_client(hostname, port, sendsize, recvsize, localport) -char *hostname; -int port, sendsize, recvsize, *localport; +static int +stream_client_internal(hostname, port, sendsize, recvsize, localport, priv) + char *hostname; + int port, sendsize, recvsize, *localport, priv; { int client_socket, len; #ifdef SO_KEEPALIVE @@ -155,11 +156,15 @@ struct sockaddr_in svaddr, claddr; struct hostent *hostp; int save_errno; + char *f; + f = priv ? "stream_client_privileged" : "stream_client"; + if((hostp = gethostbyname(hostname)) == NULL) { save_errno = errno; - dbprintf(("%s: stream_client: gethostbyname(%s) failed\n", + dbprintf(("%s: %s: gethostbyname(%s) failed\n", get_pname(), + f, hostname)); errno = save_errno; return -1; @@ -172,8 +177,9 @@ if((client_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) { save_errno = errno; - dbprintf(("%s: stream_client: socket() failed: %s\n", + dbprintf(("%s: %s: socket() failed: %s\n", get_pname(), + f, strerror(save_errno))); errno = save_errno; return -1; @@ -189,8 +195,9 @@ (void *)&on, sizeof(on)); if(r == -1) { save_errno = errno; - dbprintf(("%s: stream_client: setsockopt() failed: %s\n", + dbprintf(("%s: %s: setsockopt() failed: %s\n", get_pname(), + f, strerror(save_errno))); aclose(client_socket); errno = save_errno; @@ -203,27 +210,43 @@ claddr.sin_addr.s_addr = INADDR_ANY; /* - * If a port range was specified, we try to get a port in that - * range first. Next, we try to get a reserved port. If that - * fails, we just go for any port. + * If a privileged port range was requested, we try to get a port in + * that range first and fail if it is not available. Next, we try + * to get a port in the range built in when Amanda was configured. + * If that fails, we just go for any port. * * It is up to the caller to make sure we have the proper permissions * to get the desired port, and to make sure we return a port that * is within the range it requires. */ + if (priv) { + int b; + + b = bind_portrange(client_socket, &claddr, 512, IPPORT_RESERVED - 1); + if (b == 0) { + goto out; /* got what we wanted */ + } + save_errno = errno; + dbprintf(("%s: %s: bind(IPPORT_RESERVED) failed: %s\n", + get_pname(), + f, + strerror(save_errno))); + aclose(client_socket); + errno = save_errno; + return -1; + } + #ifdef PORTRANGE if (bind_portrange(client_socket, &claddr, PORTRANGE) == 0) goto out; #endif - if (bind_portrange(client_socket, &claddr, 512, IPPORT_RESERVED - 1) == 0) - goto out; - claddr.sin_port = INADDR_ANY; if (bind(client_socket, (struct sockaddr *)&claddr, sizeof(claddr)) == -1) { save_errno = errno; - dbprintf(("%s: stream_client: bind(INADDR_ANY) failed: %s\n", + dbprintf(("%s: %s: bind(INADDR_ANY) failed: %s\n", get_pname(), + f, strerror(save_errno))); aclose(client_socket); errno = save_errno; @@ -237,8 +260,9 @@ len = sizeof(claddr); if(getsockname(client_socket, (struct sockaddr *)&claddr, &len) == -1) { save_errno = errno; - dbprintf(("%s: stream_client: getsockname() failed: %s\n", + dbprintf(("%s: %s: getsockname() failed: %s\n", get_pname(), + f, strerror(save_errno))); aclose(client_socket); errno = save_errno; @@ -248,8 +272,9 @@ if(connect(client_socket, (struct sockaddr *)&svaddr, sizeof(svaddr)) == -1) { save_errno = errno; - dbprintf(("%s: stream_client: connect(%d) failed: %s\n", + dbprintf(("%s: %s: connect(%d) failed: %s\n", get_pname(), + f, port, strerror(save_errno))); aclose(client_socket); @@ -257,12 +282,14 @@ return -1; } - dbprintf(("%s: stream_client: connected to %s.%d\n", + dbprintf(("%s: %s: connected to %s.%d\n", get_pname(), + f, inet_ntoa(svaddr.sin_addr), ntohs(svaddr.sin_port))); - dbprintf(("%s: stream_client: our side is %s.%d\n", + dbprintf(("%s: %s: our side is %s.%d\n", get_pname(), + f, inet_ntoa(claddr.sin_addr), ntohs(claddr.sin_port))); @@ -275,6 +302,32 @@ *localport = ntohs(claddr.sin_port); return client_socket; +} + +int +stream_client_privileged(hostname, port, sendsize, recvsize, localport) + char *hostname; + int port, sendsize, recvsize, *localport; +{ + return stream_client_internal(hostname, + port, + sendsize, + recvsize, + localport, + 1); +} + +int +stream_client(hostname, port, sendsize, recvsize, localport) + char *hostname; + int port, sendsize, recvsize, *localport; +{ + return stream_client_internal(hostname, + port, + sendsize, + recvsize, + localport, + 0); } /* don't care about these values */ Index: common-src/stream.h =================================================================== RCS file: /cvsroot/amanda/amanda/common-src/stream.h,v retrieving revision 1.4.2.2 diff -u -r1.4.2.2 stream.h --- common-src/stream.h 2001/02/28 02:11:22 1.4.2.2 +++ common-src/stream.h 2001/07/30 19:13:19 @@ -43,7 +43,15 @@ int stream_server P((int *port, int sendsize, int recvsize)); int stream_accept P((int sock, int timeout, int sendsize, int recvsize)); -int stream_client P((char *hostname, int port, int sendsize, int recvsize, - int *localport)); +int stream_client_privileged P((char *hostname, + int port, + int sendsize, + int recvsize, + int *localport)); +int stream_client P((char *hostname, + int port, + int sendsize, + int recvsize, + int *localport)); #endif Index: recover-src/amrecover.c =================================================================== RCS file: /cvsroot/amanda/amanda/recover-src/amrecover.c,v retrieving revision 1.29.4.9 diff -u -r1.29.4.9 amrecover.c --- recover-src/amrecover.c 2001/06/19 19:34:11 1.29.4.9 +++ recover-src/amrecover.c 2001/07/30 19:13:19 @@ -529,11 +524,11 @@ { error("%s/tcp unknown protocol", service_name); } - server_socket = stream_client(server_name, - ntohs(sp->s_port), - DEFAULT_SIZE, - DEFAULT_SIZE, - &my_port); + server_socket = stream_client_privileged(server_name, + ntohs(sp->s_port), + DEFAULT_SIZE, + DEFAULT_SIZE, + &my_port); if (server_socket < 0) { error("cannot connect to %s: %s", server_name, strerror(errno)); Index: recover-src/extract_list.c =================================================================== RCS file: /cvsroot/amanda/amanda/recover-src/extract_list.c,v retrieving revision 1.43.2.17 diff -u -r1.43.2.17 extract_list.c --- recover-src/extract_list.c 2001/06/18 22:28:26 1.43.2.17 +++ recover-src/extract_list.c 2001/07/30 19:13:19 @@ -1049,11 +1049,11 @@ amfree(service_name); seteuid(0); /* it either works ... */ setegid(0); - tape_server_socket = stream_client(tape_server_name, - ntohs(sp->s_port), - DEFAULT_SIZE, - DATABUF_SIZE*2, - &my_port); + tape_server_socket = stream_client_privileged(tape_server_name, + ntohs(sp->s_port), + DEFAULT_SIZE, + DATABUF_SIZE*2, + &my_port); if (tape_server_socket < 0) { printf("cannot connect to %s: %s\n", tape_server_name, strerror(errno));