Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/libsmb/namequery.c

    r746 r988  
    2222#include "../lib/util/tevent_ntstatus.h"
    2323#include "libads/sitename_cache.h"
    24 #include "libads/dns.h"
     24#include "../lib/addns/dnsquery.h"
    2525#include "../libcli/netlogon/netlogon.h"
    2626#include "lib/async_req/async_sock.h"
     27#include "lib/tsocket/tsocket.h"
    2728#include "libsmb/nmblib.h"
     29#include "../libcli/nbt/libnbt.h"
     30#include "libads/kerberos_proto.h"
    2831
    2932/* nmbd.c sets this to True. */
     
    4447#define SAFJOIN_TTL     3600
    4548
    46 static char *saf_key(const char *domain)
    47 {
    48         char *keystr;
    49 
    50         asprintf_strupper_m(&keystr, SAFKEY_FMT, domain);
    51 
    52         return keystr;
    53 }
    54 
    55 static char *saf_join_key(const char *domain)
    56 {
    57         char *keystr;
    58 
    59         asprintf_strupper_m(&keystr, SAFJOINKEY_FMT, domain);
    60 
    61         return keystr;
     49static char *saf_key(TALLOC_CTX *mem_ctx, const char *domain)
     50{
     51        return talloc_asprintf_strupper_m(mem_ctx, SAFKEY_FMT, domain);
     52}
     53
     54static char *saf_join_key(TALLOC_CTX *mem_ctx, const char *domain)
     55{
     56        return talloc_asprintf_strupper_m(mem_ctx, SAFJOINKEY_FMT, domain);
    6257}
    6358
     
    8378        }
    8479
    85         key = saf_key( domain );
     80        key = saf_key(talloc_tos(), domain);
     81        if (key == NULL) {
     82                DEBUG(1, ("saf_key() failed\n"));
     83                return false;
     84        }
    8685        expire = time( NULL ) + lp_parm_int(-1, "saf","ttl", SAF_TTL);
    8786
     
    9190        ret = gencache_set( key, servername, expire );
    9291
    93         SAFE_FREE( key );
     92        TALLOC_FREE( key );
    9493
    9594        return ret;
     
    112111        }
    113112
    114         key = saf_join_key( domain );
     113        key = saf_join_key(talloc_tos(), domain);
     114        if (key == NULL) {
     115                DEBUG(1, ("saf_join_key() failed\n"));
     116                return false;
     117        }
    115118        expire = time( NULL ) + lp_parm_int(-1, "saf","join ttl", SAFJOIN_TTL);
    116119
     
    120123        ret = gencache_set( key, servername, expire );
    121124
    122         SAFE_FREE( key );
     125        TALLOC_FREE( key );
    123126
    124127        return ret;
     
    135138        }
    136139
    137         key = saf_join_key(domain);
     140        key = saf_join_key(talloc_tos(), domain);
     141        if (key == NULL) {
     142                DEBUG(1, ("saf_join_key() failed\n"));
     143                return false;
     144        }
    138145        ret = gencache_del(key);
    139         SAFE_FREE(key);
     146        TALLOC_FREE(key);
    140147
    141148        if (ret) {
     
    143150        }
    144151
    145         key = saf_key(domain);
     152        key = saf_key(talloc_tos(), domain);
     153        if (key == NULL) {
     154                DEBUG(1, ("saf_key() failed\n"));
     155                return false;
     156        }
    146157        ret = gencache_del(key);
    147         SAFE_FREE(key);
     158        TALLOC_FREE(key);
    148159
    149160        if (ret) {
     
    157168****************************************************************************/
    158169
    159 char *saf_fetch( const char *domain )
     170char *saf_fetch(TALLOC_CTX *mem_ctx, const char *domain )
    160171{
    161172        char *server = NULL;
     
    169180        }
    170181
    171         key = saf_join_key( domain );
    172 
    173         ret = gencache_get( key, &server, &timeout );
    174 
    175         SAFE_FREE( key );
     182        key = saf_join_key(talloc_tos(), domain);
     183        if (key == NULL) {
     184                DEBUG(1, ("saf_join_key() failed\n"));
     185                return NULL;
     186        }
     187
     188        ret = gencache_get( key, mem_ctx, &server, &timeout );
     189
     190        TALLOC_FREE( key );
    176191
    177192        if ( ret ) {
     
    181196        }
    182197
    183         key = saf_key( domain );
    184 
    185         ret = gencache_get( key, &server, &timeout );
    186 
    187         SAFE_FREE( key );
     198        key = saf_key(talloc_tos(), domain);
     199        if (key == NULL) {
     200                DEBUG(1, ("saf_key() failed\n"));
     201                return NULL;
     202        }
     203
     204        ret = gencache_get( key, mem_ctx, &server, &timeout );
     205
     206        TALLOC_FREE( key );
    188207
    189208        if ( !ret ) {
     
    198217}
    199218
     219static void set_socket_addr_v4(struct sockaddr_storage *addr)
     220{
     221        if (!interpret_string_addr(addr, lp_nbt_client_socket_address(),
     222                                   AI_NUMERICHOST|AI_PASSIVE)) {
     223                zero_sockaddr(addr);
     224        }
     225        if (addr->ss_family != AF_INET) {
     226                zero_sockaddr(addr);
     227        }
     228}
     229
     230static struct in_addr my_socket_addr_v4(void)
     231{
     232        struct sockaddr_storage my_addr;
     233        struct sockaddr_in *in_addr = (struct sockaddr_in *)((char *)&my_addr);
     234
     235        set_socket_addr_v4(&my_addr);
     236        return in_addr->sin_addr;
     237}
     238
    200239/****************************************************************************
    201240 Generate a random trn_id.
     
    204243static int generate_trn_id(void)
    205244{
    206         uint16 id;
    207 
    208         generate_random_buffer((uint8 *)&id, sizeof(id));
     245        uint16_t id;
     246
     247        generate_random_buffer((uint8_t *)&id, sizeof(id));
    209248
    210249        return id % (unsigned)0x7FFF;
     
    227266                return NULL;
    228267
    229         ret = TALLOC_ARRAY(mem_ctx, struct node_status,*num_names);
     268        ret = talloc_array(mem_ctx, struct node_status,*num_names);
    230269        if (!ret)
    231270                return NULL;
     
    258297        struct tevent_req *reader_req;
    259298
    260         int sock;
     299        struct tdgram_context *sock;
    261300        struct tevent_req *socket_req;
    262         uint8_t buf[1024];
    263         struct sockaddr_storage addr;
    264         socklen_t addr_len;
     301        uint8_t *buf;
     302        struct tsocket_address *addr;
    265303
    266304        bool (*validator)(struct packet_struct *p,
     
    278316        TALLOC_CTX *mem_ctx,
    279317        struct tevent_context *ev,
    280         int sock, /* dgram socket */
     318        struct tdgram_context *sock,
    281319        struct nb_packet_reader *reader,
    282320        enum packet_type type,
     
    311349        }
    312350
    313         state->addr_len = sizeof(state->addr);
    314         state->socket_req = recvfrom_send(state, ev, sock,
    315                                           state->buf, sizeof(state->buf), 0,
    316                                           &state->addr, &state->addr_len);
     351        state->socket_req = tdgram_recvfrom_send(state, ev, state->sock);
    317352        if (tevent_req_nomem(state->socket_req, req)) {
    318353                return tevent_req_post(req, ev);
     
    386421        struct sock_packet_read_state *state = tevent_req_data(
    387422                req, struct sock_packet_read_state);
    388         struct sockaddr_in *in_addr;
     423        union {
     424                struct sockaddr sa;
     425                struct sockaddr_in sin;
     426        } addr;
     427        ssize_t ret;
    389428        ssize_t received;
    390429        int err;
    391 
    392         received = recvfrom_recv(subreq, &err);
     430        bool ok;
     431
     432        received = tdgram_recvfrom_recv(subreq, &err, state,
     433                                        &state->buf, &state->addr);
    393434
    394435        TALLOC_FREE(state->socket_req);
     
    407448                return;
    408449        }
    409         if (state->addr.ss_family != AF_INET) {
     450        ok = tsocket_address_is_inet(state->addr, "ipv4");
     451        if (!ok) {
    410452                goto retry;
    411453        }
    412         in_addr = (struct sockaddr_in *)(void *)&state->addr;
     454        ret = tsocket_address_bsd_sockaddr(state->addr,
     455                                           &addr.sa,
     456                                           sizeof(addr.sin));
     457        if (ret == -1) {
     458                tevent_req_nterror(req, map_nt_error_from_unix(errno));
     459                return;
     460        }
    413461
    414462        state->packet = parse_packet((char *)state->buf, received, state->type,
    415                                      in_addr->sin_addr, in_addr->sin_port);
     463                                     addr.sin.sin_addr, addr.sin.sin_port);
    416464        if (state->packet == NULL) {
    417465                DEBUG(10, ("parse_packet failed\n"));
     
    439487                state->packet = NULL;
    440488        }
    441         state->socket_req = recvfrom_send(state, state->ev, state->sock,
    442                                           state->buf, sizeof(state->buf), 0,
    443                                           &state->addr, &state->addr_len);
     489        TALLOC_FREE(state->buf);
     490        TALLOC_FREE(state->addr);
     491
     492        state->socket_req = tdgram_recvfrom_send(state, state->ev, state->sock);
    444493        if (tevent_req_nomem(state->socket_req, req)) {
    445494                return;
     
    466515struct nb_trans_state {
    467516        struct tevent_context *ev;
    468         int sock;
     517        struct tdgram_context *sock;
    469518        struct nb_packet_reader *reader;
    470519
    471         const struct sockaddr_storage *dst_addr;
     520        struct tsocket_address *src_addr;
     521        struct tsocket_address *dst_addr;
    472522        uint8_t *buf;
    473523        size_t buflen;
     
    491541        TALLOC_CTX *mem_ctx,
    492542        struct tevent_context *ev,
    493         const struct sockaddr_storage *my_addr,
    494         const struct sockaddr_storage *dst_addr,
     543        const struct sockaddr_storage *_my_addr,
     544        const struct sockaddr_storage *_dst_addr,
    495545        bool bcast,
    496546        uint8_t *buf, size_t buflen,
     
    500550        void *private_data)
    501551{
     552        const struct sockaddr *my_addr =
     553                discard_const_p(const struct sockaddr, _my_addr);
     554        size_t my_addr_len = sizeof(*_my_addr);
     555        const struct sockaddr *dst_addr =
     556                discard_const_p(const struct sockaddr, _dst_addr);
     557        size_t dst_addr_len = sizeof(*_dst_addr);
    502558        struct tevent_req *req, *subreq;
    503559        struct nb_trans_state *state;
     560        int ret;
    504561
    505562        req = tevent_req_create(mem_ctx, &state, struct nb_trans_state);
     
    509566        talloc_set_destructor(state, nb_trans_state_destructor);
    510567        state->ev = ev;
    511         state->dst_addr = dst_addr;
    512568        state->buf = buf;
    513569        state->buflen = buflen;
     
    517573        state->private_data = private_data;
    518574
    519         state->sock = open_socket_in(SOCK_DGRAM, 0, 3, my_addr, True);
    520         if (state->sock == -1) {
     575        ret = tsocket_address_bsd_from_sockaddr(state,
     576                                                my_addr, my_addr_len,
     577                                                &state->src_addr);
     578        if (ret == -1) {
    521579                tevent_req_nterror(req, map_nt_error_from_unix(errno));
    522                 DEBUG(10, ("open_socket_in failed: %s\n", strerror(errno)));
    523580                return tevent_req_post(req, ev);
    524581        }
    525582
    526         if (bcast) {
    527                 set_socket_options(state->sock,"SO_BROADCAST");
     583        ret = tsocket_address_bsd_from_sockaddr(state,
     584                                                dst_addr, dst_addr_len,
     585                                                &state->dst_addr);
     586        if (ret == -1) {
     587                tevent_req_nterror(req, map_nt_error_from_unix(errno));
     588                return tevent_req_post(req, ev);
     589        }
     590
     591        ret = tdgram_inet_udp_broadcast_socket(state->src_addr, state,
     592                                               &state->sock);
     593        if (ret == -1) {
     594                tevent_req_nterror(req, map_nt_error_from_unix(errno));
     595                return tevent_req_post(req, ev);
    528596        }
    529597
     
    538606static int nb_trans_state_destructor(struct nb_trans_state *s)
    539607{
    540         if (s->sock != -1) {
    541                 close(s->sock);
    542                 s->sock = -1;
    543         }
    544608        if (s->packet != NULL) {
    545609                free_packet(s->packet);
     
    574638        tevent_req_set_callback(subreq, nb_trans_done, req);
    575639
    576         subreq = sendto_send(state, state->ev, state->sock,
    577                              state->buf, state->buflen, 0, state->dst_addr);
     640        subreq = tdgram_sendto_send(state, state->ev,
     641                                    state->sock,
     642                                    state->buf, state->buflen,
     643                                    state->dst_addr);
    578644        if (tevent_req_nomem(subreq, req)) {
    579645                return;
     
    591657        int err;
    592658
    593         sent = sendto_recv(subreq, &err);
     659        sent = tdgram_sendto_recv(subreq, &err);
    594660        TALLOC_FREE(subreq);
    595661        if (sent == -1) {
     
    620686                return;
    621687        }
    622         subreq = sendto_send(state, state->ev, state->sock,
    623                              state->buf, state->buflen, 0, state->dst_addr);
     688        subreq = tdgram_sendto_send(state, state->ev,
     689                                    state->sock,
     690                                    state->buf, state->buflen,
     691                                    state->dst_addr);
    624692        if (tevent_req_nomem(subreq, req)) {
    625693                return;
     
    706774        in_addr->sin_port = htons(NMB_PORT);
    707775
    708         if (!interpret_string_addr(&state->my_addr, lp_socket_address(),
    709                                    AI_NUMERICHOST|AI_PASSIVE)) {
    710                 zero_sockaddr(&state->my_addr);
    711         }
     776        set_socket_addr_v4(&state->my_addr);
    712777
    713778        ZERO_STRUCT(p);
     
    834899        NTSTATUS status = NT_STATUS_NO_MEMORY;
    835900
    836         ev = tevent_context_init(frame);
     901        ev = samba_tevent_context_init(frame);
    837902        if (ev == NULL) {
    838903                goto fail;
     
    893958        }
    894959
    895         if (!interpret_string_addr(&ss, lp_socket_address(),
    896                                 AI_NUMERICHOST|AI_PASSIVE)) {
    897                 zero_sockaddr(&ss);
    898         }
     960        set_socket_addr_v4(&ss);
    899961
    900962        /* W2K PDC's seem not to respond to '*'#0. JRA */
     
    9641026        for (i=0;i<num_interfaces;i++) {
    9651027                const struct sockaddr_storage *pss = iface_n_bcast(i);
    966                 unsigned char *p_ss1 = NULL;
    967                 unsigned char *p_ss2 = NULL;
    968                 unsigned char *p_if = NULL;
     1028                const unsigned char *p_ss1 = NULL;
     1029                const unsigned char *p_ss2 = NULL;
     1030                const unsigned char *p_if = NULL;
    9691031                size_t len = 0;
    9701032                int bits1, bits2;
     
    9751037                }
    9761038                if (pss->ss_family == AF_INET) {
    977                         p_if = (unsigned char *)
     1039                        p_if = (const unsigned char *)
    9781040                                &((const struct sockaddr_in *)pss)->sin_addr;
    979                         p_ss1 = (unsigned char *)
     1041                        p_ss1 = (const unsigned char *)
    9801042                                &((const struct sockaddr_in *)ss1)->sin_addr;
    981                         p_ss2 = (unsigned char *)
     1043                        p_ss2 = (const unsigned char *)
    9821044                                &((const struct sockaddr_in *)ss2)->sin_addr;
    9831045                        len = 4;
     
    9851047#if defined(HAVE_IPV6)
    9861048                if (pss->ss_family == AF_INET6) {
    987                         p_if = (unsigned char *)
     1049                        p_if = (const unsigned char *)
    9881050                                &((const struct sockaddr_in6 *)pss)->sin6_addr;
    989                         p_ss1 = (unsigned char *)
     1051                        p_ss1 = (const unsigned char *)
    9901052                                &((const struct sockaddr_in6 *)ss1)->sin6_addr;
    991                         p_ss2 = (unsigned char *)
     1053                        p_ss2 = (const unsigned char *)
    9921054                                &((const struct sockaddr_in6 *)ss2)->sin6_addr;
    9931055                        len = 16;
     
    10041066
    10051067        /* Bias towards directly reachable IPs */
    1006         if (iface_local((struct sockaddr *)ss1)) {
     1068        if (iface_local((const struct sockaddr *)ss1)) {
    10071069                if (ss1->ss_family == AF_INET) {
    10081070                        max_bits1 += 32;
     
    10111073                }
    10121074        }
    1013         if (iface_local((struct sockaddr *)ss2)) {
     1075        if (iface_local((const struct sockaddr *)ss2)) {
    10141076                if (ss2->ss_family == AF_INET) {
    10151077                        max_bits2 += 32;
     
    10251087*******************************************************************/
    10261088
    1027 int ip_service_compare(struct ip_service *ss1, struct ip_service *ss2)
     1089static int ip_service_compare(struct ip_service *ss1, struct ip_service *ss2)
    10281090{
    10291091        int result;
     
    10721134 *********************************************************************/
    10731135
    1074 static int remove_duplicate_addrs2(struct ip_service *iplist, int count )
     1136int remove_duplicate_addrs2(struct ip_service *iplist, int count )
    10751137{
    10761138        int i, j;
     
    10861148
    10871149                for ( j=i+1; j<count; j++ ) {
    1088                         if (sockaddr_equal((struct sockaddr *)&iplist[i].ss, (struct sockaddr *)&iplist[j].ss) &&
     1150                        if (sockaddr_equal((struct sockaddr *)(void *)&iplist[i].ss,
     1151                                           (struct sockaddr *)(void *)&iplist[j].ss) &&
    10891152                                        iplist[i].port == iplist[j].port) {
    10901153                                zero_sockaddr(&iplist[j].ss);
     
    11121175{
    11131176        TALLOC_CTX *frame = talloc_stackframe();
    1114         struct ip_service *iplist_new = TALLOC_ARRAY(frame, struct ip_service, count);
     1177        struct ip_service *iplist_new = talloc_array(frame, struct ip_service, count);
    11151178        int i, j;
    11161179
     
    12021265        in_addr->sin_port = htons(NMB_PORT);
    12031266
    1204         if (!interpret_string_addr(&state->my_addr, lp_socket_address(),
    1205                                    AI_NUMERICHOST|AI_PASSIVE)) {
    1206                 zero_sockaddr(&state->my_addr);
    1207         }
     1267        set_socket_addr_v4(&state->my_addr);
    12081268
    12091269        ZERO_STRUCT(p);
     
    13151375        }
    13161376
    1317         tmp_addrs = TALLOC_REALLOC_ARRAY(
     1377        tmp_addrs = talloc_realloc(
    13181378                state, state->addrs, struct sockaddr_storage,
    13191379                state->num_addrs + nmb->answers->rdlength/6);
     
    13451405                for (j=0; j<state->num_addrs; j++) {
    13461406                        if (sockaddr_equal(
    1347                                     (struct sockaddr *)&addr,
    1348                                     (struct sockaddr *)&state->addrs[j])) {
     1407                                    (struct sockaddr *)(void *)&addr,
     1408                                    (struct sockaddr *)(void *)&state->addrs[j])) {
    13491409                                break;
    13501410                        }
     
    14251485        NTSTATUS status;
    14261486
    1427         if (tevent_req_is_nterror(req, &status)
    1428             && !NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
    1429                 return status;
     1487        if (tevent_req_is_nterror(req, &status)) {
     1488                if (state->bcast &&
     1489                    NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
     1490                        /*
     1491                         * In the broadcast case we collect replies until the
     1492                         * timeout.
     1493                         */
     1494                        status = NT_STATUS_OK;
     1495                }
     1496                if (!NT_STATUS_IS_OK(status)) {
     1497                        return status;
     1498                }
    14301499        }
    14311500        if (state->num_addrs == 0) {
     
    14541523        NTSTATUS status = NT_STATUS_NO_MEMORY;
    14551524
    1456         ev = tevent_context_init(frame);
     1525        ev = samba_tevent_context_init(frame);
    14571526        if (ev == NULL) {
    14581527                goto fail;
     
    15241593                (*return_iplist)[real_count].port = PORT_NONE;
    15251594                real_count++;
    1526         }
     1595        }
    15271596
    15281597        *pcount = real_count;
    15291598        return true;
     1599}
     1600
     1601struct name_queries_state {
     1602        struct tevent_context *ev;
     1603        const char *name;
     1604        int name_type;
     1605        bool bcast;
     1606        bool recurse;
     1607        const struct sockaddr_storage *addrs;
     1608        int num_addrs;
     1609        int wait_msec;
     1610        int timeout_msec;
     1611
     1612        struct tevent_req **subreqs;
     1613        int num_received;
     1614        int num_sent;
     1615
     1616        int received_index;
     1617        struct sockaddr_storage *result_addrs;
     1618        int num_result_addrs;
     1619        uint8_t flags;
     1620};
     1621
     1622static void name_queries_done(struct tevent_req *subreq);
     1623static void name_queries_next(struct tevent_req *subreq);
     1624
     1625/*
     1626 * Send a name query to multiple destinations with a wait time in between
     1627 */
     1628
     1629static struct tevent_req *name_queries_send(
     1630        TALLOC_CTX *mem_ctx, struct tevent_context *ev,
     1631        const char *name, int name_type,
     1632        bool bcast, bool recurse,
     1633        const struct sockaddr_storage *addrs,
     1634        int num_addrs, int wait_msec, int timeout_msec)
     1635{
     1636        struct tevent_req *req, *subreq;
     1637        struct name_queries_state *state;
     1638
     1639        req = tevent_req_create(mem_ctx, &state,
     1640                                struct name_queries_state);
     1641        if (req == NULL) {
     1642                return NULL;
     1643        }
     1644        state->ev = ev;
     1645        state->name = name;
     1646        state->name_type = name_type;
     1647        state->bcast = bcast;
     1648        state->recurse = recurse;
     1649        state->addrs = addrs;
     1650        state->num_addrs = num_addrs;
     1651        state->wait_msec = wait_msec;
     1652        state->timeout_msec = timeout_msec;
     1653
     1654        state->subreqs = talloc_zero_array(
     1655                state, struct tevent_req *, num_addrs);
     1656        if (tevent_req_nomem(state->subreqs, req)) {
     1657                return tevent_req_post(req, ev);
     1658        }
     1659        state->num_sent = 0;
     1660
     1661        subreq = name_query_send(
     1662                state->subreqs, state->ev, name, name_type, bcast, recurse,
     1663                &state->addrs[state->num_sent]);
     1664        if (tevent_req_nomem(subreq, req)) {
     1665                return tevent_req_post(req, ev);
     1666        }
     1667        if (!tevent_req_set_endtime(
     1668                    subreq, state->ev,
     1669                    timeval_current_ofs(0, state->timeout_msec * 1000))) {
     1670                tevent_req_oom(req);
     1671                return tevent_req_post(req, ev);
     1672        }
     1673        tevent_req_set_callback(subreq, name_queries_done, req);
     1674
     1675        state->subreqs[state->num_sent] = subreq;
     1676        state->num_sent += 1;
     1677
     1678        if (state->num_sent < state->num_addrs) {
     1679                subreq = tevent_wakeup_send(
     1680                        state, state->ev,
     1681                        timeval_current_ofs(0, state->wait_msec * 1000));
     1682                if (tevent_req_nomem(subreq, req)) {
     1683                        return tevent_req_post(req, ev);
     1684                }
     1685                tevent_req_set_callback(subreq, name_queries_next, req);
     1686        }
     1687        return req;
     1688}
     1689
     1690static void name_queries_done(struct tevent_req *subreq)
     1691{
     1692        struct tevent_req *req = tevent_req_callback_data(
     1693                subreq, struct tevent_req);
     1694        struct name_queries_state *state = tevent_req_data(
     1695                req, struct name_queries_state);
     1696        int i;
     1697        NTSTATUS status;
     1698
     1699        status = name_query_recv(subreq, state, &state->result_addrs,
     1700                                 &state->num_result_addrs, &state->flags);
     1701
     1702        for (i=0; i<state->num_sent; i++) {
     1703                if (state->subreqs[i] == subreq) {
     1704                        break;
     1705                }
     1706        }
     1707        if (i == state->num_sent) {
     1708                tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
     1709                return;
     1710        }
     1711        TALLOC_FREE(state->subreqs[i]);
     1712
     1713        state->num_received += 1;
     1714
     1715        if (!NT_STATUS_IS_OK(status)) {
     1716
     1717                if (state->num_received >= state->num_addrs) {
     1718                        tevent_req_nterror(req, status);
     1719                        return;
     1720                }
     1721                /*
     1722                 * Still outstanding requests, just wait
     1723                 */
     1724                return;
     1725        }
     1726        state->received_index = i;
     1727        tevent_req_done(req);
     1728}
     1729
     1730static void name_queries_next(struct tevent_req *subreq)
     1731{
     1732        struct tevent_req *req = tevent_req_callback_data(
     1733                subreq, struct tevent_req);
     1734        struct name_queries_state *state = tevent_req_data(
     1735                req, struct name_queries_state);
     1736
     1737        if (!tevent_wakeup_recv(subreq)) {
     1738                tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
     1739                return;
     1740        }
     1741
     1742        subreq = name_query_send(
     1743                state->subreqs, state->ev,
     1744                state->name, state->name_type, state->bcast, state->recurse,
     1745                &state->addrs[state->num_sent]);
     1746        if (tevent_req_nomem(subreq, req)) {
     1747                return;
     1748        }
     1749        tevent_req_set_callback(subreq, name_queries_done, req);
     1750        if (!tevent_req_set_endtime(
     1751                    subreq, state->ev,
     1752                    timeval_current_ofs(0, state->timeout_msec * 1000))) {
     1753                tevent_req_oom(req);
     1754                return;
     1755        }
     1756        state->subreqs[state->num_sent] = subreq;
     1757        state->num_sent += 1;
     1758
     1759        if (state->num_sent < state->num_addrs) {
     1760                subreq = tevent_wakeup_send(
     1761                        state, state->ev,
     1762                        timeval_current_ofs(0, state->wait_msec * 1000));
     1763                if (tevent_req_nomem(subreq, req)) {
     1764                        return;
     1765                }
     1766                tevent_req_set_callback(subreq, name_queries_next, req);
     1767        }
     1768}
     1769
     1770static NTSTATUS name_queries_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
     1771                                  struct sockaddr_storage **result_addrs,
     1772                                  int *num_result_addrs, uint8_t *flags,
     1773                                  int *received_index)
     1774{
     1775        struct name_queries_state *state = tevent_req_data(
     1776                req, struct name_queries_state);
     1777        NTSTATUS status;
     1778
     1779        if (tevent_req_is_nterror(req, &status)) {
     1780                return status;
     1781        }
     1782
     1783        if (result_addrs != NULL) {
     1784                *result_addrs = talloc_move(mem_ctx, &state->result_addrs);
     1785        }
     1786        if (num_result_addrs != NULL) {
     1787                *num_result_addrs = state->num_result_addrs;
     1788        }
     1789        if (flags != NULL) {
     1790                *flags = state->flags;
     1791        }
     1792        if (received_index != NULL) {
     1793                *received_index = state->received_index;
     1794        }
     1795        return NT_STATUS_OK;
    15301796}
    15311797
     
    15331799 Resolve via "bcast" method.
    15341800*********************************************************/
     1801
     1802struct name_resolve_bcast_state {
     1803        struct sockaddr_storage *addrs;
     1804        int num_addrs;
     1805};
     1806
     1807static void name_resolve_bcast_done(struct tevent_req *subreq);
     1808
     1809struct tevent_req *name_resolve_bcast_send(TALLOC_CTX *mem_ctx,
     1810                                           struct tevent_context *ev,
     1811                                           const char *name,
     1812                                           int name_type)
     1813{
     1814        struct tevent_req *req, *subreq;
     1815        struct name_resolve_bcast_state *state;
     1816        struct sockaddr_storage *bcast_addrs;
     1817        int i, num_addrs, num_bcast_addrs;
     1818
     1819        req = tevent_req_create(mem_ctx, &state,
     1820                                struct name_resolve_bcast_state);
     1821        if (req == NULL) {
     1822                return NULL;
     1823        }
     1824
     1825        if (lp_disable_netbios()) {
     1826                DEBUG(5, ("name_resolve_bcast(%s#%02x): netbios is disabled\n",
     1827                          name, name_type));
     1828                tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
     1829                return tevent_req_post(req, ev);
     1830        }
     1831
     1832        /*
     1833         * "bcast" means do a broadcast lookup on all the local interfaces.
     1834         */
     1835
     1836        DEBUG(3, ("name_resolve_bcast: Attempting broadcast lookup "
     1837                  "for name %s<0x%x>\n", name, name_type));
     1838
     1839        num_addrs = iface_count();
     1840        bcast_addrs = talloc_array(state, struct sockaddr_storage, num_addrs);
     1841        if (tevent_req_nomem(bcast_addrs, req)) {
     1842                return tevent_req_post(req, ev);
     1843        }
     1844
     1845        /*
     1846         * Lookup the name on all the interfaces, return on
     1847         * the first successful match.
     1848         */
     1849        num_bcast_addrs = 0;
     1850
     1851        for (i=0; i<num_addrs; i++) {
     1852                const struct sockaddr_storage *pss = iface_n_bcast(i);
     1853
     1854                if (pss->ss_family != AF_INET) {
     1855                        continue;
     1856                }
     1857                bcast_addrs[num_bcast_addrs] = *pss;
     1858                num_bcast_addrs += 1;
     1859        }
     1860
     1861        subreq = name_queries_send(state, ev, name, name_type, true, true,
     1862                                   bcast_addrs, num_bcast_addrs, 0, 1000);
     1863        if (tevent_req_nomem(subreq, req)) {
     1864                return tevent_req_post(req, ev);
     1865        }
     1866        tevent_req_set_callback(subreq, name_resolve_bcast_done, req);
     1867        return req;
     1868}
     1869
     1870static void name_resolve_bcast_done(struct tevent_req *subreq)
     1871{
     1872        struct tevent_req *req = tevent_req_callback_data(
     1873                subreq, struct tevent_req);
     1874        struct name_resolve_bcast_state *state = tevent_req_data(
     1875                req, struct name_resolve_bcast_state);
     1876        NTSTATUS status;
     1877
     1878        status = name_queries_recv(subreq, state,
     1879                                   &state->addrs, &state->num_addrs,
     1880                                   NULL, NULL);
     1881        TALLOC_FREE(subreq);
     1882        if (tevent_req_nterror(req, status)) {
     1883                return;
     1884        }
     1885        tevent_req_done(req);
     1886}
     1887
     1888NTSTATUS name_resolve_bcast_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
     1889                                 struct sockaddr_storage **addrs,
     1890                                 int *num_addrs)
     1891{
     1892        struct name_resolve_bcast_state *state = tevent_req_data(
     1893                req, struct name_resolve_bcast_state);
     1894        NTSTATUS status;
     1895
     1896        if (tevent_req_is_nterror(req, &status)) {
     1897                return status;
     1898        }
     1899        *addrs = talloc_move(mem_ctx, &state->addrs);
     1900        *num_addrs = state->num_addrs;
     1901        return NT_STATUS_OK;
     1902}
    15351903
    15361904NTSTATUS name_resolve_bcast(const char *name,
     
    15401908                        int *return_count)
    15411909{
    1542         int i;
    1543         int num_interfaces = iface_count();
    1544         struct sockaddr_storage *ss_list;
    1545         NTSTATUS status = NT_STATUS_NOT_FOUND;
    1546 
    1547         if (lp_disable_netbios()) {
    1548                 DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n",
    1549                                         name, name_type));
    1550                 return NT_STATUS_INVALID_PARAMETER;
    1551         }
    1552 
    1553         *return_iplist = NULL;
    1554         *return_count = 0;
    1555 
    1556         /*
    1557          * "bcast" means do a broadcast lookup on all the local interfaces.
    1558          */
    1559 
    1560         DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup "
    1561                 "for name %s<0x%x>\n", name, name_type));
    1562 
    1563         /*
    1564          * Lookup the name on all the interfaces, return on
    1565          * the first successful match.
    1566          */
    1567         for( i = num_interfaces-1; i >= 0; i--) {
    1568                 const struct sockaddr_storage *pss = iface_n_bcast(i);
    1569 
    1570                 /* Done this way to fix compiler error on IRIX 5.x */
    1571                 if (!pss) {
    1572                         continue;
    1573                 }
    1574                 status = name_query(name, name_type, true, true, pss,
    1575                                     talloc_tos(), &ss_list, return_count,
    1576                                     NULL);
    1577                 if (NT_STATUS_IS_OK(status)) {
    1578                         goto success;
    1579                 }
    1580         }
    1581 
    1582         /* failed - no response */
    1583 
     1910        TALLOC_CTX *frame = talloc_stackframe();
     1911        struct tevent_context *ev;
     1912        struct tevent_req *req;
     1913        NTSTATUS status = NT_STATUS_NO_MEMORY;
     1914
     1915        ev = samba_tevent_context_init(frame);
     1916        if (ev == NULL) {
     1917                goto fail;
     1918        }
     1919        req = name_resolve_bcast_send(frame, ev, name, name_type);
     1920        if (req == NULL) {
     1921                goto fail;
     1922        }
     1923        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
     1924                goto fail;
     1925        }
     1926        status = name_resolve_bcast_recv(req, mem_ctx, return_iplist,
     1927                                         return_count);
     1928 fail:
     1929        TALLOC_FREE(frame);
    15841930        return status;
    1585 
    1586 success:
    1587         *return_iplist = ss_list;
    1588         return status;
    1589 }
    1590 
    1591 /********************************************************
    1592  Resolve via "wins" method.
    1593 *********************************************************/
    1594 
    1595 NTSTATUS resolve_wins(const char *name,
    1596                 int name_type,
    1597                 struct ip_service **return_iplist,
    1598                 int *return_count)
    1599 {
    1600         int t, i;
    1601         char **wins_tags;
    1602         struct sockaddr_storage src_ss, *ss_list = NULL;
     1931}
     1932
     1933struct query_wins_list_state {
     1934        struct tevent_context *ev;
     1935        const char *name;
     1936        uint8_t name_type;
     1937        struct in_addr *servers;
     1938        uint32_t num_servers;
     1939        struct sockaddr_storage server;
     1940        uint32_t num_sent;
     1941
     1942        struct sockaddr_storage *addrs;
     1943        int num_addrs;
     1944        uint8_t flags;
     1945};
     1946
     1947static void query_wins_list_done(struct tevent_req *subreq);
     1948
     1949/*
     1950 * Query a list of (replicating) wins servers in sequence, call them
     1951 * dead if they don't reply
     1952 */
     1953
     1954static struct tevent_req *query_wins_list_send(
     1955        TALLOC_CTX *mem_ctx, struct tevent_context *ev,
     1956        struct in_addr src_ip, const char *name, uint8_t name_type,
     1957        struct in_addr *servers, int num_servers)
     1958{
     1959        struct tevent_req *req, *subreq;
     1960        struct query_wins_list_state *state;
     1961
     1962        req = tevent_req_create(mem_ctx, &state,
     1963                                struct query_wins_list_state);
     1964        if (req == NULL) {
     1965                return NULL;
     1966        }
     1967        state->ev = ev;
     1968        state->name = name;
     1969        state->name_type = name_type;
     1970        state->servers = servers;
     1971        state->num_servers = num_servers;
     1972
     1973        if (state->num_servers == 0) {
     1974                tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
     1975                return tevent_req_post(req, ev);
     1976        }
     1977
     1978        in_addr_to_sockaddr_storage(
     1979                &state->server, state->servers[state->num_sent]);
     1980
     1981        subreq = name_query_send(state, state->ev,
     1982                                 state->name, state->name_type,
     1983                                 false, true, &state->server);
     1984        state->num_sent += 1;
     1985        if (tevent_req_nomem(subreq, req)) {
     1986                return tevent_req_post(req, ev);
     1987        }
     1988        if (!tevent_req_set_endtime(subreq, state->ev,
     1989                                    timeval_current_ofs(2, 0))) {
     1990                tevent_req_oom(req);
     1991                return tevent_req_post(req, ev);
     1992        }
     1993        tevent_req_set_callback(subreq, query_wins_list_done, req);
     1994        return req;
     1995}
     1996
     1997static void query_wins_list_done(struct tevent_req *subreq)
     1998{
     1999        struct tevent_req *req = tevent_req_callback_data(
     2000                subreq, struct tevent_req);
     2001        struct query_wins_list_state *state = tevent_req_data(
     2002                req, struct query_wins_list_state);
     2003        NTSTATUS status;
     2004
     2005        status = name_query_recv(subreq, state,
     2006                                 &state->addrs, &state->num_addrs,
     2007                                 &state->flags);
     2008        TALLOC_FREE(subreq);
     2009        if (NT_STATUS_IS_OK(status)) {
     2010                tevent_req_done(req);
     2011                return;
     2012        }
     2013        if (!NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
     2014                tevent_req_nterror(req, status);
     2015                return;
     2016        }
     2017        wins_srv_died(state->servers[state->num_sent-1],
     2018                      my_socket_addr_v4());
     2019
     2020        if (state->num_sent == state->num_servers) {
     2021                tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
     2022                return;
     2023        }
     2024
     2025        in_addr_to_sockaddr_storage(
     2026                &state->server, state->servers[state->num_sent]);
     2027
     2028        subreq = name_query_send(state, state->ev,
     2029                                 state->name, state->name_type,
     2030                                 false, true, &state->server);
     2031        state->num_sent += 1;
     2032        if (tevent_req_nomem(subreq, req)) {
     2033                return;
     2034        }
     2035        if (!tevent_req_set_endtime(subreq, state->ev,
     2036                                    timeval_current_ofs(2, 0))) {
     2037                tevent_req_oom(req);
     2038                return;
     2039        }
     2040        tevent_req_set_callback(subreq, query_wins_list_done, req);
     2041}
     2042
     2043static NTSTATUS query_wins_list_recv(struct tevent_req *req,
     2044                                     TALLOC_CTX *mem_ctx,
     2045                                     struct sockaddr_storage **addrs,
     2046                                     int *num_addrs,
     2047                                     uint8_t *flags)
     2048{
     2049        struct query_wins_list_state *state = tevent_req_data(
     2050                req, struct query_wins_list_state);
     2051        NTSTATUS status;
     2052
     2053        if (tevent_req_is_nterror(req, &status)) {
     2054                return status;
     2055        }
     2056        if (addrs != NULL) {
     2057                *addrs = talloc_move(mem_ctx, &state->addrs);
     2058        }
     2059        if (num_addrs != NULL) {
     2060                *num_addrs = state->num_addrs;
     2061        }
     2062        if (flags != NULL) {
     2063                *flags = state->flags;
     2064        }
     2065        return NT_STATUS_OK;
     2066}
     2067
     2068struct resolve_wins_state {
     2069        int num_sent;
     2070        int num_received;
     2071
     2072        struct sockaddr_storage *addrs;
     2073        int num_addrs;
     2074        uint8_t flags;
     2075};
     2076
     2077static void resolve_wins_done(struct tevent_req *subreq);
     2078
     2079struct tevent_req *resolve_wins_send(TALLOC_CTX *mem_ctx,
     2080                                     struct tevent_context *ev,
     2081                                     const char *name,
     2082                                     int name_type)
     2083{
     2084        struct tevent_req *req, *subreq;
     2085        struct resolve_wins_state *state;
     2086        char **wins_tags = NULL;
     2087        struct sockaddr_storage src_ss;
    16032088        struct in_addr src_ip;
    1604         NTSTATUS status;
    1605 
    1606         if (lp_disable_netbios()) {
    1607                 DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n",
    1608                                         name, name_type));
    1609                 return NT_STATUS_INVALID_PARAMETER;
    1610         }
    1611 
    1612         *return_iplist = NULL;
    1613         *return_count = 0;
    1614 
    1615         DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n",
    1616                                 name, name_type));
     2089        int i, num_wins_tags;
     2090
     2091        req = tevent_req_create(mem_ctx, &state,
     2092                                struct resolve_wins_state);
     2093        if (req == NULL) {
     2094                return NULL;
     2095        }
    16172096
    16182097        if (wins_srv_count() < 1) {
    16192098                DEBUG(3,("resolve_wins: WINS server resolution selected "
    16202099                        "and no WINS servers listed.\n"));
    1621                 return NT_STATUS_INVALID_PARAMETER;
    1622         }
    1623 
    1624         /* we try a lookup on each of the WINS tags in turn */
    1625         wins_tags = wins_srv_tags();
    1626 
    1627         if (!wins_tags) {
    1628                 /* huh? no tags?? give up in disgust */
    1629                 return NT_STATUS_INVALID_PARAMETER;
     2100                tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
     2101                goto fail;
    16302102        }
    16312103
    16322104        /* the address we will be sending from */
    1633         if (!interpret_string_addr(&src_ss, lp_socket_address(),
     2105        if (!interpret_string_addr(&src_ss, lp_nbt_client_socket_address(),
    16342106                                AI_NUMERICHOST|AI_PASSIVE)) {
    16352107                zero_sockaddr(&src_ss);
     
    16422114                        "on IPv6 address %s\n",
    16432115                        addr));
    1644                 wins_srv_tags_free(wins_tags);
    1645                 return NT_STATUS_INVALID_PARAMETER;
    1646         }
    1647 
    1648         src_ip = ((struct sockaddr_in *)&src_ss)->sin_addr;
    1649 
    1650         /* in the worst case we will try every wins server with every
    1651            tag! */
    1652         for (t=0; wins_tags && wins_tags[t]; t++) {
    1653                 int srv_count = wins_srv_count_tag(wins_tags[t]);
    1654                 for (i=0; i<srv_count; i++) {
    1655                         struct sockaddr_storage wins_ss;
    1656                         struct in_addr wins_ip;
    1657 
    1658                         wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
     2116                tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
     2117                goto fail;
     2118        }
     2119
     2120        src_ip = ((const struct sockaddr_in *)(void *)&src_ss)->sin_addr;
     2121
     2122        wins_tags = wins_srv_tags();
     2123        if (wins_tags == NULL) {
     2124                tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
     2125                goto fail;
     2126        }
     2127
     2128        num_wins_tags = 0;
     2129        while (wins_tags[num_wins_tags] != NULL) {
     2130                num_wins_tags += 1;
     2131        }
     2132
     2133        for (i=0; i<num_wins_tags; i++) {
     2134                int num_servers, num_alive;
     2135                struct in_addr *servers, *alive;
     2136                int j;
     2137
     2138                if (!wins_server_tag_ips(wins_tags[i], talloc_tos(),
     2139                                         &servers, &num_servers)) {
     2140                        DEBUG(10, ("wins_server_tag_ips failed for tag %s\n",
     2141                                   wins_tags[i]));
     2142                        continue;
     2143                }
     2144
     2145                alive = talloc_array(state, struct in_addr, num_servers);
     2146                if (tevent_req_nomem(alive, req)) {
     2147                        goto fail;
     2148                }
     2149
     2150                num_alive = 0;
     2151                for (j=0; j<num_servers; j++) {
     2152                        struct in_addr wins_ip = servers[j];
    16592153
    16602154                        if (global_in_nmbd && ismyip_v4(wins_ip)) {
     
    16622156                                continue;
    16632157                        }
    1664 
    16652158                        /* skip any that have been unresponsive lately */
    16662159                        if (wins_srv_is_dead(wins_ip, src_ip)) {
    16672160                                continue;
    16682161                        }
    1669 
    1670                         DEBUG(3,("resolve_wins: using WINS server %s "
    1671                                 "and tag '%s'\n",
    1672                                 inet_ntoa(wins_ip), wins_tags[t]));
    1673 
    1674                         in_addr_to_sockaddr_storage(&wins_ss, wins_ip);
    1675                         status = name_query(name,
    1676                                                 name_type,
    1677                                                 false,
    1678                                                 true,
    1679                                                 &wins_ss,
    1680                                                 talloc_tos(),
    1681                                                 &ss_list,
    1682                                                 return_count,
    1683                                                 NULL);
    1684 
    1685                         /* exit loop if we got a list of addresses */
    1686 
    1687                         if (NT_STATUS_IS_OK(status)) {
    1688                                 goto success;
    1689                         }
    1690 
    1691                         if (NT_STATUS_EQUAL(status,
    1692                                             NT_STATUS_IO_TIMEOUT)) {
    1693                                 /* Timed out waiting for WINS server to
    1694                                  * respond.
    1695                                  * Mark it dead. */
    1696                                 wins_srv_died(wins_ip, src_ip);
    1697                         } else {
    1698                                 /* The name definitely isn't in this
    1699                                    group of WINS servers.
    1700                                    goto the next group  */
    1701                                 break;
    1702                         }
    1703                 }
     2162                        DEBUG(3, ("resolve_wins: using WINS server %s "
     2163                                 "and tag '%s'\n",
     2164                                  inet_ntoa(wins_ip), wins_tags[i]));
     2165                        alive[num_alive] = wins_ip;
     2166                        num_alive += 1;
     2167                }
     2168                TALLOC_FREE(servers);
     2169
     2170                if (num_alive == 0) {
     2171                        continue;
     2172                }
     2173
     2174                subreq = query_wins_list_send(
     2175                        state, ev, src_ip, name, name_type,
     2176                        alive, num_alive);
     2177                if (tevent_req_nomem(subreq, req)) {
     2178                        goto fail;
     2179                }
     2180                tevent_req_set_callback(subreq, resolve_wins_done, req);
     2181                state->num_sent += 1;
     2182        }
     2183
     2184        if (state->num_sent == 0) {
     2185                tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
     2186                goto fail;
    17042187        }
    17052188
    17062189        wins_srv_tags_free(wins_tags);
    1707         return NT_STATUS_NO_LOGON_SERVERS;
    1708 
    1709 success:
    1710 
    1711         status = NT_STATUS_OK;
    1712         if (!convert_ss2service(return_iplist, ss_list, return_count))
    1713                 status = NT_STATUS_INVALID_PARAMETER;
    1714 
    1715         TALLOC_FREE(ss_list);
     2190        return req;
     2191fail:
    17162192        wins_srv_tags_free(wins_tags);
    1717 
     2193        return tevent_req_post(req, ev);
     2194}
     2195
     2196static void resolve_wins_done(struct tevent_req *subreq)
     2197{
     2198        struct tevent_req *req = tevent_req_callback_data(
     2199                subreq, struct tevent_req);
     2200        struct resolve_wins_state *state = tevent_req_data(
     2201                req, struct resolve_wins_state);
     2202        NTSTATUS status;
     2203
     2204        status = query_wins_list_recv(subreq, state, &state->addrs,
     2205                                      &state->num_addrs, &state->flags);
     2206        if (NT_STATUS_IS_OK(status)) {
     2207                tevent_req_done(req);
     2208                return;
     2209        }
     2210
     2211        state->num_received += 1;
     2212
     2213        if (state->num_received < state->num_sent) {
     2214                /*
     2215                 * Wait for the others
     2216                 */
     2217                return;
     2218        }
     2219        tevent_req_nterror(req, status);
     2220}
     2221
     2222NTSTATUS resolve_wins_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
     2223                           struct sockaddr_storage **addrs,
     2224                           int *num_addrs, uint8_t *flags)
     2225{
     2226        struct resolve_wins_state *state = tevent_req_data(
     2227                req, struct resolve_wins_state);
     2228        NTSTATUS status;
     2229
     2230        if (tevent_req_is_nterror(req, &status)) {
     2231                return status;
     2232        }
     2233        if (addrs != NULL) {
     2234                *addrs = talloc_move(mem_ctx, &state->addrs);
     2235        }
     2236        if (num_addrs != NULL) {
     2237                *num_addrs = state->num_addrs;
     2238        }
     2239        if (flags != NULL) {
     2240                *flags = state->flags;
     2241        }
     2242        return NT_STATUS_OK;
     2243}
     2244
     2245/********************************************************
     2246 Resolve via "wins" method.
     2247*********************************************************/
     2248
     2249NTSTATUS resolve_wins(const char *name,
     2250                int name_type,
     2251                TALLOC_CTX *mem_ctx,
     2252                struct sockaddr_storage **return_iplist,
     2253                int *return_count)
     2254{
     2255        struct tevent_context *ev;
     2256        struct tevent_req *req;
     2257        NTSTATUS status = NT_STATUS_NO_MEMORY;
     2258
     2259        ev = samba_tevent_context_init(talloc_tos());
     2260        if (ev == NULL) {
     2261                goto fail;
     2262        }
     2263        req = resolve_wins_send(ev, ev, name, name_type);
     2264        if (req == NULL) {
     2265                goto fail;
     2266        }
     2267        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
     2268                goto fail;
     2269        }
     2270        status = resolve_wins_recv(req, mem_ctx, return_iplist, return_count,
     2271                                   NULL);
     2272fail:
     2273        TALLOC_FREE(ev);
    17182274        return status;
    17192275}
    1720 
    1721 /********************************************************
    1722  Resolve via "lmhosts" method.
    1723 *********************************************************/
    1724 
    1725 static NTSTATUS resolve_lmhosts(const char *name, int name_type,
    1726                                 struct ip_service **return_iplist,
    1727                                 int *return_count)
    1728 {
    1729         /*
    1730          * "lmhosts" means parse the local lmhosts file.
    1731          */
    1732         struct sockaddr_storage *ss_list;
    1733         NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
    1734         TALLOC_CTX *ctx = NULL;
    1735 
    1736         *return_iplist = NULL;
    1737         *return_count = 0;
    1738 
    1739         DEBUG(3,("resolve_lmhosts: "
    1740                 "Attempting lmhosts lookup for name %s<0x%x>\n",
    1741                 name, name_type));
    1742 
    1743         ctx = talloc_init("resolve_lmhosts");
    1744         if (!ctx) {
    1745                 return NT_STATUS_NO_MEMORY;
    1746         }
    1747 
    1748         status = resolve_lmhosts_file_as_sockaddr(get_dyn_LMHOSTSFILE(),
    1749                                                   name, name_type,
    1750                                                   ctx,
    1751                                                   &ss_list,
    1752                                                   return_count);
    1753         if (NT_STATUS_IS_OK(status)) {
    1754                 if (convert_ss2service(return_iplist,
    1755                                        ss_list,
    1756                                        return_count)) {
    1757                         talloc_free(ctx);
    1758                         return NT_STATUS_OK;
    1759                 } else {
    1760                         talloc_free(ctx);
    1761                         return NT_STATUS_NO_MEMORY;
    1762                 }
    1763         }
    1764         talloc_free(ctx);
    1765         return status;
    1766 }
    1767 
    17682276
    17692277/********************************************************
     
    17722280
    17732281static NTSTATUS resolve_hosts(const char *name, int name_type,
    1774                               struct ip_service **return_iplist,
     2282                              TALLOC_CTX *mem_ctx,
     2283                              struct sockaddr_storage **return_iplist,
    17752284                              int *return_count)
    17762285{
     
    18332342                *return_count += 1;
    18342343
    1835                 *return_iplist = SMB_REALLOC_ARRAY(*return_iplist,
    1836                                                 struct ip_service,
    1837                                                 *return_count);
     2344                *return_iplist = talloc_realloc(
     2345                        mem_ctx, *return_iplist, struct sockaddr_storage,
     2346                        *return_count);
    18382347                if (!*return_iplist) {
    18392348                        DEBUG(3,("resolve_hosts: malloc fail !\n"));
     
    18412350                        return NT_STATUS_NO_MEMORY;
    18422351                }
    1843                 (*return_iplist)[i].ss = ss;
    1844                 (*return_iplist)[i].port = PORT_NONE;
     2352                (*return_iplist)[i] = ss;
    18452353                i++;
    18462354        }
     
    18852393
    18862394        /* The DNS code needs fixing to find IPv6 addresses... JRA. */
    1887 
    18882395        switch (name_type) {
    18892396                case 0x1b:
    18902397                        DEBUG(5,("resolve_ads: Attempting to resolve "
    18912398                                 "PDC for %s using DNS\n", name));
    1892                         status = ads_dns_query_pdc(ctx, name, &dcs, &numdcs);
     2399                        status = ads_dns_query_pdc(ctx,
     2400                                                   name,
     2401                                                   &dcs,
     2402                                                   &numdcs);
    18932403                        break;
    18942404
     
    18962406                        DEBUG(5,("resolve_ads: Attempting to resolve "
    18972407                                 "DCs for %s using DNS\n", name));
    1898                         status = ads_dns_query_dcs(ctx, name, sitename, &dcs,
     2408                        status = ads_dns_query_dcs(ctx,
     2409                                                   name,
     2410                                                   sitename,
     2411                                                   &dcs,
    18992412                                                   &numdcs);
    19002413                        break;
     
    19022415                        DEBUG(5,("resolve_ads: Attempting to resolve "
    19032416                                 "KDCs for %s using DNS\n", name));
    1904                         status = ads_dns_query_kdcs(ctx, name, sitename, &dcs,
     2417                        status = ads_dns_query_kdcs(ctx,
     2418                                                    name,
     2419                                                    sitename,
     2420                                                    &dcs,
    19052421                                                    &numdcs);
    19062422                        break;
     
    19132429                talloc_destroy(ctx);
    19142430                return status;
     2431        }
     2432
     2433        if (numdcs == 0) {
     2434                *return_iplist = NULL;
     2435                *return_count = 0;
     2436                talloc_destroy(ctx);
     2437                return NT_STATUS_OK;
    19152438        }
    19162439
     
    20122535}
    20132536
     2537static const char **filter_out_nbt_lookup(TALLOC_CTX *mem_ctx,
     2538                                          const char **resolve_order)
     2539{
     2540        size_t i, len, result_idx;
     2541        const char **result;
     2542
     2543        len = 0;
     2544        while (resolve_order[len] != NULL) {
     2545                len += 1;
     2546        }
     2547
     2548        result = talloc_array(mem_ctx, const char *, len+1);
     2549        if (result == NULL) {
     2550                return NULL;
     2551        }
     2552
     2553        result_idx = 0;
     2554
     2555        for (i=0; i<len; i++) {
     2556                const char *tok = resolve_order[i];
     2557
     2558                if (strequal(tok, "lmhosts") || strequal(tok, "wins") ||
     2559                    strequal(tok, "bcast")) {
     2560                        continue;
     2561                }
     2562                result[result_idx++] = tok;
     2563        }
     2564        result[result_idx] = NULL;
     2565
     2566        return result;
     2567}
     2568
    20142569/*******************************************************************
    20152570 Internal interface to resolve a name into an IP address.
     
    20282583                                struct ip_service **return_iplist,
    20292584                                int *return_count,
    2030                                 const char *resolve_order)
    2031 {
    2032         char *tok;
    2033         const char *ptr;
     2585                                const char **resolve_order)
     2586{
     2587        const char *tok;
    20342588        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
    20352589        int i;
     
    20842638        /* set the name resolution order */
    20852639
    2086         if (strcmp( resolve_order, "NULL") == 0) {
     2640        if (resolve_order && strcmp(resolve_order[0], "NULL") == 0) {
    20872641                DEBUG(8,("internal_resolve_name: all lookups disabled\n"));
    20882642                return NT_STATUS_INVALID_PARAMETER;
    20892643        }
    20902644
    2091         if (!resolve_order[0]) {
    2092                 ptr = "host";
    2093         } else {
    2094                 ptr = resolve_order;
     2645        if (!resolve_order || !resolve_order[0]) {
     2646                static const char *host_order[] = { "host", NULL };
     2647                resolve_order = host_order;
     2648        }
     2649
     2650        frame = talloc_stackframe();
     2651
     2652        if ((strlen(name) > MAX_NETBIOSNAME_LEN - 1) ||
     2653            (strchr(name, '.') != NULL)) {
     2654                /*
     2655                 * Don't do NBT lookup, the name would not fit anyway
     2656                 */
     2657                resolve_order = filter_out_nbt_lookup(frame, resolve_order);
     2658                if (resolve_order == NULL) {
     2659                        TALLOC_FREE(frame);
     2660                        return NT_STATUS_NO_MEMORY;
     2661                }
    20952662        }
    20962663
    20972664        /* iterate through the name resolution backends */
    20982665
    2099         frame = talloc_stackframe();
    2100         while (next_token_talloc(frame, &ptr, &tok, LIST_SEP)) {
     2666        for (i=0; resolve_order[i]; i++) {
     2667                tok = resolve_order[i];
     2668
    21012669                if((strequal(tok, "host") || strequal(tok, "hosts"))) {
    2102                         status = resolve_hosts(name, name_type, return_iplist,
     2670                        struct sockaddr_storage *ss_list;
     2671                        status = resolve_hosts(name, name_type,
     2672                                               talloc_tos(), &ss_list,
    21032673                                               return_count);
    21042674                        if (NT_STATUS_IS_OK(status)) {
     2675                                if (!convert_ss2service(return_iplist,
     2676                                                        ss_list,
     2677                                                        return_count)) {
     2678                                        status = NT_STATUS_NO_MEMORY;
     2679                                }
    21052680                                goto done;
    21062681                        }
     
    21242699                                goto done;
    21252700                        }
    2126                 } else if(strequal( tok, "lmhosts")) {
    2127                         status = resolve_lmhosts(name, name_type,
    2128                                                  return_iplist, return_count);
     2701                } else if (strequal(tok, "lmhosts")) {
     2702                        struct sockaddr_storage *ss_list;
     2703                        status = resolve_lmhosts_file_as_sockaddr(
     2704                                get_dyn_LMHOSTSFILE(), name, name_type,
     2705                                talloc_tos(), &ss_list, return_count);
    21292706                        if (NT_STATUS_IS_OK(status)) {
     2707                                if (!convert_ss2service(return_iplist,
     2708                                                        ss_list,
     2709                                                        return_count)) {
     2710                                        status = NT_STATUS_NO_MEMORY;
     2711                                }
    21302712                                goto done;
    21312713                        }
    2132                 } else if(strequal( tok, "wins")) {
     2714                } else if (strequal(tok, "wins")) {
    21332715                        /* don't resolve 1D via WINS */
     2716                        struct sockaddr_storage *ss_list;
    21342717                        if (name_type != 0x1D) {
    21352718                                status = resolve_wins(name, name_type,
    2136                                                       return_iplist,
     2719                                                      talloc_tos(),
     2720                                                      &ss_list,
    21372721                                                      return_count);
    21382722                                if (NT_STATUS_IS_OK(status)) {
     2723                                        if (!convert_ss2service(return_iplist,
     2724                                                                ss_list,
     2725                                                                return_count)) {
     2726                                                status = NT_STATUS_NO_MEMORY;
     2727                                        }
    21392728                                        goto done;
    21402729                                }
    21412730                        }
    2142                 } else if(strequal( tok, "bcast")) {
     2731                } else if (strequal(tok, "bcast")) {
    21432732                        struct sockaddr_storage *ss_list;
    21442733                        status = name_resolve_bcast(
     
    22302819        char *sitename = NULL;
    22312820        int count = 0;
     2821        NTSTATUS status;
    22322822
    22332823        if (is_ipaddress(name)) {
     
    22352825        }
    22362826
    2237         sitename = sitename_fetch(lp_realm()); /* wild guess */
    2238 
    2239         if (NT_STATUS_IS_OK(internal_resolve_name(name, name_type, sitename,
    2240                                                   &ss_list, &count,
    2241                                                   lp_name_resolve_order()))) {
     2827        sitename = sitename_fetch(talloc_tos(), lp_realm()); /* wild guess */
     2828
     2829        status = internal_resolve_name(name, name_type, sitename,
     2830                                       &ss_list, &count,
     2831                                       lp_name_resolve_order());
     2832        if (NT_STATUS_IS_OK(status)) {
    22422833                int i;
    22432834
     
    22452836                        for (i=0; i<count; i++) {
    22462837                                if (!is_zero_addr(&ss_list[i].ss) &&
    2247                                                 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss) &&
     2838                                    !is_broadcast_addr((struct sockaddr *)(void *)&ss_list[i].ss) &&
    22482839                                                (ss_list[i].ss.ss_family == AF_INET)) {
    22492840                                        *return_ss = ss_list[i].ss;
    22502841                                        SAFE_FREE(ss_list);
    2251                                         SAFE_FREE(sitename);
     2842                                        TALLOC_FREE(sitename);
    22522843                                        return True;
    22532844                                }
     
    22582849                for (i=0; i<count; i++) {
    22592850                        if (!is_zero_addr(&ss_list[i].ss) &&
    2260                                         !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) {
     2851                            !is_broadcast_addr((struct sockaddr *)(void *)&ss_list[i].ss)) {
    22612852                                *return_ss = ss_list[i].ss;
    22622853                                SAFE_FREE(ss_list);
    2263                                 SAFE_FREE(sitename);
     2854                                TALLOC_FREE(sitename);
    22642855                                return True;
    22652856                        }
     
    22682859
    22692860        SAFE_FREE(ss_list);
    2270         SAFE_FREE(sitename);
     2861        TALLOC_FREE(sitename);
    22712862        return False;
    22722863}
     
    22962887
    22972888        if (is_ipaddress(name)) {
    2298                 *return_ss_arr = TALLOC_P(ctx, struct sockaddr_storage);
     2889                *return_ss_arr = talloc(ctx, struct sockaddr_storage);
    22992890                if (!*return_ss_arr) {
    23002891                        return NT_STATUS_NO_MEMORY;
     
    23082899        }
    23092900
    2310         sitename = sitename_fetch(lp_realm()); /* wild guess */
     2901        sitename = sitename_fetch(ctx, lp_realm()); /* wild guess */
    23112902
    23122903        status = internal_resolve_name(name, name_type, sitename,
    23132904                                                  &ss_list, &count,
    23142905                                                  lp_name_resolve_order());
    2315         SAFE_FREE(sitename);
     2906        TALLOC_FREE(sitename);
    23162907
    23172908        if (!NT_STATUS_IS_OK(status)) {
     
    23222913        for (i=0, num_entries = 0; i<count; i++) {
    23232914                if (!is_zero_addr(&ss_list[i].ss) &&
    2324                                 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) {
     2915                    !is_broadcast_addr((struct sockaddr *)(void *)&ss_list[i].ss)) {
    23252916                        num_entries++;
    23262917                }
     
    23312922        }
    23322923
    2333         *return_ss_arr = TALLOC_ARRAY(ctx,
     2924        *return_ss_arr = talloc_array(ctx,
    23342925                                struct sockaddr_storage,
    23352926                                num_entries);
     
    23412932        for (i=0, num_entries = 0; i<count; i++) {
    23422933                if (!is_zero_addr(&ss_list[i].ss) &&
    2343                                 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) {
     2934                    !is_broadcast_addr((struct sockaddr *)(void *)&ss_list[i].ss)) {
    23442935                        (*return_ss_arr)[num_entries++] = ss_list[i].ss;
    23452936                }
     
    23982989        int count = 0;
    23992990        NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
    2400 
     2991        static const char *ads_order[] = { "ads", NULL };
    24012992        /* Look up #1B name */
    24022993
    24032994        if (lp_security() == SEC_ADS) {
    24042995                status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
    2405                                                &count, "ads");
     2996                                               &count, ads_order);
    24062997        }
    24072998
     
    24113002                                               lp_name_resolve_order());
    24123003                if (!NT_STATUS_IS_OK(status)) {
     3004                        SAFE_FREE(ip_list);
    24133005                        return false;
    24143006                }
     
    24443036                        bool *ordered)
    24453037{
    2446         char *resolve_order = NULL;
     3038        const char **resolve_order = NULL;
    24473039        char *saf_servername = NULL;
    24483040        char *pserver = NULL;
     
    24593051        NTSTATUS status;
    24603052        TALLOC_CTX *ctx = talloc_init("get_dc_list");
     3053        int auto_name_type = 0x1C;
    24613054
    24623055        *ip_list = NULL;
     
    24753068           NULL. */
    24763069
    2477         resolve_order = talloc_strdup(ctx, lp_name_resolve_order());
     3070        resolve_order = lp_name_resolve_order();
    24783071        if (!resolve_order) {
    24793072                status = NT_STATUS_NO_MEMORY;
    24803073                goto out;
    24813074        }
    2482         strlower_m(resolve_order);
    24833075        if (lookup_type == DC_ADS_ONLY)  {
    2484                 if (strstr( resolve_order, "host")) {
    2485                         resolve_order = talloc_strdup(ctx, "ads");
     3076                if (str_list_check_ci(resolve_order, "host")) {
     3077                        static const char *ads_order[] = { "ads", NULL };
     3078                        resolve_order = ads_order;
    24863079
    24873080                        /* DNS SRV lookups used by the ads resolver
     
    24893082                        *ordered = true;
    24903083                } else {
    2491                         resolve_order = talloc_strdup(ctx, "NULL");
     3084                        /* this is quite bizarre! */
     3085                        static const char *null_order[] = { "NULL", NULL };
     3086                        resolve_order = null_order;
    24923087                }
    24933088        } else if (lookup_type == DC_KDC_ONLY) {
     3089                static const char *kdc_order[] = { "kdc", NULL };
    24943090                /* DNS SRV lookups used by the ads/kdc resolver
    24953091                   are already sorted by priority and weight */
    24963092                *ordered = true;
    2497                 resolve_order = talloc_strdup(ctx, "kdc");
    2498         }
    2499         if (!resolve_order) {
    2500                 status = NT_STATUS_NO_MEMORY;
    2501                 goto out;
     3093                resolve_order = kdc_order;
     3094                auto_name_type = KDC_NAME_TYPE;
    25023095        }
    25033096
     
    25053098           'password server' list to a search for our domain controllers */
    25063099
    2507         saf_servername = saf_fetch( domain);
     3100        saf_servername = saf_fetch(ctx, domain);
    25083101
    25093102        if (strequal(domain, lp_workgroup()) || strequal(domain, lp_realm())) {
    25103103                pserver = talloc_asprintf(ctx, "%s, %s",
    25113104                        saf_servername ? saf_servername : "",
    2512                         lp_passwordserver());
     3105                        lp_password_server());
    25133106        } else {
    25143107                pserver = talloc_asprintf(ctx, "%s, *",
     
    25163109        }
    25173110
    2518         SAFE_FREE(saf_servername);
     3111        TALLOC_FREE(saf_servername);
    25193112        if (!pserver) {
    25203113                status = NT_STATUS_NO_MEMORY;
    2521                 goto out;
    2522         }
    2523 
    2524         /* if we are starting from scratch, just lookup DOMAIN<0x1c> */
    2525 
    2526         if (!*pserver ) {
    2527                 DEBUG(10,("get_dc_list: no preferred domain controllers.\n"));
    2528                 status = internal_resolve_name(domain, 0x1C, sitename, ip_list,
    2529                                              count, resolve_order);
    25303114                goto out;
    25313115        }
     
    25433127        while (next_token_talloc(ctx, &p, &name, LIST_SEP)) {
    25443128                if (!done_auto_lookup && strequal(name, "*")) {
    2545                         status = internal_resolve_name(domain, 0x1C, sitename,
     3129                        status = internal_resolve_name(domain, auto_name_type,
     3130                                                       sitename,
    25463131                                                       &auto_ip_list,
    25473132                                                       &auto_count,
     
    25613146           just return the list of DC's.  Or maybe we just failed. */
    25623147
    2563         if ((num_addresses == 0)) {
     3148        if (num_addresses == 0) {
    25643149                if (done_auto_lookup) {
    25653150                        DEBUG(4,("get_dc_list: no servers found\n"));
     
    25673152                        goto out;
    25683153                }
    2569                 status = internal_resolve_name(domain, 0x1C, sitename, ip_list,
     3154                status = internal_resolve_name(domain, auto_name_type,
     3155                                               sitename, ip_list,
    25703156                                             count, resolve_order);
    25713157                goto out;
     
    26193205                 * (not that I think anyone will ever run the LDAP
    26203206                 * server in an AD domain on something other than
    2621                  * port 389 */
    2622 
    2623                 port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE;
     3207                 * port 389
     3208                 * However, the port should not be used for kerberos
     3209                 */
     3210
     3211                port = (lookup_type == DC_ADS_ONLY) ? LDAP_PORT :
     3212                        ((lookup_type == DC_KDC_ONLY) ? DEFAULT_KRB5_PORT :
     3213                         PORT_NONE);
    26243214                if ((port_str=strchr(name, ':')) != NULL) {
    26253215                        *port_str = '\0';
    2626                         port_str++;
    2627                         port = atoi(port_str);
     3216                        if (lookup_type != DC_KDC_ONLY) {
     3217                                port_str++;
     3218                                port = atoi(port_str);
     3219                        }
    26283220                }
    26293221
     
    27163308
    27173309        DEBUG(8,("get_sorted_dc_list: attempting lookup "
    2718                 "for name %s (sitename %s) using [%s]\n",
     3310                "for name %s (sitename %s)\n",
    27193311                domain,
    2720                 sitename ? sitename : "NULL",
    2721                 (ads_only ? "ads" : lp_name_resolve_order())));
     3312                 sitename ? sitename : "NULL"));
    27223313
    27233314        if (ads_only) {
Note: See TracChangeset for help on using the changeset viewer.