2 Unix SMB/CIFS implementation.
3 Samba utility functions
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Tim Potter 2000-2001
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.
24 /* the last IP received from */
25 struct in_addr lastip
;
27 /* the last port received from */
30 int smb_read_error
= 0;
32 /****************************************************************************
33 Determine if a file descriptor is in fact a socket.
34 ****************************************************************************/
36 BOOL
is_a_socket(int fd
)
40 return(getsockopt(fd
, SOL_SOCKET
, SO_TYPE
, (char *)&v
, &l
) == 0);
43 enum SOCK_OPT_TYPES
{OPT_BOOL
,OPT_INT
,OPT_ON
};
45 typedef struct smb_socket_option
{
53 static const smb_socket_option socket_options
[] = {
54 {"SO_KEEPALIVE", SOL_SOCKET
, SO_KEEPALIVE
, 0, OPT_BOOL
},
55 {"SO_REUSEADDR", SOL_SOCKET
, SO_REUSEADDR
, 0, OPT_BOOL
},
56 {"SO_BROADCAST", SOL_SOCKET
, SO_BROADCAST
, 0, OPT_BOOL
},
58 {"TCP_NODELAY", IPPROTO_TCP
, TCP_NODELAY
, 0, OPT_BOOL
},
61 {"IPTOS_LOWDELAY", IPPROTO_IP
, IP_TOS
, IPTOS_LOWDELAY
, OPT_ON
},
63 #ifdef IPTOS_THROUGHPUT
64 {"IPTOS_THROUGHPUT", IPPROTO_IP
, IP_TOS
, IPTOS_THROUGHPUT
, OPT_ON
},
67 {"SO_REUSEPORT", SOL_SOCKET
, SO_REUSEPORT
, 0, OPT_BOOL
},
70 {"SO_SNDBUF", SOL_SOCKET
, SO_SNDBUF
, 0, OPT_INT
},
73 {"SO_RCVBUF", SOL_SOCKET
, SO_RCVBUF
, 0, OPT_INT
},
76 {"SO_SNDLOWAT", SOL_SOCKET
, SO_SNDLOWAT
, 0, OPT_INT
},
79 {"SO_RCVLOWAT", SOL_SOCKET
, SO_RCVLOWAT
, 0, OPT_INT
},
82 {"SO_SNDTIMEO", SOL_SOCKET
, SO_SNDTIMEO
, 0, OPT_INT
},
85 {"SO_RCVTIMEO", SOL_SOCKET
, SO_RCVTIMEO
, 0, OPT_INT
},
89 /****************************************************************************
91 ****************************************************************************/
93 static void print_socket_options(int s
)
96 const smb_socket_option
*p
= &socket_options
[0];
98 /* wrapped in if statement to prevent streams leak in SCO Openserver 5.0 */
99 /* reported on samba-technical --jerry */
100 if ( DEBUGLEVEL
>= 5 ) {
101 for (; p
->name
!= NULL
; p
++) {
102 if (getsockopt(s
, p
->level
, p
->option
, (void *)&value
, &vlen
) == -1) {
103 DEBUG(5,("Could not test socket option %s.\n", p
->name
));
105 DEBUG(5,("socket option %s = %d\n",p
->name
,value
));
111 /****************************************************************************
112 Set user socket options.
113 ****************************************************************************/
115 void set_socket_options(int fd
, const char *options
)
119 while (next_token(&options
,tok
," \t,", sizeof(tok
))) {
123 BOOL got_value
= False
;
125 if ((p
= strchr_m(tok
,'='))) {
131 for (i
=0;socket_options
[i
].name
;i
++)
132 if (strequal(socket_options
[i
].name
,tok
))
135 if (!socket_options
[i
].name
) {
136 DEBUG(0,("Unknown socket option %s\n",tok
));
140 switch (socket_options
[i
].opttype
) {
143 ret
= setsockopt(fd
,socket_options
[i
].level
,
144 socket_options
[i
].option
,(char *)&value
,sizeof(int));
149 DEBUG(0,("syntax error - %s does not take a value\n",tok
));
152 int on
= socket_options
[i
].value
;
153 ret
= setsockopt(fd
,socket_options
[i
].level
,
154 socket_options
[i
].option
,(char *)&on
,sizeof(int));
160 DEBUG(0,("Failed to set socket option %s (Error %s)\n",tok
, strerror(errno
) ));
163 print_socket_options(fd
);
166 /****************************************************************************
168 ****************************************************************************/
170 ssize_t
read_udp_socket(int fd
,char *buf
,size_t len
)
173 struct sockaddr_in sock
;
174 socklen_t socklen
= sizeof(sock
);
176 memset((char *)&sock
,'\0',socklen
);
177 memset((char *)&lastip
,'\0',sizeof(lastip
));
178 ret
= (ssize_t
)sys_recvfrom(fd
,buf
,len
,0,(struct sockaddr
*)&sock
,&socklen
);
180 DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno
)));
184 lastip
= sock
.sin_addr
;
185 lastport
= ntohs(sock
.sin_port
);
187 DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n",
188 inet_ntoa(lastip
), lastport
, ret
));
193 /****************************************************************************
194 Read data from a socket with a timout in msec.
195 mincount = if timeout, minimum to read before returning
196 maxcount = number to be read.
197 time_out = timeout in milliseconds
198 ****************************************************************************/
200 ssize_t
read_socket_with_timeout(int fd
,char *buf
,size_t mincnt
,size_t maxcnt
,unsigned int time_out
)
206 struct timeval timeout
;
208 /* just checking .... */
216 if (mincnt
== 0) mincnt
= maxcnt
;
218 while (nread
< mincnt
) {
219 readret
= sys_read(fd
, buf
+ nread
, maxcnt
- nread
);
222 DEBUG(5,("read_socket_with_timeout: blocking read. EOF from client.\n"));
223 smb_read_error
= READ_EOF
;
228 DEBUG(0,("read_socket_with_timeout: read error = %s.\n", strerror(errno
) ));
229 smb_read_error
= READ_ERROR
;
234 return((ssize_t
)nread
);
237 /* Most difficult - timeout read */
238 /* If this is ever called on a disk file and
239 mincnt is greater then the filesize then
240 system performance will suffer severely as
241 select always returns true on disk files */
243 /* Set initial timeout */
244 timeout
.tv_sec
= (time_t)(time_out
/ 1000);
245 timeout
.tv_usec
= (long)(1000 * (time_out
% 1000));
247 for (nread
=0; nread
< mincnt
; ) {
251 selrtn
= sys_select_intr(fd
+1,&fds
,NULL
,NULL
,&timeout
);
255 /* something is wrong. Maybe the socket is dead? */
256 DEBUG(0,("read_socket_with_timeout: timeout read. select error = %s.\n", strerror(errno
) ));
257 smb_read_error
= READ_ERROR
;
261 /* Did we timeout ? */
263 DEBUG(10,("read_socket_with_timeout: timeout read. select timed out.\n"));
264 smb_read_error
= READ_TIMEOUT
;
268 readret
= sys_read(fd
, buf
+nread
, maxcnt
-nread
);
271 /* we got EOF on the file descriptor */
272 DEBUG(5,("read_socket_with_timeout: timeout read. EOF from client.\n"));
273 smb_read_error
= READ_EOF
;
278 /* the descriptor is probably dead */
279 DEBUG(0,("read_socket_with_timeout: timeout read. read error = %s.\n", strerror(errno
) ));
280 smb_read_error
= READ_ERROR
;
287 /* Return the number we got */
288 return (ssize_t
)nread
;
291 /****************************************************************************
292 read data from the client, reading exactly N bytes.
293 ****************************************************************************/
295 ssize_t
read_data(int fd
,char *buffer
,size_t N
)
303 ret
= sys_read(fd
,buffer
+ total
,N
- total
);
306 DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", (int)(N
- total
), strerror(errno
) ));
307 smb_read_error
= READ_EOF
;
312 DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N
- total
), strerror(errno
) ));
313 smb_read_error
= READ_ERROR
;
318 return (ssize_t
)total
;
321 /****************************************************************************
322 Read data from a socket, reading exactly N bytes.
323 ****************************************************************************/
325 static ssize_t
read_socket_data(int fd
,char *buffer
,size_t N
)
333 ret
= sys_read(fd
,buffer
+ total
,N
- total
);
336 DEBUG(10,("read_socket_data: recv of %d returned 0. Error = %s\n", (int)(N
- total
), strerror(errno
) ));
337 smb_read_error
= READ_EOF
;
342 DEBUG(0,("read_socket_data: recv failure for %d. Error = %s\n", (int)(N
- total
), strerror(errno
) ));
343 smb_read_error
= READ_ERROR
;
348 return (ssize_t
)total
;
351 /****************************************************************************
353 ****************************************************************************/
355 ssize_t
write_data(int fd
,char *buffer
,size_t N
)
361 ret
= sys_write(fd
,buffer
+ total
,N
- total
);
364 DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno
) ));
372 return (ssize_t
)total
;
375 /****************************************************************************
376 Write data to a socket - use send rather than write.
377 ****************************************************************************/
379 static ssize_t
write_socket_data(int fd
,char *buffer
,size_t N
)
385 ret
= sys_send(fd
,buffer
+ total
,N
- total
,0);
388 DEBUG(0,("write_socket_data: write failure. Error = %s\n", strerror(errno
) ));
396 return (ssize_t
)total
;
399 /****************************************************************************
401 ****************************************************************************/
403 ssize_t
write_socket(int fd
,char *buf
,size_t len
)
407 DEBUG(6,("write_socket(%d,%d)\n",fd
,(int)len
));
408 ret
= write_socket_data(fd
,buf
,len
);
410 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd
,(int)len
,(int)ret
));
412 DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n",
413 (int)len
, fd
, strerror(errno
) ));
418 /****************************************************************************
419 send a keepalive packet (rfc1002)
420 ****************************************************************************/
422 BOOL
send_keepalive(int client
)
424 unsigned char buf
[4];
426 buf
[0] = SMBkeepalive
;
427 buf
[1] = buf
[2] = buf
[3] = 0;
429 return(write_socket_data(client
,(char *)buf
,4) == 4);
433 /****************************************************************************
434 read 4 bytes of a smb packet and return the smb length of the packet
435 store the result in the buffer
436 This version of the function will return a length of zero on receiving
438 timeout is in milliseconds.
439 ****************************************************************************/
441 static ssize_t
read_smb_length_return_keepalive(int fd
,char *inbuf
,unsigned int timeout
)
449 ok
= (read_socket_with_timeout(fd
,inbuf
,4,4,timeout
) == 4);
451 ok
= (read_socket_data(fd
,inbuf
,4) == 4);
456 len
= smb_len(inbuf
);
457 msg_type
= CVAL(inbuf
,0);
459 if (msg_type
== SMBkeepalive
)
460 DEBUG(5,("Got keepalive packet\n"));
463 DEBUG(10,("got smb length of %d\n",len
));
468 /****************************************************************************
469 read 4 bytes of a smb packet and return the smb length of the packet
470 store the result in the buffer. This version of the function will
471 never return a session keepalive (length of zero).
472 timeout is in milliseconds.
473 ****************************************************************************/
475 ssize_t
read_smb_length(int fd
,char *inbuf
,unsigned int timeout
)
480 len
= read_smb_length_return_keepalive(fd
, inbuf
, timeout
);
485 /* Ignore session keepalives. */
486 if(CVAL(inbuf
,0) != SMBkeepalive
)
490 DEBUG(10,("read_smb_length: got smb length of %d\n",len
));
495 /****************************************************************************
496 read an smb from a fd. Note that the buffer *MUST* be of size
497 BUFFER_SIZE+SAFETY_MARGIN.
498 The timeout is in milliseconds.
499 This function will return on a
500 receipt of a session keepalive packet.
501 ****************************************************************************/
503 BOOL
receive_smb(int fd
,char *buffer
, unsigned int timeout
)
509 memset(buffer
,'\0',smb_size
+ 100);
511 len
= read_smb_length_return_keepalive(fd
,buffer
,timeout
);
513 DEBUG(10,("receive_smb: length < 0!\n"));
516 * Correct fix. smb_read_error may have already been
517 * set. Only set it here if not already set. Global
518 * variables still suck :-). JRA.
521 if (smb_read_error
== 0)
522 smb_read_error
= READ_ERROR
;
527 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
528 * of header. Don't print the error if this fits.... JRA.
531 if (len
> (BUFFER_SIZE
+ LARGE_WRITEX_HDR_SIZE
)) {
532 DEBUG(0,("Invalid packet length! (%d bytes).\n",len
));
533 if (len
> BUFFER_SIZE
+ (SAFETY_MARGIN
/2)) {
536 * Correct fix. smb_read_error may have already been
537 * set. Only set it here if not already set. Global
538 * variables still suck :-). JRA.
541 if (smb_read_error
== 0)
542 smb_read_error
= READ_ERROR
;
548 ret
= read_socket_data(fd
,buffer
+4,len
);
550 if (smb_read_error
== 0)
551 smb_read_error
= READ_ERROR
;
559 /****************************************************************************
561 ****************************************************************************/
563 BOOL
send_smb(int fd
,char *buffer
)
568 len
= smb_len(buffer
) + 4;
570 while (nwritten
< len
) {
571 ret
= write_socket(fd
,buffer
+nwritten
,len
- nwritten
);
573 DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n",
574 (int)len
,(int)ret
, strerror(errno
) ));
583 /****************************************************************************
584 Open a socket of the specified type, port, and address for incoming data.
585 ****************************************************************************/
587 int open_socket_in( int type
, int port
, int dlevel
, uint32 socket_addr
, BOOL rebind
)
589 struct sockaddr_in sock
;
592 memset( (char *)&sock
, '\0', sizeof(sock
) );
594 #ifdef HAVE_SOCK_SIN_LEN
595 sock
.sin_len
= sizeof(sock
);
597 sock
.sin_port
= htons( port
);
598 sock
.sin_family
= AF_INET
;
599 sock
.sin_addr
.s_addr
= socket_addr
;
601 res
= socket( AF_INET
, type
, 0 );
604 dbgtext( "open_socket_in(): socket() call failed: " );
605 dbgtext( "%s\n", strerror( errno
) );
610 /* This block sets/clears the SO_REUSEADDR and possibly SO_REUSEPORT. */
612 int val
= rebind
? 1 : 0;
613 if( setsockopt(res
,SOL_SOCKET
,SO_REUSEADDR
,(char *)&val
,sizeof(val
)) == -1 ) {
614 if( DEBUGLVL( dlevel
) ) {
615 dbgtext( "open_socket_in(): setsockopt: " );
616 dbgtext( "SO_REUSEADDR = %s ", val
?"True":"False" );
617 dbgtext( "on port %d failed ", port
);
618 dbgtext( "with error = %s\n", strerror(errno
) );
622 if( setsockopt(res
,SOL_SOCKET
,SO_REUSEPORT
,(char *)&val
,sizeof(val
)) == -1 ) {
623 if( DEBUGLVL( dlevel
) ) {
624 dbgtext( "open_socket_in(): setsockopt: ");
625 dbgtext( "SO_REUSEPORT = %s ", val
?"True":"False" );
626 dbgtext( "on port %d failed ", port
);
627 dbgtext( "with error = %s\n", strerror(errno
) );
630 #endif /* SO_REUSEPORT */
633 /* now we've got a socket - we need to bind it */
634 if( bind( res
, (struct sockaddr
*)&sock
, sizeof(sock
) ) == -1 ) {
635 if( DEBUGLVL(dlevel
) && (port
== SMB_PORT1
|| port
== SMB_PORT2
|| port
== NMB_PORT
) ) {
636 dbgtext( "bind failed on port %d ", port
);
637 dbgtext( "socket_addr = %s.\n", inet_ntoa( sock
.sin_addr
) );
638 dbgtext( "Error = %s\n", strerror(errno
) );
644 DEBUG( 10, ( "bind succeeded on port %d\n", port
) );
649 /****************************************************************************
650 create an outgoing socket. timeout is in milliseconds.
651 **************************************************************************/
653 int open_socket_out(int type
, struct in_addr
*addr
, int port
,int timeout
)
655 struct sockaddr_in sock_out
;
657 int connect_loop
= 250; /* 250 milliseconds */
658 int loops
= (timeout
) / connect_loop
;
660 /* create a socket to write to */
661 res
= socket(PF_INET
, type
, 0);
663 { DEBUG(0,("socket error\n")); return -1; }
665 if (type
!= SOCK_STREAM
) return(res
);
667 memset((char *)&sock_out
,'\0',sizeof(sock_out
));
668 putip((char *)&sock_out
.sin_addr
,(char *)addr
);
670 sock_out
.sin_port
= htons( port
);
671 sock_out
.sin_family
= PF_INET
;
673 /* set it non-blocking */
674 set_blocking(res
,False
);
676 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr
),port
));
678 /* and connect it to the destination */
680 ret
= connect(res
,(struct sockaddr
*)&sock_out
,sizeof(sock_out
));
682 /* Some systems return EAGAIN when they mean EINPROGRESS */
683 if (ret
< 0 && (errno
== EINPROGRESS
|| errno
== EALREADY
||
684 errno
== EAGAIN
) && loops
--) {
685 msleep(connect_loop
);
689 if (ret
< 0 && (errno
== EINPROGRESS
|| errno
== EALREADY
||
691 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr
),port
));
697 if (ret
< 0 && errno
== EISCONN
) {
704 DEBUG(2,("error connecting to %s:%d (%s)\n",
705 inet_ntoa(*addr
),port
,strerror(errno
)));
710 /* set it blocking again */
711 set_blocking(res
,True
);
717 open a connected UDP socket to host on port
719 int open_udp_socket(const char *host
, int port
)
721 int type
= SOCK_DGRAM
;
722 struct sockaddr_in sock_out
;
724 struct in_addr
*addr
;
726 addr
= interpret_addr2(host
);
728 res
= socket(PF_INET
, type
, 0);
733 memset((char *)&sock_out
,'\0',sizeof(sock_out
));
734 putip((char *)&sock_out
.sin_addr
,(char *)addr
);
735 sock_out
.sin_port
= htons(port
);
736 sock_out
.sin_family
= PF_INET
;
738 if (connect(res
,(struct sockaddr
*)&sock_out
,sizeof(sock_out
))) {
747 /* the following 3 client_*() functions are nasty ways of allowing
748 some generic functions to get info that really should be hidden in
749 particular modules */
750 static int client_fd
= -1;
752 void client_setfd(int fd
)
757 char *client_name(void)
759 return get_socket_name(client_fd
,False
);
762 char *client_addr(void)
764 return get_socket_addr(client_fd
);
767 /*******************************************************************
768 matchname - determine if host name matches IP address. Used to
769 confirm a hostname lookup to prevent spoof attacks
770 ******************************************************************/
771 static BOOL
matchname(char *remotehost
,struct in_addr addr
)
776 if ((hp
= sys_gethostbyname(remotehost
)) == 0) {
777 DEBUG(0,("sys_gethostbyname(%s): lookup failure.\n", remotehost
));
782 * Make sure that gethostbyname() returns the "correct" host name.
783 * Unfortunately, gethostbyname("localhost") sometimes yields
784 * "localhost.domain". Since the latter host name comes from the
785 * local DNS, we just have to trust it (all bets are off if the local
786 * DNS is perverted). We always check the address list, though.
789 if (strcasecmp(remotehost
, hp
->h_name
)
790 && strcasecmp(remotehost
, "localhost")) {
791 DEBUG(0,("host name/name mismatch: %s != %s\n",
792 remotehost
, hp
->h_name
));
796 /* Look up the host address in the address list we just got. */
797 for (i
= 0; hp
->h_addr_list
[i
]; i
++) {
798 if (memcmp(hp
->h_addr_list
[i
], (char *) & addr
, sizeof(addr
)) == 0)
803 * The host name does not map to the original host address. Perhaps
804 * someone has compromised a name server. More likely someone botched
805 * it, but that could be dangerous, too.
808 DEBUG(0,("host name/address mismatch: %s != %s\n",
809 inet_ntoa(addr
), hp
->h_name
));
814 /*******************************************************************
815 return the DNS name of the remote end of a socket
816 ******************************************************************/
817 char *get_socket_name(int fd
, BOOL force_lookup
)
819 static pstring name_buf
;
820 static fstring addr_buf
;
825 /* reverse lookups can be *very* expensive, and in many
826 situations won't work because many networks don't link dhcp
827 with dns. To avoid the delay we avoid the lookup if
829 if (!lp_hostname_lookups() && (force_lookup
== False
)) {
830 return get_socket_addr(fd
);
833 p
= get_socket_addr(fd
);
835 /* it might be the same as the last one - save some DNS work */
836 if (strcmp(p
, addr_buf
) == 0) return name_buf
;
838 pstrcpy(name_buf
,"UNKNOWN");
839 if (fd
== -1) return name_buf
;
841 fstrcpy(addr_buf
, p
);
843 addr
= *interpret_addr2(p
);
845 /* Look up the remote host name. */
846 if ((hp
= gethostbyaddr((char *)&addr
.s_addr
, sizeof(addr
.s_addr
), AF_INET
)) == 0) {
847 DEBUG(1,("Gethostbyaddr failed for %s\n",p
));
848 pstrcpy(name_buf
, p
);
850 pstrcpy(name_buf
,(char *)hp
->h_name
);
851 if (!matchname(name_buf
, addr
)) {
852 DEBUG(0,("Matchname failed on %s %s\n",name_buf
,p
));
853 pstrcpy(name_buf
,"UNKNOWN");
857 alpha_strcpy(name_buf
, name_buf
, "_-.", sizeof(name_buf
));
858 if (strstr(name_buf
,"..")) {
859 pstrcpy(name_buf
, "UNKNOWN");
865 /*******************************************************************
866 return the IP addr of the remote end of a socket as a string
867 ******************************************************************/
868 char *get_socket_addr(int fd
)
871 struct sockaddr_in
*sockin
= (struct sockaddr_in
*) (&sa
);
872 int length
= sizeof(sa
);
873 static fstring addr_buf
;
875 fstrcpy(addr_buf
,"0.0.0.0");
881 if (getpeername(fd
, &sa
, &length
) < 0) {
882 DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno
) ));
886 fstrcpy(addr_buf
,(char *)inet_ntoa(sockin
->sin_addr
));
892 /*******************************************************************
893 Create protected unix domain socket.
895 Some unixes cannot set permissions on a ux-dom-sock, so we
896 have to make sure that the directory contains the protection
898 ******************************************************************/
900 int create_pipe_sock(const char *socket_dir
,
901 const char *socket_name
,
904 #ifdef HAVE_UNIXSOCKET
905 struct sockaddr_un sunaddr
;
911 old_umask
= umask(0);
913 /* Create the socket directory or reuse the existing one */
915 if (lstat(socket_dir
, &st
) == -1) {
916 if (errno
== ENOENT
) {
917 /* Create directory */
918 if (mkdir(socket_dir
, dir_perms
) == -1) {
919 DEBUG(0, ("error creating socket directory "
920 "%s: %s\n", socket_dir
,
925 DEBUG(0, ("lstat failed on socket directory %s: %s\n",
926 socket_dir
, strerror(errno
)));
930 /* Check ownership and permission on existing directory */
931 if (!S_ISDIR(st
.st_mode
)) {
932 DEBUG(0, ("socket directory %s isn't a directory\n",
936 if ((st
.st_uid
!= sec_initial_uid()) ||
937 ((st
.st_mode
& 0777) != dir_perms
)) {
938 DEBUG(0, ("invalid permissions on socket directory "
939 "%s\n", socket_dir
));
944 /* Create the socket file */
946 sock
= socket(AF_UNIX
, SOCK_STREAM
, 0);
953 snprintf(path
, sizeof(path
), "%s/%s", socket_dir
, socket_name
);
956 memset(&sunaddr
, 0, sizeof(sunaddr
));
957 sunaddr
.sun_family
= AF_UNIX
;
958 safe_strcpy(sunaddr
.sun_path
, path
, sizeof(sunaddr
.sun_path
)-1);
960 if (bind(sock
, (struct sockaddr
*)&sunaddr
, sizeof(sunaddr
)) == -1) {
961 DEBUG(0, ("bind failed on pipe socket %s: %s\n", path
,
966 if (listen(sock
, 5) == -1) {
967 DEBUG(0, ("listen failed on pipe socket %s: %s\n", path
,
983 DEBUG(0, ("create_pipe_sock: No Unix sockets on this system\n"));
985 #endif /* HAVE_UNIXSOCKET */
988 /*******************************************************************
989 this is like socketpair but uses tcp. It is used by the Samba
991 The function guarantees that nobody else can attach to the socket,
992 or if they do that this function fails and the socket gets closed
993 returns 0 on success, -1 on failure
994 the resulting file descriptors are symmetrical
995 ******************************************************************/
996 static int socketpair_tcp(int fd
[2])
999 struct sockaddr_in sock
;
1000 struct sockaddr_in sock2
;
1001 socklen_t socklen
= sizeof(sock
);
1002 int connect_done
= 0;
1004 fd
[0] = fd
[1] = listener
= -1;
1006 memset(&sock
, 0, sizeof(sock
));
1008 if ((listener
= socket(PF_INET
, SOCK_STREAM
, 0)) == -1) goto failed
;
1010 memset(&sock2
, 0, sizeof(sock2
));
1011 #ifdef HAVE_SOCK_SIN_LEN
1012 sock2
.sin_len
= sizeof(sock2
);
1014 sock2
.sin_family
= PF_INET
;
1016 bind(listener
, (struct sockaddr
*)&sock2
, sizeof(sock2
));
1018 if (listen(listener
, 1) != 0) goto failed
;
1020 if (getsockname(listener
, (struct sockaddr
*)&sock
, &socklen
) != 0) goto failed
;
1022 if ((fd
[1] = socket(PF_INET
, SOCK_STREAM
, 0)) == -1) goto failed
;
1024 set_blocking(fd
[1], 0);
1026 sock
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
1028 if (connect(fd
[1],(struct sockaddr
*)&sock
,sizeof(sock
)) == -1) {
1029 if (errno
!= EINPROGRESS
) goto failed
;
1034 if ((fd
[0] = accept(listener
, (struct sockaddr
*)&sock
, &socklen
)) == -1) goto failed
;
1037 if (connect_done
== 0) {
1038 if (connect(fd
[1],(struct sockaddr
*)&sock
,sizeof(sock
)) != 0
1039 && errno
!= EISCONN
) goto failed
;
1042 set_blocking(fd
[1], 1);
1048 if (fd
[0] != -1) close(fd
[0]);
1049 if (fd
[1] != -1) close(fd
[1]);
1050 if (listener
!= -1) close(listener
);
1055 /*******************************************************************
1056 run a program on a local tcp socket, this is used to launch smbd
1057 when regression testing
1058 the return value is a socket which is attached to a subprocess
1059 running "prog". stdin and stdout are attached. stderr is left
1060 attached to the original stderr
1061 ******************************************************************/
1062 int sock_exec(const char *prog
)
1065 if (socketpair_tcp(fd
) != 0) {
1066 DEBUG(0,("socketpair_tcp failed (%s)\n", strerror(errno
)));