smbd: fix creation of BUILTIN\{Administrators,Users} when "tdbsam:map builtin = false"
[Samba/wip.git] / source3 / lib / util_sock.c
blobc5de61a094b2110f6fa69888b906338e39967476
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
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.
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.
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/>.
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 #include "../lib/tsocket/tsocket.h"
32 const char *client_addr(int fd, char *addr, size_t addrlen)
34 return get_peer_addr(fd,addr,addrlen);
37 #if 0
38 /* Not currently used. JRA. */
39 int client_socket_port(int fd)
41 return get_socket_port(fd);
43 #endif
45 /****************************************************************************
46 Determine if a file descriptor is in fact a socket.
47 ****************************************************************************/
49 bool is_a_socket(int fd)
51 int v;
52 socklen_t l;
53 l = sizeof(int);
54 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
57 /****************************************************************************
58 Read from a socket.
59 ****************************************************************************/
61 ssize_t read_udp_v4_socket(int fd,
62 char *buf,
63 size_t len,
64 struct sockaddr_storage *psa)
66 ssize_t ret;
67 socklen_t socklen = sizeof(*psa);
68 struct sockaddr_in *si = (struct sockaddr_in *)psa;
70 memset((char *)psa,'\0',socklen);
72 ret = (ssize_t)sys_recvfrom(fd,buf,len,0,
73 (struct sockaddr *)psa,&socklen);
74 if (ret <= 0) {
75 /* Don't print a low debug error for a non-blocking socket. */
76 if (errno == EAGAIN) {
77 DEBUG(10,("read_udp_v4_socket: returned EAGAIN\n"));
78 } else {
79 DEBUG(2,("read_udp_v4_socket: failed. errno=%s\n",
80 strerror(errno)));
82 return 0;
85 if (psa->ss_family != AF_INET) {
86 DEBUG(2,("read_udp_v4_socket: invalid address family %d "
87 "(not IPv4)\n", (int)psa->ss_family));
88 return 0;
91 DEBUG(10,("read_udp_v4_socket: ip %s port %d read: %lu\n",
92 inet_ntoa(si->sin_addr),
93 si->sin_port,
94 (unsigned long)ret));
96 return ret;
99 /****************************************************************************
100 Read data from a file descriptor with a timout in msec.
101 mincount = if timeout, minimum to read before returning
102 maxcount = number to be read.
103 time_out = timeout in milliseconds
104 NB. This can be called with a non-socket fd, don't change
105 sys_read() to sys_recv() or other socket call.
106 ****************************************************************************/
108 NTSTATUS read_fd_with_timeout(int fd, char *buf,
109 size_t mincnt, size_t maxcnt,
110 unsigned int time_out,
111 size_t *size_ret)
113 int pollrtn;
114 ssize_t readret;
115 size_t nread = 0;
117 /* just checking .... */
118 if (maxcnt <= 0)
119 return NT_STATUS_OK;
121 /* Blocking read */
122 if (time_out == 0) {
123 if (mincnt == 0) {
124 mincnt = maxcnt;
127 while (nread < mincnt) {
128 readret = sys_read(fd, buf + nread, maxcnt - nread);
130 if (readret == 0) {
131 DEBUG(5,("read_fd_with_timeout: "
132 "blocking read. EOF from client.\n"));
133 return NT_STATUS_END_OF_FILE;
136 if (readret == -1) {
137 return map_nt_error_from_unix(errno);
139 nread += readret;
141 goto done;
144 /* Most difficult - timeout read */
145 /* If this is ever called on a disk file and
146 mincnt is greater then the filesize then
147 system performance will suffer severely as
148 select always returns true on disk files */
150 for (nread=0; nread < mincnt; ) {
151 int revents;
153 pollrtn = poll_intr_one_fd(fd, POLLIN|POLLHUP, time_out,
154 &revents);
156 /* Check if error */
157 if (pollrtn == -1) {
158 return map_nt_error_from_unix(errno);
161 /* Did we timeout ? */
162 if ((pollrtn == 0) ||
163 ((revents & (POLLIN|POLLHUP|POLLERR)) == 0)) {
164 DEBUG(10,("read_fd_with_timeout: timeout read. "
165 "select timed out.\n"));
166 return NT_STATUS_IO_TIMEOUT;
169 readret = sys_read(fd, buf+nread, maxcnt-nread);
171 if (readret == 0) {
172 /* we got EOF on the file descriptor */
173 DEBUG(5,("read_fd_with_timeout: timeout read. "
174 "EOF from client.\n"));
175 return NT_STATUS_END_OF_FILE;
178 if (readret == -1) {
179 return map_nt_error_from_unix(errno);
182 nread += readret;
185 done:
186 /* Return the number we got */
187 if (size_ret) {
188 *size_ret = nread;
190 return NT_STATUS_OK;
193 /****************************************************************************
194 Read data from an fd, reading exactly N bytes.
195 NB. This can be called with a non-socket fd, don't add dependencies
196 on socket calls.
197 ****************************************************************************/
199 NTSTATUS read_data(int fd, char *buffer, size_t N)
201 return read_fd_with_timeout(fd, buffer, N, N, 0, NULL);
204 ssize_t iov_buflen(const struct iovec *iov, int iovcnt)
206 size_t buflen = 0;
207 int i;
209 for (i=0; i<iovcnt; i++) {
210 size_t thislen = iov[i].iov_len;
211 size_t tmp = buflen + thislen;
213 if ((tmp < buflen) || (tmp < thislen)) {
214 /* overflow */
215 return -1;
217 buflen = tmp;
219 return buflen;
222 uint8_t *iov_buf(TALLOC_CTX *mem_ctx, const struct iovec *iov, int iovcnt)
224 int i;
225 ssize_t buflen;
226 uint8_t *buf, *p;
228 buflen = iov_buflen(iov, iovcnt);
229 if (buflen == -1) {
230 return NULL;
232 buf = talloc_array(mem_ctx, uint8_t, buflen);
233 if (buf == NULL) {
234 return NULL;
237 p = buf;
238 for (i=0; i<iovcnt; i++) {
239 size_t len = iov[i].iov_len;
241 memcpy(p, iov[i].iov_base, len);
242 p += len;
244 return buf;
247 /****************************************************************************
248 Write all data from an iov array
249 NB. This can be called with a non-socket fd, don't add dependencies
250 on socket calls.
251 ****************************************************************************/
253 ssize_t write_data_iov(int fd, const struct iovec *orig_iov, int iovcnt)
255 ssize_t to_send;
256 ssize_t thistime;
257 size_t sent;
258 struct iovec *iov_copy, *iov;
260 to_send = iov_buflen(orig_iov, iovcnt);
261 if (to_send == -1) {
262 errno = EINVAL;
263 return -1;
266 thistime = sys_writev(fd, orig_iov, iovcnt);
267 if ((thistime <= 0) || (thistime == to_send)) {
268 return thistime;
270 sent = thistime;
273 * We could not send everything in one call. Make a copy of iov that
274 * we can mess with. We keep a copy of the array start in iov_copy for
275 * the TALLOC_FREE, because we're going to modify iov later on,
276 * discarding elements.
279 iov_copy = (struct iovec *)talloc_memdup(
280 talloc_tos(), orig_iov, sizeof(struct iovec) * iovcnt);
282 if (iov_copy == NULL) {
283 errno = ENOMEM;
284 return -1;
286 iov = iov_copy;
288 while (sent < to_send) {
290 * We have to discard "thistime" bytes from the beginning
291 * iov array, "thistime" contains the number of bytes sent
292 * via writev last.
294 while (thistime > 0) {
295 if (thistime < iov[0].iov_len) {
296 char *new_base =
297 (char *)iov[0].iov_base + thistime;
298 iov[0].iov_base = (void *)new_base;
299 iov[0].iov_len -= thistime;
300 break;
302 thistime -= iov[0].iov_len;
303 iov += 1;
304 iovcnt -= 1;
307 thistime = sys_writev(fd, iov, iovcnt);
308 if (thistime <= 0) {
309 break;
311 sent += thistime;
314 TALLOC_FREE(iov_copy);
315 return sent;
318 /****************************************************************************
319 Write data to a fd.
320 NB. This can be called with a non-socket fd, don't add dependencies
321 on socket calls.
322 ****************************************************************************/
324 ssize_t write_data(int fd, const char *buffer, size_t N)
326 struct iovec iov;
328 iov.iov_base = discard_const_p(void, buffer);
329 iov.iov_len = N;
330 return write_data_iov(fd, &iov, 1);
333 /****************************************************************************
334 Send a keepalive packet (rfc1002).
335 ****************************************************************************/
337 bool send_keepalive(int client)
339 unsigned char buf[4];
341 buf[0] = NBSSkeepalive;
342 buf[1] = buf[2] = buf[3] = 0;
344 return(write_data(client,(char *)buf,4) == 4);
347 /****************************************************************************
348 Read 4 bytes of a smb packet and return the smb length of the packet.
349 Store the result in the buffer.
350 This version of the function will return a length of zero on receiving
351 a keepalive packet.
352 Timeout is in milliseconds.
353 ****************************************************************************/
355 NTSTATUS read_smb_length_return_keepalive(int fd, char *inbuf,
356 unsigned int timeout,
357 size_t *len)
359 int msg_type;
360 NTSTATUS status;
362 status = read_fd_with_timeout(fd, inbuf, 4, 4, timeout, NULL);
364 if (!NT_STATUS_IS_OK(status)) {
365 return status;
368 *len = smb_len(inbuf);
369 msg_type = CVAL(inbuf,0);
371 if (msg_type == NBSSkeepalive) {
372 DEBUG(5,("Got keepalive packet\n"));
375 DEBUG(10,("got smb length of %lu\n",(unsigned long)(*len)));
377 return NT_STATUS_OK;
380 /****************************************************************************
381 Read an smb from a fd.
382 The timeout is in milliseconds.
383 This function will return on receipt of a session keepalive packet.
384 maxlen is the max number of bytes to return, not including the 4 byte
385 length. If zero it means buflen limit.
386 Doesn't check the MAC on signed packets.
387 ****************************************************************************/
389 NTSTATUS receive_smb_raw(int fd, char *buffer, size_t buflen, unsigned int timeout,
390 size_t maxlen, size_t *p_len)
392 size_t len;
393 NTSTATUS status;
395 status = read_smb_length_return_keepalive(fd,buffer,timeout,&len);
397 if (!NT_STATUS_IS_OK(status)) {
398 DEBUG(0, ("read_fd_with_timeout failed, read "
399 "error = %s.\n", nt_errstr(status)));
400 return status;
403 if (len > buflen) {
404 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
405 (unsigned long)len));
406 return NT_STATUS_INVALID_PARAMETER;
409 if(len > 0) {
410 if (maxlen) {
411 len = MIN(len,maxlen);
414 status = read_fd_with_timeout(
415 fd, buffer+4, len, len, timeout, &len);
417 if (!NT_STATUS_IS_OK(status)) {
418 DEBUG(0, ("read_fd_with_timeout failed, read error = "
419 "%s.\n", nt_errstr(status)));
420 return status;
423 /* not all of samba3 properly checks for packet-termination
424 * of strings. This ensures that we don't run off into
425 * empty space. */
426 SSVAL(buffer+4,len, 0);
429 *p_len = len;
430 return NT_STATUS_OK;
433 /****************************************************************************
434 Open a socket of the specified type, port, and address for incoming data.
435 ****************************************************************************/
437 int open_socket_in(int type,
438 uint16_t port,
439 int dlevel,
440 const struct sockaddr_storage *psock,
441 bool rebind)
443 struct sockaddr_storage sock;
444 int res;
445 socklen_t slen = sizeof(struct sockaddr_in);
447 sock = *psock;
449 #if defined(HAVE_IPV6)
450 if (sock.ss_family == AF_INET6) {
451 ((struct sockaddr_in6 *)&sock)->sin6_port = htons(port);
452 slen = sizeof(struct sockaddr_in6);
454 #endif
455 if (sock.ss_family == AF_INET) {
456 ((struct sockaddr_in *)&sock)->sin_port = htons(port);
459 res = socket(sock.ss_family, type, 0 );
460 if( res == -1 ) {
461 if( DEBUGLVL(0) ) {
462 dbgtext( "open_socket_in(): socket() call failed: " );
463 dbgtext( "%s\n", strerror( errno ) );
465 return -1;
468 /* This block sets/clears the SO_REUSEADDR and possibly SO_REUSEPORT. */
470 int val = rebind ? 1 : 0;
471 if( setsockopt(res,SOL_SOCKET,SO_REUSEADDR,
472 (char *)&val,sizeof(val)) == -1 ) {
473 if( DEBUGLVL( dlevel ) ) {
474 dbgtext( "open_socket_in(): setsockopt: " );
475 dbgtext( "SO_REUSEADDR = %s ",
476 val?"true":"false" );
477 dbgtext( "on port %d failed ", port );
478 dbgtext( "with error = %s\n", strerror(errno) );
481 #ifdef SO_REUSEPORT
482 if( setsockopt(res,SOL_SOCKET,SO_REUSEPORT,
483 (char *)&val,sizeof(val)) == -1 ) {
484 if( DEBUGLVL( dlevel ) ) {
485 dbgtext( "open_socket_in(): setsockopt: ");
486 dbgtext( "SO_REUSEPORT = %s ",
487 val?"true":"false");
488 dbgtext( "on port %d failed ", port);
489 dbgtext( "with error = %s\n", strerror(errno));
492 #endif /* SO_REUSEPORT */
495 #ifdef HAVE_IPV6
497 * As IPV6_V6ONLY is the default on some systems,
498 * we better try to be consistent and always use it.
500 * This also avoids using IPv4 via AF_INET6 sockets
501 * and makes sure %I never resolves to a '::ffff:192.168.0.1'
502 * string.
504 if (sock.ss_family == AF_INET6) {
505 int val = 1;
506 int ret;
508 ret = setsockopt(res, IPPROTO_IPV6, IPV6_V6ONLY,
509 (const void *)&val, sizeof(val));
510 if (ret == -1) {
511 if(DEBUGLVL(0)) {
512 dbgtext("open_socket_in(): IPV6_ONLY failed: ");
513 dbgtext("%s\n", strerror(errno));
515 close(res);
516 return -1;
519 #endif
521 /* now we've got a socket - we need to bind it */
522 if (bind(res, (struct sockaddr *)&sock, slen) == -1 ) {
523 if( DEBUGLVL(dlevel) && (port == NMB_PORT ||
524 port == NBT_SMB_PORT ||
525 port == TCP_SMB_PORT) ) {
526 char addr[INET6_ADDRSTRLEN];
527 print_sockaddr(addr, sizeof(addr),
528 &sock);
529 dbgtext( "bind failed on port %d ", port);
530 dbgtext( "socket_addr = %s.\n", addr);
531 dbgtext( "Error = %s\n", strerror(errno));
533 close(res);
534 return -1;
537 DEBUG( 10, ( "bind succeeded on port %d\n", port ) );
538 return( res );
541 struct open_socket_out_state {
542 int fd;
543 struct tevent_context *ev;
544 struct sockaddr_storage ss;
545 socklen_t salen;
546 uint16_t port;
547 int wait_usec;
550 static void open_socket_out_connected(struct tevent_req *subreq);
552 static int open_socket_out_state_destructor(struct open_socket_out_state *s)
554 if (s->fd != -1) {
555 close(s->fd);
557 return 0;
560 /****************************************************************************
561 Create an outgoing socket. timeout is in milliseconds.
562 **************************************************************************/
564 struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
565 struct tevent_context *ev,
566 const struct sockaddr_storage *pss,
567 uint16_t port,
568 int timeout)
570 char addr[INET6_ADDRSTRLEN];
571 struct tevent_req *result, *subreq;
572 struct open_socket_out_state *state;
573 NTSTATUS status;
575 result = tevent_req_create(mem_ctx, &state,
576 struct open_socket_out_state);
577 if (result == NULL) {
578 return NULL;
580 state->ev = ev;
581 state->ss = *pss;
582 state->port = port;
583 state->wait_usec = 10000;
584 state->salen = -1;
586 state->fd = socket(state->ss.ss_family, SOCK_STREAM, 0);
587 if (state->fd == -1) {
588 status = map_nt_error_from_unix(errno);
589 goto post_status;
591 talloc_set_destructor(state, open_socket_out_state_destructor);
593 if (!tevent_req_set_endtime(
594 result, ev, timeval_current_ofs_msec(timeout))) {
595 goto fail;
598 #if defined(HAVE_IPV6)
599 if (pss->ss_family == AF_INET6) {
600 struct sockaddr_in6 *psa6;
601 psa6 = (struct sockaddr_in6 *)&state->ss;
602 psa6->sin6_port = htons(port);
603 if (psa6->sin6_scope_id == 0
604 && IN6_IS_ADDR_LINKLOCAL(&psa6->sin6_addr)) {
605 setup_linklocal_scope_id(
606 (struct sockaddr *)&(state->ss));
608 state->salen = sizeof(struct sockaddr_in6);
610 #endif
611 if (pss->ss_family == AF_INET) {
612 struct sockaddr_in *psa;
613 psa = (struct sockaddr_in *)&state->ss;
614 psa->sin_port = htons(port);
615 state->salen = sizeof(struct sockaddr_in);
618 if (pss->ss_family == AF_UNIX) {
619 state->salen = sizeof(struct sockaddr_un);
622 print_sockaddr(addr, sizeof(addr), &state->ss);
623 DEBUG(3,("Connecting to %s at port %u\n", addr, (unsigned int)port));
625 subreq = async_connect_send(state, state->ev, state->fd,
626 (struct sockaddr *)&state->ss,
627 state->salen, NULL, NULL, NULL);
628 if ((subreq == NULL)
629 || !tevent_req_set_endtime(
630 subreq, state->ev,
631 timeval_current_ofs(0, state->wait_usec))) {
632 goto fail;
634 tevent_req_set_callback(subreq, open_socket_out_connected, result);
635 return result;
637 post_status:
638 tevent_req_nterror(result, status);
639 return tevent_req_post(result, ev);
640 fail:
641 TALLOC_FREE(result);
642 return NULL;
645 static void open_socket_out_connected(struct tevent_req *subreq)
647 struct tevent_req *req =
648 tevent_req_callback_data(subreq, struct tevent_req);
649 struct open_socket_out_state *state =
650 tevent_req_data(req, struct open_socket_out_state);
651 int ret;
652 int sys_errno;
654 ret = async_connect_recv(subreq, &sys_errno);
655 TALLOC_FREE(subreq);
656 if (ret == 0) {
657 tevent_req_done(req);
658 return;
661 if (
662 #ifdef ETIMEDOUT
663 (sys_errno == ETIMEDOUT) ||
664 #endif
665 (sys_errno == EINPROGRESS) ||
666 (sys_errno == EALREADY) ||
667 (sys_errno == EAGAIN)) {
670 * retry
673 if (state->wait_usec < 250000) {
674 state->wait_usec *= 1.5;
677 subreq = async_connect_send(state, state->ev, state->fd,
678 (struct sockaddr *)&state->ss,
679 state->salen, NULL, NULL, NULL);
680 if (tevent_req_nomem(subreq, req)) {
681 return;
683 if (!tevent_req_set_endtime(
684 subreq, state->ev,
685 timeval_current_ofs_usec(state->wait_usec))) {
686 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
687 return;
689 tevent_req_set_callback(subreq, open_socket_out_connected, req);
690 return;
693 #ifdef EISCONN
694 if (sys_errno == EISCONN) {
695 tevent_req_done(req);
696 return;
698 #endif
700 /* real error */
701 tevent_req_nterror(req, map_nt_error_from_unix(sys_errno));
704 NTSTATUS open_socket_out_recv(struct tevent_req *req, int *pfd)
706 struct open_socket_out_state *state =
707 tevent_req_data(req, struct open_socket_out_state);
708 NTSTATUS status;
710 if (tevent_req_is_nterror(req, &status)) {
711 return status;
713 *pfd = state->fd;
714 state->fd = -1;
715 return NT_STATUS_OK;
719 * @brief open a socket
721 * @param pss a struct sockaddr_storage defining the address to connect to
722 * @param port to connect to
723 * @param timeout in MILLISECONDS
724 * @param pfd file descriptor returned
726 * @return NTSTATUS code
728 NTSTATUS open_socket_out(const struct sockaddr_storage *pss, uint16_t port,
729 int timeout, int *pfd)
731 TALLOC_CTX *frame = talloc_stackframe();
732 struct tevent_context *ev;
733 struct tevent_req *req;
734 NTSTATUS status = NT_STATUS_NO_MEMORY;
736 ev = samba_tevent_context_init(frame);
737 if (ev == NULL) {
738 goto fail;
741 req = open_socket_out_send(frame, ev, pss, port, timeout);
742 if (req == NULL) {
743 goto fail;
745 if (!tevent_req_poll(req, ev)) {
746 status = NT_STATUS_INTERNAL_ERROR;
747 goto fail;
749 status = open_socket_out_recv(req, pfd);
750 fail:
751 TALLOC_FREE(frame);
752 return status;
755 struct open_socket_out_defer_state {
756 struct tevent_context *ev;
757 struct sockaddr_storage ss;
758 uint16_t port;
759 int timeout;
760 int fd;
763 static void open_socket_out_defer_waited(struct tevent_req *subreq);
764 static void open_socket_out_defer_connected(struct tevent_req *subreq);
766 struct tevent_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx,
767 struct tevent_context *ev,
768 struct timeval wait_time,
769 const struct sockaddr_storage *pss,
770 uint16_t port,
771 int timeout)
773 struct tevent_req *req, *subreq;
774 struct open_socket_out_defer_state *state;
776 req = tevent_req_create(mem_ctx, &state,
777 struct open_socket_out_defer_state);
778 if (req == NULL) {
779 return NULL;
781 state->ev = ev;
782 state->ss = *pss;
783 state->port = port;
784 state->timeout = timeout;
786 subreq = tevent_wakeup_send(
787 state, ev,
788 timeval_current_ofs(wait_time.tv_sec, wait_time.tv_usec));
789 if (subreq == NULL) {
790 goto fail;
792 tevent_req_set_callback(subreq, open_socket_out_defer_waited, req);
793 return req;
794 fail:
795 TALLOC_FREE(req);
796 return NULL;
799 static void open_socket_out_defer_waited(struct tevent_req *subreq)
801 struct tevent_req *req = tevent_req_callback_data(
802 subreq, struct tevent_req);
803 struct open_socket_out_defer_state *state = tevent_req_data(
804 req, struct open_socket_out_defer_state);
805 bool ret;
807 ret = tevent_wakeup_recv(subreq);
808 TALLOC_FREE(subreq);
809 if (!ret) {
810 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
811 return;
814 subreq = open_socket_out_send(state, state->ev, &state->ss,
815 state->port, state->timeout);
816 if (tevent_req_nomem(subreq, req)) {
817 return;
819 tevent_req_set_callback(subreq, open_socket_out_defer_connected, req);
822 static void open_socket_out_defer_connected(struct tevent_req *subreq)
824 struct tevent_req *req = tevent_req_callback_data(
825 subreq, struct tevent_req);
826 struct open_socket_out_defer_state *state = tevent_req_data(
827 req, struct open_socket_out_defer_state);
828 NTSTATUS status;
830 status = open_socket_out_recv(subreq, &state->fd);
831 TALLOC_FREE(subreq);
832 if (!NT_STATUS_IS_OK(status)) {
833 tevent_req_nterror(req, status);
834 return;
836 tevent_req_done(req);
839 NTSTATUS open_socket_out_defer_recv(struct tevent_req *req, int *pfd)
841 struct open_socket_out_defer_state *state = tevent_req_data(
842 req, struct open_socket_out_defer_state);
843 NTSTATUS status;
845 if (tevent_req_is_nterror(req, &status)) {
846 return status;
848 *pfd = state->fd;
849 state->fd = -1;
850 return NT_STATUS_OK;
853 /****************************************************************************
854 Open a connected UDP socket to host on port
855 **************************************************************************/
857 int open_udp_socket(const char *host, int port)
859 struct sockaddr_storage ss;
860 int res;
861 socklen_t salen;
863 if (!interpret_string_addr(&ss, host, 0)) {
864 DEBUG(10,("open_udp_socket: can't resolve name %s\n",
865 host));
866 return -1;
869 res = socket(ss.ss_family, SOCK_DGRAM, 0);
870 if (res == -1) {
871 return -1;
874 #if defined(HAVE_IPV6)
875 if (ss.ss_family == AF_INET6) {
876 struct sockaddr_in6 *psa6;
877 psa6 = (struct sockaddr_in6 *)&ss;
878 psa6->sin6_port = htons(port);
879 if (psa6->sin6_scope_id == 0
880 && IN6_IS_ADDR_LINKLOCAL(&psa6->sin6_addr)) {
881 setup_linklocal_scope_id(
882 (struct sockaddr *)&ss);
884 salen = sizeof(struct sockaddr_in6);
885 } else
886 #endif
887 if (ss.ss_family == AF_INET) {
888 struct sockaddr_in *psa;
889 psa = (struct sockaddr_in *)&ss;
890 psa->sin_port = htons(port);
891 salen = sizeof(struct sockaddr_in);
892 } else {
893 DEBUG(1, ("unknown socket family %d", ss.ss_family));
894 close(res);
895 return -1;
898 if (connect(res, (struct sockaddr *)&ss, salen)) {
899 close(res);
900 return -1;
903 return res;
906 /*******************************************************************
907 Return the IP addr of the remote end of a socket as a string.
908 Optionally return the struct sockaddr_storage.
909 ******************************************************************/
911 static const char *get_peer_addr_internal(int fd,
912 char *addr_buf,
913 size_t addr_buf_len,
914 struct sockaddr *pss,
915 socklen_t *plength)
917 struct sockaddr_storage ss;
918 socklen_t length = sizeof(ss);
920 strlcpy(addr_buf,"0.0.0.0",addr_buf_len);
922 if (fd == -1) {
923 return addr_buf;
926 if (pss == NULL) {
927 pss = (struct sockaddr *)&ss;
928 plength = &length;
931 if (getpeername(fd, (struct sockaddr *)pss, plength) < 0) {
932 int level = (errno == ENOTCONN) ? 2 : 0;
933 DEBUG(level, ("getpeername failed. Error was %s\n",
934 strerror(errno)));
935 return addr_buf;
938 print_sockaddr_len(addr_buf,
939 addr_buf_len,
940 pss,
941 *plength);
942 return addr_buf;
945 /*******************************************************************
946 Matchname - determine if host name matches IP address. Used to
947 confirm a hostname lookup to prevent spoof attacks.
948 ******************************************************************/
950 static bool matchname(const char *remotehost,
951 const struct sockaddr *pss,
952 socklen_t len)
954 struct addrinfo *res = NULL;
955 struct addrinfo *ailist = NULL;
956 char addr_buf[INET6_ADDRSTRLEN];
957 bool ret = interpret_string_addr_internal(&ailist,
958 remotehost,
959 AI_ADDRCONFIG|AI_CANONNAME);
961 if (!ret || ailist == NULL) {
962 DEBUG(3,("matchname: getaddrinfo failed for "
963 "name %s [%s]\n",
964 remotehost,
965 gai_strerror(ret) ));
966 return false;
970 * Make sure that getaddrinfo() returns the "correct" host name.
973 if (ailist->ai_canonname == NULL ||
974 (!strequal(remotehost, ailist->ai_canonname) &&
975 !strequal(remotehost, "localhost"))) {
976 DEBUG(0,("matchname: host name/name mismatch: %s != %s\n",
977 remotehost,
978 ailist->ai_canonname ?
979 ailist->ai_canonname : "(NULL)"));
980 freeaddrinfo(ailist);
981 return false;
984 /* Look up the host address in the address list we just got. */
985 for (res = ailist; res; res = res->ai_next) {
986 if (!res->ai_addr) {
987 continue;
989 if (sockaddr_equal((const struct sockaddr *)res->ai_addr,
990 (const struct sockaddr *)pss)) {
991 freeaddrinfo(ailist);
992 return true;
997 * The host name does not map to the original host address. Perhaps
998 * someone has compromised a name server. More likely someone botched
999 * it, but that could be dangerous, too.
1002 DEBUG(0,("matchname: host name/address mismatch: %s != %s\n",
1003 print_sockaddr_len(addr_buf,
1004 sizeof(addr_buf),
1005 pss,
1006 len),
1007 ailist->ai_canonname ? ailist->ai_canonname : "(NULL)"));
1009 if (ailist) {
1010 freeaddrinfo(ailist);
1012 return false;
1015 /*******************************************************************
1016 Deal with the singleton cache.
1017 ******************************************************************/
1019 struct name_addr_pair {
1020 struct sockaddr_storage ss;
1021 const char *name;
1024 /*******************************************************************
1025 Lookup a name/addr pair. Returns memory allocated from memcache.
1026 ******************************************************************/
1028 static bool lookup_nc(struct name_addr_pair *nc)
1030 DATA_BLOB tmp;
1032 ZERO_STRUCTP(nc);
1034 if (!memcache_lookup(
1035 NULL, SINGLETON_CACHE,
1036 data_blob_string_const_null("get_peer_name"),
1037 &tmp)) {
1038 return false;
1041 memcpy(&nc->ss, tmp.data, sizeof(nc->ss));
1042 nc->name = (const char *)tmp.data + sizeof(nc->ss);
1043 return true;
1046 /*******************************************************************
1047 Save a name/addr pair.
1048 ******************************************************************/
1050 static void store_nc(const struct name_addr_pair *nc)
1052 DATA_BLOB tmp;
1053 size_t namelen = strlen(nc->name);
1055 tmp = data_blob(NULL, sizeof(nc->ss) + namelen + 1);
1056 if (!tmp.data) {
1057 return;
1059 memcpy(tmp.data, &nc->ss, sizeof(nc->ss));
1060 memcpy(tmp.data+sizeof(nc->ss), nc->name, namelen+1);
1062 memcache_add(NULL, SINGLETON_CACHE,
1063 data_blob_string_const_null("get_peer_name"),
1064 tmp);
1065 data_blob_free(&tmp);
1068 /*******************************************************************
1069 Return the IP addr of the remote end of a socket as a string.
1070 ******************************************************************/
1072 const char *get_peer_addr(int fd, char *addr, size_t addr_len)
1074 return get_peer_addr_internal(fd, addr, addr_len, NULL, NULL);
1077 int get_remote_hostname(const struct tsocket_address *remote_address,
1078 char **name,
1079 TALLOC_CTX *mem_ctx)
1081 char name_buf[MAX_DNS_NAME_LENGTH];
1082 char tmp_name[MAX_DNS_NAME_LENGTH];
1083 struct name_addr_pair nc;
1084 struct sockaddr_storage ss;
1085 ssize_t len;
1086 int rc;
1088 if (!lp_hostname_lookups()) {
1089 nc.name = tsocket_address_inet_addr_string(remote_address,
1090 mem_ctx);
1091 if (nc.name == NULL) {
1092 return -1;
1095 len = tsocket_address_bsd_sockaddr(remote_address,
1096 (struct sockaddr *) &nc.ss,
1097 sizeof(struct sockaddr_storage));
1098 if (len < 0) {
1099 return -1;
1102 store_nc(&nc);
1103 lookup_nc(&nc);
1105 if (nc.name == NULL) {
1106 *name = talloc_strdup(mem_ctx, "UNKNOWN");
1107 } else {
1108 *name = talloc_strdup(mem_ctx, nc.name);
1110 return 0;
1113 lookup_nc(&nc);
1115 ZERO_STRUCT(ss);
1117 len = tsocket_address_bsd_sockaddr(remote_address,
1118 (struct sockaddr *) &ss,
1119 sizeof(struct sockaddr_storage));
1120 if (len < 0) {
1121 return -1;
1124 /* it might be the same as the last one - save some DNS work */
1125 if (sockaddr_equal((struct sockaddr *)&ss, (struct sockaddr *)&nc.ss)) {
1126 if (nc.name == NULL) {
1127 *name = talloc_strdup(mem_ctx, "UNKNOWN");
1128 } else {
1129 *name = talloc_strdup(mem_ctx, nc.name);
1131 return 0;
1134 /* Look up the remote host name. */
1135 rc = sys_getnameinfo((struct sockaddr *) &ss,
1136 len,
1137 name_buf,
1138 sizeof(name_buf),
1139 NULL,
1142 if (rc < 0) {
1143 char *p;
1145 p = tsocket_address_inet_addr_string(remote_address, mem_ctx);
1146 if (p == NULL) {
1147 return -1;
1150 DEBUG(1,("getnameinfo failed for %s with error %s\n",
1152 gai_strerror(rc)));
1153 strlcpy(name_buf, p, sizeof(name_buf));
1155 TALLOC_FREE(p);
1156 } else {
1157 if (!matchname(name_buf, (struct sockaddr *)&ss, len)) {
1158 DEBUG(0,("matchname failed on %s\n", name_buf));
1159 strlcpy(name_buf, "UNKNOWN", sizeof(name_buf));
1163 strlcpy(tmp_name, name_buf, sizeof(tmp_name));
1164 alpha_strcpy(name_buf, tmp_name, "_-.", sizeof(name_buf));
1165 if (strstr(name_buf,"..")) {
1166 strlcpy(name_buf, "UNKNOWN", sizeof(name_buf));
1169 nc.name = name_buf;
1170 nc.ss = ss;
1172 store_nc(&nc);
1173 lookup_nc(&nc);
1175 if (nc.name == NULL) {
1176 *name = talloc_strdup(mem_ctx, "UNKOWN");
1177 } else {
1178 *name = talloc_strdup(mem_ctx, nc.name);
1181 return 0;
1184 /*******************************************************************
1185 Create protected unix domain socket.
1187 Some unixes cannot set permissions on a ux-dom-sock, so we
1188 have to make sure that the directory contains the protection
1189 permissions instead.
1190 ******************************************************************/
1192 int create_pipe_sock(const char *socket_dir,
1193 const char *socket_name,
1194 mode_t dir_perms)
1196 #ifdef HAVE_UNIXSOCKET
1197 struct sockaddr_un sunaddr;
1198 bool ok;
1199 int sock = -1;
1200 mode_t old_umask;
1201 char *path = NULL;
1203 old_umask = umask(0);
1205 ok = directory_create_or_exist_strict(socket_dir,
1206 sec_initial_uid(),
1207 dir_perms);
1208 if (!ok) {
1209 goto out_close;
1212 /* Create the socket file */
1213 sock = socket(AF_UNIX, SOCK_STREAM, 0);
1215 if (sock == -1) {
1216 DEBUG(0, ("create_pipe_sock: socket error %s\n",
1217 strerror(errno) ));
1218 goto out_close;
1221 if (asprintf(&path, "%s/%s", socket_dir, socket_name) == -1) {
1222 goto out_close;
1225 unlink(path);
1226 memset(&sunaddr, 0, sizeof(sunaddr));
1227 sunaddr.sun_family = AF_UNIX;
1228 strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path));
1230 if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) {
1231 DEBUG(0, ("bind failed on pipe socket %s: %s\n", path,
1232 strerror(errno)));
1233 goto out_close;
1236 SAFE_FREE(path);
1238 umask(old_umask);
1239 return sock;
1241 out_close:
1242 SAFE_FREE(path);
1243 if (sock != -1)
1244 close(sock);
1246 umask(old_umask);
1247 return -1;
1249 #else
1250 DEBUG(0, ("create_pipe_sock: No Unix sockets on this system\n"));
1251 return -1;
1252 #endif /* HAVE_UNIXSOCKET */
1255 /****************************************************************************
1256 Get my own canonical name, including domain.
1257 ****************************************************************************/
1259 const char *get_mydnsfullname(void)
1261 struct addrinfo *res = NULL;
1262 char my_hostname[HOST_NAME_MAX];
1263 bool ret;
1264 DATA_BLOB tmp;
1266 if (memcache_lookup(NULL, SINGLETON_CACHE,
1267 data_blob_string_const_null("get_mydnsfullname"),
1268 &tmp)) {
1269 SMB_ASSERT(tmp.length > 0);
1270 return (const char *)tmp.data;
1273 /* get my host name */
1274 if (gethostname(my_hostname, sizeof(my_hostname)) == -1) {
1275 DEBUG(0,("get_mydnsfullname: gethostname failed\n"));
1276 return NULL;
1279 /* Ensure null termination. */
1280 my_hostname[sizeof(my_hostname)-1] = '\0';
1282 ret = interpret_string_addr_internal(&res,
1283 my_hostname,
1284 AI_ADDRCONFIG|AI_CANONNAME);
1286 if (!ret || res == NULL) {
1287 DEBUG(3,("get_mydnsfullname: getaddrinfo failed for "
1288 "name %s [%s]\n",
1289 my_hostname,
1290 gai_strerror(ret) ));
1291 return NULL;
1295 * Make sure that getaddrinfo() returns the "correct" host name.
1298 if (res->ai_canonname == NULL) {
1299 DEBUG(3,("get_mydnsfullname: failed to get "
1300 "canonical name for %s\n",
1301 my_hostname));
1302 freeaddrinfo(res);
1303 return NULL;
1306 /* This copies the data, so we must do a lookup
1307 * afterwards to find the value to return.
1310 memcache_add(NULL, SINGLETON_CACHE,
1311 data_blob_string_const_null("get_mydnsfullname"),
1312 data_blob_string_const_null(res->ai_canonname));
1314 if (!memcache_lookup(NULL, SINGLETON_CACHE,
1315 data_blob_string_const_null("get_mydnsfullname"),
1316 &tmp)) {
1317 tmp = data_blob_talloc(talloc_tos(), res->ai_canonname,
1318 strlen(res->ai_canonname) + 1);
1321 freeaddrinfo(res);
1323 return (const char *)tmp.data;
1326 /************************************************************
1327 Is this my ip address ?
1328 ************************************************************/
1330 static bool is_my_ipaddr(const char *ipaddr_str)
1332 struct sockaddr_storage ss;
1333 struct iface_struct *nics;
1334 int i, n;
1336 if (!interpret_string_addr(&ss, ipaddr_str, AI_NUMERICHOST)) {
1337 return false;
1340 if (is_zero_addr(&ss)) {
1341 return false;
1344 if (ismyaddr((struct sockaddr *)&ss) ||
1345 is_loopback_addr((struct sockaddr *)&ss)) {
1346 return true;
1349 n = get_interfaces(talloc_tos(), &nics);
1350 for (i=0; i<n; i++) {
1351 if (sockaddr_equal((struct sockaddr *)&nics[i].ip, (struct sockaddr *)&ss)) {
1352 TALLOC_FREE(nics);
1353 return true;
1356 TALLOC_FREE(nics);
1357 return false;
1360 /************************************************************
1361 Is this my name ?
1362 ************************************************************/
1364 bool is_myname_or_ipaddr(const char *s)
1366 TALLOC_CTX *ctx = talloc_tos();
1367 char *name = NULL;
1368 const char *dnsname;
1369 char *servername = NULL;
1371 if (!s) {
1372 return false;
1375 /* Santize the string from '\\name' */
1376 name = talloc_strdup(ctx, s);
1377 if (!name) {
1378 return false;
1381 servername = strrchr_m(name, '\\' );
1382 if (!servername) {
1383 servername = name;
1384 } else {
1385 servername++;
1388 /* Optimize for the common case */
1389 if (strequal(servername, lp_netbios_name())) {
1390 return true;
1393 /* Check for an alias */
1394 if (is_myname(servername)) {
1395 return true;
1398 /* Check for loopback */
1399 if (strequal(servername, "127.0.0.1") ||
1400 strequal(servername, "::1")) {
1401 return true;
1404 if (strequal(servername, "localhost")) {
1405 return true;
1408 /* Maybe it's my dns name */
1409 dnsname = get_mydnsfullname();
1410 if (dnsname && strequal(servername, dnsname)) {
1411 return true;
1414 /* Maybe its an IP address? */
1415 if (is_ipaddress(servername)) {
1416 return is_my_ipaddr(servername);
1419 /* Handle possible CNAME records - convert to an IP addr. list. */
1421 /* Use DNS to resolve the name, check all addresses. */
1422 struct addrinfo *p = NULL;
1423 struct addrinfo *res = NULL;
1425 if (!interpret_string_addr_internal(&res,
1426 servername,
1427 AI_ADDRCONFIG)) {
1428 return false;
1431 for (p = res; p; p = p->ai_next) {
1432 char addr[INET6_ADDRSTRLEN];
1433 struct sockaddr_storage ss;
1435 ZERO_STRUCT(ss);
1436 memcpy(&ss, p->ai_addr, p->ai_addrlen);
1437 print_sockaddr(addr,
1438 sizeof(addr),
1439 &ss);
1440 if (is_my_ipaddr(addr)) {
1441 freeaddrinfo(res);
1442 return true;
1445 freeaddrinfo(res);
1448 /* No match */
1449 return false;
1452 struct getaddrinfo_state {
1453 const char *node;
1454 const char *service;
1455 const struct addrinfo *hints;
1456 struct addrinfo *res;
1457 int ret;
1460 static void getaddrinfo_do(void *private_data);
1461 static void getaddrinfo_done(struct tevent_req *subreq);
1463 struct tevent_req *getaddrinfo_send(TALLOC_CTX *mem_ctx,
1464 struct tevent_context *ev,
1465 struct fncall_context *ctx,
1466 const char *node,
1467 const char *service,
1468 const struct addrinfo *hints)
1470 struct tevent_req *req, *subreq;
1471 struct getaddrinfo_state *state;
1473 req = tevent_req_create(mem_ctx, &state, struct getaddrinfo_state);
1474 if (req == NULL) {
1475 return NULL;
1478 state->node = node;
1479 state->service = service;
1480 state->hints = hints;
1482 subreq = fncall_send(state, ev, ctx, getaddrinfo_do, state);
1483 if (tevent_req_nomem(subreq, req)) {
1484 return tevent_req_post(req, ev);
1486 tevent_req_set_callback(subreq, getaddrinfo_done, req);
1487 return req;
1490 static void getaddrinfo_do(void *private_data)
1492 struct getaddrinfo_state *state =
1493 (struct getaddrinfo_state *)private_data;
1495 state->ret = getaddrinfo(state->node, state->service, state->hints,
1496 &state->res);
1499 static void getaddrinfo_done(struct tevent_req *subreq)
1501 struct tevent_req *req = tevent_req_callback_data(
1502 subreq, struct tevent_req);
1503 int ret, err;
1505 ret = fncall_recv(subreq, &err);
1506 TALLOC_FREE(subreq);
1507 if (ret == -1) {
1508 tevent_req_error(req, err);
1509 return;
1511 tevent_req_done(req);
1514 int getaddrinfo_recv(struct tevent_req *req, struct addrinfo **res)
1516 struct getaddrinfo_state *state = tevent_req_data(
1517 req, struct getaddrinfo_state);
1518 int err;
1520 if (tevent_req_is_unix_error(req, &err)) {
1521 switch(err) {
1522 case ENOMEM:
1523 return EAI_MEMORY;
1524 default:
1525 return EAI_FAIL;
1528 if (state->ret == 0) {
1529 *res = state->res;
1531 return state->ret;
1534 int poll_one_fd(int fd, int events, int timeout, int *revents)
1536 struct pollfd pfd;
1537 int ret;
1539 pfd.fd = fd;
1540 pfd.events = events;
1542 ret = poll(&pfd, 1, timeout);
1545 * Assign whatever poll did, even in the ret<=0 case.
1547 *revents = pfd.revents;
1549 return ret;
1552 int poll_intr_one_fd(int fd, int events, int timeout, int *revents)
1554 struct pollfd pfd;
1555 int ret;
1557 pfd.fd = fd;
1558 pfd.events = events;
1560 ret = sys_poll_intr(&pfd, 1, timeout);
1561 if (ret <= 0) {
1562 *revents = 0;
1563 return ret;
1565 *revents = pfd.revents;
1566 return 1;