s3-param Remove special case for global_myname(), rename to lp_netbios_name()
[gd/samba-autobuild/.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    Copyright (C) Jeremy Allison  1992-2007
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "system/filesys.h"
24 #include "memcache.h"
25 #include "../lib/async_req/async_sock.h"
26 #include "../lib/util/select.h"
27 #include "lib/socket/interfaces.h"
28 #include "../lib/util/tevent_unix.h"
29 #include "../lib/util/tevent_ntstatus.h"
30
31 const char *client_name(int fd)
32 {
33         return get_peer_name(fd,false);
34 }
35
36 const char *client_addr(int fd, char *addr, size_t addrlen)
37 {
38         return get_peer_addr(fd,addr,addrlen);
39 }
40
41 #if 0
42 /* Not currently used. JRA. */
43 int client_socket_port(int fd)
44 {
45         return get_socket_port(fd);
46 }
47 #endif
48
49 /****************************************************************************
50  Accessor functions to make thread-safe code easier later...
51 ****************************************************************************/
52
53 void set_smb_read_error(enum smb_read_errors *pre,
54                         enum smb_read_errors newerr)
55 {
56         if (pre) {
57                 *pre = newerr;
58         }
59 }
60
61 void cond_set_smb_read_error(enum smb_read_errors *pre,
62                         enum smb_read_errors newerr)
63 {
64         if (pre && *pre == SMB_READ_OK) {
65                 *pre = newerr;
66         }
67 }
68
69 /****************************************************************************
70  Determine if a file descriptor is in fact a socket.
71 ****************************************************************************/
72
73 bool is_a_socket(int fd)
74 {
75         int v;
76         socklen_t l;
77         l = sizeof(int);
78         return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
79 }
80
81 /****************************************************************************
82  Read from a socket.
83 ****************************************************************************/
84
85 ssize_t read_udp_v4_socket(int fd,
86                         char *buf,
87                         size_t len,
88                         struct sockaddr_storage *psa)
89 {
90         ssize_t ret;
91         socklen_t socklen = sizeof(*psa);
92         struct sockaddr_in *si = (struct sockaddr_in *)psa;
93
94         memset((char *)psa,'\0',socklen);
95
96         ret = (ssize_t)sys_recvfrom(fd,buf,len,0,
97                         (struct sockaddr *)psa,&socklen);
98         if (ret <= 0) {
99                 /* Don't print a low debug error for a non-blocking socket. */
100                 if (errno == EAGAIN) {
101                         DEBUG(10,("read_udp_v4_socket: returned EAGAIN\n"));
102                 } else {
103                         DEBUG(2,("read_udp_v4_socket: failed. errno=%s\n",
104                                 strerror(errno)));
105                 }
106                 return 0;
107         }
108
109         if (psa->ss_family != AF_INET) {
110                 DEBUG(2,("read_udp_v4_socket: invalid address family %d "
111                         "(not IPv4)\n", (int)psa->ss_family));
112                 return 0;
113         }
114
115         DEBUG(10,("read_udp_v4_socket: ip %s port %d read: %lu\n",
116                         inet_ntoa(si->sin_addr),
117                         si->sin_port,
118                         (unsigned long)ret));
119
120         return ret;
121 }
122
123 /****************************************************************************
124  Read data from a file descriptor with a timout in msec.
125  mincount = if timeout, minimum to read before returning
126  maxcount = number to be read.
127  time_out = timeout in milliseconds
128  NB. This can be called with a non-socket fd, don't change
129  sys_read() to sys_recv() or other socket call.
130 ****************************************************************************/
131
132 NTSTATUS read_fd_with_timeout(int fd, char *buf,
133                                   size_t mincnt, size_t maxcnt,
134                                   unsigned int time_out,
135                                   size_t *size_ret)
136 {
137         int pollrtn;
138         ssize_t readret;
139         size_t nread = 0;
140
141         /* just checking .... */
142         if (maxcnt <= 0)
143                 return NT_STATUS_OK;
144
145         /* Blocking read */
146         if (time_out == 0) {
147                 if (mincnt == 0) {
148                         mincnt = maxcnt;
149                 }
150
151                 while (nread < mincnt) {
152                         readret = sys_read(fd, buf + nread, maxcnt - nread);
153
154                         if (readret == 0) {
155                                 DEBUG(5,("read_fd_with_timeout: "
156                                         "blocking read. EOF from client.\n"));
157                                 return NT_STATUS_END_OF_FILE;
158                         }
159
160                         if (readret == -1) {
161                                 return map_nt_error_from_unix(errno);
162                         }
163                         nread += readret;
164                 }
165                 goto done;
166         }
167
168         /* Most difficult - timeout read */
169         /* If this is ever called on a disk file and
170            mincnt is greater then the filesize then
171            system performance will suffer severely as
172            select always returns true on disk files */
173
174         for (nread=0; nread < mincnt; ) {
175                 int revents;
176
177                 pollrtn = poll_intr_one_fd(fd, POLLIN|POLLHUP, time_out,
178                                            &revents);
179
180                 /* Check if error */
181                 if (pollrtn == -1) {
182                         return map_nt_error_from_unix(errno);
183                 }
184
185                 /* Did we timeout ? */
186                 if ((pollrtn == 0) ||
187                     ((revents & (POLLIN|POLLHUP|POLLERR)) == 0)) {
188                         DEBUG(10,("read_fd_with_timeout: timeout read. "
189                                 "select timed out.\n"));
190                         return NT_STATUS_IO_TIMEOUT;
191                 }
192
193                 readret = sys_read(fd, buf+nread, maxcnt-nread);
194
195                 if (readret == 0) {
196                         /* we got EOF on the file descriptor */
197                         DEBUG(5,("read_fd_with_timeout: timeout read. "
198                                 "EOF from client.\n"));
199                         return NT_STATUS_END_OF_FILE;
200                 }
201
202                 if (readret == -1) {
203                         return map_nt_error_from_unix(errno);
204                 }
205
206                 nread += readret;
207         }
208
209  done:
210         /* Return the number we got */
211         if (size_ret) {
212                 *size_ret = nread;
213         }
214         return NT_STATUS_OK;
215 }
216
217 /****************************************************************************
218  Read data from an fd, reading exactly N bytes.
219  NB. This can be called with a non-socket fd, don't add dependencies
220  on socket calls.
221 ****************************************************************************/
222
223 NTSTATUS read_data(int fd, char *buffer, size_t N)
224 {
225         return read_fd_with_timeout(fd, buffer, N, N, 0, NULL);
226 }
227
228 /****************************************************************************
229  Write all data from an iov array
230  NB. This can be called with a non-socket fd, don't add dependencies
231  on socket calls.
232 ****************************************************************************/
233
234 ssize_t write_data_iov(int fd, const struct iovec *orig_iov, int iovcnt)
235 {
236         int i;
237         size_t to_send;
238         ssize_t thistime;
239         size_t sent;
240         struct iovec *iov_copy, *iov;
241
242         to_send = 0;
243         for (i=0; i<iovcnt; i++) {
244                 to_send += orig_iov[i].iov_len;
245         }
246
247         thistime = sys_writev(fd, orig_iov, iovcnt);
248         if ((thistime <= 0) || (thistime == to_send)) {
249                 return thistime;
250         }
251         sent = thistime;
252
253         /*
254          * We could not send everything in one call. Make a copy of iov that
255          * we can mess with. We keep a copy of the array start in iov_copy for
256          * the TALLOC_FREE, because we're going to modify iov later on,
257          * discarding elements.
258          */
259
260         iov_copy = (struct iovec *)talloc_memdup(
261                 talloc_tos(), orig_iov, sizeof(struct iovec) * iovcnt);
262
263         if (iov_copy == NULL) {
264                 errno = ENOMEM;
265                 return -1;
266         }
267         iov = iov_copy;
268
269         while (sent < to_send) {
270                 /*
271                  * We have to discard "thistime" bytes from the beginning
272                  * iov array, "thistime" contains the number of bytes sent
273                  * via writev last.
274                  */
275                 while (thistime > 0) {
276                         if (thistime < iov[0].iov_len) {
277                                 char *new_base =
278                                         (char *)iov[0].iov_base + thistime;
279                                 iov[0].iov_base = (void *)new_base;
280                                 iov[0].iov_len -= thistime;
281                                 break;
282                         }
283                         thistime -= iov[0].iov_len;
284                         iov += 1;
285                         iovcnt -= 1;
286                 }
287
288                 thistime = sys_writev(fd, iov, iovcnt);
289                 if (thistime <= 0) {
290                         break;
291                 }
292                 sent += thistime;
293         }
294
295         TALLOC_FREE(iov_copy);
296         return sent;
297 }
298
299 /****************************************************************************
300  Write data to a fd.
301  NB. This can be called with a non-socket fd, don't add dependencies
302  on socket calls.
303 ****************************************************************************/
304
305 ssize_t write_data(int fd, const char *buffer, size_t N)
306 {
307         struct iovec iov;
308
309         iov.iov_base = discard_const_p(void, buffer);
310         iov.iov_len = N;
311         return write_data_iov(fd, &iov, 1);
312 }
313
314 /****************************************************************************
315  Send a keepalive packet (rfc1002).
316 ****************************************************************************/
317
318 bool send_keepalive(int client)
319 {
320         unsigned char buf[4];
321
322         buf[0] = SMBkeepalive;
323         buf[1] = buf[2] = buf[3] = 0;
324
325         return(write_data(client,(char *)buf,4) == 4);
326 }
327
328 /****************************************************************************
329  Read 4 bytes of a smb packet and return the smb length of the packet.
330  Store the result in the buffer.
331  This version of the function will return a length of zero on receiving
332  a keepalive packet.
333  Timeout is in milliseconds.
334 ****************************************************************************/
335
336 NTSTATUS read_smb_length_return_keepalive(int fd, char *inbuf,
337                                           unsigned int timeout,
338                                           size_t *len)
339 {
340         int msg_type;
341         NTSTATUS status;
342
343         status = read_fd_with_timeout(fd, inbuf, 4, 4, timeout, NULL);
344
345         if (!NT_STATUS_IS_OK(status)) {
346                 return status;
347         }
348
349         *len = smb_len(inbuf);
350         msg_type = CVAL(inbuf,0);
351
352         if (msg_type == SMBkeepalive) {
353                 DEBUG(5,("Got keepalive packet\n"));
354         }
355
356         DEBUG(10,("got smb length of %lu\n",(unsigned long)(*len)));
357
358         return NT_STATUS_OK;
359 }
360
361 /****************************************************************************
362  Read an smb from a fd.
363  The timeout is in milliseconds.
364  This function will return on receipt of a session keepalive packet.
365  maxlen is the max number of bytes to return, not including the 4 byte
366  length. If zero it means buflen limit.
367  Doesn't check the MAC on signed packets.
368 ****************************************************************************/
369
370 NTSTATUS receive_smb_raw(int fd, char *buffer, size_t buflen, unsigned int timeout,
371                          size_t maxlen, size_t *p_len)
372 {
373         size_t len;
374         NTSTATUS status;
375
376         status = read_smb_length_return_keepalive(fd,buffer,timeout,&len);
377
378         if (!NT_STATUS_IS_OK(status)) {
379                 DEBUG(0, ("read_fd_with_timeout failed, read "
380                           "error = %s.\n", nt_errstr(status)));
381                 return status;
382         }
383
384         if (len > buflen) {
385                 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
386                                         (unsigned long)len));
387                 return NT_STATUS_INVALID_PARAMETER;
388         }
389
390         if(len > 0) {
391                 if (maxlen) {
392                         len = MIN(len,maxlen);
393                 }
394
395                 status = read_fd_with_timeout(
396                         fd, buffer+4, len, len, timeout, &len);
397
398                 if (!NT_STATUS_IS_OK(status)) {
399                         DEBUG(0, ("read_fd_with_timeout failed, read error = "
400                                   "%s.\n", nt_errstr(status)));
401                         return status;
402                 }
403
404                 /* not all of samba3 properly checks for packet-termination
405                  * of strings. This ensures that we don't run off into
406                  * empty space. */
407                 SSVAL(buffer+4,len, 0);
408         }
409
410         *p_len = len;
411         return NT_STATUS_OK;
412 }
413
414 /****************************************************************************
415  Open a socket of the specified type, port, and address for incoming data.
416 ****************************************************************************/
417
418 int open_socket_in(int type,
419                 uint16_t port,
420                 int dlevel,
421                 const struct sockaddr_storage *psock,
422                 bool rebind)
423 {
424         struct sockaddr_storage sock;
425         int res;
426         socklen_t slen = sizeof(struct sockaddr_in);
427
428         sock = *psock;
429
430 #if defined(HAVE_IPV6)
431         if (sock.ss_family == AF_INET6) {
432                 ((struct sockaddr_in6 *)&sock)->sin6_port = htons(port);
433                 slen = sizeof(struct sockaddr_in6);
434         }
435 #endif
436         if (sock.ss_family == AF_INET) {
437                 ((struct sockaddr_in *)&sock)->sin_port = htons(port);
438         }
439
440         res = socket(sock.ss_family, type, 0 );
441         if( res == -1 ) {
442                 if( DEBUGLVL(0) ) {
443                         dbgtext( "open_socket_in(): socket() call failed: " );
444                         dbgtext( "%s\n", strerror( errno ) );
445                 }
446                 return -1;
447         }
448
449         /* This block sets/clears the SO_REUSEADDR and possibly SO_REUSEPORT. */
450         {
451                 int val = rebind ? 1 : 0;
452                 if( setsockopt(res,SOL_SOCKET,SO_REUSEADDR,
453                                         (char *)&val,sizeof(val)) == -1 ) {
454                         if( DEBUGLVL( dlevel ) ) {
455                                 dbgtext( "open_socket_in(): setsockopt: " );
456                                 dbgtext( "SO_REUSEADDR = %s ",
457                                                 val?"true":"false" );
458                                 dbgtext( "on port %d failed ", port );
459                                 dbgtext( "with error = %s\n", strerror(errno) );
460                         }
461                 }
462 #ifdef SO_REUSEPORT
463                 if( setsockopt(res,SOL_SOCKET,SO_REUSEPORT,
464                                         (char *)&val,sizeof(val)) == -1 ) {
465                         if( DEBUGLVL( dlevel ) ) {
466                                 dbgtext( "open_socket_in(): setsockopt: ");
467                                 dbgtext( "SO_REUSEPORT = %s ",
468                                                 val?"true":"false");
469                                 dbgtext( "on port %d failed ", port);
470                                 dbgtext( "with error = %s\n", strerror(errno));
471                         }
472                 }
473 #endif /* SO_REUSEPORT */
474         }
475
476 #ifdef HAVE_IPV6
477         /*
478          * As IPV6_V6ONLY is the default on some systems,
479          * we better try to be consistent and always use it.
480          *
481          * This also avoids using IPv4 via AF_INET6 sockets
482          * and makes sure %I never resolves to a '::ffff:192.168.0.1'
483          * string.
484          */
485         if (sock.ss_family == AF_INET6) {
486                 int val = 1;
487                 int ret;
488
489                 ret = setsockopt(res, IPPROTO_IPV6, IPV6_V6ONLY,
490                                  (const void *)&val, sizeof(val));
491                 if (ret == -1) {
492                         if(DEBUGLVL(0)) {
493                                 dbgtext("open_socket_in(): IPV6_ONLY failed: ");
494                                 dbgtext("%s\n", strerror(errno));
495                         }
496                         close(res);
497                         return -1;
498                 }
499         }
500 #endif
501
502         /* now we've got a socket - we need to bind it */
503         if (bind(res, (struct sockaddr *)&sock, slen) == -1 ) {
504                 if( DEBUGLVL(dlevel) && (port == SMB_PORT1 ||
505                                 port == SMB_PORT2 || port == NMB_PORT) ) {
506                         char addr[INET6_ADDRSTRLEN];
507                         print_sockaddr(addr, sizeof(addr),
508                                         &sock);
509                         dbgtext( "bind failed on port %d ", port);
510                         dbgtext( "socket_addr = %s.\n", addr);
511                         dbgtext( "Error = %s\n", strerror(errno));
512                 }
513                 close(res);
514                 return -1;
515         }
516
517         DEBUG( 10, ( "bind succeeded on port %d\n", port ) );
518         return( res );
519  }
520
521 struct open_socket_out_state {
522         int fd;
523         struct event_context *ev;
524         struct sockaddr_storage ss;
525         socklen_t salen;
526         uint16_t port;
527         int wait_usec;
528 };
529
530 static void open_socket_out_connected(struct tevent_req *subreq);
531
532 static int open_socket_out_state_destructor(struct open_socket_out_state *s)
533 {
534         if (s->fd != -1) {
535                 close(s->fd);
536         }
537         return 0;
538 }
539
540 /****************************************************************************
541  Create an outgoing socket. timeout is in milliseconds.
542 **************************************************************************/
543
544 struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
545                                         struct event_context *ev,
546                                         const struct sockaddr_storage *pss,
547                                         uint16_t port,
548                                         int timeout)
549 {
550         char addr[INET6_ADDRSTRLEN];
551         struct tevent_req *result, *subreq;
552         struct open_socket_out_state *state;
553         NTSTATUS status;
554
555         result = tevent_req_create(mem_ctx, &state,
556                                    struct open_socket_out_state);
557         if (result == NULL) {
558                 return NULL;
559         }
560         state->ev = ev;
561         state->ss = *pss;
562         state->port = port;
563         state->wait_usec = 10000;
564         state->salen = -1;
565
566         state->fd = socket(state->ss.ss_family, SOCK_STREAM, 0);
567         if (state->fd == -1) {
568                 status = map_nt_error_from_unix(errno);
569                 goto post_status;
570         }
571         talloc_set_destructor(state, open_socket_out_state_destructor);
572
573         if (!tevent_req_set_endtime(
574                     result, ev, timeval_current_ofs_msec(timeout))) {
575                 goto fail;
576         }
577
578 #if defined(HAVE_IPV6)
579         if (pss->ss_family == AF_INET6) {
580                 struct sockaddr_in6 *psa6;
581                 psa6 = (struct sockaddr_in6 *)&state->ss;
582                 psa6->sin6_port = htons(port);
583                 if (psa6->sin6_scope_id == 0
584                     && IN6_IS_ADDR_LINKLOCAL(&psa6->sin6_addr)) {
585                         setup_linklocal_scope_id(
586                                 (struct sockaddr *)&(state->ss));
587                 }
588                 state->salen = sizeof(struct sockaddr_in6);
589         }
590 #endif
591         if (pss->ss_family == AF_INET) {
592                 struct sockaddr_in *psa;
593                 psa = (struct sockaddr_in *)&state->ss;
594                 psa->sin_port = htons(port);
595                 state->salen = sizeof(struct sockaddr_in);
596         }
597
598         if (pss->ss_family == AF_UNIX) {
599                 state->salen = sizeof(struct sockaddr_un);
600         }
601
602         print_sockaddr(addr, sizeof(addr), &state->ss);
603         DEBUG(3,("Connecting to %s at port %u\n", addr, (unsigned int)port));
604
605         subreq = async_connect_send(state, state->ev, state->fd,
606                                     (struct sockaddr *)&state->ss,
607                                     state->salen);
608         if ((subreq == NULL)
609             || !tevent_req_set_endtime(
610                     subreq, state->ev,
611                     timeval_current_ofs(0, state->wait_usec))) {
612                 goto fail;
613         }
614         tevent_req_set_callback(subreq, open_socket_out_connected, result);
615         return result;
616
617  post_status:
618         tevent_req_nterror(result, status);
619         return tevent_req_post(result, ev);
620  fail:
621         TALLOC_FREE(result);
622         return NULL;
623 }
624
625 static void open_socket_out_connected(struct tevent_req *subreq)
626 {
627         struct tevent_req *req =
628                 tevent_req_callback_data(subreq, struct tevent_req);
629         struct open_socket_out_state *state =
630                 tevent_req_data(req, struct open_socket_out_state);
631         int ret;
632         int sys_errno;
633
634         ret = async_connect_recv(subreq, &sys_errno);
635         TALLOC_FREE(subreq);
636         if (ret == 0) {
637                 tevent_req_done(req);
638                 return;
639         }
640
641         if (
642 #ifdef ETIMEDOUT
643                 (sys_errno == ETIMEDOUT) ||
644 #endif
645                 (sys_errno == EINPROGRESS) ||
646                 (sys_errno == EALREADY) ||
647                 (sys_errno == EAGAIN)) {
648
649                 /*
650                  * retry
651                  */
652
653                 if (state->wait_usec < 250000) {
654                         state->wait_usec *= 1.5;
655                 }
656
657                 subreq = async_connect_send(state, state->ev, state->fd,
658                                             (struct sockaddr *)&state->ss,
659                                             state->salen);
660                 if (tevent_req_nomem(subreq, req)) {
661                         return;
662                 }
663                 if (!tevent_req_set_endtime(
664                             subreq, state->ev,
665                             timeval_current_ofs_usec(state->wait_usec))) {
666                         tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
667                         return;
668                 }
669                 tevent_req_set_callback(subreq, open_socket_out_connected, req);
670                 return;
671         }
672
673 #ifdef EISCONN
674         if (sys_errno == EISCONN) {
675                 tevent_req_done(req);
676                 return;
677         }
678 #endif
679
680         /* real error */
681         tevent_req_nterror(req, map_nt_error_from_unix(sys_errno));
682 }
683
684 NTSTATUS open_socket_out_recv(struct tevent_req *req, int *pfd)
685 {
686         struct open_socket_out_state *state =
687                 tevent_req_data(req, struct open_socket_out_state);
688         NTSTATUS status;
689
690         if (tevent_req_is_nterror(req, &status)) {
691                 return status;
692         }
693         *pfd = state->fd;
694         state->fd = -1;
695         return NT_STATUS_OK;
696 }
697
698 /**
699 * @brief open a socket
700 *
701 * @param pss a struct sockaddr_storage defining the address to connect to
702 * @param port to connect to
703 * @param timeout in MILLISECONDS
704 * @param pfd file descriptor returned
705 *
706 * @return NTSTATUS code
707 */
708 NTSTATUS open_socket_out(const struct sockaddr_storage *pss, uint16_t port,
709                          int timeout, int *pfd)
710 {
711         TALLOC_CTX *frame = talloc_stackframe();
712         struct event_context *ev;
713         struct tevent_req *req;
714         NTSTATUS status = NT_STATUS_NO_MEMORY;
715
716         ev = event_context_init(frame);
717         if (ev == NULL) {
718                 goto fail;
719         }
720
721         req = open_socket_out_send(frame, ev, pss, port, timeout);
722         if (req == NULL) {
723                 goto fail;
724         }
725         if (!tevent_req_poll(req, ev)) {
726                 status = NT_STATUS_INTERNAL_ERROR;
727                 goto fail;
728         }
729         status = open_socket_out_recv(req, pfd);
730  fail:
731         TALLOC_FREE(frame);
732         return status;
733 }
734
735 struct open_socket_out_defer_state {
736         struct event_context *ev;
737         struct sockaddr_storage ss;
738         uint16_t port;
739         int timeout;
740         int fd;
741 };
742
743 static void open_socket_out_defer_waited(struct tevent_req *subreq);
744 static void open_socket_out_defer_connected(struct tevent_req *subreq);
745
746 struct tevent_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx,
747                                               struct event_context *ev,
748                                               struct timeval wait_time,
749                                               const struct sockaddr_storage *pss,
750                                               uint16_t port,
751                                               int timeout)
752 {
753         struct tevent_req *req, *subreq;
754         struct open_socket_out_defer_state *state;
755
756         req = tevent_req_create(mem_ctx, &state,
757                                 struct open_socket_out_defer_state);
758         if (req == NULL) {
759                 return NULL;
760         }
761         state->ev = ev;
762         state->ss = *pss;
763         state->port = port;
764         state->timeout = timeout;
765
766         subreq = tevent_wakeup_send(
767                 state, ev,
768                 timeval_current_ofs(wait_time.tv_sec, wait_time.tv_usec));
769         if (subreq == NULL) {
770                 goto fail;
771         }
772         tevent_req_set_callback(subreq, open_socket_out_defer_waited, req);
773         return req;
774  fail:
775         TALLOC_FREE(req);
776         return NULL;
777 }
778
779 static void open_socket_out_defer_waited(struct tevent_req *subreq)
780 {
781         struct tevent_req *req = tevent_req_callback_data(
782                 subreq, struct tevent_req);
783         struct open_socket_out_defer_state *state = tevent_req_data(
784                 req, struct open_socket_out_defer_state);
785         bool ret;
786
787         ret = tevent_wakeup_recv(subreq);
788         TALLOC_FREE(subreq);
789         if (!ret) {
790                 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
791                 return;
792         }
793
794         subreq = open_socket_out_send(state, state->ev, &state->ss,
795                                       state->port, state->timeout);
796         if (tevent_req_nomem(subreq, req)) {
797                 return;
798         }
799         tevent_req_set_callback(subreq, open_socket_out_defer_connected, req);
800 }
801
802 static void open_socket_out_defer_connected(struct tevent_req *subreq)
803 {
804         struct tevent_req *req = tevent_req_callback_data(
805                 subreq, struct tevent_req);
806         struct open_socket_out_defer_state *state = tevent_req_data(
807                 req, struct open_socket_out_defer_state);
808         NTSTATUS status;
809
810         status = open_socket_out_recv(subreq, &state->fd);
811         TALLOC_FREE(subreq);
812         if (!NT_STATUS_IS_OK(status)) {
813                 tevent_req_nterror(req, status);
814                 return;
815         }
816         tevent_req_done(req);
817 }
818
819 NTSTATUS open_socket_out_defer_recv(struct tevent_req *req, int *pfd)
820 {
821         struct open_socket_out_defer_state *state = tevent_req_data(
822                 req, struct open_socket_out_defer_state);
823         NTSTATUS status;
824
825         if (tevent_req_is_nterror(req, &status)) {
826                 return status;
827         }
828         *pfd = state->fd;
829         state->fd = -1;
830         return NT_STATUS_OK;
831 }
832
833 /****************************************************************************
834  Open a connected UDP socket to host on port
835 **************************************************************************/
836
837 int open_udp_socket(const char *host, int port)
838 {
839         struct sockaddr_storage ss;
840         int res;
841
842         if (!interpret_string_addr(&ss, host, 0)) {
843                 DEBUG(10,("open_udp_socket: can't resolve name %s\n",
844                         host));
845                 return -1;
846         }
847
848         res = socket(ss.ss_family, SOCK_DGRAM, 0);
849         if (res == -1) {
850                 return -1;
851         }
852
853 #if defined(HAVE_IPV6)
854         if (ss.ss_family == AF_INET6) {
855                 struct sockaddr_in6 *psa6;
856                 psa6 = (struct sockaddr_in6 *)&ss;
857                 psa6->sin6_port = htons(port);
858                 if (psa6->sin6_scope_id == 0
859                                 && IN6_IS_ADDR_LINKLOCAL(&psa6->sin6_addr)) {
860                         setup_linklocal_scope_id(
861                                 (struct sockaddr *)&ss);
862                 }
863         }
864 #endif
865         if (ss.ss_family == AF_INET) {
866                 struct sockaddr_in *psa;
867                 psa = (struct sockaddr_in *)&ss;
868                 psa->sin_port = htons(port);
869         }
870
871         if (sys_connect(res,(struct sockaddr *)&ss)) {
872                 close(res);
873                 return -1;
874         }
875
876         return res;
877 }
878
879 /*******************************************************************
880  Return the IP addr of the remote end of a socket as a string.
881  Optionally return the struct sockaddr_storage.
882  ******************************************************************/
883
884 static const char *get_peer_addr_internal(int fd,
885                                 char *addr_buf,
886                                 size_t addr_buf_len,
887                                 struct sockaddr *pss,
888                                 socklen_t *plength)
889 {
890         struct sockaddr_storage ss;
891         socklen_t length = sizeof(ss);
892
893         strlcpy(addr_buf,"0.0.0.0",addr_buf_len);
894
895         if (fd == -1) {
896                 return addr_buf;
897         }
898
899         if (pss == NULL) {
900                 pss = (struct sockaddr *)&ss;
901                 plength = &length;
902         }
903
904         if (getpeername(fd, (struct sockaddr *)pss, plength) < 0) {
905                 int level = (errno == ENOTCONN) ? 2 : 0;
906                 DEBUG(level, ("getpeername failed. Error was %s\n",
907                                strerror(errno)));
908                 return addr_buf;
909         }
910
911         print_sockaddr_len(addr_buf,
912                         addr_buf_len,
913                         pss,
914                         *plength);
915         return addr_buf;
916 }
917
918 /*******************************************************************
919  Matchname - determine if host name matches IP address. Used to
920  confirm a hostname lookup to prevent spoof attacks.
921 ******************************************************************/
922
923 static bool matchname(const char *remotehost,
924                 const struct sockaddr *pss,
925                 socklen_t len)
926 {
927         struct addrinfo *res = NULL;
928         struct addrinfo *ailist = NULL;
929         char addr_buf[INET6_ADDRSTRLEN];
930         bool ret = interpret_string_addr_internal(&ailist,
931                         remotehost,
932                         AI_ADDRCONFIG|AI_CANONNAME);
933
934         if (!ret || ailist == NULL) {
935                 DEBUG(3,("matchname: getaddrinfo failed for "
936                         "name %s [%s]\n",
937                         remotehost,
938                         gai_strerror(ret) ));
939                 return false;
940         }
941
942         /*
943          * Make sure that getaddrinfo() returns the "correct" host name.
944          */
945
946         if (ailist->ai_canonname == NULL ||
947                 (!strequal(remotehost, ailist->ai_canonname) &&
948                  !strequal(remotehost, "localhost"))) {
949                 DEBUG(0,("matchname: host name/name mismatch: %s != %s\n",
950                          remotehost,
951                          ailist->ai_canonname ?
952                                  ailist->ai_canonname : "(NULL)"));
953                 freeaddrinfo(ailist);
954                 return false;
955         }
956
957         /* Look up the host address in the address list we just got. */
958         for (res = ailist; res; res = res->ai_next) {
959                 if (!res->ai_addr) {
960                         continue;
961                 }
962                 if (sockaddr_equal((const struct sockaddr *)res->ai_addr,
963                                         (const struct sockaddr *)pss)) {
964                         freeaddrinfo(ailist);
965                         return true;
966                 }
967         }
968
969         /*
970          * The host name does not map to the original host address. Perhaps
971          * someone has compromised a name server. More likely someone botched
972          * it, but that could be dangerous, too.
973          */
974
975         DEBUG(0,("matchname: host name/address mismatch: %s != %s\n",
976                 print_sockaddr_len(addr_buf,
977                         sizeof(addr_buf),
978                         pss,
979                         len),
980                  ailist->ai_canonname ? ailist->ai_canonname : "(NULL)"));
981
982         if (ailist) {
983                 freeaddrinfo(ailist);
984         }
985         return false;
986 }
987
988 /*******************************************************************
989  Deal with the singleton cache.
990 ******************************************************************/
991
992 struct name_addr_pair {
993         struct sockaddr_storage ss;
994         const char *name;
995 };
996
997 /*******************************************************************
998  Lookup a name/addr pair. Returns memory allocated from memcache.
999 ******************************************************************/
1000
1001 static bool lookup_nc(struct name_addr_pair *nc)
1002 {
1003         DATA_BLOB tmp;
1004
1005         ZERO_STRUCTP(nc);
1006
1007         if (!memcache_lookup(
1008                         NULL, SINGLETON_CACHE,
1009                         data_blob_string_const_null("get_peer_name"),
1010                         &tmp)) {
1011                 return false;
1012         }
1013
1014         memcpy(&nc->ss, tmp.data, sizeof(nc->ss));
1015         nc->name = (const char *)tmp.data + sizeof(nc->ss);
1016         return true;
1017 }
1018
1019 /*******************************************************************
1020  Save a name/addr pair.
1021 ******************************************************************/
1022
1023 static void store_nc(const struct name_addr_pair *nc)
1024 {
1025         DATA_BLOB tmp;
1026         size_t namelen = strlen(nc->name);
1027
1028         tmp = data_blob(NULL, sizeof(nc->ss) + namelen + 1);
1029         if (!tmp.data) {
1030                 return;
1031         }
1032         memcpy(tmp.data, &nc->ss, sizeof(nc->ss));
1033         memcpy(tmp.data+sizeof(nc->ss), nc->name, namelen+1);
1034
1035         memcache_add(NULL, SINGLETON_CACHE,
1036                         data_blob_string_const_null("get_peer_name"),
1037                         tmp);
1038         data_blob_free(&tmp);
1039 }
1040
1041 /*******************************************************************
1042  Return the DNS name of the remote end of a socket.
1043 ******************************************************************/
1044
1045 const char *get_peer_name(int fd, bool force_lookup)
1046 {
1047         struct name_addr_pair nc;
1048         char addr_buf[INET6_ADDRSTRLEN];
1049         struct sockaddr_storage ss;
1050         socklen_t length = sizeof(ss);
1051         const char *p;
1052         int ret;
1053         char name_buf[MAX_DNS_NAME_LENGTH];
1054         char tmp_name[MAX_DNS_NAME_LENGTH];
1055
1056         /* reverse lookups can be *very* expensive, and in many
1057            situations won't work because many networks don't link dhcp
1058            with dns. To avoid the delay we avoid the lookup if
1059            possible */
1060         if (!lp_hostname_lookups() && (force_lookup == false)) {
1061                 length = sizeof(nc.ss);
1062                 nc.name = get_peer_addr_internal(fd, addr_buf, sizeof(addr_buf),
1063                         (struct sockaddr *)&nc.ss, &length);
1064                 store_nc(&nc);
1065                 lookup_nc(&nc);
1066                 return nc.name ? nc.name : "UNKNOWN";
1067         }
1068
1069         lookup_nc(&nc);
1070
1071         memset(&ss, '\0', sizeof(ss));
1072         p = get_peer_addr_internal(fd, addr_buf, sizeof(addr_buf), (struct sockaddr *)&ss, &length);
1073
1074         /* it might be the same as the last one - save some DNS work */
1075         if (sockaddr_equal((struct sockaddr *)&ss, (struct sockaddr *)&nc.ss)) {
1076                 return nc.name ? nc.name : "UNKNOWN";
1077         }
1078
1079         /* Not the same. We need to lookup. */
1080         if (fd == -1) {
1081                 return "UNKNOWN";
1082         }
1083
1084         /* Look up the remote host name. */
1085         ret = sys_getnameinfo((struct sockaddr *)&ss,
1086                         length,
1087                         name_buf,
1088                         sizeof(name_buf),
1089                         NULL,
1090                         0,
1091                         0);
1092
1093         if (ret) {
1094                 DEBUG(1,("get_peer_name: getnameinfo failed "
1095                         "for %s with error %s\n",
1096                         p,
1097                         gai_strerror(ret)));
1098                 strlcpy(name_buf, p, sizeof(name_buf));
1099         } else {
1100                 if (!matchname(name_buf, (struct sockaddr *)&ss, length)) {
1101                         DEBUG(0,("Matchname failed on %s %s\n",name_buf,p));
1102                         strlcpy(name_buf,"UNKNOWN",sizeof(name_buf));
1103                 }
1104         }
1105
1106         strlcpy(tmp_name, name_buf, sizeof(tmp_name));
1107         alpha_strcpy(name_buf, tmp_name, "_-.", sizeof(name_buf));
1108         if (strstr(name_buf,"..")) {
1109                 strlcpy(name_buf, "UNKNOWN", sizeof(name_buf));
1110         }
1111
1112         nc.name = name_buf;
1113         nc.ss = ss;
1114
1115         store_nc(&nc);
1116         lookup_nc(&nc);
1117         return nc.name ? nc.name : "UNKNOWN";
1118 }
1119
1120 /*******************************************************************
1121  Return the IP addr of the remote end of a socket as a string.
1122  ******************************************************************/
1123
1124 const char *get_peer_addr(int fd, char *addr, size_t addr_len)
1125 {
1126         return get_peer_addr_internal(fd, addr, addr_len, NULL, NULL);
1127 }
1128
1129 /*******************************************************************
1130  Create protected unix domain socket.
1131
1132  Some unixes cannot set permissions on a ux-dom-sock, so we
1133  have to make sure that the directory contains the protection
1134  permissions instead.
1135  ******************************************************************/
1136
1137 int create_pipe_sock(const char *socket_dir,
1138                      const char *socket_name,
1139                      mode_t dir_perms)
1140 {
1141 #ifdef HAVE_UNIXSOCKET
1142         struct sockaddr_un sunaddr;
1143         struct stat st;
1144         int sock;
1145         mode_t old_umask;
1146         char *path = NULL;
1147
1148         old_umask = umask(0);
1149
1150         /* Create the socket directory or reuse the existing one */
1151
1152         if (lstat(socket_dir, &st) == -1) {
1153                 if (errno == ENOENT) {
1154                         /* Create directory */
1155                         if (mkdir(socket_dir, dir_perms) == -1) {
1156                                 DEBUG(0, ("error creating socket directory "
1157                                         "%s: %s\n", socket_dir,
1158                                         strerror(errno)));
1159                                 goto out_umask;
1160                         }
1161                 } else {
1162                         DEBUG(0, ("lstat failed on socket directory %s: %s\n",
1163                                 socket_dir, strerror(errno)));
1164                         goto out_umask;
1165                 }
1166         } else {
1167                 /* Check ownership and permission on existing directory */
1168                 if (!S_ISDIR(st.st_mode)) {
1169                         DEBUG(0, ("socket directory '%s' isn't a directory\n",
1170                                 socket_dir));
1171                         goto out_umask;
1172                 }
1173                 if (st.st_uid != sec_initial_uid()) {
1174                         DEBUG(0, ("invalid ownership on directory "
1175                                   "'%s'\n", socket_dir));
1176                         umask(old_umask);
1177                         goto out_umask;
1178                 }
1179                 if ((st.st_mode & 0777) != dir_perms) {
1180                         DEBUG(0, ("invalid permissions on directory "
1181                                   "'%s': has 0%o should be 0%o\n", socket_dir,
1182                                   (st.st_mode & 0777), dir_perms));
1183                         umask(old_umask);
1184                         goto out_umask;
1185                 }
1186         }
1187
1188         /* Create the socket file */
1189
1190         sock = socket(AF_UNIX, SOCK_STREAM, 0);
1191
1192         if (sock == -1) {
1193                 DEBUG(0, ("create_pipe_sock: socket error %s\n",
1194                         strerror(errno) ));
1195                 goto out_close;
1196         }
1197
1198         if (asprintf(&path, "%s/%s", socket_dir, socket_name) == -1) {
1199                 goto out_close;
1200         }
1201
1202         unlink(path);
1203         memset(&sunaddr, 0, sizeof(sunaddr));
1204         sunaddr.sun_family = AF_UNIX;
1205         strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path));
1206
1207         if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) {
1208                 DEBUG(0, ("bind failed on pipe socket %s: %s\n", path,
1209                         strerror(errno)));
1210                 goto out_close;
1211         }
1212
1213         if (listen(sock, 5) == -1) {
1214                 DEBUG(0, ("listen failed on pipe socket %s: %s\n", path,
1215                         strerror(errno)));
1216                 goto out_close;
1217         }
1218
1219         SAFE_FREE(path);
1220
1221         umask(old_umask);
1222         return sock;
1223
1224 out_close:
1225         SAFE_FREE(path);
1226         if (sock != -1)
1227                 close(sock);
1228
1229 out_umask:
1230         umask(old_umask);
1231         return -1;
1232
1233 #else
1234         DEBUG(0, ("create_pipe_sock: No Unix sockets on this system\n"));
1235         return -1;
1236 #endif /* HAVE_UNIXSOCKET */
1237 }
1238
1239 /****************************************************************************
1240  Get my own canonical name, including domain.
1241 ****************************************************************************/
1242
1243 const char *get_mydnsfullname(void)
1244 {
1245         struct addrinfo *res = NULL;
1246         char my_hostname[HOST_NAME_MAX];
1247         bool ret;
1248         DATA_BLOB tmp;
1249
1250         if (memcache_lookup(NULL, SINGLETON_CACHE,
1251                         data_blob_string_const_null("get_mydnsfullname"),
1252                         &tmp)) {
1253                 SMB_ASSERT(tmp.length > 0);
1254                 return (const char *)tmp.data;
1255         }
1256
1257         /* get my host name */
1258         if (gethostname(my_hostname, sizeof(my_hostname)) == -1) {
1259                 DEBUG(0,("get_mydnsfullname: gethostname failed\n"));
1260                 return NULL;
1261         }
1262
1263         /* Ensure null termination. */
1264         my_hostname[sizeof(my_hostname)-1] = '\0';
1265
1266         ret = interpret_string_addr_internal(&res,
1267                                 my_hostname,
1268                                 AI_ADDRCONFIG|AI_CANONNAME);
1269
1270         if (!ret || res == NULL) {
1271                 DEBUG(3,("get_mydnsfullname: getaddrinfo failed for "
1272                         "name %s [%s]\n",
1273                         my_hostname,
1274                         gai_strerror(ret) ));
1275                 return NULL;
1276         }
1277
1278         /*
1279          * Make sure that getaddrinfo() returns the "correct" host name.
1280          */
1281
1282         if (res->ai_canonname == NULL) {
1283                 DEBUG(3,("get_mydnsfullname: failed to get "
1284                         "canonical name for %s\n",
1285                         my_hostname));
1286                 freeaddrinfo(res);
1287                 return NULL;
1288         }
1289
1290         /* This copies the data, so we must do a lookup
1291          * afterwards to find the value to return.
1292          */
1293
1294         memcache_add(NULL, SINGLETON_CACHE,
1295                         data_blob_string_const_null("get_mydnsfullname"),
1296                         data_blob_string_const_null(res->ai_canonname));
1297
1298         if (!memcache_lookup(NULL, SINGLETON_CACHE,
1299                         data_blob_string_const_null("get_mydnsfullname"),
1300                         &tmp)) {
1301                 tmp = data_blob_talloc(talloc_tos(), res->ai_canonname,
1302                                 strlen(res->ai_canonname) + 1);
1303         }
1304
1305         freeaddrinfo(res);
1306
1307         return (const char *)tmp.data;
1308 }
1309
1310 /************************************************************
1311  Is this my ip address ?
1312 ************************************************************/
1313
1314 static bool is_my_ipaddr(const char *ipaddr_str)
1315 {
1316         struct sockaddr_storage ss;
1317         struct iface_struct *nics;
1318         int i, n;
1319
1320         if (!interpret_string_addr(&ss, ipaddr_str, AI_NUMERICHOST)) {
1321                 return false;
1322         }
1323
1324         if (is_zero_addr(&ss)) {
1325                 return false;
1326         }
1327
1328         if (ismyaddr((struct sockaddr *)&ss) ||
1329                         is_loopback_addr((struct sockaddr *)&ss)) {
1330                 return true;
1331         }
1332
1333         n = get_interfaces(talloc_tos(), &nics);
1334         for (i=0; i<n; i++) {
1335                 if (sockaddr_equal((struct sockaddr *)&nics[i].ip, (struct sockaddr *)&ss)) {
1336                         TALLOC_FREE(nics);
1337                         return true;
1338                 }
1339         }
1340         TALLOC_FREE(nics);
1341         return false;
1342 }
1343
1344 /************************************************************
1345  Is this my name ?
1346 ************************************************************/
1347
1348 bool is_myname_or_ipaddr(const char *s)
1349 {
1350         TALLOC_CTX *ctx = talloc_tos();
1351         char *name = NULL;
1352         const char *dnsname;
1353         char *servername = NULL;
1354
1355         if (!s) {
1356                 return false;
1357         }
1358
1359         /* Santize the string from '\\name' */
1360         name = talloc_strdup(ctx, s);
1361         if (!name) {
1362                 return false;
1363         }
1364
1365         servername = strrchr_m(name, '\\' );
1366         if (!servername) {
1367                 servername = name;
1368         } else {
1369                 servername++;
1370         }
1371
1372         /* Optimize for the common case */
1373         if (strequal(servername, lp_netbios_name())) {
1374                 return true;
1375         }
1376
1377         /* Check for an alias */
1378         if (is_myname(servername)) {
1379                 return true;
1380         }
1381
1382         /* Check for loopback */
1383         if (strequal(servername, "127.0.0.1") ||
1384                         strequal(servername, "::1")) {
1385                 return true;
1386         }
1387
1388         if (strequal(servername, "localhost")) {
1389                 return true;
1390         }
1391
1392         /* Maybe it's my dns name */
1393         dnsname = get_mydnsfullname();
1394         if (dnsname && strequal(servername, dnsname)) {
1395                 return true;
1396         }
1397
1398         /* Maybe its an IP address? */
1399         if (is_ipaddress(servername)) {
1400                 return is_my_ipaddr(servername);
1401         }
1402
1403         /* Handle possible CNAME records - convert to an IP addr. list. */
1404         {
1405                 /* Use DNS to resolve the name, check all addresses. */
1406                 struct addrinfo *p = NULL;
1407                 struct addrinfo *res = NULL;
1408
1409                 if (!interpret_string_addr_internal(&res,
1410                                 servername,
1411                                 AI_ADDRCONFIG)) {
1412                         return false;
1413                 }
1414
1415                 for (p = res; p; p = p->ai_next) {
1416                         char addr[INET6_ADDRSTRLEN];
1417                         struct sockaddr_storage ss;
1418
1419                         ZERO_STRUCT(ss);
1420                         memcpy(&ss, p->ai_addr, p->ai_addrlen);
1421                         print_sockaddr(addr,
1422                                         sizeof(addr),
1423                                         &ss);
1424                         if (is_my_ipaddr(addr)) {
1425                                 freeaddrinfo(res);
1426                                 return true;
1427                         }
1428                 }
1429                 freeaddrinfo(res);
1430         }
1431
1432         /* No match */
1433         return false;
1434 }
1435
1436 struct getaddrinfo_state {
1437         const char *node;
1438         const char *service;
1439         const struct addrinfo *hints;
1440         struct addrinfo *res;
1441         int ret;
1442 };
1443
1444 static void getaddrinfo_do(void *private_data);
1445 static void getaddrinfo_done(struct tevent_req *subreq);
1446
1447 struct tevent_req *getaddrinfo_send(TALLOC_CTX *mem_ctx,
1448                                     struct tevent_context *ev,
1449                                     struct fncall_context *ctx,
1450                                     const char *node,
1451                                     const char *service,
1452                                     const struct addrinfo *hints)
1453 {
1454         struct tevent_req *req, *subreq;
1455         struct getaddrinfo_state *state;
1456
1457         req = tevent_req_create(mem_ctx, &state, struct getaddrinfo_state);
1458         if (req == NULL) {
1459                 return NULL;
1460         }
1461
1462         state->node = node;
1463         state->service = service;
1464         state->hints = hints;
1465
1466         subreq = fncall_send(state, ev, ctx, getaddrinfo_do, state);
1467         if (tevent_req_nomem(subreq, req)) {
1468                 return tevent_req_post(req, ev);
1469         }
1470         tevent_req_set_callback(subreq, getaddrinfo_done, req);
1471         return req;
1472 }
1473
1474 static void getaddrinfo_do(void *private_data)
1475 {
1476         struct getaddrinfo_state *state =
1477                 (struct getaddrinfo_state *)private_data;
1478
1479         state->ret = getaddrinfo(state->node, state->service, state->hints,
1480                                  &state->res);
1481 }
1482
1483 static void getaddrinfo_done(struct tevent_req *subreq)
1484 {
1485         struct tevent_req *req = tevent_req_callback_data(
1486                 subreq, struct tevent_req);
1487         int ret, err;
1488
1489         ret = fncall_recv(subreq, &err);
1490         TALLOC_FREE(subreq);
1491         if (ret == -1) {
1492                 tevent_req_error(req, err);
1493                 return;
1494         }
1495         tevent_req_done(req);
1496 }
1497
1498 int getaddrinfo_recv(struct tevent_req *req, struct addrinfo **res)
1499 {
1500         struct getaddrinfo_state *state = tevent_req_data(
1501                 req, struct getaddrinfo_state);
1502         int err;
1503
1504         if (tevent_req_is_unix_error(req, &err)) {
1505                 switch(err) {
1506                 case ENOMEM:
1507                         return EAI_MEMORY;
1508                 default:
1509                         return EAI_FAIL;
1510                 }
1511         }
1512         if (state->ret == 0) {
1513                 *res = state->res;
1514         }
1515         return state->ret;
1516 }
1517
1518 int poll_one_fd(int fd, int events, int timeout, int *revents)
1519 {
1520         struct pollfd *fds;
1521         int ret;
1522         int saved_errno;
1523
1524         fds = talloc_zero_array(talloc_tos(), struct pollfd, 2);
1525         if (fds == NULL) {
1526                 errno = ENOMEM;
1527                 return -1;
1528         }
1529         fds[0].fd = fd;
1530         fds[0].events = events;
1531
1532         ret = sys_poll(fds, 1, timeout);
1533
1534         /*
1535          * Assign whatever poll did, even in the ret<=0 case.
1536          */
1537         *revents = fds[0].revents;
1538         saved_errno = errno;
1539         TALLOC_FREE(fds);
1540         errno = saved_errno;
1541
1542         return ret;
1543 }
1544
1545 int poll_intr_one_fd(int fd, int events, int timeout, int *revents)
1546 {
1547         struct pollfd pfd;
1548         int ret;
1549
1550         pfd.fd = fd;
1551         pfd.events = events;
1552
1553         ret = sys_poll_intr(&pfd, 1, timeout);
1554         if (ret <= 0) {
1555                 *revents = 0;
1556                 return ret;
1557         }
1558         *revents = pfd.revents;
1559         return 1;
1560 }