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/>.
23 #include "system/filesys.h"
24 #include "../lib/util/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"
31 #include "lib/util/sys_rw.h"
32 #include "lib/util/sys_rw_data.h"
33 #include "source3/lib/util_tsock.h"
35 /****************************************************************************
36 Determine if a file descriptor is in fact a socket.
37 ****************************************************************************/
39 bool is_a_socket(int fd
)
44 return(getsockopt(fd
, SOL_SOCKET
, SO_TYPE
, (char *)&v
, &l
) == 0);
47 /****************************************************************************
48 Read data from a file descriptor with a timeout in msec.
49 mincount = if timeout, minimum to read before returning
50 maxcount = number to be read.
51 time_out = timeout in milliseconds
52 NB. This can be called with a non-socket fd, don't change
53 sys_read() to sys_recv() or other socket call.
54 ****************************************************************************/
56 NTSTATUS
read_fd_with_timeout(int fd
, char *buf
,
57 size_t mincnt
, size_t maxcnt
,
58 unsigned int time_out
,
65 /* just checking .... */
75 while (nread
< mincnt
) {
76 readret
= sys_read(fd
, buf
+ nread
, maxcnt
- nread
);
79 DEBUG(5,("read_fd_with_timeout: "
80 "blocking read. EOF from client.\n"));
81 return NT_STATUS_END_OF_FILE
;
85 return map_nt_error_from_unix(errno
);
92 /* Most difficult - timeout read */
93 /* If this is ever called on a disk file and
94 mincnt is greater then the filesize then
95 system performance will suffer severely as
96 select always returns true on disk files */
98 for (nread
=0; nread
< mincnt
; ) {
101 pollrtn
= poll_intr_one_fd(fd
, POLLIN
|POLLHUP
, time_out
,
106 return map_nt_error_from_unix(errno
);
109 /* Did we timeout ? */
110 if ((pollrtn
== 0) ||
111 ((revents
& (POLLIN
|POLLHUP
|POLLERR
)) == 0)) {
112 DEBUG(10,("read_fd_with_timeout: timeout read. "
113 "select timed out.\n"));
114 return NT_STATUS_IO_TIMEOUT
;
117 readret
= sys_read(fd
, buf
+nread
, maxcnt
-nread
);
120 /* we got EOF on the file descriptor */
121 DEBUG(5,("read_fd_with_timeout: timeout read. "
122 "EOF from client.\n"));
123 return NT_STATUS_END_OF_FILE
;
127 return map_nt_error_from_unix(errno
);
134 /* Return the number we got */
141 /****************************************************************************
142 Read data from an fd, reading exactly N bytes.
143 NB. This can be called with a non-socket fd, don't add dependencies
145 ****************************************************************************/
147 NTSTATUS
read_data_ntstatus(int fd
, char *buffer
, size_t N
)
149 return read_fd_with_timeout(fd
, buffer
, N
, N
, 0, NULL
);
152 /****************************************************************************
153 Read 4 bytes of a smb packet and return the smb length of the packet.
154 Store the result in the buffer.
155 This version of the function will return a length of zero on receiving
157 Timeout is in milliseconds.
158 ****************************************************************************/
160 NTSTATUS
read_smb_length_return_keepalive(int fd
, char *inbuf
,
161 unsigned int timeout
,
167 status
= read_fd_with_timeout(fd
, inbuf
, 4, 4, timeout
, NULL
);
169 if (!NT_STATUS_IS_OK(status
)) {
173 *len
= smb_len(inbuf
);
174 msg_type
= CVAL(inbuf
,0);
176 if (msg_type
== NBSSkeepalive
) {
177 DEBUG(5,("Got keepalive packet\n"));
180 DEBUG(10,("got smb length of %lu\n",(unsigned long)(*len
)));
185 /****************************************************************************
186 Read an smb from a fd.
187 The timeout is in milliseconds.
188 This function will return on receipt of a session keepalive packet.
189 maxlen is the max number of bytes to return, not including the 4 byte
190 length. If zero it means buflen limit.
191 Doesn't check the MAC on signed packets.
192 ****************************************************************************/
194 NTSTATUS
receive_smb_raw(int fd
, char *buffer
, size_t buflen
, unsigned int timeout
,
195 size_t maxlen
, size_t *p_len
)
200 status
= read_smb_length_return_keepalive(fd
,buffer
,timeout
,&len
);
202 if (!NT_STATUS_IS_OK(status
)) {
203 DEBUG(0, ("read_fd_with_timeout failed, read "
204 "error = %s.\n", nt_errstr(status
)));
209 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
210 (unsigned long)len
));
211 return NT_STATUS_INVALID_PARAMETER
;
216 len
= MIN(len
,maxlen
);
219 status
= read_fd_with_timeout(
220 fd
, buffer
+4, len
, len
, timeout
, &len
);
222 if (!NT_STATUS_IS_OK(status
)) {
223 DEBUG(0, ("read_fd_with_timeout failed, read error = "
224 "%s.\n", nt_errstr(status
)));
228 /* not all of samba3 properly checks for packet-termination
229 * of strings. This ensures that we don't run off into
231 SSVAL(buffer
+4,len
, 0);
239 * Open a socket of the specified type, port, and address for incoming data.
241 * Return sock or -errno
246 const struct sockaddr_storage
*paddr
,
250 struct samba_sockaddr addr
= {
251 .sa_socklen
= sizeof(struct sockaddr_storage
),
255 int val
= rebind
? 1 : 0;
258 switch (addr
.u
.sa
.sa_family
) {
260 addr
.sa_socklen
= sizeof(struct sockaddr_in6
);
263 addr
.sa_socklen
= sizeof(struct sockaddr_in
);
267 ok
= samba_sockaddr_set_port(&addr
, port
);
270 DBG_DEBUG("samba_sockaddr_set_port failed\n");
274 sock
= socket(addr
.u
.ss
.ss_family
, type
, 0 );
277 DBG_DEBUG("socket() failed: %s\n", strerror(errno
));
282 sock
, SOL_SOCKET
, SO_REUSEADDR
, (char *)&val
, sizeof(val
));
285 DBG_DEBUG("setsockopt(SO_REUSEADDR) failed: %s\n",
292 sock
, SOL_SOCKET
, SO_REUSEPORT
, (char *)&val
, sizeof(val
));
295 DBG_DEBUG("setsockopt(SO_REUSEPORT) failed: %s\n",
299 #endif /* SO_REUSEPORT */
303 * As IPV6_V6ONLY is the default on some systems,
304 * we better try to be consistent and always use it.
306 * This also avoids using IPv4 via AF_INET6 sockets
307 * and makes sure %I never resolves to a '::ffff:192.168.0.1'
310 if (addr
.u
.ss
.ss_family
== AF_INET6
) {
322 DBG_DEBUG("setsockopt(IPV6_V6ONLY) failed: %s\n",
329 /* now we've got a socket - we need to bind it */
330 ret
= bind(sock
, &addr
.u
.sa
, addr
.sa_socklen
);
332 char addrstr
[INET6_ADDRSTRLEN
];
336 print_sockaddr(addrstr
, sizeof(addrstr
), &addr
.u
.ss
);
337 DBG_DEBUG("bind for %s port %"PRIu16
" failed: %s\n",
344 DBG_DEBUG("bind succeeded on port %"PRIu16
"\n", port
);
356 struct open_socket_out_state
{
358 struct tevent_context
*ev
;
359 struct sockaddr_storage ss
;
362 struct tevent_req
*connect_subreq
;
365 static void open_socket_out_connected(struct tevent_req
*subreq
);
367 static void open_socket_out_cleanup(struct tevent_req
*req
,
368 enum tevent_req_state req_state
)
370 struct open_socket_out_state
*state
=
371 tevent_req_data(req
, struct open_socket_out_state
);
374 * Make sure that the async_connect_send subreq has a chance to reset
375 * fcntl before the socket goes away.
377 TALLOC_FREE(state
->connect_subreq
);
379 if (req_state
== TEVENT_REQ_DONE
) {
381 * we keep the socket open for the caller to use
386 if (state
->fd
!= -1) {
392 /****************************************************************************
393 Create an outgoing socket. timeout is in milliseconds.
394 **************************************************************************/
396 struct tevent_req
*open_socket_out_send(TALLOC_CTX
*mem_ctx
,
397 struct tevent_context
*ev
,
398 const struct sockaddr_storage
*pss
,
402 char addr
[INET6_ADDRSTRLEN
];
403 struct tevent_req
*req
;
404 struct open_socket_out_state
*state
;
407 req
= tevent_req_create(mem_ctx
, &state
,
408 struct open_socket_out_state
);
417 state
->fd
= socket(state
->ss
.ss_family
, SOCK_STREAM
, 0);
418 if (state
->fd
== -1) {
419 status
= map_nt_error_from_unix(errno
);
420 tevent_req_nterror(req
, status
);
421 return tevent_req_post(req
, ev
);
424 tevent_req_set_cleanup_fn(req
, open_socket_out_cleanup
);
426 if ((timeout
!= 0) &&
427 !tevent_req_set_endtime(
428 req
, ev
, timeval_current_ofs_msec(timeout
))) {
430 return tevent_req_post(req
, ev
);
433 #if defined(HAVE_IPV6)
434 if (pss
->ss_family
== AF_INET6
) {
435 struct sockaddr_in6
*psa6
;
436 psa6
= (struct sockaddr_in6
*)&state
->ss
;
437 psa6
->sin6_port
= htons(port
);
438 if (psa6
->sin6_scope_id
== 0
439 && IN6_IS_ADDR_LINKLOCAL(&psa6
->sin6_addr
)) {
440 setup_linklocal_scope_id(
441 (struct sockaddr
*)&(state
->ss
));
443 state
->salen
= sizeof(struct sockaddr_in6
);
446 if (pss
->ss_family
== AF_INET
) {
447 struct sockaddr_in
*psa
;
448 psa
= (struct sockaddr_in
*)&state
->ss
;
449 psa
->sin_port
= htons(port
);
450 state
->salen
= sizeof(struct sockaddr_in
);
453 if (pss
->ss_family
== AF_UNIX
) {
454 state
->salen
= sizeof(struct sockaddr_un
);
457 print_sockaddr(addr
, sizeof(addr
), &state
->ss
);
458 DEBUG(3,("Connecting to %s at port %u\n", addr
, (unsigned int)port
));
460 state
->connect_subreq
= async_connect_send(
461 state
, state
->ev
, state
->fd
, (struct sockaddr
*)&state
->ss
,
462 state
->salen
, NULL
, NULL
, NULL
);
463 if (tevent_req_nomem(state
->connect_subreq
, NULL
)) {
464 return tevent_req_post(req
, ev
);
466 tevent_req_set_callback(state
->connect_subreq
,
467 open_socket_out_connected
, req
);
471 static void open_socket_out_connected(struct tevent_req
*subreq
)
473 struct tevent_req
*req
=
474 tevent_req_callback_data(subreq
, struct tevent_req
);
475 struct open_socket_out_state
*state
=
476 tevent_req_data(req
, struct open_socket_out_state
);
480 ret
= async_connect_recv(subreq
, &sys_errno
);
482 state
->connect_subreq
= NULL
;
484 tevent_req_done(req
);
488 tevent_req_nterror(req
, map_nt_error_from_unix(sys_errno
));
491 NTSTATUS
open_socket_out_recv(struct tevent_req
*req
, int *pfd
)
493 struct open_socket_out_state
*state
=
494 tevent_req_data(req
, struct open_socket_out_state
);
497 if (tevent_req_is_nterror(req
, &status
)) {
498 tevent_req_received(req
);
503 tevent_req_received(req
);
508 * @brief open a socket
510 * @param pss a struct sockaddr_storage defining the address to connect to
511 * @param port to connect to
512 * @param timeout in MILLISECONDS
513 * @param pfd file descriptor returned
515 * @return NTSTATUS code
517 NTSTATUS
open_socket_out(const struct sockaddr_storage
*pss
, uint16_t port
,
518 int timeout
, int *pfd
)
520 TALLOC_CTX
*frame
= talloc_stackframe();
521 struct tevent_context
*ev
;
522 struct tevent_req
*req
;
523 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
525 ev
= samba_tevent_context_init(frame
);
530 req
= open_socket_out_send(frame
, ev
, pss
, port
, timeout
);
534 if (!tevent_req_poll(req
, ev
)) {
535 status
= NT_STATUS_INTERNAL_ERROR
;
538 status
= open_socket_out_recv(req
, pfd
);
544 struct open_socket_out_defer_state
{
545 struct tevent_context
*ev
;
546 struct sockaddr_storage ss
;
552 static void open_socket_out_defer_waited(struct tevent_req
*subreq
);
553 static void open_socket_out_defer_connected(struct tevent_req
*subreq
);
555 struct tevent_req
*open_socket_out_defer_send(TALLOC_CTX
*mem_ctx
,
556 struct tevent_context
*ev
,
557 struct timeval wait_time
,
558 const struct sockaddr_storage
*pss
,
562 struct tevent_req
*req
, *subreq
;
563 struct open_socket_out_defer_state
*state
;
565 req
= tevent_req_create(mem_ctx
, &state
,
566 struct open_socket_out_defer_state
);
573 state
->timeout
= timeout
;
575 subreq
= tevent_wakeup_send(
577 timeval_current_ofs(wait_time
.tv_sec
, wait_time
.tv_usec
));
578 if (subreq
== NULL
) {
581 tevent_req_set_callback(subreq
, open_socket_out_defer_waited
, req
);
588 static void open_socket_out_defer_waited(struct tevent_req
*subreq
)
590 struct tevent_req
*req
= tevent_req_callback_data(
591 subreq
, struct tevent_req
);
592 struct open_socket_out_defer_state
*state
= tevent_req_data(
593 req
, struct open_socket_out_defer_state
);
596 ret
= tevent_wakeup_recv(subreq
);
599 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
603 subreq
= open_socket_out_send(state
, state
->ev
, &state
->ss
,
604 state
->port
, state
->timeout
);
605 if (tevent_req_nomem(subreq
, req
)) {
608 tevent_req_set_callback(subreq
, open_socket_out_defer_connected
, req
);
611 static void open_socket_out_defer_connected(struct tevent_req
*subreq
)
613 struct tevent_req
*req
= tevent_req_callback_data(
614 subreq
, struct tevent_req
);
615 struct open_socket_out_defer_state
*state
= tevent_req_data(
616 req
, struct open_socket_out_defer_state
);
619 status
= open_socket_out_recv(subreq
, &state
->fd
);
621 if (!NT_STATUS_IS_OK(status
)) {
622 tevent_req_nterror(req
, status
);
625 tevent_req_done(req
);
628 NTSTATUS
open_socket_out_defer_recv(struct tevent_req
*req
, int *pfd
)
630 struct open_socket_out_defer_state
*state
= tevent_req_data(
631 req
, struct open_socket_out_defer_state
);
634 if (tevent_req_is_nterror(req
, &status
)) {
642 /*******************************************************************
643 Return the IP addr of the remote end of a socket as a string.
644 Optionally return the struct sockaddr_storage.
645 ******************************************************************/
647 static const char *get_peer_addr_internal(int fd
,
650 struct sockaddr
*pss
,
653 struct sockaddr_storage ss
;
654 socklen_t length
= sizeof(ss
);
656 strlcpy(addr_buf
,"0.0.0.0",addr_buf_len
);
663 pss
= (struct sockaddr
*)&ss
;
667 if (getpeername(fd
, (struct sockaddr
*)pss
, plength
) < 0) {
668 int level
= (errno
== ENOTCONN
) ? 2 : 0;
669 DEBUG(level
, ("getpeername failed. Error was %s\n",
674 print_sockaddr_len(addr_buf
,
681 /*******************************************************************
682 Matchname - determine if host name matches IP address. Used to
683 confirm a hostname lookup to prevent spoof attacks.
684 ******************************************************************/
686 static bool matchname(const char *remotehost
,
687 const struct sockaddr
*pss
,
690 struct addrinfo
*res
= NULL
;
691 struct addrinfo
*ailist
= NULL
;
692 char addr_buf
[INET6_ADDRSTRLEN
];
693 bool ret
= interpret_string_addr_internal(&ailist
,
695 AI_ADDRCONFIG
|AI_CANONNAME
);
697 if (!ret
|| ailist
== NULL
) {
698 DEBUG(3,("matchname: getaddrinfo failed for "
701 gai_strerror(ret
) ));
706 * Make sure that getaddrinfo() returns the "correct" host name.
709 if (ailist
->ai_canonname
== NULL
||
710 (!strequal(remotehost
, ailist
->ai_canonname
) &&
711 !strequal(remotehost
, "localhost"))) {
712 DEBUG(0,("matchname: host name/name mismatch: %s != %s\n",
714 ailist
->ai_canonname
?
715 ailist
->ai_canonname
: "(NULL)"));
716 freeaddrinfo(ailist
);
720 /* Look up the host address in the address list we just got. */
721 for (res
= ailist
; res
; res
= res
->ai_next
) {
725 if (sockaddr_equal((const struct sockaddr
*)res
->ai_addr
,
726 (const struct sockaddr
*)pss
)) {
727 freeaddrinfo(ailist
);
733 * The host name does not map to the original host address. Perhaps
734 * someone has compromised a name server. More likely someone botched
735 * it, but that could be dangerous, too.
738 DEBUG(0,("matchname: host name/address mismatch: %s != %s\n",
739 print_sockaddr_len(addr_buf
,
743 ailist
->ai_canonname
? ailist
->ai_canonname
: "(NULL)"));
746 freeaddrinfo(ailist
);
751 /*******************************************************************
752 Deal with the singleton cache.
753 ******************************************************************/
755 struct name_addr_pair
{
756 struct sockaddr_storage ss
;
760 /*******************************************************************
761 Lookup a name/addr pair. Returns memory allocated from memcache.
762 ******************************************************************/
764 static bool lookup_nc(struct name_addr_pair
*nc
)
770 if (!memcache_lookup(
771 NULL
, SINGLETON_CACHE
,
772 data_blob_string_const_null("get_peer_name"),
777 memcpy(&nc
->ss
, tmp
.data
, sizeof(nc
->ss
));
778 nc
->name
= (const char *)tmp
.data
+ sizeof(nc
->ss
);
782 /*******************************************************************
783 Save a name/addr pair.
784 ******************************************************************/
786 static void store_nc(const struct name_addr_pair
*nc
)
789 size_t namelen
= strlen(nc
->name
);
791 tmp
= data_blob(NULL
, sizeof(nc
->ss
) + namelen
+ 1);
795 memcpy(tmp
.data
, &nc
->ss
, sizeof(nc
->ss
));
796 memcpy(tmp
.data
+sizeof(nc
->ss
), nc
->name
, namelen
+1);
798 memcache_add(NULL
, SINGLETON_CACHE
,
799 data_blob_string_const_null("get_peer_name"),
801 data_blob_free(&tmp
);
804 /*******************************************************************
805 Return the IP addr of the remote end of a socket as a string.
806 ******************************************************************/
808 const char *get_peer_addr(int fd
, char *addr
, size_t addr_len
)
810 return get_peer_addr_internal(fd
, addr
, addr_len
, NULL
, NULL
);
813 int get_remote_hostname(const struct tsocket_address
*remote_address
,
817 char name_buf
[MAX_DNS_NAME_LENGTH
];
818 char tmp_name
[MAX_DNS_NAME_LENGTH
];
819 struct name_addr_pair nc
;
820 struct sockaddr_storage ss
;
824 if (!lp_hostname_lookups()) {
825 nc
.name
= tsocket_address_inet_addr_string(remote_address
,
827 if (nc
.name
== NULL
) {
831 len
= tsocket_address_bsd_sockaddr(remote_address
,
832 (struct sockaddr
*) &nc
.ss
,
833 sizeof(struct sockaddr_storage
));
841 if (nc
.name
== NULL
) {
842 *name
= talloc_strdup(mem_ctx
, "UNKNOWN");
844 *name
= talloc_strdup(mem_ctx
, nc
.name
);
853 len
= tsocket_address_bsd_sockaddr(remote_address
,
854 (struct sockaddr
*) &ss
,
855 sizeof(struct sockaddr_storage
));
860 /* it might be the same as the last one - save some DNS work */
861 if (sockaddr_equal((struct sockaddr
*)&ss
, (struct sockaddr
*)&nc
.ss
)) {
862 if (nc
.name
== NULL
) {
863 *name
= talloc_strdup(mem_ctx
, "UNKNOWN");
865 *name
= talloc_strdup(mem_ctx
, nc
.name
);
870 /* Look up the remote host name. */
871 rc
= sys_getnameinfo((struct sockaddr
*) &ss
,
881 p
= tsocket_address_inet_addr_string(remote_address
, mem_ctx
);
886 DEBUG(1,("getnameinfo failed for %s with error %s\n",
889 strlcpy(name_buf
, p
, sizeof(name_buf
));
893 if (!matchname(name_buf
, (struct sockaddr
*)&ss
, len
)) {
894 DEBUG(0,("matchname failed on %s\n", name_buf
));
895 strlcpy(name_buf
, "UNKNOWN", sizeof(name_buf
));
899 strlcpy(tmp_name
, name_buf
, sizeof(tmp_name
));
900 alpha_strcpy(name_buf
, tmp_name
, "_-.", sizeof(name_buf
));
901 if (strstr(name_buf
,"..")) {
902 strlcpy(name_buf
, "UNKNOWN", sizeof(name_buf
));
911 if (nc
.name
== NULL
) {
912 *name
= talloc_strdup(mem_ctx
, "UNKNOWN");
914 *name
= talloc_strdup(mem_ctx
, nc
.name
);
920 /*******************************************************************
921 Create protected unix domain socket.
923 Some unixes cannot set permissions on a ux-dom-sock, so we
924 have to make sure that the directory contains the protection
926 ******************************************************************/
928 int create_pipe_sock(const char *socket_dir
,
929 const char *socket_name
,
932 #ifdef HAVE_UNIXSOCKET
933 struct sockaddr_un sunaddr
;
940 old_umask
= umask(0);
942 ok
= directory_create_or_exist_strict(socket_dir
,
949 /* Create the socket file */
950 sock
= socket(AF_UNIX
, SOCK_STREAM
, 0);
953 DEBUG(0, ("create_pipe_sock: socket error %s\n",
958 if (asprintf(&path
, "%s/%s", socket_dir
, socket_name
) == -1) {
963 memset(&sunaddr
, 0, sizeof(sunaddr
));
964 sunaddr
.sun_family
= AF_UNIX
;
966 path_len
= strlcpy(sunaddr
.sun_path
, path
, sizeof(sunaddr
.sun_path
));
967 if (path_len
> sizeof(sunaddr
.sun_path
)) {
968 DBG_ERR("Refusing to attempt to create pipe socket "
969 "%s. Path is longer than permitted for a "
970 "unix domain socket. It would truncate to "
977 if (bind(sock
, (struct sockaddr
*)&sunaddr
, sizeof(sunaddr
)) == -1) {
978 DEBUG(0, ("bind failed on pipe socket %s: %s\n", path
,
997 DEBUG(0, ("create_pipe_sock: No Unix sockets on this system\n"));
999 #endif /* HAVE_UNIXSOCKET */
1002 /****************************************************************************
1003 Get my own canonical name, including domain.
1004 ****************************************************************************/
1006 const char *get_mydnsfullname(void)
1008 struct addrinfo
*res
= NULL
;
1009 char my_hostname
[HOST_NAME_MAX
];
1013 if (memcache_lookup(NULL
, SINGLETON_CACHE
,
1014 data_blob_string_const_null("get_mydnsfullname"),
1016 SMB_ASSERT(tmp
.length
> 0);
1017 return (const char *)tmp
.data
;
1020 /* get my host name */
1021 if (gethostname(my_hostname
, sizeof(my_hostname
)) == -1) {
1022 DEBUG(0,("get_mydnsfullname: gethostname failed\n"));
1026 /* Ensure null termination. */
1027 my_hostname
[sizeof(my_hostname
)-1] = '\0';
1029 ret
= interpret_string_addr_internal(&res
,
1031 AI_ADDRCONFIG
|AI_CANONNAME
);
1033 if (!ret
|| res
== NULL
) {
1034 DEBUG(3,("get_mydnsfullname: getaddrinfo failed for "
1037 gai_strerror(ret
) ));
1042 * Make sure that getaddrinfo() returns the "correct" host name.
1045 if (res
->ai_canonname
== NULL
) {
1046 DEBUG(3,("get_mydnsfullname: failed to get "
1047 "canonical name for %s\n",
1053 /* This copies the data, so we must do a lookup
1054 * afterwards to find the value to return.
1057 memcache_add(NULL
, SINGLETON_CACHE
,
1058 data_blob_string_const_null("get_mydnsfullname"),
1059 data_blob_string_const_null(res
->ai_canonname
));
1061 if (!memcache_lookup(NULL
, SINGLETON_CACHE
,
1062 data_blob_string_const_null("get_mydnsfullname"),
1064 tmp
= data_blob_talloc(talloc_tos(), res
->ai_canonname
,
1065 strlen(res
->ai_canonname
) + 1);
1070 return (const char *)tmp
.data
;
1073 /************************************************************
1074 Is this my ip address ?
1075 ************************************************************/
1077 static bool is_my_ipaddr(const char *ipaddr_str
)
1079 struct sockaddr_storage ss
;
1080 struct iface_struct
*nics
;
1083 if (!interpret_string_addr(&ss
, ipaddr_str
, AI_NUMERICHOST
)) {
1087 if (is_zero_addr(&ss
)) {
1091 if (ismyaddr((struct sockaddr
*)&ss
) ||
1092 is_loopback_addr((struct sockaddr
*)&ss
)) {
1096 n
= get_interfaces(talloc_tos(), &nics
);
1097 for (i
=0; i
<n
; i
++) {
1098 if (sockaddr_equal((struct sockaddr
*)&nics
[i
].ip
, (struct sockaddr
*)&ss
)) {
1107 /************************************************************
1109 ************************************************************/
1111 bool is_myname_or_ipaddr(const char *s
)
1113 TALLOC_CTX
*ctx
= talloc_tos();
1115 const char *dnsname
;
1116 char *servername
= NULL
;
1122 /* Sanitize the string from '\\name' */
1123 name
= talloc_strdup(ctx
, s
);
1128 servername
= strrchr_m(name
, '\\' );
1135 /* Optimize for the common case */
1136 if (strequal(servername
, lp_netbios_name())) {
1140 /* Check for an alias */
1141 if (is_myname(servername
)) {
1145 /* Check for loopback */
1146 if (strequal(servername
, "127.0.0.1") ||
1147 strequal(servername
, "::1")) {
1151 if (strequal(servername
, "localhost")) {
1155 /* Maybe it's my dns name */
1156 dnsname
= get_mydnsfullname();
1157 if (dnsname
&& strequal(servername
, dnsname
)) {
1161 /* Maybe its an IP address? */
1162 if (is_ipaddress(servername
)) {
1163 return is_my_ipaddr(servername
);
1166 /* Handle possible CNAME records - convert to an IP addr. list. */
1168 /* Use DNS to resolve the name, check all addresses. */
1169 struct addrinfo
*p
= NULL
;
1170 struct addrinfo
*res
= NULL
;
1172 if (!interpret_string_addr_internal(&res
,
1178 for (p
= res
; p
; p
= p
->ai_next
) {
1179 char addr
[INET6_ADDRSTRLEN
];
1180 struct sockaddr_storage ss
;
1183 memcpy(&ss
, p
->ai_addr
, p
->ai_addrlen
);
1184 print_sockaddr(addr
,
1187 if (is_my_ipaddr(addr
)) {
1199 int poll_one_fd(int fd
, int events
, int timeout
, int *revents
)
1205 pfd
.events
= events
;
1207 ret
= poll(&pfd
, 1, timeout
);
1210 * Assign whatever poll did, even in the ret<=0 case.
1212 *revents
= pfd
.revents
;
1217 int poll_intr_one_fd(int fd
, int events
, int timeout
, int *revents
)
1223 pfd
.events
= events
;
1225 ret
= sys_poll_intr(&pfd
, 1, timeout
);
1230 *revents
= pfd
.revents
;