if we are adding a new sambaAccount, make sure that we add a
[Samba.git] / source / lib / util_sock.c
blob8f5efcab786b85d951ce11b16f8eaa38b4629ef2
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 Samba utility functions
5 Copyright (C) Andrew Tridgell 1992-1998
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "includes.h"
24 #ifdef WITH_SSL
25 #include <openssl/ssl.h>
26 #undef Realloc /* SSLeay defines this and samba has a function of this name */
27 extern SSL *ssl;
28 extern int sslFd;
29 #endif /* WITH_SSL */
31 /* the last IP received from */
32 struct in_addr lastip;
34 /* the last port received from */
35 int lastport=0;
37 int smb_read_error = 0;
39 /****************************************************************************
40 Determine if a file descriptor is in fact a socket.
41 ****************************************************************************/
43 BOOL is_a_socket(int fd)
45 int v;
46 socklen_t l;
47 l = sizeof(int);
48 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
51 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
53 typedef struct smb_socket_option {
54 char *name;
55 int level;
56 int option;
57 int value;
58 int opttype;
59 } smb_socket_option;
61 smb_socket_option socket_options[] = {
62 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
63 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
64 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
65 #ifdef TCP_NODELAY
66 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
67 #endif
68 #ifdef IPTOS_LOWDELAY
69 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
70 #endif
71 #ifdef IPTOS_THROUGHPUT
72 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
73 #endif
74 #ifdef SO_REUSEPORT
75 {"SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT, 0, OPT_BOOL},
76 #endif
77 #ifdef SO_SNDBUF
78 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
79 #endif
80 #ifdef SO_RCVBUF
81 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
82 #endif
83 #ifdef SO_SNDLOWAT
84 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
85 #endif
86 #ifdef SO_RCVLOWAT
87 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
88 #endif
89 #ifdef SO_SNDTIMEO
90 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
91 #endif
92 #ifdef SO_RCVTIMEO
93 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
94 #endif
95 {NULL,0,0,0,0}};
97 /****************************************************************************
98 Print socket options.
99 ****************************************************************************/
101 static void print_socket_options(int s)
103 int value;
104 socklen_t vlen = 4;
105 smb_socket_option *p = &socket_options[0];
107 for (; p->name != NULL; p++) {
108 if (getsockopt(s, p->level, p->option, (void *)&value, &vlen) == -1) {
109 DEBUG(5,("Could not test socket option %s.\n", p->name));
110 } else {
111 DEBUG(5,("socket option %s = %d\n",p->name,value));
116 /****************************************************************************
117 Set user socket options.
118 ****************************************************************************/
120 void set_socket_options(int fd, char *options)
122 fstring tok;
124 while (next_token(&options,tok," \t,", sizeof(tok))) {
125 int ret=0,i;
126 int value = 1;
127 char *p;
128 BOOL got_value = False;
130 if ((p = strchr(tok,'='))) {
131 *p = 0;
132 value = atoi(p+1);
133 got_value = True;
136 for (i=0;socket_options[i].name;i++)
137 if (strequal(socket_options[i].name,tok))
138 break;
140 if (!socket_options[i].name) {
141 DEBUG(0,("Unknown socket option %s\n",tok));
142 continue;
145 switch (socket_options[i].opttype) {
146 case OPT_BOOL:
147 case OPT_INT:
148 ret = setsockopt(fd,socket_options[i].level,
149 socket_options[i].option,(char *)&value,sizeof(int));
150 break;
152 case OPT_ON:
153 if (got_value)
154 DEBUG(0,("syntax error - %s does not take a value\n",tok));
157 int on = socket_options[i].value;
158 ret = setsockopt(fd,socket_options[i].level,
159 socket_options[i].option,(char *)&on,sizeof(int));
161 break;
164 if (ret != 0)
165 DEBUG(0,("Failed to set socket option %s (Error %s)\n",tok, strerror(errno) ));
168 print_socket_options(fd);
171 /****************************************************************************
172 Read from a socket.
173 ****************************************************************************/
175 ssize_t read_udp_socket(int fd,char *buf,size_t len)
177 ssize_t ret;
178 struct sockaddr_in sock;
179 socklen_t socklen = sizeof(sock);
181 memset((char *)&sock,'\0',socklen);
182 memset((char *)&lastip,'\0',sizeof(lastip));
183 ret = (ssize_t)sys_recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen);
184 if (ret <= 0) {
185 DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
186 return(0);
189 lastip = sock.sin_addr;
190 lastport = ntohs(sock.sin_port);
192 DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n",
193 inet_ntoa(lastip), lastport, ret));
195 return(ret);
198 /****************************************************************************
199 Read data from a socket with a timout in msec.
200 mincount = if timeout, minimum to read before returning
201 maxcount = number to be read.
202 time_out = timeout in milliseconds
203 ****************************************************************************/
205 static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out)
207 fd_set fds;
208 int selrtn;
209 ssize_t readret;
210 size_t nread = 0;
211 struct timeval timeout;
213 /* just checking .... */
214 if (maxcnt <= 0)
215 return(0);
217 smb_read_error = 0;
219 /* Blocking read */
220 if (time_out <= 0) {
221 if (mincnt == 0) mincnt = maxcnt;
223 while (nread < mincnt) {
224 #ifdef WITH_SSL
225 if(fd == sslFd){
226 readret = SSL_read(ssl, buf + nread, maxcnt - nread);
227 }else{
228 readret = sys_read(fd, buf + nread, maxcnt - nread);
230 #else /* WITH_SSL */
231 readret = sys_read(fd, buf + nread, maxcnt - nread);
232 #endif /* WITH_SSL */
234 if (readret == 0) {
235 DEBUG(5,("read_socket_with_timeout: blocking read. EOF from client.\n"));
236 smb_read_error = READ_EOF;
237 return -1;
240 if (readret == -1) {
241 DEBUG(0,("read_socket_with_timeout: read error = %s.\n", strerror(errno) ));
242 smb_read_error = READ_ERROR;
243 return -1;
245 nread += readret;
247 return((ssize_t)nread);
250 /* Most difficult - timeout read */
251 /* If this is ever called on a disk file and
252 mincnt is greater then the filesize then
253 system performance will suffer severely as
254 select always returns true on disk files */
256 /* Set initial timeout */
257 timeout.tv_sec = (time_t)(time_out / 1000);
258 timeout.tv_usec = (long)(1000 * (time_out % 1000));
260 for (nread=0; nread < mincnt; ) {
261 FD_ZERO(&fds);
262 FD_SET(fd,&fds);
264 selrtn = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout);
266 /* Check if error */
267 if(selrtn == -1) {
268 /* something is wrong. Maybe the socket is dead? */
269 DEBUG(0,("read_socket_with_timeout: timeout read. select error = %s.\n", strerror(errno) ));
270 smb_read_error = READ_ERROR;
271 return -1;
274 /* Did we timeout ? */
275 if (selrtn == 0) {
276 DEBUG(10,("read_socket_with_timeout: timeout read. select timed out.\n"));
277 smb_read_error = READ_TIMEOUT;
278 return -1;
281 #ifdef WITH_SSL
282 if(fd == sslFd){
283 readret = SSL_read(ssl, buf + nread, maxcnt - nread);
284 }else{
285 readret = sys_read(fd, buf + nread, maxcnt - nread);
287 #else /* WITH_SSL */
288 readret = sys_read(fd, buf+nread, maxcnt-nread);
289 #endif /* WITH_SSL */
291 if (readret == 0) {
292 /* we got EOF on the file descriptor */
293 DEBUG(5,("read_socket_with_timeout: timeout read. EOF from client.\n"));
294 smb_read_error = READ_EOF;
295 return -1;
298 if (readret == -1) {
299 /* the descriptor is probably dead */
300 DEBUG(0,("read_socket_with_timeout: timeout read. read error = %s.\n", strerror(errno) ));
301 smb_read_error = READ_ERROR;
302 return -1;
305 nread += readret;
308 /* Return the number we got */
309 return((ssize_t)nread);
312 /****************************************************************************
313 Read data from a fd with a timout in msec.
314 mincount = if timeout, minimum to read before returning
315 maxcount = number to be read.
316 time_out = timeout in milliseconds
317 ****************************************************************************/
319 ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out)
321 fd_set fds;
322 int selrtn;
323 ssize_t readret;
324 size_t nread = 0;
325 struct timeval timeout;
327 /* just checking .... */
328 if (maxcnt <= 0)
329 return(0);
331 /* Blocking read */
332 if (time_out <= 0) {
333 if (mincnt == 0) mincnt = maxcnt;
335 while (nread < mincnt) {
336 #ifdef WITH_SSL
337 if(fd == sslFd){
338 readret = SSL_read(ssl, buf + nread, maxcnt - nread);
339 }else{
340 readret = sys_read(fd, buf + nread, maxcnt - nread);
342 #else /* WITH_SSL */
343 readret = sys_read(fd, buf + nread, maxcnt - nread);
344 #endif /* WITH_SSL */
346 if (readret <= 0)
347 return readret;
349 nread += readret;
351 return((ssize_t)nread);
354 /* Most difficult - timeout read */
355 /* If this is ever called on a disk file and
356 mincnt is greater then the filesize then
357 system performance will suffer severely as
358 select always returns true on disk files */
360 /* Set initial timeout */
361 timeout.tv_sec = (time_t)(time_out / 1000);
362 timeout.tv_usec = (long)(1000 * (time_out % 1000));
364 for (nread=0; nread < mincnt; ) {
365 FD_ZERO(&fds);
366 FD_SET(fd,&fds);
368 selrtn = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout);
370 if(selrtn <= 0)
371 return selrtn;
373 #ifdef WITH_SSL
374 if(fd == sslFd){
375 readret = SSL_read(ssl, buf + nread, maxcnt - nread);
376 }else{
377 readret = sys_read(fd, buf + nread, maxcnt - nread);
379 #else /* WITH_SSL */
380 readret = sys_read(fd, buf+nread, maxcnt-nread);
381 #endif /* WITH_SSL */
383 if (readret <= 0)
384 return readret;
386 nread += readret;
389 /* Return the number we got */
390 return((ssize_t)nread);
393 /****************************************************************************
394 send a keepalive packet (rfc1002)
395 ****************************************************************************/
397 BOOL send_keepalive(int client)
399 unsigned char buf[4];
401 buf[0] = 0x85;
402 buf[1] = buf[2] = buf[3] = 0;
404 return(write_socket_data(client,(char *)buf,4) == 4);
407 /****************************************************************************
408 read data from the client, reading exactly N bytes.
409 ****************************************************************************/
411 ssize_t read_data(int fd,char *buffer,size_t N)
413 ssize_t ret;
414 size_t total=0;
416 smb_read_error = 0;
418 while (total < N) {
419 #ifdef WITH_SSL
420 if(fd == sslFd){
421 ret = SSL_read(ssl, buffer + total, N - total);
422 }else{
423 ret = sys_read(fd,buffer + total,N - total);
425 #else /* WITH_SSL */
426 ret = sys_read(fd,buffer + total,N - total);
427 #endif /* WITH_SSL */
429 if (ret == 0) {
430 DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) ));
431 smb_read_error = READ_EOF;
432 return 0;
435 if (ret == -1) {
436 DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) ));
437 smb_read_error = READ_ERROR;
438 return -1;
440 total += ret;
442 return (ssize_t)total;
445 /****************************************************************************
446 Write data to a fd.
447 ****************************************************************************/
449 ssize_t write_data(int fd,char *buffer,size_t N)
451 size_t total=0;
452 ssize_t ret;
454 while (total < N) {
455 #ifdef WITH_SSL
456 if(fd == sslFd){
457 ret = SSL_write(ssl,buffer + total,N - total);
458 } else {
459 ret = sys_write(fd,buffer + total,N - total);
461 #else /* WITH_SSL */
462 ret = sys_write(fd,buffer + total,N - total);
463 #endif /* WITH_SSL */
465 if (ret == -1) {
466 DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) ));
467 return -1;
469 if (ret == 0)
470 return (ssize_t)total;
472 total += (size_t)ret;
475 return (ssize_t)total;
478 /****************************************************************************
479 Write data to a socket - use send rather than write.
480 ****************************************************************************/
482 ssize_t write_socket_data(int fd,char *buffer,size_t N)
484 size_t total=0;
485 ssize_t ret;
487 while (total < N) {
488 #ifdef WITH_SSL
489 if(fd == sslFd){
490 ret = SSL_write(ssl,buffer + total,N - total);
491 }else{
492 ret = sys_send(fd,buffer + total,N - total, 0);
494 #else /* WITH_SSL */
495 ret = sys_send(fd,buffer + total,N - total,0);
496 #endif /* WITH_SSL */
498 if (ret == -1) {
499 DEBUG(0,("write_socket_data: write failure. Error = %s\n", strerror(errno) ));
500 return -1;
502 if (ret == 0)
503 return (ssize_t)total;
505 total += ret;
507 return (ssize_t)total;
510 /****************************************************************************
511 write to a socket
512 ****************************************************************************/
514 ssize_t write_socket(int fd,char *buf,size_t len)
516 ssize_t ret=0;
518 DEBUG(6,("write_socket(%d,%d)\n",fd,(int)len));
519 ret = write_socket_data(fd,buf,len);
521 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,(int)len,(int)ret));
522 if(ret <= 0)
523 DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n",
524 (int)len, fd, strerror(errno) ));
526 return(ret);
529 /****************************************************************************
530 read 4 bytes of a smb packet and return the smb length of the packet
531 store the result in the buffer
532 This version of the function will return a length of zero on receiving
533 a keepalive packet.
534 timeout is in milliseconds.
535 ****************************************************************************/
537 static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int timeout)
539 ssize_t len=0;
540 int msg_type;
541 BOOL ok = False;
543 while (!ok) {
544 if (timeout > 0)
545 ok = (read_socket_with_timeout(fd,inbuf,4,4,timeout) == 4);
546 else
547 ok = (read_data(fd,inbuf,4) == 4);
549 if (!ok)
550 return(-1);
552 len = smb_len(inbuf);
553 msg_type = CVAL(inbuf,0);
555 if (msg_type == 0x85)
556 DEBUG(5,("Got keepalive packet\n"));
559 DEBUG(10,("got smb length of %d\n",len));
561 return(len);
564 /****************************************************************************
565 read 4 bytes of a smb packet and return the smb length of the packet
566 store the result in the buffer. This version of the function will
567 never return a session keepalive (length of zero).
568 timeout is in milliseconds.
569 ****************************************************************************/
571 ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout)
573 ssize_t len;
575 for(;;) {
576 len = read_smb_length_return_keepalive(fd, inbuf, timeout);
578 if(len < 0)
579 return len;
581 /* Ignore session keepalives. */
582 if(CVAL(inbuf,0) != 0x85)
583 break;
586 DEBUG(10,("read_smb_length: got smb length of %d\n",len));
588 return len;
591 /****************************************************************************
592 read an smb from a fd. Note that the buffer *MUST* be of size
593 BUFFER_SIZE+SAFETY_MARGIN.
594 The timeout is in milliseconds.
595 This function will return on a
596 receipt of a session keepalive packet.
597 ****************************************************************************/
599 BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
601 ssize_t len,ret;
603 smb_read_error = 0;
605 memset(buffer,'\0',smb_size + 100);
607 len = read_smb_length_return_keepalive(fd,buffer,timeout);
608 if (len < 0) {
609 DEBUG(10,("receive_smb: length < 0 !\n"));
612 * Correct fix. smb_read_error may have already been
613 * set. Only set it here if not already set. Global
614 * variables still suck :-). JRA.
617 if (smb_read_error == 0)
618 smb_read_error = READ_ERROR;
619 return(False);
623 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
624 * of header. Don't print the error if this fits.... JRA.
627 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
628 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
629 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) {
632 * Correct fix. smb_read_error may have already been
633 * set. Only set it here if not already set. Global
634 * variables still suck :-). JRA.
637 if (smb_read_error == 0)
638 smb_read_error = READ_ERROR;
639 return False;
643 if(len > 0) {
644 ret = read_data(fd,buffer+4,len);
645 if (ret != len) {
646 if (smb_read_error == 0)
647 smb_read_error = READ_ERROR;
648 return False;
652 return(True);
655 /****************************************************************************
656 read an smb from a fd ignoring all keepalive packets. Note that the buffer
657 *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN.
658 The timeout is in milliseconds
660 This is exactly the same as receive_smb except that it never returns
661 a session keepalive packet (just as receive_smb used to do).
662 receive_smb was changed to return keepalives as the oplock processing means this call
663 should never go into a blocking read.
664 ****************************************************************************/
666 BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout)
668 BOOL ret;
670 for(;;)
672 ret = receive_smb(fd, buffer, timeout);
674 if (!ret)
676 DEBUG(10,("client_receive_smb failed\n"));
677 show_msg(buffer);
678 return ret;
681 /* Ignore session keepalive packets. */
682 if(CVAL(buffer,0) != 0x85)
683 break;
685 show_msg(buffer);
686 return ret;
689 /****************************************************************************
690 send an smb to a fd
691 ****************************************************************************/
693 BOOL send_smb(int fd,char *buffer)
695 size_t len;
696 size_t nwritten=0;
697 ssize_t ret;
698 len = smb_len(buffer) + 4;
700 while (nwritten < len) {
701 ret = write_socket(fd,buffer+nwritten,len - nwritten);
702 if (ret <= 0) {
703 DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n",
704 (int)len,(int)ret, strerror(errno) ));
705 return False;
707 nwritten += ret;
710 return True;
713 /****************************************************************************
714 send a single packet to a port on another machine
715 ****************************************************************************/
717 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
719 BOOL ret;
720 int out_fd;
721 struct sockaddr_in sock_out;
723 /* create a socket to write to */
724 out_fd = socket(AF_INET, type, 0);
725 if (out_fd == -1)
727 DEBUG(0,("socket failed"));
728 return False;
731 /* set the address and port */
732 memset((char *)&sock_out,'\0',sizeof(sock_out));
733 putip((char *)&sock_out.sin_addr,(char *)&ip);
734 sock_out.sin_port = htons( port );
735 sock_out.sin_family = AF_INET;
737 if (DEBUGLEVEL > 0)
738 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
739 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
741 /* send it */
742 ret = (sys_sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
744 if (!ret)
745 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
746 inet_ntoa(ip),port,strerror(errno)));
748 close(out_fd);
749 return(ret);
752 /****************************************************************************
753 Open a socket of the specified type, port, and address for incoming data.
754 ****************************************************************************/
756 int open_socket_in( int type, int port, int dlevel, uint32 socket_addr, BOOL rebind )
758 struct sockaddr_in sock;
759 int res;
761 memset( (char *)&sock, '\0', sizeof(sock) );
763 #ifdef HAVE_SOCK_SIN_LEN
764 sock.sin_len = sizeof(sock);
765 #endif
766 sock.sin_port = htons( port );
767 sock.sin_family = AF_INET;
768 sock.sin_addr.s_addr = socket_addr;
770 res = socket( AF_INET, type, 0 );
771 if( res == -1 ) {
772 if( DEBUGLVL(0) ) {
773 dbgtext( "open_socket_in(): socket() call failed: " );
774 dbgtext( "%s\n", strerror( errno ) );
776 return -1;
779 /* This block sets/clears the SO_REUSEADDR and possibly SO_REUSEPORT. */
781 int val = rebind ? 1 : 0;
782 if( setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val)) == -1 ) {
783 if( DEBUGLVL( dlevel ) ) {
784 dbgtext( "open_socket_in(): setsockopt: " );
785 dbgtext( "SO_REUSEADDR = %s ", val?"True":"False" );
786 dbgtext( "on port %d failed ", port );
787 dbgtext( "with error = %s\n", strerror(errno) );
790 #ifdef SO_REUSEPORT
791 if( setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val)) == -1 ) {
792 if( DEBUGLVL( dlevel ) ) {
793 dbgtext( "open_socket_in(): setsockopt: ");
794 dbgtext( "SO_REUSEPORT = %s ", val?"True":"False" );
795 dbgtext( "on port %d failed ", port );
796 dbgtext( "with error = %s\n", strerror(errno) );
799 #endif /* SO_REUSEPORT */
802 /* now we've got a socket - we need to bind it */
803 if( bind( res, (struct sockaddr *)&sock, sizeof(sock) ) == -1 ) {
804 if( DEBUGLVL(dlevel) && (port == SMB_PORT || port == NMB_PORT) ) {
805 dbgtext( "bind failed on port %d ", port );
806 dbgtext( "socket_addr = %s.\n", inet_ntoa( sock.sin_addr ) );
807 dbgtext( "Error = %s\n", strerror(errno) );
809 close( res );
810 return( -1 );
813 DEBUG( 3, ( "bind succeeded on port %d\n", port ) );
815 return( res );
818 /****************************************************************************
819 create an outgoing socket. timeout is in milliseconds.
820 **************************************************************************/
822 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
824 struct sockaddr_in sock_out;
825 int res,ret;
826 int connect_loop = 250; /* 250 milliseconds */
827 int loops = (timeout) / connect_loop;
829 /* create a socket to write to */
830 res = socket(PF_INET, type, 0);
831 if (res == -1)
832 { DEBUG(0,("socket error\n")); return -1; }
834 if (type != SOCK_STREAM) return(res);
836 memset((char *)&sock_out,'\0',sizeof(sock_out));
837 putip((char *)&sock_out.sin_addr,(char *)addr);
839 sock_out.sin_port = htons( port );
840 sock_out.sin_family = PF_INET;
842 /* set it non-blocking */
843 set_blocking(res,False);
845 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
847 /* and connect it to the destination */
848 connect_again:
849 ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
851 /* Some systems return EAGAIN when they mean EINPROGRESS */
852 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
853 errno == EAGAIN) && loops--) {
854 msleep(connect_loop);
855 goto connect_again;
858 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
859 errno == EAGAIN)) {
860 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
861 close(res);
862 return -1;
865 #ifdef EISCONN
866 if (ret < 0 && errno == EISCONN) {
867 errno = 0;
868 ret = 0;
870 #endif
872 if (ret < 0) {
873 DEBUG(2,("error connecting to %s:%d (%s)\n",
874 inet_ntoa(*addr),port,strerror(errno)));
875 close(res);
876 return -1;
879 /* set it blocking again */
880 set_blocking(res,True);
882 return res;
885 /* the following 3 client_*() functions are nasty ways of allowing
886 some generic functions to get info that really should be hidden in
887 particular modules */
888 static int client_fd = -1;
890 void client_setfd(int fd)
892 client_fd = fd;
895 char *client_name(void)
897 return get_socket_name(client_fd);
900 char *client_addr(void)
902 return get_socket_addr(client_fd);
905 /*******************************************************************
906 matchname - determine if host name matches IP address. Used to
907 confirm a hostname lookup to prevent spoof attacks
908 ******************************************************************/
909 static BOOL matchname(char *remotehost,struct in_addr addr)
911 struct hostent *hp;
912 int i;
914 if ((hp = sys_gethostbyname(remotehost)) == 0) {
915 DEBUG(0,("sys_gethostbyname(%s): lookup failure.\n", remotehost));
916 return False;
920 * Make sure that gethostbyname() returns the "correct" host name.
921 * Unfortunately, gethostbyname("localhost") sometimes yields
922 * "localhost.domain". Since the latter host name comes from the
923 * local DNS, we just have to trust it (all bets are off if the local
924 * DNS is perverted). We always check the address list, though.
927 if (strcasecmp(remotehost, hp->h_name)
928 && strcasecmp(remotehost, "localhost")) {
929 DEBUG(0,("host name/name mismatch: %s != %s\n",
930 remotehost, hp->h_name));
931 return False;
934 /* Look up the host address in the address list we just got. */
935 for (i = 0; hp->h_addr_list[i]; i++) {
936 if (memcmp(hp->h_addr_list[i], (void *) & addr, sizeof(addr)) == 0)
937 return True;
941 * The host name does not map to the original host address. Perhaps
942 * someone has compromised a name server. More likely someone botched
943 * it, but that could be dangerous, too.
946 DEBUG(0,("host name/address mismatch: %s != %s\n",
947 inet_ntoa(addr), hp->h_name));
948 return False;
952 /*******************************************************************
953 return the DNS name of the remote end of a socket
954 ******************************************************************/
955 char *get_socket_name(int fd)
957 static pstring name_buf;
958 static fstring addr_buf;
959 struct hostent *hp;
960 struct in_addr addr;
961 char *p;
963 p = get_socket_addr(fd);
965 /* it might be the same as the last one - save some DNS work */
966 if (strcmp(p, addr_buf) == 0) return name_buf;
968 pstrcpy(name_buf,"UNKNOWN");
969 if (fd == -1) return name_buf;
971 fstrcpy(addr_buf, p);
973 addr = *interpret_addr2(p);
975 /* Look up the remote host name. */
976 if ((hp = gethostbyaddr((char *)&addr.s_addr, sizeof(addr.s_addr), AF_INET)) == 0) {
977 DEBUG(1,("Gethostbyaddr failed for %s\n",p));
978 pstrcpy(name_buf, p);
979 } else {
980 pstrcpy(name_buf,(char *)hp->h_name);
981 if (!matchname(name_buf, addr)) {
982 DEBUG(0,("Matchname failed on %s %s\n",name_buf,p));
983 pstrcpy(name_buf,"UNKNOWN");
987 alpha_strcpy(name_buf, name_buf, "_-.", sizeof(name_buf));
988 if (strstr(name_buf,"..")) {
989 pstrcpy(name_buf, "UNKNOWN");
992 return name_buf;
995 /*******************************************************************
996 return the IP addr of the remote end of a socket as a string
997 ******************************************************************/
998 char *get_socket_addr(int fd)
1000 struct sockaddr sa;
1001 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
1002 socklen_t length = sizeof(sa);
1003 static fstring addr_buf;
1005 fstrcpy(addr_buf,"0.0.0.0");
1007 if (fd == -1) {
1008 return addr_buf;
1011 if (getpeername(fd, &sa, &length) < 0) {
1012 DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) ));
1013 return addr_buf;
1016 fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
1018 return addr_buf;
1021 /*******************************************************************
1022 Create protected unix domain socket.
1024 some unixen cannot set permissions on a ux-dom-sock, so we
1025 have to make sure that the directory contains the protection
1026 permissions, instead.
1027 ******************************************************************/
1028 int create_pipe_sock(const char *socket_dir,
1029 const char *socket_name,
1030 mode_t dir_perms)
1032 struct sockaddr_un sunaddr;
1033 struct stat st;
1034 int sock;
1035 mode_t old_umask;
1036 pstring path;
1038 /* Create the socket directory or reuse the existing one */
1040 if (lstat(socket_dir, &st) == -1) {
1042 if (errno == ENOENT) {
1044 /* Create directory */
1046 if (mkdir(socket_dir, dir_perms) == -1) {
1047 DEBUG(0, ("error creating socket directory "
1048 "%s: %s\n", socket_dir,
1049 strerror(errno)));
1050 return -1;
1053 } else {
1055 DEBUG(0, ("lstat failed on socket directory %s: %s\n",
1056 socket_dir, strerror(errno)));
1057 return -1;
1060 } else {
1062 /* Check ownership and permission on existing directory */
1064 if (!S_ISDIR(st.st_mode)) {
1065 DEBUG(0, ("socket directory %s isn't a directory\n",
1066 socket_dir));
1067 return -1;
1070 if ((st.st_uid != sec_initial_uid()) ||
1071 ((st.st_mode & 0777) != dir_perms)) {
1072 DEBUG(0, ("invalid permissions on socket directory "
1073 "%s\n", socket_dir));
1074 return -1;
1078 /* Create the socket file */
1080 old_umask = umask(0);
1082 sock = socket(AF_UNIX, SOCK_STREAM, 0);
1084 if (sock == -1) {
1085 perror("socket");
1086 umask(old_umask);
1087 return -1;
1090 snprintf(path, sizeof(path), "%s/%s", socket_dir, socket_name);
1092 unlink(path);
1093 memset(&sunaddr, 0, sizeof(sunaddr));
1094 sunaddr.sun_family = AF_UNIX;
1095 safe_strcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)-1);
1097 if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) {
1098 DEBUG(0, ("bind failed on pipe socket %s: %s\n",
1099 path,
1100 strerror(errno)));
1101 close(sock);
1102 umask(old_umask);
1103 return -1;
1106 if (listen(sock, 5) == -1) {
1107 DEBUG(0, ("listen failed on pipe socket %s: %s\n",
1108 path,
1109 strerror(errno)));
1110 close(sock);
1111 umask(old_umask);
1112 return -1;
1115 umask(old_umask);
1117 /* Success! */
1119 return sock;
1122 /*******************************************************************
1123 this is like socketpair but uses tcp. It is used by the Samba
1124 regression test code
1125 The function guarantees that nobody else can attach to the socket,
1126 or if they do that this function fails and the socket gets closed
1127 returns 0 on success, -1 on failure
1128 the resulting file descriptors are symmetrical
1129 ******************************************************************/
1130 static int socketpair_tcp(int fd[2])
1132 int listener;
1133 struct sockaddr_in sock;
1134 struct sockaddr_in sock2;
1135 socklen_t socklen = sizeof(sock);
1136 int connect_done = 0;
1138 fd[0] = fd[1] = listener = -1;
1140 memset(&sock, 0, sizeof(sock));
1142 if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
1144 memset(&sock2, 0, sizeof(sock2));
1145 #ifdef HAVE_SOCK_SIN_LEN
1146 sock2.sin_len = sizeof(sock2);
1147 #endif
1148 sock2.sin_family = PF_INET;
1150 bind(listener, (struct sockaddr *)&sock2, sizeof(sock2));
1152 if (listen(listener, 1) != 0) goto failed;
1154 if (getsockname(listener, (struct sockaddr *)&sock, &socklen) != 0) goto failed;
1156 if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
1158 set_blocking(fd[1], 0);
1160 sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1162 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) {
1163 if (errno != EINPROGRESS) goto failed;
1164 } else {
1165 connect_done = 1;
1168 if ((fd[0] = accept(listener, (struct sockaddr *)&sock, &socklen)) == -1) goto failed;
1170 close(listener);
1171 if (connect_done == 0) {
1172 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0
1173 && errno != EISCONN) goto failed;
1176 set_blocking(fd[1], 1);
1178 /* all OK! */
1179 return 0;
1181 failed:
1182 if (fd[0] != -1) close(fd[0]);
1183 if (fd[1] != -1) close(fd[1]);
1184 if (listener != -1) close(listener);
1185 return -1;
1189 /*******************************************************************
1190 run a program on a local tcp socket, this is used to launch smbd
1191 when regression testing
1192 the return value is a socket which is attached to a subprocess
1193 running "prog". stdin and stdout are attached. stderr is left
1194 attached to the original stderr
1195 ******************************************************************/
1196 int sock_exec(const char *prog)
1198 int fd[2];
1199 if (socketpair_tcp(fd) != 0) {
1200 DEBUG(0,("socketpair_tcp failed (%s)\n", strerror(errno)));
1201 return -1;
1203 if (fork() == 0) {
1204 close(fd[0]);
1205 close(0);
1206 close(1);
1207 dup(fd[1]);
1208 dup(fd[1]);
1209 exit(system(prog));
1211 close(fd[1]);
1212 return fd[0];