5460bf57b89eecc3ce644b206b0a73183fd759ad
[kai/samba.git] / source3 / lib / util_sock.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Samba utility functions
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Tim Potter      2000-2001
6    
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.
11    
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.
16    
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.
20 */
21
22 #include "includes.h"
23
24 /* the last IP received from */
25 struct in_addr lastip;
26
27 /* the last port received from */
28 int lastport=0;
29
30 int smb_read_error = 0;
31
32 /****************************************************************************
33  Determine if a file descriptor is in fact a socket.
34 ****************************************************************************/
35
36 BOOL is_a_socket(int fd)
37 {
38         int v,l;
39         l = sizeof(int);
40         return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
41 }
42
43 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
44
45 typedef struct smb_socket_option {
46         const char *name;
47         int level;
48         int option;
49         int value;
50         int opttype;
51 } smb_socket_option;
52
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},
57 #ifdef TCP_NODELAY
58   {"TCP_NODELAY",       IPPROTO_TCP,   TCP_NODELAY,     0,                 OPT_BOOL},
59 #endif
60 #ifdef IPTOS_LOWDELAY
61   {"IPTOS_LOWDELAY",    IPPROTO_IP,    IP_TOS,          IPTOS_LOWDELAY,    OPT_ON},
62 #endif
63 #ifdef IPTOS_THROUGHPUT
64   {"IPTOS_THROUGHPUT",  IPPROTO_IP,    IP_TOS,          IPTOS_THROUGHPUT,  OPT_ON},
65 #endif
66 #ifdef SO_REUSEPORT
67   {"SO_REUSEPORT",      SOL_SOCKET,    SO_REUSEPORT,    0,                 OPT_BOOL},
68 #endif
69 #ifdef SO_SNDBUF
70   {"SO_SNDBUF",         SOL_SOCKET,    SO_SNDBUF,       0,                 OPT_INT},
71 #endif
72 #ifdef SO_RCVBUF
73   {"SO_RCVBUF",         SOL_SOCKET,    SO_RCVBUF,       0,                 OPT_INT},
74 #endif
75 #ifdef SO_SNDLOWAT
76   {"SO_SNDLOWAT",       SOL_SOCKET,    SO_SNDLOWAT,     0,                 OPT_INT},
77 #endif
78 #ifdef SO_RCVLOWAT
79   {"SO_RCVLOWAT",       SOL_SOCKET,    SO_RCVLOWAT,     0,                 OPT_INT},
80 #endif
81 #ifdef SO_SNDTIMEO
82   {"SO_SNDTIMEO",       SOL_SOCKET,    SO_SNDTIMEO,     0,                 OPT_INT},
83 #endif
84 #ifdef SO_RCVTIMEO
85   {"SO_RCVTIMEO",       SOL_SOCKET,    SO_RCVTIMEO,     0,                 OPT_INT},
86 #endif
87   {NULL,0,0,0,0}};
88
89 /****************************************************************************
90  Print socket options.
91 ****************************************************************************/
92
93 static void print_socket_options(int s)
94 {
95         int value, vlen = 4;
96         const smb_socket_option *p = &socket_options[0];
97
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));
104                 } else {
105                         DEBUG(5,("socket option %s = %d\n",p->name,value));
106                         }
107                 }
108         }
109  }
110
111 /****************************************************************************
112  Set user socket options.
113 ****************************************************************************/
114
115 void set_socket_options(int fd, const char *options)
116 {
117         fstring tok;
118
119         while (next_token(&options,tok," \t,", sizeof(tok))) {
120                 int ret=0,i;
121                 int value = 1;
122                 char *p;
123                 BOOL got_value = False;
124
125                 if ((p = strchr_m(tok,'='))) {
126                         *p = 0;
127                         value = atoi(p+1);
128                         got_value = True;
129                 }
130
131                 for (i=0;socket_options[i].name;i++)
132                         if (strequal(socket_options[i].name,tok))
133                                 break;
134
135                 if (!socket_options[i].name) {
136                         DEBUG(0,("Unknown socket option %s\n",tok));
137                         continue;
138                 }
139
140                 switch (socket_options[i].opttype) {
141                 case OPT_BOOL:
142                 case OPT_INT:
143                         ret = setsockopt(fd,socket_options[i].level,
144                                                 socket_options[i].option,(char *)&value,sizeof(int));
145                         break;
146
147                 case OPT_ON:
148                         if (got_value)
149                                 DEBUG(0,("syntax error - %s does not take a value\n",tok));
150
151                         {
152                                 int on = socket_options[i].value;
153                                 ret = setsockopt(fd,socket_options[i].level,
154                                                         socket_options[i].option,(char *)&on,sizeof(int));
155                         }
156                         break;    
157                 }
158       
159                 if (ret != 0)
160                         DEBUG(0,("Failed to set socket option %s (Error %s)\n",tok, strerror(errno) ));
161         }
162
163         print_socket_options(fd);
164 }
165
166 /****************************************************************************
167  Read from a socket.
168 ****************************************************************************/
169
170 ssize_t read_udp_socket(int fd,char *buf,size_t len)
171 {
172         ssize_t ret;
173         struct sockaddr_in sock;
174         socklen_t socklen = sizeof(sock);
175
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);
179         if (ret <= 0) {
180                 DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
181                 return(0);
182         }
183
184         lastip = sock.sin_addr;
185         lastport = ntohs(sock.sin_port);
186
187         DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n",
188                         inet_ntoa(lastip), lastport, ret));
189
190         return(ret);
191 }
192
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 ****************************************************************************/
199
200 ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out)
201 {
202         fd_set fds;
203         int selrtn;
204         ssize_t readret;
205         size_t nread = 0;
206         struct timeval timeout;
207         
208         /* just checking .... */
209         if (maxcnt <= 0)
210                 return(0);
211         
212         smb_read_error = 0;
213         
214         /* Blocking read */
215         if (time_out <= 0) {
216                 if (mincnt == 0) mincnt = maxcnt;
217                 
218                 while (nread < mincnt) {
219                         readret = sys_read(fd, buf + nread, maxcnt - nread);
220                         
221                         if (readret == 0) {
222                                 DEBUG(5,("read_socket_with_timeout: blocking read. EOF from client.\n"));
223                                 smb_read_error = READ_EOF;
224                                 return -1;
225                         }
226                         
227                         if (readret == -1) {
228                                 DEBUG(0,("read_socket_with_timeout: read error = %s.\n", strerror(errno) ));
229                                 smb_read_error = READ_ERROR;
230                                 return -1;
231                         }
232                         nread += readret;
233                 }
234                 return((ssize_t)nread);
235         }
236         
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 */
242         
243         /* Set initial timeout */
244         timeout.tv_sec = (time_t)(time_out / 1000);
245         timeout.tv_usec = (long)(1000 * (time_out % 1000));
246         
247         for (nread=0; nread < mincnt; ) {      
248                 FD_ZERO(&fds);
249                 FD_SET(fd,&fds);
250                 
251                 selrtn = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout);
252                 
253                 /* Check if error */
254                 if (selrtn == -1) {
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;
258                         return -1;
259                 }
260                 
261                 /* Did we timeout ? */
262                 if (selrtn == 0) {
263                         DEBUG(10,("read_socket_with_timeout: timeout read. select timed out.\n"));
264                         smb_read_error = READ_TIMEOUT;
265                         return -1;
266                 }
267                 
268                 readret = sys_read(fd, buf+nread, maxcnt-nread);
269                 
270                 if (readret == 0) {
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;
274                         return -1;
275                 }
276                 
277                 if (readret == -1) {
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;
281                         return -1;
282                 }
283                 
284                 nread += readret;
285         }
286         
287         /* Return the number we got */
288         return (ssize_t)nread;
289 }
290
291 /****************************************************************************
292   read data from the client, reading exactly N bytes. 
293 ****************************************************************************/
294
295 ssize_t read_data(int fd,char *buffer,size_t N)
296 {
297         ssize_t ret;
298         size_t total=0;  
299  
300         smb_read_error = 0;
301
302         while (total < N) {
303                 ret = sys_read(fd,buffer + total,N - total);
304
305                 if (ret == 0) {
306                         DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) ));
307                         smb_read_error = READ_EOF;
308                         return 0;
309                 }
310
311                 if (ret == -1) {
312                         DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) ));
313                         smb_read_error = READ_ERROR;
314                         return -1;
315                 }
316                 total += ret;
317         }
318         return (ssize_t)total;
319 }
320
321 /****************************************************************************
322  Read data from a socket, reading exactly N bytes. 
323 ****************************************************************************/
324
325 static ssize_t read_socket_data(int fd,char *buffer,size_t N)
326 {
327         ssize_t ret;
328         size_t total=0;  
329  
330         smb_read_error = 0;
331
332         while (total < N) {
333                 ret = sys_read(fd,buffer + total,N - total);
334
335                 if (ret == 0) {
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;
338                         return 0;
339                 }
340
341                 if (ret == -1) {
342                         DEBUG(0,("read_socket_data: recv failure for %d. Error = %s\n", (int)(N - total), strerror(errno) ));
343                         smb_read_error = READ_ERROR;
344                         return -1;
345                 }
346                 total += ret;
347         }
348         return (ssize_t)total;
349 }
350
351 /****************************************************************************
352  Write data to a fd.
353 ****************************************************************************/
354
355 ssize_t write_data(int fd,char *buffer,size_t N)
356 {
357         size_t total=0;
358         ssize_t ret;
359
360         while (total < N) {
361                 ret = sys_write(fd,buffer + total,N - total);
362
363                 if (ret == -1) {
364                         DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) ));
365                         return -1;
366                 }
367                 if (ret == 0)
368                         return total;
369
370                 total += ret;
371         }
372         return (ssize_t)total;
373 }
374
375 /****************************************************************************
376  Write data to a socket - use send rather than write.
377 ****************************************************************************/
378
379 static ssize_t write_socket_data(int fd,char *buffer,size_t N)
380 {
381         size_t total=0;
382         ssize_t ret;
383
384         while (total < N) {
385                 ret = sys_send(fd,buffer + total,N - total,0);
386
387                 if (ret == -1) {
388                         DEBUG(0,("write_socket_data: write failure. Error = %s\n", strerror(errno) ));
389                         return -1;
390                 }
391                 if (ret == 0)
392                         return total;
393
394                 total += ret;
395         }
396         return (ssize_t)total;
397 }
398
399 /****************************************************************************
400 write to a socket
401 ****************************************************************************/
402
403 ssize_t write_socket(int fd,char *buf,size_t len)
404 {
405         ssize_t ret=0;
406
407         DEBUG(6,("write_socket(%d,%d)\n",fd,(int)len));
408         ret = write_socket_data(fd,buf,len);
409       
410         DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,(int)len,(int)ret));
411         if(ret <= 0)
412                 DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n", 
413                         (int)len, fd, strerror(errno) ));
414
415         return(ret);
416 }
417
418 /****************************************************************************
419 send a keepalive packet (rfc1002)
420 ****************************************************************************/
421
422 BOOL send_keepalive(int client)
423 {
424         unsigned char buf[4];
425
426         buf[0] = SMBkeepalive;
427         buf[1] = buf[2] = buf[3] = 0;
428
429         return(write_socket_data(client,(char *)buf,4) == 4);
430 }
431
432
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
437 a keepalive packet.
438 timeout is in milliseconds.
439 ****************************************************************************/
440
441 static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int timeout)
442 {
443         ssize_t len=0;
444         int msg_type;
445         BOOL ok = False;
446
447         while (!ok) {
448                 if (timeout > 0)
449                         ok = (read_socket_with_timeout(fd,inbuf,4,4,timeout) == 4);
450                 else 
451                         ok = (read_socket_data(fd,inbuf,4) == 4);
452
453                 if (!ok)
454                         return(-1);
455
456                 len = smb_len(inbuf);
457                 msg_type = CVAL(inbuf,0);
458
459                 if (msg_type == SMBkeepalive) 
460                         DEBUG(5,("Got keepalive packet\n"));
461         }
462
463         DEBUG(10,("got smb length of %d\n",len));
464
465         return(len);
466 }
467
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 ****************************************************************************/
474
475 ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout)
476 {
477         ssize_t len;
478
479         for(;;) {
480                 len = read_smb_length_return_keepalive(fd, inbuf, timeout);
481
482                 if(len < 0)
483                         return len;
484
485                 /* Ignore session keepalives. */
486                 if(CVAL(inbuf,0) != SMBkeepalive)
487                         break;
488         }
489
490         DEBUG(10,("read_smb_length: got smb length of %d\n",len));
491
492         return len;
493 }
494
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 ****************************************************************************/
502
503 BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
504 {
505         ssize_t len,ret;
506
507         smb_read_error = 0;
508
509         memset(buffer,'\0',smb_size + 100);
510
511         len = read_smb_length_return_keepalive(fd,buffer,timeout);
512         if (len < 0) {
513                 DEBUG(10,("receive_smb: length < 0!\n"));
514
515                 /*
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.
519                  */
520
521                 if (smb_read_error == 0)
522                         smb_read_error = READ_ERROR;
523                 return False;
524         }
525
526         /*
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.
529          */
530
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)) {
534
535                         /*
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.
539                          */
540
541                         if (smb_read_error == 0)
542                                 smb_read_error = READ_ERROR;
543                         return False;
544                 }
545         }
546
547         if(len > 0) {
548                 ret = read_socket_data(fd,buffer+4,len);
549                 if (ret != len) {
550                         if (smb_read_error == 0)
551                                 smb_read_error = READ_ERROR;
552                         return False;
553                 }
554         }
555
556         return(True);
557 }
558
559 /****************************************************************************
560   send an smb to a fd 
561 ****************************************************************************/
562
563 BOOL send_smb(int fd,char *buffer)
564 {
565         size_t len;
566         size_t nwritten=0;
567         ssize_t ret;
568         len = smb_len(buffer) + 4;
569
570         while (nwritten < len) {
571                 ret = write_socket(fd,buffer+nwritten,len - nwritten);
572                 if (ret <= 0) {
573                         DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n",
574                                 (int)len,(int)ret, strerror(errno) ));
575                         return False;
576                 }
577                 nwritten += ret;
578         }
579
580         return True;
581 }
582
583 /****************************************************************************
584  Open a socket of the specified type, port, and address for incoming data.
585 ****************************************************************************/
586
587 int open_socket_in( int type, int port, int dlevel, uint32 socket_addr, BOOL rebind )
588 {
589         struct sockaddr_in sock;
590         int res;
591
592         memset( (char *)&sock, '\0', sizeof(sock) );
593
594 #ifdef HAVE_SOCK_SIN_LEN
595         sock.sin_len         = sizeof(sock);
596 #endif
597         sock.sin_port        = htons( port );
598         sock.sin_family      = AF_INET;
599         sock.sin_addr.s_addr = socket_addr;
600
601         res = socket( AF_INET, type, 0 );
602         if( res == -1 ) {
603                 if( DEBUGLVL(0) ) {
604                         dbgtext( "open_socket_in(): socket() call failed: " );
605                         dbgtext( "%s\n", strerror( errno ) );
606                 }
607                 return -1;
608         }
609
610         /* This block sets/clears the SO_REUSEADDR and possibly SO_REUSEPORT. */
611         {
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) );
619                         }
620                 }
621 #ifdef SO_REUSEPORT
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) );
628                         }
629                 }
630 #endif /* SO_REUSEPORT */
631         }
632
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) );
639                 }
640                 close( res ); 
641                 return( -1 ); 
642         }
643
644         DEBUG( 10, ( "bind succeeded on port %d\n", port ) );
645
646         return( res );
647  }
648
649 /****************************************************************************
650   create an outgoing socket. timeout is in milliseconds.
651   **************************************************************************/
652
653 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
654 {
655   struct sockaddr_in sock_out;
656   int res,ret;
657   int connect_loop = 250; /* 250 milliseconds */
658   int loops = (timeout) / connect_loop;
659
660   /* create a socket to write to */
661   res = socket(PF_INET, type, 0);
662   if (res == -1) 
663     { DEBUG(0,("socket error\n")); return -1; }
664
665   if (type != SOCK_STREAM) return(res);
666   
667   memset((char *)&sock_out,'\0',sizeof(sock_out));
668   putip((char *)&sock_out.sin_addr,(char *)addr);
669   
670   sock_out.sin_port = htons( port );
671   sock_out.sin_family = PF_INET;
672
673   /* set it non-blocking */
674   set_blocking(res,False);
675
676   DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
677   
678   /* and connect it to the destination */
679 connect_again:
680   ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
681
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);
686     goto connect_again;
687   }
688
689   if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
690          errno == EAGAIN)) {
691       DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
692       close(res);
693       return -1;
694   }
695
696 #ifdef EISCONN
697   if (ret < 0 && errno == EISCONN) {
698     errno = 0;
699     ret = 0;
700   }
701 #endif
702
703   if (ret < 0) {
704     DEBUG(2,("error connecting to %s:%d (%s)\n",
705              inet_ntoa(*addr),port,strerror(errno)));
706     close(res);
707     return -1;
708   }
709
710   /* set it blocking again */
711   set_blocking(res,True);
712
713   return res;
714 }
715
716 /*
717   open a connected UDP socket to host on port
718 */
719 int open_udp_socket(const char *host, int port)
720 {
721         int type = SOCK_DGRAM;
722         struct sockaddr_in sock_out;
723         int res;
724         struct in_addr *addr;
725
726         addr = interpret_addr2(host);
727
728         res = socket(PF_INET, type, 0);
729         if (res == -1) {
730                 return -1;
731         }
732
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;
737
738         if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))) {
739                 close(res);
740                 return -1;
741         }
742
743         return res;
744 }
745
746
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;
751
752 void client_setfd(int fd)
753 {
754         client_fd = fd;
755 }
756
757 char *client_name(void)
758 {
759         return get_socket_name(client_fd,False);
760 }
761
762 char *client_addr(void)
763 {
764         return get_socket_addr(client_fd);
765 }
766
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)
772 {
773         struct hostent *hp;
774         int     i;
775         
776         if ((hp = sys_gethostbyname(remotehost)) == 0) {
777                 DEBUG(0,("sys_gethostbyname(%s): lookup failure.\n", remotehost));
778                 return False;
779         } 
780
781         /*
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.
787          */
788         
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));
793                 return False;
794         }
795         
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)
799                         return True;
800         }
801         
802         /*
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.
806          */
807         
808         DEBUG(0,("host name/address mismatch: %s != %s\n",
809                  inet_ntoa(addr), hp->h_name));
810         return False;
811 }
812
813  
814 /*******************************************************************
815  return the DNS name of the remote end of a socket
816  ******************************************************************/
817 char *get_socket_name(int fd, BOOL force_lookup)
818 {
819         static pstring name_buf;
820         static fstring addr_buf;
821         struct hostent *hp;
822         struct in_addr addr;
823         char *p;
824
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
828            possible */
829         if (!lp_hostname_lookups() && (force_lookup == False)) {
830                 return get_socket_addr(fd);
831         }
832         
833         p = get_socket_addr(fd);
834
835         /* it might be the same as the last one - save some DNS work */
836         if (strcmp(p, addr_buf) == 0) return name_buf;
837
838         pstrcpy(name_buf,"UNKNOWN");
839         if (fd == -1) return name_buf;
840
841         fstrcpy(addr_buf, p);
842
843         addr = *interpret_addr2(p);
844         
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);
849         } else {
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");
854                 }
855         }
856
857         alpha_strcpy(name_buf, name_buf, "_-.", sizeof(name_buf));
858         if (strstr(name_buf,"..")) {
859                 pstrcpy(name_buf, "UNKNOWN");
860         }
861
862         return name_buf;
863 }
864
865 /*******************************************************************
866  return the IP addr of the remote end of a socket as a string 
867  ******************************************************************/
868 char *get_socket_addr(int fd)
869 {
870         struct sockaddr sa;
871         struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
872         int     length = sizeof(sa);
873         static fstring addr_buf;
874
875         fstrcpy(addr_buf,"0.0.0.0");
876
877         if (fd == -1) {
878                 return addr_buf;
879         }
880         
881         if (getpeername(fd, &sa, &length) < 0) {
882                 DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) ));
883                 return addr_buf;
884         }
885         
886         fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
887         
888         return addr_buf;
889 }
890
891
892 /*******************************************************************
893  Create protected unix domain socket.
894
895  Some unixes cannot set permissions on a ux-dom-sock, so we
896  have to make sure that the directory contains the protection
897  permissions instead.
898  ******************************************************************/
899
900 int create_pipe_sock(const char *socket_dir,
901                      const char *socket_name,
902                      mode_t dir_perms)
903 {
904 #ifdef HAVE_UNIXSOCKET
905         struct sockaddr_un sunaddr;
906         struct stat st;
907         int sock;
908         mode_t old_umask;
909         pstring path;
910         
911         old_umask = umask(0);
912         
913         /* Create the socket directory or reuse the existing one */
914         
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, 
921                                         strerror(errno)));
922                                 goto out_umask;
923                         }
924                 } else {
925                         DEBUG(0, ("lstat failed on socket directory %s: %s\n",
926                                 socket_dir, strerror(errno)));
927                         goto out_umask;
928                 }
929         } else {
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",
933                                 socket_dir));
934                         goto out_umask;
935                 }
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));
940                         goto out_umask;
941                 }
942         }
943         
944         /* Create the socket file */
945         
946         sock = socket(AF_UNIX, SOCK_STREAM, 0);
947         
948         if (sock == -1) {
949                 perror("socket");
950                 goto out_umask;
951         }
952         
953         snprintf(path, sizeof(path), "%s/%s", socket_dir, socket_name);
954         
955         unlink(path);
956         memset(&sunaddr, 0, sizeof(sunaddr));
957         sunaddr.sun_family = AF_UNIX;
958         safe_strcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)-1);
959         
960         if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) {
961                 DEBUG(0, ("bind failed on pipe socket %s: %s\n", path,
962                         strerror(errno)));
963                 goto out_close;
964         }
965         
966         if (listen(sock, 5) == -1) {
967                 DEBUG(0, ("listen failed on pipe socket %s: %s\n", path,
968                         strerror(errno)));
969                 goto out_close;
970         }
971         
972         umask(old_umask);
973         return sock;
974
975 out_close:
976         close(sock);
977
978 out_umask:
979         umask(old_umask);
980         return -1;
981
982 #else
983         DEBUG(0, ("create_pipe_sock: No Unix sockets on this system\n"));
984         return -1;
985 #endif /* HAVE_UNIXSOCKET */
986 }
987
988 /*******************************************************************
989 this is like socketpair but uses tcp. It is used by the Samba
990 regression test code
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])
997 {
998         int listener;
999         struct sockaddr_in sock;
1000         struct sockaddr_in sock2;
1001         socklen_t socklen = sizeof(sock);
1002         int connect_done = 0;
1003         
1004         fd[0] = fd[1] = listener = -1;
1005
1006         memset(&sock, 0, sizeof(sock));
1007         
1008         if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
1009
1010         memset(&sock2, 0, sizeof(sock2));
1011 #ifdef HAVE_SOCK_SIN_LEN
1012         sock2.sin_len = sizeof(sock2);
1013 #endif
1014         sock2.sin_family = PF_INET;
1015
1016         bind(listener, (struct sockaddr *)&sock2, sizeof(sock2));
1017
1018         if (listen(listener, 1) != 0) goto failed;
1019
1020         if (getsockname(listener, (struct sockaddr *)&sock, &socklen) != 0) goto failed;
1021
1022         if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
1023
1024         set_blocking(fd[1], 0);
1025
1026         sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1027
1028         if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) {
1029                 if (errno != EINPROGRESS) goto failed;
1030         } else {
1031                 connect_done = 1;
1032         }
1033
1034         if ((fd[0] = accept(listener, (struct sockaddr *)&sock, &socklen)) == -1) goto failed;
1035
1036         close(listener);
1037         if (connect_done == 0) {
1038                 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0
1039                     && errno != EISCONN) goto failed;
1040         }
1041
1042         set_blocking(fd[1], 1);
1043
1044         /* all OK! */
1045         return 0;
1046
1047  failed:
1048         if (fd[0] != -1) close(fd[0]);
1049         if (fd[1] != -1) close(fd[1]);
1050         if (listener != -1) close(listener);
1051         return -1;
1052 }
1053
1054
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)
1063 {
1064         int fd[2];
1065         if (socketpair_tcp(fd) != 0) {
1066                 DEBUG(0,("socketpair_tcp failed (%s)\n", strerror(errno)));
1067                 return -1;
1068         }
1069         if (fork() == 0) {
1070                 close(fd[0]);
1071                 close(0);
1072                 close(1);
1073                 dup(fd[1]);
1074                 dup(fd[1]);
1075                 exit(system(prog));
1076         }
1077         close(fd[1]);
1078         return fd[0];
1079 }