~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source3/lib/util_sock.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
24
/*******************************************************************
 
25
 Map a text hostname or IP address (IPv4 or IPv6) into a
 
26
 struct sockaddr_storage.
 
27
******************************************************************/
 
28
 
 
29
bool interpret_string_addr(struct sockaddr_storage *pss,
 
30
                const char *str,
 
31
                int flags)
 
32
{
 
33
        struct addrinfo *res = NULL;
 
34
#if defined(HAVE_IPV6)
 
35
        char addr[INET6_ADDRSTRLEN];
 
36
        unsigned int scope_id = 0;
 
37
 
 
38
        if (strchr_m(str, ':')) {
 
39
                char *p = strchr_m(str, '%');
 
40
 
 
41
                /*
 
42
                 * Cope with link-local.
 
43
                 * This is IP:v6:addr%ifname.
 
44
                 */
 
45
 
 
46
                if (p && (p > str) && ((scope_id = if_nametoindex(p+1)) != 0)) {
 
47
                        strlcpy(addr, str,
 
48
                                MIN(PTR_DIFF(p,str)+1,
 
49
                                        sizeof(addr)));
 
50
                        str = addr;
 
51
                }
 
52
        }
 
53
#endif
 
54
 
 
55
        zero_sockaddr(pss);
 
56
 
 
57
        if (!interpret_string_addr_internal(&res, str, flags|AI_ADDRCONFIG)) {
 
58
                return false;
 
59
        }
 
60
        if (!res) {
 
61
                return false;
 
62
        }
 
63
        /* Copy the first sockaddr. */
 
64
        memcpy(pss, res->ai_addr, res->ai_addrlen);
 
65
 
 
66
#if defined(HAVE_IPV6)
 
67
        if (pss->ss_family == AF_INET6 && scope_id) {
 
68
                struct sockaddr_in6 *ps6 = (struct sockaddr_in6 *)pss;
 
69
                if (IN6_IS_ADDR_LINKLOCAL(&ps6->sin6_addr) &&
 
70
                                ps6->sin6_scope_id == 0) {
 
71
                        ps6->sin6_scope_id = scope_id;
 
72
                }
 
73
        }
 
74
#endif
 
75
 
 
76
        freeaddrinfo(res);
 
77
        return true;
 
78
}
 
79
 
 
80
/*******************************************************************
 
81
 Set an address to INADDR_ANY.
 
82
******************************************************************/
 
83
 
 
84
void zero_sockaddr(struct sockaddr_storage *pss)
 
85
{
 
86
        memset(pss, '\0', sizeof(*pss));
 
87
        /* Ensure we're at least a valid sockaddr-storage. */
 
88
        pss->ss_family = AF_INET;
 
89
}
 
90
 
 
91
/****************************************************************************
 
92
 Get a port number in host byte order from a sockaddr_storage.
 
93
****************************************************************************/
 
94
 
 
95
uint16_t get_sockaddr_port(const struct sockaddr_storage *pss)
 
96
{
 
97
        uint16_t port = 0;
 
98
 
 
99
        if (pss->ss_family != AF_INET) {
 
100
#if defined(HAVE_IPV6)
 
101
                /* IPv6 */
 
102
                const struct sockaddr_in6 *sa6 =
 
103
                        (const struct sockaddr_in6 *)pss;
 
104
                port = ntohs(sa6->sin6_port);
 
105
#endif
 
106
        } else {
 
107
                const struct sockaddr_in *sa =
 
108
                        (const struct sockaddr_in *)pss;
 
109
                port = ntohs(sa->sin_port);
 
110
        }
 
111
        return port;
 
112
}
 
113
 
 
114
/****************************************************************************
 
115
 Print out an IPv4 or IPv6 address from a struct sockaddr_storage.
 
116
****************************************************************************/
 
117
 
 
118
static char *print_sockaddr_len(char *dest,
 
119
                        size_t destlen,
 
120
                        const struct sockaddr *psa,
 
121
                        socklen_t psalen)
 
122
{
 
123
        if (destlen > 0) {
 
124
                dest[0] = '\0';
 
125
        }
 
126
        (void)sys_getnameinfo(psa,
 
127
                        psalen,
 
128
                        dest, destlen,
 
129
                        NULL, 0,
 
130
                        NI_NUMERICHOST);
 
131
        return dest;
 
132
}
 
133
 
 
134
/****************************************************************************
 
135
 Print out an IPv4 or IPv6 address from a struct sockaddr_storage.
 
136
****************************************************************************/
 
137
 
 
138
char *print_sockaddr(char *dest,
 
139
                        size_t destlen,
 
140
                        const struct sockaddr_storage *psa)
 
141
{
 
142
        return print_sockaddr_len(dest, destlen, (struct sockaddr *)psa,
 
143
                        sizeof(struct sockaddr_storage));
 
144
}
 
145
 
 
146
/****************************************************************************
 
147
 Print out a canonical IPv4 or IPv6 address from a struct sockaddr_storage.
 
148
****************************************************************************/
 
149
 
 
150
char *print_canonical_sockaddr(TALLOC_CTX *ctx,
 
151
                        const struct sockaddr_storage *pss)
 
152
{
 
153
        char addr[INET6_ADDRSTRLEN];
 
154
        char *dest = NULL;
 
155
        int ret;
 
156
 
 
157
        /* Linux getnameinfo() man pages says port is unitialized if
 
158
           service name is NULL. */
 
159
 
 
160
        ret = sys_getnameinfo((const struct sockaddr *)pss,
 
161
                        sizeof(struct sockaddr_storage),
 
162
                        addr, sizeof(addr),
 
163
                        NULL, 0,
 
164
                        NI_NUMERICHOST);
 
165
        if (ret != 0) {
 
166
                return NULL;
 
167
        }
 
168
 
 
169
        if (pss->ss_family != AF_INET) {
 
170
#if defined(HAVE_IPV6)
 
171
                dest = talloc_asprintf(ctx, "[%s]", addr);
 
172
#else
 
173
                return NULL;
 
174
#endif
 
175
        } else {
 
176
                dest = talloc_asprintf(ctx, "%s", addr);
 
177
        }
 
178
        
 
179
        return dest;
 
180
}
 
181
 
 
182
/****************************************************************************
 
183
 Return the string of an IP address (IPv4 or IPv6).
 
184
****************************************************************************/
 
185
 
 
186
static const char *get_socket_addr(int fd, char *addr_buf, size_t addr_len)
 
187
{
 
188
        struct sockaddr_storage sa;
 
189
        socklen_t length = sizeof(sa);
 
190
 
 
191
        /* Ok, returning a hard coded IPv4 address
 
192
         * is bogus, but it's just as bogus as a
 
193
         * zero IPv6 address. No good choice here.
 
194
         */
 
195
 
 
196
        strlcpy(addr_buf, "0.0.0.0", addr_len);
 
197
 
 
198
        if (fd == -1) {
 
199
                return addr_buf;
 
200
        }
 
201
 
 
202
        if (getsockname(fd, (struct sockaddr *)&sa, &length) < 0) {
 
203
                DEBUG(0,("getsockname failed. Error was %s\n",
 
204
                        strerror(errno) ));
 
205
                return addr_buf;
 
206
        }
 
207
 
 
208
        return print_sockaddr_len(addr_buf, addr_len, (struct sockaddr *)&sa, length);
 
209
}
 
210
 
 
211
#if 0
 
212
/* Not currently used. JRA. */
 
213
/****************************************************************************
 
214
 Return the port number we've bound to on a socket.
 
215
****************************************************************************/
 
216
 
 
217
static int get_socket_port(int fd)
 
218
{
 
219
        struct sockaddr_storage sa;
 
220
        socklen_t length = sizeof(sa);
 
221
 
 
222
        if (fd == -1) {
 
223
                return -1;
 
224
        }
 
225
 
 
226
        if (getsockname(fd, (struct sockaddr *)&sa, &length) < 0) {
 
227
                DEBUG(0,("getpeername failed. Error was %s\n",
 
228
                        strerror(errno) ));
 
229
                return -1;
 
230
        }
 
231
 
 
232
#if defined(HAVE_IPV6)
 
233
        if (sa.ss_family == AF_INET6) {
 
234
                return ntohs(((struct sockaddr_in6 *)&sa)->sin6_port);
 
235
        }
 
236
#endif
 
237
        if (sa.ss_family == AF_INET) {
 
238
                return ntohs(((struct sockaddr_in *)&sa)->sin_port);
 
239
        }
 
240
        return -1;
 
241
}
 
242
#endif
 
243
 
 
244
const char *client_name(int fd)
 
245
{
 
246
        return get_peer_name(fd,false);
 
247
}
 
248
 
 
249
const char *client_addr(int fd, char *addr, size_t addrlen)
 
250
{
 
251
        return get_peer_addr(fd,addr,addrlen);
 
252
}
 
253
 
 
254
const char *client_socket_addr(int fd, char *addr, size_t addr_len)
 
255
{
 
256
        return get_socket_addr(fd, addr, addr_len);
 
257
}
 
258
 
 
259
#if 0
 
260
/* Not currently used. JRA. */
 
261
int client_socket_port(int fd)
 
262
{
 
263
        return get_socket_port(fd);
 
264
}
 
265
#endif
 
266
 
 
267
/****************************************************************************
 
268
 Accessor functions to make thread-safe code easier later...
 
269
****************************************************************************/
 
270
 
 
271
void set_smb_read_error(enum smb_read_errors *pre,
 
272
                        enum smb_read_errors newerr)
 
273
{
 
274
        if (pre) {
 
275
                *pre = newerr;
 
276
        }
 
277
}
 
278
 
 
279
void cond_set_smb_read_error(enum smb_read_errors *pre,
 
280
                        enum smb_read_errors newerr)
 
281
{
 
282
        if (pre && *pre == SMB_READ_OK) {
 
283
                *pre = newerr;
 
284
        }
 
285
}
 
