From 748fe7a383e50079493648839cf0ab69aa2223a0 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 9 Nov 1998 16:40:38 +0000 Subject: split socket util functions into util_sock.c. util.c NOT committed and util_sock.c NOT included in Makefile.in. registry commands added to rpcclient. waiting for 2_0_0 split before committing modified files. these files are new modules, and are not referenced in the Makefile.in (This used to be commit 373f60256fc6dc800f73d88ea9a302933a4a3246) --- source3/lib/util_sock.c | 851 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 851 insertions(+) create mode 100644 source3/lib/util_sock.c (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c new file mode 100644 index 0000000000..47c94f21fc --- /dev/null +++ b/source3/lib/util_sock.c @@ -0,0 +1,851 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + Samba utility functions + Copyright (C) Andrew Tridgell 1992-1998 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#ifdef WITH_SSL +#include +#undef Realloc /* SSLeay defines this and samba has a function of this name */ +extern SSL *ssl; +extern int sslFd; +#endif /* WITH_SSL */ + +extern int DEBUGLEVEL; + +BOOL passive = False; + +/* the client file descriptor */ +int Client = -1; + +/* the last IP received from */ +struct in_addr lastip; + +/* the last port received from */ +int lastport=0; + + +int smb_read_error = 0; + + +/**************************************************************************** +determine if a file descriptor is in fact a socket +****************************************************************************/ +BOOL is_a_socket(int fd) +{ + int v,l; + l = sizeof(int); + return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0); +} + + +enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON}; + +struct +{ + char *name; + int level; + int option; + int value; + int opttype; +} socket_options[] = { + {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL}, + {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL}, + {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL}, +#ifdef TCP_NODELAY + {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL}, +#endif +#ifdef IPTOS_LOWDELAY + {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON}, +#endif +#ifdef IPTOS_THROUGHPUT + {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON}, +#endif +#ifdef SO_SNDBUF + {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT}, +#endif +#ifdef SO_RCVBUF + {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT}, +#endif +#ifdef SO_SNDLOWAT + {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT}, +#endif +#ifdef SO_RCVLOWAT + {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT}, +#endif +#ifdef SO_SNDTIMEO + {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT}, +#endif +#ifdef SO_RCVTIMEO + {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT}, +#endif + {NULL,0,0,0,0}}; + + + +/**************************************************************************** +set user socket options +****************************************************************************/ +void set_socket_options(int fd, char *options) +{ + fstring tok; + + while (next_token(&options,tok," \t,", sizeof(tok))) + { + int ret=0,i; + int value = 1; + char *p; + BOOL got_value = False; + + if ((p = strchr(tok,'='))) + { + *p = 0; + value = atoi(p+1); + got_value = True; + } + + for (i=0;socket_options[i].name;i++) + if (strequal(socket_options[i].name,tok)) + break; + + if (!socket_options[i].name) + { + DEBUG(0,("Unknown socket option %s\n",tok)); + continue; + } + + switch (socket_options[i].opttype) + { + case OPT_BOOL: + case OPT_INT: + ret = setsockopt(fd,socket_options[i].level, + socket_options[i].option,(char *)&value,sizeof(int)); + break; + + case OPT_ON: + if (got_value) + DEBUG(0,("syntax error - %s does not take a value\n",tok)); + + { + int on = socket_options[i].value; + ret = setsockopt(fd,socket_options[i].level, + socket_options[i].option,(char *)&on,sizeof(int)); + } + break; + } + + if (ret != 0) + DEBUG(0,("Failed to set socket option %s\n",tok)); + } +} + + + +/**************************************************************************** + close the socket communication +****************************************************************************/ +void close_sockets(void ) +{ +#ifdef WITH_SSL + sslutil_disconnect(Client); +#endif /* WITH_SSL */ + + close(Client); + Client = 0; +} + + + +/**************************************************************************** +write to a socket +****************************************************************************/ +ssize_t write_socket(int fd,char *buf,size_t len) +{ + ssize_t ret=0; + + if (passive) + return(len); + DEBUG(6,("write_socket(%d,%d)\n",fd,len)); + ret = write_data(fd,buf,len); + + DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret)); + if(ret <= 0) + DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n", + len, fd, strerror(errno) )); + + return(ret); +} + +/**************************************************************************** +read from a socket +****************************************************************************/ +ssize_t read_udp_socket(int fd,char *buf,size_t len) +{ + ssize_t ret; + struct sockaddr_in sock; + int socklen; + + socklen = sizeof(sock); + bzero((char *)&sock,socklen); + bzero((char *)&lastip,sizeof(lastip)); + ret = (ssize_t)recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen); + if (ret <= 0) { + DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno))); + return(0); + } + + lastip = sock.sin_addr; + lastport = ntohs(sock.sin_port); + + DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n", + inet_ntoa(lastip), lastport, ret)); + + return(ret); +} + +/**************************************************************************** +read data from a device with a timout in msec. +mincount = if timeout, minimum to read before returning +maxcount = number to be read. +time_out = timeout in milliseconds +****************************************************************************/ + +ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out) +{ + fd_set fds; + int selrtn; + ssize_t readret; + size_t nread = 0; + struct timeval timeout; + + /* just checking .... */ + if (maxcnt <= 0) return(0); + + smb_read_error = 0; + + /* Blocking read */ + if (time_out <= 0) { + if (mincnt == 0) mincnt = maxcnt; + + while (nread < mincnt) { +#ifdef WITH_SSL + if(fd == sslFd){ + readret = SSL_read(ssl, buf + nread, maxcnt - nread); + }else{ + readret = read(fd, buf + nread, maxcnt - nread); + } +#else /* WITH_SSL */ + readret = read(fd, buf + nread, maxcnt - nread); +#endif /* WITH_SSL */ + + if (readret == 0) { + smb_read_error = READ_EOF; + return -1; + } + + if (readret == -1) { + smb_read_error = READ_ERROR; + return -1; + } + nread += readret; + } + return((ssize_t)nread); + } + + /* Most difficult - timeout read */ + /* If this is ever called on a disk file and + mincnt is greater then the filesize then + system performance will suffer severely as + select always returns true on disk files */ + + /* Set initial timeout */ + timeout.tv_sec = (time_t)(time_out / 1000); + timeout.tv_usec = (long)(1000 * (time_out % 1000)); + + for (nread=0; nread < mincnt; ) + { + FD_ZERO(&fds); + FD_SET(fd,&fds); + + selrtn = sys_select(fd+1,&fds,&timeout); + + /* Check if error */ + if(selrtn == -1) { + /* something is wrong. Maybe the socket is dead? */ + smb_read_error = READ_ERROR; + return -1; + } + + /* Did we timeout ? */ + if (selrtn == 0) { + smb_read_error = READ_TIMEOUT; + return -1; + } + +#ifdef WITH_SSL + if(fd == sslFd){ + readret = SSL_read(ssl, buf + nread, maxcnt - nread); + }else{ + readret = read(fd, buf + nread, maxcnt - nread); + } +#else /* WITH_SSL */ + readret = read(fd, buf+nread, maxcnt-nread); +#endif /* WITH_SSL */ + + if (readret == 0) { + /* we got EOF on the file descriptor */ + smb_read_error = READ_EOF; + return -1; + } + + if (readret == -1) { + /* the descriptor is probably dead */ + smb_read_error = READ_ERROR; + return -1; + } + + nread += readret; + } + + /* Return the number we got */ + return((ssize_t)nread); +} + + +/**************************************************************************** +send a keepalive packet (rfc1002) +****************************************************************************/ +BOOL send_keepalive(int client) +{ + unsigned char buf[4]; + + buf[0] = 0x85; + buf[1] = buf[2] = buf[3] = 0; + + return(write_data(client,(char *)buf,4) == 4); +} + + + +/**************************************************************************** + read data from the client, reading exactly N bytes. +****************************************************************************/ +ssize_t read_data(int fd,char *buffer,size_t N) +{ + ssize_t ret; + size_t total=0; + + smb_read_error = 0; + + while (total < N) + { +#ifdef WITH_SSL + if(fd == sslFd){ + ret = SSL_read(ssl, buffer + total, N - total); + }else{ + ret = read(fd,buffer + total,N - total); + } +#else /* WITH_SSL */ + ret = read(fd,buffer + total,N - total); +#endif /* WITH_SSL */ + + if (ret == 0) + { + smb_read_error = READ_EOF; + return 0; + } + if (ret == -1) + { + smb_read_error = READ_ERROR; + return -1; + } + total += ret; + } + return (ssize_t)total; +} + + +/**************************************************************************** + write data to a fd +****************************************************************************/ +ssize_t write_data(int fd,char *buffer,size_t N) +{ + size_t total=0; + ssize_t ret; + + while (total < N) + { +#ifdef WITH_SSL + if(fd == sslFd){ + ret = SSL_write(ssl,buffer + total,N - total); + }else{ + ret = write(fd,buffer + total,N - total); + } +#else /* WITH_SSL */ + ret = write(fd,buffer + total,N - total); +#endif /* WITH_SSL */ + + if (ret == -1) return -1; + if (ret == 0) return total; + + total += ret; + } + return (ssize_t)total; +} + + + +/**************************************************************************** +read 4 bytes of a smb packet and return the smb length of the packet +store the result in the buffer +This version of the function will return a length of zero on receiving +a keepalive packet. +timeout is in milliseconds. +****************************************************************************/ +static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int timeout) +{ + ssize_t len=0; + int msg_type; + BOOL ok = False; + + while (!ok) + { + if (timeout > 0) + ok = (read_with_timeout(fd,inbuf,4,4,timeout) == 4); + else + ok = (read_data(fd,inbuf,4) == 4); + + if (!ok) + return(-1); + + len = smb_len(inbuf); + msg_type = CVAL(inbuf,0); + + if (msg_type == 0x85) + DEBUG(5,("Got keepalive packet\n")); + } + + DEBUG(10,("got smb length of %d\n",len)); + + return(len); +} + +/**************************************************************************** +read 4 bytes of a smb packet and return the smb length of the packet +store the result in the buffer. This version of the function will +never return a session keepalive (length of zero). +timeout is in milliseconds. +****************************************************************************/ +ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout) +{ + ssize_t len; + + for(;;) + { + len = read_smb_length_return_keepalive(fd, inbuf, timeout); + + if(len < 0) + return len; + + /* Ignore session keepalives. */ + if(CVAL(inbuf,0) != 0x85) + break; + } + + return len; +} + +/**************************************************************************** + read an smb from a fd. Note that the buffer *MUST* be of size + BUFFER_SIZE+SAFETY_MARGIN. + The timeout is in milliseconds. + This function will return on a + receipt of a session keepalive packet. +****************************************************************************/ +BOOL receive_smb(int fd,char *buffer, unsigned int timeout) +{ + ssize_t len,ret; + + smb_read_error = 0; + + bzero(buffer,smb_size + 100); + + len = read_smb_length_return_keepalive(fd,buffer,timeout); + if (len < 0) + { + DEBUG(10,("receive_smb: length < 0!\n")); + return(False); + } + + if (len > BUFFER_SIZE) { + DEBUG(0,("Invalid packet length! (%d bytes).\n",len)); + if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) + { + exit(1); + } + } + + if(len > 0) { + ret = read_data(fd,buffer+4,len); + if (ret != len) { + smb_read_error = READ_ERROR; + return False; + } + } + return(True); +} + +/**************************************************************************** + read an smb from a fd ignoring all keepalive packets. Note that the buffer + *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN. + The timeout is in milliseconds + + This is exactly the same as receive_smb except that it never returns + a session keepalive packet (just as receive_smb used to do). + receive_smb was changed to return keepalives as the oplock processing means this call + should never go into a blocking read. +****************************************************************************/ + +BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) +{ + BOOL ret; + + for(;;) + { + ret = receive_smb(fd, buffer, timeout); + + if (!ret) + { + DEBUG(10,("client_receive_smb failed\n")); + show_msg(buffer); + return ret; + } + + /* Ignore session keepalive packets. */ + if(CVAL(buffer,0) != 0x85) + break; + } + show_msg(buffer); + return ret; +} + +/**************************************************************************** + send an smb to a fd +****************************************************************************/ +BOOL send_smb(int fd,char *buffer) +{ + size_t len; + size_t nwritten=0; + ssize_t ret; + len = smb_len(buffer) + 4; + + while (nwritten < len) + { + ret = write_socket(fd,buffer+nwritten,len - nwritten); + if (ret <= 0) + { + DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret)); + close_sockets(); + exit(1); + } + nwritten += ret; + } + + return True; +} + + + +/**************************************************************************** +send a single packet to a port on another machine +****************************************************************************/ +BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type) +{ + BOOL ret; + int out_fd; + struct sockaddr_in sock_out; + + if (passive) + return(True); + + /* create a socket to write to */ + out_fd = socket(AF_INET, type, 0); + if (out_fd == -1) + { + DEBUG(0,("socket failed")); + return False; + } + + /* set the address and port */ + bzero((char *)&sock_out,sizeof(sock_out)); + putip((char *)&sock_out.sin_addr,(char *)&ip); + sock_out.sin_port = htons( port ); + sock_out.sin_family = AF_INET; + + if (DEBUGLEVEL > 0) + DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n", + len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM")); + + /* send it */ + ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0); + + if (!ret) + DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n", + inet_ntoa(ip),port,strerror(errno))); + + close(out_fd); + return(ret); +} + + +/**************************************************************************** +open a socket of the specified type, port and address for incoming data +****************************************************************************/ +int open_socket_in(int type, int port, int dlevel,uint32 socket_addr) +{ + struct hostent *hp; + struct sockaddr_in sock; + pstring host_name; + int res; + + /* get my host name */ + if (gethostname(host_name, MAXHOSTNAMELEN) == -1) + { DEBUG(0,("gethostname failed\n")); return -1; } + + /* get host info */ + if ((hp = Get_Hostbyname(host_name)) == 0) + { + DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",host_name)); + return -1; + } + + bzero((char *)&sock,sizeof(sock)); + memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length); + +#ifdef HAVE_SOCK_SIN_LEN + sock.sin_len = sizeof(sock); +#endif + sock.sin_port = htons( port ); + sock.sin_family = hp->h_addrtype; + sock.sin_addr.s_addr = socket_addr; + res = socket(hp->h_addrtype, type, 0); + if (res == -1) + { DEBUG(0,("socket failed\n")); return -1; } + + { + int one=1; + setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one)); + } + + /* now we've got a socket - we need to bind it */ + if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) + { + if (port) { + if (port == SMB_PORT || port == NMB_PORT) + DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n", + port,inet_ntoa(sock.sin_addr),strerror(errno))); + close(res); + + if (dlevel > 0 && port < 1000) + port = 7999; + + if (port >= 1000 && port < 9000) + return(open_socket_in(type,port+1,dlevel,socket_addr)); + } + + return(-1); + } + DEBUG(3,("bind succeeded on port %d\n",port)); + + return res; +} + + +/**************************************************************************** + create an outgoing socket + **************************************************************************/ +int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) +{ + struct sockaddr_in sock_out; + int res,ret; + int connect_loop = 250; /* 250 milliseconds */ + int loops = (timeout * 1000) / connect_loop; + + /* create a socket to write to */ + res = socket(PF_INET, type, 0); + if (res == -1) + { DEBUG(0,("socket error\n")); return -1; } + + if (type != SOCK_STREAM) return(res); + + bzero((char *)&sock_out,sizeof(sock_out)); + putip((char *)&sock_out.sin_addr,(char *)addr); + + sock_out.sin_port = htons( port ); + sock_out.sin_family = PF_INET; + + /* set it non-blocking */ + set_blocking(res,False); + + DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port)); + + /* and connect it to the destination */ +connect_again: + ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out)); + + /* Some systems return EAGAIN when they mean EINPROGRESS */ + if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || + errno == EAGAIN) && loops--) { + msleep(connect_loop); + goto connect_again; + } + + if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || + errno == EAGAIN)) { + DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port)); + close(res); + return -1; + } + +#ifdef EISCONN + if (ret < 0 && errno == EISCONN) { + errno = 0; + ret = 0; + } +#endif + + if (ret < 0) { + DEBUG(1,("error connecting to %s:%d (%s)\n", + inet_ntoa(*addr),port,strerror(errno))); + close(res); + return -1; + } + + /* set it blocking again */ + set_blocking(res,True); + + return res; +} + + +/******************************************************************* + Reset the 'done' variables so after a client process is created + from a fork call these calls will be re-done. This should be + expanded if more variables need reseting. + ******************************************************************/ + +static BOOL global_client_name_done = False; +static BOOL global_client_addr_done = False; + +void reset_globals_after_fork(void) +{ + global_client_name_done = False; + global_client_addr_done = False; + + /* + * Re-seed the random crypto generator, so all smbd's + * started from the same parent won't generate the same + * sequence. + */ + { + unsigned char dummy; + generate_random_buffer( &dummy, 1, True); + } +} + +/******************************************************************* + return the DNS name of the client + ******************************************************************/ +char *client_name(int fd) +{ + struct sockaddr sa; + struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); + int length = sizeof(sa); + static pstring name_buf; + struct hostent *hp; + static int last_fd=-1; + + if (global_client_name_done && last_fd == fd) + return name_buf; + + last_fd = fd; + global_client_name_done = False; + + pstrcpy(name_buf,"UNKNOWN"); + + if (fd == -1) { + return name_buf; + } + + if (getpeername(fd, &sa, &length) < 0) { + DEBUG(0,("getpeername failed\n")); + return name_buf; + } + + /* Look up the remote host name. */ + if ((hp = gethostbyaddr((char *) &sockin->sin_addr, + sizeof(sockin->sin_addr), + AF_INET)) == 0) { + DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr(fd))); + StrnCpy(name_buf,client_addr(fd),sizeof(name_buf) - 1); + } else { + StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1); + if (!matchname(name_buf, sockin->sin_addr)) { + DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr(fd))); + pstrcpy(name_buf,"UNKNOWN"); + } + } + global_client_name_done = True; + return name_buf; +} + +/******************************************************************* + return the IP addr of the client as a string + ******************************************************************/ +char *client_addr(int fd) +{ + struct sockaddr sa; + struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); + int length = sizeof(sa); + static fstring addr_buf; + static int last_fd = -1; + + if (global_client_addr_done && fd == last_fd) + return addr_buf; + + last_fd = fd; + global_client_addr_done = False; + + fstrcpy(addr_buf,"0.0.0.0"); + + if (fd == -1) { + return addr_buf; + } + + if (getpeername(fd, &sa, &length) < 0) { + DEBUG(0,("getpeername failed\n")); + return addr_buf; + } + + fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr)); + + global_client_addr_done = True; + return addr_buf; +} -- cgit From 2164685b9f959814af2067aa0dcac2d1b2ac0bc5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 13 Nov 1998 02:07:07 +0000 Subject: include/smb.h: Re-added zero pointer protection to ZERO_STRUCTP. lib/util_sock.c: Added strerror() calls to getpeername failures (which seem to be giving IRIX trouble at the moment). rpc_parse/parse_sec.c: Changed use of ZERO_STRUCTPN to ZERO_STRUCTP which again does zero pointer protection. smbd/quotas.c: Fixed typo. Jeremy. (This used to be commit b62f008974c96e0302d6c146cf49bc2045bef005) --- source3/lib/util_sock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 47c94f21fc..3a52732a2a 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -795,7 +795,7 @@ char *client_name(int fd) } if (getpeername(fd, &sa, &length) < 0) { - DEBUG(0,("getpeername failed\n")); + DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) )); return name_buf; } @@ -840,7 +840,7 @@ char *client_addr(int fd) } if (getpeername(fd, &sa, &length) < 0) { - DEBUG(0,("getpeername failed\n")); + DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) )); return addr_buf; } -- cgit From 8fc1504ff8204dd1ca735f31c769f6dadf0f88cb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 13 Nov 1998 21:41:01 +0000 Subject: Makefile.in configure configure.in include/config.h.in: Changes for DGUX and UNIXWARE. groupdb/aliasdb.c groupdb/aliasfile.c groupdb/groupfile.c: Don't use snprinf, use slprintf. include/includes.h: Fix YP problem. include/smb.h: Fix ZERO_STRUCTP. lib/util_sock.c: Added strerror() in debugs. passdb/ldap.c: Don't use snprinf, use slprintf. rpc_client/cli_lsarpc.c rpc_client/cli_pipe.c rpc_parse/parse_sec.c rpc_server/srv_pipe.c: Don't use snprinf, use slprintf. script/installman.sh: DGUX changes. smbd/open.c smbd/oplock.c: Fixed gcc warnings. web/swat.c: Changes USER to SWAT_USER. (This used to be commit 4c2b5a00983501e5d4aad1456ba8b5ab0dfd9b4c) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 3a52732a2a..4a67fa00aa 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -168,7 +168,7 @@ void close_sockets(void ) #endif /* WITH_SSL */ close(Client); - Client = 0; + Client = -1; } -- cgit From f221bfa4ace27b898c9326b1d81df59e0ceba032 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 18 Aug 1999 20:10:12 +0000 Subject: debug info display (netbios layer). (This used to be commit 5c974cc4a4cdcb9fd3fe01e93aa577b81cf2d18b) --- source3/lib/util_sock.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 4a67fa00aa..e9859dfa17 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -526,6 +526,7 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout) BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) { BOOL ret; + uint8 msg_type; for(;;) { @@ -539,9 +540,18 @@ BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) } /* Ignore session keepalive packets. */ - if(CVAL(buffer,0) != 0x85) + msg_type = CVAL(buffer,0); + if (msg_type != 0x85) break; } + if (msg_type == 0) + { + show_msg(buffer); + } + else + { + dump_data(10, buffer, smb_len(buffer) + 4); + } show_msg(buffer); return ret; } -- cgit From 7f8f5e15bdffec00454168c0591fa39a88d191c2 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 8 Sep 1999 19:37:45 +0000 Subject: bertl patch for making samba listen on port 445, just like nt 5 does. cool! (This used to be commit 727e1421b2c0f8c72c428776593498103304082b) --- source3/lib/util_sock.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index e9859dfa17..50c295f2bd 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -35,6 +35,9 @@ BOOL passive = False; /* the client file descriptor */ int Client = -1; +/* the port, where client connected */ +int ClientPort = 0; + /* the last IP received from */ struct in_addr lastip; -- cgit From 6ddfc68e0496dc41f8c9a022a0b04a2066b43c9d Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 1 Dec 1999 02:15:14 +0000 Subject: sys_select added one more argument (read, write selectors). (This used to be commit e4d92ff9dfc51735e6932748f66a7c20b2c1cb6a) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 50c295f2bd..fc5c2958e4 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -287,7 +287,7 @@ ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned FD_ZERO(&fds); FD_SET(fd,&fds); - selrtn = sys_select(fd+1,&fds,&timeout); + selrtn = sys_select(fd+1,&fds,NULL, &timeout); /* Check if error */ if(selrtn == -1) { -- cgit From f521205cb3d188fdcadcbd205dcfda4a7dcb89a0 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sat, 4 Dec 1999 19:14:37 +0000 Subject: jeremy is going to hate me for this. created an "nmb-agent" utility that, yes: it connects to the 137 socket and accepts unix socket connections which it redirects onto port 137. it uses the name_trn_id field to filter requests to the correct location. name_query() and name_status() are the first victims to use this feature (by specifying a file descriptor of -1). (This used to be commit d923bc8da2cf996408194d98381409191dd81a16) --- source3/lib/util_sock.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index fc5c2958e4..c0ca723e38 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -862,3 +862,35 @@ char *client_addr(int fd) global_client_addr_done = True; return addr_buf; } + +/******************************************************************* + opens and connects to a unix pipe socket + ******************************************************************/ +int open_pipe_sock(char *path) +{ + int sock; + struct sockaddr_un sa; + + sock = socket(AF_UNIX, SOCK_STREAM, 0); + + if (sock < 0) + { + DEBUG(0, ("unix socket open failed\n")); + return sock; + } + + ZERO_STRUCT(sa); + sa.sun_family = AF_UNIX; + safe_strcpy(sa.sun_path, path, sizeof(sa.sun_path)-1); + + DEBUG(10, ("socket open succeeded. file name: %s\n", sa.sun_path)); + + if (connect(sock, (struct sockaddr*) &sa, sizeof(sa)) < 0) + { + DEBUG(0,("socket connect to %s failed\n", sa.sun_path)); + close(sock); + return -1; + } + + return sock; +} -- cgit From 854f35e20fa4748312e4b0fbae6bb38342ab0389 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 5 Dec 1999 00:13:17 +0000 Subject: created create_pipe_socket() function. (This used to be commit a3af3b4312144943413894b18b5845b56474ebb5) --- source3/lib/util_sock.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index c0ca723e38..71e51d2771 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -894,3 +894,65 @@ int open_pipe_sock(char *path) return sock; } + +int create_pipe_socket(char *dir, int dir_perms, + char *path, int path_perms) +{ + int s; + struct sockaddr_un sa; + + mkdir(dir, dir_perms); + + if (chmod(dir, dir_perms) < 0) + { + DEBUG(0, ("chmod on %s failed\n", dir)); + return -1; + } + + if (!remove(path)) + { + DEBUG(0, ("remove on %s failed\n", path)); + return -1; + } + + /* start listening on unix socket */ + s = socket(AF_UNIX, SOCK_STREAM, 0); + + if (s < 0) + { + DEBUG(0, ("socket open failed\n")); + return -1; + } + + ZERO_STRUCT(sa); + sa.sun_family = AF_UNIX; + safe_strcpy(sa.sun_path, path, sizeof(sa.sun_path)-1); + + if (bind(s, (struct sockaddr*) &sa, sizeof(sa)) < 0) + { + DEBUG(0, ("socket bind to %s failed\n", sa.sun_path)); + close(s); + remove(path); + return -1; + } + + if (s == -1) + { + DEBUG(0,("bind failed\n")); + remove(path); + return -1; + } + + if (path_perms != 0) + { + chmod(path, path_perms); + } + + if (listen(s, 5) == -1) + { + DEBUG(0,("listen failed\n")); + return -1; + } + + return s; +} -- cgit From a0ba234cf9b40adf6b5390e4e67730163a42883f Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 6 Dec 1999 00:44:32 +0000 Subject: the first independent msrpc daemon - lsarpcd. one horrible cut / paste job from smbd, plus a code split of shared components between the two. the job is not _yet_ complete, as i need to be able to do a become_user() call for security reasons. i picked lsarpcd first because you don't _need_ security on it (microsoft botched so badly on this one, it's not real. at least they fixed this in nt5 with restrictanonymous=0x2). fixing this involves sending the current smb and unix credentials down the unix pipe so that the daemon it eventually goes to can pick them up at the other end. i can't believe this all worked!!! (This used to be commit 2245b0c6d13c7c5886e81f9137b05df883598c26) --- source3/lib/util_sock.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 71e51d2771..d9b0f97259 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -901,6 +901,9 @@ int create_pipe_socket(char *dir, int dir_perms, int s; struct sockaddr_un sa; + DEBUG(10,("create_pipe_socket: %s %d %s %d\n", + dir, dir_perms, path, path_perms)); + mkdir(dir, dir_perms); if (chmod(dir, dir_perms) < 0) @@ -912,7 +915,6 @@ int create_pipe_socket(char *dir, int dir_perms, if (!remove(path)) { DEBUG(0, ("remove on %s failed\n", path)); - return -1; } /* start listening on unix socket */ @@ -954,5 +956,7 @@ int create_pipe_socket(char *dir, int dir_perms, return -1; } + DEBUG(5,("unix socket opened: %s\n", path)); + return s; } -- cgit From 3db52feb1f3b2c07ce0b06ad4a7099fa6efe3fc7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Dec 1999 13:27:58 +0000 Subject: first pass at updating head branch to be to be the same as the SAMBA_2_0 branch (This used to be commit 453a822a76780063dff23526c35408866d0c0154) --- source3/lib/util_sock.c | 529 ++++++++++++++++++++++++++++-------------------- 1 file changed, 305 insertions(+), 224 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index d9b0f97259..77ba4a7f4c 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -35,22 +35,18 @@ BOOL passive = False; /* the client file descriptor */ int Client = -1; -/* the port, where client connected */ -int ClientPort = 0; - /* the last IP received from */ struct in_addr lastip; /* the last port received from */ int lastport=0; - int smb_read_error = 0; - /**************************************************************************** -determine if a file descriptor is in fact a socket + Determine if a file descriptor is in fact a socket. ****************************************************************************/ + BOOL is_a_socket(int fd) { int v,l; @@ -58,7 +54,6 @@ BOOL is_a_socket(int fd) return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0); } - enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON}; struct @@ -101,69 +96,63 @@ struct #endif {NULL,0,0,0,0}}; - - /**************************************************************************** -set user socket options + Set user socket options. ****************************************************************************/ + void set_socket_options(int fd, char *options) { - fstring tok; - - while (next_token(&options,tok," \t,", sizeof(tok))) - { - int ret=0,i; - int value = 1; - char *p; - BOOL got_value = False; - - if ((p = strchr(tok,'='))) - { - *p = 0; - value = atoi(p+1); - got_value = True; - } + fstring tok; + + while (next_token(&options,tok," \t,", sizeof(tok))) { + int ret=0,i; + int value = 1; + char *p; + BOOL got_value = False; + + if ((p = strchr(tok,'='))) { + *p = 0; + value = atoi(p+1); + got_value = True; + } - for (i=0;socket_options[i].name;i++) - if (strequal(socket_options[i].name,tok)) - break; + for (i=0;socket_options[i].name;i++) + if (strequal(socket_options[i].name,tok)) + break; - if (!socket_options[i].name) - { - DEBUG(0,("Unknown socket option %s\n",tok)); - continue; - } + if (!socket_options[i].name) { + DEBUG(0,("Unknown socket option %s\n",tok)); + continue; + } - switch (socket_options[i].opttype) - { - case OPT_BOOL: - case OPT_INT: - ret = setsockopt(fd,socket_options[i].level, - socket_options[i].option,(char *)&value,sizeof(int)); - break; - - case OPT_ON: - if (got_value) - DEBUG(0,("syntax error - %s does not take a value\n",tok)); - - { - int on = socket_options[i].value; - ret = setsockopt(fd,socket_options[i].level, - socket_options[i].option,(char *)&on,sizeof(int)); - } - break; - } + switch (socket_options[i].opttype) { + case OPT_BOOL: + case OPT_INT: + ret = setsockopt(fd,socket_options[i].level, + socket_options[i].option,(char *)&value,sizeof(int)); + break; + + case OPT_ON: + if (got_value) + DEBUG(0,("syntax error - %s does not take a value\n",tok)); + + { + int on = socket_options[i].value; + ret = setsockopt(fd,socket_options[i].level, + socket_options[i].option,(char *)&on,sizeof(int)); + } + break; + } - if (ret != 0) - DEBUG(0,("Failed to set socket option %s\n",tok)); - } + if (ret != 0) + DEBUG(0,("Failed to set socket option %s (Error %s)\n",tok, strerror(errno) )); + } } - - /**************************************************************************** - close the socket communication + Close the socket communication. ****************************************************************************/ + void close_sockets(void ) { #ifdef WITH_SSL @@ -174,31 +163,10 @@ void close_sockets(void ) Client = -1; } - - /**************************************************************************** -write to a socket + Read from a socket. ****************************************************************************/ -ssize_t write_socket(int fd,char *buf,size_t len) -{ - ssize_t ret=0; - - if (passive) - return(len); - DEBUG(6,("write_socket(%d,%d)\n",fd,len)); - ret = write_data(fd,buf,len); - - DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret)); - if(ret <= 0) - DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n", - len, fd, strerror(errno) )); - return(ret); -} - -/**************************************************************************** -read from a socket -****************************************************************************/ ssize_t read_udp_socket(int fd,char *buf,size_t len) { ssize_t ret; @@ -206,8 +174,8 @@ ssize_t read_udp_socket(int fd,char *buf,size_t len) int socklen; socklen = sizeof(sock); - bzero((char *)&sock,socklen); - bzero((char *)&lastip,sizeof(lastip)); + memset((char *)&sock,'\0',socklen); + memset((char *)&lastip,'\0',sizeof(lastip)); ret = (ssize_t)recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen); if (ret <= 0) { DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno))); @@ -224,13 +192,13 @@ ssize_t read_udp_socket(int fd,char *buf,size_t len) } /**************************************************************************** -read data from a device with a timout in msec. -mincount = if timeout, minimum to read before returning -maxcount = number to be read. -time_out = timeout in milliseconds + Read data from a socket with a timout in msec. + mincount = if timeout, minimum to read before returning + maxcount = number to be read. + time_out = timeout in milliseconds ****************************************************************************/ -ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out) +static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out) { fd_set fds; int selrtn; @@ -239,7 +207,8 @@ ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned struct timeval timeout; /* just checking .... */ - if (maxcnt <= 0) return(0); + if (maxcnt <= 0) + return(0); smb_read_error = 0; @@ -259,11 +228,13 @@ ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned #endif /* WITH_SSL */ if (readret == 0) { + DEBUG(5,("read_socket_with_timeout: blocking read. EOF from client.\n")); smb_read_error = READ_EOF; return -1; } if (readret == -1) { + DEBUG(0,("read_socket_with_timeout: read error = %s.\n", strerror(errno) )); smb_read_error = READ_ERROR; return -1; } @@ -282,22 +253,23 @@ ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned timeout.tv_sec = (time_t)(time_out / 1000); timeout.tv_usec = (long)(1000 * (time_out % 1000)); - for (nread=0; nread < mincnt; ) - { + for (nread=0; nread < mincnt; ) { FD_ZERO(&fds); FD_SET(fd,&fds); - selrtn = sys_select(fd+1,&fds,NULL, &timeout); + selrtn = sys_select(fd+1,&fds,&timeout); /* Check if error */ if(selrtn == -1) { /* something is wrong. Maybe the socket is dead? */ + DEBUG(0,("read_socket_with_timeout: timeout read. select error = %s.\n", strerror(errno) )); smb_read_error = READ_ERROR; return -1; } - + /* Did we timeout ? */ if (selrtn == 0) { + DEBUG(10,("read_socket_with_timeout: timeout read. select timed out.\n")); smb_read_error = READ_TIMEOUT; return -1; } @@ -314,12 +286,14 @@ ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned if (readret == 0) { /* we got EOF on the file descriptor */ + DEBUG(5,("read_socket_with_timeout: timeout read. EOF from client.\n")); smb_read_error = READ_EOF; return -1; } if (readret == -1) { /* the descriptor is probably dead */ + DEBUG(0,("read_socket_with_timeout: timeout read. read error = %s.\n", strerror(errno) )); smb_read_error = READ_ERROR; return -1; } @@ -331,10 +305,91 @@ ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned return((ssize_t)nread); } +/**************************************************************************** + Read data from a fd with a timout in msec. + mincount = if timeout, minimum to read before returning + maxcount = number to be read. + time_out = timeout in milliseconds +****************************************************************************/ + +ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out) +{ + fd_set fds; + int selrtn; + ssize_t readret; + size_t nread = 0; + struct timeval timeout; + + /* just checking .... */ + if (maxcnt <= 0) + return(0); + + /* Blocking read */ + if (time_out <= 0) { + if (mincnt == 0) mincnt = maxcnt; + + while (nread < mincnt) { +#ifdef WITH_SSL + if(fd == sslFd){ + readret = SSL_read(ssl, buf + nread, maxcnt - nread); + }else{ + readret = read(fd, buf + nread, maxcnt - nread); + } +#else /* WITH_SSL */ + readret = read(fd, buf + nread, maxcnt - nread); +#endif /* WITH_SSL */ + + if (readret <= 0) + return readret; + + nread += readret; + } + return((ssize_t)nread); + } + + /* Most difficult - timeout read */ + /* If this is ever called on a disk file and + mincnt is greater then the filesize then + system performance will suffer severely as + select always returns true on disk files */ + + /* Set initial timeout */ + timeout.tv_sec = (time_t)(time_out / 1000); + timeout.tv_usec = (long)(1000 * (time_out % 1000)); + + for (nread=0; nread < mincnt; ) { + FD_ZERO(&fds); + FD_SET(fd,&fds); + + selrtn = sys_select(fd+1,&fds,&timeout); + + if(selrtn <= 0) + return selrtn; + +#ifdef WITH_SSL + if(fd == sslFd){ + readret = SSL_read(ssl, buf + nread, maxcnt - nread); + }else{ + readret = read(fd, buf + nread, maxcnt - nread); + } +#else /* WITH_SSL */ + readret = read(fd, buf+nread, maxcnt-nread); +#endif /* WITH_SSL */ + + if (readret <= 0) + return readret; + + nread += readret; + } + + /* Return the number we got */ + return((ssize_t)nread); +} /**************************************************************************** send a keepalive packet (rfc1002) ****************************************************************************/ + BOOL send_keepalive(int client) { unsigned char buf[4]; @@ -342,14 +397,13 @@ BOOL send_keepalive(int client) buf[0] = 0x85; buf[1] = buf[2] = buf[3] = 0; - return(write_data(client,(char *)buf,4) == 4); + return(write_socket_data(client,(char *)buf,4) == 4); } - - /**************************************************************************** read data from the client, reading exactly N bytes. ****************************************************************************/ + ssize_t read_data(int fd,char *buffer,size_t N) { ssize_t ret; @@ -371,11 +425,13 @@ ssize_t read_data(int fd,char *buffer,size_t N) if (ret == 0) { + DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) )); smb_read_error = READ_EOF; return 0; } if (ret == -1) { + DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) )); smb_read_error = READ_ERROR; return -1; } @@ -384,10 +440,50 @@ ssize_t read_data(int fd,char *buffer,size_t N) return (ssize_t)total; } +/**************************************************************************** + Read data from a socket, reading exactly N bytes. +****************************************************************************/ + +static ssize_t read_socket_data(int fd,char *buffer,size_t N) +{ + ssize_t ret; + size_t total=0; + + smb_read_error = 0; + + while (total < N) + { +#ifdef WITH_SSL + if(fd == sslFd){ + ret = SSL_read(ssl, buffer + total, N - total); + }else{ + ret = read(fd,buffer + total,N - total); + } +#else /* WITH_SSL */ + ret = read(fd,buffer + total,N - total); +#endif /* WITH_SSL */ + + if (ret == 0) + { + DEBUG(10,("read_socket_data: recv of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) )); + smb_read_error = READ_EOF; + return 0; + } + if (ret == -1) + { + DEBUG(0,("read_socket_data: recv failure for %d. Error = %s\n", (int)(N - total), strerror(errno) )); + smb_read_error = READ_ERROR; + return -1; + } + total += ret; + } + return (ssize_t)total; +} /**************************************************************************** - write data to a fd + Write data to a fd. ****************************************************************************/ + ssize_t write_data(int fd,char *buffer,size_t N) { size_t total=0; @@ -405,7 +501,42 @@ ssize_t write_data(int fd,char *buffer,size_t N) ret = write(fd,buffer + total,N - total); #endif /* WITH_SSL */ - if (ret == -1) return -1; + if (ret == -1) { + DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) )); + return -1; + } + if (ret == 0) return total; + + total += ret; + } + return (ssize_t)total; +} + +/**************************************************************************** + Write data to a socket - use send rather than write. +****************************************************************************/ + +ssize_t write_socket_data(int fd,char *buffer,size_t N) +{ + size_t total=0; + ssize_t ret; + + while (total < N) + { +#ifdef WITH_SSL + if(fd == sslFd){ + ret = SSL_write(ssl,buffer + total,N - total); + }else{ + ret = send(fd,buffer + total,N - total, 0); + } +#else /* WITH_SSL */ + ret = send(fd,buffer + total,N - total,0); +#endif /* WITH_SSL */ + + if (ret == -1) { + DEBUG(0,("write_socket_data: write failure. Error = %s\n", strerror(errno) )); + return -1; + } if (ret == 0) return total; total += ret; @@ -413,7 +544,26 @@ ssize_t write_data(int fd,char *buffer,size_t N) return (ssize_t)total; } +/**************************************************************************** +write to a socket +****************************************************************************/ +ssize_t write_socket(int fd,char *buf,size_t len) +{ + ssize_t ret=0; + + if (passive) + return(len); + DEBUG(6,("write_socket(%d,%d)\n",fd,(int)len)); + ret = write_socket_data(fd,buf,len); + + DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,(int)len,(int)ret)); + if(ret <= 0) + DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n", + (int)len, fd, strerror(errno) )); + + return(ret); +} /**************************************************************************** read 4 bytes of a smb packet and return the smb length of the packet @@ -422,6 +572,7 @@ This version of the function will return a length of zero on receiving a keepalive packet. timeout is in milliseconds. ****************************************************************************/ + static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int timeout) { ssize_t len=0; @@ -431,9 +582,9 @@ static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int while (!ok) { if (timeout > 0) - ok = (read_with_timeout(fd,inbuf,4,4,timeout) == 4); + ok = (read_socket_with_timeout(fd,inbuf,4,4,timeout) == 4); else - ok = (read_data(fd,inbuf,4) == 4); + ok = (read_socket_data(fd,inbuf,4) == 4); if (!ok) return(-1); @@ -456,6 +607,7 @@ store the result in the buffer. This version of the function will never return a session keepalive (length of zero). timeout is in milliseconds. ****************************************************************************/ + ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout) { ssize_t len; @@ -472,6 +624,8 @@ ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout) break; } + DEBUG(10,("read_smb_length: got smb length of %d\n",len)); + return len; } @@ -482,13 +636,14 @@ ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout) This function will return on a receipt of a session keepalive packet. ****************************************************************************/ + BOOL receive_smb(int fd,char *buffer, unsigned int timeout) { ssize_t len,ret; smb_read_error = 0; - bzero(buffer,smb_size + 100); + memset(buffer,'\0',smb_size + 100); len = read_smb_length_return_keepalive(fd,buffer,timeout); if (len < 0) @@ -506,7 +661,7 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout) } if(len > 0) { - ret = read_data(fd,buffer+4,len); + ret = read_socket_data(fd,buffer+4,len); if (ret != len) { smb_read_error = READ_ERROR; return False; @@ -529,7 +684,6 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout) BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) { BOOL ret; - uint8 msg_type; for(;;) { @@ -543,25 +697,45 @@ BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) } /* Ignore session keepalive packets. */ - msg_type = CVAL(buffer,0); - if (msg_type != 0x85) + if(CVAL(buffer,0) != 0x85) break; } - if (msg_type == 0) - { - show_msg(buffer); - } - else - { - dump_data(10, buffer, smb_len(buffer) + 4); - } show_msg(buffer); return ret; } +/**************************************************************************** + send an null session message to a fd +****************************************************************************/ + +BOOL send_null_session_msg(int fd) +{ + ssize_t ret; + uint32 blank = 0; + size_t len = 4; + size_t nwritten=0; + char *buffer = (char *)␣ + + while (nwritten < len) + { + ret = write_socket(fd,buffer+nwritten,len - nwritten); + if (ret <= 0) + { + DEBUG(0,("send_null_session_msg: Error writing %d bytes to client. %d. Exiting\n",(int)len,(int)ret)); + close_sockets(); + exit(1); + } + nwritten += ret; + } + + DEBUG(10,("send_null_session_msg: sent 4 null bytes to client.\n")); + return True; +} + /**************************************************************************** send an smb to a fd ****************************************************************************/ + BOOL send_smb(int fd,char *buffer) { size_t len; @@ -574,7 +748,7 @@ BOOL send_smb(int fd,char *buffer) ret = write_socket(fd,buffer+nwritten,len - nwritten); if (ret <= 0) { - DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret)); + DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",(int)len,(int)ret)); close_sockets(); exit(1); } @@ -584,11 +758,10 @@ BOOL send_smb(int fd,char *buffer) return True; } - - /**************************************************************************** send a single packet to a port on another machine ****************************************************************************/ + BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type) { BOOL ret; @@ -607,7 +780,7 @@ BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type) } /* set the address and port */ - bzero((char *)&sock_out,sizeof(sock_out)); + memset((char *)&sock_out,'\0',sizeof(sock_out)); putip((char *)&sock_out.sin_addr,(char *)&ip); sock_out.sin_port = htons( port ); sock_out.sin_family = AF_INET; @@ -627,11 +800,11 @@ BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type) return(ret); } - /**************************************************************************** open a socket of the specified type, port and address for incoming data ****************************************************************************/ -int open_socket_in(int type, int port, int dlevel,uint32 socket_addr) + +int open_socket_in(int type, int port, int dlevel,uint32 socket_addr, BOOL rebind) { struct hostent *hp; struct sockaddr_in sock; @@ -649,7 +822,7 @@ int open_socket_in(int type, int port, int dlevel,uint32 socket_addr) return -1; } - bzero((char *)&sock,sizeof(sock)); + memset((char *)&sock,'\0',sizeof(sock)); memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length); #ifdef HAVE_SOCK_SIN_LEN @@ -663,8 +836,12 @@ int open_socket_in(int type, int port, int dlevel,uint32 socket_addr) { DEBUG(0,("socket failed\n")); return -1; } { - int one=1; - setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one)); + int val=1; + if(rebind) + val=1; + else + val=0; + setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val)); } /* now we've got a socket - we need to bind it */ @@ -680,7 +857,7 @@ int open_socket_in(int type, int port, int dlevel,uint32 socket_addr) port = 7999; if (port >= 1000 && port < 9000) - return(open_socket_in(type,port+1,dlevel,socket_addr)); + return(open_socket_in(type,port+1,dlevel,socket_addr,rebind)); } return(-1); @@ -690,16 +867,16 @@ int open_socket_in(int type, int port, int dlevel,uint32 socket_addr) return res; } - /**************************************************************************** - create an outgoing socket + create an outgoing socket. timeout is in milliseconds. **************************************************************************/ + int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) { struct sockaddr_in sock_out; int res,ret; int connect_loop = 250; /* 250 milliseconds */ - int loops = (timeout * 1000) / connect_loop; + int loops = (timeout) / connect_loop; /* create a socket to write to */ res = socket(PF_INET, type, 0); @@ -708,7 +885,7 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) if (type != SOCK_STREAM) return(res); - bzero((char *)&sock_out,sizeof(sock_out)); + memset((char *)&sock_out,'\0',sizeof(sock_out)); putip((char *)&sock_out.sin_addr,(char *)addr); sock_out.sin_port = htons( port ); @@ -786,6 +963,7 @@ void reset_globals_after_fork(void) /******************************************************************* return the DNS name of the client ******************************************************************/ + char *client_name(int fd) { struct sockaddr sa; @@ -832,6 +1010,7 @@ char *client_name(int fd) /******************************************************************* return the IP addr of the client as a string ******************************************************************/ + char *client_addr(int fd) { struct sockaddr sa; @@ -862,101 +1041,3 @@ char *client_addr(int fd) global_client_addr_done = True; return addr_buf; } - -/******************************************************************* - opens and connects to a unix pipe socket - ******************************************************************/ -int open_pipe_sock(char *path) -{ - int sock; - struct sockaddr_un sa; - - sock = socket(AF_UNIX, SOCK_STREAM, 0); - - if (sock < 0) - { - DEBUG(0, ("unix socket open failed\n")); - return sock; - } - - ZERO_STRUCT(sa); - sa.sun_family = AF_UNIX; - safe_strcpy(sa.sun_path, path, sizeof(sa.sun_path)-1); - - DEBUG(10, ("socket open succeeded. file name: %s\n", sa.sun_path)); - - if (connect(sock, (struct sockaddr*) &sa, sizeof(sa)) < 0) - { - DEBUG(0,("socket connect to %s failed\n", sa.sun_path)); - close(sock); - return -1; - } - - return sock; -} - -int create_pipe_socket(char *dir, int dir_perms, - char *path, int path_perms) -{ - int s; - struct sockaddr_un sa; - - DEBUG(10,("create_pipe_socket: %s %d %s %d\n", - dir, dir_perms, path, path_perms)); - - mkdir(dir, dir_perms); - - if (chmod(dir, dir_perms) < 0) - { - DEBUG(0, ("chmod on %s failed\n", dir)); - return -1; - } - - if (!remove(path)) - { - DEBUG(0, ("remove on %s failed\n", path)); - } - - /* start listening on unix socket */ - s = socket(AF_UNIX, SOCK_STREAM, 0); - - if (s < 0) - { - DEBUG(0, ("socket open failed\n")); - return -1; - } - - ZERO_STRUCT(sa); - sa.sun_family = AF_UNIX; - safe_strcpy(sa.sun_path, path, sizeof(sa.sun_path)-1); - - if (bind(s, (struct sockaddr*) &sa, sizeof(sa)) < 0) - { - DEBUG(0, ("socket bind to %s failed\n", sa.sun_path)); - close(s); - remove(path); - return -1; - } - - if (s == -1) - { - DEBUG(0,("bind failed\n")); - remove(path); - return -1; - } - - if (path_perms != 0) - { - chmod(path, path_perms); - } - - if (listen(s, 5) == -1) - { - DEBUG(0,("listen failed\n")); - return -1; - } - - DEBUG(5,("unix socket opened: %s\n", path)); - - return s; -} -- cgit From fbd17c8dafeefac788f4bc1c41045726825f513f Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 3 Jan 2000 19:19:48 +0000 Subject: simple mods to add msrpc pipe redirection. default behaviour: fall back to using internal msrpc code in smbd. (This used to be commit 8976e26d46cb991710bc77463f7f928ac00dd4d8) --- source3/lib/util_sock.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 77ba4a7f4c..3a09c52a7a 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1041,3 +1041,103 @@ char *client_addr(int fd) global_client_addr_done = True; return addr_buf; } + +/******************************************************************* + opens and connects to a unix pipe socket + ******************************************************************/ +int open_pipe_sock(char *path) +{ + int sock; + struct sockaddr_un sa; + + sock = socket(AF_UNIX, SOCK_STREAM, 0); + + if (sock < 0) + { + DEBUG(0, ("unix socket open failed\n")); + return sock; + } + + ZERO_STRUCT(sa); + sa.sun_family = AF_UNIX; + safe_strcpy(sa.sun_path, path, sizeof(sa.sun_path)-1); + + DEBUG(10, ("socket open succeeded. file name: %s\n", sa.sun_path)); + + if (connect(sock, (struct sockaddr*) &sa, sizeof(sa)) < 0) + { + DEBUG(0,("socket connect to %s failed\n", sa.sun_path)); + close(sock); + return -1; + } + + return sock; +} + +int create_pipe_socket(char *dir, int dir_perms, + char *path, int path_perms) +{ + int s; + struct sockaddr_un sa; + + DEBUG(0,("create_pipe_socket: %s %d %s %d\n", + dir, dir_perms, path, path_perms)); + + DEBUG(0,("*** RACE CONDITION. PLEASE SOMEONE EXAMINE create_pipe_Socket AND FIX IT ***\n")); + + mkdir(dir, dir_perms); + + if (chmod(dir, dir_perms) < 0) + { + DEBUG(0, ("chmod on %s failed\n", dir)); + return -1; + } + + if (!remove(path)) + { + DEBUG(0, ("remove on %s failed\n", path)); + } + + /* start listening on unix socket */ + s = socket(AF_UNIX, SOCK_STREAM, 0); + + if (s < 0) + { + DEBUG(0, ("socket open failed\n")); + return -1; + } + + ZERO_STRUCT(sa); + sa.sun_family = AF_UNIX; + safe_strcpy(sa.sun_path, path, sizeof(sa.sun_path)-1); + + if (bind(s, (struct sockaddr*) &sa, sizeof(sa)) < 0) + { + DEBUG(0, ("socket bind to %s failed\n", sa.sun_path)); + close(s); + remove(path); + return -1; + } + + if (s == -1) + { + DEBUG(0,("bind failed\n")); + remove(path); + return -1; + } + + if (path_perms != 0) + { + chmod(path, path_perms); + } + + if (listen(s, 5) == -1) + { + DEBUG(0,("listen failed\n")); + return -1; + } + + DEBUG(5,("unix socket opened: %s\n", path)); + + return s; +} -- cgit From 8b45838ffc389538142a8923ea3b690014e7bbce Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 Feb 2000 22:48:19 +0000 Subject: Added support for SO_REUSEPORT for systems that have it. Jeremy. (This used to be commit 377515cf9624720362c0b76969b9381d9972a13f) --- source3/lib/util_sock.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 3a09c52a7a..fd5ed71c9c 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -76,6 +76,9 @@ struct #ifdef IPTOS_THROUGHPUT {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON}, #endif +#ifdef SO_REUSEPORT + {"SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT, 0, OPT_BOOL}, +#endif #ifdef SO_SNDBUF {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT}, #endif @@ -841,7 +844,14 @@ int open_socket_in(int type, int port, int dlevel,uint32 socket_addr, BOOL rebin val=1; else val=0; - setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val)); + if(setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val)) == -1) + DEBUG(dlevel,("setsockopt: SO_REUSEADDR=%d on port %d failed with error = %s\n", + val, port, strerror(errno) )); +#ifdef SO_REUSEPORT + if(setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val)) == -1) + DEBUG(dlevel,("setsockopt: SO_REUSEPORT=%d on port %d failed with error = %s\n", + val, port, strerror(errno) )); +#endif /* SO_REUSEPORT */ } /* now we've got a socket - we need to bind it */ -- cgit From 2fa922611bf7160e2c1ce80c11b50006448bf98d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 11 Apr 2000 13:55:53 +0000 Subject: finally got sick of the "extern int Client" code and the stupid assumption that we have one socket everywhere while doing so I discovered a few bugs! 1) the clientgen session retarget code if used from smbd or nmbd would cause a crash as it called close_sockets() which closed our main socket! fixed by removing close_sockets() completely - it is unnecessary 2) the caching in client_addr() and client_name() was bogus - it could easily get fooled and give the wrong result. fixed. 3) the retarget could could recurse, allowing an easy denial of service attack on nmbd. fixed. (This used to be commit 5937ab14d222696e40a3fc6f0e6a536f2d7305d3) --- source3/lib/util_sock.c | 154 ++++++++++++++++++++++++++++-------------------- 1 file changed, 89 insertions(+), 65 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index fd5ed71c9c..bf02e40520 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -32,9 +32,6 @@ extern int DEBUGLEVEL; BOOL passive = False; -/* the client file descriptor */ -int Client = -1; - /* the last IP received from */ struct in_addr lastip; @@ -152,20 +149,6 @@ void set_socket_options(int fd, char *options) } } -/**************************************************************************** - Close the socket communication. -****************************************************************************/ - -void close_sockets(void ) -{ -#ifdef WITH_SSL - sslutil_disconnect(Client); -#endif /* WITH_SSL */ - - close(Client); - Client = -1; -} - /**************************************************************************** Read from a socket. ****************************************************************************/ @@ -725,7 +708,6 @@ BOOL send_null_session_msg(int fd) if (ret <= 0) { DEBUG(0,("send_null_session_msg: Error writing %d bytes to client. %d. Exiting\n",(int)len,(int)ret)); - close_sockets(); exit(1); } nwritten += ret; @@ -752,7 +734,6 @@ BOOL send_smb(int fd,char *buffer) if (ret <= 0) { DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",(int)len,(int)ret)); - close_sockets(); exit(1); } nwritten += ret; @@ -951,14 +932,9 @@ connect_again: expanded if more variables need reseting. ******************************************************************/ -static BOOL global_client_name_done = False; -static BOOL global_client_addr_done = False; void reset_globals_after_fork(void) { - global_client_name_done = False; - global_client_addr_done = False; - /* * Re-seed the random crypto generator, so all smbd's * started from the same parent won't generate the same @@ -969,71 +945,120 @@ void reset_globals_after_fork(void) generate_random_buffer( &dummy, 1, True); } } - + +/* the following 3 client_*() functions are nasty ways of allowing + some generic functions to get info that really should be hidden in + particular modules */ +static int client_fd = -1; + +void client_setfd(int fd) +{ + client_fd = fd; +} + +char *client_name(void) +{ + return get_socket_name(client_fd); +} + +char *client_addr(void) +{ + return get_socket_addr(client_fd); +} + /******************************************************************* - return the DNS name of the client + matchname - determine if host name matches IP address. Used to + confirm a hostname lookup to prevent spoof attacks ******************************************************************/ - -char *client_name(int fd) +static BOOL matchname(char *remotehost,struct in_addr addr) { - struct sockaddr sa; - struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); - int length = sizeof(sa); - static pstring name_buf; struct hostent *hp; - static int last_fd=-1; + int i; - if (global_client_name_done && last_fd == fd) - return name_buf; + if ((hp = Get_Hostbyname(remotehost)) == 0) { + DEBUG(0,("Get_Hostbyname(%s): lookup failure.\n", remotehost)); + return False; + } + + /* + * Make sure that gethostbyname() returns the "correct" host name. + * Unfortunately, gethostbyname("localhost") sometimes yields + * "localhost.domain". Since the latter host name comes from the + * local DNS, we just have to trust it (all bets are off if the local + * DNS is perverted). We always check the address list, though. + */ - last_fd = fd; - global_client_name_done = False; - - pstrcpy(name_buf,"UNKNOWN"); - - if (fd == -1) { - return name_buf; + if (strcasecmp(remotehost, hp->h_name) + && strcasecmp(remotehost, "localhost")) { + DEBUG(0,("host name/name mismatch: %s != %s\n", + remotehost, hp->h_name)); + return False; } - if (getpeername(fd, &sa, &length) < 0) { - DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) )); - return name_buf; + /* Look up the host address in the address list we just got. */ + for (i = 0; hp->h_addr_list[i]; i++) { + if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0) + return True; } + /* + * The host name does not map to the original host address. Perhaps + * someone has compromised a name server. More likely someone botched + * it, but that could be dangerous, too. + */ + + DEBUG(0,("host name/address mismatch: %s != %s\n", + inet_ntoa(addr), hp->h_name)); + return False; +} + + +/******************************************************************* + return the DNS name of the remote end of a socket + ******************************************************************/ +char *get_socket_name(int fd) +{ + static pstring name_buf; + static fstring addr_buf; + struct hostent *hp; + struct in_addr addr; + char *p; + + p = get_socket_addr(fd); + + /* it might be the same as the last one - save some DNS work */ + if (strcmp(p, addr_buf) == 0) return name_buf; + + pstrcpy(name_buf,"UNKNOWN"); + if (fd == -1) return name_buf; + + fstrcpy(addr_buf, p); + + if (inet_aton(p, &addr) == 0) return name_buf; + /* Look up the remote host name. */ - if ((hp = gethostbyaddr((char *) &sockin->sin_addr, - sizeof(sockin->sin_addr), - AF_INET)) == 0) { - DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr(fd))); - StrnCpy(name_buf,client_addr(fd),sizeof(name_buf) - 1); + if ((hp = gethostbyaddr((char *)&addr.s_addr, sizeof(addr.s_addr), AF_INET)) == 0) { + DEBUG(1,("Gethostbyaddr failed for %s\n",p)); + pstrcpy(name_buf, p); } else { - StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1); - if (!matchname(name_buf, sockin->sin_addr)) { - DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr(fd))); + pstrcpy(name_buf,(char *)hp->h_name); + if (!matchname(name_buf, addr)) { + DEBUG(0,("Matchname failed on %s %s\n",name_buf,p)); pstrcpy(name_buf,"UNKNOWN"); } } - global_client_name_done = True; return name_buf; } /******************************************************************* - return the IP addr of the client as a string + return the IP addr of the remote end of a socket as a string ******************************************************************/ - -char *client_addr(int fd) +char *get_socket_addr(int fd) { struct sockaddr sa; struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); int length = sizeof(sa); static fstring addr_buf; - static int last_fd = -1; - - if (global_client_addr_done && fd == last_fd) - return addr_buf; - - last_fd = fd; - global_client_addr_done = False; fstrcpy(addr_buf,"0.0.0.0"); @@ -1048,7 +1073,6 @@ char *client_addr(int fd) fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr)); - global_client_addr_done = True; return addr_buf; } -- cgit From e52431f70a92f44ca12f3b6e1dafe3b7d67914da Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 14 Apr 2000 04:34:08 +0000 Subject: use interpret_addr2() instead of inet_aton() (This used to be commit f65c6ec6db8e05685c719e23d7b06b3452fbbb4e) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index bf02e40520..33c6e91709 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1034,7 +1034,7 @@ char *get_socket_name(int fd) fstrcpy(addr_buf, p); - if (inet_aton(p, &addr) == 0) return name_buf; + addr = *interpret_addr2(p); /* Look up the remote host name. */ if ((hp = gethostbyaddr((char *)&addr.s_addr, sizeof(addr.s_addr), AF_INET)) == 0) { -- cgit From 612682354fa978d7b883028b3aace52a2882adca Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 19 Apr 2000 04:01:16 +0000 Subject: - got rid of the "passive" option - cleaned up the standard_sub_*() calls a lot (This used to be commit 2c2d95d77d3667eaa9252506a82b9054b0d0e01c) --- source3/lib/util_sock.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 33c6e91709..bb62442beb 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -30,8 +30,6 @@ extern int sslFd; extern int DEBUGLEVEL; -BOOL passive = False; - /* the last IP received from */ struct in_addr lastip; @@ -538,8 +536,6 @@ ssize_t write_socket(int fd,char *buf,size_t len) { ssize_t ret=0; - if (passive) - return(len); DEBUG(6,("write_socket(%d,%d)\n",fd,(int)len)); ret = write_socket_data(fd,buf,len); @@ -752,9 +748,6 @@ BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type) int out_fd; struct sockaddr_in sock_out; - if (passive) - return(True); - /* create a socket to write to */ out_fd = socket(AF_INET, type, 0); if (out_fd == -1) -- cgit From 8843a6379d7c1cf59f0f3673cbc567b09994b7d2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 11 Jun 2000 05:57:58 +0000 Subject: Linux kernel oplocks now seem to work, but need a _lot_ of testing I had to modify sys_select() to not loop on EINTR. I added a wrapper called sys_select_intr() which gives the old behaviour. (This used to be commit b28cc4163bc2faaa80c5782fc02c8f03c410cdeb) --- source3/lib/util_sock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index bb62442beb..e6aef16d16 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -241,7 +241,7 @@ static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t ma FD_ZERO(&fds); FD_SET(fd,&fds); - selrtn = sys_select(fd+1,&fds,&timeout); + selrtn = sys_select_intr(fd+1,&fds,&timeout); /* Check if error */ if(selrtn == -1) { @@ -345,7 +345,7 @@ ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned FD_ZERO(&fds); FD_SET(fd,&fds); - selrtn = sys_select(fd+1,&fds,&timeout); + selrtn = sys_select_intr(fd+1,&fds,&timeout); if(selrtn <= 0) return selrtn; -- cgit From 81275cbcf705b675650ca803f8c98cdb7a167fa7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 6 Oct 2000 21:12:25 +0000 Subject: Print socket options - patch from Dave Collier-Brown @ Sun. Jeremy. (This used to be commit c18d6f8701c8e6ca03f9fff79cf28c842b3b5ff9) --- source3/lib/util_sock.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index e6aef16d16..88fe8189b0 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -51,14 +51,16 @@ BOOL is_a_socket(int fd) enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON}; -struct +typedef struct smb_socket_option { char *name; int level; int option; int value; int opttype; -} socket_options[] = { +} smb_socket_option; + +smb_socket_option socket_options[] = { {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL}, {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL}, {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL}, @@ -94,6 +96,23 @@ struct #endif {NULL,0,0,0,0}}; +/**************************************************************************** + Print socket options. +****************************************************************************/ +static void print_socket_options(int s) +{ + int value, vlen = 4; + smb_socket_option *p = &socket_options[0]; + + for (; p->name != NULL; p++) { + if (getsockopt(s, p->level, p->option, (void *)&value, &vlen) == -1) { + DEBUG(3,("Could not test socket option %s.\n", p->name)); + } else { + DEBUG(3,("socket option %s = %d\n",p->name,value)); + } + } + } + /**************************************************************************** Set user socket options. ****************************************************************************/ @@ -145,6 +164,8 @@ void set_socket_options(int fd, char *options) if (ret != 0) DEBUG(0,("Failed to set socket option %s (Error %s)\n",tok, strerror(errno) )); } + + print_socket_options(fd); } /**************************************************************************** -- cgit From 9051f1e2c70e5fcfab2068a201509bc9129d20ad Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 10 May 2001 00:35:24 +0000 Subject: Bumped up debug level on set socket options from 3 to 5. (This used to be commit f0b8ff4eeb3f276c37d062dbd25f7c8b0a02d593) --- source3/lib/util_sock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 88fe8189b0..3269042117 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -106,9 +106,9 @@ static void print_socket_options(int s) for (; p->name != NULL; p++) { if (getsockopt(s, p->level, p->option, (void *)&value, &vlen) == -1) { - DEBUG(3,("Could not test socket option %s.\n", p->name)); + DEBUG(5,("Could not test socket option %s.\n", p->name)); } else { - DEBUG(3,("socket option %s = %d\n",p->name,value)); + DEBUG(5,("socket option %s = %d\n",p->name,value)); } } } -- cgit From 9ff6634db923da17b0946141abf3ce7df61a0dab Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 May 2001 19:28:22 +0000 Subject: Fixup the large_writex problem (a large_writex can send a full 64k of data, we already have space for this we just need to understand the length correctly). Jeremy. (This used to be commit 19145bae720bbcc32dcab380c62a33d1f0e3eef0) --- source3/lib/util_sock.c | 51 ++++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 24 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 3269042117..b59debe929 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -642,35 +642,38 @@ ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout) BOOL receive_smb(int fd,char *buffer, unsigned int timeout) { - ssize_t len,ret; + ssize_t len,ret; - smb_read_error = 0; + smb_read_error = 0; - memset(buffer,'\0',smb_size + 100); + memset(buffer,'\0',smb_size + 100); - len = read_smb_length_return_keepalive(fd,buffer,timeout); - if (len < 0) - { - DEBUG(10,("receive_smb: length < 0!\n")); - return(False); - } + len = read_smb_length_return_keepalive(fd,buffer,timeout); + if (len < 0) { + DEBUG(10,("receive_smb: length < 0!\n")); + return(False); + } - if (len > BUFFER_SIZE) { - DEBUG(0,("Invalid packet length! (%d bytes).\n",len)); - if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) - { - exit(1); - } - } + /* + * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes + * of header. Don't print the error if this fits.... JRA. + */ - if(len > 0) { - ret = read_socket_data(fd,buffer+4,len); - if (ret != len) { - smb_read_error = READ_ERROR; - return False; - } - } - return(True); + if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) { + DEBUG(0,("Invalid packet length! (%d bytes).\n",len)); + if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) + exit(1); + } + + if(len > 0) { + ret = read_socket_data(fd,buffer+4,len); + if (ret != len) { + smb_read_error = READ_ERROR; + return False; + } + } + + return(True); } /**************************************************************************** -- cgit From e8e07a26eb1365d195c0345ad075ff828517fe53 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 6 Jun 2001 22:04:26 +0000 Subject: Changes to use new genrand code that got missed while I was in Japan. Jeremy. (This used to be commit 5a15831b9ae79ce1ce34d5574fe5da114d184e45) --- source3/lib/util_sock.c | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index b59debe929..144498138a 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -942,27 +942,6 @@ connect_again: return res; } - -/******************************************************************* - Reset the 'done' variables so after a client process is created - from a fork call these calls will be re-done. This should be - expanded if more variables need reseting. - ******************************************************************/ - - -void reset_globals_after_fork(void) -{ - /* - * Re-seed the random crypto generator, so all smbd's - * started from the same parent won't generate the same - * sequence. - */ - { - unsigned char dummy; - generate_random_buffer( &dummy, 1, True); - } -} - /* the following 3 client_*() functions are nasty ways of allowing some generic functions to get info that really should be hidden in particular modules */ -- cgit From f63ee18c684af33342de2c5757f9fdf0b7d84997 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 9 Jun 2001 01:38:54 +0000 Subject: *Wonderful* patch from Andrew Bartlett that will help ensure tdb's are cleaned on clients abending connections. Thanks Andrew ! Jeremy. (This used to be commit 1b3977c5367a0b713b194f369abd9872ae01ac2a) --- source3/lib/util_sock.c | 64 +++++++++++++++---------------------------------- 1 file changed, 19 insertions(+), 45 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 144498138a..d741f038ce 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -661,8 +661,10 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout) if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) { DEBUG(0,("Invalid packet length! (%d bytes).\n",len)); - if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) - exit(1); + if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) { + smb_read_error = READ_ERROR; + return False; + } } if(len > 0) { @@ -710,56 +712,28 @@ BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) return ret; } -/**************************************************************************** - send an null session message to a fd -****************************************************************************/ - -BOOL send_null_session_msg(int fd) -{ - ssize_t ret; - uint32 blank = 0; - size_t len = 4; - size_t nwritten=0; - char *buffer = (char *)␣ - - while (nwritten < len) - { - ret = write_socket(fd,buffer+nwritten,len - nwritten); - if (ret <= 0) - { - DEBUG(0,("send_null_session_msg: Error writing %d bytes to client. %d. Exiting\n",(int)len,(int)ret)); - exit(1); - } - nwritten += ret; - } - - DEBUG(10,("send_null_session_msg: sent 4 null bytes to client.\n")); - return True; -} - /**************************************************************************** send an smb to a fd ****************************************************************************/ BOOL send_smb(int fd,char *buffer) { - size_t len; - size_t nwritten=0; - ssize_t ret; - len = smb_len(buffer) + 4; - - while (nwritten < len) - { - ret = write_socket(fd,buffer+nwritten,len - nwritten); - if (ret <= 0) - { - DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",(int)len,(int)ret)); - exit(1); - } - nwritten += ret; - } + size_t len; + size_t nwritten=0; + ssize_t ret; + len = smb_len(buffer) + 4; + + while (nwritten < len) { + ret = write_socket(fd,buffer+nwritten,len - nwritten); + if (ret <= 0) { + DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n", + (int)len,(int)ret, strerror(errno) )); + return False; + } + nwritten += ret; + } - return True; + return True; } /**************************************************************************** -- cgit From 7b01c627c62ef6be519110fcd6cb88c86c5cd0ab Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 18 Jun 2001 05:42:18 +0000 Subject: Removed silly Get_Hostbyname() wrapper as DNS names are case-insensitive and the use of this function only increased timeouts when Samba queries a broken DNS server. (This used to be commit 720fea53603b2f99153709e6717ca930ab60ca9f) --- source3/lib/util_sock.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index d741f038ce..b0426e3809 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -791,9 +791,9 @@ int open_socket_in(int type, int port, int dlevel,uint32 socket_addr, BOOL rebin { DEBUG(0,("gethostname failed\n")); return -1; } /* get host info */ - if ((hp = Get_Hostbyname(host_name)) == 0) + if ((hp = sys_gethostbyname(host_name)) == 0) { - DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",host_name)); + DEBUG(0,( "sys_gethostbyname: Unknown host %s\n",host_name)); return -1; } @@ -945,8 +945,8 @@ static BOOL matchname(char *remotehost,struct in_addr addr) struct hostent *hp; int i; - if ((hp = Get_Hostbyname(remotehost)) == 0) { - DEBUG(0,("Get_Hostbyname(%s): lookup failure.\n", remotehost)); + if ((hp = sys_gethostbyname(remotehost)) == 0) { + DEBUG(0,("sys_gethostbyname(%s): lookup failure.\n", remotehost)); return False; } -- cgit From 868d010aa1b614109b54928e46eb626a1d320a2d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 22 Jun 2001 15:14:45 +0000 Subject: added the ability to test smbd safely as an ordinary user. The way it works is that libsmb/ creates a local tcp socket then launches smbd as a subprocess attached to that socket. smbd thinks it is being launched from inetd. to use it do the following: - compile with -DSMB_REGRESSION_TEST - run like this (also works with smbtorture etc) export SMBD_TEST=1 export LIBSMB_PROG=bin/smbd smbclient //server/share -Uuser%pass obviously you need to setup a smb.conf etc. Using --prefix to configure is useful. The aim of all this stuff is to add a decent set of regression tests to the build farm, so we know if smbd actually runs correctly on all the platforms, not just builds. We can run smbtorture, masktest, locktest etc, plus a bunch of smbclient scripts and any new tests we write. This doesn't help much with nmbd (at least not yet) but its a good start. (This used to be commit 7e8e6ae9a88c4d2587eb4e7f0501cd71bd36ebb2) --- source3/lib/util_sock.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index b0426e3809..426d0572f1 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1145,3 +1145,84 @@ int create_pipe_socket(char *dir, int dir_perms, return s; } + +#ifdef SMB_REGRESSION_TEST +/******************************************************************* +this is like socketpair but uses tcp. It is used by the Samba +user testing + ******************************************************************/ +static int socketpair_tcp(int fd[2]) +{ + int listener; + struct sockaddr sock; + socklen_t socklen = sizeof(sock); + int len = socklen; + int one = 1; + int connect_done = 0; + + fd[0] = fd[1] = listener = -1; + + memset(&sock, 0, sizeof(sock)); + + if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed; + + setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one)); + + if (listen(listener, 1) != 0) goto failed; + + if (getsockname(listener, &sock, &socklen) != 0) goto failed; + + if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed; + + setsockopt(fd[1],SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one)); + + set_blocking(fd[1], 0); + + if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) { + if (errno != EINPROGRESS) goto failed; + } else { + connect_done = 1; + } + + if ((fd[0] = accept(listener, &sock, &len)) == -1) goto failed; + + setsockopt(fd[0],SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one)); + + close(listener); + if (connect_done == 0) { + if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0) goto failed; + } + + set_blocking(fd[1], 1); + + /* all OK! */ + return 0; + + failed: + if (fd[0] != -1) close(fd[0]); + if (fd[1] != -1) close(fd[1]); + if (listener != -1) close(listener); + return -1; +} + + +/******************************************************************* +run a program on a local tcp socket, this is used to launch smbd +in the test code + ******************************************************************/ +int sock_exec(char *prog) +{ + int fd[2]; + if (socketpair_tcp(fd) != 0) return -1; + if (fork() == 0) { + close(fd[0]); + close(0); + close(1); + dup(fd[1]); + dup(fd[1]); + exit(system(prog)); + } + close(fd[1]); + return fd[0]; +} +#endif -- cgit From 8b79a473faf2ff25acb220500158920490c71576 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 25 Jun 2001 00:46:34 +0000 Subject: - make the regresison test mode code build in by default. This should allow us to have test targets without special configure options - fixed make proto so that it actually does something (This used to be commit 55109a752578e9389d853cb27ec17c2114ecff77) --- source3/lib/util_sock.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 426d0572f1..7f8b83ec7d 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1146,36 +1146,33 @@ int create_pipe_socket(char *dir, int dir_perms, return s; } -#ifdef SMB_REGRESSION_TEST /******************************************************************* this is like socketpair but uses tcp. It is used by the Samba -user testing +regression test code +The function guarantees that nobody else can attach to the socket, +or if they do that this function fails and the socket gets closed +returns 0 on success, -1 on failure +the resulting file descriptors are symmetrical ******************************************************************/ static int socketpair_tcp(int fd[2]) { int listener; struct sockaddr sock; socklen_t socklen = sizeof(sock); - int len = socklen; - int one = 1; int connect_done = 0; - + fd[0] = fd[1] = listener = -1; memset(&sock, 0, sizeof(sock)); if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed; - setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one)); - if (listen(listener, 1) != 0) goto failed; if (getsockname(listener, &sock, &socklen) != 0) goto failed; if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed; - setsockopt(fd[1],SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one)); - set_blocking(fd[1], 0); if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) { @@ -1184,9 +1181,7 @@ static int socketpair_tcp(int fd[2]) connect_done = 1; } - if ((fd[0] = accept(listener, &sock, &len)) == -1) goto failed; - - setsockopt(fd[0],SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one)); + if ((fd[0] = accept(listener, &sock, &socklen)) == -1) goto failed; close(listener); if (connect_done == 0) { @@ -1208,9 +1203,12 @@ static int socketpair_tcp(int fd[2]) /******************************************************************* run a program on a local tcp socket, this is used to launch smbd -in the test code +when regression testing +the return value is a socket which is attached to a subprocess +running "prog". stdin and stdout are attached. stderr is left +attached to the original stderr ******************************************************************/ -int sock_exec(char *prog) +int sock_exec(const char *prog) { int fd[2]; if (socketpair_tcp(fd) != 0) return -1; @@ -1225,4 +1223,4 @@ int sock_exec(char *prog) close(fd[1]); return fd[0]; } -#endif + -- cgit From c6f647dfd9dff2e9681f084b01cc7267b779f8fd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 27 Jun 2001 10:44:14 +0000 Subject: handle EISCONN in socketpair_tcp this should get the auto-tests working on IRIX (This used to be commit 87f90d48d857828a6ed12bdc58d0d881be45dfce) --- source3/lib/util_sock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 7f8b83ec7d..d7bef0697e 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1185,7 +1185,8 @@ static int socketpair_tcp(int fd[2]) close(listener); if (connect_done == 0) { - if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0) goto failed; + if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0 + && errno != EISCONN) goto failed; } set_blocking(fd[1], 1); -- cgit From 5ac133bac731e3f014df35126dd5ecb87837b8a6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 27 Jun 2001 13:58:44 +0000 Subject: on sco2 socketpair_tcp needs a bind (This used to be commit d8e5409ebb883844d9a1abc9840af1809957a444) --- source3/lib/util_sock.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index d7bef0697e..e3673f011a 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1158,6 +1158,7 @@ static int socketpair_tcp(int fd[2]) { int listener; struct sockaddr sock; + struct sockaddr_in sock2; socklen_t socklen = sizeof(sock); int connect_done = 0; @@ -1167,6 +1168,14 @@ static int socketpair_tcp(int fd[2]) if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed; + memset(&sock2, 0, sizeof(sock2)); +#ifdef HAVE_SOCK_SIN_LEN + sock2.sin_len = sizeof(sock2); +#endif + sock2.sin_family = PF_INET; + + bind(listener, (struct sockaddr *)&sock2, sizeof(sock2)); + if (listen(listener, 1) != 0) goto failed; if (getsockname(listener, &sock, &socklen) != 0) goto failed; -- cgit From 8f91108faf42fbaedd7ed8bbfb107f216fee1bbe Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 27 Jun 2001 17:26:29 +0000 Subject: Syncup between 2.2 and HEAD. Jeremy. (This used to be commit 39d4131a4571c9c7a96bdc2f6cd6be80a6c330af) --- source3/lib/util_sock.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index e3673f011a..ccbc86bb0b 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -174,26 +174,25 @@ void set_socket_options(int fd, char *options) ssize_t read_udp_socket(int fd,char *buf,size_t len) { - ssize_t ret; - struct sockaddr_in sock; - int socklen; - - socklen = sizeof(sock); - memset((char *)&sock,'\0',socklen); - memset((char *)&lastip,'\0',sizeof(lastip)); - ret = (ssize_t)recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen); - if (ret <= 0) { - DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno))); - return(0); - } + ssize_t ret; + struct sockaddr_in sock; + socklen_t socklen = sizeof(sock); - lastip = sock.sin_addr; - lastport = ntohs(sock.sin_port); + memset((char *)&sock,'\0',socklen); + memset((char *)&lastip,'\0',sizeof(lastip)); + ret = (ssize_t)recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen); + if (ret <= 0) { + DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno))); + return(0); + } - DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n", - inet_ntoa(lastip), lastport, ret)); + lastip = sock.sin_addr; + lastport = ntohs(sock.sin_port); - return(ret); + DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n", + inet_ntoa(lastip), lastport, ret)); + + return(ret); } /**************************************************************************** -- cgit From b470d157cd74d2278cb926974c61a5062928e24a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 3 Jul 2001 03:56:49 +0000 Subject: fixed socketpair_tcp for OpenBSD (This used to be commit d99ce6a5e3455ed38ca3c1ac676b5048edf8c706) --- source3/lib/util_sock.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index ccbc86bb0b..01cff85f65 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1156,7 +1156,7 @@ the resulting file descriptors are symmetrical static int socketpair_tcp(int fd[2]) { int listener; - struct sockaddr sock; + struct sockaddr_in sock; struct sockaddr_in sock2; socklen_t socklen = sizeof(sock); int connect_done = 0; @@ -1177,19 +1177,21 @@ static int socketpair_tcp(int fd[2]) if (listen(listener, 1) != 0) goto failed; - if (getsockname(listener, &sock, &socklen) != 0) goto failed; + if (getsockname(listener, (struct sockaddr *)&sock, &socklen) != 0) goto failed; if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed; set_blocking(fd[1], 0); + sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) { if (errno != EINPROGRESS) goto failed; } else { connect_done = 1; } - if ((fd[0] = accept(listener, &sock, &socklen)) == -1) goto failed; + if ((fd[0] = accept(listener, (struct sockaddr *)&sock, &socklen)) == -1) goto failed; close(listener); if (connect_done == 0) { @@ -1220,7 +1222,10 @@ attached to the original stderr int sock_exec(const char *prog) { int fd[2]; - if (socketpair_tcp(fd) != 0) return -1; + if (socketpair_tcp(fd) != 0) { + DEBUG(0,("socketpair_tcp failed (%s)\n", strerror(errno))); + return -1; + } if (fork() == 0) { close(fd[0]); close(0); -- cgit From 527e824293ee934ca5da0ef5424efe5ab7757248 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 4 Jul 2001 07:36:09 +0000 Subject: strchr and strrchr are macros when compiling with optimisation in gcc, so we can't redefine them. damn. (This used to be commit c41fc06376d1a2b83690612304e85010b5e5f3cf) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 01cff85f65..a55ef1a92e 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -127,7 +127,7 @@ void set_socket_options(int fd, char *options) char *p; BOOL got_value = False; - if ((p = strchr(tok,'='))) { + if ((p = strchr_m(tok,'='))) { *p = 0; value = atoi(p+1); got_value = True; -- cgit From 61e6d867c4afd27e0a2358282532c478707f30db Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 5 Jul 2001 04:44:09 +0000 Subject: use alpha_strcpy on DNS names (This used to be commit f6f9e95dd9254c6aad19d4fa1ff891bfa33070b6) --- source3/lib/util_sock.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index a55ef1a92e..760ceceede 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1016,6 +1016,12 @@ char *get_socket_name(int fd) pstrcpy(name_buf,"UNKNOWN"); } } + + alpha_strcpy(name_buf, name_buf, "_-.", sizeof(name_buf)); + if (strstr(name_buf,"..")) { + pstrcpy(name_buf, "UNKNOWN"); + } + return name_buf; } -- cgit From 575e609c3ba3f6557b66935a9ad5538cf241b057 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2001 02:53:48 +0000 Subject: much better handling of broken DNS servers we no longer lookup our own name when we create a socket in open_socket_in(). That makes things work much better with the broken DNS server at VA (This used to be commit a83d506e5cd6cef23298211b2fe4e0e25c9e5f48) --- source3/lib/util_sock.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 760ceceede..f18fa2e019 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -780,32 +780,18 @@ open a socket of the specified type, port and address for incoming data int open_socket_in(int type, int port, int dlevel,uint32 socket_addr, BOOL rebind) { - struct hostent *hp; struct sockaddr_in sock; - pstring host_name; int res; - /* get my host name */ - if (gethostname(host_name, MAXHOSTNAMELEN) == -1) - { DEBUG(0,("gethostname failed\n")); return -1; } - - /* get host info */ - if ((hp = sys_gethostbyname(host_name)) == 0) - { - DEBUG(0,( "sys_gethostbyname: Unknown host %s\n",host_name)); - return -1; - } - memset((char *)&sock,'\0',sizeof(sock)); - memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length); #ifdef HAVE_SOCK_SIN_LEN sock.sin_len = sizeof(sock); #endif sock.sin_port = htons( port ); - sock.sin_family = hp->h_addrtype; + sock.sin_family = AF_INET; sock.sin_addr.s_addr = socket_addr; - res = socket(hp->h_addrtype, type, 0); + res = socket(AF_INET, type, 0); if (res == -1) { DEBUG(0,("socket failed\n")); return -1; } -- cgit From c45fbe69f5b7a57fea9ba18cfa47e63b42de7992 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 23 Aug 2001 16:25:57 +0000 Subject: better error reporting for servers that don't do port 445 (This used to be commit a896dc299eba12886d800e6c88309d534232cabc) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index f18fa2e019..d7a2a2e7b9 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -889,7 +889,7 @@ connect_again: #endif if (ret < 0) { - DEBUG(1,("error connecting to %s:%d (%s)\n", + DEBUG(2,("error connecting to %s:%d (%s)\n", inet_ntoa(*addr),port,strerror(errno))); close(res); return -1; -- cgit From 18d3c23e36f5d97deed3c26e90f6573a83640436 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Fri, 24 Aug 2001 01:49:23 +0000 Subject: get rid of old debug code and possible socket leak (This used to be commit f942397d6515402be0c7c1085fc2e6d48eb6928f) --- source3/lib/util_sock.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index d7a2a2e7b9..8f2eceabbc 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -814,20 +814,12 @@ int open_socket_in(int type, int port, int dlevel,uint32 socket_addr, BOOL rebin /* now we've got a socket - we need to bind it */ if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) { - if (port) { if (port == SMB_PORT || port == NMB_PORT) DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n", port,inet_ntoa(sock.sin_addr),strerror(errno))); close(res); - if (dlevel > 0 && port < 1000) - port = 7999; - - if (port >= 1000 && port < 9000) - return(open_socket_in(type,port+1,dlevel,socket_addr,rebind)); - } - - return(-1); + return(-1); } DEBUG(3,("bind succeeded on port %d\n",port)); -- cgit From 1beb3867fb02671960ee5f1ab0101a1be125e62a Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Sun, 26 Aug 2001 04:16:51 +0000 Subject: Fussing with debug lines in open_socket_in(). I cleaned up some slightly funky code that was simply setting a local int to 0 or 1 and also added calls to strerror() in some of the debug lines. The use of the dlevel parameter in this function is a little awkward. There should probably be some comments about it in the source. (This used to be commit 3031e7acdc4eac99a736f45161dee9bf81c1cc87) --- source3/lib/util_sock.c | 88 +++++++++++++++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 32 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 8f2eceabbc..363e775186 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -775,56 +775,80 @@ BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type) } /**************************************************************************** -open a socket of the specified type, port and address for incoming data +open a socket of the specified type, port, and address for incoming data ****************************************************************************/ -int open_socket_in(int type, int port, int dlevel,uint32 socket_addr, BOOL rebind) -{ +int open_socket_in( int type, int port, int dlevel, + uint32 socket_addr, BOOL rebind ) + { struct sockaddr_in sock; int res; - memset((char *)&sock,'\0',sizeof(sock)); + /* Clear the sockaddr_in structure (why not bzero()?). */ + memset( (char *)&sock, '\0', sizeof(sock) ); #ifdef HAVE_SOCK_SIN_LEN - sock.sin_len = sizeof(sock); + sock.sin_len = sizeof(sock); #endif - sock.sin_port = htons( port ); - sock.sin_family = AF_INET; + sock.sin_port = htons( port ); + sock.sin_family = AF_INET; sock.sin_addr.s_addr = socket_addr; - res = socket(AF_INET, type, 0); - if (res == -1) - { DEBUG(0,("socket failed\n")); return -1; } + res = socket( AF_INET, type, 0 ); + if( res < 0 ) + { + if( DEBUGLVL(0) ) + { + dbgtext( "open_socket_in(): socket() call failed: " ); + dbgtext( "%s\n", strerror( errno ) ); + } + return -1; + } + + /* This block sets/clears the SO_REUSEADDR and possibly SO_REUSEPORT. */ { - int val=1; - if(rebind) - val=1; - else - val=0; - if(setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val)) == -1) - DEBUG(dlevel,("setsockopt: SO_REUSEADDR=%d on port %d failed with error = %s\n", - val, port, strerror(errno) )); + int val = rebind ? 1 : 0; + if( setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val)) == -1 ) + { + if( DEBUGLVL( dlevel ) ) + { + dbgtext( "open_socket_in(): setsockopt: " ); + dbgtext( "SO_REUSEADDR = %d ", val?"True":"False" ); + dbgtext( "on port %d failed ", port ); + dbgtext( "with error = %s\n", strerror(errno) ); + } + } #ifdef SO_REUSEPORT - if(setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val)) == -1) - DEBUG(dlevel,("setsockopt: SO_REUSEPORT=%d on port %d failed with error = %s\n", - val, port, strerror(errno) )); + if( setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val)) == -1 ) + { + if( DEBUGLVL( dlevel ) ) + { + dbgtext( "open_socket_in(): setsockopt: " + dbgtext( "SO_REUSEPORT = %d ", val?"True":"False" ); + dbgtext( "on port %d failed ", port ); + dbgtext( "with error = %s\n", strerror(errno) ); + } + } #endif /* SO_REUSEPORT */ } /* now we've got a socket - we need to bind it */ - if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) - { - if (port == SMB_PORT || port == NMB_PORT) - DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n", - port,inet_ntoa(sock.sin_addr),strerror(errno))); - close(res); - - return(-1); + if( bind( res, (struct sockaddr *)&sock, sizeof(sock) ) < 0 ) + { + if( DEBUGLVL(dlevel) && (port == SMB_PORT || port == NMB_PORT) ) + { + dbgtext( "bind failed on port %d ", port ); + dbgtext( "socket_addr = %s.\n", inet_ntoa( sock.sin_addr ) ); + dbgtext( "Error = %s\n", strerror(errno) ); + } + close( res ); + return( -1 ); } - DEBUG(3,("bind succeeded on port %d\n",port)); - return res; -} + DEBUG( 3, ( "bind succeeded on port %d\n", port ) ); + + return( res ); + } /**************************************************************************** create an outgoing socket. timeout is in milliseconds. -- cgit From cee2b0dc2c55f659c84ed41d95f7459bc7764c33 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 26 Aug 2001 19:11:33 +0000 Subject: bzero is not used (deprecated) as it's a BSDism. Syscalls must check for -1, not < 0 (POSIX). Formating (tab) fixups. Jeremy. (This used to be commit 7263949584a5e01fd5316770861a7550bd3f1155) --- source3/lib/util_sock.c | 114 ++++++++++++++++++++++-------------------------- 1 file changed, 52 insertions(+), 62 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 363e775186..144f7cbd68 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -775,80 +775,70 @@ BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type) } /**************************************************************************** -open a socket of the specified type, port, and address for incoming data + Open a socket of the specified type, port, and address for incoming data. ****************************************************************************/ -int open_socket_in( int type, int port, int dlevel, - uint32 socket_addr, BOOL rebind ) - { - struct sockaddr_in sock; - int res; +int open_socket_in( int type, int port, int dlevel, uint32 socket_addr, BOOL rebind ) +{ + struct sockaddr_in sock; + int res; - /* Clear the sockaddr_in structure (why not bzero()?). */ - memset( (char *)&sock, '\0', sizeof(sock) ); + memset( (char *)&sock, '\0', sizeof(sock) ); #ifdef HAVE_SOCK_SIN_LEN - sock.sin_len = sizeof(sock); + sock.sin_len = sizeof(sock); #endif - sock.sin_port = htons( port ); - sock.sin_family = AF_INET; - sock.sin_addr.s_addr = socket_addr; - - res = socket( AF_INET, type, 0 ); - if( res < 0 ) - { - if( DEBUGLVL(0) ) - { - dbgtext( "open_socket_in(): socket() call failed: " ); - dbgtext( "%s\n", strerror( errno ) ); - } - return -1; - } + sock.sin_port = htons( port ); + sock.sin_family = AF_INET; + sock.sin_addr.s_addr = socket_addr; + + res = socket( AF_INET, type, 0 ); + if( res == -1 ) { + if( DEBUGLVL(0) ) { + dbgtext( "open_socket_in(): socket() call failed: " ); + dbgtext( "%s\n", strerror( errno ) ); + } + return -1; + } - /* This block sets/clears the SO_REUSEADDR and possibly SO_REUSEPORT. */ - { - int val = rebind ? 1 : 0; - if( setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val)) == -1 ) - { - if( DEBUGLVL( dlevel ) ) - { - dbgtext( "open_socket_in(): setsockopt: " ); - dbgtext( "SO_REUSEADDR = %d ", val?"True":"False" ); - dbgtext( "on port %d failed ", port ); - dbgtext( "with error = %s\n", strerror(errno) ); - } - } + /* This block sets/clears the SO_REUSEADDR and possibly SO_REUSEPORT. */ + { + int val = rebind ? 1 : 0; + if( setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val)) == -1 ) { + if( DEBUGLVL( dlevel ) ) { + dbgtext( "open_socket_in(): setsockopt: " ); + dbgtext( "SO_REUSEADDR = %d ", val?"True":"False" ); + dbgtext( "on port %d failed ", port ); + dbgtext( "with error = %s\n", strerror(errno) ); + } + } #ifdef SO_REUSEPORT - if( setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val)) == -1 ) - { - if( DEBUGLVL( dlevel ) ) - { - dbgtext( "open_socket_in(): setsockopt: " - dbgtext( "SO_REUSEPORT = %d ", val?"True":"False" ); - dbgtext( "on port %d failed ", port ); - dbgtext( "with error = %s\n", strerror(errno) ); - } - } + if( setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val)) == -1 ) { + if( DEBUGLVL( dlevel ) ) { + dbgtext( "open_socket_in(): setsockopt: " + dbgtext( "SO_REUSEPORT = %d ", val?"True":"False" ); + dbgtext( "on port %d failed ", port ); + dbgtext( "with error = %s\n", strerror(errno) ); + } + } #endif /* SO_REUSEPORT */ - } + } - /* now we've got a socket - we need to bind it */ - if( bind( res, (struct sockaddr *)&sock, sizeof(sock) ) < 0 ) - { - if( DEBUGLVL(dlevel) && (port == SMB_PORT || port == NMB_PORT) ) - { - dbgtext( "bind failed on port %d ", port ); - dbgtext( "socket_addr = %s.\n", inet_ntoa( sock.sin_addr ) ); - dbgtext( "Error = %s\n", strerror(errno) ); - } - close( res ); - return( -1 ); - } + /* now we've got a socket - we need to bind it */ + if( bind( res, (struct sockaddr *)&sock, sizeof(sock) ) == -1 ) { + if( DEBUGLVL(dlevel) && (port == SMB_PORT || port == NMB_PORT) ) { + dbgtext( "bind failed on port %d ", port ); + dbgtext( "socket_addr = %s.\n", inet_ntoa( sock.sin_addr ) ); + dbgtext( "Error = %s\n", strerror(errno) ); + } + close( res ); + return( -1 ); + } - DEBUG( 3, ( "bind succeeded on port %d\n", port ) ); + DEBUG( 3, ( "bind succeeded on port %d\n", port ) ); - return( res ); - } + return( res ); + } /**************************************************************************** create an outgoing socket. timeout is in milliseconds. -- cgit From b031af348c7dcc8c74bf49945211c466b8eca079 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 27 Aug 2001 19:46:22 +0000 Subject: converted another bunch of stuff to NTSTATUS (This used to be commit 1d36250e338ae0ff9fbbf86019809205dd97d05e) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 144f7cbd68..16b457c413 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -807,7 +807,7 @@ int open_socket_in( int type, int port, int dlevel, uint32 socket_addr, BOOL reb if( setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val)) == -1 ) { if( DEBUGLVL( dlevel ) ) { dbgtext( "open_socket_in(): setsockopt: " ); - dbgtext( "SO_REUSEADDR = %d ", val?"True":"False" ); + dbgtext( "SO_REUSEADDR = %s ", val?"True":"False" ); dbgtext( "on port %d failed ", port ); dbgtext( "with error = %s\n", strerror(errno) ); } -- cgit From 1f079939001fa4a48b37c319049bc273db85a79f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 28 Aug 2001 01:28:01 +0000 Subject: fixed typo (This used to be commit 2d1829dfd041336a587443435d8dccab365a2b56) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 16b457c413..47f1d507ed 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -815,7 +815,7 @@ int open_socket_in( int type, int port, int dlevel, uint32 socket_addr, BOOL reb #ifdef SO_REUSEPORT if( setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val)) == -1 ) { if( DEBUGLVL( dlevel ) ) { - dbgtext( "open_socket_in(): setsockopt: " + dbgtext( "open_socket_in(): setsockopt: "); dbgtext( "SO_REUSEPORT = %d ", val?"True":"False" ); dbgtext( "on port %d failed ", port ); dbgtext( "with error = %s\n", strerror(errno) ); -- cgit From 5366c4c542b2a1c7bcc268daba02af25ce6eab6e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 13 Sep 2001 00:30:47 +0000 Subject: added a new global option "hostname lookups = yes/no" This should finally kill off the remaining places where we attempt reverse lookups of the IP of the client. It may be that some pam modules called via the session code will need "hostname lookups = yes" but I've left it off by default as most sites don't need it and so many sites have broken reverse maps (This used to be commit 2b83ad03965d00bba88fe56452d2990099b75ef1) --- source3/lib/util_sock.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 47f1d507ed..9d7e5df303 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -984,6 +984,14 @@ char *get_socket_name(int fd) struct hostent *hp; struct in_addr addr; char *p; + + /* reverse lookups can be *very* expensive, and in many + situations won't work because many networks don't link dhcp + with dns. To avoid the delay we avoid the lookup if + possible */ + if (!lp_hostname_lookups()) { + return get_socket_addr(fd); + } p = get_socket_addr(fd); -- cgit From 2c4d1d39b148b8587deb8fca2db4113354165989 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 26 Sep 2001 17:29:53 +0000 Subject: OpenSSL merge from 2.2 (This used to be commit efc6df5a3914da9e7b792ccaccd1403c72c09f78) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 9d7e5df303..e1f291386e 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -22,7 +22,7 @@ #include "includes.h" #ifdef WITH_SSL -#include +#include #undef Realloc /* SSLeay defines this and samba has a function of this name */ extern SSL *ssl; extern int sslFd; -- cgit From dc1fc3ee8ec2199bc73bb5d7ec711c6800f61d65 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 2 Oct 2001 04:29:50 +0000 Subject: Removed 'extern int DEBUGLEVEL' as it is now in the smb.h header. (This used to be commit 2d0922b0eabfdc0aaf1d0797482fef47ed7fde8e) --- source3/lib/util_sock.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index e1f291386e..5979cd8b5a 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -28,8 +28,6 @@ extern SSL *ssl; extern int sslFd; #endif /* WITH_SSL */ -extern int DEBUGLEVEL; - /* the last IP received from */ struct in_addr lastip; @@ -1243,4 +1241,3 @@ int sock_exec(const char *prog) close(fd[1]); return fd[0]; } - -- cgit From 7cd889f566ebe352721943e53a055db5b817f12f Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sat, 20 Oct 2001 23:34:40 +0000 Subject: Converted a bunch of 0x85 constants to SMBkeepalive. (This used to be commit b16a15a13ed7d267c6366abaeeb3ccafa5776f5e) --- source3/lib/util_sock.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 5979cd8b5a..681bc3065d 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -396,7 +396,7 @@ BOOL send_keepalive(int client) { unsigned char buf[4]; - buf[0] = 0x85; + buf[0] = SMBkeepalive; buf[1] = buf[2] = buf[3] = 0; return(write_socket_data(client,(char *)buf,4) == 4); @@ -592,7 +592,7 @@ static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int len = smb_len(inbuf); msg_type = CVAL(inbuf,0); - if (msg_type == 0x85) + if (msg_type == SMBkeepalive) DEBUG(5,("Got keepalive packet\n")); } @@ -620,7 +620,7 @@ ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout) return len; /* Ignore session keepalives. */ - if(CVAL(inbuf,0) != 0x85) + if(CVAL(inbuf,0) != SMBkeepalive) break; } @@ -702,7 +702,7 @@ BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) } /* Ignore session keepalive packets. */ - if(CVAL(buffer,0) != 0x85) + if(CVAL(buffer,0) != SMBkeepalive) break; } show_msg(buffer); -- cgit From 0c8ef484792b568dbec79fbf45cbf42534114ce5 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 24 Oct 2001 00:36:49 +0000 Subject: Removed unused function. (This used to be commit ef06de2a1ca434ab658940146b5d6c16bf580bb3) --- source3/lib/util_sock.c | 68 ------------------------------------------------- 1 file changed, 68 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 681bc3065d..340a83cf13 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1081,74 +1081,6 @@ int open_pipe_sock(char *path) return sock; } -int create_pipe_socket(char *dir, int dir_perms, - char *path, int path_perms) -{ - int s; - struct sockaddr_un sa; - - DEBUG(0,("create_pipe_socket: %s %d %s %d\n", - dir, dir_perms, path, path_perms)); - - DEBUG(0,("*** RACE CONDITION. PLEASE SOMEONE EXAMINE create_pipe_Socket AND FIX IT ***\n")); - - mkdir(dir, dir_perms); - - if (chmod(dir, dir_perms) < 0) - { - DEBUG(0, ("chmod on %s failed\n", dir)); - return -1; - } - - if (!remove(path)) - { - DEBUG(0, ("remove on %s failed\n", path)); - } - - /* start listening on unix socket */ - s = socket(AF_UNIX, SOCK_STREAM, 0); - - if (s < 0) - { - DEBUG(0, ("socket open failed\n")); - return -1; - } - - ZERO_STRUCT(sa); - sa.sun_family = AF_UNIX; - safe_strcpy(sa.sun_path, path, sizeof(sa.sun_path)-1); - - if (bind(s, (struct sockaddr*) &sa, sizeof(sa)) < 0) - { - DEBUG(0, ("socket bind to %s failed\n", sa.sun_path)); - close(s); - remove(path); - return -1; - } - - if (s == -1) - { - DEBUG(0,("bind failed\n")); - remove(path); - return -1; - } - - if (path_perms != 0) - { - chmod(path, path_perms); - } - - if (listen(s, 5) == -1) - { - DEBUG(0,("listen failed\n")); - return -1; - } - - DEBUG(5,("unix socket opened: %s\n", path)); - - return s; -} - /******************************************************************* this is like socketpair but uses tcp. It is used by the Samba regression test code -- cgit From ad2974cd05b4d08c8b92f505bf95aa8e8533235f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 24 Nov 2001 14:16:41 +0000 Subject: added "net join" command this completes the first stage of the smbd ADS support (This used to be commit 058a5aee901e6609969ef7e1d482a720a84a4a12) --- source3/lib/util_sock.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 340a83cf13..045e18ac22 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -905,6 +905,37 @@ connect_again: return res; } +/* + open a connected UDP socket to host on port +*/ +int open_udp_socket(const char *host, int port) +{ + int type = SOCK_DGRAM; + struct sockaddr_in sock_out; + int res; + struct in_addr *addr; + + addr = interpret_addr2(host); + + res = socket(PF_INET, type, 0); + if (res == -1) { + return -1; + } + + memset((char *)&sock_out,'\0',sizeof(sock_out)); + putip((char *)&sock_out.sin_addr,(char *)addr); + sock_out.sin_port = htons(port); + sock_out.sin_family = PF_INET; + + if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))) { + close(res); + return -1; + } + + return res; +} + + /* the following 3 client_*() functions are nasty ways of allowing some generic functions to get info that really should be hidden in particular modules */ -- cgit From 93d458c5f68a7168ce543e820906bc55a5d3a339 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 20 Dec 2001 10:02:30 +0000 Subject: fixed warnings on irix and crash bug on big endian machines (This used to be commit cc6c263993eaf0715f231fc80ca7e6e65694548b) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 045e18ac22..a56a974193 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -814,7 +814,7 @@ int open_socket_in( int type, int port, int dlevel, uint32 socket_addr, BOOL reb if( setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val)) == -1 ) { if( DEBUGLVL( dlevel ) ) { dbgtext( "open_socket_in(): setsockopt: "); - dbgtext( "SO_REUSEPORT = %d ", val?"True":"False" ); + dbgtext( "SO_REUSEPORT = %s ", val?"True":"False" ); dbgtext( "on port %d failed ", port ); dbgtext( "with error = %s\n", strerror(errno) ); } -- cgit From 0d1ecbbb73e958707612f9c9308c1d20e9b84909 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 13 Jan 2002 11:13:54 +0000 Subject: I'm doing some things towards the NamedPipes game with lckl and he has asked me to move this from being a static to matching its mate in lib/util_sock.c. In any case, this should discorage anybody from using the 'wrong' version of this function. (ie the one from TNG, which needs a bit more error checking depending on use). Andrew Bartlett (This used to be commit e6a3a01f795a85d908180ff19469ce09a2803512) --- source3/lib/util_sock.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index a56a974193..9f01d8223d 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1,8 +1,9 @@ /* Unix SMB/Netbios implementation. - Version 1.9. + Version 3.0. Samba utility functions Copyright (C) Andrew Tridgell 1992-1998 + Copyright (C) Tim Potter 2000-2001 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1112,6 +1113,107 @@ int open_pipe_sock(char *path) return sock; } +/******************************************************************* + Create protected unix domain socket. + + some unixen cannot set permissions on a ux-dom-sock, so we + have to make sure that the directory contains the protection + permissions, instead. + ******************************************************************/ +int create_pipe_sock(const char *socket_dir, + const char *socket_name, + mode_t dir_perms) +{ + struct sockaddr_un sunaddr; + struct stat st; + int sock; + mode_t old_umask; + pstring path; + + /* Create the socket directory or reuse the existing one */ + + if (lstat(socket_dir, &st) == -1) { + + if (errno == ENOENT) { + + /* Create directory */ + + if (mkdir(socket_dir, dir_perms) == -1) { + DEBUG(0, ("error creating socket directory " + "%s: %s\n", socket_dir, + strerror(errno))); + return -1; + } + + } else { + + DEBUG(0, ("lstat failed on socket directory %s: %s\n", + socket_dir, strerror(errno))); + return -1; + } + + } else { + + /* Check ownership and permission on existing directory */ + + if (!S_ISDIR(st.st_mode)) { + DEBUG(0, ("socket directory %s isn't a directory\n", + socket_dir)); + return -1; + } + + if ((st.st_uid != sec_initial_uid()) || + ((st.st_mode & 0777) != dir_perms)) { + DEBUG(0, ("invalid permissions on socket directory " + "%s\n", socket_dir)); + return -1; + } + } + + /* Create the socket file */ + + old_umask = umask(0); + + sock = socket(AF_UNIX, SOCK_STREAM, 0); + + if (sock == -1) { + perror("socket"); + umask(old_umask); + return -1; + } + + snprintf(path, sizeof(path), "%s/%s", socket_dir, socket_name); + + unlink(path); + memset(&sunaddr, 0, sizeof(sunaddr)); + sunaddr.sun_family = AF_UNIX; + safe_strcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)-1); + + if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) { + DEBUG(0, ("bind failed on pipe socket %s: %s\n", + path, + strerror(errno))); + close(sock); + umask(old_umask); + return -1; + } + + if (listen(sock, 5) == -1) { + DEBUG(0, ("listen failed on pipe socket %s: %s\n", + path, + strerror(errno))); + close(sock); + umask(old_umask); + return -1; + } + + umask(old_umask); + + /* Success! */ + + return sock; +} + /******************************************************************* this is like socketpair but uses tcp. It is used by the Samba regression test code -- cgit From fef35c5ce042d6b4472b194eabb91c287fd52fd1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 13 Jan 2002 12:33:42 +0000 Subject: Re-indent these two functions to make it actually possible to understand their contents... Andrew Bartlett (This used to be commit e20d69d51862ea3fd5a7317a9592bd4dc6e68bfd) --- source3/lib/util_sock.c | 322 ++++++++++++++++++++++++------------------------ 1 file changed, 161 insertions(+), 161 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 9f01d8223d..690b626224 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -203,109 +203,109 @@ ssize_t read_udp_socket(int fd,char *buf,size_t len) static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out) { - fd_set fds; - int selrtn; - ssize_t readret; - size_t nread = 0; - struct timeval timeout; - - /* just checking .... */ - if (maxcnt <= 0) - return(0); - - smb_read_error = 0; - - /* Blocking read */ - if (time_out <= 0) { - if (mincnt == 0) mincnt = maxcnt; - - while (nread < mincnt) { + fd_set fds; + int selrtn; + ssize_t readret; + size_t nread = 0; + struct timeval timeout; + + /* just checking .... */ + if (maxcnt <= 0) + return(0); + + smb_read_error = 0; + + /* Blocking read */ + if (time_out <= 0) { + if (mincnt == 0) mincnt = maxcnt; + + while (nread < mincnt) { #ifdef WITH_SSL - if(fd == sslFd){ - readret = SSL_read(ssl, buf + nread, maxcnt - nread); - }else{ - readret = read(fd, buf + nread, maxcnt - nread); - } + if(fd == sslFd){ + readret = SSL_read(ssl, buf + nread, maxcnt - nread); + }else{ + readret = read(fd, buf + nread, maxcnt - nread); + } #else /* WITH_SSL */ - readret = read(fd, buf + nread, maxcnt - nread); + readret = read(fd, buf + nread, maxcnt - nread); #endif /* WITH_SSL */ - - if (readret == 0) { - DEBUG(5,("read_socket_with_timeout: blocking read. EOF from client.\n")); - smb_read_error = READ_EOF; - return -1; - } - - if (readret == -1) { - DEBUG(0,("read_socket_with_timeout: read error = %s.\n", strerror(errno) )); - smb_read_error = READ_ERROR; - return -1; - } - nread += readret; - } - return((ssize_t)nread); - } - - /* Most difficult - timeout read */ - /* If this is ever called on a disk file and - mincnt is greater then the filesize then - system performance will suffer severely as - select always returns true on disk files */ - - /* Set initial timeout */ - timeout.tv_sec = (time_t)(time_out / 1000); - timeout.tv_usec = (long)(1000 * (time_out % 1000)); - - for (nread=0; nread < mincnt; ) { - FD_ZERO(&fds); - FD_SET(fd,&fds); - - selrtn = sys_select_intr(fd+1,&fds,&timeout); - - /* Check if error */ - if(selrtn == -1) { - /* something is wrong. Maybe the socket is dead? */ - DEBUG(0,("read_socket_with_timeout: timeout read. select error = %s.\n", strerror(errno) )); - smb_read_error = READ_ERROR; - return -1; - } - - /* Did we timeout ? */ - if (selrtn == 0) { - DEBUG(10,("read_socket_with_timeout: timeout read. select timed out.\n")); - smb_read_error = READ_TIMEOUT; - return -1; - } - + + if (readret == 0) { + DEBUG(5,("read_socket_with_timeout: blocking read. EOF from client.\n")); + smb_read_error = READ_EOF; + return -1; + } + + if (readret == -1) { + DEBUG(0,("read_socket_with_timeout: read error = %s.\n", strerror(errno) )); + smb_read_error = READ_ERROR; + return -1; + } + nread += readret; + } + return((ssize_t)nread); + } + + /* Most difficult - timeout read */ + /* If this is ever called on a disk file and + mincnt is greater then the filesize then + system performance will suffer severely as + select always returns true on disk files */ + + /* Set initial timeout */ + timeout.tv_sec = (time_t)(time_out / 1000); + timeout.tv_usec = (long)(1000 * (time_out % 1000)); + + for (nread=0; nread < mincnt; ) { + FD_ZERO(&fds); + FD_SET(fd,&fds); + + selrtn = sys_select_intr(fd+1,&fds,&timeout); + + /* Check if error */ + if(selrtn == -1) { + /* something is wrong. Maybe the socket is dead? */ + DEBUG(0,("read_socket_with_timeout: timeout read. select error = %s.\n", strerror(errno) )); + smb_read_error = READ_ERROR; + return -1; + } + + /* Did we timeout ? */ + if (selrtn == 0) { + DEBUG(10,("read_socket_with_timeout: timeout read. select timed out.\n")); + smb_read_error = READ_TIMEOUT; + return -1; + } + #ifdef WITH_SSL - if(fd == sslFd){ - readret = SSL_read(ssl, buf + nread, maxcnt - nread); - }else{ - readret = read(fd, buf + nread, maxcnt - nread); - } + if(fd == sslFd){ + readret = SSL_read(ssl, buf + nread, maxcnt - nread); + }else{ + readret = read(fd, buf + nread, maxcnt - nread); + } #else /* WITH_SSL */ - readret = read(fd, buf+nread, maxcnt-nread); + readret = read(fd, buf+nread, maxcnt-nread); #endif /* WITH_SSL */ - - if (readret == 0) { - /* we got EOF on the file descriptor */ - DEBUG(5,("read_socket_with_timeout: timeout read. EOF from client.\n")); - smb_read_error = READ_EOF; - return -1; - } - - if (readret == -1) { - /* the descriptor is probably dead */ - DEBUG(0,("read_socket_with_timeout: timeout read. read error = %s.\n", strerror(errno) )); - smb_read_error = READ_ERROR; - return -1; - } - - nread += readret; - } - - /* Return the number we got */ - return((ssize_t)nread); + + if (readret == 0) { + /* we got EOF on the file descriptor */ + DEBUG(5,("read_socket_with_timeout: timeout read. EOF from client.\n")); + smb_read_error = READ_EOF; + return -1; + } + + if (readret == -1) { + /* the descriptor is probably dead */ + DEBUG(0,("read_socket_with_timeout: timeout read. read error = %s.\n", strerror(errno) )); + smb_read_error = READ_ERROR; + return -1; + } + + nread += readret; + } + + /* Return the number we got */ + return((ssize_t)nread); } /**************************************************************************** @@ -317,76 +317,76 @@ static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t ma ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out) { - fd_set fds; - int selrtn; - ssize_t readret; - size_t nread = 0; - struct timeval timeout; - - /* just checking .... */ - if (maxcnt <= 0) - return(0); - - /* Blocking read */ - if (time_out <= 0) { - if (mincnt == 0) mincnt = maxcnt; - - while (nread < mincnt) { + fd_set fds; + int selrtn; + ssize_t readret; + size_t nread = 0; + struct timeval timeout; + + /* just checking .... */ + if (maxcnt <= 0) + return(0); + + /* Blocking read */ + if (time_out <= 0) { + if (mincnt == 0) mincnt = maxcnt; + + while (nread < mincnt) { #ifdef WITH_SSL - if(fd == sslFd){ - readret = SSL_read(ssl, buf + nread, maxcnt - nread); - }else{ - readret = read(fd, buf + nread, maxcnt - nread); - } + if(fd == sslFd){ + readret = SSL_read(ssl, buf + nread, maxcnt - nread); + }else{ + readret = read(fd, buf + nread, maxcnt - nread); + } #else /* WITH_SSL */ - readret = read(fd, buf + nread, maxcnt - nread); + readret = read(fd, buf + nread, maxcnt - nread); #endif /* WITH_SSL */ - - if (readret <= 0) - return readret; - - nread += readret; - } - return((ssize_t)nread); - } - - /* Most difficult - timeout read */ - /* If this is ever called on a disk file and - mincnt is greater then the filesize then - system performance will suffer severely as - select always returns true on disk files */ - - /* Set initial timeout */ - timeout.tv_sec = (time_t)(time_out / 1000); - timeout.tv_usec = (long)(1000 * (time_out % 1000)); - - for (nread=0; nread < mincnt; ) { - FD_ZERO(&fds); - FD_SET(fd,&fds); - - selrtn = sys_select_intr(fd+1,&fds,&timeout); - - if(selrtn <= 0) - return selrtn; - + + if (readret <= 0) + return readret; + + nread += readret; + } + return((ssize_t)nread); + } + + /* Most difficult - timeout read */ + /* If this is ever called on a disk file and + mincnt is greater then the filesize then + system performance will suffer severely as + select always returns true on disk files */ + + /* Set initial timeout */ + timeout.tv_sec = (time_t)(time_out / 1000); + timeout.tv_usec = (long)(1000 * (time_out % 1000)); + + for (nread=0; nread < mincnt; ) { + FD_ZERO(&fds); + FD_SET(fd,&fds); + + selrtn = sys_select_intr(fd+1,&fds,&timeout); + + if(selrtn <= 0) + return selrtn; + #ifdef WITH_SSL - if(fd == sslFd){ - readret = SSL_read(ssl, buf + nread, maxcnt - nread); - }else{ - readret = read(fd, buf + nread, maxcnt - nread); - } + if(fd == sslFd){ + readret = SSL_read(ssl, buf + nread, maxcnt - nread); + }else{ + readret = read(fd, buf + nread, maxcnt - nread); + } #else /* WITH_SSL */ - readret = read(fd, buf+nread, maxcnt-nread); + readret = read(fd, buf+nread, maxcnt-nread); #endif /* WITH_SSL */ - - if (readret <= 0) - return readret; - - nread += readret; - } - - /* Return the number we got */ - return((ssize_t)nread); + + if (readret <= 0) + return readret; + + nread += readret; + } + + /* Return the number we got */ + return((ssize_t)nread); } /**************************************************************************** -- cgit From f7a657721a7ca6831bfeeecfcf5930f86174b721 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 13 Jan 2002 12:37:01 +0000 Subject: A couple of coding syle updates to follow the re-indent. (This used to be commit 7417d6f9310188d2ad3d8f41d3dcbe55862c72ac) --- source3/lib/util_sock.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 690b626224..8e7b69cac8 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -221,9 +221,9 @@ static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t ma while (nread < mincnt) { #ifdef WITH_SSL - if(fd == sslFd){ + if (fd == sslFd) { readret = SSL_read(ssl, buf + nread, maxcnt - nread); - }else{ + } else { readret = read(fd, buf + nread, maxcnt - nread); } #else /* WITH_SSL */ @@ -263,7 +263,7 @@ static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t ma selrtn = sys_select_intr(fd+1,&fds,&timeout); /* Check if error */ - if(selrtn == -1) { + if (selrtn == -1) { /* something is wrong. Maybe the socket is dead? */ DEBUG(0,("read_socket_with_timeout: timeout read. select error = %s.\n", strerror(errno) )); smb_read_error = READ_ERROR; @@ -278,7 +278,7 @@ static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t ma } #ifdef WITH_SSL - if(fd == sslFd){ + if (fd == sslFd) { readret = SSL_read(ssl, buf + nread, maxcnt - nread); }else{ readret = read(fd, buf + nread, maxcnt - nread); @@ -305,7 +305,7 @@ static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t ma } /* Return the number we got */ - return((ssize_t)nread); + return (ssize_t)nread; } /**************************************************************************** -- cgit From df3d5b3556146e2d60c1a5656b16236f96832a16 Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Tue, 15 Jan 2002 01:37:12 +0000 Subject: Add constness to filenames passed to functions. (This used to be commit 8d106dc1f4a51112516d72ae68747ca6b5b904b7) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 8e7b69cac8..c6c26155da 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -116,7 +116,7 @@ static void print_socket_options(int s) Set user socket options. ****************************************************************************/ -void set_socket_options(int fd, char *options) +void set_socket_options(int fd, const char *options) { fstring tok; -- cgit From 4668960b1de80f9928104d20a7dfd8eee9d21c77 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 19 Jan 2002 21:37:38 +0000 Subject: Added #ifdef for FreeBSD TCP bug. Jeremy. (This used to be commit 80df5ab07e2149e7cc3a4a0a6695da01e8f9492c) --- source3/lib/util_sock.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index c6c26155da..ba3c6f71b4 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -666,7 +666,11 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout) } if(len > 0) { +#ifdef FREEBSD_TCP_BUG + ret = read_socket_with_timeout(fd,buffer+4,len,len,10000); +#else ret = read_socket_data(fd,buffer+4,len); +#endif if (ret != len) { smb_read_error = READ_ERROR; return False; -- cgit From bb6af711b8f9a525b74198abbe7f1c37014ca6f7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 20 Jan 2002 02:40:05 +0000 Subject: This is the current patch from Luke Leighton to add a degree of seperation betwen reading/writing the raw NamedPipe SMB packets and the matching operations inside smbd's RPC components. This patch is designed for no change in behaviour, and my tests hold that to be true. This patch does however allow for the future loadable modules interface to specify function pointers in replacement of the fixed state. The pipes_struct has been split into two peices, with smb_np_struct taking the information that should be generic to where the data ends up. Some other minor changes are made: we get another small helper function in util_sock.c and some of the original code has better failure debugs and variable use. (As per on-list comments). Andrew Bartlett (This used to be commit 8ef13cabdddf58b741886782297fb64b2fb7e489) --- source3/lib/util_sock.c | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index ba3c6f71b4..10ed2aaa0b 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -194,6 +194,30 @@ ssize_t read_udp_socket(int fd,char *buf,size_t len) return(ret); } +/******************************************************************* + checks if read data is outstanding. + ********************************************************************/ +int read_data_outstanding(int fd, unsigned int time_out) +{ + int selrtn; + fd_set fds; + struct timeval timeout; + + FD_ZERO(&fds); + FD_SET(fd, &fds); + + timeout.tv_sec = (time_t) (time_out / 1000); + timeout.tv_usec = (long)(1000 * (time_out % 1000)); + + selrtn = sys_select_intr(fd + 1, &fds, &timeout); + + if (selrtn <= 0) + { + return selrtn; + } + return FD_ISSET(fd, &fds) ? 1 : 0; +} + /**************************************************************************** Read data from a socket with a timout in msec. mincount = if timeout, minimum to read before returning @@ -315,13 +339,11 @@ static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t ma time_out = timeout in milliseconds ****************************************************************************/ -ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out) +ssize_t read_with_timeout(int fd, char *buf, size_t mincnt, size_t maxcnt, + unsigned int time_out) { - fd_set fds; - int selrtn; ssize_t readret; size_t nread = 0; - struct timeval timeout; /* just checking .... */ if (maxcnt <= 0) @@ -356,15 +378,8 @@ ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned system performance will suffer severely as select always returns true on disk files */ - /* Set initial timeout */ - timeout.tv_sec = (time_t)(time_out / 1000); - timeout.tv_usec = (long)(1000 * (time_out % 1000)); - for (nread=0; nread < mincnt; ) { - FD_ZERO(&fds); - FD_SET(fd,&fds); - - selrtn = sys_select_intr(fd+1,&fds,&timeout); + int selrtn = read_data_outstanding(fd, time_out); if(selrtn <= 0) return selrtn; -- cgit From 71bc6b9af24bbf2f59ef6407419f02c6709fcced Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 21 Jan 2002 23:36:47 +0000 Subject: Removed freebsd hack. Not correct. Jeremy. (This used to be commit 61b4ce7aef53ab82bdc5bc214e50c1891e097c11) --- source3/lib/util_sock.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 10ed2aaa0b..6de09553e0 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -681,11 +681,7 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout) } if(len > 0) { -#ifdef FREEBSD_TCP_BUG - ret = read_socket_with_timeout(fd,buffer+4,len,len,10000); -#else ret = read_socket_data(fd,buffer+4,len); -#endif if (ret != len) { smb_read_error = READ_ERROR; return False; -- cgit From 50648ac3cc165e37300f4a889fa05ee35384793d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 22 Jan 2002 00:31:41 +0000 Subject: Having a const parameter for set_socket_options() causes too much confusion. (This used to be commit 025a0ea8bac876633b790b62558a8ec1b7460e1b) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 6de09553e0..0ca36b3788 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -116,7 +116,7 @@ static void print_socket_options(int s) Set user socket options. ****************************************************************************/ -void set_socket_options(int fd, const char *options) +void set_socket_options(int fd, char *options) { fstring tok; -- cgit From cd68afe31256ad60748b34f7318a180cfc2127cc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 30 Jan 2002 06:08:46 +0000 Subject: Removed version number from file header. Changed "SMB/Netbios" to "SMB/CIFS" in file header. (This used to be commit 6a58c9bd06d0d7502a24bf5ce5a2faf0a146edfa) --- source3/lib/util_sock.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 0ca36b3788..3d32d77000 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0. + Unix SMB/CIFS implementation. Samba utility functions Copyright (C) Andrew Tridgell 1992-1998 Copyright (C) Tim Potter 2000-2001 -- cgit From 69adbb0ce3bb9d5bd569c13aaa3ac8f390c1586a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 31 Jan 2002 23:26:12 +0000 Subject: Fix from Michael Steffens to make signal processing work correctly in winbindd. This is a really good patch that gives full select semantics to the Samba modified select. Jeremy. (This used to be commit 3af16ade173cac24c1ac5eff4a36b439f16ac036) --- source3/lib/util_sock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 3d32d77000..daab7933da 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -208,7 +208,7 @@ int read_data_outstanding(int fd, unsigned int time_out) timeout.tv_sec = (time_t) (time_out / 1000); timeout.tv_usec = (long)(1000 * (time_out % 1000)); - selrtn = sys_select_intr(fd + 1, &fds, &timeout); + selrtn = sys_select_intr(fd + 1, &fds, NULL, NULL, &timeout); if (selrtn <= 0) { @@ -283,7 +283,7 @@ static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t ma FD_ZERO(&fds); FD_SET(fd,&fds); - selrtn = sys_select_intr(fd+1,&fds,&timeout); + selrtn = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout); /* Check if error */ if (selrtn == -1) { -- cgit From ae9bac99fa9cda2e480afa10a7c00b37ad4fd255 Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Fri, 15 Feb 2002 22:20:08 +0000 Subject: Back out 1.16.2.3: receive_smb: You might think that we ought to set smb_read_error here, but apparently that breaks the recursive main loop in oplock.c. Global variables suck. :-/ (This used to be commit b6d5d02aa1bf0caa28343dc87444f049c5fd8ce5) --- source3/lib/util_sock.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index daab7933da..45beb38ac9 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -663,7 +663,11 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout) len = read_smb_length_return_keepalive(fd,buffer,timeout); if (len < 0) { DEBUG(10,("receive_smb: length < 0!\n")); - return(False); + /* XXX: You might think that we ought to set + * smb_read_error here, but apparently that breaks the + * recursive main loop in oplock.c. Global variables + * suck. */ + return False; } /* -- cgit From de494520b0a8b0d58c0f320e7badad419e878c1e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 23 Feb 2002 21:03:21 +0000 Subject: Only set smb_read_error if not already set. Jeremy. (This used to be commit 8220135fd16b4a1778e49f8315f64754924af0d8) --- source3/lib/util_sock.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 45beb38ac9..9081f28f83 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -663,10 +663,15 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout) len = read_smb_length_return_keepalive(fd,buffer,timeout); if (len < 0) { DEBUG(10,("receive_smb: length < 0!\n")); - /* XXX: You might think that we ought to set - * smb_read_error here, but apparently that breaks the - * recursive main loop in oplock.c. Global variables - * suck. */ + + /* + * Correct fix. smb_read_error may have already been + * set. Only set it here if not already set. Global + * variables still suck :-). JRA. + */ + + if (smb_read_error == 0) + smb_read_error = READ_ERROR; return False; } @@ -678,7 +683,15 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout) if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) { DEBUG(0,("Invalid packet length! (%d bytes).\n",len)); if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) { - smb_read_error = READ_ERROR; + + /* + * Correct fix. smb_read_error may have already been + * set. Only set it here if not already set. Global + * variables still suck :-). JRA. + */ + + if (smb_read_error == 0) + smb_read_error = READ_ERROR; return False; } } @@ -686,7 +699,8 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout) if(len > 0) { ret = read_socket_data(fd,buffer+4,len); if (ret != len) { - smb_read_error = READ_ERROR; + if (smb_read_error == 0) + smb_read_error = READ_ERROR; return False; } } -- cgit From c90cd26e9430b2fc065f620bdb6aaf4be0372fcc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 23 Mar 2002 02:57:44 +0000 Subject: Fix the mp3 rename bug - also tidy up our open code and remove the special cases for rename and unlink. Had to add desired_access into the share mode record. Jeremy. (This used to be commit 3b1b8ac43535fb0839c5474fa55bf7150f6cde31) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 9081f28f83..af3182264d 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -677,7 +677,7 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout) /* * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes - * of header. Don't print the error if this fits.... JRA. + * of header. Don't print the error if this fits.... JRA. */ if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) { -- cgit From e90b65284812aaa5ff9e9935ce9bbad7791cbbcd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 10:35:28 +0000 Subject: updated the 3.0 branch from the head branch - ready for alpha18 (This used to be commit 03ac082dcb375b6f3ca3d810a6a6367542bc23ce) --- source3/lib/util_sock.c | 470 +++++++++++++++--------------------------------- 1 file changed, 145 insertions(+), 325 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index af3182264d..4f1f2a1470 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -21,13 +21,6 @@ #include "includes.h" -#ifdef WITH_SSL -#include -#undef Realloc /* SSLeay defines this and samba has a function of this name */ -extern SSL *ssl; -extern int sslFd; -#endif /* WITH_SSL */ - /* the last IP received from */ struct in_addr lastip; @@ -42,23 +35,22 @@ int smb_read_error = 0; BOOL is_a_socket(int fd) { - int v,l; - l = sizeof(int); - return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0); + int v,l; + l = sizeof(int); + return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0); } enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON}; -typedef struct smb_socket_option -{ - char *name; - int level; - int option; - int value; - int opttype; +typedef struct smb_socket_option { + char *name; + int level; + int option; + int value; + int opttype; } smb_socket_option; -smb_socket_option socket_options[] = { +static const smb_socket_option socket_options[] = { {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL}, {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL}, {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL}, @@ -97,10 +89,11 @@ smb_socket_option socket_options[] = { /**************************************************************************** Print socket options. ****************************************************************************/ + static void print_socket_options(int s) { int value, vlen = 4; - smb_socket_option *p = &socket_options[0]; + const smb_socket_option *p = &socket_options[0]; for (; p->name != NULL; p++) { if (getsockopt(s, p->level, p->option, (void *)&value, &vlen) == -1) { @@ -178,7 +171,7 @@ ssize_t read_udp_socket(int fd,char *buf,size_t len) memset((char *)&sock,'\0',socklen); memset((char *)&lastip,'\0',sizeof(lastip)); - ret = (ssize_t)recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen); + ret = (ssize_t)sys_recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen); if (ret <= 0) { DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno))); return(0); @@ -196,7 +189,7 @@ ssize_t read_udp_socket(int fd,char *buf,size_t len) /******************************************************************* checks if read data is outstanding. ********************************************************************/ -int read_data_outstanding(int fd, unsigned int time_out) +static int read_data_outstanding(int fd, unsigned int time_out) { int selrtn; fd_set fds; @@ -243,15 +236,7 @@ static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t ma if (mincnt == 0) mincnt = maxcnt; while (nread < mincnt) { -#ifdef WITH_SSL - if (fd == sslFd) { - readret = SSL_read(ssl, buf + nread, maxcnt - nread); - } else { - readret = read(fd, buf + nread, maxcnt - nread); - } -#else /* WITH_SSL */ - readret = read(fd, buf + nread, maxcnt - nread); -#endif /* WITH_SSL */ + readret = sys_read(fd, buf + nread, maxcnt - nread); if (readret == 0) { DEBUG(5,("read_socket_with_timeout: blocking read. EOF from client.\n")); @@ -300,15 +285,7 @@ static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t ma return -1; } -#ifdef WITH_SSL - if (fd == sslFd) { - readret = SSL_read(ssl, buf + nread, maxcnt - nread); - }else{ - readret = read(fd, buf + nread, maxcnt - nread); - } -#else /* WITH_SSL */ - readret = read(fd, buf+nread, maxcnt-nread); -#endif /* WITH_SSL */ + readret = sys_read(fd, buf+nread, maxcnt-nread); if (readret == 0) { /* we got EOF on the file descriptor */ @@ -353,15 +330,7 @@ ssize_t read_with_timeout(int fd, char *buf, size_t mincnt, size_t maxcnt, if (mincnt == 0) mincnt = maxcnt; while (nread < mincnt) { -#ifdef WITH_SSL - if(fd == sslFd){ - readret = SSL_read(ssl, buf + nread, maxcnt - nread); - }else{ - readret = read(fd, buf + nread, maxcnt - nread); - } -#else /* WITH_SSL */ - readret = read(fd, buf + nread, maxcnt - nread); -#endif /* WITH_SSL */ + readret = sys_read(fd, buf + nread, maxcnt - nread); if (readret <= 0) return readret; @@ -383,15 +352,7 @@ ssize_t read_with_timeout(int fd, char *buf, size_t mincnt, size_t maxcnt, if(selrtn <= 0) return selrtn; -#ifdef WITH_SSL - if(fd == sslFd){ - readret = SSL_read(ssl, buf + nread, maxcnt - nread); - }else{ - readret = read(fd, buf + nread, maxcnt - nread); - } -#else /* WITH_SSL */ - readret = read(fd, buf+nread, maxcnt-nread); -#endif /* WITH_SSL */ + readret = sys_read(fd, buf+nread, maxcnt-nread); if (readret <= 0) return readret; @@ -403,58 +364,34 @@ ssize_t read_with_timeout(int fd, char *buf, size_t mincnt, size_t maxcnt, return((ssize_t)nread); } -/**************************************************************************** -send a keepalive packet (rfc1002) -****************************************************************************/ - -BOOL send_keepalive(int client) -{ - unsigned char buf[4]; - - buf[0] = SMBkeepalive; - buf[1] = buf[2] = buf[3] = 0; - - return(write_socket_data(client,(char *)buf,4) == 4); -} - /**************************************************************************** read data from the client, reading exactly N bytes. ****************************************************************************/ ssize_t read_data(int fd,char *buffer,size_t N) { - ssize_t ret; - size_t total=0; + ssize_t ret; + size_t total=0; - smb_read_error = 0; - - while (total < N) - { -#ifdef WITH_SSL - if(fd == sslFd){ - ret = SSL_read(ssl, buffer + total, N - total); - }else{ - ret = read(fd,buffer + total,N - total); - } -#else /* WITH_SSL */ - ret = read(fd,buffer + total,N - total); -#endif /* WITH_SSL */ - - if (ret == 0) - { - DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) )); - smb_read_error = READ_EOF; - return 0; - } - if (ret == -1) - { - DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) )); - smb_read_error = READ_ERROR; - return -1; - } - total += ret; - } - return (ssize_t)total; + smb_read_error = 0; + + while (total < N) { + ret = sys_read(fd,buffer + total,N - total); + + if (ret == 0) { + DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) )); + smb_read_error = READ_EOF; + return 0; + } + + if (ret == -1) { + DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) )); + smb_read_error = READ_ERROR; + return -1; + } + total += ret; + } + return (ssize_t)total; } /**************************************************************************** @@ -463,38 +400,28 @@ ssize_t read_data(int fd,char *buffer,size_t N) static ssize_t read_socket_data(int fd,char *buffer,size_t N) { - ssize_t ret; - size_t total=0; + ssize_t ret; + size_t total=0; - smb_read_error = 0; - - while (total < N) - { -#ifdef WITH_SSL - if(fd == sslFd){ - ret = SSL_read(ssl, buffer + total, N - total); - }else{ - ret = read(fd,buffer + total,N - total); - } -#else /* WITH_SSL */ - ret = read(fd,buffer + total,N - total); -#endif /* WITH_SSL */ - - if (ret == 0) - { - DEBUG(10,("read_socket_data: recv of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) )); - smb_read_error = READ_EOF; - return 0; - } - if (ret == -1) - { - DEBUG(0,("read_socket_data: recv failure for %d. Error = %s\n", (int)(N - total), strerror(errno) )); - smb_read_error = READ_ERROR; - return -1; - } - total += ret; - } - return (ssize_t)total; + smb_read_error = 0; + + while (total < N) { + ret = sys_read(fd,buffer + total,N - total); + + if (ret == 0) { + DEBUG(10,("read_socket_data: recv of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) )); + smb_read_error = READ_EOF; + return 0; + } + + if (ret == -1) { + DEBUG(0,("read_socket_data: recv failure for %d. Error = %s\n", (int)(N - total), strerror(errno) )); + smb_read_error = READ_ERROR; + return -1; + } + total += ret; + } + return (ssize_t)total; } /**************************************************************************** @@ -503,62 +430,46 @@ static ssize_t read_socket_data(int fd,char *buffer,size_t N) ssize_t write_data(int fd,char *buffer,size_t N) { - size_t total=0; - ssize_t ret; - - while (total < N) - { -#ifdef WITH_SSL - if(fd == sslFd){ - ret = SSL_write(ssl,buffer + total,N - total); - }else{ - ret = write(fd,buffer + total,N - total); - } -#else /* WITH_SSL */ - ret = write(fd,buffer + total,N - total); -#endif /* WITH_SSL */ - - if (ret == -1) { - DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) )); - return -1; - } - if (ret == 0) return total; + size_t total=0; + ssize_t ret; - total += ret; - } - return (ssize_t)total; + while (total < N) { + ret = sys_write(fd,buffer + total,N - total); + + if (ret == -1) { + DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) )); + return -1; + } + if (ret == 0) + return total; + + total += ret; + } + return (ssize_t)total; } /**************************************************************************** Write data to a socket - use send rather than write. ****************************************************************************/ -ssize_t write_socket_data(int fd,char *buffer,size_t N) +static ssize_t write_socket_data(int fd,char *buffer,size_t N) { - size_t total=0; - ssize_t ret; - - while (total < N) - { -#ifdef WITH_SSL - if(fd == sslFd){ - ret = SSL_write(ssl,buffer + total,N - total); - }else{ - ret = send(fd,buffer + total,N - total, 0); - } -#else /* WITH_SSL */ - ret = send(fd,buffer + total,N - total,0); -#endif /* WITH_SSL */ - - if (ret == -1) { - DEBUG(0,("write_socket_data: write failure. Error = %s\n", strerror(errno) )); - return -1; - } - if (ret == 0) return total; + size_t total=0; + ssize_t ret; - total += ret; - } - return (ssize_t)total; + while (total < N) { + ret = sys_send(fd,buffer + total,N - total,0); + + if (ret == -1) { + DEBUG(0,("write_socket_data: write failure. Error = %s\n", strerror(errno) )); + return -1; + } + if (ret == 0) + return total; + + total += ret; + } + return (ssize_t)total; } /**************************************************************************** @@ -567,19 +478,34 @@ write to a socket ssize_t write_socket(int fd,char *buf,size_t len) { - ssize_t ret=0; + ssize_t ret=0; - DEBUG(6,("write_socket(%d,%d)\n",fd,(int)len)); - ret = write_socket_data(fd,buf,len); + DEBUG(6,("write_socket(%d,%d)\n",fd,(int)len)); + ret = write_socket_data(fd,buf,len); - DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,(int)len,(int)ret)); - if(ret <= 0) - DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n", - (int)len, fd, strerror(errno) )); + DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,(int)len,(int)ret)); + if(ret <= 0) + DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n", + (int)len, fd, strerror(errno) )); + + return(ret); +} + +/**************************************************************************** +send a keepalive packet (rfc1002) +****************************************************************************/ - return(ret); +BOOL send_keepalive(int client) +{ + unsigned char buf[4]; + + buf[0] = SMBkeepalive; + buf[1] = buf[2] = buf[3] = 0; + + return(write_socket_data(client,(char *)buf,4) == 4); } + /**************************************************************************** read 4 bytes of a smb packet and return the smb length of the packet store the result in the buffer @@ -590,30 +516,29 @@ timeout is in milliseconds. static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int timeout) { - ssize_t len=0; - int msg_type; - BOOL ok = False; + ssize_t len=0; + int msg_type; + BOOL ok = False; - while (!ok) - { - if (timeout > 0) - ok = (read_socket_with_timeout(fd,inbuf,4,4,timeout) == 4); - else - ok = (read_socket_data(fd,inbuf,4) == 4); + while (!ok) { + if (timeout > 0) + ok = (read_socket_with_timeout(fd,inbuf,4,4,timeout) == 4); + else + ok = (read_socket_data(fd,inbuf,4) == 4); - if (!ok) - return(-1); + if (!ok) + return(-1); - len = smb_len(inbuf); - msg_type = CVAL(inbuf,0); + len = smb_len(inbuf); + msg_type = CVAL(inbuf,0); - if (msg_type == SMBkeepalive) - DEBUG(5,("Got keepalive packet\n")); - } + if (msg_type == SMBkeepalive) + DEBUG(5,("Got keepalive packet\n")); + } - DEBUG(10,("got smb length of %d\n",len)); + DEBUG(10,("got smb length of %d\n",len)); - return(len); + return(len); } /**************************************************************************** @@ -625,23 +550,22 @@ timeout is in milliseconds. ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout) { - ssize_t len; + ssize_t len; - for(;;) - { - len = read_smb_length_return_keepalive(fd, inbuf, timeout); + for(;;) { + len = read_smb_length_return_keepalive(fd, inbuf, timeout); - if(len < 0) - return len; + if(len < 0) + return len; - /* Ignore session keepalives. */ - if(CVAL(inbuf,0) != SMBkeepalive) - break; - } + /* Ignore session keepalives. */ + if(CVAL(inbuf,0) != SMBkeepalive) + break; + } - DEBUG(10,("read_smb_length: got smb length of %d\n",len)); + DEBUG(10,("read_smb_length: got smb length of %d\n",len)); - return len; + return len; } /**************************************************************************** @@ -708,40 +632,6 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout) return(True); } -/**************************************************************************** - read an smb from a fd ignoring all keepalive packets. Note that the buffer - *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN. - The timeout is in milliseconds - - This is exactly the same as receive_smb except that it never returns - a session keepalive packet (just as receive_smb used to do). - receive_smb was changed to return keepalives as the oplock processing means this call - should never go into a blocking read. -****************************************************************************/ - -BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) -{ - BOOL ret; - - for(;;) - { - ret = receive_smb(fd, buffer, timeout); - - if (!ret) - { - DEBUG(10,("client_receive_smb failed\n")); - show_msg(buffer); - return ret; - } - - /* Ignore session keepalive packets. */ - if(CVAL(buffer,0) != SMBkeepalive) - break; - } - show_msg(buffer); - return ret; -} - /**************************************************************************** send an smb to a fd ****************************************************************************/ @@ -766,45 +656,6 @@ BOOL send_smb(int fd,char *buffer) return True; } -/**************************************************************************** -send a single packet to a port on another machine -****************************************************************************/ - -BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type) -{ - BOOL ret; - int out_fd; - struct sockaddr_in sock_out; - - /* create a socket to write to */ - out_fd = socket(AF_INET, type, 0); - if (out_fd == -1) - { - DEBUG(0,("socket failed")); - return False; - } - - /* set the address and port */ - memset((char *)&sock_out,'\0',sizeof(sock_out)); - putip((char *)&sock_out.sin_addr,(char *)&ip); - sock_out.sin_port = htons( port ); - sock_out.sin_family = AF_INET; - - if (DEBUGLEVEL > 0) - DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n", - len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM")); - - /* send it */ - ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0); - - if (!ret) - DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n", - inet_ntoa(ip),port,strerror(errno))); - - close(out_fd); - return(ret); -} - /**************************************************************************** Open a socket of the specified type, port, and address for incoming data. ****************************************************************************/ @@ -866,7 +717,7 @@ int open_socket_in( int type, int port, int dlevel, uint32 socket_addr, BOOL reb return( -1 ); } - DEBUG( 3, ( "bind succeeded on port %d\n", port ) ); + DEBUG( 10, ( "bind succeeded on port %d\n", port ) ); return( res ); } @@ -1113,37 +964,6 @@ char *get_socket_addr(int fd) return addr_buf; } -/******************************************************************* - opens and connects to a unix pipe socket - ******************************************************************/ -int open_pipe_sock(char *path) -{ - int sock; - struct sockaddr_un sa; - - sock = socket(AF_UNIX, SOCK_STREAM, 0); - - if (sock < 0) - { - DEBUG(0, ("unix socket open failed\n")); - return sock; - } - - ZERO_STRUCT(sa); - sa.sun_family = AF_UNIX; - safe_strcpy(sa.sun_path, path, sizeof(sa.sun_path)-1); - - DEBUG(10, ("socket open succeeded. file name: %s\n", sa.sun_path)); - - if (connect(sock, (struct sockaddr*) &sa, sizeof(sa)) < 0) - { - DEBUG(0,("socket connect to %s failed\n", sa.sun_path)); - close(sock); - return -1; - } - - return sock; -} /******************************************************************* Create protected unix domain socket. @@ -1153,8 +973,8 @@ int open_pipe_sock(char *path) permissions, instead. ******************************************************************/ int create_pipe_sock(const char *socket_dir, - const char *socket_name, - mode_t dir_perms) + const char *socket_name, + mode_t dir_perms) { struct sockaddr_un sunaddr; struct stat st; -- cgit From b2edf254eda92f775e7d3d9b6793b4d77f9000b6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 17 Aug 2002 17:00:51 +0000 Subject: sync 3.0 branch with head (This used to be commit 3928578b52cfc949be5e0ef444fce1558d75f290) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 4f1f2a1470..5e2b7c5ed9 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -708,7 +708,7 @@ int open_socket_in( int type, int port, int dlevel, uint32 socket_addr, BOOL reb /* now we've got a socket - we need to bind it */ if( bind( res, (struct sockaddr *)&sock, sizeof(sock) ) == -1 ) { - if( DEBUGLVL(dlevel) && (port == SMB_PORT || port == NMB_PORT) ) { + if( DEBUGLVL(dlevel) && (port == SMB_PORT1 || port == SMB_PORT2 || port == NMB_PORT) ) { dbgtext( "bind failed on port %d ", port ); dbgtext( "socket_addr = %s.\n", inet_ntoa( sock.sin_addr ) ); dbgtext( "Error = %s\n", strerror(errno) ); -- cgit From a834a73e341059be154426390304a42e4a011f72 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 25 Sep 2002 15:19:00 +0000 Subject: sync'ing up for 3.0alpha20 release (This used to be commit 65e7b5273bb58802bf0c389b77f7fcae0a1f6139) --- source3/lib/util_sock.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 5e2b7c5ed9..fc2abf976f 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -871,7 +871,7 @@ static BOOL matchname(char *remotehost,struct in_addr addr) /* Look up the host address in the address list we just got. */ for (i = 0; hp->h_addr_list[i]; i++) { - if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0) + if (memcmp(hp->h_addr_list[i], (char *) & addr, sizeof(addr)) == 0) return True; } @@ -976,6 +976,7 @@ int create_pipe_sock(const char *socket_dir, const char *socket_name, mode_t dir_perms) { +#ifdef HAVE_UNIXSOCKET struct sockaddr_un sunaddr; struct stat st; int sock; @@ -1064,6 +1065,10 @@ int create_pipe_sock(const char *socket_dir, /* Success! */ return sock; +#else + DEBUG(0, ("create_pipe_sock: No Unix sockets on this system\n")); + return -1; +#endif /* HAVE_UNIXSOCKET */ } /******************************************************************* -- cgit From 35ac9d287f000c27dc864789b341bebe7acb4c74 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 26 Oct 2002 02:20:59 +0000 Subject: Try to catch up on the code I've put into HEAD that should be in 3.0: - vorlan's hosts allow with DNS names patch - use x_fileno() in debug.c, not the struct directly. - check for server timeout on password change (was reporting success) - better error/status loggin in both the pam_winbind client and winbindd_pam server code. - (pdb_ldap) don't set the ldap version twice - we do it on every bind anyway. (This used to be commit 9fa1863d8e7788eda83911ca2610754486b33069) --- source3/lib/util_sock.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index fc2abf976f..04c20f6596 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -832,7 +832,7 @@ void client_setfd(int fd) char *client_name(void) { - return get_socket_name(client_fd); + return get_socket_name(client_fd,False); } char *client_addr(void) @@ -890,7 +890,7 @@ static BOOL matchname(char *remotehost,struct in_addr addr) /******************************************************************* return the DNS name of the remote end of a socket ******************************************************************/ -char *get_socket_name(int fd) +char *get_socket_name(int fd, BOOL force_lookup) { static pstring name_buf; static fstring addr_buf; @@ -902,7 +902,7 @@ char *get_socket_name(int fd) situations won't work because many networks don't link dhcp with dns. To avoid the delay we avoid the lookup if possible */ - if (!lp_hostname_lookups()) { + if (!lp_hostname_lookups() && (force_lookup == False)) { return get_socket_addr(fd); } -- cgit From 2f194322d419350f35a48dff750066894d68eccf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 Nov 2002 23:20:50 +0000 Subject: Removed global_myworkgroup, global_myname, global_myscope. Added liberal dashes of const. This is a rather large check-in, some things may break. It does compile though :-). Jeremy. (This used to be commit f755711df8f74f9b8e8c1a2b0d07d02a931eeb89) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 04c20f6596..2acb20861b 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -108,7 +108,7 @@ static void print_socket_options(int s) Set user socket options. ****************************************************************************/ -void set_socket_options(int fd, char *options) +void set_socket_options(int fd, const char *options) { fstring tok; -- cgit From 634c54310c92c48dd4eceec602e230a021bdcfc5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 3 Jan 2003 08:28:12 +0000 Subject: Merge from HEAD - make Samba compile with -Wwrite-strings without additional warnings. (Adds a lot of const). Andrew Bartlett (This used to be commit 3a7458f9472432ef12c43008414925fd1ce8ea0c) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 2acb20861b..e162e5cd77 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -43,7 +43,7 @@ BOOL is_a_socket(int fd) enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON}; typedef struct smb_socket_option { - char *name; + const char *name; int level; int option; int value; -- cgit From 99cdb462083381c88689a4e698ca48b6ed4cf5ac Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 15 Jan 2003 18:57:41 +0000 Subject: *lots of small merges form HEAD *sync up configure.in *don't build torture tools in make all *make sure to remove torture tools as part of make clean (This used to be commit 0fb724b3216eeeb97e61ff12755ca3a31bcad6ef) --- source3/lib/util_sock.c | 82 +------------------------------------------------ 1 file changed, 1 insertion(+), 81 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index e162e5cd77..3a7899df3d 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -186,30 +186,6 @@ ssize_t read_udp_socket(int fd,char *buf,size_t len) return(ret); } -/******************************************************************* - checks if read data is outstanding. - ********************************************************************/ -static int read_data_outstanding(int fd, unsigned int time_out) -{ - int selrtn; - fd_set fds; - struct timeval timeout; - - FD_ZERO(&fds); - FD_SET(fd, &fds); - - timeout.tv_sec = (time_t) (time_out / 1000); - timeout.tv_usec = (long)(1000 * (time_out % 1000)); - - selrtn = sys_select_intr(fd + 1, &fds, NULL, NULL, &timeout); - - if (selrtn <= 0) - { - return selrtn; - } - return FD_ISSET(fd, &fds) ? 1 : 0; -} - /**************************************************************************** Read data from a socket with a timout in msec. mincount = if timeout, minimum to read before returning @@ -217,7 +193,7 @@ static int read_data_outstanding(int fd, unsigned int time_out) time_out = timeout in milliseconds ****************************************************************************/ -static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out) +ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out) { fd_set fds; int selrtn; @@ -308,62 +284,6 @@ static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t ma return (ssize_t)nread; } -/**************************************************************************** - Read data from a fd with a timout in msec. - mincount = if timeout, minimum to read before returning - maxcount = number to be read. - time_out = timeout in milliseconds -****************************************************************************/ - -ssize_t read_with_timeout(int fd, char *buf, size_t mincnt, size_t maxcnt, - unsigned int time_out) -{ - ssize_t readret; - size_t nread = 0; - - /* just checking .... */ - if (maxcnt <= 0) - return(0); - - /* Blocking read */ - if (time_out <= 0) { - if (mincnt == 0) mincnt = maxcnt; - - while (nread < mincnt) { - readret = sys_read(fd, buf + nread, maxcnt - nread); - - if (readret <= 0) - return readret; - - nread += readret; - } - return((ssize_t)nread); - } - - /* Most difficult - timeout read */ - /* If this is ever called on a disk file and - mincnt is greater then the filesize then - system performance will suffer severely as - select always returns true on disk files */ - - for (nread=0; nread < mincnt; ) { - int selrtn = read_data_outstanding(fd, time_out); - - if(selrtn <= 0) - return selrtn; - - readret = sys_read(fd, buf+nread, maxcnt-nread); - - if (readret <= 0) - return readret; - - nread += readret; - } - - /* Return the number we got */ - return((ssize_t)nread); -} - /**************************************************************************** read data from the client, reading exactly N bytes. ****************************************************************************/ -- cgit From a90def7e8aaa26dbda37a7835f90d64d1b0722e2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 7 Feb 2003 21:59:51 +0000 Subject: Samba janitor: adding mbp's umask patch :-). Jeremy. (This used to be commit d4d8d27bf136bdbc785c7aad027537aabaa56a76) --- source3/lib/util_sock.c | 148 ++++++++++++++++++++++-------------------------- 1 file changed, 69 insertions(+), 79 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 3a7899df3d..42527e8fd0 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -888,103 +888,93 @@ char *get_socket_addr(int fd) /******************************************************************* Create protected unix domain socket. - some unixen cannot set permissions on a ux-dom-sock, so we + Some unixes cannot set permissions on a ux-dom-sock, so we have to make sure that the directory contains the protection - permissions, instead. + permissions instead. ******************************************************************/ + int create_pipe_sock(const char *socket_dir, const char *socket_name, mode_t dir_perms) { #ifdef HAVE_UNIXSOCKET - struct sockaddr_un sunaddr; - struct stat st; - int sock; - mode_t old_umask; - pstring path; - - /* Create the socket directory or reuse the existing one */ - - if (lstat(socket_dir, &st) == -1) { - - if (errno == ENOENT) { - - /* Create directory */ - - if (mkdir(socket_dir, dir_perms) == -1) { - DEBUG(0, ("error creating socket directory " - "%s: %s\n", socket_dir, - strerror(errno))); - return -1; - } - - } else { - - DEBUG(0, ("lstat failed on socket directory %s: %s\n", - socket_dir, strerror(errno))); - return -1; - } - - } else { - - /* Check ownership and permission on existing directory */ - - if (!S_ISDIR(st.st_mode)) { - DEBUG(0, ("socket directory %s isn't a directory\n", - socket_dir)); - return -1; - } - - if ((st.st_uid != sec_initial_uid()) || - ((st.st_mode & 0777) != dir_perms)) { - DEBUG(0, ("invalid permissions on socket directory " - "%s\n", socket_dir)); - return -1; - } - } + struct sockaddr_un sunaddr; + struct stat st; + int sock; + mode_t old_umask; + pstring path; - /* Create the socket file */ + old_umask = umask(0); - old_umask = umask(0); + /* Create the socket directory or reuse the existing one */ - sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (lstat(socket_dir, &st) == -1) { + if (errno == ENOENT) { + /* Create directory */ + if (mkdir(socket_dir, dir_perms) == -1) { + DEBUG(0, ("error creating socket directory " + "%s: %s\n", socket_dir, + strerror(errno))); + goto out_umask; + } + } else { + DEBUG(0, ("lstat failed on socket directory %s: %s\n", + socket_dir, strerror(errno))); + goto out_umask; + } + } else { + /* Check ownership and permission on existing directory */ + if (!S_ISDIR(st.st_mode)) { + DEBUG(0, ("socket directory %s isn't a directory\n", + socket_dir)); + goto out_umask; + } + if ((st.st_uid != sec_initial_uid()) || + ((st.st_mode & 0777) != dir_perms)) { + DEBUG(0, ("invalid permissions on socket directory " + "%s\n", socket_dir)); + goto out_umask; + } + } - if (sock == -1) { - perror("socket"); - umask(old_umask); - return -1; - } + /* Create the socket file */ - snprintf(path, sizeof(path), "%s/%s", socket_dir, socket_name); + sock = socket(AF_UNIX, SOCK_STREAM, 0); - unlink(path); - memset(&sunaddr, 0, sizeof(sunaddr)); - sunaddr.sun_family = AF_UNIX; - safe_strcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)-1); + if (sock == -1) { + perror("socket"); + goto out_umask; + } - if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) { - DEBUG(0, ("bind failed on pipe socket %s: %s\n", - path, - strerror(errno))); - close(sock); - umask(old_umask); - return -1; - } + snprintf(path, sizeof(path), "%s/%s", socket_dir, socket_name); - if (listen(sock, 5) == -1) { - DEBUG(0, ("listen failed on pipe socket %s: %s\n", - path, - strerror(errno))); - close(sock); - umask(old_umask); - return -1; - } + unlink(path); + memset(&sunaddr, 0, sizeof(sunaddr)); + sunaddr.sun_family = AF_UNIX; + safe_strcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)-1); - umask(old_umask); + if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) { + DEBUG(0, ("bind failed on pipe socket %s: %s\n", path, + strerror(errno))); + goto out_close; + } - /* Success! */ + if (listen(sock, 5) == -1) { + DEBUG(0, ("listen failed on pipe socket %s: %s\n", path, + strerror(errno))); + goto out_close; + } - return sock; + umask(old_umask); + return sock; + +out_close: + close(sock); + +out_umask: + umask(old_umask); + return -1; + #else DEBUG(0, ("create_pipe_sock: No Unix sockets on this system\n")); return -1; -- cgit From 40b85808a20bcfcd6c1a867283698b7f63a531f5 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 11 Apr 2003 14:18:02 +0000 Subject: workaround streams leak on SCO openserver 5.0.x (This used to be commit ab51878a978ffb53f23f1c6d22a48f98e6ae0805) --- source3/lib/util_sock.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 42527e8fd0..5460bf57b8 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -95,11 +95,15 @@ static void print_socket_options(int s) int value, vlen = 4; const smb_socket_option *p = &socket_options[0]; + /* wrapped in if statement to prevent streams leak in SCO Openserver 5.0 */ + /* reported on samba-technical --jerry */ + if ( DEBUGLEVEL >= 5 ) { for (; p->name != NULL; p++) { if (getsockopt(s, p->level, p->option, (void *)&value, &vlen) == -1) { DEBUG(5,("Could not test socket option %s.\n", p->name)); } else { DEBUG(5,("socket option %s = %d\n",p->name,value)); + } } } } -- cgit From 596de71fc60b622d7a9d5e12baf234db0bf22499 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 24 Apr 2003 09:52:29 +0000 Subject: When possible, store the IP address of the connecting client, not just the hostname. This makes 'last -i' show the IP. Thanks to Philip Anderson for the idea. Andrew Bartlett (This used to be commit 107731c080da1e3e4e13e966f8b79bfd2692a952) --- source3/lib/util_sock.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 5460bf57b8..2439cd8eac 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -764,6 +764,19 @@ char *client_addr(void) return get_socket_addr(client_fd); } +struct in_addr *client_inaddr(struct sockaddr *sa) +{ + struct sockaddr_in *sockin = (struct sockaddr_in *) (sa); + int length = sizeof(*sa); + + if (getpeername(client_fd, sa, &length) < 0) { + DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) )); + return NULL; + } + + return &sockin->sin_addr; +} + /******************************************************************* matchname - determine if host name matches IP address. Used to confirm a hostname lookup to prevent spoof attacks -- cgit From 5a6138082024d17eedab317038e8969c9f536530 Mon Sep 17 00:00:00 2001 From: Paul Green Date: Wed, 30 Apr 2003 17:48:46 +0000 Subject: Refactor existing sock_exec() and socketpair_tcp() functions into their own source file. I will be making changes to sock_exec to work on VOS, which has a blocking connect() call, but first I want to get it in its own source file so that it can be called from a test program. (This used to be commit 10bf65d335b7d7076484172faa2b4689ed437552) --- source3/lib/util_sock.c | 93 ------------------------------------------------- 1 file changed, 93 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 2439cd8eac..8c171852ab 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -997,96 +997,3 @@ out_umask: return -1; #endif /* HAVE_UNIXSOCKET */ } - -/******************************************************************* -this is like socketpair but uses tcp. It is used by the Samba -regression test code -The function guarantees that nobody else can attach to the socket, -or if they do that this function fails and the socket gets closed -returns 0 on success, -1 on failure -the resulting file descriptors are symmetrical - ******************************************************************/ -static int socketpair_tcp(int fd[2]) -{ - int listener; - struct sockaddr_in sock; - struct sockaddr_in sock2; - socklen_t socklen = sizeof(sock); - int connect_done = 0; - - fd[0] = fd[1] = listener = -1; - - memset(&sock, 0, sizeof(sock)); - - if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed; - - memset(&sock2, 0, sizeof(sock2)); -#ifdef HAVE_SOCK_SIN_LEN - sock2.sin_len = sizeof(sock2); -#endif - sock2.sin_family = PF_INET; - - bind(listener, (struct sockaddr *)&sock2, sizeof(sock2)); - - if (listen(listener, 1) != 0) goto failed; - - if (getsockname(listener, (struct sockaddr *)&sock, &socklen) != 0) goto failed; - - if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed; - - set_blocking(fd[1], 0); - - sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - - if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) { - if (errno != EINPROGRESS) goto failed; - } else { - connect_done = 1; - } - - if ((fd[0] = accept(listener, (struct sockaddr *)&sock, &socklen)) == -1) goto failed; - - close(listener); - if (connect_done == 0) { - if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0 - && errno != EISCONN) goto failed; - } - - set_blocking(fd[1], 1); - - /* all OK! */ - return 0; - - failed: - if (fd[0] != -1) close(fd[0]); - if (fd[1] != -1) close(fd[1]); - if (listener != -1) close(listener); - return -1; -} - - -/******************************************************************* -run a program on a local tcp socket, this is used to launch smbd -when regression testing -the return value is a socket which is attached to a subprocess -running "prog". stdin and stdout are attached. stderr is left -attached to the original stderr - ******************************************************************/ -int sock_exec(const char *prog) -{ - int fd[2]; - if (socketpair_tcp(fd) != 0) { - DEBUG(0,("socketpair_tcp failed (%s)\n", strerror(errno))); - return -1; - } - if (fork() == 0) { - close(fd[0]); - close(0); - close(1); - dup(fd[1]); - dup(fd[1]); - exit(system(prog)); - } - close(fd[1]); - return fd[0]; -} -- cgit From 6b814c9908c307abf427af37c00332de5e369eb4 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 16 Jul 2003 02:17:55 +0000 Subject: Volker's patch for open_socket_out() to speed up connections (This used to be commit 7d63b690004a59316a70059db0d9ad0ea9001288) --- source3/lib/util_sock.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 8c171852ab..1bd4c3a96b 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -654,8 +654,8 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) { struct sockaddr_in sock_out; int res,ret; - int connect_loop = 250; /* 250 milliseconds */ - int loops = (timeout) / connect_loop; + int connect_loop = 10; + int increment = 10; /* create a socket to write to */ res = socket(PF_INET, type, 0); @@ -681,8 +681,13 @@ connect_again: /* Some systems return EAGAIN when they mean EINPROGRESS */ if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || - errno == EAGAIN) && loops--) { + errno == EAGAIN) && (connect_loop < timeout) ) { msleep(connect_loop); + connect_loop += increment; + if (increment < 250) { + /* After 8 rounds we end up at a max of 255 msec */ + increment *= 1.5; + } goto connect_again; } -- cgit From 4fbbaff415dbb8f1d06b6213e394860bf07a6b6d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 Jul 2003 21:06:21 +0000 Subject: Add API framework for server SMB signing. Jeremy. (This used to be commit 61fc9a7b2eafdf8cbed1f8d9aae016b828c91a08) --- source3/lib/util_sock.c | 182 ++++++++++++++++++++++++++---------------------- 1 file changed, 100 insertions(+), 82 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 1bd4c3a96b..5320b504eb 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -289,7 +289,7 @@ ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,un } /**************************************************************************** - read data from the client, reading exactly N bytes. + Read data from the client, reading exactly N bytes. ****************************************************************************/ ssize_t read_data(int fd,char *buffer,size_t N) @@ -397,7 +397,7 @@ static ssize_t write_socket_data(int fd,char *buffer,size_t N) } /**************************************************************************** -write to a socket + Write to a socket. ****************************************************************************/ ssize_t write_socket(int fd,char *buf,size_t len) @@ -416,7 +416,7 @@ ssize_t write_socket(int fd,char *buf,size_t len) } /**************************************************************************** -send a keepalive packet (rfc1002) + Send a keepalive packet (rfc1002). ****************************************************************************/ BOOL send_keepalive(int client) @@ -431,11 +431,11 @@ BOOL send_keepalive(int client) /**************************************************************************** -read 4 bytes of a smb packet and return the smb length of the packet -store the result in the buffer -This version of the function will return a length of zero on receiving -a keepalive packet. -timeout is in milliseconds. + Read 4 bytes of a smb packet and return the smb length of the packet. + Store the result in the buffer. + This version of the function will return a length of zero on receiving + a keepalive packet. + Timeout is in milliseconds. ****************************************************************************/ static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int timeout) @@ -466,10 +466,10 @@ static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int } /**************************************************************************** -read 4 bytes of a smb packet and return the smb length of the packet -store the result in the buffer. This version of the function will -never return a session keepalive (length of zero). -timeout is in milliseconds. + Read 4 bytes of a smb packet and return the smb length of the packet. + Store the result in the buffer. This version of the function will + never return a session keepalive (length of zero). + Timeout is in milliseconds. ****************************************************************************/ ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout) @@ -493,11 +493,10 @@ ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout) } /**************************************************************************** - read an smb from a fd. Note that the buffer *MUST* be of size - BUFFER_SIZE+SAFETY_MARGIN. - The timeout is in milliseconds. - This function will return on a - receipt of a session keepalive packet. + Read an smb from a fd. Note that the buffer *MUST* be of size + BUFFER_SIZE+SAFETY_MARGIN. + The timeout is in milliseconds. + This function will return on receipt of a session keepalive packet. ****************************************************************************/ BOOL receive_smb(int fd,char *buffer, unsigned int timeout) @@ -553,11 +552,19 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout) } } + /* Check the incoming SMB signature. */ + if (!srv_check_sign_mac(buffer)) { + DEBUG(0, ("receive_smb: SMB Signature verification failed on incoming packet!\n")); + if (smb_read_error == 0) + smb_read_error = READ_BAD_SIG; + return False; + }; + return(True); } /**************************************************************************** - send an smb to a fd + Send an smb to a fd. ****************************************************************************/ BOOL send_smb(int fd,char *buffer) @@ -565,6 +572,10 @@ BOOL send_smb(int fd,char *buffer) size_t len; size_t nwritten=0; ssize_t ret; + + /* Sign the outgoing packet if required. */ + srv_calculate_sign_mac(buffer); + len = smb_len(buffer) + 4; while (nwritten < len) { @@ -647,80 +658,86 @@ int open_socket_in( int type, int port, int dlevel, uint32 socket_addr, BOOL reb } /**************************************************************************** - create an outgoing socket. timeout is in milliseconds. - **************************************************************************/ + Create an outgoing socket. timeout is in milliseconds. +**************************************************************************/ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) { - struct sockaddr_in sock_out; - int res,ret; - int connect_loop = 10; - int increment = 10; + struct sockaddr_in sock_out; + int res,ret; + int connect_loop = 10; + int increment = 10; - /* create a socket to write to */ - res = socket(PF_INET, type, 0); - if (res == -1) - { DEBUG(0,("socket error\n")); return -1; } + /* create a socket to write to */ + res = socket(PF_INET, type, 0); + if (res == -1) { + DEBUG(0,("socket error\n")); + return -1; + } - if (type != SOCK_STREAM) return(res); + if (type != SOCK_STREAM) + return(res); - memset((char *)&sock_out,'\0',sizeof(sock_out)); - putip((char *)&sock_out.sin_addr,(char *)addr); + memset((char *)&sock_out,'\0',sizeof(sock_out)); + putip((char *)&sock_out.sin_addr,(char *)addr); - sock_out.sin_port = htons( port ); - sock_out.sin_family = PF_INET; + sock_out.sin_port = htons( port ); + sock_out.sin_family = PF_INET; - /* set it non-blocking */ - set_blocking(res,False); + /* set it non-blocking */ + set_blocking(res,False); - DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port)); + DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port)); - /* and connect it to the destination */ -connect_again: - ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out)); - - /* Some systems return EAGAIN when they mean EINPROGRESS */ - if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || - errno == EAGAIN) && (connect_loop < timeout) ) { - msleep(connect_loop); - connect_loop += increment; - if (increment < 250) { - /* After 8 rounds we end up at a max of 255 msec */ - increment *= 1.5; - } - goto connect_again; - } - - if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || - errno == EAGAIN)) { - DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port)); - close(res); - return -1; - } + /* and connect it to the destination */ + connect_again: + + ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out)); + + /* Some systems return EAGAIN when they mean EINPROGRESS */ + if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || + errno == EAGAIN) && (connect_loop < timeout) ) { + msleep(connect_loop); + connect_loop += increment; + if (increment < 250) { + /* After 8 rounds we end up at a max of 255 msec */ + increment *= 1.5; + } + goto connect_again; + } + + if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || + errno == EAGAIN)) { + DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port)); + close(res); + return -1; + } #ifdef EISCONN - if (ret < 0 && errno == EISCONN) { - errno = 0; - ret = 0; - } + + if (ret < 0 && errno == EISCONN) { + errno = 0; + ret = 0; + } #endif - if (ret < 0) { - DEBUG(2,("error connecting to %s:%d (%s)\n", - inet_ntoa(*addr),port,strerror(errno))); - close(res); - return -1; - } + if (ret < 0) { + DEBUG(2,("error connecting to %s:%d (%s)\n", + inet_ntoa(*addr),port,strerror(errno))); + close(res); + return -1; + } - /* set it blocking again */ - set_blocking(res,True); + /* set it blocking again */ + set_blocking(res,True); - return res; + return res; } -/* - open a connected UDP socket to host on port -*/ +/**************************************************************************** + Open a connected UDP socket to host on port +**************************************************************************/ + int open_udp_socket(const char *host, int port) { int type = SOCK_DGRAM; @@ -783,9 +800,10 @@ struct in_addr *client_inaddr(struct sockaddr *sa) } /******************************************************************* - matchname - determine if host name matches IP address. Used to - confirm a hostname lookup to prevent spoof attacks - ******************************************************************/ + Matchname - determine if host name matches IP address. Used to + confirm a hostname lookup to prevent spoof attacks. +******************************************************************/ + static BOOL matchname(char *remotehost,struct in_addr addr) { struct hostent *hp; @@ -828,10 +846,10 @@ static BOOL matchname(char *remotehost,struct in_addr addr) return False; } - /******************************************************************* - return the DNS name of the remote end of a socket - ******************************************************************/ + Return the DNS name of the remote end of a socket. +******************************************************************/ + char *get_socket_name(int fd, BOOL force_lookup) { static pstring name_buf; @@ -881,8 +899,9 @@ char *get_socket_name(int fd, BOOL force_lookup) } /******************************************************************* - return the IP addr of the remote end of a socket as a string + Return the IP addr of the remote end of a socket as a string. ******************************************************************/ + char *get_socket_addr(int fd) { struct sockaddr sa; @@ -906,7 +925,6 @@ char *get_socket_addr(int fd) return addr_buf; } - /******************************************************************* Create protected unix domain socket. -- cgit From 3a5dc7c2ecacecf7dd0cfd71ff1bb298d70b391b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 23 Jul 2003 12:33:59 +0000 Subject: convert snprintf() calls using pstrings & fstrings to pstr_sprintf() and fstr_sprintf() to try to standardize. lots of snprintf() calls were using len-1; some were using len. At least this helps to be consistent. (This used to be commit 9f835b85dd38cbe655eb19021ff763f31886ac00) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 5320b504eb..b8b8471708 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -986,7 +986,7 @@ int create_pipe_sock(const char *socket_dir, goto out_umask; } - snprintf(path, sizeof(path), "%s/%s", socket_dir, socket_name); + pstr_sprintf(path, "%s/%s", socket_dir, socket_name); unlink(path); memset(&sunaddr, 0, sizeof(sunaddr)); -- cgit From f589164ed94d79161d0798296c325b81c5eadbc7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Oct 2003 21:19:00 +0000 Subject: Patch from Stefan Metzmacher to fix signing problems when reverse connecting back to a client for printer notify. Jeremy. (This used to be commit 06aa434c3fdb139e3f3143d19413556945cbcd4f) --- source3/lib/util_sock.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index b8b8471708..5a1f631ba4 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -497,9 +497,10 @@ ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout) BUFFER_SIZE+SAFETY_MARGIN. The timeout is in milliseconds. This function will return on receipt of a session keepalive packet. + Doesn't check the MAC on signed packets. ****************************************************************************/ -BOOL receive_smb(int fd,char *buffer, unsigned int timeout) +BOOL receive_smb_raw(int fd,char *buffer, unsigned int timeout) { ssize_t len,ret; @@ -509,7 +510,7 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout) len = read_smb_length_return_keepalive(fd,buffer,timeout); if (len < 0) { - DEBUG(10,("receive_smb: length < 0!\n")); + DEBUG(10,("receive_smb_raw: length < 0!\n")); /* * Correct fix. smb_read_error may have already been @@ -552,6 +553,20 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout) } } + return True; +} + +/**************************************************************************** + Wrapper for receive_smb_raw(). + Checks the MAC on signed packets. +****************************************************************************/ + +BOOL receive_smb(int fd,char *buffer, unsigned int timeout) +{ + if (!receive_smb_raw(fd, buffer, timeout)) { + return False; + } + /* Check the incoming SMB signature. */ if (!srv_check_sign_mac(buffer)) { DEBUG(0, ("receive_smb: SMB Signature verification failed on incoming packet!\n")); -- cgit From bb0598faf58679a7ad26a1caab8eadb154a07ae2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 22 Oct 2003 23:38:20 +0000 Subject: Put strcasecmp/strncasecmp on the banned list (except for needed calls in iconv.c and nsswitch/). Using them means you're not thinking about multibyte at all and I really want to discourage that. Jeremy. (This used to be commit d7e35dfb9283d560d0ed2ab231f36ed92767dace) --- source3/lib/util_sock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 5a1f631ba4..eb19caa31b 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -837,8 +837,8 @@ static BOOL matchname(char *remotehost,struct in_addr addr) * DNS is perverted). We always check the address list, though. */ - if (strcasecmp(remotehost, hp->h_name) - && strcasecmp(remotehost, "localhost")) { + if (!strequal(remotehost, hp->h_name) + && !strequal(remotehost, "localhost")) { DEBUG(0,("host name/name mismatch: %s != %s\n", remotehost, hp->h_name)); return False; -- cgit From fbb8f131c2336e921677f41e9fb8bce7406f3336 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 3 Nov 2003 14:34:25 +0000 Subject: Fix more 64-bit printf warnings. (This used to be commit 23443e3aa079710221557e18158d0ddb8ff48a36) --- source3/lib/util_sock.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index eb19caa31b..b59d7aa7eb 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -184,8 +184,8 @@ ssize_t read_udp_socket(int fd,char *buf,size_t len) lastip = sock.sin_addr; lastport = ntohs(sock.sin_port); - DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n", - inet_ntoa(lastip), lastport, ret)); + DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %lu\n", + inet_ntoa(lastip), lastport, (unsigned long)ret)); return(ret); } @@ -460,7 +460,7 @@ static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int DEBUG(5,("Got keepalive packet\n")); } - DEBUG(10,("got smb length of %d\n",len)); + DEBUG(10,("got smb length of %lu\n",(unsigned long)len)); return(len); } @@ -487,7 +487,8 @@ ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout) break; } - DEBUG(10,("read_smb_length: got smb length of %d\n",len)); + DEBUG(10,("read_smb_length: got smb length of %lu\n", + (unsigned long)len)); return len; } @@ -529,7 +530,7 @@ BOOL receive_smb_raw(int fd,char *buffer, unsigned int timeout) */ if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) { - DEBUG(0,("Invalid packet length! (%d bytes).\n",len)); + DEBUG(0,("Invalid packet length! (%lu bytes).\n",(unsigned long)len)); if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) { /* -- cgit From d5573ccde3b5c39eb9a4637d5a9d7a95b66d86e3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 7 Nov 2003 09:03:02 +0000 Subject: Simple rename of get_socket_addr to get_peer_addr and get_socket_name to get_peer_name. This is to get closer to the getsockname/getpeername system functions. Next step will be the %i macro for the local IP address. I still want to play %L-games in times of port 445. Volker (This used to be commit d7162122eaf5d897e5de51604e431bfbaa20e905) --- source3/lib/util_sock.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index b59d7aa7eb..bdd167b04d 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -794,12 +794,12 @@ void client_setfd(int fd) char *client_name(void) { - return get_socket_name(client_fd,False); + return get_peer_name(client_fd,False); } char *client_addr(void) { - return get_socket_addr(client_fd); + return get_peer_addr(client_fd); } struct in_addr *client_inaddr(struct sockaddr *sa) @@ -866,7 +866,7 @@ static BOOL matchname(char *remotehost,struct in_addr addr) Return the DNS name of the remote end of a socket. ******************************************************************/ -char *get_socket_name(int fd, BOOL force_lookup) +char *get_peer_name(int fd, BOOL force_lookup) { static pstring name_buf; static fstring addr_buf; @@ -879,10 +879,10 @@ char *get_socket_name(int fd, BOOL force_lookup) with dns. To avoid the delay we avoid the lookup if possible */ if (!lp_hostname_lookups() && (force_lookup == False)) { - return get_socket_addr(fd); + return get_peer_addr(fd); } - p = get_socket_addr(fd); + p = get_peer_addr(fd); /* it might be the same as the last one - save some DNS work */ if (strcmp(p, addr_buf) == 0) return name_buf; @@ -918,7 +918,7 @@ char *get_socket_name(int fd, BOOL force_lookup) Return the IP addr of the remote end of a socket as a string. ******************************************************************/ -char *get_socket_addr(int fd) +char *get_peer_addr(int fd) { struct sockaddr sa; struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); -- cgit From 88b0120e5668bc2092563bbaa35928e5cabe29d9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 7 Nov 2003 10:11:48 +0000 Subject: Implement %i-Macro for the locally used IP address. With this you can again have virtual hosts with different configurations on a single smbd even on port 445. Volker (This used to be commit 3a7c8c4f0e7fcfc2e20e1ad5e4b8e3c215ef1f0d) --- source3/lib/util_sock.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index bdd167b04d..1d62da53c5 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -802,6 +802,11 @@ char *client_addr(void) return get_peer_addr(client_fd); } +char *client_socket_addr(void) +{ + return get_socket_addr(client_fd); +} + struct in_addr *client_inaddr(struct sockaddr *sa) { struct sockaddr_in *sockin = (struct sockaddr_in *) (sa); @@ -941,6 +946,29 @@ char *get_peer_addr(int fd) return addr_buf; } +char *get_socket_addr(int fd) +{ + struct sockaddr sa; + struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); + int length = sizeof(sa); + static fstring addr_buf; + + fstrcpy(addr_buf,"0.0.0.0"); + + if (fd == -1) { + return addr_buf; + } + + if (getsockname(fd, &sa, &length) < 0) { + DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) )); + return addr_buf; + } + + fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr)); + + return addr_buf; +} + /******************************************************************* Create protected unix domain socket. -- cgit From e25b7b8eed38942dc8daaff3b7273c1c60fe82f0 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 9 Dec 2003 18:20:27 +0000 Subject: fix bug in get_peer_name() caused by --enable-developer and using the same src & dest strings to alpha_strcpy(); reported by Michael Young (This used to be commit b7df6849c9368aa2e5960de54a03be269ab89fef) --- source3/lib/util_sock.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 1d62da53c5..328ca92727 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -874,6 +874,7 @@ static BOOL matchname(char *remotehost,struct in_addr addr) char *get_peer_name(int fd, BOOL force_lookup) { static pstring name_buf; + pstring tmp_name; static fstring addr_buf; struct hostent *hp; struct in_addr addr; @@ -890,10 +891,12 @@ char *get_peer_name(int fd, BOOL force_lookup) p = get_peer_addr(fd); /* it might be the same as the last one - save some DNS work */ - if (strcmp(p, addr_buf) == 0) return name_buf; + if (strcmp(p, addr_buf) == 0) + return name_buf; pstrcpy(name_buf,"UNKNOWN"); - if (fd == -1) return name_buf; + if (fd == -1) + return name_buf; fstrcpy(addr_buf, p); @@ -911,7 +914,12 @@ char *get_peer_name(int fd, BOOL force_lookup) } } - alpha_strcpy(name_buf, name_buf, "_-.", sizeof(name_buf)); + /* can't pass the same source and dest strings in when you + use --enable-developer or the clobber_region() call will + get you */ + + pstrcpy( tmp_name, name_buf ); + alpha_strcpy(name_buf, tmp_name, "_-.", sizeof(name_buf)); if (strstr(name_buf,"..")) { pstrcpy(name_buf, "UNKNOWN"); } -- cgit From 7847b611acff4ed2453aaacdd1455ceaf84bb431 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 2 Feb 2004 12:09:35 +0000 Subject: there are places in the samba3 code that don't check properly for packet-termination of strings. This change ensures that when we go past the end of a packet we hit 2 null bytes, thus terminating. We are relying on the SAFETY_MARGIN packet allocation stuff here. (This used to be commit 655ec168288159f5c0961ed8cbdd84c4e14eab26) --- source3/lib/util_sock.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 328ca92727..5eb9c18b60 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -552,6 +552,10 @@ BOOL receive_smb_raw(int fd,char *buffer, unsigned int timeout) smb_read_error = READ_ERROR; return False; } + + /* not all of samba3 properly checks for packet-termination of strings. This + ensures that we don't run off into empty space. */ + SSVAL(buffer+4,len, 0); } return True; -- cgit From 8a547323d26a0350eb0a2bfc4d9ebeaade7baacc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Feb 2004 11:00:25 +0000 Subject: More 'static' work. Andrew Bartlett (This used to be commit 25a09004e8a51eb3192adbb580239427bfee0ec9) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 5eb9c18b60..594bc121b1 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -958,7 +958,7 @@ char *get_peer_addr(int fd) return addr_buf; } -char *get_socket_addr(int fd) +static char *get_socket_addr(int fd) { struct sockaddr sa; struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); -- cgit From 45616e18a866fc54f046d17ecd615e16d820250e Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 10 Feb 2004 04:02:53 +0000 Subject: more fixes from the static changes; please move static functions to the top of files to prevent this from happening (This used to be commit 7a61c2ae450d3e41c45e6e3773ad00f6ab9beb16) --- source3/lib/util_sock.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 594bc121b1..782f5f3f73 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -29,6 +29,29 @@ int lastport=0; int smb_read_error = 0; +static char *get_socket_addr(int fd) +{ + struct sockaddr sa; + struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); + int length = sizeof(sa); + static fstring addr_buf; + + fstrcpy(addr_buf,"0.0.0.0"); + + if (fd == -1) { + return addr_buf; + } + + if (getsockname(fd, &sa, &length) < 0) { + DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) )); + return addr_buf; + } + + fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr)); + + return addr_buf; +} + /**************************************************************************** Determine if a file descriptor is in fact a socket. ****************************************************************************/ @@ -958,29 +981,6 @@ char *get_peer_addr(int fd) return addr_buf; } -static char *get_socket_addr(int fd) -{ - struct sockaddr sa; - struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); - int length = sizeof(sa); - static fstring addr_buf; - - fstrcpy(addr_buf,"0.0.0.0"); - - if (fd == -1) { - return addr_buf; - } - - if (getsockname(fd, &sa, &length) < 0) { - DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) )); - return addr_buf; - } - - fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr)); - - return addr_buf; -} - /******************************************************************* Create protected unix domain socket. -- cgit From 24df38dbc6648261f86adcffd664ffc43f8f3346 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Mon, 23 Feb 2004 02:54:03 +0000 Subject: Janitor for tpot...bugzilla #1098, msleep already exists on aix (This used to be commit 4319df7fdc2d878c509381923cc1db4d731620ba) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 782f5f3f73..a275ddabb9 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -740,7 +740,7 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) /* Some systems return EAGAIN when they mean EINPROGRESS */ if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || errno == EAGAIN) && (connect_loop < timeout) ) { - msleep(connect_loop); + smb_msleep(connect_loop); connect_loop += increment; if (increment < 250) { /* After 8 rounds we end up at a max of 255 msec */ -- cgit From 56ce6136792478c63d371a7b187c1318043e081f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 19 Mar 2004 16:22:47 +0000 Subject: updating release notes & merging Derrel Lipman's libsmbclient patch from HEAD (This used to be commit 5fbfaa687a3674287eeadd205f56b2b253a9e2a9) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index a275ddabb9..19fb41f6ca 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -714,7 +714,7 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) /* create a socket to write to */ res = socket(PF_INET, type, 0); if (res == -1) { - DEBUG(0,("socket error\n")); + DEBUG(0,("socket error (%s)\n", strerror(errno))); return -1; } -- cgit From e9a7e67e01c115328f95690cbf63ca1ef0b4d408 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 27 Mar 2004 07:33:59 +0000 Subject: Merge from HEAD the SMB signing patch that I developed a couple of weeks ago. This patch re-adds support for 'optional' SMB signing. It also ensures that we are much more careful about when we enable signing, particularly with on-the-fly smb.conf reloads. The client code will now attempt to use smb signing by default, and disable it if the server doesn't correctly support it. Andrew Bartlett (This used to be commit e27b5cbe75d89ec839dafd52dd33101885a4c263) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 19fb41f6ca..845aaa4b13 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -596,7 +596,7 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout) } /* Check the incoming SMB signature. */ - if (!srv_check_sign_mac(buffer)) { + if (!srv_check_sign_mac(buffer, True)) { DEBUG(0, ("receive_smb: SMB Signature verification failed on incoming packet!\n")); if (smb_read_error == 0) smb_read_error = READ_BAD_SIG; -- cgit From fc7a1ee35e3bc7aff7a78e0e8e066699fa70fa4b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 30 Apr 2004 13:58:23 +0000 Subject: r426: fixed bug noticed by wim.delvaux@adaptiveplanet.com in handling of timeout in socket connections (This used to be commit 88278b24de4e3e408ac8a6139bd375a72bc664ce) --- source3/lib/util_sock.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 845aaa4b13..3984f5e8ac 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -741,6 +741,7 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || errno == EAGAIN) && (connect_loop < timeout) ) { smb_msleep(connect_loop); + timeout -= connect_loop; connect_loop += increment; if (increment < 250) { /* After 8 rounds we end up at a max of 255 msec */ -- cgit From f9eda19d80f40b39ffbd48119928651512a11d49 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 5 May 2004 03:03:38 +0000 Subject: r487: fixing some compile issues with the IBM AIX compiler reoported on the ml -- now to watch the build farm some more (This used to be commit 79fed5f5a73cfe4811f626acbcf85860e23e7826) --- source3/lib/util_sock.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 3984f5e8ac..b6bfdca5cf 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -33,7 +33,7 @@ static char *get_socket_addr(int fd) { struct sockaddr sa; struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); - int length = sizeof(sa); + socklen_t length = sizeof(sa); static fstring addr_buf; fstrcpy(addr_buf,"0.0.0.0"); @@ -58,7 +58,8 @@ static char *get_socket_addr(int fd) BOOL is_a_socket(int fd) { - int v,l; + int v; + socklen_t l; l = sizeof(int); return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0); } @@ -115,7 +116,8 @@ static const smb_socket_option socket_options[] = { static void print_socket_options(int s) { - int value, vlen = 4; + int value; + socklen_t vlen = 4; const smb_socket_option *p = &socket_options[0]; /* wrapped in if statement to prevent streams leak in SCO Openserver 5.0 */ @@ -838,7 +840,7 @@ char *client_socket_addr(void) struct in_addr *client_inaddr(struct sockaddr *sa) { struct sockaddr_in *sockin = (struct sockaddr_in *) (sa); - int length = sizeof(*sa); + socklen_t length = sizeof(*sa); if (getpeername(client_fd, sa, &length) < 0) { DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) )); @@ -963,7 +965,7 @@ char *get_peer_addr(int fd) { struct sockaddr sa; struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); - int length = sizeof(sa); + socklen_t length = sizeof(sa); static fstring addr_buf; fstrcpy(addr_buf,"0.0.0.0"); -- cgit From 76ca0f6f3f57c487564697c795da65672bbf4052 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 10 Jun 2004 17:09:00 +0000 Subject: r1104: get_called_name is used in the printing subsystem. In case of multi-homed servers we need to make sure that the clients are given back the IP address they connected to. Volker (This used to be commit 5f482df169eebae87ec769a05e3c3fc6e32af1e3) --- source3/lib/util_sock.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index b6bfdca5cf..4b9881a449 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -52,6 +52,23 @@ static char *get_socket_addr(int fd) return addr_buf; } +static int get_socket_port(int fd) +{ + struct sockaddr sa; + struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); + socklen_t length = sizeof(sa); + + if (fd == -1) + return -1; + + if (getsockname(fd, &sa, &length) < 0) { + DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) )); + return -1; + } + + return ntohs(sockin->sin_port); +} + /**************************************************************************** Determine if a file descriptor is in fact a socket. ****************************************************************************/ @@ -837,6 +854,11 @@ char *client_socket_addr(void) return get_socket_addr(client_fd); } +int client_socket_port(void) +{ + return get_socket_port(client_fd); +} + struct in_addr *client_inaddr(struct sockaddr *sa) { struct sockaddr_in *sockin = (struct sockaddr_in *) (sa); -- cgit From 6ae9b63f012b6cc3accd129016fc4c1cf2c29322 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 14 Oct 2004 22:30:33 +0000 Subject: r2978: Fix #1926 typo in debug. Found by Bill McGonigle . Jeremy. (This used to be commit 4fd314243e82d9c55bc9849a722424d45553013e) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 4b9881a449..8c16533bf9 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -43,7 +43,7 @@ static char *get_socket_addr(int fd) } if (getsockname(fd, &sa, &length) < 0) { - DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) )); + DEBUG(0,("getsockname failed. Error was %s\n", strerror(errno) )); return addr_buf; } -- cgit From 24d3605d99513fd0ce11671a40ad3fca8a1caaf5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 18 Nov 2004 11:57:49 +0000 Subject: r3843: If a connection to a DC is requested, open connections simultaeneously to all DCs found. The first one to reply wins. Volker (This used to be commit 84ac54aef2bd56b5c889d3b05b8828aceb8ae00e) --- source3/lib/util_sock.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 8c16533bf9..27a7551e37 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -797,6 +797,142 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) return res; } +/**************************************************************************** + Create an outgoing TCP socket to any of the addrs. This is for + simultaneous connects to port 445 and 139 of a host or even a variety + of DC's all of which are equivalent for our purposes. +**************************************************************************/ + +BOOL open_any_socket_out(struct sockaddr_in *addrs, int num_addrs, + int timeout, int *fd_index, int *fd) +{ + int i, resulting_index, res; + int *sockets; + BOOL good_connect; + + fd_set wr_fds; + struct timeval tv; + int maxfd; + + int connect_loop = 10000; /* 10 milliseconds */ + + timeout *= 1000; /* convert to microseconds */ + + sockets = malloc(num_addrs * sizeof(*sockets)); + + if (sockets == NULL) + return False; + + resulting_index = -1; + + for (i=0; imaxfd) + maxfd = sockets[i]; + } + + tv.tv_sec = 0; + tv.tv_usec = connect_loop; + + res = sys_select(maxfd+1, NULL, &wr_fds, NULL, &tv); + + if (res < 0) + goto done; + + if (res == 0) + goto next_round; + + for (i=0; i timeout) + connect_loop = timeout; + goto connect_again; + + done: + for (i=0; i= 0) + close(sockets[i]); + } + + if (resulting_index >= 0) { + *fd_index = resulting_index; + *fd = sockets[*fd_index]; + set_blocking(*fd, True); + } + + free(sockets); + + return (resulting_index >= 0); +} /**************************************************************************** Open a connected UDP socket to host on port **************************************************************************/ -- cgit From acf9d61421faa6c0055d57fdee7db300dc5431aa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Dec 2004 18:25:53 +0000 Subject: r4088: Get medieval on our ass about malloc.... :-). Take control of all our allocation functions so we can funnel through some well known functions. Should help greatly with malloc checking. HEAD patch to follow. Jeremy. (This used to be commit 620f2e608f70ba92f032720c031283d295c5c06a) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 27a7551e37..c09e4579c4 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -818,7 +818,7 @@ BOOL open_any_socket_out(struct sockaddr_in *addrs, int num_addrs, timeout *= 1000; /* convert to microseconds */ - sockets = malloc(num_addrs * sizeof(*sockets)); + sockets = SMB_MALLOC_ARRAY(int, num_addrs); if (sockets == NULL) return False; -- cgit From 786b6c5e284b0f9b01a7554e217e67ae777adf5a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 15 Dec 2004 12:05:48 +0000 Subject: r4217: Fix open_any_socket_out. This was a missing merge from HEAD or rather a commit to 3_0 from the wrong source. Fixed slightly over HEAD, HEAD merge will follow. Deal with connection refused according to the specs. Volker (This used to be commit 7230cb87eba2c296217bb0255893c55ae5d695d3) --- source3/lib/util_sock.c | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index c09e4579c4..58bc5ed6fe 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -810,7 +810,7 @@ BOOL open_any_socket_out(struct sockaddr_in *addrs, int num_addrs, int *sockets; BOOL good_connect; - fd_set wr_fds; + fd_set r_fds, wr_fds; struct timeval tv; int maxfd; @@ -840,6 +840,9 @@ BOOL open_any_socket_out(struct sockaddr_in *addrs, int num_addrs, for (i=0; imaxfd) maxfd = sockets[i]; } @@ -875,7 +886,7 @@ BOOL open_any_socket_out(struct sockaddr_in *addrs, int num_addrs, tv.tv_sec = 0; tv.tv_usec = connect_loop; - res = sys_select(maxfd+1, NULL, &wr_fds, NULL, &tv); + res = sys_select(maxfd+1, &r_fds, &wr_fds, NULL, &tv); if (res < 0) goto done; @@ -885,21 +896,24 @@ BOOL open_any_socket_out(struct sockaddr_in *addrs, int num_addrs, for (i=0; i Date: Sun, 1 May 2005 10:13:08 +0000 Subject: r6553: Added Linux per-socket TCP settings patch from "Ed Boraas" . Jeremy. (This used to be commit 96f0e2d3fc68010f9e956802710ce0bdb8d7c664) --- source3/lib/util_sock.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 58bc5ed6fe..4222c3c5ef 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -98,6 +98,15 @@ static const smb_socket_option socket_options[] = { #ifdef TCP_NODELAY {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL}, #endif +#ifdef TCP_KEEPCNT + {"TCP_KEEPCNT", IPPROTO_TCP, TCP_KEEPCNT, 0, OPT_INT}, +#endif +#ifdef TCP_KEEPIDLE + {"TCP_KEEPIDLE", IPPROTO_TCP, TCP_KEEPIDLE, 0, OPT_INT}, +#endif +#ifdef TCP_KEEPINTVL + {"TCP_KEEPINTVL", IPPROTO_TCP, TCP_KEEPINTVL, 0, OPT_INT}, +#endif #ifdef IPTOS_LOWDELAY {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON}, #endif -- cgit From fe0ce8dd8e18de6110404661f26db7a66ebac5ad Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 18 May 2005 18:02:15 +0000 Subject: r6890: Refactor printing interface to take offset into job. Fixes bug where large print jobs can have out-of-order offsets. Bug found by Arcady Chernyak Jeremy. (This used to be commit 482f7e0e3706098b71aa0b31a134994acb1e9fcf) --- source3/lib/util_sock.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 4222c3c5ef..72837d73d9 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -403,7 +403,7 @@ static ssize_t read_socket_data(int fd,char *buffer,size_t N) Write data to a fd. ****************************************************************************/ -ssize_t write_data(int fd,char *buffer,size_t N) +ssize_t write_data(int fd, const char *buffer, size_t N) { size_t total=0; ssize_t ret; @@ -427,7 +427,7 @@ ssize_t write_data(int fd,char *buffer,size_t N) Write data to a socket - use send rather than write. ****************************************************************************/ -static ssize_t write_socket_data(int fd,char *buffer,size_t N) +static ssize_t write_socket_data(int fd, const char *buffer, size_t N) { size_t total=0; ssize_t ret; @@ -451,7 +451,7 @@ static ssize_t write_socket_data(int fd,char *buffer,size_t N) Write to a socket. ****************************************************************************/ -ssize_t write_socket(int fd,char *buf,size_t len) +ssize_t write_socket(int fd, const char *buf, size_t len) { ssize_t ret=0; @@ -489,7 +489,7 @@ BOOL send_keepalive(int client) Timeout is in milliseconds. ****************************************************************************/ -static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int timeout) +static ssize_t read_smb_length_return_keepalive(int fd, char *inbuf, unsigned int timeout) { ssize_t len=0; int msg_type; @@ -523,7 +523,7 @@ static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int Timeout is in milliseconds. ****************************************************************************/ -ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout) +ssize_t read_smb_length(int fd, char *inbuf, unsigned int timeout) { ssize_t len; @@ -552,7 +552,7 @@ ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout) Doesn't check the MAC on signed packets. ****************************************************************************/ -BOOL receive_smb_raw(int fd,char *buffer, unsigned int timeout) +BOOL receive_smb_raw(int fd, char *buffer, unsigned int timeout) { ssize_t len,ret; @@ -617,7 +617,7 @@ BOOL receive_smb_raw(int fd,char *buffer, unsigned int timeout) Checks the MAC on signed packets. ****************************************************************************/ -BOOL receive_smb(int fd,char *buffer, unsigned int timeout) +BOOL receive_smb(int fd, char *buffer, unsigned int timeout) { if (!receive_smb_raw(fd, buffer, timeout)) { return False; @@ -638,7 +638,7 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout) Send an smb to a fd. ****************************************************************************/ -BOOL send_smb(int fd,char *buffer) +BOOL send_smb(int fd, char *buffer) { size_t len; size_t nwritten=0; -- cgit From 54aee75980dd7eb4cc4d5b8e94149fc088a3d7e5 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Fri, 27 May 2005 14:38:00 +0000 Subject: r7025: 1 if not all data is available at the time we go to read a packet, retry the read using a timeout to ensure that all data for the packet is received. 2 some minor changes to meet coding standards 3 eliminate some compiler warnings (This used to be commit 7b4d4f6109d815ec70c65564435d7d9bd22f66d9) --- source3/lib/util_sock.c | 71 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 58 insertions(+), 13 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 72837d73d9..ca7ecce74b 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -554,7 +554,8 @@ ssize_t read_smb_length(int fd, char *inbuf, unsigned int timeout) BOOL receive_smb_raw(int fd, char *buffer, unsigned int timeout) { - ssize_t len,ret; + char *p; + ssize_t n_remaining, n_read, len, ret; smb_read_error = 0; @@ -570,18 +571,20 @@ BOOL receive_smb_raw(int fd, char *buffer, unsigned int timeout) * variables still suck :-). JRA. */ - if (smb_read_error == 0) + if (smb_read_error == 0) { smb_read_error = READ_ERROR; + } return False; } /* - * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes - * of header. Don't print the error if this fits.... JRA. - */ + * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 + * bytes of header. Don't print the error if this fits.... JRA. + */ if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) { - DEBUG(0,("Invalid packet length! (%lu bytes).\n",(unsigned long)len)); + DEBUG(0,("Invalid packet length! (%lu bytes).\n", + (unsigned long)len)); if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) { /* @@ -590,23 +593,65 @@ BOOL receive_smb_raw(int fd, char *buffer, unsigned int timeout) * variables still suck :-). JRA. */ - if (smb_read_error == 0) + if (smb_read_error == 0) { smb_read_error = READ_ERROR; + } return False; } } if(len > 0) { - ret = read_socket_data(fd,buffer+4,len); - if (ret != len) { - if (smb_read_error == 0) + /* + * Read the remainder of the data. Don't use a timeout since + * the overhead of it is not usually necessary. + */ + p = buffer + 4; /* initial read buffer pointer */ + n_remaining = len; /* initial length to be read */ + n_read = 0; /* initialize number of bytes read */ + + ret = read_socket_data(fd, p, n_remaining); + + if ((ret < 0 && errno == EAGAIN) || + (ret > 0 && ret < n_remaining)) { + /* + * We were able to read the length earlier, but all of + * the remainder of the data is not yet available to + * us (as indicated by EAGAIN if we got nothing, or by + * the amount of just-read data not matching the + * packet length). Read again, this time awaiting the + * data to arrive for a short period of time. + */ + + /* If partial read occurred... */ + if (ret > 0) { + /* ... then update buffer pointer and counts */ + p += ret; + n_read += ret; + n_remaining -= ret; + } + + ret = read_socket_with_timeout(fd, p, n_remaining, + n_remaining, 20000); + if (ret > 0) { + n_read += ret; + } + } else { + n_read = ret; + } + + if (n_read != len) { + if (smb_read_error == 0) { smb_read_error = READ_ERROR; + } return False; } - /* not all of samba3 properly checks for packet-termination of strings. This - ensures that we don't run off into empty space. */ - SSVAL(buffer+4,len, 0); + /* + * not all of samba3 properly checks for packet-termination of + * strings. This ensures that we don't run off into empty + * space. + */ + SSVAL(buffer+4, len, 0); } return True; -- cgit From c3df3e3a087e333ed074e1f53f0dea0fb85a5dac Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 27 May 2005 17:47:24 +0000 Subject: r7034: Revert change in util_sock.c from derrell until this is discussed more on samba-technical. Jeremy. (This used to be commit 7ad6fdc1ef4754fc25d81ab27fd5ebb40e04a6cf) --- source3/lib/util_sock.c | 71 +++++++++---------------------------------------- 1 file changed, 13 insertions(+), 58 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index ca7ecce74b..72837d73d9 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -554,8 +554,7 @@ ssize_t read_smb_length(int fd, char *inbuf, unsigned int timeout) BOOL receive_smb_raw(int fd, char *buffer, unsigned int timeout) { - char *p; - ssize_t n_remaining, n_read, len, ret; + ssize_t len,ret; smb_read_error = 0; @@ -571,20 +570,18 @@ BOOL receive_smb_raw(int fd, char *buffer, unsigned int timeout) * variables still suck :-). JRA. */ - if (smb_read_error == 0) { + if (smb_read_error == 0) smb_read_error = READ_ERROR; - } return False; } /* - * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 - * bytes of header. Don't print the error if this fits.... JRA. - */ + * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes + * of header. Don't print the error if this fits.... JRA. + */ if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) { - DEBUG(0,("Invalid packet length! (%lu bytes).\n", - (unsigned long)len)); + DEBUG(0,("Invalid packet length! (%lu bytes).\n",(unsigned long)len)); if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) { /* @@ -593,65 +590,23 @@ BOOL receive_smb_raw(int fd, char *buffer, unsigned int timeout) * variables still suck :-). JRA. */ - if (smb_read_error == 0) { + if (smb_read_error == 0) smb_read_error = READ_ERROR; - } return False; } } if(len > 0) { - /* - * Read the remainder of the data. Don't use a timeout since - * the overhead of it is not usually necessary. - */ - p = buffer + 4; /* initial read buffer pointer */ - n_remaining = len; /* initial length to be read */ - n_read = 0; /* initialize number of bytes read */ - - ret = read_socket_data(fd, p, n_remaining); - - if ((ret < 0 && errno == EAGAIN) || - (ret > 0 && ret < n_remaining)) { - /* - * We were able to read the length earlier, but all of - * the remainder of the data is not yet available to - * us (as indicated by EAGAIN if we got nothing, or by - * the amount of just-read data not matching the - * packet length). Read again, this time awaiting the - * data to arrive for a short period of time. - */ - - /* If partial read occurred... */ - if (ret > 0) { - /* ... then update buffer pointer and counts */ - p += ret; - n_read += ret; - n_remaining -= ret; - } - - ret = read_socket_with_timeout(fd, p, n_remaining, - n_remaining, 20000); - if (ret > 0) { - n_read += ret; - } - } else { - n_read = ret; - } - - if (n_read != len) { - if (smb_read_error == 0) { + ret = read_socket_data(fd,buffer+4,len); + if (ret != len) { + if (smb_read_error == 0) smb_read_error = READ_ERROR; - } return False; } - /* - * not all of samba3 properly checks for packet-termination of - * strings. This ensures that we don't run off into empty - * space. - */ - SSVAL(buffer+4, len, 0); + /* not all of samba3 properly checks for packet-termination of strings. This + ensures that we don't run off into empty space. */ + SSVAL(buffer+4,len, 0); } return True; -- cgit From 96f179752d338b9958f645e769e562c43e8eb156 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 27 May 2005 20:07:28 +0000 Subject: r7039: Ensure we always call read_socket_with_timeout() when timeout > 0. Better solution after much helpful input from derrell@samba.org. We may eventually change the read_socket_with_timeout() interface to count down the timeout value. Jeremy. (This used to be commit 09c9a62aa53ed26e59ed57e577614d02a796c492) --- source3/lib/util_sock.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 72837d73d9..20dbdf8054 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -597,7 +597,12 @@ BOOL receive_smb_raw(int fd, char *buffer, unsigned int timeout) } if(len > 0) { - ret = read_socket_data(fd,buffer+4,len); + if (timeout > 0) { + ret = read_socket_with_timeout(fd,buffer+4,len,len,timeout); + } else { + ret = read_socket_data(fd,buffer+4,len); + } + if (ret != len) { if (smb_read_error == 0) smb_read_error = READ_ERROR; -- cgit From 06ae1e805e45fa381739a64ef79fa99b25fa025c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 6 Jun 2005 04:07:10 +0000 Subject: r7318: Unify HEAD and 3.0 socket functions. Add HEAD functions here #ifdef'ed out. Correct branch this time ! Jeremy. (This used to be commit 052b4f8e2849b4897176e64cc29b6a5f686d946e) --- source3/lib/util_sock.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 20dbdf8054..6107e5abed 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -241,6 +241,99 @@ ssize_t read_udp_socket(int fd,char *buf,size_t len) return(ret); } +#if 0 + +Socket routines from HEAD - maybe re-enable in future. JRA. + +/**************************************************************************** + Work out if we've timed out. +****************************************************************************/ + +static BOOL timeout_until(struct timeval *timeout, const struct timeval *endtime) +{ + struct timeval now; + SMB_BIG_INT t_dif; + + GetTimeOfDay(&now); + + t_dif = usec_time_diff(endtime, &now); + if (t_dif <= 0) { + return False; + } + + timeout->tv_sec = (t_dif / (SMB_BIG_INT)1000000); + timeout->tv_usec = (t_dif % (SMB_BIG_INT)1000000); + return True; +} + +/**************************************************************************** + Read data from the client, reading exactly N bytes, or until endtime timeout. + Use with a non-blocking socket if endtime != NULL. +****************************************************************************/ + +ssize_t read_data_until(int fd,char *buffer,size_t N, const struct timeval *endtime) +{ + ssize_t ret; + size_t total=0; + + smb_read_error = 0; + + while (total < N) { + + if (endtime != NULL) { + fd_set r_fds; + struct timeval timeout; + int selrtn; + + if (!timeout_until(&timeout, endtime)) { + DEBUG(10,("read_data_until: read timed out\n")); + smb_read_error = READ_TIMEOUT; + return -1; + } + + FD_ZERO(&r_fds); + FD_SET(fd, &r_fds); + + /* Select but ignore EINTR. */ + selrtn = sys_select_intr(fd+1, &r_fds, NULL, NULL, &timeout); + if (selrtn == -1) { + /* something is wrong. Maybe the socket is dead? */ + DEBUG(0,("read_data_until: select error = %s.\n", strerror(errno) )); + smb_read_error = READ_ERROR; + return -1; + } + + /* Did we timeout ? */ + if (selrtn == 0) { + DEBUG(10,("read_data_until: select timed out.\n")); + smb_read_error = READ_TIMEOUT; + return -1; + } + } + + ret = sys_read(fd,buffer + total,N - total); + + if (ret == 0) { + DEBUG(10,("read_data_until: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) )); + smb_read_error = READ_EOF; + return 0; + } + + if (ret == -1) { + if (errno == EAGAIN) { + /* Non-blocking socket with no data available. Try select again. */ + continue; + } + DEBUG(0,("read_data_until: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) )); + smb_read_error = READ_ERROR; + return -1; + } + total += ret; + } + return (ssize_t)total; +} +#endif + /**************************************************************************** Read data from a socket with a timout in msec. mincount = if timeout, minimum to read before returning -- cgit From 33a4c0b5a1052026193dcbb800e2bccb1b832730 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 13 Jun 2005 22:26:08 +0000 Subject: r7554: Refactor very messy code in util_sock.c Remove write_socket_data/read_socket_data as they do nothing that write_socket/read_socket don't do. Add a more useful error message when read_socket/write_socket error out on the main client fd for a process (ie. try and list the IP of the client that errored). Jeremy. (This used to be commit cbd7578e7c226e6a8002542141b914ed4c7a8269) --- source3/lib/util_sock.c | 228 ++++++++++++++++++++---------------------------- 1 file changed, 95 insertions(+), 133 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 6107e5abed..e5e16f1c48 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -3,6 +3,7 @@ Samba utility functions Copyright (C) Andrew Tridgell 1992-1998 Copyright (C) Tim Potter 2000-2001 + Copyright (C) Jeremy Allison 1992-2005 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,13 +22,15 @@ #include "includes.h" -/* the last IP received from */ -struct in_addr lastip; - -/* the last port received from */ -int lastport=0; +/* the following 3 client_*() functions are nasty ways of allowing + some generic functions to get info that really should be hidden in + particular modules */ +static int client_fd = -1; -int smb_read_error = 0; +void client_setfd(int fd) +{ + client_fd = fd; +} static char *get_socket_addr(int fd) { @@ -69,6 +72,47 @@ static int get_socket_port(int fd) return ntohs(sockin->sin_port); } +char *client_name(void) +{ + return get_peer_name(client_fd,False); +} + +char *client_addr(void) +{ + return get_peer_addr(client_fd); +} + +char *client_socket_addr(void) +{ + return get_socket_addr(client_fd); +} + +int client_socket_port(void) +{ + return get_socket_port(client_fd); +} + +struct in_addr *client_inaddr(struct sockaddr *sa) +{ + struct sockaddr_in *sockin = (struct sockaddr_in *) (sa); + socklen_t length = sizeof(*sa); + + if (getpeername(client_fd, sa, &length) < 0) { + DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) )); + return NULL; + } + + return &sockin->sin_addr; +} + +/* the last IP received from */ +struct in_addr lastip; + +/* the last port received from */ +int lastport=0; + +int smb_read_error = 0; + /**************************************************************************** Determine if a file descriptor is in fact a socket. ****************************************************************************/ @@ -356,8 +400,10 @@ ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,un smb_read_error = 0; /* Blocking read */ - if (time_out <= 0) { - if (mincnt == 0) mincnt = maxcnt; + if (time_out == 0) { + if (mincnt == 0) { + mincnt = maxcnt; + } while (nread < mincnt) { readret = sys_read(fd, buf + nread, maxcnt - nread); @@ -369,7 +415,13 @@ ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,un } if (readret == -1) { - DEBUG(0,("read_socket_with_timeout: read error = %s.\n", strerror(errno) )); + if (fd == client_fd) { + /* Try and give an error message saying what client failed. */ + DEBUG(0,("read_socket_with_timeout: client %s read error = %s.\n", + client_addr(), strerror(errno) )); + } else { + DEBUG(0,("read_socket_with_timeout: read error = %s.\n", strerror(errno) )); + } smb_read_error = READ_ERROR; return -1; } @@ -397,7 +449,13 @@ ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,un /* Check if error */ if (selrtn == -1) { /* something is wrong. Maybe the socket is dead? */ - DEBUG(0,("read_socket_with_timeout: timeout read. select error = %s.\n", strerror(errno) )); + if (fd == client_fd) { + /* Try and give an error message saying what client failed. */ + DEBUG(0,("read_socket_with_timeout: timeout read for client %s. select error = %s.\n", + client_addr(), strerror(errno) )); + } else { + DEBUG(0,("read_socket_with_timeout: timeout read. select error = %s.\n", strerror(errno) )); + } smb_read_error = READ_ERROR; return -1; } @@ -420,7 +478,13 @@ ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,un if (readret == -1) { /* the descriptor is probably dead */ - DEBUG(0,("read_socket_with_timeout: timeout read. read error = %s.\n", strerror(errno) )); + if (fd == client_fd) { + /* Try and give an error message saying what client failed. */ + DEBUG(0,("read_socket_with_timeout: timeout read to client %s. read error = %s.\n", + client_addr(), strerror(errno) )); + } else { + DEBUG(0,("read_socket_with_timeout: timeout read. read error = %s.\n", strerror(errno) )); + } smb_read_error = READ_ERROR; return -1; } @@ -453,37 +517,13 @@ ssize_t read_data(int fd,char *buffer,size_t N) } if (ret == -1) { - DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) )); - smb_read_error = READ_ERROR; - return -1; - } - total += ret; - } - return (ssize_t)total; -} - -/**************************************************************************** - Read data from a socket, reading exactly N bytes. -****************************************************************************/ - -static ssize_t read_socket_data(int fd,char *buffer,size_t N) -{ - ssize_t ret; - size_t total=0; - - smb_read_error = 0; - - while (total < N) { - ret = sys_read(fd,buffer + total,N - total); - - if (ret == 0) { - DEBUG(10,("read_socket_data: recv of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) )); - smb_read_error = READ_EOF; - return 0; - } - - if (ret == -1) { - DEBUG(0,("read_socket_data: recv failure for %d. Error = %s\n", (int)(N - total), strerror(errno) )); + if (fd == client_fd) { + /* Try and give an error message saying what client failed. */ + DEBUG(0,("read_data: read failure for %d bytes to client %s. Error = %s\n", + (int)(N - total), client_addr(), strerror(errno) )); + } else { + DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) )); + } smb_read_error = READ_ERROR; return -1; } @@ -505,60 +545,25 @@ ssize_t write_data(int fd, const char *buffer, size_t N) ret = sys_write(fd,buffer + total,N - total); if (ret == -1) { - DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) )); + if (fd == client_fd) { + /* Try and give an error message saying what client failed. */ + DEBUG(0,("write_data: write failure in writing to client %s. Error %s\n", + client_addr(), strerror(errno) )); + } else { + DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) )); + } return -1; } - if (ret == 0) - return total; - - total += ret; - } - return (ssize_t)total; -} - -/**************************************************************************** - Write data to a socket - use send rather than write. -****************************************************************************/ - -static ssize_t write_socket_data(int fd, const char *buffer, size_t N) -{ - size_t total=0; - ssize_t ret; - - while (total < N) { - ret = sys_send(fd,buffer + total,N - total,0); - if (ret == -1) { - DEBUG(0,("write_socket_data: write failure. Error = %s\n", strerror(errno) )); - return -1; - } - if (ret == 0) + if (ret == 0) { return total; + } total += ret; } return (ssize_t)total; } -/**************************************************************************** - Write to a socket. -****************************************************************************/ - -ssize_t write_socket(int fd, const char *buf, size_t len) -{ - ssize_t ret=0; - - DEBUG(6,("write_socket(%d,%d)\n",fd,(int)len)); - ret = write_socket_data(fd,buf,len); - - DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,(int)len,(int)ret)); - if(ret <= 0) - DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n", - (int)len, fd, strerror(errno) )); - - return(ret); -} - /**************************************************************************** Send a keepalive packet (rfc1002). ****************************************************************************/ @@ -570,7 +575,7 @@ BOOL send_keepalive(int client) buf[0] = SMBkeepalive; buf[1] = buf[2] = buf[3] = 0; - return(write_socket_data(client,(char *)buf,4) == 4); + return(write_data(client,(char *)buf,4) == 4); } @@ -592,7 +597,7 @@ static ssize_t read_smb_length_return_keepalive(int fd, char *inbuf, unsigned in if (timeout > 0) ok = (read_socket_with_timeout(fd,inbuf,4,4,timeout) == 4); else - ok = (read_socket_data(fd,inbuf,4) == 4); + ok = (read_data(fd,inbuf,4) == 4); if (!ok) return(-1); @@ -693,7 +698,7 @@ BOOL receive_smb_raw(int fd, char *buffer, unsigned int timeout) if (timeout > 0) { ret = read_socket_with_timeout(fd,buffer+4,len,len,timeout); } else { - ret = read_socket_data(fd,buffer+4,len); + ret = read_data(fd,buffer+4,len); } if (ret != len) { @@ -748,7 +753,7 @@ BOOL send_smb(int fd, char *buffer) len = smb_len(buffer) + 4; while (nwritten < len) { - ret = write_socket(fd,buffer+nwritten,len - nwritten); + ret = write_data(fd,buffer+nwritten,len - nwritten); if (ret <= 0) { DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n", (int)len,(int)ret, strerror(errno) )); @@ -1086,49 +1091,6 @@ int open_udp_socket(const char *host, int port) } -/* the following 3 client_*() functions are nasty ways of allowing - some generic functions to get info that really should be hidden in - particular modules */ -static int client_fd = -1; - -void client_setfd(int fd) -{ - client_fd = fd; -} - -char *client_name(void) -{ - return get_peer_name(client_fd,False); -} - -char *client_addr(void) -{ - return get_peer_addr(client_fd); -} - -char *client_socket_addr(void) -{ - return get_socket_addr(client_fd); -} - -int client_socket_port(void) -{ - return get_socket_port(client_fd); -} - -struct in_addr *client_inaddr(struct sockaddr *sa) -{ - struct sockaddr_in *sockin = (struct sockaddr_in *) (sa); - socklen_t length = sizeof(*sa); - - if (getpeername(client_fd, sa, &length) < 0) { - DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) )); - return NULL; - } - - return &sockin->sin_addr; -} - /******************************************************************* Matchname - determine if host name matches IP address. Used to confirm a hostname lookup to prevent spoof attacks. -- cgit From 2efcdb2fb8202952df3337c3dde9617b9bb096f4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 15 Jun 2005 00:22:59 +0000 Subject: r7591: Don't call getpeeraddr on a disconnected socket. Jeremy. (This used to be commit a9cd218eb607066a65818b534ec5e3ecb55da4cf) --- source3/lib/util_sock.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index e5e16f1c48..6562dae952 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -26,10 +26,13 @@ some generic functions to get info that really should be hidden in particular modules */ static int client_fd = -1; +/* What to print out on a client disconnect error. */ +static char client_ip_string[16]; void client_setfd(int fd) { client_fd = fd; + safe_strcpy(client_ip_string, get_peer_addr(client_fd), sizeof(client_ip_string)-1); } static char *get_socket_addr(int fd) @@ -418,7 +421,7 @@ ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,un if (fd == client_fd) { /* Try and give an error message saying what client failed. */ DEBUG(0,("read_socket_with_timeout: client %s read error = %s.\n", - client_addr(), strerror(errno) )); + client_ip_string, strerror(errno) )); } else { DEBUG(0,("read_socket_with_timeout: read error = %s.\n", strerror(errno) )); } @@ -452,7 +455,7 @@ ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,un if (fd == client_fd) { /* Try and give an error message saying what client failed. */ DEBUG(0,("read_socket_with_timeout: timeout read for client %s. select error = %s.\n", - client_addr(), strerror(errno) )); + client_ip_string, strerror(errno) )); } else { DEBUG(0,("read_socket_with_timeout: timeout read. select error = %s.\n", strerror(errno) )); } @@ -481,7 +484,7 @@ ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,un if (fd == client_fd) { /* Try and give an error message saying what client failed. */ DEBUG(0,("read_socket_with_timeout: timeout read to client %s. read error = %s.\n", - client_addr(), strerror(errno) )); + client_ip_string, strerror(errno) )); } else { DEBUG(0,("read_socket_with_timeout: timeout read. read error = %s.\n", strerror(errno) )); } @@ -520,7 +523,7 @@ ssize_t read_data(int fd,char *buffer,size_t N) if (fd == client_fd) { /* Try and give an error message saying what client failed. */ DEBUG(0,("read_data: read failure for %d bytes to client %s. Error = %s\n", - (int)(N - total), client_addr(), strerror(errno) )); + (int)(N - total), client_ip_string, strerror(errno) )); } else { DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) )); } @@ -548,7 +551,7 @@ ssize_t write_data(int fd, const char *buffer, size_t N) if (fd == client_fd) { /* Try and give an error message saying what client failed. */ DEBUG(0,("write_data: write failure in writing to client %s. Error %s\n", - client_addr(), strerror(errno) )); + client_ip_string, strerror(errno) )); } else { DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) )); } -- cgit From d67b72a0f220b5a41496498914c8e28733ced8a1 Mon Sep 17 00:00:00 2001 From: James Peach Date: Sun, 15 Jan 2006 23:13:47 +0000 Subject: r12953: Support the TCP_FASTACK socket option if it is available. Note that this will not acutally help, but it is good to be complete. (This used to be commit 2163e4b6b453ebf1fefc64e74890300108bbf8f6) --- source3/lib/util_sock.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 6562dae952..91c3305996 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -180,6 +180,9 @@ static const smb_socket_option socket_options[] = { #endif #ifdef SO_RCVTIMEO {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT}, +#endif +#ifdef TCP_FASTACK + {"TCP_FASTACK", IPPROTO_TCP, TCP_FASTACK, 0, OPT_INT}, #endif {NULL,0,0,0,0}}; -- cgit From fc13f284179df5f3f3a1d475bf84da21dc89c970 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Apr 2006 01:43:13 +0000 Subject: r15030: On a performace hunt... Remove as many extraneous memset's as possible. Jeremy. (This used to be commit 1217ed392b75aa8bfefa9c3f1ec5fa3bba841ee0) --- source3/lib/util_sock.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 91c3305996..12fc2ead95 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -662,8 +662,6 @@ BOOL receive_smb_raw(int fd, char *buffer, unsigned int timeout) smb_read_error = 0; - memset(buffer,'\0',smb_size + 100); - len = read_smb_length_return_keepalive(fd,buffer,timeout); if (len < 0) { DEBUG(10,("receive_smb_raw: length < 0!\n")); @@ -708,8 +706,9 @@ BOOL receive_smb_raw(int fd, char *buffer, unsigned int timeout) } if (ret != len) { - if (smb_read_error == 0) + if (smb_read_error == 0) { smb_read_error = READ_ERROR; + } return False; } -- cgit From f895fcf1090c0400981587c36d040629b858deec Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 May 2006 01:30:00 +0000 Subject: r15672: Fix for bug #3783. winbindd_cm.c calls open_any_socket_out() to make connections to ports 445 or 139 on the DC it's trying to contact. It calls sys_select() on the non-blocking sockets, not sys_select_intr(). This is a mistake (I believe) as it allows a signal to early terminate the connection attempts - whereas sys_select_intr() will ignore signals until we get back to the main processing loop where they'll be handled correctly. This change means winbindd_cm will not early terminate if it gets a message whilst trying to connect to DC's. Gunther, Volker and Jerry please review (but I think this is correct). Jeremy. (This used to be commit 24aaa486771f797d35ea6b0711c12cd3e663dd8c) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 12fc2ead95..de90b29294 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1003,7 +1003,7 @@ BOOL open_any_socket_out(struct sockaddr_in *addrs, int num_addrs, tv.tv_sec = 0; tv.tv_usec = connect_loop; - res = sys_select(maxfd+1, &r_fds, &wr_fds, NULL, &tv); + res = sys_select_intr(maxfd+1, &r_fds, &wr_fds, NULL, &tv); if (res < 0) goto done; -- cgit From 0648638fef56a65f9389c8a98f66c57663e8c401 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 May 2006 19:49:44 +0000 Subject: r15700: Make nmbd udp sockets non-blocking to prevent problem with select returning true but no data being available. Fix for bug #3779. Jeremy. (This used to be commit e5787cf75b2e7d50f551f34f28d280c27b0aa134) --- source3/lib/util_sock.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index de90b29294..1a73a310b6 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -278,7 +278,12 @@ ssize_t read_udp_socket(int fd,char *buf,size_t len) memset((char *)&lastip,'\0',sizeof(lastip)); ret = (ssize_t)sys_recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen); if (ret <= 0) { - DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno))); + /* Don't print a low debug error for a non-blocking socket. */ + if (errno == EAGAIN) { + DEBUG(10,("read socket returned EAGAIN. ERRNO=%s\n",strerror(errno))); + } else { + DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno))); + } return(0); } -- cgit From 050534827f7dcbc9cd78683e477aaa6dd2ba9394 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 13 Dec 2006 05:54:39 +0000 Subject: r20148: Forgot to merge. Ensure open_any_socket_out() is safe from signals. Jeremy. (This used to be commit c264a0aa4a83a3d47db33446b16a8766bc14824f) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 1a73a310b6..2866a443d4 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -974,7 +974,7 @@ BOOL open_any_socket_out(struct sockaddr_in *addrs, int num_addrs, } if (errno == EINPROGRESS || errno == EALREADY || - errno == EAGAIN) { + errno == EAGAIN || errno == EINTR) { /* These are the error messages that something is progressing. */ good_connect = True; -- cgit From ecd496f06654e8316260c9a6ddab5e473f9cc452 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 17 Mar 2007 00:32:54 +0000 Subject: r21865: Add in the stubs for SMB transport encryption. Will flesh these out as I implement. Don't add to SAMBA_3_0_25, this is experimental code. NFSv4 you're now officially on notice... :-). Jeremy. (This used to be commit 5bfe638f2172e272741997100ee5ae8ff280494d) --- source3/lib/util_sock.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 2866a443d4..663502bef0 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -732,15 +732,28 @@ BOOL receive_smb_raw(int fd, char *buffer, unsigned int timeout) BOOL receive_smb(int fd, char *buffer, unsigned int timeout) { + NTSTATUS status; + if (!receive_smb_raw(fd, buffer, timeout)) { return False; } + status = srv_decrypt_buffer(buffer); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("receive_smb: SMB decryption failed on incoming packet! Error %s\n", + nt_errstr(status) )); + if (smb_read_error == 0) { + smb_read_error = READ_BAD_DECRYPT; + } + return False; + } + /* Check the incoming SMB signature. */ if (!srv_check_sign_mac(buffer, True)) { DEBUG(0, ("receive_smb: SMB Signature verification failed on incoming packet!\n")); - if (smb_read_error == 0) + if (smb_read_error == 0) { smb_read_error = READ_BAD_SIG; + } return False; }; @@ -753,6 +766,7 @@ BOOL receive_smb(int fd, char *buffer, unsigned int timeout) BOOL send_smb(int fd, char *buffer) { + NTSTATUS status; size_t len; size_t nwritten=0; ssize_t ret; @@ -760,6 +774,13 @@ BOOL send_smb(int fd, char *buffer) /* Sign the outgoing packet if required. */ srv_calculate_sign_mac(buffer); + status = srv_encrypt_buffer(buffer); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("send_smb: SMB encryption failed on outgoing packet! Error %s\n", + nt_errstr(status) )); + return False; + } + len = smb_len(buffer) + 4; while (nwritten < len) { -- cgit From c48b610b516b72edd6232235a6f83d388f5a0552 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 19 Mar 2007 20:39:58 +0000 Subject: r21876: Start adding in the seal implementation - prototype code for the server side enc. (doesn't break anything). I'll keep updating this until I've got NTLM seal working on both client and server, then add in the gss level seal. Jeremy. (This used to be commit 530ac29abf23e920baa549e7cec55199edd8bd74) --- source3/lib/util_sock.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 663502bef0..296405edd3 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -770,29 +770,32 @@ BOOL send_smb(int fd, char *buffer) size_t len; size_t nwritten=0; ssize_t ret; + char *buf_out; /* Sign the outgoing packet if required. */ srv_calculate_sign_mac(buffer); - status = srv_encrypt_buffer(buffer); + status = srv_encrypt_buffer(buffer, &buf_out); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("send_smb: SMB encryption failed on outgoing packet! Error %s\n", nt_errstr(status) )); return False; } - len = smb_len(buffer) + 4; + len = smb_len(buf_out) + 4; while (nwritten < len) { - ret = write_data(fd,buffer+nwritten,len - nwritten); + ret = write_data(fd,buf_out+nwritten,len - nwritten); if (ret <= 0) { DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n", (int)len,(int)ret, strerror(errno) )); + srv_free_buffer(buf_out); return False; } nwritten += ret; } + srv_free_buffer(buf_out); return True; } -- cgit From 7ccf45684a1f83d7d48a4227aa56c53081d68283 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 19 Mar 2007 22:45:35 +0000 Subject: r21880: Make client and server calls into encryption code symetrical, depending on encryption context pointer. Jeremy. (This used to be commit d3f3ced6c8a03d971143baf878158d671dfcbc3b) --- source3/lib/util_sock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 296405edd3..755ad39261 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -789,13 +789,13 @@ BOOL send_smb(int fd, char *buffer) if (ret <= 0) { DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n", (int)len,(int)ret, strerror(errno) )); - srv_free_buffer(buf_out); + srv_free_enc_buffer(buf_out); return False; } nwritten += ret; } - srv_free_buffer(buf_out); + srv_free_enc_buffer(buf_out); return True; } -- cgit From 8c395be5e514a28f13608a462c0c0e8417e21160 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Mar 2007 23:49:57 +0000 Subject: r21922: Fixed the build by rather horrid means. I really need to restructure libsmb/smb_signing.c so it isn't in the base libs path but lives in libsmb instead (like smb_seal.c does). Jeremy. (This used to be commit 1b828f051d0782201f697de15ff973bd6b097d5b) --- source3/lib/util_sock.c | 57 +++++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 28 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 755ad39261..a58fb03e77 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -732,32 +732,32 @@ BOOL receive_smb_raw(int fd, char *buffer, unsigned int timeout) BOOL receive_smb(int fd, char *buffer, unsigned int timeout) { - NTSTATUS status; - if (!receive_smb_raw(fd, buffer, timeout)) { return False; } - status = srv_decrypt_buffer(buffer); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("receive_smb: SMB decryption failed on incoming packet! Error %s\n", - nt_errstr(status) )); - if (smb_read_error == 0) { - smb_read_error = READ_BAD_DECRYPT; + if (srv_encryption_on()) { + NTSTATUS status = srv_decrypt_buffer(buffer); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("receive_smb: SMB decryption failed on incoming packet! Error %s\n", + nt_errstr(status) )); + if (smb_read_error == 0) { + smb_read_error = READ_BAD_DECRYPT; + } + return False; } - return False; - } - - /* Check the incoming SMB signature. */ - if (!srv_check_sign_mac(buffer, True)) { - DEBUG(0, ("receive_smb: SMB Signature verification failed on incoming packet!\n")); - if (smb_read_error == 0) { - smb_read_error = READ_BAD_SIG; + } else { + /* Check the incoming SMB signature. */ + if (!srv_check_sign_mac(buffer, True)) { + DEBUG(0, ("receive_smb: SMB Signature verification failed on incoming packet!\n")); + if (smb_read_error == 0) { + smb_read_error = READ_BAD_SIG; + } + return False; } - return False; - }; + } - return(True); + return True; } /**************************************************************************** @@ -766,20 +766,21 @@ BOOL receive_smb(int fd, char *buffer, unsigned int timeout) BOOL send_smb(int fd, char *buffer) { - NTSTATUS status; size_t len; size_t nwritten=0; ssize_t ret; - char *buf_out; + char *buf_out = buffer; /* Sign the outgoing packet if required. */ - srv_calculate_sign_mac(buffer); - - status = srv_encrypt_buffer(buffer, &buf_out); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("send_smb: SMB encryption failed on outgoing packet! Error %s\n", - nt_errstr(status) )); - return False; + if (!srv_encryption_on()) { + srv_calculate_sign_mac(buf_out); + } else { + NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("send_smb: SMB encryption failed on outgoing packet! Error %s\n", + nt_errstr(status) )); + return False; + } } len = smb_len(buf_out) + 4; -- cgit From 34dac35e48ca0c03d2744d9925566665285eb973 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 Mar 2007 18:04:36 +0000 Subject: r21990: Stop messing with the signing engine just because we're encrypted. This will make further changes and spec much more clear. Jeremy. (This used to be commit ffa3a5c508a494d22e8ee3ada424a6517ddf8923) --- source3/lib/util_sock.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index a58fb03e77..2ddce70fbb 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -746,15 +746,15 @@ BOOL receive_smb(int fd, char *buffer, unsigned int timeout) } return False; } - } else { - /* Check the incoming SMB signature. */ - if (!srv_check_sign_mac(buffer, True)) { - DEBUG(0, ("receive_smb: SMB Signature verification failed on incoming packet!\n")); - if (smb_read_error == 0) { - smb_read_error = READ_BAD_SIG; - } - return False; + } + + /* Check the incoming SMB signature. */ + if (!srv_check_sign_mac(buffer, True)) { + DEBUG(0, ("receive_smb: SMB Signature verification failed on incoming packet!\n")); + if (smb_read_error == 0) { + smb_read_error = READ_BAD_SIG; } + return False; } return True; @@ -772,9 +772,9 @@ BOOL send_smb(int fd, char *buffer) char *buf_out = buffer; /* Sign the outgoing packet if required. */ - if (!srv_encryption_on()) { - srv_calculate_sign_mac(buf_out); - } else { + srv_calculate_sign_mac(buf_out); + + if (srv_encryption_on()) { NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("send_smb: SMB encryption failed on outgoing packet! Error %s\n", -- cgit From a6fa4b4e56fbd825c7b195933c9da2afced5d39d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 12 Apr 2007 01:09:19 +0000 Subject: r22181: Fix for EISCON in open_any_socket_out from William Jojo for bug #3632. Jeremy. (This used to be commit 7979a5a350739150a9c7077f2c35d9512d8596e4) --- source3/lib/util_sock.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 2ddce70fbb..46bb709521 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -999,6 +999,9 @@ BOOL open_any_socket_out(struct sockaddr_in *addrs, int num_addrs, } if (errno == EINPROGRESS || errno == EALREADY || +#ifdef EISCONN + errno == EISCONN || +#endif errno == EAGAIN || errno == EINTR) { /* These are the error messages that something is progressing. */ -- cgit From 32106b23951e01fb17f814584ebbcc8d7288cb75 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 May 2007 00:07:38 +0000 Subject: r22920: Add in the UNIX capability for 24-bit readX, as discussed with the Apple guys and Linux kernel guys. Still looking at how to do writeX as there's no recvfile(). Jeremy. (This used to be commit a53268fb2082de586e2df250d8ddfcff53379102) --- source3/lib/util_sock.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 46bb709521..8f32e47bb8 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -658,10 +658,12 @@ ssize_t read_smb_length(int fd, char *inbuf, unsigned int timeout) BUFFER_SIZE+SAFETY_MARGIN. The timeout is in milliseconds. This function will return on receipt of a session keepalive packet. + maxlen is the max number of bytes to return, not including the 4 byte + length. If zero it means BUFFER_SIZE+SAFETY_MARGIN limit. Doesn't check the MAC on signed packets. ****************************************************************************/ -BOOL receive_smb_raw(int fd, char *buffer, unsigned int timeout) +ssize_t receive_smb_raw(int fd, char *buffer, unsigned int timeout, size_t maxlen) { ssize_t len,ret; @@ -679,7 +681,7 @@ BOOL receive_smb_raw(int fd, char *buffer, unsigned int timeout) if (smb_read_error == 0) smb_read_error = READ_ERROR; - return False; + return -1; } /* @@ -699,11 +701,15 @@ BOOL receive_smb_raw(int fd, char *buffer, unsigned int timeout) if (smb_read_error == 0) smb_read_error = READ_ERROR; - return False; + return -1; } } if(len > 0) { + if (maxlen) { + len = MIN(len,maxlen); + } + if (timeout > 0) { ret = read_socket_with_timeout(fd,buffer+4,len,len,timeout); } else { @@ -714,7 +720,7 @@ BOOL receive_smb_raw(int fd, char *buffer, unsigned int timeout) if (smb_read_error == 0) { smb_read_error = READ_ERROR; } - return False; + return -1; } /* not all of samba3 properly checks for packet-termination of strings. This @@ -722,7 +728,7 @@ BOOL receive_smb_raw(int fd, char *buffer, unsigned int timeout) SSVAL(buffer+4,len, 0); } - return True; + return len; } /**************************************************************************** @@ -732,7 +738,7 @@ BOOL receive_smb_raw(int fd, char *buffer, unsigned int timeout) BOOL receive_smb(int fd, char *buffer, unsigned int timeout) { - if (!receive_smb_raw(fd, buffer, timeout)) { + if (!receive_smb_raw(fd, buffer, timeout, 0)) { return False; } -- cgit From 51101a94505c16bb8c429e8f10ee1eaa85ffc5e0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 May 2007 01:13:25 +0000 Subject: r22923: Fix runaway smbd now receive_smb_raw() returns a ssize_t not a BOOL. Jeremy. (This used to be commit 9204f1741bbdd693351b61ac1810dd722cfbf233) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 8f32e47bb8..d491fe7e4c 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -738,7 +738,7 @@ ssize_t receive_smb_raw(int fd, char *buffer, unsigned int timeout, size_t maxle BOOL receive_smb(int fd, char *buffer, unsigned int timeout) { - if (!receive_smb_raw(fd, buffer, timeout, 0)) { + if (receive_smb_raw(fd, buffer, timeout, 0) <= 0) { return False; } -- cgit From 05ee952d1029f65b03412e2284f58d2d82184732 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 May 2007 01:49:33 +0000 Subject: r22926: Don't use <=0, use < 0 to allow keepalives to propagate up. Jeremy. (This used to be commit bf0313629e16c27461b028d3ea49185e99fc4d9c) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index d491fe7e4c..d102e570ab 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -738,7 +738,7 @@ ssize_t receive_smb_raw(int fd, char *buffer, unsigned int timeout, size_t maxle BOOL receive_smb(int fd, char *buffer, unsigned int timeout) { - if (receive_smb_raw(fd, buffer, timeout, 0) <= 0) { + if (receive_smb_raw(fd, buffer, timeout, 0) < 0) { return False; } -- cgit From d824b98f80ba186030cbb70b3a1e5daf80469ecd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Jul 2007 19:25:36 +0000 Subject: r23779: Change from v2 or later to v3 or later. Jeremy. (This used to be commit 407e6e695b8366369b7c76af1ff76869b45347b3) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index d102e570ab..0b2d521eb8 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, -- cgit From 5e54558c6dea67b56bbfaba5698f3a434d3dffb6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 00:52:41 +0000 Subject: r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text (This used to be commit b0132e94fc5fef936aa766fb99a306b3628e9f07) --- source3/lib/util_sock.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 0b2d521eb8..46d640cd55 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" -- cgit From cc6a41017c577742af73b4bc60993d8d415ea580 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Jul 2007 09:36:09 +0000 Subject: r23997: Check in the infrastructure for getting rid of the global InBuffer/OutBuffer The complete history of this patch can be found under http://www.samba.org/~vlendec/inbuf-checkin/. Jeremy, Jerry: If possible I would like to see this in 3.2.0. I'm only checking into 3_2 at the moment, as it currently will slow down operations for all non-converted (i.e. all at this moment) operations, as it will copy the talloc'ed inbuf over the global InBuffer. It will need quite a bit of effort to convert everything necessary for the normal operations an XP box does. I have patches for negprot, session setup, tcon_and_X, open_and_X, close. More to come, but I would appreciate some help here. Volker (This used to be commit 5594af2b208c860d3f4b453af6a649d9e4295d1c) --- source3/lib/util_sock.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 46d640cd55..9dcbdd9f02 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -730,6 +730,85 @@ ssize_t receive_smb_raw(int fd, char *buffer, unsigned int timeout, size_t maxle return len; } +static ssize_t receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd, + char **buffer, unsigned int timeout) +{ + char lenbuf[4]; + ssize_t len,ret; + + smb_read_error = 0; + + len = read_smb_length_return_keepalive(fd, lenbuf, timeout); + if (len < 0) { + DEBUG(10,("receive_smb_raw: length < 0!\n")); + + /* + * Correct fix. smb_read_error may have already been + * set. Only set it here if not already set. Global + * variables still suck :-). JRA. + */ + + if (smb_read_error == 0) + smb_read_error = READ_ERROR; + return -1; + } + + /* + * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes + * of header. Don't print the error if this fits.... JRA. + */ + + if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) { + DEBUG(0,("Invalid packet length! (%lu bytes).\n",(unsigned long)len)); + if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) { + + /* + * Correct fix. smb_read_error may have already been + * set. Only set it here if not already set. Global + * variables still suck :-). JRA. + */ + + if (smb_read_error == 0) + smb_read_error = READ_ERROR; + return -1; + } + } + + /* + * The +4 here can't wrap, we've checked the length above already. + */ + + *buffer = TALLOC_ARRAY(mem_ctx, char, len+4); + + if (*buffer == NULL) { + DEBUG(0, ("Could not allocate inbuf of length %d\n", + (int)len+4)); + if (smb_read_error == 0) + smb_read_error = READ_ERROR; + return -1; + } + + memcpy(*buffer, lenbuf, sizeof(lenbuf)); + + if(len > 0) { + if (timeout > 0) { + ret = read_socket_with_timeout(fd,(*buffer)+4, len, + len, timeout); + } else { + ret = read_data(fd, (*buffer)+4, len); + } + + if (ret != len) { + if (smb_read_error == 0) { + smb_read_error = READ_ERROR; + } + return -1; + } + } + + return len + 4; +} + /**************************************************************************** Wrapper for receive_smb_raw(). Checks the MAC on signed packets. @@ -765,6 +844,43 @@ BOOL receive_smb(int fd, char *buffer, unsigned int timeout) return True; } +ssize_t receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd, char **buffer, + unsigned int timeout) +{ + ssize_t len; + + len = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout); + + if (len < 0) { + return -1; + } + + if (srv_encryption_on()) { + NTSTATUS status = srv_decrypt_buffer(*buffer); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("receive_smb: SMB decryption failed on " + "incoming packet! Error %s\n", + nt_errstr(status) )); + if (smb_read_error == 0) { + smb_read_error = READ_BAD_DECRYPT; + } + return -1; + } + } + + /* Check the incoming SMB signature. */ + if (!srv_check_sign_mac(*buffer, True)) { + DEBUG(0, ("receive_smb: SMB Signature verification failed on " + "incoming packet!\n")); + if (smb_read_error == 0) { + smb_read_error = READ_BAD_SIG; + } + return -1; + } + + return len; +} + /**************************************************************************** Send an smb to a fd. ****************************************************************************/ -- cgit From 31adfe3446c2e50c70a4710e33ec2877e5ab227d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 2 Oct 2007 19:50:53 +0000 Subject: r25473: Reformatting only. Prepare for new ip functions. Jeremy. (This used to be commit 2a8f3dd55074eeb3d96a1b478981780651bbe88b) --- source3/lib/util_sock.c | 494 +++++++++++++++++++++++------------------------- 1 file changed, 240 insertions(+), 254 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 9dcbdd9f02..eecbb9eec4 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1,20 +1,20 @@ -/* +/* Unix SMB/CIFS implementation. Samba utility functions Copyright (C) Andrew Tridgell 1992-1998 Copyright (C) Tim Potter 2000-2001 Copyright (C) Jeremy Allison 1992-2005 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -31,7 +31,9 @@ static char client_ip_string[16]; void client_setfd(int fd) { client_fd = fd; - safe_strcpy(client_ip_string, get_peer_addr(client_fd), sizeof(client_ip_string)-1); + safe_strcpy(client_ip_string, + get_peer_addr(client_fd), + sizeof(client_ip_string)-1); } static char *get_socket_addr(int fd) @@ -46,14 +48,15 @@ static char *get_socket_addr(int fd) if (fd == -1) { return addr_buf; } - + if (getsockname(fd, &sa, &length) < 0) { - DEBUG(0,("getsockname failed. Error was %s\n", strerror(errno) )); + DEBUG(0,("getsockname failed. Error was %s\n", + strerror(errno) )); return addr_buf; } - + fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr)); - + return addr_buf; } @@ -65,12 +68,13 @@ static int get_socket_port(int fd) if (fd == -1) return -1; - + if (getsockname(fd, &sa, &length) < 0) { - DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) )); + DEBUG(0,("getpeername failed. Error was %s\n", + strerror(errno) )); return -1; } - + return ntohs(sockin->sin_port); } @@ -98,12 +102,13 @@ struct in_addr *client_inaddr(struct sockaddr *sa) { struct sockaddr_in *sockin = (struct sockaddr_in *) (sa); socklen_t length = sizeof(*sa); - + if (getpeername(client_fd, sa, &length) < 0) { - DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) )); + DEBUG(0,("getpeername failed. Error was %s\n", + strerror(errno) )); return NULL; } - + return &sockin->sin_addr; } @@ -138,50 +143,50 @@ typedef struct smb_socket_option { } smb_socket_option; static const smb_socket_option socket_options[] = { - {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL}, - {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL}, - {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL}, + {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL}, + {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL}, + {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL}, #ifdef TCP_NODELAY - {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL}, + {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL}, #endif #ifdef TCP_KEEPCNT - {"TCP_KEEPCNT", IPPROTO_TCP, TCP_KEEPCNT, 0, OPT_INT}, + {"TCP_KEEPCNT", IPPROTO_TCP, TCP_KEEPCNT, 0, OPT_INT}, #endif #ifdef TCP_KEEPIDLE - {"TCP_KEEPIDLE", IPPROTO_TCP, TCP_KEEPIDLE, 0, OPT_INT}, + {"TCP_KEEPIDLE", IPPROTO_TCP, TCP_KEEPIDLE, 0, OPT_INT}, #endif #ifdef TCP_KEEPINTVL - {"TCP_KEEPINTVL", IPPROTO_TCP, TCP_KEEPINTVL, 0, OPT_INT}, + {"TCP_KEEPINTVL", IPPROTO_TCP, TCP_KEEPINTVL, 0, OPT_INT}, #endif #ifdef IPTOS_LOWDELAY - {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON}, + {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON}, #endif #ifdef IPTOS_THROUGHPUT - {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON}, + {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON}, #endif #ifdef SO_REUSEPORT - {"SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT, 0, OPT_BOOL}, + {"SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT, 0, OPT_BOOL}, #endif #ifdef SO_SNDBUF - {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT}, + {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT}, #endif #ifdef SO_RCVBUF - {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT}, + {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT}, #endif #ifdef SO_SNDLOWAT - {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT}, + {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT}, #endif #ifdef SO_RCVLOWAT - {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT}, + {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT}, #endif #ifdef SO_SNDTIMEO - {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT}, + {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT}, #endif #ifdef SO_RCVTIMEO - {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT}, + {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT}, #endif #ifdef TCP_FASTACK - {"TCP_FASTACK", IPPROTO_TCP, TCP_FASTACK, 0, OPT_INT}, + {"TCP_FASTACK", IPPROTO_TCP, TCP_FASTACK, 0, OPT_INT}, #endif {NULL,0,0,0,0}}; @@ -195,14 +200,18 @@ static void print_socket_options(int s) socklen_t vlen = 4; const smb_socket_option *p = &socket_options[0]; - /* wrapped in if statement to prevent streams leak in SCO Openserver 5.0 */ + /* wrapped in if statement to prevent streams + * leak in SCO Openserver 5.0 */ /* reported on samba-technical --jerry */ if ( DEBUGLEVEL >= 5 ) { - for (; p->name != NULL; p++) { - if (getsockopt(s, p->level, p->option, (void *)&value, &vlen) == -1) { - DEBUG(5,("Could not test socket option %s.\n", p->name)); - } else { - DEBUG(5,("socket option %s = %d\n",p->name,value)); + for (; p->name != NULL; p++) { + if (getsockopt(s, p->level, p->option, + (void *)&value, &vlen) == -1) { + DEBUG(5,("Could not test socket option %s.\n", + p->name)); + } else { + DEBUG(5,("socket option %s = %d\n", + p->name,value)); } } } @@ -241,23 +250,28 @@ void set_socket_options(int fd, const char *options) case OPT_BOOL: case OPT_INT: ret = setsockopt(fd,socket_options[i].level, - socket_options[i].option,(char *)&value,sizeof(int)); + socket_options[i].option, + (char *)&value,sizeof(int)); break; case OPT_ON: if (got_value) - DEBUG(0,("syntax error - %s does not take a value\n",tok)); + DEBUG(0,("syntax error - %s " + "does not take a value\n",tok)); { int on = socket_options[i].value; ret = setsockopt(fd,socket_options[i].level, - socket_options[i].option,(char *)&on,sizeof(int)); + socket_options[i].option, + (char *)&on,sizeof(int)); } - break; + break; + } + + if (ret != 0) { + DEBUG(0,("Failed to set socket option %s (Error %s)\n", + tok, strerror(errno) )); } - - if (ret != 0) - DEBUG(0,("Failed to set socket option %s (Error %s)\n",tok, strerror(errno) )); } print_socket_options(fd); @@ -275,13 +289,16 @@ ssize_t read_udp_socket(int fd,char *buf,size_t len) memset((char *)&sock,'\0',socklen); memset((char *)&lastip,'\0',sizeof(lastip)); - ret = (ssize_t)sys_recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen); + ret = (ssize_t)sys_recvfrom(fd,buf,len,0, + (struct sockaddr *)&sock,&socklen); if (ret <= 0) { /* Don't print a low debug error for a non-blocking socket. */ if (errno == EAGAIN) { - DEBUG(10,("read socket returned EAGAIN. ERRNO=%s\n",strerror(errno))); + DEBUG(10,("read socket returned EAGAIN. ERRNO=%s\n", + strerror(errno))); } else { - DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno))); + DEBUG(2,("read socket failed. ERRNO=%s\n", + strerror(errno))); } return(0); } @@ -295,99 +312,6 @@ ssize_t read_udp_socket(int fd,char *buf,size_t len) return(ret); } -#if 0 - -Socket routines from HEAD - maybe re-enable in future. JRA. - -/**************************************************************************** - Work out if we've timed out. -****************************************************************************/ - -static BOOL timeout_until(struct timeval *timeout, const struct timeval *endtime) -{ - struct timeval now; - SMB_BIG_INT t_dif; - - GetTimeOfDay(&now); - - t_dif = usec_time_diff(endtime, &now); - if (t_dif <= 0) { - return False; - } - - timeout->tv_sec = (t_dif / (SMB_BIG_INT)1000000); - timeout->tv_usec = (t_dif % (SMB_BIG_INT)1000000); - return True; -} - -/**************************************************************************** - Read data from the client, reading exactly N bytes, or until endtime timeout. - Use with a non-blocking socket if endtime != NULL. -****************************************************************************/ - -ssize_t read_data_until(int fd,char *buffer,size_t N, const struct timeval *endtime) -{ - ssize_t ret; - size_t total=0; - - smb_read_error = 0; - - while (total < N) { - - if (endtime != NULL) { - fd_set r_fds; - struct timeval timeout; - int selrtn; - - if (!timeout_until(&timeout, endtime)) { - DEBUG(10,("read_data_until: read timed out\n")); - smb_read_error = READ_TIMEOUT; - return -1; - } - - FD_ZERO(&r_fds); - FD_SET(fd, &r_fds); - - /* Select but ignore EINTR. */ - selrtn = sys_select_intr(fd+1, &r_fds, NULL, NULL, &timeout); - if (selrtn == -1) { - /* something is wrong. Maybe the socket is dead? */ - DEBUG(0,("read_data_until: select error = %s.\n", strerror(errno) )); - smb_read_error = READ_ERROR; - return -1; - } - - /* Did we timeout ? */ - if (selrtn == 0) { - DEBUG(10,("read_data_until: select timed out.\n")); - smb_read_error = READ_TIMEOUT; - return -1; - } - } - - ret = sys_read(fd,buffer + total,N - total); - - if (ret == 0) { - DEBUG(10,("read_data_until: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) )); - smb_read_error = READ_EOF; - return 0; - } - - if (ret == -1) { - if (errno == EAGAIN) { - /* Non-blocking socket with no data available. Try select again. */ - continue; - } - DEBUG(0,("read_data_until: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) )); - smb_read_error = READ_ERROR; - return -1; - } - total += ret; - } - return (ssize_t)total; -} -#endif - /**************************************************************************** Read data from a socket with a timout in msec. mincount = if timeout, minimum to read before returning @@ -395,42 +319,52 @@ ssize_t read_data_until(int fd,char *buffer,size_t N, const struct timeval *endt time_out = timeout in milliseconds ****************************************************************************/ -ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out) +ssize_t read_socket_with_timeout(int fd, + char *buf, + size_t mincnt, + size_t maxcnt, + unsigned int time_out) { fd_set fds; int selrtn; ssize_t readret; size_t nread = 0; struct timeval timeout; - + /* just checking .... */ if (maxcnt <= 0) return(0); - + smb_read_error = 0; - + /* Blocking read */ if (time_out == 0) { if (mincnt == 0) { mincnt = maxcnt; } - + while (nread < mincnt) { readret = sys_read(fd, buf + nread, maxcnt - nread); - + if (readret == 0) { - DEBUG(5,("read_socket_with_timeout: blocking read. EOF from client.\n")); + DEBUG(5,("read_socket_with_timeout: " + "blocking read. EOF from client.\n")); smb_read_error = READ_EOF; return -1; } - + if (readret == -1) { if (fd == client_fd) { - /* Try and give an error message saying what client failed. */ - DEBUG(0,("read_socket_with_timeout: client %s read error = %s.\n", - client_ip_string, strerror(errno) )); + /* Try and give an error message + * saying what client failed. */ + DEBUG(0,("read_socket_with_timeout: " + "client %s read error = %s.\n", + client_ip_string, + strerror(errno) )); } else { - DEBUG(0,("read_socket_with_timeout: read error = %s.\n", strerror(errno) )); + DEBUG(0,("read_socket_with_timeout: " + "read error = %s.\n", + strerror(errno) )); } smb_read_error = READ_ERROR; return -1; @@ -439,100 +373,119 @@ ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,un } return((ssize_t)nread); } - + /* Most difficult - timeout read */ - /* If this is ever called on a disk file and + /* If this is ever called on a disk file and mincnt is greater then the filesize then - system performance will suffer severely as + system performance will suffer severely as select always returns true on disk files */ - + /* Set initial timeout */ timeout.tv_sec = (time_t)(time_out / 1000); timeout.tv_usec = (long)(1000 * (time_out % 1000)); - - for (nread=0; nread < mincnt; ) { + + for (nread=0; nread < mincnt; ) { FD_ZERO(&fds); FD_SET(fd,&fds); - + selrtn = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout); - + /* Check if error */ if (selrtn == -1) { /* something is wrong. Maybe the socket is dead? */ if (fd == client_fd) { - /* Try and give an error message saying what client failed. */ - DEBUG(0,("read_socket_with_timeout: timeout read for client %s. select error = %s.\n", - client_ip_string, strerror(errno) )); + /* Try and give an error message saying + * what client failed. */ + DEBUG(0,("read_socket_with_timeout: timeout " + "read for client %s. select error = %s.\n", + client_ip_string, strerror(errno) )); } else { - DEBUG(0,("read_socket_with_timeout: timeout read. select error = %s.\n", strerror(errno) )); + DEBUG(0,("read_socket_with_timeout: timeout " + "read. select error = %s.\n", + strerror(errno) )); } smb_read_error = READ_ERROR; return -1; } - + /* Did we timeout ? */ if (selrtn == 0) { - DEBUG(10,("read_socket_with_timeout: timeout read. select timed out.\n")); + DEBUG(10,("read_socket_with_timeout: timeout read. " + "select timed out.\n")); smb_read_error = READ_TIMEOUT; return -1; } - + readret = sys_read(fd, buf+nread, maxcnt-nread); - + if (readret == 0) { /* we got EOF on the file descriptor */ - DEBUG(5,("read_socket_with_timeout: timeout read. EOF from client.\n")); + DEBUG(5,("read_socket_with_timeout: timeout read. " + "EOF from client.\n")); smb_read_error = READ_EOF; return -1; } - + if (readret == -1) { /* the descriptor is probably dead */ if (fd == client_fd) { - /* Try and give an error message saying what client failed. */ - DEBUG(0,("read_socket_with_timeout: timeout read to client %s. read error = %s.\n", + /* Try and give an error message + * saying what client failed. */ + DEBUG(0,("read_socket_with_timeout: timeout " + "read to client %s. read error = %s.\n", client_ip_string, strerror(errno) )); } else { - DEBUG(0,("read_socket_with_timeout: timeout read. read error = %s.\n", strerror(errno) )); + DEBUG(0,("read_socket_with_timeout: timeout " + "read. read error = %s.\n", + strerror(errno) )); } smb_read_error = READ_ERROR; return -1; } - + nread += readret; } - + /* Return the number we got */ return (ssize_t)nread; } /**************************************************************************** - Read data from the client, reading exactly N bytes. + Read data from the client, reading exactly N bytes. ****************************************************************************/ ssize_t read_data(int fd,char *buffer,size_t N) { ssize_t ret; - size_t total=0; - + size_t total=0; + smb_read_error = 0; while (total < N) { ret = sys_read(fd,buffer + total,N - total); if (ret == 0) { - DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) )); + DEBUG(10,("read_data: read of %d returned 0. " + "Error = %s\n", + (int)(N - total), strerror(errno) )); smb_read_error = READ_EOF; return 0; } if (ret == -1) { if (fd == client_fd) { - /* Try and give an error message saying what client failed. */ - DEBUG(0,("read_data: read failure for %d bytes to client %s. Error = %s\n", - (int)(N - total), client_ip_string, strerror(errno) )); + /* Try and give an error message saying + * what client failed. */ + DEBUG(0,("read_data: read failure for %d " + "bytes to client %s. Error = %s\n", + (int)(N - total), + client_ip_string, + strerror(errno) )); } else { - DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) )); + DEBUG(0,("read_data: read failure for %d. " + "Error = %s\n", + (int)(N - total), + strerror(errno) )); } smb_read_error = READ_ERROR; return -1; @@ -556,11 +509,14 @@ ssize_t write_data(int fd, const char *buffer, size_t N) if (ret == -1) { if (fd == client_fd) { - /* Try and give an error message saying what client failed. */ - DEBUG(0,("write_data: write failure in writing to client %s. Error %s\n", + /* Try and give an error message saying + * what client failed. */ + DEBUG(0,("write_data: write failure in " + "writing to client %s. Error %s\n", client_ip_string, strerror(errno) )); } else { - DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) )); + DEBUG(0,("write_data: write failure. " + "Error = %s\n", strerror(errno) )); } return -1; } @@ -588,7 +544,6 @@ BOOL send_keepalive(int client) return(write_data(client,(char *)buf,4) == 4); } - /**************************************************************************** Read 4 bytes of a smb packet and return the smb length of the packet. Store the result in the buffer. @@ -597,26 +552,31 @@ BOOL send_keepalive(int client) Timeout is in milliseconds. ****************************************************************************/ -static ssize_t read_smb_length_return_keepalive(int fd, char *inbuf, unsigned int timeout) +static ssize_t read_smb_length_return_keepalive(int fd, + char *inbuf, + unsigned int timeout) { ssize_t len=0; int msg_type; BOOL ok = False; while (!ok) { - if (timeout > 0) - ok = (read_socket_with_timeout(fd,inbuf,4,4,timeout) == 4); - else + if (timeout > 0) { + ok = (read_socket_with_timeout(fd,inbuf,4,4,timeout) + == 4); + } else { ok = (read_data(fd,inbuf,4) == 4); - - if (!ok) - return(-1); + } + if (!ok) { + return -1; + } len = smb_len(inbuf); msg_type = CVAL(inbuf,0); - if (msg_type == SMBkeepalive) + if (msg_type == SMBkeepalive) { DEBUG(5,("Got keepalive packet\n")); + } } DEBUG(10,("got smb length of %lu\n",(unsigned long)len)); @@ -655,14 +615,17 @@ ssize_t read_smb_length(int fd, char *inbuf, unsigned int timeout) /**************************************************************************** Read an smb from a fd. Note that the buffer *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN. - The timeout is in milliseconds. + The timeout is in milliseconds. This function will return on receipt of a session keepalive packet. maxlen is the max number of bytes to return, not including the 4 byte length. If zero it means BUFFER_SIZE+SAFETY_MARGIN limit. Doesn't check the MAC on signed packets. ****************************************************************************/ -ssize_t receive_smb_raw(int fd, char *buffer, unsigned int timeout, size_t maxlen) +ssize_t receive_smb_raw(int fd, + char *buffer, + unsigned int timeout, + size_t maxlen) { ssize_t len,ret; @@ -689,7 +652,8 @@ ssize_t receive_smb_raw(int fd, char *buffer, unsigned int timeout, size_t maxle */ if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) { - DEBUG(0,("Invalid packet length! (%lu bytes).\n",(unsigned long)len)); + DEBUG(0,("Invalid packet length! (%lu bytes).\n", + (unsigned long)len)); if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) { /* @@ -710,7 +674,11 @@ ssize_t receive_smb_raw(int fd, char *buffer, unsigned int timeout, size_t maxle } if (timeout > 0) { - ret = read_socket_with_timeout(fd,buffer+4,len,len,timeout); + ret = read_socket_with_timeout(fd, + buffer+4, + len, + len, + timeout); } else { ret = read_data(fd,buffer+4,len); } @@ -721,9 +689,10 @@ ssize_t receive_smb_raw(int fd, char *buffer, unsigned int timeout, size_t maxle } return -1; } - - /* not all of samba3 properly checks for packet-termination of strings. This - ensures that we don't run off into empty space. */ + + /* not all of samba3 properly checks for packet-termination + * of strings. This ensures that we don't run off into + * empty space. */ SSVAL(buffer+4,len, 0); } @@ -759,7 +728,8 @@ static ssize_t receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd, */ if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) { - DEBUG(0,("Invalid packet length! (%lu bytes).\n",(unsigned long)len)); + DEBUG(0,("Invalid packet length! (%lu bytes).\n", + (unsigned long)len)); if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) { /* @@ -823,7 +793,8 @@ BOOL receive_smb(int fd, char *buffer, unsigned int timeout) if (srv_encryption_on()) { NTSTATUS status = srv_decrypt_buffer(buffer); if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("receive_smb: SMB decryption failed on incoming packet! Error %s\n", + DEBUG(0, ("receive_smb: SMB decryption failed " + "on incoming packet! Error %s\n", nt_errstr(status) )); if (smb_read_error == 0) { smb_read_error = READ_BAD_DECRYPT; @@ -834,7 +805,8 @@ BOOL receive_smb(int fd, char *buffer, unsigned int timeout) /* Check the incoming SMB signature. */ if (!srv_check_sign_mac(buffer, True)) { - DEBUG(0, ("receive_smb: SMB Signature verification failed on incoming packet!\n")); + DEBUG(0, ("receive_smb: SMB Signature verification " + "failed on incoming packet!\n")); if (smb_read_error == 0) { smb_read_error = READ_BAD_SIG; } @@ -898,7 +870,8 @@ BOOL send_smb(int fd, char *buffer) if (srv_encryption_on()) { NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out); if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("send_smb: SMB encryption failed on outgoing packet! Error %s\n", + DEBUG(0, ("send_smb: SMB encryption failed " + "on outgoing packet! Error %s\n", nt_errstr(status) )); return False; } @@ -925,7 +898,11 @@ BOOL send_smb(int fd, char *buffer) Open a socket of the specified type, port, and address for incoming data. ****************************************************************************/ -int open_socket_in( int type, int port, int dlevel, uint32 socket_addr, BOOL rebind ) +int open_socket_in(int type, + int port, + int dlevel, + uint32 socket_addr, + BOOL rebind ) { struct sockaddr_in sock; int res; @@ -951,19 +928,23 @@ int open_socket_in( int type, int port, int dlevel, uint32 socket_addr, BOOL reb /* This block sets/clears the SO_REUSEADDR and possibly SO_REUSEPORT. */ { int val = rebind ? 1 : 0; - if( setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val)) == -1 ) { + if( setsockopt(res,SOL_SOCKET,SO_REUSEADDR, + (char *)&val,sizeof(val)) == -1 ) { if( DEBUGLVL( dlevel ) ) { dbgtext( "open_socket_in(): setsockopt: " ); - dbgtext( "SO_REUSEADDR = %s ", val?"True":"False" ); + dbgtext( "SO_REUSEADDR = %s ", + val?"True":"False" ); dbgtext( "on port %d failed ", port ); dbgtext( "with error = %s\n", strerror(errno) ); } } #ifdef SO_REUSEPORT - if( setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val)) == -1 ) { + if( setsockopt(res,SOL_SOCKET,SO_REUSEPORT, + (char *)&val,sizeof(val)) == -1 ) { if( DEBUGLVL( dlevel ) ) { dbgtext( "open_socket_in(): setsockopt: "); - dbgtext( "SO_REUSEPORT = %s ", val?"True":"False" ); + dbgtext( "SO_REUSEPORT = %s ", + val?"True":"False" ); dbgtext( "on port %d failed ", port ); dbgtext( "with error = %s\n", strerror(errno) ); } @@ -973,13 +954,15 @@ int open_socket_in( int type, int port, int dlevel, uint32 socket_addr, BOOL reb /* now we've got a socket - we need to bind it */ if( bind( res, (struct sockaddr *)&sock, sizeof(sock) ) == -1 ) { - if( DEBUGLVL(dlevel) && (port == SMB_PORT1 || port == SMB_PORT2 || port == NMB_PORT) ) { + if( DEBUGLVL(dlevel) && (port == SMB_PORT1 || + port == SMB_PORT2 || port == NMB_PORT) ) { dbgtext( "bind failed on port %d ", port ); - dbgtext( "socket_addr = %s.\n", inet_ntoa( sock.sin_addr ) ); + dbgtext( "socket_addr = %s.\n", + inet_ntoa( sock.sin_addr ) ); dbgtext( "Error = %s\n", strerror(errno) ); } - close( res ); - return( -1 ); + close( res ); + return -1; } DEBUG( 10, ( "bind succeeded on port %d\n", port ) ); @@ -1007,10 +990,10 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) if (type != SOCK_STREAM) return(res); - + memset((char *)&sock_out,'\0',sizeof(sock_out)); putip((char *)&sock_out.sin_addr,(char *)addr); - + sock_out.sin_port = htons( port ); sock_out.sin_family = PF_INET; @@ -1018,7 +1001,7 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) set_blocking(res,False); DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port)); - + /* and connect it to the destination */ connect_again: @@ -1039,13 +1022,13 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || errno == EAGAIN)) { - DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port)); + DEBUG(1,("timeout connecting to %s:%d\n", + inet_ntoa(*addr),port)); close(res); return -1; } #ifdef EISCONN - if (ret < 0 && errno == EISCONN) { errno = 0; ret = 0; @@ -1259,11 +1242,12 @@ static BOOL matchname(char *remotehost,struct in_addr addr) { struct hostent *hp; int i; - + if ((hp = sys_gethostbyname(remotehost)) == 0) { - DEBUG(0,("sys_gethostbyname(%s): lookup failure.\n", remotehost)); + DEBUG(0,("sys_gethostbyname(%s): lookup failure.\n", + remotehost)); return False; - } + } /* * Make sure that gethostbyname() returns the "correct" host name. @@ -1272,26 +1256,26 @@ static BOOL matchname(char *remotehost,struct in_addr addr) * local DNS, we just have to trust it (all bets are off if the local * DNS is perverted). We always check the address list, though. */ - + if (!strequal(remotehost, hp->h_name) && !strequal(remotehost, "localhost")) { DEBUG(0,("host name/name mismatch: %s != %s\n", remotehost, hp->h_name)); return False; } - + /* Look up the host address in the address list we just got. */ for (i = 0; hp->h_addr_list[i]; i++) { - if (memcmp(hp->h_addr_list[i], (char *) & addr, sizeof(addr)) == 0) + if (memcmp(hp->h_addr_list[i], (char *)&addr,sizeof(addr)) == 0) return True; } - + /* * The host name does not map to the original host address. Perhaps * someone has compromised a name server. More likely someone botched * it, but that could be dangerous, too. */ - + DEBUG(0,("host name/address mismatch: %s != %s\n", inet_ntoa(addr), hp->h_name)); return False; @@ -1317,23 +1301,24 @@ char *get_peer_name(int fd, BOOL force_lookup) if (!lp_hostname_lookups() && (force_lookup == False)) { return get_peer_addr(fd); } - + p = get_peer_addr(fd); /* it might be the same as the last one - save some DNS work */ - if (strcmp(p, addr_buf) == 0) + if (strcmp(p, addr_buf) == 0) return name_buf; pstrcpy(name_buf,"UNKNOWN"); - if (fd == -1) + if (fd == -1) return name_buf; fstrcpy(addr_buf, p); addr = *interpret_addr2(p); - + /* Look up the remote host name. */ - if ((hp = gethostbyaddr((char *)&addr.s_addr, sizeof(addr.s_addr), AF_INET)) == 0) { + if ((hp = gethostbyaddr((char *)&addr.s_addr, + sizeof(addr.s_addr), AF_INET)) == 0) { DEBUG(1,("Gethostbyaddr failed for %s\n",p)); pstrcpy(name_buf, p); } else { @@ -1344,10 +1329,10 @@ char *get_peer_name(int fd, BOOL force_lookup) } } - /* can't pass the same source and dest strings in when you - use --enable-developer or the clobber_region() call will + /* can't pass the same source and dest strings in when you + use --enable-developer or the clobber_region() call will get you */ - + pstrcpy( tmp_name, name_buf ); alpha_strcpy(name_buf, tmp_name, "_-.", sizeof(name_buf)); if (strstr(name_buf,"..")) { @@ -1373,14 +1358,15 @@ char *get_peer_addr(int fd) if (fd == -1) { return addr_buf; } - + if (getpeername(fd, &sa, &length) < 0) { - DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) )); + DEBUG(0,("getpeername failed. Error was %s\n", + strerror(errno) )); return addr_buf; } - + fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr)); - + return addr_buf; } @@ -1402,17 +1388,17 @@ int create_pipe_sock(const char *socket_dir, int sock; mode_t old_umask; pstring path; - + old_umask = umask(0); - + /* Create the socket directory or reuse the existing one */ - + if (lstat(socket_dir, &st) == -1) { if (errno == ENOENT) { /* Create directory */ if (mkdir(socket_dir, dir_perms) == -1) { DEBUG(0, ("error creating socket directory " - "%s: %s\n", socket_dir, + "%s: %s\n", socket_dir, strerror(errno))); goto out_umask; } @@ -1428,42 +1414,42 @@ int create_pipe_sock(const char *socket_dir, socket_dir)); goto out_umask; } - if ((st.st_uid != sec_initial_uid()) || + if ((st.st_uid != sec_initial_uid()) || ((st.st_mode & 0777) != dir_perms)) { DEBUG(0, ("invalid permissions on socket directory " "%s\n", socket_dir)); goto out_umask; } } - + /* Create the socket file */ - + sock = socket(AF_UNIX, SOCK_STREAM, 0); - + if (sock == -1) { perror("socket"); goto out_umask; } - + pstr_sprintf(path, "%s/%s", socket_dir, socket_name); - + unlink(path); memset(&sunaddr, 0, sizeof(sunaddr)); sunaddr.sun_family = AF_UNIX; safe_strcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)-1); - + if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) { DEBUG(0, ("bind failed on pipe socket %s: %s\n", path, strerror(errno))); goto out_close; } - + if (listen(sock, 5) == -1) { DEBUG(0, ("listen failed on pipe socket %s: %s\n", path, strerror(errno))); goto out_close; } - + umask(old_umask); return sock; -- cgit From 0d87820380416955a132d565a479b4234f78c113 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 3 Oct 2007 20:43:55 +0000 Subject: r25492: Start adding IPv6 compatible code to lib/util_sock.c and deal with the ripple effects this causes. utmp has to change etc. Remove some global varables and store address/port in the unexpected db. Jeremy. (This used to be commit 18c6a2211d9e25233d01715b3f78977edcd6d869) --- source3/lib/util_sock.c | 127 ++++++++++++++++++++++++++++-------------------- 1 file changed, 73 insertions(+), 54 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index eecbb9eec4..bcc1e8e15e 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -3,7 +3,7 @@ Samba utility functions Copyright (C) Andrew Tridgell 1992-1998 Copyright (C) Tim Potter 2000-2001 - Copyright (C) Jeremy Allison 1992-2005 + Copyright (C) Jeremy Allison 1992-2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -26,7 +26,35 @@ particular modules */ static int client_fd = -1; /* What to print out on a client disconnect error. */ -static char client_ip_string[16]; +static char client_ip_string[INET6_ADDRSTRLEN]; + +/**************************************************************************** + Pritn out an IPv4 or IPv6 address from a struct sockaddr_storage. +****************************************************************************/ + +char *print_sockaddr(char *dest, + size_t destlen, + struct sockaddr_storage *psa) +{ + if (destlen > 0) { + dest[0] = '\0'; + } +#ifdef AF_INET6 + if (psa->ss_family == AF_INET6) { + inet_ntop(AF_INET6, + &((struct sockaddr_in6 *)psa)->sin6_addr, + dest, + destlen); + } +#endif + if (psa->ss_family == AF_INET) { + inet_ntop(AF_INET, + &((struct sockaddr_in *)psa)->sin_addr, + dest, + destlen); + } + return dest; +} void client_setfd(int fd) { @@ -38,44 +66,49 @@ void client_setfd(int fd) static char *get_socket_addr(int fd) { - struct sockaddr sa; - struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); + struct sockaddr_storage sa; socklen_t length = sizeof(sa); - static fstring addr_buf; + static char addr_buf[INET6_ADDRSTRLEN]; - fstrcpy(addr_buf,"0.0.0.0"); + addr_buf[0] = '\0'; if (fd == -1) { return addr_buf; } - if (getsockname(fd, &sa, &length) < 0) { + if (getsockname(fd, (struct sockaddr *)&sa, &length) < 0) { DEBUG(0,("getsockname failed. Error was %s\n", - strerror(errno) )); + strerror(errno) )); return addr_buf; } - fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr)); - - return addr_buf; + return print_sockaddr(addr_buf, sizeof(addr_buf), &sa); } static int get_socket_port(int fd) { - struct sockaddr sa; - struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); + struct sockaddr_storage sa; socklen_t length = sizeof(sa); - if (fd == -1) + if (fd == -1) { return -1; + } - if (getsockname(fd, &sa, &length) < 0) { + if (getsockname(fd, (struct sockaddr *)&sa, &length) < 0) { DEBUG(0,("getpeername failed. Error was %s\n", - strerror(errno) )); + strerror(errno) )); return -1; } - return ntohs(sockin->sin_port); +#ifdef AF_INET6 + if (sa.ss_family == AF_INET6) { + return ntohs(((struct sockaddr_in6 *)&sa)->sin6_port); + } +#endif + if (sa.ss_family == AF_INET) { + return ntohs(((struct sockaddr_in *)&sa)->sin_port); + } + return -1; } char *client_name(void) @@ -98,26 +131,6 @@ int client_socket_port(void) return get_socket_port(client_fd); } -struct in_addr *client_inaddr(struct sockaddr *sa) -{ - struct sockaddr_in *sockin = (struct sockaddr_in *) (sa); - socklen_t length = sizeof(*sa); - - if (getpeername(client_fd, sa, &length) < 0) { - DEBUG(0,("getpeername failed. Error was %s\n", - strerror(errno) )); - return NULL; - } - - return &sockin->sin_addr; -} - -/* the last IP received from */ -struct in_addr lastip; - -/* the last port received from */ -int lastport=0; - int smb_read_error = 0; /**************************************************************************** @@ -281,35 +294,42 @@ void set_socket_options(int fd, const char *options) Read from a socket. ****************************************************************************/ -ssize_t read_udp_socket(int fd,char *buf,size_t len) +ssize_t read_udp_v4_socket(int fd, + char *buf, + size_t len, + struct sockaddr_storage *psa) { ssize_t ret; - struct sockaddr_in sock; - socklen_t socklen = sizeof(sock); + socklen_t socklen = sizeof(*psa); + struct sockaddr_in *si = (struct sockaddr_in *)psa; + + memset((char *)psa,'\0',socklen); - memset((char *)&sock,'\0',socklen); - memset((char *)&lastip,'\0',sizeof(lastip)); ret = (ssize_t)sys_recvfrom(fd,buf,len,0, - (struct sockaddr *)&sock,&socklen); + (struct sockaddr *)psa,&socklen); if (ret <= 0) { /* Don't print a low debug error for a non-blocking socket. */ if (errno == EAGAIN) { - DEBUG(10,("read socket returned EAGAIN. ERRNO=%s\n", - strerror(errno))); + DEBUG(10,("read_udp_v4_socket: returned EAGAIN\n")); } else { - DEBUG(2,("read socket failed. ERRNO=%s\n", - strerror(errno))); + DEBUG(2,("read_udp_v4_socket: failed. errno=%s\n", + strerror(errno))); } - return(0); + return 0; } - lastip = sock.sin_addr; - lastport = ntohs(sock.sin_port); + if (psa->ss_family != AF_INET) { + DEBUG(2,("read_udp_v4_socket:: invalid address family %d " + "(not IPv4)\n", (int)psa->ss_family)); + return 0; + } - DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %lu\n", - inet_ntoa(lastip), lastport, (unsigned long)ret)); + DEBUG(10,("read_udp_socket: ip %s port %d read: %lu\n", + inet_ntoa(si->sin_addr), + si->sin_port, + (unsigned long)ret)); - return(ret); + return ret; } /**************************************************************************** @@ -1232,7 +1252,6 @@ int open_udp_socket(const char *host, int port) return res; } - /******************************************************************* Matchname - determine if host name matches IP address. Used to confirm a hostname lookup to prevent spoof attacks. -- cgit From 3dbb3d4c269ecf28f25d857aa8a4e5c1109ee5e8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 5 Oct 2007 01:11:33 +0000 Subject: r25510: Now we're returning the port instead of using a global, remember to use ntohs. Hopefully will fix the build farm. Jeremy. (This used to be commit 5174acccb589edbfbe4ba633f4178f7200d7d6c4) --- source3/lib/util_sock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index bcc1e8e15e..f77fcc9968 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -319,12 +319,12 @@ ssize_t read_udp_v4_socket(int fd, } if (psa->ss_family != AF_INET) { - DEBUG(2,("read_udp_v4_socket:: invalid address family %d " + DEBUG(2,("read_udp_v4_socket: invalid address family %d " "(not IPv4)\n", (int)psa->ss_family)); return 0; } - DEBUG(10,("read_udp_socket: ip %s port %d read: %lu\n", + DEBUG(10,("read_udp_v4_socket: ip %s port %d read: %lu\n", inet_ntoa(si->sin_addr), si->sin_port, (unsigned long)ret)); -- cgit From f7055aef172663f1b511c72ce9f3ec62c8ed0c0d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 8 Oct 2007 02:48:03 +0000 Subject: r25565: Fix unintended consequence change for IPv6 noticed by Volker. We used to return 0.0.0.0 for the text address of an uninitialized socket - ensure we still do so. Once uninitialized address is as good as any other. Jeremy. (This used to be commit 2827bbe0f853d413b6fcb0eb676048c041cea713) --- source3/lib/util_sock.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index f77fcc9968..d061d73a81 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -70,7 +70,12 @@ static char *get_socket_addr(int fd) socklen_t length = sizeof(sa); static char addr_buf[INET6_ADDRSTRLEN]; - addr_buf[0] = '\0'; + /* Ok, returning a hard coded IPv4 address + * is bogus, but it's just as bogus as a + * zero IPv6 address. No good choice here. + */ + + safe_strcpy(addr_buf, "0.0.0.0", sizeof(addr_buf)-1); if (fd == -1) { return addr_buf; -- cgit From e5a951325a6cac8567af3a66de6d2df577508ae4 Mon Sep 17 00:00:00 2001 From: "Gerald (Jerry) Carter" Date: Wed, 10 Oct 2007 15:34:30 -0500 Subject: [GLUE] Rsync SAMBA_3_2_0 SVN r25598 in order to create the v3-2-test branch. (This used to be commit 5c6c8e1fe93f340005110a7833946191659d88ab) --- source3/lib/util_sock.c | 45 +++------------------------------------------ 1 file changed, 3 insertions(+), 42 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index d061d73a81..1508ddfce3 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -815,19 +815,6 @@ BOOL receive_smb(int fd, char *buffer, unsigned int timeout) return False; } - if (srv_encryption_on()) { - NTSTATUS status = srv_decrypt_buffer(buffer); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("receive_smb: SMB decryption failed " - "on incoming packet! Error %s\n", - nt_errstr(status) )); - if (smb_read_error == 0) { - smb_read_error = READ_BAD_DECRYPT; - } - return False; - } - } - /* Check the incoming SMB signature. */ if (!srv_check_sign_mac(buffer, True)) { DEBUG(0, ("receive_smb: SMB Signature verification " @@ -852,19 +839,6 @@ ssize_t receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd, char **buffer, return -1; } - if (srv_encryption_on()) { - NTSTATUS status = srv_decrypt_buffer(*buffer); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("receive_smb: SMB decryption failed on " - "incoming packet! Error %s\n", - nt_errstr(status) )); - if (smb_read_error == 0) { - smb_read_error = READ_BAD_DECRYPT; - } - return -1; - } - } - /* Check the incoming SMB signature. */ if (!srv_check_sign_mac(*buffer, True)) { DEBUG(0, ("receive_smb: SMB Signature verification failed on " @@ -887,35 +861,22 @@ BOOL send_smb(int fd, char *buffer) size_t len; size_t nwritten=0; ssize_t ret; - char *buf_out = buffer; /* Sign the outgoing packet if required. */ - srv_calculate_sign_mac(buf_out); - - if (srv_encryption_on()) { - NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("send_smb: SMB encryption failed " - "on outgoing packet! Error %s\n", - nt_errstr(status) )); - return False; - } - } + srv_calculate_sign_mac(buffer); - len = smb_len(buf_out) + 4; + len = smb_len(buffer) + 4; while (nwritten < len) { - ret = write_data(fd,buf_out+nwritten,len - nwritten); + ret = write_data(fd,buffer+nwritten,len - nwritten); if (ret <= 0) { DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n", (int)len,(int)ret, strerror(errno) )); - srv_free_enc_buffer(buf_out); return False; } nwritten += ret; } - srv_free_enc_buffer(buf_out); return True; } -- cgit From 8e54530b52fd256137740107e9fdf000f00a7a30 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 10 Oct 2007 18:25:16 -0700 Subject: Add start of IPv6 implementation. Currently most of this is avoiding IPv6 in winbindd, but moves most of the socket functions that were wrongly in lib/util.c into lib/util_sock.c and provides generic IPv4/6 independent versions of most things. Still lots of work to do, but now I can see how I'll fix the access check code. Nasty part that remains is the name resolution code which is used to returning arrays of in_addr structs. Jeremy. (This used to be commit 3f6bd0e1ec5cc6670f3d08f76fc2cd94c9cd1a08) --- source3/lib/util_sock.c | 515 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 466 insertions(+), 49 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 1508ddfce3..7a1a05ec29 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -29,33 +29,353 @@ static int client_fd = -1; static char client_ip_string[INET6_ADDRSTRLEN]; /**************************************************************************** - Pritn out an IPv4 or IPv6 address from a struct sockaddr_storage. + Return true if a string could be a pure IPv4 address. ****************************************************************************/ -char *print_sockaddr(char *dest, - size_t destlen, - struct sockaddr_storage *psa) +bool is_ipaddress_v4(const char *str) { - if (destlen > 0) { - dest[0] = '\0'; + bool pure_address = true; + int i; + + for (i=0; pure_address && str[i]; i++) { + if (!(isdigit((int)str[i]) || str[i] == '.')) { + pure_address = false; + } + } + + /* Check that a pure number is not misinterpreted as an IP */ + pure_address = pure_address && (strchr_m(str, '.') != NULL); + return pure_address; +} + +/**************************************************************************** + Interpret an internet address or name into an IP address in 4 byte form. +****************************************************************************/ + +uint32 interpret_addr(const char *str) +{ + struct hostent *hp; + uint32 res; + + if (strcmp(str,"0.0.0.0") == 0) + return(0); + if (strcmp(str,"255.255.255.255") == 0) + return(0xFFFFFFFF); + + /* if it's in the form of an IP address then + * get the lib to interpret it */ + if (is_ipaddress_v4(str)) { + res = inet_addr(str); + } else { + /* otherwise assume it's a network name of some sort and use + sys_gethostbyname */ + if ((hp = sys_gethostbyname(str)) == 0) { + DEBUG(3,("sys_gethostbyname: Unknown host. %s\n",str)); + return 0; + } + + if(hp->h_addr == NULL) { + DEBUG(3,("sys_gethostbyname: host address is " + "invalid for host %s\n",str)); + return 0; + } + putip((char *)&res,(char *)hp->h_addr); + } + + if (res == (uint32)-1) + return(0); + + return(res); +} + +/******************************************************************* + A convenient addition to interpret_addr(). +******************************************************************/ + +struct in_addr *interpret_addr2(const char *str) +{ + static struct in_addr ret; + uint32 a = interpret_addr(str); + ret.s_addr = a; + return(&ret); +} + +/******************************************************************* + Map a text hostname or IP address (IPv4 or IPv6) into a + struct sockaddr_storage. +******************************************************************/ + +bool interpret_string_addr(struct sockaddr_storage *pss, const char *str) +{ + int ret; + struct addrinfo *res = NULL; + struct addrinfo hints; + + memset(pss,'\0', sizeof(*pss)); + + memset(&hints, '\0', sizeof(hints)); + /* By default make sure it supports TCP. */ + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_ADDRCONFIG; + + ret = getaddrinfo(str, NULL, + &hints, + &res); + + if (ret) { + DEBUG(3,("interpret_string_addr: getaddrinfo failed for " + "name %s [%s]\n", + str, + gai_strerror(ret) )); + return false; + } + + /* Copy the first sockaddr. */ + memcpy(pss, res->ai_addr, res->ai_addrlen); + freeaddrinfo(res); + return true; +} + +/******************************************************************* + Check if an IPv7 is 127.0.0.1 +******************************************************************/ + +bool is_loopback_ip_v4(struct in_addr ip) +{ + struct in_addr a; + a.s_addr = htonl(INADDR_LOOPBACK); + return(ip.s_addr == a.s_addr); +} + +/******************************************************************* + Check if a struct sockaddr_storage is the loopback address. +******************************************************************/ + +bool is_loopback_addr(const struct sockaddr_storage *pss) +{ +#if defined(AF_INET6) + if (pss->ss_family == AF_INET) { + struct in6_addr *pin6 = &((struct sockaddr_in6 *)pss)->sin6_addr; + return IN6_IS_ADDR_LOOPBACK(pin6); + } +#endif + if (pss->ss_family == AF_INET) { + struct in_addr *pin = &((struct sockaddr_in *)pss)->sin_addr; + return is_loopback_ip_v4(*pin); + } + return false; +} + +/******************************************************************* + Check if an IPv4 is 0.0.0.0. +******************************************************************/ + +bool is_zero_ip_v4(struct in_addr ip) +{ + uint32 a; + putip((char *)&a,(char *)&ip); + return(a == 0); +} + +/******************************************************************* + Check if a struct sockaddr_storage has an unspecified address. +******************************************************************/ + +bool is_zero_addr(const struct sockaddr_storage *pss) +{ +#if defined(AF_INET6) + if (pss->ss_family == AF_INET) { + struct in6_addr *pin6 = &((struct sockaddr_in6 *)pss)->sin6_addr; + return IN6_IS_ADDR_UNSPECIFIED(pin6); + } +#endif + if (pss->ss_family == AF_INET) { + struct in_addr *pin = &((struct sockaddr_in *)pss)->sin_addr; + return is_zero_ip_v4(*pin); } + return false; +} + +/******************************************************************* + Set an IP to 0.0.0.0. +******************************************************************/ + +void zero_ip_v4(struct in_addr *ip) +{ + static bool init; + static struct in_addr ipzero; + + if (!init) { + ipzero = *interpret_addr2("0.0.0.0"); + init = true; + } + + *ip = ipzero; +} + +/******************************************************************* + Are two IPs on the same subnet - IPv4 version ? +********************************************************************/ + +bool same_net_v4(struct in_addr ip1,struct in_addr ip2,struct in_addr mask) +{ + uint32 net1,net2,nmask; + + nmask = ntohl(mask.s_addr); + net1 = ntohl(ip1.s_addr); + net2 = ntohl(ip2.s_addr); + + return((net1 & nmask) == (net2 & nmask)); +} + +/******************************************************************* + Convert an IPv4 struct in_addr to a struct sockaddr_storage. +********************************************************************/ + +void in_addr_to_sockaddr_storage(struct sockaddr_storage *ss, + struct in_addr ip) +{ + struct sockaddr_in *sa = (struct sockaddr_in *)ss; + memset(ss, '\0', sizeof(*ss)); + ss->ss_family = AF_INET; + sa->sin_addr = ip; +} + +#ifdef AF_INET6 +/******************************************************************* + Convert an IPv6 struct in_addr to a struct sockaddr_storage. +********************************************************************/ + +void in6_addr_to_sockaddr_storage(struct sockaddr_storage *ss, + struct in6_addr ip) +{ + struct sockaddr_in6 *sa = (struct sockaddr_in6 *)ss; + memset(ss, '\0', sizeof(*ss)); + ss->ss_family = AF_INET6; + sa->sin6_addr = ip; +} +#endif + +/******************************************************************* + Are two IPs on the same subnet? +********************************************************************/ + +bool same_net(const struct sockaddr_storage *ip1, + const struct sockaddr_storage *ip2, + const struct sockaddr_storage *mask) +{ + if (ip1->ss_family != ip2->ss_family) { + /* Never on the same net. */ + return false; + } + +#ifdef AF_INET6 + if (ip1->ss_family == AF_INET6) { + struct sockaddr_in6 ip1_6 = *(struct sockaddr_in6 *)ip1; + struct sockaddr_in6 ip2_6 = *(struct sockaddr_in6 *)ip2; + struct sockaddr_in6 mask_6 = *(struct sockaddr_in6 *)mask; + char *p1 = (char *)&ip1_6.sin6_addr; + char *p2 = (char *)&ip2_6.sin6_addr; + char *m = (char *)&mask_6.sin6_addr; + int i; + + for (i = 0; i < sizeof(struct in6_addr); i++) { + *p1++ &= *m; + *p2++ &= *m; + m++; + } + return (memcmp(&ip1_6.sin6_addr, + &ip2_6.sin6_addr, + sizeof(struct in6_addr)) == 0); + } +#endif + if (ip1->ss_family == AF_INET) { + return same_net_v4(((const struct sockaddr_in *)ip1)->sin_addr, + ((const struct sockaddr_in *)ip2)->sin_addr, + ((const struct sockaddr_in *)mask)->sin_addr); + } + return false; +} + +/******************************************************************* + Are two sockaddr_storage's the same family and address ? Ignore port etc. +********************************************************************/ + +bool addr_equal(const struct sockaddr_storage *ip1, + const struct sockaddr_storage *ip2) +{ + if (ip1->ss_family != ip2->ss_family) { + /* Never the same. */ + return false; + } + +#ifdef AF_INET6 + if (ip1->ss_family == AF_INET6) { + return (memcmp(&((const struct sockaddr_in6 *)ip1)->sin6_addr, + &((const struct sockaddr_in6 *)ip2)->sin6_addr, + sizeof(struct in6_addr)) == 0); + } +#endif + if (ip1->ss_family == AF_INET) { + return (memcmp(&((const struct sockaddr_in *)ip1)->sin_addr, + &((const struct sockaddr_in *)ip2)->sin_addr, + sizeof(struct in_addr)) == 0); + } + return false; +} + + +/**************************************************************************** + Is an IP address the INADDR_ANY or in6addr_any value ? +****************************************************************************/ + +bool is_address_any(const struct sockaddr_storage *psa) +{ #ifdef AF_INET6 if (psa->ss_family == AF_INET6) { - inet_ntop(AF_INET6, - &((struct sockaddr_in6 *)psa)->sin6_addr, - dest, - destlen); + struct sockaddr_in6 *si6 = (struct sockaddr_in6 *)psa; + if (memcmp(&in6addr_any, + &si6->sin6_addr, + sizeof(in6addr_any)) == 0) { + return true; + } + return false; } #endif if (psa->ss_family == AF_INET) { - inet_ntop(AF_INET, - &((struct sockaddr_in *)psa)->sin_addr, - dest, - destlen); + struct sockaddr_in *si = (struct sockaddr_in *)psa; + if (si->sin_addr.s_addr == INADDR_ANY) { + return true; + } + return false; } + return false; +} + +/**************************************************************************** + Print out an IPv4 or IPv6 address from a struct sockaddr_storage. +****************************************************************************/ + +char *print_sockaddr(char *dest, + size_t destlen, + const struct sockaddr_storage *psa, + socklen_t psalen) +{ + if (destlen > 0) { + dest[0] = '\0'; + } + (void)getnameinfo((const struct sockaddr *)psa, + psalen, + dest, destlen, + NULL, 0, + NI_NUMERICHOST); return dest; } +/**************************************************************************** + Set the global client_fd variable. +****************************************************************************/ + void client_setfd(int fd) { client_fd = fd; @@ -64,6 +384,10 @@ void client_setfd(int fd) sizeof(client_ip_string)-1); } +/**************************************************************************** + Return a static string of an IP address (IPv4 or IPv6). +****************************************************************************/ + static char *get_socket_addr(int fd) { struct sockaddr_storage sa; @@ -87,9 +411,13 @@ static char *get_socket_addr(int fd) return addr_buf; } - return print_sockaddr(addr_buf, sizeof(addr_buf), &sa); + return print_sockaddr(addr_buf, sizeof(addr_buf), &sa, length); } +/**************************************************************************** + Return the port number we've bound to on a socket. +****************************************************************************/ + static int get_socket_port(int fd) { struct sockaddr_storage sa; @@ -118,7 +446,7 @@ static int get_socket_port(int fd) char *client_name(void) { - return get_peer_name(client_fd,False); + return get_peer_name(client_fd,false); } char *client_addr(void) @@ -142,7 +470,7 @@ int smb_read_error = 0; Determine if a file descriptor is in fact a socket. ****************************************************************************/ -BOOL is_a_socket(int fd) +bool is_a_socket(int fd) { int v; socklen_t l; @@ -247,12 +575,12 @@ void set_socket_options(int fd, const char *options) int ret=0,i; int value = 1; char *p; - BOOL got_value = False; + bool got_value = false; if ((p = strchr_m(tok,'='))) { *p = 0; value = atoi(p+1); - got_value = True; + got_value = true; } for (i=0;socket_options[i].name;i++) @@ -559,7 +887,7 @@ ssize_t write_data(int fd, const char *buffer, size_t N) Send a keepalive packet (rfc1002). ****************************************************************************/ -BOOL send_keepalive(int client) +bool send_keepalive(int client) { unsigned char buf[4]; @@ -583,7 +911,7 @@ static ssize_t read_smb_length_return_keepalive(int fd, { ssize_t len=0; int msg_type; - BOOL ok = False; + bool ok = false; while (!ok) { if (timeout > 0) { @@ -809,23 +1137,23 @@ static ssize_t receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd, Checks the MAC on signed packets. ****************************************************************************/ -BOOL receive_smb(int fd, char *buffer, unsigned int timeout) +bool receive_smb(int fd, char *buffer, unsigned int timeout) { if (receive_smb_raw(fd, buffer, timeout, 0) < 0) { - return False; + return false; } /* Check the incoming SMB signature. */ - if (!srv_check_sign_mac(buffer, True)) { + if (!srv_check_sign_mac(buffer, true)) { DEBUG(0, ("receive_smb: SMB Signature verification " "failed on incoming packet!\n")); if (smb_read_error == 0) { smb_read_error = READ_BAD_SIG; } - return False; + return false; } - return True; + return true; } ssize_t receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd, char **buffer, @@ -840,7 +1168,7 @@ ssize_t receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd, char **buffer, } /* Check the incoming SMB signature. */ - if (!srv_check_sign_mac(*buffer, True)) { + if (!srv_check_sign_mac(*buffer, true)) { DEBUG(0, ("receive_smb: SMB Signature verification failed on " "incoming packet!\n")); if (smb_read_error == 0) { @@ -856,7 +1184,7 @@ ssize_t receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd, char **buffer, Send an smb to a fd. ****************************************************************************/ -BOOL send_smb(int fd, char *buffer) +bool send_smb(int fd, char *buffer) { size_t len; size_t nwritten=0; @@ -872,12 +1200,12 @@ BOOL send_smb(int fd, char *buffer) if (ret <= 0) { DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n", (int)len,(int)ret, strerror(errno) )); - return False; + return false; } nwritten += ret; } - return True; + return true; } /**************************************************************************** @@ -888,7 +1216,7 @@ int open_socket_in(int type, int port, int dlevel, uint32 socket_addr, - BOOL rebind ) + bool rebind ) { struct sockaddr_in sock; int res; @@ -919,7 +1247,7 @@ int open_socket_in(int type, if( DEBUGLVL( dlevel ) ) { dbgtext( "open_socket_in(): setsockopt: " ); dbgtext( "SO_REUSEADDR = %s ", - val?"True":"False" ); + val?"true":"false" ); dbgtext( "on port %d failed ", port ); dbgtext( "with error = %s\n", strerror(errno) ); } @@ -930,7 +1258,7 @@ int open_socket_in(int type, if( DEBUGLVL( dlevel ) ) { dbgtext( "open_socket_in(): setsockopt: "); dbgtext( "SO_REUSEPORT = %s ", - val?"True":"False" ); + val?"true":"false" ); dbgtext( "on port %d failed ", port ); dbgtext( "with error = %s\n", strerror(errno) ); } @@ -984,7 +1312,7 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) sock_out.sin_family = PF_INET; /* set it non-blocking */ - set_blocking(res,False); + set_blocking(res,false); DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port)); @@ -1029,7 +1357,7 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) } /* set it blocking again */ - set_blocking(res,True); + set_blocking(res,true); return res; } @@ -1040,12 +1368,12 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) of DC's all of which are equivalent for our purposes. **************************************************************************/ -BOOL open_any_socket_out(struct sockaddr_in *addrs, int num_addrs, +bool open_any_socket_out(struct sockaddr_in *addrs, int num_addrs, int timeout, int *fd_index, int *fd) { int i, resulting_index, res; int *sockets; - BOOL good_connect; + bool good_connect; fd_set r_fds, wr_fds; struct timeval tv; @@ -1058,7 +1386,7 @@ BOOL open_any_socket_out(struct sockaddr_in *addrs, int num_addrs, sockets = SMB_MALLOC_ARRAY(int, num_addrs); if (sockets == NULL) - return False; + return false; resulting_index = -1; @@ -1069,11 +1397,11 @@ BOOL open_any_socket_out(struct sockaddr_in *addrs, int num_addrs, sockets[i] = socket(PF_INET, SOCK_STREAM, 0); if (sockets[i] < 0) goto done; - set_blocking(sockets[i], False); + set_blocking(sockets[i], false); } connect_again: - good_connect = False; + good_connect = false; for (i=0; i= 0) { *fd_index = resulting_index; *fd = sockets[*fd_index]; - set_blocking(*fd, True); + set_blocking(*fd, true); } free(sockets); @@ -1223,7 +1551,7 @@ int open_udp_socket(const char *host, int port) confirm a hostname lookup to prevent spoof attacks. ******************************************************************/ -static BOOL matchname(char *remotehost,struct in_addr addr) +static bool matchname(char *remotehost,struct in_addr addr) { struct hostent *hp; int i; @@ -1231,7 +1559,7 @@ static BOOL matchname(char *remotehost,struct in_addr addr) if ((hp = sys_gethostbyname(remotehost)) == 0) { DEBUG(0,("sys_gethostbyname(%s): lookup failure.\n", remotehost)); - return False; + return false; } /* @@ -1246,13 +1574,13 @@ static BOOL matchname(char *remotehost,struct in_addr addr) && !strequal(remotehost, "localhost")) { DEBUG(0,("host name/name mismatch: %s != %s\n", remotehost, hp->h_name)); - return False; + return false; } /* Look up the host address in the address list we just got. */ for (i = 0; hp->h_addr_list[i]; i++) { if (memcmp(hp->h_addr_list[i], (char *)&addr,sizeof(addr)) == 0) - return True; + return true; } /* @@ -1263,14 +1591,14 @@ static BOOL matchname(char *remotehost,struct in_addr addr) DEBUG(0,("host name/address mismatch: %s != %s\n", inet_ntoa(addr), hp->h_name)); - return False; + return false; } /******************************************************************* Return the DNS name of the remote end of a socket. ******************************************************************/ -char *get_peer_name(int fd, BOOL force_lookup) +char *get_peer_name(int fd, bool force_lookup) { static pstring name_buf; pstring tmp_name; @@ -1283,7 +1611,7 @@ char *get_peer_name(int fd, BOOL force_lookup) situations won't work because many networks don't link dhcp with dns. To avoid the delay we avoid the lookup if possible */ - if (!lp_hostname_lookups() && (force_lookup == False)) { + if (!lp_hostname_lookups() && (force_lookup == false)) { return get_peer_addr(fd); } @@ -1450,3 +1778,92 @@ out_umask: return -1; #endif /* HAVE_UNIXSOCKET */ } + +/************************************************************ + Is this my name ? Needs fixing for IPv6. +************************************************************/ + +bool is_myname_or_ipaddr(const char *s) +{ + fstring name, dnsname; + char *servername; + + if ( !s ) + return false; + + /* santize the string from '\\name' */ + + fstrcpy( name, s ); + + servername = strrchr_m( name, '\\' ); + if ( !servername ) + servername = name; + else + servername++; + + /* optimize for the common case */ + + if (strequal(servername, global_myname())) + return true; + + /* check for an alias */ + + if (is_myname(servername)) + return true; + + /* check for loopback */ + + if (strequal(servername, "127.0.0.1")) + return true; + + if (strequal(servername, "localhost")) + return true; + + /* maybe it's my dns name */ + + if ( get_mydnsfullname( dnsname ) ) + if ( strequal( servername, dnsname ) ) + return true; + + /* handle possible CNAME records */ + + if ( !is_ipaddress_v4( servername ) ) { + /* use DNS to resolve the name, but only the first address */ + struct hostent *hp; + + if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) { + struct in_addr return_ip; + putip( (char*)&return_ip, (char*)hp->h_addr ); + fstrcpy( name, inet_ntoa( return_ip ) ); + servername = name; + } + } + + /* maybe its an IP address? */ + if (is_ipaddress_v4(servername)) { + struct sockaddr_storage ss; + struct iface_struct nics[MAX_INTERFACES]; + int i, n; + struct in_addr ip; + + ip = *interpret_addr2(servername); + if (is_zero_ip_v4(ip) || is_loopback_ip_v4(ip)) { + return false; + } + + in_addr_to_sockaddr_storage(&ss, ip); + + n = get_interfaces(nics, MAX_INTERFACES); + for (i=0; i Date: Thu, 11 Oct 2007 15:36:13 -0700 Subject: Add const to the get_peer_addr() and get_socket_addr() calls. Use the IPv6 varient for get_peer_addr(). Jeremy. (This used to be commit baf1f52e34ae2465a7a34be1065da29ed97e7bea) --- source3/lib/util_sock.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 7a1a05ec29..5a96bb79d6 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -388,7 +388,7 @@ void client_setfd(int fd) Return a static string of an IP address (IPv4 or IPv6). ****************************************************************************/ -static char *get_socket_addr(int fd) +static const char *get_socket_addr(int fd) { struct sockaddr_storage sa; socklen_t length = sizeof(sa); @@ -444,17 +444,17 @@ static int get_socket_port(int fd) return -1; } -char *client_name(void) +const char *client_name(void) { return get_peer_name(client_fd,false); } -char *client_addr(void) +const char *client_addr(void) { return get_peer_addr(client_fd); } -char *client_socket_addr(void) +const char *client_socket_addr(void) { return get_socket_addr(client_fd); } @@ -1598,14 +1598,14 @@ static bool matchname(char *remotehost,struct in_addr addr) Return the DNS name of the remote end of a socket. ******************************************************************/ -char *get_peer_name(int fd, bool force_lookup) +const char *get_peer_name(int fd, bool force_lookup) { static pstring name_buf; pstring tmp_name; static fstring addr_buf; struct hostent *hp; struct in_addr addr; - char *p; + const char *p; /* reverse lookups can be *very* expensive, and in many situations won't work because many networks don't link dhcp @@ -1659,27 +1659,28 @@ char *get_peer_name(int fd, bool force_lookup) Return the IP addr of the remote end of a socket as a string. ******************************************************************/ -char *get_peer_addr(int fd) +const char *get_peer_addr(int fd) { - struct sockaddr sa; - struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); - socklen_t length = sizeof(sa); - static fstring addr_buf; + struct sockaddr_storage ss; + socklen_t length = sizeof(ss); + static char addr_buf[INET6_ADDRSTRLEN]; - fstrcpy(addr_buf,"0.0.0.0"); + safe_strcpy(addr_buf,"0.0.0.0",sizeof(addr_buf)-1); if (fd == -1) { return addr_buf; } - if (getpeername(fd, &sa, &length) < 0) { + if (getpeername(fd, (struct sockaddr *)&ss, &length) < 0) { DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) )); return addr_buf; } - fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr)); - + print_sockaddr(addr_buf, + sizeof(addr_buf), + &ss, + length); return addr_buf; } -- cgit From e9cf3a8ca264118c0050579940f2812ac0aa356c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 12 Oct 2007 13:38:04 -0700 Subject: Convert get_peer_addr() to IPv6. Only is_myname_or_ipaddr() lefto to do then I can fix the lib/access.c functions. Jeremy. (This used to be commit 3403c6c330b886c86d6d856c3ffc13b043fd6fc1) --- source3/lib/util_sock.c | 167 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 112 insertions(+), 55 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 5a96bb79d6..8c5d1b6fec 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1546,41 +1546,102 @@ int open_udp_socket(const char *host, int port) return res; } +/******************************************************************* + Return the IP addr of the remote end of a socket as a string. + Optionally return the struct sockaddr_storage. + ******************************************************************/ + +static const char *get_peer_addr_internal(int fd, + struct sockaddr_storage *pss, + socklen_t *plength) +{ + struct sockaddr_storage ss; + socklen_t length = sizeof(ss); + static char addr_buf[INET6_ADDRSTRLEN]; + + safe_strcpy(addr_buf,"0.0.0.0",sizeof(addr_buf)-1); + + if (fd == -1) { + return addr_buf; + } + + if (pss == NULL) { + pss = &ss; + } + if (plength == NULL) { + plength = &length; + } + + if (getpeername(fd, (struct sockaddr *)pss, plength) < 0) { + DEBUG(0,("getpeername failed. Error was %s\n", + strerror(errno) )); + return addr_buf; + } + + print_sockaddr(addr_buf, + sizeof(addr_buf), + pss, + *plength); + return addr_buf; +} + + /******************************************************************* Matchname - determine if host name matches IP address. Used to confirm a hostname lookup to prevent spoof attacks. ******************************************************************/ -static bool matchname(char *remotehost,struct in_addr addr) +static bool matchname(const char *remotehost, + const struct sockaddr_storage *pss, + socklen_t len) { - struct hostent *hp; - int i; + struct addrinfo hints; + struct addrinfo *res = NULL; + struct addrinfo *ailist = NULL; + char addr_buf[INET6_ADDRSTRLEN]; + int ret = -1; + + memset(&hints,'\0',sizeof(struct addrinfo)); + /* By default make sure it supports TCP. */ + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_ADDRCONFIG|AI_CANONNAME; - if ((hp = sys_gethostbyname(remotehost)) == 0) { - DEBUG(0,("sys_gethostbyname(%s): lookup failure.\n", - remotehost)); + ret = getaddrinfo(remotehost, NULL, + &hints, + &res); + + if (ret || res == NULL) { + DEBUG(3,("matchname: getaddrinfo failed for " + "name %s [%s]\n", + remotehost, + gai_strerror(ret) )); return false; } /* - * Make sure that gethostbyname() returns the "correct" host name. - * Unfortunately, gethostbyname("localhost") sometimes yields - * "localhost.domain". Since the latter host name comes from the - * local DNS, we just have to trust it (all bets are off if the local - * DNS is perverted). We always check the address list, though. + * Make sure that getaddrinfo() returns the "correct" host name. */ - if (!strequal(remotehost, hp->h_name) - && !strequal(remotehost, "localhost")) { - DEBUG(0,("host name/name mismatch: %s != %s\n", - remotehost, hp->h_name)); + if (res->ai_canonname == NULL || + (!strequal(remotehost, res->ai_canonname) && + !strequal(remotehost, "localhost"))) { + DEBUG(0,("matchname: host name/name mismatch: %s != %s\n", + remotehost, + res->ai_canonname ? res->ai_canonname : "(NULL)")); + freeaddrinfo(res); return false; } /* Look up the host address in the address list we just got. */ - for (i = 0; hp->h_addr_list[i]; i++) { - if (memcmp(hp->h_addr_list[i], (char *)&addr,sizeof(addr)) == 0) + for (ailist = res; ailist; ailist = ailist->ai_next) { + if (!ailist->ai_addr) { + continue; + } + if (addr_equal((const struct sockaddr_storage *)ailist->ai_addr, + pss)) { + freeaddrinfo(res); return true; + } } /* @@ -1589,8 +1650,14 @@ static bool matchname(char *remotehost,struct in_addr addr) * it, but that could be dangerous, too. */ - DEBUG(0,("host name/address mismatch: %s != %s\n", - inet_ntoa(addr), hp->h_name)); + DEBUG(0,("matchname: host name/address mismatch: %s != %s\n", + print_sockaddr(addr_buf, + sizeof(addr_buf), + pss, + len), + res->ai_canonname ? res->ai_canonname : "(NULL)")); + + freeaddrinfo(res); return false; } @@ -1600,12 +1667,13 @@ static bool matchname(char *remotehost,struct in_addr addr) const char *get_peer_name(int fd, bool force_lookup) { - static pstring name_buf; - pstring tmp_name; static fstring addr_buf; - struct hostent *hp; - struct in_addr addr; + static pstring name_buf; + struct sockaddr_storage ss; + socklen_t length = sizeof(ss); const char *p; + int ret; + pstring tmp_name; /* reverse lookups can be *very* expensive, and in many situations won't work because many networks don't link dhcp @@ -1615,28 +1683,37 @@ const char *get_peer_name(int fd, bool force_lookup) return get_peer_addr(fd); } - p = get_peer_addr(fd); + p = get_peer_addr_internal(fd, &ss, &length); /* it might be the same as the last one - save some DNS work */ - if (strcmp(p, addr_buf) == 0) + if (strcmp(p, addr_buf) == 0) { return name_buf; + } pstrcpy(name_buf,"UNKNOWN"); - if (fd == -1) + if (fd == -1) { return name_buf; + } fstrcpy(addr_buf, p); - addr = *interpret_addr2(p); - /* Look up the remote host name. */ - if ((hp = gethostbyaddr((char *)&addr.s_addr, - sizeof(addr.s_addr), AF_INET)) == 0) { - DEBUG(1,("Gethostbyaddr failed for %s\n",p)); + ret = getnameinfo((struct sockaddr *)&ss, + length, + name_buf, + sizeof(name_buf), + NULL, + 0, + NI_NUMERICHOST); + + if (ret) { + DEBUG(1,("get_peer_name: getnameinfo failed " + "for %s with error %s\n", + p, + gai_strerror(ret))); pstrcpy(name_buf, p); } else { - pstrcpy(name_buf,(char *)hp->h_name); - if (!matchname(name_buf, addr)) { + if (!matchname(name_buf, &ss, length)) { DEBUG(0,("Matchname failed on %s %s\n",name_buf,p)); pstrcpy(name_buf,"UNKNOWN"); } @@ -1646,7 +1723,7 @@ const char *get_peer_name(int fd, bool force_lookup) use --enable-developer or the clobber_region() call will get you */ - pstrcpy( tmp_name, name_buf ); + pstrcpy(tmp_name, name_buf ); alpha_strcpy(name_buf, tmp_name, "_-.", sizeof(name_buf)); if (strstr(name_buf,"..")) { pstrcpy(name_buf, "UNKNOWN"); @@ -1661,27 +1738,7 @@ const char *get_peer_name(int fd, bool force_lookup) const char *get_peer_addr(int fd) { - struct sockaddr_storage ss; - socklen_t length = sizeof(ss); - static char addr_buf[INET6_ADDRSTRLEN]; - - safe_strcpy(addr_buf,"0.0.0.0",sizeof(addr_buf)-1); - - if (fd == -1) { - return addr_buf; - } - - if (getpeername(fd, (struct sockaddr *)&ss, &length) < 0) { - DEBUG(0,("getpeername failed. Error was %s\n", - strerror(errno) )); - return addr_buf; - } - - print_sockaddr(addr_buf, - sizeof(addr_buf), - &ss, - length); - return addr_buf; + return get_peer_addr_internal(fd, NULL, NULL); } /******************************************************************* -- cgit From 6c8225445b9c6d92abee48d4954a7d3fe2d2e987 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 12 Oct 2007 21:50:41 -0700 Subject: Dummy formatting commit to check I've set up my home git correctly. (This used to be commit a1166e9e651f4acdcf7926c5d8e9cf0c9108fe71) --- source3/lib/util_sock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 8c5d1b6fec..8079932620 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1846,8 +1846,9 @@ bool is_myname_or_ipaddr(const char *s) fstring name, dnsname; char *servername; - if ( !s ) + if ( !s ) { return false; + } /* santize the string from '\\name' */ -- cgit From 666f50b01f282e520c59b94944d4b1583168d46a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 15 Oct 2007 16:11:48 -0700 Subject: Move to protocol independent code in most of lib/util_sock.c We don't use gethostbyname any more except in one case where we're looking for host aliases (I don't know how to do that with getaddrinfo yet). New function should be getaddrinfo(). Next step will be fixing lib/access.c, and then changing libsmb/namequery.c to cope with IPv6 address returns. Jeremy. (This used to be commit 4a56b697b6adcf095e25895c4a9ba3192ed34124) --- source3/lib/util_sock.c | 337 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 223 insertions(+), 114 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 8079932620..eb3b35339c 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -29,63 +29,133 @@ static int client_fd = -1; static char client_ip_string[INET6_ADDRSTRLEN]; /**************************************************************************** - Return true if a string could be a pure IPv4 address. + Return true if a string could be an IPv4 address. ****************************************************************************/ bool is_ipaddress_v4(const char *str) { - bool pure_address = true; - int i; + int ret = -1; + struct in_addr dest; - for (i=0; pure_address && str[i]; i++) { - if (!(isdigit((int)str[i]) || str[i] == '.')) { - pure_address = false; - } + ret = inet_pton(AF_INET, str, &dest); + if (ret > 0) { + return true; } + return false; +} - /* Check that a pure number is not misinterpreted as an IP */ - pure_address = pure_address && (strchr_m(str, '.') != NULL); - return pure_address; +/**************************************************************************** + Return true if a string could be an IPv4 or IPv6 address. +****************************************************************************/ + +bool is_ipaddress(const char *str) +{ + int ret = -1; + +#if defined(AF_INET6) + struct in6_addr dest6; + + ret = inet_pton(AF_INET6, str, &dest6); + if (ret > 0) { + return true; + } +#endif + return is_ipaddress_v4(str); +} + +/******************************************************************* + Wrap getaddrinfo... +******************************************************************/ + +static bool interpret_string_addr_internal(struct addrinfo **ppres, + const char *str, int flags) +{ + int ret; + struct addrinfo hints; + + memset(&hints, '\0', sizeof(hints)); + /* By default make sure it supports TCP. */ + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = flags; + + ret = getaddrinfo(str, NULL, + &hints, + ppres); + if (ret) { + DEBUG(3,("interpret_string_addr_interal: getaddrinfo failed " + "for name %s [%s]\n", + str, + gai_strerror(ret) )); + return false; + } + return true; } /**************************************************************************** Interpret an internet address or name into an IP address in 4 byte form. + RETURNS IN NETWORK BYTE ORDER (big endian). ****************************************************************************/ uint32 interpret_addr(const char *str) { - struct hostent *hp; - uint32 res; + uint32 ret; - if (strcmp(str,"0.0.0.0") == 0) - return(0); - if (strcmp(str,"255.255.255.255") == 0) - return(0xFFFFFFFF); - - /* if it's in the form of an IP address then + /* If it's in the form of an IP address then * get the lib to interpret it */ if (is_ipaddress_v4(str)) { - res = inet_addr(str); + struct in_addr dest; + + if (inet_pton(AF_INET, str, &dest) <= 0) { + /* Error - this shouldn't happen ! */ + DEBUG(0,("interpret_addr: inet_pton failed " + "host %s\n", + str)); + return 0; + } + ret = dest.s_addr; /* NETWORK BYTE ORDER ! */ } else { - /* otherwise assume it's a network name of some sort and use - sys_gethostbyname */ - if ((hp = sys_gethostbyname(str)) == 0) { - DEBUG(3,("sys_gethostbyname: Unknown host. %s\n",str)); + /* Otherwise assume it's a network name of some sort and use + getadddrinfo. */ + struct addrinfo *res = NULL; + struct addrinfo *res_list = NULL; + if (!interpret_string_addr_internal(&res_list, + str, + AI_ADDRCONFIG)) { + DEBUG(3,("interpret_addr: Unknown host. %s\n",str)); return 0; } - if(hp->h_addr == NULL) { - DEBUG(3,("sys_gethostbyname: host address is " + /* Find the first IPv4 address. */ + for (res = res_list; res; res = res->ai_next) { + if (res->ai_family != AF_INET) { + continue; + } + if (res->ai_addr == NULL) { + continue; + } + break; + } + if(res == NULL) { + DEBUG(3,("interpret_addr: host address is " "invalid for host %s\n",str)); + if (res_list) { + freeaddrinfo(res_list); + } return 0; } - putip((char *)&res,(char *)hp->h_addr); + putip((char *)&ret, + &((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr); + if (res_list) { + freeaddrinfo(res_list); + } } - if (res == (uint32)-1) - return(0); + /* This is so bogus - all callers need fixing... JRA. */ + if (ret == (uint32)-1) { + return 0; + } - return(res); + return ret; } /******************************************************************* @@ -105,31 +175,20 @@ struct in_addr *interpret_addr2(const char *str) struct sockaddr_storage. ******************************************************************/ -bool interpret_string_addr(struct sockaddr_storage *pss, const char *str) +bool interpret_string_addr(struct sockaddr_storage *pss, + const char *str, + int flags) { - int ret; struct addrinfo *res = NULL; - struct addrinfo hints; memset(pss,'\0', sizeof(*pss)); - memset(&hints, '\0', sizeof(hints)); - /* By default make sure it supports TCP. */ - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_ADDRCONFIG; - - ret = getaddrinfo(str, NULL, - &hints, - &res); - - if (ret) { - DEBUG(3,("interpret_string_addr: getaddrinfo failed for " - "name %s [%s]\n", - str, - gai_strerror(ret) )); + if (!interpret_string_addr_internal(&res, str, flags|AI_ADDRCONFIG)) { + return false; + } + if (!res) { return false; } - /* Copy the first sockaddr. */ memcpy(pss, res->ai_addr, res->ai_addrlen); freeaddrinfo(res); @@ -155,7 +214,8 @@ bool is_loopback_addr(const struct sockaddr_storage *pss) { #if defined(AF_INET6) if (pss->ss_family == AF_INET) { - struct in6_addr *pin6 = &((struct sockaddr_in6 *)pss)->sin6_addr; + struct in6_addr *pin6 = + &((struct sockaddr_in6 *)pss)->sin6_addr; return IN6_IS_ADDR_LOOPBACK(pin6); } #endif @@ -185,7 +245,8 @@ bool is_zero_addr(const struct sockaddr_storage *pss) { #if defined(AF_INET6) if (pss->ss_family == AF_INET) { - struct in6_addr *pin6 = &((struct sockaddr_in6 *)pss)->sin6_addr; + struct in6_addr *pin6 = + &((struct sockaddr_in6 *)pss)->sin6_addr; return IN6_IS_ADDR_UNSPECIFIED(pin6); } #endif @@ -1215,7 +1276,7 @@ bool send_smb(int fd, char *buffer) int open_socket_in(int type, int port, int dlevel, - uint32 socket_addr, + uint32 socket_addr, /* NETWORK BYTE ORDER */ bool rebind ) { struct sockaddr_in sock; @@ -1595,22 +1656,14 @@ static bool matchname(const char *remotehost, const struct sockaddr_storage *pss, socklen_t len) { - struct addrinfo hints; struct addrinfo *res = NULL; struct addrinfo *ailist = NULL; char addr_buf[INET6_ADDRSTRLEN]; - int ret = -1; - - memset(&hints,'\0',sizeof(struct addrinfo)); - /* By default make sure it supports TCP. */ - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_ADDRCONFIG|AI_CANONNAME; - - ret = getaddrinfo(remotehost, NULL, - &hints, - &res); + bool ret = interpret_string_addr_internal(&ailist, + remotehost, + AI_ADDRCONFIG|AI_CANONNAME); - if (ret || res == NULL) { + if (!ret || ailist == NULL) { DEBUG(3,("matchname: getaddrinfo failed for " "name %s [%s]\n", remotehost, @@ -1622,24 +1675,25 @@ static bool matchname(const char *remotehost, * Make sure that getaddrinfo() returns the "correct" host name. */ - if (res->ai_canonname == NULL || - (!strequal(remotehost, res->ai_canonname) && + if (ailist->ai_canonname == NULL || + (!strequal(remotehost, ailist->ai_canonname) && !strequal(remotehost, "localhost"))) { DEBUG(0,("matchname: host name/name mismatch: %s != %s\n", remotehost, - res->ai_canonname ? res->ai_canonname : "(NULL)")); - freeaddrinfo(res); + ailist->ai_canonname ? + ailist->ai_canonname : "(NULL)")); + freeaddrinfo(ailist); return false; } /* Look up the host address in the address list we just got. */ - for (ailist = res; ailist; ailist = ailist->ai_next) { - if (!ailist->ai_addr) { + for (res = ailist; res; res = res->ai_next) { + if (!res->ai_addr) { continue; } - if (addr_equal((const struct sockaddr_storage *)ailist->ai_addr, + if (addr_equal((const struct sockaddr_storage *)res->ai_addr, pss)) { - freeaddrinfo(res); + freeaddrinfo(ailist); return true; } } @@ -1655,9 +1709,11 @@ static bool matchname(const char *remotehost, sizeof(addr_buf), pss, len), - res->ai_canonname ? res->ai_canonname : "(NULL)")); + ailist->ai_canonname ? ailist->ai_canonname : "(NULL)")); - freeaddrinfo(res); + if (ailist) { + freeaddrinfo(ailist); + } return false; } @@ -1837,8 +1893,62 @@ out_umask: #endif /* HAVE_UNIXSOCKET */ } +/**************************************************************************** + Get my own canonical name, including domain. +****************************************************************************/ + +bool get_mydnsfullname(fstring my_dnsname) +{ + static fstring dnshostname; + + if (!*dnshostname) { + struct addrinfo *res = NULL; + bool ret; + + /* get my host name */ + if (gethostname(dnshostname, sizeof(dnshostname)) == -1) { + *dnshostname = '\0'; + DEBUG(0,("get_mydnsfullname: gethostname failed\n")); + return false; + } + + /* Ensure null termination. */ + dnshostname[sizeof(dnshostname)-1] = '\0'; + + ret = interpret_string_addr_internal(&res, + dnshostname, + AI_ADDRCONFIG|AI_CANONNAME); + + if (!ret || res == NULL) { + DEBUG(3,("get_mydnsfullname: getaddrinfo failed for " + "name %s [%s]\n", + dnshostname, + gai_strerror(ret) )); + return false; + } + + /* + * Make sure that getaddrinfo() returns the "correct" host name. + */ + + if (res->ai_canonname == NULL) { + DEBUG(3,("get_mydnsfullname: failed to get " + "canonical name for %s\n", + dnshostname)); + freeaddrinfo(res); + return false; + } + + + fstrcpy(dnshostname, res->ai_canonname); + freeaddrinfo(res); + } + fstrcpy(my_dnsname, dnshostname); + return true; +} + /************************************************************ - Is this my name ? Needs fixing for IPv6. + Is this my name ? ************************************************************/ bool is_myname_or_ipaddr(const char *s) @@ -1846,83 +1956,82 @@ bool is_myname_or_ipaddr(const char *s) fstring name, dnsname; char *servername; - if ( !s ) { + if (!s) { return false; } - /* santize the string from '\\name' */ + /* Santize the string from '\\name' */ + fstrcpy(name, s); - fstrcpy( name, s ); - - servername = strrchr_m( name, '\\' ); - if ( !servername ) + servername = strrchr_m(name, '\\' ); + if (!servername) { servername = name; - else + } else { servername++; + } - /* optimize for the common case */ - - if (strequal(servername, global_myname())) + /* Optimize for the common case */ + if (strequal(servername, global_myname())) { return true; + } - /* check for an alias */ - - if (is_myname(servername)) + /* Check for an alias */ + if (is_myname(servername)) { return true; + } - /* check for loopback */ - - if (strequal(servername, "127.0.0.1")) + /* Check for loopback */ + if (strequal(servername, "127.0.0.1") || + strequal(servername, "::1")) { return true; + } - if (strequal(servername, "localhost")) + if (strequal(servername, "localhost")) { return true; + } - /* maybe it's my dns name */ - - if ( get_mydnsfullname( dnsname ) ) - if ( strequal( servername, dnsname ) ) + /* Maybe it's my dns name */ + if (get_mydnsfullname(dnsname)) { + if (strequal(servername, dnsname)) { return true; + } + } - /* handle possible CNAME records */ - - if ( !is_ipaddress_v4( servername ) ) { - /* use DNS to resolve the name, but only the first address */ - struct hostent *hp; - - if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) { - struct in_addr return_ip; - putip( (char*)&return_ip, (char*)hp->h_addr ); - fstrcpy( name, inet_ntoa( return_ip ) ); + /* Handle possible CNAME records - convert to an IP addr. */ + if (!is_ipaddress(servername)) { + /* Use DNS to resolve the name, but only the first address */ + struct sockaddr_storage ss; + if (interpret_string_addr(&ss, servername,0)) { + print_sockaddr(name, + sizeof(name), + &ss, + sizeof(ss)); servername = name; } } - /* maybe its an IP address? */ - if (is_ipaddress_v4(servername)) { + /* Maybe its an IP address? */ + if (is_ipaddress(servername)) { struct sockaddr_storage ss; struct iface_struct nics[MAX_INTERFACES]; int i, n; - struct in_addr ip; - ip = *interpret_addr2(servername); - if (is_zero_ip_v4(ip) || is_loopback_ip_v4(ip)) { + if (!interpret_string_addr(&ss, servername, AI_NUMERICHOST)) { return false; } - in_addr_to_sockaddr_storage(&ss, ip); + if (is_zero_addr(&ss) || is_loopback_addr(&ss)) { + return false; + } n = get_interfaces(nics, MAX_INTERFACES); for (i=0; i Date: Fri, 19 Oct 2007 08:14:12 -0500 Subject: Add test for "struct in6_addr" to the HAVE_IPV6 configure test. Also make use of "if defined(HAVE_IPV6)" rather than testing for AF_INET6 since this is not sufficient on HP-UX 11.11 to ensure a working IPv6 implementation. (This used to be commit 620785df4e57b72471ff0315e22e0d2f28a2b1a5) --- source3/lib/util_sock.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index eb3b35339c..c6b1311cf5 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -52,7 +52,7 @@ bool is_ipaddress(const char *str) { int ret = -1; -#if defined(AF_INET6) +#if defined(HAVE_IPV6) struct in6_addr dest6; ret = inet_pton(AF_INET6, str, &dest6); @@ -212,7 +212,7 @@ bool is_loopback_ip_v4(struct in_addr ip) bool is_loopback_addr(const struct sockaddr_storage *pss) { -#if defined(AF_INET6) +#if defined(HAVE_IPV6) if (pss->ss_family == AF_INET) { struct in6_addr *pin6 = &((struct sockaddr_in6 *)pss)->sin6_addr; @@ -243,7 +243,7 @@ bool is_zero_ip_v4(struct in_addr ip) bool is_zero_addr(const struct sockaddr_storage *pss) { -#if defined(AF_INET6) +#if defined(HAVE_IPV6) if (pss->ss_family == AF_INET) { struct in6_addr *pin6 = &((struct sockaddr_in6 *)pss)->sin6_addr; @@ -302,7 +302,7 @@ void in_addr_to_sockaddr_storage(struct sockaddr_storage *ss, sa->sin_addr = ip; } -#ifdef AF_INET6 +#if defined(HAVE_IPV6) /******************************************************************* Convert an IPv6 struct in_addr to a struct sockaddr_storage. ********************************************************************/ @@ -330,7 +330,7 @@ bool same_net(const struct sockaddr_storage *ip1, return false; } -#ifdef AF_INET6 +#if defined(HAVE_IPV6) if (ip1->ss_family == AF_INET6) { struct sockaddr_in6 ip1_6 = *(struct sockaddr_in6 *)ip1; struct sockaddr_in6 ip2_6 = *(struct sockaddr_in6 *)ip2; @@ -370,7 +370,7 @@ bool addr_equal(const struct sockaddr_storage *ip1, return false; } -#ifdef AF_INET6 +#if defined(HAVE_IPV6) if (ip1->ss_family == AF_INET6) { return (memcmp(&((const struct sockaddr_in6 *)ip1)->sin6_addr, &((const struct sockaddr_in6 *)ip2)->sin6_addr, @@ -392,7 +392,7 @@ bool addr_equal(const struct sockaddr_storage *ip1, bool is_address_any(const struct sockaddr_storage *psa) { -#ifdef AF_INET6 +#if defined(HAVE_IPV6) if (psa->ss_family == AF_INET6) { struct sockaddr_in6 *si6 = (struct sockaddr_in6 *)psa; if (memcmp(&in6addr_any, @@ -494,7 +494,7 @@ static int get_socket_port(int fd) return -1; } -#ifdef AF_INET6 +#if defined(HAVE_IPV6) if (sa.ss_family == AF_INET6) { return ntohs(((struct sockaddr_in6 *)&sa)->sin6_port); } -- cgit From f88b7a076be74a29a3bf876b4e2705f4a1ecf42b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 24 Oct 2007 14:16:54 -0700 Subject: This is a large patch (sorry). Migrate from struct in_addr to struct sockaddr_storage in most places that matter (ie. not the nmbd and NetBIOS lookups). This passes make test on an IPv4 box, but I'll have to do more work/testing on IPv6 enabled boxes. This should now give us a framework for testing and finishing the IPv6 migration. It's at the state where someone with a working IPv6 setup should (theorecically) be able to type : smbclient //ipv6-address/share and have it work. Jeremy. (This used to be commit 98e154c3125d5732c37a72d74b0eb5cd7b6155fd) --- source3/lib/util_sock.c | 206 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 162 insertions(+), 44 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index c6b1311cf5..2d784717b2 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -63,6 +63,27 @@ bool is_ipaddress(const char *str) return is_ipaddress_v4(str); } +/**************************************************************************** + Is a sockaddr_storage a broadcast address ? +****************************************************************************/ + +bool is_broadcast_addr(const struct sockaddr_storage *pss) +{ +#if defined(HAVE_IPV6) + if (pss->ss_family == AF_INET6) { + const struct in6_addr *sin6 = + &((const struct sockaddr_in6 *)pss)->sin6_addr; + return IN6_IS_ADDR_MULTICAST(sin6); + } +#endif + if (pss->ss_family == AF_INET) { + uint32_t addr = + ntohl(((const struct sockaddr_in *)pss)->sin_addr.s_addr); + return addr == INADDR_BROADCAST; + } + return false; +} + /******************************************************************* Wrap getaddrinfo... ******************************************************************/ @@ -181,7 +202,7 @@ bool interpret_string_addr(struct sockaddr_storage *pss, { struct addrinfo *res = NULL; - memset(pss,'\0', sizeof(*pss)); + zero_addr(pss, AF_INET); if (!interpret_string_addr_internal(&res, str, flags|AI_ADDRCONFIG)) { return false; @@ -274,6 +295,17 @@ void zero_ip_v4(struct in_addr *ip) *ip = ipzero; } +/******************************************************************* + Set an address to INADDR_ANY, or IN6ADDR_ANY. +******************************************************************/ + +void zero_addr(struct sockaddr_storage *pss, int family) +{ + memset(pss, '\0', sizeof(*pss)); + /* Ensure we're at least a valid sockaddr-storage. */ + pss->ss_family = family; +} + /******************************************************************* Are two IPs on the same subnet - IPv4 version ? ********************************************************************/ @@ -385,7 +417,6 @@ bool addr_equal(const struct sockaddr_storage *ip1, return false; } - /**************************************************************************** Is an IP address the INADDR_ANY or in6addr_any value ? ****************************************************************************/ @@ -417,7 +448,7 @@ bool is_address_any(const struct sockaddr_storage *psa) Print out an IPv4 or IPv6 address from a struct sockaddr_storage. ****************************************************************************/ -char *print_sockaddr(char *dest, +char *print_sockaddr_len(char *dest, size_t destlen, const struct sockaddr_storage *psa, socklen_t psalen) @@ -433,6 +464,75 @@ char *print_sockaddr(char *dest, return dest; } +/**************************************************************************** + Print out an IPv4 or IPv6 address from a struct sockaddr_storage. +****************************************************************************/ + +char *print_sockaddr(char *dest, + size_t destlen, + const struct sockaddr_storage *psa) +{ + return print_sockaddr_len(dest, destlen, psa, sizeof(*psa)); +} + +/**************************************************************************** + Print out a canonical IPv4 or IPv6 address from a struct sockaddr_storage. +****************************************************************************/ + +char *print_canonical_sockaddr(TALLOC_CTX *ctx, + const struct sockaddr_storage *pss) +{ + char addr[INET6_ADDRSTRLEN]; + char *dest = NULL; + int ret; + + ret = getnameinfo((const struct sockaddr *)pss, + sizeof(struct sockaddr_storage), + addr, sizeof(addr), + NULL, 0, + NI_NUMERICHOST); + if (ret) { + return NULL; + } + if (pss->ss_family != AF_INET) { +#if defined(HAVE_IPV6) + /* IPv6 */ + const struct sockaddr_in6 *sa6 = + (const struct sockaddr_in6 *)pss; + uint16_t port = ntohs(sa6->sin6_port); + + if (port) { + dest = talloc_asprintf(ctx, + "[%s]:%d", + addr, + (unsigned int)port); + } else { + dest = talloc_asprintf(ctx, + "[%s]", + addr); + } +#else + return NULL; +#endif + } else { + const struct sockaddr_in *sa = + (const struct sockaddr_in *)pss; + uint16_t port = ntohs(sa->sin_port); + + if (port) { + dest = talloc_asprintf(ctx, + "%s:%d", + addr, + (unsigned int)port); + } else { + dest = talloc_asprintf(ctx, + "%s", + addr); + } + } + return dest; +} + /**************************************************************************** Set the global client_fd variable. ****************************************************************************/ @@ -472,7 +572,7 @@ static const char *get_socket_addr(int fd) return addr_buf; } - return print_sockaddr(addr_buf, sizeof(addr_buf), &sa, length); + return print_sockaddr_len(addr_buf, sizeof(addr_buf), &sa, length); } /**************************************************************************** @@ -1274,24 +1374,26 @@ bool send_smb(int fd, char *buffer) ****************************************************************************/ int open_socket_in(int type, - int port, + uint16_t port, int dlevel, - uint32 socket_addr, /* NETWORK BYTE ORDER */ - bool rebind ) + const struct sockaddr_storage *psock, + bool rebind) { - struct sockaddr_in sock; + struct sockaddr_storage sock; int res; - memset( (char *)&sock, '\0', sizeof(sock) ); + sock = *psock; -#ifdef HAVE_SOCK_SIN_LEN - sock.sin_len = sizeof(sock); +#if defined(HAVE_IPV6) + if (sock.ss_family == AF_INET6) { + ((struct sockaddr_in6 *)&sock)->sin6_port = htons(port); + } #endif - sock.sin_port = htons( port ); - sock.sin_family = AF_INET; - sock.sin_addr.s_addr = socket_addr; + if (sock.ss_family == AF_INET) { + ((struct sockaddr_in *)&sock)->sin_port = htons(port); + } - res = socket( AF_INET, type, 0 ); + res = socket(sock.ss_family, type, 0 ); if( res == -1 ) { if( DEBUGLVL(0) ) { dbgtext( "open_socket_in(): socket() call failed: " ); @@ -1319,9 +1421,9 @@ int open_socket_in(int type, if( DEBUGLVL( dlevel ) ) { dbgtext( "open_socket_in(): setsockopt: "); dbgtext( "SO_REUSEPORT = %s ", - val?"true":"false" ); - dbgtext( "on port %d failed ", port ); - dbgtext( "with error = %s\n", strerror(errno) ); + val?"true":"false"); + dbgtext( "on port %d failed ", port); + dbgtext( "with error = %s\n", strerror(errno)); } } #endif /* SO_REUSEPORT */ @@ -1331,17 +1433,18 @@ int open_socket_in(int type, if( bind( res, (struct sockaddr *)&sock, sizeof(sock) ) == -1 ) { if( DEBUGLVL(dlevel) && (port == SMB_PORT1 || port == SMB_PORT2 || port == NMB_PORT) ) { - dbgtext( "bind failed on port %d ", port ); - dbgtext( "socket_addr = %s.\n", - inet_ntoa( sock.sin_addr ) ); - dbgtext( "Error = %s\n", strerror(errno) ); + char addr[INET6_ADDRSTRLEN]; + print_sockaddr(addr, sizeof(addr), + &sock); + dbgtext( "bind failed on port %d ", port); + dbgtext( "socket_addr = %s.\n", addr); + dbgtext( "Error = %s\n", strerror(errno)); } - close( res ); + close(res); return -1; } DEBUG( 10, ( "bind succeeded on port %d\n", port ) ); - return( res ); } @@ -1349,33 +1452,46 @@ int open_socket_in(int type, Create an outgoing socket. timeout is in milliseconds. **************************************************************************/ -int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) +int open_socket_out(int type, + const struct sockaddr_storage *pss, + uint16_t port, + int timeout) { - struct sockaddr_in sock_out; + char addr[INET6_ADDRSTRLEN]; + struct sockaddr_storage sock_out = *pss; int res,ret; int connect_loop = 10; int increment = 10; /* create a socket to write to */ - res = socket(PF_INET, type, 0); + res = socket(pss->ss_family, type, 0); if (res == -1) { DEBUG(0,("socket error (%s)\n", strerror(errno))); return -1; } - if (type != SOCK_STREAM) - return(res); - - memset((char *)&sock_out,'\0',sizeof(sock_out)); - putip((char *)&sock_out.sin_addr,(char *)addr); + if (type != SOCK_STREAM) { + return res; + } - sock_out.sin_port = htons( port ); - sock_out.sin_family = PF_INET; +#if defined(HAVE_IPV6) + if (pss->ss_family == AF_INET6) { + struct sockaddr_in6 *psa6 = (struct sockaddr_in6 *)&sock_out; + psa6->sin6_port = htons(port); + } +#endif + if (pss->ss_family == AF_INET) { + struct sockaddr_in *psa = (struct sockaddr_in *)&sock_out; + psa->sin_port = htons(port); + } /* set it non-blocking */ set_blocking(res,false); - DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port)); + print_sockaddr(addr, sizeof(addr), &sock_out); + DEBUG(3,("Connecting to %s at port %u\n", + addr, + (unsigned int)port)); /* and connect it to the destination */ connect_again: @@ -1397,8 +1513,9 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || errno == EAGAIN)) { - DEBUG(1,("timeout connecting to %s:%d\n", - inet_ntoa(*addr),port)); + DEBUG(1,("timeout connecting to %s:%u\n", + addr, + (unsigned int)port)); close(res); return -1; } @@ -1412,7 +1529,9 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) if (ret < 0) { DEBUG(2,("error connecting to %s:%d (%s)\n", - inet_ntoa(*addr),port,strerror(errno))); + addr, + (unsigned int)port, + strerror(errno))); close(res); return -1; } @@ -1429,7 +1548,7 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) of DC's all of which are equivalent for our purposes. **************************************************************************/ -bool open_any_socket_out(struct sockaddr_in *addrs, int num_addrs, +bool open_any_socket_out(struct sockaddr_storage *addrs, int num_addrs, int timeout, int *fd_index, int *fd) { int i, resulting_index, res; @@ -1455,7 +1574,7 @@ bool open_any_socket_out(struct sockaddr_in *addrs, int num_addrs, sockets[i] = -1; for (i=0; i Date: Thu, 25 Oct 2007 16:14:52 -0700 Subject: When doing reverse lookups actually look up the name, not just the numeric address (doh!) :-). Jeremy. (This used to be commit 9aa9ecd8cc29d055d78f16b8fb2156ec04063c42) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 2d784717b2..8a85f7a5c5 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1879,7 +1879,7 @@ const char *get_peer_name(int fd, bool force_lookup) sizeof(name_buf), NULL, 0, - NI_NUMERICHOST); + 0); if (ret) { DEBUG(1,("get_peer_name: getnameinfo failed " -- cgit From 6128d116b3f09ce0b055d2df89b2f7282185782e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 25 Oct 2007 18:28:36 -0700 Subject: Fix resolve name to resolve IPv6 addresses of link-local%ifaddr Jeremy. (This used to be commit e6609cab732d5cd5cc9a5ae50aee15147f2ec6ec) --- source3/lib/util_sock.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 8a85f7a5c5..c30f21eeb7 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -64,7 +64,7 @@ bool is_ipaddress(const char *str) } /**************************************************************************** - Is a sockaddr_storage a broadcast address ? + Is a sockaddr_storage a broadcast address ? ****************************************************************************/ bool is_broadcast_addr(const struct sockaddr_storage *pss) @@ -1478,6 +1478,10 @@ int open_socket_out(int type, if (pss->ss_family == AF_INET6) { struct sockaddr_in6 *psa6 = (struct sockaddr_in6 *)&sock_out; psa6->sin6_port = htons(port); + if (psa6->sin6_scope_id == 0 && + IN6_IS_ADDR_LINKLOCAL(&psa6->sin6_addr)) { + setup_linklocal_scope_id(&sock_out); + } } #endif if (pss->ss_family == AF_INET) { -- cgit From e054affb7bb3e2aa00663c2d4dfa04c19870ddaf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 25 Oct 2007 19:07:25 -0700 Subject: Fix bug in writing names into gencache as well as 2 typos where AF_INET6 was mistypes as AF_INET. JERRY YOU NEED THESE FIXES. Fixes smbclient -L localhost -U% Bugs reported by Kukks (thanks kukks). Jeremy. (This used to be commit f109f82622ca30ae2360e8300152e90b9587ffd8) --- source3/lib/util_sock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index c30f21eeb7..80d4af8cdb 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -234,7 +234,7 @@ bool is_loopback_ip_v4(struct in_addr ip) bool is_loopback_addr(const struct sockaddr_storage *pss) { #if defined(HAVE_IPV6) - if (pss->ss_family == AF_INET) { + if (pss->ss_family == AF_INET6) { struct in6_addr *pin6 = &((struct sockaddr_in6 *)pss)->sin6_addr; return IN6_IS_ADDR_LOOPBACK(pin6); @@ -265,7 +265,7 @@ bool is_zero_ip_v4(struct in_addr ip) bool is_zero_addr(const struct sockaddr_storage *pss) { #if defined(HAVE_IPV6) - if (pss->ss_family == AF_INET) { + if (pss->ss_family == AF_INET6) { struct in6_addr *pin6 = &((struct sockaddr_in6 *)pss)->sin6_addr; return IN6_IS_ADDR_UNSPECIFIED(pin6); -- cgit From fc91aa6988e93ee5a001781d56699e3c1b9684a7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 26 Oct 2007 16:03:20 -0700 Subject: Move the horrible hack for link local addresses out of namequery.c and into util_sock.c. is_ipaddress() now copes with link:local:v6%ifname addresses, as does interpret_string_addr(). Jeremy (This used to be commit a3f7db3d30ced566c8340696914f1be3293a9c5b) --- source3/lib/util_sock.c | 55 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 4 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 80d4af8cdb..91da407458 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -53,11 +53,27 @@ bool is_ipaddress(const char *str) int ret = -1; #if defined(HAVE_IPV6) - struct in6_addr dest6; + if (strchr_m(str, ':')) { + char addr[INET6_ADDRSTRLEN]; + struct in6_addr dest6; + const char *sp = str; + char *p = strchr_m(str, '%'); - ret = inet_pton(AF_INET6, str, &dest6); - if (ret > 0) { - return true; + /* + * Cope with link-local. + * This is IP:v6:addr%ifname. + */ + + if (p && (p > str) && (if_nametoindex(p+1) != 0)) { + strlcpy(addr, str, + MIN(PTR_DIFF(p,str)+1, + sizeof(addr))); + sp = addr; + } + ret = inet_pton(AF_INET6, addr, &dest6); + if (ret > 0) { + return true; + } } #endif return is_ipaddress_v4(str); @@ -200,7 +216,27 @@ bool interpret_string_addr(struct sockaddr_storage *pss, const char *str, int flags) { + char addr[INET6_ADDRSTRLEN]; struct addrinfo *res = NULL; +#if defined(HAVE_IPV6) + unsigned int scope_id = 0; + + if (strchr_m(str, ':')) { + char *p = strchr_m(str, '%'); + + /* + * Cope with link-local. + * This is IP:v6:addr%ifname. + */ + + if (p && (p > str) && ((scope_id = if_nametoindex(p+1)) != 0)) { + strlcpy(addr, str, + MIN(PTR_DIFF(p,str)+1, + sizeof(addr))); + str = addr; + } + } +#endif zero_addr(pss, AF_INET); @@ -212,6 +248,17 @@ bool interpret_string_addr(struct sockaddr_storage *pss, } /* Copy the first sockaddr. */ memcpy(pss, res->ai_addr, res->ai_addrlen); + +#if defined(HAVE_IPV6) + if (pss->ss_family == AF_INET6 && scope_id) { + struct sockaddr_in6 *ps6 = (struct sockaddr_in6 *)pss; + if (IN6_IS_ADDR_LINKLOCAL(&ps6->sin6_addr) && + ps6->sin6_scope_id == 0) { + ps6->sin6_scope_id = scope_id; + } + } +#endif + freeaddrinfo(res); return true; } -- cgit From d4307679b95088d05f0abad440de5e961ee965df Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 27 Oct 2007 20:29:36 -0700 Subject: Change all occurrences of zero_addr(&ss,AF_INET) to zero_addr(&ss). All current uses were always of the AF_INET form, so simplify the call. If in the future we need to zero an addr to AF_INET6 this can be done separately. Jeremy. (This used to be commit 2e92418a138bf2738b77b7e0fcb2fa37ad84fc0c) --- source3/lib/util_sock.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 91da407458..e66bd5f15a 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -238,7 +238,7 @@ bool interpret_string_addr(struct sockaddr_storage *pss, } #endif - zero_addr(pss, AF_INET); + zero_addr(pss); if (!interpret_string_addr_internal(&res, str, flags|AI_ADDRCONFIG)) { return false; @@ -343,14 +343,14 @@ void zero_ip_v4(struct in_addr *ip) } /******************************************************************* - Set an address to INADDR_ANY, or IN6ADDR_ANY. + Set an address to INADDR_ANY. ******************************************************************/ -void zero_addr(struct sockaddr_storage *pss, int family) +void zero_addr(struct sockaddr_storage *pss) { memset(pss, '\0', sizeof(*pss)); /* Ensure we're at least a valid sockaddr-storage. */ - pss->ss_family = family; + pss->ss_family = AF_INET; } /******************************************************************* -- cgit From c3250149e12338fac5093991b385ad2807c92d1f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 30 Oct 2007 16:22:24 -0700 Subject: Add new parameter, "min receivefile size" (by default set to zero). If non-zero, writeX calls greater than this value will be left in the socket buffer for later handling with recvfile (or userspace equivalent). Definition of recvfile for your system is left as an exercise for the reader (I'm working on getting splice working :-). Jeremy. (This used to be commit 11c03b75ddbcb6e36b231bb40a1773d1c550621c) --- source3/lib/util_sock.c | 106 +----------------------------------------------- 1 file changed, 1 insertion(+), 105 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index e66bd5f15a..bbcbcacb4a 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1113,7 +1113,7 @@ bool send_keepalive(int client) Timeout is in milliseconds. ****************************************************************************/ -static ssize_t read_smb_length_return_keepalive(int fd, +ssize_t read_smb_length_return_keepalive(int fd, char *inbuf, unsigned int timeout) { @@ -1260,86 +1260,6 @@ ssize_t receive_smb_raw(int fd, return len; } -static ssize_t receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd, - char **buffer, unsigned int timeout) -{ - char lenbuf[4]; - ssize_t len,ret; - - smb_read_error = 0; - - len = read_smb_length_return_keepalive(fd, lenbuf, timeout); - if (len < 0) { - DEBUG(10,("receive_smb_raw: length < 0!\n")); - - /* - * Correct fix. smb_read_error may have already been - * set. Only set it here if not already set. Global - * variables still suck :-). JRA. - */ - - if (smb_read_error == 0) - smb_read_error = READ_ERROR; - return -1; - } - - /* - * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes - * of header. Don't print the error if this fits.... JRA. - */ - - if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) { - DEBUG(0,("Invalid packet length! (%lu bytes).\n", - (unsigned long)len)); - if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) { - - /* - * Correct fix. smb_read_error may have already been - * set. Only set it here if not already set. Global - * variables still suck :-). JRA. - */ - - if (smb_read_error == 0) - smb_read_error = READ_ERROR; - return -1; - } - } - - /* - * The +4 here can't wrap, we've checked the length above already. - */ - - *buffer = TALLOC_ARRAY(mem_ctx, char, len+4); - - if (*buffer == NULL) { - DEBUG(0, ("Could not allocate inbuf of length %d\n", - (int)len+4)); - if (smb_read_error == 0) - smb_read_error = READ_ERROR; - return -1; - } - - memcpy(*buffer, lenbuf, sizeof(lenbuf)); - - if(len > 0) { - if (timeout > 0) { - ret = read_socket_with_timeout(fd,(*buffer)+4, len, - len, timeout); - } else { - ret = read_data(fd, (*buffer)+4, len); - } - - if (ret != len) { - if (smb_read_error == 0) { - smb_read_error = READ_ERROR; - } - return -1; - } - } - - return len + 4; -} - /**************************************************************************** Wrapper for receive_smb_raw(). Checks the MAC on signed packets. @@ -1364,30 +1284,6 @@ bool receive_smb(int fd, char *buffer, unsigned int timeout) return true; } -ssize_t receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd, char **buffer, - unsigned int timeout) -{ - ssize_t len; - - len = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout); - - if (len < 0) { - return -1; - } - - /* Check the incoming SMB signature. */ - if (!srv_check_sign_mac(*buffer, true)) { - DEBUG(0, ("receive_smb: SMB Signature verification failed on " - "incoming packet!\n")); - if (smb_read_error == 0) { - smb_read_error = READ_BAD_SIG; - } - return -1; - } - - return len; -} - /**************************************************************************** Send an smb to a fd. ****************************************************************************/ -- cgit From e075b3692bb2c9507231f0662010fc55c1b506c4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 2 Nov 2007 10:25:34 -0700 Subject: Fix Solaris by ensuring we use the IPv4 or IPv6 length in any getnameinfo calls. Jeremy (This used to be commit 4d7badb0c44f287034f58d9a412e662c0fbecdc9) --- source3/lib/util_sock.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index bbcbcacb4a..b4fda54ebd 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -495,7 +495,7 @@ bool is_address_any(const struct sockaddr_storage *psa) Print out an IPv4 or IPv6 address from a struct sockaddr_storage. ****************************************************************************/ -char *print_sockaddr_len(char *dest, +static char *print_sockaddr_len(char *dest, size_t destlen, const struct sockaddr_storage *psa, socklen_t psalen) @@ -503,7 +503,7 @@ char *print_sockaddr_len(char *dest, if (destlen > 0) { dest[0] = '\0'; } - (void)getnameinfo((const struct sockaddr *)psa, + (void)sys_getnameinfo((const struct sockaddr *)psa, psalen, dest, destlen, NULL, 0, @@ -519,7 +519,8 @@ char *print_sockaddr(char *dest, size_t destlen, const struct sockaddr_storage *psa) { - return print_sockaddr_len(dest, destlen, psa, sizeof(*psa)); + return print_sockaddr_len(dest, destlen, psa, + sizeof(struct sockaddr_storage)); } /**************************************************************************** -- cgit From a45c91ec6aff3ff40462258f4527fe4a57991955 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 2 Nov 2007 14:22:19 -0700 Subject: Ensure we use the correct socklen_t values for bind() for Solaris. Jeremy. (This used to be commit 638579d75a2aa00836dc4c0c772381b775944b16) --- source3/lib/util_sock.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index b4fda54ebd..4a73f92bd8 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1325,12 +1325,14 @@ int open_socket_in(int type, { struct sockaddr_storage sock; int res; + socklen_t slen = sizeof(struct sockaddr_in); sock = *psock; #if defined(HAVE_IPV6) if (sock.ss_family == AF_INET6) { ((struct sockaddr_in6 *)&sock)->sin6_port = htons(port); + slen = sizeof(struct sockaddr_in6); } #endif if (sock.ss_family == AF_INET) { @@ -1374,7 +1376,7 @@ int open_socket_in(int type, } /* now we've got a socket - we need to bind it */ - if( bind( res, (struct sockaddr *)&sock, sizeof(sock) ) == -1 ) { + if (bind(res, (struct sockaddr *)&sock, slen) == -1 ) { if( DEBUGLVL(dlevel) && (port == SMB_PORT1 || port == SMB_PORT2 || port == NMB_PORT) ) { char addr[INET6_ADDRSTRLEN]; -- cgit From 73d407968002587eadd0ff13eb413ddf07c78771 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 3 Nov 2007 15:12:42 -0700 Subject: Remove the smb_read_error global variable and replace it with accessor functions. "One global or pstring a day...." :-). Jeremy. (This used to be commit d50d14c300abc83b7015718ec48acc8b3227a273) --- source3/lib/util_sock.c | 59 +++++++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 21 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 4a73f92bd8..ea33de8077 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -673,7 +673,28 @@ int client_socket_port(void) return get_socket_port(client_fd); } -int smb_read_error = 0; +/**************************************************************************** + Accessor functions to make thread-safe code easier later... +****************************************************************************/ + +static enum smb_read_errors smb_read_error = SMB_READ_OK; + +enum smb_read_errors get_smb_read_error(void) +{ + return smb_read_error; +} + +void set_smb_read_error(enum smb_read_errors newerr) +{ + smb_read_error = newerr; +} + +void cond_set_smb_read_error(enum smb_read_errors newerr) +{ + if (smb_read_error == SMB_READ_OK) { + smb_read_error = newerr; + } +} /**************************************************************************** Determine if a file descriptor is in fact a socket. @@ -897,7 +918,7 @@ ssize_t read_socket_with_timeout(int fd, if (maxcnt <= 0) return(0); - smb_read_error = 0; + set_smb_read_error(SMB_READ_OK); /* Blocking read */ if (time_out == 0) { @@ -911,7 +932,7 @@ ssize_t read_socket_with_timeout(int fd, if (readret == 0) { DEBUG(5,("read_socket_with_timeout: " "blocking read. EOF from client.\n")); - smb_read_error = READ_EOF; + set_smb_read_error(SMB_READ_EOF); return -1; } @@ -928,7 +949,7 @@ ssize_t read_socket_with_timeout(int fd, "read error = %s.\n", strerror(errno) )); } - smb_read_error = READ_ERROR; + set_smb_read_error(SMB_READ_ERROR); return -1; } nread += readret; @@ -966,7 +987,7 @@ ssize_t read_socket_with_timeout(int fd, "read. select error = %s.\n", strerror(errno) )); } - smb_read_error = READ_ERROR; + set_smb_read_error(SMB_READ_ERROR); return -1; } @@ -974,7 +995,7 @@ ssize_t read_socket_with_timeout(int fd, if (selrtn == 0) { DEBUG(10,("read_socket_with_timeout: timeout read. " "select timed out.\n")); - smb_read_error = READ_TIMEOUT; + set_smb_read_error(SMB_READ_TIMEOUT); return -1; } @@ -984,7 +1005,7 @@ ssize_t read_socket_with_timeout(int fd, /* we got EOF on the file descriptor */ DEBUG(5,("read_socket_with_timeout: timeout read. " "EOF from client.\n")); - smb_read_error = READ_EOF; + set_smb_read_error(SMB_READ_EOF); return -1; } @@ -1001,7 +1022,7 @@ ssize_t read_socket_with_timeout(int fd, "read. read error = %s.\n", strerror(errno) )); } - smb_read_error = READ_ERROR; + set_smb_read_error(SMB_READ_ERROR); return -1; } @@ -1021,7 +1042,7 @@ ssize_t read_data(int fd,char *buffer,size_t N) ssize_t ret; size_t total=0; - smb_read_error = 0; + set_smb_read_error(SMB_READ_OK); while (total < N) { ret = sys_read(fd,buffer + total,N - total); @@ -1030,7 +1051,7 @@ ssize_t read_data(int fd,char *buffer,size_t N) DEBUG(10,("read_data: read of %d returned 0. " "Error = %s\n", (int)(N - total), strerror(errno) )); - smb_read_error = READ_EOF; + set_smb_read_error(SMB_READ_EOF); return 0; } @@ -1049,7 +1070,7 @@ ssize_t read_data(int fd,char *buffer,size_t N) (int)(N - total), strerror(errno) )); } - smb_read_error = READ_ERROR; + set_smb_read_error(SMB_READ_ERROR); return -1; } total += ret; @@ -1191,7 +1212,7 @@ ssize_t receive_smb_raw(int fd, { ssize_t len,ret; - smb_read_error = 0; + set_smb_read_error(SMB_READ_OK); len = read_smb_length_return_keepalive(fd,buffer,timeout); if (len < 0) { @@ -1203,8 +1224,7 @@ ssize_t receive_smb_raw(int fd, * variables still suck :-). JRA. */ - if (smb_read_error == 0) - smb_read_error = READ_ERROR; + cond_set_smb_read_error(SMB_READ_ERROR); return -1; } @@ -1224,8 +1244,7 @@ ssize_t receive_smb_raw(int fd, * variables still suck :-). JRA. */ - if (smb_read_error == 0) - smb_read_error = READ_ERROR; + cond_set_smb_read_error(SMB_READ_ERROR); return -1; } } @@ -1246,9 +1265,7 @@ ssize_t receive_smb_raw(int fd, } if (ret != len) { - if (smb_read_error == 0) { - smb_read_error = READ_ERROR; - } + cond_set_smb_read_error(SMB_READ_ERROR); return -1; } @@ -1276,8 +1293,8 @@ bool receive_smb(int fd, char *buffer, unsigned int timeout) if (!srv_check_sign_mac(buffer, true)) { DEBUG(0, ("receive_smb: SMB Signature verification " "failed on incoming packet!\n")); - if (smb_read_error == 0) { - smb_read_error = READ_BAD_SIG; + if (get_smb_read_error() == 0) { + smb_read_error = SMB_READ_BAD_SIG; } return false; } -- cgit From 6658165d5e9cd186fea74e1581091233e8990e9b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 3 Nov 2007 18:15:45 -0700 Subject: Stop get_peer_addr() and client_addr() from using global statics. Part of my library cleanups. Jeremy. (This used to be commit e848506c858bd16706c1d7f6b4b032005512b8ac) --- source3/lib/util_sock.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index ea33de8077..b1e508182d 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -587,9 +587,10 @@ char *print_canonical_sockaddr(TALLOC_CTX *ctx, void client_setfd(int fd) { + char addr[INET6_ADDRSTRLEN]; client_fd = fd; safe_strcpy(client_ip_string, - get_peer_addr(client_fd), + get_peer_addr(client_fd,addr), sizeof(client_ip_string)-1); } @@ -658,9 +659,9 @@ const char *client_name(void) return get_peer_name(client_fd,false); } -const char *client_addr(void) +const char *client_addr(char addr[INET6_ADDRSTRLEN]) { - return get_peer_addr(client_fd); + return get_peer_addr(client_fd,addr); } const char *client_socket_addr(void) @@ -1699,12 +1700,12 @@ int open_udp_socket(const char *host, int port) ******************************************************************/ static const char *get_peer_addr_internal(int fd, + char addr_buf[INET6_ADDRSTRLEN], struct sockaddr_storage *pss, socklen_t *plength) { struct sockaddr_storage ss; socklen_t length = sizeof(ss); - static char addr_buf[INET6_ADDRSTRLEN]; safe_strcpy(addr_buf,"0.0.0.0",sizeof(addr_buf)-1); @@ -1732,7 +1733,6 @@ static const char *get_peer_addr_internal(int fd, return addr_buf; } - /******************************************************************* Matchname - determine if host name matches IP address. Used to confirm a hostname lookup to prevent spoof attacks. @@ -1807,10 +1807,12 @@ static bool matchname(const char *remotehost, Return the DNS name of the remote end of a socket. ******************************************************************/ +static char addr_buf_cache[INET6_ADDRSTRLEN]; + const char *get_peer_name(int fd, bool force_lookup) { - static fstring addr_buf; static pstring name_buf; + char addr_buf[INET6_ADDRSTRLEN]; struct sockaddr_storage ss; socklen_t length = sizeof(ss); const char *p; @@ -1822,13 +1824,14 @@ const char *get_peer_name(int fd, bool force_lookup) with dns. To avoid the delay we avoid the lookup if possible */ if (!lp_hostname_lookups() && (force_lookup == false)) { - return get_peer_addr(fd); + pstrcpy(name_buf, get_peer_addr(fd, addr_buf)); + return name_buf; } - p = get_peer_addr_internal(fd, &ss, &length); + p = get_peer_addr_internal(fd, addr_buf, &ss, &length); /* it might be the same as the last one - save some DNS work */ - if (strcmp(p, addr_buf) == 0) { + if (strcmp(p, addr_buf_cache) == 0) { return name_buf; } @@ -1837,7 +1840,7 @@ const char *get_peer_name(int fd, bool force_lookup) return name_buf; } - fstrcpy(addr_buf, p); + safe_strcpy(addr_buf_cache, p, sizeof(addr_buf_cache)-1); /* Look up the remote host name. */ ret = getnameinfo((struct sockaddr *)&ss, @@ -1878,9 +1881,9 @@ const char *get_peer_name(int fd, bool force_lookup) Return the IP addr of the remote end of a socket as a string. ******************************************************************/ -const char *get_peer_addr(int fd) +const char *get_peer_addr(int fd, char addr[INET6_ADDRSTRLEN]) { - return get_peer_addr_internal(fd, NULL, NULL); + return get_peer_addr_internal(fd, addr, NULL, NULL); } /******************************************************************* -- cgit From 25074433f412c4dd2531fd268d51be8753ddc11b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 3 Nov 2007 18:41:26 -0700 Subject: I can't get away without a 'length' arg. :-). Jeremy. (This used to be commit 95d01279a5def709d0a5d5ae7224d6286006d120) --- source3/lib/util_sock.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index b1e508182d..5422bc2180 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -590,7 +590,7 @@ void client_setfd(int fd) char addr[INET6_ADDRSTRLEN]; client_fd = fd; safe_strcpy(client_ip_string, - get_peer_addr(client_fd,addr), + get_peer_addr(client_fd,addr,sizeof(addr)), sizeof(client_ip_string)-1); } @@ -659,9 +659,9 @@ const char *client_name(void) return get_peer_name(client_fd,false); } -const char *client_addr(char addr[INET6_ADDRSTRLEN]) +const char *client_addr(char *addr, size_t addrlen) { - return get_peer_addr(client_fd,addr); + return get_peer_addr(client_fd,addr,addrlen); } const char *client_socket_addr(void) @@ -1700,14 +1700,15 @@ int open_udp_socket(const char *host, int port) ******************************************************************/ static const char *get_peer_addr_internal(int fd, - char addr_buf[INET6_ADDRSTRLEN], + char *addr_buf, + size_t addr_buf_len, struct sockaddr_storage *pss, socklen_t *plength) { struct sockaddr_storage ss; socklen_t length = sizeof(ss); - safe_strcpy(addr_buf,"0.0.0.0",sizeof(addr_buf)-1); + safe_strcpy(addr_buf,"0.0.0.0",addr_buf_len-1); if (fd == -1) { return addr_buf; @@ -1824,11 +1825,11 @@ const char *get_peer_name(int fd, bool force_lookup) with dns. To avoid the delay we avoid the lookup if possible */ if (!lp_hostname_lookups() && (force_lookup == false)) { - pstrcpy(name_buf, get_peer_addr(fd, addr_buf)); + pstrcpy(name_buf, get_peer_addr(fd, addr_buf, sizeof(addr_buf))); return name_buf; } - p = get_peer_addr_internal(fd, addr_buf, &ss, &length); + p = get_peer_addr_internal(fd, addr_buf, sizeof(addr_buf), &ss, &length); /* it might be the same as the last one - save some DNS work */ if (strcmp(p, addr_buf_cache) == 0) { @@ -1881,9 +1882,9 @@ const char *get_peer_name(int fd, bool force_lookup) Return the IP addr of the remote end of a socket as a string. ******************************************************************/ -const char *get_peer_addr(int fd, char addr[INET6_ADDRSTRLEN]) +const char *get_peer_addr(int fd, char *addr, size_t addr_len) { - return get_peer_addr_internal(fd, addr, NULL, NULL); + return get_peer_addr_internal(fd, addr, addr_len, NULL, NULL); } /******************************************************************* -- cgit From 56aa420195f4bf8007fbbbe362dbaf961a97f423 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 3 Nov 2007 20:27:59 -0700 Subject: Missed one case where I need to pass down addrlen. Jeremy (This used to be commit 62b5ca3334598aec3304d21118f67702afc3854a) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 5422bc2180..3cce12381c 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1728,7 +1728,7 @@ static const char *get_peer_addr_internal(int fd, } print_sockaddr_len(addr_buf, - sizeof(addr_buf), + addr_buf_len, pss, *plength); return addr_buf; -- cgit From 51a0354d751f48a2542984c81e218da33669bbeb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 3 Nov 2007 22:34:46 -0700 Subject: Remove more static data from lib/util_sock.c and callers. Jeremy. (This used to be commit 35aaa36f82c70964cee5d0778eb04547b226dd3f) --- source3/lib/util_sock.c | 58 ++++++++++++++++++++----------------------------- 1 file changed, 24 insertions(+), 34 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 3cce12381c..b31736430e 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -199,12 +199,11 @@ uint32 interpret_addr(const char *str) A convenient addition to interpret_addr(). ******************************************************************/ -struct in_addr *interpret_addr2(const char *str) +struct in_addr *interpret_addr2(struct in_addr *ip, const char *str) { - static struct in_addr ret; uint32 a = interpret_addr(str); - ret.s_addr = a; - return(&ret); + ip->s_addr = a; + return ip; } /******************************************************************* @@ -331,15 +330,7 @@ bool is_zero_addr(const struct sockaddr_storage *pss) void zero_ip_v4(struct in_addr *ip) { - static bool init; - static struct in_addr ipzero; - - if (!init) { - ipzero = *interpret_addr2("0.0.0.0"); - init = true; - } - - *ip = ipzero; + memset(ip, '\0', sizeof(struct in_addr)); } /******************************************************************* @@ -595,21 +586,20 @@ void client_setfd(int fd) } /**************************************************************************** - Return a static string of an IP address (IPv4 or IPv6). + Return the string of an IP address (IPv4 or IPv6). ****************************************************************************/ -static const char *get_socket_addr(int fd) +static const char *get_socket_addr(int fd, char *addr_buf, size_t addr_len) { struct sockaddr_storage sa; socklen_t length = sizeof(sa); - static char addr_buf[INET6_ADDRSTRLEN]; /* Ok, returning a hard coded IPv4 address * is bogus, but it's just as bogus as a * zero IPv6 address. No good choice here. */ - safe_strcpy(addr_buf, "0.0.0.0", sizeof(addr_buf)-1); + safe_strcpy(addr_buf, "0.0.0.0", addr_len-1); if (fd == -1) { return addr_buf; @@ -621,7 +611,7 @@ static const char *get_socket_addr(int fd) return addr_buf; } - return print_sockaddr_len(addr_buf, sizeof(addr_buf), &sa, length); + return print_sockaddr_len(addr_buf, addr_len, &sa, length); } /**************************************************************************** @@ -664,9 +654,9 @@ const char *client_addr(char *addr, size_t addrlen) return get_peer_addr(client_fd,addr,addrlen); } -const char *client_socket_addr(void) +const char *client_socket_addr(char *addr, size_t addr_len) { - return get_socket_addr(client_fd); + return get_socket_addr(client_fd, addr, addr_len); } int client_socket_port(void) @@ -1672,9 +1662,9 @@ int open_udp_socket(const char *host, int port) int type = SOCK_DGRAM; struct sockaddr_in sock_out; int res; - struct in_addr *addr; + struct in_addr addr; - addr = interpret_addr2(host); + (void)interpret_addr2(&addr, host); res = socket(PF_INET, type, 0); if (res == -1) { @@ -1682,7 +1672,7 @@ int open_udp_socket(const char *host, int port) } memset((char *)&sock_out,'\0',sizeof(sock_out)); - putip((char *)&sock_out.sin_addr,(char *)addr); + putip((char *)&sock_out.sin_addr,(char *)&addr); sock_out.sin_port = htons(port); sock_out.sin_family = PF_INET; @@ -1987,32 +1977,32 @@ out_umask: Get my own canonical name, including domain. ****************************************************************************/ +static fstring dnshostname_cache; + bool get_mydnsfullname(fstring my_dnsname) { - static fstring dnshostname; - - if (!*dnshostname) { + if (!*dnshostname_cache) { struct addrinfo *res = NULL; bool ret; /* get my host name */ - if (gethostname(dnshostname, sizeof(dnshostname)) == -1) { - *dnshostname = '\0'; + if (gethostname(dnshostname_cache, sizeof(dnshostname_cache)) == -1) { + *dnshostname_cache = '\0'; DEBUG(0,("get_mydnsfullname: gethostname failed\n")); return false; } /* Ensure null termination. */ - dnshostname[sizeof(dnshostname)-1] = '\0'; + dnshostname_cache[sizeof(dnshostname_cache)-1] = '\0'; ret = interpret_string_addr_internal(&res, - dnshostname, + dnshostname_cache, AI_ADDRCONFIG|AI_CANONNAME); if (!ret || res == NULL) { DEBUG(3,("get_mydnsfullname: getaddrinfo failed for " "name %s [%s]\n", - dnshostname, + dnshostname_cache, gai_strerror(ret) )); return false; } @@ -2024,16 +2014,16 @@ bool get_mydnsfullname(fstring my_dnsname) if (res->ai_canonname == NULL) { DEBUG(3,("get_mydnsfullname: failed to get " "canonical name for %s\n", - dnshostname)); + dnshostname_cache)); freeaddrinfo(res); return false; } - fstrcpy(dnshostname, res->ai_canonname); + fstrcpy(dnshostname_cache, res->ai_canonname); freeaddrinfo(res); } - fstrcpy(my_dnsname, dnshostname); + fstrcpy(my_dnsname, dnshostname_cache); return true; } -- cgit From 5b0b4f23ef5fec3d1ad518237f973d4e014b5766 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 3 Nov 2007 23:20:10 -0700 Subject: Remove most of the remaining globals out of lib/util_sock.c. I have a plan for dealing with the remaining..... Watch this space. Jeremy. (This used to be commit 963fc7685212689f02b3adcc05b4273ee5c382d4) --- source3/lib/util_sock.c | 68 ++++++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 38 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index b31736430e..4b39e32115 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -21,13 +21,6 @@ #include "includes.h" -/* the following 3 client_*() functions are nasty ways of allowing - some generic functions to get info that really should be hidden in - particular modules */ -static int client_fd = -1; -/* What to print out on a client disconnect error. */ -static char client_ip_string[INET6_ADDRSTRLEN]; - /**************************************************************************** Return true if a string could be an IPv4 address. ****************************************************************************/ @@ -572,19 +565,6 @@ char *print_canonical_sockaddr(TALLOC_CTX *ctx, return dest; } -/**************************************************************************** - Set the global client_fd variable. -****************************************************************************/ - -void client_setfd(int fd) -{ - char addr[INET6_ADDRSTRLEN]; - client_fd = fd; - safe_strcpy(client_ip_string, - get_peer_addr(client_fd,addr,sizeof(addr)), - sizeof(client_ip_string)-1); -} - /**************************************************************************** Return the string of an IP address (IPv4 or IPv6). ****************************************************************************/ @@ -614,6 +594,8 @@ static const char *get_socket_addr(int fd, char *addr_buf, size_t addr_len) return print_sockaddr_len(addr_buf, addr_len, &sa, length); } +#if 0 +/* Not currently used. JRA. */ /**************************************************************************** Return the port number we've bound to on a socket. ****************************************************************************/ @@ -643,26 +625,30 @@ static int get_socket_port(int fd) } return -1; } +#endif -const char *client_name(void) +const char *client_name(int fd) { - return get_peer_name(client_fd,false); + return get_peer_name(fd,false); } -const char *client_addr(char *addr, size_t addrlen) +const char *client_addr(int fd, char *addr, size_t addrlen) { - return get_peer_addr(client_fd,addr,addrlen); + return get_peer_addr(fd,addr,addrlen); } -const char *client_socket_addr(char *addr, size_t addr_len) +const char *client_socket_addr(int fd, char *addr, size_t addr_len) { - return get_socket_addr(client_fd, addr, addr_len); + return get_socket_addr(fd, addr, addr_len); } -int client_socket_port(void) +#if 0 +/* Not currently used. JRA. */ +int client_socket_port(int fd) { - return get_socket_port(client_fd); + return get_socket_port(fd); } +#endif /**************************************************************************** Accessor functions to make thread-safe code easier later... @@ -904,6 +890,7 @@ ssize_t read_socket_with_timeout(int fd, ssize_t readret; size_t nread = 0; struct timeval timeout; + char addr[INET6_ADDRSTRLEN]; /* just checking .... */ if (maxcnt <= 0) @@ -928,12 +915,12 @@ ssize_t read_socket_with_timeout(int fd, } if (readret == -1) { - if (fd == client_fd) { + if (fd == get_client_fd()) { /* Try and give an error message * saying what client failed. */ DEBUG(0,("read_socket_with_timeout: " "client %s read error = %s.\n", - client_ip_string, + get_peer_addr(fd,addr,sizeof(addr)), strerror(errno) )); } else { DEBUG(0,("read_socket_with_timeout: " @@ -967,12 +954,13 @@ ssize_t read_socket_with_timeout(int fd, /* Check if error */ if (selrtn == -1) { /* something is wrong. Maybe the socket is dead? */ - if (fd == client_fd) { + if (fd == get_client_fd()) { /* Try and give an error message saying * what client failed. */ DEBUG(0,("read_socket_with_timeout: timeout " "read for client %s. select error = %s.\n", - client_ip_string, strerror(errno) )); + get_peer_addr(fd,addr,sizeof(addr)), + strerror(errno) )); } else { DEBUG(0,("read_socket_with_timeout: timeout " "read. select error = %s.\n", @@ -1002,12 +990,13 @@ ssize_t read_socket_with_timeout(int fd, if (readret == -1) { /* the descriptor is probably dead */ - if (fd == client_fd) { + if (fd == get_client_fd()) { /* Try and give an error message * saying what client failed. */ DEBUG(0,("read_socket_with_timeout: timeout " "read to client %s. read error = %s.\n", - client_ip_string, strerror(errno) )); + get_peer_addr(fd,addr,sizeof(addr)), + strerror(errno) )); } else { DEBUG(0,("read_socket_with_timeout: timeout " "read. read error = %s.\n", @@ -1032,6 +1021,7 @@ ssize_t read_data(int fd,char *buffer,size_t N) { ssize_t ret; size_t total=0; + char addr[INET6_ADDRSTRLEN]; set_smb_read_error(SMB_READ_OK); @@ -1047,13 +1037,13 @@ ssize_t read_data(int fd,char *buffer,size_t N) } if (ret == -1) { - if (fd == client_fd) { + if (fd == get_client_fd()) { /* Try and give an error message saying * what client failed. */ DEBUG(0,("read_data: read failure for %d " "bytes to client %s. Error = %s\n", (int)(N - total), - client_ip_string, + get_peer_addr(fd,addr,sizeof(addr)), strerror(errno) )); } else { DEBUG(0,("read_data: read failure for %d. " @@ -1077,17 +1067,19 @@ ssize_t write_data(int fd, const char *buffer, size_t N) { size_t total=0; ssize_t ret; + char addr[INET6_ADDRSTRLEN]; while (total < N) { ret = sys_write(fd,buffer + total,N - total); if (ret == -1) { - if (fd == client_fd) { + if (fd == get_client_fd()) { /* Try and give an error message saying * what client failed. */ DEBUG(0,("write_data: write failure in " "writing to client %s. Error %s\n", - client_ip_string, strerror(errno) )); + get_peer_addr(fd,addr,sizeof(addr)), + strerror(errno) )); } else { DEBUG(0,("write_data: write failure. " "Error = %s\n", strerror(errno) )); -- cgit From 85ff0b2d75c54a369256f4d1fd198568697b803d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 4 Nov 2007 22:12:31 -0800 Subject: Don't use 0 when we mean SMB_READ_OK. Jeremy. (This used to be commit 08ee4314a9e25700288f4ea1af22ee1732dfea61) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 4b39e32115..ea0bf281ad 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1276,7 +1276,7 @@ bool receive_smb(int fd, char *buffer, unsigned int timeout) if (!srv_check_sign_mac(buffer, true)) { DEBUG(0, ("receive_smb: SMB Signature verification " "failed on incoming packet!\n")); - if (get_smb_read_error() == 0) { + if (get_smb_read_error() == SMB_READ_OK) { smb_read_error = SMB_READ_BAD_SIG; } return false; -- cgit From 6a2a27076ff298d747038d4feaf288b263ba31f5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 4 Nov 2007 22:14:19 -0800 Subject: This should really be a cond_set_smb_read_error(). Jeremy. (This used to be commit 5ab76b58c00dde89b56060482f5cdc5d0c6c56cb) --- source3/lib/util_sock.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index ea0bf281ad..d87d954536 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1276,9 +1276,7 @@ bool receive_smb(int fd, char *buffer, unsigned int timeout) if (!srv_check_sign_mac(buffer, true)) { DEBUG(0, ("receive_smb: SMB Signature verification " "failed on incoming packet!\n")); - if (get_smb_read_error() == SMB_READ_OK) { - smb_read_error = SMB_READ_BAD_SIG; - } + cond_set_smb_read_error(SMB_READ_BAD_SIG); return false; } -- cgit From 536a9e79222e3e49514386feae30470cdd171871 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 4 Nov 2007 22:20:04 -0800 Subject: Don't alloc struct iface_struct nics[MAX_INTERFACES]; (128 entries) on the stack - use talloc. Jeremy (This used to be commit b5e37af251a26648b0e4f59ca548c5374399175e) --- source3/lib/util_sock.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index d87d954536..02097239cf 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -2082,7 +2082,7 @@ bool is_myname_or_ipaddr(const char *s) /* Maybe its an IP address? */ if (is_ipaddress(servername)) { struct sockaddr_storage ss; - struct iface_struct nics[MAX_INTERFACES]; + struct iface_struct *nics; int i, n; if (!interpret_string_addr(&ss, servername, AI_NUMERICHOST)) { @@ -2093,12 +2093,19 @@ bool is_myname_or_ipaddr(const char *s) return false; } + nics = TALLOC_ARRAY(talloc_tos(), struct iface_struct, + MAX_INTERFACES); + if (!nics) { + return false; + } n = get_interfaces(nics, MAX_INTERFACES); for (i=0; i Date: Mon, 5 Nov 2007 11:12:56 -0800 Subject: Remove the horror that was the global smb_rw_error. Each cli struct has it's own local copy of this variable, so use that in client code. In the smbd server, add one static to smbd/proccess.c and use that inside smbd. Fix a bunch of places where smb_rw_error could be set by calling read_data() in places where we weren't reading from the SMB client socket (ie. winbindd). Jeremy. (This used to be commit 255c2adf7b6ef30932b5bb9f142ccef4a5d3d0db) --- source3/lib/util_sock.c | 87 +++++++++++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 43 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 02097239cf..4a870b71b3 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -654,22 +654,19 @@ int client_socket_port(int fd) Accessor functions to make thread-safe code easier later... ****************************************************************************/ -static enum smb_read_errors smb_read_error = SMB_READ_OK; - -enum smb_read_errors get_smb_read_error(void) -{ - return smb_read_error; -} - -void set_smb_read_error(enum smb_read_errors newerr) +void set_smb_read_error(enum smb_read_errors *pre, + enum smb_read_errors newerr) { - smb_read_error = newerr; + if (pre) { + *pre = newerr; + } } -void cond_set_smb_read_error(enum smb_read_errors newerr) +void cond_set_smb_read_error(enum smb_read_errors *pre, + enum smb_read_errors newerr) { - if (smb_read_error == SMB_READ_OK) { - smb_read_error = newerr; + if (pre && *pre == SMB_READ_OK) { + *pre = newerr; } } @@ -883,7 +880,8 @@ ssize_t read_socket_with_timeout(int fd, char *buf, size_t mincnt, size_t maxcnt, - unsigned int time_out) + unsigned int time_out, + enum smb_read_errors *pre) { fd_set fds; int selrtn; @@ -896,7 +894,7 @@ ssize_t read_socket_with_timeout(int fd, if (maxcnt <= 0) return(0); - set_smb_read_error(SMB_READ_OK); + set_smb_read_error(pre,SMB_READ_OK); /* Blocking read */ if (time_out == 0) { @@ -910,7 +908,7 @@ ssize_t read_socket_with_timeout(int fd, if (readret == 0) { DEBUG(5,("read_socket_with_timeout: " "blocking read. EOF from client.\n")); - set_smb_read_error(SMB_READ_EOF); + set_smb_read_error(pre,SMB_READ_EOF); return -1; } @@ -927,7 +925,7 @@ ssize_t read_socket_with_timeout(int fd, "read error = %s.\n", strerror(errno) )); } - set_smb_read_error(SMB_READ_ERROR); + set_smb_read_error(pre,SMB_READ_ERROR); return -1; } nread += readret; @@ -966,7 +964,7 @@ ssize_t read_socket_with_timeout(int fd, "read. select error = %s.\n", strerror(errno) )); } - set_smb_read_error(SMB_READ_ERROR); + set_smb_read_error(pre,SMB_READ_ERROR); return -1; } @@ -974,7 +972,7 @@ ssize_t read_socket_with_timeout(int fd, if (selrtn == 0) { DEBUG(10,("read_socket_with_timeout: timeout read. " "select timed out.\n")); - set_smb_read_error(SMB_READ_TIMEOUT); + set_smb_read_error(pre,SMB_READ_TIMEOUT); return -1; } @@ -984,7 +982,7 @@ ssize_t read_socket_with_timeout(int fd, /* we got EOF on the file descriptor */ DEBUG(5,("read_socket_with_timeout: timeout read. " "EOF from client.\n")); - set_smb_read_error(SMB_READ_EOF); + set_smb_read_error(pre,SMB_READ_EOF); return -1; } @@ -1002,7 +1000,7 @@ ssize_t read_socket_with_timeout(int fd, "read. read error = %s.\n", strerror(errno) )); } - set_smb_read_error(SMB_READ_ERROR); + set_smb_read_error(pre,SMB_READ_ERROR); return -1; } @@ -1017,13 +1015,13 @@ ssize_t read_socket_with_timeout(int fd, Read data from the client, reading exactly N bytes. ****************************************************************************/ -ssize_t read_data(int fd,char *buffer,size_t N) +ssize_t read_data(int fd,char *buffer,size_t N, enum smb_read_errors *pre) { ssize_t ret; size_t total=0; char addr[INET6_ADDRSTRLEN]; - set_smb_read_error(SMB_READ_OK); + set_smb_read_error(pre,SMB_READ_OK); while (total < N) { ret = sys_read(fd,buffer + total,N - total); @@ -1032,7 +1030,7 @@ ssize_t read_data(int fd,char *buffer,size_t N) DEBUG(10,("read_data: read of %d returned 0. " "Error = %s\n", (int)(N - total), strerror(errno) )); - set_smb_read_error(SMB_READ_EOF); + set_smb_read_error(pre,SMB_READ_EOF); return 0; } @@ -1051,7 +1049,7 @@ ssize_t read_data(int fd,char *buffer,size_t N) (int)(N - total), strerror(errno) )); } - set_smb_read_error(SMB_READ_ERROR); + set_smb_read_error(pre,SMB_READ_ERROR); return -1; } total += ret; @@ -1119,8 +1117,9 @@ bool send_keepalive(int client) ****************************************************************************/ ssize_t read_smb_length_return_keepalive(int fd, - char *inbuf, - unsigned int timeout) + char *inbuf, + unsigned int timeout, + enum smb_read_errors *pre) { ssize_t len=0; int msg_type; @@ -1128,10 +1127,10 @@ ssize_t read_smb_length_return_keepalive(int fd, while (!ok) { if (timeout > 0) { - ok = (read_socket_with_timeout(fd,inbuf,4,4,timeout) - == 4); + ok = (read_socket_with_timeout(fd,inbuf,4,4, + timeout,pre) == 4); } else { - ok = (read_data(fd,inbuf,4) == 4); + ok = (read_data(fd,inbuf,4,pre) == 4); } if (!ok) { return -1; @@ -1147,7 +1146,7 @@ ssize_t read_smb_length_return_keepalive(int fd, DEBUG(10,("got smb length of %lu\n",(unsigned long)len)); - return(len); + return len; } /**************************************************************************** @@ -1157,12 +1156,12 @@ ssize_t read_smb_length_return_keepalive(int fd, Timeout is in milliseconds. ****************************************************************************/ -ssize_t read_smb_length(int fd, char *inbuf, unsigned int timeout) +ssize_t read_smb_length(int fd, char *inbuf, unsigned int timeout, enum smb_read_errors *pre) { ssize_t len; for(;;) { - len = read_smb_length_return_keepalive(fd, inbuf, timeout); + len = read_smb_length_return_keepalive(fd, inbuf, timeout, pre); if(len < 0) return len; @@ -1191,13 +1190,14 @@ ssize_t read_smb_length(int fd, char *inbuf, unsigned int timeout) ssize_t receive_smb_raw(int fd, char *buffer, unsigned int timeout, - size_t maxlen) + size_t maxlen, + enum smb_read_errors *pre) { ssize_t len,ret; - set_smb_read_error(SMB_READ_OK); + set_smb_read_error(pre,SMB_READ_OK); - len = read_smb_length_return_keepalive(fd,buffer,timeout); + len = read_smb_length_return_keepalive(fd,buffer,timeout,pre); if (len < 0) { DEBUG(10,("receive_smb_raw: length < 0!\n")); @@ -1207,7 +1207,7 @@ ssize_t receive_smb_raw(int fd, * variables still suck :-). JRA. */ - cond_set_smb_read_error(SMB_READ_ERROR); + cond_set_smb_read_error(pre,SMB_READ_ERROR); return -1; } @@ -1227,7 +1227,7 @@ ssize_t receive_smb_raw(int fd, * variables still suck :-). JRA. */ - cond_set_smb_read_error(SMB_READ_ERROR); + cond_set_smb_read_error(pre,SMB_READ_ERROR); return -1; } } @@ -1242,13 +1242,14 @@ ssize_t receive_smb_raw(int fd, buffer+4, len, len, - timeout); + timeout, + pre); } else { - ret = read_data(fd,buffer+4,len); + ret = read_data(fd,buffer+4,len,pre); } if (ret != len) { - cond_set_smb_read_error(SMB_READ_ERROR); + cond_set_smb_read_error(pre,SMB_READ_ERROR); return -1; } @@ -1266,9 +1267,9 @@ ssize_t receive_smb_raw(int fd, Checks the MAC on signed packets. ****************************************************************************/ -bool receive_smb(int fd, char *buffer, unsigned int timeout) +bool receive_smb(int fd, char *buffer, unsigned int timeout, enum smb_read_errors *pre) { - if (receive_smb_raw(fd, buffer, timeout, 0) < 0) { + if (receive_smb_raw(fd, buffer, timeout, 0, pre) < 0) { return false; } @@ -1276,7 +1277,7 @@ bool receive_smb(int fd, char *buffer, unsigned int timeout) if (!srv_check_sign_mac(buffer, true)) { DEBUG(0, ("receive_smb: SMB Signature verification " "failed on incoming packet!\n")); - cond_set_smb_read_error(SMB_READ_BAD_SIG); + cond_set_smb_read_error(pre,SMB_READ_BAD_SIG); return false; } -- cgit From e501c0cd44116ee6e42c14100fea526558c37cb2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 7 Nov 2007 12:48:58 -0800 Subject: Unify the name and addr cache for client_name to make threading easier ultimately. Jeremy. (This used to be commit 48e0725cd6bb976ca799e6b8464c94aeffb1672b) --- source3/lib/util_sock.c | 52 +++++++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 21 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 4a870b71b3..bd6fdbb105 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -579,7 +579,7 @@ static const char *get_socket_addr(int fd, char *addr_buf, size_t addr_len) * zero IPv6 address. No good choice here. */ - safe_strcpy(addr_buf, "0.0.0.0", addr_len-1); + strlcpy(addr_buf, "0.0.0.0", addr_len); if (fd == -1) { return addr_buf; @@ -1689,7 +1689,7 @@ static const char *get_peer_addr_internal(int fd, struct sockaddr_storage ss; socklen_t length = sizeof(ss); - safe_strcpy(addr_buf,"0.0.0.0",addr_buf_len-1); + strlcpy(addr_buf,"0.0.0.0",addr_buf_len); if (fd == -1) { return addr_buf; @@ -1785,45 +1785,54 @@ static bool matchname(const char *remotehost, return false; } +static struct { + struct sockaddr_storage ss; + char *name; +} nc; + /******************************************************************* Return the DNS name of the remote end of a socket. ******************************************************************/ -static char addr_buf_cache[INET6_ADDRSTRLEN]; - -const char *get_peer_name(int fd, bool force_lookup) +const char *get_peer_name(int fd, + bool force_lookup) { - static pstring name_buf; char addr_buf[INET6_ADDRSTRLEN]; struct sockaddr_storage ss; socklen_t length = sizeof(ss); const char *p; int ret; - pstring tmp_name; + char name_buf[HOST_NAME_MAX]; + char tmp_name[HOST_NAME_MAX]; /* reverse lookups can be *very* expensive, and in many situations won't work because many networks don't link dhcp with dns. To avoid the delay we avoid the lookup if possible */ if (!lp_hostname_lookups() && (force_lookup == false)) { - pstrcpy(name_buf, get_peer_addr(fd, addr_buf, sizeof(addr_buf))); - return name_buf; + length = sizeof(nc.ss); + p = get_peer_addr_internal(fd, addr_buf, sizeof(addr_buf), + &nc.ss, &length); + SAFE_FREE(nc.name); + nc.name = SMB_STRDUP(p); + return nc.name ? nc.name : "UNKNOWN"; } + memset(&ss, '\0', sizeof(ss)); p = get_peer_addr_internal(fd, addr_buf, sizeof(addr_buf), &ss, &length); /* it might be the same as the last one - save some DNS work */ - if (strcmp(p, addr_buf_cache) == 0) { - return name_buf; + if (addr_equal(&ss, &nc.ss)) { + return nc.name ? nc.name : "UNKNOWN"; } - pstrcpy(name_buf,"UNKNOWN"); + /* Not the same. Reset the cache. */ + zero_addr(&nc.ss); + SAFE_FREE(nc.name); if (fd == -1) { - return name_buf; + return "UNKNOWN"; } - safe_strcpy(addr_buf_cache, p, sizeof(addr_buf_cache)-1); - /* Look up the remote host name. */ ret = getnameinfo((struct sockaddr *)&ss, length, @@ -1838,11 +1847,11 @@ const char *get_peer_name(int fd, bool force_lookup) "for %s with error %s\n", p, gai_strerror(ret))); - pstrcpy(name_buf, p); + strlcpy(name_buf, p, sizeof(name_buf)); } else { if (!matchname(name_buf, &ss, length)) { DEBUG(0,("Matchname failed on %s %s\n",name_buf,p)); - pstrcpy(name_buf,"UNKNOWN"); + strlcpy(name_buf,"UNKNOWN",sizeof(name_buf)); } } @@ -1850,13 +1859,14 @@ const char *get_peer_name(int fd, bool force_lookup) use --enable-developer or the clobber_region() call will get you */ - pstrcpy(tmp_name, name_buf ); + strlcpy(tmp_name, name_buf, sizeof(tmp_name)); alpha_strcpy(name_buf, tmp_name, "_-.", sizeof(name_buf)); if (strstr(name_buf,"..")) { - pstrcpy(name_buf, "UNKNOWN"); + strlcpy(name_buf, "UNKNOWN", sizeof(name_buf)); } - return name_buf; + nc.name = SMB_STRDUP(name_buf); + return nc.name ? nc.name : "UNKNOWN"; } /******************************************************************* @@ -1934,7 +1944,7 @@ int create_pipe_sock(const char *socket_dir, unlink(path); memset(&sunaddr, 0, sizeof(sunaddr)); sunaddr.sun_family = AF_UNIX; - safe_strcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)-1); + strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)); if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) { DEBUG(0, ("bind failed on pipe socket %s: %s\n", path, -- cgit From d40e47db4b5da41c8604a2058f3a0b0a82164f08 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 8 Nov 2007 17:25:45 -0800 Subject: Remove more fstring/pstring bad useage. Go talloc ! Jeremy. (This used to be commit 2a0173743d2cf615d52278f3dd87cc804abe2d16) --- source3/lib/util_sock.c | 52 +++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 25 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index bd6fdbb105..66da297dc7 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1978,34 +1978,34 @@ out_umask: Get my own canonical name, including domain. ****************************************************************************/ -static fstring dnshostname_cache; - -bool get_mydnsfullname(fstring my_dnsname) +const char *get_mydnsfullname(void) { - if (!*dnshostname_cache) { + static char *dnshostname_cache; + + if (dnshostname_cache == NULL || !*dnshostname_cache) { struct addrinfo *res = NULL; + char my_hostname[HOST_NAME_MAX]; bool ret; /* get my host name */ - if (gethostname(dnshostname_cache, sizeof(dnshostname_cache)) == -1) { - *dnshostname_cache = '\0'; + if (gethostname(my_hostname, sizeof(my_hostname)) == -1) { DEBUG(0,("get_mydnsfullname: gethostname failed\n")); - return false; + return NULL; } /* Ensure null termination. */ - dnshostname_cache[sizeof(dnshostname_cache)-1] = '\0'; + my_hostname[sizeof(my_hostname)-1] = '\0'; ret = interpret_string_addr_internal(&res, - dnshostname_cache, + my_hostname, AI_ADDRCONFIG|AI_CANONNAME); if (!ret || res == NULL) { DEBUG(3,("get_mydnsfullname: getaddrinfo failed for " "name %s [%s]\n", - dnshostname_cache, + my_hostname, gai_strerror(ret) )); - return false; + return NULL; } /* @@ -2015,17 +2015,15 @@ bool get_mydnsfullname(fstring my_dnsname) if (res->ai_canonname == NULL) { DEBUG(3,("get_mydnsfullname: failed to get " "canonical name for %s\n", - dnshostname_cache)); + my_hostname)); freeaddrinfo(res); - return false; + return NULL; } - - fstrcpy(dnshostname_cache, res->ai_canonname); + dnshostname_cache = SMB_STRDUP(res->ai_canonname); freeaddrinfo(res); } - fstrcpy(my_dnsname, dnshostname_cache); - return true; + return dnshostname_cache; } /************************************************************ @@ -2034,15 +2032,20 @@ bool get_mydnsfullname(fstring my_dnsname) bool is_myname_or_ipaddr(const char *s) { - fstring name, dnsname; - char *servername; + TALLOC_CTX *ctx = talloc_tos(); + char *name = NULL; + const char *dnsname; + char *servername = NULL; if (!s) { return false; } /* Santize the string from '\\name' */ - fstrcpy(name, s); + name = talloc_strdup(ctx, s); + if (!name) { + return false; + } servername = strrchr_m(name, '\\' ); if (!servername) { @@ -2072,10 +2075,9 @@ bool is_myname_or_ipaddr(const char *s) } /* Maybe it's my dns name */ - if (get_mydnsfullname(dnsname)) { - if (strequal(servername, dnsname)) { - return true; - } + dnsname = get_mydnsfullname(); + if (dnsname && strequal(servername, dnsname)) { + return true; } /* Handle possible CNAME records - convert to an IP addr. */ @@ -2104,7 +2106,7 @@ bool is_myname_or_ipaddr(const char *s) return false; } - nics = TALLOC_ARRAY(talloc_tos(), struct iface_struct, + nics = TALLOC_ARRAY(ctx, struct iface_struct, MAX_INTERFACES); if (!nics) { return false; -- cgit From 91c1933e675ed8bc0a0fad49a6f651273f29df95 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 11 Nov 2007 21:45:55 -0800 Subject: Remove a pstring. Jeremy. (This used to be commit c0412b5d13546f388b615a073e82e7730e01d731) --- source3/lib/util_sock.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 66da297dc7..28154067d3 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1895,7 +1895,7 @@ int create_pipe_sock(const char *socket_dir, struct stat st; int sock; mode_t old_umask; - pstring path; + char *path = NULL; old_umask = umask(0); @@ -1935,11 +1935,15 @@ int create_pipe_sock(const char *socket_dir, sock = socket(AF_UNIX, SOCK_STREAM, 0); if (sock == -1) { - perror("socket"); - goto out_umask; + DEBUG(0, ("create_pipe_sock: socket error %s\n", + strerror(errno) )); + goto out_close; } - pstr_sprintf(path, "%s/%s", socket_dir, socket_name); + asprintf(&path, "%s/%s", socket_dir, socket_name); + if (!path) { + goto out_close; + } unlink(path); memset(&sunaddr, 0, sizeof(sunaddr)); @@ -1958,10 +1962,13 @@ int create_pipe_sock(const char *socket_dir, goto out_close; } + SAFE_FREE(path); + umask(old_umask); return sock; out_close: + SAFE_FREE(path); close(sock); out_umask: -- cgit From acb829ecc3b9af3f141425ecac032a7c722a1815 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 15 Nov 2007 18:27:26 -0800 Subject: Add MAX_DNS_NAME_LENGTH, remove more pstrings. Jeremy. (This used to be commit a1725f4ff7ed375808c78ac661b539557748d0a5) --- source3/lib/util_sock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 28154067d3..a59b1d5ef2 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1802,8 +1802,8 @@ const char *get_peer_name(int fd, socklen_t length = sizeof(ss); const char *p; int ret; - char name_buf[HOST_NAME_MAX]; - char tmp_name[HOST_NAME_MAX]; + char name_buf[MAX_DNS_NAME_LENGTH]; + char tmp_name[MAX_DNS_NAME_LENGTH]; /* reverse lookups can be *very* expensive, and in many situations won't work because many networks don't link dhcp -- cgit From e68bbe3548df2400022a86af4681bcdf89481e9a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Nov 2007 10:10:52 -0800 Subject: Add set_sockaddr_port function for winbindd. Jeremy. (This used to be commit 4b47052694285a1d1d313dfd61bd17011d62948d) --- source3/lib/util_sock.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index a59b1d5ef2..f1a6d826e0 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -627,6 +627,19 @@ static int get_socket_port(int fd) } #endif +void set_sockaddr_port(struct sockaddr_storage *psa, uint16 port) +{ +#if defined(HAVE_IPV6) + if (psa->ss_family == AF_INET6) { + ((struct sockaddr_in6 *)psa)->sin6_port = htons(port); + } +#else + if (psa->ss_family == AF_INET) { + ((struct sockaddr_in *)psa)->sin_port = htons(port); + } +#endif +} + const char *client_name(int fd) { return get_peer_name(fd,false); -- cgit From dc9237d231a39bbed988baa9371ceb785ba32665 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Nov 2007 10:31:18 -0800 Subject: Doh ! Don't use #else when #endif is needed. Jeremy. (This used to be commit a04e916b89c901911ffc0a62e57a3ec87fe7ac28) --- source3/lib/util_sock.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index f1a6d826e0..e49db340ae 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -633,11 +633,10 @@ void set_sockaddr_port(struct sockaddr_storage *psa, uint16 port) if (psa->ss_family == AF_INET6) { ((struct sockaddr_in6 *)psa)->sin6_port = htons(port); } -#else +#endif if (psa->ss_family == AF_INET) { ((struct sockaddr_in *)psa)->sin_port = htons(port); } -#endif } const char *client_name(int fd) -- cgit From 42cfffae80480eae4381902fff3f7c61f858a933 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 7 Dec 2007 17:32:32 -0800 Subject: Remove next_token - all uses must now be next_token_talloc. No more temptations to use static length strings. Jeremy. (This used to be commit ec003f39369910dee852b7cafb883ddaa321c2de) --- source3/lib/util_sock.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index e49db340ae..e919cc5a46 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -785,9 +785,10 @@ static void print_socket_options(int s) void set_socket_options(int fd, const char *options) { - fstring tok; + TALLOC_CTX *ctx = talloc_stackframe(); + char *tok; - while (next_token(&options,tok," \t,", sizeof(tok))) { + while (next_token_talloc(ctx, &options, &tok," \t,")) { int ret=0,i; int value = 1; char *p; @@ -836,6 +837,7 @@ void set_socket_options(int fd, const char *options) } } + TALLOC_FREE(ctx); print_socket_options(fd); } -- cgit From daba3f8b54b04fe8623db3bab90c3aba15d4c379 Mon Sep 17 00:00:00 2001 From: James Peach Date: Sun, 9 Dec 2007 13:28:00 -0800 Subject: Fix connect(2) callers to use correct sockaddr size. Some systems (eg Mac OSX 10.5) require the length passed to match the socket address family. This introduces sys_connect() that does the right thing, and replaces all uses oc connect(2) with sys_connect(). Note that there are some LGPL callers that still call connect(2) directly. (This used to be commit e1bfdc17c49da582cdf907e260301ab1946b2ed3) --- source3/lib/util_sock.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index e919cc5a46..8f1bd9e686 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1459,7 +1459,7 @@ int open_socket_out(int type, /* and connect it to the destination */ connect_again: - ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out)); + ret = sys_connect(res, (struct sockaddr *)&sock_out); /* Some systems return EAGAIN when they mean EINPROGRESS */ if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || @@ -1547,12 +1547,13 @@ bool open_any_socket_out(struct sockaddr_storage *addrs, int num_addrs, good_connect = false; for (i=0; i Date: Wed, 26 Dec 2007 17:12:36 -0800 Subject: Add SMB encryption. Still fixing client decrypt but negotiation works. Jeremy. (This used to be commit d78045601af787731f0737b8627450018902b104) --- source3/lib/util_sock.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 8f1bd9e686..d16a8f079a 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1287,6 +1287,17 @@ bool receive_smb(int fd, char *buffer, unsigned int timeout, enum smb_read_error return false; } + if (srv_encryption_on()) { + NTSTATUS status = srv_decrypt_buffer(buffer); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("receive_smb: SMB decryption failed " + "on incoming packet! Error %s\n", + nt_errstr(status) )); + cond_set_smb_read_error(pre, SMB_READ_BAD_DECRYPT); + return false; + } + } + /* Check the incoming SMB signature. */ if (!srv_check_sign_mac(buffer, true)) { DEBUG(0, ("receive_smb: SMB Signature verification " @@ -1307,22 +1318,35 @@ bool send_smb(int fd, char *buffer) size_t len; size_t nwritten=0; ssize_t ret; + char *buf_out = buffer; /* Sign the outgoing packet if required. */ - srv_calculate_sign_mac(buffer); + srv_calculate_sign_mac(buf_out); + + if (srv_encryption_on()) { + NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("send_smb: SMB encryption failed " + "on outgoing packet! Error %s\n", + nt_errstr(status) )); + return false; + } + } - len = smb_len(buffer) + 4; + len = smb_len(buf_out) + 4; while (nwritten < len) { - ret = write_data(fd,buffer+nwritten,len - nwritten); + ret = write_data(fd,buf_out+nwritten,len - nwritten); if (ret <= 0) { DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n", (int)len,(int)ret, strerror(errno) )); + srv_free_enc_buffer(buf_out); return false; } nwritten += ret; } + srv_free_enc_buffer(buf_out); return true; } -- cgit From cc957c7f6d1956740feb7169b45f388d387e175a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 2 Jan 2008 17:37:39 -0800 Subject: Convert the little caches in util_sock.c to use the singleton memcache. Vl please check (passes make valgrindtest). Jeremy. (This used to be commit a4d613cde86caf5782c4bfc47122d6ba807990ac) --- source3/lib/util_sock.c | 165 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 118 insertions(+), 47 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index d16a8f079a..013a5fe29f 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1824,18 +1824,67 @@ static bool matchname(const char *remotehost, return false; } -static struct { - struct sockaddr_storage ss; - char *name; -} nc; +/******************************************************************* + Deal with the singleton cache. +******************************************************************/ + +struct name_addr_pair { + struct sockaddr_storage ss; + const char *name; +}; + +/******************************************************************* + Lookup a name/addr pair. Returns memory allocated from memcache. +******************************************************************/ + +static bool lookup_nc(struct name_addr_pair *nc) +{ + DATA_BLOB tmp; + + ZERO_STRUCTP(nc); + + if (!memcache_lookup( + NULL, SINGLETON_CACHE, + data_blob_string_const("get_peer_name"), + &tmp)) { + return false; + } + + memcpy(&nc->ss, tmp.data, sizeof(nc->ss)); + nc->name = (const char *)tmp.data + sizeof(nc->ss); + return true; +} + +/******************************************************************* + Save a name/addr pair. +******************************************************************/ + +static void store_nc(const struct name_addr_pair *nc) +{ + DATA_BLOB tmp; + size_t namelen = strlen(nc->name); + + tmp.length = sizeof(nc->ss) + namelen + 1; + tmp.data = (uint8_t *)SMB_MALLOC(tmp.length); + if (!tmp.data) { + return; + } + memcpy(tmp.data, &nc->ss, sizeof(nc->ss)); + memcpy(tmp.data+sizeof(nc->ss), nc->name, namelen+1); + + memcache_add(NULL, SINGLETON_CACHE, + data_blob_string_const("get_peer_name"), + tmp); + SAFE_FREE(tmp.data); +} /******************************************************************* Return the DNS name of the remote end of a socket. ******************************************************************/ -const char *get_peer_name(int fd, - bool force_lookup) +const char *get_peer_name(int fd, bool force_lookup) { + struct name_addr_pair nc; char addr_buf[INET6_ADDRSTRLEN]; struct sockaddr_storage ss; socklen_t length = sizeof(ss); @@ -1850,13 +1899,15 @@ const char *get_peer_name(int fd, possible */ if (!lp_hostname_lookups() && (force_lookup == false)) { length = sizeof(nc.ss); - p = get_peer_addr_internal(fd, addr_buf, sizeof(addr_buf), + nc.name = get_peer_addr_internal(fd, addr_buf, sizeof(addr_buf), &nc.ss, &length); - SAFE_FREE(nc.name); - nc.name = SMB_STRDUP(p); + store_nc(&nc); + lookup_nc(&nc); return nc.name ? nc.name : "UNKNOWN"; } + lookup_nc(&nc); + memset(&ss, '\0', sizeof(ss)); p = get_peer_addr_internal(fd, addr_buf, sizeof(addr_buf), &ss, &length); @@ -1865,9 +1916,7 @@ const char *get_peer_name(int fd, return nc.name ? nc.name : "UNKNOWN"; } - /* Not the same. Reset the cache. */ - zero_addr(&nc.ss); - SAFE_FREE(nc.name); + /* Not the same. We need to lookup. */ if (fd == -1) { return "UNKNOWN"; } @@ -1904,7 +1953,11 @@ const char *get_peer_name(int fd, strlcpy(name_buf, "UNKNOWN", sizeof(name_buf)); } - nc.name = SMB_STRDUP(name_buf); + nc.name = name_buf; + nc.ss = ss; + + store_nc(&nc); + lookup_nc(&nc); return nc.name ? nc.name : "UNKNOWN"; } @@ -2026,50 +2079,68 @@ out_umask: const char *get_mydnsfullname(void) { - static char *dnshostname_cache; - - if (dnshostname_cache == NULL || !*dnshostname_cache) { - struct addrinfo *res = NULL; - char my_hostname[HOST_NAME_MAX]; - bool ret; + struct addrinfo *res = NULL; + char my_hostname[HOST_NAME_MAX]; + bool ret; + DATA_BLOB tmp; - /* get my host name */ - if (gethostname(my_hostname, sizeof(my_hostname)) == -1) { - DEBUG(0,("get_mydnsfullname: gethostname failed\n")); - return NULL; - } + if (memcache_lookup(NULL, SINGLETON_CACHE, + data_blob_string_const("get_mydnsfullname"), + &tmp)) { + SMB_ASSERT(tmp.length > 0); + return (const char *)tmp.data; + } - /* Ensure null termination. */ - my_hostname[sizeof(my_hostname)-1] = '\0'; + /* get my host name */ + if (gethostname(my_hostname, sizeof(my_hostname)) == -1) { + DEBUG(0,("get_mydnsfullname: gethostname failed\n")); + return NULL; + } - ret = interpret_string_addr_internal(&res, - my_hostname, - AI_ADDRCONFIG|AI_CANONNAME); + /* Ensure null termination. */ + my_hostname[sizeof(my_hostname)-1] = '\0'; - if (!ret || res == NULL) { - DEBUG(3,("get_mydnsfullname: getaddrinfo failed for " - "name %s [%s]\n", + ret = interpret_string_addr_internal(&res, my_hostname, - gai_strerror(ret) )); - return NULL; - } + AI_ADDRCONFIG|AI_CANONNAME); - /* - * Make sure that getaddrinfo() returns the "correct" host name. - */ + if (!ret || res == NULL) { + DEBUG(3,("get_mydnsfullname: getaddrinfo failed for " + "name %s [%s]\n", + my_hostname, + gai_strerror(ret) )); + return NULL; + } - if (res->ai_canonname == NULL) { - DEBUG(3,("get_mydnsfullname: failed to get " - "canonical name for %s\n", - my_hostname)); - freeaddrinfo(res); - return NULL; - } + /* + * Make sure that getaddrinfo() returns the "correct" host name. + */ - dnshostname_cache = SMB_STRDUP(res->ai_canonname); + if (res->ai_canonname == NULL) { + DEBUG(3,("get_mydnsfullname: failed to get " + "canonical name for %s\n", + my_hostname)); freeaddrinfo(res); + return NULL; + } + + /* This copies the data, so we must do a lookup + * afterwards to find the value to return. + */ + + memcache_add(NULL, SINGLETON_CACHE, + data_blob_string_const("get_mydnsfullname"), + data_blob_string_const(res->ai_canonname)); + + freeaddrinfo(res); + + if (!memcache_lookup(NULL, SINGLETON_CACHE, + data_blob_string_const("get_mydnsfullname"), + &tmp)) { + return NULL; } - return dnshostname_cache; + + return (const char *)tmp.data; } /************************************************************ -- cgit From 149e86b8427359042830faddad10a103f51184da Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 3 Jan 2008 10:24:45 +0100 Subject: Trivial simplification ... things you come across when you review code (This used to be commit 1e006bcfb15d44ecb81b6994c588d30d87b48033) --- source3/lib/util_sock.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 013a5fe29f..b92cd3d624 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1864,8 +1864,7 @@ static void store_nc(const struct name_addr_pair *nc) DATA_BLOB tmp; size_t namelen = strlen(nc->name); - tmp.length = sizeof(nc->ss) + namelen + 1; - tmp.data = (uint8_t *)SMB_MALLOC(tmp.length); + tmp = data_blob(NULL, sizeof(nc->ss) + namelen + 1); if (!tmp.data) { return; } @@ -1875,7 +1874,7 @@ static void store_nc(const struct name_addr_pair *nc) memcache_add(NULL, SINGLETON_CACHE, data_blob_string_const("get_peer_name"), tmp); - SAFE_FREE(tmp.data); + data_blob_free(&tmp); } /******************************************************************* -- cgit From 9254bb4ef1c3c3a52ea8e935edb0e7a86ec3ea7a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 4 Jan 2008 12:56:23 -0800 Subject: Refactor the crypto code after a very helpful conversation with Volker. Mostly making sure we have data on the incoming packet type, not stored in the smb header. Jeremy. (This used to be commit c4e5a505043965eec77b5bb9bc60957e8f3b97c8) --- source3/lib/util_sock.c | 74 ------------------------------------------------- 1 file changed, 74 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index b92cd3d624..945506ea77 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1276,80 +1276,6 @@ ssize_t receive_smb_raw(int fd, return len; } -/**************************************************************************** - Wrapper for receive_smb_raw(). - Checks the MAC on signed packets. -****************************************************************************/ - -bool receive_smb(int fd, char *buffer, unsigned int timeout, enum smb_read_errors *pre) -{ - if (receive_smb_raw(fd, buffer, timeout, 0, pre) < 0) { - return false; - } - - if (srv_encryption_on()) { - NTSTATUS status = srv_decrypt_buffer(buffer); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("receive_smb: SMB decryption failed " - "on incoming packet! Error %s\n", - nt_errstr(status) )); - cond_set_smb_read_error(pre, SMB_READ_BAD_DECRYPT); - return false; - } - } - - /* Check the incoming SMB signature. */ - if (!srv_check_sign_mac(buffer, true)) { - DEBUG(0, ("receive_smb: SMB Signature verification " - "failed on incoming packet!\n")); - cond_set_smb_read_error(pre,SMB_READ_BAD_SIG); - return false; - } - - return true; -} - -/**************************************************************************** - Send an smb to a fd. -****************************************************************************/ - -bool send_smb(int fd, char *buffer) -{ - size_t len; - size_t nwritten=0; - ssize_t ret; - char *buf_out = buffer; - - /* Sign the outgoing packet if required. */ - srv_calculate_sign_mac(buf_out); - - if (srv_encryption_on()) { - NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("send_smb: SMB encryption failed " - "on outgoing packet! Error %s\n", - nt_errstr(status) )); - return false; - } - } - - len = smb_len(buf_out) + 4; - - while (nwritten < len) { - ret = write_data(fd,buf_out+nwritten,len - nwritten); - if (ret <= 0) { - DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n", - (int)len,(int)ret, strerror(errno) )); - srv_free_enc_buffer(buf_out); - return false; - } - nwritten += ret; - } - - srv_free_enc_buffer(buf_out); - return true; -} - /**************************************************************************** Open a socket of the specified type, port, and address for incoming data. ****************************************************************************/ -- cgit From bd8abea49fed09e131ab5162821b0ed05c1ab1b0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 Jan 2008 13:21:46 -0800 Subject: Fix IPv6 bug #5204, which caused krb5 DNS lookups for a name '['. Jeremy. (This used to be commit f2aa921505e49f894bfed4e5e2f9fc01918b1bb0) --- source3/lib/util_sock.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 945506ea77..10428113ae 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -475,6 +475,29 @@ bool is_address_any(const struct sockaddr_storage *psa) return false; } +/**************************************************************************** + Get a port number in host byte order from a sockaddr_storage. +****************************************************************************/ + +uint16_t get_sockaddr_port(const struct sockaddr_storage *pss) +{ + uint16_t port = 0; + + if (pss->ss_family != AF_INET) { +#if defined(HAVE_IPV6) + /* IPv6 */ + const struct sockaddr_in6 *sa6 = + (const struct sockaddr_in6 *)pss; + port = ntohs(sa6->sin6_port); +#endif + } else { + const struct sockaddr_in *sa = + (const struct sockaddr_in *)pss; + port = ntohs(sa->sin_port); + } + return port; +} + /**************************************************************************** Print out an IPv4 or IPv6 address from a struct sockaddr_storage. ****************************************************************************/ @@ -518,7 +541,7 @@ char *print_canonical_sockaddr(TALLOC_CTX *ctx, char *dest = NULL; int ret; - ret = getnameinfo((const struct sockaddr *)pss, + ret = sys_getnameinfo((const struct sockaddr *)pss, sizeof(struct sockaddr_storage), addr, sizeof(addr), NULL, 0, @@ -1847,7 +1870,7 @@ const char *get_peer_name(int fd, bool force_lookup) } /* Look up the remote host name. */ - ret = getnameinfo((struct sockaddr *)&ss, + ret = sys_getnameinfo((struct sockaddr *)&ss, length, name_buf, sizeof(name_buf), -- cgit From 7b6a439efe8a077bf333a9badde021eb9a54b227 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Mon, 21 Jan 2008 13:18:38 +0100 Subject: util_sock: Fix memcache bug in get_mydnsfullname. get_mydnsfullname relied on memcache_add(); memcache_lookup() working. When run from ntlm_auth, the global_cache variable in memcache is NULL, so the add and lookup both fail. In that case, just return the result of the getaddrinfo call. Jeremy, please check. (This used to be commit 1db41ff52565e9f336a22fb9ffd80d51677e023b) --- source3/lib/util_sock.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 10428113ae..f524d0d826 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -2080,14 +2080,14 @@ const char *get_mydnsfullname(void) data_blob_string_const("get_mydnsfullname"), data_blob_string_const(res->ai_canonname)); - freeaddrinfo(res); - if (!memcache_lookup(NULL, SINGLETON_CACHE, data_blob_string_const("get_mydnsfullname"), &tmp)) { - return NULL; + tmp = data_blob_string_const(res->ai_canonname); } + freeaddrinfo(res); + return (const char *)tmp.data; } -- cgit From 36e3e75e0683eb9fd14d8a282d9a2324f01fddf7 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Mon, 21 Jan 2008 18:01:55 +0100 Subject: util_sock: Don't return a pointer to freed memory. Fix a bug in my bugfix. Thanks to vl for spotting that one. (This used to be commit 24f68b90cca111256a7b03f7062cb57c2b08a0d6) --- source3/lib/util_sock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index f524d0d826..a3975f6c1f 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -2083,7 +2083,8 @@ const char *get_mydnsfullname(void) if (!memcache_lookup(NULL, SINGLETON_CACHE, data_blob_string_const("get_mydnsfullname"), &tmp)) { - tmp = data_blob_string_const(res->ai_canonname); + tmp = data_blob_talloc(talloc_tos(), res->ai_canonname, + strlen(res->ai_canonname) + 1); } freeaddrinfo(res); -- cgit From a925a53f61ebdc6b4386b7c0853f2f87cbe2e166 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 23 Jan 2008 16:42:31 +0100 Subject: read_socket_with_timeout has timeout=0 handling (This used to be commit 7101026061c470ed962267b43ac0aa67cc761a64) --- source3/lib/util_sock.c | 39 +-------------------------------------- 1 file changed, 1 insertion(+), 38 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index a3975f6c1f..fb8f41513b 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1054,44 +1054,7 @@ ssize_t read_socket_with_timeout(int fd, ssize_t read_data(int fd,char *buffer,size_t N, enum smb_read_errors *pre) { - ssize_t ret; - size_t total=0; - char addr[INET6_ADDRSTRLEN]; - - set_smb_read_error(pre,SMB_READ_OK); - - while (total < N) { - ret = sys_read(fd,buffer + total,N - total); - - if (ret == 0) { - DEBUG(10,("read_data: read of %d returned 0. " - "Error = %s\n", - (int)(N - total), strerror(errno) )); - set_smb_read_error(pre,SMB_READ_EOF); - return 0; - } - - if (ret == -1) { - if (fd == get_client_fd()) { - /* Try and give an error message saying - * what client failed. */ - DEBUG(0,("read_data: read failure for %d " - "bytes to client %s. Error = %s\n", - (int)(N - total), - get_peer_addr(fd,addr,sizeof(addr)), - strerror(errno) )); - } else { - DEBUG(0,("read_data: read failure for %d. " - "Error = %s\n", - (int)(N - total), - strerror(errno) )); - } - set_smb_read_error(pre,SMB_READ_ERROR); - return -1; - } - total += ret; - } - return (ssize_t)total; + return read_socket_with_timeout(fd, buffer, N, N, 0, pre); } /**************************************************************************** -- cgit From 9344628bef74ac759197601dc5dd44514b836e3e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 23 Jan 2008 17:37:59 +0100 Subject: More read_data -> read_socket_with_timeout (This used to be commit f1d7de462cf0f64648a3a1fc6f0c64a7bbdb3c2a) --- source3/lib/util_sock.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index fb8f41513b..1a7cc02229 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1126,12 +1126,7 @@ ssize_t read_smb_length_return_keepalive(int fd, bool ok = false; while (!ok) { - if (timeout > 0) { - ok = (read_socket_with_timeout(fd,inbuf,4,4, - timeout,pre) == 4); - } else { - ok = (read_data(fd,inbuf,4,pre) == 4); - } + ok = (read_socket_with_timeout(fd,inbuf,4,4,timeout,pre) == 4); if (!ok) { return -1; } @@ -1237,16 +1232,8 @@ ssize_t receive_smb_raw(int fd, len = MIN(len,maxlen); } - if (timeout > 0) { - ret = read_socket_with_timeout(fd, - buffer+4, - len, - len, - timeout, - pre); - } else { - ret = read_data(fd,buffer+4,len,pre); - } + ret = read_socket_with_timeout(fd, buffer+4, len, len, timeout, + pre); if (ret != len) { cond_set_smb_read_error(pre,SMB_READ_ERROR); -- cgit From 31a6f807842259ded10dff549f2f57d77ee79c6e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 25 Jan 2008 09:21:44 +0100 Subject: Remove a pointless while loop (This used to be commit f591bd68eafdbaefcaa95510cc4cb9a74cef0562) --- source3/lib/util_sock.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 1a7cc02229..ce1569d021 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1123,20 +1123,16 @@ ssize_t read_smb_length_return_keepalive(int fd, { ssize_t len=0; int msg_type; - bool ok = false; - while (!ok) { - ok = (read_socket_with_timeout(fd,inbuf,4,4,timeout,pre) == 4); - if (!ok) { - return -1; - } + if (read_socket_with_timeout(fd, inbuf, 4, 4, timeout, pre) != 4) { + return -1; + } - len = smb_len(inbuf); - msg_type = CVAL(inbuf,0); + len = smb_len(inbuf); + msg_type = CVAL(inbuf,0); - if (msg_type == SMBkeepalive) { - DEBUG(5,("Got keepalive packet\n")); - } + if (msg_type == SMBkeepalive) { + DEBUG(5,("Got keepalive packet\n")); } DEBUG(10,("got smb length of %lu\n",(unsigned long)len)); -- cgit From e2ad28509c4e31fa4d397290b61e376d55e3abb2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 25 Jan 2008 09:28:19 +0100 Subject: Tiny simplification (This used to be commit e78f6872bfc19ce0476b8d79c856a8d9c646a913) --- source3/lib/util_sock.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index ce1569d021..ced1130536 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1150,16 +1150,15 @@ ssize_t read_smb_length_return_keepalive(int fd, ssize_t read_smb_length(int fd, char *inbuf, unsigned int timeout, enum smb_read_errors *pre) { ssize_t len; + uint8_t msgtype = SMBkeepalive; - for(;;) { - len = read_smb_length_return_keepalive(fd, inbuf, timeout, pre); - - if(len < 0) + while (msgtype == SMBkeepalive) { + len = read_smb_length_return_keepalive(fd, inbuf, timeout, + pre); + if (len < 0) { return len; - - /* Ignore session keepalives. */ - if(CVAL(inbuf,0) != SMBkeepalive) - break; + } + msgtype = CVAL(inbuf, 0); } DEBUG(10,("read_smb_length: got smb length of %lu\n", -- cgit From 680a0f0c69f2c31e0e72276444d130d3a60bef82 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 1 Feb 2008 15:37:11 +0100 Subject: Fix a typo (This used to be commit 1efdef08ae19a01b03bf6730df1fb4a9a4a8aba0) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index ced1130536..f5797f175b 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -112,7 +112,7 @@ static bool interpret_string_addr_internal(struct addrinfo **ppres, &hints, ppres); if (ret) { - DEBUG(3,("interpret_string_addr_interal: getaddrinfo failed " + DEBUG(3,("interpret_string_addr_internal: getaddrinfo failed " "for name %s [%s]\n", str, gai_strerror(ret) )); -- cgit From 3f970f91c2af77acd531c37ee3aa1a09ca71e7ab Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 24 Jan 2008 19:17:14 +0100 Subject: Add read_socket_with_timeout_ntstatus (This used to be commit 546ca0414aa1a9389e620b8f532224a3a19256d4) --- source3/lib/util_sock.c | 71 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 48 insertions(+), 23 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index f5797f175b..f61cdb151e 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -913,12 +913,10 @@ ssize_t read_udp_v4_socket(int fd, time_out = timeout in milliseconds ****************************************************************************/ -ssize_t read_socket_with_timeout(int fd, - char *buf, - size_t mincnt, - size_t maxcnt, - unsigned int time_out, - enum smb_read_errors *pre) +NTSTATUS read_socket_with_timeout_ntstatus(int fd, char *buf, + size_t mincnt, size_t maxcnt, + unsigned int time_out, + size_t *size_ret) { fd_set fds; int selrtn; @@ -929,9 +927,7 @@ ssize_t read_socket_with_timeout(int fd, /* just checking .... */ if (maxcnt <= 0) - return(0); - - set_smb_read_error(pre,SMB_READ_OK); + return NT_STATUS_OK; /* Blocking read */ if (time_out == 0) { @@ -945,8 +941,7 @@ ssize_t read_socket_with_timeout(int fd, if (readret == 0) { DEBUG(5,("read_socket_with_timeout: " "blocking read. EOF from client.\n")); - set_smb_read_error(pre,SMB_READ_EOF); - return -1; + return NT_STATUS_END_OF_FILE; } if (readret == -1) { @@ -962,12 +957,11 @@ ssize_t read_socket_with_timeout(int fd, "read error = %s.\n", strerror(errno) )); } - set_smb_read_error(pre,SMB_READ_ERROR); - return -1; + return map_nt_error_from_unix(errno); } nread += readret; } - return((ssize_t)nread); + goto done; } /* Most difficult - timeout read */ @@ -1001,16 +995,14 @@ ssize_t read_socket_with_timeout(int fd, "read. select error = %s.\n", strerror(errno) )); } - set_smb_read_error(pre,SMB_READ_ERROR); - return -1; + return map_nt_error_from_unix(errno); } /* Did we timeout ? */ if (selrtn == 0) { DEBUG(10,("read_socket_with_timeout: timeout read. " "select timed out.\n")); - set_smb_read_error(pre,SMB_READ_TIMEOUT); - return -1; + return NT_STATUS_IO_TIMEOUT; } readret = sys_read(fd, buf+nread, maxcnt-nread); @@ -1019,8 +1011,7 @@ ssize_t read_socket_with_timeout(int fd, /* we got EOF on the file descriptor */ DEBUG(5,("read_socket_with_timeout: timeout read. " "EOF from client.\n")); - set_smb_read_error(pre,SMB_READ_EOF); - return -1; + return NT_STATUS_END_OF_FILE; } if (readret == -1) { @@ -1037,15 +1028,49 @@ ssize_t read_socket_with_timeout(int fd, "read. read error = %s.\n", strerror(errno) )); } - set_smb_read_error(pre,SMB_READ_ERROR); - return -1; + return map_nt_error_from_unix(errno); } nread += readret; } + done: /* Return the number we got */ - return (ssize_t)nread; + if (size_ret) { + *size_ret = nread; + } + return NT_STATUS_OK; +} + +ssize_t read_socket_with_timeout(int fd, char *buf, + size_t mincnt, size_t maxcnt, + unsigned int time_out, + enum smb_read_errors *pre) +{ + NTSTATUS status; + size_t size_ret; + + set_smb_read_error(pre, SMB_READ_OK); + + status = read_socket_with_timeout_ntstatus(fd, buf, mincnt, maxcnt, + time_out, &size_ret); + + if (NT_STATUS_IS_OK(status)) { + return size_ret; + } + + if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) { + set_smb_read_error(pre, SMB_READ_EOF); + return -1; + } + + if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { + set_smb_read_error(pre, SMB_READ_TIMEOUT); + return -1; + } + + set_smb_read_error(pre, SMB_READ_ERROR); + return -1; } /**************************************************************************** -- cgit From 3e5b98555b832772d6fe93a57005bc39222a5189 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 25 Jan 2008 21:02:52 +0100 Subject: Convert read_smb_length_return_keepalive to read_socket_with_timeout_ntstatus (This used to be commit 59e8f22f36be5a70fdb101964570ce7c10e8ff65) --- source3/lib/util_sock.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index f61cdb151e..d32d67f2fc 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1146,10 +1146,27 @@ ssize_t read_smb_length_return_keepalive(int fd, unsigned int timeout, enum smb_read_errors *pre) { - ssize_t len=0; + size_t len=0; int msg_type; + NTSTATUS status; + + set_smb_read_error(pre, SMB_READ_OK); + + status = read_socket_with_timeout_ntstatus(fd, inbuf, 4, 4, timeout, + NULL); + + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) { + set_smb_read_error(pre, SMB_READ_EOF); + return -1; + } + + if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { + set_smb_read_error(pre, SMB_READ_TIMEOUT); + return -1; + } - if (read_socket_with_timeout(fd, inbuf, 4, 4, timeout, pre) != 4) { + set_smb_read_error(pre, SMB_READ_ERROR); return -1; } -- cgit From 0afbfa4284db8204a3696f4fea6cff96965e6074 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 25 Jan 2008 21:24:48 +0100 Subject: Convert read_smb_length_return_keepalive to return NTSTATUS (This used to be commit 73a79a957a33a8761acf54598ce71e3604ecf3c5) --- source3/lib/util_sock.c | 80 +++++++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 36 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index d32d67f2fc..f62b20b6fc 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1141,36 +1141,21 @@ bool send_keepalive(int client) Timeout is in milliseconds. ****************************************************************************/ -ssize_t read_smb_length_return_keepalive(int fd, - char *inbuf, - unsigned int timeout, - enum smb_read_errors *pre) +NTSTATUS read_smb_length_return_keepalive(int fd, char *inbuf, + unsigned int timeout, + size_t *len) { - size_t len=0; int msg_type; NTSTATUS status; - set_smb_read_error(pre, SMB_READ_OK); - status = read_socket_with_timeout_ntstatus(fd, inbuf, 4, 4, timeout, NULL); if (!NT_STATUS_IS_OK(status)) { - if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) { - set_smb_read_error(pre, SMB_READ_EOF); - return -1; - } - - if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { - set_smb_read_error(pre, SMB_READ_TIMEOUT); - return -1; - } - - set_smb_read_error(pre, SMB_READ_ERROR); - return -1; + return status; } - len = smb_len(inbuf); + *len = smb_len(inbuf); msg_type = CVAL(inbuf,0); if (msg_type == SMBkeepalive) { @@ -1179,7 +1164,7 @@ ssize_t read_smb_length_return_keepalive(int fd, DEBUG(10,("got smb length of %lu\n",(unsigned long)len)); - return len; + return NT_STATUS_OK; } /**************************************************************************** @@ -1191,15 +1176,31 @@ ssize_t read_smb_length_return_keepalive(int fd, ssize_t read_smb_length(int fd, char *inbuf, unsigned int timeout, enum smb_read_errors *pre) { - ssize_t len; + size_t len; uint8_t msgtype = SMBkeepalive; + set_smb_read_error(pre, SMB_READ_OK); + while (msgtype == SMBkeepalive) { - len = read_smb_length_return_keepalive(fd, inbuf, timeout, - pre); - if (len < 0) { - return len; + NTSTATUS status; + + status = read_smb_length_return_keepalive(fd, inbuf, timeout, + &len); + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) { + set_smb_read_error(pre, SMB_READ_EOF); + return -1; + } + + if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { + set_smb_read_error(pre, SMB_READ_TIMEOUT); + return -1; + } + + set_smb_read_error(pre, SMB_READ_ERROR); + return -1; } + msgtype = CVAL(inbuf, 0); } @@ -1225,21 +1226,28 @@ ssize_t receive_smb_raw(int fd, size_t maxlen, enum smb_read_errors *pre) { - ssize_t len,ret; + size_t len; + ssize_t ret; + NTSTATUS status; set_smb_read_error(pre,SMB_READ_OK); - len = read_smb_length_return_keepalive(fd,buffer,timeout,pre); - if (len < 0) { - DEBUG(10,("receive_smb_raw: length < 0!\n")); + status = read_smb_length_return_keepalive(fd,buffer,timeout,&len); - /* - * Correct fix. smb_read_error may have already been - * set. Only set it here if not already set. Global - * variables still suck :-). JRA. - */ + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("receive_smb_raw: %s!\n", nt_errstr(status))); + + if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) { + set_smb_read_error(pre, SMB_READ_EOF); + return -1; + } + + if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { + set_smb_read_error(pre, SMB_READ_TIMEOUT); + return -1; + } - cond_set_smb_read_error(pre,SMB_READ_ERROR); + set_smb_read_error(pre, SMB_READ_ERROR); return -1; } -- cgit From 9f6e983d0b67b64daf27dab130348d3491bad4ac Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 25 Jan 2008 21:31:40 +0100 Subject: Convert read_smb_length to return NTSTATUS (This used to be commit 5750c3a51b4ddac635a98195d1621b24f91bad3f) --- source3/lib/util_sock.c | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index f62b20b6fc..32dd2bd8a8 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1174,31 +1174,18 @@ NTSTATUS read_smb_length_return_keepalive(int fd, char *inbuf, Timeout is in milliseconds. ****************************************************************************/ -ssize_t read_smb_length(int fd, char *inbuf, unsigned int timeout, enum smb_read_errors *pre) +NTSTATUS read_smb_length(int fd, char *inbuf, unsigned int timeout, + size_t *len) { - size_t len; uint8_t msgtype = SMBkeepalive; - set_smb_read_error(pre, SMB_READ_OK); - while (msgtype == SMBkeepalive) { NTSTATUS status; status = read_smb_length_return_keepalive(fd, inbuf, timeout, - &len); + len); if (!NT_STATUS_IS_OK(status)) { - if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) { - set_smb_read_error(pre, SMB_READ_EOF); - return -1; - } - - if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { - set_smb_read_error(pre, SMB_READ_TIMEOUT); - return -1; - } - - set_smb_read_error(pre, SMB_READ_ERROR); - return -1; + return status; } msgtype = CVAL(inbuf, 0); @@ -1207,7 +1194,7 @@ ssize_t read_smb_length(int fd, char *inbuf, unsigned int timeout, enum smb_read DEBUG(10,("read_smb_length: got smb length of %lu\n", (unsigned long)len)); - return len; + return NT_STATUS_OK; } /**************************************************************************** -- cgit From 5e43eeb1b6eef7ea7a88ffc51a0a0535e9bd8023 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 25 Jan 2008 23:41:48 +0100 Subject: Get rid of read_socket_with_timeout (This used to be commit f9c8ac83ff42137d2101d3bb17e5dcc3c3d70a8f) --- source3/lib/util_sock.c | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 32dd2bd8a8..d0d321ee39 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1042,21 +1042,20 @@ NTSTATUS read_socket_with_timeout_ntstatus(int fd, char *buf, return NT_STATUS_OK; } -ssize_t read_socket_with_timeout(int fd, char *buf, - size_t mincnt, size_t maxcnt, - unsigned int time_out, - enum smb_read_errors *pre) +/**************************************************************************** + Read data from the client, reading exactly N bytes. +****************************************************************************/ + +ssize_t read_data(int fd,char *buffer,size_t N, enum smb_read_errors *pre) { NTSTATUS status; - size_t size_ret; set_smb_read_error(pre, SMB_READ_OK); - status = read_socket_with_timeout_ntstatus(fd, buf, mincnt, maxcnt, - time_out, &size_ret); + status = read_socket_with_timeout_ntstatus(fd, buffer, N, N, 0, NULL); if (NT_STATUS_IS_OK(status)) { - return size_ret; + return N; } if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) { @@ -1073,15 +1072,6 @@ ssize_t read_socket_with_timeout(int fd, char *buf, return -1; } -/**************************************************************************** - Read data from the client, reading exactly N bytes. -****************************************************************************/ - -ssize_t read_data(int fd,char *buffer,size_t N, enum smb_read_errors *pre) -{ - return read_socket_with_timeout(fd, buffer, N, N, 0, pre); -} - /**************************************************************************** Write data to a fd. ****************************************************************************/ @@ -1214,7 +1204,6 @@ ssize_t receive_smb_raw(int fd, enum smb_read_errors *pre) { size_t len; - ssize_t ret; NTSTATUS status; set_smb_read_error(pre,SMB_READ_OK); @@ -1264,11 +1253,23 @@ ssize_t receive_smb_raw(int fd, len = MIN(len,maxlen); } - ret = read_socket_with_timeout(fd, buffer+4, len, len, timeout, - pre); + set_smb_read_error(pre, SMB_READ_OK); - if (ret != len) { - cond_set_smb_read_error(pre,SMB_READ_ERROR); + status = read_socket_with_timeout_ntstatus( + fd, buffer+4, len, len, timeout, &len); + + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) { + set_smb_read_error(pre, SMB_READ_EOF); + return -1; + } + + if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { + set_smb_read_error(pre, SMB_READ_TIMEOUT); + return -1; + } + + set_smb_read_error(pre, SMB_READ_ERROR); return -1; } -- cgit From 6ddfa6ae7734ffdd26ac38478c27cc9d646ddadd Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 25 Jan 2008 23:43:50 +0100 Subject: read_socket_with_timeout_ntstatus->read_socket_with_timeout (This used to be commit 90554799afa42855c3e7b87dc632e67f0952f988) --- source3/lib/util_sock.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index d0d321ee39..fcea5d8be6 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -913,10 +913,10 @@ ssize_t read_udp_v4_socket(int fd, time_out = timeout in milliseconds ****************************************************************************/ -NTSTATUS read_socket_with_timeout_ntstatus(int fd, char *buf, - size_t mincnt, size_t maxcnt, - unsigned int time_out, - size_t *size_ret) +NTSTATUS read_socket_with_timeout(int fd, char *buf, + size_t mincnt, size_t maxcnt, + unsigned int time_out, + size_t *size_ret) { fd_set fds; int selrtn; @@ -1052,7 +1052,7 @@ ssize_t read_data(int fd,char *buffer,size_t N, enum smb_read_errors *pre) set_smb_read_error(pre, SMB_READ_OK); - status = read_socket_with_timeout_ntstatus(fd, buffer, N, N, 0, NULL); + status = read_socket_with_timeout(fd, buffer, N, N, 0, NULL); if (NT_STATUS_IS_OK(status)) { return N; @@ -1138,8 +1138,7 @@ NTSTATUS read_smb_length_return_keepalive(int fd, char *inbuf, int msg_type; NTSTATUS status; - status = read_socket_with_timeout_ntstatus(fd, inbuf, 4, 4, timeout, - NULL); + status = read_socket_with_timeout(fd, inbuf, 4, 4, timeout, NULL); if (!NT_STATUS_IS_OK(status)) { return status; @@ -1255,7 +1254,7 @@ ssize_t receive_smb_raw(int fd, set_smb_read_error(pre, SMB_READ_OK); - status = read_socket_with_timeout_ntstatus( + status = read_socket_with_timeout( fd, buffer+4, len, len, timeout, &len); if (!NT_STATUS_IS_OK(status)) { -- cgit From 88c27f83d449fa20cba47cbf0a5dbaedc99859d8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 25 Jan 2008 23:54:22 +0100 Subject: Convert receive_smb_raw to NTSTATUS (This used to be commit ba771bd858602452a9e58c3aab1336f2ac8a25ef) --- source3/lib/util_sock.c | 51 +++++++------------------------------------------ 1 file changed, 7 insertions(+), 44 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index fcea5d8be6..ede2cdae71 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1196,34 +1196,17 @@ NTSTATUS read_smb_length(int fd, char *inbuf, unsigned int timeout, Doesn't check the MAC on signed packets. ****************************************************************************/ -ssize_t receive_smb_raw(int fd, - char *buffer, - unsigned int timeout, - size_t maxlen, - enum smb_read_errors *pre) +NTSTATUS receive_smb_raw(int fd, char *buffer, unsigned int timeout, + size_t maxlen, size_t *p_len) { size_t len; NTSTATUS status; - set_smb_read_error(pre,SMB_READ_OK); - status = read_smb_length_return_keepalive(fd,buffer,timeout,&len); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("receive_smb_raw: %s!\n", nt_errstr(status))); - - if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) { - set_smb_read_error(pre, SMB_READ_EOF); - return -1; - } - - if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { - set_smb_read_error(pre, SMB_READ_TIMEOUT); - return -1; - } - - set_smb_read_error(pre, SMB_READ_ERROR); - return -1; + return status; } /* @@ -1235,15 +1218,7 @@ ssize_t receive_smb_raw(int fd, DEBUG(0,("Invalid packet length! (%lu bytes).\n", (unsigned long)len)); if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) { - - /* - * Correct fix. smb_read_error may have already been - * set. Only set it here if not already set. Global - * variables still suck :-). JRA. - */ - - cond_set_smb_read_error(pre,SMB_READ_ERROR); - return -1; + return NT_STATUS_INVALID_PARAMETER; } } @@ -1252,24 +1227,11 @@ ssize_t receive_smb_raw(int fd, len = MIN(len,maxlen); } - set_smb_read_error(pre, SMB_READ_OK); - status = read_socket_with_timeout( fd, buffer+4, len, len, timeout, &len); if (!NT_STATUS_IS_OK(status)) { - if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) { - set_smb_read_error(pre, SMB_READ_EOF); - return -1; - } - - if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { - set_smb_read_error(pre, SMB_READ_TIMEOUT); - return -1; - } - - set_smb_read_error(pre, SMB_READ_ERROR); - return -1; + return status; } /* not all of samba3 properly checks for packet-termination @@ -1278,7 +1240,8 @@ ssize_t receive_smb_raw(int fd, SSVAL(buffer+4,len, 0); } - return len; + *p_len = len; + return NT_STATUS_OK; } /**************************************************************************** -- cgit From b42a5d68a3ffd88fd60c64b6a75fe2d687d9c92d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 26 Jan 2008 10:39:21 +0100 Subject: Convert read_data() to NTSTATUS (This used to be commit af40b71023f8c4a2133d996ea698c72b97624043) --- source3/lib/util_sock.c | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index ede2cdae71..25d539cace 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1046,30 +1046,9 @@ NTSTATUS read_socket_with_timeout(int fd, char *buf, Read data from the client, reading exactly N bytes. ****************************************************************************/ -ssize_t read_data(int fd,char *buffer,size_t N, enum smb_read_errors *pre) +NTSTATUS read_data(int fd, char *buffer, size_t N) { - NTSTATUS status; - - set_smb_read_error(pre, SMB_READ_OK); - - status = read_socket_with_timeout(fd, buffer, N, N, 0, NULL); - - if (NT_STATUS_IS_OK(status)) { - return N; - } - - if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) { - set_smb_read_error(pre, SMB_READ_EOF); - return -1; - } - - if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { - set_smb_read_error(pre, SMB_READ_TIMEOUT); - return -1; - } - - set_smb_read_error(pre, SMB_READ_ERROR); - return -1; + return read_socket_with_timeout(fd, buffer, N, N, 0, NULL); } /**************************************************************************** -- cgit From abe2fd76977d472b044f30b522aa9c114db089fc Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 5 Feb 2008 22:17:20 +0100 Subject: Fix a debug message (This used to be commit 24aa3518aef7e36fde03d58f36487cbf29c027c9) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 25d539cace..71d48d6053 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1130,7 +1130,7 @@ NTSTATUS read_smb_length_return_keepalive(int fd, char *inbuf, DEBUG(5,("Got keepalive packet\n")); } - DEBUG(10,("got smb length of %lu\n",(unsigned long)len)); + DEBUG(10,("got smb length of %lu\n",(unsigned long)(*len))); return NT_STATUS_OK; } -- cgit From abf84656593c567e42025eaf6b1961a2294f913b Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 18 Feb 2008 10:43:46 +1100 Subject: Fix possible close of invalid fd if call to socket() returns -1. (This used to be commit f7d2f692994918037e603ef95dd097b03d2c5456) --- source3/lib/util_sock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 71d48d6053..e040f4631a 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1933,7 +1933,8 @@ int create_pipe_sock(const char *socket_dir, out_close: SAFE_FREE(path); - close(sock); + if (sock != -1) + close(sock); out_umask: umask(old_umask); -- cgit From 317639287886181edf08ccecad1b324e4cc55d0b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 25 Feb 2008 15:24:49 +0100 Subject: Fix some warnings warning: ignoring return value of 'asprintf', declared with attribute warn_unused_result (This used to be commit ad37b7b0aee265a3e4d8b7552610f4b9a105434d) --- source3/lib/util_sock.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index e040f4631a..a7c35c4887 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1904,8 +1904,7 @@ int create_pipe_sock(const char *socket_dir, goto out_close; } - asprintf(&path, "%s/%s", socket_dir, socket_name); - if (!path) { + if (asprintf(&path, "%s/%s", socket_dir, socket_name) == -1) { goto out_close; } -- cgit From e9c2515df0ac92e275da3dcd62de6cc50009bf6e Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 29 Feb 2008 13:35:16 +0100 Subject: Eliminate tons of build warnings on non-IPV6 system. Michael (This used to be commit ee4810099c2d26a0ebab3c41a95bc6b57921683d) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index a7c35c4887..2a65943872 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -370,7 +370,7 @@ void in_addr_to_sockaddr_storage(struct sockaddr_storage *ss, Convert an IPv6 struct in_addr to a struct sockaddr_storage. ********************************************************************/ -void in6_addr_to_sockaddr_storage(struct sockaddr_storage *ss, + void in6_addr_to_sockaddr_storage(struct sockaddr_storage *ss, struct in6_addr ip) { struct sockaddr_in6 *sa = (struct sockaddr_in6 *)ss; -- cgit From a5e1910f82228bc779508e3977a05ec553d99a01 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 16 Mar 2008 12:23:44 -0700 Subject: Fix Coverity ID 567 Jeremy, please push it if you like it and mark the bug as fixed on the Coverity site. Thanks, Volker (This used to be commit 2fd25423700cb60f20a8b8d6613279cb06fb518d) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 2a65943872..65625138ba 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -63,7 +63,7 @@ bool is_ipaddress(const char *str) sizeof(addr))); sp = addr; } - ret = inet_pton(AF_INET6, addr, &dest6); + ret = inet_pton(AF_INET6, sp, &dest6); if (ret > 0) { return true; } -- cgit From 22d7cd6605b156ca74011b4c05ed47018e7dce7a Mon Sep 17 00:00:00 2001 From: "Gerald (Jerry) Carter" Date: Mon, 24 Mar 2008 14:48:29 -0500 Subject: Ignore port when pulling IP addr from struct sockaddr_storage. Linux man page states that getaddinfo() will leave the port uninitialized when passing in NULL for the service name. So we can't really trust that anymore. I doubt non-default KDC ports are an issues so just drop the port from the generated krb5.conf. AIX exhibits this bug the most. (This used to be commit 36f8bafbd3dee66a869aa26cfc2eb4aa62019325) --- source3/lib/util_sock.c | 44 ++++++++++---------------------------------- 1 file changed, 10 insertions(+), 34 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 65625138ba..8ceabe19b2 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -108,9 +108,13 @@ static bool interpret_string_addr_internal(struct addrinfo **ppres, hints.ai_socktype = SOCK_STREAM; hints.ai_flags = flags; + /* Linux man page on getaddinfo() says port will be + uninitialized when service string in NULL */ + ret = getaddrinfo(str, NULL, &hints, ppres); + if (ret) { DEBUG(3,("interpret_string_addr_internal: getaddrinfo failed " "for name %s [%s]\n", @@ -541,50 +545,22 @@ char *print_canonical_sockaddr(TALLOC_CTX *ctx, char *dest = NULL; int ret; + /* Linux getnameinfo() man pages says port is unitialized if + service name is NULL. */ + ret = sys_getnameinfo((const struct sockaddr *)pss, sizeof(struct sockaddr_storage), addr, sizeof(addr), NULL, 0, NI_NUMERICHOST); - if (ret) { + if (ret != 0) { return NULL; } - if (pss->ss_family != AF_INET) { #if defined(HAVE_IPV6) - /* IPv6 */ - const struct sockaddr_in6 *sa6 = - (const struct sockaddr_in6 *)pss; - uint16_t port = ntohs(sa6->sin6_port); - - if (port) { - dest = talloc_asprintf(ctx, - "[%s]:%d", - addr, - (unsigned int)port); - } else { - dest = talloc_asprintf(ctx, - "[%s]", - addr); - } + dest = talloc_asprintf(ctx, "[%s]", addr); #else - return NULL; + dest = talloc_asprintf(ctx, "%s", addr); #endif - } else { - const struct sockaddr_in *sa = - (const struct sockaddr_in *)pss; - uint16_t port = ntohs(sa->sin_port); - - if (port) { - dest = talloc_asprintf(ctx, - "%s:%d", - addr, - (unsigned int)port); - } else { - dest = talloc_asprintf(ctx, - "%s", - addr); - } - } return dest; } -- cgit From f4f0d39bfa929f8127505d318667010750c421ca Mon Sep 17 00:00:00 2001 From: "Gerald W. Carter" Date: Wed, 26 Mar 2008 16:58:27 -0500 Subject: Fix a bug in the output from print_canonical_sockaddr() fix from 36f8bafbd3dee66a8.... Make sure that IPv4 addresses are not enclised in []'s. (This used to be commit 4ddf58dbdc3d74cb72788ef4a2ec7587d4948c40) --- source3/lib/util_sock.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 8ceabe19b2..30a3b83be7 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -556,11 +556,17 @@ char *print_canonical_sockaddr(TALLOC_CTX *ctx, if (ret != 0) { return NULL; } + + if (pss->ss_family != AF_INET) { #if defined(HAVE_IPV6) - dest = talloc_asprintf(ctx, "[%s]", addr); + dest = talloc_asprintf(ctx, "[%s]", addr); #else - dest = talloc_asprintf(ctx, "%s", addr); + return NULL; #endif + } else { + dest = talloc_asprintf(ctx, "%s", addr); + } + return dest; } -- cgit From b6e9fffaa2cdb45533cf8fd751a4a857124e5a2c Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Mon, 7 Apr 2008 11:22:14 +0200 Subject: increase log level for this failed setsockopt call. EINVAL is a normal error on Solaris when we do this on an already resetted connection. (This used to be commit 42bc4ff7fd6bfc92bde015ae8f3a9fb62d443cd5) --- source3/lib/util_sock.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 30a3b83be7..f252377b7e 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -837,7 +837,10 @@ void set_socket_options(int fd, const char *options) } if (ret != 0) { - DEBUG(0,("Failed to set socket option %s (Error %s)\n", + /* be aware that some systems like Solaris return + * EINVAL to a setsockopt() call when the client + * sent a RST previously - no need to worry */ + DEBUG(2,("Failed to set socket option %s (Error %s)\n", tok, strerror(errno) )); } } -- cgit From d36434f31268b75040311352f23c92c9a61e8cda Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 28 May 2008 09:31:42 -0700 Subject: Security fix for CVE-2008-1105: Boundary failure when parsing SMB responses can result in a buffer overrun. Jeremy. (This used to be commit 23b825e9d2c74c5b940cf4d3aa56c18692259972) --- source3/lib/util_sock.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index f252377b7e..b2a1ece5db 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1151,16 +1151,15 @@ NTSTATUS read_smb_length(int fd, char *inbuf, unsigned int timeout, } /**************************************************************************** - Read an smb from a fd. Note that the buffer *MUST* be of size - BUFFER_SIZE+SAFETY_MARGIN. + Read an smb from a fd. The timeout is in milliseconds. This function will return on receipt of a session keepalive packet. maxlen is the max number of bytes to return, not including the 4 byte - length. If zero it means BUFFER_SIZE+SAFETY_MARGIN limit. + length. If zero it means buflen limit. Doesn't check the MAC on signed packets. ****************************************************************************/ -NTSTATUS receive_smb_raw(int fd, char *buffer, unsigned int timeout, +NTSTATUS receive_smb_raw(int fd, char *buffer, size_t buflen, unsigned int timeout, size_t maxlen, size_t *p_len) { size_t len; @@ -1173,17 +1172,10 @@ NTSTATUS receive_smb_raw(int fd, char *buffer, unsigned int timeout, return status; } - /* - * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes - * of header. Don't print the error if this fits.... JRA. - */ - - if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) { + if (len > buflen) { DEBUG(0,("Invalid packet length! (%lu bytes).\n", (unsigned long)len)); - if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) { - return NT_STATUS_INVALID_PARAMETER; - } + return NT_STATUS_INVALID_PARAMETER; } if(len > 0) { -- cgit From 272690bda864d04e9e95e103393fb51d1affc334 Mon Sep 17 00:00:00 2001 From: Zach Loafman Date: Mon, 7 Jul 2008 19:30:47 -0700 Subject: Minor style correction Set sin[6]_family instead of ss_family in in[6]_addr_to_sockaddr_storage so that assignments look like they're going to the same place. (This used to be commit 3d19112f645fb0f4bb6b644207ed2cee0b6b3ea9) --- source3/lib/util_sock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index b2a1ece5db..822ff26331 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -365,7 +365,7 @@ void in_addr_to_sockaddr_storage(struct sockaddr_storage *ss, { struct sockaddr_in *sa = (struct sockaddr_in *)ss; memset(ss, '\0', sizeof(*ss)); - ss->ss_family = AF_INET; + sa->sin_family = AF_INET; sa->sin_addr = ip; } @@ -379,7 +379,7 @@ void in_addr_to_sockaddr_storage(struct sockaddr_storage *ss, { struct sockaddr_in6 *sa = (struct sockaddr_in6 *)ss; memset(ss, '\0', sizeof(*ss)); - ss->ss_family = AF_INET6; + sa->sin6_family = AF_INET6; sa->sin6_addr = ip; } #endif -- cgit From 06d0790c0799112b89534a646e78d0cb38b06e20 Mon Sep 17 00:00:00 2001 From: Zach Loafman Date: Thu, 3 Jul 2008 22:53:42 -0700 Subject: Fix various build warnings This fixes various build warnings on our platform. I'm sure I haven't caught them all, but it's a start. (This used to be commit 6b73f259cb67d9dda9127907d706f9244a871fa3) --- source3/lib/util_sock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 822ff26331..7356b3ec35 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -43,9 +43,9 @@ bool is_ipaddress_v4(const char *str) bool is_ipaddress(const char *str) { +#if defined(HAVE_IPV6) int ret = -1; -#if defined(HAVE_IPV6) if (strchr_m(str, ':')) { char addr[INET6_ADDRSTRLEN]; struct in6_addr dest6; @@ -212,9 +212,9 @@ bool interpret_string_addr(struct sockaddr_storage *pss, const char *str, int flags) { - char addr[INET6_ADDRSTRLEN]; struct addrinfo *res = NULL; #if defined(HAVE_IPV6) + char addr[INET6_ADDRSTRLEN]; unsigned int scope_id = 0; if (strchr_m(str, ':')) { -- cgit From 304554115a2f2dc316386a9ea5bec237d67f595f Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Wed, 3 Sep 2008 15:31:39 -0700 Subject: Cleanup of DC enumeration in get_dcs() This is a fix for a few small inefficiencies/bugs in the get_dcs() path. * because the third add_one_dc_unique() loop was outside the ADS check all DCs returned from the non-sitename lookup were being tacked onto the dc_name_ip list twice. * add_one_dc_unique() now checks if the given IP address already exists before adding it to the list, making the returned list actually unique * added more thorough doxygen comment headers (This used to be commit cb2d488e1dbd90953c496c5e25d648977884f7e3) --- source3/lib/util_sock.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'source3/lib/util_sock.c') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 7356b3ec35..e20768ed89 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1379,11 +1379,22 @@ int open_socket_out(int type, return res; } -/**************************************************************************** - Create an outgoing TCP socket to any of the addrs. This is for - simultaneous connects to port 445 and 139 of a host or even a variety - of DC's all of which are equivalent for our purposes. -**************************************************************************/ +/******************************************************************* + Create an outgoing TCP socket to the first addr that connects. + + This is for simultaneous connection attempts to port 445 and 139 of a host + or for simultatneous connection attempts to multiple DCs at once. We return + a socket fd of the first successful connection. + + @param[in] addrs list of Internet addresses and ports to connect to + @param[in] num_addrs number of address/port pairs in the addrs list + @param[in] timeout time after which we stop waiting for a socket connection + to succeed, given in milliseconds + @param[out] fd_index the entry in addrs which we successfully connected to + @param[out] fd fd of the open and connected socket + @return true on a successful connection, false if all connection attempts + failed or we timed out +*******************************************************************/ bool open_any_socket_out(struct sockaddr_storage *addrs, int num_addrs, int timeout, int *fd_index, int *fd) -- cgit