286
 
 
287
/****************************************************************************
 
288
 Determine if a file descriptor is in fact a socket.
 
289
****************************************************************************/
 
290
 
 
291
bool is_a_socket(int fd)
 
292
{
 
293
        int v;
 
294
        socklen_t l;
 
295
        l = sizeof(int);
 
296
        return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
 
297
}
 
298
 
 
299
enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
 
300
 
 
301
typedef struct smb_socket_option {
 
302
        const char *name;
 
303
        int level;
 
304
        int option;
 
305
        int value;
 
306
        int opttype;
 
307
} smb_socket_option;
 
308
 
 
309
static const smb_socket_option socket_options[] = {
 
310
  {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
 
311
  {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
 
312
  {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
 
313
#ifdef TCP_NODELAY
 
314
  {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
 
315
#endif
 
316
#ifdef TCP_KEEPCNT
 
317
  {"TCP_KEEPCNT", IPPROTO_TCP, TCP_KEEPCNT, 0, OPT_INT},
 
318
#endif
 
319
#ifdef TCP_KEEPIDLE
 
320
  {"TCP_KEEPIDLE", IPPROTO_TCP, TCP_KEEPIDLE, 0, OPT_INT},
 
321
#endif
 
322
#ifdef TCP_KEEPINTVL
 
323
  {"TCP_KEEPINTVL", IPPROTO_TCP, TCP_KEEPINTVL, 0, OPT_INT},
 
324
#endif
 
325
#ifdef IPTOS_LOWDELAY
 
326
  {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
 
327
#endif
 
328
#ifdef IPTOS_THROUGHPUT
 
329
  {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
 
330
#endif
 
331
#ifdef SO_REUSEPORT
 
332
  {"SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT, 0, OPT_BOOL},
 
333
#endif
 
334
#ifdef SO_SNDBUF
 
335
  {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
 
336
#endif
 
337
#ifdef SO_RCVBUF
 
338
  {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
 
339
#endif
 
340
#ifdef SO_SNDLOWAT
 
341
  {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
 
342
#endif
 
343
#ifdef SO_RCVLOWAT
 
344
  {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
 
345
#endif
 
346
#ifdef SO_SNDTIMEO
 
347
  {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
 
348
#endif
 
349
#ifdef SO_RCVTIMEO
 
350
  {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
 
351
#endif
 
352
#ifdef TCP_FASTACK
 
353
  {"TCP_FASTACK", IPPROTO_TCP, TCP_FASTACK, 0, OPT_INT},
 
354
#endif
 
355
  {NULL,0,0,0,0}};
 
356
 
 
357
/****************************************************************************
 
358
 Print socket options.
 
359
****************************************************************************/
 
360
 
 
361
static void print_socket_options(int s)
 
362
{
 
363
        int value;
 
364
        socklen_t vlen = 4;
 
365
        const smb_socket_option *p = &socket_options[0];
 
366
 
 
367
        /* wrapped in if statement to prevent streams
 
368
         * leak in SCO Openserver 5.0 */
 
369
        /* reported on samba-technical  --jerry */
 
370
        if ( DEBUGLEVEL >= 5 ) {
 
371
                DEBUG(5,("Socket options:\n"));
 
372
                for (; p->name != NULL; p++) {
 
373
                        if (getsockopt(s, p->level, p->option,
 
374
                                                (void *)&value, &vlen) == -1) {
 
375
                                DEBUGADD(5,("\tCould not test socket option %s.\n",
 
376
                                                        p->name));
 
377
                        } else {
 
378
                                DEBUGADD(5,("\t%s = %d\n",
 
379
                                                        p->name,value));
 
380
                        }
 
381
                }
 
382
        }
 
383
 }
 
384
 
 
385
/****************************************************************************
 
386
 Set user socket options.
 
387
****************************************************************************/
 
388
 
 
389
void set_socket_options(int fd, const char *options)
 
390
{
 
391
        TALLOC_CTX *ctx = talloc_stackframe();
 
392
        char *tok;
 
393
 
 
394
        while (next_token_talloc(ctx, &options, &tok," \t,")) {
 
395
                int ret=0,i;
 
396
                int value = 1;
 
397
                char *p;
 
398
                bool got_value = false;
 
399
 
 
400
                if ((p = strchr_m(tok,'='))) {
 
401
                        *p = 0;
 
402
                        value = atoi(p+1);
 
403
                        got_value = true;
 
404
                }
 
405
 
 
406
                for (i=0;socket_options[i].name;i++)
 
407
                        if (strequal(socket_options[i].name,tok))
 
408
                                break;
 
409
 
 
410
                if (!socket_options[i].name) {
 
411
                        DEBUG(0,("Unknown socket option %s\n",tok));
 
412
                        continue;
 
413
                }
 
414
 
 
415
                switch (socket_options[i].opttype) {
 
416
                case OPT_BOOL:
 
417
                case OPT_INT:
 
418
                        ret = setsockopt(fd,socket_options[i].level,
 
419
                                        socket_options[i].option,
 
420
                                        (char *)&value,sizeof(int));
 
421
                        break;
 
422
 
 
423
                case OPT_ON:
 
424
                        if (got_value)
 
425
                                DEBUG(0,("syntax error - %s "
 
426
                                        "does not take a value\n",tok));
 
427
 
 
428
                        {
 
429
                                int on = socket_options[i].value;
 
430
                                ret = setsockopt(fd,socket_options[i].level,
 
431
                                        socket_options[i].option,
 
432
                                        (char *)&on,sizeof(int));
 
433
                        }
 
434
                        break;
 
435
                }
 
436
 
 
437
                if (ret != 0) {
 
438
                        /* be aware that some systems like Solaris return
 
439
                         * EINVAL to a setsockopt() call when the client
 
440
                         * sent a RST previously - no need to worry */
 
441
                        DEBUG(2,("Failed to set socket option %s (Error %s)\n",
 
442
                                tok, strerror(errno) ));
 
443
                }
 
444
        }
 
445
 
 
446
        TALLOC_FREE(ctx);
 
447
        print_socket_options(fd);
 
448
}
 
449
 
 
450
/****************************************************************************
 
451
 Read from a socket.
 
452
****************************************************************************/
 
453
 
 
454
ssize_t read_udp_v4_socket(int fd,
 
455
                        char *buf,
 
456
                        size_t len,
 
457
                        struct sockaddr_storage *psa)
 
458
{
 
459
        ssize_t ret;
 
460
        socklen_t socklen = sizeof(*psa);
 
461
        struct sockaddr_in *si = (struct sockaddr_in *)psa;
 
462
 
 
463
        memset((char *)psa,'\0',socklen);
 
464
 
 
465
        ret = (ssize_t)sys_recvfrom(fd,buf,len,0,
 
466
                        (struct sockaddr *)psa,&socklen);
 
467
        if (ret <= 0) {
 
468
                /* Don't print a low debug error for a non-blocking socket. */
 
469
                if (errno == EAGAIN) {
 
470
                        DEBUG(10,("read_udp_v4_socket: returned EAGAIN\n"));
 
471
                } else {
 
472
                        DEBUG(2,("read_udp_v4_socket: failed. errno=%s\n",
 
473
                                strerror(errno)));
 
474
                }
 
475
                return 0;
 
476
        }
 
477
 
 
478
        if (psa->ss_family != AF_INET) {
 
479
                DEBUG(2,("read_udp_v4_socket: invalid address family %d "
 
480
                        "(not IPv4)\n", (int)psa->ss_family));
 
481
                return 0;
 
482
        }
 
483
 
 
484
        DEBUG(10,("read_udp_v4_socket: ip %s port %d read: %lu\n",
 
485
                        inet_ntoa(si->sin_addr),
 
486
                        si->sin_port,
 
487
                        (unsigned long)ret));
 
488
 
 
489
        return ret;
 
490
}
 
491
 
 
492
/****************************************************************************
 
493
 Read data from a file descriptor with a timout in msec.
 
494
 mincount = if timeout, minimum to read before returning
 
495
 maxcount = number to be read.
 
496
 time_out = timeout in milliseconds
 
497
 NB. This can be called with a non-socket fd, don't change
 
498
 sys_read() to sys_recv() or other socket call.
 
499
****************************************************************************/
 
500
 
 
501
NTSTATUS read_fd_with_timeout(int fd, char *buf,
 
502
                                  size_t mincnt, size_t maxcnt,
 
503
                                  unsigned int time_out,
 
504
                                  size_t *size_ret)
 
505
{
 
506
        fd_set fds;
 
507
        int selrtn;
 
508
        ssize_t readret;
 
509
        size_t nread = 0;
 
510
        struct timeval timeout;
 
511
        char addr[INET6_ADDRSTRLEN];
 
512
 
 
513
        /* just checking .... */
 
514
        if (maxcnt <= 0)
 
515
                return NT_STATUS_OK;
 
516
 
 
517
        /* Blocking read */
 
518
        if (time_out == 0) {
 
519
                if (mincnt == 0) {
 
520
                        mincnt = maxcnt;
 
521
                }
 
522
 
 
523
                while (nread < mincnt) {
 
524
                        readret = sys_read(fd, buf + nread, maxcnt - nread);
 
525
 
 
526
                        if (readret == 0) {
 
527
                                DEBUG(5,("read_fd_with_timeout: "
 
528
                                        "blocking read. EOF from client.\n"));
 
529
                                return NT_STATUS_END_OF_FILE;
 
530
                        }
 
531
 
 
532
                        if (readret == -1) {
 
533
                                if (fd == get_client_fd()) {
 
534
                                        /* Try and give an error message
 
535
                                         * saying what client failed. */
 
536
                                        DEBUG(0,("read_fd_with_timeout: "
 
537
                                                "client %s read error = %s.\n",
 
538
                                                get_peer_addr(fd,addr,sizeof(addr)),
 
539
                                                strerror(errno) ));
 
540
                                } else {
 
541
                                        DEBUG(0,("read_fd_with_timeout: "
 
542
                                                "read error = %s.\n",
 
543
                                                strerror(errno) ));
 
544
                                }
 
545
                                return map_nt_error_from_unix(errno);
 
546
                        }
 
547
                        nread += readret;
 
548
                }
 
549
                goto done;
 
550
        }
 
551
 
 
552
        /* Most difficult - timeout read */
 
553
        /* If this is ever called on a disk file and
 
554
           mincnt is greater then the filesize then
 
555
           system performance will suffer severely as
 
556
           select always returns true on disk files */
 
557
 
 
558
        /* Set initial timeout */
 
559
        timeout.tv_sec = (time_t)(time_out / 1000);
 
560
        timeout.tv_usec = (long)(1000 * (time_out % 1000));
 
561
 
 
562
        for (nread=0; nread < mincnt; ) {
 
563
                FD_ZERO(&fds);
 
564
                FD_SET(fd,&fds);
 
565
 
 
566
                selrtn = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout);
 
567
 
 
568
                /* Check if error */
 
569
                if (selrtn == -1) {
 
570
                        /* something is wrong. Maybe the socket is dead? */
 
571
                        if (fd == get_client_fd()) {
 
572
                                /* Try and give an error message saying
 
573
                                 * what client failed. */
 
574
                                DEBUG(0,("read_fd_with_timeout: timeout "
 
575
                                "read for client %s. select error = %s.\n",
 
576
                                get_peer_addr(fd,addr,sizeof(addr)),
 
577
                                strerror(errno) ));
 
578
                        } else {
 
579
                                DEBUG(0,("read_fd_with_timeout: timeout "
 
580
                                "read. select error = %s.\n",
 
581
                                strerror(errno) ));
 
582
                        }
 
583
                        return map_nt_error_from_unix(errno);
 
584
                }
 
585
 
 
586
                /* Did we timeout ? */
 
587
                if (selrtn == 0) {
 
588
                        DEBUG(10,("read_fd_with_timeout: timeout read. "
 
589
                                "select timed out.\n"));
 
590
                        return NT_STATUS_IO_TIMEOUT;
 
591
                }
 
592
 
 
593
                readret = sys_read(fd, buf+nread, maxcnt-nread);
 
594
 
 
595
                if (readret == 0) {
 
596
                        /* we got EOF on the file descriptor */
 
597
                        DEBUG(5,("read_fd_with_timeout: timeout read. "
 
598
                                "EOF from client.\n"));
 
599
                        return NT_STATUS_END_OF_FILE;
 
600
                }
 
601
 
 
602
                if (readret == -1) {
 
603
                        /* the descriptor is probably dead */
 
604
                        if (fd == get_client_fd()) {
 
605
                                /* Try and give an error message
 
606
                                 * saying what client failed. */
 
607
                                DEBUG(0,("read_fd_with_timeout: timeout "
 
608
                                        "read to client %s. read error = %s.\n",
 
609
                                        get_peer_addr(fd,addr,sizeof(addr)),
 
610
                                        strerror(errno) ));
 
611
                        } else {
 
612
                                DEBUG(0,("read_fd_with_timeout: timeout "
 
613
                                        "read. read error = %s.\n",
 
614
                                        strerror(errno) ));
 
615
                        }
 
616
                        return map_nt_error_from_unix(errno);
 
617
                }
 
618
 
 
619
                nread += readret;
 
620
        }
 
621
 
 
622
 done:
 
623
        /* Return the number we got */
 
624
        if (size_ret) {
 
625
                *size_ret = nread;
 
626
        }
 
627
        return NT_STATUS_OK;
 
628
}
 
629
 
 
630
/****************************************************************************
 
631
 Read data from an fd, reading exactly N bytes.
 
632
 NB. This can be called with a non-socket fd, don't add dependencies
 
633
 on socket calls.
 
634
****************************************************************************/
 
635
 
 
636
NTSTATUS read_data(int fd, char *buffer, size_t N)
 
637
{
 
638
        return read_fd_with_timeout(fd, buffer, N, N, 0, NULL);
 
639
}
 
640
 
 
641
/****************************************************************************
 
642
 Write all data from an iov array
 
643
 NB. This can be called with a non-socket fd, don't add dependencies
 
644
 on socket calls.
 
645
****************************************************************************/
 
646
 
 
647
ssize_t write_data_iov(int fd, const struct iovec *orig_iov, int iovcnt)
 
648
{
 
649
        int i;
 
650
        size_t to_send;
 
651
        ssize_t thistime;
 
652
        size_t sent;
 
653
        struct iovec *iov_copy, *iov;
 
654
 
 
655
        to_send = 0;
 
656
        for (i=0; i<iovcnt; i++) {
 
657
                to_send += orig_iov[i].iov_len;
 
658
        }
 
659
 
 
660
        thistime = sys_writev(fd, orig_iov, iovcnt);
 
661
        if ((thistime <= 0) || (thistime == to_send)) {
 
662
                return thistime;
 
663
        }
 
664
        sent = thistime;
 
665
 
 
666
        /*
 
667
         * We could not send everything in one call. Make a copy of iov that
 
668
         * we can mess with. We keep a copy of the array start in iov_copy for
 
669
         * the TALLOC_FREE, because we're going to modify iov later on,
 
670
         * discarding elements.
 
671
         */
 
672
 
 
673
        iov_copy = (struct iovec *)TALLOC_MEMDUP(
 
674
                talloc_tos(), orig_iov, sizeof(struct iovec) * iovcnt);
 
675
 
 
676
        if (iov_copy == NULL) {
 
677
                errno = ENOMEM;
 
678
                return -1;
 
679
        }
 
680
        iov = iov_copy;
 
681
 
 
682
        while (sent < to_send) {
 
683
                /*
 
684
                 * We have to discard "thistime" bytes from the beginning
 
685
                 * iov array, "thistime" contains the number of bytes sent
 
686
                 * via writev last.
 
687
                 */
 
688
                while (thistime > 0) {
 
689
                        if (thistime < iov[0].iov_len) {
 
690
                                char *new_base =
 
691
                                        (char *)iov[0].iov_base + thistime;
 
692
                                iov[0].iov_base = new_base;
 
693
                                iov[0].iov_len -= thistime;
 
694
                                break;
 
695
                        }
 
696
                        thistime -= iov[0].iov_len;
 
697
                        iov += 1;
 
698
                        iovcnt -= 1;
 
699
                }
 
700
 
 
701
                thistime = sys_writev(fd, iov, iovcnt);
 
702
                if (thistime <= 0) {
 
703
                        break;
 
704
                }
 
705
                sent += thistime;
 
706
        }
 
707
 
 
708
        TALLOC_FREE(iov_copy);
 
709
        return sent;
 
710
}
 
711
 
 
712
/****************************************************************************
 
713
 Write data to a fd.
 
714
 NB. This can be called with a non-socket fd, don't add dependencies
 
715
 on socket calls.
 
716
****************************************************************************/
 
717
 
 
718
ssize_t write_data(int fd, const char *buffer, size_t N)
 
719
{
 
720
        ssize_t ret;
 
721
        struct iovec iov;
 
722
 
 
723
        iov.iov_base = CONST_DISCARD(char *, buffer);
 
724
        iov.iov_len = N;
 
725
 
 
726
        ret = write_data_iov(fd, &iov, 1);
 
727
        if (ret >= 0) {
 
728
                return ret;
 
729
        }
 
730
 
 
731
        if (fd == get_client_fd()) {
 
732
                char addr[INET6_ADDRSTRLEN];
 
733
                /*
 
734
                 * Try and give an error message saying what client failed.
 
735
                 */
 
736
                DEBUG(0, ("write_data: write failure in writing to client %s. "
 
737
                          "Error %s\n", get_peer_addr(fd,addr,sizeof(addr)),
 
738
                          strerror(errno)));
 
739
        } else {
 
740
                DEBUG(0,("write_data: write failure. Error = %s\n",
 
741
                         strerror(errno) ));
 
742
        }
 
743
 
 
744
        return -1;
 
745
}
 
746
 
 
747
/****************************************************************************
 
748
 Send a keepalive packet (rfc1002).
 
749
****************************************************************************/
 
750
 
 
751
bool send_keepalive(int client)
 
752
{
 
753
        unsigned char buf[4];
 
754
 
 
755
        buf[0] = SMBkeepalive;
 
756
        buf[1] = buf[2] = buf[3] = 0;
 
757
 
 
758
        return(write_data(client,(char *)buf,4) == 4);
 
759
}
 
760
 
 
761
/****************************************************************************
 
762
 Read 4 bytes of a smb packet and return the smb length of the packet.
 
763
 Store the result in the buffer.
 
764
 This version of the function will return a length of zero on receiving
 
765
 a keepalive packet.
 
766
 Timeout is in milliseconds.
 
767
****************************************************************************/
 
768
 
 
769
NTSTATUS read_smb_length_return_keepalive(int fd, char *inbuf,
 
770
                                          unsigned int timeout,
 
771
                                          size_t *len)
 
772
{
 
773
        int msg_type;
 
774
        NTSTATUS status;
 
775
 
 
776
        status = read_fd_with_timeout(fd, inbuf, 4, 4, timeout, NULL);
 
777
 
 
778
        if (!NT_STATUS_IS_OK(status)) {
 
779
                return status;
 
780
        }
 
781
 
 
782
        *len = smb_len(inbuf);
 
783
        msg_type = CVAL(inbuf,0);
 
784
 
 
785
        if (msg_type == SMBkeepalive) {
 
786
                DEBUG(5,("Got keepalive packet\n"));
 
787
        }
 
788
 
 
789
        DEBUG(10,("got smb length of %lu\n",(unsigned long)(*len)));
 
790
 
 
791
        return NT_STATUS_OK;
 
792
}
 
793
 
 
794
/****************************************************************************
 
795
 Read 4 bytes of a smb packet and return the smb length of the packet.
 
796
 Store the result in the buffer. This version of the function will
 
797
 never return a session keepalive (length of zero).
 
798
 Timeout is in milliseconds.
 
799
****************************************************************************/
 
800
 
 
801
NTSTATUS read_smb_length(int fd, char *inbuf, unsigned int timeout,
 
802
                         size_t *len)
 
803
{
 
804
        uint8_t msgtype = SMBkeepalive;
 
805
 
 
806
        while (msgtype == SMBkeepalive) {
 
807
                NTSTATUS status;
 
808
 
 
809
                status = read_smb_length_return_keepalive(fd, inbuf, timeout,
 
810
                                                          len);
 
811
                if (!NT_STATUS_IS_OK(status)) {
 
812
                        return status;
 
813
                }
 
814
 
 
815
                msgtype = CVAL(inbuf, 0);
 
816
        }
 
817
 
 
818
        DEBUG(10,("read_smb_length: got smb length of %lu\n",
 
819
                  (unsigned long)len));
 
820
 
 
821
        return NT_STATUS_OK;
 
822
}
 
823
 
 
824
/****************************************************************************
 
825
 Read an smb from a fd.
 
826
 The timeout is in milliseconds.
 
827
 This function will return on receipt of a session keepalive packet.
 
828
 maxlen is the max number of bytes to return, not including the 4 byte
 
829
 length. If zero it means buflen limit.
 
830
 Doesn't check the MAC on signed packets.
 
831
****************************************************************************/
 
832
 
 
833
NTSTATUS receive_smb_raw(int fd, char *buffer, size_t buflen, unsigned int timeout,
 
834
                         size_t maxlen, size_t *p_len)
 
835
{
 
836
        size_t len;
 
837
        NTSTATUS status;
 
838
 
 
839
        status = read_smb_length_return_keepalive(fd,buffer,timeout,&len);
 
840
 
 
841
        if (!NT_STATUS_IS_OK(status)) {
 
842
                DEBUG(10, ("receive_smb_raw: %s!\n", nt_errstr(status)));
 
843
                return status;
 
844
        }
 
845
 
 
846
        if (len > buflen) {
 
847
                DEBUG(0,("Invalid packet length! (%lu bytes).\n",
 
848
                                        (unsigned long)len));
 
849
                return NT_STATUS_INVALID_PARAMETER;
 
850
        }
 
851
 
 
852
        if(len > 0) {
 
853
                if (maxlen) {
 
854
                        len = MIN(len,maxlen);
 
855
                }
 
856
 
 
857
                status = read_fd_with_timeout(
 
858
                        fd, buffer+4, len, len, timeout, &len);
 
859
 
 
860
                if (!NT_STATUS_IS_OK(status)) {
 
861
                        return status;
 
862
                }
 
863
 
 
864
                /* not all of samba3 properly checks for packet-termination
 
865
                 * of strings. This ensures that we don't run off into
 
866
                 * empty space. */
 
867
                SSVAL(buffer+4,len, 0);
 
868
        }
 
869
 
 
870
        *p_len = len;
 
871
        return NT_STATUS_OK;
 
872
}
 
873
 
 
874
/****************************************************************************
 
875
 Open a socket of the specified type, port, and address for incoming data.
 
876
****************************************************************************/
 
877
 
 
878
int open_socket_in(int type,
 
879
                uint16_t port,
 
880
                int dlevel,
 
881
                const struct sockaddr_storage *psock,
 
882
                bool rebind)
 
883
{
 
884
        struct sockaddr_storage sock;
 
885
        int res;
 
886
        socklen_t slen = sizeof(struct sockaddr_in);
 
887
 
 
888
        sock = *psock;
 
889
 
 
890
#if defined(HAVE_IPV6)
 
891
        if (sock.ss_family == AF_INET6) {
 
892
                ((struct sockaddr_in6 *)&sock)->sin6_port = htons(port);
 
893
                slen = sizeof(struct sockaddr_in6);
 
894
        }
 
895
#endif
 
896
        if (sock.ss_family == AF_INET) {
 
897
                ((struct sockaddr_in *)&sock)->sin_port = htons(port);
 
898
        }
 
899
 
 
900
        res = socket(sock.ss_family, type, 0 );
 
901
        if( res == -1 ) {
 
902
                if( DEBUGLVL(0) ) {
 
903
                        dbgtext( "open_socket_in(): socket() call failed: " );
 
904
                        dbgtext( "%s\n", strerror( errno ) );
 
905
                }
 
906
                return -1;
 
907
        }
 
908
 
 
909
        /* This block sets/clears the SO_REUSEADDR and possibly SO_REUSEPORT. */
 
910
        {
 
911
                int val = rebind ? 1 : 0;
 
912
                if( setsockopt(res,SOL_SOCKET,SO_REUSEADDR,
 
913
                                        (char *)&val,sizeof(val)) == -1 ) {
 
914
                        if( DEBUGLVL( dlevel ) ) {
 
915
                                dbgtext( "open_socket_in(): setsockopt: " );
 
916
                                dbgtext( "SO_REUSEADDR = %s ",
 
917
                                                val?"true":"false" );
 
918
                                dbgtext( "on port %d failed ", port );
 
919
                                dbgtext( "with error = %s\n", strerror(errno) );
 
920
                        }
 
921
                }
 
922
#ifdef SO_REUSEPORT
 
923
                if( setsockopt(res,SOL_SOCKET,SO_REUSEPORT,
 
924
                                        (char *)&val,sizeof(val)) == -1 ) {
 
925
                        if( DEBUGLVL( dlevel ) ) {
 
926
                                dbgtext( "open_socket_in(): setsockopt: ");
 
927
                                dbgtext( "SO_REUSEPORT = %s ",
 
928
                                                val?"true":"false");
 
929
                                dbgtext( "on port %d failed ", port);
 
930
                                dbgtext( "with error = %s\n", strerror(errno));
 
931
                        }
 
932
                }
 
933
#endif /* SO_REUSEPORT */
 
934
        }
 
935
 
 
936
        /* now we've got a socket - we need to bind it */
 
937
        if (bind(res, (struct sockaddr *)&sock, slen) == -1 ) {
 
938
                if( DEBUGLVL(dlevel) && (port == SMB_PORT1 ||
 
939
                                port == SMB_PORT2 || port == NMB_PORT) ) {
 
940
                        char addr[INET6_ADDRSTRLEN];
 
941
                        print_sockaddr(addr, sizeof(addr),
 
942
                                        &sock);
 
943
                        dbgtext( "bind failed on port %d ", port);
 
944
                        dbgtext( "socket_addr = %s.\n", addr);
 
945
                        dbgtext( "Error = %s\n", strerror(errno));
 
946
                }
 
947
                close(res);
 
948
                return -1;
 
949
        }
 
950
 
 
951
        DEBUG( 10, ( "bind succeeded on port %d\n", port ) );
 
952
        return( res );
 
953
 }
 
954
 
 
955
struct open_socket_out_state {
 
956
        int fd;
 
957
        struct event_context *ev;
 
958
        struct sockaddr_storage ss;
 
959
        socklen_t salen;
 
960
        uint16_t port;
 
961
        int wait_nsec;
 
962
};
 
963
 
 
964
static void open_socket_out_connected(struct tevent_req *subreq);
 
965
 
 
966
static int open_socket_out_state_destructor(struct open_socket_out_state *s)
 
967
{
 
968
        if (s->fd != -1) {
 
969
                close(s->fd);
 
970
        }
 
971
        return 0;
 
972
}
 
973
 
 
974
/****************************************************************************
 
975
 Create an outgoing socket. timeout is in milliseconds.
 
976
**************************************************************************/
 
977
 
 
978
struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
 
979
                                        struct event_context *ev,
 
980
                                        const struct sockaddr_storage *pss,
 
981
                                        uint16_t port,
 
982
                                        int timeout)
 
983
{
 
984
        char addr[INET6_ADDRSTRLEN];
 
985
        struct tevent_req *result, *subreq;
 
986
        struct open_socket_out_state *state;
 
987
        NTSTATUS status;
 
988
 
 
989
        result = tevent_req_create(mem_ctx, &state,
 
990
                                   struct open_socket_out_state);
 
991
        if (result == NULL) {
 
992
                return NULL;
 
993
        }
 
994
        state->ev = ev;
 
995
        state->ss = *pss;
 
996
        state->port = port;
 
997
        state->wait_nsec = 10000;
 
998
        state->salen = -1;
 
999
 
 
1000
        state->fd = socket(state->ss.ss_family, SOCK_STREAM, 0);
 
1001
        if (state->fd == -1) {
 
1002
                status = map_nt_error_from_unix(errno);
 
1003
                goto post_status;
 
1004
        }
 
1005
        talloc_set_destructor(state, open_socket_out_state_destructor);
 
1006
 
 
1007
        if (!tevent_req_set_endtime(
 
1008
                    result, ev, timeval_current_ofs(0, timeout*1000))) {
 
1009
                goto fail;
 
1010
        }
 
1011
 
 
1012
#if defined(HAVE_IPV6)
 
1013
        if (pss->ss_family == AF_INET6) {
 
1014
                struct sockaddr_in6 *psa6;
 
1015
                psa6 = (struct sockaddr_in6 *)&state->ss;
 
1016
                psa6->sin6_port = htons(port);
 
1017
                if (psa6->sin6_scope_id == 0
 
1018
                    && IN6_IS_ADDR_LINKLOCAL(&psa6->sin6_addr)) {
 
1019
                        setup_linklocal_scope_id(
 
1020
                                (struct sockaddr *)&(state->ss));
 
1021
                }
 
1022
                state->salen = sizeof(struct sockaddr_in6);
 
1023
        }
 
1024
#endif
 
1025
        if (pss->ss_family == AF_INET) {
 
1026
                struct sockaddr_in *psa;
 
1027
                psa = (struct sockaddr_in *)&state->ss;
 
1028
                psa->sin_port = htons(port);
 
1029
                state->salen = sizeof(struct sockaddr_in);
 
1030
        }
 
1031
 
 
1032
        print_sockaddr(addr, sizeof(addr), &state->ss);
 
1033
        DEBUG(3,("Connecting to %s at port %u\n", addr, (unsigned int)port));
 
1034
 
 
1035
        subreq = async_connect_send(state, state->ev, state->fd,
 
1036
                                    (struct sockaddr *)&state->ss,
 
1037
                                    state->salen);
 
1038
        if ((subreq == NULL)
 
1039
            || !tevent_req_set_endtime(
 
1040
                    subreq, state->ev,
 
1041
                    timeval_current_ofs(0, state->wait_nsec))) {
 
1042
                goto fail;
 
1043
        }
 
1044
        tevent_req_set_callback(subreq, open_socket_out_connected, result);
 
1045
        return result;
 
1046
 
 
1047
 post_status:
 
1048
        tevent_req_nterror(result, status);
 
1049
        return tevent_req_post(result, ev);
 
1050
 fail:
 
1051
        TALLOC_FREE(result);
 
1052
        return NULL;
 
1053
}
 
1054
 
 
1055
static void open_socket_out_connected(struct tevent_req *subreq)
 
1056
{
 
1057
        struct tevent_req *req =
 
1058
                tevent_req_callback_data(subreq, struct tevent_req);
 
1059
        struct open_socket_out_state *state =
 
1060
                tevent_req_data(req, struct open_socket_out_state);
 
1061
        int ret;
 
1062
        int sys_errno;
 
1063
 
 
1064
        ret = async_connect_recv(subreq, &sys_errno);
 
1065
        TALLOC_FREE(subreq);
 
1066
        if (ret == 0) {
 
1067
                tevent_req_done(req);
 
1068
                return;
 
1069
        }
 
1070
 
 
1071
        if (
 
1072
#ifdef ETIMEDOUT
 
1073
                (sys_errno == ETIMEDOUT) ||
 
1074
#endif
 
1075
                (sys_errno == EINPROGRESS) ||
 
1076
                (sys_errno == EALREADY) ||
 
1077
                (sys_errno == EAGAIN)) {
 
1078
 
 
1079
                /*
 
1080
                 * retry
 
1081
                 */
 
1082
 
 
1083
                if (state->wait_nsec < 250000) {
 
1084
                        state->wait_nsec *= 1.5;
 
1085
                }
 
1086
 
 
1087
                subreq = async_connect_send(state, state->ev, state->fd,
 
1088
                                            (struct sockaddr *)&state->ss,
 
1089
                                            state->salen);
 
1090
                if (tevent_req_nomem(subreq, req)) {
 
1091
                        return;
 
1092
                }
 
1093
                if (!tevent_req_set_endtime(
 
1094
                            subreq, state->ev,
 
1095
                            timeval_current_ofs(0, state->wait_nsec))) {
 
1096
                        tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
 
1097
                        return;
 
1098
                }
 
1099
                tevent_req_set_callback(subreq, open_socket_out_connected, req);
 
1100
                return;
 
1101
        }
 
1102
 
 
1103
#ifdef EISCONN
 
1104
        if (sys_errno == EISCONN) {
 
1105
                tevent_req_done(req);
 
1106
                return;
 
1107
        }
 
1108
#endif
 
1109
 
 
1110
        /* real error */
 
1111
        tevent_req_nterror(req, map_nt_error_from_unix(sys_errno));
 
1112
}
 
1113
 
 
1114
NTSTATUS open_socket_out_recv(struct tevent_req *req, int *pfd)
 
1115
{
 
1116
        struct open_socket_out_state *state =
 
1117
                tevent_req_data(req, struct open_socket_out_state);
 
1118
        NTSTATUS status;
 
1119
 
 
1120
        if (tevent_req_is_nterror(req, &status)) {
 
1121
                return status;
 
1122
        }
 
1123
        *pfd = state->fd;
 
1124
        state->fd = -1;
 
1125
        return NT_STATUS_OK;
 
1126
}
 
1127
 
 
1128
NTSTATUS open_socket_out(const struct sockaddr_storage *pss, uint16_t port,
 
1129
                         int timeout, int *pfd)
 
1130
{
 
1131
        TALLOC_CTX *frame = talloc_stackframe();
 
1132
        struct event_context *ev;
 
1133
        struct tevent_req *req;
 
1134
        NTSTATUS status = NT_STATUS_NO_MEMORY;
 
1135
 
 
1136
        ev = event_context_init(frame);
 
1137
        if (ev == NULL) {
 
1138
                goto fail;
 
1139
        }
 
1140
 
 
1141
        req = open_socket_out_send(frame, ev, pss, port, timeout);
 
1142
        if (req == NULL) {
 
1143
                goto fail;
 
1144
        }
 
1145
        if (!tevent_req_poll(req, ev)) {
 
1146
                status = NT_STATUS_INTERNAL_ERROR;
 
1147
                goto fail;
 
1148
        }
 
1149
        status = open_socket_out_recv(req, pfd);
 
1150
 fail:
 
1151
        TALLOC_FREE(frame);
 
1152
        return status;
 
1153
}
 
1154
 
 
1155
struct open_socket_out_defer_state {
 
1156
        struct event_context *ev;
 
1157
        struct sockaddr_storage ss;
 
1158
        uint16_t port;
 
1159
        int timeout;
 
1160
        int fd;
 
1161
};
 
1162
 
 
1163
static void open_socket_out_defer_waited(struct tevent_req *subreq);
 
1164
static void open_socket_out_defer_connected(struct tevent_req *subreq);
 
1165
 
 
1166
struct tevent_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx,
 
1167
                                              struct event_context *ev,
 
1168
                                              struct timeval wait_time,
 
1169
                                              const struct sockaddr_storage *pss,
 
1170
                                              uint16_t port,
 
1171
                                              int timeout)
 
1172
{
 
1173
        struct tevent_req *req, *subreq;
 
1174
        struct open_socket_out_defer_state *state;
 
1175
 
 
1176
        req = tevent_req_create(mem_ctx, &state,
 
1177
                                struct open_socket_out_defer_state);
 
1178
        if (req == NULL) {
 
1179
                return NULL;
 
1180
        }
 
1181
        state->ev = ev;
 
1182
        state->ss = *pss;
 
1183
        state->port = port;
 
1184
        state->timeout = timeout;
 
1185
 
 
1186
        subreq = tevent_wakeup_send(
 
1187
                state, ev,
 
1188
                timeval_current_ofs(wait_time.tv_sec, wait_time.tv_usec));
 
1189
        if (subreq == NULL) {
 
1190
                goto fail;
 
1191
        }
 
1192
        tevent_req_set_callback(subreq, open_socket_out_defer_waited, req);
 
1193
        return req;
 
1194
 fail:
 
1195
        TALLOC_FREE(req);
 
1196
        return NULL;
 
1197
}
 
1198
 
 
1199
static void open_socket_out_defer_waited(struct tevent_req *subreq)
 
1200
{
 
1201
        struct tevent_req *req = tevent_req_callback_data(
 
1202
                subreq, struct tevent_req);
 
1203
        struct open_socket_out_defer_state *state = tevent_req_data(
 
1204
                req, struct open_socket_out_defer_state);
 
1205
        bool ret;
 
1206
 
 
1207
        ret = tevent_wakeup_recv(subreq);
 
1208
        TALLOC_FREE(subreq);
 
1209
        if (!ret) {
 
1210
                tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
 
1211
                return;
 
1212
        }
 
1213
 
 
1214
        subreq = open_socket_out_send(state, state->ev, &state->ss,
 
1215
                                      state->port, state->timeout);
 
1216
        if (tevent_req_nomem(subreq, req)) {
 
1217
                return;
 
1218
        }
 
1219
        tevent_req_set_callback(subreq, open_socket_out_defer_connected, req);
 
1220
}
 
1221
 
 
1222
static void open_socket_out_defer_connected(struct tevent_req *subreq)
 
1223
{
 
1224
        struct tevent_req *req = tevent_req_callback_data(
 
1225
                subreq, struct tevent_req);
 
1226
        struct open_socket_out_defer_state *state = tevent_req_data(
 
1227
                req, struct open_socket_out_defer_state);
 
1228
        NTSTATUS status;
 
1229
 
 
1230
        status = open_socket_out_recv(subreq, &state->fd);
 
1231
        TALLOC_FREE(subreq);
 
1232
        if (!NT_STATUS_IS_OK(status)) {
 
1233
                tevent_req_nterror(req, status);
 
1234
                return;
 
1235
        }
 
1236
        tevent_req_done(req);
 
1237
}
 
1238
 
 
1239
NTSTATUS open_socket_out_defer_recv(struct tevent_req *req, int *pfd)
 
1240
{
 
1241
        struct open_socket_out_defer_state *state = tevent_req_data(
 
1242
                req, struct open_socket_out_defer_state);
 
1243
        NTSTATUS status;
 
1244
 
 
1245
        if (tevent_req_is_nterror(req, &status)) {
 
1246
                return status;
 
1247
        }
 
1248
        *pfd = state->fd;
 
1249
        state->fd = -1;
 
1250
        return NT_STATUS_OK;
 
1251
}
 
1252
 
 
1253
/*******************************************************************
 
1254
 Create an outgoing TCP socket to the first addr that connects.
 
1255
 
 
1256
 This is for simultaneous connection attempts to port 445 and 139 of a host
 
1257
 or for simultatneous connection attempts to multiple DCs at once.  We return
 
1258
 a socket fd of the first successful connection.
 
1259
 
 
1260
 @param[in] addrs list of Internet addresses and ports to connect to
 
1261
 @param[in] num_addrs number of address/port pairs in the addrs list
 
1262
 @param[in] timeout time after which we stop waiting for a socket connection
 
1263
            to succeed, given in milliseconds
 
1264
 @param[out] fd_index the entry in addrs which we successfully connected to
 
1265
 @param[out] fd fd of the open and connected socket
 
1266
 @return true on a successful connection, false if all connection attempts
 
1267
         failed or we timed out
 
1268
*******************************************************************/
 
1269
 
 
1270
bool open_any_socket_out(struct sockaddr_storage *addrs, int num_addrs,
 
1271
                         int timeout, int *fd_index, int *fd)
 
1272
{
 
1273
        int i, resulting_index, res;
 
1274
        int *sockets;
 
1275
        bool good_connect;
 
1276
 
 
1277
        fd_set r_fds, wr_fds;
 
1278
        struct timeval tv;
 
1279
        int maxfd;
 
1280
 
 
1281
        int connect_loop = 10000; /* 10 milliseconds */
 
1282
 
 
1283
        timeout *= 1000;        /* convert to microseconds */
 
1284
 
 
1285
        sockets = SMB_MALLOC_ARRAY(int, num_addrs);
 
1286
 
 
1287
        if (sockets == NULL)
 
1288
                return false;
 
1289
 
 
1290
        resulting_index = -1;
 
1291
 
 
1292
        for (i=0; i<num_addrs; i++)
 
1293
                sockets[i] = -1;
 
1294
 
 
1295
        for (i=0; i<num_addrs; i++) {
 
1296
                sockets[i] = socket(addrs[i].ss_family, SOCK_STREAM, 0);
 
1297
                if (sockets[i] < 0)
 
1298
                        goto done;
 
1299
                set_blocking(sockets[i], false);
 
1300
        }
 
1301
 
 
1302
 connect_again:
 
1303
        good_connect = false;
 
1304
 
 
1305
        for (i=0; i<num_addrs; i++) {
 
1306
                const struct sockaddr * a = 
 
1307
                    (const struct sockaddr *)&(addrs[i]);
 
1308
 
 
1309
                if (sockets[i] == -1)
 
1310
                        continue;
 
1311
 
 
1312
                if (sys_connect(sockets[i], a) == 0) {
 
1313
                        /* Rather unlikely as we are non-blocking, but it
 
1314
                         * might actually happen. */
 
1315
                        resulting_index = i;
 
1316
                        goto done;
 
1317
                }
 
1318
 
 
1319
                if (errno == EINPROGRESS || errno == EALREADY ||
 
1320
#ifdef EISCONN
 
1321
                        errno == EISCONN ||
 
1322
#endif
 
1323
                    errno == EAGAIN || errno == EINTR) {
 
1324
                        /* These are the error messages that something is
 
1325
                           progressing. */
 
1326
                        good_connect = true;
 
1327
                } else if (errno != 0) {
 
1328
                        /* There was a direct error */
 
1329
                        close(sockets[i]);
 
1330
                        sockets[i] = -1;
 
1331
                }
 
1332
        }
 
1333
 
 
1334
        if (!good_connect) {
 
1335
                /* All of the connect's resulted in real error conditions */
 
1336
                goto done;
 
1337
        }
 
1338
 
 
1339
        /* Lets see if any of the connect attempts succeeded */
 
1340
 
 
1341
        maxfd = 0;
 
1342
        FD_ZERO(&wr_fds);
 
1343
        FD_ZERO(&r_fds);
 
1344
 
 
1345
        for (i=0; i<num_addrs; i++) {
 
1346
                if (sockets[i] == -1)
 
1347
                        continue;
 
1348
                FD_SET(sockets[i], &wr_fds);
 
1349
                FD_SET(sockets[i], &r_fds);
 
1350
                if (sockets[i]>maxfd)
 
1351
                        maxfd = sockets[i];
 
1352
        }
 
1353
 
 
1354
        tv.tv_sec = 0;
 
1355
        tv.tv_usec = connect_loop;
 
1356
 
 
1357
        res = sys_select_intr(maxfd+1, &r_fds, &wr_fds, NULL, &tv);
 
1358
 
 
1359
        if (res < 0)
 
1360
                goto done;
 
1361
 
 
1362
        if (res == 0)
 
1363
                goto next_round;
 
1364
 
 
1365
        for (i=0; i<num_addrs; i++) {
 
1366
 
 
1367
                if (sockets[i] == -1)
 
1368
                        continue;
 
1369
 
 
1370
                /* Stevens, Network Programming says that if there's a
 
1371
                 * successful connect, the socket is only writable. Upon an
 
1372
                 * error, it's both readable and writable. */
 
1373
 
 
1374
                if (FD_ISSET(sockets[i], &r_fds) &&
 
1375
                    FD_ISSET(sockets[i], &wr_fds)) {
 
1376
                        /* readable and writable, so it's an error */
 
1377
                        close(sockets[i]);
 
1378
                        sockets[i] = -1;
 
1379
                        continue;
 
1380
                }
 
1381
 
 
1382
                if (!FD_ISSET(sockets[i], &r_fds) &&
 
1383
                    FD_ISSET(sockets[i], &wr_fds)) {
 
1384
                        /* Only writable, so it's connected */
 
1385
                        resulting_index = i;
 
1386
                        goto done;
 
1387
                }
 
1388
        }
 
1389
 
 
1390
 next_round:
 
1391
 
 
1392
        timeout -= connect_loop;
 
1393
        if (timeout <= 0)
 
1394
                goto done;
 
1395
        connect_loop *= 1.5;
 
1396
        if (connect_loop > timeout)
 
1397
                connect_loop = timeout;
 
1398
        goto connect_again;
 
1399
 
 
1400
 done:
 
1401
        for (i=0; i<num_addrs; i++) {
 
1402
                if (i == resulting_index)
 
1403
                        continue;
 
1404
                if (sockets[i] >= 0)
 
1405
                        close(sockets[i]);
 
1406
        }
 
1407
 
 
1408
        if (resulting_index >= 0) {
 
1409
                *fd_index = resulting_index;
 
1410
                *fd = sockets[*fd_index];
 
1411
                set_blocking(*fd, true);
 
1412
        }
 
1413
 
 
1414
        free(sockets);
 
1415
 
 
1416
        return (resulting_index >= 0);
 
1417
}
 
1418
/****************************************************************************
 
1419
 Open a connected UDP socket to host on port
 
1420
**************************************************************************/
 
1421
 
 
1422
int open_udp_socket(const char *host, int port)
 
1423
{
 
1424
        struct sockaddr_storage ss;
 
1425
        int res;
 
1426
 
 
1427
        if (!interpret_string_addr(&ss, host, 0)) {
 
1428
                DEBUG(10,("open_udp_socket: can't resolve name %s\n",
 
1429
                        host));
 
1430
                return -1;
 
1431
        }
 
1432
 
 
1433
        res = socket(ss.ss_family, SOCK_DGRAM, 0);
 
1434
        if (res == -1) {
 
1435
                return -1;
 
1436
        }
 
1437
 
 
1438
#if defined(HAVE_IPV6)
 
1439
        if (ss.ss_family == AF_INET6) {
 
1440
                struct sockaddr_in6 *psa6;
 
1441
                psa6 = (struct sockaddr_in6 *)&ss;
 
1442
                psa6->sin6_port = htons(port);
 
1443
                if (psa6->sin6_scope_id == 0
 
1444
                                && IN6_IS_ADDR_LINKLOCAL(&psa6->sin6_addr)) {
 
1445
                        setup_linklocal_scope_id(
 
1446
                                (struct sockaddr *)&ss);
 
1447
                }
 
1448
        }
 
1449
#endif
 
1450
        if (ss.ss_family == AF_INET) {
 
1451
                struct sockaddr_in *psa;
 
1452
                psa = (struct sockaddr_in *)&ss;
 
1453
                psa->sin_port = htons(port);
 
1454
        }
 
1455
 
 
1456
        if (sys_connect(res,(struct sockaddr *)&ss)) {
 
1457
                close(res);
 
1458
                return -1;
 
1459
        }
 
1460
 
 
1461
        return res;
 
1462
}
 
1463
 
 
1464
/*******************************************************************
 
1465
 Return the IP addr of the remote end of a socket as a string.
 
1466
 Optionally return the struct sockaddr_storage.
 
1467
 ******************************************************************/
 
1468
 
 
1469
static const char *get_peer_addr_internal(int fd,
 
1470
                                char *addr_buf,
 
1471
                                size_t addr_buf_len,
 
1472
                                struct sockaddr *pss,
 
1473
                                socklen_t *plength)
 
1474
{
 
1475
        struct sockaddr_storage ss;
 
1476
        socklen_t length = sizeof(ss);
 
1477
 
 
1478
        strlcpy(addr_buf,"0.0.0.0",addr_buf_len);
 
1479
 
 
1480
        if (fd == -1) {
 
1481
                return addr_buf;
 
1482
        }
 
1483
 
 
1484
        if (pss == NULL) {
 
1485
                pss = (struct sockaddr *)&ss;
 
1486
                plength = &length;
 
1487
        }
 
1488
 
 
1489
        if (getpeername(fd, (struct sockaddr *)pss, plength) < 0) {
 
1490
                DEBUG(0,("getpeername failed. Error was %s\n",
 
1491
                                        strerror(errno) ));
 
1492
                return addr_buf;
 
1493
        }
 
1494
 
 
1495
        print_sockaddr_len(addr_buf,
 
1496
                        addr_buf_len,
 
1497
                        pss,
 
1498
                        *plength);
 
1499
        return addr_buf;
 
1500
}
 
1501
 
 
1502
/*******************************************************************
 
1503
 Matchname - determine if host name matches IP address. Used to
 
1504
 confirm a hostname lookup to prevent spoof attacks.
 
1505
******************************************************************/
 
1506
 
 
1507
static bool matchname(const char *remotehost,
 
1508
                const struct sockaddr *pss,
 
1509
                socklen_t len)
 
1510
{
 
1511
        struct addrinfo *res = NULL;
 
1512
        struct addrinfo *ailist = NULL;
 
1513
        char addr_buf[INET6_ADDRSTRLEN];
 
1514
        bool ret = interpret_string_addr_internal(&ailist,
 
1515
                        remotehost,
 
1516
                        AI_ADDRCONFIG|AI_CANONNAME);
 
1517
 
 
1518
        if (!ret || ailist == NULL) {
 
1519
                DEBUG(3,("matchname: getaddrinfo failed for "
 
1520
                        "name %s [%s]\n",
 
1521
                        remotehost,
 
1522
                        gai_strerror(ret) ));
 
1523
                return false;
 
1524
        }
 
1525
 
 
1526
        /*
 
1527
         * Make sure that getaddrinfo() returns the "correct" host name.
 
1528
         */
 
1529
 
 
1530
        if (ailist->ai_canonname == NULL ||
 
1531
                (!strequal(remotehost, ailist->ai_canonname) &&
 
1532
                 !strequal(remotehost, "localhost"))) {
 
1533
                DEBUG(0,("matchname: host name/name mismatch: %s != %s\n",
 
1534
                         remotehost,
 
1535
                         ailist->ai_canonname ?
 
1536
                                 ailist->ai_canonname : "(NULL)"));
 
1537
                freeaddrinfo(ailist);
 
1538
                return false;
 
1539
        }
 
1540
 
 
1541
        /* Look up the host address in the address list we just got. */
 
1542
        for (res = ailist; res; res = res->ai_next) {
 
1543
                if (!res->ai_addr) {
 
1544
                        continue;
 
1545
                }
 
1546
                if (sockaddr_equal((const struct sockaddr *)res->ai_addr,
 
1547
                                        (struct sockaddr *)pss)) {
 
1548
                        freeaddrinfo(ailist);
 
1549
                        return true;
 
1550
                }
 
1551
        }
 
1552
 
 
1553
        /*
 
1554
         * The host name does not map to the original host address. Perhaps
 
1555
         * someone has compromised a name server. More likely someone botched
 
1556
         * it, but that could be dangerous, too.
 
1557
         */
 
1558
 
 
1559
        DEBUG(0,("matchname: host name/address mismatch: %s != %s\n",
 
1560
                print_sockaddr_len(addr_buf,
 
1561
                        sizeof(addr_buf),
 
1562
                        pss,
 
1563
                        len),
 
1564
                 ailist->ai_canonname ? ailist->ai_canonname : "(NULL)"));
 
1565
 
 
1566
        if (ailist) {
 
1567
                freeaddrinfo(ailist);
 
1568
        }
 
1569
        return false;
 
1570
}
 
1571
 
 
1572
/*******************************************************************
 
1573
 Deal with the singleton cache.
 
1574
******************************************************************/
 
1575
 
 
1576
struct name_addr_pair {
 
1577
        struct sockaddr_storage ss;
 
1578
        const char *name;
 
1579
};
 
1580
 
 
1581
/*******************************************************************
 
1582
 Lookup a name/addr pair. Returns memory allocated from memcache.
 
1583
******************************************************************/
 
1584
 
 
1585
static bool lookup_nc(struct name_addr_pair *nc)
 
1586
{
 
1587
        DATA_BLOB tmp;
 
1588
 
 
1589
        ZERO_STRUCTP(nc);
 
1590
 
 
1591
        if (!memcache_lookup(
 
1592
                        NULL, SINGLETON_CACHE,
 
1593
                        data_blob_string_const_null("get_peer_name"),
 
1594
                        &tmp)) {
 
1595
                return false;
 
1596
        }
 
1597
 
 
1598
        memcpy(&nc->ss, tmp.data, sizeof(nc->ss));
 
1599
        nc->name = (const char *)tmp.data + sizeof(nc->ss);
 
1600
        return true;
 
1601
}
 
1602
 
 
1603
/*******************************************************************
 
1604
 Save a name/addr pair.
 
1605
******************************************************************/
 
1606
 
 
1607
static void store_nc(const struct name_addr_pair *nc)
 
1608
{
 
1609
        DATA_BLOB tmp;
 
1610
        size_t namelen = strlen(nc->name);
 
1611
 
 
1612
        tmp = data_blob(NULL, sizeof(nc->ss) + namelen + 1);
 
1613
        if (!tmp.data) {
 
1614
                return;
 
1615
        }
 
1616
        memcpy(tmp.data, &nc->ss, sizeof(nc->ss));
 
1617
        memcpy(tmp.data+sizeof(nc->ss), nc->name, namelen+1);
 
1618
 
 
1619
        memcache_add(NULL, SINGLETON_CACHE,
 
1620
                        data_blob_string_const_null("get_peer_name"),
 
1621
                        tmp);
 
1622
        data_blob_free(&tmp);
 
1623
}
 
1624
 
 
1625
/*******************************************************************
 
1626
 Return the DNS name of the remote end of a socket.
 
1627
******************************************************************/
 
1628
 
 
1629
const char *get_peer_name(int fd, bool force_lookup)
 
1630
{
 
1631
        struct name_addr_pair nc;
 
1632
        char addr_buf[INET6_ADDRSTRLEN];
 
1633
        struct sockaddr_storage ss;
 
1634
        socklen_t length = sizeof(ss);
 
1635
        const char *p;
 
1636
        int ret;
 
1637
        char name_buf[MAX_DNS_NAME_LENGTH];
 
1638
        char tmp_name[MAX_DNS_NAME_LENGTH];
 
1639
 
 
1640
        /* reverse lookups can be *very* expensive, and in many
 
1641
           situations won't work because many networks don't link dhcp
 
1642
           with dns. To avoid the delay we avoid the lookup if
 
1643
           possible */
 
1644
        if (!lp_hostname_lookups() && (force_lookup == false)) {
 
1645
                length = sizeof(nc.ss);
 
1646
                nc.name = get_peer_addr_internal(fd, addr_buf, sizeof(addr_buf),
 
1647
                        (struct sockaddr *)&nc.ss, &length);
 
1648
                store_nc(&nc);
 
1649
                lookup_nc(&nc);
 
1650
                return nc.name ? nc.name : "UNKNOWN";
 
1651
        }
 
1652
 
 
1653
        lookup_nc(&nc);
 
1654
 
 
1655
        memset(&ss, '\0', sizeof(ss));
 
1656
        p = get_peer_addr_internal(fd, addr_buf, sizeof(addr_buf), (struct sockaddr *)&ss, &length);
 
1657
 
 
1658
        /* it might be the same as the last one - save some DNS work */
 
1659
        if (sockaddr_equal((struct sockaddr *)&ss, (struct sockaddr *)&nc.ss)) {
 
1660
                return nc.name ? nc.name : "UNKNOWN";
 
1661
        }
 
1662
 
 
1663
        /* Not the same. We need to lookup. */
 
1664
        if (fd == -1) {
 
1665
                return "UNKNOWN";
 
1666
        }
 
1667
 
 
1668
        /* Look up the remote host name. */
 
1669
        ret = sys_getnameinfo((struct sockaddr *)&ss,
 
1670
                        length,
 
1671
                        name_buf,
 
1672
                        sizeof(name_buf),
 
1673
                        NULL,
 
1674
                        0,
 
1675
                        0);
 
1676
 
 
1677
        if (ret) {
 
1678
                DEBUG(1,("get_peer_name: getnameinfo failed "
 
1679
                        "for %s with error %s\n",
 
1680
                        p,
 
1681
                        gai_strerror(ret)));
 
1682
                strlcpy(name_buf, p, sizeof(name_buf));
 
1683
        } else {
 
1684
                if (!matchname(name_buf, (struct sockaddr *)&ss, length)) {
 
1685
                        DEBUG(0,("Matchname failed on %s %s\n",name_buf,p));
 
1686
                        strlcpy(name_buf,"UNKNOWN",sizeof(name_buf));
 
1687
                }
 
1688
        }
 
1689
 
 
1690
        /* can't pass the same source and dest strings in when you
 
1691
           use --enable-developer or the clobber_region() call will
 
1692
           get you */
 
1693
 
 
1694
        strlcpy(tmp_name, name_buf, sizeof(tmp_name));
 
1695
        alpha_strcpy(name_buf, tmp_name, "_-.", sizeof(name_buf));
 
1696
        if (strstr(name_buf,"..")) {
 
1697
                strlcpy(name_buf, "UNKNOWN", sizeof(name_buf));
 
1698
        }
 
1699
 
 
1700
        nc.name = name_buf;
 
1701
        nc.ss = ss;
 
1702
 
 
1703
        store_nc(&nc);
 
1704
        lookup_nc(&nc);
 
1705
        return nc.name ? nc.name : "UNKNOWN";
 
1706
}
 
1707
 
 
1708
/*******************************************************************
 
1709
 Return the IP addr of the remote end of a socket as a string.
 
1710
 ******************************************************************/
 
1711
 
 
1712
const char *get_peer_addr(int fd, char *addr, size_t addr_len)
 
1713
{
 
1714
        return get_peer_addr_internal(fd, addr, addr_len, NULL, NULL);
 
1715
}
 
1716
 
 
1717
/*******************************************************************
 
1718
 Create protected unix domain socket.
 
1719
 
 
1720
 Some unixes cannot set permissions on a ux-dom-sock, so we
 
1721
 have to make sure that the directory contains the protection
 
1722
 permissions instead.
 
1723
 ******************************************************************/
 
1724
 
 
1725
int create_pipe_sock(const char *socket_dir,
 
1726
                     const char *socket_name,
 
1727
                     mode_t dir_perms)
 
1728
{
 
1729
#ifdef HAVE_UNIXSOCKET
 
1730
        struct sockaddr_un sunaddr;
 
1731
        struct stat st;
 
1732
        int sock;
 
1733
        mode_t old_umask;
 
1734
        char *path = NULL;
 
1735
 
 
1736
        old_umask = umask(0);
 
1737
 
 
1738
        /* Create the socket directory or reuse the existing one */
 
1739
 
 
1740
        if (lstat(socket_dir, &st) == -1) {
 
1741
                if (errno == ENOENT) {
 
1742
                        /* Create directory */
 
1743
                        if (mkdir(socket_dir, dir_perms) == -1) {
 
1744
                                DEBUG(0, ("error creating socket directory "
 
1745
                                        "%s: %s\n", socket_dir,
 
1746
                                        strerror(errno)));
 
1747
                                goto out_umask;
 
1748
                        }
 
1749
                } else {
 
1750
                        DEBUG(0, ("lstat failed on socket directory %s: %s\n",
 
1751
                                socket_dir, strerror(errno)));
 
1752
                        goto out_umask;
 
1753
                }
 
1754
        } else {
 
1755
                /* Check ownership and permission on existing directory */
 
1756
                if (!S_ISDIR(st.st_mode)) {
 
1757
                        DEBUG(0, ("socket directory %s isn't a directory\n",
 
1758
                                socket_dir));
 
1759
                        goto out_umask;
 
1760
                }
 
1761
                if ((st.st_uid != sec_initial_uid()) ||
 
1762
                                ((st.st_mode & 0777) != dir_perms)) {
 
1763
                        DEBUG(0, ("invalid permissions on socket directory "
 
1764
                                "%s\n", socket_dir));
 
1765
                        goto out_umask;
 
1766
                }
 
1767
        }
 
1768
 
 
1769
        /* Create the socket file */
 
1770
 
 
1771
        sock = socket(AF_UNIX, SOCK_STREAM, 0);
 
1772
 
 
1773
        if (sock == -1) {
 
1774
                DEBUG(0, ("create_pipe_sock: socket error %s\n",
 
1775
                        strerror(errno) ));
 
1776
                goto out_close;
 
1777
        }
 
1778
 
 
1779
        if (asprintf(&path, "%s/%s", socket_dir, socket_name) == -1) {
 
1780
                goto out_close;
 
1781
        }
 
1782
 
 
1783
        unlink(path);
 
1784
        memset(&sunaddr, 0, sizeof(sunaddr));
 
1785
        sunaddr.sun_family = AF_UNIX;
 
1786
        strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path));
 
1787
 
 
1788
        if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) {
 
1789
                DEBUG(0, ("bind failed on pipe socket %s: %s\n", path,
 
1790
                        strerror(errno)));
 
1791
                goto out_close;
 
1792
        }
 
1793
 
 
1794
        if (listen(sock, 5) == -1) {
 
1795
                DEBUG(0, ("listen failed on pipe socket %s: %s\n", path,
 
1796
                        strerror(errno)));
 
1797
                goto out_close;
 
1798
        }
 
1799
 
 
1800
        SAFE_FREE(path);
 
1801
 
 
1802
        umask(old_umask);
 
1803
        return sock;
 
1804
 
 
1805
out_close:
 
1806
        SAFE_FREE(path);
 
1807
        if (sock != -1)
 
1808
                close(sock);
 
1809
 
 
1810
out_umask:
 
1811
        umask(old_umask);
 
1812
        return -1;
 
1813
 
 
1814
#else
 
1815
        DEBUG(0, ("create_pipe_sock: No Unix sockets on this system\n"));
 
1816
        return -1;
 
1817
#endif /* HAVE_UNIXSOCKET */
 
1818
}
 
1819
 
 
1820
/****************************************************************************
 
1821
 Get my own canonical name, including domain.
 
1822
****************************************************************************/
 
1823
 
 
1824
const char *get_mydnsfullname(void)
 
1825
{
 
1826
        struct addrinfo *res = NULL;
 
1827
        char my_hostname[HOST_NAME_MAX];
 
1828
        bool ret;
 
1829
        DATA_BLOB tmp;
 
1830
 
 
1831
        if (memcache_lookup(NULL, SINGLETON_CACHE,
 
1832
                        data_blob_string_const_null("get_mydnsfullname"),
 
1833
                        &tmp)) {
 
1834
                SMB_ASSERT(tmp.length > 0);
 
1835
                return (const char *)tmp.data;
 
1836
        }
 
1837
 
 
1838
        /* get my host name */
 
1839
        if (gethostname(my_hostname, sizeof(my_hostname)) == -1) {
 
1840
                DEBUG(0,("get_mydnsfullname: gethostname failed\n"));
 
1841
                return NULL;
 
1842
        }
 
1843
 
 
1844
        /* Ensure null termination. */
 
1845
        my_hostname[sizeof(my_hostname)-1] = '\0';
 
1846
 
 
1847
        ret = interpret_string_addr_internal(&res,
 
1848
                                my_hostname,
 
1849
                                AI_ADDRCONFIG|AI_CANONNAME);
 
1850
 
 
1851
        if (!ret || res == NULL) {
 
1852
                DEBUG(3,("get_mydnsfullname: getaddrinfo failed for "
 
1853
                        "name %s [%s]\n",
 
1854
                        my_hostname,
 
1855
                        gai_strerror(ret) ));
 
1856
                return NULL;
 
1857
        }
 
1858
 
 
1859
        /*
 
1860
         * Make sure that getaddrinfo() returns the "correct" host name.
 
1861
         */
 
1862
 
 
1863
        if (res->ai_canonname == NULL) {
 
1864
                DEBUG(3,("get_mydnsfullname: failed to get "
 
1865
                        "canonical name for %s\n",
 
1866
                        my_hostname));
 
1867
                freeaddrinfo(res);
 
1868
                return NULL;
 
1869
        }
 
1870
 
 
1871
        /* This copies the data, so we must do a lookup
 
1872
         * afterwards to find the value to return.
 
1873
         */
 
1874
 
 
1875
        memcache_add(NULL, SINGLETON_CACHE,
 
1876
                        data_blob_string_const_null("get_mydnsfullname"),
 
1877
                        data_blob_string_const_null(res->ai_canonname));
 
1878
 
 
1879
        if (!memcache_lookup(NULL, SINGLETON_CACHE,
 
1880
                        data_blob_string_const_null("get_mydnsfullname"),
 
1881
                        &tmp)) {
 
1882
                tmp = data_blob_talloc(talloc_tos(), res->ai_canonname,
 
1883
                                strlen(res->ai_canonname) + 1);
 
1884
        }
 
1885
 
 
1886
        freeaddrinfo(res);
 
1887
 
 
1888
        return (const char *)tmp.data;
 
1889
}
 
1890
 
 
1891
/************************************************************
 
1892
 Is this my name ?
 
1893
************************************************************/
 
1894
 
 
1895
bool is_myname_or_ipaddr(const char *s)
 
1896
{
 
1897
        TALLOC_CTX *ctx = talloc_tos();
 
1898
        char addr[INET6_ADDRSTRLEN];
 
1899
        char *name = NULL;
 
1900
        const char *dnsname;
 
1901
        char *servername = NULL;
 
1902
 
 
1903
        if (!s) {
 
1904
                return false;
 
1905
        }
 
1906
 
 
1907
        /* Santize the string from '\\name' */
 
1908
        name = talloc_strdup(ctx, s);
 
1909
        if (!name) {
 
1910
                return false;
 
1911
        }
 
1912
 
 
1913
        servername = strrchr_m(name, '\\' );
 
1914
        if (!servername) {
 
1915
                servername = name;
 
1916
        } else {
 
1917
                servername++;
 
1918
        }
 
1919
 
 
1920
        /* Optimize for the common case */
 
1921
        if (strequal(servername, global_myname())) {
 
1922
                return true;
 
1923
        }
 
1924
 
 
1925
        /* Check for an alias */
 
1926
        if (is_myname(servername)) {
 
1927
                return true;
 
1928
        }
 
1929
 
 
1930
        /* Check for loopback */
 
1931
        if (strequal(servername, "127.0.0.1") ||
 
1932
                        strequal(servername, "::1")) {
 
1933
                return true;
 
1934
        }
 
1935
 
 
1936
        if (strequal(servername, "localhost")) {
 
1937
                return true;
 
1938
        }
 
1939
 
 
1940
        /* Maybe it's my dns name */
 
1941
        dnsname = get_mydnsfullname();
 
1942
        if (dnsname && strequal(servername, dnsname)) {
 
1943
                return true;
 
1944
        }
 
1945
 
 
1946
        /* Handle possible CNAME records - convert to an IP addr. */
 
1947
        if (!is_ipaddress(servername)) {
 
1948
                /* Use DNS to resolve the name, but only the first address */
 
1949
                struct sockaddr_storage ss;
 
1950
                if (interpret_string_addr(&ss, servername, 0)) {
 
1951
                        print_sockaddr(addr,
 
1952
                                        sizeof(addr),
 
1953
                                        &ss);
 
1954
                        servername = addr;
 
1955
                }
 
1956
        }
 
1957
 
 
1958
        /* Maybe its an IP address? */
 
1959
        if (is_ipaddress(servername)) {
 
1960
                struct sockaddr_storage ss;
 
1961
                struct iface_struct *nics;
 
1962
                int i, n;
 
1963
 
 
1964
                if (!interpret_string_addr(&ss, servername, AI_NUMERICHOST)) {
 
1965
                        return false;
 
1966
                }
 
1967
 
 
1968
                if (ismyaddr((struct sockaddr *)&ss)) {
 
1969
                        return true;
 
1970
                }
 
1971
 
 
1972
                if (is_zero_addr((struct sockaddr *)&ss) || 
 
1973
                        is_loopback_addr((struct sockaddr *)&ss)) {
 
1974
                        return false;
 
1975
                }
 
1976
 
 
1977
                n = get_interfaces(talloc_tos(), &nics);
 
1978
                for (i=0; i<n; i++) {
 
1979
                        if (sockaddr_equal((struct sockaddr *)&nics[i].ip, (struct sockaddr *)&ss)) {
 
1980
                                TALLOC_FREE(nics);
 
1981
                                return true;
 
1982
                        }
 
1983
                }
 
1984
                TALLOC_FREE(nics);
 
1985
        }
 
1986
 
 
1987
        /* No match */
 
1988
        return false;
 
1989
}